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