From f41598ee33fcbc599d997252e7b214b3fa960d2f Mon Sep 17 00:00:00 2001 From: wandererfan Date: Mon, 14 May 2018 09:17:00 -0400 Subject: [PATCH] Fix CCW ellipse arcs --- src/Mod/Import/App/ImpExpDxf.cpp | 16 +++++++++--- src/Mod/Import/App/dxf.cpp | 45 +++++++++++++++++++++++++------- src/Mod/Import/App/dxf.h | 4 +-- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/Mod/Import/App/ImpExpDxf.cpp b/src/Mod/Import/App/ImpExpDxf.cpp index eddffa9741..27776eb22c 100644 --- a/src/Mod/Import/App/ImpExpDxf.cpp +++ b/src/Mod/Import/App/ImpExpDxf.cpp @@ -472,13 +472,21 @@ void ImpExpDxfWrite::exportEllipseArc(BRepAdaptor_Curve c) gp_Vec v1(m,s); gp_Vec v2(m,e); gp_Vec v3(0,0,1); - double a = v3.DotCross(v1,v2); + double a = v3.DotCross(v1,v2); // a = v3 dot (v1 cross v2) + // relates to "handedness" of 3 vectors + // a > 0 ==> v2 is CCW from v1 (righthanded)? + // a < 0 ==> v2 is CW from v1 (lefthanded)? - double startAngle = fmod(f,2.0*M_PI); + double startAngle = fmod(f,2.0*M_PI); //revolutions double endAngle = fmod(l,2.0*M_PI); - bool dir = (a < 0) ? true: false; + bool endIsCW = (a < 0) ? true: false; //if !endIsCW swap(start,end) + //not sure if this is a hack or not. seems to make valid arcs. + if (!endIsCW) { + startAngle = -startAngle; + endAngle = -endAngle; + } - WriteEllipse(center, major, minor, rotation, startAngle, endAngle, dir, getLayerName().c_str() ); + WriteEllipse(center, major, minor, rotation, startAngle, endAngle, endIsCW, getLayerName().c_str()); } void ImpExpDxfWrite::exportBSpline(BRepAdaptor_Curve c) diff --git a/src/Mod/Import/App/dxf.cpp b/src/Mod/Import/App/dxf.cpp index 210f47491d..d66079af04 100644 --- a/src/Mod/Import/App/dxf.cpp +++ b/src/Mod/Import/App/dxf.cpp @@ -108,13 +108,16 @@ void CDxfWrite::WriteLWPolyLine(LWPolyDataOut pd, const char* layer_name) (*m_ofs) << 230 << endl; (*m_ofs) << pd.Extr.z << endl; } + void CDxfWrite::WritePoint(const double* s, const char* layer_name) { (*m_ofs) << 0 << endl; (*m_ofs) << "POINT" << endl; (*m_ofs) << 8 << endl; // Group code for layer name - (*m_ofs) << layer_name << endl; // Layer number - (*m_ofs) << 10 << endl; // Start point of line + (*m_ofs) << layer_name << endl; // Layer name + (*m_ofs) << 100 << endl; + (*m_ofs) << "AcDbPoint" << endl; + (*m_ofs) << 10 << endl; (*m_ofs) << s[0] << endl; // X in WCS coordinates (*m_ofs) << 20 << endl; (*m_ofs) << s[1] << endl; // Y in WCS coordinates @@ -171,7 +174,7 @@ void CDxfWrite::WriteCircle(const double* c, double radius, const char* layer_na (*m_ofs) << radius << endl; // Radius } -void CDxfWrite::WriteEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool dir, const char* layer_name ) +void CDxfWrite::WriteEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool endIsCW, const char* layer_name ) { double m[3]; m[2]=0; @@ -180,7 +183,7 @@ void CDxfWrite::WriteEllipse(const double* c, double major_radius, double minor_ double ratio = minor_radius/major_radius; - if(!dir){ + if(!endIsCW){ //end is NOT CW from start double temp = start_angle; start_angle = end_angle; end_angle = temp; @@ -203,9 +206,10 @@ void CDxfWrite::WriteEllipse(const double* c, double major_radius, double minor_ (*m_ofs) << m[1] << endl; // Major Y (*m_ofs) << 31 << endl; (*m_ofs) << m[2] << endl; // Major Z - (*m_ofs) << 41 << endl; - (*m_ofs) << start_angle << endl; // Start angle - (*m_ofs) << 42 << endl; + // 210,220,230 extrusion direction X,Y,Z + (*m_ofs) << 41 << endl; + (*m_ofs) << start_angle << endl; // Start angle (radians [0..2pi]) + (*m_ofs) << 42 << endl; (*m_ofs) << end_angle << endl; // End angle } @@ -217,11 +221,12 @@ void CDxfWrite::WriteSpline(SplineDataOut sd, const char* layer_name) (*m_ofs) << 0 << endl; (*m_ofs) << "SPLINE" << endl; (*m_ofs) << 8 << endl; // Group code for layer name - (*m_ofs) << layer_name << endl; // Layer number + (*m_ofs) << layer_name << endl; // Layer name (*m_ofs) << 100 << endl; (*m_ofs) << "AcDbEntity" << endl; (*m_ofs) << 100 << endl; - (*m_ofs) << "AcDbSpline" << endl; //normal 210,220,230 + (*m_ofs) << "AcDbSpline" << endl; + //normal 210,220,230 (*m_ofs) << 70 << endl; (*m_ofs) << sd.flag << endl; //flags (*m_ofs) << 71 << endl; @@ -274,6 +279,28 @@ void CDxfWrite::WriteSpline(SplineDataOut sd, const char* layer_name) } } +//*************************** +//WriteVertex +//added by Wandererfan 2018 (wandererfan@gmail.com) for FreeCAD project +void CDxfWrite::WriteVertex(double x, double y, double z, const char* layer_name) +{ + (*m_ofs) << 0 << endl; + (*m_ofs) << "VERTEX" << endl; + (*m_ofs) << 8 << endl; + (*m_ofs) << layer_name << endl; + (*m_ofs) << 100 << endl; + (*m_ofs) << "AcDbEntity" << endl; + (*m_ofs) << 100 << endl; + (*m_ofs) << "AcDbVertex" << endl; + (*m_ofs) << 10 << endl; + (*m_ofs) << x << endl; + (*m_ofs) << 20 << endl; + (*m_ofs) << y << endl; + (*m_ofs) << 30 << endl; + (*m_ofs) << z << endl; + (*m_ofs) << 70 << endl; //flag + (*m_ofs) << 0 << endl; +} CDxfRead::CDxfRead(const char* filepath) diff --git a/src/Mod/Import/App/dxf.h b/src/Mod/Import/App/dxf.h index f6534d27a4..2b516b9cdc 100644 --- a/src/Mod/Import/App/dxf.h +++ b/src/Mod/Import/App/dxf.h @@ -130,11 +130,11 @@ public: void WriteLine(const double* s, const double* e, const char* layer_name ); void WritePoint(const double*, const char*); void WriteArc(const double* s, const double* e, const double* c, bool dir, const char* layer_name ); - void WriteEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool dir, const char* layer_name ); + void WriteEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool endIsCW, const char* layer_name); void WriteCircle(const double* c, double radius, const char* layer_name ); void WriteSpline(SplineDataOut sd, const char* layer_name); void WriteLWPolyLine(LWPolyDataOut pd, const char* layer_name); - + void WriteVertex(double x, double y, double z, const char* layer_name); }; // derive a class from this and implement it's virtual functions