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