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