1 // Created on: 1994-12-13
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Standard_Stream.hxx>
18 #include <Standard_Macro.hxx>
20 #include <BRepTest.hxx>
23 #include <Draw_Appli.hxx>
24 #include <Draw_Interpretor.hxx>
25 #include <Draw_Box.hxx>
27 #include <BRepBuilderAPI.hxx>
28 #include <BRepBuilderAPI_FindPlane.hxx>
29 #include <BRepBuilderAPI_Copy.hxx>
30 #include <BRepBuilderAPI_Transform.hxx>
31 #include <BRepBuilderAPI_GTransform.hxx>
32 #include <BRepBuilderAPI_NurbsConvert.hxx>
35 #include <gp_GTrsf.hxx>
36 #include <BRepOffsetAPI_NormalProjection.hxx>
37 #include <BRepLib.hxx>
38 #include <BRep_Builder.hxx>
39 #include <BRepBndLib.hxx>
40 #include <Bnd_Box.hxx>
41 #include <Bnd_Box2d.hxx>
42 #include <TopExp_Explorer.hxx>
44 #include <BRepTools_WireExplorer.hxx>
46 #include <GCPnts_QuasiUniformAbscissa.hxx>
47 #include <Geom2dAdaptor_Curve.hxx>
48 #include <GeomAdaptor_Curve.hxx>
49 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
50 #include <DrawTrSurf.hxx>
51 #include <Geom_Plane.hxx>
53 #include <OSD_Timer.hxx>
54 #include <Draw_Segment3D.hxx>
55 #include <Draw_Marker3D.hxx>
56 #include <Draw_MarkerShape.hxx>
57 #include <BRepPrimAPI_MakeBox.hxx>
59 #include <Standard_Dump.hxx>
63 Standard_IMPORT Draw_Viewer dout;
65 //=======================================================================
66 //function : ConvertBndToShape
67 //purpose : Creates TopoDS_Solid from theBox
68 //=======================================================================
69 static void ConvertBndToShape(const Bnd_OBB& theBox,
70 const char* const theName)
74 DBRep::Set (theName, TopoDS_Shape());
78 const gp_Pnt &aBaryCenter = theBox.Center();
79 const gp_XYZ &aXDir = theBox.XDirection(),
80 &aYDir = theBox.YDirection(),
81 &aZDir = theBox.ZDirection();
82 Standard_Real aHalfX = theBox.XHSize(),
83 aHalfY = theBox.YHSize(),
84 aHalfZ = theBox.ZHSize();
86 gp_Ax2 anAxes(aBaryCenter, aZDir, aXDir);
87 anAxes.SetLocation(aBaryCenter.XYZ() - aHalfX*aXDir - aHalfY*aYDir - aHalfZ*aZDir);
88 TopoDS_Solid aBox = BRepPrimAPI_MakeBox(anAxes, 2.0*aHalfX, 2.0*aHalfY, 2.0*aHalfZ);
89 DBRep::Set(theName, aBox);
92 //=======================================================================
94 //=======================================================================
96 static Standard_Integer addpcurve(Draw_Interpretor& , Standard_Integer n, const char** a)
99 TopoDS_Shape E = DBRep::Get(a[1]);
100 if (E.IsNull()) return 1;
101 Handle(Geom2d_Curve) PC = DrawTrSurf::GetCurve2d(a[2]);
102 TopoDS_Shape F = DBRep::Get(a[3]);
103 Standard_Real tol = 1.e-7;
105 tol = Draw::Atof(a[4]);
108 BB.UpdateEdge(TopoDS::Edge(E), PC, TopoDS::Face(F),tol);
114 //=======================================================================
116 //=======================================================================
118 static Standard_Integer transform(Draw_Interpretor& ,Standard_Integer n,const char** a)
120 if (n <= 1) return 1;
123 Standard_Integer last = n;
124 const char* aName = a[0];
126 Standard_Boolean isBasic = Standard_False;
127 Standard_Boolean isCopy = Standard_False;
129 // Check "copy" flag.
130 if (!strcmp(a[n-1], "-copy")) {
131 isCopy = Standard_True;
135 if (!strcmp(aName,"reset")) {
138 isBasic = (aName[0] == 'b');
141 if (!strcmp(aName,"move")) {
143 TopoDS_Shape SL = DBRep::Get(a[n-1]);
144 if (SL.IsNull()) return 0;
145 T = SL.Location().Transformation();
148 else if (!strcmp(aName,"translate")) {
150 T.SetTranslation(gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1])));
153 else if (!strcmp(aName,"rotate")) {
155 T.SetRotation(gp_Ax1(gp_Pnt(Draw::Atof(a[n-7]),Draw::Atof(a[n-6]),Draw::Atof(a[n-5])),
156 gp_Vec(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2]))),
157 Draw::Atof(a[n-1])* (M_PI / 180.0));
160 else if (!strcmp(aName,"mirror")) {
162 T.SetMirror(gp_Ax2(gp_Pnt(Draw::Atof(a[n-6]),Draw::Atof(a[n-5]),Draw::Atof(a[n-4])),
163 gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1]))));
166 else if (!strcmp(aName,"scale")) {
168 T.SetScale(gp_Pnt(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2])),Draw::Atof(a[n-1]));
173 if (T.Form() == gp_Identity || isBasic) {
174 TopLoc_Location L(T);
175 for (Standard_Integer i = 1; i < last; i++) {
176 TopoDS_Shape S = DBRep::Get(a[i]);
179 std::cerr << "Error: " << a[i] << " is not a valid shape\n";
183 DBRep::Set(a[i],S.Located(L));
187 BRepBuilderAPI_Transform trf(T);
188 for (Standard_Integer i = 1; i < last; i++) {
189 TopoDS_Shape S = DBRep::Get(a[i]);
191 std::cerr << "Error: " << a[i] << " is not a valid shape\n";
195 trf.Perform(S, isCopy);
198 DBRep::Set(a[i],trf.Shape());
205 ///=======================================================================
207 //=======================================================================
209 static Standard_Integer deform(Draw_Interpretor& di,Standard_Integer n,const char** a)
211 if (n <= 1) return 1;
213 Standard_Integer last = n;
218 // gp_Mat rot(Draw::Atof(a[last-3]),0,0,0,Draw::Atof(a[last-2]),0,0,0,Draw::Atof(a[last-1]));
219 gp_Mat rot(Draw::Atof(a[3]),0,0,0,Draw::Atof(a[4]),0,0,0,Draw::Atof(a[5]));
220 GT.SetVectorialPart(rot);
222 BRepBuilderAPI_GTransform gtrf(GT);
223 BRepBuilderAPI_NurbsConvert nbscv;
224 // for (Standard_Integer i = 1; i < last; i++) {
225 // TopoDS_Shape S = DBRep::Get(a[i]);
226 TopoDS_Shape S = DBRep::Get(a[2]);
228 //std::cout << a[2] << " is not a valid shape" << std::endl;
229 di << a[2] << " is not a valid shape\n";
234 DBRep::Set(a[1],gtrf.Shape());
244 //=======================================================================
246 //=======================================================================
248 static Standard_Integer tcopy(Draw_Interpretor& di,Standard_Integer n,const char** a)
250 Standard_Boolean copyGeom = Standard_True;
251 Standard_Boolean copyMesh = Standard_False;
252 Standard_Integer iFirst = 1; // index of first shape argument
256 for (Standard_Integer i = 1; i <= 2; i++)
262 copyGeom = Standard_False;
265 else if (a[i][1] == 'm')
267 copyMesh = Standard_True;
273 if (n < 3 || (n - iFirst) % 2) {
274 std::cout << "Use: " << a[0] << " [-n(ogeom)] [-m(esh)] shape1 copy1 [shape2 copy2 [...]]" << std::endl;
275 std::cout << "Option -n forbids copying of geometry (it will be shared)" << std::endl;
276 std::cout << "Option -m forces copying of mesh (disabled by default)" << std::endl;
280 BRepBuilderAPI_Copy cop;
281 Standard_Integer nbPairs = (n - iFirst) / 2;
282 for (Standard_Integer i=0; i < nbPairs; i++) {
283 cop.Perform(DBRep::Get(a[i+iFirst]), copyGeom, copyMesh);
284 DBRep::Set(a[i+iFirst+1],cop.Shape());
285 di << a[i+iFirst+1] << " ";
291 //=======================================================================
293 //=======================================================================
295 static Standard_Integer nurbsconvert(Draw_Interpretor& di,Standard_Integer n,const char** a)
298 if ((n-1)%2 != 0) return 1;
299 BRepBuilderAPI_NurbsConvert nbscv;
300 for (Standard_Integer i=0; i<(n-1)/2; i++) {
301 TopoDS_Shape S = DBRep::Get(a[2*i+2]);
303 //std::cout << a[2*i+2] << " is not a valid shape" << std::endl;
304 di << a[2*i+2] << " is not a valid shape\n";
309 DBRep::Set(a[2*i+1],nbscv.Shape());
321 //=======================================================================
322 // make a 3D edge curve
323 //=======================================================================
325 static Standard_Integer mkedgecurve (Draw_Interpretor& ,Standard_Integer n,const char** a)
329 Standard_Real Tolerance = Draw::Atof(a[2]) ;
331 TopoDS_Shape S = DBRep::Get(a[1]);
333 if (S.IsNull()) return 1;
335 BRepLib::BuildCurves3d(S,
340 //=======================================================================
342 //=======================================================================
344 static Standard_Integer sameparameter(Draw_Interpretor& di,Standard_Integer n,const char** a)
348 di << "Use sameparameter [result] shape [toler]\n";
349 di << "shape is an initial shape\n";
350 di << "result is a result shape. if skipped = > initial shape will be modified\n";
351 di << "toler is tolerance (default is 1.e-7)";
354 Standard_Real aTol = 1.e-7;
355 Standard_Boolean force = !strcmp(a[0],"fsameparameter");
357 Standard_Real aTol1 = Draw::Atof(a[n-1]);
358 Standard_Boolean IsUseTol = aTol1>0;
362 TopoDS_Shape anInpS = DBRep::Get(IsUseTol ? a[n-2] : a[n-1]);
366 if ((n == 4 && IsUseTol) || (n == 3 && !IsUseTol))
368 TopoDS_Shape aResultSh;
369 BRepTools_ReShape aResh;
370 BRepLib::SameParameter(anInpS,aResh,aTol,force);
371 aResultSh = aResh.Apply(anInpS);
372 DBRep::Set(a[1],aResultSh);
376 BRepLib::SameParameter(anInpS,aTol,force);
377 DBRep::Set(a[1],anInpS);
382 //=======================================================================
383 //function : updatetol
385 //=======================================================================
386 static Standard_Integer updatetol(Draw_Interpretor& di,Standard_Integer n,const char** a)
390 di << "Use updatetololerance [result] shape [param]\n";
391 di << "shape is an initial shape\n";
392 di << "result is a result shape. if skipped = > initial shape will be modified\n";
393 di << "if [param] is absent - not verify of face tolerance, else - perform it";
396 TopoDS_Shape aSh1 = DBRep::Get(a[n-1]);
397 Standard_Boolean IsF = aSh1.IsNull();
399 TopoDS_Shape anInpS = IsF ? DBRep::Get(a[n-2]) : aSh1;
403 if ((n == 4 && IsF) || (n == 3 && !IsF))
405 TopoDS_Shape aResultSh;
406 BRepTools_ReShape aResh;
407 BRepLib::UpdateTolerances(anInpS,aResh, IsF);
408 aResultSh = aResh.Apply(anInpS);
409 DBRep::Set(a[1],aResultSh);
413 BRepLib::UpdateTolerances(anInpS, IsF);
414 DBRep::Set(a[1],anInpS);
420 //=======================================================================
421 //function : OrienSolid
423 //=======================================================================
424 static Standard_Integer orientsolid(Draw_Interpretor& ,Standard_Integer n,const char** a)
428 TopoDS_Shape S = DBRep::Get(a[1]);
429 if (S.IsNull()) return 1;
430 if (S.ShapeType()!=TopAbs_SOLID) return 1;
432 BRepLib::OrientClosedSolid(TopoDS::Solid(S));
439 //=======================================================================
440 //function : getcoords
442 //=======================================================================
443 static Standard_Integer getcoords(Draw_Interpretor& di,Standard_Integer n,const char** a)
448 for (Standard_Integer i = 1; i < n; i++)
450 const TopoDS_Shape aShape = DBRep::Get (a[i]);
455 if (aShape.ShapeType() == TopAbs_VERTEX)
457 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
458 gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
460 di << a[i] << " (x,y,z) : " << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
467 //! Parse 6 real values for defining AABB.
468 static Standard_Boolean parseMinMax (const char** theArgVec, Bnd_Box& theBox)
470 const TCollection_AsciiString aMin[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
471 const TCollection_AsciiString aMax[3] = { theArgVec[3], theArgVec[4], theArgVec[5] };
472 if (!aMin[0].IsRealValue()
473 || !aMin[1].IsRealValue()
474 || !aMin[2].IsRealValue()
475 || !aMax[0].IsRealValue()
476 || !aMax[1].IsRealValue()
477 || !aMax[2].IsRealValue())
479 return Standard_False;
482 const gp_Pnt aPntMin (aMin[0].RealValue(), aMin[1].RealValue(), aMin[2].RealValue());
483 const gp_Pnt aPntMax (aMax[0].RealValue(), aMax[1].RealValue(), aMax[2].RealValue());
485 theBox.Add (aPntMin);
486 theBox.Add (aPntMax);
487 return Standard_True;
490 //=======================================================================
491 //function : BoundBox
493 //=======================================================================
494 static Standard_Integer BoundBox(Draw_Interpretor& theDI,
495 Standard_Integer theNArg,
496 const char** theArgVal)
498 // 1. Parse arguments
503 Standard_Boolean doPrint = Standard_False;
504 Standard_Boolean doDumpJson = Standard_False;
505 Standard_Boolean useOldSyntax = Standard_False;
506 Standard_Boolean isOBB = Standard_False;
507 Standard_Boolean isTriangulationReq = Standard_True;
508 Standard_Boolean isOptimal = Standard_False;
509 Standard_Boolean isTolerUsed = Standard_False;
510 Standard_Boolean isFinitePart = Standard_False;
511 Standard_Boolean hasToDraw = Standard_True;
513 TCollection_AsciiString anOutVars[6];
514 TCollection_AsciiString aResShapeName;
515 for (Standard_Integer anArgIter = 1; anArgIter < theNArg; ++anArgIter)
517 TCollection_AsciiString anArgCase (theArgVal[anArgIter]);
518 anArgCase.LowerCase();
519 if (anArgCase == "-obb")
521 isOBB = Standard_True;
523 else if (anArgCase == "-aabb")
525 isOBB = Standard_False;
527 else if (anArgCase == "-shape"
528 && anArgIter + 1 < theNArg
529 && aResShapeName.IsEmpty())
531 aResShapeName = theArgVal[++anArgIter];
532 hasToDraw = Standard_False;
534 else if (anArgCase == "-dump"
535 || anArgCase == "-print")
537 doPrint = Standard_True;
539 else if (anArgCase == "-dumpjson")
541 doDumpJson = Standard_True;
543 else if (anArgCase == "-save"
544 && anArgIter + 6 < theNArg
545 && anOutVars[0].IsEmpty())
547 for (int aCompIter = 0; aCompIter < 6; ++aCompIter)
549 anOutVars[aCompIter] = theArgVal[anArgIter + aCompIter + 1];
553 else if (anArgCase == "-notriangulation")
555 isTriangulationReq = Standard_False;
557 else if (anArgCase == "-optimal")
559 isOptimal = Standard_True;
561 else if (anArgCase == "-exttoler")
563 isTolerUsed = Standard_True;
565 else if (anArgCase == "-nodraw")
567 hasToDraw = Standard_False;
569 else if (anArgCase == "-finite"
570 || anArgCase == "-finitepart")
572 isFinitePart = Standard_True;
574 else if (aShape.IsNull()
575 && !DBRep::Get (theArgVal[anArgIter]).IsNull())
577 aShape = DBRep::Get (theArgVal[anArgIter]);
579 else if (anAABB.IsVoid()
580 && anArgIter + 5 < theNArg
581 && parseMinMax (theArgVal + anArgIter, anAABB))
587 std::cout << "Syntax error at argument '" << theArgVal[anArgIter] << "'.\n";
595 std::cout << "Syntax error: input is not specified (neither shape nor coordinates)\n";
598 else if (!anAABB.IsVoid()
599 && (isOBB || isOptimal || isTolerUsed))
601 std::cout << "Syntax error: Options -obb, -optimal and -extToler cannot be used for explicitly defined AABB.\n";
605 && !anOutVars[0].IsEmpty())
607 std::cout << "Error: Option -save works only with axes-aligned boxes.\n";
611 // enable printing (old syntax) if neither saving to shape nor to DRAW variables is requested
612 if (! doPrint && ! doDumpJson && anOutVars[0].IsEmpty() && aResShapeName.IsEmpty())
614 doPrint = Standard_True;
615 useOldSyntax = Standard_True;
618 // 2. Compute box and save results
619 Handle(Draw_Box) aDB;
623 BRepBndLib::AddOBB(aShape, anOBB, isTriangulationReq, isOptimal, isTolerUsed);
627 theDI << "Void box.\n";
631 const gp_Pnt &aBaryCenter= anOBB.Center();
632 const gp_XYZ &aXDir = anOBB.XDirection(),
633 &aYDir = anOBB.YDirection(),
634 &aZDir = anOBB.ZDirection();
635 theDI << "Oriented bounding box\n";
636 theDI << "Center: " << aBaryCenter.X() << " " <<
637 aBaryCenter.Y() << " " <<
638 aBaryCenter.Z() << "\n";
639 theDI << "X-axis: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
640 theDI << "Y-axis: " << aYDir.X() << " " << aYDir.Y() << " " << aYDir.Z() << "\n";
641 theDI << "Z-axis: " << aZDir.X() << " " << aZDir.Y() << " " << aZDir.Z() << "\n";
642 theDI << "Half X: " << anOBB.XHSize() << "\n"
643 << "Half Y: " << anOBB.YHSize() << "\n"
644 << "Half Z: " << anOBB.ZHSize() << "\n";
649 Standard_SStream aStream;
650 anOBB.DumpJson (aStream);
652 theDI << "Oriented bounding box\n";
653 theDI << Standard_Dump::FormatJson (aStream);
659 aDB = new Draw_Box (anOBB, Draw_orange);
662 if (!aResShapeName.IsEmpty())
664 ConvertBndToShape (anOBB, aResShapeName.ToCString());
669 if (!aShape.IsNull())
674 BRepBndLib::AddOptimal (aShape, anAABB, isTriangulationReq, isTolerUsed);
678 BRepBndLib::Add (aShape, anAABB, isTriangulationReq);
684 theDI << "Void box.\n";
688 if (isFinitePart && anAABB.IsOpen())
690 anAABB = anAABB.FinitePart();
692 const gp_Pnt aMin = anAABB.CornerMin();
693 const gp_Pnt aMax = anAABB.CornerMax();
700 theDI << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
701 << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
705 theDI << "Axes-aligned bounding box\n";
706 theDI << "X-range: " << aMin.X() << " " << aMax.X() << "\n"
707 << "Y-range: " << aMin.Y() << " " << aMax.Y() << "\n"
708 << "Z-range: " << aMin.Z() << " " << aMax.Z() << "\n";
710 && anAABB.HasFinitePart())
712 Bnd_Box aFinitAabb = anAABB.FinitePart();
713 const gp_Pnt aFinMin = aFinitAabb.CornerMin();
714 const gp_Pnt aFinMax = aFinitAabb.CornerMax();
715 theDI << "Finite part\n";
716 theDI << "X-range: " << aFinMin.X() << " " << aFinMax.X() << "\n"
717 << "Y-range: " << aFinMin.Y() << " " << aFinMax.Y() << "\n"
718 << "Z-range: " << aFinMin.Z() << " " << aFinMax.Z() << "\n";
725 Standard_SStream aStream;
726 anAABB.DumpJson (aStream);
728 theDI << "Bounding box\n";
729 theDI << Standard_Dump::FormatJson (aStream);
732 // save DRAW variables
733 if (!anOutVars[0].IsEmpty())
735 Draw::Set (anOutVars[0].ToCString(), aMin.X());
736 Draw::Set (anOutVars[1].ToCString(), aMin.Y());
737 Draw::Set (anOutVars[2].ToCString(), aMin.Z());
738 Draw::Set (anOutVars[3].ToCString(), aMax.X());
739 Draw::Set (anOutVars[4].ToCString(), aMax.Y());
740 Draw::Set (anOutVars[5].ToCString(), aMax.Z());
743 // add presentation to DRAW viewer
746 aDB = new Draw_Box (anAABB, Draw_orange);
751 if (!aResShapeName.IsEmpty())
753 ConvertBndToShape (anAABB, aResShapeName.ToCString());
764 //=======================================================================
765 //function : IsBoxesInterfered
767 //=======================================================================
768 static Standard_Integer IsBoxesInterfered(Draw_Interpretor& theDI,
769 Standard_Integer theNArg,
770 const char** theArgVal)
774 theDI << "Use: isbbinterf shape1 shape2 [-o].\n";
778 const TopoDS_Shape aShape1 = DBRep::Get(theArgVal[1]);
779 const TopoDS_Shape aShape2 = DBRep::Get(theArgVal[2]);
781 Standard_Boolean isOBB = (theNArg > 3) && (!strcmp(theArgVal[3], "-o"));
785 Bnd_OBB anOBB1, anOBB2;
786 BRepBndLib::AddOBB(aShape1, anOBB1);
787 BRepBndLib::AddOBB(aShape2, anOBB2);
789 if(anOBB1.IsOut(anOBB2))
791 theDI << "The shapes are NOT interfered by OBB.\n";
795 theDI << "The shapes are interfered by OBB.\n";
800 Bnd_Box anAABB1, anAABB2;
801 BRepBndLib::Add(aShape1, anAABB1);
802 BRepBndLib::Add(aShape2, anAABB2);
804 if(anAABB1.IsOut(anAABB2))
806 theDI << "The shapes are NOT interfered by AABB.\n";
810 theDI << "The shapes are interfered by AABB.\n";
817 //=======================================================================
818 //function : gbounding
820 //=======================================================================
821 #include <GeomAdaptor_Surface.hxx>
822 #include <BndLib_AddSurface.hxx>
823 #include <BndLib_Add3dCurve.hxx>
824 #include <BndLib_Add2dCurve.hxx>
825 #include <Draw_Segment2D.hxx>
826 static Standard_Integer gbounding(Draw_Interpretor& di,Standard_Integer n,const char** a)
828 if (n != 2 && n != 3)
830 di << "Usage: gbounding surf/curve/curve2d [-o] \n";
831 di << "[-o] turn on Optimal mode ('off' by default) \n";
836 Standard_Boolean IsOptimal = Standard_False;
837 if (n == 3 && !strcmp(a[2], "-o"))
838 IsOptimal = Standard_True;
840 Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
844 Standard_Boolean Is3d = Standard_True;
845 Handle(Geom_Curve) C;
846 Handle(Geom_Surface) S;
847 Handle_Geom2d_Curve C2d;
848 S = DrawTrSurf::GetSurface(a[1]);
852 GeomAdaptor_Surface aGAS(S);
854 BndLib_AddSurface::AddOptimal(aGAS, Precision::Confusion(), B);
856 BndLib_AddSurface::Add(aGAS, Precision::Confusion(), B);
860 C = DrawTrSurf::GetCurve(a[1]);
864 GeomAdaptor_Curve aGAC(C);
866 BndLib_Add3dCurve::AddOptimal(aGAC, Precision::Confusion(), B);
868 BndLib_Add3dCurve::Add(aGAC, Precision::Confusion(), B);
872 C2d = DrawTrSurf::GetCurve2d(a[1]);
876 Is3d = Standard_False;
878 BndLib_Add2dCurve::AddOptimal(C2d, C2d->FirstParameter(), C2d->LastParameter(), Precision::Confusion(), B2d);
880 BndLib_Add2dCurve::Add(C2d, C2d->FirstParameter(), C2d->LastParameter(), Precision::Confusion(), B2d);
884 di << "Wrong argument \n";
892 B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
893 DB = new Draw_Box(B, Draw_vert);
895 di << axmin<<" "<< aymin<<" "<< azmin<<" "<< axmax<<" "<< aymax<<" "<< azmax;
899 B2d.Get(axmin,aymin,axmax,aymax);
900 gp_Pnt2d p1(axmin, aymin);
901 gp_Pnt2d p2(axmax, aymin);
902 gp_Pnt2d p3(axmax, aymax);
903 gp_Pnt2d p4(axmin, aymax);
904 Draw_Segment2D* S1 = new Draw_Segment2D(p1, p2, Draw_vert);
905 Draw_Segment2D* S2 = new Draw_Segment2D(p2, p3, Draw_vert);
906 Draw_Segment2D* S3 = new Draw_Segment2D(p3, p4, Draw_vert);
907 Draw_Segment2D* S4 = new Draw_Segment2D(p4, p1, Draw_vert);
908 dout << S1 << S2 << S3 << S4;
909 di << axmin<<" "<< aymin<<" "<< axmax<<" "<< aymax;
915 //=======================================================================
916 //function : findplane
918 //=======================================================================
919 static Standard_Integer findplane(Draw_Interpretor& di,Standard_Integer n,const char** a)
922 TopoDS_Shape S = DBRep::Get(a[1]);
923 if (S.IsNull()) return 1;
924 Standard_Real tolerance = 1.0e-5 ;
925 BRepBuilderAPI_FindPlane a_plane_finder(S,
927 if (a_plane_finder.Found()) {
928 //std::cout << " a plane is found " ;
929 di << " a plane is found \n";
930 const Handle(Geom_Geometry)& aSurf = a_plane_finder.Plane(); // to avoid ambiguity
931 DrawTrSurf::Set(a[2],aSurf) ;
935 //=======================================================================
936 //function : precision
938 //=======================================================================
940 static Standard_Integer precision(Draw_Interpretor& di,Standard_Integer n,const char** a)
945 //std::cout << " Current Precision = " << BRepBuilderAPI::Precision() << std::endl;
946 di << " Current Precision = " << BRepBuilderAPI::Precision() << "\n";
949 BRepBuilderAPI::Precision(Draw::Atof(a[1]));
955 //=======================================================================
956 //function : reperage shape (Int lin Shape) + pointe double click + maxtol
958 //=======================================================================
959 #include <IntCurvesFace_ShapeIntersector.hxx>
960 #include <gp_Lin.hxx>
962 static Standard_Integer reperageshape(Draw_Interpretor& di, Standard_Integer narg , const char** a)
964 Standard_Integer details=0;
966 if(narg==3) details=1;
967 const char *id1 = a[1];
968 TopoDS_Shape TheShape1 = DBRep::Get(id1);
970 //std::cout << "Pick positions with button "<<std::endl;
971 di << "Pick positions with button \n";
972 Standard_Integer id,X,Y,b;
975 dout.Select(id,X,Y,b);
979 Standard_Real z = dout.Zoom(id);
980 P2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z, 0.0);
982 P1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,-1.0);
986 gp_Ax1 Axe(P1,gp_Vec(P1,P2));
987 IntCurvesFace_ShapeIntersector Inter;
988 Inter.Load(TheShape1,1e-7);
990 Inter.Perform(Axe,-RealLast(),RealLast());
992 //std::cout<<"\n --> ";
995 for(Standard_Integer i=1; i<=Inter.NbPnt(); i++) {
996 Standard_Integer numface=1;
998 for(ExF.Init(TheShape1,TopAbs_FACE);
1000 ExF.Next(),numface++) {
1001 TopoDS_Face Face=TopoDS::Face(ExF.Current());
1002 if(Face.IsEqual(Inter.Face(i))) {
1003 //std::cout<<" "<<a[1]<<"_"<<numface;
1004 di<<" "<<a[1]<<"_"<<numface;
1008 const gp_Pnt& P = Inter.Pnt(i);
1009 Standard_Real PMin = Inter.WParameter(i);
1011 //std::cout<<" w:"<<PMin<<std::endl;
1012 di<<" w:"<<PMin<< "\n";
1014 if(Inter.Transition(i) == IntCurveSurface_In) {
1015 if(Inter.State(i) == TopAbs_IN) {
1016 Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_Square, Draw_rouge,2);
1017 dout << p; dout.Flush();
1019 else if(Inter.State(i) == TopAbs_ON) {
1020 Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_Square, Draw_vert,2);
1021 dout << p; dout.Flush();
1025 if(Inter.Transition(i) == IntCurveSurface_Out) {
1026 if(Inter.State(i) == TopAbs_IN) {
1027 Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_X, Draw_rouge,2);
1028 dout << p; dout.Flush();
1030 else if(Inter.State(i) == TopAbs_ON) {
1031 Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_X, Draw_vert,2);
1032 dout << p; dout.Flush();
1038 //std::cout<<std::endl;
1044 static Standard_Integer maxtolerance(Draw_Interpretor& theCommands,
1045 Standard_Integer n, const char** a) {
1047 TopoDS_Shape TheShape = DBRep::Get(a[1]);
1048 if(TheShape.IsNull()) return(1);
1050 Standard_Real T,TMF,TME,TMV,TmF,TmE,TmV;
1051 Standard_Integer nbF,nbE,nbV;
1052 TMF=TME=TMV=-RealLast();
1053 TmF=TmE=TmV=RealLast();
1055 TopTools_MapOfShape mapS;
1058 for(TopExp_Explorer ex(TheShape,TopAbs_FACE);
1061 TopoDS_Face Face=TopoDS::Face(ex.Current());
1062 T=BRep_Tool::Tolerance(Face);
1068 nbF = mapS.Extent();
1071 for(TopExp_Explorer ex(TheShape,TopAbs_EDGE);
1074 TopoDS_Edge Edge=TopoDS::Edge(ex.Current());
1075 T=BRep_Tool::Tolerance(Edge);
1081 nbE = mapS.Extent();
1084 for(TopExp_Explorer ex(TheShape,TopAbs_VERTEX);
1087 TopoDS_Vertex Vertex=TopoDS::Vertex(ex.Current());
1088 T=BRep_Tool::Tolerance(Vertex);
1094 nbV = mapS.Extent();
1096 Standard_SStream sss;
1097 sss << "\n## Tolerances on the shape " << a[1] << " (nbFaces:" << nbF
1098 << " nbEdges:" << nbE << " nbVtx:" << nbV << ")\n" ;
1100 sss.setf(std::ios::scientific);
1101 if(TmF<=TMF) sss << "\n Face : Min " << std::setw(8) << TmF <<" Max " << std::setw(8) << TMF << " \n ";
1102 if(TmE<=TME) sss << "\n Edge : Min " << std::setw(8) << TmE <<" Max " << std::setw(8) << TME << " \n ";
1103 if(TmV<=TMV) sss << "\n Vertex : Min " << std::setw(8) << TmV <<" Max " << std::setw(8) << TMV << " \n ";
1110 static Standard_Integer vecdc(Draw_Interpretor& di,Standard_Integer ,const char** ) {
1111 //std::cout << "Pick positions with button "<<std::endl;
1112 di << "Pick positions with button \n";
1114 Standard_Integer id,X,Y,b;
1116 gp_Pnt P1,P2,PP1,PP2;
1118 //-----------------------------------------------------------
1119 dout.Select(id,X,Y,b); dout.GetTrsf(id,T);
1121 Standard_Real z = dout.Zoom(id);
1122 P1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1125 dout.Select(id,X,Y,b); dout.GetTrsf(id,T);
1126 T.Invert(); z = dout.Zoom(id);
1128 P2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1130 Standard_Real xa,ya,za;
1131 if(Abs(P1.X())>Abs(P2.X())) xa = P1.X(); else xa = P2.X();
1132 if(Abs(P1.Y())>Abs(P2.Y())) ya = P1.Y(); else ya = P2.Y();
1133 if(Abs(P1.Z())>Abs(P2.Z())) za = P1.Z(); else za = P2.Z();
1134 P1.SetCoord(xa,ya,za);
1135 Handle(Draw_Marker3D) D0 = new Draw_Marker3D(gp_Pnt(P1.X(),
1138 Draw_Square,Draw_blanc,1);
1142 //-----------------------------------------------------------
1143 dout.Select(id,X,Y,b);
1147 PP1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1149 dout.Select(id,X,Y,b);
1153 PP2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1155 if(Abs(PP1.X())>Abs(PP2.X())) xa = PP1.X(); else xa = PP2.X();
1156 if(Abs(PP1.Y())>Abs(PP2.Y())) ya = PP1.Y(); else ya = PP2.Y();
1157 if(Abs(PP1.Z())>Abs(PP2.Z())) za = PP1.Z(); else za = PP2.Z();
1158 PP1.SetCoord(xa,ya,za);
1159 Handle(Draw_Segment3D) d = new Draw_Segment3D(P1,PP1,Draw_blanc);
1162 //std::cout<<"\nttran "<<PP1.X()-P1.X()<<" "<<PP1.Y()-P1.Y()<<" "<<PP1.Z()-P1.Z()<<std::endl;
1163 di <<"\nttran "<<PP1.X()-P1.X()<<" "<<PP1.Y()-P1.Y()<<" "<<PP1.Z()-P1.Z()<< "\n";
1165 static Standard_Integer nboxvecdp=0;
1166 //std::cout<<"\nbox b"<<++nboxvecdp<<" "<<Min(P1.X(),PP1.X())<<" "<<Min(P1.Y(),PP1.Y())<<" "<<Min(PP1.Z(),P1.Z());
1167 //std::cout<<" "<<Abs(PP1.X()-P1.X())<<" "<<Abs(PP1.Y()-P1.Y())<<" "<<Abs(PP1.Z()-P1.Z())<<std::endl;
1169 //std::cout<<"\nDistance :"<<sqrt( (PP1.X()-P1.X())*(PP1.X()-P1.X())
1170 // +(PP1.Y()-P1.Y())*(PP1.Y()-P1.Y())
1171 // +(PP1.Z()-P1.Z())*(PP1.Z()-P1.Z()))<<std::endl;
1173 di <<"\nbox b"<<++nboxvecdp<<" "<<Min(P1.X(),PP1.X())<<" "<<Min(P1.Y(),PP1.Y())<<" "<<Min(PP1.Z(),P1.Z());
1174 di <<" "<<Abs(PP1.X()-P1.X())<<" "<<Abs(PP1.Y()-P1.Y())<<" "<<Abs(PP1.Z()-P1.Z())<< "\n";
1176 di <<"\nDistance :"<<sqrt( (PP1.X()-P1.X())*(PP1.X()-P1.X())
1177 +(PP1.Y()-P1.Y())*(PP1.Y()-P1.Y())
1178 +(PP1.Z()-P1.Z())*(PP1.Z()-P1.Z()))<< "\n";
1181 //=======================================================================
1183 //=======================================================================
1185 #include <TopTools_SequenceOfShape.hxx>
1186 static Standard_Integer nproject(Draw_Interpretor& di, Standard_Integer n, const char** a)
1188 if ( n < 4) return 1;
1189 TopoDS_Shape InpShape;
1190 Standard_Integer arg = 2, i;
1191 TopTools_SequenceOfShape Args;
1193 Standard_Real Tol = 1.e-4;
1194 Standard_Real Tol2d;
1195 Standard_Real MaxDistance = 1.e-3;
1196 GeomAbs_Shape Continuity = GeomAbs_C2;
1197 Standard_Integer MaxDeg = 14;
1198 Standard_Integer MaxSeg = 16;
1200 while((n > arg) && !(InpShape = DBRep::Get(a[arg])).IsNull()){
1201 Args.Append(InpShape);
1204 if(Args.Length() < 2) return 1;
1206 BRepOffsetAPI_NormalProjection OrtProj(Args.Last());
1208 for(i = 1; i < Args.Length(); i++)
1209 OrtProj.Add(Args(i));
1212 if (!strcmp(a[arg],"-g")) {
1213 OrtProj.SetLimit(Standard_False);
1218 if (!strcmp(a[arg],"-d")) {
1221 MaxDistance = Draw::Atof(a[arg++]);
1222 OrtProj.SetMaxDistance(MaxDistance);
1225 Tol = Max(Draw::Atof(a[arg++]),1.e-10);
1229 if (Draw::Atoi(a[arg]) == 0) Continuity = GeomAbs_C0;
1230 else if (Draw::Atoi(a[arg]) == 1) Continuity = GeomAbs_C1;
1236 MaxDeg = Draw::Atoi(a[arg++]);
1237 if (MaxDeg<1 || MaxDeg>14) MaxDeg = 14;
1240 if(n > arg) MaxSeg = Draw::Atoi(a[arg]);
1242 Tol2d = Pow(Tol, 2./3);
1244 OrtProj.SetParams(Tol, Tol2d, Continuity, MaxDeg, MaxSeg);
1246 TopTools_ListOfShape Wire;
1247 Standard_Boolean IsWire=OrtProj.BuildWire(Wire);
1249 //std::cout << " BuildWire OK " << std::endl;
1250 di << " BuildWire OK \n";
1252 DBRep::Set(a[1], OrtProj.Shape());
1256 //==========================================================================
1258 // exploration of a wire
1259 //==========================================================================
1260 static Standard_Integer wexplo (Draw_Interpretor&,
1261 Standard_Integer argc, const char** argv)
1264 if (argc < 2) return 1;
1266 TopoDS_Shape C1 = DBRep::Get (argv[1],TopAbs_WIRE);
1269 if (argc > 2) C2 = DBRep::Get (argv[2],TopAbs_FACE);
1271 if (C1.IsNull()) return 1;
1273 BRepTools_WireExplorer we;
1274 if (C2.IsNull()) we.Init(TopoDS::Wire(C1));
1275 else we.Init(TopoDS::Wire(C1),TopoDS::Face(C2));
1277 Standard_Integer k = 1;
1279 TopoDS_Edge E = we.Current();
1280 Sprintf(name,"WEDGE_%d",k);
1289 static Standard_Integer scalexyz(Draw_Interpretor& /*di*/, Standard_Integer n, const char** a)
1291 if (n < 6) return 1;
1293 TopoDS_Shape aShapeBase = DBRep::Get(a[2]);
1294 if (aShapeBase.IsNull()) return 1;
1296 Standard_Real aFactorX = Draw::Atof(a[3]);
1297 Standard_Real aFactorY = Draw::Atof(a[4]);
1298 Standard_Real aFactorZ = Draw::Atof(a[5]);
1301 gp_Mat rot (aFactorX, 0, 0,
1304 aGTrsf.SetVectorialPart(rot);
1305 BRepBuilderAPI_GTransform aBRepGTrsf (aShapeBase, aGTrsf, Standard_False);
1306 if (!aBRepGTrsf.IsDone())
1307 throw Standard_ConstructionError("Scaling not done");
1308 TopoDS_Shape Result = aBRepGTrsf.Shape();
1310 DBRep::Set(a[1], Result);
1314 //=======================================================================
1315 //function : compareshapes
1317 //=======================================================================
1318 static Standard_Integer compareshapes(Draw_Interpretor& di,
1323 di << "Compare shapes. Usage: compare shape1 shape2\n";
1327 TopoDS_Shape aS1 = DBRep::Get(a[1]);
1328 TopoDS_Shape aS2 = DBRep::Get(a[2]);
1330 if (aS1.IsNull() || aS2.IsNull()) {
1331 di << "null shapes\n";
1335 if (aS1.IsSame(aS2)) {
1336 di << "same shapes\n";
1337 if (aS1.IsEqual(aS2)) {
1338 di << "equal shapes\n";
1342 di << "shapes are not same\n";
1347 //=======================================================================
1348 //function : issubshape
1350 //=======================================================================
1351 static Standard_Integer issubshape(Draw_Interpretor& di,
1356 di << "Check if the shape is sub-shape of other shape and get its index in the shape.\n";
1357 di << "Usage: issubshape subshape shape\n";
1361 TopoDS_Shape aSubShape = DBRep::Get(a[1]);
1362 TopoDS_Shape aShape = DBRep::Get(a[2]);
1364 if (aSubShape.IsNull() || aShape.IsNull()) {
1365 di << "null shapes\n";
1368 // find index of the sub-shape in the shape
1369 TopTools_MapOfShape aMShapes;
1370 // try to find the SubShape in Shape
1371 TopExp_Explorer anExp(aShape, aSubShape.ShapeType());
1372 for (; anExp.More(); anExp.Next()) {
1373 const TopoDS_Shape& aSS = anExp.Current();
1374 if (aMShapes.Add(aSS)) {
1375 if (aSS.IsSame(aSubShape)) {
1382 di << a[1] << " is sub-shape of " << a[2] << ". Index in the shape: " << aMShapes.Extent() << ".\n";
1385 di << a[1] << " is NOT sub-shape of " << a[2] << ".\n";
1391 void BRepTest::BasicCommands(Draw_Interpretor& theCommands)
1393 static Standard_Boolean done = Standard_False;
1395 done = Standard_True;
1397 DBRep::BasicCommands(theCommands);
1399 const char* g = "TOPOLOGY Basic shape commands";
1401 theCommands.Add("addpcurve",
1402 "addpcurve edge 2dcurve face [tol (default 1.e-7)]",
1406 theCommands.Add("reset",
1407 "reset name1 name2 ..., remove location",
1411 theCommands.Add("tmove",
1412 "tmove name1 name2 ... name, set location from name [-copy]",
1416 theCommands.Add("ttranslate",
1417 "ttranslate name1 name2 ... dx dy dz [-copy]",
1421 theCommands.Add("trotate",
1422 "trotate name1 name2 ... x y z dx dy dz angle [-copy]",
1426 theCommands.Add("tmirror",
1427 "tmirror name x y z dx dy dz [-copy]",
1431 theCommands.Add("tscale",
1432 "tscale name x y z scale [-copy]",
1436 theCommands.Add("tcopy",
1437 "tcopy [-n(ogeom)] [-m(esh)] name1 result1 [name2 result2 ...]",
1441 theCommands.Add("bmove",
1442 "bmove name1 name2 ... name, set location from name",
1446 theCommands.Add("btranslate",
1447 "btranslate name1 name2 ... dx dy dz",
1451 theCommands.Add("brotate",
1452 "brotate name1 name2 ... x y z dx dy dz angle",
1456 theCommands.Add("bmirror",
1457 "bmirror name x y z dx dy dz",
1461 theCommands.Add("bscale",
1462 "bscale name x y z scale",
1466 theCommands.Add("precision",
1467 "precision [preci]",
1471 theCommands.Add("mkedgecurve",
1472 "mkedgecurve name tolerance",
1476 theCommands.Add("fsameparameter",
1477 "fsameparameter shapename [tol (default 1.e-7)], \nforce sameparameter on all edges of the shape",
1481 theCommands.Add("sameparameter",
1482 "sameparameter [result] shape [tol]",
1486 theCommands.Add("updatetolerance",
1487 "updatetolerance [result] shape [param] \n if [param] is absent - not verify of face tolerance, else - perform it",
1491 theCommands.Add("solidorientation",
1492 "orientsolid myClosedSolid",
1496 theCommands.Add("getcoords",
1497 "getcoords vertex1 vertex 2... ; shows coords of input vertices",
1501 theCommands.Add ("bounding",
1502 "bounding {shape | xmin ymin zmin xmax ymax zmax}"
1503 "\n\t\t: [-obb] [-noTriangulation] [-optimal] [-extToler]"
1504 "\n\t\t: [-dump] [-print] [-dumpJson] [-shape name] [-nodraw] [-finitePart]"
1505 "\n\t\t: [-save xmin ymin zmin xmax ymax zmax]"
1507 "\n\t\t: Computes a bounding box. Two types of the source data are supported:"
1508 "\n\t\t: a shape or AABB corners (xmin, ymin, zmin, xmax, ymax, zmax)."
1510 "\n\t\t: Calculation options (applicable only if input is a shape):"
1511 "\n\t\t: -obb Compute Oriented Bounding Box (OBB) instead of AABB."
1512 "\n\t\t: -noTriangulation Force use of exact geometry for calculation"
1513 "\n\t\t: even if triangulation is present."
1514 "\n\t\t: -optimal Force calculation of optimal (more tight) AABB."
1515 "\n\t\t: In case of OBB:"
1516 "\n\t\t: - for PCA approach applies to initial AABB used in OBB calculation"
1517 "\n\t\t: - for DiTo approach modifies the DiTo algorithm to check more axes."
1518 "\n\t\t: -extToler Include tolerance of the shape in the resulting box."
1520 "\n\t\t: Output options:"
1521 "\n\t\t: -dump Prints the information about computed Bounding Box."
1522 "\n\t\t: -print Prints the information about computed Bounding Box."
1523 "\n\t\t: It is enabled by default (with plain old syntax for AABB)"
1524 "\n\t\t: if neither -shape nor -save is specified."
1525 "\n\t\t: -dumpJson Prints DumpJson information about Bounding Box."
1526 "\n\t\t: -shape Stores computed box as solid in DRAW variable with specified name."
1527 "\n\t\t: -save Stores min and max coordinates of AABB in specified variables."
1528 "\n\t\t: -noDraw Avoid drawing resulting Bounding Box in DRAW viewer."
1529 "\n\t\t: -finite Return finite part of infinite box.",
1530 __FILE__, BoundBox, g);
1533 theCommands.Add("gbounding",
1534 "gbounding surf/curve/curve2d [-o] ",
1538 theCommands.Add("isbbinterf", "isbbinterf shape1 shape2 [-o]\n"
1539 "Checks whether the bounding-boxes created from "
1540 "the given shapes are interfered. If \"-o\"-option "
1541 "is switched on then the oriented boxes will be checked. "
1542 "Otherwise, axes-aligned boxes will be checked.",
1543 __FILE__, IsBoxesInterfered, g);
1545 theCommands.Add("nurbsconvert",
1546 "nurbsconvert result name [result name]",
1550 theCommands.Add("deform",
1551 "deform newname name CoeffX CoeffY CoeffZ",
1555 theCommands.Add("findplane",
1556 "findplane name planename ",
1560 theCommands.Add("maxtolerance",
1561 "maxtolerance shape ",
1565 theCommands.Add("reperageshape",
1566 "reperage shape -> list of shape (result of interstion shape , line)",
1570 theCommands.Add("vecdc",
1571 "vecdc + Pointe double click ",
1575 theCommands.Add("nproject","nproject pj e1 e2 e3 ... surf -g -d [dmax] [Tol [continuity [maxdeg [maxseg]]]",
1579 theCommands.Add("wexplo","wexplo wire [face] create WEDGE_i",
1583 theCommands.Add("scalexyz",
1584 "scalexyz res shape factor_x factor_y factor_z",
1588 theCommands.Add("compare",
1589 "Compare shapes. Usage: compare shape1 shape2",
1593 theCommands.Add("issubshape",
1594 "issubshape subshape shape\n"
1595 "\t\tCheck if the shape is sub-shape of other shape and get its index in the shape.",