1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 // This file is part of Open CASCADE Technology software library.
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
18 #include <BOPAlgo_PaveFiller.hxx>
19 #include <BOPAlgo_SectionAttribute.hxx>
20 #include <BOPCol_ListOfInteger.hxx>
21 #include <BOPDS_Curve.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPDS_FaceInfo.hxx>
24 #include <BOPDS_MapOfPaveBlock.hxx>
25 #include <BOPDS_Pave.hxx>
26 #include <BOPDS_PaveBlock.hxx>
27 #include <BOPDS_ShapeInfo.hxx>
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <Geom2d_TrimmedCurve.hxx>
34 #include <Geom2dAdaptor_Curve.hxx>
35 #include <Geom2dInt_GInter.hxx>
36 #include <gp_Lin2d.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <IntRes2d_IntersectionPoint.hxx>
40 #include <IntTools_Context.hxx>
41 #include <Precision.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Vertex.hxx>
47 void MakeSplitEdge1 (const TopoDS_Edge& aE,
48 const TopoDS_Face& aF,
49 const TopoDS_Vertex& aV1,
50 const Standard_Real aP1,
51 const TopoDS_Vertex& aV2,
52 const Standard_Real aP2,
53 TopoDS_Edge& aNewEdge);
55 //=======================================================================
56 //function : ProcessDE
58 //=======================================================================
59 void BOPAlgo_PaveFiller::ProcessDE()
61 Standard_Integer nF, aNb, nE, nV, nVSD, aNbPB;
62 Handle(NCollection_BaseAllocator) aAllocator;
63 Handle(BOPDS_PaveBlock) aPBD;
64 BOPCol_ListIteratorOfListOfInteger aItLI;
66 // 1. Find degnerated edges
67 //-----------------------------------------------------scope f
70 NCollection_BaseAllocator::CommonBaseAllocator();
71 BOPDS_ListOfPaveBlock aLPBOut(aAllocator);
73 aNb=myDS->NbSourceShapes();
74 for (nE=0; nE<aNb; ++nE) {
75 const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
76 if (aSIE.ShapeType()==TopAbs_EDGE) {
77 if (aSIE.HasFlag(nF)) {
78 const BOPDS_ShapeInfo& aSIF=myDS->ShapeInfo(nF);
79 nV=aSIE.SubShapes().First();
80 if (myDS->HasShapeSD(nV, nVSD)) {
85 if (aSIF.ShapeType() == TopAbs_FACE) {
86 // 1. Find PaveBlocks that are go through nV for nF
87 FindPaveBlocks(nV, nF, aLPBOut);
88 aNbPB=aLPBOut.Extent();
92 BOPDS_ListOfPaveBlock& aLPBD = myDS->ChangePaveBlocks(nE);
93 Standard_ASSERT_VOID(!aLPBD.IsEmpty(), "ListOfPaveBlock is unexpectedly empty");
98 FillPaves(nV, nE, nF, aLPBOut, aPBD);
100 myDS->UpdatePaveBlock(aPBD);
103 MakeSplitEdge(nE, nF);
107 if (aSIF.ShapeType() == TopAbs_EDGE) {
108 Standard_Real aTol=1.e-7;
109 Standard_Integer nEn;
111 const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
112 const TopoDS_Vertex& aVn = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
117 BB.Degenerated(aE, Standard_True);
118 BB.UpdateEdge(aE, aTol);
120 aSI.SetShapeType(TopAbs_EDGE);
122 nEn=myDS->Append(aSI);
123 BOPDS_ListOfPaveBlock& aLPBD=myDS->ChangePaveBlocks(nE);
132 //=======================================================================
133 //function : FindPaveBlocks
135 //=======================================================================
136 void BOPAlgo_PaveFiller::FindPaveBlocks(const Standard_Integer nV,
137 const Standard_Integer nF,
138 BOPDS_ListOfPaveBlock& aLPBOut)
140 Standard_Integer i, aNbPBOn, aNbPBIn, aNbPBSc, nV1, nV2;
142 const BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
144 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
145 aNbPBIn = aMPBIn.Extent();
146 for (i = 1; i <= aNbPBIn; ++i) {
147 const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(i);
148 aPB->Indices(nV1, nV2);
149 if (nV==nV1 || nV==nV2) {
154 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
155 aNbPBOn = aMPBOn.Extent();
156 for (i = 1; i <= aNbPBOn; ++i) {
157 const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(i);
158 aPB->Indices(nV1, nV2);
159 if (nV==nV1 || nV==nV2) {
164 const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
165 aNbPBSc = aMPBSc.Extent();
166 for (i = 1; i <= aNbPBSc; ++i) {
167 const Handle(BOPDS_PaveBlock)& aPB = aMPBSc(i);
168 aPB->Indices(nV1, nV2);
169 if (nV==nV1 || nV==nV2) {
175 //=======================================================================
176 //function : MakeSplitEdge
178 //=======================================================================
179 void BOPAlgo_PaveFiller::MakeSplitEdge (const Standard_Integer nDE,
180 const Standard_Integer nDF)
182 Standard_Integer nSp, nV1, nV2, aNbPB;
183 Standard_Real aT1, aT2;
184 TopoDS_Edge aDE, aSp;
185 TopoDS_Vertex aV1, aV2;
186 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
189 aSI.SetShapeType(TopAbs_EDGE);
191 aDE=(*(TopoDS_Edge *)(&myDS->Shape(nDE)));
192 aDE.Orientation(TopAbs_FORWARD);
194 const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nDF)));
196 BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nDE);
199 aItLPB.Initialize(aLPB);
200 for (; aItLPB.More(); aItLPB.Next()) {
201 Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
203 const BOPDS_Pave& aPave1=aPB->Pave1();
204 aPave1.Contents(nV1, aT1);
206 const BOPDS_Pave& aPave2=aPB->Pave2();
207 aPave2.Contents(nV2, aT2);
209 if (myDS->IsNewShape(nV1) || aNbPB>1) {
210 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
211 aV1.Orientation(TopAbs_FORWARD);
213 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
214 aV2.Orientation(TopAbs_REVERSED);
216 MakeSplitEdge1(aDE, aDF, aV1, aT1, aV2, aT2, aSp);
219 nSp=myDS->Append(aSI);
223 myDS->ChangeShapeInfo(nDE).SetReference(-1);
230 //=======================================================================
231 //function : FillPaves
232 //purpose : Find all pave blocks passing through the vertex <nVD> and
233 // intersecting the 2D curve of the degenerated edge
234 // somewhere in the middle. Save intersection points into
235 // Extra paves of the pave block of degenerated edge for future
237 //=======================================================================
238 void BOPAlgo_PaveFiller::FillPaves(const Standard_Integer nVD,
239 const Standard_Integer nED,
240 const Standard_Integer nFD,
241 const BOPDS_ListOfPaveBlock& aLPBOut,
242 const Handle(BOPDS_PaveBlock)& aPBD)
244 // Prepare pave to put to pave block as an Extra pave
248 const TopoDS_Vertex& aDV = (*(TopoDS_Vertex *)(&myDS->Shape(nVD)));
249 const TopoDS_Edge& aDE = (*(TopoDS_Edge *)(&myDS->Shape(nED)));
250 const TopoDS_Face& aDF = (*(TopoDS_Face *)(&myDS->Shape(nFD)));
252 Standard_Real aTolV = BRep_Tool::Tolerance(aDV);
253 const BRepAdaptor_Surface& aBAS = myContext->SurfaceAdaptor(aDF);
255 // 2D intersection tolerance should be computed as a resolution
256 // from the tolerance of vertex to resolve the touching cases
257 Standard_Real aTolInt = Precision::PConfusion();
258 // UResolution from the tolerance of the vertex
259 Standard_Real aURes = aBAS.UResolution(aTolV);
260 // VResolution from the tolerance of the vertex
261 Standard_Real aVRes = aBAS.VResolution(aTolV);
263 aTolInt = Max(aTolInt, Max(aURes, aVRes));
265 // Parametric tolerance to compare intersection point with boundaries
266 // should be computed as a resolution from the tolerance of vertex
267 // in the direction of the 2D curve of degenerated edge
268 Standard_Real aTolCmp = Precision::PConfusion();
270 Standard_Real aTD1, aTD2;
271 Handle(Geom2d_Curve) aC2DDE = BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
272 // Get direction of the curve
273 Standard_Boolean bUDir = Abs(aC2DDE->Value(aTD1).Y() - aC2DDE->Value(aTD2).Y()) < Precision::PConfusion();
275 aTolCmp = Max(aTolCmp, (bUDir ? aURes : aVRes));
277 // Prepare adaptor for the degenerated edge for intersection
278 Geom2dAdaptor_Curve aGAC1;
279 aGAC1.Load(aC2DDE, aTD1, aTD2);
281 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBOut);
282 for (; aItLPB.More(); aItLPB.Next()) {
283 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
284 Standard_Integer nE = aPB->Edge();
288 const TopoDS_Edge& aE = (*(TopoDS_Edge *)(&myDS->Shape(nE)));
289 Standard_Real aT1, aT2;
290 Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
295 // Prepare adaptor for the passing edge for intersection
296 Geom2dAdaptor_Curve aGAC2;
298 Handle(Geom2d_Line) aL2D = Handle(Geom2d_Line)::DownCast(aC2D);
299 if (!aL2D.IsNull()) {
303 aGAC2.Load(aC2D, aT1, aT2);
306 Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInt, aTolInt);
307 if (!aGInter.IsDone()) {
311 // Analyze intersection points
312 Standard_Integer i, aNbPoints = aGInter.NbPoints();
313 for (i = 1; i <= aNbPoints; ++i) {
314 Standard_Real aX = aGInter.Point(i).ParamOnFirst();
315 if (aX - aTD1 < aTolCmp || aTD2 - aX < aTolCmp) {
319 Standard_Integer anInd;
320 if (aPBD->ContainsParameter(aX, aTolCmp, anInd)) {
324 aPave.SetParameter(aX);
325 aPBD->AppendExtPave1(aPave);
329 //=======================================================================
330 // function: MakeSplitEdge1
332 //=======================================================================
333 void MakeSplitEdge1 (const TopoDS_Edge& aE,
334 const TopoDS_Face& aF,
335 const TopoDS_Vertex& aV1,
336 const Standard_Real aP1,
337 const TopoDS_Vertex& aV2,
338 const Standard_Real aP2,
339 TopoDS_Edge& aNewEdge)
341 Standard_Real aTol=1.e-7;
350 BB.Range(E, aF, aP1, aP2);
352 BB.Degenerated(E, Standard_True);
354 BB.UpdateEdge(E, aTol);