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