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