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> |
ad8b073e |
19 | #include <BOPAlgo_Alerts.hxx> |
42cf5bc1 |
20 | #include <BOPAlgo_SectionAttribute.hxx> |
3510db62 |
21 | #include <BOPAlgo_Tools.hxx> |
319da2e4 |
22 | #include <BOPCol_IndexedMapOfShape.hxx> |
505abfb8 |
23 | #include <BOPCol_NCVector.hxx> |
c7b59798 |
24 | #include <BOPCol_Parallel.hxx> |
4e57c75e |
25 | #include <BOPDS_CommonBlock.hxx> |
42cf5bc1 |
26 | #include <BOPDS_Curve.hxx> |
27 | #include <BOPDS_DS.hxx> |
28 | #include <BOPDS_FaceInfo.hxx> |
29 | #include <BOPDS_Interf.hxx> |
30 | #include <BOPDS_Iterator.hxx> |
31 | #include <BOPDS_ListOfPaveBlock.hxx> |
56c62737 |
32 | #include <BOPDS_MapOfPair.hxx> |
42cf5bc1 |
33 | #include <BOPDS_MapOfPaveBlock.hxx> |
4e57c75e |
34 | #include <BOPDS_Pave.hxx> |
42cf5bc1 |
35 | #include <BOPDS_PaveBlock.hxx> |
4e57c75e |
36 | #include <BOPDS_ShapeInfo.hxx> |
4e57c75e |
37 | #include <BOPDS_VectorOfCurve.hxx> |
38 | #include <BOPDS_VectorOfFaceInfo.hxx> |
42cf5bc1 |
39 | #include <BOPDS_VectorOfInterfFF.hxx> |
40 | #include <BOPDS_VectorOfListOfPaveBlock.hxx> |
f1baf495 |
41 | #include <BOPTools_AlgoTools.hxx> |
42 | #include <BOPTools_AlgoTools2D.hxx> |
f16a6cc5 |
43 | #include <BRepLib.hxx> |
42cf5bc1 |
44 | #include <BRep_Builder.hxx> |
45 | #include <BRep_Tool.hxx> |
46 | #include <BRepBndLib.hxx> |
47 | #include <Geom2d_Curve.hxx> |
48 | #include <Geom_Curve.hxx> |
49 | #include <Geom_Plane.hxx> |
50 | #include <Geom_RectangularTrimmedSurface.hxx> |
51 | #include <Geom_Surface.hxx> |
3510db62 |
52 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
53 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
42cf5bc1 |
54 | #include <gp_Pnt.hxx> |
55 | #include <IntTools_Context.hxx> |
3510db62 |
56 | #include <IntTools_Tools.hxx> |
42cf5bc1 |
57 | #include <TopExp.hxx> |
58 | #include <TopExp_Explorer.hxx> |
3510db62 |
59 | #include <TopoDS.hxx> |
42cf5bc1 |
60 | #include <TopoDS_Edge.hxx> |
61 | #include <TopoDS_Face.hxx> |
62 | #include <TopoDS_Vertex.hxx> |
f1baf495 |
63 | |
319da2e4 |
64 | |
f1baf495 |
65 | static |
66 | Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF); |
4e57c75e |
67 | |
505abfb8 |
68 | |
4e57c75e |
69 | static void UpdateVertices(const TopoDS_Edge& aE, |
70 | const TopoDS_Face& aF); |
71 | |
505abfb8 |
72 | //======================================================================= |
73 | //class : BOPAlgo_SplitEdge |
74 | //purpose : |
75 | //======================================================================= |
36f4947b |
76 | class BOPAlgo_SplitEdge : public BOPAlgo_Algo { |
77 | |
505abfb8 |
78 | public: |
36f4947b |
79 | DEFINE_STANDARD_ALLOC |
80 | |
81 | BOPAlgo_SplitEdge() : |
82 | BOPAlgo_Algo() { |
505abfb8 |
83 | myT1=0.; |
84 | myT2=0.; |
3510db62 |
85 | myTol = 0.; |
505abfb8 |
86 | } |
87 | // |
36f4947b |
88 | virtual ~BOPAlgo_SplitEdge() { |
505abfb8 |
89 | } |
90 | // |
91 | void SetData(const TopoDS_Edge& aE, |
92 | const TopoDS_Vertex& aV1, |
93 | const Standard_Real aT1, |
94 | const TopoDS_Vertex& aV2, |
95 | const Standard_Real aT2) { |
96 | myE=aE; |
97 | myV1=aV1; |
98 | myT1=aT1; |
99 | myV2=aV2; |
100 | myT2=aT2; |
101 | myESp=aE; |
102 | } |
103 | // |
104 | void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) { |
105 | myPB=aPB; |
106 | } |
107 | // |
108 | Handle(BOPDS_PaveBlock)& PaveBlock() { |
109 | return myPB; |
110 | } |
111 | // |
112 | void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) { |
113 | myCB=aCB; |
114 | } |
115 | // |
116 | Handle(BOPDS_CommonBlock)& CommonBlock() { |
117 | return myCB; |
118 | } |
119 | // |
120 | const TopoDS_Edge& SplitEdge() const { |
121 | return myESp; |
122 | } |
123 | // |
124 | const Bnd_Box Box() { |
125 | return myBox; |
126 | } |
127 | // |
3510db62 |
128 | Standard_Real Tolerance() const { |
129 | return myTol; |
130 | } |
131 | // |
132 | void SetDS(const BOPDS_PDS theDS) { |
133 | myDS = theDS; |
134 | } |
135 | // |
136 | void SetContext(const Handle(IntTools_Context)& aContext) { |
137 | myContext = aContext; |
138 | } |
139 | // |
36f4947b |
140 | virtual void Perform () { |
141 | BOPAlgo_Algo::UserBreak(); |
3510db62 |
142 | myTol = BOPAlgo_Tools::ComputeToleranceOfCB(myCB, myDS, myContext); |
505abfb8 |
143 | BOPTools_AlgoTools::MakeSplitEdge(myE, |
144 | myV1, myT1, |
145 | myV2, myT2, |
146 | myESp); |
3510db62 |
147 | BRepBndLib::Add(myESp, myBox); |
148 | myBox.SetGap(myBox.GetGap() + Precision::Confusion()); |
505abfb8 |
149 | } |
150 | // |
151 | protected: |
152 | // -> |
153 | TopoDS_Edge myE; |
154 | TopoDS_Vertex myV1; |
155 | Standard_Real myT1; |
156 | TopoDS_Vertex myV2; |
157 | Standard_Real myT2; |
158 | // <-> |
159 | Handle(BOPDS_PaveBlock) myPB; |
160 | Handle(BOPDS_CommonBlock) myCB; |
161 | // <- |
162 | TopoDS_Edge myESp; |
163 | Bnd_Box myBox; |
3510db62 |
164 | Standard_Real myTol; |
165 | // |
166 | BOPDS_PDS myDS; |
167 | Handle(IntTools_Context) myContext; |
505abfb8 |
168 | }; |
169 | // |
170 | //======================================================================= |
171 | typedef BOPCol_NCVector |
172 | <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge; |
173 | // |
3510db62 |
174 | typedef BOPCol_ContextFunctor |
505abfb8 |
175 | <BOPAlgo_SplitEdge, |
3510db62 |
176 | BOPAlgo_VectorOfSplitEdge, |
177 | Handle(IntTools_Context), |
178 | IntTools_Context> BOPAlgo_SplitEdgeFunctor; |
505abfb8 |
179 | // |
3510db62 |
180 | typedef BOPCol_ContextCnt |
505abfb8 |
181 | <BOPAlgo_SplitEdgeFunctor, |
3510db62 |
182 | BOPAlgo_VectorOfSplitEdge, |
183 | Handle(IntTools_Context)> BOPAlgo_SplitEdgeCnt; |
505abfb8 |
184 | // |
4e57c75e |
185 | //======================================================================= |
f1baf495 |
186 | //class : BOPAlgo_MPC |
187 | //purpose : |
188 | //======================================================================= |
36f4947b |
189 | class BOPAlgo_MPC : public BOPAlgo_Algo { |
190 | |
f1baf495 |
191 | public: |
36f4947b |
192 | DEFINE_STANDARD_ALLOC |
193 | |
194 | BOPAlgo_MPC() : |
195 | BOPAlgo_Algo(), |
196 | myFlag(Standard_False) { |
f1baf495 |
197 | }; |
198 | // |
36f4947b |
199 | virtual ~BOPAlgo_MPC(){ |
f1baf495 |
200 | }; |
201 | // |
202 | void SetEdge(const TopoDS_Edge& aE) { |
203 | myE=aE; |
204 | } |
205 | // |
206 | const TopoDS_Edge& Edge() const { |
207 | return myE; |
208 | } |
209 | // |
210 | void SetFace(const TopoDS_Face& aF) { |
211 | myF=aF; |
212 | } |
213 | // |
214 | const TopoDS_Face& Face() const { |
215 | return myF; |
216 | } |
217 | // |
218 | void SetFlag(const Standard_Boolean bFlag) { |
219 | myFlag=bFlag; |
220 | } |
221 | // |
222 | Standard_Boolean Flag() const { |
223 | return myFlag; |
224 | } |
225 | // |
905522ee |
226 | void SetData(const TopoDS_Edge& aEz, |
227 | const TopoDS_Vertex& aV1, |
228 | const Standard_Real aT1, |
229 | const TopoDS_Vertex& aV2, |
230 | const Standard_Real aT2) { |
231 | myEz=aEz; |
232 | myV1=aV1; |
233 | myT1=aT1; |
234 | myV2=aV2; |
235 | myT2=aT2; |
236 | } |
237 | // |
238 | void SetContext(const Handle(IntTools_Context)& aContext) { |
239 | myContext=aContext; |
240 | } |
241 | // |
242 | const Handle(IntTools_Context)& Context()const { |
243 | return myContext; |
244 | } |
245 | // |
36f4947b |
246 | virtual void Perform() { |
ad8b073e |
247 | try |
248 | { |
249 | OCC_CATCH_SIGNALS |
250 | |
56c62737 |
251 | // Check if edge has pcurve. If no then make its copy to avoid data races, |
252 | // and use it to build pcurve. |
253 | TopoDS_Edge aCopyE = myE; |
254 | Standard_Real f, l; |
255 | Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(aCopyE, myF, f, l); |
256 | if (aC2d.IsNull()) |
257 | { |
258 | aCopyE = BOPTools_AlgoTools::CopyEdge(aCopyE); |
259 | |
260 | Standard_Integer iErr = 1; |
261 | if (!myEz.IsNull()) |
262 | { |
263 | // Attach pcurve from the original edge |
264 | TopoDS_Edge aSpz; |
265 | BOPTools_AlgoTools::MakeSplitEdge(myEz, myV1, myT1, |
266 | myV2, myT2, aSpz); |
267 | iErr = BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz, |
268 | aCopyE, |
269 | myF, |
270 | myContext); |
271 | } |
272 | if (iErr) |
273 | BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aCopyE, myF, myContext); |
274 | |
275 | myNewC2d = BRep_Tool::CurveOnSurface(aCopyE, myF, f, l); |
276 | if (myNewC2d.IsNull()) |
277 | { |
278 | AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape())); |
279 | return; |
280 | } |
281 | else |
282 | myNewTol = BRep_Tool::Tolerance(aCopyE); |
ad8b073e |
283 | } |
56c62737 |
284 | |
ad8b073e |
285 | if (myFlag) { |
56c62737 |
286 | UpdateVertices(aCopyE, myF); |
ad8b073e |
287 | } |
905522ee |
288 | } |
ad8b073e |
289 | catch (Standard_Failure) |
290 | { |
291 | AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape())); |
f1baf495 |
292 | } |
293 | } |
56c62737 |
294 | |
295 | const Handle(Geom2d_Curve)& GetNewPCurve() const |
296 | { |
297 | return myNewC2d; |
298 | } |
299 | |
300 | Standard_Real GetNewTolerance() const |
301 | { |
302 | return myNewTol; |
303 | } |
304 | |
f1baf495 |
305 | protected: |
306 | Standard_Boolean myFlag; |
307 | TopoDS_Edge myE; |
308 | TopoDS_Face myF; |
905522ee |
309 | TopoDS_Edge myEz; |
310 | TopoDS_Vertex myV1; |
311 | Standard_Real myT1; |
312 | TopoDS_Vertex myV2; |
313 | Standard_Real myT2; |
56c62737 |
314 | Handle(Geom2d_Curve) myNewC2d; |
315 | Standard_Real myNewTol; |
905522ee |
316 | // |
317 | Handle(IntTools_Context) myContext; |
f1baf495 |
318 | }; |
319 | // |
320 | //======================================================================= |
321 | typedef BOPCol_NCVector |
322 | <BOPAlgo_MPC> BOPAlgo_VectorOfMPC; |
323 | // |
905522ee |
324 | typedef BOPCol_ContextFunctor |
f1baf495 |
325 | <BOPAlgo_MPC, |
905522ee |
326 | BOPAlgo_VectorOfMPC, |
327 | Handle(IntTools_Context), |
328 | IntTools_Context> BOPAlgo_MPCFunctor; |
f1baf495 |
329 | // |
905522ee |
330 | typedef BOPCol_ContextCnt |
f1baf495 |
331 | <BOPAlgo_MPCFunctor, |
905522ee |
332 | BOPAlgo_VectorOfMPC, |
333 | Handle(IntTools_Context)> BOPAlgo_MPCCnt; |
f1baf495 |
334 | // |
335 | //======================================================================= |
336 | //class : BOPAlgo_BPC |
337 | //purpose : |
338 | //======================================================================= |
339 | class BOPAlgo_BPC { |
340 | public: |
341 | BOPAlgo_BPC(){ |
342 | }; |
343 | // |
344 | ~BOPAlgo_BPC(){ |
345 | }; |
346 | // |
347 | void SetFace(const TopoDS_Face& aF) { |
348 | myF=aF; |
349 | } |
350 | // |
351 | void SetEdge(const TopoDS_Edge& aE) { |
352 | myE=aE; |
353 | } |
354 | // |
2078dfc7 |
355 | const TopoDS_Edge& GetEdge() const { |
356 | return myE; |
357 | } |
358 | const TopoDS_Face& GetFace() const { |
359 | return myF; |
360 | } |
92efcf78 |
361 | const Handle(Geom2d_Curve)& GetCurve2d() const { |
2078dfc7 |
362 | return myCurve; |
363 | } |
364 | Standard_Boolean IsToUpdate() const { |
365 | return myToUpdate; |
366 | } |
367 | // |
f1baf495 |
368 | void Perform() { |
f16a6cc5 |
369 | BRepLib::BuildPCurveForEdgeOnPlane(myE, myF, myCurve, myToUpdate); |
f1baf495 |
370 | }; |
371 | // |
372 | protected: |
373 | TopoDS_Edge myE; |
374 | TopoDS_Face myF; |
92efcf78 |
375 | Handle(Geom2d_Curve) myCurve; |
2078dfc7 |
376 | Standard_Boolean myToUpdate; |
f1baf495 |
377 | }; |
378 | //======================================================================= |
379 | typedef BOPCol_NCVector |
380 | <BOPAlgo_BPC> BOPAlgo_VectorOfBPC; |
381 | // |
c7b59798 |
382 | typedef BOPCol_Functor |
f1baf495 |
383 | <BOPAlgo_BPC, |
384 | BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor; |
385 | // |
c7b59798 |
386 | typedef BOPCol_Cnt |
f1baf495 |
387 | <BOPAlgo_BPCFunctor, |
388 | BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt; |
389 | // |
390 | // |
391 | //======================================================================= |
4e57c75e |
392 | // function: MakeSplitEdges |
393 | // purpose: |
394 | //======================================================================= |
505abfb8 |
395 | void BOPAlgo_PaveFiller::MakeSplitEdges() |
4e57c75e |
396 | { |
4e57c75e |
397 | BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool(); |
33ba8565 |
398 | Standard_Integer aNbPBP = aPBP.Extent(); |
4e57c75e |
399 | if(!aNbPBP) { |
400 | return; |
401 | } |
402 | // |
78c66ef1 |
403 | Standard_Boolean bCB, bV1, bV2; |
505abfb8 |
404 | Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k; |
4e57c75e |
405 | Standard_Real aT1, aT2; |
3510db62 |
406 | BOPDS_ListIteratorOfListOfPaveBlock aItPB; |
505abfb8 |
407 | Handle(BOPDS_PaveBlock) aPB; |
408 | BOPDS_MapOfPaveBlock aMPB(100); |
409 | TopoDS_Vertex aV1, aV2; |
410 | TopoDS_Edge aE; |
411 | BOPAlgo_VectorOfSplitEdge aVBSE; |
412 | |
3510db62 |
413 | // |
414 | UpdateCommonBlocksWithSDVertices(); |
415 | // |
416 | aNbPBP=aPBP.Extent(); |
4e57c75e |
417 | // |
418 | for (i=0; i<aNbPBP; ++i) { |
419 | BOPDS_ListOfPaveBlock& aLPB=aPBP(i); |
420 | // |
421 | aNbPB=aLPB.Extent(); |
4e57c75e |
422 | if (aNbPB==1) { |
423 | aPB=aLPB.First(); |
424 | aPB->Indices(nV1, nV2); |
425 | bV1=myDS->IsNewShape(nV1); |
426 | bV2=myDS->IsNewShape(nV2); |
3510db62 |
427 | bCB=myDS->IsCommonBlock(aPB); |
4e57c75e |
428 | // |
3510db62 |
429 | if (!(bV1 || bV2)) { // no new vertices here |
edfa30de |
430 | if (!myNonDestructive || !bCB) { |
431 | if (bCB) { |
432 | if (!aPB->HasEdge()) { |
433 | const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB); |
434 | nE = aCB->PaveBlock1()->OriginalEdge(); |
435 | aCB->SetEdge(nE); |
436 | // Compute tolerance of the common block and update the edge |
437 | Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext); |
438 | myDS->UpdateEdgeTolerance(nE, aTol); |
439 | } |
440 | } |
441 | else { |
442 | nE = aPB->OriginalEdge(); |
443 | aPB->SetEdge(nE); |
3510db62 |
444 | } |
445 | continue; |
446 | } |
4e57c75e |
447 | } |
448 | } |
449 | // |
450 | aItPB.Initialize(aLPB); |
451 | for (; aItPB.More(); aItPB.Next()) { |
452 | aPB=aItPB.Value(); |
3510db62 |
453 | nE=aPB->OriginalEdge(); |
454 | const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE); |
455 | if (aSIE.HasFlag()){ |
456 | continue; |
457 | } |
458 | // |
5a77460e |
459 | const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB); |
4e57c75e |
460 | bCB=!aCB.IsNull(); |
461 | if (bCB) { |
4e57c75e |
462 | aPB=aCB->PaveBlock1(); |
463 | } |
464 | // |
465 | if (aMPB.Add(aPB)) { |
466 | nE=aPB->OriginalEdge(); |
78c66ef1 |
467 | aPB->Indices(nV1, nV2); |
468 | aPB->Range(aT1, aT2); |
4e57c75e |
469 | // |
505abfb8 |
470 | aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
471 | aE.Orientation(TopAbs_FORWARD); |
472 | // |
473 | aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
474 | aV1.Orientation(TopAbs_FORWARD); |
4e57c75e |
475 | // |
505abfb8 |
476 | aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
477 | aV2.Orientation(TopAbs_REVERSED); |
478 | // |
479 | BOPAlgo_SplitEdge& aBSE=aVBSE.Append1(); |
480 | // |
481 | aBSE.SetData(aE, aV1, aT1, aV2, aT2); |
482 | aBSE.SetPaveBlock(aPB); |
4e57c75e |
483 | if (bCB) { |
505abfb8 |
484 | aBSE.SetCommonBlock(aCB); |
4e57c75e |
485 | } |
3510db62 |
486 | aBSE.SetDS(myDS); |
36f4947b |
487 | aBSE.SetProgressIndicator(myProgressIndicator); |
505abfb8 |
488 | } |
489 | } // for (; aItPB.More(); aItPB.Next()) { |
490 | } // for (i=0; i<aNbPBP; ++i) { |
491 | // |
492 | aNbVBSE=aVBSE.Extent(); |
493 | //====================================================== |
3510db62 |
494 | BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE, myContext); |
505abfb8 |
495 | //====================================================== |
496 | // |
497 | BOPDS_ShapeInfo aSI; |
4e57c75e |
498 | // |
505abfb8 |
499 | aSI.SetShapeType(TopAbs_EDGE); |
500 | // |
501 | for (k=0; k < aNbVBSE; ++k) { |
502 | BOPAlgo_SplitEdge& aBSE=aVBSE(k); |
503 | // |
504 | const TopoDS_Edge& aSp=aBSE.SplitEdge(); |
505 | const Bnd_Box& aBox=aBSE.Box(); |
506 | // |
507 | Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock(); |
508 | Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock(); |
509 | // |
510 | aSI.SetShape(aSp); |
511 | aSI.ChangeBox()=aBox; |
512 | // |
513 | nSp=myDS->Append(aSI); |
514 | // |
515 | if (!aCBk.IsNull()) { |
3510db62 |
516 | myDS->UpdateEdgeTolerance(nSp, aBSE.Tolerance()); |
505abfb8 |
517 | aCBk->SetEdge(nSp); |
518 | } |
519 | else { |
520 | aPBk->SetEdge(nSp); |
521 | } |
522 | } |
4e57c75e |
523 | } |
3510db62 |
524 | |
78c66ef1 |
525 | //======================================================================= |
526 | // function: SplitEdge |
527 | // purpose: |
528 | //======================================================================= |
529 | Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, |
530 | const Standard_Integer nV1, |
531 | const Standard_Real aT1, |
532 | const Standard_Integer nV2, |
533 | const Standard_Real aT2) |
534 | { |
535 | Standard_Integer nSp; |
536 | TopoDS_Vertex aV1, aV2; |
537 | TopoDS_Edge aE, aSp; |
538 | BOPDS_ShapeInfo aSI; |
539 | // |
540 | aSI.SetShapeType(TopAbs_EDGE); |
541 | // |
542 | aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
543 | aE.Orientation(TopAbs_FORWARD); |
544 | // |
545 | aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
546 | aV1.Orientation(TopAbs_FORWARD); |
547 | // |
548 | aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
549 | aV2.Orientation(TopAbs_REVERSED); |
550 | // |
551 | BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp); |
552 | // |
553 | aSI.SetShape(aSp); |
554 | // |
555 | Bnd_Box& aBox=aSI.ChangeBox(); |
556 | BRepBndLib::Add(aSp, aBox); |
3510db62 |
557 | aBox.SetGap(aBox.GetGap() + Precision::Confusion()); |
78c66ef1 |
558 | // |
559 | nSp=myDS->Append(aSI); |
560 | return nSp; |
561 | } |
4e57c75e |
562 | //======================================================================= |
563 | // function: MakePCurves |
564 | // purpose: |
565 | //======================================================================= |
505abfb8 |
566 | void BOPAlgo_PaveFiller::MakePCurves() |
4e57c75e |
567 | { |
0c5a6d47 |
568 | if (myAvoidBuildPCurve || |
569 | (!mySectionAttribute.PCurveOnS1() && !mySectionAttribute.PCurveOnS2())) |
570 | return; |
905522ee |
571 | Standard_Boolean bHasPC; |
56c62737 |
572 | Standard_Integer i, nF1, aNbC, k, nE, aNbFF, aNbFI, nEx; |
319da2e4 |
573 | Standard_Integer j, aNbPBIn, aNbPBOn; |
4e57c75e |
574 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB; |
4e57c75e |
575 | TopoDS_Face aF1F, aF2F; |
f1baf495 |
576 | BOPAlgo_VectorOfMPC aVMPC; |
4e57c75e |
577 | // |
4e57c75e |
578 | // 1. Process Common Blocks |
579 | const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool(); |
580 | // |
581 | aNbFI=aFIP.Extent(); |
582 | for (i=0; i<aNbFI; ++i) { |
583 | const BOPDS_FaceInfo& aFI=aFIP(i); |
584 | nF1=aFI.Index(); |
585 | // |
586 | aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1))); |
587 | aF1F.Orientation(TopAbs_FORWARD); |
588 | // In |
589 | const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn(); |
319da2e4 |
590 | aNbPBIn = aMPBIn.Extent(); |
591 | for (j = 1; j <= aNbPBIn; ++j) { |
592 | const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(j); |
4e57c75e |
593 | nE=aPB->Edge(); |
594 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
595 | // |
f1baf495 |
596 | BOPAlgo_MPC& aMPC=aVMPC.Append1(); |
597 | aMPC.SetEdge(aE); |
598 | aMPC.SetFace(aF1F); |
36f4947b |
599 | aMPC.SetProgressIndicator(myProgressIndicator); |
4e57c75e |
600 | } |
f1baf495 |
601 | // |
4e57c75e |
602 | // On |
603 | const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn(); |
319da2e4 |
604 | aNbPBOn = aMPBOn.Extent(); |
605 | for (j = 1; j <= aNbPBOn; ++j) { |
606 | const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(j); |
905522ee |
607 | nE=aPB->Edge(); |
608 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
609 | bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F); |
610 | if (bHasPC) { |
611 | continue; |
612 | } |
613 | // |
614 | Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB); |
c04c30b3 |
615 | if (aCB.IsNull()) { |
905522ee |
616 | continue; |
617 | } |
618 | // |
619 | const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks(); |
620 | if (aLPB.Extent()<2) { |
621 | continue; |
622 | } |
623 | // |
624 | BOPAlgo_MPC& aMPC=aVMPC.Append1(); |
625 | // |
626 | aItLPB.Initialize(aLPB); |
627 | for(; aItLPB.More(); aItLPB.Next()) { |
628 | const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value(); |
629 | if (aPBx==aPB) { |
630 | continue; |
631 | } |
632 | // |
633 | nEx=aPBx->OriginalEdge(); |
634 | const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx))); |
635 | bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F); |
636 | if (!bHasPC) { |
637 | continue; |
638 | } |
639 | // |
640 | Standard_Integer nV1x, nV2x; |
641 | Standard_Real aT1x, aT2x; |
642 | TopoDS_Vertex aV1x, aV2x; |
643 | TopoDS_Edge aEz; |
644 | // |
645 | aEz=aEx; |
646 | aEz.Orientation(TopAbs_FORWARD); |
647 | // |
648 | aPBx->Indices(nV1x, nV2x); |
649 | aPBx->Range(aT1x, aT2x); |
650 | // |
651 | aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x))); |
652 | aV1x.Orientation(TopAbs_FORWARD); |
4e57c75e |
653 | // |
905522ee |
654 | aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x))); |
655 | aV2x.Orientation(TopAbs_REVERSED); |
656 | // |
657 | aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x); |
658 | // |
659 | break; |
4e57c75e |
660 | } |
905522ee |
661 | // |
662 | aMPC.SetEdge(aE); |
663 | aMPC.SetFace(aF1F); |
664 | aMPC.SetProgressIndicator(myProgressIndicator); |
4e57c75e |
665 | } |
f1baf495 |
666 | }// for (i=0; i<aNbFI; ++i) { |
4e57c75e |
667 | // |
56c62737 |
668 | // 2. Process section edges. P-curves on them must already be computed. |
669 | // However, we must provide the call to UpdateVertices. |
f1baf495 |
670 | Standard_Boolean bPCurveOnS[2]; |
f1baf495 |
671 | bPCurveOnS[0]=mySectionAttribute.PCurveOnS1(); |
672 | bPCurveOnS[1]=mySectionAttribute.PCurveOnS2(); |
673 | // |
674 | if (bPCurveOnS[0] || bPCurveOnS[1]) { |
56c62737 |
675 | // container to remember already added edge-face pairs |
676 | BOPDS_MapOfPair anEFPairs; |
f1baf495 |
677 | BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); |
678 | aNbFF=aFFs.Extent(); |
679 | for (i=0; i<aNbFF; ++i) { |
680 | const BOPDS_InterfFF& aFF=aFFs(i); |
56c62737 |
681 | const BOPDS_VectorOfCurve& aVNC = aFF.Curves(); |
682 | aNbC = aVNC.Extent(); |
683 | if (aNbC == 0) |
684 | continue; |
685 | Standard_Integer nF[2]; |
686 | aFF.Indices(nF[0], nF[1]); |
f1baf495 |
687 | // |
56c62737 |
688 | TopoDS_Face aFf[2]; |
689 | aFf[0] = (*(TopoDS_Face *)(&myDS->Shape(nF[0]))); |
f1baf495 |
690 | aFf[0].Orientation(TopAbs_FORWARD); |
691 | // |
56c62737 |
692 | aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF[1]))); |
f1baf495 |
693 | aFf[1].Orientation(TopAbs_FORWARD); |
694 | // |
56c62737 |
695 | for (k=0; k<aNbC; ++k) |
696 | { |
f1baf495 |
697 | const BOPDS_Curve& aNC=aVNC(k); |
698 | const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks(); |
699 | aItLPB.Initialize(aLPB); |
56c62737 |
700 | for(; aItLPB.More(); aItLPB.Next()) |
701 | { |
f1baf495 |
702 | const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value(); |
703 | nE=aPB->Edge(); |
704 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
705 | // |
56c62737 |
706 | for (Standard_Integer m = 0; m<2; ++m) |
707 | { |
708 | if (bPCurveOnS[m] && anEFPairs.Add(BOPDS_Pair(nE, nF[m]))) |
709 | { |
710 | BOPAlgo_MPC& aMPC = aVMPC.Append1(); |
f1baf495 |
711 | aMPC.SetEdge(aE); |
712 | aMPC.SetFace(aFf[m]); |
56c62737 |
713 | aMPC.SetFlag(Standard_True); |
36f4947b |
714 | aMPC.SetProgressIndicator(myProgressIndicator); |
f1baf495 |
715 | } |
716 | } |
4e57c75e |
717 | } |
718 | } |
f1baf495 |
719 | }// for (i=0; i<aNbFF; ++i) { |
720 | }//if (bPCurveOnS1 || bPCurveOnS2 ) { |
721 | // |
722 | //====================================================== |
905522ee |
723 | BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext); |
f1baf495 |
724 | //====================================================== |
ad8b073e |
725 | |
56c62737 |
726 | // Add warnings of the failed projections and update edges with new pcurves |
ad8b073e |
727 | Standard_Integer aNb = aVMPC.Extent(); |
728 | for (i = 0; i < aNb; ++i) |
729 | { |
56c62737 |
730 | const BOPAlgo_MPC& aMPC = aVMPC(i); |
731 | if (aMPC.HasErrors()) |
ad8b073e |
732 | { |
733 | TopoDS_Compound aWC; |
734 | BRep_Builder().MakeCompound(aWC); |
56c62737 |
735 | BRep_Builder().Add(aWC, aMPC.Edge()); |
736 | BRep_Builder().Add(aWC, aMPC.Face()); |
ad8b073e |
737 | AddWarning(new BOPAlgo_AlertBuildingPCurveFailed(aWC)); |
738 | } |
56c62737 |
739 | else |
740 | { |
741 | const Handle(Geom2d_Curve)& aNewPC = aMPC.GetNewPCurve(); |
742 | // if aNewPC is null we do not need to update the edge because it already contains |
743 | // valid p-curve, and only vertices have been updated. |
744 | if (!aNewPC.IsNull()) |
745 | BRep_Builder().UpdateEdge(aMPC.Edge(), aNewPC, aMPC.Face(), aMPC.GetNewTolerance()); |
746 | } |
ad8b073e |
747 | } |
4e57c75e |
748 | } |
4e57c75e |
749 | //======================================================================= |
4e57c75e |
750 | //function : UpdateVertices |
751 | //purpose : update tolerances of vertices comparing extremities of |
752 | // 3d and 2d curves |
753 | //======================================================================= |
505abfb8 |
754 | void UpdateVertices(const TopoDS_Edge& aE, |
755 | const TopoDS_Face& aF) |
4e57c75e |
756 | { |
757 | Standard_Integer j; |
758 | Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD; |
759 | gp_Pnt aP3D, aP3Dx; |
760 | gp_Pnt2d aP2Dx; |
761 | Handle(Geom_Surface) aS; |
762 | Handle(Geom_Curve) aC3D; |
763 | Handle(Geom2d_Curve) aC2D; |
764 | TopoDS_Edge aEf; |
765 | TopoDS_Vertex aV[2]; |
766 | BRep_Builder aBB; |
767 | // |
768 | aEf=aE; |
769 | aEf.Orientation(TopAbs_FORWARD); |
770 | // |
771 | TopExp::Vertices(aEf, aV[0], aV[1]); |
772 | // |
773 | aS=BRep_Tool::Surface(aF); |
774 | aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]); |
775 | aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]); |
776 | // |
777 | for (j=0; j<2; ++j) { |
778 | aTolV2=BRep_Tool::Tolerance(aV[j]); |
779 | aTolV2=aTolV2*aTolV2; |
780 | // |
781 | aC3D->D0(aT[j], aP3D); |
782 | aC2D->D0(aT[j], aP2Dx); |
783 | aP2Dx.Coord(aUx, aVx); |
784 | aS->D0(aUx, aVx, aP3Dx); |
785 | aD2=aP3D.SquareDistance(aP3Dx); |
786 | if (aD2>aTolV2) { |
787 | aD=sqrt(aD2); |
788 | aBB.UpdateVertex(aV[j], aD); |
789 | } |
790 | } |
791 | } |
f1baf495 |
792 | //======================================================================= |
793 | // function: Prepare |
794 | // purpose: |
795 | //======================================================================= |
796 | void BOPAlgo_PaveFiller::Prepare() |
797 | { |
3510db62 |
798 | if (myNonDestructive) { |
799 | // do not allow storing pcurves in original edges if non-destructive mode is on |
800 | return; |
801 | } |
f1baf495 |
802 | TopAbs_ShapeEnum aType[] = { |
803 | TopAbs_VERTEX, |
804 | TopAbs_EDGE, |
805 | TopAbs_FACE |
806 | }; |
25dfc507 |
807 | Standard_Boolean bIsBasedOnPlane; |
319da2e4 |
808 | Standard_Integer i, aNb, n1, nF, aNbF; |
f1baf495 |
809 | TopExp_Explorer aExp; |
319da2e4 |
810 | BOPCol_IndexedMapOfShape aMF; |
f1baf495 |
811 | // |
f1baf495 |
812 | aNb=3; |
813 | for(i=0; i<aNb; ++i) { |
814 | myIterator->Initialize(aType[i], aType[2]); |
815 | for (; myIterator->More(); myIterator->Next()) { |
25dfc507 |
816 | myIterator->Value(n1, nF); |
f1baf495 |
817 | const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); |
818 | // |
819 | bIsBasedOnPlane=IsBasedOnPlane(aF); |
820 | if (bIsBasedOnPlane) { |
821 | aMF.Add(aF); |
822 | } |
823 | } |
824 | } |
825 | // |
319da2e4 |
826 | aNbF = aMF.Extent(); |
827 | if (!aNbF) { |
f1baf495 |
828 | return; |
829 | } |
830 | // |
2078dfc7 |
831 | // Build pcurves of edges on planes; first collect pairs edge-face. |
f1baf495 |
832 | BOPAlgo_VectorOfBPC aVBPC; |
833 | // |
319da2e4 |
834 | for (i = 1; i <= aNbF; ++i) { |
835 | const TopoDS_Face& aF = *(TopoDS_Face*)&aMF(i); |
f1baf495 |
836 | aExp.Init(aF, aType[1]); |
837 | for (; aExp.More(); aExp.Next()) { |
838 | const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current()); |
839 | BOPAlgo_BPC& aBPC=aVBPC.Append1(); |
840 | aBPC.SetEdge(aE); |
841 | aBPC.SetFace(aF); |
842 | } |
843 | } |
844 | // |
845 | //====================================================== |
846 | BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC); |
847 | //====================================================== |
2078dfc7 |
848 | |
849 | // pcurves are built, and now update edges |
850 | BRep_Builder aBB; |
851 | TopoDS_Edge E; |
852 | for (i = 0; i < aVBPC.Extent(); i++) { |
853 | const BOPAlgo_BPC& aBPC=aVBPC(i); |
854 | if (aBPC.IsToUpdate()) { |
855 | Standard_Real aTolE = BRep_Tool::Tolerance(aBPC.GetEdge()); |
856 | aBB.UpdateEdge(aBPC.GetEdge(), aBPC.GetCurve2d(), aBPC.GetFace(), aTolE); |
857 | } |
858 | } |
f1baf495 |
859 | } |
860 | //======================================================================= |
861 | //function : IsBasedOnPlane |
862 | //purpose : |
863 | //======================================================================= |
864 | Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF) |
865 | { |
866 | TopLoc_Location aLoc; |
867 | Handle(Geom_RectangularTrimmedSurface) aGRTS; |
868 | Handle(Geom_Plane) aGP; |
869 | |
870 | const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc); |
871 | aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS); |
872 | if(!aGRTS.IsNull()) { |
873 | aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface()); |
874 | } |
875 | else { |
876 | aGP = Handle(Geom_Plane)::DownCast(aS); |
877 | } |
878 | // |
879 | return (!aGP.IsNull()); |
880 | } |