0030476: Visualization, Path Tracing - Adaptive Screen Sampling leads to unstable...
[occt.git] / src / BOPTest / BOPTest_PartitionCommands.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
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>
27 #include <DBRep.hxx>
28 #include <Draw.hxx>
29 #include <Draw_Color.hxx>
30 #include <DrawTrSurf.hxx>
31 #include <OSD_Timer.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopoDS.hxx>
34
35 #include <stdio.h>
36 #include <string.h>
37 //
38 //
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**);
44
45 //=======================================================================
46 //function : PartitionCommands
47 //purpose  : 
48 //=======================================================================
49 void BOPTest::PartitionCommands(Draw_Interpretor& theCommands)
50 {
51   static Standard_Boolean done = Standard_False;
52   if (done) return;
53   done = Standard_True;
54   // Chapter's name
55   const char* g = "BOPTest commands";
56   // 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);
61
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"
70                   " Where:\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);
75 }
76 //=======================================================================
77 //function : bfillds
78 //purpose  : 
79 //=======================================================================
80 Standard_Integer bfillds(Draw_Interpretor& di, 
81                          Standard_Integer n, 
82                          const char** a) 
83
84   if (n > 2) {
85     di << " use bfillds [-t]\n";
86     return 0;
87   }
88   //
89   char buf[32];
90   Standard_Boolean bRunParallel, bNonDestructive, bShowTime;
91   Standard_Integer i, aNbS;
92   Standard_Real aTol;
93   TopTools_ListIteratorOfListOfShape aIt;
94   TopTools_ListOfShape aLC;
95   TopTools_ListOfShape& aLS=BOPTest_Objects::Shapes();
96   aNbS=aLS.Extent();
97   if (!aNbS) {
98     di << " no objects to process\n";
99     return 0;
100   }
101   //
102   bShowTime = Standard_False;
103   //
104   bRunParallel=BOPTest_Objects::RunParallel();
105   bNonDestructive = BOPTest_Objects::NonDestructive();
106   aTol = BOPTest_Objects::FuzzyValue();
107   BOPAlgo_GlueEnum aGlue = BOPTest_Objects::Glue();
108   //
109   for (i=1; i<n; ++i) {
110     if (!strcmp(a[i], "-t")) {
111       bShowTime=Standard_True;
112     }
113   }
114   //
115   TopTools_ListOfShape& aLT=BOPTest_Objects::Tools();
116   //
117   aIt.Initialize(aLS);
118   for (; aIt.More(); aIt.Next()) {
119     const TopoDS_Shape& aS=aIt.Value();
120     aLC.Append(aS);
121   }
122   //
123   aIt.Initialize(aLT);
124   for (; aIt.More(); aIt.Next()) {
125     const TopoDS_Shape& aS=aIt.Value();
126      aLC.Append(aS);
127   }
128   //
129   BOPAlgo_PaveFiller& aPF=BOPTest_Objects::PaveFiller();
130   //
131   aPF.SetArguments(aLC);
132   aPF.SetRunParallel(bRunParallel);
133   aPF.SetNonDestructive(bNonDestructive);
134   aPF.SetFuzzyValue(aTol);
135   aPF.SetGlue(aGlue);
136   aPF.SetUseOBB(BOPTest_Objects::UseOBB());
137   //
138   OSD_Timer aTimer;
139   aTimer.Start();
140   //
141   aPF.Perform();
142   BOPTest::ReportAlerts(aPF.GetReport());
143   if (aPF.HasErrors()) {
144     return 0;
145   }
146   //
147   aTimer.Stop();
148   //
149   if (bShowTime)
150   {
151     Sprintf(buf, "  Tps: %7.2lf\n", aTimer.ElapsedTime());
152     di << buf;
153   }
154   //
155   return 0;
156 }
157 //=======================================================================
158 //function : bbuild
159 //purpose  : 
160 //=======================================================================
161 Standard_Integer bbuild(Draw_Interpretor& di,
162                         Standard_Integer n, 
163                         const char** a) 
164
165   if (n<2) {
166     di << " use bbuild r [-t]\n";
167     return 0;
168   }
169   //
170   BOPDS_PDS pDS=BOPTest_Objects::PDS();
171   if (!pDS) {
172     di << " prepare PaveFiller first\n";
173     return 0;
174   }
175   //
176   char buf[128];
177   Standard_Boolean bRunParallel, bShowTime;
178   Standard_Integer i;
179
180   TopTools_ListIteratorOfListOfShape aIt;
181   //
182   BOPAlgo_PaveFiller& aPF=BOPTest_Objects::PaveFiller();
183   //
184   BOPTest_Objects::SetBuilderDefault();
185   BOPAlgo_Builder& aBuilder=BOPTest_Objects::Builder();
186   aBuilder.Clear();
187   //
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);
193   }
194   //
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);
200   }
201   //
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;
207     }
208   }
209   aBuilder.SetRunParallel(bRunParallel);
210   aBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
211   aBuilder.SetToFillHistory(BRepTest_Objects::IsHistoryNeeded());
212   //
213   //
214   OSD_Timer aTimer;
215   aTimer.Start();
216   //
217   aBuilder.PerformWithFiller(aPF); 
218   BOPTest::ReportAlerts(aBuilder.GetReport());
219
220   // Set history of GF operation into the session
221   if (BRepTest_Objects::IsHistoryNeeded())
222     BRepTest_Objects::SetHistory(aPF.Arguments(), aBuilder);
223
224   if (aBuilder.HasErrors()) {
225     return 0;
226   }
227   //
228   aTimer.Stop();
229   //
230   if (bShowTime)
231   {
232     Sprintf(buf, "  Tps: %7.2lf\n", aTimer.ElapsedTime());
233     di << buf;
234   }
235   //
236   const TopoDS_Shape& aR=aBuilder.Shape();
237   if (aR.IsNull()) {
238     di << " null shape\n";
239     return 0;
240   }
241   //
242   DBRep::Set(a[1], aR);
243   return 0;
244 }
245 //=======================================================================
246 //function : bbop
247 //purpose  : 
248 //=======================================================================
249 Standard_Integer bbop(Draw_Interpretor& di, 
250                       Standard_Integer n, 
251                       const char** a) 
252
253   if (n<3) {
254     di << " use bbop r op [-t]\n";
255     return 0;
256   }
257   //
258   BOPDS_PDS pDS=BOPTest_Objects::PDS();
259   if (!pDS) {
260     di << " prepare PaveFiller first\n";
261     return 0;
262   }
263   //
264   char buf[32];
265   Standard_Boolean bRunParallel, bShowTime;
266   Standard_Integer iOp, i;
267   BOPAlgo_Operation aOp;
268   TopTools_ListIteratorOfListOfShape aIt; 
269   //
270   iOp=Draw::Atoi(a[2]);
271   if (iOp<0 || iOp>4) {
272     di << " invalid operation type\n";
273     return 0;
274   }
275   aOp=(BOPAlgo_Operation)iOp;
276   //
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;
282     }
283   }
284   //
285   BOPAlgo_PaveFiller& aPF=BOPTest_Objects::PaveFiller();
286   //
287   BOPAlgo_Builder *pBuilder=NULL;
288   
289   if (aOp!=BOPAlgo_SECTION) { 
290     pBuilder=&BOPTest_Objects::BOP();
291   } 
292   else {
293     pBuilder=&BOPTest_Objects::Section();
294   }
295   //
296   pBuilder->Clear();
297   //
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);
303   }
304   //
305   if (aOp!=BOPAlgo_SECTION) {
306     BOPAlgo_BOP *pBOP=(BOPAlgo_BOP *)pBuilder;
307     //
308     TopTools_ListOfShape& aLSTools=BOPTest_Objects::Tools();
309     aIt.Initialize(aLSTools);
310     for (; aIt.More(); aIt.Next()) {
311       const TopoDS_Shape& aS=aIt.Value();
312       pBOP->AddTool(aS);
313     }
314     //
315     pBOP->SetOperation(aOp);
316   }
317   else {
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);
323     }
324   }
325   //
326   pBuilder->SetRunParallel(bRunParallel);
327   pBuilder->SetCheckInverted(BOPTest_Objects::CheckInverted());
328   pBuilder->SetToFillHistory(BRepTest_Objects::IsHistoryNeeded());
329   //
330   OSD_Timer aTimer;
331   aTimer.Start();
332   //
333   pBuilder->PerformWithFiller(aPF);
334   BOPTest::ReportAlerts(pBuilder->GetReport());
335
336   // Set history of Boolean operation into the session
337   if (BRepTest_Objects::IsHistoryNeeded())
338     BRepTest_Objects::SetHistory(aPF.Arguments(), *pBuilder);
339
340   if (pBuilder->HasErrors()) {
341     return 0;
342   }
343   //
344   aTimer.Stop();
345   //
346   if (bShowTime) {
347     Sprintf(buf, "  Tps: %7.2lf\n", aTimer.ElapsedTime());
348     di << buf;
349   }
350   //
351   const TopoDS_Shape& aR=pBuilder->Shape();
352   if (aR.IsNull()) {
353     di << " null shape\n";
354     return 0;
355   }
356   //
357   BOPTest_Objects::SetBuilder(pBuilder);
358   //
359   DBRep::Set(a[1], aR);
360   return 0;
361 }
362
363 //=======================================================================
364 //function : bsplit
365 //purpose  : 
366 //=======================================================================
367 Standard_Integer bsplit(Draw_Interpretor& di,
368                         Standard_Integer n,
369                         const char** a)
370
371   if (n < 2) {
372     di << " use bsplit r [-t (show time)]\n";
373     return 1;
374   }
375   //
376   BOPDS_PDS pDS = BOPTest_Objects::PDS();
377   if (!pDS) {
378     di << " prepare PaveFiller first\n";
379     return 0;
380   }
381   //
382   BOPAlgo_PaveFiller& aPF = BOPTest_Objects::PaveFiller();
383   //
384   BOPAlgo_Splitter* pSplitter = &BOPTest_Objects::Splitter();
385   pSplitter->Clear();
386   //
387   // set objects
388   const TopTools_ListOfShape& aLSObjects = BOPTest_Objects::Shapes();
389   pSplitter->SetArguments(aLSObjects);
390   //
391   // set tools
392   TopTools_ListOfShape& aLSTools = BOPTest_Objects::Tools();
393   pSplitter->SetTools(aLSTools);
394   //
395   // set options
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());
401   //
402   // measure the time of the operation
403   OSD_Timer aTimer;
404   aTimer.Start();
405   //
406   // perform the operation
407   pSplitter->PerformWithFiller(aPF);
408   //
409   aTimer.Stop();
410   BOPTest::ReportAlerts(pSplitter->GetReport());
411
412   // Set history of Split operation into the session
413   if (BRepTest_Objects::IsHistoryNeeded())
414     BRepTest_Objects::SetHistory(aPF.Arguments(), *pSplitter);
415
416   if (pSplitter->HasErrors()) {
417     return 0;
418   }
419   //
420   // show time if necessary
421   if (n == 3 && !strcmp(a[2], "-t")) {
422     char buf[20];
423     Sprintf(buf, "  Tps: %7.2lf\n", aTimer.ElapsedTime());
424     di << buf;
425   }
426   //
427   // Debug commands support
428   BOPTest_Objects::SetBuilder(pSplitter);
429   //
430   const TopoDS_Shape& aR = pSplitter->Shape();
431   if (aR.IsNull()) {
432     di << " null shape\n";
433     return 0;
434   }
435   //
436   DBRep::Set(a[1], aR);
437   return 0;
438 }
439
440 //=======================================================================
441 //function : buildbop
442 //purpose  : 
443 //=======================================================================
444 Standard_Integer buildbop(Draw_Interpretor& di,
445                           Standard_Integer n,
446                           const char** a)
447 {
448   if (n < 3)
449   {
450     di.PrintHelp(a[0]);
451     return 1;
452   }
453
454   BOPDS_PDS pDS = BOPTest_Objects::PDS();
455   if (!pDS)
456   {
457     di << "Error: perform intersection of arguments first";
458     return 1;
459   }
460
461   BOPAlgo_Builder *pBuilder = &BOPTest_Objects::Builder();
462   if (pBuilder->HasErrors())
463   {
464     di << "Error: there were problems during GF";
465     return 0;
466   }
467
468   if (pBuilder->Arguments().IsEmpty() ||
469       pBuilder->Shape().IsNull())
470   {
471     di << "Error: it seems the GF has not been yet performed";
472     return 1;
473   }
474
475   // Get arguments and operation
476   TopTools_ListOfShape aLObjects, aLTools;
477   BOPAlgo_Operation anOp = BOPAlgo_UNKNOWN;
478
479   for (Standard_Integer i = 2; i < n; ++i)
480   {
481     if (!strcmp(a[i], "-o") || !strcmp(a[i], "-t"))
482     {
483       if (i == (n - 1))
484       {
485         di << "Error: shapes are expected after the key " << a[i];
486         return 1;
487       }
488
489       TopTools_ListOfShape& aList = !strcmp(a[i], "-o") ? aLObjects : aLTools;
490       Standard_Integer j = i + 1;
491       for (; j < n; ++j)
492       {
493         if (a[j][0] == '-')
494         {
495           // reached the following key
496           i = j - 1;
497           break;
498         }
499         else
500         {
501           // Get the shape
502           TopoDS_Shape aS = DBRep::Get(a[j]);
503           if (aS.IsNull())
504           {
505             di << "Error: " << a[j] << " is a null shape";
506             return 1;
507           }
508           if (aS.ShapeType() != TopAbs_SOLID)
509           {
510             di << "Error: " << a[j] << " is not a solid";
511             return 1;
512           }
513           if (pDS->Index(aS) < 0)
514           {
515             di << "Error: " << a[j] << " is not an argument of GF";
516             return 1;
517           }
518           aList.Append(aS);
519         }
520       }
521       // End of arguments is reached
522       if (j == n) break;
523     }
524     else if (!strcmp(a[i], "-op"))
525     {
526       if (i == (n - 1))
527       {
528         di << "Error: operation type is expected after the key " << a[i];
529         return 1;
530       }
531
532       ++i;
533       if (!strcasecmp(a[i], "common"))
534         anOp = BOPAlgo_COMMON;
535       else if (!strcasecmp(a[i], "fuse"))
536         anOp = BOPAlgo_FUSE;
537       else if (!strcasecmp(a[i], "cut"))
538         anOp = BOPAlgo_CUT;
539       else if (!strcasecmp(a[i], "tuc"))
540         anOp = BOPAlgo_CUT21;
541       else
542       {
543         di << "Error: unknown operation type";
544         return 1;
545       }
546     }
547     else
548     {
549       di << "Error: " << a[i] << " invalid key";
550       return 1;
551     }
552   }
553
554   if (anOp == BOPAlgo_UNKNOWN)
555   {
556     di << "Error: operation has not been specified";
557     return 1;
558   }
559
560   Standard_Boolean hasObjects = !aLObjects.IsEmpty();
561   Standard_Boolean hasTools   = !aLTools.IsEmpty();
562   if (!hasObjects && !hasTools)
563   {
564     di << "Error: no shapes are given";
565     return 1;
566   }
567
568   // Create new report for the operation
569   Handle(Message_Report) aReport = new Message_Report;
570
571   // Build specific operation
572   pBuilder->BuildBOP(aLObjects, aLTools, anOp, aReport);
573
574   // Report alerts of the operation
575   BOPTest::ReportAlerts(aReport);
576
577   if (!aReport->GetAlerts(Message_Fail).IsEmpty())
578   {
579     return 0;
580   }
581
582   // Set history of Split operation into the session
583   if (BRepTest_Objects::IsHistoryNeeded())
584     BRepTest_Objects::SetHistory(pDS->Arguments(), *pBuilder);
585
586   // Result shape
587   const TopoDS_Shape& aR = pBuilder->Shape();
588   // Draw result shape
589   DBRep::Set(a[1], aR);
590
591   return 0;
592 }