Salome HOME
e7da2ac055fea44cca07d7dc80c5aa57f96380e4
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_ShellSolid.cxx
1 // File:        GEOMAlgo_ShellSolid.cxx
2 // Created:     Wed Jan 12 12:49:45 2005
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <GEOMAlgo_ShellSolid.ixx>
8
9 #include <Standard_Failure.hxx>
10
11 #include <gp_Pnt2d.hxx>
12 #include <gp_Pnt.hxx>
13 #include <gp_Dir.hxx>
14
15 #include <TopoDS.hxx>
16 #include <TopoDS_Face.hxx>
17 #include <TopoDS_Edge.hxx>
18 #include <TopoDS_Shape.hxx>
19 #include <TopoDS_Solid.hxx>
20
21 #include <BRep_Tool.hxx>
22 #include <BRepTools.hxx>
23
24 #include <TopTools_ListOfShape.hxx>
25 #include <TopTools_ListIteratorOfListOfShape.hxx>
26 #include <TopExp_Explorer.hxx>
27
28 #include <BRepClass3d_SolidClassifier.hxx>
29
30 #include <IntTools_Context.hxx>
31 #include <BOPTColStd_Dump.hxx>
32 #include <BooleanOperations_ShapesDataStructure.hxx>
33
34 #include <BOPTools_PaveFiller.hxx>
35 #include <BOPTools_SolidStateFiller.hxx>
36 #include <BOPTools_PCurveMaker.hxx>
37 #include <BOPTools_DEProcessor.hxx>
38 #include <BOPTools_InterferencePool.hxx>
39 #include <BOPTools_CArray1OfSSInterference.hxx>
40 #include <BOPTools_ListOfPaveBlock.hxx>
41 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
42 #include <BOPTools_PaveBlock.hxx>
43 #include <BOPTools_SSInterference.hxx>
44 #include <BOPTools_SequenceOfCurves.hxx>
45 #include <BOPTools_Curve.hxx>
46 #include <BOPTools_PaveFiller.hxx>
47 #include <BOPTools_SplitShapesPool.hxx>
48 #include <BOPTools_Tools3D.hxx>
49 #include <BOPTools_DSFiller.hxx>
50
51 #include <BOP_WireEdgeSet.hxx>
52 #include <BOP_SDFWESFiller.hxx>
53 #include <BOP_FaceBuilder.hxx>
54
55 //=======================================================================
56 //function : GEOMAlgo_ShellSolid
57 //purpose  : 
58 //=======================================================================
59 GEOMAlgo_ShellSolid::GEOMAlgo_ShellSolid()
60 :
61   GEOMAlgo_ShapeSolid()
62 {
63 }
64 //=======================================================================
65 //function : ~
66 //purpose  : 
67 //=======================================================================
68 GEOMAlgo_ShellSolid::~GEOMAlgo_ShellSolid()
69 {
70 }
71 //=======================================================================
72 // function: 
73 // purpose: 
74 //=======================================================================
75 void GEOMAlgo_ShellSolid::Perform() 
76 {
77   myErrorStatus=0;
78   //
79   try {
80     if (myDSFiller==NULL) {
81       myErrorStatus=10;
82       return;
83     }
84     if(!myDSFiller->IsDone()) {
85       myErrorStatus=11;
86       return;
87     }
88     //
89     Standard_Boolean bIsNewFiller;
90     //
91     bIsNewFiller=myDSFiller->IsNewFiller();
92     if (bIsNewFiller) {
93       Prepare();
94       myDSFiller->SetNewFiller(!bIsNewFiller);
95     }
96     //
97     myRank=(myDSFiller->DS().Object().ShapeType()==TopAbs_SHELL) ? 1 : 2;
98     BuildResult();
99   }
100   catch (Standard_Failure) {
101     myErrorStatus=12;
102   }
103 }
104 //=======================================================================
105 // function: Prepare
106 // purpose: 
107 //=======================================================================
108 void GEOMAlgo_ShellSolid::Prepare() 
109 {
110   const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller();
111   // 
112   // 1 States
113   BOPTools_SolidStateFiller aStateFiller(aPaveFiller);
114   aStateFiller.Do();
115   //
116   // 2 Project section edges on corresp. faces -> P-Curves on edges.
117   BOPTools_PCurveMaker aPCurveMaker(aPaveFiller);
118   aPCurveMaker.Do();
119   //
120   // 3. Degenerated Edges Processing
121   BOPTools_DEProcessor aDEProcessor(aPaveFiller);
122   aDEProcessor.Do();
123   //
124   // 4. Detect Same Domain Faces
125   DetectSDFaces();
126 }
127 //=================================================================================
128 // function: BuildResult
129 // purpose: 
130 //=================================================================================
131 void GEOMAlgo_ShellSolid::BuildResult() 
132 {
133   Standard_Boolean bIsTouchCase;
134   Standard_Integer i, j, nF1, nF2, aNbFFs, aNbS, aNbCurves, nSp, iRank1;
135   Standard_Integer nE, nF, aNbPB, iBeg, iEnd;
136   BooleanOperations_StateOfShape aState;
137   TopExp_Explorer anExp;
138   TopAbs_ShapeEnum aType;
139   gp_Pnt2d aP2D;
140   gp_Pnt aP3D;
141   //
142   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
143   const BOPTools_InterferencePool& anInterfPool=myDSFiller->InterfPool();
144   BOPTools_InterferencePool* pInterfPool=(BOPTools_InterferencePool*) &anInterfPool;
145   BOPTools_CArray1OfSSInterference& aFFs=pInterfPool->SSInterferences();
146   const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller();
147   const BOPTools_SplitShapesPool& aSplitShapesPool=aPaveFiller.SplitShapesPool();
148   //
149   // 1. process pf non-interferring faces
150   iBeg=1;
151   iEnd=aDS.NumberOfShapesOfTheObject();
152   if (myRank==2) {
153     iBeg=iEnd+1;
154     iEnd=aDS.NumberOfSourceShapes();
155   }
156   //
157   for (i=iBeg; i<=iEnd; ++i) {
158     aType=aDS.GetShapeType(i);
159     if (aType!=TopAbs_FACE) {
160       continue;
161     }
162     //
163     const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(i));
164     aState=aDS.GetState(i);
165     if (aState==BooleanOperations_IN) {
166       myLSIN.Append(aF1);
167     }
168     else if (aState==BooleanOperations_OUT) {
169       myLSOUT.Append(aF1);
170     }
171   }
172   //
173   // 2. process pf interferred faces
174   aNbFFs=aFFs.Extent();
175   for (i=1; i<=aNbFFs; ++i) {
176     BOPTools_SSInterference& aFFi=aFFs(i);
177     //
178     nF1=aFFi.Index1();
179     nF2=aFFi.Index2();
180     iRank1=aDS.Rank(nF1);
181     nF=(iRank1==myRank) ? nF1 : nF2;
182     const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF));
183     //
184     bIsTouchCase=aFFi.IsTangentFaces();
185     //
186     if (bIsTouchCase) {
187       myLSON.Append(aF1);
188       continue;
189     }
190     //
191     // Has section edges ?
192     aNbS=0;
193     BOPTools_SequenceOfCurves& aBCurves=aFFi.Curves();
194     aNbCurves=aBCurves.Length();
195     for (j=1; j<=aNbCurves; j++) {
196       BOPTools_Curve& aBC=aBCurves(j);
197       const BOPTools_ListOfPaveBlock& aSectEdges=aBC.NewPaveBlocks();
198       aNbS=aSectEdges.Extent();
199       if (aNbS) {
200         break;
201       }
202     }
203     //
204     if (aNbS) { // it has
205       continue;
206     }
207     //
208     anExp.Init(aF1, TopAbs_EDGE);
209     for (; anExp.More(); anExp.Next()) {
210       const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
211       if (BRep_Tool::Degenerated(aE)) {
212         continue;
213       }
214       //
215       nE=aDS.ShapeIndex(aE, myRank);
216       const BOPTools_ListOfPaveBlock& aLPB=aSplitShapesPool(aDS.RefEdge(nE));
217       aNbPB=aLPB.Extent();
218       //
219       if (aNbPB<2) {
220         nSp=nE;
221         if (aNbPB) {
222           const BOPTools_PaveBlock& aPB=aLPB.First();
223           nSp=aPB.Edge();
224         }
225         const TopoDS_Shape& aSp=aDS.Shape(nSp);
226         //
227         aState=aDS.GetState(nSp);
228         if (aState==BooleanOperations_IN) {
229           myLSIN.Append(aF1);
230         }
231         else if (aState==BooleanOperations_OUT) {
232           myLSOUT.Append(aF1);
233         }
234         else if (aState==BooleanOperations_ON) {
235           Standard_Real aTol;
236           TopAbs_State aSt;
237           //
238           //const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape((iRank1==myRank)? nF2 : nF1));
239           //aTol=BRep_Tool::Tolerance(aF2);
240           aTol=1.e-7;
241           //
242           BOPTools_Tools3D::PointNearEdge(aE, aF1, aP2D, aP3D);
243           const TopoDS_Solid& aRefSolid=(myRank==1) ? 
244             TopoDS::Solid(aDS.Tool()) : TopoDS::Solid(aDS.Object());
245           //
246           BOPTools_PaveFiller* pPF=(BOPTools_PaveFiller*)& aPaveFiller;
247           IntTools_Context& aCtx=pPF->ChangeContext();
248           //
249           BRepClass3d_SolidClassifier& aSC=aCtx.SolidClassifier(aRefSolid);
250           aSC.Perform(aP3D, aTol);
251           aSt=aSC.State();
252           if (aSt==TopAbs_IN) {
253             myLSIN.Append(aF1);
254           }
255           else if (aSt==TopAbs_OUT) {
256             myLSOUT.Append(aF1);
257           }
258         } 
259         break; 
260       } // if (aNbPB<2) { 
261     } //for (; anExp.More(); anExp.Next())
262   } 
263 }
264 //=======================================================================
265 // function: DetectSDFaces
266 // purpose: 
267 //=======================================================================
268 void GEOMAlgo_ShellSolid::DetectSDFaces()
269 {
270   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
271   BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
272   BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
273   //
274   Standard_Boolean bFlag;
275   Standard_Integer i, aNb, nF1, nF2,  iZone, aNbSps, iSenseFlag;
276   gp_Dir aDNF1, aDNF2;
277
278   aNb=aFFs.Extent();
279   for (i=1; i<=aNb; i++) {
280     bFlag=Standard_False;
281     
282     BOPTools_SSInterference& aFF=aFFs(i);
283     
284     nF1=aFF.Index1();
285     nF2=aFF.Index2();
286     const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
287     const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
288     //
289     // iSenseFlag;
290     const BOPTools_ListOfPaveBlock& aLPB=aFF.PaveBlocks();
291     aNbSps=aLPB.Extent();
292
293     if (!aNbSps) {
294       continue;
295     }
296     
297     const BOPTools_PaveBlock& aPB=aLPB.First();
298     const TopoDS_Edge& aSpE=TopoDS::Edge(aDS.Shape(aPB.Edge()));
299     
300     BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1); 
301     BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2);
302     iSenseFlag=BOPTools_Tools3D::SenseFlag (aDNF1, aDNF2);
303     //
304     if (iSenseFlag==1 || iSenseFlag==-1) {
305     //
306     //
307       TopoDS_Face aF1FWD=aF1;
308       aF1FWD.Orientation (TopAbs_FORWARD);
309       
310       BOP_WireEdgeSet aWES (aF1FWD);
311       BOP_SDFWESFiller aWESFiller(nF1, nF2, *myDSFiller);
312       aWESFiller.SetSenseFlag(iSenseFlag);
313       aWESFiller.SetOperation(BOP_COMMON);
314       aWESFiller.Do(aWES);
315       
316       BOP_FaceBuilder aFB;
317       aFB.Do(aWES);
318       const TopTools_ListOfShape& aLF=aFB.NewFaces();
319
320       iZone=0;
321       TopTools_ListIteratorOfListOfShape anIt(aLF);
322       for (; anIt.More(); anIt.Next()) {
323         const TopoDS_Shape& aFR=anIt.Value();
324
325         if (aFR.ShapeType()==TopAbs_FACE) {
326           const TopoDS_Face& aFaceResult=TopoDS::Face(aFR);
327           //
328           Standard_Boolean bIsValidIn2D, bNegativeFlag;
329           bIsValidIn2D=BOPTools_Tools3D::IsValidArea (aFaceResult, bNegativeFlag);
330           if (bIsValidIn2D) { 
331             //if(CheckSameDomainFaceInside(aFaceResult, aF2)) {
332             iZone=1;
333             break;
334             //}
335           }
336           //
337         }
338       }
339       
340       if (iZone) { 
341         bFlag=Standard_True;
342         aFF.SetStatesMap(aWESFiller.StatesMap());
343       }
344       
345     }// if (iSenseFlag)
346   
347   aFF.SetTangentFacesFlag(bFlag);
348   aFF.SetSenseFlag (iSenseFlag);
349   }// end of for (i=1; i<=aNb; i++) 
350 }