1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <BOPAlgo_BOP.hxx>
17 #include <BOPAlgo_Builder.hxx>
18 #include <BOPAlgo_Operation.hxx>
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPAlgo_Section.hxx>
21 #include <BOPAlgo_Splitter.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPTest.hxx>
24 #include <BOPTest_DrawableShape.hxx>
25 #include <BOPTest_Objects.hxx>
26 #include <BRepTest_Objects.hxx>
29 #include <Draw_Color.hxx>
30 #include <DrawTrSurf.hxx>
31 #include <OSD_Timer.hxx>
32 #include <TopoDS_Shape.hxx>
39 static Standard_Integer bfillds (Draw_Interpretor&, Standard_Integer, const char**);
40 static Standard_Integer bbuild (Draw_Interpretor&, Standard_Integer, const char**);
41 static Standard_Integer bbop (Draw_Interpretor&, Standard_Integer, const char**);
42 static Standard_Integer bsplit (Draw_Interpretor&, Standard_Integer, const char**);
43 static Standard_Integer buildbop (Draw_Interpretor&, Standard_Integer, const char**);
45 //=======================================================================
46 //function : PartitionCommands
48 //=======================================================================
49 void BOPTest::PartitionCommands(Draw_Interpretor& theCommands)
51 static Standard_Boolean done = Standard_False;
55 const char* g = "BOPTest commands";
57 theCommands.Add("bfillds", "use bfillds [-t]" , __FILE__, bfillds, g);
58 theCommands.Add("bbuild" , "use bbuild r [-t]" , __FILE__, bbuild, g);
59 theCommands.Add("bbop" , "use bbop r op [-t]", __FILE__, bbop, g);
60 theCommands.Add("bsplit" , "use bsplit r [-t]" , __FILE__, bsplit, g);
62 theCommands.Add("buildbop", "Builds the result of BOP basing on the GF.\n"
63 " The command uses classification approach for building the result of BOP\n"
64 " (thus it operates on solids only and can be used on open solids):\n"
65 " - FUSE is built from the faces OUT of all arguments\n"
66 " - COMMON is built from the faces IN any of the object/tools\n"
67 " - CUT is built from the objects faces OUT of the tools and tools faces IN the objects.\n"
68 " Please note that history for solids will not be available.\n\n"
69 " Usage: buildbop result -o s1 [s2 ...] -t s3 [s4 ...] -op operation (common/fuse/cut/tuc)\n"
71 " result - result shape of the operation\n"
72 " s1 s2 s3 s4 - arguments (solids) of the GF operation\n"
73 " operation - type of boolean operation",
74 __FILE__, buildbop, g);
76 //=======================================================================
79 //=======================================================================
80 Standard_Integer bfillds(Draw_Interpretor& di,
85 di << " use bfillds [-t]\n";
90 Standard_Boolean bRunParallel, bNonDestructive, bShowTime;
91 Standard_Integer i, aNbS;
93 TopTools_ListIteratorOfListOfShape aIt;
94 TopTools_ListOfShape aLC;
95 TopTools_ListOfShape& aLS=BOPTest_Objects::Shapes();
98 di << " no objects to process\n";
102 bShowTime = Standard_False;
104 bRunParallel=BOPTest_Objects::RunParallel();
105 bNonDestructive = BOPTest_Objects::NonDestructive();
106 aTol = BOPTest_Objects::FuzzyValue();
107 BOPAlgo_GlueEnum aGlue = BOPTest_Objects::Glue();
109 for (i=1; i<n; ++i) {
110 if (!strcmp(a[i], "-t")) {
111 bShowTime=Standard_True;
115 TopTools_ListOfShape& aLT=BOPTest_Objects::Tools();
118 for (; aIt.More(); aIt.Next()) {
119 const TopoDS_Shape& aS=aIt.Value();
124 for (; aIt.More(); aIt.Next()) {
125 const TopoDS_Shape& aS=aIt.Value();
129 BOPAlgo_PaveFiller& aPF=BOPTest_Objects::PaveFiller();
131 aPF.SetArguments(aLC);
132 aPF.SetRunParallel(bRunParallel);
133 aPF.SetNonDestructive(bNonDestructive);
134 aPF.SetFuzzyValue(aTol);
136 aPF.SetUseOBB(BOPTest_Objects::UseOBB());
142 BOPTest::ReportAlerts(aPF.GetReport());
143 if (aPF.HasErrors()) {
151 Sprintf(buf, " Tps: %7.2lf\n", aTimer.ElapsedTime());
157 //=======================================================================
160 //=======================================================================
161 Standard_Integer bbuild(Draw_Interpretor& di,
166 di << " use bbuild r [-t]\n";
170 BOPDS_PDS pDS=BOPTest_Objects::PDS();
172 di << " prepare PaveFiller first\n";
177 Standard_Boolean bRunParallel, bShowTime;
180 TopTools_ListIteratorOfListOfShape aIt;
182 BOPAlgo_PaveFiller& aPF=BOPTest_Objects::PaveFiller();
184 BOPTest_Objects::SetBuilderDefault();
185 BOPAlgo_Builder& aBuilder=BOPTest_Objects::Builder();
188 TopTools_ListOfShape& aLSObj=BOPTest_Objects::Shapes();
189 aIt.Initialize(aLSObj);
190 for (; aIt.More(); aIt.Next()) {
191 const TopoDS_Shape& aS=aIt.Value();
192 aBuilder.AddArgument(aS);
195 TopTools_ListOfShape& aLSTool=BOPTest_Objects::Tools();
196 aIt.Initialize(aLSTool);
197 for (; aIt.More(); aIt.Next()) {
198 const TopoDS_Shape& aS=aIt.Value();
199 aBuilder.AddArgument(aS);
202 bShowTime=Standard_False;
203 bRunParallel=BOPTest_Objects::RunParallel();
204 for (i=2; i<n; ++i) {
205 if (!strcmp(a[i], "-t")) {
206 bShowTime=Standard_True;
209 aBuilder.SetRunParallel(bRunParallel);
210 aBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
211 aBuilder.SetToFillHistory(BRepTest_Objects::IsHistoryNeeded());
217 aBuilder.PerformWithFiller(aPF);
218 BOPTest::ReportAlerts(aBuilder.GetReport());
220 // Set history of GF operation into the session
221 if (BRepTest_Objects::IsHistoryNeeded())
222 BRepTest_Objects::SetHistory(aPF.Arguments(), aBuilder);
224 if (aBuilder.HasErrors()) {
232 Sprintf(buf, " Tps: %7.2lf\n", aTimer.ElapsedTime());
236 const TopoDS_Shape& aR=aBuilder.Shape();
238 di << " null shape\n";
242 DBRep::Set(a[1], aR);
245 //=======================================================================
248 //=======================================================================
249 Standard_Integer bbop(Draw_Interpretor& di,
254 di << " use bbop r op [-t]\n";
258 BOPDS_PDS pDS=BOPTest_Objects::PDS();
260 di << " prepare PaveFiller first\n";
265 Standard_Boolean bRunParallel, bShowTime;
266 Standard_Integer iOp, i;
267 BOPAlgo_Operation aOp;
268 TopTools_ListIteratorOfListOfShape aIt;
270 iOp=Draw::Atoi(a[2]);
271 if (iOp<0 || iOp>4) {
272 di << " invalid operation type\n";
275 aOp=(BOPAlgo_Operation)iOp;
277 bShowTime=Standard_False;
278 bRunParallel=BOPTest_Objects::RunParallel();
279 for (i=3; i<n; ++i) {
280 if (!strcmp(a[i], "-t")) {
281 bShowTime=Standard_True;
285 BOPAlgo_PaveFiller& aPF=BOPTest_Objects::PaveFiller();
287 BOPAlgo_Builder *pBuilder=NULL;
289 if (aOp!=BOPAlgo_SECTION) {
290 pBuilder=&BOPTest_Objects::BOP();
293 pBuilder=&BOPTest_Objects::Section();
298 TopTools_ListOfShape& aLSObj=BOPTest_Objects::Shapes();
299 aIt.Initialize(aLSObj);
300 for (; aIt.More(); aIt.Next()) {
301 const TopoDS_Shape& aS=aIt.Value();
302 pBuilder->AddArgument(aS);
305 if (aOp!=BOPAlgo_SECTION) {
306 BOPAlgo_BOP *pBOP=(BOPAlgo_BOP *)pBuilder;
308 TopTools_ListOfShape& aLSTools=BOPTest_Objects::Tools();
309 aIt.Initialize(aLSTools);
310 for (; aIt.More(); aIt.Next()) {
311 const TopoDS_Shape& aS=aIt.Value();
315 pBOP->SetOperation(aOp);
318 TopTools_ListOfShape& aLSTools=BOPTest_Objects::Tools();
319 aIt.Initialize(aLSTools);
320 for (; aIt.More(); aIt.Next()) {
321 const TopoDS_Shape& aS=aIt.Value();
322 pBuilder->AddArgument(aS);
326 pBuilder->SetRunParallel(bRunParallel);
327 pBuilder->SetCheckInverted(BOPTest_Objects::CheckInverted());
328 pBuilder->SetToFillHistory(BRepTest_Objects::IsHistoryNeeded());
333 pBuilder->PerformWithFiller(aPF);
334 BOPTest::ReportAlerts(pBuilder->GetReport());
336 // Set history of Boolean operation into the session
337 if (BRepTest_Objects::IsHistoryNeeded())
338 BRepTest_Objects::SetHistory(aPF.Arguments(), *pBuilder);
340 if (pBuilder->HasErrors()) {
347 Sprintf(buf, " Tps: %7.2lf\n", aTimer.ElapsedTime());
351 const TopoDS_Shape& aR=pBuilder->Shape();
353 di << " null shape\n";
357 BOPTest_Objects::SetBuilder(pBuilder);
359 DBRep::Set(a[1], aR);
363 //=======================================================================
366 //=======================================================================
367 Standard_Integer bsplit(Draw_Interpretor& di,
372 di << " use bsplit r [-t (show time)]\n";
376 BOPDS_PDS pDS = BOPTest_Objects::PDS();
378 di << " prepare PaveFiller first\n";
382 BOPAlgo_PaveFiller& aPF = BOPTest_Objects::PaveFiller();
384 BOPAlgo_Splitter* pSplitter = &BOPTest_Objects::Splitter();
388 const TopTools_ListOfShape& aLSObjects = BOPTest_Objects::Shapes();
389 pSplitter->SetArguments(aLSObjects);
392 TopTools_ListOfShape& aLSTools = BOPTest_Objects::Tools();
393 pSplitter->SetTools(aLSTools);
396 pSplitter->SetRunParallel(BOPTest_Objects::RunParallel());
397 pSplitter->SetNonDestructive(BOPTest_Objects::NonDestructive());
398 pSplitter->SetFuzzyValue(BOPTest_Objects::FuzzyValue());
399 pSplitter->SetCheckInverted(BOPTest_Objects::CheckInverted());
400 pSplitter->SetToFillHistory(BRepTest_Objects::IsHistoryNeeded());
402 // measure the time of the operation
406 // perform the operation
407 pSplitter->PerformWithFiller(aPF);
410 BOPTest::ReportAlerts(pSplitter->GetReport());
412 // Set history of Split operation into the session
413 if (BRepTest_Objects::IsHistoryNeeded())
414 BRepTest_Objects::SetHistory(aPF.Arguments(), *pSplitter);
416 if (pSplitter->HasErrors()) {
420 // show time if necessary
421 if (n == 3 && !strcmp(a[2], "-t")) {
423 Sprintf(buf, " Tps: %7.2lf\n", aTimer.ElapsedTime());
427 // Debug commands support
428 BOPTest_Objects::SetBuilder(pSplitter);
430 const TopoDS_Shape& aR = pSplitter->Shape();
432 di << " null shape\n";
436 DBRep::Set(a[1], aR);
440 //=======================================================================
441 //function : buildbop
443 //=======================================================================
444 Standard_Integer buildbop(Draw_Interpretor& di,
454 BOPDS_PDS pDS = BOPTest_Objects::PDS();
457 di << "Error: perform intersection of arguments first";
461 BOPAlgo_Builder *pBuilder = &BOPTest_Objects::Builder();
462 if (pBuilder->HasErrors())
464 di << "Error: there were problems during GF";
468 if (pBuilder->Arguments().IsEmpty() ||
469 pBuilder->Shape().IsNull())
471 di << "Error: it seems the GF has not been yet performed";
475 // Get arguments and operation
476 TopTools_ListOfShape aLObjects, aLTools;
477 BOPAlgo_Operation anOp = BOPAlgo_UNKNOWN;
479 for (Standard_Integer i = 2; i < n; ++i)
481 if (!strcmp(a[i], "-o") || !strcmp(a[i], "-t"))
485 di << "Error: shapes are expected after the key " << a[i];
489 TopTools_ListOfShape& aList = !strcmp(a[i], "-o") ? aLObjects : aLTools;
490 Standard_Integer j = i + 1;
495 // reached the following key
502 TopoDS_Shape aS = DBRep::Get(a[j]);
505 di << "Error: " << a[j] << " is a null shape";
508 if (aS.ShapeType() != TopAbs_SOLID)
510 di << "Error: " << a[j] << " is not a solid";
513 if (pDS->Index(aS) < 0)
515 di << "Error: " << a[j] << " is not an argument of GF";
521 // End of arguments is reached
524 else if (!strcmp(a[i], "-op"))
528 di << "Error: operation type is expected after the key " << a[i];
533 if (!strcasecmp(a[i], "common"))
534 anOp = BOPAlgo_COMMON;
535 else if (!strcasecmp(a[i], "fuse"))
537 else if (!strcasecmp(a[i], "cut"))
539 else if (!strcasecmp(a[i], "tuc"))
540 anOp = BOPAlgo_CUT21;
543 di << "Error: unknown operation type";
549 di << "Error: " << a[i] << " invalid key";
554 if (anOp == BOPAlgo_UNKNOWN)
556 di << "Error: operation has not been specified";
560 Standard_Boolean hasObjects = !aLObjects.IsEmpty();
561 Standard_Boolean hasTools = !aLTools.IsEmpty();
562 if (!hasObjects && !hasTools)
564 di << "Error: no shapes are given";
568 // Create new report for the operation
569 Handle(Message_Report) aReport = new Message_Report;
571 // Build specific operation
572 pBuilder->BuildBOP(aLObjects, aLTools, anOp, aReport);
574 // Report alerts of the operation
575 BOPTest::ReportAlerts(aReport);
577 if (!aReport->GetAlerts(Message_Fail).IsEmpty())
582 // Set history of Split operation into the session
583 if (BRepTest_Objects::IsHistoryNeeded())
584 BRepTest_Objects::SetHistory(pDS->Arguments(), *pBuilder);
587 const TopoDS_Shape& aR = pBuilder->Shape();
589 DBRep::Set(a[1], aR);