0030949: Foundation Classes - Dump improvement for OCCT classes
[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
59 #include <Standard_Dump.hxx>
60
61 #include <stdio.h>
62
63 Standard_IMPORT Draw_Viewer dout;
64
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)
71 {
72   if (theBox.IsVoid())
73   {
74     DBRep::Set (theName, TopoDS_Shape());
75     return;
76   }
77
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();
85
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);
90 }
91
92 //=======================================================================
93 // addpcurve
94 //=======================================================================
95
96 static Standard_Integer addpcurve(Draw_Interpretor& , Standard_Integer n, const char** a)
97 {
98   if(n < 4) return 1;
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;
104   if (n > 4) {
105     tol = Draw::Atof(a[4]);
106   }
107   BRep_Builder BB;
108   BB.UpdateEdge(TopoDS::Edge(E), PC, TopoDS::Face(F),tol); 
109   DBRep::Set(a[1], E);
110   return 0;
111 }
112
113
114 //=======================================================================
115 // transform
116 //=======================================================================
117
118 static Standard_Integer transform(Draw_Interpretor& ,Standard_Integer n,const char** a)
119 {
120   if (n <= 1) return 1;
121
122   gp_Trsf T;
123   Standard_Integer last = n;
124   const char* aName = a[0];
125
126   Standard_Boolean isBasic = Standard_False;
127   Standard_Boolean isCopy = Standard_False;
128
129   // Check "copy" flag.
130   if (!strcmp(a[n-1], "-copy")) {
131     isCopy = Standard_True;
132     last = --n;
133   }
134
135   if (!strcmp(aName,"reset")) {
136   }
137   else {
138     isBasic = (aName[0] == 'b');
139     aName++;
140
141     if (!strcmp(aName,"move")) {
142       if (n < 3) return 1;
143       TopoDS_Shape SL = DBRep::Get(a[n-1]);
144       if (SL.IsNull()) return 0;
145       T = SL.Location().Transformation();
146       last = n-1;
147     }
148     else if (!strcmp(aName,"translate")) {
149       if (n < 5) return 1;
150       T.SetTranslation(gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1])));
151       last = n-3;
152     }
153     else if (!strcmp(aName,"rotate")) {
154       if (n < 9) return 1;
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));
158       last = n-7;
159     }
160     else if (!strcmp(aName,"mirror")) {
161       if (n < 8) return 1;
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]))));
164       last = n-6;
165     }
166     else if (!strcmp(aName,"scale")) {
167       if (n < 6) return 1;
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]));
169       last = n-4;
170     }
171   }
172
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]);
177       if (S.IsNull())
178       {
179         std::cerr << "Error: " << a[i] << " is not a valid shape\n";
180         return 1;
181       }
182       else
183         DBRep::Set(a[i],S.Located(L));
184     }
185   }
186   else {
187     BRepBuilderAPI_Transform trf(T);
188     for (Standard_Integer i = 1; i < last; i++) {
189       TopoDS_Shape S = DBRep::Get(a[i]);
190       if (S.IsNull()) {
191         std::cerr << "Error: " << a[i] << " is not a valid shape\n";
192         return 1;
193       }
194       else {
195         trf.Perform(S, isCopy);
196         if (!trf.IsDone())
197           return 1;
198         DBRep::Set(a[i],trf.Shape());
199       }
200     }
201   }
202   return 0;
203 }
204
205 ///=======================================================================
206 // gtransform
207 //=======================================================================
208
209 static Standard_Integer deform(Draw_Interpretor& di,Standard_Integer n,const char** a)
210 {
211   if (n <= 1) return 1;
212   
213   Standard_Integer last = n;
214   
215   gp_Trsf T;
216   gp_GTrsf GT(T);
217   
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);
221   last -= 3;
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]);    
227   if (S.IsNull()) {
228     //std::cout << a[2] << " is not a valid shape" << std::endl;
229     di << a[2] << " is not a valid shape\n";
230   }
231   else {
232     gtrf.Perform(S);
233     if (gtrf.IsDone()){
234       DBRep::Set(a[1],gtrf.Shape());
235     }
236     else {
237       return 1;
238     }
239   }
240   
241   return 0;
242 }
243
244 //=======================================================================
245 // tcopy
246 //=======================================================================
247
248 static Standard_Integer tcopy(Draw_Interpretor& di,Standard_Integer n,const char** a)
249 {
250   Standard_Boolean copyGeom = Standard_True;
251   Standard_Boolean copyMesh = Standard_False;
252   Standard_Integer iFirst = 1; // index of first shape argument
253
254   if (n > 1)
255   {
256     for (Standard_Integer i = 1; i <= 2; i++)
257     {
258       if (a[i][0] != '-')
259         break;
260       if (a[i][1] == 'n')
261       {
262         copyGeom = Standard_False;
263         iFirst++;
264       }
265       else if (a[i][1] == 'm')
266       {
267         copyMesh = Standard_True;
268         iFirst++;
269       }
270     }
271   }
272
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;
277     return 1;
278   }
279
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] << " ";
286   }
287   return 0;
288 }
289
290
291 //=======================================================================
292 // NurbsConvert
293 //=======================================================================
294
295 static Standard_Integer nurbsconvert(Draw_Interpretor& di,Standard_Integer n,const char** a)
296 {
297   if (n < 3) return 1;
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]);
302     if (S.IsNull()) {
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";
305     }
306     else {
307       nbscv.Perform(S);
308       if (nbscv.IsDone()){
309         DBRep::Set(a[2*i+1],nbscv.Shape());
310       }
311       else {
312         return 1;
313       }
314     }
315   }
316   
317   return 0;
318   
319 }
320
321 //=======================================================================
322 // make a 3D edge curve
323 //=======================================================================
324
325 static Standard_Integer mkedgecurve (Draw_Interpretor& ,Standard_Integer n,const char** a)
326 {
327
328   if (n < 3) return 1;
329   Standard_Real Tolerance = Draw::Atof(a[2]) ;
330
331   TopoDS_Shape S = DBRep::Get(a[1]);
332   
333   if (S.IsNull()) return 1;
334   
335    BRepLib::BuildCurves3d(S,
336                           Tolerance) ;
337    return 0 ;
338 }
339
340 //=======================================================================
341 // sameparameter
342 //=======================================================================
343
344 static Standard_Integer sameparameter(Draw_Interpretor& di,Standard_Integer n,const char** a)
345 {
346   if (n < 2) 
347   {
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)";
352     return 1;
353   }
354   Standard_Real aTol = 1.e-7;
355   Standard_Boolean force  = !strcmp(a[0],"fsameparameter");
356
357   Standard_Real aTol1 = Draw::Atof(a[n-1]);
358   Standard_Boolean IsUseTol = aTol1>0;
359   if (IsUseTol)
360     aTol = aTol1;
361
362   TopoDS_Shape anInpS = DBRep::Get(IsUseTol ? a[n-2] : a[n-1]);
363   if (anInpS.IsNull())
364     return 1;
365
366   if ((n == 4 && IsUseTol) || (n == 3 && !IsUseTol))
367   {
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); 
373   }
374   else
375   {
376     BRepLib::SameParameter(anInpS,aTol,force);
377     DBRep::Set(a[1],anInpS); 
378   }
379
380   return 0;
381 }
382 //=======================================================================
383 //function : updatetol
384 //purpose  : 
385 //=======================================================================
386 static Standard_Integer updatetol(Draw_Interpretor& di,Standard_Integer n,const char** a)
387 {
388   if (n < 2) 
389   {
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";
394     return 1;
395   }
396   TopoDS_Shape aSh1 = DBRep::Get(a[n-1]);
397   Standard_Boolean IsF = aSh1.IsNull();
398
399   TopoDS_Shape anInpS = IsF ? DBRep::Get(a[n-2]) : aSh1;
400   if (anInpS.IsNull())
401     return 1;
402
403   if ((n == 4 && IsF) || (n == 3 && !IsF))
404   {
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); 
410   }
411   else
412   {
413     BRepLib::UpdateTolerances(anInpS, IsF);
414     DBRep::Set(a[1],anInpS); 
415   }
416
417   return 0;
418 }
419
420 //=======================================================================
421 //function : OrienSolid
422 //purpose  : 
423 //=======================================================================
424 static Standard_Integer orientsolid(Draw_Interpretor& ,Standard_Integer n,const char** a)
425 {
426   if (n < 2) return 1;
427
428   TopoDS_Shape S = DBRep::Get(a[1]);
429   if (S.IsNull()) return 1;
430   if (S.ShapeType()!=TopAbs_SOLID) return 1;
431
432   BRepLib::OrientClosedSolid(TopoDS::Solid(S));
433
434   DBRep::Set(a[1],S);
435   return 0;
436
437 }
438
439 //=======================================================================
440 //function : getcoords
441 //purpose  : 
442 //=======================================================================
443 static Standard_Integer getcoords(Draw_Interpretor& di,Standard_Integer n,const char** a)
444 {
445   if(n < 2) 
446     return 1;
447
448   for (Standard_Integer i = 1; i < n; i++) 
449   {
450     const TopoDS_Shape aShape = DBRep::Get (a[i]);
451
452     if (aShape.IsNull())
453       continue;
454
455     if (aShape.ShapeType() == TopAbs_VERTEX)
456     {
457       const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
458       gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
459
460       di << a[i] << " (x,y,z) : " << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
461     }
462   }
463
464   return 0;
465 }
466
467 //! Parse 6 real values for defining AABB.
468 static Standard_Boolean parseMinMax (const char** theArgVec, Bnd_Box& theBox)
469 {
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())
478   {
479     return Standard_False;
480   }
481
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());
484   theBox.SetVoid();
485   theBox.Add (aPntMin);
486   theBox.Add (aPntMax);
487   return Standard_True;
488 }
489
490 //=======================================================================
491 //function : BoundBox
492 //purpose  : 
493 //=======================================================================
494 static Standard_Integer BoundBox(Draw_Interpretor& theDI,
495                                  Standard_Integer theNArg,
496                                  const char** theArgVal)
497 {
498   // 1. Parse arguments
499
500   TopoDS_Shape aShape;
501   Bnd_Box anAABB;
502
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;
512   
513   TCollection_AsciiString anOutVars[6];
514   TCollection_AsciiString aResShapeName;
515   for (Standard_Integer anArgIter = 1; anArgIter < theNArg; ++anArgIter)
516   {
517     TCollection_AsciiString anArgCase (theArgVal[anArgIter]);
518     anArgCase.LowerCase();
519     if (anArgCase == "-obb")
520     {
521       isOBB = Standard_True;
522     }
523     else if (anArgCase == "-aabb")
524     {
525       isOBB = Standard_False;
526     }
527     else if (anArgCase == "-shape"
528           && anArgIter + 1 < theNArg
529           && aResShapeName.IsEmpty())
530     {
531       aResShapeName = theArgVal[++anArgIter];
532       hasToDraw = Standard_False;
533     }
534     else if (anArgCase == "-dump"
535           || anArgCase == "-print")
536     {
537       doPrint = Standard_True;
538     }
539     else if (anArgCase == "-dumpjson")
540     {
541       doDumpJson = Standard_True;
542     }
543     else if (anArgCase == "-save"
544           && anArgIter + 6 < theNArg
545           && anOutVars[0].IsEmpty())
546     {
547       for (int aCompIter = 0; aCompIter < 6; ++aCompIter)
548       {
549         anOutVars[aCompIter] = theArgVal[anArgIter + aCompIter + 1];
550       }
551       anArgIter += 6;
552     }
553     else if (anArgCase == "-notriangulation")
554     {
555       isTriangulationReq = Standard_False;
556     }
557     else if (anArgCase == "-optimal")
558     {
559       isOptimal = Standard_True;
560     }
561     else if (anArgCase == "-exttoler")
562     {
563       isTolerUsed = Standard_True;
564     }
565     else if (anArgCase == "-nodraw")
566     {
567       hasToDraw = Standard_False;
568     }
569     else if (anArgCase == "-finite"
570           || anArgCase == "-finitepart")
571     {
572       isFinitePart = Standard_True;
573     }
574     else if (aShape.IsNull()
575          && !DBRep::Get (theArgVal[anArgIter]).IsNull())
576     {
577       aShape = DBRep::Get (theArgVal[anArgIter]);
578     }
579     else if (anAABB.IsVoid()
580           && anArgIter + 5 < theNArg
581           && parseMinMax (theArgVal + anArgIter, anAABB))
582     {
583       anArgIter += 5;
584     }
585     else
586     {
587       std::cout << "Syntax error at argument '" << theArgVal[anArgIter] << "'.\n";
588       return 1;
589     }
590   }
591
592   if (anAABB.IsVoid()
593    && aShape.IsNull())
594   {
595     std::cout << "Syntax error: input is not specified (neither shape nor coordinates)\n";
596     return 1;
597   }
598   else if (!anAABB.IsVoid()
599         && (isOBB || isOptimal || isTolerUsed))
600   {
601     std::cout << "Syntax error: Options -obb, -optimal and -extToler cannot be used for explicitly defined AABB.\n";
602     return 1;
603   }
604   else if (isOBB
605        && !anOutVars[0].IsEmpty())
606   {
607     std::cout << "Error: Option -save works only with axes-aligned boxes.\n";
608     return 1;
609   }
610
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())
613   {
614     doPrint = Standard_True;
615     useOldSyntax = Standard_True;
616   }
617
618   // 2. Compute box and save results
619   Handle(Draw_Box) aDB;
620   if (isOBB)
621   {
622     Bnd_OBB anOBB;
623     BRepBndLib::AddOBB(aShape, anOBB, isTriangulationReq, isOptimal, isTolerUsed);
624
625     if (anOBB.IsVoid())
626     {
627       theDI << "Void box.\n";
628     }
629     else if (doPrint)
630     {
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";
645     }
646
647     if (doDumpJson)
648     {
649       Standard_SStream aStream;
650       anOBB.DumpJson (aStream);
651
652       theDI << "Oriented bounding box\n";
653       theDI << Standard_Dump::FormatJson (aStream);
654     }
655
656     if (hasToDraw
657     && !anOBB.IsVoid())
658     {
659       aDB = new Draw_Box (anOBB, Draw_orange);
660     }
661
662     if (!aResShapeName.IsEmpty())
663     {
664       ConvertBndToShape (anOBB, aResShapeName.ToCString());
665     }
666   }
667   else // if(!isOBB)
668   {
669     if (!aShape.IsNull())
670     {
671       anAABB.SetVoid ();
672       if(isOptimal)
673       {
674         BRepBndLib::AddOptimal (aShape, anAABB, isTriangulationReq, isTolerUsed);
675       }
676       else
677       {
678         BRepBndLib::Add (aShape, anAABB, isTriangulationReq);
679       }
680     }
681
682     if (anAABB.IsVoid())
683     {
684       theDI << "Void box.\n";
685     }
686     else
687     {
688       if (isFinitePart && anAABB.IsOpen())
689       {
690         anAABB = anAABB.FinitePart();
691       }
692       const gp_Pnt aMin = anAABB.CornerMin();
693       const gp_Pnt aMax = anAABB.CornerMax();
694
695       // print to DRAW
696       if (doPrint)
697       {
698         if (useOldSyntax)
699         {
700           theDI << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
701                 << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
702         }
703         else
704         {
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";
709           if (anAABB.IsOpen()
710            && anAABB.HasFinitePart())
711           {
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";
719           }
720         }
721       }
722
723       if (doDumpJson)
724       {
725         Standard_SStream aStream;
726         anAABB.DumpJson (aStream);
727
728         theDI << "Bounding box\n";
729         theDI << Standard_Dump::FormatJson (aStream);
730       }
731
732       // save DRAW variables
733       if (!anOutVars[0].IsEmpty())
734       {
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());
741       }
742
743       // add presentation to DRAW viewer
744       if (hasToDraw)
745       {
746         aDB = new Draw_Box (anAABB, Draw_orange);
747       }
748     }
749
750     // save as shape
751     if (!aResShapeName.IsEmpty())
752     {
753       ConvertBndToShape (anAABB, aResShapeName.ToCString());
754     }
755   }
756
757   if (!aDB.IsNull())
758   {
759     dout << aDB;
760   }
761   return 0;
762 }
763
764 //=======================================================================
765 //function : IsBoxesInterfered
766 //purpose  : 
767 //=======================================================================
768 static Standard_Integer IsBoxesInterfered(Draw_Interpretor& theDI,
769                                           Standard_Integer theNArg,
770                                           const char** theArgVal)
771 {
772   if(theNArg < 2)
773   {
774     theDI << "Use: isbbinterf shape1 shape2 [-o].\n";
775     return 1;
776   }
777
778   const TopoDS_Shape aShape1 = DBRep::Get(theArgVal[1]);
779   const TopoDS_Shape aShape2 = DBRep::Get(theArgVal[2]);
780
781   Standard_Boolean isOBB = (theNArg > 3) && (!strcmp(theArgVal[3], "-o"));
782
783   if(isOBB)
784   {
785     Bnd_OBB anOBB1, anOBB2;
786     BRepBndLib::AddOBB(aShape1, anOBB1);
787     BRepBndLib::AddOBB(aShape2, anOBB2);
788
789     if(anOBB1.IsOut(anOBB2))
790     {
791       theDI << "The shapes are NOT interfered by OBB.\n";
792     }
793     else
794     {
795       theDI << "The shapes are interfered by OBB.\n";
796     }
797   }
798   else
799   {
800     Bnd_Box anAABB1, anAABB2;
801     BRepBndLib::Add(aShape1, anAABB1);
802     BRepBndLib::Add(aShape2, anAABB2);
803
804     if(anAABB1.IsOut(anAABB2))
805     {
806       theDI << "The shapes are NOT interfered by AABB.\n";
807     }
808     else
809     {
810       theDI << "The shapes are interfered by AABB.\n";
811     }
812   }
813
814   return 0;
815 }
816
817 //=======================================================================
818 //function : gbounding
819 //purpose  : 
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)
827 {
828   if (n != 2 && n != 3) 
829   {
830     di << "Usage: gbounding surf/curve/curve2d [-o] \n";
831     di << "[-o] turn on Optimal mode ('off' by default) \n";
832     return 1;
833   }
834   else
835   {
836     Standard_Boolean IsOptimal = Standard_False;
837     if (n == 3 && !strcmp(a[2], "-o"))
838       IsOptimal = Standard_True;
839     
840     Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
841     Bnd_Box B;
842     Bnd_Box2d B2d;
843     Handle(Draw_Box) DB;
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]);
849     if (!S.IsNull())
850     {
851       //add surf
852       GeomAdaptor_Surface aGAS(S);
853       if (IsOptimal)
854         BndLib_AddSurface::AddOptimal(aGAS, Precision::Confusion(), B);
855       else
856         BndLib_AddSurface::Add(aGAS, Precision::Confusion(), B);
857     }
858     else
859     {
860       C = DrawTrSurf::GetCurve(a[1]);
861       if (!C.IsNull())
862       {
863         // add cur
864         GeomAdaptor_Curve aGAC(C);
865         if (IsOptimal)
866           BndLib_Add3dCurve::AddOptimal(aGAC, Precision::Confusion(), B);
867         else
868           BndLib_Add3dCurve::Add(aGAC, Precision::Confusion(), B);
869       }
870       else
871       {
872         C2d = DrawTrSurf::GetCurve2d(a[1]);
873         if (!C2d.IsNull())
874         {
875           //add cur2d
876           Is3d = Standard_False;
877           if (IsOptimal)
878             BndLib_Add2dCurve::AddOptimal(C2d, C2d->FirstParameter(), C2d->LastParameter(), Precision::Confusion(), B2d); 
879           else
880             BndLib_Add2dCurve::Add(C2d, C2d->FirstParameter(), C2d->LastParameter(), Precision::Confusion(), B2d); 
881         }
882         else
883         {
884           di << "Wrong argument \n";
885           return 1;
886         }
887       }
888     }
889
890     if (Is3d)
891     {
892       B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
893       DB = new Draw_Box(B, Draw_vert);
894       dout<<DB;
895       di << axmin<<" "<< aymin<<" "<< azmin<<" "<< axmax<<" "<< aymax<<" "<< azmax;
896     }
897     else
898     {
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;
910     }
911   }
912   return 0;
913 }
914
915 //=======================================================================
916 //function : findplane
917 //purpose  : 
918 //=======================================================================
919 static Standard_Integer findplane(Draw_Interpretor& di,Standard_Integer n,const char** a)
920 {
921   if (n < 3) return 1;
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,
926                                    tolerance) ;
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) ;
932   }
933   return 0 ;
934 }
935 //=======================================================================
936 //function : precision
937 //purpose  : 
938 //=======================================================================
939
940 static Standard_Integer precision(Draw_Interpretor& di,Standard_Integer n,const char** a)
941 {
942   n--;
943
944   if ( n == 0) {
945     //std::cout << " Current Precision = " << BRepBuilderAPI::Precision() << std::endl;
946     di << " Current Precision = " << BRepBuilderAPI::Precision() << "\n";
947   }
948   else {
949     BRepBuilderAPI::Precision(Draw::Atof(a[1]));
950   }
951   return 0;
952 }
953
954
955 //=======================================================================
956 //function : reperage shape (Int lin Shape) + pointe double click   + maxtol
957 //purpose  : 
958 //=======================================================================
959 #include <IntCurvesFace_ShapeIntersector.hxx>
960 #include <gp_Lin.hxx>
961
962 static Standard_Integer reperageshape(Draw_Interpretor& di, Standard_Integer narg , const char** a) 
963 {
964   Standard_Integer details=0;
965   if(narg<2) return 1;
966   if(narg==3) details=1;
967   const char *id1 = a[1];
968   TopoDS_Shape TheShape1 = DBRep::Get(id1);
969   
970   //std::cout << "Pick positions with button "<<std::endl;
971   di << "Pick positions with button \n";
972   Standard_Integer id,X,Y,b;
973   gp_Trsf T;
974   gp_Pnt P1,P2;
975   dout.Select(id,X,Y,b);
976   
977   dout.GetTrsf(id,T);
978   T.Invert();
979   Standard_Real z = dout.Zoom(id);
980   P2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z, 0.0);
981   P2.Transform(T);
982   P1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,-1.0);
983   P1.Transform(T);
984   
985   
986   gp_Ax1 Axe(P1,gp_Vec(P1,P2));
987   IntCurvesFace_ShapeIntersector Inter;
988   Inter.Load(TheShape1,1e-7);
989   
990   Inter.Perform(Axe,-RealLast(),RealLast());
991   
992   //std::cout<<"\n --> ";
993   di <<"\n --> ";
994   if(Inter.NbPnt()) { 
995     for(Standard_Integer i=1; i<=Inter.NbPnt(); i++) { 
996       Standard_Integer numface=1;
997       TopExp_Explorer ExF;
998       for(ExF.Init(TheShape1,TopAbs_FACE);
999           ExF.More();
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;
1005           continue;       
1006         }
1007       }
1008       const gp_Pnt& P = Inter.Pnt(i);
1009       Standard_Real PMin = Inter.WParameter(i);
1010       if(details) { 
1011         //std::cout<<" w:"<<PMin<<std::endl;
1012         di<<" w:"<<PMin<< "\n";
1013       }
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();
1018         }
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();
1022         }
1023       }
1024       else { 
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();
1029           }
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();
1033           }
1034         } 
1035       }
1036     }
1037   }
1038   //std::cout<<std::endl;
1039   di << "\n";
1040   return(0);
1041 }
1042
1043
1044 static Standard_Integer maxtolerance(Draw_Interpretor& theCommands, 
1045                                      Standard_Integer n, const char** a) { 
1046   if(n<2) return(1);
1047   TopoDS_Shape TheShape = DBRep::Get(a[1]);
1048   if(TheShape.IsNull()) return(1);
1049
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();
1054   
1055   TopTools_MapOfShape mapS;
1056   mapS.Clear();
1057
1058   for(TopExp_Explorer ex(TheShape,TopAbs_FACE);
1059       ex.More();
1060       ex.Next()) { 
1061     TopoDS_Face Face=TopoDS::Face(ex.Current());
1062     T=BRep_Tool::Tolerance(Face);
1063     if(T>TMF) TMF=T;
1064     if(T<TmF) TmF=T;
1065     mapS.Add(Face);
1066   }
1067   
1068   nbF = mapS.Extent();
1069   mapS.Clear();
1070   
1071   for(TopExp_Explorer ex(TheShape,TopAbs_EDGE);
1072       ex.More();
1073       ex.Next()) { 
1074     TopoDS_Edge Edge=TopoDS::Edge(ex.Current());
1075     T=BRep_Tool::Tolerance(Edge);
1076     if(T>TME) TME=T;
1077     if(T<TmE) TmE=T;
1078     mapS.Add(Edge);
1079   }
1080
1081   nbE = mapS.Extent();
1082   mapS.Clear();
1083
1084   for(TopExp_Explorer ex(TheShape,TopAbs_VERTEX);
1085       ex.More();
1086       ex.Next()) { 
1087     TopoDS_Vertex Vertex=TopoDS::Vertex(ex.Current());
1088     T=BRep_Tool::Tolerance(Vertex);
1089     if(T>TMV) TMV=T;
1090     if(T<TmV) TmV=T;
1091     mapS.Add(Vertex);
1092   }
1093
1094   nbV = mapS.Extent();
1095
1096   Standard_SStream sss;
1097   sss << "\n## Tolerances on the shape " << a[1] << "  (nbFaces:" << nbF
1098       << "  nbEdges:" << nbE << " nbVtx:" << nbV << ")\n" ;
1099   sss.precision(5);
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 ";
1104   theCommands << sss;
1105
1106   return 0;
1107 }
1108
1109
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";
1113
1114   Standard_Integer id,X,Y,b;
1115   gp_Trsf T;
1116   gp_Pnt P1,P2,PP1,PP2;
1117   
1118   //-----------------------------------------------------------
1119   dout.Select(id,X,Y,b);    dout.GetTrsf(id,T);
1120   T.Invert();
1121   Standard_Real z = dout.Zoom(id);
1122   P1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1123   P1.Transform(T);
1124   
1125   dout.Select(id,X,Y,b);  dout.GetTrsf(id,T);
1126   T.Invert();  z = dout.Zoom(id);
1127   
1128   P2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1129   P2.Transform(T);
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(),
1136                                                       P1.Y(),
1137                                                       P1.Z()),
1138                                                Draw_Square,Draw_blanc,1);
1139   
1140   dout << D0;
1141   dout.Flush();
1142   //-----------------------------------------------------------
1143   dout.Select(id,X,Y,b);  
1144   dout.GetTrsf(id,T);
1145   T.Invert();
1146   z = dout.Zoom(id);
1147   PP1.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1148   PP1.Transform(T);
1149   dout.Select(id,X,Y,b);
1150   dout.GetTrsf(id,T);
1151   T.Invert();
1152   z = dout.Zoom(id);
1153   PP2.SetCoord((Standard_Real)X /z,(Standard_Real)Y /z,0.0);
1154   PP2.Transform(T);
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);
1160   dout << d;
1161   dout.Flush();
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";
1164
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;
1168
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;
1172
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";
1175
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";
1179   return(0);
1180 }
1181 //=======================================================================
1182 // nproject
1183 //=======================================================================
1184
1185 #include <TopTools_SequenceOfShape.hxx>
1186  static Standard_Integer nproject(Draw_Interpretor& di, Standard_Integer n, const char** a)
1187 {
1188   if ( n < 4) return 1;
1189   TopoDS_Shape InpShape;
1190   Standard_Integer arg = 2, i;
1191   TopTools_SequenceOfShape Args; 
1192
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;           
1199
1200   while((n > arg) && !(InpShape = DBRep::Get(a[arg])).IsNull()){
1201     Args.Append(InpShape);
1202     arg++;
1203   }
1204   if(Args.Length() < 2) return 1;
1205   
1206   BRepOffsetAPI_NormalProjection OrtProj(Args.Last());
1207
1208   for(i = 1; i < Args.Length(); i++)
1209     OrtProj.Add(Args(i));
1210
1211   if(n > arg)
1212     if (!strcmp(a[arg],"-g")) {
1213       OrtProj.SetLimit(Standard_False);
1214       arg++;
1215     }
1216   
1217   if(n > arg)
1218     if (!strcmp(a[arg],"-d")) {
1219       arg++;
1220       if(n > arg)
1221         MaxDistance = Draw::Atof(a[arg++]);
1222       OrtProj.SetMaxDistance(MaxDistance);
1223     }
1224   if(n > arg) {
1225     Tol = Max(Draw::Atof(a[arg++]),1.e-10);
1226   }
1227
1228   if(n > arg) {
1229     if (Draw::Atoi(a[arg]) == 0) Continuity = GeomAbs_C0;
1230     else if (Draw::Atoi(a[arg]) == 1) Continuity = GeomAbs_C1;
1231     arg++;
1232   }
1233
1234  
1235   if(n > arg) {
1236     MaxDeg = Draw::Atoi(a[arg++]);
1237     if (MaxDeg<1 || MaxDeg>14) MaxDeg = 14;
1238   }
1239
1240   if(n > arg) MaxSeg = Draw::Atoi(a[arg]);
1241     
1242   Tol2d = Pow(Tol, 2./3);
1243
1244   OrtProj.SetParams(Tol, Tol2d, Continuity, MaxDeg, MaxSeg);
1245   OrtProj.Build();
1246   TopTools_ListOfShape Wire;
1247   Standard_Boolean IsWire=OrtProj.BuildWire(Wire);
1248   if (IsWire) {
1249     //std::cout << " BuildWire OK " << std::endl;
1250     di << " BuildWire OK \n";
1251   }
1252   DBRep::Set(a[1], OrtProj.Shape());
1253   return 0;  
1254 }
1255
1256 //==========================================================================
1257 //function : wexplo
1258 //           exploration of a wire 
1259 //==========================================================================
1260 static Standard_Integer wexplo (Draw_Interpretor&, 
1261                                 Standard_Integer argc, const char** argv)
1262
1263   char name[100];
1264   if (argc < 2) return 1;
1265   
1266   TopoDS_Shape C1 = DBRep::Get (argv[1],TopAbs_WIRE);
1267   TopoDS_Shape C2 ;
1268
1269   if (argc > 2)  C2 = DBRep::Get (argv[2],TopAbs_FACE);
1270
1271   if (C1.IsNull()) return 1;
1272
1273   BRepTools_WireExplorer we;
1274   if (C2.IsNull()) we.Init(TopoDS::Wire(C1));
1275   else             we.Init(TopoDS::Wire(C1),TopoDS::Face(C2));
1276
1277   Standard_Integer k = 1;
1278   while (we.More()) {
1279     TopoDS_Edge E = we.Current();
1280     Sprintf(name,"WEDGE_%d",k); 
1281           DBRep::Set(name,E);
1282     we.Next();
1283     k++;
1284   }
1285
1286   return 0;
1287 }
1288
1289 static Standard_Integer scalexyz(Draw_Interpretor& /*di*/, Standard_Integer n, const char** a)
1290 {
1291   if (n < 6) return 1;
1292
1293   TopoDS_Shape aShapeBase = DBRep::Get(a[2]);
1294   if (aShapeBase.IsNull()) return 1;
1295   
1296   Standard_Real aFactorX = Draw::Atof(a[3]);
1297   Standard_Real aFactorY = Draw::Atof(a[4]);
1298   Standard_Real aFactorZ = Draw::Atof(a[5]);
1299
1300   gp_GTrsf aGTrsf;
1301   gp_Mat rot (aFactorX, 0, 0,
1302               0, aFactorY, 0,
1303               0, 0, aFactorZ);
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();
1309
1310   DBRep::Set(a[1], Result);
1311   return 0;  
1312 }
1313
1314 //=======================================================================
1315 //function : compareshapes
1316 //purpose  : 
1317 //=======================================================================
1318 static Standard_Integer compareshapes(Draw_Interpretor& di,
1319                                       Standard_Integer n,
1320                                       const char** a)
1321 {
1322   if (n != 3) {
1323     di << "Compare shapes. Usage: compare shape1 shape2\n";
1324     return 1;
1325   }
1326   // get shapes
1327   TopoDS_Shape aS1 = DBRep::Get(a[1]);
1328   TopoDS_Shape aS2 = DBRep::Get(a[2]);
1329   // check shapes
1330   if (aS1.IsNull() || aS2.IsNull()) {
1331     di << "null shapes\n";
1332     return 0;
1333   }
1334   // compare shapes
1335   if (aS1.IsSame(aS2)) {
1336     di << "same shapes\n";
1337     if (aS1.IsEqual(aS2)) {
1338       di << "equal shapes\n";
1339     }
1340   }
1341   else {
1342     di << "shapes are not same\n";
1343   }
1344   return 0;
1345 }
1346
1347 //=======================================================================
1348 //function : issubshape
1349 //purpose  : 
1350 //=======================================================================
1351 static Standard_Integer issubshape(Draw_Interpretor& di,
1352                                    Standard_Integer n,
1353                                    const char** a)
1354 {  
1355   if (n != 3) {
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";
1358     return 1;
1359   }
1360   // get shapes
1361   TopoDS_Shape aSubShape = DBRep::Get(a[1]);
1362   TopoDS_Shape aShape    = DBRep::Get(a[2]);
1363   // check shapes
1364   if (aSubShape.IsNull() || aShape.IsNull()) {
1365     di << "null shapes\n";
1366     return 0;
1367   }
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)) {
1376         break;
1377       }
1378     }
1379   }
1380   //
1381   if (anExp.More()) {
1382     di << a[1] << " is sub-shape of " << a[2] << ". Index in the shape: " << aMShapes.Extent() << ".\n";
1383   }
1384   else {
1385     di << a[1] << " is NOT sub-shape of " << a[2] << ".\n";
1386   }
1387   //
1388   return 0;
1389 }
1390
1391 void  BRepTest::BasicCommands(Draw_Interpretor& theCommands)
1392 {
1393   static Standard_Boolean done = Standard_False;
1394   if (done) return;
1395   done = Standard_True;
1396
1397   DBRep::BasicCommands(theCommands);
1398
1399   const char* g = "TOPOLOGY Basic shape commands";
1400
1401   theCommands.Add("addpcurve",
1402                   "addpcurve edge 2dcurve face [tol (default 1.e-7)]",
1403                   __FILE__,
1404                   addpcurve,g);
1405
1406   theCommands.Add("reset",
1407                   "reset name1 name2 ..., remove location",
1408                   __FILE__,
1409                   transform,g);
1410
1411   theCommands.Add("tmove",
1412                   "tmove name1 name2 ... name, set location from name [-copy]",
1413                   __FILE__,
1414                   transform,g);
1415
1416   theCommands.Add("ttranslate",
1417                   "ttranslate name1 name2 ... dx dy dz [-copy]",
1418                   __FILE__,
1419                   transform,g);
1420
1421   theCommands.Add("trotate",
1422                   "trotate name1 name2 ... x y z dx dy dz angle [-copy]",
1423                   __FILE__,
1424                   transform,g);
1425
1426   theCommands.Add("tmirror",
1427                   "tmirror name x y z dx dy dz [-copy]",
1428                   __FILE__,
1429                   transform,g);
1430
1431   theCommands.Add("tscale",
1432                   "tscale name x y z scale [-copy]",
1433                   __FILE__,
1434                   transform,g);
1435
1436   theCommands.Add("tcopy",
1437                   "tcopy [-n(ogeom)] [-m(esh)] name1 result1 [name2 result2 ...]",
1438                   __FILE__,
1439                   tcopy,g);
1440
1441   theCommands.Add("bmove",
1442                   "bmove name1 name2 ... name, set location from name",
1443                   __FILE__,
1444                   transform,g);
1445
1446   theCommands.Add("btranslate",
1447                   "btranslate name1 name2 ... dx dy dz",
1448                   __FILE__,
1449                   transform,g);
1450
1451   theCommands.Add("brotate",
1452                   "brotate name1 name2 ... x y z dx dy dz angle",
1453                   __FILE__,
1454                   transform,g);
1455
1456   theCommands.Add("bmirror",
1457                   "bmirror name x y z dx dy dz",
1458                   __FILE__,
1459                   transform,g);
1460
1461   theCommands.Add("bscale",
1462                   "bscale name x y z scale",
1463                   __FILE__,
1464                   transform,g);
1465
1466   theCommands.Add("precision",
1467                   "precision [preci]",
1468                   __FILE__,
1469                   precision,g);
1470
1471   theCommands.Add("mkedgecurve",
1472                   "mkedgecurve name tolerance",
1473                   __FILE__,
1474                   mkedgecurve,g);
1475
1476   theCommands.Add("fsameparameter",
1477                   "fsameparameter shapename [tol (default 1.e-7)], \nforce sameparameter on all edges of the shape",
1478                   __FILE__,
1479                   sameparameter,g);
1480
1481   theCommands.Add("sameparameter",
1482                   "sameparameter [result] shape [tol]",
1483                   __FILE__,
1484                   sameparameter,g);
1485
1486   theCommands.Add("updatetolerance",
1487                   "updatetolerance [result] shape [param] \n  if [param] is absent - not verify of face tolerance, else - perform it",
1488                   __FILE__,
1489                   updatetol,g);
1490
1491   theCommands.Add("solidorientation",
1492                   "orientsolid myClosedSolid",
1493                   __FILE__,
1494                   orientsolid,g);
1495
1496   theCommands.Add("getcoords",
1497     "getcoords vertex1 vertex 2... ; shows coords of input vertices",
1498     __FILE__,
1499     getcoords,g);
1500   
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]"
1506          "\n\t\t:"
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)."
1509          "\n\t\t:"
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."
1519          "\n\t\t:"
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);
1531
1532  //
1533   theCommands.Add("gbounding",
1534                   "gbounding surf/curve/curve2d [-o] ",
1535                   __FILE__,
1536                   gbounding,g);
1537
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);
1544
1545   theCommands.Add("nurbsconvert",
1546                   "nurbsconvert result name [result name]",
1547                   __FILE__,
1548                   nurbsconvert,g);
1549
1550   theCommands.Add("deform",
1551                   "deform newname name CoeffX CoeffY CoeffZ",
1552                   __FILE__,
1553                   deform,g);
1554   
1555   theCommands.Add("findplane",
1556                   "findplane name planename ",
1557                   __FILE__,
1558                   findplane,g) ;
1559   
1560   theCommands.Add("maxtolerance",
1561                   "maxtolerance shape ",
1562                   __FILE__,
1563                   maxtolerance,g) ;
1564
1565   theCommands.Add("reperageshape",
1566                   "reperage shape -> list of shape (result of interstion shape , line)",
1567                   __FILE__,
1568                   reperageshape,g) ;
1569
1570   theCommands.Add("vecdc",
1571                   "vecdc + Pointe double click ",
1572                   __FILE__,
1573                   vecdc,g) ;
1574
1575   theCommands.Add("nproject","nproject pj e1 e2 e3 ... surf -g -d [dmax] [Tol [continuity [maxdeg [maxseg]]]",
1576                   __FILE__,
1577                   nproject,g);
1578
1579   theCommands.Add("wexplo","wexplo wire [face] create WEDGE_i",
1580                   __FILE__,
1581                   wexplo,g);
1582
1583   theCommands.Add("scalexyz",
1584                   "scalexyz res shape factor_x factor_y factor_z",
1585                   __FILE__,
1586                   scalexyz, g);
1587
1588   theCommands.Add("compare",
1589                   "Compare shapes. Usage: compare shape1 shape2",
1590                   __FILE__,
1591                   compareshapes, g);
1592
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.",
1596                   __FILE__,
1597                   issubshape, g);
1598 }