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