1b4fd285bc507fed69e9de939d7e12cce9ccabe6
[occt.git] / src / BOPTools / BOPTools_DSFiller.cxx
1 // File:        BOPTools_PoolsFiller.cxx
2 // Created:     Tue Feb 20 12:44:28 2001
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5 //
6
7 #include <BOPTools_DSFiller.ixx>
8 #include <BOPTools_PaveFiller.hxx>
9
10 #include <TopAbs_ShapeEnum.hxx>
11
12 #include <BRep_Builder.hxx>
13 #include <TopExp.hxx>
14 #include <TopExp_Explorer.hxx>
15
16 #include <TopoDS.hxx>
17 #include <TopoDS_Iterator.hxx>
18 #include <TopoDS_Shape.hxx>
19 #include <TopoDS_Wire.hxx>
20 #include <TopoDS_Shell.hxx>
21 #include <TopoDS_Solid.hxx>
22 #include <TopoDS_Edge.hxx>
23
24 #include <TopTools_ListOfShape.hxx>
25 #include <TopTools_ListIteratorOfListOfShape.hxx>
26
27 #include <BOPTools_Tools3D.hxx>
28
29 //
30 static
31         void FillList(const TopoDS_Shape& aS,
32                       Standard_Boolean& bCompSolidFound,
33                       TopTools_ListOfShape& aResultList);
34 static
35         void BuildSolid(const TopTools_ListOfShape& aRL, TopoDS_Shape& aS);
36 static
37         void BuildShell(const TopTools_ListOfShape& aRL, TopoDS_Shape& aS);
38 static
39         void BuildWire (const TopTools_ListOfShape& aRL, TopoDS_Shape& aS);
40 static
41   TopAbs_ShapeEnum GetTypeCurrent(const TopAbs_ShapeEnum aTypeX);
42
43 // static
44 //        Standard_Integer TreatCompound(const TopoDS_Shape& aS,
45 //                                    TopoDS_Shape& aShapeResult);
46
47 // Peter KURNEV
48 // p-kurnev@opencascade.com
49 //=======================================================================
50 // function: BOPTools_PoolsFiller
51 // purpose: 
52 //=======================================================================
53   BOPTools_DSFiller::BOPTools_DSFiller() 
54 {
55   myPaveFiller=NULL;
56   myInterfPool=NULL;
57   myDS=NULL;
58   myNewFiller=Standard_True;
59   myIsDone=Standard_False;
60 }
61 //=======================================================================
62 // function: Clear
63 // purpose: 
64 //=======================================================================
65   void BOPTools_DSFiller::Clear()
66 {
67   if (myPaveFiller!=NULL) {
68     delete myPaveFiller;
69   }
70   if (myInterfPool!=NULL) {
71     delete myInterfPool;
72   }
73   if (myDS!=NULL) {
74     delete myDS;
75   }
76   myPaveFiller=NULL;
77   myInterfPool=NULL;
78   myDS=NULL;
79 }
80
81 //=======================================================================
82 // function: Perform
83 // purpose: 
84 //=======================================================================
85   void BOPTools_DSFiller::Perform()
86 {
87   myIsDone=Standard_False;
88
89   if (myShape1.IsNull() || myShape2.IsNull()) {
90     return;
91   }
92   //
93   // Clear contents of the DS if it was before
94   Clear();
95   //
96   myNewFiller=Standard_True;
97   //
98   myDS        = new BooleanOperations_ShapesDataStructure (myShape1, myShape2);
99   myInterfPool= new BOPTools_InterferencePool (*myDS);
100   //
101   // Build Vertices, Paves, splits, 
102   myPaveFiller = new BOPTools_PaveFiller(*myInterfPool);
103   myPaveFiller->Perform();
104   myIsDone=myPaveFiller->IsDone();
105 }
106
107 //=======================================================================
108 // function: InitFillersAndPools
109 // purpose: 
110 //=======================================================================
111   void BOPTools_DSFiller::InitFillersAndPools()
112 {
113   myIsDone=Standard_False;
114
115   if (myShape1.IsNull() || myShape2.IsNull()) {
116     return;
117   }
118   //
119   // Clear contents of the DS if it was before
120   Clear();
121   //
122   myNewFiller=Standard_True;
123   //
124   myDS        = new BooleanOperations_ShapesDataStructure (myShape1, myShape2);
125   myInterfPool= new BOPTools_InterferencePool (*myDS);
126   //
127   myPaveFiller = new BOPTools_PaveFiller(*myInterfPool);
128 }
129
130 //=======================================================================
131 // function: PartialPerform
132 // purpose: 
133 //=======================================================================
134   void BOPTools_DSFiller::PartialPerform(const TColStd_SetOfInteger& anObjSubSet,
135                                          const TColStd_SetOfInteger& aToolSubSet)
136 {
137   myIsDone=Standard_False;
138
139   //
140   // Build Vertices, Paves, splits, 
141   myPaveFiller->PartialPerform(anObjSubSet, aToolSubSet);
142   myIsDone=myPaveFiller->IsDone();
143
144 }
145
146 //=======================================================================
147 // function: ToCompletePerform
148 // purpose: 
149 //=======================================================================
150   void BOPTools_DSFiller::ToCompletePerform()
151 {
152   if(myIsDone) {
153     myIsDone=Standard_False;
154     //
155     myPaveFiller->ToCompletePerform();
156     myIsDone=myPaveFiller->IsDone();
157     if(myIsDone) {
158       // Check if any interference exists
159       myIsDone=Standard_False;
160     
161       Standard_Integer nbs = myDS->NumberOfNewShapes();
162       if(nbs > 0) {
163         myIsDone=Standard_True;
164         return;
165       }
166       
167     }
168   }
169 }
170
171 //=======================================================================
172 // function: Perform
173 // purpose:
174 //=======================================================================
175   void BOPTools_DSFiller::Perform(const BOPTools_SSIntersectionAttribute& theSectionAttribute) 
176 {
177   myIsDone=Standard_False;
178     
179   if (myShape1.IsNull() || myShape2.IsNull()) {
180     return;
181   }
182   //
183   // Clear contents of the DS if it was before
184   Clear();
185   //
186   myNewFiller=Standard_True;
187   //
188   myDS        = new BooleanOperations_ShapesDataStructure (myShape1, myShape2);
189   myInterfPool= new BOPTools_InterferencePool (*myDS);
190   //
191   // Build Vertices, Paves, splits, 
192   myPaveFiller = new BOPTools_PaveFiller(*myInterfPool, theSectionAttribute);
193   myPaveFiller->Perform();
194   myIsDone=myPaveFiller->IsDone();
195 }
196
197 //=======================================================================
198 // function:Destroy
199 // purpose:
200 //=======================================================================
201   void BOPTools_DSFiller::Destroy() 
202 {
203   Clear();
204 }
205
206 //=======================================================================
207 // function: SetShapes
208 // purpose: 
209 //=======================================================================
210   void BOPTools_DSFiller::SetShapes (const TopoDS_Shape& aS1,
211                                      const TopoDS_Shape& aS2)
212 {
213   myShape1=aS1;
214   myShape2=aS2;
215   //
216   Standard_Integer aNbShapes;
217   TopAbs_ShapeEnum aT1, aT2;
218   aT1=aS1.ShapeType();
219   aT2=aS2.ShapeType();
220   //
221   if (aT1==TopAbs_COMPOUND || aT2==TopAbs_COMPOUND) {
222     Standard_Boolean bIsEmptyShape1, bIsEmptyShape2;
223    
224     bIsEmptyShape1=BOPTools_Tools3D::IsEmptyShape(myShape1);
225     bIsEmptyShape2=BOPTools_Tools3D::IsEmptyShape(myShape2);
226     if (bIsEmptyShape1 || bIsEmptyShape2) {
227       myIsDone=Standard_True;
228       return;
229     }
230   }
231   //
232   // 1.1
233   TopoDS_Iterator anIt;
234   TopoDS_Shape aSTmp;
235
236   if (aT1==TopAbs_COMPOUND || aT1==TopAbs_COMPSOLID) {
237     aNbShapes=0;
238     anIt.Initialize(aS1);
239     for (; anIt.More(); anIt.Next()) {
240       if (!aNbShapes) {
241         aSTmp=anIt.Value();
242       }
243       aNbShapes++;
244       if (aNbShapes>1) {
245         break;
246       }
247     }
248     //
249     if (aT1==TopAbs_COMPOUND) {
250       if (aNbShapes==1) {
251         TreatCompound(aS1, aSTmp);
252         myShape1=aSTmp;
253         aT1=myShape1.ShapeType();
254       }
255       else if (aNbShapes>1) {
256         TreatCompound(aS1, aSTmp);
257         myShape1=aSTmp;
258         aT1=myShape1.ShapeType();
259       }
260     }
261   }
262   //
263
264   if (aT1==TopAbs_COMPOUND || aT1==TopAbs_COMPSOLID) {
265     myIsDone=Standard_False; 
266     return;
267   }
268   //
269   // 1.2 aS2
270   if (aT2==TopAbs_COMPOUND || aT2==TopAbs_COMPSOLID) {
271     aNbShapes=0;
272     anIt.Initialize(aS2);
273     for (; anIt.More(); anIt.Next()) {
274       if (!aNbShapes) {
275         aSTmp=anIt.Value();
276       }
277       aNbShapes++;
278       if (aNbShapes>1) {
279         break;
280       }
281     }
282     //
283     if (aT2==TopAbs_COMPOUND) {
284       if (aNbShapes==1) {
285         TreatCompound(aS2, aSTmp);
286         myShape2=aSTmp;
287         aT2=myShape2.ShapeType();
288       }
289       else if (aNbShapes>1) {
290         TreatCompound(aS2, aSTmp);
291         myShape2=aSTmp;
292         aT2=myShape2.ShapeType();
293       }
294     }
295   }
296   //
297   
298   if (aT2==TopAbs_COMPOUND || aT2==TopAbs_COMPSOLID) {
299     myIsDone=Standard_False; 
300     return;
301   }
302   //
303   // 2.1
304   BRep_Builder BB;
305   TopoDS_Shell aSh1, aSh2;
306   TopoDS_Wire  aW1, aW2;
307   
308   if (aT1==TopAbs_FACE) {
309     if (aT2==TopAbs_SOLID || 
310         aT2==TopAbs_SHELL || 
311         aT2==TopAbs_FACE  ||
312         aT2==TopAbs_WIRE  ||
313         aT2==TopAbs_EDGE) {
314       BB.MakeShell(aSh1);
315       BB.Add(aSh1, myShape1);
316       myShape1=aSh1;
317       aT1=TopAbs_SHELL;
318     }
319   }
320   //
321   // 2.2
322   if (aT2==TopAbs_FACE) {
323     if (aT1==TopAbs_SOLID ||
324         aT1==TopAbs_SHELL ||
325         aT1==TopAbs_WIRE  ||
326         aT1==TopAbs_EDGE) {
327       BB.MakeShell(aSh2);
328       BB.Add(aSh2, myShape2);
329       myShape2=aSh2;
330       aT2=TopAbs_SHELL;
331     }
332   }
333   // 3.1
334   if (aT1==TopAbs_EDGE) {
335     if (aT2==TopAbs_SOLID || 
336         aT2==TopAbs_SHELL ||
337         aT2==TopAbs_WIRE  ||
338         aT2==TopAbs_EDGE) {
339       BB.MakeWire (aW1);
340       BB.Add(aW1, myShape1);
341       myShape1=aW1;
342       aT1=TopAbs_WIRE;
343     }
344   }
345   // 3.2
346   if (aT2==TopAbs_EDGE) {
347     if (aT1==TopAbs_SOLID || 
348         aT1==TopAbs_SHELL ||
349         aT1==TopAbs_WIRE) {
350       BB.MakeWire (aW2);
351       BB.Add(aW2, myShape2);
352       myShape2=aW2;
353       aT2=TopAbs_WIRE;
354     }
355   }
356
357   myIsDone=Standard_True; 
358 }
359
360 //=======================================================================
361 // function: Shape1
362 // purpose: 
363 //=======================================================================
364   const TopoDS_Shape& BOPTools_DSFiller::Shape1 () const 
365 {
366   return myShape1;
367 }
368
369 //=======================================================================
370 // function: Shape2
371 // purpose: 
372 //=======================================================================
373   const TopoDS_Shape& BOPTools_DSFiller::Shape2 () const 
374 {
375   return myShape2;
376 }
377 //=======================================================================
378 // function: DS
379 // purpose: 
380 //=======================================================================
381   const BooleanOperations_ShapesDataStructure& BOPTools_DSFiller::DS () const 
382 {
383   return *myDS;
384 }
385 //=======================================================================
386 // function: InterfPool
387 // purpose: 
388 //=======================================================================
389   const BOPTools_InterferencePool& BOPTools_DSFiller::InterfPool () const
390 {
391   return *myInterfPool;
392 }
393 //=======================================================================
394 // function: PavePool
395 // purpose: 
396 //=======================================================================
397   const BOPTools_PavePool& BOPTools_DSFiller::PavePool () const 
398 {
399   return myPaveFiller->PavePool();
400 }
401
402 //=======================================================================
403 // function: CommonBlockPool
404 // purpose: 
405 //=======================================================================
406   const BOPTools_CommonBlockPool& BOPTools_DSFiller::CommonBlockPool () const 
407 {
408   return myPaveFiller->CommonBlockPool();
409 }
410
411 //=======================================================================
412 // function:  SplitShapesPool
413 // purpose: 
414 //=======================================================================
415   const BOPTools_SplitShapesPool& BOPTools_DSFiller::SplitShapesPool() const
416 {
417   return myPaveFiller->SplitShapesPool();
418 }
419
420 //=======================================================================
421 // function:  PaveFiller
422 // purpose: 
423 //=======================================================================
424   const BOPTools_PaveFiller& BOPTools_DSFiller::PaveFiller() const
425 {
426   return *myPaveFiller;
427 }
428
429 //=======================================================================
430 // function: IsNewFiller 
431 // purpose: 
432 //=======================================================================
433   Standard_Boolean BOPTools_DSFiller::IsNewFiller() const
434 {
435   return myNewFiller;
436 }
437
438
439 //=======================================================================
440 // function:  SetNewFiller
441 // purpose: 
442 //=======================================================================
443   void BOPTools_DSFiller::SetNewFiller(const Standard_Boolean aFlag) const
444 {
445   BOPTools_DSFiller* pDSFiller=(BOPTools_DSFiller*)this;
446   pDSFiller->myNewFiller=aFlag;
447 }
448 //=======================================================================
449 // function:  IsDone
450 // purpose: 
451 //=======================================================================
452   Standard_Boolean BOPTools_DSFiller::IsDone()const 
453 {
454   return myIsDone;
455 }
456 //
457 //=======================================================================
458 //function :TreatCompound
459 //purpose  : 
460 //=======================================================================
461 // Standard_Integer TreatCompound(const TopoDS_Shape& aS,
462 //                             TopoDS_Shape& aShapeResult)
463 Standard_Integer BOPTools_DSFiller::TreatCompound(const TopoDS_Shape& aS,
464                                                   TopoDS_Shape&       aShapeResult) 
465 {
466   //
467   TopAbs_ShapeEnum aType, aTypeX;
468   //
469   aType=aS.ShapeType();
470   //
471   if (aType==TopAbs_COMPSOLID) {
472     aShapeResult=aS;
473     return 1;
474   }
475   //
476   if (aType!=TopAbs_COMPOUND) {
477     // Nothing to do 
478     aShapeResult=aS;
479     return 2;
480   }
481   // 
482   // 1 Fill the list by real shapes (solids, shells, wires, edges)
483   Standard_Boolean bCompSolidFound=Standard_False;
484   TopTools_ListOfShape aRL1, aRL;
485   FillList (aS, bCompSolidFound, aRL1);
486   if (bCompSolidFound) {
487     aShapeResult=aS;
488     return 3;
489   }
490   // 2
491   // Analyse the list   and find the type
492   Standard_Integer i=0;
493   TopExp_Explorer anExp;
494   TopAbs_ShapeEnum aTypeCurrent=TopAbs_SHAPE,
495                    aType0=TopAbs_SHAPE;
496   
497   //aTypeCurrent=TopAbs_SHAPE;
498   TopTools_ListIteratorOfListOfShape anItL(aRL1);
499   for (; anItL.More(); anItL.Next(), i++) {
500     const TopoDS_Shape& aSX=anItL.Value();
501     aTypeX=aSX.ShapeType();
502     
503     aTypeCurrent=GetTypeCurrent(aTypeX);
504     
505     if (i==0) {
506       aType0=aTypeCurrent;
507       if (aType0==TopAbs_SHAPE) {
508         // Unknown shape type;
509         aShapeResult=aS;
510         return 4;
511       }
512     }
513
514     else {
515       if (aTypeCurrent!=aType0) {
516         // Heterogenous types occured;
517         aShapeResult=aS;
518         return 5;
519       }
520     }
521     // 
522     // Fill the RL
523     if (aTypeCurrent==TopAbs_SOLID) {
524       anExp.Init(aSX, TopAbs_SHELL);
525       for (; anExp.More(); anExp.Next()) {
526         const TopoDS_Shape& aSY=anExp.Current();
527         aRL.Append(aSY);
528       }
529     }
530     //
531     else if (aTypeCurrent==TopAbs_SHELL) {
532       if (aTypeX==TopAbs_FACE) {
533         aRL.Append(aSX);
534       }
535       else {
536         anExp.Init(aSX, TopAbs_FACE);
537         for (; anExp.More(); anExp.Next()) {
538           const TopoDS_Shape& aSY=anExp.Current();
539           aRL.Append(aSY);
540         }
541       }
542     }
543     //
544     else if (aTypeCurrent==TopAbs_WIRE) {
545       if (aTypeX==TopAbs_EDGE) {
546         aRL.Append(aSX);
547       }
548       else {
549         anExp.Init(aSX, TopAbs_EDGE);
550         for (; anExp.More(); anExp.Next()) {
551           const TopoDS_Shape& aSY=anExp.Current();
552           aRL.Append(aSY);
553         }
554       }
555     }
556   }
557   //
558   // Make Composite shape
559   //BRep_Builder aBB;
560   
561   if (aType0==TopAbs_SOLID) {
562     BuildSolid(aRL, aShapeResult);
563   }
564   if (aType0==TopAbs_SHELL) {
565     BuildShell(aRL, aShapeResult);
566   }
567   if (aType0==TopAbs_WIRE) {
568     BuildWire(aRL, aShapeResult);
569   }
570   //OK
571   return 0;
572 }
573 //=======================================================================
574 //function : BuildSolid
575 //purpose  : 
576 //=======================================================================
577 void BuildSolid(const TopTools_ListOfShape& aRL,
578                 TopoDS_Shape& aS)
579 {
580   BRep_Builder aBB;
581   TopoDS_Solid aSolid;
582   aBB.MakeSolid(aSolid);        
583   TopTools_ListIteratorOfListOfShape anItL;
584   anItL.Initialize(aRL);
585   for (; anItL.More(); anItL.Next()) {
586     const TopoDS_Shape& aSX=anItL.Value();
587     aBB.Add(aSolid, TopoDS::Shell(aSX));
588   }
589   aS=aSolid;
590 }
591 //=======================================================================
592 //function : BuildShell
593 //purpose  : 
594 //=======================================================================
595 void BuildShell(const TopTools_ListOfShape& aRL,
596                 TopoDS_Shape& aS)
597 {
598   BRep_Builder aBB;
599   TopoDS_Shell aShell;
600   aBB.MakeShell(aShell);        
601   TopTools_ListIteratorOfListOfShape anItL;
602   anItL.Initialize(aRL);
603   for (; anItL.More(); anItL.Next()) {
604     const TopoDS_Shape& aSX=anItL.Value();
605     aBB.Add(aShell, aSX);
606   }
607   aS=aShell;
608 }
609 //=======================================================================
610 //function : BuildWire
611 //purpose  : 
612 //=======================================================================
613 void BuildWire(const TopTools_ListOfShape& aRL,
614                TopoDS_Shape& aS)
615 {
616   BRep_Builder aBB;
617   TopoDS_Wire aWire;
618   aBB.MakeWire(aWire);  
619   TopTools_ListIteratorOfListOfShape anItL;
620   anItL.Initialize(aRL);
621   for (; anItL.More(); anItL.Next()) {
622     const TopoDS_Shape& aSX=anItL.Value();
623     aBB.Add(aWire, aSX);
624   }
625   aS=aWire;
626 }
627 //=======================================================================
628 //function :FillList
629 //purpose  : 
630 //=======================================================================
631 void FillList(const TopoDS_Shape& aS,
632               Standard_Boolean& bCompSolidFound,
633               TopTools_ListOfShape& aResultList)
634 {
635   if (bCompSolidFound) {
636     return;
637   }
638   TopAbs_ShapeEnum aTypeX;
639   TopoDS_Iterator anIt;
640   anIt.Initialize(aS);
641   for (; anIt.More(); anIt.Next()) {
642     const TopoDS_Shape& aSX=anIt.Value();
643     aTypeX=aSX.ShapeType();
644     //
645     if (aTypeX==TopAbs_COMPSOLID) {
646       bCompSolidFound=Standard_True;
647       return;
648     }
649     //
650     if (aTypeX==TopAbs_COMPOUND) {
651       FillList(aSX, bCompSolidFound, aResultList);
652       if (bCompSolidFound) {
653         return;
654       }
655     }
656     if (aTypeX!=TopAbs_COMPOUND) {
657       aResultList.Append(aSX);
658     }
659     
660   }     
661 }
662 //=======================================================================
663 //function :GetTypeCurrent
664 //purpose  : 
665 //=======================================================================
666 TopAbs_ShapeEnum  GetTypeCurrent(const TopAbs_ShapeEnum aTypeX)
667 {
668   TopAbs_ShapeEnum aTypeCurrent=TopAbs_SHAPE;
669
670   if (aTypeX==TopAbs_SOLID) {
671     aTypeCurrent=TopAbs_SOLID;
672   }
673   
674   if (aTypeX==TopAbs_SHELL || aTypeX==TopAbs_FACE ) {
675     aTypeCurrent=TopAbs_SHELL;
676   }
677
678   if (aTypeX==TopAbs_WIRE || aTypeX==TopAbs_EDGE ) {
679     aTypeCurrent=TopAbs_WIRE;
680   }
681   return aTypeCurrent;
682 }
683 //