4e57c75e |
1 | // Created by: Peter KURNEV |
973c2be1 |
2 | // Copyright (c) 2010-2014 OPEN CASCADE SAS |
4e57c75e |
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 |
6 | // |
973c2be1 |
7 | // This file is part of Open CASCADE Technology software library. |
4e57c75e |
8 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
4e57c75e |
14 | // |
973c2be1 |
15 | // Alternatively, this file may be used under the terms of Open CASCADE |
16 | // commercial license or contractual agreement. |
4e57c75e |
17 | |
42cf5bc1 |
18 | #include <BOPAlgo_PaveFiller.hxx> |
1155d05a |
19 | #include <Bnd_Box.hxx> |
20 | #include <BOPAlgo_Alerts.hxx> |
42cf5bc1 |
21 | #include <BOPAlgo_SectionAttribute.hxx> |
22 | #include <BOPAlgo_Tools.hxx> |
42cf5bc1 |
23 | #include <BOPDS_CommonBlock.hxx> |
24 | #include <BOPDS_CoupleOfPaveBlocks.hxx> |
4e57c75e |
25 | #include <BOPDS_Curve.hxx> |
42cf5bc1 |
26 | #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx> |
27 | #include <BOPDS_DS.hxx> |
4e57c75e |
28 | #include <BOPDS_FaceInfo.hxx> |
42cf5bc1 |
29 | #include <BOPDS_Interf.hxx> |
30 | #include <BOPDS_Iterator.hxx> |
31 | #include <BOPDS_ListOfPave.hxx> |
32 | #include <BOPDS_ListOfPaveBlock.hxx> |
4e57c75e |
33 | #include <BOPDS_MapOfPaveBlock.hxx> |
34 | #include <BOPDS_PaveBlock.hxx> |
42cf5bc1 |
35 | #include <BOPDS_Point.hxx> |
36 | #include <BOPDS_ShapeInfo.hxx> |
4e57c75e |
37 | #include <BOPDS_VectorOfCurve.hxx> |
38 | #include <BOPDS_VectorOfPoint.hxx> |
42cf5bc1 |
39 | #include <BOPTools_AlgoTools.hxx> |
40 | #include <BOPTools_AlgoTools3D.hxx> |
1155d05a |
41 | #include <BOPTools_Parallel.hxx> |
42cf5bc1 |
42 | #include <BRep_Builder.hxx> |
3510db62 |
43 | #include <BRep_TEdge.hxx> |
1155d05a |
44 | #include <BRep_Tool.hxx> |
42cf5bc1 |
45 | #include <BRepAdaptor_Curve.hxx> |
46 | #include <BRepAdaptor_Surface.hxx> |
47 | #include <BRepBndLib.hxx> |
48 | #include <BRepBuilderAPI_MakeVertex.hxx> |
1155d05a |
49 | #include <BRepLib.hxx> |
42cf5bc1 |
50 | #include <BRepTools.hxx> |
42cf5bc1 |
51 | #include <Geom_Curve.hxx> |
1155d05a |
52 | #include <Geom2d_Curve.hxx> |
42cf5bc1 |
53 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
54 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
55 | #include <gp_Pnt.hxx> |
56 | #include <IntSurf_ListOfPntOn2S.hxx> |
57 | #include <IntSurf_PntOn2S.hxx> |
3510db62 |
58 | #include <IntTools.hxx> |
42cf5bc1 |
59 | #include <IntTools_Context.hxx> |
60 | #include <IntTools_Curve.hxx> |
61 | #include <IntTools_EdgeFace.hxx> |
62 | #include <IntTools_FaceFace.hxx> |
63 | #include <IntTools_PntOn2Faces.hxx> |
64 | #include <IntTools_SequenceOfCurves.hxx> |
65 | #include <IntTools_SequenceOfPntOn2Faces.hxx> |
66 | #include <IntTools_ShrunkRange.hxx> |
67 | #include <IntTools_Tools.hxx> |
1155d05a |
68 | #include <NCollection_Vector.hxx> |
42cf5bc1 |
69 | #include <Precision.hxx> |
1155d05a |
70 | #include <TColStd_ListOfInteger.hxx> |
71 | #include <TColStd_MapOfInteger.hxx> |
42cf5bc1 |
72 | #include <TopExp.hxx> |
73 | #include <TopExp_Explorer.hxx> |
3510db62 |
74 | #include <TopoDS.hxx> |
42cf5bc1 |
75 | #include <TopoDS_Compound.hxx> |
76 | #include <TopoDS_Edge.hxx> |
77 | #include <TopoDS_Face.hxx> |
78 | #include <TopoDS_Vertex.hxx> |
1155d05a |
79 | #include <TopTools_DataMapOfShapeInteger.hxx> |
80 | #include <TopTools_ListOfShape.hxx> |
4e57c75e |
81 | |
42cf5bc1 |
82 | // |
5652dc62 |
83 | static Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1, |
84 | const BRepAdaptor_Surface& aBAS2); |
4e57c75e |
85 | |
a2098360 |
86 | ///////////////////////////////////////////////////////////////////////// |
87 | //======================================================================= |
88 | //class : BOPAlgo_FaceFace |
89 | //purpose : |
90 | //======================================================================= |
36f4947b |
91 | class BOPAlgo_FaceFace : |
92 | public IntTools_FaceFace, |
93 | public BOPAlgo_Algo { |
94 | |
a2098360 |
95 | public: |
36f4947b |
96 | DEFINE_STANDARD_ALLOC |
97 | |
98 | BOPAlgo_FaceFace() : |
99 | IntTools_FaceFace(), |
100 | BOPAlgo_Algo(), |
101 | myIF1(-1), myIF2(-1), myTolFF(1.e-7) { |
a2098360 |
102 | } |
103 | // |
36f4947b |
104 | virtual ~BOPAlgo_FaceFace() { |
a2098360 |
105 | } |
106 | // |
107 | void SetIndices(const Standard_Integer nF1, |
108 | const Standard_Integer nF2) { |
109 | myIF1=nF1; |
110 | myIF2=nF2; |
111 | } |
112 | // |
113 | void Indices(Standard_Integer& nF1, |
114 | Standard_Integer& nF2) const { |
115 | nF1=myIF1; |
116 | nF2=myIF2; |
117 | } |
118 | // |
119 | void SetFaces(const TopoDS_Face& aF1, |
120 | const TopoDS_Face& aF2) { |
121 | myF1=aF1; |
122 | myF2=aF2; |
123 | } |
124 | // |
125 | const TopoDS_Face& Face1()const { |
126 | return myF1; |
127 | } |
128 | // |
129 | const TopoDS_Face& Face2()const { |
130 | return myF2; |
131 | } |
132 | // |
133 | void SetTolFF(const Standard_Real aTolFF) { |
134 | myTolFF=aTolFF; |
135 | } |
136 | // |
137 | Standard_Real TolFF() const{ |
138 | return myTolFF; |
139 | } |
140 | // |
0d0481c7 |
141 | void SetFuzzyValue(const Standard_Real theFuzz) { |
142 | IntTools_FaceFace::SetFuzzyValue(theFuzz); |
143 | } |
144 | // |
36f4947b |
145 | virtual void Perform() { |
146 | BOPAlgo_Algo::UserBreak(); |
ad8b073e |
147 | try |
148 | { |
149 | OCC_CATCH_SIGNALS |
150 | |
151 | IntTools_FaceFace::Perform(myF1, myF2); |
152 | } |
153 | catch (Standard_Failure) |
154 | { |
155 | AddError(new BOPAlgo_AlertIntersectionFailed); |
156 | } |
a2098360 |
157 | } |
158 | // |
159 | protected: |
160 | Standard_Integer myIF1; |
161 | Standard_Integer myIF2; |
162 | Standard_Real myTolFF; |
163 | TopoDS_Face myF1; |
164 | TopoDS_Face myF2; |
165 | }; |
166 | // |
167 | //======================================================================= |
1155d05a |
168 | typedef NCollection_Vector |
a2098360 |
169 | <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace; |
170 | // |
1155d05a |
171 | typedef BOPTools_Functor |
a2098360 |
172 | <BOPAlgo_FaceFace, |
173 | BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor; |
174 | // |
1155d05a |
175 | typedef BOPTools_Cnt |
a2098360 |
176 | <BOPAlgo_FaceFaceFunctor, |
177 | BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt; |
178 | ///////////////////////////////////////////////////////////////////////// |
4e57c75e |
179 | //======================================================================= |
180 | //function : PerformFF |
181 | //purpose : |
182 | //======================================================================= |
7ff8f019 |
183 | void BOPAlgo_PaveFiller::PerformFF() |
4e57c75e |
184 | { |
4e57c75e |
185 | myIterator->Initialize(TopAbs_FACE, TopAbs_FACE); |
5652dc62 |
186 | Standard_Integer iSize = myIterator->ExpectedLength(); |
4e57c75e |
187 | if (!iSize) { |
188 | return; |
189 | } |
190 | // |
5652dc62 |
191 | BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF(); |
4e57c75e |
192 | aFFs.SetIncrement(iSize); |
4e57c75e |
193 | // |
5652dc62 |
194 | // Options for the intersection algorithm |
195 | Standard_Boolean bApprox = mySectionAttribute.Approximation(), |
196 | bCompC2D1 = mySectionAttribute.PCurveOnS1(), |
197 | bCompC2D2 = mySectionAttribute.PCurveOnS2(); |
198 | Standard_Real anApproxTol = 1.e-7; |
199 | // Post-processing options |
200 | Standard_Boolean bSplitCurve = Standard_False; |
201 | // |
202 | // Fence map to store faces with updated FaceInfo structure |
1155d05a |
203 | TColStd_MapOfInteger aMIFence; |
5652dc62 |
204 | // Prepare the pairs of faces for intersection |
205 | BOPAlgo_VectorOfFaceFace aVFaceFace; |
206 | Standard_Integer nF1, nF2; |
4e57c75e |
207 | // |
208 | for (; myIterator->More(); myIterator->Next()) { |
25dfc507 |
209 | myIterator->Value(nF1, nF2); |
98b37659 |
210 | |
211 | // Update/Initialize FaceInfo structure for first face |
212 | if (myDS->HasFaceInfo(nF1)) |
213 | { |
214 | if (aMIFence.Add(nF1)) |
215 | { |
216 | myDS->UpdateFaceInfoOn(nF1); |
217 | myDS->UpdateFaceInfoIn(nF1); |
218 | } |
3510db62 |
219 | } |
98b37659 |
220 | else if (myDS->HasInterfShapeSubShapes(nF2, nF1)) |
221 | { |
222 | myDS->ChangeFaceInfo(nF1); |
223 | aMIFence.Add(nF1); |
3510db62 |
224 | } |
98b37659 |
225 | |
226 | // Update/Initialize FaceInfo structure for second face |
227 | if (myDS->HasFaceInfo(nF2)) |
228 | { |
229 | if (aMIFence.Add(nF2)) |
230 | { |
231 | myDS->UpdateFaceInfoOn(nF2); |
232 | myDS->UpdateFaceInfoIn(nF2); |
b4109929 |
233 | } |
234 | } |
98b37659 |
235 | else if (myDS->HasInterfShapeSubShapes(nF1, nF2)) |
236 | { |
237 | myDS->ChangeFaceInfo(nF2); |
238 | aMIFence.Add(nF2); |
239 | } |
b4109929 |
240 | // |
98b37659 |
241 | if (myGlue == BOPAlgo_GlueOff) |
242 | { |
243 | const TopoDS_Face& aF1 = (*(TopoDS_Face *)(&myDS->Shape(nF1))); |
244 | const TopoDS_Face& aF2 = (*(TopoDS_Face *)(&myDS->Shape(nF2))); |
245 | // |
246 | const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1); |
247 | const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2); |
248 | if (aBAS1.GetType() == GeomAbs_Plane && |
249 | aBAS2.GetType() == GeomAbs_Plane) { |
250 | // Check if the planes are really interfering |
251 | Standard_Boolean bToIntersect = CheckPlanes(nF1, nF2); |
252 | if (!bToIntersect) { |
1155d05a |
253 | BOPDS_InterfFF& aFF = aFFs.Appended(); |
98b37659 |
254 | aFF.SetIndices(nF1, nF2); |
255 | aFF.Init(0, 0); |
256 | continue; |
257 | } |
258 | } |
259 | // |
1155d05a |
260 | BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Appended(); |
483ce1bd |
261 | // |
262 | aFaceFace.SetIndices(nF1, nF2); |
263 | aFaceFace.SetFaces(aF1, aF2); |
5652dc62 |
264 | // compute minimal tolerance for the curves |
265 | Standard_Real aTolFF = ToleranceFF(aBAS1, aBAS2); |
483ce1bd |
266 | aFaceFace.SetTolFF(aTolFF); |
267 | // |
268 | IntSurf_ListOfPntOn2S aListOfPnts; |
269 | GetEFPnts(nF1, nF2, aListOfPnts); |
5652dc62 |
270 | Standard_Integer aNbLP = aListOfPnts.Extent(); |
483ce1bd |
271 | if (aNbLP) { |
272 | aFaceFace.SetList(aListOfPnts); |
273 | } |
274 | // |
5652dc62 |
275 | aFaceFace.SetParameters(bApprox, bCompC2D1, bCompC2D2, anApproxTol); |
483ce1bd |
276 | aFaceFace.SetFuzzyValue(myFuzzyValue); |
277 | aFaceFace.SetProgressIndicator(myProgressIndicator); |
278 | } |
279 | else { |
280 | // for the Glue mode just add all interferences of that type |
1155d05a |
281 | BOPDS_InterfFF& aFF = aFFs.Appended(); |
483ce1bd |
282 | aFF.SetIndices(nF1, nF2); |
483ce1bd |
283 | aFF.SetTangentFaces(Standard_False); |
284 | aFF.Init(0, 0); |
4e57c75e |
285 | } |
a2098360 |
286 | }//for (; myIterator->More(); myIterator->Next()) { |
287 | // |
a2098360 |
288 | //====================================================== |
5652dc62 |
289 | // Perform intersection |
a2098360 |
290 | BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace); |
291 | //====================================================== |
5652dc62 |
292 | // Treatment of the results |
1155d05a |
293 | Standard_Integer k, aNbFaceFace = aVFaceFace.Length(); |
5652dc62 |
294 | for (k = 0; k < aNbFaceFace; ++k) { |
295 | BOPAlgo_FaceFace& aFaceFace = aVFaceFace(k); |
a2098360 |
296 | aFaceFace.Indices(nF1, nF2); |
ad8b073e |
297 | if (!aFaceFace.IsDone() || aFaceFace.HasErrors()) { |
1155d05a |
298 | BOPDS_InterfFF& aFF = aFFs.Appended(); |
4e57c75e |
299 | aFF.SetIndices(nF1, nF2); |
5652dc62 |
300 | aFF.Init(0, 0); |
ad8b073e |
301 | // Warn about failed intersection of faces |
302 | AddIntersectionFailedWarning(aFaceFace.Face1(), aFaceFace.Face2()); |
5652dc62 |
303 | continue; |
304 | } |
305 | // |
306 | Standard_Boolean bTangentFaces = aFaceFace.TangentFaces(); |
307 | Standard_Real aTolFF = aFaceFace.TolFF(); |
308 | // |
309 | aFaceFace.PrepareLines3D(bSplitCurve); |
310 | // |
311 | const IntTools_SequenceOfCurves& aCvsX = aFaceFace.Lines(); |
312 | const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceFace.Points(); |
313 | // |
314 | Standard_Integer aNbCurves = aCvsX.Length(); |
315 | Standard_Integer aNbPoints = aPntsX.Length(); |
316 | // |
317 | if (aNbCurves || aNbPoints) { |
318 | myDS->AddInterf(nF1, nF2); |
319 | } |
320 | // |
1155d05a |
321 | BOPDS_InterfFF& aFF = aFFs.Appended(); |
5652dc62 |
322 | aFF.SetIndices(nF1, nF2); |
323 | aFF.SetTangentFaces(bTangentFaces); |
324 | aFF.Init(aNbCurves, aNbPoints); |
325 | // |
326 | // Curves |
327 | // Fix bounding box expanding coefficient. |
328 | Standard_Real aBoxExpandValue = aTolFF; |
329 | if (aNbCurves > 0) |
330 | { |
331 | // Modify geometric expanding coefficient by topology value, |
332 | // since this bounding box used in sharing (vertex or edge). |
333 | Standard_Real aMaxVertexTol = Max(BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX), |
334 | BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX)); |
335 | aBoxExpandValue += aMaxVertexTol; |
336 | } |
337 | // |
338 | BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves(); |
339 | for (Standard_Integer i = 1; i <= aNbCurves; ++i) { |
340 | Bnd_Box aBox; |
341 | const IntTools_Curve& aIC = aCvsX(i); |
342 | Standard_Boolean bIsValid = IntTools_Tools::CheckCurve(aIC, aBox); |
343 | if (bIsValid) { |
1155d05a |
344 | BOPDS_Curve& aNC = aVNC.Appended(); |
5652dc62 |
345 | aNC.SetCurve(aIC); |
346 | // make sure that the bounding box has the maximal gap |
347 | aBox.Enlarge(aBoxExpandValue); |
348 | aNC.SetBox(aBox); |
349 | aNC.SetTolerance(Max(aIC.Tolerance(), aTolFF)); |
4e57c75e |
350 | } |
5652dc62 |
351 | } |
352 | // |
353 | // Points |
354 | BOPDS_VectorOfPoint& aVNP = aFF.ChangePoints(); |
355 | for (Standard_Integer i = 1; i <= aNbPoints; ++i) { |
356 | const IntTools_PntOn2Faces& aPi = aPntsX(i); |
357 | const gp_Pnt& aP = aPi.P1().Pnt(); |
4e57c75e |
358 | // |
1155d05a |
359 | BOPDS_Point& aNP = aVNP.Appended(); |
5652dc62 |
360 | aNP.SetPnt(aP); |
4e57c75e |
361 | } |
5652dc62 |
362 | } |
4e57c75e |
363 | } |
364 | //======================================================================= |
365 | //function : MakeBlocks |
366 | //purpose : |
367 | //======================================================================= |
78c66ef1 |
368 | void BOPAlgo_PaveFiller::MakeBlocks() |
4e57c75e |
369 | { |
483ce1bd |
370 | if (myGlue != BOPAlgo_GlueOff) { |
371 | return; |
372 | } |
373 | // |
4e57c75e |
374 | BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); |
1155d05a |
375 | Standard_Integer aNbFF = aFFs.Length(); |
4e57c75e |
376 | if (!aNbFF) { |
377 | return; |
378 | } |
379 | // |
380 | Standard_Boolean bExist, bValid2D; |
381 | Standard_Integer i, nF1, nF2, aNbC, aNbP, j; |
382 | Standard_Integer nV1, nV2; |
5652dc62 |
383 | Standard_Real aT1, aT2; |
488e5b9d |
384 | Handle(NCollection_BaseAllocator) aAllocator; |
4e57c75e |
385 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB; |
386 | TopoDS_Edge aES; |
387 | Handle(BOPDS_PaveBlock) aPBOut; |
388 | // |
389 | //-----------------------------------------------------scope f |
488e5b9d |
390 | aAllocator= |
391 | NCollection_BaseAllocator::CommonBaseAllocator(); |
4e57c75e |
392 | // |
1155d05a |
393 | TColStd_ListOfInteger aLSE(aAllocator), aLBV(aAllocator); |
6f1ea0f4 |
394 | TColStd_MapOfInteger aMVOnIn(100, aAllocator), aMVCommon(100, aAllocator), |
4e57c75e |
395 | aMVStick(100,aAllocator), aMVEF(100, aAllocator), |
01b5b3df |
396 | aMI(100, aAllocator), aMVBounds(100, aAllocator); |
decdfc94 |
397 | BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator); |
0d0481c7 |
398 | BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator), aMPBCommon; |
4e57c75e |
399 | BOPDS_ListOfPaveBlock aLPB(aAllocator); |
400 | BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator); |
1155d05a |
401 | TopTools_DataMapOfShapeInteger aMVI(100, aAllocator); |
78c66ef1 |
402 | BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator); |
1155d05a |
403 | TColStd_DataMapOfIntegerReal aMVTol(100, aAllocator); |
404 | TColStd_DataMapOfIntegerInteger aDMNewSD(100, aAllocator); |
405 | TColStd_DataMapOfIntegerListOfInteger aDMVLV; |
406 | TColStd_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator); |
407 | TColStd_DataMapIteratorOfDataMapOfIntegerReal aItMV; |
408 | TopTools_IndexedMapOfShape aMicroEdges(100, aAllocator); |
409 | TopTools_IndexedMapOfShape aVertsOnRejectedPB; |
4e57c75e |
410 | // |
411 | for (i=0; i<aNbFF; ++i) { |
36f4947b |
412 | // |
413 | UserBreak(); |
414 | // |
4e57c75e |
415 | BOPDS_InterfFF& aFF=aFFs(i); |
416 | aFF.Indices(nF1, nF2); |
417 | // |
418 | BOPDS_VectorOfPoint& aVP=aFF.ChangePoints(); |
1155d05a |
419 | aNbP=aVP.Length(); |
4e57c75e |
420 | BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves(); |
1155d05a |
421 | aNbC=aVC.Length(); |
4e57c75e |
422 | if (!aNbP && !aNbC) { |
423 | continue; |
424 | } |
425 | // |
426 | const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1))); |
427 | const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2))); |
428 | // |
5652dc62 |
429 | Standard_Real aTolFF = Max(BRep_Tool::Tolerance(aF1), BRep_Tool::Tolerance(aF2)); |
3285a59a |
430 | // |
5652dc62 |
431 | BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1); |
432 | BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2); |
4e57c75e |
433 | // |
434 | aMVOnIn.Clear(); |
6f1ea0f4 |
435 | aMVCommon.Clear(); |
4e57c75e |
436 | aMPBOnIn.Clear(); |
0d0481c7 |
437 | aMPBCommon.Clear(); |
3285a59a |
438 | aDMBV.Clear(); |
b4109929 |
439 | aMVTol.Clear(); |
3f317e7d |
440 | aLSE.Clear(); |
4e57c75e |
441 | // |
6f1ea0f4 |
442 | myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMVCommon, aMPBOnIn, aMPBCommon); |
4e57c75e |
443 | myDS->SharedEdges(nF1, nF2, aLSE, aAllocator); |
32e849eb |
444 | // |
445 | Standard_Boolean bHasRealSectionEdge = Standard_False; |
4e57c75e |
446 | // 1. Treat Points |
447 | for (j=0; j<aNbP; ++j) { |
448 | TopoDS_Vertex aV; |
449 | BOPDS_CoupleOfPaveBlocks aCPB; |
450 | // |
451 | BOPDS_Point& aNP=aVP.ChangeValue(j); |
452 | const gp_Pnt& aP=aNP.Pnt(); |
453 | // |
5652dc62 |
454 | bExist=IsExistingVertex(aP, aTolFF, aMVOnIn); |
4e57c75e |
455 | if (!bExist) { |
5652dc62 |
456 | BOPTools_AlgoTools::MakeNewVertex(aP, aTolFF, aV); |
4e57c75e |
457 | // |
458 | aCPB.SetIndexInterf(i); |
459 | aCPB.SetIndex(j); |
460 | aMSCPB.Add(aV, aCPB); |
461 | } |
462 | } |
463 | // |
464 | // 2. Treat Curves |
465 | aMVStick.Clear(); |
466 | aMVEF.Clear(); |
78c66ef1 |
467 | GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI); |
4e57c75e |
468 | // |
0d0481c7 |
469 | for (j = 0; j < aNbC; ++j) { |
470 | BOPDS_Curve& aNC = aVC.ChangeValue(j); |
4e57c75e |
471 | // DEBt |
472 | aNC.InitPaveBlock1(); |
473 | // |
6f1ea0f4 |
474 | // In order to avoid problems connected with |
475 | // extending tolerance of vertex while putting |
476 | // (e.g. see "bugs modalg_6 bug26789_1" test case), |
477 | // all not-common vertices will be checked by |
478 | // BndBoxes before putting. For common-vertices, |
479 | // filtering by BndBoxes is not necessary. |
480 | PutPavesOnCurve(aMVOnIn, aMVCommon, aNC, aMI, aMVEF, aMVTol, aDMVLV); |
0d0481c7 |
481 | } |
482 | |
483 | // if some E-F vertex was put on a curve due to large E-F intersection range, |
484 | // and it also was put on another curve correctly then remove this vertex from |
485 | // the first curve. Detect such case if the distance to curve exceeds aTolR3D. |
5652dc62 |
486 | FilterPavesOnCurves(aVC); |
0d0481c7 |
487 | |
488 | for (j = 0; j<aNbC; ++j) { |
489 | BOPDS_Curve& aNC=aVC.ChangeValue(j); |
490 | const IntTools_Curve& aIC=aNC.Curve(); |
4e57c75e |
491 | // |
0d0481c7 |
492 | PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol, aDMVLV); |
7ff8f019 |
493 | //904/F7 |
4e57c75e |
494 | if (aNbC == 1) { |
0d0481c7 |
495 | PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol, aDMVLV); |
4e57c75e |
496 | } |
497 | // |
498 | if (aIC.HasBounds()) { |
3285a59a |
499 | aLBV.Clear(); |
500 | // |
5652dc62 |
501 | PutBoundPaveOnCurve(aF1, aF2, aNC, aLBV); |
3285a59a |
502 | // |
503 | if (!aLBV.IsEmpty()) { |
504 | aDMBV.Bind(j, aLBV); |
1155d05a |
505 | TColStd_ListIteratorOfListOfInteger aItI(aLBV); |
01b5b3df |
506 | for (; aItI.More(); aItI.Next()) { |
507 | aMVBounds.Add(aItI.Value()); |
508 | } |
3285a59a |
509 | } |
4e57c75e |
510 | } |
511 | }//for (j=0; j<aNbC; ++j) { |
0d0481c7 |
512 | |
4e57c75e |
513 | // Put closing pave if needed |
514 | for (j=0; j<aNbC; ++j) { |
515 | BOPDS_Curve& aNC=aVC.ChangeValue(j); |
516 | PutClosingPaveOnCurve (aNC); |
517 | } |
518 | // |
519 | // 3. Make section edges |
520 | for (j=0; j<aNbC; ++j) { |
521 | BOPDS_Curve& aNC=aVC.ChangeValue(j); |
522 | const IntTools_Curve& aIC=aNC.Curve(); |
5652dc62 |
523 | Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance()); |
4e57c75e |
524 | // |
525 | BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks(); |
526 | Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1(); |
527 | // |
528 | aLPB.Clear(); |
529 | aPB1->Update(aLPB, Standard_False); |
530 | // |
531 | aItLPB.Initialize(aLPB); |
532 | for (; aItLPB.More(); aItLPB.Next()) { |
533 | Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue(); |
534 | aPB->Indices(nV1, nV2); |
535 | aPB->Range (aT1, aT2); |
536 | // |
537 | if (fabs(aT1 - aT2) < Precision::PConfusion()) { |
538 | continue; |
539 | } |
540 | // |
465d1fba |
541 | bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC, |
542 | aF1, aF2, aTolR3D); |
4e57c75e |
543 | if (!bValid2D) { |
544 | continue; |
545 | } |
546 | // |
93e38faa |
547 | bExist=IsExistingPaveBlock(aPB, aNC, aLSE); |
4e57c75e |
548 | if (bExist) { |
549 | continue; |
550 | } |
551 | // |
01b5b3df |
552 | const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
553 | const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
554 | // |
555 | // Make Edge |
556 | BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES); |
557 | // |
558 | // check for micro edge |
559 | if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) { |
560 | // If the section edge is a micro edge, i.e. the whole edge is |
561 | // covered by the tolerance spheres of its vertices, it will be |
562 | // passed into post treatment process to fuse its vertices. |
563 | // The edge itself will not be kept. |
564 | if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) { |
565 | aMicroEdges.Add(aES); |
566 | // keep vertices for post treatment |
567 | aMVI.Bind(aV1, nV1); |
568 | aMVI.Bind(aV2, nV2); |
569 | } |
570 | continue; |
571 | } |
572 | // |
05cf4d98 |
573 | Standard_Real aTolNew; |
0d0481c7 |
574 | bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew); |
4e57c75e |
575 | if (bExist) { |
32e849eb |
576 | if (!aMPBAdd.Contains(aPBOut)) { |
4e57c75e |
577 | Standard_Boolean bInBothFaces = Standard_True; |
5a77460e |
578 | if (!myDS->IsCommonBlock(aPBOut)) { |
4e57c75e |
579 | Standard_Integer nE; |
580 | Standard_Real aTolE; |
581 | // |
582 | nE = aPBOut->Edge(); |
583 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE); |
584 | aTolE = BRep_Tool::Tolerance(aE); |
5652dc62 |
585 | if (aTolNew < aNC.Tolerance()) |
586 | aTolNew = aNC.Tolerance(); // use real tolerance of intersection |
05cf4d98 |
587 | if (aTolNew > aTolE) { |
588 | UpdateEdgeTolerance(nE, aTolNew); |
4e57c75e |
589 | } |
590 | bInBothFaces = Standard_False; |
3510db62 |
591 | } |
592 | else { |
4e57c75e |
593 | bInBothFaces = (aFI1.PaveBlocksOn().Contains(aPBOut) || |
594 | aFI1.PaveBlocksIn().Contains(aPBOut))&& |
595 | (aFI2.PaveBlocksOn().Contains(aPBOut) || |
596 | aFI2.PaveBlocksIn().Contains(aPBOut)); |
597 | } |
598 | if (!bInBothFaces) { |
32e849eb |
599 | aMPBAdd.Add(aPBOut); |
3285a59a |
600 | PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC); |
ad8b073e |
601 | // Try fusing the vertices of the existing pave block |
602 | // with the vertices put on the real section curve (except |
603 | // for technological vertices, which will be removed) |
604 | Standard_Integer nVOut1, nVOut2; |
605 | aPBOut->Indices(nVOut1, nVOut2); |
606 | if (nV1 != nVOut1 && nV1 != nVOut2 && !aMVBounds.Contains(nV1)) |
607 | { |
608 | aVertsOnRejectedPB.Add(aV1); |
609 | } |
610 | if (nV2 != nVOut1 && nV2 != nVOut2 && !aMVBounds.Contains(nV2)) |
611 | { |
612 | aVertsOnRejectedPB.Add(aV2); |
613 | } |
4e57c75e |
614 | } |
615 | } |
616 | continue; |
617 | } |
618 | // |
01b5b3df |
619 | // Make p-curves |
4e57c75e |
620 | BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC, |
621 | mySectionAttribute.PCurveOnS1(), |
51db0179 |
622 | mySectionAttribute.PCurveOnS2(), |
623 | myContext); |
4e57c75e |
624 | // |
4e57c75e |
625 | // Append the Pave Block to the Curve j |
626 | aLPBC.Append(aPB); |
627 | // |
628 | // Keep info for post treatment |
629 | BOPDS_CoupleOfPaveBlocks aCPB; |
630 | aCPB.SetIndexInterf(i); |
631 | aCPB.SetIndex(j); |
632 | aCPB.SetPaveBlock1(aPB); |
633 | // |
634 | aMSCPB.Add(aES, aCPB); |
635 | aMVI.Bind(aV1, nV1); |
636 | aMVI.Bind(aV2, nV2); |
b4109929 |
637 | // |
638 | aMVTol.UnBind(nV1); |
639 | aMVTol.UnBind(nV2); |
32e849eb |
640 | // |
641 | bHasRealSectionEdge = Standard_True; |
4e57c75e |
642 | } |
643 | // |
644 | aLPBC.RemoveFirst(); |
645 | }//for (j=0; j<aNbC; ++j) { |
0d0481c7 |
646 | // |
b4109929 |
647 | //back to previous tolerance values for unused vertices |
0d0481c7 |
648 | //and forget about SD groups of such vertices |
b4109929 |
649 | aItMV.Initialize(aMVTol); |
650 | for (; aItMV.More(); aItMV.Next()) { |
651 | nV1 = aItMV.Key(); |
0d0481c7 |
652 | Standard_Real aTol = aItMV.Value(); |
b4109929 |
653 | // |
654 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1); |
465d1fba |
655 | const Handle(BRep_TVertex)& TV = |
656 | *((Handle(BRep_TVertex)*)&aV.TShape()); |
b4109929 |
657 | TV->Tolerance(aTol); |
0d0481c7 |
658 | // reset bnd box |
659 | BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1); |
660 | Bnd_Box& aBoxDS=aSIDS.ChangeBox(); |
661 | aBoxDS = Bnd_Box(); |
662 | BRepBndLib::Add(aV, aBoxDS); |
663 | aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion()); |
664 | // |
665 | if (aDMVLV.IsBound(nV1)) |
666 | aDMVLV.UnBind(nV1); |
b4109929 |
667 | } |
668 | // |
3285a59a |
669 | ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd); |
32e849eb |
670 | // |
671 | // If the pair of faces has produced any real section edges |
672 | // it is necessary to check if these edges do not intersect |
673 | // any common IN edges of the faces. For that, all such edges |
674 | // are added for Post Treatment along with sections edges. |
675 | if (bHasRealSectionEdge) { |
676 | const BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.PaveBlocksIn(); |
677 | const BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.PaveBlocksIn(); |
678 | // |
679 | // For simplicity add all IN edges into the first set of section curves. |
680 | // These existing edges will be removed from the set on the post treatment |
681 | // stage in the UpdateFaceInfo function. |
682 | BOPDS_ListOfPaveBlock& aLPBC = aVC.ChangeValue(0).ChangePaveBlocks(); |
683 | // |
684 | Standard_Integer aNbIn1 = aMPBIn1.Extent(); |
685 | for (j = 1; j <= aNbIn1; ++j) { |
686 | const Handle(BOPDS_PaveBlock)& aPB = aMPBIn1(j); |
687 | if (aMPBIn2.Contains(aPB) && aMPBAdd.Add(aPB)) { |
688 | PreparePostTreatFF(i, 0, aPB, aMSCPB, aMVI, aLPBC); |
689 | } |
690 | } |
691 | } |
4e57c75e |
692 | }//for (i=0; i<aNbFF; ++i) { |
bfb65235 |
693 | |
694 | // Remove "micro" section edges |
695 | RemoveMicroSectionEdges(aMSCPB, aMicroEdges); |
696 | |
4e57c75e |
697 | // post treatment |
0d0481c7 |
698 | MakeSDVerticesFF(aDMVLV, aDMNewSD); |
ad8b073e |
699 | PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aVertsOnRejectedPB, aAllocator); |
33ba8565 |
700 | if (HasErrors()) { |
4e57c75e |
701 | return; |
702 | } |
3510db62 |
703 | // reduce tolerances of section edges where it is appropriate |
704 | CorrectToleranceOfSE(); |
4e57c75e |
705 | // |
706 | // update face info |
0d0481c7 |
707 | UpdateFaceInfo(aDMExEdges, aDMNewSD); |
78c66ef1 |
708 | //Update all pave blocks |
0d0481c7 |
709 | UpdatePaveBlocks(aDMNewSD); |
32e849eb |
710 | // |
711 | // Treat possible common zones by trying to put each section edge |
712 | // into all faces, not participated in creation of that edge, as IN edge |
713 | PutSEInOtherFaces(); |
714 | // |
4e57c75e |
715 | //-----------------------------------------------------scope t |
4e57c75e |
716 | aMVStick.Clear(); |
717 | aMPBOnIn.Clear(); |
718 | aMVOnIn.Clear(); |
6f1ea0f4 |
719 | aMVCommon.Clear(); |
4e57c75e |
720 | aDMExEdges.Clear(); |
78c66ef1 |
721 | aMI.Clear(); |
0d0481c7 |
722 | aDMNewSD.Clear(); |
723 | } |
724 | |
725 | //======================================================================= |
726 | //function : MakeSDVerticesFF |
727 | //purpose : |
728 | //======================================================================= |
729 | void BOPAlgo_PaveFiller::MakeSDVerticesFF |
1155d05a |
730 | (const TColStd_DataMapOfIntegerListOfInteger& theDMVLV, |
731 | TColStd_DataMapOfIntegerInteger& theDMNewSD) |
0d0481c7 |
732 | { |
733 | // Create a new SD vertex for each group of coinciding vertices |
734 | // and put new substitutions to theDMNewSD. |
1155d05a |
735 | TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItG(theDMVLV); |
0d0481c7 |
736 | for (; aItG.More(); aItG.Next()) { |
1155d05a |
737 | const TColStd_ListOfInteger& aList = aItG.Value(); |
0d0481c7 |
738 | // make SD vertices w/o creation of interfs |
739 | Standard_Integer nSD = MakeSDVertices(aList, Standard_False); |
740 | // update theDMNewSD |
1155d05a |
741 | TColStd_ListIteratorOfListOfInteger aItL(aList); |
0d0481c7 |
742 | for (; aItL.More(); aItL.Next()) { |
743 | Standard_Integer nV = aItL.Value(); |
744 | theDMNewSD.Bind(nV, nSD); |
745 | } |
746 | } |
4e57c75e |
747 | } |
748 | |
749 | //======================================================================= |
750 | //function : PostTreatFF |
751 | //purpose : |
752 | //======================================================================= |
33ba8565 |
753 | void BOPAlgo_PaveFiller::PostTreatFF |
4e57c75e |
754 | (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB, |
4e57c75e |
755 | BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges, |
1155d05a |
756 | TColStd_DataMapOfIntegerInteger& aDMNewSD, |
757 | const TopTools_IndexedMapOfShape& theMicroEdges, |
758 | const TopTools_IndexedMapOfShape& theVertsOnRejectedPB, |
7f22979e |
759 | const Handle(NCollection_BaseAllocator)& theAllocator) |
4e57c75e |
760 | { |
33ba8565 |
761 | Standard_Integer aNbS = theMSCPB.Extent(); |
4e57c75e |
762 | if (!aNbS) { |
33ba8565 |
763 | return; |
4e57c75e |
764 | } |
765 | // |
766 | Standard_Boolean bHasPaveBlocks, bOld; |
33ba8565 |
767 | Standard_Integer nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k; |
3510db62 |
768 | Standard_Integer aNbLPBx; |
4e57c75e |
769 | TopAbs_ShapeEnum aType; |
770 | TopoDS_Shape aV, aE; |
1155d05a |
771 | TopTools_ListIteratorOfListOfShape aItLS; |
4e57c75e |
772 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB; |
773 | BOPDS_PDS aPDS; |
774 | Handle(BOPDS_PaveBlock) aPB1; |
3510db62 |
775 | BOPDS_Pave aPave[2]; |
4e57c75e |
776 | BOPDS_ShapeInfo aSI; |
777 | // |
1155d05a |
778 | TopTools_ListOfShape aLS(theAllocator); |
4e57c75e |
779 | BOPAlgo_PaveFiller aPF(theAllocator); |
3510db62 |
780 | aPF.SetIsPrimary(Standard_False); |
781 | aPF.SetNonDestructive(myNonDestructive); |
4e57c75e |
782 | // |
783 | BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); |
784 | // |
01b5b3df |
785 | Standard_Integer aNbME = theMicroEdges.Extent(); |
ad8b073e |
786 | Standard_Integer aNbVOnRPB = theVertsOnRejectedPB.Extent(); |
4e57c75e |
787 | // 0 |
ad8b073e |
788 | if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0)) { |
4e57c75e |
789 | const TopoDS_Shape& aS=theMSCPB.FindKey(1); |
790 | const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1); |
4e57c75e |
791 | // |
792 | aType=aS.ShapeType(); |
793 | if (aType==TopAbs_VERTEX) { |
794 | aSI.SetShapeType(aType); |
795 | aSI.SetShape(aS); |
796 | iV=myDS->Append(aSI); |
797 | // |
798 | iX=aCPB.IndexInterf(); |
799 | iP=aCPB.Index(); |
800 | BOPDS_InterfFF& aFF=aFFs(iX); |
801 | BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints(); |
802 | BOPDS_Point& aNP=aVNP(iP); |
803 | aNP.SetIndex(iV); |
804 | } |
805 | else if (aType==TopAbs_EDGE) { |
806 | aPB1=aCPB.PaveBlock1(); |
807 | // |
808 | if (aPB1->HasEdge()) { |
809 | BOPDS_ListOfPaveBlock aLPBx; |
810 | aLPBx.Append(aPB1); |
811 | aDMExEdges.Bind(aPB1, aLPBx); |
812 | } else { |
813 | aSI.SetShapeType(aType); |
814 | aSI.SetShape(aS); |
815 | iE=myDS->Append(aSI); |
816 | // |
817 | aPB1->SetEdge(iE); |
818 | } |
819 | } |
33ba8565 |
820 | return; |
4e57c75e |
821 | } |
822 | // |
823 | // 1 prepare arguments |
1155d05a |
824 | TopTools_MapOfShape anAddedSD; |
4e57c75e |
825 | for (k=1; k<=aNbS; ++k) { |
826 | const TopoDS_Shape& aS=theMSCPB.FindKey(k); |
827 | aLS.Append(aS); |
24542bc0 |
828 | // add vertices-candidates for SD from the map aDMNewSD, |
829 | // so that they took part in fuse operation. |
830 | TopoDS_Iterator itV(aS); |
831 | for (; itV.More(); itV.Next()) |
832 | { |
833 | const TopoDS_Shape& aVer = itV.Value(); |
834 | Standard_Integer iVer = myDS->Index(aVer); |
835 | const Standard_Integer* pSD = aDMNewSD.Seek(iVer); |
836 | if (pSD) |
837 | { |
838 | const TopoDS_Shape& aVSD = myDS->Shape(*pSD); |
839 | if (anAddedSD.Add(aVSD)) |
840 | aLS.Append(aVSD); |
841 | } |
842 | } |
4e57c75e |
843 | } |
844 | // |
01b5b3df |
845 | // The section edges considered as a micro should be |
846 | // specially treated - their vertices should be united and |
847 | // the edge itself should be removed. Thus, we add only |
848 | // its vertices into operation. |
849 | // |
850 | BRep_Builder aBB; |
851 | for (k = 1; k <= aNbME; ++k) { |
79cbd2cf |
852 | const TopoDS_Edge& aEM = TopoDS::Edge(theMicroEdges(k)); |
01b5b3df |
853 | // |
6769ec6b |
854 | TopoDS_Vertex aVerts[2]; |
855 | TopExp::Vertices(aEM, aVerts[0], aVerts[1]); |
856 | for (Standard_Integer i = 0; i < 2; ++i) { |
857 | nV = myDS->Index(aVerts[i]); |
858 | const Standard_Integer* pSD = aDMNewSD.Seek(nV); |
859 | if (pSD) { |
860 | aVerts[i] = TopoDS::Vertex(myDS->Shape(*pSD)); |
861 | } |
862 | // |
863 | if (anAddedSD.Add(aVerts[i])) { |
864 | aLS.Append(aVerts[i]); |
865 | } |
866 | } |
01b5b3df |
867 | // |
6769ec6b |
868 | if (aVerts[0].IsSame(aVerts[1])) { |
869 | continue; |
870 | } |
01b5b3df |
871 | // |
872 | // make sure these vertices will be united |
6769ec6b |
873 | const gp_Pnt& aP1 = BRep_Tool::Pnt(aVerts[0]); |
874 | const gp_Pnt& aP2 = BRep_Tool::Pnt(aVerts[1]); |
01b5b3df |
875 | // |
876 | Standard_Real aDist = aP1.Distance(aP2); |
6769ec6b |
877 | Standard_Real aTolV1 = BRep_Tool::Tolerance(aVerts[0]); |
878 | Standard_Real aTolV2 = BRep_Tool::Tolerance(aVerts[1]); |
01b5b3df |
879 | // |
880 | aDist -= (aTolV1 + aTolV2); |
881 | if (aDist > 0.) { |
882 | aDist /= 2.; |
6769ec6b |
883 | aBB.UpdateVertex(aVerts[0], aTolV1 + aDist); |
884 | aBB.UpdateVertex(aVerts[1], aTolV2 + aDist); |
01b5b3df |
885 | } |
886 | } |
ad8b073e |
887 | |
888 | // Add vertices put on the real section curves to unify them with the |
889 | // vertices of the edges, by which these sections curves have been rejected |
890 | for (Standard_Integer i = 1; i <= aNbVOnRPB; ++i) |
891 | { |
892 | TopoDS_Shape aVer = theVertsOnRejectedPB(i); |
893 | Standard_Integer iVer = myDS->Index(aVer); |
894 | const Standard_Integer* pSD = aDMNewSD.Seek(iVer); |
895 | if (pSD) |
896 | aVer = myDS->Shape(*pSD); |
897 | |
898 | if (anAddedSD.Add(aVer)) |
899 | aLS.Append(aVer); |
900 | } |
01b5b3df |
901 | // |
4e57c75e |
902 | // 2 Fuse shapes |
36f4947b |
903 | aPF.SetProgressIndicator(myProgressIndicator); |
a942f2da |
904 | aPF.SetRunParallel(myRunParallel); |
4e57c75e |
905 | aPF.SetArguments(aLS); |
906 | aPF.Perform(); |
33ba8565 |
907 | if (aPF.HasErrors()) { |
908 | AddError (new BOPAlgo_AlertPostTreatFF); |
909 | return; |
4e57c75e |
910 | } |
911 | aPDS=aPF.PDS(); |
912 | // |
edfa30de |
913 | // Map to store the real tolerance of the common block |
914 | // and avoid repeated computation of it |
915 | NCollection_DataMap<Handle(BOPDS_CommonBlock), |
916 | Standard_Real, |
917 | TColStd_MapTransientHasher> aMCBTol; |
918 | // Map to avoid creation of different pave blocks for |
919 | // the same intersection edge |
920 | NCollection_DataMap<Standard_Integer, Handle(BOPDS_PaveBlock)> aMEPB; |
921 | // |
4e57c75e |
922 | aItLS.Initialize(aLS); |
923 | for (; aItLS.More(); aItLS.Next()) { |
924 | const TopoDS_Shape& aSx=aItLS.Value(); |
925 | nSx=aPDS->Index(aSx); |
926 | const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx); |
927 | // |
928 | aType=aSIx.ShapeType(); |
929 | // |
930 | if (aType==TopAbs_VERTEX) { |
01b5b3df |
931 | Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx); |
932 | // |
4e57c75e |
933 | if (aPDS->HasShapeSD(nSx, nVSD)) { |
934 | aV=aPDS->Shape(nVSD); |
935 | } |
936 | else { |
937 | aV=aSx; |
938 | } |
939 | // index of new vertex in theDS -> iV |
24542bc0 |
940 | iV = myDS->Index(aV); |
941 | if (iV < 0) { |
4e57c75e |
942 | aSI.SetShapeType(aType); |
943 | aSI.SetShape(aV); |
944 | iV=myDS->Append(aSI); |
4e57c75e |
945 | } |
01b5b3df |
946 | // |
947 | if (!bIntersectionPoint) { |
948 | // save SD connection |
24542bc0 |
949 | nSx = myDS->Index(aSx); |
0d0481c7 |
950 | aDMNewSD.Bind(nSx, iV); |
01b5b3df |
951 | myDS->AddShapeSD(nSx, iV); |
952 | } |
953 | else { |
24542bc0 |
954 | // update FF interference |
955 | const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx); |
956 | iX=aCPB.IndexInterf(); |
957 | iP=aCPB.Index(); |
958 | BOPDS_InterfFF& aFF=aFFs(iX); |
959 | BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints(); |
960 | BOPDS_Point& aNP=aVNP(iP); |
961 | aNP.SetIndex(iV); |
01b5b3df |
962 | } |
4e57c75e |
963 | }//if (aType==TopAbs_VERTEX) { |
964 | // |
965 | else if (aType==TopAbs_EDGE) { |
966 | bHasPaveBlocks=aPDS->HasPaveBlocks(nSx); |
967 | const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx); |
968 | iX=aCPB.IndexInterf(); |
969 | iC=aCPB.Index(); |
970 | aPB1=aCPB.PaveBlock1(); |
971 | // |
972 | bOld = aPB1->HasEdge(); |
973 | if (bOld) { |
974 | BOPDS_ListOfPaveBlock aLPBx; |
975 | aDMExEdges.Bind(aPB1, aLPBx); |
976 | } |
977 | // |
978 | if (!bHasPaveBlocks) { |
979 | if (bOld) { |
980 | aDMExEdges.ChangeFind(aPB1).Append(aPB1); |
1b7ae951 |
981 | } |
982 | else { |
4e57c75e |
983 | aSI.SetShapeType(aType); |
984 | aSI.SetShape(aSx); |
3510db62 |
985 | iE = myDS->Append(aSI); |
4e57c75e |
986 | // |
987 | aPB1->SetEdge(iE); |
988 | } |
989 | } |
990 | else { |
991 | BOPDS_InterfFF& aFF=aFFs(iX); |
992 | BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves(); |
993 | BOPDS_Curve& aNC=aVNC(iC); |
994 | BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks(); |
995 | // |
3510db62 |
996 | // check if edge occured to be micro edge; |
997 | // note we check not the edge aSx itself, but its image in aPDS |
998 | const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx); |
999 | aNbLPBx = aLPBx.Extent(); |
1000 | if (aPDS->HasPaveBlocks(nSx) && |
1001 | (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData()))) { |
1002 | BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC); |
1003 | for (; it.More(); it.Next()) { |
1004 | if (it.Value() == aPB1) { |
1005 | aLPBC.Remove(it); |
1006 | break; |
1007 | } |
1008 | } |
1009 | continue; |
1010 | } |
4e57c75e |
1011 | // |
1012 | if (bOld && !aNbLPBx) { |
1013 | aDMExEdges.ChangeFind(aPB1).Append(aPB1); |
1014 | continue; |
1015 | } |
1016 | // |
1017 | if (!bOld) { |
1018 | aItLPB.Initialize(aLPBC); |
1019 | for (; aItLPB.More(); aItLPB.Next()) { |
1020 | const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value(); |
1021 | if (aPBC==aPB1) { |
1022 | aLPBC.Remove(aItLPB); |
1023 | break; |
1024 | } |
4e57c75e |
1025 | } |
6769ec6b |
1026 | } |
4e57c75e |
1027 | // |
6769ec6b |
1028 | if (aNbLPBx) { |
4e57c75e |
1029 | aItLPB.Initialize(aLPBx); |
4e57c75e |
1030 | for (; aItLPB.More(); aItLPB.Next()) { |
1031 | const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value(); |
5a77460e |
1032 | const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx); |
4e57c75e |
1033 | // |
1034 | // update vertices of paves |
24542bc0 |
1035 | aPave[0] = aPBx->Pave1(); |
1036 | aPave[1] = aPBx->Pave2(); |
4e57c75e |
1037 | for (j=0; j<2; ++j) { |
3510db62 |
1038 | nV = aPave[j].Index(); |
1039 | aV = aPDS->Shape(nV); |
24542bc0 |
1040 | // index of new vertex in myDS -> iV |
1041 | iV = myDS->Index(aV); |
1042 | if (iV < 0) { |
3510db62 |
1043 | aSI.SetShapeType(TopAbs_VERTEX); |
1044 | aSI.SetShape(aV); |
1045 | iV = myDS->Append(aSI); |
4e57c75e |
1046 | } |
78c66ef1 |
1047 | const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2(); |
8ae442a8 |
1048 | if (aP1.Index() != iV) { |
1049 | if (aP1.Parameter() == aPave[j].Parameter()) { |
1050 | aDMNewSD.Bind(aP1.Index(), iV); |
1051 | myDS->AddShapeSD(aP1.Index(), iV); |
1052 | } |
1053 | else { |
1054 | // check aPDS to have the SD connection between these vertices |
1055 | const TopoDS_Shape& aVPave = myDS->Shape(aP1.Index()); |
1056 | Standard_Integer nVnewSD, nVnew = aPDS->Index(aVPave); |
1057 | if (aPDS->HasShapeSD(nVnew, nVnewSD)) { |
1058 | if (nVnewSD == nV) { |
1059 | aDMNewSD.Bind(aP1.Index(), iV); |
1060 | myDS->AddShapeSD(aP1.Index(), iV); |
1061 | } |
1062 | } |
1063 | } |
78c66ef1 |
1064 | } |
1065 | // |
4e57c75e |
1066 | aPave[j].SetIndex(iV); |
1067 | } |
1068 | // |
1069 | // add edge |
1070 | aE=aPDS->Shape(aPBRx->Edge()); |
24542bc0 |
1071 | iE = myDS->Index(aE); |
24542bc0 |
1072 | if (iE < 0) { |
4e57c75e |
1073 | aSI.SetShapeType(aType); |
1074 | aSI.SetShape(aE); |
1075 | iE=myDS->Append(aSI); |
edfa30de |
1076 | } |
1077 | // |
1078 | // update real edge tolerance according to distances in common block if any |
1079 | if (aPDS->IsCommonBlock(aPBRx)) { |
1080 | const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx); |
1081 | Standard_Real *pTol = aMCBTol.ChangeSeek(aCB); |
1082 | if (!pTol) { |
3510db62 |
1083 | Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context()); |
edfa30de |
1084 | pTol = aMCBTol.Bound(aCB, aTol); |
1085 | } |
1086 | // |
1087 | if (aNC.Tolerance() < *pTol) { |
1088 | aNC.SetTolerance(*pTol); |
3510db62 |
1089 | } |
4e57c75e |
1090 | } |
4e57c75e |
1091 | // append new PaveBlock to aLPBC |
edfa30de |
1092 | Handle(BOPDS_PaveBlock) *pPBC = aMEPB.ChangeSeek(iE); |
1093 | if (!pPBC) { |
1094 | pPBC = aMEPB.Bound(iE, new BOPDS_PaveBlock()); |
1095 | BOPDS_Pave aPaveR1, aPaveR2; |
1096 | aPaveR1 = aPBRx->Pave1(); |
1097 | aPaveR2 = aPBRx->Pave2(); |
1098 | aPaveR1.SetIndex(myDS->Index(aPDS->Shape(aPaveR1.Index()))); |
1099 | aPaveR2.SetIndex(myDS->Index(aPDS->Shape(aPaveR2.Index()))); |
1100 | // |
1101 | (*pPBC)->SetPave1(aPaveR1); |
1102 | (*pPBC)->SetPave2(aPaveR2); |
1103 | (*pPBC)->SetEdge(iE); |
1104 | } |
4e57c75e |
1105 | // |
4e57c75e |
1106 | if (bOld) { |
edfa30de |
1107 | (*pPBC)->SetOriginalEdge(aPB1->OriginalEdge()); |
1108 | aDMExEdges.ChangeFind(aPB1).Append(*pPBC); |
4e57c75e |
1109 | } |
1110 | else { |
edfa30de |
1111 | aLPBC.Append(*pPBC); |
4e57c75e |
1112 | } |
1113 | } |
1114 | } |
1115 | } |
1116 | }//else if (aType==TopAbs_EDGE) |
1117 | }//for (; aItLS.More(); aItLS.Next()) { |
24542bc0 |
1118 | |
1119 | // Update SD for vertices that did not participate in operation |
1155d05a |
1120 | TColStd_DataMapOfIntegerInteger::Iterator itDM(aDMNewSD); |
24542bc0 |
1121 | for (; itDM.More(); itDM.Next()) |
1122 | { |
1123 | const Standard_Integer* pSD = aDMNewSD.Seek(itDM.Value()); |
1124 | if (pSD) |
1125 | { |
1126 | itDM.ChangeValue() = *pSD; |
1127 | myDS->AddShapeSD(itDM.Key(), *pSD); |
1128 | } |
1129 | } |
33ba8565 |
1130 | return; |
4e57c75e |
1131 | } |
1132 | |
1133 | //======================================================================= |
1134 | //function : UpdateFaceInfo |
1135 | //purpose : |
1136 | //======================================================================= |
465d1fba |
1137 | void BOPAlgo_PaveFiller::UpdateFaceInfo |
1b7ae951 |
1138 | (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME, |
1155d05a |
1139 | const TColStd_DataMapOfIntegerInteger& theDMV) |
4e57c75e |
1140 | { |
1141 | Standard_Integer i, j, nV1, nF1, nF2, |
1b7ae951 |
1142 | aNbFF, aNbC, aNbP; |
4e57c75e |
1143 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB; |
1155d05a |
1144 | TColStd_MapOfInteger aMF; |
4e57c75e |
1145 | // |
1146 | BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); |
1155d05a |
1147 | aNbFF=aFFs.Length(); |
4e57c75e |
1148 | // |
1149 | //1. Sections (curves, points); |
1150 | for (i=0; i<aNbFF; ++i) { |
1151 | BOPDS_InterfFF& aFF=aFFs(i); |
1152 | aFF.Indices(nF1, nF2); |
1153 | // |
1154 | BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1); |
1155 | BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2); |
1156 | // |
1b7ae951 |
1157 | // 1.1. Section edges |
4e57c75e |
1158 | BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves(); |
1155d05a |
1159 | aNbC=aVNC.Length(); |
4e57c75e |
1160 | for (j=0; j<aNbC; ++j) { |
1161 | BOPDS_Curve& aNC=aVNC(j); |
1162 | BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks(); |
4e57c75e |
1163 | // |
1b7ae951 |
1164 | // Add section edges to face info |
3285a59a |
1165 | aItLPB.Initialize(aLPBC); |
1166 | for (; aItLPB.More(); ) { |
4e57c75e |
1167 | const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value(); |
3285a59a |
1168 | // |
1169 | // Treat existing pave blocks |
1170 | if (theDME.IsBound(aPB)) { |
1171 | BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB); |
1172 | UpdateExistingPaveBlocks(aPB, aLPB, nF1, nF2); |
1173 | aLPBC.Remove(aItLPB); |
1174 | continue; |
1175 | } |
1176 | // |
4e57c75e |
1177 | aFI1.ChangePaveBlocksSc().Add(aPB); |
1178 | aFI2.ChangePaveBlocksSc().Add(aPB); |
3285a59a |
1179 | aItLPB.Next(); |
4e57c75e |
1180 | } |
1181 | } |
1b7ae951 |
1182 | // |
1183 | // 1.2. Section vertices |
4e57c75e |
1184 | const BOPDS_VectorOfPoint& aVNP=aFF.Points(); |
1155d05a |
1185 | aNbP=aVNP.Length(); |
4e57c75e |
1186 | for (j=0; j<aNbP; ++j) { |
1187 | const BOPDS_Point& aNP=aVNP(j); |
1188 | nV1=aNP.Index(); |
85915310 |
1189 | if (nV1<0) { |
1190 | continue; |
1191 | } |
4e57c75e |
1192 | aFI1.ChangeVerticesSc().Add(nV1); |
1193 | aFI2.ChangeVerticesSc().Add(nV1); |
1194 | } |
1b7ae951 |
1195 | // |
1196 | aMF.Add(nF1); |
1197 | aMF.Add(nF2); |
4e57c75e |
1198 | } |
1199 | // |
1b7ae951 |
1200 | Standard_Boolean bVerts, bEdges; |
1201 | // |
1202 | bVerts = theDMV.Extent() > 0; |
1203 | bEdges = theDME.Extent() > 0; |
1204 | // |
1205 | if (!bVerts && !bEdges) { |
4e57c75e |
1206 | return; |
1207 | } |
1208 | // |
1b7ae951 |
1209 | // 2. Update Face Info information with new vertices and new |
1210 | // pave blocks created in PostTreatFF from existing ones |
1211 | Standard_Integer nV2, aNbPB; |
1155d05a |
1212 | TColStd_MapIteratorOfMapOfInteger aItMF; |
1213 | TColStd_DataMapIteratorOfDataMapOfIntegerInteger aItMV; |
1b7ae951 |
1214 | // |
1215 | aItMF.Initialize(aMF); |
1216 | for (; aItMF.More(); aItMF.Next()) { |
1217 | nF1 = aItMF.Value(); |
4e57c75e |
1218 | // |
1b7ae951 |
1219 | BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1); |
4e57c75e |
1220 | // |
1b7ae951 |
1221 | // 2.1. Update information about vertices |
1222 | if (bVerts) { |
1155d05a |
1223 | TColStd_MapOfInteger& aMVOn = aFI.ChangeVerticesOn(); |
1224 | TColStd_MapOfInteger& aMVIn = aFI.ChangeVerticesIn(); |
1b7ae951 |
1225 | // |
1226 | aItMV.Initialize(theDMV); |
1227 | for (; aItMV.More(); aItMV.Next()) { |
1228 | nV1 = aItMV.Key(); |
1229 | nV2 = aItMV.Value(); |
1230 | // |
1231 | if (aMVOn.Remove(nV1)) { |
1232 | aMVOn.Add(nV2); |
4e57c75e |
1233 | } |
1b7ae951 |
1234 | // |
1235 | if (aMVIn.Remove(nV1)) { |
1236 | aMVIn.Add(nV2); |
1237 | } |
1238 | } // for (; aItMV.More(); aItMV.Next()) { |
1239 | } // if (bVerts) { |
1240 | // |
1241 | // 2.2. Update information about pave blocks |
1242 | if (bEdges) { |
1243 | BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.ChangePaveBlocksOn(); |
1244 | BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn(); |
1245 | // |
1246 | BOPDS_IndexedMapOfPaveBlock aMPBCopy; |
1247 | for (i = 0; i < 2; ++i) { |
1248 | BOPDS_IndexedMapOfPaveBlock& aMPBOnIn = !i ? aMPBOn : aMPBIn; |
1249 | aMPBCopy = aMPBOnIn; |
1250 | aMPBOnIn.Clear(); |
1251 | // |
1252 | aNbPB = aMPBCopy.Extent(); |
1253 | for (j = 1; j <= aNbPB; ++j) { |
1254 | const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j); |
1255 | if (theDME.IsBound(aPB)) { |
1256 | const BOPDS_ListOfPaveBlock& aLPB = theDME.Find(aPB); |
3285a59a |
1257 | if (aLPB.IsEmpty()) { |
1258 | aMPBOnIn.Add(aPB); |
1259 | continue; |
1260 | } |
1261 | // |
1b7ae951 |
1262 | aItLPB.Initialize(aLPB); |
1263 | for (; aItLPB.More(); aItLPB.Next()) { |
1264 | const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value(); |
1265 | aMPBOnIn.Add(aPB1); |
1266 | } |
1267 | } |
1268 | else { |
1269 | aMPBOnIn.Add(aPB); |
1270 | } |
1271 | } // for (j = 1; j <= aNbPB; ++j) { |
1272 | } // for (i = 0; i < 2; ++i) { |
1273 | } // if (bEdges) { |
1274 | } |
4e57c75e |
1275 | } |
4e57c75e |
1276 | //======================================================================= |
1277 | //function : IsExistingVertex |
1278 | //purpose : |
1279 | //======================================================================= |
3510db62 |
1280 | Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex |
1281 | (const gp_Pnt& aP, |
1282 | const Standard_Real theTolR3D, |
1155d05a |
1283 | const TColStd_MapOfInteger& aMVOnIn)const |
4e57c75e |
1284 | { |
1285 | Standard_Boolean bRet; |
1286 | Standard_Integer nV, iFlag; |
0d0481c7 |
1287 | Standard_Real aTolCheck; |
4e57c75e |
1288 | gp_Pnt aPV; |
1289 | Bnd_Box aBoxP; |
1155d05a |
1290 | TColStd_MapIteratorOfMapOfInteger aIt; |
4e57c75e |
1291 | // |
0d0481c7 |
1292 | aTolCheck = theTolR3D + myFuzzyValue; |
4e57c75e |
1293 | bRet=Standard_True; |
1294 | // |
1295 | aBoxP.Add(aP); |
1296 | aBoxP.Enlarge(theTolR3D); |
1297 | // |
1298 | aIt.Initialize(aMVOnIn); |
1299 | for (; aIt.More(); aIt.Next()) { |
4e57c75e |
1300 | nV=aIt.Value(); |
3510db62 |
1301 | const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV); |
1302 | const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape())); |
1303 | const Bnd_Box& aBoxV=aSIV.Box(); |
4e57c75e |
1304 | // |
1305 | if (!aBoxP.IsOut(aBoxV)) { |
0d0481c7 |
1306 | iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, aTolCheck); |
4e57c75e |
1307 | if (!iFlag) { |
1308 | return bRet; |
1309 | } |
1310 | } |
1311 | } |
1312 | return !bRet; |
1313 | } |
1314 | //======================================================================= |
1315 | //function : IsExistingPaveBlock |
1316 | //purpose : |
1317 | //======================================================================= |
3510db62 |
1318 | Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock |
1319 | (const Handle(BOPDS_PaveBlock)& thePB, |
1320 | const BOPDS_Curve& theNC, |
1155d05a |
1321 | const TColStd_ListOfInteger& theLSE) |
4e57c75e |
1322 | { |
1323 | Standard_Boolean bRet=Standard_True; |
1324 | // |
1325 | if (theLSE.IsEmpty()) { |
1326 | return !bRet; |
1327 | } |
1328 | // |
0d0481c7 |
1329 | Standard_Real aT1, aT2, aTm, aTx, aTolE, aTolCheck, aTol, aDist; |
93e38faa |
1330 | Standard_Integer nE, iFlag, nV1, nV2; |
4e57c75e |
1331 | gp_Pnt aPm; |
1332 | Bnd_Box aBoxPm; |
1155d05a |
1333 | TColStd_ListIteratorOfListOfInteger aItLI; |
4e57c75e |
1334 | // |
1335 | thePB->Range(aT1, aT2); |
93e38faa |
1336 | thePB->Indices(nV1, nV2); |
1337 | const TopoDS_Vertex &aV1 = TopoDS::Vertex(myDS->Shape(nV1)), |
1338 | &aV2 = TopoDS::Vertex(myDS->Shape(nV2)); |
1339 | const Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1), |
1340 | aTolV2 = BRep_Tool::Tolerance(aV2); |
1341 | |
1342 | aTol = Max(aTolV1, aTolV2); |
1343 | |
4e57c75e |
1344 | aTm=IntTools_Tools::IntermediatePoint (aT1, aT2); |
1345 | theNC.Curve().D0(aTm, aPm); |
1346 | aBoxPm.Add(aPm); |
93e38faa |
1347 | aBoxPm.Enlarge(aTol); |
4e57c75e |
1348 | // |
1349 | aItLI.Initialize(theLSE); |
1350 | for (; aItLI.More(); aItLI.Next()) { |
1351 | nE=aItLI.Value(); |
3510db62 |
1352 | if (nE < 0) |
1353 | continue; |
4e57c75e |
1354 | const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE); |
1355 | const Bnd_Box& aBoxE=aSIE.Box(); |
1356 | if (!aBoxE.IsOut(aBoxPm)) { |
1357 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape())); |
0d0481c7 |
1358 | aTolE = BRep_Tool::Tolerance(aE); |
1359 | aTolCheck = Max(aTolE, aTol) + myFuzzyValue; |
1360 | iFlag = myContext->ComputePE(aPm, aTolCheck, aE, aTx, aDist); |
4e57c75e |
1361 | if (!iFlag) { |
86218548 |
1362 | if (aDist > aTolE) |
1363 | // Update tolerance of the edge |
1364 | UpdateEdgeTolerance(nE, aDist); |
4e57c75e |
1365 | return bRet; |
1366 | } |
1367 | } |
1368 | } |
1369 | return !bRet; |
1370 | } |
1371 | |
1372 | //======================================================================= |
1373 | //function : IsExistingPaveBlock |
1374 | //purpose : |
1375 | //======================================================================= |
0d0481c7 |
1376 | Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock |
4e57c75e |
1377 | (const Handle(BOPDS_PaveBlock)& thePB, |
1378 | const BOPDS_Curve& theNC, |
1379 | const Standard_Real theTolR3D, |
decdfc94 |
1380 | const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn, |
0d0481c7 |
1381 | const BOPDS_MapOfPaveBlock& theMPBCommon, |
05cf4d98 |
1382 | Handle(BOPDS_PaveBlock)& aPBOut, |
1383 | Standard_Real& theTolNew) |
4e57c75e |
1384 | { |
1385 | Standard_Boolean bRet; |
0d0481c7 |
1386 | Standard_Real aT1, aT2, aTm, aTx, aTolCheck; |
decdfc94 |
1387 | Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB; |
4e57c75e |
1388 | gp_Pnt aP1, aPm, aP2; |
93e38faa |
1389 | Bnd_Box aBoxP1, aBoxPm, aBoxP2, aBoxTmp; |
4e57c75e |
1390 | // |
78c66ef1 |
1391 | bRet=Standard_False; |
0d0481c7 |
1392 | aTolCheck = theTolR3D + myFuzzyValue; |
4e57c75e |
1393 | const IntTools_Curve& aIC=theNC.Curve(); |
1394 | // |
1395 | thePB->Range(aT1, aT2); |
1396 | thePB->Indices(nV11, nV12); |
93e38faa |
1397 | const Standard_Real aTolV11 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV11))); |
1398 | const Standard_Real aTolV12 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV12))); |
0d0481c7 |
1399 | const Standard_Real aTolV1 = Max(aTolV11, aTolV12) + myFuzzyValue; |
93e38faa |
1400 | |
4e57c75e |
1401 | //first point |
1402 | aIC.D0(aT1, aP1); |
1403 | aBoxP1.Add(aP1); |
93e38faa |
1404 | aBoxP1.Enlarge(aTolV11); |
4e57c75e |
1405 | //intermediate point |
1406 | aTm=IntTools_Tools::IntermediatePoint (aT1, aT2); |
1407 | aIC.D0(aTm, aPm); |
1408 | aBoxPm.Add(aPm); |
4e57c75e |
1409 | //last point |
1410 | aIC.D0(aT2, aP2); |
1411 | aBoxP2.Add(aP2); |
93e38faa |
1412 | aBoxP2.Enlarge(aTolV12); |
4e57c75e |
1413 | // |
05cf4d98 |
1414 | theTolNew = 0.; |
decdfc94 |
1415 | aNbPB = theMPBOnIn.Extent(); |
1416 | for (i = 1; i <= aNbPB; ++i) { |
1417 | const Handle(BOPDS_PaveBlock)& aPB = theMPBOnIn(i); |
4e57c75e |
1418 | aPB->Indices(nV21, nV22); |
93e38faa |
1419 | const Standard_Real aTolV21 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV21))); |
1420 | const Standard_Real aTolV22 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV22))); |
0d0481c7 |
1421 | const Standard_Real aTolV2 = Max(aTolV21, aTolV22) + myFuzzyValue; |
4e57c75e |
1422 | nSp=aPB->Edge(); |
3510db62 |
1423 | if (nSp < 0) |
1424 | continue; |
4e57c75e |
1425 | const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp); |
78c66ef1 |
1426 | const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape())); |
4e57c75e |
1427 | const Bnd_Box& aBoxSp=aSISp.Box(); |
78c66ef1 |
1428 | // |
465d1fba |
1429 | iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 : |
1430 | (!aBoxSp.IsOut(aBoxP1) ? 1 : 0); |
1431 | iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 : |
1432 | (!aBoxSp.IsOut(aBoxP2) ? 1 : 0); |
78c66ef1 |
1433 | if (iFlag1 && iFlag2) { |
f4dee9bb |
1434 | Standard_Real aDist = 0.; |
93e38faa |
1435 | |
0d0481c7 |
1436 | Standard_Real aRealTol = aTolCheck; |
1437 | if (myDS->IsCommonBlock(aPB)) |
1438 | { |
1439 | aRealTol = Max(aRealTol, Max(aTolV1, aTolV2)); |
1440 | if (theMPBCommon.Contains(aPB)) |
1441 | // for an edge, which is a common block with a face, |
1442 | // increase the chance to coincide with section curve |
1443 | aRealTol *= 2.; |
1444 | } |
1445 | |
93e38faa |
1446 | aBoxTmp = aBoxPm; |
1447 | aBoxTmp.Enlarge(aRealTol); |
1448 | |
1449 | if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm, |
1450 | aRealTol, |
1451 | aSp, |
1452 | aTx, theTolNew)) { |
78c66ef1 |
1453 | continue; |
1454 | } |
1455 | // |
1456 | if (iFlag1 == 1) { |
93e38faa |
1457 | iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx, aDist); |
f4dee9bb |
1458 | if (iFlag1 && theTolNew < aDist) |
05cf4d98 |
1459 | theTolNew = aDist; |
78c66ef1 |
1460 | } |
1461 | // |
1462 | if (iFlag2 == 1) { |
93e38faa |
1463 | iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx, aDist); |
f4dee9bb |
1464 | if (iFlag2 && theTolNew < aDist) |
05cf4d98 |
1465 | theTolNew = aDist; |
78c66ef1 |
1466 | } |
1467 | // |
1468 | if (iFlag1 && iFlag2) { |
1469 | aPBOut = aPB; |
1470 | bRet=Standard_True; |
1471 | break; |
4e57c75e |
1472 | } |
1473 | } |
1474 | } |
78c66ef1 |
1475 | return bRet; |
4e57c75e |
1476 | } |
4bc805bf |
1477 | |
1478 | //======================================================================= |
1479 | //function : |
1480 | //purpose : |
1481 | //======================================================================= |
1482 | static void getBoundPaves(const BOPDS_DS* theDS, |
1483 | BOPDS_Curve& theNC, |
1484 | Standard_Integer theNV[2]) |
1485 | { |
1486 | theNV[0] = theNV[1] = -1; |
1487 | |
1488 | // get extreme paves |
1489 | Handle(BOPDS_PaveBlock)& aPB = theNC.ChangePaveBlock1(); |
1490 | const BOPDS_ListOfPave& aLP = aPB->ExtPaves(); |
1491 | Standard_Integer aNbEP = aLP.Extent(); |
1492 | if (aNbEP == 0) |
1493 | return; |
1494 | Standard_Real aTmin = RealLast(); |
1495 | Standard_Real aTmax = -aTmin; |
1496 | for (BOPDS_ListIteratorOfListOfPave aItLP(aLP); aItLP.More(); aItLP.Next()) |
1497 | { |
1498 | const BOPDS_Pave& aPv = aItLP.Value(); |
1499 | Standard_Integer nV; |
1500 | Standard_Real aTV; |
1501 | aPv.Contents(nV, aTV); |
1502 | if (aTV < aTmin) { |
1503 | theNV[0] = aPv.Index(); |
1504 | aTmin = aTV; |
1505 | } |
1506 | if (aTV > aTmax) { |
1507 | theNV[1] = aPv.Index(); |
1508 | aTmax = aTV; |
1509 | } |
1510 | } |
1511 | |
1512 | // compare extreme vertices with ends of the curve |
1513 | const IntTools_Curve& aIC = theNC.Curve(); |
1514 | Standard_Real aT[2]; |
1515 | gp_Pnt aP[2]; |
1516 | aIC.Bounds(aT[0], aT[1], aP[0], aP[1]); |
1517 | Standard_Real aTol = Max(theNC.Tolerance(), theNC.TangentialTolerance()); |
1518 | aTol += Precision::Confusion(); |
1519 | for (Standard_Integer j = 0; j < 2; ++j) |
1520 | { |
1521 | const BOPDS_ShapeInfo& aSIV = theDS->ShapeInfo(theNV[j]); |
1522 | const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&aSIV.Shape())); |
1523 | Standard_Integer iFlag = BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol); |
1524 | if (iFlag != 0) |
1525 | theNV[j] = -1; |
1526 | } |
1527 | } |
1528 | |
4e57c75e |
1529 | //======================================================================= |
1530 | //function : PutBoundPaveOnCurve |
1531 | //purpose : |
1532 | //======================================================================= |
0d0481c7 |
1533 | void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1, |
1534 | const TopoDS_Face& aF2, |
0d0481c7 |
1535 | BOPDS_Curve& aNC, |
1155d05a |
1536 | TColStd_ListOfInteger& aLVB) |
4e57c75e |
1537 | { |
4e57c75e |
1538 | const IntTools_Curve& aIC=aNC.Curve(); |
4bc805bf |
1539 | Standard_Real aT[2]; |
1540 | gp_Pnt aP[2]; |
4e57c75e |
1541 | aIC.Bounds(aT[0], aT[1], aP[0], aP[1]); |
5652dc62 |
1542 | Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance()); |
4bc805bf |
1543 | Handle(BOPDS_PaveBlock)& aPB = aNC.ChangePaveBlock1(); |
1544 | // Get numbers of vertices assigned to the ends of the curve |
1545 | Standard_Integer aBndNV[2]; |
1546 | getBoundPaves(myDS, aNC, aBndNV); |
4e57c75e |
1547 | // |
4bc805bf |
1548 | Standard_Real aTolVnew = Precision::Confusion(); |
1549 | for (Standard_Integer j = 0; j<2; ++j) |
1550 | { |
1551 | if (aBndNV[j] < 0) |
1552 | { |
1553 | // no vertex on this end |
1554 | if (j && aP[1].IsEqual(aP[0], aTolVnew)) { |
1555 | //if curve is closed, process only one bound |
1556 | continue; |
4e57c75e |
1557 | } |
4bc805bf |
1558 | Standard_Boolean bVF = myContext->IsValidPointForFaces(aP[j], aF1, aF2, aTolR3D); |
4e57c75e |
1559 | if (!bVF) { |
1560 | continue; |
1561 | } |
4bc805bf |
1562 | TopoDS_Vertex aVn; |
4e57c75e |
1563 | BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn); |
4bc805bf |
1564 | BOPTools_AlgoTools::UpdateVertex(aIC, aT[j], aVn); |
1565 | aTolVnew = BRep_Tool::Tolerance(aVn); |
1566 | |
1567 | BOPDS_ShapeInfo aSIVn; |
4e57c75e |
1568 | aSIVn.SetShapeType(TopAbs_VERTEX); |
1569 | aSIVn.SetShape(aVn); |
4bc805bf |
1570 | |
1571 | Bnd_Box& aBox = aSIVn.ChangeBox(); |
1572 | BRepBndLib::Add(aVn, aBox); |
1573 | aBox.SetGap(aBox.GetGap() + Precision::Confusion()); |
1574 | |
1575 | Standard_Integer nVn = myDS->Append(aSIVn); |
1576 | |
1577 | BOPDS_Pave aPn; |
4e57c75e |
1578 | aPn.SetIndex(nVn); |
1579 | aPn.SetParameter(aT[j]); |
1580 | aPB->AppendExtPave(aPn); |
4bc805bf |
1581 | |
3285a59a |
1582 | aLVB.Append(nVn); |
4e57c75e |
1583 | } |
1584 | } |
1585 | } |
1586 | |
1587 | //======================================================================= |
78c66ef1 |
1588 | //function : PutPavesOnCurve |
4e57c75e |
1589 | //purpose : |
1590 | //======================================================================= |
6f1ea0f4 |
1591 | void BOPAlgo_PaveFiller::PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn, |
1592 | const TColStd_MapOfInteger& theMVCommon, |
1593 | BOPDS_Curve& theNC, |
1594 | const TColStd_MapOfInteger& theMI, |
1595 | const TColStd_MapOfInteger& theMVEF, |
1596 | TColStd_DataMapOfIntegerReal& theMVTol, |
1597 | TColStd_DataMapOfIntegerListOfInteger& theDMVLV) |
4e57c75e |
1598 | { |
4e57c75e |
1599 | Standard_Integer nV; |
1155d05a |
1600 | TColStd_MapIteratorOfMapOfInteger aIt; |
4e57c75e |
1601 | // |
6f1ea0f4 |
1602 | const Bnd_Box& aBoxC = theNC.Box(); |
1603 | const Standard_Real aTolR3D = Max(theNC.Tolerance(), theNC.TangentialTolerance()); |
4e57c75e |
1604 | // |
78c66ef1 |
1605 | //Put EF vertices first |
6f1ea0f4 |
1606 | aIt.Initialize(theMVEF); |
1607 | for (; aIt.More(); aIt.Next()) |
1608 | { |
1609 | nV = aIt.Value(); |
1610 | PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 2); |
78c66ef1 |
1611 | } |
6f1ea0f4 |
1612 | |
78c66ef1 |
1613 | //Put all other vertices |
6f1ea0f4 |
1614 | aIt.Initialize(theMVOnIn); |
1615 | for (; aIt.More(); aIt.Next()) |
1616 | { |
1617 | nV = aIt.Value(); |
1618 | if (theMVEF.Contains(nV)) |
1619 | { |
78c66ef1 |
1620 | continue; |
1621 | } |
6f1ea0f4 |
1622 | |
1623 | if (!theMVCommon.Contains(nV)) |
1624 | { |
1625 | const BOPDS_ShapeInfo& aSIV = myDS->ShapeInfo(nV); |
1626 | const Bnd_Box& aBoxV = aSIV.Box(); |
b4109929 |
1627 | // |
6f1ea0f4 |
1628 | if (aBoxC.IsOut(aBoxV)) |
1629 | { |
1630 | continue; |
1631 | } |
1632 | if (!myDS->IsNewShape(nV)) |
1633 | { |
78c66ef1 |
1634 | continue; |
b4109929 |
1635 | } |
4e57c75e |
1636 | } |
78c66ef1 |
1637 | // |
6f1ea0f4 |
1638 | PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 1); |
0d0481c7 |
1639 | } |
1640 | } |
1641 | |
1642 | //======================================================================= |
1643 | //function : FilterPavesOnCurves |
1644 | //purpose : |
1645 | //======================================================================= |
1646 | namespace { |
1647 | struct PaveBlockDist { |
1648 | Handle(BOPDS_PaveBlock) PB; |
1649 | Standard_Real Dist; // square distance from vertex to the paveblock |
1650 | Standard_Real SinAngle; // sinus of angle between projection vector |
1651 | // and tangent at projection point |
5652dc62 |
1652 | Standard_Real Tolerance; // tolerance of the section curve |
0d0481c7 |
1653 | }; |
1654 | } |
5652dc62 |
1655 | void BOPAlgo_PaveFiller::FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC) |
0d0481c7 |
1656 | { |
0d0481c7 |
1657 | // For each vertex found in ExtPaves of pave blocks of section curves |
1658 | // collect list of pave blocks with distance to the curve |
1659 | NCollection_IndexedDataMap<Standard_Integer,NCollection_List<PaveBlockDist> > aIDMVertPBs; |
1660 | Standard_Integer i; |
1661 | const Standard_Real anEps = gp::Resolution(); |
1155d05a |
1662 | for (i = 0; i < theVNC.Length(); ++i) |
0d0481c7 |
1663 | { |
1664 | const BOPDS_Curve& aNC = theVNC(i); |
1665 | const IntTools_Curve& aIC = aNC.Curve(); |
5652dc62 |
1666 | const Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance()); |
0d0481c7 |
1667 | GeomAdaptor_Curve aGAC(aIC.Curve()); |
1668 | const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First(); |
1669 | const BOPDS_ListOfPave& aPaves = aPB->ExtPaves(); |
1670 | BOPDS_ListOfPave::Iterator itPaves(aPaves); |
1671 | for (; itPaves.More(); itPaves.Next()) |
1672 | { |
1673 | const BOPDS_Pave& aPave = itPaves.Value(); |
1674 | Standard_Integer nV = aPave.Index(); |
1675 | const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV)); |
1676 | // compute distance from vertex to the point on curve with vertex parameter |
1677 | gp_Pnt aPV = BRep_Tool::Pnt(aV); |
1678 | Standard_Real aPar = aPave.Parameter(); |
1679 | gp_Pnt aPonC; |
1680 | gp_Vec aD1; |
1681 | aGAC.D1(aPar, aPonC, aD1); |
1682 | gp_Vec aProjVec(aPV, aPonC); |
1683 | Standard_Real aSqDist = aProjVec.SquareMagnitude(); |
1684 | Standard_Real aSqD1Mod = aD1.SquareMagnitude(); |
1685 | Standard_Real aSin = aProjVec.CrossSquareMagnitude(aD1); |
1686 | if (aSqDist > anEps && aSqD1Mod > anEps) |
1687 | aSin = sqrt(aSin / aSqDist / aSqD1Mod); |
1688 | NCollection_List<PaveBlockDist>* pList = aIDMVertPBs.ChangeSeek(nV); |
1689 | if (!pList) |
1690 | pList = &aIDMVertPBs.ChangeFromIndex(aIDMVertPBs.Add(nV, NCollection_List<PaveBlockDist>())); |
5652dc62 |
1691 | PaveBlockDist aPBD = { aPB, aSqDist, aSin, aTolR3D }; |
0d0481c7 |
1692 | pList->Append(aPBD); |
1693 | } |
1694 | } |
1695 | |
1696 | // Process each vertex |
1697 | const Standard_Real aSinAngleMin = 0.5; // angle below which projection is suspicious |
1698 | for (i = 1; i <= aIDMVertPBs.Extent(); i++) |
1699 | { |
1700 | Standard_Integer nV = aIDMVertPBs.FindKey(i); |
1701 | const NCollection_List<PaveBlockDist>& aList = aIDMVertPBs(i); |
1702 | // Find a pave with minimal distance |
1703 | Standard_Real aMinDist = RealLast(); |
1704 | Handle(BOPDS_PaveBlock) aPBMinDist; |
1705 | NCollection_List<PaveBlockDist>::Iterator itL(aList); |
1706 | for (; itL.More(); itL.Next()) |
1707 | { |
1708 | const PaveBlockDist& aPBD = itL.Value(); |
1709 | if (aPBD.Dist < aMinDist) |
1710 | { |
1711 | aMinDist = aPBD.Dist; |
1712 | aPBMinDist = aPBD.PB; |
1713 | } |
1714 | } |
1715 | // Remove a vertex from a pave block if the distance is greater than the tolerance |
1716 | // and there are other pave blocks for which the distance is less than the current. |
1717 | // Do not remove a vertex if it is projected on the curve with quite large angle |
1718 | // (see test bugs modalg_6 bug27761). |
0d0481c7 |
1719 | for (itL.Init(aList); itL.More(); itL.Next()) |
1720 | { |
1721 | const PaveBlockDist& aPBD = itL.Value(); |
5652dc62 |
1722 | Standard_Real aCheckDist = 100. * Max(aPBD.Tolerance*aPBD.Tolerance, aMinDist); |
0d0481c7 |
1723 | if (aPBD.Dist > aCheckDist && aPBD.SinAngle < aSinAngleMin) |
1724 | { |
1725 | aPBD.PB->RemoveExtPave(nV); |
1726 | } |
1727 | } |
4e57c75e |
1728 | } |
1729 | } |
1730 | |
1731 | //======================================================================= |
1732 | //function : ExtendedTolerance |
1733 | //purpose : |
1734 | //======================================================================= |
465d1fba |
1735 | Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance |
1736 | (const Standard_Integer nV, |
1155d05a |
1737 | const TColStd_MapOfInteger& aMI, |
465d1fba |
1738 | Standard_Real& aTolVExt, |
1739 | const Standard_Integer aType) |
4e57c75e |
1740 | { |
1741 | Standard_Boolean bFound = Standard_False; |
1742 | if (!(myDS->IsNewShape(nV))) { |
1743 | return bFound; |
1744 | } |
78c66ef1 |
1745 | // |
1746 | Standard_Integer i, k, aNbLines, aNbInt; |
4e57c75e |
1747 | Standard_Real aT11, aT12, aD1, aD2, aD; |
1748 | TopoDS_Vertex aV; |
1749 | gp_Pnt aPV, aP11, aP12; |
78c66ef1 |
1750 | // |
1751 | k = 0; |
1752 | aNbInt = 2; |
1753 | if (aType == 1) { |
1754 | aNbInt = 1; |
1755 | } else if (aType == 2) { |
1756 | k = 1; |
1757 | } |
1758 | // |
4e57c75e |
1759 | aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV))); |
1760 | aPV=BRep_Tool::Pnt(aV); |
1761 | // |
1762 | BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE(); |
1763 | BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF(); |
78c66ef1 |
1764 | // |
1765 | for (; k<aNbInt; ++k) { |
1155d05a |
1766 | aNbLines = !k ? aEEs.Length() : aEFs.Length(); |
4e57c75e |
1767 | for (i = 0; i < aNbLines; ++i) { |
1768 | BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) : |
78c66ef1 |
1769 | (BOPDS_Interf*) (&aEFs(i)); |
4e57c75e |
1770 | if (aInt->IndexNew() == nV) { |
465d1fba |
1771 | if (aMI.Contains(aInt->Index1()) && |
1772 | aMI.Contains(aInt->Index2())) { |
4e57c75e |
1773 | const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() : |
78c66ef1 |
1774 | aEFs(i).CommonPart(); |
4e57c75e |
1775 | // |
1776 | const TopoDS_Edge& aE1=aComPrt.Edge1(); |
1777 | aComPrt.Range1(aT11, aT12); |
1778 | BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11); |
1779 | BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12); |
1780 | aD1=aPV.Distance(aP11); |
1781 | aD2=aPV.Distance(aP12); |
1782 | aD=(aD1>aD2)? aD1 : aD2; |
1783 | if (aD>aTolVExt) { |
1784 | aTolVExt=aD; |
1785 | } |
1786 | return !bFound; |
1787 | }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) { |
1788 | }//if (aInt->IndexNew() == nV) { |
1789 | }//for (i = 0; i < aNbLines; ++i) { |
1790 | }//for (k=0; k<2; ++k) { |
4e57c75e |
1791 | return bFound; |
1792 | } |
1793 | |
1794 | //======================================================================= |
1795 | //function : GetEFPnts |
1796 | //purpose : |
1797 | //======================================================================= |
3510db62 |
1798 | void BOPAlgo_PaveFiller::GetEFPnts |
1799 | (const Standard_Integer nF1, |
1800 | const Standard_Integer nF2, |
1801 | IntSurf_ListOfPntOn2S& aListOfPnts) |
4e57c75e |
1802 | { |
1803 | Standard_Integer nE, nF, nFOpposite, aNbEFs, i; |
1804 | Standard_Real U1, U2, V1, V2, f, l; |
1155d05a |
1805 | TColStd_MapOfInteger aMI; |
4e57c75e |
1806 | // |
1807 | //collect indexes of all shapes from nF1 and nF2. |
78c66ef1 |
1808 | GetFullShapeMap(nF1, aMI); |
1809 | GetFullShapeMap(nF2, aMI); |
4e57c75e |
1810 | // |
1811 | BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF(); |
1155d05a |
1812 | aNbEFs = aEFs.Length(); |
4e57c75e |
1813 | // |
1814 | for(i = 0; i < aNbEFs; ++i) { |
1815 | const BOPDS_InterfEF& aEF = aEFs(i); |
78c66ef1 |
1816 | if (aEF.HasIndexNew()) { |
1817 | aEF.Indices(nE, nFOpposite); |
1818 | if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) { |
1819 | const IntTools_CommonPrt& aCP = aEF.CommonPart(); |
4e57c75e |
1820 | Standard_Real aPar = aCP.VertexParameter1(); |
1821 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE))); |
465d1fba |
1822 | const TopoDS_Face& aFOpposite = |
1823 | (*(TopoDS_Face*)(&myDS->Shape(nFOpposite))); |
4e57c75e |
1824 | // |
1825 | const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l); |
1826 | // |
1827 | nF = (nFOpposite == nF1) ? nF2 : nF1; |
1828 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF))); |
465d1fba |
1829 | Handle(Geom2d_Curve) aPCurve = |
1830 | BRep_Tool::CurveOnSurface(aE, aF, f, l); |
4e57c75e |
1831 | // |
465d1fba |
1832 | GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite); |
4e57c75e |
1833 | // |
1834 | gp_Pnt aPoint; |
1835 | aCurve->D0(aPar, aPoint); |
1836 | IntSurf_PntOn2S aPnt; |
1837 | if(!aPCurve.IsNull()) { |
1838 | gp_Pnt2d aP2d = aPCurve->Value(aPar); |
1839 | aProj.Perform(aPoint); |
1840 | if(aProj.IsDone()) { |
1841 | aProj.LowerDistanceParameters(U1,V1); |
1842 | if (nF == nF1) { |
1843 | aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1); |
1844 | } else { |
1845 | aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y()); |
1846 | } |
1847 | aListOfPnts.Append(aPnt); |
1848 | } |
1849 | } |
1850 | else { |
1851 | GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF); |
1852 | aProj1.Perform(aPoint); |
1853 | aProj.Perform(aPoint); |
1854 | if(aProj1.IsDone() && aProj.IsDone()){ |
1855 | aProj1.LowerDistanceParameters(U1,V1); |
1856 | aProj.LowerDistanceParameters(U2,V2); |
1857 | if (nF == nF1) { |
1858 | aPnt.SetValue(U1,V1,U2,V2); |
1859 | } else { |
1860 | aPnt.SetValue(U2,V2,U1,V1); |
1861 | } |
1862 | aListOfPnts.Append(aPnt); |
1863 | } |
1864 | } |
1865 | } |
1866 | } |
1867 | } |
1868 | } |
1869 | |
1870 | //======================================================================= |
0d0481c7 |
1871 | //function : PutEFPavesOnCurve |
4e57c75e |
1872 | //purpose : |
1873 | //======================================================================= |
465d1fba |
1874 | void BOPAlgo_PaveFiller::PutEFPavesOnCurve |
1875 | (BOPDS_Curve& aNC, |
1155d05a |
1876 | const TColStd_MapOfInteger& aMI, |
1877 | const TColStd_MapOfInteger& aMVEF, |
1878 | TColStd_DataMapOfIntegerReal& aMVTol, |
1879 | TColStd_DataMapOfIntegerListOfInteger& aDMVLV) |
4e57c75e |
1880 | { |
1881 | if (!aMVEF.Extent()) { |
1882 | return; |
1883 | } |
1884 | // |
1885 | const IntTools_Curve& aIC=aNC.Curve(); |
1886 | GeomAbs_CurveType aTypeC; |
1887 | aTypeC=aIC.Type(); |
1888 | if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) { |
1889 | return; |
1890 | } |
1891 | // |
1892 | Standard_Integer nV; |
1155d05a |
1893 | TColStd_MapOfInteger aMV; |
4e57c75e |
1894 | // |
1895 | aMV.Assign(aMVEF); |
1896 | RemoveUsedVertices(aNC, aMV); |
1897 | if (!aMV.Extent()) { |
1898 | return; |
1899 | } |
1900 | // |
1901 | Standard_Real aDist; |
1902 | BOPDS_Pave aPave; |
1903 | // |
1904 | const Handle(Geom_Curve)& aC3D=aIC.Curve(); |
4e57c75e |
1905 | GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D); |
78c66ef1 |
1906 | // |
1155d05a |
1907 | TColStd_MapIteratorOfMapOfInteger aItMI; |
4e57c75e |
1908 | aItMI.Initialize(aMV); |
1909 | for (; aItMI.More(); aItMI.Next()) { |
1910 | nV = aItMI.Value(); |
1911 | const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV))); |
1912 | gp_Pnt aPV = BRep_Tool::Pnt(aV); |
1913 | aProjPT.Perform(aPV); |
1914 | Standard_Integer aNbPoints = aProjPT.NbPoints(); |
1915 | if (aNbPoints) { |
1916 | aDist = aProjPT.LowerDistance(); |
0d0481c7 |
1917 | PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol, aDMVLV); |
4e57c75e |
1918 | } |
1919 | } |
1920 | } |
1921 | |
1922 | //======================================================================= |
4bc805bf |
1923 | //function : PutStickPavesOnCurve |
4e57c75e |
1924 | //purpose : |
1925 | //======================================================================= |
465d1fba |
1926 | void BOPAlgo_PaveFiller::PutStickPavesOnCurve |
1927 | (const TopoDS_Face& aF1, |
1928 | const TopoDS_Face& aF2, |
1155d05a |
1929 | const TColStd_MapOfInteger& aMI, |
465d1fba |
1930 | BOPDS_Curve& aNC, |
1155d05a |
1931 | const TColStd_MapOfInteger& aMVStick, |
1932 | TColStd_DataMapOfIntegerReal& aMVTol, |
1933 | TColStd_DataMapOfIntegerListOfInteger& aDMVLV) |
4e57c75e |
1934 | { |
4bc805bf |
1935 | // Get numbers of vertices assigned to the ends of the curve |
1936 | Standard_Integer aBndNV[2]; |
1937 | getBoundPaves(myDS, aNC, aBndNV); |
1938 | if (aBndNV[0] >= 0 && aBndNV[1] >= 0) |
1939 | { |
1940 | // both curve ends already have assigned vertices |
1941 | return; |
1942 | } |
1155d05a |
1943 | TColStd_MapOfInteger aMV; |
4e57c75e |
1944 | aMV.Assign(aMVStick); |
1945 | RemoveUsedVertices(aNC, aMV); |
1946 | // |
1947 | if (!aMV.Extent()) { |
1948 | return; |
1949 | } |
1950 | // |
4e57c75e |
1951 | Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1); |
1952 | Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2); |
ec0cdc0e |
1953 | // |
1954 | const IntTools_Curve& aIC=aNC.Curve(); |
ec0cdc0e |
1955 | //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) { |
1956 | Handle(Geom2d_Curve) aC2D[2]; |
1957 | // |
1958 | aC2D[0]=aIC.FirstCurve2d(); |
1959 | aC2D[1]=aIC.SecondCurve2d(); |
1960 | if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) { |
1961 | Standard_Integer nV, m, n; |
1962 | Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr; |
1963 | gp_Pnt aPC[2], aPV; |
1964 | gp_Dir aDN[2]; |
1965 | gp_Pnt2d aP2D; |
1155d05a |
1966 | TColStd_MapIteratorOfMapOfInteger aItMI, aItMI1; |
ec0cdc0e |
1967 | // |
1968 | aDT2=2e-7; // the rich criteria |
1969 | aDScPr=5.e-9; // the creasing criteria |
1970 | aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]); |
4e57c75e |
1971 | // |
ec0cdc0e |
1972 | aItMI.Initialize(aMV); |
1973 | for (; aItMI.More(); aItMI.Next()) { |
1974 | nV = aItMI.Value(); |
1975 | const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV)); |
1976 | aPV=BRep_Tool::Pnt(aV); |
4e57c75e |
1977 | // |
ec0cdc0e |
1978 | for (m=0; m<2; ++m) { |
4bc805bf |
1979 | if (aBndNV[m] >= 0) |
1980 | continue; |
ec0cdc0e |
1981 | aD2=aPC[m].SquareDistance(aPV); |
1982 | if (aD2>aDT2) {// no rich |
1983 | continue; |
1984 | } |
78c66ef1 |
1985 | // |
ec0cdc0e |
1986 | for (n=0; n<2; ++n) { |
1987 | Handle(Geom_Surface)& aS=(!n)? aS1 : aS2; |
1988 | aC2D[n]->D0(aTC[m], aP2D); |
1989 | aP2D.Coord(u, v); |
1990 | BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]); |
1991 | } |
1992 | // |
1993 | aScPr=aDN[0]*aDN[1]; |
1994 | if (aScPr<0.) { |
1995 | aScPr=-aScPr; |
1996 | } |
1997 | aScPr=1.-aScPr; |
78c66ef1 |
1998 | // |
ec0cdc0e |
1999 | if (aScPr>aDScPr) { |
2000 | continue; |
2001 | } |
2002 | // |
2003 | // The intersection curve aIC is vanishing curve (the crease) |
2004 | aD=sqrt(aD2); |
2005 | // |
0d0481c7 |
2006 | PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol, aDMVLV); |
4e57c75e |
2007 | } |
ec0cdc0e |
2008 | }//for (jVU=1; jVU=aNbVU; ++jVU) { |
2009 | } |
4e57c75e |
2010 | } |
2011 | |
2012 | //======================================================================= |
2013 | //function : GetStickVertices |
2014 | //purpose : |
2015 | //======================================================================= |
3510db62 |
2016 | void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1, |
2017 | const Standard_Integer nF2, |
1155d05a |
2018 | TColStd_MapOfInteger& aMVStick, |
2019 | TColStd_MapOfInteger& aMVEF, |
2020 | TColStd_MapOfInteger& aMI) |
4e57c75e |
2021 | { |
78c66ef1 |
2022 | Standard_Integer nS1, nS2, nVNew, aTypeInt, i; |
4e57c75e |
2023 | // |
2024 | BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV(); |
2025 | BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE(); |
2026 | BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE(); |
2027 | BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF(); |
2028 | BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF(); |
2029 | // |
465d1fba |
2030 | Standard_Integer aNbLines[5] = { |
1155d05a |
2031 | aVVs.Length(), aVEs.Length(), aEEs.Length(), |
2032 | aVFs.Length(), aEFs.Length() |
465d1fba |
2033 | }; |
78c66ef1 |
2034 | //collect indices of all shapes from nF1 and nF2. |
2035 | aMI.Clear(); |
2036 | GetFullShapeMap(nF1, aMI); |
2037 | GetFullShapeMap(nF2, aMI); |
2038 | // |
2039 | //collect VV, VE, EE, VF interferences |
2040 | for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) { |
2041 | for (i = 0; i < aNbLines[aTypeInt]; ++i) { |
2042 | BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) : |
2043 | ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) : |
465d1fba |
2044 | ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) : |
2045 | (BOPDS_Interf*)(&aVFs(i)))); |
78c66ef1 |
2046 | if (aInt->HasIndexNew()) { |
2047 | aInt->Indices(nS1, nS2); |
2048 | if(aMI.Contains(nS1) && aMI.Contains(nS2)) { |
2049 | nVNew = aInt->IndexNew(); |
2050 | aMVStick.Add(nVNew); |
2051 | } |
4e57c75e |
2052 | } |
2053 | } |
2054 | } |
4e57c75e |
2055 | //collect EF interferences |
78c66ef1 |
2056 | for (i = 0; i < aNbLines[4]; ++i) { |
2057 | const BOPDS_InterfEF& aInt = aEFs(i); |
2058 | if (aInt.HasIndexNew()) { |
2059 | aInt.Indices(nS1, nS2); |
2060 | if(aMI.Contains(nS1) && aMI.Contains(nS2)) { |
2061 | nVNew = aInt.IndexNew(); |
4e57c75e |
2062 | aMVStick.Add(nVNew); |
2063 | aMVEF.Add(nVNew); |
2064 | } |
2065 | } |
2066 | } |
2067 | } |
2068 | |
2069 | //======================================================================= |
78c66ef1 |
2070 | // function: GetFullShapeMap |
4e57c75e |
2071 | // purpose: |
2072 | //======================================================================= |
78c66ef1 |
2073 | void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF, |
1155d05a |
2074 | TColStd_MapOfInteger& aMI) |
4e57c75e |
2075 | { |
1155d05a |
2076 | TColStd_ListIteratorOfListOfInteger aIt; |
78c66ef1 |
2077 | Standard_Integer nS; |
2078 | // |
2079 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF); |
1155d05a |
2080 | const TColStd_ListOfInteger& aLI = aSI.SubShapes(); |
78c66ef1 |
2081 | // |
4e57c75e |
2082 | aMI.Add(nF); |
78c66ef1 |
2083 | aIt.Initialize(aLI); |
2084 | for (; aIt.More(); aIt.Next()) { |
2085 | nS = aIt.Value(); |
2086 | aMI.Add(nS); |
4e57c75e |
2087 | } |
2088 | } |
2089 | |
2090 | //======================================================================= |
2091 | // function: RemoveUsedVertices |
2092 | // purpose: |
2093 | //======================================================================= |
2094 | void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC, |
1155d05a |
2095 | TColStd_MapOfInteger& aMV) |
4e57c75e |
2096 | { |
2097 | if (!aMV.Extent()) { |
2098 | return; |
2099 | } |
2100 | Standard_Integer nV; |
2101 | BOPDS_Pave aPave; |
2102 | BOPDS_ListIteratorOfListOfPave aItLP; |
2103 | // |
2104 | Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1(); |
2105 | const BOPDS_ListOfPave& aLP = aPB->ExtPaves(); |
2106 | aItLP.Initialize(aLP); |
2107 | for (;aItLP.More();aItLP.Next()) { |
2108 | aPave = aItLP.Value(); |
2109 | nV = aPave.Index(); |
2110 | aMV.Remove(nV); |
2111 | } |
2112 | } |
2113 | |
2114 | //======================================================================= |
2115 | //function : PutPaveOnCurve |
2116 | //purpose : |
2117 | //======================================================================= |
0d0481c7 |
2118 | void BOPAlgo_PaveFiller::PutPaveOnCurve |
465d1fba |
2119 | (const Standard_Integer nV, |
2120 | const Standard_Real aTolR3D, |
0d0481c7 |
2121 | const BOPDS_Curve& aNC, |
1155d05a |
2122 | const TColStd_MapOfInteger& aMI, |
2123 | TColStd_DataMapOfIntegerReal& aMVTol, |
2124 | TColStd_DataMapOfIntegerListOfInteger& aDMVLV, |
465d1fba |
2125 | const Standard_Integer iCheckExtend) |
4e57c75e |
2126 | { |
2127 | Standard_Boolean bIsVertexOnLine; |
0d0481c7 |
2128 | Standard_Real aT; |
4e57c75e |
2129 | // |
787c4320 |
2130 | const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV))); |
0d0481c7 |
2131 | const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First(); |
4e57c75e |
2132 | const IntTools_Curve& aIC = aNC.Curve(); |
2133 | // |
0d0481c7 |
2134 | Standard_Real aTolV = (aMVTol.IsBound(nV) ? aMVTol(nV) : BRep_Tool::Tolerance(aV)); |
2135 | |
2136 | bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT); |
78c66ef1 |
2137 | if (!bIsVertexOnLine && iCheckExtend) { |
787c4320 |
2138 | ExtendedTolerance(nV, aMI, aTolV, iCheckExtend); |
0d0481c7 |
2139 | bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT); |
78c66ef1 |
2140 | } |
2141 | // |
4e57c75e |
2142 | if (bIsVertexOnLine) { |
787c4320 |
2143 | // check if aPB contains the parameter aT |
2144 | Standard_Boolean bExist; |
0d0481c7 |
2145 | Standard_Integer nVUsed; |
2146 | Standard_Real aPTol, aDTol; |
4e57c75e |
2147 | // |
787c4320 |
2148 | aDTol = 1.e-12; |
4e57c75e |
2149 | // |
787c4320 |
2150 | GeomAdaptor_Curve aGAC(aIC.Curve()); |
24542bc0 |
2151 | aPTol = aGAC.Resolution(Max(aTolR3D, aTolV)); |
b4109929 |
2152 | // |
0d0481c7 |
2153 | bExist = aPB->ContainsParameter(aT, aPTol, nVUsed); |
787c4320 |
2154 | if (bExist) { |
2155 | // use existing pave |
1155d05a |
2156 | TColStd_ListOfInteger* pList = aDMVLV.ChangeSeek(nVUsed); |
0d0481c7 |
2157 | if (!pList) { |
1155d05a |
2158 | pList = aDMVLV.Bound(nVUsed, TColStd_ListOfInteger()); |
0d0481c7 |
2159 | pList->Append(nVUsed); |
2160 | if (!aMVTol.IsBound(nVUsed)) { |
2161 | const TopoDS_Vertex& aVUsed = (*(TopoDS_Vertex *)(&myDS->Shape(nVUsed))); |
2162 | aTolV = BRep_Tool::Tolerance(aVUsed); |
2163 | aMVTol.Bind(nVUsed, aTolV); |
2164 | } |
2165 | } |
6769ec6b |
2166 | // avoid repeated elements in the list |
1155d05a |
2167 | TColStd_ListIteratorOfListOfInteger aItLI(*pList); |
6769ec6b |
2168 | for (; aItLI.More(); aItLI.Next()) { |
2169 | if (aItLI.Value() == nV) { |
2170 | break; |
2171 | } |
2172 | } |
2173 | if (!aItLI.More()) { |
2174 | pList->Append(nV); |
2175 | } |
2176 | // save initial tolerance for the vertex |
0d0481c7 |
2177 | if (!aMVTol.IsBound(nV)) { |
2178 | aTolV = BRep_Tool::Tolerance(aV); |
2179 | aMVTol.Bind(nV, aTolV); |
2180 | } |
787c4320 |
2181 | } |
2182 | else { |
2183 | // add new pave |
2184 | BOPDS_Pave aPave; |
2185 | aPave.SetIndex(nV); |
2186 | aPave.SetParameter(aT); |
2187 | aPB->AppendExtPave(aPave); |
2188 | // |
0d0481c7 |
2189 | gp_Pnt aP1 = aGAC.Value(aT); |
2190 | aTolV = BRep_Tool::Tolerance(aV); |
2191 | gp_Pnt aP2 = BRep_Tool::Pnt(aV); |
2192 | Standard_Real aDist = aP1.Distance(aP2); |
2193 | if (aDist > aTolV) { |
2194 | BRep_Builder().UpdateVertex(aV, aDist + aDTol); |
2195 | // |
2196 | if (!aMVTol.IsBound(nV)) { |
2197 | aMVTol.Bind(nV, aTolV); |
2198 | } |
2199 | // |
2200 | BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV); |
2201 | Bnd_Box& aBoxDS=aSIDS.ChangeBox(); |
2202 | BRepBndLib::Add(aV, aBoxDS); |
2203 | aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion()); |
b4109929 |
2204 | } |
2205 | } |
4e57c75e |
2206 | } |
2207 | } |
2208 | |
2209 | //======================================================================= |
0d0481c7 |
2210 | //function : ProcessExistingPaveBlocks |
4e57c75e |
2211 | //purpose : |
2212 | //======================================================================= |
3510db62 |
2213 | void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks |
4e57c75e |
2214 | (const Standard_Integer theInt, |
decdfc94 |
2215 | const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn, |
1155d05a |
2216 | const TColStd_DataMapOfIntegerListOfInteger& aDMBV, |
4e57c75e |
2217 | BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB, |
1155d05a |
2218 | TopTools_DataMapOfShapeInteger& aMVI, |
4e57c75e |
2219 | BOPDS_MapOfPaveBlock& aMPB) |
2220 | { |
3285a59a |
2221 | if (aDMBV.IsEmpty()) { |
2222 | return; |
2223 | } |
2224 | // |
3510db62 |
2225 | Standard_Real aT, dummy; |
3285a59a |
2226 | Standard_Integer i, nV, nE, iC, aNbPB, iFlag; |
1155d05a |
2227 | TColStd_ListIteratorOfListOfInteger aItLI; |
2228 | TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV; |
4e57c75e |
2229 | // |
3285a59a |
2230 | BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF(); |
4e57c75e |
2231 | BOPDS_InterfFF& aFF = aFFs(theInt); |
3285a59a |
2232 | BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves(); |
2233 | // |
2234 | aNbPB = aMPBOnIn.Extent(); |
2235 | // |
2236 | aItBV.Initialize(aDMBV); |
2237 | for (; aItBV.More(); aItBV.Next()) { |
2238 | iC = aItBV.Key(); |
1155d05a |
2239 | const TColStd_ListOfInteger& aLBV = aItBV.Value(); |
4e57c75e |
2240 | // |
3285a59a |
2241 | BOPDS_Curve& aNC = aVC.ChangeValue(iC); |
2242 | BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks(); |
2243 | // |
2244 | aItLI.Initialize(aLBV); |
2245 | for (; aItLI.More(); aItLI.Next()) { |
2246 | nV = aItLI.Value(); |
2247 | const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV); |
2248 | const Bnd_Box& aBoxV=aSIV.Box(); |
2249 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape(); |
2250 | if (!aMVI.IsBound(aV)) { |
4e57c75e |
2251 | continue; |
2252 | } |
4e57c75e |
2253 | // |
3285a59a |
2254 | for (i = 1; i <= aNbPB; ++i) { |
2255 | const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn(i); |
2256 | if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) { |
2257 | continue; |
2258 | } |
2259 | // |
2260 | if (aMPB.Contains(aPB)) { |
2261 | continue; |
2262 | } |
3510db62 |
2263 | if (myDS->ShapeInfo(aPB->OriginalEdge()).HasFlag()) { // skip degenerated edges |
2264 | continue; |
2265 | } |
3285a59a |
2266 | // |
2267 | nE = aPB->Edge(); |
2268 | const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE); |
2269 | const Bnd_Box& aBoxE = aSIE.Box(); |
2270 | // |
2271 | if (aBoxV.IsOut(aBoxE)) { |
2272 | continue; |
2273 | } |
2274 | // |
4e57c75e |
2275 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape(); |
2276 | // |
0d0481c7 |
2277 | iFlag = myContext->ComputeVE(aV, aE, aT, dummy, myFuzzyValue); |
4e57c75e |
2278 | if (!iFlag) { |
2279 | aMPB.Add(aPB); |
3285a59a |
2280 | PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC); |
4e57c75e |
2281 | } |
2282 | } |
2283 | } |
2284 | } |
2285 | } |
4e57c75e |
2286 | //======================================================================= |
2287 | //function : UpdateExistingPaveBlocks |
2288 | //purpose : |
2289 | //======================================================================= |
3510db62 |
2290 | void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks |
2291 | (const Handle(BOPDS_PaveBlock)& aPBf, |
2292 | BOPDS_ListOfPaveBlock& aLPB, |
2293 | const Standard_Integer nF1, |
2294 | const Standard_Integer nF2) |
4e57c75e |
2295 | { |
01b5b3df |
2296 | if (!aLPB.Extent()) { |
2297 | return; |
2298 | } |
2299 | // |
4e57c75e |
2300 | Standard_Integer nE; |
2301 | Standard_Boolean bCB; |
2302 | Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n; |
2303 | Handle(BOPDS_CommonBlock) aCB; |
2304 | BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2; |
4e57c75e |
2305 | // |
4e57c75e |
2306 | BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1); |
2307 | BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2); |
2308 | // |
2309 | BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.ChangePaveBlocksOn(); |
2310 | BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.ChangePaveBlocksIn(); |
2311 | BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn(); |
2312 | BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn(); |
2313 | // |
01b5b3df |
2314 | // 1. Remove old pave blocks |
5a77460e |
2315 | const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf); |
4e57c75e |
2316 | bCB = !aCB1.IsNull(); |
2317 | BOPDS_ListOfPaveBlock aLPB1; |
2318 | // |
2319 | if (bCB) { |
2320 | aLPB1.Assign(aCB1->PaveBlocks()); |
2321 | } else { |
2322 | aLPB1.Append(aPBf); |
2323 | } |
2324 | aIt1.Initialize(aLPB1); |
2325 | for (; aIt1.More(); aIt1.Next()) { |
2326 | aPB1 = aIt1.Value(); |
2327 | nE = aPB1->OriginalEdge(); |
2328 | // |
2329 | BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE); |
2330 | aIt2.Initialize(aLPB2); |
2331 | for (; aIt2.More(); aIt2.Next()) { |
2332 | aPB2 = aIt2.Value(); |
2333 | if (aPB1 == aPB2) { |
2334 | aLPB2.Remove(aIt2); |
2335 | break; |
2336 | } |
2337 | } |
2338 | } |
2339 | // |
01b5b3df |
2340 | // 2. Update pave blocks |
4e57c75e |
2341 | if (bCB) { |
edfa30de |
2342 | // Create new common blocks |
3285a59a |
2343 | BOPDS_ListOfPaveBlock aLPBNew; |
1155d05a |
2344 | const TColStd_ListOfInteger& aFaces = aCB1->Faces(); |
4e57c75e |
2345 | aIt.Initialize(aLPB); |
2346 | for (; aIt.More(); aIt.Next()) { |
51740958 |
2347 | const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value(); |
edfa30de |
2348 | BOPDS_Pave aPBValuePaves[2] = {aPBValue->Pave1(), aPBValue->Pave2()}; |
4e57c75e |
2349 | // |
2350 | aCB = new BOPDS_CommonBlock; |
2351 | aIt1.Initialize(aLPB1); |
2352 | for (; aIt1.More(); aIt1.Next()) { |
2353 | aPB2 = aIt1.Value(); |
2354 | nE = aPB2->OriginalEdge(); |
2355 | // |
edfa30de |
2356 | // Create new pave block |
4e57c75e |
2357 | aPB2n = new BOPDS_PaveBlock; |
edfa30de |
2358 | if (aPBValue->OriginalEdge() == nE) { |
2359 | aPB2n->SetPave1(aPBValuePaves[0]); |
2360 | aPB2n->SetPave2(aPBValuePaves[1]); |
2361 | } |
2362 | else { |
2363 | // For the different original edge compute the parameters of paves |
2364 | BOPDS_Pave aPave[2]; |
2365 | for (Standard_Integer i = 0; i < 2; ++i) { |
2366 | Standard_Integer nV = aPBValuePaves[i].Index(); |
2367 | aPave[i].SetIndex(nV); |
2368 | if (nV == aPB2->Pave1().Index()) { |
2369 | aPave[i].SetParameter(aPB2->Pave1().Parameter()); |
2370 | } |
2371 | else if (nV == aPB2->Pave2().Index()) { |
2372 | aPave[i].SetParameter(aPB2->Pave2().Parameter()); |
2373 | } |
2374 | else { |
2375 | // Compute the parameter by projecting the point |
2376 | const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV)); |
2377 | const TopoDS_Edge& aEOr = TopoDS::Edge(myDS->Shape(nE)); |
2378 | Standard_Real aTOut, aDist; |
2379 | Standard_Integer iErr = myContext->ComputeVE(aV, aEOr, aTOut, aDist, myFuzzyValue); |
2380 | if (!iErr) { |
2381 | aPave[i].SetParameter(aTOut); |
2382 | } |
2383 | else { |
2384 | // Unable to project - set the parameter of the closest boundary |
2385 | const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(aPB2->Pave1().Index())); |
2386 | const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(aPB2->Pave2().Index())); |
2387 | // |
2388 | gp_Pnt aP = BRep_Tool::Pnt(aV); |
2389 | gp_Pnt aP1 = BRep_Tool::Pnt(aV1); |
2390 | gp_Pnt aP2 = BRep_Tool::Pnt(aV2); |
2391 | // |
2392 | Standard_Real aDist1 = aP.SquareDistance(aP1); |
2393 | Standard_Real aDist2 = aP.SquareDistance(aP2); |
2394 | // |
2395 | aPave[i].SetParameter(aDist1 < aDist2 ? aPB2->Pave1().Parameter() : aPB2->Pave2().Parameter()); |
2396 | } |
2397 | } |
2398 | } |
2399 | // |
2400 | if (aPave[1].Parameter() < aPave[0].Parameter()) { |
2401 | BOPDS_Pave aPaveTmp = aPave[0]; |
2402 | aPave[0] = aPave[1]; |
2403 | aPave[1] = aPaveTmp; |
2404 | } |
2405 | // |
2406 | aPB2n->SetPave1(aPave[0]); |
2407 | aPB2n->SetPave2(aPave[1]); |
2408 | } |
2409 | // |
51740958 |
2410 | aPB2n->SetEdge(aPBValue->Edge()); |
4e57c75e |
2411 | aPB2n->SetOriginalEdge(nE); |
2412 | aCB->AddPaveBlock(aPB2n); |
5a77460e |
2413 | myDS->SetCommonBlock(aPB2n, aCB); |
4e57c75e |
2414 | myDS->ChangePaveBlocks(nE).Append(aPB2n); |
2415 | } |
3510db62 |
2416 | aCB->SetFaces(aFaces); |
4e57c75e |
2417 | // |
3285a59a |
2418 | const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First(); |
2419 | aLPBNew.Append(aPBNew); |
4e57c75e |
2420 | } |
3285a59a |
2421 | // |
2422 | aLPB = aLPBNew; |
4e57c75e |
2423 | } |
1b7ae951 |
2424 | else { |
2425 | nE = aPBf->OriginalEdge(); |
2426 | BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE); |
2427 | aIt.Initialize(aLPB); |
2428 | for (; aIt.More(); aIt.Next()) { |
2429 | aPB = aIt.Value(); |
2430 | aLPBE.Append(aPB); |
4e57c75e |
2431 | } |
2432 | } |
2433 | // |
4e57c75e |
2434 | Standard_Boolean bIn1, bIn2; |
2435 | // |
2436 | bIn1 = aMPBOn1.Contains(aPBf) || aMPBIn1.Contains(aPBf); |
2437 | bIn2 = aMPBOn2.Contains(aPBf) || aMPBIn2.Contains(aPBf); |
2438 | // |
1b7ae951 |
2439 | if (bIn1 && bIn2) { |
2440 | return; |
2441 | } |
2442 | // |
01b5b3df |
2443 | // 3. Check new pave blocks for coincidence |
1b7ae951 |
2444 | // with the opposite face. |
2445 | // In case of coincidence create common blocks |
2446 | Standard_Integer nF; |
1b7ae951 |
2447 | // |
2448 | nF = bIn1 ? nF2 : nF1; |
2449 | const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF); |
2450 | BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1; |
1b7ae951 |
2451 | // |
2452 | aIt.Initialize(aLPB); |
2453 | for (; aIt.More(); aIt.Next()) { |
51740958 |
2454 | Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue(); |
2455 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge()); |
1b7ae951 |
2456 | // |
2457 | IntTools_EdgeFace anEF; |
2458 | anEF.SetEdge(aE); |
2459 | anEF.SetFace(aF); |
0d0481c7 |
2460 | anEF.SetFuzzyValue(myFuzzyValue); |
51740958 |
2461 | anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter()); |
1b7ae951 |
2462 | anEF.SetContext(myContext); |
2463 | anEF.Perform(); |
4e57c75e |
2464 | // |
1b7ae951 |
2465 | const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts(); |
2466 | if (aCPrts.Length() == 1) { |
2467 | Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE); |
2468 | if (bCoinc) { |
2469 | if (bCB) { |
51740958 |
2470 | aCB = myDS->CommonBlock(aPBChangeValue); |
1b7ae951 |
2471 | } else { |
2472 | aCB = new BOPDS_CommonBlock; |
51740958 |
2473 | aCB->AddPaveBlock(aPBChangeValue); |
2474 | myDS->SetCommonBlock(aPBChangeValue, aCB); |
1b7ae951 |
2475 | } |
2476 | aCB->AddFace(nF); |
2477 | // |
51740958 |
2478 | aMPBIn.Add(aPBChangeValue); |
1b7ae951 |
2479 | } |
4e57c75e |
2480 | } |
2481 | } |
2482 | } |
4e57c75e |
2483 | //======================================================================= |
2484 | // function: PutClosingPaveOnCurve |
2485 | // purpose: |
2486 | //======================================================================= |
3510db62 |
2487 | void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC) |
4e57c75e |
2488 | { |
86218548 |
2489 | const IntTools_Curve& aIC = aNC.Curve(); |
2490 | const Handle(Geom_Curve)& aC3D = aIC.Curve(); |
2491 | // check 3d curve |
2492 | if (aC3D.IsNull()) |
4e57c75e |
2493 | return; |
86218548 |
2494 | |
2495 | // check bounds |
2496 | if (!aIC.HasBounds()) |
4e57c75e |
2497 | return; |
86218548 |
2498 | |
2499 | // check closeness |
2500 | Standard_Real aT[2]; |
2501 | gp_Pnt aP[2]; |
2502 | aIC.Bounds(aT[0], aT[1], aP[0], aP[1]); |
2503 | |
2504 | // Find the pave which has been put at one of the ends |
2505 | Standard_Integer nV = -1; |
2506 | // Keep the opposite parameter |
2507 | Standard_Real aTOp = 0.; |
2508 | |
2509 | Standard_Boolean bFound = Standard_False; |
2510 | |
2511 | Handle(BOPDS_PaveBlock)& aPB = aNC.ChangePaveBlock1(); |
2512 | BOPDS_ListOfPave& aLP = aPB->ChangeExtPaves(); |
2513 | BOPDS_ListIteratorOfListOfPave aItLP(aLP); |
2514 | for (; aItLP.More() && !bFound; aItLP.Next()) |
2515 | { |
2516 | const BOPDS_Pave& aPC = aItLP.Value(); |
2517 | Standard_Real aTC = aPC.Parameter(); |
2518 | for (Standard_Integer j = 0; j < 2; ++j) |
2519 | { |
2520 | if (Abs(aTC - aT[j]) < Precision::PConfusion()) |
2521 | { |
2522 | nV = aPC.Index(); |
2523 | aTOp = (!j) ? aT[1] : aT[0]; |
2524 | bFound = Standard_True; |
4e57c75e |
2525 | break; |
2526 | } |
2527 | } |
2528 | } |
86218548 |
2529 | |
2530 | if (!bFound) |
2531 | return; |
2532 | |
2533 | // Check if the curve is closed using the tolerance |
2534 | // of found vertex |
2535 | const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV)); |
2536 | const Standard_Real aTolV = BRep_Tool::Tolerance(aV); |
2537 | |
2538 | Standard_Real aDist = aP[0].Distance(aP[1]); |
2539 | if (aDist > aTolV) |
2540 | return; |
2541 | |
2542 | // Check if there will be valid range on the curve |
2543 | Standard_Real aFirst, aLast; |
2544 | if (!BRepLib::FindValidRange(GeomAdaptor_Curve(aIC.Curve()), aIC.Tolerance(), |
2545 | aT[0], aP[0], aTolV, |
2546 | aT[1], aP[1], aTolV, |
2547 | aFirst, aLast)) |
2548 | { |
2549 | return; |
2550 | } |
2551 | |
2552 | // Add closing pave to the curve |
2553 | BOPDS_Pave aPave; |
2554 | aPave.SetIndex(nV); |
2555 | aPave.SetParameter(aTOp); |
2556 | aLP.Append(aPave); |
4e57c75e |
2557 | } |
4e57c75e |
2558 | //======================================================================= |
2559 | //function : PreparePostTreatFF |
2560 | //purpose : |
2561 | //======================================================================= |
3510db62 |
2562 | void BOPAlgo_PaveFiller::PreparePostTreatFF |
4e57c75e |
2563 | (const Standard_Integer aInt, |
3285a59a |
2564 | const Standard_Integer aCur, |
4e57c75e |
2565 | const Handle(BOPDS_PaveBlock)& aPB, |
2566 | BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB, |
1155d05a |
2567 | TopTools_DataMapOfShapeInteger& aMVI, |
3285a59a |
2568 | BOPDS_ListOfPaveBlock& aLPBC) |
4e57c75e |
2569 | { |
3285a59a |
2570 | Standard_Integer nV1, nV2; |
4e57c75e |
2571 | // |
4e57c75e |
2572 | aLPBC.Append(aPB); |
2573 | // |
2574 | aPB->Indices(nV1, nV2); |
2575 | const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
2576 | const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
2577 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge()); |
2578 | // Keep info for post treatment |
2579 | BOPDS_CoupleOfPaveBlocks aCPB; |
2580 | aCPB.SetIndexInterf(aInt); |
3285a59a |
2581 | aCPB.SetIndex(aCur); |
4e57c75e |
2582 | aCPB.SetPaveBlock1(aPB); |
2583 | // |
2584 | aMSCPB.Add(aE, aCPB); |
2585 | aMVI.Bind(aV1, nV1); |
2586 | aMVI.Bind(aV2, nV2); |
2587 | } |
2588 | |
b4109929 |
2589 | //======================================================================= |
2590 | //function : CheckPlanes |
2591 | //purpose : |
2592 | //======================================================================= |
465d1fba |
2593 | Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes |
2594 | (const Standard_Integer nF1, |
2595 | const Standard_Integer nF2)const |
b4109929 |
2596 | { |
2597 | Standard_Boolean bToIntersect; |
af4e6dab |
2598 | Standard_Integer i, nV2, iCnt; |
1155d05a |
2599 | TColStd_MapIteratorOfMapOfInteger aIt; |
b4109929 |
2600 | // |
af4e6dab |
2601 | bToIntersect=Standard_False; |
b4109929 |
2602 | // |
af4e6dab |
2603 | const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1); |
2604 | const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2); |
b4109929 |
2605 | // |
1155d05a |
2606 | const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn(); |
2607 | const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn(); |
b4109929 |
2608 | // |
af4e6dab |
2609 | iCnt=0; |
2610 | for (i=0; (i<2 && !bToIntersect); ++i) { |
1155d05a |
2611 | const TColStd_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn() |
af4e6dab |
2612 | : aFI2.VerticesOn(); |
2613 | // |
2614 | aIt.Initialize(aMV2); |
b4109929 |
2615 | for (; aIt.More(); aIt.Next()) { |
af4e6dab |
2616 | nV2=aIt.Value(); |
2617 | if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) { |
78c66ef1 |
2618 | ++iCnt; |
2619 | if (iCnt>1) { |
2620 | bToIntersect=!bToIntersect; |
2621 | break; |
2622 | } |
b4109929 |
2623 | } |
2624 | } |
2625 | } |
b4109929 |
2626 | // |
2627 | return bToIntersect; |
2628 | } |
4e57c75e |
2629 | //======================================================================= |
78c66ef1 |
2630 | //function : UpdatePaveBlocks |
2631 | //purpose : |
2632 | //======================================================================= |
465d1fba |
2633 | void BOPAlgo_PaveFiller::UpdatePaveBlocks |
1155d05a |
2634 | (const TColStd_DataMapOfIntegerInteger& aDMNewSD) |
78c66ef1 |
2635 | { |
0d0481c7 |
2636 | if (aDMNewSD.IsEmpty()) { |
78c66ef1 |
2637 | return; |
2638 | } |
2639 | // |
2640 | Standard_Integer nSp, aNbPBP, nV[2], i, j; |
2641 | Standard_Real aT[2]; |
2642 | Standard_Boolean bCB, bRebuild; |
2643 | BOPDS_ListIteratorOfListOfPaveBlock aItPB; |
2644 | BOPDS_MapOfPaveBlock aMPB; |
1155d05a |
2645 | TColStd_MapOfInteger aMicroEdges; |
78c66ef1 |
2646 | // |
24542bc0 |
2647 | BOPDS_ListOfPaveBlock anAllPBs; |
2648 | |
2649 | // Get pave blocks of section edges |
2650 | BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF(); |
1155d05a |
2651 | Standard_Integer aNbFF = aFFs.Length(); |
24542bc0 |
2652 | for (i = 0; i < aNbFF; ++i) |
2653 | { |
2654 | const BOPDS_InterfFF& aFF = aFFs(i); |
2655 | const BOPDS_VectorOfCurve& aVNC = aFF.Curves(); |
1155d05a |
2656 | Standard_Integer aNbC = aVNC.Length(); |
24542bc0 |
2657 | for (j = 0; j < aNbC; ++j) |
2658 | { |
2659 | const BOPDS_Curve& aNC = aVNC(j); |
2660 | const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks(); |
2661 | aItPB.Initialize(aLPBC); |
2662 | for (; aItPB.More(); aItPB.Next()) |
2663 | anAllPBs.Append(aItPB.Value()); |
2664 | } |
2665 | } |
2666 | |
2667 | // Get pave blocks from the pool |
3510db62 |
2668 | BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool(); |
1155d05a |
2669 | aNbPBP = aPBP.Length(); |
3510db62 |
2670 | for (i = 0; i < aNbPBP; ++i) { |
2671 | BOPDS_ListOfPaveBlock& aLPB = aPBP(i); |
78c66ef1 |
2672 | aItPB.Initialize(aLPB); |
24542bc0 |
2673 | for (; aItPB.More(); aItPB.Next()) |
2674 | anAllPBs.Append(aItPB.Value()); |
2675 | } |
2676 | |
2677 | // Process all pave blocks |
2678 | aItPB.Initialize(anAllPBs); |
2679 | for (; aItPB.More(); aItPB.Next()) |
2680 | { |
2681 | Handle(BOPDS_PaveBlock) aPB = aItPB.Value(); |
2682 | const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB); |
2683 | bCB = !aCB.IsNull(); |
2684 | if (bCB) { |
2685 | aPB = aCB->PaveBlock1(); |
2686 | } |
2687 | // |
2688 | if (aMPB.Add(aPB)) { |
2689 | bRebuild = Standard_False; |
2690 | aPB->Indices(nV[0], nV[1]); |
2691 | aPB->Range(aT[0], aT[1]); |
2692 | // remember the fact if the edge had different vertices before substitution |
2693 | Standard_Boolean wasRegularEdge = (nV[0] != nV[1]); |
78c66ef1 |
2694 | // |
24542bc0 |
2695 | for (j = 0; j < 2; ++j) { |
2696 | if (aDMNewSD.IsBound(nV[j])) { |
2697 | BOPDS_Pave aPave; |
2698 | // |
2699 | nV[j] = aDMNewSD.Find(nV[j]); |
2700 | aPave.SetIndex(nV[j]); |
2701 | aPave.SetParameter(aT[j]); |
2702 | // |
2703 | bRebuild = Standard_True; |
2704 | if (!j) { |
2705 | aPB->SetPave1(aPave); |
78c66ef1 |
2706 | } |
2707 | else { |
24542bc0 |
2708 | aPB->SetPave2(aPave); |
2709 | } |
2710 | } |
2711 | } |
2712 | // |
2713 | if (bRebuild) { |
73375359 |
2714 | Standard_Integer nE = aPB->Edge(); |
2715 | // Check if the Pave Block has the edge set |
2716 | if (nE < 0) { |
2717 | // untouched edge |
2718 | nE = aPB->OriginalEdge(); |
2719 | } |
2720 | Standard_Boolean isDegEdge = myDS->ShapeInfo(nE).HasFlag(); |
24542bc0 |
2721 | if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) { |
2722 | // now edge has the same vertex on both ends; |
2723 | // check if it is not a regular closed curve. |
4bc805bf |
2724 | FillShrunkData(aPB); |
2725 | if (!aPB->HasShrunkData()) |
2726 | { |
24542bc0 |
2727 | // micro edge, so mark it for removal |
73375359 |
2728 | aMicroEdges.Add(nE); |
24542bc0 |
2729 | continue; |
78c66ef1 |
2730 | } |
24542bc0 |
2731 | } |
73375359 |
2732 | nSp = SplitEdge(nE, nV[0], aT[0], nV[1], aT[1]); |
24542bc0 |
2733 | if (bCB) |
2734 | aCB->SetEdge(nSp); |
2735 | else |
2736 | aPB->SetEdge(nSp); |
2737 | }// if (bRebuild) { |
2738 | }// if (aMPB.Add(aPB)) { |
2739 | }// for (; aItPB.More(); aItPB.Next()) { |
78c66ef1 |
2740 | aMPB.Clear(); |
3510db62 |
2741 | |
2742 | if (aMicroEdges.Extent()) |
2743 | RemovePaveBlocks(aMicroEdges); |
78c66ef1 |
2744 | } |
3510db62 |
2745 | //======================================================================= |
2746 | //function : RemovePaveBlocks |
2747 | //purpose : |
2748 | //======================================================================= |
1155d05a |
2749 | void BOPAlgo_PaveFiller::RemovePaveBlocks(const TColStd_MapOfInteger theEdges) |
3510db62 |
2750 | { |
2751 | // Remove all pave blocks referring to input edges: |
2752 | // |
2753 | // 1. from the Pave Blocks Pool |
2754 | BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool(); |
1155d05a |
2755 | Standard_Integer aNbPBP = aPBP.Length(), i; |
3510db62 |
2756 | for (i = 0; i < aNbPBP; ++i) { |
2757 | BOPDS_ListOfPaveBlock& aLPB = aPBP(i); |
2758 | // |
2759 | BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB); |
2760 | while (aItPB.More()) { |
2761 | const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value(); |
2762 | if (theEdges.Contains(aPB->Edge())) |
2763 | aLPB.Remove(aItPB); |
2764 | else |
2765 | aItPB.Next(); |
2766 | } |
2767 | } |
2768 | |
2769 | // 2. from Face Info and section curves |
1155d05a |
2770 | TColStd_MapOfInteger aMPassed; |
3510db62 |
2771 | BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF(); |
1155d05a |
2772 | Standard_Integer aNbFF = aFFs.Length(), j; |
3510db62 |
2773 | for (i = 0; i < aNbFF; ++i) { |
2774 | BOPDS_InterfFF& aFF = aFFs(i); |
2775 | Standard_Integer nF1, nF2; |
2776 | aFF.Indices(nF1, nF2); |
2777 | // |
2778 | // rebuild pave block maps of face info |
2779 | for (j = 0; j < 2; j++) { |
2780 | Standard_Integer nF = (j == 0 ? nF1 : nF2); |
2781 | if (!aMPassed.Add(nF)) |
2782 | continue; |
2783 | BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF); |
2784 | BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(), |
2785 | &aFI.ChangePaveBlocksOn(), &aFI.ChangePaveBlocksSc() }; |
2786 | for (Standard_Integer k = 0; k < 3; k++) { |
2787 | Standard_Integer aNbPB = aIMPB[k]->Extent(), m; |
2788 | for (m = 1; m <= aNbPB; ++m) { |
2789 | const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m); |
2790 | if (theEdges.Contains(aPB->Edge())) |
2791 | break; |
2792 | } |
2793 | if (m <= aNbPB) { |
2794 | BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k]; |
2795 | aIMPB[k]->Clear(); |
2796 | for (m = 1; m <= aNbPB; ++m) { |
2797 | const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m); |
2798 | if (!theEdges.Contains(aPB->Edge())) |
2799 | aIMPB[k]->Add(aPB); |
2800 | } |
2801 | } |
2802 | } |
2803 | } |
2804 | // remove from Section pave blocks |
2805 | BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves(); |
1155d05a |
2806 | Standard_Integer aNbC = aVNC.Length(); |
3510db62 |
2807 | for (j = 0; j < aNbC; ++j) { |
2808 | BOPDS_Curve& aNC = aVNC(j); |
2809 | BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks(); |
2810 | BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB); |
2811 | while (aItPB.More()) { |
2812 | const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value(); |
2813 | if (theEdges.Contains(aPB->Edge())) |
2814 | aLPB.Remove(aItPB); |
2815 | else |
2816 | aItPB.Next(); |
2817 | } |
2818 | } |
2819 | } |
2820 | } |
78c66ef1 |
2821 | //======================================================================= |
4e57c75e |
2822 | //function : ToleranceFF |
2823 | //purpose : Computes the TolFF according to the tolerance value and |
2824 | // types of the faces. |
2825 | //======================================================================= |
5652dc62 |
2826 | Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1, |
2827 | const BRepAdaptor_Surface& aBAS2) |
4e57c75e |
2828 | { |
5652dc62 |
2829 | Standard_Real aTol1 = aBAS1.Tolerance(); |
2830 | Standard_Real aTol2 = aBAS2.Tolerance(); |
2831 | Standard_Real aTolFF = Max(aTol1, aTol2); |
4e57c75e |
2832 | // |
5652dc62 |
2833 | Standard_Boolean isAna1, isAna2; |
b4109929 |
2834 | isAna1 = (aBAS1.GetType() == GeomAbs_Plane || |
2835 | aBAS1.GetType() == GeomAbs_Cylinder || |
2836 | aBAS1.GetType() == GeomAbs_Cone || |
2837 | aBAS1.GetType() == GeomAbs_Sphere || |
2838 | aBAS1.GetType() == GeomAbs_Torus); |
4e57c75e |
2839 | // |
b4109929 |
2840 | isAna2 = (aBAS2.GetType() == GeomAbs_Plane || |
2841 | aBAS2.GetType() == GeomAbs_Cylinder || |
2842 | aBAS2.GetType() == GeomAbs_Cone || |
2843 | aBAS2.GetType() == GeomAbs_Sphere || |
2844 | aBAS2.GetType() == GeomAbs_Torus); |
4e57c75e |
2845 | // |
b4109929 |
2846 | if (!isAna1 || !isAna2) { |
2847 | aTolFF = Max(aTolFF, 5.e-6); |
2848 | } |
5652dc62 |
2849 | return aTolFF; |
4e57c75e |
2850 | } |
3510db62 |
2851 | //======================================================================= |
2852 | //function : UpdateBlocksWithSharedVertices |
2853 | //purpose : |
2854 | //======================================================================= |
2855 | void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices() |
2856 | { |
2857 | if (!myNonDestructive) { |
2858 | return; |
2859 | } |
2860 | // |
3510db62 |
2861 | Standard_Integer aNbFF; |
2862 | // |
2863 | BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); |
1155d05a |
2864 | aNbFF=aFFs.Length(); |
3510db62 |
2865 | if (!aNbFF) { |
2866 | return; |
2867 | } |
2868 | // |
2869 | Standard_Boolean bOnCurve, bHasShapeSD; |
2870 | Standard_Integer i, nF1, nF2, aNbC, j, nV, nVSD; |
5652dc62 |
2871 | Standard_Real aTolV; |
1155d05a |
2872 | TColStd_MapOfInteger aMF; |
3510db62 |
2873 | // |
2874 | for (i=0; i<aNbFF; ++i) { |
2875 | BOPDS_InterfFF& aFF=aFFs(i); |
2876 | // |
2877 | BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves(); |
1155d05a |
2878 | aNbC=aVC.Length(); |
3510db62 |
2879 | if (!aNbC) { |
2880 | continue; |
2881 | } |
2882 | // |
2883 | aFF.Indices(nF1, nF2); |
3510db62 |
2884 | // |
2885 | if (aMF.Add(nF1)) { |
2886 | myDS->UpdateFaceInfoOn(nF1); |
2887 | } |
2888 | if (aMF.Add(nF2)) { |
2889 | myDS->UpdateFaceInfoOn(nF2); |
2890 | } |
2891 | // |
2892 | // Collect old vertices that are shared for nF1, nF2 ->aMI; |
1155d05a |
2893 | TColStd_MapOfInteger aMI; |
2894 | TColStd_MapIteratorOfMapOfInteger aItMI; |
3510db62 |
2895 | // |
2896 | BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1); |
2897 | BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2); |
2898 | // |
1155d05a |
2899 | const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn(); |
2900 | const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn(); |
2901 | const TColStd_MapOfInteger& aMVOn2=aFI2.VerticesOn(); |
2902 | const TColStd_MapOfInteger& aMVIn2=aFI2.VerticesIn(); |
3510db62 |
2903 | // |
2904 | for (j=0; j<2; ++j) { |
1155d05a |
2905 | const TColStd_MapOfInteger& aMV1=(!j) ? aMVOn1 : aMVIn1; |
3510db62 |
2906 | aItMI.Initialize(aMV1); |
2907 | for (; aItMI.More(); aItMI.Next()) { |
2908 | nV=aItMI.Value(); |
2909 | if (myDS->IsNewShape(nV)) { |
2910 | continue; |
2911 | } |
2912 | if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) { |
2913 | aMI.Add(nV); |
2914 | } |
2915 | } |
2916 | } |
2917 | // |
2918 | // Try to put vertices aMI on curves |
2919 | for (j=0; j<aNbC; ++j) { |
2920 | BOPDS_Curve& aNC=aVC.ChangeValue(j); |
5652dc62 |
2921 | Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance()); |
3510db62 |
2922 | // |
2923 | aItMI.Initialize(aMI); |
2924 | for (; aItMI.More(); aItMI.Next()) { |
2925 | nV=aItMI.Value(); |
2926 | // |
2927 | bHasShapeSD=myDS->HasShapeSD(nV, nVSD); |
2928 | if (bHasShapeSD) { |
2929 | continue; |
2930 | } |
2931 | // |
2932 | bOnCurve=EstimatePaveOnCurve(nV, aNC, aTolR3D); |
2933 | if (!bOnCurve) { |
2934 | continue; |
2935 | } |
2936 | // |
2937 | const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV)); |
2938 | aTolV=BRep_Tool::Tolerance(aV); |
2939 | // |
2940 | UpdateVertex(nV, aTolV); |
2941 | } |
2942 | }//for (j=0; j<aNbC; ++j) { |
2943 | }//for (i=0; i<aNbFF; ++i) { |
2944 | // |
2945 | UpdateCommonBlocksWithSDVertices(); |
2946 | } |
2947 | //======================================================================= |
2948 | //function : EstimatePaveOnCurve |
2949 | //purpose : |
2950 | //======================================================================= |
2951 | Standard_Boolean BOPAlgo_PaveFiller::EstimatePaveOnCurve |
2952 | (const Standard_Integer nV, |
2953 | const BOPDS_Curve& aNC, |
2954 | const Standard_Real aTolR3D) |
2955 | { |
2956 | Standard_Boolean bIsVertexOnLine; |
2957 | Standard_Real aT; |
2958 | // |
2959 | const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV)); |
2960 | const IntTools_Curve& aIC=aNC.Curve(); |
2961 | // |
2962 | bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT); |
2963 | return bIsVertexOnLine; |
2964 | } |
2965 | |
2966 | //======================================================================= |
2967 | //function : CorrectToleranceOfSE |
2968 | //purpose : |
2969 | //======================================================================= |
2970 | void BOPAlgo_PaveFiller::CorrectToleranceOfSE() |
2971 | { |
2972 | BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF(); |
2973 | NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs; |
1155d05a |
2974 | TColStd_MapOfInteger aMVIToReduce; |
edfa30de |
2975 | // Fence map to avoid repeated checking of the same edge |
2976 | BOPDS_MapOfPaveBlock aMPB; |
3510db62 |
2977 | // |
5be33fb6 |
2978 | // 1. iterate on all sections F-F |
1155d05a |
2979 | Standard_Integer aNb = aFFs.Length(), i; |
3510db62 |
2980 | for (i = 0; i < aNb; ++i) { |
01b5b3df |
2981 | BOPDS_InterfFF& aFF = aFFs(i); |
5652dc62 |
2982 | // |
01b5b3df |
2983 | BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves(); |
1155d05a |
2984 | Standard_Integer aNbC = aVNC.Length(), k; |
24542bc0 |
2985 | for (k = 0; k < aNbC; ++k) { |
01b5b3df |
2986 | BOPDS_Curve& aNC = aVNC(k); |
2987 | BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks(); |
24542bc0 |
2988 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); |
01b5b3df |
2989 | for (; aItLPB.More(); ) { |
24542bc0 |
2990 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
2991 | Standard_Integer nE; |
5be33fb6 |
2992 | if (!aPB->HasEdge(nE)) { |
01b5b3df |
2993 | aLPB.Remove(aItLPB); |
24542bc0 |
2994 | continue; |
2995 | } |
5be33fb6 |
2996 | // |
edfa30de |
2997 | if (!aMPB.Add(aPB)) { |
2998 | aItLPB.Next(); |
2999 | continue; |
3000 | } |
3001 | // |
5be33fb6 |
3002 | Standard_Boolean bIsReduced = Standard_False; |
5652dc62 |
3003 | if (aPB->OriginalEdge() < 0) { |
3004 | // It is possible that due to small angle between faces the |
3005 | // common zone between faces can be large and the tangential |
3006 | // tolerance of the curve will be large as well. |
3007 | // Here we're trying to reduce the tolerance of the section |
3008 | // edge using the valid tolerance of the edge. |
3009 | // Note, that if the pave block has created common block with |
3010 | // other edges its valid tolerance could have been changed to |
3011 | // cover all edges in common block (see PostTreatFF() method). |
3012 | Standard_Real aTolC = aNC.Tolerance(); |
3013 | Standard_Real aTolTang = aNC.TangentialTolerance(); |
3014 | if (aTolC < aTolTang) { |
3015 | const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE)); |
3016 | Standard_Real aTolE = BRep_Tool::Tolerance(aE); |
3017 | if (aTolC < aTolE) { |
3018 | // reduce edge tolerance |
3019 | reinterpret_cast<BRep_TEdge*>(aE.TShape().operator->())->Tolerance(aTolC); |
3020 | bIsReduced = Standard_True; |
3021 | } |
3510db62 |
3022 | } |
5be33fb6 |
3023 | } |
3024 | // |
24542bc0 |
3025 | // fill in the map vertex index - pave blocks |
3026 | for (Standard_Integer j=0; j < 2; j++) { |
5be33fb6 |
3027 | Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index()); |
8ae442a8 |
3028 | myDS->HasShapeSD(nV, nV); |
24542bc0 |
3029 | BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV); |
3030 | if (!pPBList) { |
3031 | pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock())); |
3032 | } |
5be33fb6 |
3033 | pPBList->Append(aPB); |
3034 | if (bIsReduced) { |
3035 | aMVIToReduce.Add(nV); |
3036 | } |
3037 | } |
01b5b3df |
3038 | aItLPB.Next(); |
5be33fb6 |
3039 | } |
3040 | } |
3041 | } |
3042 | // |
3043 | if (aMVIToReduce.IsEmpty()) { |
3044 | return; |
3045 | } |
3046 | // |
3047 | // 2. try to reduce tolerances of connected vertices |
3048 | // 2.1 find all other edges containing these connected vertices to avoid |
3049 | // reducing the tolerance to the value less than the tolerances of edges, |
3050 | // i.e. minimal tolerance for the vertex is the max tolerance of the |
3051 | // edges containing this vertex |
1155d05a |
3052 | TColStd_DataMapOfIntegerReal aMVITol; |
5be33fb6 |
3053 | BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool(); |
1155d05a |
3054 | aNb = aPBP.Length(); |
5be33fb6 |
3055 | for (i = 0; i < aNb; ++i) { |
3056 | const BOPDS_ListOfPaveBlock& aLPB = aPBP(i); |
3057 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); |
3058 | for (; aItLPB.More(); aItLPB.Next()) { |
3059 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
3060 | Standard_Integer nE; |
3061 | if (!aPB->HasEdge(nE)) { |
3062 | continue; |
3063 | } |
3064 | const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE)); |
3065 | Standard_Real aTolE = BRep_Tool::Tolerance(aE); |
3066 | // |
3067 | Standard_Integer nV[2]; |
3068 | aPB->Indices(nV[0], nV[1]); |
3069 | // |
3070 | for (Standard_Integer j = 0; j < 2; j++) { |
3071 | if (aMVIToReduce.Contains(nV[j])) { |
3072 | Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]); |
3073 | if (!aMaxTol) { |
3074 | aMVITol.Bind(nV[j], aTolE); |
3075 | } |
3076 | else if (aTolE > *aMaxTol) { |
3077 | *aMaxTol = aTolE; |
3510db62 |
3078 | } |
3079 | } |
3080 | } |
3081 | } |
3082 | } |
5be33fb6 |
3083 | // |
3084 | // 2.2 reduce tolerances if possible |
3510db62 |
3085 | aNb = aMVIPBs.Extent(); |
3086 | for (i = 1; i <= aNb; ++i) { |
3087 | Standard_Integer nV = aMVIPBs.FindKey(i); |
5be33fb6 |
3088 | if (!aMVIToReduce.Contains(nV)) { |
3089 | continue; |
3090 | } |
3091 | // |
3510db62 |
3092 | const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV)); |
5be33fb6 |
3093 | Standard_Real aTolV = BRep_Tool::Tolerance(aV); |
3094 | Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.; |
3095 | // it makes no sense to compute the real tolerance if it is |
3096 | // impossible to reduce the tolerance at least 0.1% of the current value |
3097 | if (aTolV - aMaxTol < 0.001 * aTolV) { |
3098 | continue; |
3099 | } |
3510db62 |
3100 | // |
3101 | // compute the maximal distance from the vertex to the adjacent edges |
5be33fb6 |
3102 | gp_Pnt aP = BRep_Tool::Pnt(aV); |
3103 | // |
8ae442a8 |
3104 | // Avoid repeated checks |
3105 | BOPDS_MapOfPaveBlock aMPBFence; |
3106 | // |
3510db62 |
3107 | const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i); |
3108 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); |
3109 | for (; aItLPB.More(); aItLPB.Next()) { |
3110 | const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); |
8ae442a8 |
3111 | if (!aMPBFence.Add(aPB)) { |
3112 | continue; |
3113 | } |
3510db62 |
3114 | Standard_Integer nE = aPB->Edge(); |
3115 | const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE)); |
3510db62 |
3116 | BRepAdaptor_Curve aC(aE); |
8ae442a8 |
3117 | for (Standard_Integer iPave = 0; iPave < 2; ++iPave) { |
3118 | const BOPDS_Pave& aPave = !iPave ? aPB->Pave1() : aPB->Pave2(); |
3119 | Standard_Integer nVSD = aPave.Index(); |
3120 | myDS->HasShapeSD(nVSD, nVSD); |
3121 | if (nVSD != nV) { |
3122 | continue; |
3123 | } |
3124 | // |
3125 | gp_Pnt aPonE = aC.Value(aPave.Parameter()); |
3126 | Standard_Real aDist = aP.Distance(aPonE); |
3127 | aDist += BRep_Tool::Tolerance(aE); |
3128 | if (aDist > aMaxTol) { |
3129 | aMaxTol = aDist; |
3130 | } |
3510db62 |
3131 | } |
3132 | } |
5be33fb6 |
3133 | // |
3510db62 |
3134 | if (aMaxTol < aTolV) { |
3135 | reinterpret_cast<BRep_TVertex*>(aV.TShape().operator->())->Tolerance(aMaxTol); |
3136 | } |
3137 | } |
3138 | } |
32e849eb |
3139 | |
3140 | //======================================================================= |
3141 | //function : PutSEInOtherFaces |
3142 | //purpose : |
3143 | //======================================================================= |
3144 | void BOPAlgo_PaveFiller::PutSEInOtherFaces() |
3145 | { |
3146 | // Try to intersect each section edge with the faces |
3147 | // not participated in its creation |
3148 | // |
3149 | // 1. Get all section edges |
3150 | BOPDS_IndexedMapOfPaveBlock aMPBScAll; |
3151 | // |
3152 | BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF(); |
1155d05a |
3153 | Standard_Integer i, j, aNbFF = aFFs.Length(); |
32e849eb |
3154 | // |
3155 | for (i = 0; i < aNbFF; ++i) { |
3156 | const BOPDS_VectorOfCurve& aVNC = aFFs(i).Curves(); |
1155d05a |
3157 | Standard_Integer aNbC = aVNC.Length(); |
32e849eb |
3158 | for (j = 0; j < aNbC; ++j) { |
3159 | const BOPDS_ListOfPaveBlock& aLPBC = aVNC(j).PaveBlocks(); |
3160 | BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPBC); |
3161 | for (; aItPB.More(); aItPB.Next()) { |
3162 | aMPBScAll.Add(aItPB.Value()); |
3163 | } |
3164 | } |
3165 | } |
3166 | // |
3167 | Standard_Integer aNbPBSc = aMPBScAll.Extent(); |
3168 | // |
3169 | // 2. Loop for all faces and check each section curve |
3170 | Standard_Integer aNbS = myDS->NbSourceShapes(); |
3171 | for (i = 0; i < aNbS; ++i) { |
3172 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
3173 | if (aSI.ShapeType() != TopAbs_FACE) { |
3174 | continue; |
3175 | } |
3176 | // |
3177 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape())); |
3178 | BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(i); |
3179 | // |
3180 | // IN edges to add new ones |
3181 | BOPDS_IndexedMapOfPaveBlock& aMFPBIn = aFI.ChangePaveBlocksIn(); |
3182 | // Section edges to check the participation of the face |
3183 | const BOPDS_IndexedMapOfPaveBlock& aMFPBSc = aFI.PaveBlocksSc(); |
3184 | // |
3185 | // Get vertices of the face to check that vertices of the |
3186 | // processed section edge belong to the face |
1155d05a |
3187 | TColStd_MapOfInteger aMFVerts; |
32e849eb |
3188 | // Get vertices from ON, IN and Sc pave blocks of the face |
3189 | for (j = 0; j < 3; ++j) { |
3190 | const BOPDS_IndexedMapOfPaveBlock& aMPB = |
3191 | !j ? aFI.PaveBlocksOn() : (j == 1 ? aMFPBIn : aMFPBSc); |
3192 | Standard_Integer aNbPB = aMPB.Extent(); |
3193 | for (Standard_Integer k = 1; k <= aNbPB; ++k) { |
3194 | const Handle(BOPDS_PaveBlock)& aPB = aMPB(k); |
3195 | aMFVerts.Add(aPB->Pave1().Index()); |
3196 | aMFVerts.Add(aPB->Pave2().Index()); |
3197 | } |
3198 | } |
3199 | // Add ON, IN and Sc vertices of the face |
3200 | for (j = 0; j < 3; ++j) { |
1155d05a |
3201 | const TColStd_MapOfInteger& aMFV = !j ? aFI.VerticesOn() : |
32e849eb |
3202 | (j == 1 ? aFI.VerticesIn() : aFI.VerticesSc()); |
1155d05a |
3203 | TColStd_MapIteratorOfMapOfInteger aItMI(aMFV); |
32e849eb |
3204 | for (; aItMI.More(); aItMI.Next()) { |
3205 | aMFVerts.Add(aItMI.Value()); |
3206 | } |
3207 | } |
3208 | // |
3209 | // Check each section edge for possible belonging to the face |
3210 | for (j = 1; j <= aNbPBSc; ++j) { |
3211 | const Handle(BOPDS_PaveBlock)& aPB = aMPBScAll(j); |
3212 | if (aMFPBSc.Contains(aPB)) { |
3213 | continue; |
3214 | } |
3215 | // |
3216 | // Both vertices of the section edge should belong to the face |
3217 | if (!aMFVerts.Contains(aPB->Pave1().Index()) || |
3218 | !aMFVerts.Contains(aPB->Pave2().Index())) { |
3219 | continue; |
3220 | } |
3221 | // |
3222 | // Perform intersection |
3223 | const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge())); |
3224 | // |
3225 | IntTools_EdgeFace anEFInt; |
3226 | anEFInt.SetEdge(aE); |
3227 | anEFInt.SetFace(aF); |
3228 | anEFInt.SetFuzzyValue(myFuzzyValue); |
3229 | anEFInt.SetRange(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()); |
3230 | anEFInt.SetContext(myContext); |
3231 | anEFInt.UseQuickCoincidenceCheck(Standard_True); |
3232 | anEFInt.Perform(); |
3233 | // |
3234 | const IntTools_SequenceOfCommonPrts& aCPrts = anEFInt.CommonParts(); |
3235 | if ((aCPrts.Length() == 1) && (aCPrts(1).Type() == TopAbs_EDGE)) { |
3236 | Handle(BOPDS_CommonBlock) aCB; |
3237 | if (myDS->IsCommonBlock(aPB)) { |
3238 | aCB = myDS->CommonBlock(aPB); |
3239 | } |
3240 | else { |
3241 | aCB = new BOPDS_CommonBlock; |
3242 | aCB->AddPaveBlock(aPB); |
3243 | } |
3244 | // |
3245 | aCB->AddFace(i); |
3246 | // |
3247 | aMFPBIn.Add(aPB); |
3248 | } |
3249 | } |
3250 | } |
3251 | } |
bfb65235 |
3252 | |
3253 | //======================================================================= |
3254 | //function : RemoveMicroSectionEdges |
3255 | //purpose : |
3256 | //======================================================================= |
3257 | void BOPAlgo_PaveFiller::RemoveMicroSectionEdges |
3258 | (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB, |
3259 | TopTools_IndexedMapOfShape& theMicroEdges) |
3260 | { |
3261 | if (theMSCPB.IsEmpty()) |
3262 | // no section edges |
3263 | return; |
3264 | |
3265 | // Get all F/F interferences |
3266 | BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF(); |
3267 | |
3268 | // Build the new map of section edges avoiding the micro edges |
3269 | BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aSEPBMap; |
3270 | // Analyze all section edges |
3271 | Standard_Integer aNbCPB = theMSCPB.Extent(); |
3272 | for (Standard_Integer i = 1; i <= aNbCPB; ++i) |
3273 | { |
3274 | const TopoDS_Shape& aSI = theMSCPB.FindKey(i); |
3275 | const BOPDS_CoupleOfPaveBlocks& aCPB = theMSCPB(i); |
3276 | |
3277 | if (aSI.ShapeType() != TopAbs_EDGE) |
3278 | { |
3279 | // Not an edge |
3280 | aSEPBMap.Add(aSI, aCPB); |
3281 | continue; |
3282 | } |
3283 | |
3284 | // Get pave block for analysis |
3285 | const Handle(BOPDS_PaveBlock)& aPB = aCPB.PaveBlock1(); |
3286 | if (aPB->HasEdge()) |
3287 | { |
3288 | // Not a real section edge |
3289 | aSEPBMap.Add(aSI, aCPB); |
3290 | continue; |
3291 | } |
3292 | |
3293 | if (!BOPTools_AlgoTools::IsMicroEdge(TopoDS::Edge(aSI), myContext, Standard_False)) |
3294 | { |
3295 | // Normal edge |
3296 | aSEPBMap.Add(aSI, aCPB); |
3297 | continue; |
3298 | } |
3299 | |
3300 | // Micro edge is found, avoid it in the <theMSCPB> map |
3301 | // and remove from the F/F Intersection info structure |
3302 | |
3303 | // Get F/F interference which created this micro edge |
3304 | BOPDS_InterfFF& aFF = aFFs(aCPB.IndexInterf()); |
3305 | // Get curve from which this edge has been created |
3306 | BOPDS_Curve& aCurve = aFF.ChangeCurves().ChangeValue(aCPB.Index()); |
3307 | // Get all section pave blocks created from this curve |
3308 | BOPDS_ListOfPaveBlock& aLPBC = aCurve.ChangePaveBlocks(); |
3309 | // Remove pave block from the list |
3310 | for (BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC); it.More(); it.Next()) |
3311 | { |
3312 | if (it.Value() == aPB) |
3313 | { |
3314 | aLPBC.Remove(it); |
3315 | break; |
3316 | } |
3317 | } |
3318 | |
3319 | // Add the "micro" edge to the map of "micro" edges for |
3320 | // unification of its vertices in the PostTreatFF method |
3321 | theMicroEdges.Add(aSI); |
3322 | } |
3323 | |
3324 | // Overwrite the old map if necessary |
3325 | if (aSEPBMap.Extent() != theMSCPB.Extent()) |
3326 | theMSCPB = aSEPBMap; |
3327 | } |