1 // Created on: 2003-10-21
2 // Created by: Mikhail KLOKOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BOPAlgo_BOP.hxx>
18 #include <BOPAlgo_PaveFiller.hxx>
19 #include <BOPDS_DS.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAlgoAPI_Section.hxx>
23 #include <BRepFill_TrimShellCorner.hxx>
24 #include <BRepLib_MakeEdge.hxx>
25 #include <BRepLib_MakeWire.hxx>
26 #include <BRepLib_MakeVertex.hxx>
27 #include <BRepTools_ReShape.hxx>
28 #include <gce_MakeLin.hxx>
29 #include <GCPnts_UniformAbscissa.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom_Curve.hxx>
32 #include <GeomLib.hxx>
33 #include <gp_Ax2.hxx>
34 #include <gp_Pln.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <IntTools_BeanFaceIntersector.hxx>
37 #include <IntTools_Context.hxx>
38 #include <IntTools_Range.hxx>
39 #include <IntTools_Tools.hxx>
40 #include <TColgp_Array1OfDir.hxx>
41 #include <TColgp_Array1OfPnt.hxx>
42 #include <TColgp_Array2OfPnt.hxx>
43 #include <TColgp_SequenceOfPnt.hxx>
44 #include <TColStd_Array1OfBoolean.hxx>
45 #include <TColStd_ListIteratorOfListOfInteger.hxx>
46 #include <TColStd_ListOfInteger.hxx>
47 #include <TopExp.hxx>
48 #include <TopExp_Explorer.hxx>
49 #include <TopLoc_Location.hxx>
50 #include <TopoDS.hxx>
51 #include <TopoDS_Compound.hxx>
52 #include <TopoDS_Face.hxx>
53 #include <TopoDS_Iterator.hxx>
54 #include <TopoDS_Shape.hxx>
55 #include <TopoDS_Shell.hxx>
56 #include <TopoDS_Wire.hxx>
57 #include <TopTools_Array1OfListOfShape.hxx>
58 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
59 #include <TopTools_DataMapOfShapeListOfShape.hxx>
60 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
61 #include <TopTools_ListIteratorOfListOfShape.hxx>
62 #include <TopTools_ListOfShape.hxx>
63 #include <TopTools_MapOfShape.hxx>
64 #include <TopTools_SequenceOfShape.hxx>
65 #include <BRepExtrema_ExtCC.hxx>
66
67 static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
68 TopoDS_Compound& theComp,
69 const gp_Ax1& theAxis);
70
71 static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1,
72 const TopoDS_Vertex& theVertex2,
73 const gp_Ax1& theAxis,
74 TopoDS_Compound& theComp,
75 TopTools_ListOfShape& theElist);
76
77 static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge,
78 const TopoDS_Edge& theLastEdge,
79 const TopoDS_Vertex& theFirstVertex,
80 const TopoDS_Vertex& theLastVertex,
81 TopoDS_Vertex& theCommonVertex);
82
83 static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
84 const Standard_Integer theEIndex1,
85 const Standard_Integer theEIndex2,
86 TopoDS_Vertex& theCommonVertex,
87 Standard_Real& theParamOnE1,
88 Standard_Real& theParamOnE2);
89
90 static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
91 const BOPDS_PDS& theDS,
92 TopTools_DataMapOfShapeListOfShape& theHistMap);
93
94 static void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)& theVEdges,
95 const Standard_Integer theIndex,
96 const TopoDS_Shape& theNewVedge,
97 TopTools_DataMapOfShapeListOfShape& theHistMap);
98
99 static void FindFreeVertices(const TopoDS_Shape& theShape,
100 const TopTools_MapOfShape& theVerticesToAvoid,
101 TopTools_ListOfShape& theListOfVertex);
102
103 static Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList,
104 const gp_Pnt2d& theFirstPoint,
105 const gp_Pnt2d& theLastPoint,
106 const TopoDS_Face& theFace,
107 TopTools_ListOfShape& theOrientedList);
108
109 static Standard_Boolean FillGap(const TopoDS_Vertex& theFirstVertex,
110 const TopoDS_Vertex& theLastVertex,
111 const gp_Pnt2d& theFirstPoint,
112 const gp_Pnt2d& theLastPoint,
113 const TopoDS_Face& theFace,
114 const TopoDS_Compound& theSectionEdges,
115 TopTools_ListOfShape& theOrderedList);
116
117 static Standard_Boolean FindNextEdge(const TopoDS_Vertex& theFirstVertex,
118 const TopoDS_Vertex& theLastVertex,
119 const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
120 const TopTools_MapOfShape& theMapToAvoid,
121 TopTools_ListOfShape& theOrderedList);
122
123 static Standard_Boolean FindVertex(const TopoDS_Edge& theEdge,
124 const Standard_Integer theRank,
125 const BOPDS_PDS& theDS,
126 const TopTools_DataMapOfShapeListOfShape& theHistMap,
127 TopoDS_Vertex& theVertex,
128 BOPDS_Pave& thePave);
129
130 static Standard_Boolean FindNextVertex(const Standard_Integer theEdgeIndex,
131 const BOPDS_Pave& thePrevPave,
132 const BOPDS_PDS& theDS,
133 TopoDS_Vertex& theNextVertex,
134 BOPDS_Pave& thePave);
135
136 static Standard_Boolean GetPave(const Standard_Integer theEdgeIndex,
137 const Standard_Boolean isFirst,
138 const BOPDS_PDS& theDS,
139 BOPDS_Pave& thePave);
140
141 static Standard_Boolean FindFromUEdge(const TopoDS_Edge& theUE1Old,
142 const TopoDS_Edge& theUE2Old,
143 const TopoDS_Edge& theUE1New,
144 const TopoDS_Edge& theUE2New,
145 const TopoDS_Face& theFace,
146 const TopoDS_Compound& theSecEdges,
147 const Standard_Integer theRank,
148 const TopoDS_Edge& theBoundEdge,
149 const Standard_Integer theBoundEdgeIndex,
150 const BOPDS_PDS& theDS,
151 const TopTools_DataMapOfShapeListOfShape& theHistMap,
152 TopoDS_Compound& theSecEdgesNew,
153 TopTools_ListOfShape& theListOfWireEdges,
154 BOPDS_Pave& theFoundPave,
155 Standard_Boolean& isOnUEdge);
156
157 static Standard_Boolean FindFromVEdge(const BOPDS_Pave& thePrevPave,
158 const Standard_Boolean& isOnUEdge,
159 const TopoDS_Edge& theUE1Old,
160 const TopoDS_Edge& theUE2Old,
161 const TopoDS_Face& theFace,
162 const TopoDS_Compound& theSecEdges,
163 const Standard_Integer theRank,
164 const TopoDS_Edge& theBoundEdge,
165 const Standard_Integer theBoundEdgeIndex,
166 const BOPDS_PDS& theDS,
167 const TopTools_DataMapOfShapeListOfShape& theHistMap,
168 TopTools_ListOfShape& theListOfWireEdges,
169 Standard_Boolean& isSectionFound);
170
171 static void RemoveEdges(const TopoDS_Compound& theSourceComp,
172 const TopTools_ListOfShape& theListToRemove,
173 TopoDS_Compound& theResultComp);
174
175 static Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve& theBCurves,
176 const TopoDS_Face& theSecPlane,
177 const BOPDS_PDS& theDS,
178 TopoDS_Compound& theResult);
179
180 static Standard_Boolean GetUEdges(const Standard_Integer theIndex,
181 const Standard_Integer theRank,
182 const Handle(TopTools_HArray2OfShape)& theUEdges,
183 const TopoDS_Edge& theBoundEdge,
184 const TopoDS_Face& theFace,
185 TopoDS_Edge& theFirstUEdge,
186 TopoDS_Edge& theSecondUEdge);
187
188 static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
189 gp_Pln& thePlane,
190 Standard_Boolean& IsSingular);
191
192 static void UpdateSectionEdge(TopoDS_Edge& theEdge,
193 const TopoDS_Vertex& theConstVertex,
194 TopoDS_Vertex& theVertex,
195 const Standard_Real theParam);
196
197
198 // ===========================================================================================
199 // function: Constructor
200 // purpose:
201 // ===========================================================================================
BRepFill_TrimShellCorner(const Handle (TopTools_HArray2OfShape)& theFaces,const BRepFill_TransitionStyle theTransition,const gp_Ax2 & theAxeOfBisPlane)202 BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
203 const BRepFill_TransitionStyle theTransition,
204 const gp_Ax2& theAxeOfBisPlane) :
205 myTransition(theTransition),
206 myAxeOfBisPlane(theAxeOfBisPlane),
207 myDone(Standard_False),
208 myHasSection(Standard_False)
209 {
210 myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(),
211 theFaces->LowerCol(), theFaces->UpperCol());
212 myFaces->ChangeArray2() = theFaces->Array2();
213 }
214
215 // ===========================================================================================
216 // function: AddBounds
217 // purpose:
218 // ===========================================================================================
AddBounds(const Handle (TopTools_HArray2OfShape)& theBounds)219 void BRepFill_TrimShellCorner::AddBounds(const Handle(TopTools_HArray2OfShape)& theBounds)
220 {
221 myBounds = new TopTools_HArray2OfShape(theBounds->LowerRow(), theBounds->UpperRow(),
222 theBounds->LowerCol(), theBounds->UpperCol());
223 myBounds->ChangeArray2() = theBounds->Array2();
224 }
225
226 // ===========================================================================================
227 // function: AddUEdges
228 // purpose:
229 // ===========================================================================================
AddUEdges(const Handle (TopTools_HArray2OfShape)& theUEdges)230 void BRepFill_TrimShellCorner::AddUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges)
231 {
232 myUEdges = new TopTools_HArray2OfShape(theUEdges->LowerRow(), theUEdges->UpperRow(),
233 theUEdges->LowerCol(), theUEdges->UpperCol());
234 myUEdges->ChangeArray2() = theUEdges->Array2();
235 }
236
237 // ===========================================================================================
238 // function: AddVEdges
239 // purpose:
240 // ===========================================================================================
AddVEdges(const Handle (TopTools_HArray2OfShape)& theVEdges,const Standard_Integer theIndex)241 void BRepFill_TrimShellCorner::AddVEdges(const Handle(TopTools_HArray2OfShape)& theVEdges,
242 const Standard_Integer theIndex)
243 {
244 myVEdges = new TopTools_HArray1OfShape(theVEdges->LowerRow(), theVEdges->UpperRow());
245
246 for (Standard_Integer i = theVEdges->LowerRow(); i <= theVEdges->UpperRow(); i++)
247 myVEdges->SetValue(i, theVEdges->Value(i, theIndex));
248 }
249
250 // ===========================================================================================
251 // function: Perform
252 // purpose:
253 // ===========================================================================================
Perform()254 void BRepFill_TrimShellCorner::Perform()
255 {
256 Standard_Integer anIndex1, anIndex2, nF1, nF2, i, j, aNbP, aNbC;
257 Standard_Boolean bhassec;
258
259 myDone = Standard_False;
260 myHistMap.Clear();
261
262 if(myFaces->RowLength() != 2)
263 return;
264 Standard_Integer ii = 0, jj = 0;
265 BRep_Builder aBB;
266
267 for(jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++) {
268 TopoDS_Shell aShell;
269 aBB.MakeShell(aShell);
270
271 for(ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
272 aBB.Add(aShell, myFaces->Value(ii, jj));
273 }
274 aShell.Closed (BRep_Tool::IsClosed (aShell));
275
276 if(jj == myFaces->LowerCol()) {
277 myShape1 = aShell;
278 }
279 else {
280 myShape2 = aShell;
281 }
282 }
283
284 Standard_Real aMaxTol = 0.;
285 TopExp_Explorer anExp(myShape1, TopAbs_VERTEX);
286 for (; anExp.More(); anExp.Next())
287 {
288 aMaxTol = Max(aMaxTol, BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Current())));
289 }
290
291 anExp.Init(myShape2, TopAbs_VERTEX);
292 for (; anExp.More(); anExp.Next())
293 {
294 aMaxTol = Max(aMaxTol, BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Current())));
295 }
296
297 Standard_Real aFuzzy = 4.*Precision::Confusion();
298 BOPAlgo_PaveFiller aPF;
299 TopTools_ListOfShape aLS;
300 aLS.Append(myShape1);
301 aLS.Append(myShape2);
302 aPF.SetArguments(aLS);
303 if (aMaxTol < 1.005 * Precision::Confusion())
304 {
305 aFuzzy = Max(aPF.FuzzyValue(), aFuzzy);
306 aPF.SetFuzzyValue(aFuzzy);
307 }
308 //
309 aPF.Perform();
310 if (aPF.HasErrors()) {
311 return;
312 }
313 //
314 const BOPDS_PDS& theDS = aPF.PDS();
315 //
316 BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
317 Standard_Integer aNbFFs = aFFs.Length();
318
319 if(!SplitUEdges(myUEdges, theDS, myHistMap)) {
320 return;
321 }
322
323 for(ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
324 TopoDS_Shape aF1 = myFaces->Value(ii, myFaces->LowerCol());
325 TopoDS_Shape aF2 = myFaces->Value(ii, myFaces->UpperCol());
326 //
327 anIndex1 = theDS->Index(aF1);
328 anIndex2 = theDS->Index(aF2);
329
330 if((anIndex1 == -1) || (anIndex2 == -1))
331 continue;
332
333 for (i=0; i < aNbFFs; ++i) {
334 BOPDS_InterfFF& aFFi = aFFs(i);
335 aFFi.Indices(nF1, nF2);
336 //
337 BOPDS_VectorOfPoint& aVP=aFFi.ChangePoints();
338 aNbP=aVP.Length();
339 const BOPDS_VectorOfCurve& aVC=aFFi.Curves();
340 aNbC=aVC.Length();
341 if (!aNbP && !aNbC) {
342 if (!theDS->HasInterfSubShapes(nF1, nF2)) {
343 continue;
344 }
345 }
346 //
347 if((nF1 == anIndex1) && (nF2 == anIndex2)) {
348 bhassec = Standard_False;
349 //
350 for (j = 0; j < aNbC; ++j) {
351 const BOPDS_Curve& aBCurve = aVC(j);
352 const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
353 //
354 if (aSectEdges.Extent()) {
355 bhassec = Standard_True;
356 break;
357 }
358 }
359
360 if(!bhassec) {
361 if(!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2)) {
362 myHistMap.Clear();
363 return;
364 }
365 }
366 else {
367 if(!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i)) {
368 myHistMap.Clear();
369 return;
370 }
371 }
372 break;
373 }
374 }
375 }
376 myDone = Standard_True;
377 }
378
379 // ===========================================================================================
380 // function: IsDone
381 // purpose:
382 // ===========================================================================================
IsDone() const383 Standard_Boolean BRepFill_TrimShellCorner::IsDone() const
384 {
385 return myDone;
386 }
387
388 // ===========================================================================================
389 // function: HasSection
390 // purpose:
391 // ===========================================================================================
HasSection() const392 Standard_Boolean BRepFill_TrimShellCorner::HasSection() const
393 {
394 return myHasSection;
395 }
396
397 // ===========================================================================================
398 // function: Modified
399 // purpose:
400 // ===========================================================================================
Modified(const TopoDS_Shape & theShape,TopTools_ListOfShape & theModified)401 void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape& theShape,
402 TopTools_ListOfShape& theModified)
403 {
404 theModified.Clear();
405
406 if(myHistMap.IsBound(theShape)) {
407 theModified = myHistMap.Find(theShape);
408 }
409 }
410
411 // ----------------------------------------------------------------------------------------------------
412 // function: MakeFacesNonSec
413 // purpose: Updates <myHistMap> by new faces in the case when old faces do not intersect
414 // ----------------------------------------------------------------------------------------------------
415 Standard_Boolean
MakeFacesNonSec(const Standard_Integer theIndex,const BOPDS_PDS & theDS,const Standard_Integer theFaceIndex1,const Standard_Integer theFaceIndex2)416 BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer theIndex,
417 const BOPDS_PDS& theDS,
418 const Standard_Integer theFaceIndex1,
419 const Standard_Integer theFaceIndex2)
420 {
421 Standard_Boolean bHasNewEdge = Standard_False;
422 TopoDS_Edge aNewEdge;
423
424 BRep_Builder aBB;
425 const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1);
426 const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2);
427
428 // search common vertex between bounds. begin
429 TopoDS_Vertex aCommonVertex;
430 Standard_Integer anIndex1 = theDS->Index(aE1);
431 Standard_Integer anIndex2 = theDS->Index(aE2);
432 Standard_Real apar1 = 0., apar2 = 0.;
433
434 Standard_Boolean bvertexfound =
435 FindCommonVertex(theDS, anIndex1, anIndex2, aCommonVertex, apar1, apar2);
436 // search common vertex between bounds. end
437
438 Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
439
440 // search common vertices between uedges. begin
441 TopTools_ListOfShape aCommonVertices;
442 Standard_Integer acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
443 Standard_Integer ueit = 0, eindex = 0;
444
445 for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
446 const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol());
447 const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol());
448 TopoDS_Edge aUE1 = TopoDS::Edge(aShape1);
449 TopoDS_Edge aUE2 = TopoDS::Edge(aShape2);
450
451 if (myHistMap.IsBound(aShape1)) {
452 const TopTools_ListOfShape& lst = myHistMap.Find(aShape1);
453
454 if(!lst.IsEmpty())
455 aUE1 = TopoDS::Edge(lst.First());
456 }
457
458 if (myHistMap.IsBound(aShape2)) {
459 const TopTools_ListOfShape& lst = myHistMap.Find(aShape2);
460
461 if(!lst.IsEmpty())
462 aUE2 = TopoDS::Edge(lst.First());
463 }
464
465 if(!aShape1.IsSame(aUE1))
466 aSubstitutor->Replace(aShape1.Oriented(TopAbs_FORWARD), aUE1.Oriented(TopAbs_FORWARD));
467
468 if(!aShape2.IsSame(aUE2))
469 aSubstitutor->Replace(aShape2.Oriented(TopAbs_FORWARD), aUE2.Oriented(TopAbs_FORWARD));
470
471 TopoDS_Vertex V1 = TopExp::LastVertex(aUE1);
472 TopoDS_Vertex V2 = TopExp::FirstVertex(aUE2);
473
474 if(V1.IsSame(V2)) {
475 acommonflag = (acommonflag == 0) ? ueit : 3;
476 aCommonVertices.Append(V1);
477 }
478 }
479 // search common vertices between uedges. end
480
481 if(bvertexfound) {
482 if(aCommonVertices.Extent() != 1)
483 return Standard_False;
484
485 if(acommonflag == 1)
486 aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()), aCommonVertex);
487 else
488 aNewEdge = BRepLib_MakeEdge(aCommonVertex, TopoDS::Vertex(aCommonVertices.First()));
489
490 bHasNewEdge = Standard_True;
491 }
492
493 if(aCommonVertices.Extent() == 2) {
494 aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()),
495 TopoDS::Vertex(aCommonVertices.Last()));
496 bHasNewEdge = Standard_True;
497 }
498 Standard_Integer fit = 0;
499
500 for(fit = 1; fit <= 2; fit++) {
501 TopoDS_Compound aComp;
502 TopTools_MapOfShape aMapV;
503 aBB.MakeCompound(aComp);
504
505 for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
506 const TopoDS_Shape& aShape = myUEdges->Value(eindex, myUEdges->LowerCol() + fit - 1);
507 TopoDS_Shape aUE = aShape;
508
509 if(myHistMap.IsBound(aShape)) {
510 const TopTools_ListOfShape& lst = myHistMap.Find(aShape);
511
512 if(!lst.IsEmpty())
513 aUE = TopoDS::Edge(lst.First());
514 }
515 const TopoDS_Shape& aV = (fit == 1) ? TopExp::FirstVertex(TopoDS::Edge(aUE)) : TopExp::LastVertex(TopoDS::Edge(aUE));
516 aMapV.Add(aV);
517 aBB.Add(aComp, aUE);
518 }
519
520 if(bHasNewEdge) {
521 aBB.Add(aComp, aNewEdge);
522 StoreVedgeInHistMap(myVEdges, theIndex, aNewEdge, myHistMap);
523 }
524
525 TopTools_ListOfShape alonevertices;
526 FindFreeVertices(aComp, aMapV, alonevertices);
527
528 if(!alonevertices.IsEmpty() && (alonevertices.Extent() != 2))
529 return Standard_False;
530
531 Standard_Integer aFaceIndex = (fit == 1) ? theFaceIndex1 : theFaceIndex2;
532 TopoDS_Shape aFace = theDS->Shape(aFaceIndex);
533 TopAbs_Orientation aFaceOri = aFace.Orientation();
534 aFace.Orientation(TopAbs_FORWARD);
535
536 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
537
538 if(bHasNewEdge) {
539 aNewEdge.Orientation(TopAbs_FORWARD);
540 }
541
542 TopTools_ListOfShape aOrderedList;
543
544 if(!alonevertices.IsEmpty()) {
545 Standard_Integer anEIndex = (fit == 1) ? anIndex1 : anIndex2;
546 Standard_Boolean bfound1 = Standard_False;
547 Standard_Boolean bfound2 = Standard_False;
548 Standard_Real aparam1 = 0., aparam2 = 0.;
549
550 BOPDS_ListOfPave aLP;
551 theDS->Paves(anEIndex, aLP);
552 BOPDS_ListIteratorOfListOfPave aIt;
553 aIt.Initialize(aLP);
554 for ( ; aIt.More(); aIt.Next()) {
555 const BOPDS_Pave& aPave = aIt.Value();
556 TopoDS_Shape aV = theDS->Shape(aPave.Index());
557
558 if(aV.IsSame(alonevertices.First())) {
559 if(!bfound1) {
560 aparam1 = aPave.Parameter();
561 bfound1 = Standard_True;
562 }
563 }
564
565 if(aV.IsSame(alonevertices.Last())) {
566 if(!bfound2) {
567 aparam2 = aPave.Parameter();
568 bfound2 = Standard_True;
569 }
570 }
571 }
572
573 if(bfound1 && bfound2) {
574 TopoDS_Edge aNewBoundE;
575
576 if(fit == 1) {
577 aNewBoundE = TopoDS::Edge(aE1.EmptyCopied());
578 }
579 else {
580 aNewBoundE = TopoDS::Edge(aE2.EmptyCopied());
581 }
582 TopoDS_Vertex aV1, aV2;
583
584 if(aparam1 < aparam2) {
585 aV1 = TopoDS::Vertex(alonevertices.First());
586 aV2 = TopoDS::Vertex(alonevertices.Last());
587 }
588 else {
589 aV1 = TopoDS::Vertex(alonevertices.Last());
590 aV2 = TopoDS::Vertex(alonevertices.First());
591 Standard_Real tmp = aparam1;
592 aparam1 = aparam2;
593 aparam2 = tmp;
594 }
595 aV1.Orientation(TopAbs_FORWARD);
596 aV2.Orientation(TopAbs_REVERSED);
597 aBB.Add(aNewBoundE, aV1);
598 aBB.Add(aNewBoundE, aV2);
599 aBB.Range(aNewBoundE, aparam1, aparam2);
600 aNewBoundE.Orientation(TopAbs_FORWARD);
601
602 aOrderedList.Append(aNewBoundE);
603
604 if(bHasNewEdge) {
605 TopExp_Explorer anExpV(aNewEdge, TopAbs_VERTEX);
606 Standard_Boolean bfoundv = Standard_False;
607
608 for(; !bfoundv && anExpV.More(); anExpV.Next()) {
609 if(aV2.IsSame(anExpV.Current()))
610 bfoundv = Standard_True;
611 }
612
613 if(bfoundv)
614 aOrderedList.Append(aNewEdge);
615 else
616 aOrderedList.Prepend(aNewEdge);
617 }
618 }
619 else {
620 return Standard_False;
621 }
622 }
623 else {
624 if(bHasNewEdge) {
625 aOrderedList.Append(aNewEdge);
626 }
627 }
628
629 if(!aOrderedList.IsEmpty()) {
630 TopoDS_Wire aW;
631 aBB.MakeWire(aW);
632 TopTools_ListIteratorOfListOfShape anItE(aOrderedList);
633
634 for(; anItE.More(); anItE.Next()) {
635 aBB.Add(aW, anItE.Value());
636 }
637 if(fit == 1)
638 aSubstitutor->Replace(aE1.Oriented(TopAbs_FORWARD), aW);
639 else
640 aSubstitutor->Replace(aE2.Oriented(TopAbs_FORWARD), aW);
641 }
642
643 aSubstitutor->Apply(aFace);
644 TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
645 aNewFace.Orientation(aFaceOri);
646 TopTools_ListOfShape atmpList;
647 atmpList.Append(aNewFace);
648 myHistMap.Bind(aFace, atmpList);
649
650 anExpE.Init(aFace, TopAbs_EDGE);
651
652 for(; anExpE.More(); anExpE.Next()) {
653 TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
654
655 if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
656 continue;
657
658 if (myHistMap.IsBound(anExpE.Current()))
659 continue;
660 TopTools_ListOfShape aListOfNewEdge;
661 TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
662
663 for(; anExpE2.More(); anExpE2.Next()) {
664 aListOfNewEdge.Append(anExpE2.Current());
665 }
666 myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
667 }
668 }
669
670 return Standard_True;
671 }
672
673 // ----------------------------------------------------------------------------------------------------
674 // function: MakeFacesSec
675 // purpose: Updates <myHistMap> by new faces in the case when old faces intersect each other
676 // ----------------------------------------------------------------------------------------------------
677 Standard_Boolean
MakeFacesSec(const Standard_Integer theIndex,const BOPDS_PDS & theDS,const Standard_Integer theFaceIndex1,const Standard_Integer theFaceIndex2,const Standard_Integer theSSInterfIndex)678 BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer theIndex,
679 const BOPDS_PDS& theDS,
680 const Standard_Integer theFaceIndex1,
681 const Standard_Integer theFaceIndex2,
682 const Standard_Integer theSSInterfIndex)
683 {
684 const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
685 const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex);
686 const BOPDS_VectorOfCurve& aBCurves = aFFi.Curves();
687
688 TopoDS_Compound aSecEdges;
689 TopoDS_Face aSecPlane;
690
691 if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges))
692 return Standard_False;
693
694 //Extract vertices on the intersection of correspondent U-edges
695 const TopoDS_Shape& LeftE1 = myUEdges->Value(theIndex, 1);
696 const TopoDS_Shape& LeftE2 = myUEdges->Value(theIndex, 2);
697 const TopoDS_Shape& RightE1 = myUEdges->Value(theIndex+1, 1);
698 const TopoDS_Shape& RightE2 = myUEdges->Value(theIndex+1, 2);
699
700 Standard_Integer IndexOfLeftE1 = theDS->Index(LeftE1);
701 Standard_Integer IndexOfLeftE2 = theDS->Index(LeftE2);
702 Standard_Integer IndexOfRightE1 = theDS->Index(RightE1);
703 Standard_Integer IndexOfRightE2 = theDS->Index(RightE2);
704
705 TopoDS_Vertex FirstVertex, LastVertex;
706 Standard_Real ParamOnLeftE1, ParamOnLeftE2, ParamOnRightE1, ParamOnRightE2;
707 FindCommonVertex(theDS, IndexOfLeftE1, IndexOfLeftE2,
708 FirstVertex, ParamOnLeftE1, ParamOnLeftE2);
709 FindCommonVertex(theDS, IndexOfRightE1, IndexOfRightE2,
710 LastVertex, ParamOnRightE1, ParamOnRightE2);
711
712 TopoDS_Shape SecWire;
713 gp_Pln SecPlane;
714 Standard_Boolean IsSingular;
715 Standard_Boolean WireFound = ChooseSection(aSecEdges,
716 FirstVertex, LastVertex,
717 SecWire, SecPlane, IsSingular );
718
719 if(WireFound) {
720 //aSecEdges = SecWire;
721 TopoDS_Compound aComp;
722 BRep_Builder BB;
723 BB.MakeCompound(aComp);
724 TopExp_Explorer explo( SecWire, TopAbs_EDGE );
725
726 for (; explo.More(); explo.Next())
727 BB.Add( aComp, explo.Current() );
728 aSecEdges = aComp;
729
730 StoreVedgeInHistMap(myVEdges, theIndex, SecWire, myHistMap);
731 }
732
733 TopTools_ListOfShape aCommonVertices;
734 // Standard_Integer acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
735 Standard_Integer fit = 0; //, ueit = 0, eindex = 0, i = 0;
736 Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
737
738 for(fit = 0; fit < 2; fit++) {
739 Standard_Integer aFaceIndex = (fit == 0) ? theFaceIndex1 : theFaceIndex2;
740 TopoDS_Face aFace = TopoDS::Face(theDS->Shape(aFaceIndex));
741 TopAbs_Orientation aFaceOri = aFace.Orientation();
742 TopoDS_Face aFaceF = aFace;
743 aFaceF.Orientation(TopAbs_FORWARD);
744 TopoDS_Edge aBoundEdge = TopoDS::Edge(myBounds->Value(theIndex, myBounds->LowerCol() +fit));
745 Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge);
746 TopoDS_Edge aUE1;
747 TopoDS_Edge aUE2;
748
749 if(!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
750 return Standard_False;
751
752 TopoDS_Edge aUE1old = aUE1;
753 TopoDS_Edge aUE2old = aUE2;
754
755 if (myHistMap.IsBound(aUE1)) {
756 const TopTools_ListOfShape& lst = myHistMap.Find(aUE1);
757
758 if(!lst.IsEmpty()) {
759 const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation());
760
761 if(!aUE1.IsSame(anEdge))
762 aSubstitutor->Replace(aUE1.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
763 aUE1 = TopoDS::Edge(anEdge);
764 }
765 }
766
767 if (myHistMap.IsBound(aUE2)) {
768 const TopTools_ListOfShape& lst = myHistMap.Find(aUE2);
769
770 if(!lst.IsEmpty()) {
771 const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation());
772
773 if(!aUE2.IsSame(anEdge))
774 aSubstitutor->Replace(aUE2.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
775 aUE2 = TopoDS::Edge(anEdge);
776 }
777 }
778 TopoDS_Vertex aPrevVertex, aNextVertex;
779 TopoDS_Compound aCompOfSecEdges = aSecEdges;
780 TopTools_ListOfShape aListOfWireEdges;
781 BRep_Builder aBB;
782 BOPDS_Pave aPave1;
783 Standard_Boolean isPave1OnUEdge = Standard_True;
784
785 if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex,
786 theDS, myHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) {
787 TopTools_ListOfShape aSecondListOfEdges;
788 Standard_Boolean bisSectionFound = Standard_False;
789
790 if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge,
791 aBoundEdgeIndex, theDS, myHistMap, aSecondListOfEdges, bisSectionFound)) {
792 return Standard_False;
793 }
794
795 if(!bisSectionFound && aListOfWireEdges.IsEmpty()) {
796 return Standard_False;
797 }
798 aListOfWireEdges.Append(aSecondListOfEdges);
799 }
800 else {
801 return Standard_False;
802 }
803
804 if(!aListOfWireEdges.IsEmpty()) {
805 TopoDS_Wire aW;
806 aBB.MakeWire(aW);
807 TopTools_ListIteratorOfListOfShape aEIt(aListOfWireEdges);
808
809 for(; aEIt.More(); aEIt.Next()) {
810 if(!aBoundEdge.IsSame(aEIt.Value()))
811 aBB.Add(aW, aEIt.Value());
812 }
813 aSubstitutor->Replace(aBoundEdge.Oriented(TopAbs_FORWARD), aW);
814 }
815
816 aSubstitutor->Apply(aFace);
817 TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
818 aNewFace.Orientation(aFaceOri);
819 TopTools_ListOfShape atmpList;
820 atmpList.Append(aNewFace);
821 myHistMap.Bind(aFace, atmpList);
822
823 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
824
825 for(; anExpE.More(); anExpE.Next()) {
826 TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
827
828 if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
829 continue;
830
831 if (myHistMap.IsBound(anExpE.Current()))
832 continue;
833 TopTools_ListOfShape aListOfNewEdge;
834 TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
835
836 for(; anExpE2.More(); anExpE2.Next()) {
837 aListOfNewEdge.Append(anExpE2.Current());
838 }
839 myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
840 }
841 }
842 return Standard_True;
843 }
844
845 //=======================================================================
846 //function : ChooseSection
847 //purpose :
848 //=======================================================================
ChooseSection(const TopoDS_Shape & Comp,const TopoDS_Vertex & theFirstVertex,const TopoDS_Vertex & theLastVertex,TopoDS_Shape & resWire,gp_Pln & resPlane,Standard_Boolean & IsSingular)849 Standard_Boolean BRepFill_TrimShellCorner::ChooseSection(const TopoDS_Shape& Comp,
850 const TopoDS_Vertex& theFirstVertex,
851 const TopoDS_Vertex& theLastVertex,
852 TopoDS_Shape& resWire,
853 gp_Pln& resPlane,
854 Standard_Boolean& IsSingular)
855 {
856 IsSingular = Standard_False;
857
858 Standard_Integer ind, i, j;
859 BRep_Builder BB;
860
861 if (myTransition == BRepFill_Right &&
862 !theFirstVertex.IsNull() &&
863 !theLastVertex.IsNull()) //the case where section wire goes from
864 //its known first vertex to its known last vertex
865 {
866 TopoDS_Wire NewWire;
867 BB.MakeWire(NewWire);
868
869 TopoDS_Compound OldComp;
870 BB.MakeCompound( OldComp );
871 TopoDS_Iterator iter( Comp );
872 for (; iter.More(); iter.Next())
873 BB.Add( OldComp, iter.Value() );
874
875 TopoDS_Edge FirstEdge = FindEdgeCloseToBisectorPlane(theFirstVertex,
876 OldComp,
877 myAxeOfBisPlane.Axis());
878 if (FirstEdge.IsNull())
879 return Standard_False;
880
881 iter.Initialize(OldComp);
882 if (!iter.More())
883 {
884 iter.Initialize(Comp);
885 BB.Add( OldComp, iter.Value() );
886 }
887 TopoDS_Edge LastEdge = FindEdgeCloseToBisectorPlane(theLastVertex,
888 OldComp,
889 myAxeOfBisPlane.Axis());
890 if (LastEdge.IsNull())
891 return Standard_False;
892
893 if (FirstEdge.IsNull() || LastEdge.IsNull())
894 {
895 return Standard_False;
896 }
897
898 BB.Add(NewWire, FirstEdge);
899
900 if (!FirstEdge.IsSame(LastEdge))
901 {
902 TopoDS_Vertex aCommonVertex;
903 Standard_Boolean CommonVertexExists = FindCommonVertex(FirstEdge, LastEdge,
904 theFirstVertex, theLastVertex,
905 aCommonVertex);
906 if (CommonVertexExists)
907 BB.Add(NewWire, LastEdge);
908 else
909 {
910 TopoDS_Vertex Vertex1, Vertex2, V1, V2;
911 TopExp::Vertices(FirstEdge, V1, V2);
912 Vertex1 = (theFirstVertex.IsSame(V1))? V2 : V1;
913 TopExp::Vertices(LastEdge, V1, V2);
914 Vertex2 = (theLastVertex.IsSame(V1))? V2 : V1;
915
916 TopTools_ListOfShape MiddleEdges;
917 if (FindMiddleEdges(Vertex1, Vertex2, myAxeOfBisPlane.Axis(), OldComp, MiddleEdges))
918 {
919 TopTools_ListIteratorOfListOfShape itl(MiddleEdges);
920 for (; itl.More(); itl.Next())
921 BB.Add(NewWire, itl.Value());
922 BB.Add(NewWire, LastEdge);
923 }
924 else
925 {
926 //trim <FirstEdge> and <LastEdge> in the points of extrema
927 //these points become new vertex with centre between them
928 BRepExtrema_ExtCC Extrema(FirstEdge, LastEdge);
929 if (Extrema.IsDone() && Extrema.NbExt() > 0)
930 {
931 Standard_Integer imin = 1;
932 for (i = 2; i <= Extrema.NbExt(); i++)
933 if (Extrema.SquareDistance(i) < Extrema.SquareDistance(imin))
934 imin = i;
935
936 Standard_Real aMinDist = sqrt(Extrema.SquareDistance(imin));
937 Standard_Real ParamOnFirstEdge = Extrema.ParameterOnE1(imin);
938 Standard_Real ParamOnLastEdge = Extrema.ParameterOnE2(imin);
939 gp_Pnt PointOnFirstEdge = Extrema.PointOnE1(imin);
940 gp_Pnt PointOnLastEdge = Extrema.PointOnE2(imin);
941 gp_Pnt MidPnt((PointOnFirstEdge.XYZ() + PointOnLastEdge.XYZ())/2);
942 aCommonVertex = BRepLib_MakeVertex(MidPnt);
943 BB.UpdateVertex(aCommonVertex, 1.001*aMinDist/2);
944
945 UpdateSectionEdge(FirstEdge, theFirstVertex, aCommonVertex, ParamOnFirstEdge);
946 UpdateSectionEdge(LastEdge, theLastVertex, aCommonVertex, ParamOnLastEdge);
947
948 BB.Add(NewWire, LastEdge);
949 }
950 }
951 }
952 }
953
954 resWire = NewWire;
955 resPlane = gp_Pln(myAxeOfBisPlane);
956 return Standard_True;
957 }
958
959 //General case: try to find continuous section closest to bisector plane
960 TopoDS_Compound OldComp;
961 BRep_Builder B;
962 B.MakeCompound( OldComp );
963 TopoDS_Iterator iter( Comp );
964 for (; iter.More(); iter.Next())
965 B.Add( OldComp, iter.Value() );
966
967 Standard_Boolean anError = Standard_False;
968 //TopoDS_Wire NewWire [2];
969 TopTools_SequenceOfShape Wseq;
970 for (;;)
971 {
972 TopExp_Explorer explo( OldComp, TopAbs_EDGE );
973 if (!explo.More())
974 break;
975 TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
976 TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge );
977 B.Remove( OldComp, FirstEdge );
978 if (NewWire.Closed())
979 {
980 Wseq.Append(NewWire);
981 continue;
982 }
983
984 for (;;)
985 {
986 TopoDS_Vertex Extremity [2];
987 TopExp::Vertices( NewWire, Extremity[0], Extremity[1] );
988 if (Extremity[0].IsNull() || Extremity[1].IsNull())
989 {
990 anError = Standard_True;
991 break;
992 }
993 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
994 TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
995 TopTools_ListOfShape Vedges [2];
996 for (j = 0; j < 2; j++)
997 if (VEmap.Contains( Extremity[j] ))
998 Vedges[j] = VEmap.FindFromKey( Extremity[j] );
999 if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
1000 //no more edges in OldComp to continue NewWire
1001 break;
1002 Standard_Boolean Modified = Standard_False;
1003 for (j = 0; j < 2; j++)
1004 {
1005 if (Vedges[j].Extent() == 1)
1006 {
1007 const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() );
1008 NewWire = BRepLib_MakeWire( NewWire, anEdge );
1009 B.Remove( OldComp, anEdge );
1010 Modified = Standard_True;
1011 }
1012 }
1013 if (!Modified) //only multiple connections
1014 {
1015 ind = (Vedges[0].IsEmpty())? 1 : 0;
1016 TopTools_SequenceOfShape Edges;
1017 TopTools_ListIteratorOfListOfShape itl( Vedges[ind] );
1018 for (; itl.More(); itl.Next())
1019 Edges.Append( itl.Value() );
1020 Standard_Integer theind=0;
1021 Standard_Real MinDeviation = RealLast();
1022 for (j = 1; j <= Edges.Length(); j++)
1023 {
1024 TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) );
1025 gp_Pln aPlane;
1026 Standard_Boolean issing;
1027 Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing );
1028 if (Deviation < MinDeviation)
1029 {
1030 MinDeviation = Deviation;
1031 theind = j;
1032 }
1033 }
1034 NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) );
1035 B.Remove( OldComp, Edges(theind) );
1036 }
1037 if (NewWire.Closed())
1038 break;
1039 }
1040 Wseq.Append(NewWire);
1041 if (anError)
1042 break;
1043 }
1044
1045 Standard_Real MinAngle = RealLast();
1046 TopExp_Explorer Explo( OldComp, TopAbs_EDGE );
1047 if (!anError && !Explo.More()) //wires are built successfully and compound <OldComp> is empty
1048 {
1049 if (Wseq.Length() == 1) //only one wire => it becomes result
1050 {
1051 resWire = Wseq.First();
1052 ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular );
1053 return Standard_True;
1054 }
1055 else //we must choose the wire which average plane is closest to bisector plane
1056 { //(check angle between axes)
1057 for (i = 1; i <= Wseq.Length(); i++)
1058 {
1059 TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) );
1060 gp_Pln aPln;
1061 Standard_Boolean issing;
1062 ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
1063 if (issing)
1064 continue;
1065
1066 Standard_Real Angle = aPln.Axis().Angle( myAxeOfBisPlane.Axis() );
1067 if (Angle > M_PI/2)
1068 Angle = M_PI - Angle;
1069
1070 if (Angle < MinAngle)
1071 {
1072 MinAngle = Angle;
1073 resWire = aWire;
1074 resPlane = aPln;
1075 }
1076 }
1077 return Standard_True;
1078 }
1079 }
1080 return Standard_False;
1081 }
1082
1083
1084 // ------------------------------------------------------------------------------------------
1085 // static function: SplitUEdges
1086 // purpose:
1087 // ------------------------------------------------------------------------------------------
SplitUEdges(const Handle (TopTools_HArray2OfShape)& theUEdges,const BOPDS_PDS & theDS,TopTools_DataMapOfShapeListOfShape & theHistMap)1088 Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
1089 const BOPDS_PDS& theDS,
1090 TopTools_DataMapOfShapeListOfShape& theHistMap) {
1091
1092 const BOPDS_VectorOfInterfVV& aVVs = theDS->InterfVV();
1093
1094 BRep_Builder aBB;
1095 Standard_Integer ueit = 0, upRow, lowCol, upCol;
1096 TopTools_Array2OfShape aNewVertices(1,2,1,2);
1097 //
1098 upRow = theUEdges->UpperRow();
1099 lowCol = theUEdges->LowerCol();
1100 upCol = theUEdges->UpperCol();
1101 //
1102 for(ueit = theUEdges->LowerRow(); ueit <= upRow; ueit++) {
1103 const TopoDS_Shape& aE1 = theUEdges->Value(ueit, lowCol);
1104 const TopoDS_Shape& aE2 = theUEdges->Value(ueit, upCol);
1105
1106 if(theHistMap.IsBound(aE1) || theHistMap.IsBound(aE2))
1107 continue;
1108
1109 Standard_Integer anEIndex1 = theDS->Index(aE1);
1110 Standard_Integer anEIndex2 = theDS->Index(aE2);
1111
1112 TopoDS_Vertex aCommonVertex;
1113 Standard_Real apar1 = 0., apar2 = 0.;
1114 Standard_Boolean bvertexfound =
1115 FindCommonVertex(theDS, anEIndex1, anEIndex2, aCommonVertex, apar1, apar2);
1116 //
1117 if(!bvertexfound) {
1118 TopoDS_Vertex V1 = TopExp::LastVertex(TopoDS::Edge(aE1));
1119 TopoDS_Vertex V2 = TopExp::FirstVertex(TopoDS::Edge(aE2));
1120 Standard_Integer vindex1 = theDS->Index(V1);
1121 Standard_Integer vindex2 = theDS->Index(V2);
1122 Standard_Integer vvit = 0;
1123 Standard_Integer aNbVVs = aVVs.Length();
1124
1125 for(vvit = 0; !bvertexfound && (vvit < aNbVVs); vvit++) {
1126 //const BOPTools_VVInterference& aVV = aVVs(vvit);
1127 const BOPDS_InterfVV& aVV = aVVs(vvit);
1128
1129 if(((vindex1 == aVV.Index1()) && (vindex2 == aVV.Index2())) ||
1130 ((vindex1 == aVV.Index2()) && (vindex2 == aVV.Index1()))) {
1131
1132 if(!aVV.HasIndexNew()) {
1133 continue;
1134 }
1135 aCommonVertex = TopoDS::Vertex(theDS->Shape(aVV.IndexNew()));
1136 bvertexfound = Standard_True;
1137 apar1 = BRep_Tool::Parameter(V1, TopoDS::Edge(aE1));
1138 apar2 = BRep_Tool::Parameter(V2, TopoDS::Edge(aE2));
1139 }
1140 }
1141 }
1142
1143 if(bvertexfound) {
1144 TopoDS_Vertex aV1, aV2;
1145 Standard_Real f = 0., l = 0.;
1146 //
1147 TopoDS_Edge aNewE1 = TopoDS::Edge(aE1.EmptyCopied());
1148 TopExp::Vertices(TopoDS::Edge(aE1), aV1, aV2);
1149 aNewE1.Orientation(TopAbs_FORWARD);
1150 aV1.Orientation(TopAbs_FORWARD);
1151 aBB.Add(aNewE1, aV1);
1152 aCommonVertex.Orientation(TopAbs_REVERSED);
1153 aBB.Add(aNewE1, aCommonVertex);
1154 BRep_Tool::Range(TopoDS::Edge(aE1), f, l);
1155 aBB.Range(aNewE1, f, apar1);
1156
1157 //
1158 TopoDS_Edge aNewE2 = TopoDS::Edge(aE2.EmptyCopied());
1159 TopExp::Vertices(TopoDS::Edge(aE2), aV1, aV2);
1160 aNewE2.Orientation(TopAbs_FORWARD);
1161 aCommonVertex.Orientation(TopAbs_FORWARD);
1162 aBB.Add(aNewE2, aCommonVertex);
1163 aBB.Add(aNewE2, aV2);
1164 BRep_Tool::Range(TopoDS::Edge(aE2), f, l);
1165 aBB.Range(aNewE2, apar2, l);
1166
1167 TopTools_ListOfShape lst;
1168 lst.Append(aNewE1);
1169 theHistMap.Bind(aE1, lst);
1170 lst.Clear();
1171 lst.Append(aNewE2);
1172 theHistMap.Bind(aE2, lst);
1173 }
1174 }
1175 return Standard_True;
1176 }
1177
1178 // ------------------------------------------------------------------------------------------
1179 // static function: StoreVedgeInHistMap
1180 // purpose:
1181 // ------------------------------------------------------------------------------------------
StoreVedgeInHistMap(const Handle (TopTools_HArray1OfShape)& theVEdges,const Standard_Integer theIndex,const TopoDS_Shape & theNewVshape,TopTools_DataMapOfShapeListOfShape & theHistMap)1182 void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)& theVEdges,
1183 const Standard_Integer theIndex,
1184 const TopoDS_Shape& theNewVshape,
1185 TopTools_DataMapOfShapeListOfShape& theHistMap)
1186 {
1187 //Replace default value in the map (v-iso edge of face)
1188 //by intersection of two consecutive faces
1189 const TopoDS_Shape& aVEdge = theVEdges->Value(theIndex);
1190
1191 theHistMap.Bound(aVEdge, TopTools_ListOfShape())->Append(theNewVshape);
1192 }
1193
1194 // ------------------------------------------------------------------------------------------
1195 // static function: FindFreeVertices
1196 // purpose:
1197 // ------------------------------------------------------------------------------------------
FindFreeVertices(const TopoDS_Shape & theShape,const TopTools_MapOfShape & theVerticesToAvoid,TopTools_ListOfShape & theListOfVertex)1198 void FindFreeVertices(const TopoDS_Shape& theShape,
1199 const TopTools_MapOfShape& theVerticesToAvoid,
1200 TopTools_ListOfShape& theListOfVertex) {
1201
1202 theListOfVertex.Clear();
1203 TopTools_IndexedDataMapOfShapeListOfShape aMap;
1204 TopExp::MapShapesAndAncestors(theShape, TopAbs_VERTEX, TopAbs_EDGE, aMap);
1205 Standard_Integer i = 0;
1206
1207 for(i = 1; i <= aMap.Extent(); i++) {
1208 const TopoDS_Shape& aKey = aMap.FindKey(i);
1209
1210 if(theVerticesToAvoid.Contains(aKey))
1211 continue;
1212 const TopTools_ListOfShape& aList = aMap.FindFromIndex(i);
1213
1214 if(aList.Extent() < 2) {
1215 theListOfVertex.Append(aKey);
1216 }
1217 }
1218 }
1219
1220 // ------------------------------------------------------------------------------------------
1221 // static function: FindCommonVertex
1222 // purpose:
1223 // ------------------------------------------------------------------------------------------
FindCommonVertex(const BOPDS_PDS & theDS,const Standard_Integer theEIndex1,const Standard_Integer theEIndex2,TopoDS_Vertex & theCommonVertex,Standard_Real & theParamOnE1,Standard_Real & theParamOnE2)1224 Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
1225 const Standard_Integer theEIndex1,
1226 const Standard_Integer theEIndex2,
1227 TopoDS_Vertex& theCommonVertex,
1228 Standard_Real& theParamOnE1,
1229 Standard_Real& theParamOnE2) {
1230
1231 const BOPDS_VectorOfInterfEE& aEEs = theDS->InterfEE();
1232
1233 Standard_Boolean bvertexfound = Standard_False;
1234 TopoDS_Vertex aCommonVertex;
1235 Standard_Integer eeit = 0;
1236
1237 Standard_Integer aNbEEs;
1238 aNbEEs = aEEs.Length();
1239 for(eeit = 0; eeit < aNbEEs; ++eeit) {
1240 const BOPDS_InterfEE& aEE = aEEs(eeit);
1241
1242 if((theEIndex1 == aEE.Index1() && theEIndex2 == aEE.Index2()) ||
1243 (theEIndex1 == aEE.Index2() && theEIndex2 == aEE.Index1())) {
1244
1245 if(!aEE.HasIndexNew())
1246 continue;
1247
1248 IntTools_CommonPrt aCP = aEE.CommonPart();
1249 if(aCP.Type() == TopAbs_VERTEX)
1250 {
1251 theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew());
1252
1253 if (theEIndex1 == aEE.Index1())
1254 IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2);
1255 else
1256 IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1);
1257
1258 //
1259 bvertexfound = Standard_True;
1260 break;
1261 }
1262 }
1263 }
1264 return bvertexfound;
1265 }
1266
1267 // ----------------------------------------------------------------------------------------------------
1268 // static function: GetUEdges
1269 // purpose:
1270 // ----------------------------------------------------------------------------------------------------
GetUEdges(const Standard_Integer theIndex,const Standard_Integer theRank,const Handle (TopTools_HArray2OfShape)& theUEdges,const TopoDS_Edge & theBoundEdge,const TopoDS_Face & theFace,TopoDS_Edge & theFirstUEdge,TopoDS_Edge & theSecondUEdge)1271 Standard_Boolean GetUEdges(const Standard_Integer theIndex,
1272 const Standard_Integer theRank,
1273 const Handle(TopTools_HArray2OfShape)& theUEdges,
1274 const TopoDS_Edge& theBoundEdge,
1275 const TopoDS_Face& theFace,
1276 TopoDS_Edge& theFirstUEdge,
1277 TopoDS_Edge& theSecondUEdge) {
1278 const TopoDS_Shape& aUE1 = theUEdges->Value(theIndex, theUEdges->LowerCol() + theRank);
1279 const TopoDS_Shape& aUE2 = theUEdges->Value(theIndex + 1, theUEdges->LowerCol() + theRank);
1280
1281 TopoDS_Face aFace = theFace;
1282 aFace.Orientation(TopAbs_FORWARD);
1283 TopoDS_Edge E1, E2;
1284 TopExp_Explorer anExp(aFace, TopAbs_EDGE);
1285
1286 for(; anExp.More(); anExp.Next()) {
1287 if(E1.IsNull() && aUE1.IsSame(anExp.Current())) {
1288 E1 = TopoDS::Edge(anExp.Current());
1289 }
1290 else if(E2.IsNull() && aUE2.IsSame(anExp.Current())) {
1291 E2 = TopoDS::Edge(anExp.Current());
1292 }
1293 }
1294
1295 if(E1.IsNull() || E2.IsNull())
1296 return Standard_False;
1297
1298 Standard_Real f, l;
1299 Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1, aFace, f, l);
1300
1301 if(C1.IsNull())
1302 return Standard_False;
1303 gp_Pnt2d PU1 = (theRank == 0) ? C1->Value(l) : C1->Value(f);
1304 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFace, f, l);
1305
1306 if(C2.IsNull())
1307 return Standard_False;
1308 BRep_Tool::Range(theBoundEdge, f, l);
1309 gp_Pnt2d pf = C2->Value(f);
1310 TopoDS_Vertex aV = (theRank == 0) ? TopExp::LastVertex(E1) : TopExp::FirstVertex(E1);
1311 Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
1312 BRepAdaptor_Surface aBAS(aFace, Standard_False);
1313
1314 if(pf.Distance(PU1) > aBAS.UResolution(aTolerance)) {
1315 TopoDS_Edge atmpE = E1;
1316 E1 = E2;
1317 E2 = atmpE;
1318 }
1319 theFirstUEdge = E1;
1320 theSecondUEdge = E2;
1321 return Standard_True;
1322 }
1323
1324 // ----------------------------------------------------------------------------------------------------
1325 // static function: FillGap
1326 // purpose:
1327 // ----------------------------------------------------------------------------------------------------
FillGap(const TopoDS_Vertex & theFirstVertex,const TopoDS_Vertex & theLastVertex,const gp_Pnt2d & theFirstPoint,const gp_Pnt2d & theLastPoint,const TopoDS_Face & theFace,const TopoDS_Compound & theSectionEdges,TopTools_ListOfShape & theOrderedList)1328 Standard_Boolean FillGap(const TopoDS_Vertex& theFirstVertex,
1329 const TopoDS_Vertex& theLastVertex,
1330 const gp_Pnt2d& theFirstPoint,
1331 const gp_Pnt2d& theLastPoint,
1332 const TopoDS_Face& theFace,
1333 const TopoDS_Compound& theSectionEdges,
1334 TopTools_ListOfShape& theOrderedList) {
1335
1336 TopTools_IndexedDataMapOfShapeListOfShape aMap;
1337 TopExp::MapShapesAndAncestors(theSectionEdges, TopAbs_VERTEX, TopAbs_EDGE, aMap);
1338
1339 if(aMap.IsEmpty()) {
1340 return Standard_False;
1341 }
1342
1343 if(!aMap.Contains(theFirstVertex) ||
1344 !aMap.Contains(theLastVertex)) {
1345 return Standard_False;
1346 }
1347 TopTools_ListOfShape aListOfEdge;
1348 // Standard_Integer i = 0;
1349 // TopoDS_Vertex aCurVertex = theFirstVertex;
1350 TopTools_MapOfShape aMapToAvoid;
1351
1352 if(FindNextEdge(theFirstVertex, theLastVertex, aMap, aMapToAvoid, aListOfEdge)) {
1353 if(!aListOfEdge.IsEmpty()) {
1354 return CheckAndOrientEdges(aListOfEdge, theFirstPoint, theLastPoint, theFace, theOrderedList);
1355 }
1356 }
1357 return Standard_False;
1358 }
1359
1360 // ----------------------------------------------------------------------------------------------------
1361 // static function: FindNextEdge
1362 // purpose:
1363 // ----------------------------------------------------------------------------------------------------
FindNextEdge(const TopoDS_Vertex & theFirstVertex,const TopoDS_Vertex & theLastVertex,const TopTools_IndexedDataMapOfShapeListOfShape & theMapVE,const TopTools_MapOfShape & theMapToAvoid,TopTools_ListOfShape & theOrderedList)1364 Standard_Boolean FindNextEdge(const TopoDS_Vertex& theFirstVertex,
1365 const TopoDS_Vertex& theLastVertex,
1366 const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
1367 const TopTools_MapOfShape& theMapToAvoid,
1368 TopTools_ListOfShape& theOrderedList) {
1369 TopoDS_Vertex aCurVertex = theFirstVertex;
1370 TopTools_MapOfShape aMapToAvoid;
1371 aMapToAvoid = theMapToAvoid;
1372 TopTools_ListOfShape aListOfEdge;
1373 Standard_Integer i = 0;
1374
1375 for(i = 1; i <= theMapVE.Extent(); i++) {
1376 if(!theMapVE.Contains(aCurVertex))
1377 break;
1378 const TopTools_ListOfShape& lste = theMapVE.FindFromKey(aCurVertex);
1379 Standard_Boolean befound = Standard_False;
1380
1381 TopTools_ListIteratorOfListOfShape anIt(lste);
1382
1383 for(; anIt.More(); anIt.Next()) {
1384 TopoDS_Shape anEdge = anIt.Value();
1385 TopoDS_Vertex aSaveCurVertex = aCurVertex;
1386
1387 if(!aMapToAvoid.Contains(anEdge)) {
1388 TopoDS_Vertex V1, V2;
1389 TopExp::Vertices(TopoDS::Edge(anEdge), V1, V2);
1390
1391 if(!aCurVertex.IsSame(V1)) {
1392 aCurVertex = V1;
1393 }
1394 else if(!aCurVertex.IsSame(V2)) {
1395 aCurVertex = V2;
1396 }
1397 aMapToAvoid.Add(anEdge);
1398 befound = Standard_True;
1399 aListOfEdge.Append(anEdge);
1400
1401 if(!aCurVertex.IsSame(theLastVertex)) {
1402 TopTools_ListOfShape aListtmp;
1403
1404 if(!FindNextEdge(aCurVertex, theLastVertex, theMapVE, aMapToAvoid, aListtmp)) {
1405 aListOfEdge.Clear();
1406 aCurVertex = aSaveCurVertex;
1407 continue;
1408 }
1409 else {
1410 aListOfEdge.Append(aListtmp);
1411 theOrderedList.Append(aListOfEdge);
1412 return Standard_True;
1413 }
1414 }
1415 break;
1416 }
1417 }
1418
1419 if(aCurVertex.IsSame(theLastVertex))
1420 break;
1421
1422 if(!befound) {
1423 return Standard_False;
1424 }
1425 }
1426
1427 if(aCurVertex.IsSame(theLastVertex)) {
1428 theOrderedList.Append(aListOfEdge);
1429 return Standard_True;
1430 }
1431 return Standard_False;
1432 }
1433
1434 // ----------------------------------------------------------------------------------------------------
1435 // static function: CheckAndOrientEdges
1436 // purpose:
1437 // ----------------------------------------------------------------------------------------------------
CheckAndOrientEdges(const TopTools_ListOfShape & theOrderedList,const gp_Pnt2d & theFirstPoint,const gp_Pnt2d & theLastPoint,const TopoDS_Face & theFace,TopTools_ListOfShape & theOrientedList)1438 Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList,
1439 const gp_Pnt2d& theFirstPoint,
1440 const gp_Pnt2d& theLastPoint,
1441 const TopoDS_Face& theFace,
1442 TopTools_ListOfShape& theOrientedList) {
1443 TopTools_ListIteratorOfListOfShape anIt(theOrderedList);
1444
1445 if(!anIt.More())
1446 return Standard_True;
1447
1448 Standard_Real f, l;
1449 TopoDS_Edge aEPrev = TopoDS::Edge(anIt.Value());
1450 anIt.Next();
1451
1452 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(aEPrev, theFace, f, l);
1453 TopoDS_Vertex Vf, Vl;
1454 TopExp::Vertices(aEPrev, Vf, Vl);
1455 BRepAdaptor_Surface aBAS(theFace, Standard_False);
1456
1457 Standard_Real aTolerance1 = (Vf.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vf);
1458 Standard_Real aTolerance2 = (Vl.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vl);
1459 Standard_Real utol = aBAS.UResolution(aTolerance1);
1460 Standard_Real vtol = aBAS.VResolution(aTolerance1);
1461 aTolerance1 = (utol > vtol) ? utol : vtol;
1462 utol = aBAS.UResolution(aTolerance2);
1463 vtol = aBAS.VResolution(aTolerance2);
1464 aTolerance2 = (utol > vtol) ? utol : vtol;
1465
1466 gp_Pnt2d ap = aCurve->Value(f);
1467 Standard_Boolean bFirstFound = Standard_False;
1468 Standard_Boolean bLastFound = Standard_False;
1469
1470 if(ap.Distance(theFirstPoint) < aTolerance1) {
1471 if(theOrientedList.IsEmpty())
1472 theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
1473 bFirstFound = Standard_True;
1474 }
1475 else if(ap.Distance(theLastPoint) < aTolerance1) {
1476 if(theOrientedList.IsEmpty())
1477 theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
1478 bLastFound = Standard_True;
1479 }
1480 ap = aCurve->Value(l);
1481
1482 if(ap.Distance(theLastPoint) < aTolerance2) {
1483 if(theOrientedList.IsEmpty())
1484 theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
1485 bLastFound = Standard_True;
1486 }
1487 else if(ap.Distance(theFirstPoint) < aTolerance2) {
1488 if(theOrientedList.IsEmpty())
1489 theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
1490 bFirstFound = Standard_True;
1491 }
1492
1493 if (!theOrientedList.IsEmpty())
1494 aEPrev = TopoDS::Edge (theOrientedList.Last());
1495
1496 for(; anIt.More(); anIt.Next()) {
1497 const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
1498 TopoDS_Vertex aV11, aV12;
1499 TopExp::Vertices(aEPrev, aV11, aV12, Standard_True);
1500 TopoDS_Vertex aV21, aV22;
1501 TopExp::Vertices(aE, aV21, aV22, Standard_False);
1502
1503 TopAbs_Orientation anOri =
1504 (aV12.IsSame (aV21) || aV11.IsSame (aV22)) ? TopAbs_FORWARD : TopAbs_REVERSED;
1505 theOrientedList.Append(aE.Oriented(anOri));
1506 aEPrev = TopoDS::Edge (theOrientedList.Last());
1507
1508 aTolerance1 = (aV21.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV21);
1509 aTolerance2 = (aV22.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV22);
1510 utol = aBAS.UResolution(aTolerance1);
1511 vtol = aBAS.VResolution(aTolerance1);
1512 aTolerance1 = (utol > vtol) ? utol : vtol;
1513 utol = aBAS.UResolution(aTolerance2);
1514 vtol = aBAS.VResolution(aTolerance2);
1515 aTolerance2 = (utol > vtol) ? utol : vtol;
1516 aCurve = BRep_Tool::CurveOnSurface(aE, theFace, f, l);
1517 ap = aCurve->Value(f);
1518
1519 if(ap.Distance(theFirstPoint) < aTolerance1) {
1520 bFirstFound = Standard_True;
1521 }
1522 else if(ap.Distance(theLastPoint) < aTolerance1) {
1523 bLastFound = Standard_True;
1524 }
1525 ap = aCurve->Value(l);
1526
1527 if(ap.Distance(theFirstPoint) < aTolerance2) {
1528 bFirstFound = Standard_True;
1529 }
1530 else if(ap.Distance(theLastPoint) < aTolerance2) {
1531 bLastFound = Standard_True;
1532 }
1533 }
1534
1535 return bFirstFound && bLastFound;
1536 }
1537
1538 // ----------------------------------------------------------------------------------------------------
1539 // static function: FindVertex
1540 // purpose:
1541 // ----------------------------------------------------------------------------------------------------
FindVertex(const TopoDS_Edge & theEdge,const Standard_Integer theRank,const BOPDS_PDS & theDS,const TopTools_DataMapOfShapeListOfShape & theHistMap,TopoDS_Vertex & theVertex,BOPDS_Pave & thePave)1542 Standard_Boolean FindVertex(const TopoDS_Edge& theEdge,
1543 const Standard_Integer theRank,
1544 const BOPDS_PDS& theDS,
1545 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1546 TopoDS_Vertex& theVertex,
1547 BOPDS_Pave& thePave) {
1548
1549 if(!theHistMap.IsBound(theEdge))
1550 return Standard_False;
1551
1552 const TopTools_ListOfShape& lst = theHistMap.Find(theEdge);
1553
1554 if(lst.IsEmpty())
1555 return Standard_False;
1556
1557 TopoDS_Edge aNewEdge = TopoDS::Edge(lst.First());
1558 Standard_Real f, l;
1559 BRep_Tool::Range(aNewEdge, f, l);
1560
1561 if(theRank == 0) {
1562 thePave.SetParameter(l);
1563 theVertex = TopExp::LastVertex(aNewEdge);
1564 }
1565 else {
1566 thePave.SetParameter(f);
1567 theVertex = TopExp::FirstVertex(aNewEdge);
1568 }
1569 Standard_Integer anIndex = theDS->Index(theVertex);
1570 if (anIndex == -1) {
1571 Standard_Integer i, i1, i2;
1572 i1=theDS->NbSourceShapes();
1573 i2=theDS->NbShapes();
1574 for (i=i1; i<i2; ++i) {
1575 const TopoDS_Shape& aSx=theDS->Shape(i);
1576 if(aSx.IsSame(theVertex)) {
1577 anIndex = i;
1578 break;
1579 }
1580 }
1581 }
1582
1583 thePave.SetIndex(anIndex);
1584
1585 return Standard_True;
1586 }
1587
1588 // ----------------------------------------------------------------------------------------------------
1589 // static function: FindNextVertex
1590 // purpose:
1591 // ----------------------------------------------------------------------------------------------------
FindNextVertex(const Standard_Integer theEdgeIndex,const BOPDS_Pave & thePrevPave,const BOPDS_PDS & theDS,TopoDS_Vertex & theNextVertex,BOPDS_Pave & thePave)1592 Standard_Boolean FindNextVertex(const Standard_Integer theEdgeIndex,
1593 const BOPDS_Pave& thePrevPave,
1594 const BOPDS_PDS& theDS,
1595 TopoDS_Vertex& theNextVertex,
1596 BOPDS_Pave& thePave) {
1597
1598 Standard_Boolean bTakePave, bFound;
1599 BOPDS_Pave aTmpPave;
1600 BOPDS_ListIteratorOfListOfPave aItP;
1601 //
1602 BOPDS_Pave anullpave;
1603 bFound = Standard_False;
1604 bTakePave = thePrevPave.IsEqual(anullpave);
1605
1606 BOPDS_ListOfPave aLP;
1607 theDS->Paves(theEdgeIndex, aLP);
1608 aItP.Initialize(aLP);
1609 for (; aItP.More(); aItP.Next()) {
1610 aTmpPave = aItP.Value();
1611 //
1612 if (bTakePave) {
1613 if (theDS->IsNewShape(aTmpPave.Index())) {
1614 theNextVertex = *(TopoDS_Vertex*)&theDS->Shape(aTmpPave.Index());
1615 thePave = aTmpPave;
1616 bFound = Standard_True;
1617 break;
1618 }
1619 }
1620 //
1621 else if (aTmpPave.IsEqual(thePrevPave)) {
1622 bTakePave = Standard_True;
1623 }
1624 }
1625
1626 return bFound;
1627 }
1628
1629 // ----------------------------------------------------------------------------------------------------
1630 // static function: GetPave
1631 // purpose:
1632 // ----------------------------------------------------------------------------------------------------
GetPave(const Standard_Integer theEdgeIndex,const Standard_Boolean isFirst,const BOPDS_PDS & theDS,BOPDS_Pave & thePave)1633 Standard_Boolean GetPave(const Standard_Integer theEdgeIndex,
1634 const Standard_Boolean isFirst,
1635 const BOPDS_PDS& theDS,
1636 BOPDS_Pave& thePave) {
1637
1638 Handle(BOPDS_PaveBlock) aPB;
1639 BOPDS_ListOfPave aLP;
1640
1641 theDS->Paves(theEdgeIndex, aLP);
1642 if (!aLP.Extent()) {
1643 return Standard_False;
1644 }
1645 //
1646 if (isFirst) {
1647 thePave = aLP.First();
1648 }
1649 else {
1650 thePave = aLP.Last();
1651 }
1652
1653 return Standard_True;
1654 }
1655
1656 // ----------------------------------------------------------------------------------------------------
1657 // static function: FindFromUEdge
1658 // purpose:
1659 // ----------------------------------------------------------------------------------------------------
FindFromUEdge(const TopoDS_Edge & theUE1Old,const TopoDS_Edge & theUE2Old,const TopoDS_Edge & theUE1New,const TopoDS_Edge & theUE2New,const TopoDS_Face & theFace,const TopoDS_Compound & theSecEdges,const Standard_Integer theRank,const TopoDS_Edge & theBoundEdge,const Standard_Integer theBoundEdgeIndex,const BOPDS_PDS & theDS,const TopTools_DataMapOfShapeListOfShape & theHistMap,TopoDS_Compound & theSecEdgesNew,TopTools_ListOfShape & theListOfWireEdges,BOPDS_Pave & theFoundPave,Standard_Boolean & isOnUEdge)1660 Standard_Boolean FindFromUEdge(const TopoDS_Edge& theUE1Old,
1661 const TopoDS_Edge& theUE2Old,
1662 const TopoDS_Edge& theUE1New,
1663 const TopoDS_Edge& theUE2New,
1664 const TopoDS_Face& theFace,
1665 const TopoDS_Compound& theSecEdges,
1666 const Standard_Integer theRank,
1667 const TopoDS_Edge& theBoundEdge,
1668 const Standard_Integer theBoundEdgeIndex,
1669 const BOPDS_PDS& theDS,
1670 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1671 TopoDS_Compound& theSecEdgesNew,
1672 TopTools_ListOfShape& theListOfWireEdges,
1673 BOPDS_Pave& theFoundPave,
1674 Standard_Boolean& isOnUEdge) {
1675 theFoundPave.SetIndex(0);
1676 theFoundPave.SetParameter(0.);
1677 isOnUEdge = Standard_True;
1678
1679 TopoDS_Face aFaceF = theFace;
1680 aFaceF.Orientation(TopAbs_FORWARD);
1681 TopoDS_Vertex aPrevVertex, aNextVertex;
1682 TopoDS_Compound aCompOfSecEdges = theSecEdges;
1683 TopTools_ListOfShape aListOfWireEdges;
1684 // BRep_Builder aBB;
1685
1686 BOPDS_Pave aPave1, aPave2;
1687 Standard_Real f = 0., l = 0.;
1688 gp_Pnt2d p1, p2;
1689 TopoDS_Vertex aFirstV, aLastV;
1690 BOPDS_Pave atmpPave;
1691
1692 if(!FindVertex(theUE1Old, theRank, theDS, theHistMap, aPrevVertex, atmpPave)) {
1693 return Standard_True;
1694 }
1695
1696 if(aPrevVertex.IsNull()) {
1697 return Standard_False;
1698 }
1699
1700 aFirstV = aPrevVertex;
1701 Standard_Boolean bSecFound = Standard_False;
1702 Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1New, aFaceF, f, l);
1703 p1 = (theRank == 0) ? aC1->Value(l) : aC1->Value(f);
1704 BOPDS_Pave afoundpave;
1705 BOPDS_ListOfPave aLP;
1706 theDS->Paves(theBoundEdgeIndex, aLP);
1707 Standard_Integer nbpave = aLP.Extent();
1708 Standard_Integer pit = 0;
1709
1710 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1711 aLastV = aNextVertex;
1712 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
1713 p2 = aC2->Value(aPave2.Parameter());
1714 TopTools_ListOfShape aOrderedList;
1715
1716 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1717 // remove found edges...
1718 TopoDS_Compound aComp;
1719 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1720 aCompOfSecEdges = aComp;
1721 aListOfWireEdges.Append(aOrderedList);
1722 afoundpave = aPave2;
1723 isOnUEdge = Standard_False;
1724 bSecFound = Standard_True;
1725 break;
1726 }
1727 aPrevVertex = aNextVertex;
1728 aPave1 = aPave2;
1729 pit++;
1730 }
1731
1732 if(!bSecFound && FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1733 aLastV = aNextVertex;
1734 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theUE2New, aFaceF, f, l);
1735 p2 = aC2->Value(aPave2.Parameter());
1736 TopTools_ListOfShape aOrderedList;
1737
1738 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1739 // remove found edges...
1740 TopoDS_Compound aComp;
1741
1742 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1743 aCompOfSecEdges = aComp;
1744 aListOfWireEdges.Append(aOrderedList);
1745 afoundpave = aPave2;
1746 bSecFound = Standard_True;
1747 isOnUEdge = Standard_True;
1748 }
1749 }
1750
1751 if(bSecFound) {
1752 theFoundPave = afoundpave;
1753 theListOfWireEdges = aListOfWireEdges;
1754 theSecEdgesNew = aCompOfSecEdges;
1755 }
1756 return Standard_True;
1757 }
1758
1759
1760 // ----------------------------------------------------------------------------------------------------
1761 // static function: FindFromVEdge
1762 // purpose:
1763 // ----------------------------------------------------------------------------------------------------
FindFromVEdge(const BOPDS_Pave & thePrevPave,const Standard_Boolean & isOnUEdge,const TopoDS_Edge & theUE1Old,const TopoDS_Edge & theUE2Old,const TopoDS_Face & theFace,const TopoDS_Compound & theSecEdges,const Standard_Integer theRank,const TopoDS_Edge & theBoundEdge,const Standard_Integer theBoundEdgeIndex,const BOPDS_PDS & theDS,const TopTools_DataMapOfShapeListOfShape & theHistMap,TopTools_ListOfShape & theListOfWireEdges,Standard_Boolean & isSectionFound)1764 Standard_Boolean FindFromVEdge(const BOPDS_Pave& thePrevPave,
1765 const Standard_Boolean& isOnUEdge,
1766 const TopoDS_Edge& theUE1Old,
1767 const TopoDS_Edge& theUE2Old,
1768 const TopoDS_Face& theFace,
1769 const TopoDS_Compound& theSecEdges,
1770 const Standard_Integer theRank,
1771 const TopoDS_Edge& theBoundEdge,
1772 const Standard_Integer theBoundEdgeIndex,
1773 const BOPDS_PDS& theDS,
1774 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1775 TopTools_ListOfShape& theListOfWireEdges,
1776 Standard_Boolean& isSectionFound) {
1777
1778 theListOfWireEdges.Clear();
1779 isSectionFound = Standard_False;
1780 //
1781 TopoDS_Face aFaceF = theFace;
1782 aFaceF.Orientation(TopAbs_FORWARD);
1783 TopoDS_Vertex aPrevVertex, aNextVertex;
1784 TopoDS_Compound aCompOfSecEdges = theSecEdges;
1785 TopTools_ListOfShape aListOfWireEdges;
1786 // BRep_Builder aBB;
1787
1788 BOPDS_Pave aPave1, aPave2;
1789
1790 if(isOnUEdge) {
1791 TopoDS_Vertex atmpVertex;
1792 BOPDS_Pave aPaveOfE2;
1793
1794 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, atmpVertex, aPaveOfE2)) {
1795 if(thePrevPave.IsEqual(aPaveOfE2))
1796 return Standard_True;
1797 }
1798 }
1799
1800 Standard_Real f = 0., l = 0.;
1801 gp_Pnt2d p1(0., 0.), p2(0., 0.);
1802 TopoDS_Vertex aFirstV, aLastV;
1803 Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1Old, aFaceF, f, l);
1804 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
1805 Standard_Boolean bSecFound = Standard_False;
1806
1807 aPave1 = thePrevPave;
1808
1809 if(isOnUEdge) {
1810 BOPDS_Pave atmpPave;
1811
1812 if(!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave)) {
1813 return Standard_False;
1814 }
1815 aPave1 = atmpPave;
1816 }
1817 p1 = aC2->Value(aPave1.Parameter());
1818 aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
1819
1820 BOPDS_ListOfPave aLP;
1821 theDS->Paves(theBoundEdgeIndex, aLP);
1822 Standard_Integer nbpave = aLP.Extent();
1823 Standard_Integer pit = 0;
1824 TopTools_Array1OfListOfShape anArrayOfListOfSec(1, nbpave);
1825
1826 // by pairs non continuously. begin
1827 Standard_Integer k = 0;
1828 BOPDS_Pave aFirstPave = aPave1;
1829 TopoDS_Vertex aFirstVertex = aPrevVertex;
1830 gp_Pnt2d apfirst = p1;
1831 BOPDS_ListOfPave aFirstPaves, aLastPaves;
1832 TColStd_ListOfInteger aListOfFlags;
1833 Standard_Integer apaircounter = 1;
1834
1835 for(k = 0; k < nbpave; k++) {
1836 aPave1 = aFirstPave;
1837 p1 = apfirst;
1838 aPrevVertex = aFirstVertex;
1839 Standard_Boolean bfound = Standard_False;
1840 pit = 0;
1841
1842 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1843 aFirstV = aPrevVertex;
1844 aLastV = aNextVertex;
1845 p2 = aC2->Value(aPave2.Parameter());
1846
1847 TopTools_ListOfShape aOrderedList;
1848
1849 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1850 TopoDS_Compound aComp;
1851 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1852 aCompOfSecEdges = aComp;
1853
1854 anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
1855 aFirstPaves.Append(aFirstPave);
1856 aLastPaves.Append(aPave2);
1857 aListOfFlags.Append(1);
1858 aFirstPave = aPave2;
1859 aFirstVertex = aNextVertex;
1860 apfirst = p2;
1861 aPrevVertex = aNextVertex;
1862 bSecFound = Standard_True;
1863 bfound = Standard_True;
1864 }
1865 aPave1 = aPave2;
1866 pit++;
1867 }
1868
1869 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1870 aFirstV = aPrevVertex;
1871 aLastV = aNextVertex;
1872 Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1873 p2 = aC3->Value(aPave2.Parameter());
1874
1875 TopTools_ListOfShape aOrderedList;
1876
1877 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1878 TopoDS_Compound aComp;
1879 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1880 aCompOfSecEdges = aComp;
1881 anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
1882 aFirstPaves.Append(aFirstPave);
1883 aLastPaves.Append(aPave2);
1884 aListOfFlags.Append(0);
1885 bSecFound = Standard_True;
1886 break;
1887 }
1888 }
1889
1890 if(!bfound) {
1891 if(!FindNextVertex(theBoundEdgeIndex, aFirstPave, theDS, aNextVertex, aPave2)) {
1892 break;
1893 }
1894 aFirstPave = aPave2;
1895 apfirst = aC2->Value(aPave2.Parameter());
1896 aFirstVertex = aNextVertex;
1897 }
1898 }
1899 // by pairs non continuously. end
1900
1901 // by pairs continuously. begin
1902 aPave1 = thePrevPave;
1903
1904 if(isOnUEdge) {
1905 BOPDS_Pave atmpPave;
1906
1907 if(!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave)) {
1908 return Standard_False;
1909 }
1910 aPave1 = atmpPave;
1911 }
1912 p1 = aC2->Value(aPave1.Parameter());
1913 aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
1914
1915 pit = 0;
1916
1917 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1918 aFirstV = aPrevVertex;
1919 aLastV = aNextVertex;
1920 p2 = aC2->Value(aPave2.Parameter());
1921
1922 Standard_Boolean bisinside = Standard_False;
1923 Standard_Integer apbindex = 0;
1924 Standard_Integer apbcounter = 1;
1925 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1926 BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
1927 TColStd_ListIteratorOfListOfInteger aFlagIt;
1928
1929 for(aPIt1.Initialize(aFirstPaves), aPIt2.Initialize(aLastPaves), aFlagIt.Initialize(aListOfFlags);
1930 aPIt1.More() && aPIt2.More() && aFlagIt.More();
1931 aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++) {
1932
1933 Standard_Boolean bfin = Standard_False;
1934 Standard_Boolean blin = Standard_False;
1935
1936 if(aPave1.IsEqual(aPIt1.Value())) {
1937 bfin = Standard_True;
1938 }
1939 else {
1940 bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
1941 }
1942
1943 if(aFlagIt.Value()) {
1944 if(aPave2.IsEqual(aPIt2.Value())) {
1945 blin = Standard_True;
1946 }
1947 else {
1948 blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
1949 }
1950 }
1951 else {
1952 if((aPave2.Index() == aPIt2.Value().Index()) && (aPave2.Index() > 0)) {
1953 Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1954 gp_Pnt2d p3 = pc->Value(aPIt2.Value().Parameter());
1955 TopoDS_Vertex aV = TopoDS::Vertex(theDS->Shape(aPave2.Index()));
1956 BRepAdaptor_Surface aBAS(aFaceF, Standard_False);
1957 Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
1958 Standard_Real utol = aBAS.UResolution(aTolerance);
1959 Standard_Real vtol = aBAS.VResolution(aTolerance);
1960 aTolerance = (utol > vtol) ? utol : vtol;
1961
1962 if(p2.Distance(p3) < aTolerance)
1963 blin = Standard_True;
1964 }
1965 }
1966
1967 if(bfin && blin) {
1968 apbindex = apbcounter;
1969 bisinside = Standard_True;
1970 break;
1971 }
1972 }
1973
1974 if(!bisinside) {
1975
1976 TopTools_ListOfShape aOrderedList;
1977
1978 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1979 TopoDS_Compound aComp;
1980 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1981 aCompOfSecEdges = aComp;
1982 aListOfWireEdges.Append(aOrderedList);
1983
1984 bSecFound = Standard_True;
1985 }
1986 else {
1987 TopoDS_Edge aESplit;
1988 // get split
1989 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
1990
1991 for(; aPBIt.More(); aPBIt.Next()) {
1992 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
1993 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
1994 aPB1->Pave1().IsEqual(aPave1) &&
1995 aPB1->Pave2().IsEqual(aPave2) ) {
1996 if(aPB1->Edge() > 0) {
1997 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
1998 break;
1999 }
2000 }
2001 }
2002
2003 if(!aESplit.IsNull()) {
2004 aListOfWireEdges.Append(aESplit);
2005 }
2006 }
2007 }
2008 else {
2009 if(apbindex > 0) {
2010 TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
2011 aListOfWireEdges.Append(aListOfSec);
2012 }
2013 }
2014 aPave1 = aPave2;
2015 aPrevVertex = aNextVertex;
2016 p1 = p2;
2017 pit++;
2018 }
2019
2020 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
2021 aFirstV = aPrevVertex;
2022 aLastV = aNextVertex;
2023 Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
2024 p2 = aC3->Value(aPave2.Parameter());
2025
2026 Standard_Boolean bisinside = Standard_False;
2027 Standard_Integer apbindex = 0;
2028 Standard_Integer apbcounter = 1;
2029 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2030 BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
2031 TColStd_ListIteratorOfListOfInteger aFlagIt;
2032
2033 for(aPIt1.Initialize(aFirstPaves), aPIt2.Initialize(aLastPaves), aFlagIt.Initialize(aListOfFlags);
2034 aPIt1.More() && aPIt2.More() && aFlagIt.More();
2035 aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++) {
2036
2037 Standard_Boolean bfin = Standard_False;
2038 Standard_Boolean blin = Standard_False;
2039
2040 if(aPave1.IsEqual(aPIt1.Value())) {
2041 bfin = Standard_True;
2042 }
2043 else {
2044 bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
2045 }
2046
2047 if(aFlagIt.Value()) {
2048 if(aPave2.IsEqual(aPIt2.Value())) {
2049 blin = Standard_True;
2050 }
2051 else {
2052 blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
2053 }
2054 }
2055 else {
2056 blin = Standard_True;
2057 }
2058
2059 if(bfin && blin) {
2060 apbindex = apbcounter;
2061 bisinside = Standard_True;
2062 break;
2063 }
2064 }
2065
2066 if(!bisinside) {
2067
2068 TopTools_ListOfShape aOrderedList;
2069
2070 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
2071 TopoDS_Compound aComp;
2072 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
2073 aCompOfSecEdges = aComp;
2074 aListOfWireEdges.Append(aOrderedList);
2075
2076 bSecFound = Standard_True;
2077 }
2078 else {
2079 //add split
2080 TopoDS_Edge aESplit;
2081 // get split
2082 if(!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
2083 return Standard_False;
2084 //
2085 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
2086 for(; aPBIt.More(); aPBIt.Next()) {
2087 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
2088 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
2089 aPB1->Pave1().IsEqual(aPave1) &&
2090 aPB1->Pave2().IsEqual(aPave2) ) {
2091 if(aPB1->Edge() > 0) {
2092 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
2093 break;
2094 }
2095 }
2096 }
2097
2098 if(!aESplit.IsNull()) {
2099 aListOfWireEdges.Append(aESplit);
2100 }
2101 }
2102 }
2103 else {
2104 if(apbindex > 0) {
2105 TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
2106 aListOfWireEdges.Append(aListOfSec);
2107 }
2108 }
2109 }
2110 else {
2111 //add split
2112 TopoDS_Edge aESplit;
2113 // get split
2114 if(!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
2115 return Standard_False;
2116
2117 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2118 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
2119 for(; aPBIt.More(); aPBIt.Next()) {
2120 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
2121 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
2122 aPB1->Pave1().IsEqual(aPave1) &&
2123 aPB1->Pave2().IsEqual(aPave2) ) {
2124 if(aPB1->Edge() > 0) {
2125 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
2126 break;
2127 }
2128 }
2129 }
2130
2131 if(!aESplit.IsNull()) {
2132 aListOfWireEdges.Append(aESplit);
2133 }
2134 }
2135
2136 // by pairs continuously. end
2137 theListOfWireEdges = aListOfWireEdges;
2138 isSectionFound = bSecFound;
2139 return Standard_True;
2140 }
2141
2142 // ----------------------------------------------------------------------------------------------------
2143 // static function: RemoveEdges
2144 // purpose:
2145 // ----------------------------------------------------------------------------------------------------
RemoveEdges(const TopoDS_Compound & theSourceComp,const TopTools_ListOfShape & theListToRemove,TopoDS_Compound & theResultComp)2146 void RemoveEdges(const TopoDS_Compound& theSourceComp,
2147 const TopTools_ListOfShape& theListToRemove,
2148 TopoDS_Compound& theResultComp) {
2149 BRep_Builder aBB;
2150 TopoDS_Compound aComp;
2151 aBB.MakeCompound(aComp);
2152 TopExp_Explorer anExp(theSourceComp, TopAbs_EDGE);
2153
2154 for(; anExp.More(); anExp.Next()) {
2155 Standard_Boolean bfound = Standard_False;
2156 TopTools_ListIteratorOfListOfShape anIt(theListToRemove);
2157
2158 for(; !bfound && anIt.More(); anIt.Next()) {
2159 bfound = anExp.Current().IsSame(anIt.Value());
2160 }
2161
2162 if(!bfound) {
2163 aBB.Add(aComp, anExp.Current());
2164 }
2165 }
2166 theResultComp = aComp;
2167 }
2168
2169 // ----------------------------------------------------------------------------------------------------
2170 // static function: FilterSectionEdges
2171 // purpose:
2172 // ----------------------------------------------------------------------------------------------------
FilterSectionEdges(const BOPDS_VectorOfCurve & theBCurves,const TopoDS_Face & theSecPlane,const BOPDS_PDS & theDS,TopoDS_Compound & theResult)2173 Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve& theBCurves,
2174 const TopoDS_Face& theSecPlane,
2175 const BOPDS_PDS& theDS,
2176 TopoDS_Compound& theResult) {
2177
2178 theResult.Nullify();
2179
2180 BRep_Builder aBB;
2181 aBB.MakeCompound(theResult);
2182 Standard_Integer aNbCurves = theBCurves.Length();
2183 Standard_Integer cit = 0;
2184 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2185
2186 for(cit = 0; cit < aNbCurves; ++cit) {
2187 const BOPDS_Curve& aBCurve = theBCurves(cit);
2188 const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
2189
2190 aPBIt.Initialize(aSectEdges);
2191 for (; aPBIt.More(); aPBIt.Next()) {
2192 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
2193 Standard_Integer nSect = aPB->Edge();
2194 const TopoDS_Shape& aS = theDS->Shape(nSect);
2195 TopoDS_Edge anEdge = TopoDS::Edge(aS);
2196 Standard_Boolean bAddEdge = Standard_True;
2197
2198 if(!theSecPlane.IsNull()) {
2199 IntTools_BeanFaceIntersector anIntersector(anEdge, theSecPlane);
2200 Standard_Real f = 0., l = 0.;
2201 BRep_Tool::Range(anEdge, f, l);
2202 anIntersector.SetBeanParameters(f, l);
2203 //
2204 Handle(IntTools_Context) aContext = new IntTools_Context;
2205 anIntersector.SetContext(aContext);
2206 //
2207 anIntersector.Perform();
2208
2209 if(anIntersector.IsDone()) {
2210 bAddEdge = Standard_False;
2211 Standard_Integer r = 0;
2212
2213 for(r = 1; r <= anIntersector.Result().Length(); r++) {
2214 const IntTools_Range& aRange = anIntersector.Result().Value(r);
2215
2216 if(((aRange.First() - f) < Precision::PConfusion()) &&
2217 ((l - aRange.Last()) < Precision::PConfusion())) {
2218 bAddEdge = Standard_True;
2219 break;
2220 }//if(((aRange.First() - f) < Precision::PConfusion()) &&
2221 }//for(r = 1; r <= anIntersector.Result().Length(); r++) {
2222 }//if(anIntersector.IsDone()) {
2223 }//if(!theSecPlane.IsNull()) {
2224
2225 if(bAddEdge) {
2226 aBB.Add(theResult, aS);
2227 }
2228 }//for (; aPBIt.More(); aPBIt.Next()) {
2229 }//for(cit = 0; cit < aNbCurves; ++cit) {
2230
2231 return Standard_True;
2232 }
2233
2234
2235 //=======================================================================
2236 //function : ComputeAveragePlaneAndMaxDeviation
2237 //purpose :
2238 //=======================================================================
ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape & aWire,gp_Pln & thePlane,Standard_Boolean & IsSingular)2239 static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
2240 gp_Pln& thePlane,
2241 Standard_Boolean& IsSingular)
2242 {
2243 Standard_Integer N = 40;
2244 Standard_Integer nedges = aWire.NbChildren();
2245
2246 TColgp_Array1OfPnt Pnts( 1, nedges*N );
2247 Standard_Integer ind = 1, i;
2248 for (TopoDS_Iterator iter (aWire); iter.More(); iter.Next())
2249 {
2250 const TopoDS_Edge& anEdge = TopoDS::Edge( iter.Value() );
2251 BRepAdaptor_Curve aCurve(anEdge);
2252 GCPnts_UniformAbscissa Distribution( aCurve, N+1 );
2253 for (i = 1; i <= N; i++)
2254 {
2255 Standard_Real par = Distribution.Parameter(i);
2256 Pnts( ind++ ) = aCurve.Value(par);
2257 }
2258 }
2259
2260 gp_Ax2 Axe;
2261 GeomLib::AxeOfInertia( Pnts, Axe, IsSingular );
2262 if (IsSingular)
2263 return -1;
2264
2265 thePlane = gp_Pln( Axe );
2266 Standard_Real MaxDeviation = 0;
2267 for (i = 1; i <= Pnts.Length(); i++)
2268 {
2269 Standard_Real dist = thePlane.Distance( Pnts(i) );
2270 if (dist > MaxDeviation)
2271 MaxDeviation = dist;
2272 }
2273 return MaxDeviation;
2274 }
2275
2276
UpdateSectionEdge(TopoDS_Edge & theEdge,const TopoDS_Vertex & theConstVertex,TopoDS_Vertex & theVertex,const Standard_Real theParam)2277 static void UpdateSectionEdge(TopoDS_Edge& theEdge,
2278 const TopoDS_Vertex& theConstVertex,
2279 TopoDS_Vertex& theVertex,
2280 const Standard_Real theParam)
2281 {
2282 TopoDS_Edge F_Edge = theEdge;
2283 F_Edge.Orientation(TopAbs_FORWARD);
2284
2285 TopAbs_Orientation OrOfVertex;
2286 TopoDS_Vertex V1, V2, AnotherVertex;
2287 TopExp::Vertices(F_Edge, V1, V2);
2288 if (theConstVertex.IsSame(V1))
2289 {
2290 //OrOfConst = TopAbs_FORWARD;
2291 OrOfVertex = TopAbs_REVERSED;
2292 AnotherVertex = V2;
2293 }
2294 else
2295 {
2296 //OrOfConst = TopAbs_REVERSED;
2297 OrOfVertex = TopAbs_FORWARD;
2298 AnotherVertex = V1;
2299 }
2300
2301 BRep_Builder BB;
2302 Standard_Real fpar, lpar;
2303 BRep_Tool::Range(F_Edge, fpar, lpar);
2304 if (OrOfVertex == TopAbs_FORWARD)
2305 fpar = theParam;
2306 else
2307 lpar = theParam;
2308 BB.Range(F_Edge, fpar, lpar);
2309
2310 F_Edge.Free(Standard_True);
2311 BB.Remove(F_Edge, AnotherVertex);
2312 theVertex.Orientation(OrOfVertex);
2313 BB.Add(F_Edge, theVertex);
2314 }
2315
2316 //Finds the edge connected to <theVertex> in the compound <theComp>
2317 //that is closest to bisector plane angularly.
2318 //Removes found edge from <theComp>
2319 //<theAxis> is the axis of bisector plane
FindEdgeCloseToBisectorPlane(const TopoDS_Vertex & theVertex,TopoDS_Compound & theComp,const gp_Ax1 & theAxis)2320 static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
2321 TopoDS_Compound& theComp,
2322 const gp_Ax1& theAxis)
2323 {
2324 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
2325 TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
2326
2327 TopoDS_Edge MinEdge;
2328 if (!VEmap.Contains(theVertex))
2329 return MinEdge;
2330
2331 BRep_Builder BB;
2332
2333 const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex);
2334 if (Edges.Extent() == 1)
2335 MinEdge = TopoDS::Edge(Edges.First());
2336 else
2337 {
2338 TopTools_ListIteratorOfListOfShape itl(Edges);
2339 Standard_Real MinAngle = RealLast();
2340 for (; itl.More(); itl.Next())
2341 {
2342 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2343 TopoDS_Wire aWire;
2344 BB.MakeWire(aWire);
2345 BB.Add(aWire, anEdge);
2346 gp_Pln aPln;
2347 Standard_Boolean issing;
2348 ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
2349 Standard_Real anAngle;
2350 if (issing) //edge is a segment of line
2351 {
2352 //<anAngle> is angle between <anEdge> and its projection on bisector plane
2353 BRepAdaptor_Curve BAcurve(anEdge);
2354 gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
2355 gp_Pnt LastPnt = BAcurve.Value(BAcurve.LastParameter());
2356 gp_Vec EdgeVec(FirstPnt, LastPnt);
2357 gp_Ax1 EdgeAxis(FirstPnt, EdgeVec);
2358 anAngle = EdgeAxis.Direction().Angle(theAxis.Direction());
2359 if (anAngle > M_PI/2)
2360 anAngle = M_PI - anAngle;
2361 anAngle = M_PI/2 - anAngle;
2362 }
2363 else
2364 {
2365 anAngle = aPln.Axis().Angle( theAxis );
2366 if (anAngle > M_PI/2)
2367 anAngle = M_PI - anAngle;
2368 }
2369
2370 if (anAngle < MinAngle)
2371 {
2372 MinAngle = anAngle;
2373 MinEdge = anEdge;
2374 }
2375 }
2376 } //else (more than one edge)
2377
2378 BB.Remove(theComp, MinEdge);
2379 return MinEdge;
2380 }
2381
FindMiddleEdges(const TopoDS_Vertex & theVertex1,const TopoDS_Vertex & theVertex2,const gp_Ax1 & theAxis,TopoDS_Compound & theComp,TopTools_ListOfShape & theElist)2382 static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1,
2383 const TopoDS_Vertex& theVertex2,
2384 const gp_Ax1& theAxis,
2385 TopoDS_Compound& theComp,
2386 TopTools_ListOfShape& theElist)
2387 {
2388 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
2389 TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
2390 if (VEmap.IsEmpty())
2391 return Standard_False;
2392
2393 if (!VEmap.Contains(theVertex1) ||
2394 !VEmap.Contains(theVertex2))
2395 return Standard_False;
2396
2397 TopoDS_Vertex CurVertex = theVertex1;
2398 for (;;)
2399 {
2400 TopoDS_Edge CurEdge;
2401
2402 CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis);
2403 if (CurEdge.IsNull())
2404 return Standard_False;
2405
2406 TopoDS_Vertex V1, V2;
2407 TopExp::Vertices(CurEdge, V1, V2);
2408 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2409
2410 theElist.Append(CurEdge);
2411 if (CurVertex.IsSame(theVertex2))
2412 return Standard_True;
2413 }
2414 }
2415
FindCommonVertex(const TopoDS_Edge & theFirstEdge,const TopoDS_Edge & theLastEdge,const TopoDS_Vertex & theFirstVertex,const TopoDS_Vertex & theLastVertex,TopoDS_Vertex & theCommonVertex)2416 static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge,
2417 const TopoDS_Edge& theLastEdge,
2418 const TopoDS_Vertex& theFirstVertex,
2419 const TopoDS_Vertex& theLastVertex,
2420 TopoDS_Vertex& theCommonVertex)
2421 {
2422 if (!theFirstVertex.IsSame(theLastVertex))
2423 {
2424 Standard_Boolean CommonVertexExists = TopExp::CommonVertex(theFirstEdge,
2425 theLastEdge,
2426 theCommonVertex);
2427 return CommonVertexExists;
2428 }
2429
2430 TopoDS_Vertex V1, V2, V3, V4;
2431 TopExp::Vertices(theFirstEdge, V1, V2);
2432 TopExp::Vertices(theLastEdge, V3, V4);
2433
2434 if (V1.IsSame(theFirstVertex))
2435 {
2436 if (V2.IsSame(V3) ||
2437 V2.IsSame(V4))
2438 {
2439 theCommonVertex = V2;
2440 return Standard_True;
2441 }
2442 }
2443 else
2444 {
2445 if (V1.IsSame(V3) ||
2446 V1.IsSame(V4))
2447 {
2448 theCommonVertex = V1;
2449 return Standard_True;
2450 }
2451 }
2452
2453 return Standard_False;
2454 }
2455