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