0026570: Crash on attempt to rotate a shape.
[occt.git] / src / BRepTest / BRepTest_BasicCommands.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Standard_Stream.hxx>
18 #include <Standard_Macro.hxx>
19
20 #include <BRepTest.hxx>
21
22 #include <DBRep.hxx>
23 #include <Draw_Appli.hxx>
24 #include <Draw_Interpretor.hxx>
25 #include <Draw_Box.hxx>
26
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>
33 #include <gp_Ax2.hxx>
34 #include <gp_Mat.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>
43 #include <TopoDS.hxx>
44 #include <BRepTools_WireExplorer.hxx>
45
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>
52
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>
58 #include <stdio.h>
59
60 Standard_IMPORT Draw_Viewer dout;
61
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)
68 {
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();
76
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);
81 }
82
83 //=======================================================================
84 // addpcurve
85 //=======================================================================
86
87 static Standard_Integer addpcurve(Draw_Interpretor& , Standard_Integer n, const char** a)
88 {
89   if(n < 4) return 1;
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;
95   if (n > 4) {
96     tol = Draw::Atof(a[4]);
97   }
98   BRep_Builder BB;
99   BB.UpdateEdge(TopoDS::Edge(E), PC, TopoDS::Face(F),tol); 
100   DBRep::Set(a[1], E);
101   return 0;
102 }
103
104
105 //=======================================================================
106 // transform
107 //=======================================================================
108
109 static Standard_Integer transform(Draw_Interpretor& ,Standard_Integer n,const char** a)
110 {
111   if (n <= 1) return 1;
112
113   gp_Trsf T;
114   Standard_Integer last = n;
115   const char* aName = a[0];
116
117   Standard_Boolean isBasic = Standard_False;
118   Standard_Boolean isCopy = Standard_False;
119
120   // Check "copy" flag.
121   if (!strcmp(a[n-1], "-copy")) {
122     isCopy = Standard_True;
123     last = --n;
124   }
125
126   if (!strcmp(aName,"reset")) {
127   }
128   else {
129     isBasic = (aName[0] == 'b');
130     aName++;
131
132     if (!strcmp(aName,"move")) {
133       if (n < 3) return 1;
134       TopoDS_Shape SL = DBRep::Get(a[n-1]);
135       if (SL.IsNull()) return 0;
136       T = SL.Location().Transformation();
137       last = n-1;
138     }
139     else if (!strcmp(aName,"translate")) {
140       if (n < 5) return 1;
141       T.SetTranslation(gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1])));
142       last = n-3;
143     }
144     else if (!strcmp(aName,"rotate")) {
145       if (n < 9) return 1;
146       T.SetRotation(gp_Ax1(gp_Pnt(Draw::Atof(a[n-7]),Draw::Atof(a[n-6]),Draw::Atof(a[n-5])),
147                     gp_Vec(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2]))),
148                     Draw::Atof(a[n-1])* (M_PI / 180.0));
149       last = n-7;
150     }
151     else if (!strcmp(aName,"mirror")) {
152       if (n < 8) return 1;
153       T.SetMirror(gp_Ax2(gp_Pnt(Draw::Atof(a[n-6]),Draw::Atof(a[n-5]),Draw::Atof(a[n-4])),
154                   gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1]))));
155       last = n-6;
156     }
157     else if (!strcmp(aName,"scale")) {
158       if (n < 6) return 1;
159       T.SetScale(gp_Pnt(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2])),Draw::Atof(a[n-1]));
160       last = n-4;
161     }
162   }
163
164   if (T.Form() == gp_Identity || isBasic) {
165     TopLoc_Location L(T);
166     for (Standard_Integer i = 1; i < last; i++) {
167       TopoDS_Shape S = DBRep::Get(a[i]);
168       if (S.IsNull())
169       {
170         std::cerr << "Error: " << a[i] << " is not a valid shape\n";
171         return 1;
172       }
173       else
174         DBRep::Set(a[i],S.Located(L));
175     }
176   }
177   else {
178     BRepBuilderAPI_Transform trf(T);
179     for (Standard_Integer i = 1; i < last; i++) {
180       TopoDS_Shape S = DBRep::Get(a[i]);
181       if (S.IsNull()) {
182         std::cerr << "Error: " << a[i] << " is not a valid shape\n";
183         return 1;
184       }
185       else {
186         trf.Perform(S, isCopy);
187         if (!trf.IsDone())
188           return 1;
189         DBRep::Set(a[i],trf.Shape());
190       }
191     }
192   }
193   return 0;
194 }
195
196 ///=======================================================================
197 // gtransform
198 //=======================================================================
199
200 static Standard_Integer deform(Draw_Interpretor& di,Standard_Integer n,const char** a)
201 {
202   if (n <= 1) return 1;
203   
204   Standard_Integer last = n;
205   
206   gp_Trsf T;
207   gp_GTrsf GT(T);
208   
209 //  gp_Mat rot(Draw::Atof(a[last-3]),0,0,0,Draw::Atof(a[last-2]),0,0,0,Draw::Atof(a[last-1]));
210   gp_Mat rot(Draw::Atof(a[3]),0,0,0,Draw::Atof(a[4]),0,0,0,Draw::Atof(a[5]));
211   GT.SetVectorialPart(rot);
212   last -= 3;
213   BRepBuilderAPI_GTransform gtrf(GT);
214   BRepBuilderAPI_NurbsConvert nbscv;
215   //  for (Standard_Integer i = 1; i < last; i++) {
216   //    TopoDS_Shape S = DBRep::Get(a[i]);
217   TopoDS_Shape S = DBRep::Get(a[2]);    
218   if (S.IsNull()) {
219     //cout << a[2] << " is not a valid shape" << endl;
220     di << a[2] << " is not a valid shape\n";
221   }
222   else {
223     gtrf.Perform(S);
224     if (gtrf.IsDone()){
225       DBRep::Set(a[1],gtrf.Shape());
226     }
227     else {
228       return 1;
229     }
230   }
231   
232   return 0;
233 }
234
235 //=======================================================================
236 // tcopy
237 //=======================================================================
238
239 static Standard_Integer tcopy(Draw_Interpretor& di,Standard_Integer n,const char** a)
240 {
241   Standard_Boolean copyGeom = Standard_True;
242   Standard_Boolean copyMesh = Standard_False;
243   Standard_Integer iFirst = 1; // index of first shape argument
244
245   if (n > 1)
246   {
247     for (Standard_Integer i = 1; i <= 2; i++)
248     {
249       if (a[i][0] != '-')
250         break;
251       if (a[i][1] == 'n')
252       {
253         copyGeom = Standard_False;
254         iFirst++;
255       }
256       else if (a[i][1] == 'm')
257       {
258         copyMesh = Standard_True;
259         iFirst++;
260       }
261     }
262   }
263
264   if (n < 3 || (n - iFirst) % 2) {
265     cout << "Use: " << a[0] << " [-n(ogeom)] [-m(esh)] shape1 copy1 [shape2 copy2 [...]]" << endl;
266     cout << "Option -n forbids copying of geometry (it will be shared)" << endl;
267     cout << "Option -m forces copying of mesh (disabled by default)" << endl;
268     return 1;
269   }
270
271   BRepBuilderAPI_Copy cop;
272   Standard_Integer nbPairs = (n - iFirst) / 2;
273   for (Standard_Integer i=0; i < nbPairs; i++) {
274     cop.Perform(DBRep::Get(a[i+iFirst]), copyGeom, copyMesh);
275     DBRep::Set(a[i+iFirst+1],cop.Shape());
276     di << a[i+iFirst+1] << " ";
277   }
278   return 0;
279 }
280
281
282 //=======================================================================
283 // NurbsConvert
284 //=======================================================================
285
286 static Standard_Integer nurbsconvert(Draw_Interpretor& di,Standard_Integer n,const char** a)
287 {
288   if (n < 3) return 1;
289   if ((n-1)%2 != 0) return 1;
290   BRepBuilderAPI_NurbsConvert nbscv;
291   for (Standard_Integer i=0; i<(n-1)/2; i++) {
292     TopoDS_Shape S = DBRep::Get(a[2*i+2]);
293     if (S.IsNull()) {
294       //cout << a[2*i+2] << " is not a valid shape" << endl;
295       di << a[2*i+2] << " is not a valid shape\n";
296     }
297     else {
298       nbscv.Perform(S);
299       if (nbscv.IsDone()){
300         DBRep::Set(a[2*i+1],nbscv.Shape());
301       }
302       else {
303         return 1;
304       }
305     }
306   }
307   
308   return 0;
309   
310 }
311
312 //=======================================================================
313 // make a 3D edge curve
314 //=======================================================================
315
316 static Standard_Integer mkedgecurve (Draw_Interpretor& ,Standard_Integer n,const char** a)
317 {
318
319   if (n < 3) return 1;
320   Standard_Real Tolerance = Draw::Atof(a[2]) ;
321
322   TopoDS_Shape S = DBRep::Get(a[1]);
323   
324   if (S.IsNull()) return 1;
325   
326    BRepLib::BuildCurves3d(S,
327                           Tolerance) ;
328    return 0 ;
329 }
330
331 //=======================================================================
332 // sameparameter
333 //=======================================================================
334
335 static Standard_Integer sameparameter(Draw_Interpretor& di,Standard_Integer n,const char** a)
336 {
337   if (n < 2) 
338   {
339     di << "Use sameparameter [result] shape [toler]\n";
340     di << "shape is an initial shape\n";
341     di << "result is a result shape. if skipped = > initial shape will be modified\n";
342     di << "toler is tolerance (default is 1.e-7)";
343     return 1;
344   }
345   Standard_Real aTol = 1.e-7;
346   Standard_Boolean force  = !strcmp(a[0],"fsameparameter");
347
348   Standard_Real aTol1 = Draw::Atof(a[n-1]);
349   Standard_Boolean IsUseTol = aTol1>0;
350   if (IsUseTol)
351     aTol = aTol1;
352
353   TopoDS_Shape anInpS = DBRep::Get(IsUseTol ? a[n-2] : a[n-1]);
354   if (anInpS.IsNull())
355     return 1;
356
357   if ((n == 4 && IsUseTol) || (n == 3 && !IsUseTol))
358   {
359     TopoDS_Shape aResultSh;
360     BRepTools_ReShape aResh;
361     BRepLib::SameParameter(anInpS,aResh,aTol,force);
362     aResultSh = aResh.Apply(anInpS);
363     DBRep::Set(a[1],aResultSh); 
364   }
365   else
366   {
367     BRepLib::SameParameter(anInpS,aTol,force);
368     DBRep::Set(a[1],anInpS); 
369   }
370
371   return 0;
372 }
373 //=======================================================================
374 //function : updatetol
375 //purpose  : 
376 //=======================================================================
377 static Standard_Integer updatetol(Draw_Interpretor& di,Standard_Integer n,const char** a)
378 {
379   if (n < 2) 
380   {
381     di << "Use updatetololerance [result] shape [param]\n";
382     di << "shape is an initial shape\n";
383     di << "result is a result shape. if skipped = > initial shape will be modified\n";
384     di << "if [param] is absent - not verify of face tolerance, else - perform it";
385     return 1;
386   }
387   TopoDS_Shape aSh1 = DBRep::Get(a[n-1]);
388   Standard_Boolean IsF = aSh1.IsNull();
389
390   TopoDS_Shape anInpS = IsF ? DBRep::Get(a[n-2]) : aSh1;
391   if (anInpS.IsNull())
392     return 1;
393
394   if ((n == 4 && IsF) || (n == 3 && !IsF))
395   {
396     TopoDS_Shape aResultSh;
397     BRepTools_ReShape aResh;
398     BRepLib::UpdateTolerances(anInpS,aResh, IsF);
399     aResultSh = aResh.Apply(anInpS);
400     DBRep::Set(a[1],aResultSh); 
401   }
402   else
403   {
404     BRepLib::UpdateTolerances(anInpS, IsF);
405     DBRep::Set(a[1],anInpS); 
406   }
407
408   return 0;
409 }
410
411 //=======================================================================
412 //function : OrienSolid
413 //purpose  : 
414 //=======================================================================
415 static Standard_Integer orientsolid(Draw_Interpretor& ,Standard_Integer n,const char** a)
416 {
417   if (n < 2) return 1;
418
419   TopoDS_Shape S = DBRep::Get(a[1]);
420   if (S.IsNull()) return 1;
421   if (S.ShapeType()!=TopAbs_SOLID) return 1;
422
423   BRepLib::OrientClosedSolid(TopoDS::Solid(S));
424
425   DBRep::Set(a[1],S);
426   return 0;
427
428 }
429
430 //=======================================================================
431 //function : getcoords
432 //purpose  : 
433 //=======================================================================
434 static Standard_Integer getcoords(Draw_Interpretor& di,Standard_Integer n,const char** a)
435 {
436   if(n < 2) 
437     return 1;
438
439   for (Standard_Integer i = 1; i < n; i++) 
440   {
441     const TopoDS_Shape aShape = DBRep::Get (a[i]);
442
443     if (aShape.IsNull())
444       continue;
445
446     if (aShape.ShapeType() == TopAbs_VERTEX)
447     {
448       const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
449       gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
450
451       di << a[i] << " (x,y,z) : " << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
452     }
453   }
454
455   return 0;
456 }
457
458 //=======================================================================
459 //function : BoundBox
460 //purpose  : 
461 //=======================================================================
462 static Standard_Integer BoundBox(Draw_Interpretor& theDI,
463                                  Standard_Integer theNArg,
464                                  const char** theArgVal)
465 {
466   if(theNArg < 2)
467   {
468     theDI << "Use: " << theArgVal[0] << " {-s shape | -c xmin ymin zmin xmax ymax zmax} "
469              "[-obb]\n\t\t[-shape name] [-dump] [-notriangulation]\n\t\t"
470              "[-perfmeter name NbIters] [-nodraw] [-optimal] [-exttoler]\n\t\t"
471              "[-save xmin ymin zmin xmax ymax zmax]\n\n\n";
472
473     theDI << "Computes a bounding box (BndBox). Two types of the source data are supported:\n";
474     theDI << "  * \"-s\"-option sets the shape, which will be circumscribed by the BndBox;\n";
475     theDI << "  * \"-c\"-option sets two opposite corners (having (xmin, ymin, zmin) and\n\t"
476              "(xmax, ymax, zmax) coordinates) of the resulting\n\taxis-aligned BndBox (AABB).\n";
477     theDI << "\nThe following options are supported:\n";
478     theDI << "  * \"-obb\". If it is switched on then the oriented BndBox (OBB) will "
479              "be\n\tcreated. Otherwise, AABB will be created.\n";
480     theDI << "  * \"-shape\". If it is switched on then the resulting BndBox will be "
481              "stored\n\tas a shape (solid) with specified name.\n";
482     theDI << "  * \"-nodraw\". If it is switched on then the resulting BndBox will not be\n\t"
483              "drawn as DRAW-object.\n";
484     theDI << "  * \"-dump\". Prints the information about the created BndBox.\n";
485     theDI << "  * \"-notriangulation\". By default, AABB is built from existing mesh.\n\t"
486              "This option allows ignoring triangulation.\n";
487     theDI << "  * \"-save\". Stores the information about created AABB in "
488              "specified variables.\n";
489     theDI << "  * \"-optimal\". If it is switched on then the AABB will be optimal.\n\t"
490              "This option is useful for OBB, too. It allows constructing\n\toptimal "
491              "initial AABB.\n";
492     theDI << "  * \"-exttoler\". If it is switched on then the resulting box will be "
493              "extended\n\ton the tolerance of the source shape.\n";
494     theDI << "  * \"-perfmeter\" - Auxiliary option. It provides compatibility "
495              "with\n\tOCCT-test system. \"name\" is the counter name for "
496              "\"chrono\"-TCL-command.\n\tNbIters is the number of iterations.\n";
497     return 1;
498   }
499
500   TopoDS_Shape aShape;
501   
502   Standard_Boolean isOBB = Standard_False;
503   Standard_Boolean hasToPrint = Standard_False,
504                    isTriangulationReq = Standard_True,
505                    isOptimal = Standard_False,
506                    isTolerUsed = Standard_False,
507                    hasToDraw = Standard_True;
508   Standard_Integer aNbIters = 1;
509   Standard_Integer aStartIdxToSave = -1,
510                    aStartIdxToCreate = -1,
511                    aNameToShape = -1,
512                    anIdxCounterName = -1;
513
514   for(Standard_Integer anAIdx = 1; anAIdx < theNArg; anAIdx++)
515   {
516     if(theArgVal[anAIdx][0] != '-')
517     {
518       theDI << "Error: Wrong option \"" << theArgVal[anAIdx] << 
519                "\". Please use \'-\' symbol\n";
520       return 1;
521     }
522
523     if(!strcmp(theArgVal[anAIdx], "-s"))
524     {
525       aShape = DBRep::Get(theArgVal[++anAIdx]);
526       if(aShape.IsNull())
527       {
528         theDI << "Error: Argument " << theArgVal[anAIdx] << " is not a shape.\n";
529         return 1;
530       }
531     }
532     else if(!strcmp(theArgVal[anAIdx], "-c"))
533     {
534       aStartIdxToCreate = anAIdx + 1;
535       anAIdx += 6;
536     }
537     else if(!strncmp(theArgVal[anAIdx], "-obb", 4))
538     {
539       isOBB = Standard_True;
540     }
541     else if(!strncmp(theArgVal[anAIdx], "-shape", 4))
542     {
543       aNameToShape = ++anAIdx;
544     }
545     else if(!strncmp(theArgVal[anAIdx], "-dump", 4))
546     {
547       hasToPrint = Standard_True;
548     }
549     else if(!strncmp(theArgVal[anAIdx], "-save", 4))
550     {
551       aStartIdxToSave = anAIdx+1;
552       anAIdx += 6;
553     }
554     else if(!strncmp(theArgVal[anAIdx], "-notriangulation", 9))
555     {
556       isTriangulationReq = Standard_False;
557     }
558     else if(!strncmp(theArgVal[anAIdx], "-perfmeter", 8))
559     {
560       anIdxCounterName = ++anAIdx;
561       aNbIters = Draw::Atoi(theArgVal[++anAIdx]);
562     }
563     else if(!strncmp(theArgVal[anAIdx], "-optimal", 4))
564     {
565       isOptimal = Standard_True;
566     }
567     else if(!strcmp(theArgVal[anAIdx], "-exttoler"))
568     {
569       isTolerUsed = Standard_True;
570     }
571     else if(!strcmp(theArgVal[anAIdx], "-nodraw"))
572     {
573       hasToDraw = Standard_False;
574     }
575     else
576     {
577       theDI << "Error: Unknown option  \"" << theArgVal[anAIdx] << "\".\n";
578       return 1;
579     }
580   }
581
582   if(aShape.IsNull() && (aStartIdxToCreate < 0))
583   {
584     theDI << "Error: One of the options \'-s\' or \'-c\' must be set necessarily.\n";
585     return 1;
586   }
587
588   if(aStartIdxToCreate > 0)
589   {
590     if(!aShape.IsNull())
591     {
592       theDI << "Error: Options \'-s\' and \'-c\' are fail for using simultaneously.\n";
593       return 1;
594     }
595     else if(isOBB)
596     {
597       theDI << "Error: Options \'-c\' and \"-obb\" are fail for using simultaneously.\n";
598       return 1;
599     }
600   }
601
602   if(isOptimal)
603   {
604     if(aShape.IsNull())
605     {
606       theDI << "Error: Options \"-optimal\" is used without any shape. "
607                "Use \'-s\'-option.\n";
608       return 1;
609     }
610   }
611
612   if(isTolerUsed)
613   {
614     if(aShape.IsNull())
615     {
616       theDI << "Error: Option \"-exttoler\" is used without any shape. "
617         "Use \'-s\'-option.\n";
618       return 1;
619     }
620   }
621
622   Handle(Draw_Box) aDB;
623   OSD_Timer aTimer;
624
625   if(isOBB)
626   {
627     if(aStartIdxToSave > 0)
628     {
629       theDI << "Error: Option \"-save\" work only with axes-aligned boxes.\n";
630       return 1;
631     }
632
633     Bnd_OBB anOBB;
634     Standard_Integer aN = aNbIters;
635
636     aTimer.Start();
637     while(aN-- > 0)
638     {
639       anOBB.SetVoid();
640       BRepBndLib::AddOBB(aShape, anOBB, isTriangulationReq, isOptimal, isTolerUsed);
641     }
642     aTimer.Stop();
643
644     if(anOBB.IsVoid())
645     {
646       theDI << "Void box.\n";
647       hasToPrint = Standard_False;
648     }
649
650     const gp_Pnt &aBaryCenter= anOBB.Center();
651     const gp_XYZ &aXDir = anOBB.XDirection(),
652                  &aYDir = anOBB.YDirection(),
653                  &aZDir = anOBB.ZDirection();
654     Standard_Real aHalfX = anOBB.XHSize(), 
655                   aHalfY = anOBB.YHSize(),
656                   aHalfZ = anOBB.ZHSize();
657
658     if(hasToPrint)
659     {
660       theDI << "Oriented bounding box\n";
661       theDI << "Center: " << aBaryCenter.X() << " " << 
662                              aBaryCenter.Y() << " " <<
663                              aBaryCenter.Z() << "\n";
664       theDI << "X-axis: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
665       theDI << "Y-axis: " << aYDir.X() << " " << aYDir.Y() << " " << aYDir.Z() << "\n";
666       theDI << "Z-axis: " << aZDir.X() << " " << aZDir.Y() << " " << aZDir.Z() << "\n";
667       theDI << "Half X: " << aHalfX << "\n" << 
668                "Half Y: " << aHalfY << "\n" << "Half Z: " << aHalfZ << "\n";
669     }
670     
671     if(hasToDraw)
672       aDB = new Draw_Box(anOBB, Draw_orange);
673
674     if(aNameToShape > 0)
675     {
676       ConvertBndToShape(anOBB, theArgVal[aNameToShape]);
677     }
678   }
679   else // if(!isOBB)
680   {
681     Standard_Real aXmin = RealFirst(), aYmin = RealFirst(), aZmin = RealFirst(),
682                   aXMax = RealLast(), aYMax = RealLast(), aZMax = RealLast();
683
684     Bnd_Box anAABB;
685
686     if(aStartIdxToCreate < 0)
687     {
688       Standard_Integer aN = aNbIters;
689       if(isOptimal)
690       {
691         aTimer.Start();
692         while(aN-- > 0)
693         {
694           anAABB.SetVoid();
695           BRepBndLib::AddOptimal(aShape, anAABB, isTriangulationReq, isTolerUsed);
696         }
697         aTimer.Stop();
698       }
699       else
700       {
701         aTimer.Start();
702         while(aN-- > 0)
703         {
704           anAABB.SetVoid();
705           BRepBndLib::Add(aShape, anAABB, isTriangulationReq);
706         }
707         aTimer.Stop();
708       }
709     }
710     else
711     {
712       if(anIdxCounterName > 0)
713       {
714         theDI << "Error: Option \"-perfmeter\"does not work if the option \'-c\' "
715                  "is switched on.\n";
716         return 1;
717       }
718
719       Standard_Integer anIdx = aStartIdxToCreate;
720       aXmin = Draw::Atof(theArgVal[anIdx++]);
721       aYmin = Draw::Atof(theArgVal[anIdx++]);
722       aZmin = Draw::Atof(theArgVal[anIdx++]);
723       aXMax = Draw::Atof(theArgVal[anIdx++]);
724       aYMax = Draw::Atof(theArgVal[anIdx++]);
725       aZMax = Draw::Atof(theArgVal[anIdx++]);
726
727       anAABB.Add(gp_Pnt(aXmin, aYmin, aZmin));
728       anAABB.Add(gp_Pnt(aXMax, aYMax, aZMax));
729     }
730
731     if(anAABB.IsVoid())
732     {
733       theDI << "Void box.\n";
734       hasToPrint = Standard_False;
735     }
736
737     if(hasToPrint || (aStartIdxToSave>0))
738     {
739       anAABB.Get(aXmin, aYmin, aZmin, aXMax, aYMax, aZMax);
740
741       if(hasToPrint)
742       {
743         theDI << "Axes-aligned bounding box\n";
744         theDI << "X-range: " << aXmin << " " << aXMax << "\n" <<
745                  "Y-range: " << aYmin << " " << aYMax << "\n" <<
746                  "Z-range: " << aZmin << " " << aZMax << "\n";
747       }
748
749       if(aStartIdxToSave > 0)
750       {
751         Draw::Set(theArgVal[aStartIdxToSave++], aXmin);
752         Draw::Set(theArgVal[aStartIdxToSave++], aYmin);
753         Draw::Set(theArgVal[aStartIdxToSave++], aZmin);
754         Draw::Set(theArgVal[aStartIdxToSave++], aXMax);
755         Draw::Set(theArgVal[aStartIdxToSave++], aYMax);
756         Draw::Set(theArgVal[aStartIdxToSave++], aZMax);
757       }
758     }
759
760     if(hasToDraw)
761       aDB = new Draw_Box(anAABB, Draw_orange);
762
763     if(aNameToShape > 0)
764     {
765       ConvertBndToShape(anAABB, theArgVal[aNameToShape]);
766     }
767   }
768
769   if(hasToDraw)
770     dout << aDB;
771
772   if(anIdxCounterName > 0)
773   {
774     theDI << "COUNTER " << theArgVal[anIdxCounterName] << ": " << aTimer.ElapsedTime() << "\n";
775   }
776
777   return 0;
778 }
779
780 //=======================================================================
781 //function : IsBoxesInterfered
782 //purpose  : 
783 //=======================================================================
784 static Standard_Integer IsBoxesInterfered(Draw_Interpretor& theDI,
785                                           Standard_Integer theNArg,
786                                           const char** theArgVal)
787 {
788   if(theNArg < 2)
789   {
790     theDI << "Use: isbbinterf shape1 shape2 [-o].\n";
791     return 1;
792   }
793
794   const TopoDS_Shape aShape1 = DBRep::Get(theArgVal[1]);
795   const TopoDS_Shape aShape2 = DBRep::Get(theArgVal[2]);
796
797   Standard_Boolean isOBB = (theNArg > 3) && (!strcmp(theArgVal[3], "-o"));
798
799   if(isOBB)
800   {
801     Bnd_OBB anOBB1, anOBB2;
802     BRepBndLib::AddOBB(aShape1, anOBB1);
803     BRepBndLib::AddOBB(aShape2, anOBB2);
804
805     if(anOBB1.IsOut(anOBB2))
806     {
807       theDI << "The shapes are NOT interfered by OBB.\n";
808     }
809     else
810     {
811       theDI << "The shapes are interfered by OBB.\n";
812     }
813   }
814   else
815   {
816     Bnd_Box anAABB1, anAABB2;
817     BRepBndLib::Add(aShape1, anAABB1);
818     BRepBndLib::Add(aShape2, anAABB2);
819
820     if(anAABB1.IsOut(anAABB2))
821     {
822       theDI << "The shapes are NOT interfered by AABB.\n";
823     }
824     else
825     {
826       theDI << "The shapes are interfered by AABB.\n";
827     }
828   }
829
830   return 0;
831 }
832
833 //=======================================================================
834 //function : gbounding
835 //purpose  : 
836 //=======================================================================
837 #include <GeomAdaptor_Surface.hxx>
838 #include <BndLib_AddSurface.hxx>
839 #include <BndLib_Add3dCurve.hxx>
840 #include <BndLib_Add2dCurve.hxx>
841 #include <Draw_Segment2D.hxx>
842 static Standard_Integer gbounding(Draw_Interpretor& di,Standard_Integer n,const char** a)
843 {
844   if (n != 2 && n != 3) 
845   {
846     di << "Usage: gbounding surf/curve/curve2d [-o] \n";
847     di << "[-o] turn on Optimal mode ('off' by default) \n";
848     return 1;
849   }
850   else
851   {
852     Standard_Boolean IsOptimal = Standard_False;
853     if (n == 3 && !strcmp(a[2], "-o"))
854       IsOptimal = Standard_True;
855     
856     Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
857     Bnd_Box B;
858     Bnd_Box2d B2d;
859     Handle(Draw_Box) DB;
860     Standard_Boolean Is3d = Standard_True;
861     Handle(Geom_Curve) C;
862     Handle(Geom_Surface) S;
863     Handle_Geom2d_Curve C2d;
864     S = DrawTrSurf::GetSurface(a[1]);
865     if (!S.IsNull())
866     {
867       //add surf
868       GeomAdaptor_Surface aGAS(S);
869       if (IsOptimal)
870         BndLib_AddSurface::AddOptimal(aGAS, Precision::Confusion(), B);
871       else
872         BndLib_AddSurface::Add(aGAS, Precision::Confusion(), B);
873     }
874     else
875     {
876       C = DrawTrSurf::GetCurve(a[1]);
877       if (!C.IsNull())
878       {
879         // add cur
880         GeomAdaptor_Curve aGAC(C);
881         if (IsOptimal)
882           BndLib_Add3dCurve::AddOptimal(aGAC, Precision::Confusion(), B);
883         else
884           BndLib_Add3dCurve::Add(aGAC, Precision::Confusion(), B);
885       }
886       else
887       {
888         C2d = DrawTrSurf::GetCurve2d(a[1]);
889         if (!C2d.IsNull())
890         {
891           //add cur2d
892           Is3d = Standard_False;
893           if (IsOptimal)
894             BndLib_Add2dCurve::AddOptimal(C2d, C2d->FirstParameter(), C2d->LastParameter(), Precision::Confusion(), B2d); 
895           else
896             BndLib_Add2dCurve::Add(C2d, C2d->FirstParameter(), C2d->LastParameter(), Precision::Confusion(), B2d); 
897         }
898         else
899         {
900           di << "Wrong argument \n";
901           return 1;
902         }
903       }
904     }
905
906     if (Is3d)
907     {
908       B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
909       DB = new Draw_Box(B, Draw_vert);
910       dout<<DB;
911       di << axmin<<" "<< aymin<<" "<< azmin<<" "<< axmax<<" "<< aymax<<" "<< azmax;
912     }
913     else
914     {
915       B2d.Get(axmin,aymin,axmax,aymax);
916       gp_Pnt2d p1(axmin, aymin);
917       gp_Pnt2d p2(axmax, aymin);
918       gp_Pnt2d p3(axmax, aymax);
919       gp_Pnt2d p4(axmin, aymax);
920       Draw_Segment2D* S1 = new Draw_Segment2D(p1, p2, Draw_vert);
921       Draw_Segment2D* S2 = new Draw_Segment2D(p2, p3, Draw_vert);
922       Draw_Segment2D* S3 = new Draw_Segment2D(p3, p4, Draw_vert);
923       Draw_Segment2D* S4 = new Draw_Segment2D(p4, p1, Draw_vert);
924       dout << S1 << S2 << S3 << S4;
925       di << axmin<<" "<< aymin<<" "<< axmax<<" "<< aymax;
926     }
927   }
928   return 0;
929 }
930
931 //=======================================================================
932 //function : findplane
933 //purpose  : 
934 //=======================================================================
935 static Standard_Integer findplane(Draw_Interpretor& di,Standard_Integer n,const char** a)
936 {
937   if (n < 3) return 1;
938   TopoDS_Shape S = DBRep::Get(a[1]);
939   if (S.IsNull()) return 1;
940   Standard_Real tolerance = 1.0e-5 ;
941   BRepBuilderAPI_FindPlane a_plane_finder(S,
942                                    tolerance) ;
943   if (a_plane_finder.Found()) {
944     //cout << " a plane is found "   ;
945     di << " a plane is found \n";
946     const Handle(Geom_Geometry)& aSurf = a_plane_finder.Plane(); // to avoid ambiguity
947     DrawTrSurf::Set(a[2],aSurf) ;
948   }
949   return 0 ;
950 }
951 //=======================================================================
952 //function : precision
953 //purpose  : 
954 //=======================================================================
955
956 static Standard_Integer precision(Draw_Interpretor& di,Standard_Integer n,const char** a)
957 {
958   n--;
959
960   if ( n == 0) {
961     //cout << " Current Precision = " << BRepBuilderAPI::Precision() << endl;
962     di << " Current Precision = " << BRepBuilderAPI::Precision() << "\n";
963   }
964   else {
965     BRepBuilderAPI::Precision(Draw::Atof(a[1]));
966   }
967   return 0;
968 }
969
970
971 //=======================================================================
972 //function : reperage shape (Int lin Shape) + pointe double click   + maxtol
973 //purpose  : 
974 //=======================================================================
975 #include <IntCurvesFace_ShapeIntersector.hxx>
976 #include <gp_Lin.hxx>
977
978 static Standard_Integer reperageshape(Draw_Interpretor& di, Standard_Integer narg , const char** a) 
979 {
980   Standard_Integer details=0;
981   if(narg<2) return 1;
982   if(narg==3) details=1;
983   const char *id1 = a[1];
984   TopoDS_Shape TheShape1 = DBRep::Get(id1);
985   
986   //cout << "Pick positions with button "<<endl;
987   di << "Pick positions with button \n";
988   Standard_Integer id,X,Y,b;
989   gp_Trsf T;
990   gp_Pnt P1,P2;
991   dout.Select(id,X,Y,b);
992   
993   dout.GetTrsf(id,T);
994   T.Invert();
995   Standard_Real z = dout.Zoom(id);
996   P2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z, 0.0);
997   P2.Transform(T);
998   P1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,-1.0);
999   P1.Transform(T);
1000   
1001   
1002   gp_Ax1 Axe(P1,gp_Vec(P1,P2));
1003   IntCurvesFace_ShapeIntersector Inter;
1004   Inter.Load(TheShape1,1e-7);
1005   
1006   Inter.Perform(Axe,-RealLast(),RealLast());
1007   
1008   //cout<<"\n --> ";
1009   di <<"\n --> ";
1010   if(Inter.NbPnt()) { 
1011     for(Standard_Integer i=1; i<=Inter.NbPnt(); i++) { 
1012       Standard_Integer numface=1;
1013       TopExp_Explorer ExF;
1014       for(ExF.Init(TheShape1,TopAbs_FACE);
1015           ExF.More();
1016           ExF.Next(),numface++) { 
1017         TopoDS_Face Face=TopoDS::Face(ExF.Current());
1018         if(Face.IsEqual(Inter.Face(i))) { 
1019           //cout<<" "<<a[1]<<"_"<<numface;
1020           di<<" "<<a[1]<<"_"<<numface;
1021           continue;       
1022         }
1023       }
1024       const gp_Pnt& P = Inter.Pnt(i);
1025       Standard_Real PMin = Inter.WParameter(i);
1026       if(details) { 
1027         //cout<<" w:"<<PMin<<endl;
1028         di<<" w:"<<PMin<< "\n";
1029       }
1030       if(Inter.Transition(i) == IntCurveSurface_In) { 
1031         if(Inter.State(i) == TopAbs_IN) { 
1032           Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_Square, Draw_rouge,2); 
1033           dout << p;   dout.Flush();
1034         }
1035         else if(Inter.State(i) == TopAbs_ON) { 
1036           Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_Square, Draw_vert,2); 
1037           dout << p;   dout.Flush();
1038         }
1039       }
1040       else { 
1041         if(Inter.Transition(i) == IntCurveSurface_Out) { 
1042           if(Inter.State(i) == TopAbs_IN) { 
1043             Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_X, Draw_rouge,2); 
1044             dout << p;   dout.Flush();
1045           }
1046           else if(Inter.State(i) == TopAbs_ON) { 
1047             Handle(Draw_Marker3D) p = new Draw_Marker3D(P, Draw_X, Draw_vert,2); 
1048             dout << p;   dout.Flush();
1049           }
1050         } 
1051       }
1052     }
1053   }
1054   //cout<<endl;
1055   di << "\n";
1056   return(0);
1057 }
1058
1059
1060 static Standard_Integer maxtolerance(Draw_Interpretor& theCommands, 
1061                                      Standard_Integer n, const char** a) { 
1062   if(n<2) return(1);
1063   TopoDS_Shape TheShape = DBRep::Get(a[1]);
1064   if(TheShape.IsNull()) return(1);
1065
1066   Standard_Real T,TMF,TME,TMV,TmF,TmE,TmV;
1067   Standard_Integer nbF,nbE,nbV;
1068   TMF=TME=TMV=-RealLast();
1069   TmF=TmE=TmV=RealLast();
1070   
1071   TopTools_MapOfShape mapS;
1072   mapS.Clear();
1073
1074   for(TopExp_Explorer ex(TheShape,TopAbs_FACE);
1075       ex.More();
1076       ex.Next()) { 
1077     TopoDS_Face Face=TopoDS::Face(ex.Current());
1078     T=BRep_Tool::Tolerance(Face);
1079     if(T>TMF) TMF=T;
1080     if(T<TmF) TmF=T;
1081     mapS.Add(Face);
1082   }
1083   
1084   nbF = mapS.Extent();
1085   mapS.Clear();
1086   
1087   for(TopExp_Explorer ex(TheShape,TopAbs_EDGE);
1088       ex.More();
1089       ex.Next()) { 
1090     TopoDS_Edge Edge=TopoDS::Edge(ex.Current());
1091     T=BRep_Tool::Tolerance(Edge);
1092     if(T>TME) TME=T;
1093     if(T<TmE) TmE=T;
1094     mapS.Add(Edge);
1095   }
1096
1097   nbE = mapS.Extent();
1098   mapS.Clear();
1099
1100   for(TopExp_Explorer ex(TheShape,TopAbs_VERTEX);
1101       ex.More();
1102       ex.Next()) { 
1103     TopoDS_Vertex Vertex=TopoDS::Vertex(ex.Current());
1104     T=BRep_Tool::Tolerance(Vertex);
1105     if(T>TMV) TMV=T;
1106     if(T<TmV) TmV=T;
1107     mapS.Add(Vertex);
1108   }
1109
1110   nbV = mapS.Extent();
1111
1112   Standard_SStream sss;
1113   sss << "\n## Tolerances on the shape " << a[1] << "  (nbFaces:" << nbF
1114       << "  nbEdges:" << nbE << " nbVtx:" << nbV << ")\n" ;
1115   sss.precision(5);
1116   sss.setf(ios::scientific);
1117   if(TmF<=TMF) sss << "\n    Face   : Min " << setw(8) << TmF <<"    Max  " << setw(8) << TMF << " \n ";
1118   if(TmE<=TME) sss << "\n    Edge   : Min " << setw(8) << TmE <<"    Max  " << setw(8) << TME << " \n ";
1119   if(TmV<=TMV) sss << "\n    Vertex : Min " << setw(8) << TmV <<"    Max  " << setw(8) << TMV << " \n ";
1120   theCommands << sss;
1121
1122   return 0;
1123 }
1124
1125
1126 static Standard_Integer vecdc(Draw_Interpretor& di,Standard_Integer ,const char** ) {
1127   //cout << "Pick positions with button "<<endl;
1128   di << "Pick positions with button \n";
1129
1130   Standard_Integer id,X,Y,b;
1131   gp_Trsf T;
1132   gp_Pnt P1,P2,PP1,PP2;
1133   
1134   //-----------------------------------------------------------
1135   dout.Select(id,X,Y,b);    dout.GetTrsf(id,T);
1136   T.Invert();
1137   Standard_Real z = dout.Zoom(id);
1138   P1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1139   P1.Transform(T);
1140   
1141   dout.Select(id,X,Y,b);  dout.GetTrsf(id,T);
1142   T.Invert();  z = dout.Zoom(id);
1143   
1144   P2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1145   P2.Transform(T);
1146   Standard_Real xa,ya,za;
1147   if(Abs(P1.X())>Abs(P2.X())) xa = P1.X(); else xa = P2.X();
1148   if(Abs(P1.Y())>Abs(P2.Y())) ya = P1.Y(); else ya = P2.Y();
1149   if(Abs(P1.Z())>Abs(P2.Z())) za = P1.Z(); else za = P2.Z();
1150   P1.SetCoord(xa,ya,za);
1151   Handle(Draw_Marker3D) D0 = new Draw_Marker3D(gp_Pnt(P1.X(),
1152                                                       P1.Y(),
1153                                                       P1.Z()),
1154                                                Draw_Square,Draw_blanc,1);
1155   
1156   dout << D0;
1157   dout.Flush();
1158   //-----------------------------------------------------------
1159   dout.Select(id,X,Y,b);  
1160   dout.GetTrsf(id,T);
1161   T.Invert();
1162   z = dout.Zoom(id);
1163   PP1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1164   PP1.Transform(T);
1165   dout.Select(id,X,Y,b);
1166   dout.GetTrsf(id,T);
1167   T.Invert();
1168   z = dout.Zoom(id);
1169   PP2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1170   PP2.Transform(T);
1171   if(Abs(PP1.X())>Abs(PP2.X())) xa = PP1.X(); else xa = PP2.X();
1172   if(Abs(PP1.Y())>Abs(PP2.Y())) ya = PP1.Y(); else ya = PP2.Y();
1173   if(Abs(PP1.Z())>Abs(PP2.Z())) za = PP1.Z(); else za = PP2.Z();
1174   PP1.SetCoord(xa,ya,za);
1175   Handle(Draw_Segment3D) d = new Draw_Segment3D(P1,PP1,Draw_blanc);
1176   dout << d;
1177   dout.Flush();
1178   //cout<<"\nttran   "<<PP1.X()-P1.X()<<" "<<PP1.Y()-P1.Y()<<" "<<PP1.Z()-P1.Z()<<endl;
1179   di <<"\nttran   "<<PP1.X()-P1.X()<<" "<<PP1.Y()-P1.Y()<<" "<<PP1.Z()-P1.Z()<< "\n";
1180
1181   static Standard_Integer nboxvecdp=0;
1182   //cout<<"\nbox  b"<<++nboxvecdp<<" "<<Min(P1.X(),PP1.X())<<" "<<Min(P1.Y(),PP1.Y())<<" "<<Min(PP1.Z(),P1.Z());
1183   //cout<<"  "<<Abs(PP1.X()-P1.X())<<" "<<Abs(PP1.Y()-P1.Y())<<" "<<Abs(PP1.Z()-P1.Z())<<endl;
1184
1185   //cout<<"\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()))<<endl;
1188
1189   di <<"\nbox  b"<<++nboxvecdp<<" "<<Min(P1.X(),PP1.X())<<" "<<Min(P1.Y(),PP1.Y())<<" "<<Min(PP1.Z(),P1.Z());
1190   di <<"  "<<Abs(PP1.X()-P1.X())<<" "<<Abs(PP1.Y()-P1.Y())<<" "<<Abs(PP1.Z()-P1.Z())<< "\n";
1191
1192   di <<"\nDistance :"<<sqrt( (PP1.X()-P1.X())*(PP1.X()-P1.X())
1193                              +(PP1.Y()-P1.Y())*(PP1.Y()-P1.Y())
1194                              +(PP1.Z()-P1.Z())*(PP1.Z()-P1.Z()))<< "\n";
1195   return(0);
1196 }
1197 //=======================================================================
1198 // nproject
1199 //=======================================================================
1200
1201 #include <TopTools_SequenceOfShape.hxx>
1202  static Standard_Integer nproject(Draw_Interpretor& di, Standard_Integer n, const char** a)
1203 {
1204   if ( n < 4) return 1;
1205   TopoDS_Shape InpShape;
1206   Standard_Integer arg = 2, i;
1207   TopTools_SequenceOfShape Args; 
1208
1209   Standard_Real Tol = 1.e-4;        
1210   Standard_Real Tol2d;
1211   Standard_Real MaxDistance = 1.e-3;
1212   GeomAbs_Shape Continuity = GeomAbs_C2;  
1213   Standard_Integer MaxDeg = 14;           
1214   Standard_Integer MaxSeg = 16;           
1215
1216   while((n > arg) && !(InpShape = DBRep::Get(a[arg])).IsNull()){
1217     Args.Append(InpShape);
1218     arg++;
1219   }
1220   if(Args.Length() < 2) return 1;
1221   
1222   BRepOffsetAPI_NormalProjection OrtProj(Args.Last());
1223
1224   for(i = 1; i < Args.Length(); i++)
1225     OrtProj.Add(Args(i));
1226
1227   if(n > arg)
1228     if (!strcmp(a[arg],"-g")) {
1229       OrtProj.SetLimit(Standard_False);
1230       arg++;
1231     }
1232   
1233   if(n > arg)
1234     if (!strcmp(a[arg],"-d")) {
1235       arg++;
1236       if(n > arg)
1237         MaxDistance = Draw::Atof(a[arg++]);
1238       OrtProj.SetMaxDistance(MaxDistance);
1239     }
1240   if(n > arg) {
1241     Tol = Max(Draw::Atof(a[arg++]),1.e-10);
1242   }
1243
1244   if(n > arg) {
1245     if (Draw::Atoi(a[arg]) == 0) Continuity = GeomAbs_C0;
1246     else if (Draw::Atoi(a[arg]) == 1) Continuity = GeomAbs_C1;
1247     arg++;
1248   }
1249
1250  
1251   if(n > arg) {
1252     MaxDeg = Draw::Atoi(a[arg++]);
1253     if (MaxDeg<1 || MaxDeg>14) MaxDeg = 14;
1254   }
1255
1256   if(n > arg) MaxSeg = Draw::Atoi(a[arg]);
1257     
1258   Tol2d = Pow(Tol, 2./3);
1259
1260   OrtProj.SetParams(Tol, Tol2d, Continuity, MaxDeg, MaxSeg);
1261   OrtProj.Build();
1262   TopTools_ListOfShape Wire;
1263   Standard_Boolean IsWire=OrtProj.BuildWire(Wire);
1264   if (IsWire) {
1265     //cout << " BuildWire OK " << endl;
1266     di << " BuildWire OK \n";
1267   }
1268   DBRep::Set(a[1], OrtProj.Shape());
1269   return 0;  
1270 }
1271
1272 //==========================================================================
1273 //function : wexplo
1274 //           exploration of a wire 
1275 //==========================================================================
1276 static Standard_Integer wexplo (Draw_Interpretor&, 
1277                                 Standard_Integer argc, const char** argv)
1278
1279   char name[100];
1280   if (argc < 2) return 1;
1281   
1282   TopoDS_Shape C1 = DBRep::Get (argv[1],TopAbs_WIRE);
1283   TopoDS_Shape C2 ;
1284
1285   if (argc > 2)  C2 = DBRep::Get (argv[2],TopAbs_FACE);
1286
1287   if (C1.IsNull()) return 1;
1288
1289   BRepTools_WireExplorer we;
1290   if (C2.IsNull()) we.Init(TopoDS::Wire(C1));
1291   else             we.Init(TopoDS::Wire(C1),TopoDS::Face(C2));
1292
1293   Standard_Integer k = 1;
1294   while (we.More()) {
1295     TopoDS_Edge E = we.Current();
1296     Sprintf(name,"WEDGE_%d",k); 
1297           DBRep::Set(name,E);
1298     we.Next();
1299     k++;
1300   }
1301
1302   return 0;
1303 }
1304
1305 static Standard_Integer scalexyz(Draw_Interpretor& /*di*/, Standard_Integer n, const char** a)
1306 {
1307   if (n < 6) return 1;
1308
1309   TopoDS_Shape aShapeBase = DBRep::Get(a[2]);
1310   if (aShapeBase.IsNull()) return 1;
1311   
1312   Standard_Real aFactorX = Draw::Atof(a[3]);
1313   Standard_Real aFactorY = Draw::Atof(a[4]);
1314   Standard_Real aFactorZ = Draw::Atof(a[5]);
1315
1316   gp_GTrsf aGTrsf;
1317   gp_Mat rot (aFactorX, 0, 0,
1318               0, aFactorY, 0,
1319               0, 0, aFactorZ);
1320   aGTrsf.SetVectorialPart(rot);
1321   BRepBuilderAPI_GTransform aBRepGTrsf (aShapeBase, aGTrsf, Standard_False);
1322   if (!aBRepGTrsf.IsDone())
1323     throw Standard_ConstructionError("Scaling not done");
1324   TopoDS_Shape Result = aBRepGTrsf.Shape();
1325
1326   DBRep::Set(a[1], Result);
1327   return 0;  
1328 }
1329
1330 //=======================================================================
1331 //function : compareshapes
1332 //purpose  : 
1333 //=======================================================================
1334 static Standard_Integer compareshapes(Draw_Interpretor& di,
1335                                       Standard_Integer n,
1336                                       const char** a)
1337 {
1338   if (n != 3) {
1339     di << "Compare shapes. Usage: compare shape1 shape2\n";
1340     return 1;
1341   }
1342   // get shapes
1343   TopoDS_Shape aS1 = DBRep::Get(a[1]);
1344   TopoDS_Shape aS2 = DBRep::Get(a[2]);
1345   // check shapes
1346   if (aS1.IsNull() || aS2.IsNull()) {
1347     di << "null shapes\n";
1348     return 0;
1349   }
1350   // compare shapes
1351   if (aS1.IsSame(aS2)) {
1352     di << "same shapes\n";
1353     if (aS1.IsEqual(aS2)) {
1354       di << "equal shapes\n";
1355     }
1356   }
1357   else {
1358     di << "shapes are not same\n";
1359   }
1360   return 0;
1361 }
1362
1363 //=======================================================================
1364 //function : issubshape
1365 //purpose  : 
1366 //=======================================================================
1367 static Standard_Integer issubshape(Draw_Interpretor& di,
1368                                    Standard_Integer n,
1369                                    const char** a)
1370 {  
1371   if (n != 3) {
1372     di << "Check if the shape is sub-shape of other shape and get its index in the shape.\n";
1373     di << "Usage: issubshape subshape shape\n";
1374     return 1;
1375   }
1376   // get shapes
1377   TopoDS_Shape aSubShape = DBRep::Get(a[1]);
1378   TopoDS_Shape aShape    = DBRep::Get(a[2]);
1379   // check shapes
1380   if (aSubShape.IsNull() || aShape.IsNull()) {
1381     di << "null shapes\n";
1382     return 0;
1383   }
1384   // find index of the sub-shape in the shape
1385   TopTools_MapOfShape aMShapes;
1386   // try to find the SubShape in Shape
1387   TopExp_Explorer anExp(aShape, aSubShape.ShapeType());
1388   for (; anExp.More(); anExp.Next()) {
1389     const TopoDS_Shape& aSS = anExp.Current();
1390     if (aMShapes.Add(aSS)) {
1391       if (aSS.IsSame(aSubShape)) {
1392         break;
1393       }
1394     }
1395   }
1396   //
1397   if (anExp.More()) {
1398     di << a[1] << " is sub-shape of " << a[2] << ". Index in the shape: " << aMShapes.Extent() << ".\n";
1399   }
1400   else {
1401     di << a[1] << " is NOT sub-shape of " << a[2] << ".\n";
1402   }
1403   //
1404   return 0;
1405 }
1406
1407 void  BRepTest::BasicCommands(Draw_Interpretor& theCommands)
1408 {
1409   static Standard_Boolean done = Standard_False;
1410   if (done) return;
1411   done = Standard_True;
1412
1413   DBRep::BasicCommands(theCommands);
1414
1415   const char* g = "TOPOLOGY Basic shape commands";
1416
1417   theCommands.Add("addpcurve",
1418                   "addpcurve edge 2dcurve face [tol (default 1.e-7)]",
1419                   __FILE__,
1420                   addpcurve,g);
1421
1422   theCommands.Add("reset",
1423                   "reset name1 name2 ..., remove location",
1424                   __FILE__,
1425                   transform,g);
1426
1427   theCommands.Add("tmove",
1428                   "tmove name1 name2 ... name, set location from name [-copy]",
1429                   __FILE__,
1430                   transform,g);
1431
1432   theCommands.Add("ttranslate",
1433                   "ttranslate name1 name2 ... dx dy dz [-copy]",
1434                   __FILE__,
1435                   transform,g);
1436
1437   theCommands.Add("trotate",
1438                   "trotate name1 name2 ... x y z dx dy dz angle [-copy]",
1439                   __FILE__,
1440                   transform,g);
1441
1442   theCommands.Add("tmirror",
1443                   "tmirror name x y z dx dy dz [-copy]",
1444                   __FILE__,
1445                   transform,g);
1446
1447   theCommands.Add("tscale",
1448                   "tscale name x y z scale [-copy]",
1449                   __FILE__,
1450                   transform,g);
1451
1452   theCommands.Add("tcopy",
1453                   "tcopy [-n(ogeom)] [-m(esh)] name1 result1 [name2 result2 ...]",
1454                   __FILE__,
1455                   tcopy,g);
1456
1457   theCommands.Add("bmove",
1458                   "bmove name1 name2 ... name, set location from name",
1459                   __FILE__,
1460                   transform,g);
1461
1462   theCommands.Add("btranslate",
1463                   "btranslate name1 name2 ... dx dy dz",
1464                   __FILE__,
1465                   transform,g);
1466
1467   theCommands.Add("brotate",
1468                   "brotate name1 name2 ... x y z dx dy dz angle",
1469                   __FILE__,
1470                   transform,g);
1471
1472   theCommands.Add("bmirror",
1473                   "bmirror name x y z dx dy dz",
1474                   __FILE__,
1475                   transform,g);
1476
1477   theCommands.Add("bscale",
1478                   "bscale name x y z scale",
1479                   __FILE__,
1480                   transform,g);
1481
1482   theCommands.Add("precision",
1483                   "precision [preci]",
1484                   __FILE__,
1485                   precision,g);
1486
1487   theCommands.Add("mkedgecurve",
1488                   "mkedgecurve name tolerance",
1489                   __FILE__,
1490                   mkedgecurve,g);
1491
1492   theCommands.Add("fsameparameter",
1493                   "fsameparameter shapename [tol (default 1.e-7)], \nforce sameparameter on all edges of the shape",
1494                   __FILE__,
1495                   sameparameter,g);
1496
1497   theCommands.Add("sameparameter",
1498                   "sameparameter [result] shape [tol]",
1499                   __FILE__,
1500                   sameparameter,g);
1501
1502   theCommands.Add("updatetolerance",
1503                   "updatetolerance [result] shape [param] \n  if [param] is absent - not verify of face tolerance, else - perform it",
1504                   __FILE__,
1505                   updatetol,g);
1506
1507   theCommands.Add("solidorientation",
1508                   "orientsolid myClosedSolid",
1509                   __FILE__,
1510                   orientsolid,g);
1511
1512   theCommands.Add("getcoords",
1513     "getcoords vertex1 vertex 2... ; shows coords of input vertices",
1514     __FILE__,
1515     getcoords,g);
1516   
1517   theCommands.Add("bounding", "enter the comand w/o any arguments to obtain the help.",
1518                   __FILE__, BoundBox, g);
1519
1520  //
1521   theCommands.Add("gbounding",
1522                   "gbounding surf/curve/curve2d [-o] ",
1523                   __FILE__,
1524                   gbounding,g);
1525
1526   theCommands.Add("isbbinterf", "isbbinterf shape1 shape2 [-o]\n"
1527                   "Checks whether the bounding-boxes created from "
1528                   "the given shapes are interfered. If \"-o\"-option "
1529                   "is switched on then the oriented boxes will be checked. "
1530                   "Otherwise, axes-aligned boxes will be checked.",
1531                   __FILE__, IsBoxesInterfered, g);
1532
1533   theCommands.Add("nurbsconvert",
1534                   "nurbsconvert result name [result name]",
1535                   __FILE__,
1536                   nurbsconvert,g);
1537
1538   theCommands.Add("deform",
1539                   "deform newname name CoeffX CoeffY CoeffZ",
1540                   __FILE__,
1541                   deform,g);
1542   
1543   theCommands.Add("findplane",
1544                   "findplane name planename ",
1545                   __FILE__,
1546                   findplane,g) ;
1547   
1548   theCommands.Add("maxtolerance",
1549                   "maxtolerance shape ",
1550                   __FILE__,
1551                   maxtolerance,g) ;
1552
1553   theCommands.Add("reperageshape",
1554                   "reperage shape -> list of shape (result of interstion shape , line)",
1555                   __FILE__,
1556                   reperageshape,g) ;
1557
1558   theCommands.Add("vecdc",
1559                   "vecdc + Pointe double click ",
1560                   __FILE__,
1561                   vecdc,g) ;
1562
1563   theCommands.Add("nproject","nproject pj e1 e2 e3 ... surf -g -d [dmax] [Tol [continuity [maxdeg [maxseg]]]",
1564                   __FILE__,
1565                   nproject,g);
1566
1567   theCommands.Add("wexplo","wexplo wire [face] create WEDGE_i",
1568                   __FILE__,
1569                   wexplo,g);
1570
1571   theCommands.Add("scalexyz",
1572                   "scalexyz res shape factor_x factor_y factor_z",
1573                   __FILE__,
1574                   scalexyz, g);
1575
1576   theCommands.Add("compare",
1577                   "Compare shapes. Usage: compare shape1 shape2",
1578                   __FILE__,
1579                   compareshapes, g);
1580
1581   theCommands.Add("issubshape",
1582                   "issubshape subshape shape\n"
1583                   "\t\tCheck if the shape is sub-shape of other shape and get its index in the shape.",
1584                   __FILE__,
1585                   issubshape, g);
1586 }