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