8b68725f0de184f45d62dfe5f7673b06ca924b0c
[occt.git] / src / BOPTest / BOPTest_BOPCommands.cxx
1 // Created on: 2000-03-16
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BOPAlgo_BOP.hxx>
18 #include <BOPAlgo_MakerVolume.hxx>
19 #include <BOPAlgo_Operation.hxx>
20 #include <BOPAlgo_PaveFiller.hxx>
21 #include <BOPAlgo_Section.hxx>
22 #include <BOPCol_ListOfShape.hxx>
23 #include <BOPDS_DS.hxx>
24 #include <BOPTest.hxx>
25 #include <BOPTest_Objects.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRepAlgoAPI_BooleanOperation.hxx>
28 #include <BRepAlgoAPI_Common.hxx>
29 #include <BRepAlgoAPI_Cut.hxx>
30 #include <BRepAlgoAPI_Fuse.hxx>
31 #include <BRepAlgoAPI_Section.hxx>
32 #include <DBRep.hxx>
33 #include <Draw.hxx>
34 #include <DrawTrSurf.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <Geom_Curve.hxx>
37 #include <IntTools_Curve.hxx>
38 #include <IntTools_FaceFace.hxx>
39 #include <IntTools_PntOn2Faces.hxx>
40 #include <NCollection_BaseAllocator.hxx>
41 #include <TCollection_AsciiString.hxx>
42 #include <TopoDS_Compound.hxx>
43 #include <TopoDS_Iterator.hxx>
44 #include <TopoDS_Shape.hxx>
45
46 #include <stdio.h>
47 //
48 //
49 static BOPAlgo_PaveFiller* pPF=NULL;
50 //
51
52 static
53   Standard_Integer bopsmt(Draw_Interpretor& di,
54                           Standard_Integer n,
55                           const char** a,
56                           const BOPAlgo_Operation aOp);
57 //
58 static
59   Standard_Integer bsmt (Draw_Interpretor& di, 
60                        Standard_Integer n, 
61                        const char** a,
62                        const BOPAlgo_Operation aOp);
63 //
64 static Standard_Integer bop       (Draw_Interpretor&, Standard_Integer, const char**);
65 static Standard_Integer bopsection(Draw_Interpretor&, Standard_Integer, const char**);
66 static Standard_Integer boptuc    (Draw_Interpretor&, Standard_Integer, const char**);
67 static Standard_Integer bopcut    (Draw_Interpretor&, Standard_Integer, const char**);
68 static Standard_Integer bopfuse   (Draw_Interpretor&, Standard_Integer, const char**);
69 static Standard_Integer bopcommon (Draw_Interpretor&, Standard_Integer, const char**);
70 //
71 static Standard_Integer bsection  (Draw_Interpretor&, Standard_Integer, const char**);
72 static Standard_Integer btuc      (Draw_Interpretor&, Standard_Integer, const char**);
73 static Standard_Integer bcut      (Draw_Interpretor&, Standard_Integer, const char**);
74 static Standard_Integer bfuse     (Draw_Interpretor&, Standard_Integer, const char**);
75 static Standard_Integer bcommon   (Draw_Interpretor&, Standard_Integer, const char**);
76 //
77 static Standard_Integer bopcurves (Draw_Interpretor&, Standard_Integer, const char**);
78 static Standard_Integer mkvolume   (Draw_Interpretor&, Standard_Integer, const char**);
79
80 //=======================================================================
81 //function : BOPCommands
82 //purpose  : 
83 //=======================================================================
84   void BOPTest::BOPCommands(Draw_Interpretor& theCommands)
85 {
86   static Standard_Boolean done = Standard_False;
87   if (done) return;
88   done = Standard_True;
89   // Chapter's name
90   const char* g = "BOPTest commands";
91   // Commands
92   
93   theCommands.Add("bop"       , "use bop s1 s2" , __FILE__, bop, g);
94   theCommands.Add("bopcommon" , "use bopcommon r"     , __FILE__, bopcommon, g);
95   theCommands.Add("bopfuse"   , "use bopfuse r"       , __FILE__,bopfuse, g);
96   theCommands.Add("bopcut"    , "use bopcut r"        , __FILE__,bopcut, g);
97   theCommands.Add("boptuc"    , "use boptuc r"        , __FILE__,boptuc, g);
98   theCommands.Add("bopsection", "use bopsection r"    , __FILE__,bopsection, g);
99   //
100   theCommands.Add("bcommon" , "use bcommon r s1 s2" , __FILE__,bcommon, g);
101   theCommands.Add("bfuse"   , "use bfuse r s1 s2"   , __FILE__,bfuse, g);
102   theCommands.Add("bcut"    , "use bcut r s1 s2"    , __FILE__,bcut, g);
103   theCommands.Add("btuc"    , "use btuc r s1 s2"    , __FILE__,btuc, g);
104   theCommands.Add("bsection", "use bsection r s1 s2 [-n2d/-n2d1/-n2d2] [-na]", 
105                                                       __FILE__, bsection, g);
106   //
107   theCommands.Add("bopcurves", "use bopcurves F1 F2 [-2d/-2d1/-2d2] [-p u1 v1 u2 v2]",
108                                                       __FILE__, bopcurves, g);
109   theCommands.Add("mkvolume", "make solids from set of shapes.\nmkvolume r b1 b2 ... [-c] [-ni]", 
110                   __FILE__, mkvolume , g);
111 }
112
113 //=======================================================================
114 //function : bop
115 //purpose  : 
116 //=======================================================================
117 Standard_Integer bop(Draw_Interpretor& di, 
118                      Standard_Integer n, 
119                      const char** a)
120 {
121   char buf[32];
122   Standard_Boolean bRunParallel, bNonDestructive;
123   Standard_Integer iErr;
124   Standard_Real aTol;
125   TopoDS_Shape aS1, aS2;
126   BOPCol_ListOfShape aLC;
127   //
128   if (n != 3) {
129     di << " use bop s1 s2 \n";
130     return 0;
131   }
132   //
133   aS1=DBRep::Get(a[1]);
134   aS2=DBRep::Get(a[2]);
135   //
136   if (aS1.IsNull() || aS2.IsNull()) {
137     di << " null shapes are not allowed \n";
138     return 0;
139   }
140   //
141   aTol=BOPTest_Objects::FuzzyValue();
142   bRunParallel=BOPTest_Objects::RunParallel();
143   bNonDestructive = BOPTest_Objects::NonDestructive();
144   BOPAlgo_GlueEnum aGlue = BOPTest_Objects::Glue();
145   //
146   aLC.Append(aS1);
147   aLC.Append(aS2);
148   //
149   if (pPF!=NULL) {
150     delete pPF;
151     pPF=NULL;
152   }
153   Handle(NCollection_BaseAllocator)aAL=
154     NCollection_BaseAllocator::CommonBaseAllocator();
155   pPF=new BOPAlgo_PaveFiller(aAL);
156   //
157   pPF->SetArguments(aLC);
158   pPF->SetFuzzyValue(aTol);
159   pPF->SetRunParallel(bRunParallel);
160   pPF->SetNonDestructive(bNonDestructive);
161   pPF->SetGlue(aGlue);
162   //
163   pPF->Perform();
164   iErr=pPF->ErrorStatus();
165   if (iErr) {
166     Sprintf(buf, " ErrorStatus : %d\n",  iErr);
167     di << buf;
168     return 0;
169   }
170   //
171   return 0;
172 }
173 //=======================================================================
174 //function : bopcommon
175 //purpose  : 
176 //=======================================================================
177 Standard_Integer bopcommon (Draw_Interpretor& di, 
178                             Standard_Integer n, 
179                             const char** a)
180 {
181   return bopsmt(di, n, a, BOPAlgo_COMMON);
182 }
183 //=======================================================================
184 //function : bopfuse
185 //purpose  : 
186 //=======================================================================
187 Standard_Integer bopfuse(Draw_Interpretor& di, 
188                          Standard_Integer n, 
189                          const char** a)
190 {
191   return bopsmt(di, n, a, BOPAlgo_FUSE);
192 }
193 //=======================================================================
194 //function : bopcut
195 //purpose  : 
196 //=======================================================================
197 Standard_Integer bopcut(Draw_Interpretor& di, 
198                         Standard_Integer n, 
199                         const char** a)
200 {
201   return bopsmt(di, n, a, BOPAlgo_CUT);
202 }
203 //=======================================================================
204 //function : boptuc
205 //purpose  : 
206 //=======================================================================
207 Standard_Integer boptuc(Draw_Interpretor& di, 
208                         Standard_Integer n, 
209                         const char** a)
210 {
211   return bopsmt(di, n, a, BOPAlgo_CUT21);
212 }
213 //=======================================================================
214 //function : bopsmt
215 //purpose  : 
216 //=======================================================================
217 Standard_Integer bopsmt(Draw_Interpretor& di,
218                         Standard_Integer n,
219                         const char** a,
220                         const BOPAlgo_Operation aOp)
221 {
222   if (n<2) {
223     di << " use bopsmt r\n";
224     return 0;
225   }
226   //
227   if (!pPF) {
228     di << " prepare PaveFiller first\n";
229     return 0;
230   }
231   //
232   if (pPF->ErrorStatus()) {
233     di << " PaveFiller has not been done\n";
234     return 0;
235   }
236   //
237   char buf[64];
238   Standard_Boolean bRunParallel;
239   Standard_Integer aNb, iErr;
240   BOPAlgo_BOP aBOP;
241   //
242   const BOPCol_ListOfShape& aLC=pPF->Arguments();
243   aNb=aLC.Extent();
244   if (aNb!=2) {
245     Sprintf (buf, " wrong number of arguments %s\n", aNb);
246     di << buf;
247     return 0;
248   }
249   // 
250   bRunParallel=BOPTest_Objects::RunParallel();
251   //
252   const TopoDS_Shape& aS1=aLC.First();
253   const TopoDS_Shape& aS2=aLC.Last();
254   //
255   aBOP.AddArgument(aS1);
256   aBOP.AddTool(aS2);
257   aBOP.SetOperation(aOp);
258   aBOP.SetRunParallel (bRunParallel);
259   //
260   aBOP.PerformWithFiller(*pPF);
261   iErr=aBOP.ErrorStatus();
262   if (iErr) {
263     Sprintf(buf, " ErrorStatus : %d\n",  iErr);
264     di << buf;
265     return 0;
266   }
267   //
268   const TopoDS_Shape& aR=aBOP.Shape();
269   if (aR.IsNull()) {
270     di << " null shape\n";
271     return 0;
272   }
273   //
274   DBRep::Set(a[1], aR);
275   return 0;
276 }
277 //=======================================================================
278 //function : bopsection
279 //purpose  : 
280 //=======================================================================
281 Standard_Integer bopsection(Draw_Interpretor& di, 
282                             Standard_Integer n, 
283                             const char** a)
284 {
285   if (n<2) {
286     di << " use bopsection r\n";
287     return 0;
288   }
289   //
290   if (!pPF) {
291     di << " prepare PaveFiller first\n";
292     return 0;
293   }
294   //
295   if (pPF->ErrorStatus()) {
296     di << " PaveFiller has not been done\n";
297     return 0;
298   }
299   //
300   char buf[64];
301   Standard_Boolean bRunParallel;
302   Standard_Integer aNb, iErr;
303   BOPAlgo_Section aBOP;
304   //
305   const BOPCol_ListOfShape& aLC=pPF->Arguments();
306   aNb=aLC.Extent();
307   if (aNb!=2) {
308     Sprintf (buf, " wrong number of arguments %s\n", aNb);
309     di << buf;
310     return 0;
311   }
312   //
313   bRunParallel=BOPTest_Objects::RunParallel();
314   //
315   const TopoDS_Shape& aS1=aLC.First();
316   const TopoDS_Shape& aS2=aLC.Last();
317   //
318   aBOP.AddArgument(aS1);
319   aBOP.AddArgument(aS2);
320   aBOP.SetRunParallel (bRunParallel);
321   //
322   aBOP.PerformWithFiller(*pPF);
323   iErr=aBOP.ErrorStatus();
324   if (iErr) {
325     Sprintf(buf, " ErrorStatus : %d\n",  iErr);
326     di << buf;
327     return 0;
328   }
329   //
330   const TopoDS_Shape& aR=aBOP.Shape();
331   if (aR.IsNull()) {
332     di << " null shape\n";
333     return 0;
334   }
335   //
336   DBRep::Set(a[1], aR);
337   return 0;
338 }
339 //=======================================================================
340 //function : bcommon
341 //purpose  : 
342 //=======================================================================
343 Standard_Integer bcommon (Draw_Interpretor& di, 
344                           Standard_Integer n, 
345                           const char** a)
346 {
347   return bsmt(di, n, a, BOPAlgo_COMMON);
348 }
349 //=======================================================================
350 //function : bfuse
351 //purpose  : 
352 //=======================================================================
353 Standard_Integer bfuse (Draw_Interpretor& di, 
354                         Standard_Integer n, 
355                         const char** a)
356 {
357   return bsmt(di, n, a, BOPAlgo_FUSE);
358 }
359 //=======================================================================
360 //function : bcut
361 //purpose  : 
362 //=======================================================================
363 Standard_Integer bcut (Draw_Interpretor& di, 
364                        Standard_Integer n, 
365                        const char** a)
366 {
367   return bsmt(di, n, a, BOPAlgo_CUT);
368 }
369 //=======================================================================
370 //function : btuc
371 //purpose  : 
372 //=======================================================================
373 Standard_Integer btuc (Draw_Interpretor& di, 
374                        Standard_Integer n, 
375                        const char** a)
376 {
377   return bsmt(di, n, a, BOPAlgo_CUT21);
378 }
379 //=======================================================================
380 //function : bsection
381 //purpose  : 
382 //=======================================================================
383 Standard_Integer  bsection(Draw_Interpretor& di, 
384                            Standard_Integer n, 
385                            const char** a)
386 {
387   if (n < 4) {
388     di << "use bsection r s1 s2 [-n2d/-n2d1/-n2d2] [-na] [tol]\n";
389     return 0;
390   }
391   //
392   TopoDS_Shape aS1, aS2;
393   //
394   aS1=DBRep::Get(a[2]);
395   aS2=DBRep::Get(a[3]);
396   if (aS1.IsNull() || aS2.IsNull()) {
397     di << " Null shapes are not allowed \n";
398     return 0;
399   }
400   // 
401   char buf[80];
402   Standard_Boolean bRunParallel, bNonDestructive, bApp, bPC1, bPC2;
403   Standard_Integer i, iErr;
404   Standard_Real aTol;
405   //
406   bApp = Standard_True;
407   bPC1 = Standard_True;
408   bPC2 = Standard_True;
409   aTol = BOPTest_Objects::FuzzyValue(); 
410   bRunParallel = BOPTest_Objects::RunParallel();
411   bNonDestructive = BOPTest_Objects::NonDestructive();
412   BOPAlgo_GlueEnum aGlue = BOPTest_Objects::Glue();
413   //
414   for (i = 4; i < n; ++i) {
415     if (!strcmp(a[i], "-n2d")) {
416       bPC1 = Standard_False;
417       bPC2 = Standard_False;
418     }
419     else if (!strcmp(a[i], "-n2d1")) {
420       bPC1 = Standard_False;
421     }
422     else if (!strcmp(a[i], "-n2d2")) {
423       bPC2 = Standard_False;
424     }
425     else if (!strcmp(a[i], "-na")) {
426       bApp = Standard_False;
427     }
428   }
429   //
430   BRepAlgoAPI_Section aSec(aS1, aS2, Standard_False);
431   //
432   aSec.Approximation(bApp);
433   aSec.ComputePCurveOn1(bPC1);
434   aSec.ComputePCurveOn2(bPC2);
435   //
436   aSec.SetFuzzyValue(aTol);
437   aSec.SetRunParallel(bRunParallel);
438   aSec.SetNonDestructive(bNonDestructive);
439   aSec.SetGlue(aGlue);
440   //
441   aSec.Build();
442   iErr=aSec.ErrorStatus();
443   if (!aSec.IsDone()) {
444     Sprintf(buf, " ErrorStatus : %d\n",  iErr);
445     di << buf;
446     return 0;
447   }
448   //
449   const TopoDS_Shape& aR=aSec.Shape();
450   if (aR.IsNull()) {
451     di << " null shape\n";
452     return 0;
453   }
454   DBRep::Set(a[1], aR);
455   return 0;
456 }
457 //=======================================================================
458 //function : bsmt
459 //purpose  : 
460 //=======================================================================
461 Standard_Integer bsmt (Draw_Interpretor& di, 
462                        Standard_Integer n, 
463                        const char** a,
464                        const BOPAlgo_Operation aOp)
465 {
466   char buf[32];
467   Standard_Boolean bRunParallel, bNonDestructive;
468   Standard_Integer iErr;
469   TopoDS_Shape aS1, aS2;
470   BOPCol_ListOfShape aLC;
471   Standard_Real aTol;
472   //
473   if (n != 4) {
474     di << " use bx r s1 s2\n";
475     return 0;
476   }
477   //
478   aS1=DBRep::Get(a[2]);
479   aS2=DBRep::Get(a[3]);
480   //
481   if (aS1.IsNull() || aS2.IsNull()) {
482     di << " null shapes are not allowed \n";
483     return 0;
484   }
485   aLC.Append(aS1);
486   aLC.Append(aS2);
487   // 
488   aTol=BOPTest_Objects::FuzzyValue();
489   bRunParallel = BOPTest_Objects::RunParallel();
490   bNonDestructive = BOPTest_Objects::NonDestructive();
491   BOPAlgo_GlueEnum aGlue = BOPTest_Objects::Glue();
492   //
493   Handle(NCollection_BaseAllocator)aAL=
494     NCollection_BaseAllocator::CommonBaseAllocator();
495   //
496   //---------------------------------------------------------------
497   BOPAlgo_PaveFiller aPF(aAL);
498   //
499   aPF.SetArguments(aLC);
500   aPF.SetFuzzyValue(aTol); 
501   aPF.SetRunParallel(bRunParallel);
502   aPF.SetNonDestructive(bNonDestructive);
503   aPF.SetGlue(aGlue);
504   //
505   aPF.Perform();
506   iErr=aPF.ErrorStatus();
507   if (iErr) {
508     Sprintf(buf, " ErrorStatus : %d\n",  iErr);
509     di << buf;
510     return 0;
511   }
512   //
513   //---------------------------------------------------------------
514   BOPAlgo_BOP aBOP(aAL);
515   //
516   aBOP.AddArgument(aS1);
517   aBOP.AddTool(aS2);
518   aBOP.SetOperation(aOp);
519   aBOP.SetRunParallel(bRunParallel);
520   // 
521   aBOP.PerformWithFiller(aPF);
522   //
523   iErr=aBOP.ErrorStatus();
524   if (iErr) {
525     Sprintf(buf, " ErrorStatus : %d\n",  iErr);
526     di << buf;
527     return 0;
528   }
529   const TopoDS_Shape& aR=aBOP.Shape();
530   if (aR.IsNull()) {
531     di << " null shape\n";
532     return 0;
533   }
534   //
535   DBRep::Set(a[1], aR);
536   return 0;
537 }
538 //=======================================================================
539 //function : bopcurves
540 //purpose  : 
541 //=======================================================================
542 Standard_Integer bopcurves (Draw_Interpretor& di, 
543                             Standard_Integer n, 
544                             const char** a)
545 {
546   if (n<3) {
547     di << " use bopcurves F1 F2 [-2d/-2d1/-2d2]\n";
548     return 1;
549   }
550   //
551   TopoDS_Shape S1 = DBRep::Get(a[1]);
552   TopoDS_Shape S2 = DBRep::Get(a[2]);
553   TopAbs_ShapeEnum aType;
554   //
555   if (S1.IsNull() || S2.IsNull()) {
556     di << " Null shapes is not allowed \n";
557     return 1;
558   }
559   //
560   aType=S1.ShapeType();
561   if (aType != TopAbs_FACE) {
562     di << " Type mismatch F1\n";
563     return 1;
564   }
565   aType=S2.ShapeType();
566   if (aType != TopAbs_FACE) {
567     di << " Type mismatch F2\n";
568     return 1;
569   }
570   //
571   const TopoDS_Face& aF1=*(TopoDS_Face*)(&S1);
572   const TopoDS_Face& aF2=*(TopoDS_Face*)(&S2);
573   //
574   Standard_Boolean aToApproxC3d, aToApproxC2dOnS1, aToApproxC2dOnS2, anIsDone;
575   Standard_Integer aNbCurves, aNbPoints;
576   Standard_Real anAppTol, aTolR;
577   IntSurf_ListOfPntOn2S aListOfPnts;
578   TCollection_AsciiString aNm("c_"), aNp("p_");
579   //
580   anAppTol = 0.0000001;
581   aToApproxC3d = Standard_True;
582   aToApproxC2dOnS1 = Standard_False;
583   aToApproxC2dOnS2 = Standard_False;
584
585   //
586   for(Standard_Integer i = 3; i < n; i++)
587   {
588     if (!strcasecmp(a[i],"-2d")) {
589       aToApproxC2dOnS1 = Standard_True;
590       aToApproxC2dOnS2 = Standard_True;
591     } 
592     else if (!strcasecmp(a[i],"-2d1")) {
593       aToApproxC2dOnS1 = Standard_True;
594     }
595     else if (!strcasecmp(a[i],"-2d2")) {
596       aToApproxC2dOnS2 = Standard_True;
597     }
598     else if (!strcasecmp(a[i],"-p")) {
599       IntSurf_PntOn2S aPt;
600       const Standard_Real aU1 = Draw::Atof(a[++i]);
601       const Standard_Real aV1 = Draw::Atof(a[++i]);
602       const Standard_Real aU2 = Draw::Atof(a[++i]);
603       const Standard_Real aV2 = Draw::Atof(a[++i]);
604
605       aPt.SetValue(aU1, aV1, aU2, aV2);
606       aListOfPnts.Append(aPt);
607     }
608     else {
609       di << "Wrong key. To build 2d curves use: bopcurves F1 F2 [-2d/-2d1/-2d2] [-p u1 v1 u2 v2]\n";
610       return 1;
611     }
612
613   }
614
615   //
616   IntTools_FaceFace aFF;
617   //
618   aFF.SetParameters (aToApproxC3d,
619                      aToApproxC2dOnS1,
620                      aToApproxC2dOnS2,
621                      anAppTol);
622   aFF.SetList(aListOfPnts);
623   //
624   aFF.Perform (aF1, aF2);
625   //
626   anIsDone=aFF.IsDone();
627   if (!anIsDone) {
628     di << "Error: anIsDone=" << (Standard_Integer) anIsDone << "\n";
629     return 0;
630   }
631   //
632   aFF.PrepareLines3D(Standard_False);
633   const IntTools_SequenceOfCurves& aSCs=aFF.Lines();
634   const IntTools_SequenceOfPntOn2Faces& aSPs = aFF.Points();
635   //
636   aNbCurves = aSCs.Length();
637   aNbPoints = aSPs.Length();
638   if (!aNbCurves && !aNbPoints) {
639     di << " has no 3d curves\n";
640     di << " has no 3d points\n";
641     return 0;
642   }
643   //
644   aTolR=aFF.TolReached3d();
645   di << "Tolerance Reached=" << aTolR << "\n";
646   //
647   // curves
648   if (aNbCurves) {
649     di << aNbCurves << " curve(s) found.\n";
650     //
651     for (Standard_Integer i=1; i<=aNbCurves; i++) {
652       const IntTools_Curve& anIC=aSCs(i);
653
654       Handle (Geom_Curve)  aC3D = anIC.Curve();
655
656       if (aC3D.IsNull()) {
657         di << " has Null 3d curve# " << i << "\n";
658         continue;
659       }
660
661       TCollection_AsciiString anIndx(i), aNmx;
662       aNmx = aNm + anIndx;
663
664       Standard_CString nameC = aNmx.ToCString();
665
666       DrawTrSurf::Set(nameC, aC3D);
667       di << nameC << " ";
668       //
669       Handle(Geom2d_Curve) aPC1 = anIC.FirstCurve2d();
670       Handle(Geom2d_Curve) aPC2 = anIC.SecondCurve2d();
671       //
672       if (!aPC1.IsNull() || !aPC2.IsNull()) {
673         di << "(";
674         //
675         if (!aPC1.IsNull()) {
676           TCollection_AsciiString pc1N("c2d1_"), pc1Nx;
677           pc1Nx = pc1N + anIndx;
678           Standard_CString nameC2d1 = pc1Nx.ToCString();
679           //
680           DrawTrSurf::Set(nameC2d1, aPC1);
681           di << nameC2d1;
682         }
683         //
684         if (!aPC2.IsNull()) {
685           TCollection_AsciiString pc2N("c2d2_"), pc2Nx;
686           pc2Nx = pc2N + anIndx;
687           Standard_CString nameC2d2 = pc2Nx.ToCString();
688           //
689           DrawTrSurf::Set(nameC2d2, aPC2);
690           //
691           if (!aPC1.IsNull()) {
692             di << ", ";
693           }
694           di << nameC2d2;
695         }
696         di << ") ";
697       }
698     }
699     di << "\n";
700   }
701   //
702   // points
703   if (aNbPoints) {
704     di << aNbPoints << " point(s) found.\n";
705     //
706     for (Standard_Integer i = 1; i <= aNbPoints; i++) {
707       const IntTools_PntOn2Faces& aPi = aSPs(i);
708       const gp_Pnt& aP = aPi.P1().Pnt();
709       //
710       TCollection_AsciiString anIndx(i), aNmx;
711       aNmx = aNp + anIndx;
712       Standard_CString nameP = aNmx.ToCString();
713       //
714       DrawTrSurf::Set(nameP, aP);
715       di << nameP << " ";
716     }
717     di << "\n";
718   }
719   //
720   return 0;
721 }
722 //=======================================================================
723 //function : mkvolume
724 //purpose  : 
725 //=======================================================================
726 Standard_Integer mkvolume(Draw_Interpretor& di, Standard_Integer n, const char** a) 
727 {
728   if (n < 3) {
729     di << "Usage: mkvolume r b1 b2 ... [-c] [-ni]\n";
730     di << "Options:\n";
731     di << " -c  - use this option if the arguments are compounds\n";
732     di << "       containing shapes that should be interfered;\n";
733     di << " -ni - use this option if the arguments should not be interfered;\n";
734     return 1;
735   }
736   //
737   const char* usage = "Type mkvolume without arguments for the usage of the command.\n";
738   //
739   Standard_Boolean bToIntersect, bRunParallel, bNonDestructive, bCompounds;
740   Standard_Integer i;
741   Standard_Real aTol;
742   TopoDS_Shape aS;
743   BOPCol_ListOfShape aLS;
744   //
745   aTol = BOPTest_Objects::FuzzyValue();
746   bRunParallel = BOPTest_Objects::RunParallel();
747   bNonDestructive = BOPTest_Objects::NonDestructive();
748   BOPAlgo_GlueEnum aGlue = BOPTest_Objects::Glue();
749   //
750   bToIntersect = Standard_True;
751   bCompounds = Standard_False;
752   //
753   for (i = 2; i < n; ++i) {
754     aS = DBRep::Get(a[i]);
755     if (!aS.IsNull()) {
756       aLS.Append(aS);
757     }
758     else {
759       if (!strcmp(a[i], "-c")) {
760         bCompounds = Standard_True;
761       }
762       else if (!strcmp(a[i], "-ni")) {
763         bToIntersect = Standard_False;
764       }
765     }
766   }
767   //
768   if (aLS.IsEmpty()) {
769     di << "No shapes to process.\n";
770     di << usage;
771     return 1;
772   }
773   //
774   // treat list of arguments for the case of compounds
775   if (bToIntersect && bCompounds) {
776     BOPCol_ListOfShape aLSx;
777     BOPCol_ListIteratorOfListOfShape aItLS;
778     //
779     aItLS.Initialize(aLS);
780     for (; aItLS.More(); aItLS.Next()) {
781       const TopoDS_Shape& aSx = aItLS.Value();
782       TopoDS_Iterator aItS(aSx);
783       for (; aItS.More(); aItS.Next()) {
784         const TopoDS_Shape& aSxS = aItS.Value();
785         aLSx.Append(aSxS);
786       }
787     }
788     //
789     aLS.Clear();
790     aLS.Assign(aLSx);
791   }
792   //
793   BOPAlgo_MakerVolume aMV;
794   aMV.SetArguments(aLS);
795   aMV.SetIntersect(bToIntersect);
796   aMV.SetRunParallel(bRunParallel);
797   aMV.SetFuzzyValue(aTol);
798   aMV.SetNonDestructive(bNonDestructive);
799   aMV.SetGlue(aGlue);
800   //
801   aMV.Perform();
802   if (aMV.ErrorStatus()) {
803     di << "Error status: " << aMV.ErrorStatus();
804     return 1;
805   }
806   //
807   const TopoDS_Shape& aR = aMV.Shape();
808   //
809   DBRep::Set(a[1], aR);
810   //
811   return 0;
812 }