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>
60 Standard_IMPORT Draw_Viewer dout;
62 //=======================================================================
63 //function : ConvertBndToShape
64 //purpose : Creates TopoDS_Solid from theBox
65 //=======================================================================
66 static void ConvertBndToShape(const Bnd_OBB& theBox,
67 const char* const theName)
69 const gp_Pnt &aBaryCenter = theBox.Center();
70 const gp_XYZ &aXDir = theBox.XDirection(),
71 &aYDir = theBox.YDirection(),
72 &aZDir = theBox.ZDirection();
73 Standard_Real aHalfX = theBox.XHSize(),
74 aHalfY = theBox.YHSize(),
75 aHalfZ = theBox.ZHSize();
77 gp_Ax2 anAxes(aBaryCenter, aZDir, aXDir);
78 anAxes.SetLocation(aBaryCenter.XYZ() - aHalfX*aXDir - aHalfY*aYDir - aHalfZ*aZDir);
79 TopoDS_Solid aBox = BRepPrimAPI_MakeBox(anAxes, 2.0*aHalfX, 2.0*aHalfY, 2.0*aHalfZ);
80 DBRep::Set(theName, aBox);
83 //=======================================================================
85 //=======================================================================
87 static Standard_Integer addpcurve(Draw_Interpretor& , Standard_Integer n, const char** a)
90 TopoDS_Shape E = DBRep::Get(a[1]);
91 if (E.IsNull()) return 1;
92 Handle(Geom2d_Curve) PC = DrawTrSurf::GetCurve2d(a[2]);
93 TopoDS_Shape F = DBRep::Get(a[3]);
94 Standard_Real tol = 1.e-7;
96 tol = Draw::Atof(a[4]);
99 BB.UpdateEdge(TopoDS::Edge(E), PC, TopoDS::Face(F),tol);
105 //=======================================================================
107 //=======================================================================
109 static Standard_Integer transform(Draw_Interpretor& ,Standard_Integer n,const char** a)
111 if (n <= 1) return 1;
114 Standard_Integer last = n;
115 const char* aName = a[0];
117 Standard_Boolean isBasic = Standard_False;
119 if (!strcmp(aName,"reset")) {
122 isBasic = (aName[0] == 'b');
125 if (!strcmp(aName,"move")) {
127 TopoDS_Shape SL = DBRep::Get(a[n-1]);
128 if (SL.IsNull()) return 0;
129 T = SL.Location().Transformation();
132 else if (!strcmp(aName,"translate")) {
134 T.SetTranslation(gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1])));
137 else if (!strcmp(aName,"rotate")) {
139 T.SetRotation(gp_Ax1(gp_Pnt(Draw::Atof(a[n-7]),Draw::Atof(a[n-6]),Draw::Atof(a[n-5])),
140 gp_Vec(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2]))),
141 Draw::Atof(a[n-1])* (M_PI / 180.0));
144 else if (!strcmp(aName,"mirror")) {
146 T.SetMirror(gp_Ax2(gp_Pnt(Draw::Atof(a[n-6]),Draw::Atof(a[n-5]),Draw::Atof(a[n-4])),
147 gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1]))));
150 else if (!strcmp(aName,"scale")) {
152 T.SetScale(gp_Pnt(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2])),Draw::Atof(a[n-1]));
157 if (T.Form() == gp_Identity || isBasic) {
158 TopLoc_Location L(T);
159 for (Standard_Integer i = 1; i < last; i++) {
160 TopoDS_Shape S = DBRep::Get(a[i]);
163 std::cerr << "Error: " << a[i] << " is not a valid shape\n";
167 DBRep::Set(a[i],S.Located(L));
171 BRepBuilderAPI_Transform trf(T);
172 for (Standard_Integer i = 1; i < last; i++) {
173 TopoDS_Shape S = DBRep::Get(a[i]);
175 std::cerr << "Error: " << a[i] << " is not a valid shape\n";
182 DBRep::Set(a[i],trf.Shape());
189 ///=======================================================================
191 //=======================================================================
193 static Standard_Integer deform(Draw_Interpretor& di,Standard_Integer n,const char** a)
195 if (n <= 1) return 1;
197 Standard_Integer last = n;
202 // gp_Mat rot(Draw::Atof(a[last-3]),0,0,0,Draw::Atof(a[last-2]),0,0,0,Draw::Atof(a[last-1]));
203 gp_Mat rot(Draw::Atof(a[3]),0,0,0,Draw::Atof(a[4]),0,0,0,Draw::Atof(a[5]));
204 GT.SetVectorialPart(rot);
206 BRepBuilderAPI_GTransform gtrf(GT);
207 BRepBuilderAPI_NurbsConvert nbscv;
208 // for (Standard_Integer i = 1; i < last; i++) {
209 // TopoDS_Shape S = DBRep::Get(a[i]);
210 TopoDS_Shape S = DBRep::Get(a[2]);
212 //cout << a[2] << " is not a valid shape" << endl;
213 di << a[2] << " is not a valid shape\n";
218 DBRep::Set(a[1],gtrf.Shape());
228 //=======================================================================
230 //=======================================================================
232 static Standard_Integer tcopy(Draw_Interpretor& di,Standard_Integer n,const char** a)
234 Standard_Boolean copyGeom = Standard_True;
235 Standard_Boolean copyMesh = Standard_False;
236 Standard_Integer iFirst = 1; // index of first shape argument
240 for (Standard_Integer i = 1; i <= 2; i++)
246 copyGeom = Standard_False;
249 else if (a[i][1] == 'm')
251 copyMesh = Standard_True;
257 if (n < 3 || (n - iFirst) % 2) {
258 cout << "Use: " << a[0] << " [-n(ogeom)] [-m(esh)] shape1 copy1 [shape2 copy2 [...]]" << endl;
259 cout << "Option -n forbids copying of geometry (it will be shared)" << endl;
260 cout << "Option -m forces copying of mesh (disabled by default)" << endl;
264 BRepBuilderAPI_Copy cop;
265 Standard_Integer nbPairs = (n - iFirst) / 2;
266 for (Standard_Integer i=0; i < nbPairs; i++) {
267 cop.Perform(DBRep::Get(a[i+iFirst]), copyGeom, copyMesh);
268 DBRep::Set(a[i+iFirst+1],cop.Shape());
269 di << a[i+iFirst+1] << " ";
275 //=======================================================================
277 //=======================================================================
279 static Standard_Integer nurbsconvert(Draw_Interpretor& di,Standard_Integer n,const char** a)
282 if ((n-1)%2 != 0) return 1;
283 BRepBuilderAPI_NurbsConvert nbscv;
284 for (Standard_Integer i=0; i<(n-1)/2; i++) {
285 TopoDS_Shape S = DBRep::Get(a[2*i+2]);
287 //cout << a[2*i+2] << " is not a valid shape" << endl;
288 di << a[2*i+2] << " is not a valid shape\n";
293 DBRep::Set(a[2*i+1],nbscv.Shape());
305 //=======================================================================
306 // make a 3D edge curve
307 //=======================================================================
309 static Standard_Integer mkedgecurve (Draw_Interpretor& ,Standard_Integer n,const char** a)
313 Standard_Real Tolerance = Draw::Atof(a[2]) ;
315 TopoDS_Shape S = DBRep::Get(a[1]);
317 if (S.IsNull()) return 1;
319 BRepLib::BuildCurves3d(S,
324 //=======================================================================
326 //=======================================================================
328 static Standard_Integer sameparameter(Draw_Interpretor& di,Standard_Integer n,const char** a)
332 di << "Use sameparameter [result] shape [toler]\n";
333 di << "shape is an initial shape\n";
334 di << "result is a result shape. if skipped = > initial shape will be modified\n";
335 di << "toler is tolerance (default is 1.e-7)";
338 Standard_Real aTol = 1.e-7;
339 Standard_Boolean force = !strcmp(a[0],"fsameparameter");
341 Standard_Real aTol1 = Draw::Atof(a[n-1]);
342 Standard_Boolean IsUseTol = aTol1>0;
346 TopoDS_Shape anInpS = DBRep::Get(IsUseTol ? a[n-2] : a[n-1]);
350 if ((n == 4 && IsUseTol) || (n == 3 && !IsUseTol))
352 TopoDS_Shape aResultSh;
353 BRepTools_ReShape aResh;
354 BRepLib::SameParameter(anInpS,aResh,aTol,force);
355 aResultSh = aResh.Apply(anInpS);
356 DBRep::Set(a[1],aResultSh);
360 BRepLib::SameParameter(anInpS,aTol,force);
361 DBRep::Set(a[1],anInpS);
366 //=======================================================================
367 //function : updatetol
369 //=======================================================================
370 static Standard_Integer updatetol(Draw_Interpretor& di,Standard_Integer n,const char** a)
374 di << "Use updatetololerance [result] shape [param]\n";
375 di << "shape is an initial shape\n";
376 di << "result is a result shape. if skipped = > initial shape will be modified\n";
377 di << "if [param] is absent - not verify of face tolerance, else - perform it";
380 TopoDS_Shape aSh1 = DBRep::Get(a[n-1]);
381 Standard_Boolean IsF = aSh1.IsNull();
383 TopoDS_Shape anInpS = IsF ? DBRep::Get(a[n-2]) : aSh1;
387 if ((n == 4 && IsF) || (n == 3 && !IsF))
389 TopoDS_Shape aResultSh;
390 BRepTools_ReShape aResh;
391 BRepLib::UpdateTolerances(anInpS,aResh, IsF);
392 aResultSh = aResh.Apply(anInpS);
393 DBRep::Set(a[1],aResultSh);
397 BRepLib::UpdateTolerances(anInpS, IsF);
398 DBRep::Set(a[1],anInpS);
404 //=======================================================================
405 //function : OrienSolid
407 //=======================================================================
408 static Standard_Integer orientsolid(Draw_Interpretor& ,Standard_Integer n,const char** a)
412 TopoDS_Shape S = DBRep::Get(a[1]);
413 if (S.IsNull()) return 1;
414 if (S.ShapeType()!=TopAbs_SOLID) return 1;
416 BRepLib::OrientClosedSolid(TopoDS::Solid(S));
423 //=======================================================================
424 //function : getcoords
426 //=======================================================================
427 static Standard_Integer getcoords(Draw_Interpretor& di,Standard_Integer n,const char** a)
432 for (Standard_Integer i = 1; i < n; i++)
434 const TopoDS_Shape aShape = DBRep::Get (a[i]);
439 if (aShape.ShapeType() == TopAbs_VERTEX)
441 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
442 gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
444 di << a[i] << " (x,y,z) : " << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
451 //=======================================================================
452 //function : BoundBox
454 //=======================================================================
455 static Standard_Integer BoundBox(Draw_Interpretor& theDI,
456 Standard_Integer theNArg,
457 const char** theArgVal)
461 theDI << "Use: " << theArgVal[0] << " {-s shape | -c xmin ymin zmin xmax ymax zmax} "
462 "[-obb]\n\t\t[-shape name] [-dump] [-notriangulation]\n\t\t"
463 "[-perfmeter name NbIters] [-nodraw] [-optimal] [-exttoler]\n\t\t"
464 "[-save xmin ymin zmin xmax ymax zmax]\n\n\n";
466 theDI << "Computes a bounding box (BndBox). Two types of the source data are supported:\n";
467 theDI << " * \"-s\"-option sets the shape, which will be circumscribed by the BndBox;\n";
468 theDI << " * \"-c\"-option sets two opposite corners (having (xmin, ymin, zmin) and\n\t"
469 "(xmax, ymax, zmax) coordinates) of the resulting\n\taxis-aligned BndBox (AABB).\n";
470 theDI << "\nThe following options are supported:\n";
471 theDI << " * \"-obb\". If it is switched on then the oriented BndBox (OBB) will "
472 "be\n\tcreated. Otherwise, AABB will be created.\n";
473 theDI << " * \"-shape\". If it is switched on then the resulting BndBox will be "
474 "stored\n\tas a shape (solid) with specified name.\n";
475 theDI << " * \"-nodraw\". If it is switched on then the resulting BndBox will not be\n\t"
476 "drawn as DRAW-object.\n";
477 theDI << " * \"-dump\". Prints the information about the created BndBox.\n";
478 theDI << " * \"-notriangulation\". By default, AABB is built from existing mesh.\n\t"
479 "This option allows ignoring triangulation.\n";
480 theDI << " * \"-save\". Stores the information about created AABB in "
481 "specified variables.\n";
482 theDI << " * \"-optimal\". If it is switched on then the AABB will be optimal.\n\t"
483 "This option is useful for OBB, too. It allows constructing\n\toptimal "
485 theDI << " * \"-exttoler\". If it is switched on then the resulting box will be "
486 "extended\n\ton the tolerance of the source shape.\n";
487 theDI << " * \"-perfmeter\" - Auxiliary option. It provides compatibility "
488 "with\n\tOCCT-test system. \"name\" is the counter name for "
489 "\"chrono\"-TCL-command.\n\tNbIters is the number of iterations.\n";
495 Standard_Boolean isOBB = Standard_False;
496 Standard_Boolean hasToPrint = Standard_False,
497 isTriangulationReq = Standard_True,
498 isOptimal = Standard_False,
499 isTolerUsed = Standard_False,
500 hasToDraw = Standard_True;
501 Standard_Integer aNbIters = 1;
502 Standard_Integer aStartIdxToSave = -1,
503 aStartIdxToCreate = -1,
505 anIdxCounterName = -1;
507 for(Standard_Integer anAIdx = 1; anAIdx < theNArg; anAIdx++)
509 if(theArgVal[anAIdx][0] != '-')
511 theDI << "Error: Wrong option \"" << theArgVal[anAIdx] <<
512 "\". Please use \'-\' symbol\n";
516 if(!strcmp(theArgVal[anAIdx], "-s"))
518 aShape = DBRep::Get(theArgVal[++anAIdx]);
521 theDI << "Error: Argument " << theArgVal[anAIdx] << " is not a shape.\n";
525 else if(!strcmp(theArgVal[anAIdx], "-c"))
527 aStartIdxToCreate = anAIdx + 1;
530 else if(!strncmp(theArgVal[anAIdx], "-obb", 4))
532 isOBB = Standard_True;
534 else if(!strncmp(theArgVal[anAIdx], "-shape", 4))
536 aNameToShape = ++anAIdx;
538 else if(!strncmp(theArgVal[anAIdx], "-dump", 4))
540 hasToPrint = Standard_True;
542 else if(!strncmp(theArgVal[anAIdx], "-save", 4))
544 aStartIdxToSave = anAIdx+1;
547 else if(!strncmp(theArgVal[anAIdx], "-notriangulation", 9))
549 isTriangulationReq = Standard_False;
551 else if(!strncmp(theArgVal[anAIdx], "-perfmeter", 8))
553 anIdxCounterName = ++anAIdx;
554 aNbIters = Draw::Atoi(theArgVal[++anAIdx]);
556 else if(!strncmp(theArgVal[anAIdx], "-optimal", 4))
558 isOptimal = Standard_True;
560 else if(!strcmp(theArgVal[anAIdx], "-exttoler"))
562 isTolerUsed = Standard_True;
564 else if(!strcmp(theArgVal[anAIdx], "-nodraw"))
566 hasToDraw = Standard_False;
570 theDI << "Error: Unknown option \"" << theArgVal[anAIdx] << "\".\n";
575 if(aShape.IsNull() && (aStartIdxToCreate < 0))
577 theDI << "Error: One of the options \'-s\' or \'-c\' must be set necessarily.\n";
581 if(aStartIdxToCreate > 0)
585 theDI << "Error: Options \'-s\' and \'-c\' are fail for using simultaneously.\n";
590 theDI << "Error: Options \'-c\' and \"-obb\" are fail for using simultaneously.\n";
599 theDI << "Error: Options \"-optimal\" is used without any shape. "
600 "Use \'-s\'-option.\n";
609 theDI << "Error: Option \"-exttoler\" is used without any shape. "
610 "Use \'-s\'-option.\n";
615 Handle(Draw_Box) aDB;
620 if(aStartIdxToSave > 0)
622 theDI << "Error: Option \"-save\" work only with axes-aligned boxes.\n";
627 Standard_Integer aN = aNbIters;
633 BRepBndLib::AddOBB(aShape, anOBB, isTriangulationReq, isOptimal, isTolerUsed);
639 theDI << "Void box.\n";
640 hasToPrint = Standard_False;
643 const gp_Pnt &aBaryCenter= anOBB.Center();
644 const gp_XYZ &aXDir = anOBB.XDirection(),
645 &aYDir = anOBB.YDirection(),
646 &aZDir = anOBB.ZDirection();
647 Standard_Real aHalfX = anOBB.XHSize(),
648 aHalfY = anOBB.YHSize(),
649 aHalfZ = anOBB.ZHSize();
653 theDI << "Oriented bounding box\n";
654 theDI << "Center: " << aBaryCenter.X() << " " <<
655 aBaryCenter.Y() << " " <<
656 aBaryCenter.Z() << "\n";
657 theDI << "X-axis: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
658 theDI << "Y-axis: " << aYDir.X() << " " << aYDir.Y() << " " << aYDir.Z() << "\n";
659 theDI << "Z-axis: " << aZDir.X() << " " << aZDir.Y() << " " << aZDir.Z() << "\n";
660 theDI << "Half X: " << aHalfX << "\n" <<
661 "Half Y: " << aHalfY << "\n" << "Half Z: " << aHalfZ << "\n";
665 aDB = new Draw_Box(anOBB, Draw_orange);
669 ConvertBndToShape(anOBB, theArgVal[aNameToShape]);
674 Standard_Real aXmin = RealFirst(), aYmin = RealFirst(), aZmin = RealFirst(),
675 aXMax = RealLast(), aYMax = RealLast(), aZMax = RealLast();
679 if(aStartIdxToCreate < 0)
681 Standard_Integer aN = aNbIters;
688 BRepBndLib::AddOptimal(aShape, anAABB, isTriangulationReq, isTolerUsed);
698 BRepBndLib::Add(aShape, anAABB, isTriangulationReq);
705 if(anIdxCounterName > 0)
707 theDI << "Error: Option \"-perfmeter\"does not work if the option \'-c\' "
712 Standard_Integer anIdx = aStartIdxToCreate;
713 aXmin = Draw::Atof(theArgVal[anIdx++]);
714 aYmin = Draw::Atof(theArgVal[anIdx++]);
715 aZmin = Draw::Atof(theArgVal[anIdx++]);
716 aXMax = Draw::Atof(theArgVal[anIdx++]);
717 aYMax = Draw::Atof(theArgVal[anIdx++]);
718 aZMax = Draw::Atof(theArgVal[anIdx++]);
720 anAABB.Add(gp_Pnt(aXmin, aYmin, aZmin));
721 anAABB.Add(gp_Pnt(aXMax, aYMax, aZMax));
726 theDI << "Void box.\n";
727 hasToPrint = Standard_False;
730 if(hasToPrint || (aStartIdxToSave>0))
732 anAABB.Get(aXmin, aYmin, aZmin, aXMax, aYMax, aZMax);
736 theDI << "Axes-aligned bounding box\n";
737 theDI << "X-range: " << aXmin << " " << aXMax << "\n" <<
738 "Y-range: " << aYmin << " " << aYMax << "\n" <<
739 "Z-range: " << aZmin << " " << aZMax << "\n";
742 if(aStartIdxToSave > 0)
744 Draw::Set(theArgVal[aStartIdxToSave++], aXmin);
745 Draw::Set(theArgVal[aStartIdxToSave++], aYmin);
746 Draw::Set(theArgVal[aStartIdxToSave++], aZmin);
747 Draw::Set(theArgVal[aStartIdxToSave++], aXMax);
748 Draw::Set(theArgVal[aStartIdxToSave++], aYMax);
749 Draw::Set(theArgVal[aStartIdxToSave++], aZMax);
754 aDB = new Draw_Box(anAABB, Draw_orange);
758 ConvertBndToShape(anAABB, theArgVal[aNameToShape]);
765 if(anIdxCounterName > 0)
767 theDI << "COUNTER " << theArgVal[anIdxCounterName] << ": " << aTimer.ElapsedTime() << "\n";
773 //=======================================================================
774 //function : IsBoxesInterfered
776 //=======================================================================
777 static Standard_Integer IsBoxesInterfered(Draw_Interpretor& theDI,
778 Standard_Integer theNArg,
779 const char** theArgVal)
783 theDI << "Use: isbbinterf shape1 shape2 [-o].\n";
787 const TopoDS_Shape aShape1 = DBRep::Get(theArgVal[1]);
788 const TopoDS_Shape aShape2 = DBRep::Get(theArgVal[2]);
790 Standard_Boolean isOBB = (theNArg > 3) && (!strcmp(theArgVal[3], "-o"));
794 Bnd_OBB anOBB1, anOBB2;
795 BRepBndLib::AddOBB(aShape1, anOBB1);
796 BRepBndLib::AddOBB(aShape2, anOBB2);
798 if(anOBB1.IsOut(anOBB2))
800 theDI << "The shapes are NOT interfered by OBB.\n";
804 theDI << "The shapes are interfered by OBB.\n";
809 Bnd_Box anAABB1, anAABB2;
810 BRepBndLib::Add(aShape1, anAABB1);
811 BRepBndLib::Add(aShape2, anAABB2);
813 if(anAABB1.IsOut(anAABB2))
815 theDI << "The shapes are NOT interfered by AABB.\n";
819 theDI << "The shapes are interfered by AABB.\n";
826 //=======================================================================
827 //function : gbounding
829 //=======================================================================
830 #include <GeomAdaptor_Surface.hxx>
831 #include <BndLib_AddSurface.hxx>
832 #include <BndLib_Add3dCurve.hxx>
833 #include <BndLib_Add2dCurve.hxx>
834 #include <Draw_Segment2D.hxx>
835 static Standard_Integer gbounding(Draw_Interpretor& di,Standard_Integer n,const char** a)
837 if (n != 2 && n != 3)
839 di << "Usage: gbounding surf/curve/curve2d [-o] \n";
840 di << "[-o] turn on Optimal mode ('off' by default) \n";
845 Standard_Boolean IsOptimal = Standard_False;
846 if (n == 3 && !strcmp(a[2], "-o"))
847 IsOptimal = Standard_True;
849 Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
853 Standard_Boolean Is3d = Standard_True;
854 Handle(Geom_Curve) C;
855 Handle(Geom_Surface) S;
856 Handle_Geom2d_Curve C2d;
857 S = DrawTrSurf::GetSurface(a[1]);
861 GeomAdaptor_Surface aGAS(S);
863 BndLib_AddSurface::AddOptimal(aGAS, Precision::Confusion(), B);
865 BndLib_AddSurface::Add(aGAS, Precision::Confusion(), B);
869 C = DrawTrSurf::GetCurve(a[1]);
873 GeomAdaptor_Curve aGAC(C);
875 BndLib_Add3dCurve::AddOptimal(aGAC, Precision::Confusion(), B);
877 BndLib_Add3dCurve::Add(aGAC, Precision::Confusion(), B);
881 C2d = DrawTrSurf::GetCurve2d(a[1]);
885 Is3d = Standard_False;
887 BndLib_Add2dCurve::AddOptimal(C2d, C2d->FirstParameter(), C2d->LastParameter(), Precision::Confusion(), B2d);
889 BndLib_Add2dCurve::Add(C2d, C2d->FirstParameter(), C2d->LastParameter(), Precision::Confusion(), B2d);
893 di << "Wrong argument \n";
901 B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
902 DB = new Draw_Box(B, Draw_vert);
904 di << axmin<<" "<< aymin<<" "<< azmin<<" "<< axmax<<" "<< aymax<<" "<< azmax;
908 B2d.Get(axmin,aymin,axmax,aymax);
909 gp_Pnt2d p1(axmin, aymin);
910 gp_Pnt2d p2(axmax, aymin);
911 gp_Pnt2d p3(axmax, aymax);
912 gp_Pnt2d p4(axmin, aymax);
913 Draw_Segment2D* S1 = new Draw_Segment2D(p1, p2, Draw_vert);
914 Draw_Segment2D* S2 = new Draw_Segment2D(p2, p3, Draw_vert);
915 Draw_Segment2D* S3 = new Draw_Segment2D(p3, p4, Draw_vert);
916 Draw_Segment2D* S4 = new Draw_Segment2D(p4, p1, Draw_vert);
917 dout << S1 << S2 << S3 << S4;
918 di << axmin<<" "<< aymin<<" "<< axmax<<" "<< aymax;
924 //=======================================================================
925 //function : findplane
927 //=======================================================================
928 static Standard_Integer findplane(Draw_Interpretor& di,Standard_Integer n,const char** a)
931 TopoDS_Shape S = DBRep::Get(a[1]);
932 if (S.IsNull()) return 1;
933 Standard_Real tolerance = 1.0e-5 ;
934 BRepBuilderAPI_FindPlane a_plane_finder(S,
936 if (a_plane_finder.Found()) {
937 //cout << " a plane is found " ;
938 di << " a plane is found \n";
939 const Handle(Geom_Geometry)& aSurf = a_plane_finder.Plane(); // to avoid ambiguity
940 DrawTrSurf::Set(a[2],aSurf) ;
944 //=======================================================================
945 //function : precision
947 //=======================================================================
949 static Standard_Integer precision(Draw_Interpretor& di,Standard_Integer n,const char** a)
954 //cout << " Current Precision = " << BRepBuilderAPI::Precision() << endl;
955 di << " Current Precision = " << BRepBuilderAPI::Precision() << "\n";
958 BRepBuilderAPI::Precision(Draw::Atof(a[1]));
964 //=======================================================================
965 //function : reperage shape (Int lin Shape) + pointe double click + maxtol
967 //=======================================================================
968 #include <IntCurvesFace_ShapeIntersector.hxx>
969 #include <gp_Lin.hxx>
971 static Standard_Integer reperageshape(Draw_Interpretor& di, Standard_Integer narg , const char** a)
973 Standard_Integer details=0;
975 if(narg==3) details=1;
976 const char *id1 = a[1];
977 TopoDS_Shape TheShape1 = DBRep::Get(id1);
979 //cout << "Pick positions with button "<<endl;
980 di << "Pick positions with button \n";
981 Standard_Integer id,X,Y,b;
984 dout.Select(id,X,Y,b);
988 Standard_Real z = dout.Zoom(id);
989 P2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z, 0.0);
991 P1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,-1.0);
995 gp_Ax1 Axe(P1,gp_Vec(P1,P2));
996 IntCurvesFace_ShapeIntersector Inter;
997 Inter.Load(TheShape1,1e-7);
999 Inter.Perform(Axe,-RealLast(),RealLast());
1004 for(Standard_Integer i=1; i<=Inter.NbPnt(); i++) {
1005 Standard_Integer numface=1;
1006 TopExp_Explorer ExF;
1007 for(ExF.Init(TheShape1,TopAbs_FACE);
1009 ExF.Next(),numface++) {
1010 TopoDS_Face Face=TopoDS::Face(ExF.Current());
1011 if(Face.IsEqual(Inter.Face(i))) {
1012 //cout<<" "<<a[1]<<"_"<<numface;
1013 di<<" "<<a[1]<<"_"<<numface;
1017 const gp_Pnt& P = Inter.Pnt(i);
1018 Standard_Real PMin = Inter.WParameter(i);
1020 //cout<<" w:"<<PMin<<endl;
1021 di<<" w:"<<PMin<< "\n";
1023 if(Inter.Transition(i) == IntCurveSurface_In) {
1024 if(Inter.State(i) == TopAbs_IN) {
1025 Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_Square, Draw_rouge,2);
1026 dout << p; dout.Flush();
1028 else if(Inter.State(i) == TopAbs_ON) {
1029 Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_Square, Draw_vert,2);
1030 dout << p; dout.Flush();
1034 if(Inter.Transition(i) == IntCurveSurface_Out) {
1035 if(Inter.State(i) == TopAbs_IN) {
1036 Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_X, Draw_rouge,2);
1037 dout << p; dout.Flush();
1039 else if(Inter.State(i) == TopAbs_ON) {
1040 Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_X, Draw_vert,2);
1041 dout << p; dout.Flush();
1053 static Standard_Integer maxtolerance(Draw_Interpretor& theCommands,
1054 Standard_Integer n, const char** a) {
1056 TopoDS_Shape TheShape = DBRep::Get(a[1]);
1057 if(TheShape.IsNull()) return(1);
1059 Standard_Real T,TMF,TME,TMV,TmF,TmE,TmV;
1060 Standard_Integer nbF,nbE,nbV;
1061 TMF=TME=TMV=-RealLast();
1062 TmF=TmE=TmV=RealLast();
1064 TopTools_MapOfShape mapS;
1067 for(TopExp_Explorer ex(TheShape,TopAbs_FACE);
1070 TopoDS_Face Face=TopoDS::Face(ex.Current());
1071 T=BRep_Tool::Tolerance(Face);
1077 nbF = mapS.Extent();
1080 for(TopExp_Explorer ex(TheShape,TopAbs_EDGE);
1083 TopoDS_Edge Edge=TopoDS::Edge(ex.Current());
1084 T=BRep_Tool::Tolerance(Edge);
1090 nbE = mapS.Extent();
1093 for(TopExp_Explorer ex(TheShape,TopAbs_VERTEX);
1096 TopoDS_Vertex Vertex=TopoDS::Vertex(ex.Current());
1097 T=BRep_Tool::Tolerance(Vertex);
1103 nbV = mapS.Extent();
1105 Standard_SStream sss;
1106 sss << "\n## Tolerances on the shape " << a[1] << " (nbFaces:" << nbF
1107 << " nbEdges:" << nbE << " nbVtx:" << nbV << ")\n" ;
1109 sss.setf(ios::scientific);
1110 if(TmF<=TMF) sss << "\n Face : Min " << setw(8) << TmF <<" Max " << setw(8) << TMF << " \n ";
1111 if(TmE<=TME) sss << "\n Edge : Min " << setw(8) << TmE <<" Max " << setw(8) << TME << " \n ";
1112 if(TmV<=TMV) sss << "\n Vertex : Min " << setw(8) << TmV <<" Max " << setw(8) << TMV << " \n ";
1119 static Standard_Integer vecdc(Draw_Interpretor& di,Standard_Integer ,const char** ) {
1120 //cout << "Pick positions with button "<<endl;
1121 di << "Pick positions with button \n";
1123 Standard_Integer id,X,Y,b;
1125 gp_Pnt P1,P2,PP1,PP2;
1127 //-----------------------------------------------------------
1128 dout.Select(id,X,Y,b); dout.GetTrsf(id,T);
1130 Standard_Real z = dout.Zoom(id);
1131 P1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1134 dout.Select(id,X,Y,b); dout.GetTrsf(id,T);
1135 T.Invert(); z = dout.Zoom(id);
1137 P2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1139 Standard_Real xa,ya,za;
1140 if(Abs(P1.X())>Abs(P2.X())) xa = P1.X(); else xa = P2.X();
1141 if(Abs(P1.Y())>Abs(P2.Y())) ya = P1.Y(); else ya = P2.Y();
1142 if(Abs(P1.Z())>Abs(P2.Z())) za = P1.Z(); else za = P2.Z();
1143 P1.SetCoord(xa,ya,za);
1144 Handle(Draw_Marker3D) D0 = new Draw_Marker3D(gp_Pnt(P1.X(),
1147 Draw_Square,Draw_blanc,1);
1151 //-----------------------------------------------------------
1152 dout.Select(id,X,Y,b);
1156 PP1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1158 dout.Select(id,X,Y,b);
1162 PP2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1164 if(Abs(PP1.X())>Abs(PP2.X())) xa = PP1.X(); else xa = PP2.X();
1165 if(Abs(PP1.Y())>Abs(PP2.Y())) ya = PP1.Y(); else ya = PP2.Y();
1166 if(Abs(PP1.Z())>Abs(PP2.Z())) za = PP1.Z(); else za = PP2.Z();
1167 PP1.SetCoord(xa,ya,za);
1168 Handle(Draw_Segment3D) d = new Draw_Segment3D(P1,PP1,Draw_blanc);
1171 //cout<<"\nttran "<<PP1.X()-P1.X()<<" "<<PP1.Y()-P1.Y()<<" "<<PP1.Z()-P1.Z()<<endl;
1172 di <<"\nttran "<<PP1.X()-P1.X()<<" "<<PP1.Y()-P1.Y()<<" "<<PP1.Z()-P1.Z()<< "\n";
1174 static Standard_Integer nboxvecdp=0;
1175 //cout<<"\nbox b"<<++nboxvecdp<<" "<<Min(P1.X(),PP1.X())<<" "<<Min(P1.Y(),PP1.Y())<<" "<<Min(PP1.Z(),P1.Z());
1176 //cout<<" "<<Abs(PP1.X()-P1.X())<<" "<<Abs(PP1.Y()-P1.Y())<<" "<<Abs(PP1.Z()-P1.Z())<<endl;
1178 //cout<<"\nDistance :"<<sqrt( (PP1.X()-P1.X())*(PP1.X()-P1.X())
1179 // +(PP1.Y()-P1.Y())*(PP1.Y()-P1.Y())
1180 // +(PP1.Z()-P1.Z())*(PP1.Z()-P1.Z()))<<endl;
1182 di <<"\nbox b"<<++nboxvecdp<<" "<<Min(P1.X(),PP1.X())<<" "<<Min(P1.Y(),PP1.Y())<<" "<<Min(PP1.Z(),P1.Z());
1183 di <<" "<<Abs(PP1.X()-P1.X())<<" "<<Abs(PP1.Y()-P1.Y())<<" "<<Abs(PP1.Z()-P1.Z())<< "\n";
1185 di <<"\nDistance :"<<sqrt( (PP1.X()-P1.X())*(PP1.X()-P1.X())
1186 +(PP1.Y()-P1.Y())*(PP1.Y()-P1.Y())
1187 +(PP1.Z()-P1.Z())*(PP1.Z()-P1.Z()))<< "\n";
1190 //=======================================================================
1192 //=======================================================================
1194 #include <TopTools_SequenceOfShape.hxx>
1195 static Standard_Integer nproject(Draw_Interpretor& di, Standard_Integer n, const char** a)
1197 if ( n < 4) return 1;
1198 TopoDS_Shape InpShape;
1199 Standard_Integer arg = 2, i;
1200 TopTools_SequenceOfShape Args;
1202 Standard_Real Tol = 1.e-4;
1203 Standard_Real Tol2d;
1204 Standard_Real MaxDistance = 1.e-3;
1205 GeomAbs_Shape Continuity = GeomAbs_C2;
1206 Standard_Integer MaxDeg = 14;
1207 Standard_Integer MaxSeg = 16;
1209 while((n > arg) && !(InpShape = DBRep::Get(a[arg])).IsNull()){
1210 Args.Append(InpShape);
1213 if(Args.Length() < 2) return 1;
1215 BRepOffsetAPI_NormalProjection OrtProj(Args.Last());
1217 for(i = 1; i < Args.Length(); i++)
1218 OrtProj.Add(Args(i));
1221 if (!strcmp(a[arg],"-g")) {
1222 OrtProj.SetLimit(Standard_False);
1227 if (!strcmp(a[arg],"-d")) {
1230 MaxDistance = Draw::Atof(a[arg++]);
1231 OrtProj.SetMaxDistance(MaxDistance);
1234 Tol = Max(Draw::Atof(a[arg++]),1.e-10);
1238 if (Draw::Atoi(a[arg]) == 0) Continuity = GeomAbs_C0;
1239 else if (Draw::Atoi(a[arg]) == 1) Continuity = GeomAbs_C1;
1245 MaxDeg = Draw::Atoi(a[arg++]);
1246 if (MaxDeg<1 || MaxDeg>14) MaxDeg = 14;
1249 if(n > arg) MaxSeg = Draw::Atoi(a[arg]);
1251 Tol2d = Pow(Tol, 2./3);
1253 OrtProj.SetParams(Tol, Tol2d, Continuity, MaxDeg, MaxSeg);
1255 TopTools_ListOfShape Wire;
1256 Standard_Boolean IsWire=OrtProj.BuildWire(Wire);
1258 //cout << " BuildWire OK " << endl;
1259 di << " BuildWire OK \n";
1261 DBRep::Set(a[1], OrtProj.Shape());
1265 //==========================================================================
1267 // exploration of a wire
1268 //==========================================================================
1269 static Standard_Integer wexplo (Draw_Interpretor&,
1270 Standard_Integer argc, const char** argv)
1273 if (argc < 2) return 1;
1275 TopoDS_Shape C1 = DBRep::Get (argv[1],TopAbs_WIRE);
1278 if (argc > 2) C2 = DBRep::Get (argv[2],TopAbs_FACE);
1280 if (C1.IsNull()) return 1;
1282 BRepTools_WireExplorer we;
1283 if (C2.IsNull()) we.Init(TopoDS::Wire(C1));
1284 else we.Init(TopoDS::Wire(C1),TopoDS::Face(C2));
1286 Standard_Integer k = 1;
1288 TopoDS_Edge E = we.Current();
1289 Sprintf(name,"WEDGE_%d",k);
1298 static Standard_Integer scalexyz(Draw_Interpretor& /*di*/, Standard_Integer n, const char** a)
1300 if (n < 6) return 1;
1302 TopoDS_Shape aShapeBase = DBRep::Get(a[2]);
1303 if (aShapeBase.IsNull()) return 1;
1305 Standard_Real aFactorX = Draw::Atof(a[3]);
1306 Standard_Real aFactorY = Draw::Atof(a[4]);
1307 Standard_Real aFactorZ = Draw::Atof(a[5]);
1310 gp_Mat rot (aFactorX, 0, 0,
1313 aGTrsf.SetVectorialPart(rot);
1314 BRepBuilderAPI_GTransform aBRepGTrsf (aShapeBase, aGTrsf, Standard_False);
1315 if (!aBRepGTrsf.IsDone())
1316 throw Standard_ConstructionError("Scaling not done");
1317 TopoDS_Shape Result = aBRepGTrsf.Shape();
1319 DBRep::Set(a[1], Result);
1323 //=======================================================================
1324 //function : compareshapes
1326 //=======================================================================
1327 static Standard_Integer compareshapes(Draw_Interpretor& di,
1332 di << "Compare shapes. Usage: compare shape1 shape2\n";
1336 TopoDS_Shape aS1 = DBRep::Get(a[1]);
1337 TopoDS_Shape aS2 = DBRep::Get(a[2]);
1339 if (aS1.IsNull() || aS2.IsNull()) {
1340 di << "null shapes\n";
1344 if (aS1.IsSame(aS2)) {
1345 di << "same shapes\n";
1346 if (aS1.IsEqual(aS2)) {
1347 di << "equal shapes\n";
1351 di << "shapes are not same\n";
1356 //=======================================================================
1357 //function : issubshape
1359 //=======================================================================
1360 static Standard_Integer issubshape(Draw_Interpretor& di,
1365 di << "Check if the shape is sub-shape of other shape and get its index in the shape.\n";
1366 di << "Usage: issubshape subshape shape\n";
1370 TopoDS_Shape aSubShape = DBRep::Get(a[1]);
1371 TopoDS_Shape aShape = DBRep::Get(a[2]);
1373 if (aSubShape.IsNull() || aShape.IsNull()) {
1374 di << "null shapes\n";
1377 // find index of the sub-shape in the shape
1378 TopTools_MapOfShape aMShapes;
1379 // try to find the SubShape in Shape
1380 TopExp_Explorer anExp(aShape, aSubShape.ShapeType());
1381 for (; anExp.More(); anExp.Next()) {
1382 const TopoDS_Shape& aSS = anExp.Current();
1383 if (aMShapes.Add(aSS)) {
1384 if (aSS.IsSame(aSubShape)) {
1391 di << a[1] << " is sub-shape of " << a[2] << ". Index in the shape: " << aMShapes.Extent() << ".\n";
1394 di << a[1] << " is NOT sub-shape of " << a[2] << ".\n";
1400 void BRepTest::BasicCommands(Draw_Interpretor& theCommands)
1402 static Standard_Boolean done = Standard_False;
1404 done = Standard_True;
1406 DBRep::BasicCommands(theCommands);
1408 const char* g = "TOPOLOGY Basic shape commands";
1410 theCommands.Add("addpcurve",
1411 "addpcurve edge 2dcurve face [tol (default 1.e-7)]",
1415 theCommands.Add("reset",
1416 "reset name1 name2 ..., remove location",
1420 theCommands.Add("tmove",
1421 "tmove name1 name2 ... name, set location from name",
1425 theCommands.Add("ttranslate",
1426 "ttranslate name1 name2 ... dx dy dz",
1430 theCommands.Add("trotate",
1431 "trotate name1 name2 ... x y z dx dy dz angle",
1435 theCommands.Add("tmirror",
1436 "tmirror name x y z dx dy dz",
1440 theCommands.Add("tscale",
1441 "tscale name x y z scale",
1445 theCommands.Add("tcopy",
1446 "tcopy [-n(ogeom)] [-m(esh)] name1 result1 [name2 result2 ...]",
1450 theCommands.Add("bmove",
1451 "bmove name1 name2 ... name, set location from name",
1455 theCommands.Add("btranslate",
1456 "btranslate name1 name2 ... dx dy dz",
1460 theCommands.Add("brotate",
1461 "brotate name1 name2 ... x y z dx dy dz angle",
1465 theCommands.Add("bmirror",
1466 "bmirror name x y z dx dy dz",
1470 theCommands.Add("bscale",
1471 "bscale name x y z scale",
1475 theCommands.Add("precision",
1476 "precision [preci]",
1480 theCommands.Add("mkedgecurve",
1481 "mkedgecurve name tolerance",
1485 theCommands.Add("fsameparameter",
1486 "fsameparameter shapename [tol (default 1.e-7)], \nforce sameparameter on all edges of the shape",
1490 theCommands.Add("sameparameter",
1491 "sameparameter [result] shape [tol]",
1495 theCommands.Add("updatetolerance",
1496 "updatetolerance [result] shape [param] \n if [param] is absent - not verify of face tolerance, else - perform it",
1500 theCommands.Add("solidorientation",
1501 "orientsolid myClosedSolid",
1505 theCommands.Add("getcoords",
1506 "getcoords vertex1 vertex 2... ; shows coords of input vertices",
1510 theCommands.Add("bounding", "enter the comand w/o any arguments to obtain the help.",
1511 __FILE__, BoundBox, g);
1514 theCommands.Add("gbounding",
1515 "gbounding surf/curve/curve2d [-o] ",
1519 theCommands.Add("isbbinterf", "isbbinterf shape1 shape2 [-o]\n"
1520 "Checks whether the bounding-boxes created from "
1521 "the given shapes are interfered. If \"-o\"-option "
1522 "is switched on then the oriented boxes will be checked. "
1523 "Otherwise, axes-aligned boxes will be checked.",
1524 __FILE__, IsBoxesInterfered, g);
1526 theCommands.Add("nurbsconvert",
1527 "nurbsconvert result name [result name]",
1531 theCommands.Add("deform",
1532 "deform newname name CoeffX CoeffY CoeffZ",
1536 theCommands.Add("findplane",
1537 "findplane name planename ",
1541 theCommands.Add("maxtolerance",
1542 "maxtolerance shape ",
1546 theCommands.Add("reperageshape",
1547 "reperage shape -> list of shape (result of interstion shape , line)",
1551 theCommands.Add("vecdc",
1552 "vecdc + Pointe double click ",
1556 theCommands.Add("nproject","nproject pj e1 e2 e3 ... surf -g -d [dmax] [Tol [continuity [maxdeg [maxseg]]]",
1560 theCommands.Add("wexplo","wexplo wire [face] create WEDGE_i",
1564 theCommands.Add("scalexyz",
1565 "scalexyz res shape factor_x factor_y factor_z",
1569 theCommands.Add("compare",
1570 "Compare shapes. Usage: compare shape1 shape2",
1574 theCommands.Add("issubshape",
1575 "issubshape subshape shape\n"
1576 "\t\tCheck if the shape is sub-shape of other shape and get its index in the shape.",