1 // File: GEOMAlgo_ShellSolid.cxx
2 // Created: Wed Jan 12 12:49:45 2005
3 // Author: Peter KURNEV
7 #include <GEOMAlgo_ShellSolid.ixx>
9 #include <Standard_Failure.hxx>
11 #include <gp_Pnt2d.hxx>
14 #include <TopoDS_Face.hxx>
15 #include <TopoDS_Edge.hxx>
17 #include <TopoDS_Shape.hxx>
18 #include <TopoDS_Solid.hxx>
20 #include <BRep_Tool.hxx>
22 #include <TopTools_ListIteratorOfListOfShape.hxx>
23 #include <TopExp_Explorer.hxx>
25 #include <BOPTColStd_Dump.hxx>
27 #include <BRepClass3d_SolidClassifier.hxx>
29 #include <IntTools_Context.hxx>
31 #include <BooleanOperations_ShapesDataStructure.hxx>
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>
51 #include <BOPTools_SSInterference.hxx>
52 #include <TopoDS_Face.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>
69 Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
70 const TopoDS_Face& theFace2);
72 //=======================================================================
73 //function : GEOMAlgo_ShellSolid
75 //=======================================================================
76 GEOMAlgo_ShellSolid::GEOMAlgo_ShellSolid()
81 //=======================================================================
84 //=======================================================================
85 GEOMAlgo_ShellSolid::~GEOMAlgo_ShellSolid()
88 //=======================================================================
91 //=======================================================================
92 void GEOMAlgo_ShellSolid::Perform()
97 if (myDSFiller==NULL) {
101 if(!myDSFiller->IsDone()) {
106 Standard_Boolean bIsNewFiller;
108 bIsNewFiller=myDSFiller->IsNewFiller();
111 myDSFiller->SetNewFiller(!bIsNewFiller);
114 myRank=(myDSFiller->DS().Object().ShapeType()==TopAbs_SHELL) ? 1 : 2;
117 catch (Standard_Failure) {
121 //=======================================================================
124 //=======================================================================
125 void GEOMAlgo_ShellSolid::Prepare()
127 const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller();
130 BOPTools_SolidStateFiller aStateFiller(aPaveFiller);
133 // 2 Project section edges on corresp. faces -> P-Curves on edges.
134 BOPTools_PCurveMaker aPCurveMaker(aPaveFiller);
137 // 3. Degenerated Edges Processing
138 BOPTools_DEProcessor aDEProcessor(aPaveFiller);
141 // 4. Detect Same Domain Faces
144 //=================================================================================
145 // function: BuildResult
147 //=================================================================================
148 void GEOMAlgo_ShellSolid::BuildResult()
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;
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();
166 // 1. process pf non-interferring faces
168 iEnd=aDS.NumberOfShapesOfTheObject();
171 iEnd=aDS.NumberOfSourceShapes();
174 for (i=iBeg; i<=iEnd; ++i) {
175 aType=aDS.GetShapeType(i);
176 if (aType!=TopAbs_FACE) {
180 const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(i));
181 aState=aDS.GetState(i);
182 if (aState==BooleanOperations_IN) {
185 else if (aState==BooleanOperations_OUT) {
190 // 2. process pf interferred faces
191 aNbFFs=aFFs.Extent();
192 for (i=1; i<=aNbFFs; ++i) {
193 BOPTools_SSInterference& aFFi=aFFs(i);
197 iRank1=aDS.Rank(nF1);
198 nF=(iRank1==myRank) ? nF1 : nF2;
199 const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF));
201 bIsTouchCase=aFFi.IsTangentFaces();
208 // Has section edges ?
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();
221 if (aNbS) { // it has
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)) {
232 nE=aDS.ShapeIndex(aE, myRank);
233 const BOPTools_ListOfPaveBlock& aLPB=aSplitShapesPool(aDS.RefEdge(nE));
239 const BOPTools_PaveBlock& aPB=aLPB.First();
242 const TopoDS_Shape& aSp=aDS.Shape(nSp);
244 aState=aDS.GetState(nSp);
245 if (aState==BooleanOperations_IN) {
248 else if (aState==BooleanOperations_OUT) {
251 else if (aState==BooleanOperations_ON) {
255 //const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape((iRank1==myRank)? nF2 : nF1));
256 //aTol=BRep_Tool::Tolerance(aF2);
259 BOPTools_Tools3D::PointNearEdge(aE, aF1, aP2D, aP3D);
260 const TopoDS_Solid& aRefSolid=(myRank==1) ?
261 TopoDS::Solid(aDS.Tool()) : TopoDS::Solid(aDS.Object());
263 BOPTools_PaveFiller* pPF=(BOPTools_PaveFiller*)& aPaveFiller;
264 IntTools_Context& aCtx=pPF->ChangeContext();
266 BRepClass3d_SolidClassifier& aSC=aCtx.SolidClassifier(aRefSolid);
267 aSC.Perform(aP3D, aTol);
269 if (aSt==TopAbs_IN) {
272 else if (aSt==TopAbs_OUT) {
278 } //for (; anExp.More(); anExp.Next())
281 //=======================================================================
282 // function: DetectSDFaces
284 //=======================================================================
285 void GEOMAlgo_ShellSolid::DetectSDFaces()
287 const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
288 BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
289 BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
291 Standard_Boolean bFlag;
292 Standard_Integer i, aNb, nF1, nF2, iZone, aNbSps, iSenseFlag;
296 for (i=1; i<=aNb; i++) {
297 bFlag=Standard_False;
299 BOPTools_SSInterference& aFF=aFFs(i);
303 const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
304 const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
307 const BOPTools_ListOfPaveBlock& aLPB=aFF.PaveBlocks();
308 aNbSps=aLPB.Extent();
314 const BOPTools_PaveBlock& aPB=aLPB.First();
315 const TopoDS_Edge& aSpE=TopoDS::Edge(aDS.Shape(aPB.Edge()));
317 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1);
318 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2);
319 iSenseFlag=BOPTools_Tools3D::SenseFlag (aDNF1, aDNF2);
321 if (iSenseFlag==1 || iSenseFlag==-1) {
324 TopoDS_Face aF1FWD=aF1;
325 aF1FWD.Orientation (TopAbs_FORWARD);
327 BOP_WireEdgeSet aWES (aF1FWD);
328 BOP_SDFWESFiller aWESFiller(nF1, nF2, *myDSFiller);
329 aWESFiller.SetSenseFlag(iSenseFlag);
330 aWESFiller.SetOperation(BOP_COMMON);
335 const TopTools_ListOfShape& aLF=aFB.NewFaces();
338 TopTools_ListIteratorOfListOfShape anIt(aLF);
339 for (; anIt.More(); anIt.Next()) {
340 const TopoDS_Shape& aFR=anIt.Value();
342 if (aFR.ShapeType()==TopAbs_FACE) {
343 const TopoDS_Face& aFaceResult=TopoDS::Face(aFR);
345 Standard_Boolean bIsValidIn2D, bNegativeFlag;
346 bIsValidIn2D=BOPTools_Tools3D::IsValidArea (aFaceResult, bNegativeFlag);
348 if(CheckSameDomainFaceInside(aFaceResult, aF2)) {
359 aFF.SetStatesMap(aWESFiller.StatesMap());
364 aFF.SetTangentFacesFlag(bFlag);
365 aFF.SetSenseFlag (iSenseFlag);
366 }// end of for (i=1; i<=aNb; i++)
368 //=======================================================================
369 //function : CheckSameDomainFaceInside
371 //=======================================================================
372 Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
373 const TopoDS_Face& theFace2)
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);
381 TopExp_Explorer anExpE(theFace1, TopAbs_EDGE);
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;
388 aTolerance += BRep_Tool::Tolerance(theFace2);
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);
396 for(Standard_Integer i = 1; i <= nbpoints; i++, U+=adeltau) {
397 Standard_Real V = vmin + adeltav;
399 for(Standard_Integer j = 1; j <= nbpoints; j++, V+=adeltav) {
400 gp_Pnt2d aPoint(U,V);
402 if(aContext.IsPointInFace(theFace1, aPoint)) {
403 gp_Pnt aP3d = aSurface->Value(U, V);
404 aProjector.Perform(aP3d);
406 if(aProjector.IsDone()) {
408 if(aProjector.LowerDistance() > aTolerance)
409 return Standard_False;
415 return Standard_True;