00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <sstream>
00028 # include <BRepAdaptor_Curve.hxx>
00029 # include <Geom_Circle.hxx>
00030 # include <gp_Circ.hxx>
00031 # include <gp_Elips.hxx>
00032 #endif
00033
00034 #include <Bnd_Box.hxx>
00035 #include <BRepBndLib.hxx>
00036 #include <BRepBuilderAPI_Transform.hxx>
00037 #include <HLRBRep_Algo.hxx>
00038 #include <TopoDS_Shape.hxx>
00039 #include <HLRTopoBRep_OutLiner.hxx>
00040
00041 #include <HLRAlgo_Projector.hxx>
00042 #include <HLRBRep_ShapeBounds.hxx>
00043 #include <HLRBRep_HLRToShape.hxx>
00044 #include <gp_Ax2.hxx>
00045 #include <gp_Pnt.hxx>
00046 #include <gp_Dir.hxx>
00047 #include <gp_Vec.hxx>
00048 #include <Poly_Polygon3D.hxx>
00049 #include <Poly_Triangulation.hxx>
00050 #include <Poly_PolygonOnTriangulation.hxx>
00051 #include <TopoDS.hxx>
00052 #include <TopoDS_Face.hxx>
00053 #include <TopoDS_Edge.hxx>
00054 #include <TopoDS_Vertex.hxx>
00055 #include <TopExp.hxx>
00056 #include <TopExp_Explorer.hxx>
00057 #include <TopTools_IndexedMapOfShape.hxx>
00058 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00059 #include <TopTools_ListOfShape.hxx>
00060 #include <TColgp_Array1OfPnt2d.hxx>
00061 #include <BRep_Tool.hxx>
00062 #include <BRepMesh.hxx>
00063
00064 #include <BRepAdaptor_CompCurve.hxx>
00065 #include <Handle_BRepAdaptor_HCompCurve.hxx>
00066 #include <Approx_Curve3d.hxx>
00067 #include <BRepAdaptor_HCurve.hxx>
00068 #include <Handle_BRepAdaptor_HCurve.hxx>
00069 #include <Geom_BSplineCurve.hxx>
00070 #include <Handle_Geom_BSplineCurve.hxx>
00071 #include <Geom_BezierCurve.hxx>
00072 #include <GeomConvert_BSplineCurveToBezierCurve.hxx>
00073 #include <GeomConvert_BSplineCurveKnotSplitting.hxx>
00074 #include <Geom2d_BSplineCurve.hxx>
00075
00076 #include "DrawingExport.h"
00077 #include <Base/Tools.h>
00078 #include <Base/Vector3D.h>
00079
00080 using namespace Drawing;
00081
00082 SVGOutput::SVGOutput()
00083 {
00084 }
00085
00086 std::string SVGOutput::exportEdges(const TopoDS_Shape& input)
00087 {
00088 std::stringstream result;
00089
00090 TopExp_Explorer edges(input, TopAbs_EDGE);
00091 for (int i = 1 ; edges.More(); edges.Next(),i++) {
00092 const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
00093 BRepAdaptor_Curve adapt(edge);
00094 if (adapt.GetType() == GeomAbs_Circle) {
00095 printCircle(adapt, result);
00096 }
00097 else if (adapt.GetType() == GeomAbs_Ellipse) {
00098 printEllipse(adapt, i, result);
00099 }
00100 else if (adapt.GetType() == GeomAbs_BSplineCurve) {
00101 printBSpline(adapt, i, result);
00102 }
00103
00104 else {
00105 printGeneric(adapt, i, result);
00106 }
00107 }
00108
00109 return result.str();
00110 }
00111
00112 void SVGOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out)
00113 {
00114 gp_Circ circ = c.Circle();
00115 const gp_Pnt& p= circ.Location();
00116 double r = circ.Radius();
00117 double f = c.FirstParameter();
00118 double l = c.LastParameter();
00119 gp_Pnt s = c.Value(f);
00120 gp_Pnt m = c.Value((l+f)/2.0);
00121 gp_Pnt e = c.Value(l);
00122
00123 gp_Vec v1(m,s);
00124 gp_Vec v2(m,e);
00125 gp_Vec v3(0,0,1);
00126 double a = v3.DotCross(v1,v2);
00127
00128
00129 if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
00130 out << "<circle cx =\"" << p.X() << "\" cy =\""
00131 << p.Y() << "\" r =\"" << r << "\" />";
00132 }
00133
00134 else {
00135
00136 char xar = '0';
00137 char las = (l-f > D_PI) ? '1' : '0';
00138 char swp = (a < 0) ? '1' : '0';
00139 out << "<path d=\"M" << s.X() << " " << s.Y()
00140 << " A" << r << " " << r << " "
00141 << xar << " " << las << " " << swp << " "
00142 << e.X() << " " << e.Y() << "\" />";
00143 }
00144 }
00145
00146 void SVGOutput::printEllipse(const BRepAdaptor_Curve& c, int id, std::ostream& out)
00147 {
00148 gp_Elips ellp = c.Ellipse();
00149 const gp_Pnt& p= ellp.Location();
00150 double r1 = ellp.MajorRadius();
00151 double r2 = ellp.MinorRadius();
00152 double f = c.FirstParameter();
00153 double l = c.LastParameter();
00154 gp_Pnt s = c.Value(f);
00155 gp_Pnt m = c.Value((l+f)/2.0);
00156 gp_Pnt e = c.Value(l);
00157
00158 gp_Vec v1(m,s);
00159 gp_Vec v2(m,e);
00160 gp_Vec v3(0,0,1);
00161 double a = v3.DotCross(v1,v2);
00162
00163
00164 if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
00165 out << "<ellipse cx =\"" << p.X() << "\" cy =\""
00166 << p.Y() << "\" rx =\"" << r1 << "\" ry =\"" << r2 << "\"/>";
00167 }
00168
00169 else {
00170
00171 gp_Dir xaxis = ellp.XAxis().Direction();
00172
00173 Standard_Real angle = xaxis.AngleWithRef(gp_Dir(1,0,0),gp_Dir(0,0,-1));
00174 angle = Base::toDegrees<double>(angle);
00175
00176 char las = (l-f > D_PI) ? '1' : '0';
00177 char swp = (a < 0) ? '1' : '0';
00178
00179 out << "<path d=\"M" << s.X() << " " << s.Y()
00180 << " A" << r1 << " " << r2 << " "
00181 << angle << " " << las << " " << swp << " "
00182 << e.X() << " " << e.Y() << "\" />" << std::endl;
00183 }
00184 }
00185
00186 void SVGOutput::printBSpline(const BRepAdaptor_Curve& c, int id, std::ostream& out)
00187 {
00188 try {
00189 std::stringstream str;
00190 Handle_Geom_BSplineCurve spline = c.BSpline();
00191 if (spline->Degree() > 3) {
00192 Standard_Real tol3D = 0.001;
00193 Standard_Integer maxDegree = 3, maxSegment = 10;
00194 Handle_BRepAdaptor_HCurve hCurve = new BRepAdaptor_HCurve(c);
00195
00196 Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C2,maxSegment,maxDegree);
00197 if (approx.IsDone() && approx.HasResult()) {
00198
00199 spline = approx.Curve();
00200 }
00201 }
00202
00203 GeomConvert_BSplineCurveToBezierCurve crt(spline);
00204 Standard_Integer arcs = crt.NbArcs();
00205 str << "<path d=\"M";
00206 for (Standard_Integer i=1; i<=arcs; i++) {
00207 Handle_Geom_BezierCurve bezier = crt.Arc(i);
00208 Standard_Integer poles = bezier->NbPoles();
00209 if (bezier->Degree() == 3) {
00210 if (poles != 4)
00211 Standard_Failure::Raise("do it the generic way");
00212 gp_Pnt p1 = bezier->Pole(1);
00213 gp_Pnt p2 = bezier->Pole(2);
00214 gp_Pnt p3 = bezier->Pole(3);
00215 gp_Pnt p4 = bezier->Pole(4);
00216 if (i == 1) {
00217 str << p1.X() << "," << p1.Y() << " C"
00218 << p2.X() << "," << p2.Y() << " "
00219 << p3.X() << "," << p3.Y() << " "
00220 << p4.X() << "," << p4.Y() << " ";
00221 }
00222 else {
00223 str << "S"
00224 << p3.X() << "," << p3.Y() << " "
00225 << p4.X() << "," << p4.Y() << " ";
00226 }
00227 }
00228 else if (bezier->Degree() == 2) {
00229 if (poles != 3)
00230 Standard_Failure::Raise("do it the generic way");
00231 gp_Pnt p1 = bezier->Pole(1);
00232 gp_Pnt p2 = bezier->Pole(2);
00233 gp_Pnt p3 = bezier->Pole(3);
00234 if (i == 1) {
00235 str << p1.X() << "," << p1.Y() << " Q"
00236 << p2.X() << "," << p2.Y() << " "
00237 << p3.X() << "," << p3.Y() << " ";
00238 }
00239 else {
00240 str << "T"
00241 << p3.X() << "," << p3.Y() << " ";
00242 }
00243 }
00244 else {
00245 Standard_Failure::Raise("do it the generic way");
00246 }
00247 }
00248
00249 str << "\" />";
00250 out << str.str();
00251 }
00252 catch (Standard_Failure) {
00253 printGeneric(c, id, out);
00254 }
00255 }
00256
00257 void SVGOutput::printGeneric(const BRepAdaptor_Curve& c, int id, std::ostream& out)
00258 {
00259 TopLoc_Location location;
00260 Handle(Poly_Polygon3D) polygon = BRep_Tool::Polygon3D(c.Edge(), location);
00261 if (!polygon.IsNull()) {
00262 const TColgp_Array1OfPnt& nodes = polygon->Nodes();
00263 char c = 'M';
00264 out << "<path id= \"" << id << "\" d=\" ";
00265 for (int i = nodes.Lower(); i <= nodes.Upper(); i++){
00266 out << c << " " << nodes(i).X() << " " << nodes(i).Y()<< " " ;
00267 c = 'L';
00268 }
00269 out << "\" />" << endl;
00270 }
00271 }
00272
00273
00274
00275 DXFOutput::DXFOutput()
00276 {
00277 }
00278
00279 std::string DXFOutput::exportEdges(const TopoDS_Shape& input)
00280 {
00281 std::stringstream result;
00282
00283 TopExp_Explorer edges(input, TopAbs_EDGE);
00284 for (int i = 1 ; edges.More(); edges.Next(),i++) {
00285 const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
00286 BRepAdaptor_Curve adapt(edge);
00287 if (adapt.GetType() == GeomAbs_Circle) {
00288 printCircle(adapt, result);
00289 }
00290 else if (adapt.GetType() == GeomAbs_Ellipse) {
00291 printEllipse(adapt, i, result);
00292 }
00293 else if (adapt.GetType() == GeomAbs_BSplineCurve) {
00294 printBSpline(adapt, i, result);
00295 }
00296
00297 else {
00298 printGeneric(adapt, i, result);
00299 }
00300 }
00301
00302 return result.str();
00303 }
00304
00305 void DXFOutput::printHeader( std::ostream& out)
00306 {
00307 out << 0 << endl;
00308 out << "SECTION" << endl;
00309 out << 2 << endl;
00310 out << "ENTITIES" << endl;
00311 }
00312
00313 void DXFOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out)
00314 {
00315 gp_Circ circ = c.Circle();
00316
00317 const gp_Pnt& p= circ.Location();
00318 double r = circ.Radius();
00319 double f = c.FirstParameter();
00320 double l = c.LastParameter();
00321 gp_Pnt s = c.Value(f);
00322 gp_Pnt m = c.Value((l+f)/2.0);
00323 gp_Pnt e = c.Value(l);
00324
00325 gp_Vec v1(m,s);
00326 gp_Vec v2(m,e);
00327 gp_Vec v3(0,0,1);
00328 double a = v3.DotCross(v1,v2);
00329
00330
00331 if (s.SquareDistance(e) < 0.001) {
00332
00333
00334 out << 0 << endl;
00335 out << "CIRCLE" << endl;
00336 out << 8 << endl;
00337 out << "sheet_layer" << endl;
00338 out << 10 << endl;
00339 out << p.X() << endl;
00340 out << 20 << endl;
00341 out << p.Y() << endl;
00342 out << 30 << endl;
00343 out << 0 << endl;
00344 out << 40 << endl;
00345 out << r << endl;
00346 }
00347
00348
00349
00350
00351 else {
00352
00353
00354
00355
00356
00357
00358
00359
00360 double ax = s.X() - p.X();
00361 double ay = s.Y() - p.Y();
00362 double bx = e.X() - p.X();
00363 double by = e.Y() - p.Y();
00364
00365 double start_angle = atan2(ay, ax) * 180/D_PI;
00366 double end_angle = atan2(by, bx) * 180/D_PI;
00367
00368
00369 if(a > 0){
00370 double temp = start_angle;
00371 start_angle = end_angle;
00372 end_angle = temp;}
00373 out << 0 << endl;
00374 out << "ARC" << endl;
00375 out << 8 << endl;
00376 out << "sheet_layer" << endl;
00377 out << 10 << endl;
00378 out << p.X() << endl;
00379 out << 20 << endl;
00380 out << p.Y() << endl;
00381 out << 30 << endl;
00382 out << 0 << endl;
00383 out << 40 << endl;
00384 out << r << endl;
00385 out << 50 << endl;
00386 out << start_angle << endl;
00387 out << 51 << endl;
00388 out << end_angle << endl;
00389
00390
00391
00392 }
00393 }
00394
00395 void DXFOutput::printEllipse(const BRepAdaptor_Curve& c, int id, std::ostream& out)
00396 {
00397 gp_Elips ellp = c.Ellipse();
00398 const gp_Pnt& p= ellp.Location();
00399 double r1 = ellp.MajorRadius();
00400 double r2 = ellp.MinorRadius();
00401 double f = c.FirstParameter();
00402 double l = c.LastParameter();
00403 gp_Pnt s = c.Value(f);
00404 gp_Pnt m = c.Value((l+f)/2.0);
00405 gp_Pnt e = c.Value(l);
00406
00407 gp_Vec v1(m,s);
00408 gp_Vec v2(m,e);
00409 gp_Vec v3(0,0,1);
00410 double a = v3.DotCross(v1,v2);
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 gp_Dir xaxis = ellp.XAxis().Direction();
00431 double angle = xaxis.Angle(gp_Dir(1,0,0));
00432
00433
00434
00435 double ax = s.X() - p.X();
00436 double ay = s.Y() - p.Y();
00437 double bx = e.X() - p.X();
00438 double by = e.Y() - p.Y();
00439
00440 double start_angle = atan2(ay, ax) * 180/D_PI;
00441 double end_angle = atan2(by, bx) * 180/D_PI;
00442
00443 double major_x;double major_y;
00444
00445 major_x = r1 * sin(angle*90);
00446 major_y = r1 * cos(angle*90);
00447
00448 double ratio = r2/r1;
00449
00450 if(a > 0){
00451 double temp = start_angle;
00452 start_angle = end_angle;
00453 end_angle = temp;
00454 }
00455 out << 0 << endl;
00456 out << "ELLIPSE" << endl;
00457 out << 8 << endl;
00458 out << "sheet_layer" << endl;
00459 out << 10 << endl;
00460 out << p.X() << endl;
00461 out << 20 << endl;
00462 out << p.Y() << endl;
00463 out << 30 << endl;
00464 out << 0 << endl;
00465 out << 11 << endl;
00466 out << major_x << endl;
00467 out << 21 << endl;
00468 out << major_y << endl;
00469 out << 31 << endl;
00470 out << 0 << endl;
00471 out << 40 << endl;
00472 out << ratio << endl;
00473 out << 41 << endl;
00474 out << start_angle << endl;
00475 out << 42 << endl;
00476 out << end_angle << endl;
00477 }
00478
00479 void DXFOutput::printBSpline(const BRepAdaptor_Curve& c, int id, std::ostream& out)
00480 {
00481 try {
00482 std::stringstream str;
00483 Handle_Geom_BSplineCurve spline = c.BSpline();
00484 if (spline->Degree() > 3) {
00485 Standard_Real tol3D = 0.001;
00486 Standard_Integer maxDegree = 3, maxSegment = 10;
00487 Handle_BRepAdaptor_HCurve hCurve = new BRepAdaptor_HCurve(c);
00488
00489 Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C2,maxSegment,maxDegree);
00490 if (approx.IsDone() && approx.HasResult()) {
00491
00492 spline = approx.Curve();
00493 }
00494 }
00495
00496 GeomConvert_BSplineCurveToBezierCurve crt(spline);
00497
00498 Standard_Integer arcs = crt.NbArcs();
00499
00500 str << 0 << endl
00501 << "SECTION" << endl
00502 << 2 << endl
00503 << "ENTITIES" << endl
00504 << 0 << endl
00505 << "SPLINE" << endl;
00506
00507
00508
00509
00510
00511
00512 for (Standard_Integer i=1; i<=arcs; i++) {
00513 Handle_Geom_BezierCurve bezier = crt.Arc(i);
00514 Standard_Integer poles = bezier->NbPoles();
00515
00516
00517
00518 if (bezier->Degree() == 3) {
00519 if (poles != 4)
00520 Standard_Failure::Raise("do it the generic way");
00521 gp_Pnt p1 = bezier->Pole(1);
00522 gp_Pnt p2 = bezier->Pole(2);
00523 gp_Pnt p3 = bezier->Pole(3);
00524 gp_Pnt p4 = bezier->Pole(4);
00525 if (i == 1) {
00526 str
00527 << 10 << endl
00528 << p1.X() << endl
00529 << 20 << endl
00530 << p1.Y() << endl
00531 << 30 << endl
00532 << 0 << endl
00533
00534 << 10 << endl
00535 << p2.X() << endl
00536 << 20 << endl
00537 << p2.Y() << endl
00538 << 30 << endl
00539 << 0 << endl
00540
00541 << 10 << endl
00542 << p3.X() << endl
00543 << 20 << endl
00544 << p3.Y() << endl
00545 << 30 << endl
00546 << 0 << endl
00547
00548 << 10 << endl
00549 << p4.X() << endl
00550 << 20 << endl
00551 << p4.Y() << endl
00552 << 30 << endl
00553 << 0 << endl
00554
00555 << 12 << endl
00556 << p1.X() << endl
00557 << 22 << endl
00558 << p1.Y() << endl
00559 << 32 << endl
00560 << 0 << endl
00561
00562 << 13 << endl
00563 << p4.X() << endl
00564 << 23 << endl
00565 << p4.Y() << endl
00566 << 33 << endl
00567 << 0 << endl;
00568 }
00569 else {
00570 str
00571 << 10 << endl
00572 << p3.X() << endl
00573 << 20 << endl
00574 << p3.Y() << endl
00575 << 30 << endl
00576 << 0 << endl
00577
00578 << 10 << endl
00579 << p4.X() << endl
00580 << 20 << endl
00581 << p4.Y() << endl
00582 << 30 << endl
00583 << 0 << endl
00584
00585 << 12 << endl
00586 << p3.X() << endl
00587 << 22 << endl
00588 << p3.Y() << endl
00589 << 32 << endl
00590 << 0 << endl
00591
00592 << 13 << endl
00593 << p4.X() << endl
00594 << 23 << endl
00595 << p4.Y() << endl
00596 << 33 << endl
00597 << 0 << endl;
00598
00599 }
00600 }
00601 else if (bezier->Degree() == 2) {
00602 if (poles != 3)
00603 Standard_Failure::Raise("do it the generic way");
00604 gp_Pnt p1 = bezier->Pole(1);
00605 gp_Pnt p2 = bezier->Pole(2);
00606 gp_Pnt p3 = bezier->Pole(3);
00607 if (i == 1) {
00608 str
00609 << 10 << endl
00610 << p1.X() << endl
00611 << 20 << endl
00612 << p1.Y() << endl
00613 << 30 << endl
00614 << 0 << endl
00615
00616 << 10 << endl
00617 << p2.X() << endl
00618 << 20 << endl
00619 << p2.Y() << endl
00620 << 30 << endl
00621 << 0 << endl
00622
00623 << 10 << endl
00624 << p3.X() << endl
00625 << 20 << endl
00626 << p3.Y() << endl
00627 << 30 << endl
00628 << 0 << endl
00629
00630 << 12 << endl
00631 << p1.X() << endl
00632 << 22 << endl
00633 << p1.Y() << endl
00634 << 32 << endl
00635 << 0 << endl
00636
00637 << 13 << endl
00638 << p3.X() << endl
00639 << 23 << endl
00640 << p3.Y() << endl
00641 << 33 << endl
00642 << 0 << endl;
00643 }
00644 else {
00645 str
00646 << 10 << endl
00647 << p3.X() << endl
00648 << 20 << endl
00649 << p3.Y() << endl
00650 << 30 << endl
00651 << 0 << endl;
00652 }
00653 }
00654 else {
00655 Standard_Failure::Raise("do it the generic way");
00656 }
00657 }
00658
00659
00660 out << str.str();
00661 }
00662 catch (Standard_Failure) {
00663 printGeneric(c, id, out);
00664 }
00665 }
00666
00667 void DXFOutput::printGeneric(const BRepAdaptor_Curve& c, int id, std::ostream& out)
00668 {
00669 double uStart = c.FirstParameter();
00670 gp_Pnt PS;
00671 gp_Vec VS;
00672 c.D1(uStart, PS, VS);
00673
00674 double uEnd = c.LastParameter();
00675 gp_Pnt PE;
00676 gp_Vec VE;
00677 c.D1(uEnd, PE, VE);
00678
00679 out << "0" << endl;
00680 out << "LINE" << endl;
00681 out << "8" << endl;
00682 out << "sheet_layer" << endl;
00683 out << "10" << endl;
00684 out << PS.X() << endl;
00685 out << "20" << endl;
00686 out << PS.Y() << endl;
00687 out << "30" << endl;
00688 out << "0" << endl;
00689 out << "11" << endl;
00690 out << PE.X() << endl;
00691 out << "21" << endl;
00692 out << PE.Y() << endl;
00693 out << "31" << endl;
00694 out << "0" << endl;
00695 }