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