]> SALOME platform Git repositories - modules/geom.git/blob - src/NMTAlgo/NMTAlgo_Splitter.cxx
Salome HOME
Merge with version on tag OCC-V2_1_0d
[modules/geom.git] / src / NMTAlgo / NMTAlgo_Splitter.cxx
1 // File:        NMTAlgo_Splitter.cxx
2 // Created:     Thu Jan 29 17:13:03 2004
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <NMTAlgo_Splitter.ixx>
8
9 #include <Precision.hxx>
10 #include <TopAbs_Orientation.hxx>
11 #include <TopExp.hxx>
12 #include <TopExp_Explorer.hxx>
13
14 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
15 #include <TopTools_DataMapOfShapeListOfShape.hxx>
16 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
17 #include <TopTools_IndexedMapOfShape.hxx>
18 #include <TopTools_ListIteratorOfListOfShape.hxx>
19 #include <TopTools_ListOfShape.hxx>
20 #include <TopTools_MapIteratorOfMapOfShape.hxx>
21 #include <TopTools_SequenceOfShape.hxx>
22
23 #include <Geom2d_Curve.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom_Surface.hxx>
26 #include <Geom_TrimmedCurve.hxx>
27 #include <gp_Pnt.hxx>
28 #include <gp_Pnt2d.hxx>
29 #include <gp_Vec.hxx>
30
31 #include <TopoDS.hxx>
32 #include <TopoDS_Compound.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Iterator.hxx>
36 #include <TopoDS_Shell.hxx>
37 #include <TopoDS_Solid.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
40
41 #include <BRepBndLib.hxx>
42 #include <BRepClass3d_SolidClassifier.hxx>
43 #include <BRepLib.hxx>
44 #include <BRep_Tool.hxx>
45
46 #include <Extrema_ExtPC.hxx>
47 #include <GeomAdaptor_Curve.hxx>
48 #include <TopOpeBRepTool_CurveTool.hxx>
49 //
50 #include <NMTTools_DSFiller.hxx>
51 #include <NMTAlgo_Tools.hxx>
52 #include <NMTAlgo_Loop3d.hxx>
53 #include <BOP_CorrectTolerances.hxx>
54
55
56 static 
57   Standard_Boolean isClosed(const TopoDS_Shape& theShape);
58
59 //=======================================================================
60 //function : NMTAlgo_Spliter::NMTAlgo_Splitter
61 //purpose  : 
62 //=======================================================================
63   NMTAlgo_Splitter::NMTAlgo_Splitter()
64 :
65   NMTAlgo_Builder()
66 {
67   myErrorStatus=0;
68 }
69 //=======================================================================
70 // function: ~NMTAlgo_Splitter
71 // purpose: 
72 //=======================================================================
73   NMTAlgo_Splitter::~NMTAlgo_Splitter()
74 {
75   Clear();
76   
77   if (myDSFiller){
78     delete myDSFiller;
79   }
80 }
81 //=======================================================================
82 // function: SourceShapes
83 // purpose: 
84 //=======================================================================
85   const TopTools_ListOfShape& NMTAlgo_Splitter::SourceShapes()const
86 {
87   return mySourceShapes;
88 }
89 //=======================================================================
90 //function : Clear
91 //purpose  : 
92 //=======================================================================
93   void NMTAlgo_Splitter::Clear()
94 {
95   NMTAlgo_Builder::Clear();
96   //
97   myListShapes.Clear();
98   myMapFaces.Clear();
99   myMapTools.Clear();
100   myClosedShapes.Clear();
101   myEqualEdges.Clear();
102   myNewSection.Clear();
103   myWrappingSolid.Clear();
104   myFaceShapeMap.Clear();
105   myInternalFaces.Clear();
106   myIntNotClFaces.Clear();
107   //
108   myImageShape.Clear();
109   myAddedFacesMap.Clear();
110   //
111   myDoneStep = TopAbs_SHAPE;
112   myIsComputed=Standard_False;
113   mySourceShapes.Clear();
114   myObjShapes.Clear();
115   myToolShapes.Clear();
116   myMapSIFC.Clear();
117   myErrorStatus=0;
118 }
119 //=======================================================================
120 //function : AddShape
121 //purpose  : add object Shape to be splited
122 //=======================================================================
123   void NMTAlgo_Splitter::AddShape(const TopoDS_Shape& aS)
124 {
125   myErrorStatus=0;
126   if (myIsComputed) {
127     // DS is already computed
128     myErrorStatus=100;
129     return;
130   }
131   //
132   if (aS.IsNull()){
133     // Null shape is not allowed here
134     myErrorStatus=101;
135     return;
136   }
137   //
138   TopAbs_ShapeEnum aType=aS.ShapeType(); 
139   //
140   if (aType < TopAbs_SOLID) { 
141     // compound or compsolid
142     TopoDS_Iterator it (aS);
143     for (; it.More(); it.Next()) {
144       const TopoDS_Shape& aSS=it.Value();
145       AddShape(aSS);
146       // to know compound by shape
147       myFaceShapeMap.Bind(aSS, aS); 
148     }
149     return;
150   }
151   //---
152   myObjShapes.Add(aS);
153   mySourceShapes.Append(aS);  
154   //---
155   //
156   TopExp_Explorer exp(aS, TopAbs_FACE);
157   if (!exp.More()) { 
158     // do not split edges and vertices
159     return;
160   }
161   // not to add twice the same S
162   Standard_Integer nbFacesBefore = myMapFaces.Extent(); 
163   //
164   for (; exp.More(); exp.Next()) {
165     const TopoDS_Shape& aFace = exp.Current();
166     if (!myFaceShapeMap.IsBound(aFace)) {
167       // keep shape of tool face added as object
168       myFaceShapeMap.Bind(aFace, aS);
169     }
170     if (myMapFaces.Add(aFace)){
171       myImagesFaces.SetRoot(aFace);
172     }
173   }
174   //
175   if (nbFacesBefore == myMapFaces.Extent()){
176     return;
177   }
178   // solids must be processed before all
179   if (aType==TopAbs_SOLID){
180     myListShapes.Prepend(aS);
181   }
182   else{
183     myListShapes.Append(aS);
184   }
185   if (isClosed(aS)){
186     myClosedShapes.Add(aS);
187   }
188 }
189 //=======================================================================
190 //function : AddTool
191 //purpose  : add cutting tool that will _NOT_ be in result
192 //=======================================================================
193   void NMTAlgo_Splitter::AddTool(const TopoDS_Shape& aS)
194 {
195   myErrorStatus=0;
196   if (myIsComputed) {
197     // DS is already computed
198     myErrorStatus=100;
199     return;
200   }
201   //
202   if (aS.IsNull()){
203     // Null shape is not allowed here
204     myErrorStatus=101;
205     return;
206   }
207   //
208   TopAbs_ShapeEnum aType=aS.ShapeType(); 
209   
210   if (aType < TopAbs_SOLID) { // compound or compsolid
211     TopoDS_Iterator it (aS);
212     for (; it.More(); it.Next()) {
213       const TopoDS_Shape& aSS=it.Value();
214       AddTool(aSS);
215       myFaceShapeMap.Bind(aSS, aS); // to know compound by shape
216     }
217     return;
218   }
219   //---
220   myToolShapes.Add(aS);
221   mySourceShapes.Append(aS);  
222   //---
223   //
224   TopExp_Explorer exp(aS, TopAbs_FACE);
225   for (; exp.More(); exp.Next()) {
226     const TopoDS_Shape& aFace = exp.Current();
227     myMapTools.Add(aFace);
228     myFaceShapeMap.Bind(aFace, aS);
229   }
230   //
231   // solids must be processed before all
232   if (aType==TopAbs_SOLID){
233     myListShapes.Prepend(aS);
234   }
235   else{
236     myListShapes.Append(aS);
237   }
238   //
239   if (isClosed(aS)) { 
240     myClosedShapes.Add(aS);
241   }
242 }
243 //=======================================================================
244 // function: Compute
245 // purpose: 
246 //=======================================================================
247   void NMTAlgo_Splitter::Compute()
248 {
249   if (!mySourceShapes.Extent()){
250     // No source shapes to treat
251     myErrorStatus=103; 
252     return;
253   }
254   //
255   BRep_Builder aBB;
256   TopoDS_Compound aCS;
257   TopTools_ListIteratorOfListOfShape aIt;
258   //
259   aBB.MakeCompound(aCS);
260   //
261   aIt.Initialize(mySourceShapes);
262   for (; aIt.More(); aIt.Next()) {
263     const TopoDS_Shape& aS=aIt.Value();
264     aBB.Add(aCS, aS);
265   }
266   //
267   NMTTools_DSFiller* pDSF=new NMTTools_DSFiller;
268   //
269   pDSF->SetCompositeShape(aCS);
270   pDSF->Perform();
271   //
272   myIsComputed=Standard_False;
273   //
274   NMTAlgo_Splitter::ComputeWithFiller(*pDSF);
275 }
276 //=======================================================================
277 // function: ComputeWithFiller
278 // purpose: 
279 //=======================================================================
280   void NMTAlgo_Splitter::ComputeWithFiller(const NMTTools_DSFiller& aDSF)
281 {
282   myErrorStatus=0;
283   //
284   if (myIsComputed) {
285     // DS is already computed
286     myErrorStatus=100; 
287     return;
288   }
289   //
290   if (!mySourceShapes.Extent()){
291     // No source shapes to treat
292     myErrorStatus=103; 
293     return;
294   }
295   //
296   NMTAlgo_Builder::ComputeWithFiller(aDSF);
297   //
298   myIsComputed=Standard_True;
299 }
300 //=======================================================================
301 //function : Build
302 //purpose  :
303 //=======================================================================
304   void NMTAlgo_Splitter::Build(const TopAbs_ShapeEnum aLimit)
305 {
306   myErrorStatus=0;
307   myLimit=aLimit;
308   //
309   if (!myIsComputed){
310     myErrorStatus=102;// DS is not computed
311     return;
312   }
313   //
314   TopoDS_Compound aCShape;
315   //
316   myBuilder.MakeCompound(aCShape);
317   myShape=aCShape;
318   //
319   // 1. VERTEX
320   //
321   if (myLimit==TopAbs_VERTEX) {
322     SplitVertices();
323     FillResult();
324     return;
325   }
326   //
327   // 2. EDGE
328   if (myLimit==TopAbs_EDGE) {
329     SplitsAndSections();
330     FillResult();
331     return;
332   }
333   //
334   // 3. WIRE
335   FillImageShape();
336   //
337   if (myLimit==TopAbs_WIRE) {
338     SplittedWires();
339     FillResult();
340     return;
341   }
342   //
343   // 4. FACE
344   //
345   if (myLimit==TopAbs_FACE) {
346     SplittedFaces();
347     FillResult();
348     return;
349   }
350   //
351   // 5.6. SHELL / SOLID
352   ShellsAndSolids();
353   BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
354 }
355 //=======================================================================
356 // function: SplitsAndSections
357 // purpose: 
358 //=======================================================================
359   void NMTAlgo_Splitter::SplitsAndSections()
360 {
361   Standard_Integer i, aNbE, aNbF;
362   TopTools_ListIteratorOfListOfShape aItLS, aIt;
363   TopTools_IndexedMapOfShape aME, aMF;
364   //
365   myQueryShapes.Clear();
366   //
367   //  1. Splits / no splits
368   aItLS.Initialize(myListShapes);
369   for ( ;aItLS.More(); aItLS.Next()) {
370     const TopoDS_Shape& aS=aItLS.Value();
371     //
372     if (myToolShapes.Contains(aS)) {
373       continue; // skip tool Shapes
374     }
375     //
376     TopExp::MapShapes(aS, TopAbs_EDGE, aME);
377     TopExp::MapShapes(aS, TopAbs_FACE, aMF);
378   }    
379   //
380   //  1. Splits / no splits
381   aNbE=aME.Extent();
382   for (i=1; i<=aNbE; ++i) {
383     const TopoDS_Shape& aE=aME(i);
384     //
385     if (!myImagesEdges.HasImage(aE)) {
386       myQueryShapes.Add(aE);
387     }
388     else {
389       const TopTools_ListOfShape& aLSp=myImagesEdges.Image(aE);
390       //
391       aIt.Initialize(aLSp);
392       for (; aIt.More(); aIt.Next()) { 
393         const TopoDS_Shape& aSp=aIt.Value();
394         myQueryShapes.Add(aSp);
395       }
396     }
397   }
398   //
399   // 2. Sections
400   aNbF=aMF.Extent();
401   for (i=1; i<=aNbF; ++i) {
402     const TopoDS_Shape& aF=aMF(i);
403     if (mySectionParts.Contains(aF)) {
404       const TopTools_ListOfShape& aLSc=mySectionParts.FindFromKey(aF);
405       aIt.Initialize(aLSc);
406       for (; aIt.More(); aIt.Next()) { 
407         const TopoDS_Shape& aSc=aIt.Value();
408         myQueryShapes.Add(aSc);
409       }
410     }
411   }
412 }
413 //=======================================================================
414 // function: SplittedWires
415 // purpose: 
416 //=======================================================================
417   void NMTAlgo_Splitter::SplittedWires()
418 {
419   Standard_Integer i, aNbF;
420   TopoDS_Iterator aIt;
421   TopTools_IndexedMapOfShape aMF;
422   //
423   SplittedFaces();
424   //
425   aMF=myQueryShapes;
426   myQueryShapes.Clear();
427   //
428   aNbF=aMF.Extent();
429   for (i=1; i<=aNbF; ++i) {
430     const TopoDS_Shape& aF=aMF(i);
431     aIt.Initialize(aF);
432     for (; aIt.More(); aIt.Next()) {
433       const TopoDS_Shape& aW=aIt.Value();
434       myQueryShapes.Add(aW);
435     }
436   }
437 }
438 //=======================================================================
439 // function: SplittedFaces
440 // purpose: 
441 //=======================================================================
442   void NMTAlgo_Splitter::SplittedFaces()
443 {
444   TopTools_ListIteratorOfListOfShape aIt;
445   TopoDS_Iterator aItF;
446   //
447   myQueryShapes.Clear();
448   //
449   aIt.Initialize(myListShapes);
450   for (; aIt.More(); aIt.Next()) {
451     const TopoDS_Shape& aS=aIt.Value();
452     //
453     if (myToolShapes.Contains(aS)) {
454       continue;
455     }
456     //
457     const TopoDS_Shape& aFC = myImageShape.Image(aS).First();
458     aItF.Initialize(aFC);
459     for (; aItF.More(); aItF.Next()) {
460       const TopoDS_Shape& aF=aItF.Value();
461       myQueryShapes.Add(aF);
462     }
463   }
464 }
465 //=======================================================================
466 //function : FillImageShape
467 //purpose  :
468 //=======================================================================
469   void NMTAlgo_Splitter::FillImageShape()
470 {
471   Standard_Integer i, aNbF, iSense;
472   TopTools_ListIteratorOfListOfShape aItS, aItFI;
473   TopExp_Explorer aExp;
474   TopAbs_Orientation aOriFS; 
475   TopoDS_Face aFIx;
476   BRep_Builder aBB;
477   //
478   myImageShape.Clear();
479   //
480   aItS.Initialize(myListShapes);
481   for ( ;aItS.More(); aItS.Next()) {
482     const TopoDS_Shape& aS=aItS.Value();
483     //
484     myQueryShapes.Clear();
485     //
486     aExp.Init(aS, TopAbs_FACE);
487     for (; aExp.More(); aExp.Next()) {
488       const TopoDS_Face& aFS=TopoDS::Face(aExp.Current());
489       aOriFS= aFS.Orientation();
490       //
491       if (!myImagesFaces.HasImage(aFS)) {
492         myQueryShapes.Add(aFS);
493         continue;
494       }
495       //
496       const TopTools_ListOfShape& aLFI=myImagesFaces.Image(aFS);
497       aItFI.Initialize(aLFI);
498       for (; aItFI.More(); aItFI.Next()) {
499         const TopoDS_Face& aFI=TopoDS::Face(aItFI.Value());
500         aFIx=aFI;
501         aFIx.Orientation(aOriFS);
502         //
503         if (mySDFaces.Contains(aFIx)) {
504           const TopoDS_Face& aFSDI=TopoDS::Face(mySDFaces.FindFromKey(aFIx));
505           TopoDS_Face aFSDIx=aFSDI;
506           //
507           iSense=NMTAlgo_Tools::Sense(aFIx, aFSDIx);
508           //
509           if (iSense < 0) {
510             aFSDIx.Reverse();
511           }
512           myQueryShapes.Add(aFSDIx);
513         }
514         else {
515           myQueryShapes.Add(aFIx);
516         }
517       }
518     }//for (; aExp.More(); aExp.Next()) {
519     //
520     TopoDS_Compound aCompound;
521     //
522     aBB.MakeCompound(aCompound);
523     //
524     aNbF=myQueryShapes.Extent();
525     for (i=1; i<=aNbF; ++i) {
526       const TopoDS_Shape& aF=myQueryShapes(i);
527       aBB.Add(aCompound, aF);
528     }
529     //
530     myImageShape.Bind(aS, aCompound);
531   }// for ( ;aItS.More(); aItS.Next())
532   //
533   myQueryShapes.Clear();
534 }
535 //=======================================================================
536 //function : FillResult
537 //purpose  :
538 //=======================================================================
539   void NMTAlgo_Splitter::FillResult()
540 {
541   Standard_Integer i, aNb;
542   //
543   aNb=myQueryShapes.Extent();
544   for (i=1; i<=aNb; ++i) {
545     const TopoDS_Shape& aS=myQueryShapes(i); 
546     myBuilder.Add (myShape, aS);
547   }
548   BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
549 }
550 //=======================================================================
551 //function : isClosed
552 //purpose  : check id a shape is closed, ie is a solid or a closed shell
553 //=======================================================================
554  Standard_Boolean isClosed(const TopoDS_Shape& theShape)
555 {
556   Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID);
557   //
558   if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) {
559     TopTools_IndexedDataMapOfShapeListOfShape MEF;
560     TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF);
561     for (Standard_Integer i=1;  isClosed && i<=MEF.Extent();  ++i)
562       isClosed = ( MEF(i).Extent() != 1 );
563   }
564   //
565   return isClosed;
566 }
567 //
568 //  myErrorStatus     
569 //
570 // 100 - DS is already computed
571 // 101 - Null shape is not allowed here
572 // 102 - DS is not computed
573 // 103 - No source shapes to treat