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