void SVGOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out) { gp_Circ circ = c.Circle(); const gp_Pnt& p= circ.Location(); double r = circ.Radius(); double f = c.FirstParameter(); double l = c.LastParameter(); gp_Pnt s = c.Value(f); gp_Pnt m = c.Value((l+f)/2.0); gp_Pnt e = c.Value(l); gp_Vec v1(m,s); gp_Vec v2(m,e); gp_Vec v3(0,0,1); double a = v3.DotCross(v1,v2); // a full circle if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) { out << "<circle cx =\"" << p.X() << "\" cy =\"" << p.Y() << "\" r =\"" << r << "\" />"; } // arc of circle else { // See also https://developer.mozilla.org/en/SVG/Tutorial/Paths char xar = '0'; // x-axis-rotation char las = (l-f > D_PI) ? '1' : '0'; // large-arc-flag char swp = (a < 0) ? '1' : '0'; // sweep-flag, i.e. clockwise (0) or counter-clockwise (1) out << "<path d=\"M" << s.X() << " " << s.Y() << " A" << r << " " << r << " " << xar << " " << las << " " << swp << " " << e.X() << " " << e.Y() << "\" />"; } }
void DXFOutput::printGeneric(const BRepAdaptor_Curve& c, int id, std::ostream& out) { double uStart = c.FirstParameter(); gp_Pnt PS; gp_Vec VS; c.D1(uStart, PS, VS); double uEnd = c.LastParameter(); gp_Pnt PE; gp_Vec VE; c.D1(uEnd, PE, VE); out << "0" << endl; out << "LINE" << endl; out << "8" << endl; // Group code for layer name out << "sheet_layer" << endl; // Layer name out << "10" << endl; // Start point of line out << PS.X() << endl; // X in WCS coordinates out << "20" << endl; out << PS.Y() << endl; // Y in WCS coordinates out << "30" << endl; out << "0" << endl; // Z in WCS coordinates out << "11" << endl; // End point of line out << PE.X() << endl; // X in WCS coordinates out << "21" << endl; out << PE.Y() << endl; // Y in WCS coordinates out << "31" << endl; out << "0" << endl; // Z in WCS coordinates }
void ImpExpDxfWrite::exportArc(BRepAdaptor_Curve& c) { gp_Circ circ = c.Circle(); gp_Pnt p = circ.Location(); double center[3] = {0,0,0}; gPntToTuple(center, p); double f = c.FirstParameter(); double l = c.LastParameter(); gp_Pnt s = c.Value(f); double start[3]; gPntToTuple(start, s); gp_Pnt m = c.Value((l+f)/2.0); gp_Pnt e = c.Value(l); double end[3] = {0,0,0}; gPntToTuple(end, e); gp_Vec v1(m,s); gp_Vec v2(m,e); gp_Vec v3(0,0,1); double a = v3.DotCross(v1,v2); bool dir = (a < 0) ? true: false; writeArc(start, end, center, dir ); }
void ImpExpDxfWrite::exportLine(BRepAdaptor_Curve& c) { double f = c.FirstParameter(); double l = c.LastParameter(); gp_Pnt s = c.Value(f); double start[3] = {0,0,0}; gPntToTuple(start, s); gp_Pnt e = c.Value(l); double end[3] = {0,0,0}; gPntToTuple(end, e); writeLine(start, end); }
void ImpExpDxfWrite::exportEllipseArc(BRepAdaptor_Curve& c) { gp_Elips ellp = c.Ellipse(); gp_Pnt p = ellp.Location(); double center[3] = {0,0,0}; gPntToTuple(center, p); double major = ellp.MajorRadius(); double minor = ellp.MinorRadius(); gp_Dir xaxis = ellp.XAxis().Direction(); //direction of major axis //rotation appears to be the clockwise angle between major & +Y?? double rotation = xaxis.AngleWithRef(gp_Dir(0, 1, 0), gp_Dir(0, 0, 1)); double f = c.FirstParameter(); double l = c.LastParameter(); gp_Pnt s = c.Value(f); gp_Pnt m = c.Value((l+f)/2.0); gp_Pnt e = c.Value(l); gp_Vec v1(m,s); gp_Vec v2(m,e); gp_Vec v3(0,0,1); 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); //revolutions double endAngle = fmod(l,2.0*M_PI); 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, endIsCW); }
void SVGOutput::printEllipse(const BRepAdaptor_Curve& c, int id, std::ostream& out) { gp_Elips ellp = c.Ellipse(); const gp_Pnt& p= ellp.Location(); double r1 = ellp.MajorRadius(); double r2 = ellp.MinorRadius(); double f = c.FirstParameter(); double l = c.LastParameter(); gp_Pnt s = c.Value(f); gp_Pnt m = c.Value((l+f)/2.0); gp_Pnt e = c.Value(l); gp_Vec v1(m,s); gp_Vec v2(m,e); gp_Vec v3(0,0,1); double a = v3.DotCross(v1,v2); // a full ellipse // See also https://developer.mozilla.org/en/SVG/Tutorial/Paths gp_Dir xaxis = ellp.XAxis().Direction(); Standard_Real angle = xaxis.AngleWithRef(gp_Dir(1,0,0),gp_Dir(0,0,-1)); angle = Base::toDegrees<double>(angle); if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) { out << "<g transform = \"rotate(" << angle << "," << p.X() << "," << p.Y() << ")\">" << std::endl; out << "<ellipse cx =\"" << p.X() << "\" cy =\"" << p.Y() << "\" rx =\"" << r1 << "\" ry =\"" << r2 << "\"/>" << std::endl; out << "</g>" << std::endl; } // arc of ellipse else { char las = (l-f > D_PI) ? '1' : '0'; // large-arc-flag char swp = (a < 0) ? '1' : '0'; // sweep-flag, i.e. clockwise (0) or counter-clockwise (1) out << "<path d=\"M" << s.X() << " " << s.Y() << " A" << r1 << " " << r2 << " " << angle << " " << las << " " << swp << " " << e.X() << " " << e.Y() << "\" />" << std::endl; } }
void DXFOutput::printEllipse(const BRepAdaptor_Curve& c, int id, std::ostream& out) { gp_Elips ellp = c.Ellipse(); const gp_Pnt& p= ellp.Location(); double r1 = ellp.MajorRadius(); double r2 = ellp.MinorRadius(); double f = c.FirstParameter(); double l = c.LastParameter(); gp_Pnt s = c.Value(f); gp_Pnt m = c.Value((l+f)/2.0); gp_Pnt e = c.Value(l); gp_Vec v1(m,s); gp_Vec v2(m,e); gp_Vec v3(0,0,1); double a = v3.DotCross(v1,v2); // a full ellipse /* if (s.SquareDistance(e) < 0.001) { out << "<ellipse cx =\"" << p.X() << "\" cy =\"" << p.Y() << "\" rx =\"" << r1 << "\" ry =\"" << r2 << "\"/>"; } // arc of ellipse else { // See also https://developer.mozilla.org/en/SVG/Tutorial/Paths gp_Dir xaxis = ellp.XAxis().Direction(); Standard_Real angle = xaxis.Angle(gp_Dir(1,0,0)); angle = Base::toDegrees<double>(angle); char las = (l-f > D_PI) ? '1' : '0'; // large-arc-flag char swp = (a < 0) ? '1' : '0'; // sweep-flag, i.e. clockwise (0) or counter-clockwise (1) out << "<path d=\"M" << s.X() << " " << s.Y() << " A" << r1 << " " << r2 << " " << angle << " " << las << " " << swp << " " << e.X() << " " << e.Y() << "\" />"; }*/ gp_Dir xaxis = ellp.XAxis().Direction(); double angle = xaxis.Angle(gp_Dir(1,0,0)); //double rotation = Base::toDegrees<double>(angle); double ax = s.X() - p.X(); double ay = s.Y() - p.Y(); double bx = e.X() - p.X(); double by = e.Y() - p.Y(); double start_angle = atan2(ay, ax) * 180/D_PI; double end_angle = atan2(by, bx) * 180/D_PI; double major_x;double major_y; major_x = r1 * sin(angle*90); major_y = r1 * cos(angle*90); double ratio = r2/r1; if(a > 0){ double temp = start_angle; start_angle = end_angle; end_angle = temp; } out << 0 << endl; out << "ELLIPSE" << endl; out << 8 << endl; // Group code for layer name out << "sheet_layer" << endl; // Layer number out << 10 << endl; // Centre X out << p.X() << endl; // X in WCS coordinates out << 20 << endl; out << p.Y() << endl; // Y in WCS coordinates out << 30 << endl; out << 0 << endl; // Z in WCS coordinates out << 11 << endl; // out << major_x << endl; // Major X out << 21 << endl; out << major_y << endl; // Major Y out << 31 << endl; out << 0 << endl; // Major Z out << 40 << endl; // out << ratio << endl; // Ratio out << 41 << endl; out << start_angle << endl; // Start angle out << 42 << endl; out << end_angle << endl; // End angle }
void DXFOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out) { gp_Circ circ = c.Circle(); //const gp_Ax1& axis = c->Axis(); const gp_Pnt& p= circ.Location(); double r = circ.Radius(); double f = c.FirstParameter(); double l = c.LastParameter(); gp_Pnt s = c.Value(f); gp_Pnt m = c.Value((l+f)/2.0); gp_Pnt e = c.Value(l); gp_Vec v1(m,s); gp_Vec v2(m,e); gp_Vec v3(0,0,1); double a = v3.DotCross(v1,v2); // a full circle if (s.SquareDistance(e) < 0.001) { //out << "<circle cx =\"" << p.X() << "\" cy =\"" //<< p.Y() << "\" r =\"" << r << "\" />"; out << 0 << endl; out << "CIRCLE" << endl; out << 8 << endl; // Group code for layer name out << "sheet_layer" << endl; // Layer number out << 10 << endl; // Centre X out << p.X() << endl; // X in WCS coordinates out << 20 << endl; out << p.Y() << endl; // Y in WCS coordinates out << 30 << endl; out << 0 << endl; // Z in WCS coordinates-leaving flat out << 40 << endl; // out << r << endl; // Radius } // arc of circle else { // See also https://developer.mozilla.org/en/SVG/Tutorial/Paths /*char xar = '0'; // x-axis-rotation char las = (l-f > D_PI) ? '1' : '0'; // large-arc-flag char swp = (a < 0) ? '1' : '0'; // sweep-flag, i.e. clockwise (0) or counter-clockwise (1) out << "<path d=\"M" << s.X() << " " << s.Y() << " A" << r << " " << r << " " << xar << " " << las << " " << swp << " " << e.X() << " " << e.Y() << "\" />";*/ double ax = s.X() - p.X(); double ay = s.Y() - p.Y(); double bx = e.X() - p.X(); double by = e.Y() - p.Y(); double start_angle = atan2(ay, ax) * 180/D_PI; double end_angle = atan2(by, bx) * 180/D_PI; if(a > 0){ double temp = start_angle; start_angle = end_angle; end_angle = temp;} out << 0 << endl; out << "ARC" << endl; out << 8 << endl; // Group code for layer name out << "sheet_layer" << endl; // Layer number out << 10 << endl; // Centre X out << p.X() << endl; // X in WCS coordinates out << 20 << endl; out << p.Y() << endl; // Y in WCS coordinates out << 30 << endl; out << 0 << endl; // Z in WCS coordinates out << 40 << endl; // out << r << endl; // Radius out << 50 << endl; out << start_angle << endl; // Start angle out << 51 << endl; out << end_angle << endl; // End angle } }
void ImpExpDxfWrite::exportBSpline(BRepAdaptor_Curve& c) { SplineDataOut sd; Handle(Geom_BSplineCurve) spline; double f,l; gp_Pnt s,ePt; Standard_Real tol3D = 0.001; Standard_Integer maxDegree = 3, maxSegment = 100; Handle(BRepAdaptor_HCurve) hCurve = new BRepAdaptor_HCurve(c); Approx_Curve3d approx(hCurve, tol3D, GeomAbs_C0, maxSegment, maxDegree); if (approx.IsDone() && approx.HasResult()) { spline = approx.Curve(); } else { if (approx.HasResult()) { //result, but not within tolerance spline = approx.Curve(); Base::Console().Message("DxfWrite::exportBSpline - result not within tolerance\n"); } else { f = c.FirstParameter(); l = c.LastParameter(); s = c.Value(f); ePt = c.Value(l); Base::Console().Message("DxfWrite::exportBSpline - no result- from:(%.3f,%.3f) to:(%.3f,%.3f) poles: %d\n", s.X(),s.Y(),ePt.X(),ePt.Y(),spline->NbPoles()); TColgp_Array1OfPnt controlPoints(0,1); controlPoints.SetValue(0,s); controlPoints.SetValue(1,ePt); spline = GeomAPI_PointsToBSpline(controlPoints,1).Curve(); } } //WF? norm of surface containing curve?? sd.norm.x = 0.0; sd.norm.y = 0.0; sd.norm.z = 1.0; sd.flag = spline->IsClosed(); sd.flag += spline->IsPeriodic()*2; sd.flag += spline->IsRational()*4; sd.flag += 8; //planar spline sd.degree = spline->Degree(); sd.control_points = spline->NbPoles(); sd.knots = spline->NbKnots(); gp_Pnt p; spline->D0(spline->FirstParameter(),p); sd.starttan = gPntTopoint3D(p); spline->D0(spline->LastParameter(),p); sd.endtan = gPntTopoint3D(p); //next bit is from DrawingExport.cpp (Dan Falk?). Standard_Integer m = 0; if (spline->IsPeriodic()) { m = spline->NbPoles() + 2*spline->Degree() - spline->Multiplicity(1) + 2; } else { for (int i=1; i<= spline->NbKnots(); i++) m += spline->Multiplicity(i); } TColStd_Array1OfReal knotsequence(1,m); spline->KnotSequence(knotsequence); for (int i = knotsequence.Lower() ; i <= knotsequence.Upper(); i++) { sd.knot.push_back(knotsequence(i)); } sd.knots = knotsequence.Length(); TColgp_Array1OfPnt poles(1,spline->NbPoles()); spline->Poles(poles); for (int i = poles.Lower(); i <= poles.Upper(); i++) { sd.control.push_back(gPntTopoint3D(poles(i))); } //OCC doesn't have separate lists for control points and fit points. writeSpline(sd); }