1 // Created on: 2003-10-21
2 // Created by: Mikhail KLOKOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
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 <GCPnts_UniformAbscissa.hxx>
29 #include <Geom2d_Curve.hxx>
30 #include <GeomLib.hxx>
33 #include <gp_Pnt2d.hxx>
34 #include <IntTools_BeanFaceIntersector.hxx>
35 #include <IntTools_Context.hxx>
36 #include <IntTools_Range.hxx>
37 #include <IntTools_Tools.hxx>
38 #include <TColgp_Array1OfDir.hxx>
39 #include <TColgp_Array1OfPnt.hxx>
40 #include <TColgp_SequenceOfPnt.hxx>
41 #include <TColStd_ListOfInteger.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopLoc_Location.hxx>
46 #include <TopoDS_Compound.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Iterator.hxx>
49 #include <TopoDS_Shape.hxx>
50 #include <TopoDS_Shell.hxx>
51 #include <TopoDS_Wire.hxx>
52 #include <TopTools_Array1OfListOfShape.hxx>
53 #include <TopTools_DataMapOfShapeListOfShape.hxx>
54 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
55 #include <TopTools_ListOfShape.hxx>
56 #include <TopTools_MapOfShape.hxx>
57 #include <TopTools_SequenceOfShape.hxx>
58 #include <BRepExtrema_ExtCC.hxx>
60 static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
61 TopoDS_Compound& theComp,
62 const gp_Ax1& theAxis);
64 static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1,
65 const TopoDS_Vertex& theVertex2,
66 const gp_Ax1& theAxis,
67 TopoDS_Compound& theComp,
68 TopTools_ListOfShape& theElist);
70 static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge,
71 const TopoDS_Edge& theLastEdge,
72 const TopoDS_Vertex& theFirstVertex,
73 const TopoDS_Vertex& theLastVertex,
74 TopoDS_Vertex& theCommonVertex);
76 static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
77 const Standard_Integer theEIndex1,
78 const Standard_Integer theEIndex2,
79 TopoDS_Vertex& theCommonVertex,
80 Standard_Real& theParamOnE1,
81 Standard_Real& theParamOnE2);
83 static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
84 const BOPDS_PDS& theDS,
85 TopTools_DataMapOfShapeListOfShape& theHistMap);
87 static void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)& theVEdges,
88 const Standard_Integer theIndex,
89 const TopoDS_Shape& theNewVedge,
90 TopTools_DataMapOfShapeListOfShape& theHistMap);
92 static void FindFreeVertices(const TopoDS_Shape& theShape,
93 const TopTools_MapOfShape& theVerticesToAvoid,
94 TopTools_ListOfShape& theListOfVertex);
96 static Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList,
97 const gp_Pnt2d& theFirstPoint,
98 const gp_Pnt2d& theLastPoint,
99 const TopoDS_Face& theFace,
100 TopTools_ListOfShape& theOrientedList);
102 static Standard_Boolean FillGap(const TopoDS_Vertex& theFirstVertex,
103 const TopoDS_Vertex& theLastVertex,
104 const gp_Pnt2d& theFirstPoint,
105 const gp_Pnt2d& theLastPoint,
106 const TopoDS_Face& theFace,
107 const TopoDS_Compound& theSectionEdges,
108 TopTools_ListOfShape& theOrderedList);
110 static Standard_Boolean FindNextEdge(const TopoDS_Vertex& theFirstVertex,
111 const TopoDS_Vertex& theLastVertex,
112 const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
113 const TopTools_MapOfShape& theMapToAvoid,
114 TopTools_ListOfShape& theOrderedList);
116 static Standard_Boolean FindVertex(const TopoDS_Edge& theEdge,
117 const Standard_Integer theRank,
118 const BOPDS_PDS& theDS,
119 const TopTools_DataMapOfShapeListOfShape& theHistMap,
120 TopoDS_Vertex& theVertex,
121 BOPDS_Pave& thePave);
123 static Standard_Boolean FindNextVertex(const Standard_Integer theEdgeIndex,
124 const BOPDS_Pave& thePrevPave,
125 const BOPDS_PDS& theDS,
126 TopoDS_Vertex& theNextVertex,
127 BOPDS_Pave& thePave);
129 static Standard_Boolean GetPave(const Standard_Integer theEdgeIndex,
130 const Standard_Boolean isFirst,
131 const BOPDS_PDS& theDS,
132 BOPDS_Pave& thePave);
134 static Standard_Boolean FindFromUEdge(const TopoDS_Edge& theUE1Old,
135 const TopoDS_Edge& theUE2Old,
136 const TopoDS_Edge& theUE1New,
137 const TopoDS_Edge& theUE2New,
138 const TopoDS_Face& theFace,
139 const TopoDS_Compound& theSecEdges,
140 const Standard_Integer theRank,
141 const TopoDS_Edge& theBoundEdge,
142 const Standard_Integer theBoundEdgeIndex,
143 const BOPDS_PDS& theDS,
144 const TopTools_DataMapOfShapeListOfShape& theHistMap,
145 TopoDS_Compound& theSecEdgesNew,
146 TopTools_ListOfShape& theListOfWireEdges,
147 BOPDS_Pave& theFoundPave,
148 Standard_Boolean& isOnUEdge);
150 static Standard_Boolean FindFromVEdge(const BOPDS_Pave& thePrevPave,
151 const Standard_Boolean& isOnUEdge,
152 const TopoDS_Edge& theUE1Old,
153 const TopoDS_Edge& theUE2Old,
154 const TopoDS_Face& theFace,
155 const TopoDS_Compound& theSecEdges,
156 const Standard_Integer theRank,
157 const TopoDS_Edge& theBoundEdge,
158 const Standard_Integer theBoundEdgeIndex,
159 const BOPDS_PDS& theDS,
160 const TopTools_DataMapOfShapeListOfShape& theHistMap,
161 TopTools_ListOfShape& theListOfWireEdges,
162 Standard_Boolean& isSectionFound);
164 static void RemoveEdges(const TopoDS_Compound& theSourceComp,
165 const TopTools_ListOfShape& theListToRemove,
166 TopoDS_Compound& theResultComp);
168 static Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve& theBCurves,
169 const TopoDS_Face& theSecPlane,
170 const BOPDS_PDS& theDS,
171 TopoDS_Compound& theResult);
173 static Standard_Boolean GetUEdges(const Standard_Integer theIndex,
174 const Standard_Integer theRank,
175 const Handle(TopTools_HArray2OfShape)& theUEdges,
176 const TopoDS_Edge& theBoundEdge,
177 const TopoDS_Face& theFace,
178 TopoDS_Edge& theFirstUEdge,
179 TopoDS_Edge& theSecondUEdge);
181 static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
183 Standard_Boolean& IsSingular);
185 static void UpdateSectionEdge(TopoDS_Edge& theEdge,
186 const TopoDS_Vertex& theConstVertex,
187 TopoDS_Vertex& theVertex,
188 const Standard_Real theParam);
191 // ===========================================================================================
192 // function: Constructor
194 // ===========================================================================================
195 BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
196 const BRepFill_TransitionStyle theTransition,
197 const gp_Ax2& theAxeOfBisPlane) :
198 myTransition(theTransition),
199 myAxeOfBisPlane(theAxeOfBisPlane),
200 myDone(Standard_False),
201 myHasSection(Standard_False)
203 myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(),
204 theFaces->LowerCol(), theFaces->UpperCol());
205 myFaces->ChangeArray2() = theFaces->Array2();
208 // ===========================================================================================
209 // function: AddBounds
211 // ===========================================================================================
212 void BRepFill_TrimShellCorner::AddBounds(const Handle(TopTools_HArray2OfShape)& theBounds)
214 myBounds = new TopTools_HArray2OfShape(theBounds->LowerRow(), theBounds->UpperRow(),
215 theBounds->LowerCol(), theBounds->UpperCol());
216 myBounds->ChangeArray2() = theBounds->Array2();
219 // ===========================================================================================
220 // function: AddUEdges
222 // ===========================================================================================
223 void BRepFill_TrimShellCorner::AddUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges)
225 myUEdges = new TopTools_HArray2OfShape(theUEdges->LowerRow(), theUEdges->UpperRow(),
226 theUEdges->LowerCol(), theUEdges->UpperCol());
227 myUEdges->ChangeArray2() = theUEdges->Array2();
230 // ===========================================================================================
231 // function: AddVEdges
233 // ===========================================================================================
234 void BRepFill_TrimShellCorner::AddVEdges(const Handle(TopTools_HArray2OfShape)& theVEdges,
235 const Standard_Integer theIndex)
237 myVEdges = new TopTools_HArray1OfShape(theVEdges->LowerRow(), theVEdges->UpperRow());
239 for (Standard_Integer i = theVEdges->LowerRow(); i <= theVEdges->UpperRow(); i++)
240 myVEdges->SetValue(i, theVEdges->Value(i, theIndex));
243 // ===========================================================================================
246 // ===========================================================================================
247 void BRepFill_TrimShellCorner::Perform()
249 Standard_Integer anIndex1, anIndex2, nF1, nF2, i, j, aNbP, aNbC;
250 Standard_Boolean bhassec;
252 myDone = Standard_False;
255 if(myFaces->RowLength() != 2)
257 Standard_Integer ii = 0, jj = 0;
260 for(jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++) {
262 aBB.MakeShell(aShell);
264 for(ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
265 aBB.Add(aShell, myFaces->Value(ii, jj));
267 aShell.Closed (BRep_Tool::IsClosed (aShell));
269 if(jj == myFaces->LowerCol()) {
277 Standard_Real aMaxTol = 0.;
278 TopExp_Explorer anExp(myShape1, TopAbs_VERTEX);
279 for (; anExp.More(); anExp.Next())
281 aMaxTol = Max(aMaxTol, BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Current())));
284 anExp.Init(myShape2, TopAbs_VERTEX);
285 for (; anExp.More(); anExp.Next())
287 aMaxTol = Max(aMaxTol, BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Current())));
290 Standard_Real aFuzzy = 4.*Precision::Confusion();
291 BOPAlgo_PaveFiller aPF;
292 TopTools_ListOfShape aLS;
293 aLS.Append(myShape1);
294 aLS.Append(myShape2);
295 aPF.SetArguments(aLS);
296 if (aMaxTol < 1.005 * Precision::Confusion())
298 aFuzzy = Max(aPF.FuzzyValue(), aFuzzy);
299 aPF.SetFuzzyValue(aFuzzy);
303 if (aPF.HasErrors()) {
307 const BOPDS_PDS& theDS = aPF.PDS();
309 BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
310 Standard_Integer aNbFFs = aFFs.Length();
312 if(!SplitUEdges(myUEdges, theDS, myHistMap)) {
316 for(ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
317 TopoDS_Shape aF1 = myFaces->Value(ii, myFaces->LowerCol());
318 TopoDS_Shape aF2 = myFaces->Value(ii, myFaces->UpperCol());
320 anIndex1 = theDS->Index(aF1);
321 anIndex2 = theDS->Index(aF2);
323 if((anIndex1 == -1) || (anIndex2 == -1))
326 for (i=0; i < aNbFFs; ++i) {
327 BOPDS_InterfFF& aFFi = aFFs(i);
328 aFFi.Indices(nF1, nF2);
330 BOPDS_VectorOfPoint& aVP=aFFi.ChangePoints();
332 const BOPDS_VectorOfCurve& aVC=aFFi.Curves();
334 if (!aNbP && !aNbC) {
335 if (!theDS->HasInterfSubShapes(nF1, nF2)) {
340 if((nF1 == anIndex1) && (nF2 == anIndex2)) {
341 bhassec = Standard_False;
343 for (j = 0; j < aNbC; ++j) {
344 const BOPDS_Curve& aBCurve = aVC(j);
345 const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
347 if (aSectEdges.Extent()) {
348 bhassec = Standard_True;
354 if(!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2)) {
360 if(!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i)) {
369 myDone = Standard_True;
372 // ===========================================================================================
375 // ===========================================================================================
376 Standard_Boolean BRepFill_TrimShellCorner::IsDone() const
381 // ===========================================================================================
382 // function: HasSection
384 // ===========================================================================================
385 Standard_Boolean BRepFill_TrimShellCorner::HasSection() const
390 // ===========================================================================================
391 // function: Modified
393 // ===========================================================================================
394 void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape& theShape,
395 TopTools_ListOfShape& theModified)
399 if(myHistMap.IsBound(theShape)) {
400 theModified = myHistMap.Find(theShape);
404 // ----------------------------------------------------------------------------------------------------
405 // function: MakeFacesNonSec
406 // purpose: Updates <myHistMap> by new faces in the case when old faces do not intersect
407 // ----------------------------------------------------------------------------------------------------
409 BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer theIndex,
410 const BOPDS_PDS& theDS,
411 const Standard_Integer theFaceIndex1,
412 const Standard_Integer theFaceIndex2)
414 Standard_Boolean bHasNewEdge = Standard_False;
415 TopoDS_Edge aNewEdge;
418 const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1);
419 const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2);
421 // search common vertex between bounds. begin
422 TopoDS_Vertex aCommonVertex;
423 Standard_Integer anIndex1 = theDS->Index(aE1);
424 Standard_Integer anIndex2 = theDS->Index(aE2);
425 Standard_Real apar1 = 0., apar2 = 0.;
427 Standard_Boolean bvertexfound =
428 FindCommonVertex(theDS, anIndex1, anIndex2, aCommonVertex, apar1, apar2);
429 // search common vertex between bounds. end
431 Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
433 // search common vertices between uedges. begin
434 TopTools_ListOfShape aCommonVertices;
435 Standard_Integer acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
436 Standard_Integer ueit = 0, eindex = 0;
438 for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
439 const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol());
440 const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol());
441 TopoDS_Edge aUE1 = TopoDS::Edge(aShape1);
442 TopoDS_Edge aUE2 = TopoDS::Edge(aShape2);
444 if (myHistMap.IsBound(aShape1)) {
445 const TopTools_ListOfShape& lst = myHistMap.Find(aShape1);
448 aUE1 = TopoDS::Edge(lst.First());
451 if (myHistMap.IsBound(aShape2)) {
452 const TopTools_ListOfShape& lst = myHistMap.Find(aShape2);
455 aUE2 = TopoDS::Edge(lst.First());
458 if(!aShape1.IsSame(aUE1))
459 aSubstitutor->Replace(aShape1.Oriented(TopAbs_FORWARD), aUE1.Oriented(TopAbs_FORWARD));
461 if(!aShape2.IsSame(aUE2))
462 aSubstitutor->Replace(aShape2.Oriented(TopAbs_FORWARD), aUE2.Oriented(TopAbs_FORWARD));
464 TopoDS_Vertex V1 = TopExp::LastVertex(aUE1);
465 TopoDS_Vertex V2 = TopExp::FirstVertex(aUE2);
468 acommonflag = (acommonflag == 0) ? ueit : 3;
469 aCommonVertices.Append(V1);
472 // search common vertices between uedges. end
475 if(aCommonVertices.Extent() != 1)
476 return Standard_False;
479 aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()), aCommonVertex);
481 aNewEdge = BRepLib_MakeEdge(aCommonVertex, TopoDS::Vertex(aCommonVertices.First()));
483 bHasNewEdge = Standard_True;
486 if(aCommonVertices.Extent() == 2) {
487 aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()),
488 TopoDS::Vertex(aCommonVertices.Last()));
489 bHasNewEdge = Standard_True;
491 Standard_Integer fit = 0;
493 for(fit = 1; fit <= 2; fit++) {
494 TopoDS_Compound aComp;
495 TopTools_MapOfShape aMapV;
496 aBB.MakeCompound(aComp);
498 for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
499 const TopoDS_Shape& aShape = myUEdges->Value(eindex, myUEdges->LowerCol() + fit - 1);
500 TopoDS_Shape aUE = aShape;
502 if(myHistMap.IsBound(aShape)) {
503 const TopTools_ListOfShape& lst = myHistMap.Find(aShape);
506 aUE = TopoDS::Edge(lst.First());
508 const TopoDS_Shape& aV = (fit == 1) ? TopExp::FirstVertex(TopoDS::Edge(aUE)) : TopExp::LastVertex(TopoDS::Edge(aUE));
514 aBB.Add(aComp, aNewEdge);
515 StoreVedgeInHistMap(myVEdges, theIndex, aNewEdge, myHistMap);
518 TopTools_ListOfShape alonevertices;
519 FindFreeVertices(aComp, aMapV, alonevertices);
521 if(!alonevertices.IsEmpty() && (alonevertices.Extent() != 2))
522 return Standard_False;
524 Standard_Integer aFaceIndex = (fit == 1) ? theFaceIndex1 : theFaceIndex2;
525 TopoDS_Shape aFace = theDS->Shape(aFaceIndex);
526 TopAbs_Orientation aFaceOri = aFace.Orientation();
527 aFace.Orientation(TopAbs_FORWARD);
529 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
532 aNewEdge.Orientation(TopAbs_FORWARD);
535 TopTools_ListOfShape aOrderedList;
537 if(!alonevertices.IsEmpty()) {
538 Standard_Integer anEIndex = (fit == 1) ? anIndex1 : anIndex2;
539 Standard_Boolean bfound1 = Standard_False;
540 Standard_Boolean bfound2 = Standard_False;
541 Standard_Real aparam1 = 0., aparam2 = 0.;
543 BOPDS_ListOfPave aLP;
544 theDS->Paves(anEIndex, aLP);
545 BOPDS_ListIteratorOfListOfPave aIt;
547 for ( ; aIt.More(); aIt.Next()) {
548 const BOPDS_Pave& aPave = aIt.Value();
549 TopoDS_Shape aV = theDS->Shape(aPave.Index());
551 if(aV.IsSame(alonevertices.First())) {
553 aparam1 = aPave.Parameter();
554 bfound1 = Standard_True;
558 if(aV.IsSame(alonevertices.Last())) {
560 aparam2 = aPave.Parameter();
561 bfound2 = Standard_True;
566 if(bfound1 && bfound2) {
567 TopoDS_Edge aNewBoundE;
570 aNewBoundE = TopoDS::Edge(aE1.EmptyCopied());
573 aNewBoundE = TopoDS::Edge(aE2.EmptyCopied());
575 TopoDS_Vertex aV1, aV2;
577 if(aparam1 < aparam2) {
578 aV1 = TopoDS::Vertex(alonevertices.First());
579 aV2 = TopoDS::Vertex(alonevertices.Last());
582 aV1 = TopoDS::Vertex(alonevertices.Last());
583 aV2 = TopoDS::Vertex(alonevertices.First());
584 Standard_Real tmp = aparam1;
588 aV1.Orientation(TopAbs_FORWARD);
589 aV2.Orientation(TopAbs_REVERSED);
590 aBB.Add(aNewBoundE, aV1);
591 aBB.Add(aNewBoundE, aV2);
592 aBB.Range(aNewBoundE, aparam1, aparam2);
593 aNewBoundE.Orientation(TopAbs_FORWARD);
595 aOrderedList.Append(aNewBoundE);
598 TopExp_Explorer anExpV(aNewEdge, TopAbs_VERTEX);
599 Standard_Boolean bfoundv = Standard_False;
601 for(; !bfoundv && anExpV.More(); anExpV.Next()) {
602 if(aV2.IsSame(anExpV.Current()))
603 bfoundv = Standard_True;
607 aOrderedList.Append(aNewEdge);
609 aOrderedList.Prepend(aNewEdge);
613 return Standard_False;
618 aOrderedList.Append(aNewEdge);
622 if(!aOrderedList.IsEmpty()) {
625 TopTools_ListIteratorOfListOfShape anItE(aOrderedList);
627 for(; anItE.More(); anItE.Next()) {
628 aBB.Add(aW, anItE.Value());
631 aSubstitutor->Replace(aE1.Oriented(TopAbs_FORWARD), aW);
633 aSubstitutor->Replace(aE2.Oriented(TopAbs_FORWARD), aW);
636 aSubstitutor->Apply(aFace);
637 TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
638 aNewFace.Orientation(aFaceOri);
639 TopTools_ListOfShape atmpList;
640 atmpList.Append(aNewFace);
641 myHistMap.Bind(aFace, atmpList);
643 anExpE.Init(aFace, TopAbs_EDGE);
645 for(; anExpE.More(); anExpE.Next()) {
646 TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
648 if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
651 if (myHistMap.IsBound(anExpE.Current()))
653 TopTools_ListOfShape aListOfNewEdge;
654 TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
656 for(; anExpE2.More(); anExpE2.Next()) {
657 aListOfNewEdge.Append(anExpE2.Current());
659 myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
663 return Standard_True;
666 // ----------------------------------------------------------------------------------------------------
667 // function: MakeFacesSec
668 // purpose: Updates <myHistMap> by new faces in the case when old faces intersect each other
669 // ----------------------------------------------------------------------------------------------------
671 BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer theIndex,
672 const BOPDS_PDS& theDS,
673 const Standard_Integer theFaceIndex1,
674 const Standard_Integer theFaceIndex2,
675 const Standard_Integer theSSInterfIndex)
677 const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
678 const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex);
679 const BOPDS_VectorOfCurve& aBCurves = aFFi.Curves();
681 TopoDS_Compound aSecEdges;
682 TopoDS_Face aSecPlane;
684 if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges))
685 return Standard_False;
687 //Extract vertices on the intersection of correspondent U-edges
688 const TopoDS_Shape& LeftE1 = myUEdges->Value(theIndex, 1);
689 const TopoDS_Shape& LeftE2 = myUEdges->Value(theIndex, 2);
690 const TopoDS_Shape& RightE1 = myUEdges->Value(theIndex+1, 1);
691 const TopoDS_Shape& RightE2 = myUEdges->Value(theIndex+1, 2);
693 Standard_Integer IndexOfLeftE1 = theDS->Index(LeftE1);
694 Standard_Integer IndexOfLeftE2 = theDS->Index(LeftE2);
695 Standard_Integer IndexOfRightE1 = theDS->Index(RightE1);
696 Standard_Integer IndexOfRightE2 = theDS->Index(RightE2);
698 TopoDS_Vertex FirstVertex, LastVertex;
699 Standard_Real ParamOnLeftE1, ParamOnLeftE2, ParamOnRightE1, ParamOnRightE2;
700 FindCommonVertex(theDS, IndexOfLeftE1, IndexOfLeftE2,
701 FirstVertex, ParamOnLeftE1, ParamOnLeftE2);
702 FindCommonVertex(theDS, IndexOfRightE1, IndexOfRightE2,
703 LastVertex, ParamOnRightE1, ParamOnRightE2);
705 TopoDS_Shape SecWire;
707 Standard_Boolean IsSingular;
708 Standard_Boolean WireFound = ChooseSection(aSecEdges,
709 FirstVertex, LastVertex,
710 SecWire, SecPlane, IsSingular );
713 //aSecEdges = SecWire;
714 TopoDS_Compound aComp;
716 BB.MakeCompound(aComp);
717 TopExp_Explorer explo( SecWire, TopAbs_EDGE );
719 for (; explo.More(); explo.Next())
720 BB.Add( aComp, explo.Current() );
723 StoreVedgeInHistMap(myVEdges, theIndex, SecWire, myHistMap);
726 TopTools_ListOfShape aCommonVertices;
727 // Standard_Integer acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
728 Standard_Integer fit = 0; //, ueit = 0, eindex = 0, i = 0;
729 Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
731 for(fit = 0; fit < 2; fit++) {
732 Standard_Integer aFaceIndex = (fit == 0) ? theFaceIndex1 : theFaceIndex2;
733 TopoDS_Face aFace = TopoDS::Face(theDS->Shape(aFaceIndex));
734 TopAbs_Orientation aFaceOri = aFace.Orientation();
735 TopoDS_Face aFaceF = aFace;
736 aFaceF.Orientation(TopAbs_FORWARD);
737 TopoDS_Edge aBoundEdge = TopoDS::Edge(myBounds->Value(theIndex, myBounds->LowerCol() +fit));
738 Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge);
742 if(!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
743 return Standard_False;
745 TopoDS_Edge aUE1old = aUE1;
746 TopoDS_Edge aUE2old = aUE2;
748 if (myHistMap.IsBound(aUE1)) {
749 const TopTools_ListOfShape& lst = myHistMap.Find(aUE1);
752 const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation());
754 if(!aUE1.IsSame(anEdge))
755 aSubstitutor->Replace(aUE1.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
756 aUE1 = TopoDS::Edge(anEdge);
760 if (myHistMap.IsBound(aUE2)) {
761 const TopTools_ListOfShape& lst = myHistMap.Find(aUE2);
764 const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation());
766 if(!aUE2.IsSame(anEdge))
767 aSubstitutor->Replace(aUE2.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
768 aUE2 = TopoDS::Edge(anEdge);
771 TopoDS_Vertex aPrevVertex, aNextVertex;
772 TopoDS_Compound aCompOfSecEdges = aSecEdges;
773 TopTools_ListOfShape aListOfWireEdges;
776 Standard_Boolean isPave1OnUEdge = Standard_True;
778 if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex,
779 theDS, myHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) {
780 TopTools_ListOfShape aSecondListOfEdges;
781 Standard_Boolean bisSectionFound = Standard_False;
783 if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge,
784 aBoundEdgeIndex, theDS, myHistMap, aSecondListOfEdges, bisSectionFound)) {
785 return Standard_False;
788 if(!bisSectionFound && aListOfWireEdges.IsEmpty()) {
789 return Standard_False;
791 aListOfWireEdges.Append(aSecondListOfEdges);
794 return Standard_False;
797 if(!aListOfWireEdges.IsEmpty()) {
800 TopTools_ListIteratorOfListOfShape aEIt(aListOfWireEdges);
802 for(; aEIt.More(); aEIt.Next()) {
803 if(!aBoundEdge.IsSame(aEIt.Value()))
804 aBB.Add(aW, aEIt.Value());
806 aSubstitutor->Replace(aBoundEdge.Oriented(TopAbs_FORWARD), aW);
809 aSubstitutor->Apply(aFace);
810 TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
811 aNewFace.Orientation(aFaceOri);
812 TopTools_ListOfShape atmpList;
813 atmpList.Append(aNewFace);
814 myHistMap.Bind(aFace, atmpList);
816 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
818 for(; anExpE.More(); anExpE.Next()) {
819 TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
821 if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
824 if (myHistMap.IsBound(anExpE.Current()))
826 TopTools_ListOfShape aListOfNewEdge;
827 TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
829 for(; anExpE2.More(); anExpE2.Next()) {
830 aListOfNewEdge.Append(anExpE2.Current());
832 myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
835 return Standard_True;
838 //=======================================================================
839 //function : ChooseSection
841 //=======================================================================
842 Standard_Boolean BRepFill_TrimShellCorner::ChooseSection(const TopoDS_Shape& Comp,
843 const TopoDS_Vertex& theFirstVertex,
844 const TopoDS_Vertex& theLastVertex,
845 TopoDS_Shape& resWire,
847 Standard_Boolean& IsSingular)
849 IsSingular = Standard_False;
851 Standard_Integer ind, i, j;
854 if (myTransition == BRepFill_Right &&
855 !theFirstVertex.IsNull() &&
856 !theLastVertex.IsNull()) //the case where section wire goes from
857 //its known first vertex to its known last vertex
860 BB.MakeWire(NewWire);
862 TopoDS_Compound OldComp;
863 BB.MakeCompound( OldComp );
864 TopoDS_Iterator iter( Comp );
865 for (; iter.More(); iter.Next())
866 BB.Add( OldComp, iter.Value() );
868 TopoDS_Edge FirstEdge = FindEdgeCloseToBisectorPlane(theFirstVertex,
870 myAxeOfBisPlane.Axis());
871 if (FirstEdge.IsNull())
872 return Standard_False;
874 iter.Initialize(OldComp);
877 iter.Initialize(Comp);
878 BB.Add( OldComp, iter.Value() );
880 TopoDS_Edge LastEdge = FindEdgeCloseToBisectorPlane(theLastVertex,
882 myAxeOfBisPlane.Axis());
883 if (LastEdge.IsNull())
884 return Standard_False;
886 if (FirstEdge.IsNull() || LastEdge.IsNull())
888 return Standard_False;
891 BB.Add(NewWire, FirstEdge);
893 if (!FirstEdge.IsSame(LastEdge))
895 TopoDS_Vertex aCommonVertex;
896 Standard_Boolean CommonVertexExists = FindCommonVertex(FirstEdge, LastEdge,
897 theFirstVertex, theLastVertex,
899 if (CommonVertexExists)
900 BB.Add(NewWire, LastEdge);
903 TopoDS_Vertex Vertex1, Vertex2, V1, V2;
904 TopExp::Vertices(FirstEdge, V1, V2);
905 Vertex1 = (theFirstVertex.IsSame(V1))? V2 : V1;
906 TopExp::Vertices(LastEdge, V1, V2);
907 Vertex2 = (theLastVertex.IsSame(V1))? V2 : V1;
909 TopTools_ListOfShape MiddleEdges;
910 if (FindMiddleEdges(Vertex1, Vertex2, myAxeOfBisPlane.Axis(), OldComp, MiddleEdges))
912 TopTools_ListIteratorOfListOfShape itl(MiddleEdges);
913 for (; itl.More(); itl.Next())
914 BB.Add(NewWire, itl.Value());
915 BB.Add(NewWire, LastEdge);
919 //trim <FirstEdge> and <LastEdge> in the points of extrema
920 //these points become new vertex with centre between them
921 BRepExtrema_ExtCC Extrema(FirstEdge, LastEdge);
922 if (Extrema.IsDone() && Extrema.NbExt() > 0)
924 Standard_Integer imin = 1;
925 for (i = 2; i <= Extrema.NbExt(); i++)
926 if (Extrema.SquareDistance(i) < Extrema.SquareDistance(imin))
929 Standard_Real aMinDist = sqrt(Extrema.SquareDistance(imin));
930 Standard_Real ParamOnFirstEdge = Extrema.ParameterOnE1(imin);
931 Standard_Real ParamOnLastEdge = Extrema.ParameterOnE2(imin);
932 gp_Pnt PointOnFirstEdge = Extrema.PointOnE1(imin);
933 gp_Pnt PointOnLastEdge = Extrema.PointOnE2(imin);
934 gp_Pnt MidPnt((PointOnFirstEdge.XYZ() + PointOnLastEdge.XYZ())/2);
935 aCommonVertex = BRepLib_MakeVertex(MidPnt);
936 BB.UpdateVertex(aCommonVertex, 1.001*aMinDist/2);
938 UpdateSectionEdge(FirstEdge, theFirstVertex, aCommonVertex, ParamOnFirstEdge);
939 UpdateSectionEdge(LastEdge, theLastVertex, aCommonVertex, ParamOnLastEdge);
941 BB.Add(NewWire, LastEdge);
948 resPlane = gp_Pln(myAxeOfBisPlane);
949 return Standard_True;
952 //General case: try to find continuous section closest to bisector plane
953 TopoDS_Compound OldComp;
955 B.MakeCompound( OldComp );
956 TopoDS_Iterator iter( Comp );
957 for (; iter.More(); iter.Next())
958 B.Add( OldComp, iter.Value() );
960 Standard_Boolean anError = Standard_False;
961 //TopoDS_Wire NewWire [2];
962 TopTools_SequenceOfShape Wseq;
965 TopExp_Explorer explo( OldComp, TopAbs_EDGE );
968 TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
969 TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge );
970 B.Remove( OldComp, FirstEdge );
971 if (NewWire.Closed())
973 Wseq.Append(NewWire);
979 TopoDS_Vertex Extremity [2];
980 TopExp::Vertices( NewWire, Extremity[0], Extremity[1] );
981 if (Extremity[0].IsNull() || Extremity[1].IsNull())
983 anError = Standard_True;
986 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
987 TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
988 TopTools_ListOfShape Vedges [2];
989 for (j = 0; j < 2; j++)
990 if (VEmap.Contains( Extremity[j] ))
991 Vedges[j] = VEmap.FindFromKey( Extremity[j] );
992 if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
993 //no more edges in OldComp to continue NewWire
995 Standard_Boolean Modified = Standard_False;
996 for (j = 0; j < 2; j++)
998 if (Vedges[j].Extent() == 1)
1000 const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() );
1001 NewWire = BRepLib_MakeWire( NewWire, anEdge );
1002 B.Remove( OldComp, anEdge );
1003 Modified = Standard_True;
1006 if (!Modified) //only multiple connections
1008 ind = (Vedges[0].IsEmpty())? 1 : 0;
1009 TopTools_SequenceOfShape Edges;
1010 TopTools_ListIteratorOfListOfShape itl( Vedges[ind] );
1011 for (; itl.More(); itl.Next())
1012 Edges.Append( itl.Value() );
1013 Standard_Integer theind=0;
1014 Standard_Real MinDeviation = RealLast();
1015 for (j = 1; j <= Edges.Length(); j++)
1017 TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) );
1019 Standard_Boolean issing;
1020 Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing );
1021 if (Deviation < MinDeviation)
1023 MinDeviation = Deviation;
1027 NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) );
1028 B.Remove( OldComp, Edges(theind) );
1030 if (NewWire.Closed())
1033 Wseq.Append(NewWire);
1038 Standard_Real MinAngle = RealLast();
1039 TopExp_Explorer Explo( OldComp, TopAbs_EDGE );
1040 if (!anError && !Explo.More()) //wires are built successfully and compound <OldComp> is empty
1042 if (Wseq.Length() == 1) //only one wire => it becomes result
1044 resWire = Wseq.First();
1045 ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular );
1046 return Standard_True;
1048 else //we must choose the wire which average plane is closest to bisector plane
1049 { //(check angle between axes)
1050 for (i = 1; i <= Wseq.Length(); i++)
1052 TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) );
1054 Standard_Boolean issing;
1055 ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
1059 Standard_Real Angle = aPln.Axis().Angle( myAxeOfBisPlane.Axis() );
1061 Angle = M_PI - Angle;
1063 if (Angle < MinAngle)
1070 return Standard_True;
1073 return Standard_False;
1077 // ------------------------------------------------------------------------------------------
1078 // static function: SplitUEdges
1080 // ------------------------------------------------------------------------------------------
1081 Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
1082 const BOPDS_PDS& theDS,
1083 TopTools_DataMapOfShapeListOfShape& theHistMap) {
1085 const BOPDS_VectorOfInterfVV& aVVs = theDS->InterfVV();
1088 Standard_Integer ueit = 0, upRow, lowCol, upCol;
1089 TopTools_Array2OfShape aNewVertices(1,2,1,2);
1091 upRow = theUEdges->UpperRow();
1092 lowCol = theUEdges->LowerCol();
1093 upCol = theUEdges->UpperCol();
1095 for(ueit = theUEdges->LowerRow(); ueit <= upRow; ueit++) {
1096 const TopoDS_Shape& aE1 = theUEdges->Value(ueit, lowCol);
1097 const TopoDS_Shape& aE2 = theUEdges->Value(ueit, upCol);
1099 if(theHistMap.IsBound(aE1) || theHistMap.IsBound(aE2))
1102 Standard_Integer anEIndex1 = theDS->Index(aE1);
1103 Standard_Integer anEIndex2 = theDS->Index(aE2);
1105 TopoDS_Vertex aCommonVertex;
1106 Standard_Real apar1 = 0., apar2 = 0.;
1107 Standard_Boolean bvertexfound =
1108 FindCommonVertex(theDS, anEIndex1, anEIndex2, aCommonVertex, apar1, apar2);
1111 TopoDS_Vertex V1 = TopExp::LastVertex(TopoDS::Edge(aE1));
1112 TopoDS_Vertex V2 = TopExp::FirstVertex(TopoDS::Edge(aE2));
1113 Standard_Integer vindex1 = theDS->Index(V1);
1114 Standard_Integer vindex2 = theDS->Index(V2);
1115 Standard_Integer vvit = 0;
1116 Standard_Integer aNbVVs = aVVs.Length();
1118 for(vvit = 0; !bvertexfound && (vvit < aNbVVs); vvit++) {
1119 //const BOPTools_VVInterference& aVV = aVVs(vvit);
1120 const BOPDS_InterfVV& aVV = aVVs(vvit);
1122 if(((vindex1 == aVV.Index1()) && (vindex2 == aVV.Index2())) ||
1123 ((vindex1 == aVV.Index2()) && (vindex2 == aVV.Index1()))) {
1125 if(!aVV.HasIndexNew()) {
1128 aCommonVertex = TopoDS::Vertex(theDS->Shape(aVV.IndexNew()));
1129 bvertexfound = Standard_True;
1130 apar1 = BRep_Tool::Parameter(V1, TopoDS::Edge(aE1));
1131 apar2 = BRep_Tool::Parameter(V2, TopoDS::Edge(aE2));
1137 TopoDS_Vertex aV1, aV2;
1138 Standard_Real f = 0., l = 0.;
1140 TopoDS_Edge aNewE1 = TopoDS::Edge(aE1.EmptyCopied());
1141 TopExp::Vertices(TopoDS::Edge(aE1), aV1, aV2);
1142 aNewE1.Orientation(TopAbs_FORWARD);
1143 aV1.Orientation(TopAbs_FORWARD);
1144 aBB.Add(aNewE1, aV1);
1145 aCommonVertex.Orientation(TopAbs_REVERSED);
1146 aBB.Add(aNewE1, aCommonVertex);
1147 BRep_Tool::Range(TopoDS::Edge(aE1), f, l);
1148 aBB.Range(aNewE1, f, apar1);
1151 TopoDS_Edge aNewE2 = TopoDS::Edge(aE2.EmptyCopied());
1152 TopExp::Vertices(TopoDS::Edge(aE2), aV1, aV2);
1153 aNewE2.Orientation(TopAbs_FORWARD);
1154 aCommonVertex.Orientation(TopAbs_FORWARD);
1155 aBB.Add(aNewE2, aCommonVertex);
1156 aBB.Add(aNewE2, aV2);
1157 BRep_Tool::Range(TopoDS::Edge(aE2), f, l);
1158 aBB.Range(aNewE2, apar2, l);
1160 TopTools_ListOfShape lst;
1162 theHistMap.Bind(aE1, lst);
1165 theHistMap.Bind(aE2, lst);
1168 return Standard_True;
1171 // ------------------------------------------------------------------------------------------
1172 // static function: StoreVedgeInHistMap
1174 // ------------------------------------------------------------------------------------------
1175 void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)& theVEdges,
1176 const Standard_Integer theIndex,
1177 const TopoDS_Shape& theNewVshape,
1178 TopTools_DataMapOfShapeListOfShape& theHistMap)
1180 //Replace default value in the map (v-iso edge of face)
1181 //by intersection of two consecutive faces
1182 const TopoDS_Shape& aVEdge = theVEdges->Value(theIndex);
1184 theHistMap.Bound(aVEdge, TopTools_ListOfShape())->Append(theNewVshape);
1187 // ------------------------------------------------------------------------------------------
1188 // static function: FindFreeVertices
1190 // ------------------------------------------------------------------------------------------
1191 void FindFreeVertices(const TopoDS_Shape& theShape,
1192 const TopTools_MapOfShape& theVerticesToAvoid,
1193 TopTools_ListOfShape& theListOfVertex) {
1195 theListOfVertex.Clear();
1196 TopTools_IndexedDataMapOfShapeListOfShape aMap;
1197 TopExp::MapShapesAndAncestors(theShape, TopAbs_VERTEX, TopAbs_EDGE, aMap);
1198 Standard_Integer i = 0;
1200 for(i = 1; i <= aMap.Extent(); i++) {
1201 const TopoDS_Shape& aKey = aMap.FindKey(i);
1203 if(theVerticesToAvoid.Contains(aKey))
1205 const TopTools_ListOfShape& aList = aMap.FindFromIndex(i);
1207 if(aList.Extent() < 2) {
1208 theListOfVertex.Append(aKey);
1213 // ------------------------------------------------------------------------------------------
1214 // static function: FindCommonVertex
1216 // ------------------------------------------------------------------------------------------
1217 Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
1218 const Standard_Integer theEIndex1,
1219 const Standard_Integer theEIndex2,
1220 TopoDS_Vertex& theCommonVertex,
1221 Standard_Real& theParamOnE1,
1222 Standard_Real& theParamOnE2) {
1224 const BOPDS_VectorOfInterfEE& aEEs = theDS->InterfEE();
1226 Standard_Boolean bvertexfound = Standard_False;
1227 TopoDS_Vertex aCommonVertex;
1228 Standard_Integer eeit = 0;
1230 Standard_Integer aNbEEs;
1231 aNbEEs = aEEs.Length();
1232 for(eeit = 0; eeit < aNbEEs; ++eeit) {
1233 const BOPDS_InterfEE& aEE = aEEs(eeit);
1235 if((theEIndex1 == aEE.Index1() && theEIndex2 == aEE.Index2()) ||
1236 (theEIndex1 == aEE.Index2() && theEIndex2 == aEE.Index1())) {
1238 if(!aEE.HasIndexNew())
1241 IntTools_CommonPrt aCP = aEE.CommonPart();
1242 if(aCP.Type() == TopAbs_VERTEX)
1244 theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew());
1246 if (theEIndex1 == aEE.Index1())
1247 IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2);
1249 IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1);
1252 bvertexfound = Standard_True;
1257 return bvertexfound;
1260 // ----------------------------------------------------------------------------------------------------
1261 // static function: GetUEdges
1263 // ----------------------------------------------------------------------------------------------------
1264 Standard_Boolean GetUEdges(const Standard_Integer theIndex,
1265 const Standard_Integer theRank,
1266 const Handle(TopTools_HArray2OfShape)& theUEdges,
1267 const TopoDS_Edge& theBoundEdge,
1268 const TopoDS_Face& theFace,
1269 TopoDS_Edge& theFirstUEdge,
1270 TopoDS_Edge& theSecondUEdge) {
1271 const TopoDS_Shape& aUE1 = theUEdges->Value(theIndex, theUEdges->LowerCol() + theRank);
1272 const TopoDS_Shape& aUE2 = theUEdges->Value(theIndex + 1, theUEdges->LowerCol() + theRank);
1274 TopoDS_Face aFace = theFace;
1275 aFace.Orientation(TopAbs_FORWARD);
1277 TopExp_Explorer anExp(aFace, TopAbs_EDGE);
1279 for(; anExp.More(); anExp.Next()) {
1280 if(E1.IsNull() && aUE1.IsSame(anExp.Current())) {
1281 E1 = TopoDS::Edge(anExp.Current());
1283 else if(E2.IsNull() && aUE2.IsSame(anExp.Current())) {
1284 E2 = TopoDS::Edge(anExp.Current());
1288 if(E1.IsNull() || E2.IsNull())
1289 return Standard_False;
1292 Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1, aFace, f, l);
1295 return Standard_False;
1296 gp_Pnt2d PU1 = (theRank == 0) ? C1->Value(l) : C1->Value(f);
1297 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFace, f, l);
1300 return Standard_False;
1301 BRep_Tool::Range(theBoundEdge, f, l);
1302 gp_Pnt2d pf = C2->Value(f);
1303 TopoDS_Vertex aV = (theRank == 0) ? TopExp::LastVertex(E1) : TopExp::FirstVertex(E1);
1304 Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
1305 BRepAdaptor_Surface aBAS(aFace, Standard_False);
1307 if(pf.Distance(PU1) > aBAS.UResolution(aTolerance)) {
1308 TopoDS_Edge atmpE = E1;
1313 theSecondUEdge = E2;
1314 return Standard_True;
1317 // ----------------------------------------------------------------------------------------------------
1318 // static function: FillGap
1320 // ----------------------------------------------------------------------------------------------------
1321 Standard_Boolean FillGap(const TopoDS_Vertex& theFirstVertex,
1322 const TopoDS_Vertex& theLastVertex,
1323 const gp_Pnt2d& theFirstPoint,
1324 const gp_Pnt2d& theLastPoint,
1325 const TopoDS_Face& theFace,
1326 const TopoDS_Compound& theSectionEdges,
1327 TopTools_ListOfShape& theOrderedList) {
1329 TopTools_IndexedDataMapOfShapeListOfShape aMap;
1330 TopExp::MapShapesAndAncestors(theSectionEdges, TopAbs_VERTEX, TopAbs_EDGE, aMap);
1332 if(aMap.IsEmpty()) {
1333 return Standard_False;
1336 if(!aMap.Contains(theFirstVertex) ||
1337 !aMap.Contains(theLastVertex)) {
1338 return Standard_False;
1340 TopTools_ListOfShape aListOfEdge;
1341 // Standard_Integer i = 0;
1342 // TopoDS_Vertex aCurVertex = theFirstVertex;
1343 TopTools_MapOfShape aMapToAvoid;
1345 if(FindNextEdge(theFirstVertex, theLastVertex, aMap, aMapToAvoid, aListOfEdge)) {
1346 if(!aListOfEdge.IsEmpty()) {
1347 return CheckAndOrientEdges(aListOfEdge, theFirstPoint, theLastPoint, theFace, theOrderedList);
1350 return Standard_False;
1353 // ----------------------------------------------------------------------------------------------------
1354 // static function: FindNextEdge
1356 // ----------------------------------------------------------------------------------------------------
1357 Standard_Boolean FindNextEdge(const TopoDS_Vertex& theFirstVertex,
1358 const TopoDS_Vertex& theLastVertex,
1359 const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
1360 const TopTools_MapOfShape& theMapToAvoid,
1361 TopTools_ListOfShape& theOrderedList) {
1362 TopoDS_Vertex aCurVertex = theFirstVertex;
1363 TopTools_MapOfShape aMapToAvoid;
1364 aMapToAvoid = theMapToAvoid;
1365 TopTools_ListOfShape aListOfEdge;
1366 Standard_Integer i = 0;
1368 for(i = 1; i <= theMapVE.Extent(); i++) {
1369 if(!theMapVE.Contains(aCurVertex))
1371 const TopTools_ListOfShape& lste = theMapVE.FindFromKey(aCurVertex);
1372 Standard_Boolean befound = Standard_False;
1374 TopTools_ListIteratorOfListOfShape anIt(lste);
1376 for(; anIt.More(); anIt.Next()) {
1377 TopoDS_Shape anEdge = anIt.Value();
1378 TopoDS_Vertex aSaveCurVertex = aCurVertex;
1380 if(!aMapToAvoid.Contains(anEdge)) {
1381 TopoDS_Vertex V1, V2;
1382 TopExp::Vertices(TopoDS::Edge(anEdge), V1, V2);
1384 if(!aCurVertex.IsSame(V1)) {
1387 else if(!aCurVertex.IsSame(V2)) {
1390 aMapToAvoid.Add(anEdge);
1391 befound = Standard_True;
1392 aListOfEdge.Append(anEdge);
1394 if(!aCurVertex.IsSame(theLastVertex)) {
1395 TopTools_ListOfShape aListtmp;
1397 if(!FindNextEdge(aCurVertex, theLastVertex, theMapVE, aMapToAvoid, aListtmp)) {
1398 aListOfEdge.Clear();
1399 aCurVertex = aSaveCurVertex;
1403 aListOfEdge.Append(aListtmp);
1404 theOrderedList.Append(aListOfEdge);
1405 return Standard_True;
1412 if(aCurVertex.IsSame(theLastVertex))
1416 return Standard_False;
1420 if(aCurVertex.IsSame(theLastVertex)) {
1421 theOrderedList.Append(aListOfEdge);
1422 return Standard_True;
1424 return Standard_False;
1427 // ----------------------------------------------------------------------------------------------------
1428 // static function: CheckAndOrientEdges
1430 // ----------------------------------------------------------------------------------------------------
1431 Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList,
1432 const gp_Pnt2d& theFirstPoint,
1433 const gp_Pnt2d& theLastPoint,
1434 const TopoDS_Face& theFace,
1435 TopTools_ListOfShape& theOrientedList) {
1436 TopTools_ListIteratorOfListOfShape anIt(theOrderedList);
1439 return Standard_True;
1442 TopoDS_Edge aEPrev = TopoDS::Edge(anIt.Value());
1445 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(aEPrev, theFace, f, l);
1446 TopoDS_Vertex Vf, Vl;
1447 TopExp::Vertices(aEPrev, Vf, Vl);
1448 BRepAdaptor_Surface aBAS(theFace, Standard_False);
1450 Standard_Real aTolerance1 = (Vf.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vf);
1451 Standard_Real aTolerance2 = (Vl.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vl);
1452 Standard_Real utol = aBAS.UResolution(aTolerance1);
1453 Standard_Real vtol = aBAS.VResolution(aTolerance1);
1454 aTolerance1 = (utol > vtol) ? utol : vtol;
1455 utol = aBAS.UResolution(aTolerance2);
1456 vtol = aBAS.VResolution(aTolerance2);
1457 aTolerance2 = (utol > vtol) ? utol : vtol;
1459 gp_Pnt2d ap = aCurve->Value(f);
1460 Standard_Boolean bFirstFound = Standard_False;
1461 Standard_Boolean bLastFound = Standard_False;
1463 if(ap.Distance(theFirstPoint) < aTolerance1) {
1464 if(theOrientedList.IsEmpty())
1465 theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
1466 bFirstFound = Standard_True;
1468 else if(ap.Distance(theLastPoint) < aTolerance1) {
1469 if(theOrientedList.IsEmpty())
1470 theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
1471 bLastFound = Standard_True;
1473 ap = aCurve->Value(l);
1475 if(ap.Distance(theLastPoint) < aTolerance2) {
1476 if(theOrientedList.IsEmpty())
1477 theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
1478 bLastFound = Standard_True;
1480 else if(ap.Distance(theFirstPoint) < aTolerance2) {
1481 if(theOrientedList.IsEmpty())
1482 theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
1483 bFirstFound = Standard_True;
1486 if (!theOrientedList.IsEmpty())
1487 aEPrev = TopoDS::Edge (theOrientedList.Last());
1489 for(; anIt.More(); anIt.Next()) {
1490 const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
1491 TopoDS_Vertex aV11, aV12;
1492 TopExp::Vertices(aEPrev, aV11, aV12, Standard_True);
1493 TopoDS_Vertex aV21, aV22;
1494 TopExp::Vertices(aE, aV21, aV22, Standard_False);
1496 TopAbs_Orientation anOri =
1497 (aV12.IsSame (aV21) || aV11.IsSame (aV22)) ? TopAbs_FORWARD : TopAbs_REVERSED;
1498 theOrientedList.Append(aE.Oriented(anOri));
1499 aEPrev = TopoDS::Edge (theOrientedList.Last());
1501 aTolerance1 = (aV21.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV21);
1502 aTolerance2 = (aV22.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV22);
1503 utol = aBAS.UResolution(aTolerance1);
1504 vtol = aBAS.VResolution(aTolerance1);
1505 aTolerance1 = (utol > vtol) ? utol : vtol;
1506 utol = aBAS.UResolution(aTolerance2);
1507 vtol = aBAS.VResolution(aTolerance2);
1508 aTolerance2 = (utol > vtol) ? utol : vtol;
1509 aCurve = BRep_Tool::CurveOnSurface(aE, theFace, f, l);
1510 ap = aCurve->Value(f);
1512 if(ap.Distance(theFirstPoint) < aTolerance1) {
1513 bFirstFound = Standard_True;
1515 else if(ap.Distance(theLastPoint) < aTolerance1) {
1516 bLastFound = Standard_True;
1518 ap = aCurve->Value(l);
1520 if(ap.Distance(theFirstPoint) < aTolerance2) {
1521 bFirstFound = Standard_True;
1523 else if(ap.Distance(theLastPoint) < aTolerance2) {
1524 bLastFound = Standard_True;
1528 return bFirstFound && bLastFound;
1531 // ----------------------------------------------------------------------------------------------------
1532 // static function: FindVertex
1534 // ----------------------------------------------------------------------------------------------------
1535 Standard_Boolean FindVertex(const TopoDS_Edge& theEdge,
1536 const Standard_Integer theRank,
1537 const BOPDS_PDS& theDS,
1538 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1539 TopoDS_Vertex& theVertex,
1540 BOPDS_Pave& thePave) {
1542 if(!theHistMap.IsBound(theEdge))
1543 return Standard_False;
1545 const TopTools_ListOfShape& lst = theHistMap.Find(theEdge);
1548 return Standard_False;
1550 TopoDS_Edge aNewEdge = TopoDS::Edge(lst.First());
1552 BRep_Tool::Range(aNewEdge, f, l);
1555 thePave.SetParameter(l);
1556 theVertex = TopExp::LastVertex(aNewEdge);
1559 thePave.SetParameter(f);
1560 theVertex = TopExp::FirstVertex(aNewEdge);
1562 Standard_Integer anIndex = theDS->Index(theVertex);
1563 if (anIndex == -1) {
1564 Standard_Integer i, i1, i2;
1565 i1=theDS->NbSourceShapes();
1566 i2=theDS->NbShapes();
1567 for (i=i1; i<i2; ++i) {
1568 const TopoDS_Shape& aSx=theDS->Shape(i);
1569 if(aSx.IsSame(theVertex)) {
1576 thePave.SetIndex(anIndex);
1578 return Standard_True;
1581 // ----------------------------------------------------------------------------------------------------
1582 // static function: FindNextVertex
1584 // ----------------------------------------------------------------------------------------------------
1585 Standard_Boolean FindNextVertex(const Standard_Integer theEdgeIndex,
1586 const BOPDS_Pave& thePrevPave,
1587 const BOPDS_PDS& theDS,
1588 TopoDS_Vertex& theNextVertex,
1589 BOPDS_Pave& thePave) {
1591 Standard_Boolean bTakePave, bFound;
1592 BOPDS_Pave aTmpPave;
1593 BOPDS_ListIteratorOfListOfPave aItP;
1595 BOPDS_Pave anullpave;
1596 bFound = Standard_False;
1597 bTakePave = thePrevPave.IsEqual(anullpave);
1599 BOPDS_ListOfPave aLP;
1600 theDS->Paves(theEdgeIndex, aLP);
1601 aItP.Initialize(aLP);
1602 for (; aItP.More(); aItP.Next()) {
1603 aTmpPave = aItP.Value();
1606 if (theDS->IsNewShape(aTmpPave.Index())) {
1607 theNextVertex = *(TopoDS_Vertex*)&theDS->Shape(aTmpPave.Index());
1609 bFound = Standard_True;
1614 else if (aTmpPave.IsEqual(thePrevPave)) {
1615 bTakePave = Standard_True;
1622 // ----------------------------------------------------------------------------------------------------
1623 // static function: GetPave
1625 // ----------------------------------------------------------------------------------------------------
1626 Standard_Boolean GetPave(const Standard_Integer theEdgeIndex,
1627 const Standard_Boolean isFirst,
1628 const BOPDS_PDS& theDS,
1629 BOPDS_Pave& thePave) {
1631 Handle(BOPDS_PaveBlock) aPB;
1632 BOPDS_ListOfPave aLP;
1634 theDS->Paves(theEdgeIndex, aLP);
1635 if (!aLP.Extent()) {
1636 return Standard_False;
1640 thePave = aLP.First();
1643 thePave = aLP.Last();
1646 return Standard_True;
1649 // ----------------------------------------------------------------------------------------------------
1650 // static function: FindFromUEdge
1652 // ----------------------------------------------------------------------------------------------------
1653 Standard_Boolean FindFromUEdge(const TopoDS_Edge& theUE1Old,
1654 const TopoDS_Edge& theUE2Old,
1655 const TopoDS_Edge& theUE1New,
1656 const TopoDS_Edge& theUE2New,
1657 const TopoDS_Face& theFace,
1658 const TopoDS_Compound& theSecEdges,
1659 const Standard_Integer theRank,
1660 const TopoDS_Edge& theBoundEdge,
1661 const Standard_Integer theBoundEdgeIndex,
1662 const BOPDS_PDS& theDS,
1663 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1664 TopoDS_Compound& theSecEdgesNew,
1665 TopTools_ListOfShape& theListOfWireEdges,
1666 BOPDS_Pave& theFoundPave,
1667 Standard_Boolean& isOnUEdge) {
1668 theFoundPave.SetIndex(0);
1669 theFoundPave.SetParameter(0.);
1670 isOnUEdge = Standard_True;
1672 TopoDS_Face aFaceF = theFace;
1673 aFaceF.Orientation(TopAbs_FORWARD);
1674 TopoDS_Vertex aPrevVertex, aNextVertex;
1675 TopoDS_Compound aCompOfSecEdges = theSecEdges;
1676 TopTools_ListOfShape aListOfWireEdges;
1677 // BRep_Builder aBB;
1679 BOPDS_Pave aPave1, aPave2;
1680 Standard_Real f = 0., l = 0.;
1682 TopoDS_Vertex aFirstV, aLastV;
1683 BOPDS_Pave atmpPave;
1685 if(!FindVertex(theUE1Old, theRank, theDS, theHistMap, aPrevVertex, atmpPave)) {
1686 return Standard_True;
1689 if(aPrevVertex.IsNull()) {
1690 return Standard_False;
1693 aFirstV = aPrevVertex;
1694 Standard_Boolean bSecFound = Standard_False;
1695 Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1New, aFaceF, f, l);
1696 p1 = (theRank == 0) ? aC1->Value(l) : aC1->Value(f);
1697 BOPDS_Pave afoundpave;
1698 BOPDS_ListOfPave aLP;
1699 theDS->Paves(theBoundEdgeIndex, aLP);
1700 Standard_Integer nbpave = aLP.Extent();
1701 Standard_Integer pit = 0;
1703 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1704 aLastV = aNextVertex;
1705 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
1706 p2 = aC2->Value(aPave2.Parameter());
1707 TopTools_ListOfShape aOrderedList;
1709 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1710 // remove found edges...
1711 TopoDS_Compound aComp;
1712 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1713 aCompOfSecEdges = aComp;
1714 aListOfWireEdges.Append(aOrderedList);
1715 afoundpave = aPave2;
1716 isOnUEdge = Standard_False;
1717 bSecFound = Standard_True;
1720 aPrevVertex = aNextVertex;
1725 if(!bSecFound && FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1726 aLastV = aNextVertex;
1727 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theUE2New, aFaceF, f, l);
1728 p2 = aC2->Value(aPave2.Parameter());
1729 TopTools_ListOfShape aOrderedList;
1731 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1732 // remove found edges...
1733 TopoDS_Compound aComp;
1735 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1736 aCompOfSecEdges = aComp;
1737 aListOfWireEdges.Append(aOrderedList);
1738 afoundpave = aPave2;
1739 bSecFound = Standard_True;
1740 isOnUEdge = Standard_True;
1745 theFoundPave = afoundpave;
1746 theListOfWireEdges = aListOfWireEdges;
1747 theSecEdgesNew = aCompOfSecEdges;
1749 return Standard_True;
1753 // ----------------------------------------------------------------------------------------------------
1754 // static function: FindFromVEdge
1756 // ----------------------------------------------------------------------------------------------------
1757 Standard_Boolean FindFromVEdge(const BOPDS_Pave& thePrevPave,
1758 const Standard_Boolean& isOnUEdge,
1759 const TopoDS_Edge& theUE1Old,
1760 const TopoDS_Edge& theUE2Old,
1761 const TopoDS_Face& theFace,
1762 const TopoDS_Compound& theSecEdges,
1763 const Standard_Integer theRank,
1764 const TopoDS_Edge& theBoundEdge,
1765 const Standard_Integer theBoundEdgeIndex,
1766 const BOPDS_PDS& theDS,
1767 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1768 TopTools_ListOfShape& theListOfWireEdges,
1769 Standard_Boolean& isSectionFound) {
1771 theListOfWireEdges.Clear();
1772 isSectionFound = Standard_False;
1774 TopoDS_Face aFaceF = theFace;
1775 aFaceF.Orientation(TopAbs_FORWARD);
1776 TopoDS_Vertex aPrevVertex, aNextVertex;
1777 TopoDS_Compound aCompOfSecEdges = theSecEdges;
1778 TopTools_ListOfShape aListOfWireEdges;
1779 // BRep_Builder aBB;
1781 BOPDS_Pave aPave1, aPave2;
1784 TopoDS_Vertex atmpVertex;
1785 BOPDS_Pave aPaveOfE2;
1787 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, atmpVertex, aPaveOfE2)) {
1788 if(thePrevPave.IsEqual(aPaveOfE2))
1789 return Standard_True;
1793 Standard_Real f = 0., l = 0.;
1794 gp_Pnt2d p1(0., 0.), p2(0., 0.);
1795 TopoDS_Vertex aFirstV, aLastV;
1796 Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1Old, aFaceF, f, l);
1797 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
1798 Standard_Boolean bSecFound = Standard_False;
1800 aPave1 = thePrevPave;
1803 BOPDS_Pave atmpPave;
1805 if(!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave)) {
1806 return Standard_False;
1810 p1 = aC2->Value(aPave1.Parameter());
1811 aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
1813 BOPDS_ListOfPave aLP;
1814 theDS->Paves(theBoundEdgeIndex, aLP);
1815 Standard_Integer nbpave = aLP.Extent();
1816 Standard_Integer pit = 0;
1817 TopTools_Array1OfListOfShape anArrayOfListOfSec(1, nbpave);
1819 // by pairs non continuously. begin
1820 Standard_Integer k = 0;
1821 BOPDS_Pave aFirstPave = aPave1;
1822 TopoDS_Vertex aFirstVertex = aPrevVertex;
1823 gp_Pnt2d apfirst = p1;
1824 BOPDS_ListOfPave aFirstPaves, aLastPaves;
1825 TColStd_ListOfInteger aListOfFlags;
1826 Standard_Integer apaircounter = 1;
1828 for(k = 0; k < nbpave; k++) {
1829 aPave1 = aFirstPave;
1831 aPrevVertex = aFirstVertex;
1832 Standard_Boolean bfound = Standard_False;
1835 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1836 aFirstV = aPrevVertex;
1837 aLastV = aNextVertex;
1838 p2 = aC2->Value(aPave2.Parameter());
1840 TopTools_ListOfShape aOrderedList;
1842 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1843 TopoDS_Compound aComp;
1844 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1845 aCompOfSecEdges = aComp;
1847 anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
1848 aFirstPaves.Append(aFirstPave);
1849 aLastPaves.Append(aPave2);
1850 aListOfFlags.Append(1);
1851 aFirstPave = aPave2;
1852 aFirstVertex = aNextVertex;
1854 aPrevVertex = aNextVertex;
1855 bSecFound = Standard_True;
1856 bfound = Standard_True;
1862 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1863 aFirstV = aPrevVertex;
1864 aLastV = aNextVertex;
1865 Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1866 p2 = aC3->Value(aPave2.Parameter());
1868 TopTools_ListOfShape aOrderedList;
1870 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1871 TopoDS_Compound aComp;
1872 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1873 aCompOfSecEdges = aComp;
1874 anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
1875 aFirstPaves.Append(aFirstPave);
1876 aLastPaves.Append(aPave2);
1877 aListOfFlags.Append(0);
1878 bSecFound = Standard_True;
1884 if(!FindNextVertex(theBoundEdgeIndex, aFirstPave, theDS, aNextVertex, aPave2)) {
1887 aFirstPave = aPave2;
1888 apfirst = aC2->Value(aPave2.Parameter());
1889 aFirstVertex = aNextVertex;
1892 // by pairs non continuously. end
1894 // by pairs continuously. begin
1895 aPave1 = thePrevPave;
1898 BOPDS_Pave atmpPave;
1900 if(!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave)) {
1901 return Standard_False;
1905 p1 = aC2->Value(aPave1.Parameter());
1906 aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
1910 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1911 aFirstV = aPrevVertex;
1912 aLastV = aNextVertex;
1913 p2 = aC2->Value(aPave2.Parameter());
1915 Standard_Boolean bisinside = Standard_False;
1916 Standard_Integer apbindex = 0;
1917 Standard_Integer apbcounter = 1;
1918 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1919 BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
1920 TColStd_ListIteratorOfListOfInteger aFlagIt;
1922 for(aPIt1.Initialize(aFirstPaves), aPIt2.Initialize(aLastPaves), aFlagIt.Initialize(aListOfFlags);
1923 aPIt1.More() && aPIt2.More() && aFlagIt.More();
1924 aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++) {
1926 Standard_Boolean bfin = Standard_False;
1927 Standard_Boolean blin = Standard_False;
1929 if(aPave1.IsEqual(aPIt1.Value())) {
1930 bfin = Standard_True;
1933 bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
1936 if(aFlagIt.Value()) {
1937 if(aPave2.IsEqual(aPIt2.Value())) {
1938 blin = Standard_True;
1941 blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
1945 if((aPave2.Index() == aPIt2.Value().Index()) && (aPave2.Index() > 0)) {
1946 Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1947 gp_Pnt2d p3 = pc->Value(aPIt2.Value().Parameter());
1948 TopoDS_Vertex aV = TopoDS::Vertex(theDS->Shape(aPave2.Index()));
1949 BRepAdaptor_Surface aBAS(aFaceF, Standard_False);
1950 Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
1951 Standard_Real utol = aBAS.UResolution(aTolerance);
1952 Standard_Real vtol = aBAS.VResolution(aTolerance);
1953 aTolerance = (utol > vtol) ? utol : vtol;
1955 if(p2.Distance(p3) < aTolerance)
1956 blin = Standard_True;
1961 apbindex = apbcounter;
1962 bisinside = Standard_True;
1969 TopTools_ListOfShape aOrderedList;
1971 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1972 TopoDS_Compound aComp;
1973 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1974 aCompOfSecEdges = aComp;
1975 aListOfWireEdges.Append(aOrderedList);
1977 bSecFound = Standard_True;
1980 TopoDS_Edge aESplit;
1982 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
1984 for(; aPBIt.More(); aPBIt.Next()) {
1985 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
1986 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
1987 aPB1->Pave1().IsEqual(aPave1) &&
1988 aPB1->Pave2().IsEqual(aPave2) ) {
1989 if(aPB1->Edge() > 0) {
1990 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
1996 if(!aESplit.IsNull()) {
1997 aListOfWireEdges.Append(aESplit);
2003 TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
2004 aListOfWireEdges.Append(aListOfSec);
2008 aPrevVertex = aNextVertex;
2013 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
2014 aFirstV = aPrevVertex;
2015 aLastV = aNextVertex;
2016 Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
2017 p2 = aC3->Value(aPave2.Parameter());
2019 Standard_Boolean bisinside = Standard_False;
2020 Standard_Integer apbindex = 0;
2021 Standard_Integer apbcounter = 1;
2022 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2023 BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
2024 TColStd_ListIteratorOfListOfInteger aFlagIt;
2026 for(aPIt1.Initialize(aFirstPaves), aPIt2.Initialize(aLastPaves), aFlagIt.Initialize(aListOfFlags);
2027 aPIt1.More() && aPIt2.More() && aFlagIt.More();
2028 aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++) {
2030 Standard_Boolean bfin = Standard_False;
2031 Standard_Boolean blin = Standard_False;
2033 if(aPave1.IsEqual(aPIt1.Value())) {
2034 bfin = Standard_True;
2037 bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
2040 if(aFlagIt.Value()) {
2041 if(aPave2.IsEqual(aPIt2.Value())) {
2042 blin = Standard_True;
2045 blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
2049 blin = Standard_True;
2053 apbindex = apbcounter;
2054 bisinside = Standard_True;
2061 TopTools_ListOfShape aOrderedList;
2063 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
2064 TopoDS_Compound aComp;
2065 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
2066 aCompOfSecEdges = aComp;
2067 aListOfWireEdges.Append(aOrderedList);
2069 bSecFound = Standard_True;
2073 TopoDS_Edge aESplit;
2075 if(!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
2076 return Standard_False;
2078 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
2079 for(; aPBIt.More(); aPBIt.Next()) {
2080 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
2081 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
2082 aPB1->Pave1().IsEqual(aPave1) &&
2083 aPB1->Pave2().IsEqual(aPave2) ) {
2084 if(aPB1->Edge() > 0) {
2085 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
2091 if(!aESplit.IsNull()) {
2092 aListOfWireEdges.Append(aESplit);
2098 TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
2099 aListOfWireEdges.Append(aListOfSec);
2105 TopoDS_Edge aESplit;
2107 if(!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
2108 return Standard_False;
2110 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2111 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
2112 for(; aPBIt.More(); aPBIt.Next()) {
2113 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
2114 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
2115 aPB1->Pave1().IsEqual(aPave1) &&
2116 aPB1->Pave2().IsEqual(aPave2) ) {
2117 if(aPB1->Edge() > 0) {
2118 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
2124 if(!aESplit.IsNull()) {
2125 aListOfWireEdges.Append(aESplit);
2129 // by pairs continuously. end
2130 theListOfWireEdges = aListOfWireEdges;
2131 isSectionFound = bSecFound;
2132 return Standard_True;
2135 // ----------------------------------------------------------------------------------------------------
2136 // static function: RemoveEdges
2138 // ----------------------------------------------------------------------------------------------------
2139 void RemoveEdges(const TopoDS_Compound& theSourceComp,
2140 const TopTools_ListOfShape& theListToRemove,
2141 TopoDS_Compound& theResultComp) {
2143 TopoDS_Compound aComp;
2144 aBB.MakeCompound(aComp);
2145 TopExp_Explorer anExp(theSourceComp, TopAbs_EDGE);
2147 for(; anExp.More(); anExp.Next()) {
2148 Standard_Boolean bfound = Standard_False;
2149 TopTools_ListIteratorOfListOfShape anIt(theListToRemove);
2151 for(; !bfound && anIt.More(); anIt.Next()) {
2152 bfound = anExp.Current().IsSame(anIt.Value());
2156 aBB.Add(aComp, anExp.Current());
2159 theResultComp = aComp;
2162 // ----------------------------------------------------------------------------------------------------
2163 // static function: FilterSectionEdges
2165 // ----------------------------------------------------------------------------------------------------
2166 Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve& theBCurves,
2167 const TopoDS_Face& theSecPlane,
2168 const BOPDS_PDS& theDS,
2169 TopoDS_Compound& theResult) {
2171 theResult.Nullify();
2174 aBB.MakeCompound(theResult);
2175 Standard_Integer aNbCurves = theBCurves.Length();
2176 Standard_Integer cit = 0;
2177 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2179 for(cit = 0; cit < aNbCurves; ++cit) {
2180 const BOPDS_Curve& aBCurve = theBCurves(cit);
2181 const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
2183 aPBIt.Initialize(aSectEdges);
2184 for (; aPBIt.More(); aPBIt.Next()) {
2185 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
2186 Standard_Integer nSect = aPB->Edge();
2187 const TopoDS_Shape& aS = theDS->Shape(nSect);
2188 TopoDS_Edge anEdge = TopoDS::Edge(aS);
2189 Standard_Boolean bAddEdge = Standard_True;
2191 if(!theSecPlane.IsNull()) {
2192 IntTools_BeanFaceIntersector anIntersector(anEdge, theSecPlane);
2193 Standard_Real f = 0., l = 0.;
2194 BRep_Tool::Range(anEdge, f, l);
2195 anIntersector.SetBeanParameters(f, l);
2197 Handle(IntTools_Context) aContext = new IntTools_Context;
2198 anIntersector.SetContext(aContext);
2200 anIntersector.Perform();
2202 if(anIntersector.IsDone()) {
2203 bAddEdge = Standard_False;
2204 Standard_Integer r = 0;
2206 for(r = 1; r <= anIntersector.Result().Length(); r++) {
2207 const IntTools_Range& aRange = anIntersector.Result().Value(r);
2209 if(((aRange.First() - f) < Precision::PConfusion()) &&
2210 ((l - aRange.Last()) < Precision::PConfusion())) {
2211 bAddEdge = Standard_True;
2213 }//if(((aRange.First() - f) < Precision::PConfusion()) &&
2214 }//for(r = 1; r <= anIntersector.Result().Length(); r++) {
2215 }//if(anIntersector.IsDone()) {
2216 }//if(!theSecPlane.IsNull()) {
2219 aBB.Add(theResult, aS);
2221 }//for (; aPBIt.More(); aPBIt.Next()) {
2222 }//for(cit = 0; cit < aNbCurves; ++cit) {
2224 return Standard_True;
2228 //=======================================================================
2229 //function : ComputeAveragePlaneAndMaxDeviation
2231 //=======================================================================
2232 static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
2234 Standard_Boolean& IsSingular)
2236 Standard_Integer N = 40;
2237 Standard_Integer nedges = aWire.NbChildren();
2239 TColgp_Array1OfPnt Pnts( 1, nedges*N );
2240 Standard_Integer ind = 1, i;
2241 for (TopoDS_Iterator iter (aWire); iter.More(); iter.Next())
2243 const TopoDS_Edge& anEdge = TopoDS::Edge( iter.Value() );
2244 BRepAdaptor_Curve aCurve(anEdge);
2245 GCPnts_UniformAbscissa Distribution( aCurve, N+1 );
2246 for (i = 1; i <= N; i++)
2248 Standard_Real par = Distribution.Parameter(i);
2249 Pnts( ind++ ) = aCurve.Value(par);
2254 GeomLib::AxeOfInertia( Pnts, Axe, IsSingular );
2258 thePlane = gp_Pln( Axe );
2259 Standard_Real MaxDeviation = 0;
2260 for (i = 1; i <= Pnts.Length(); i++)
2262 Standard_Real dist = thePlane.Distance( Pnts(i) );
2263 if (dist > MaxDeviation)
2264 MaxDeviation = dist;
2266 return MaxDeviation;
2270 static void UpdateSectionEdge(TopoDS_Edge& theEdge,
2271 const TopoDS_Vertex& theConstVertex,
2272 TopoDS_Vertex& theVertex,
2273 const Standard_Real theParam)
2275 TopoDS_Edge F_Edge = theEdge;
2276 F_Edge.Orientation(TopAbs_FORWARD);
2278 TopAbs_Orientation OrOfVertex;
2279 TopoDS_Vertex V1, V2, AnotherVertex;
2280 TopExp::Vertices(F_Edge, V1, V2);
2281 if (theConstVertex.IsSame(V1))
2283 //OrOfConst = TopAbs_FORWARD;
2284 OrOfVertex = TopAbs_REVERSED;
2289 //OrOfConst = TopAbs_REVERSED;
2290 OrOfVertex = TopAbs_FORWARD;
2295 Standard_Real fpar, lpar;
2296 BRep_Tool::Range(F_Edge, fpar, lpar);
2297 if (OrOfVertex == TopAbs_FORWARD)
2301 BB.Range(F_Edge, fpar, lpar);
2303 F_Edge.Free(Standard_True);
2304 BB.Remove(F_Edge, AnotherVertex);
2305 theVertex.Orientation(OrOfVertex);
2306 BB.Add(F_Edge, theVertex);
2309 //Finds the edge connected to <theVertex> in the compound <theComp>
2310 //that is closest to bisector plane angularly.
2311 //Removes found edge from <theComp>
2312 //<theAxis> is the axis of bisector plane
2313 static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
2314 TopoDS_Compound& theComp,
2315 const gp_Ax1& theAxis)
2317 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
2318 TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
2320 TopoDS_Edge MinEdge;
2321 if (!VEmap.Contains(theVertex))
2326 const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex);
2327 if (Edges.Extent() == 1)
2328 MinEdge = TopoDS::Edge(Edges.First());
2331 TopTools_ListIteratorOfListOfShape itl(Edges);
2332 Standard_Real MinAngle = RealLast();
2333 for (; itl.More(); itl.Next())
2335 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2338 BB.Add(aWire, anEdge);
2340 Standard_Boolean issing;
2341 ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
2342 Standard_Real anAngle;
2343 if (issing) //edge is a segment of line
2345 //<anAngle> is angle between <anEdge> and its projection on bisector plane
2346 BRepAdaptor_Curve BAcurve(anEdge);
2347 gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
2348 gp_Pnt LastPnt = BAcurve.Value(BAcurve.LastParameter());
2349 gp_Vec EdgeVec(FirstPnt, LastPnt);
2350 gp_Ax1 EdgeAxis(FirstPnt, EdgeVec);
2351 anAngle = EdgeAxis.Direction().Angle(theAxis.Direction());
2352 if (anAngle > M_PI/2)
2353 anAngle = M_PI - anAngle;
2354 anAngle = M_PI/2 - anAngle;
2358 anAngle = aPln.Axis().Angle( theAxis );
2359 if (anAngle > M_PI/2)
2360 anAngle = M_PI - anAngle;
2363 if (anAngle < MinAngle)
2369 } //else (more than one edge)
2371 BB.Remove(theComp, MinEdge);
2375 static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1,
2376 const TopoDS_Vertex& theVertex2,
2377 const gp_Ax1& theAxis,
2378 TopoDS_Compound& theComp,
2379 TopTools_ListOfShape& theElist)
2381 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
2382 TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
2383 if (VEmap.IsEmpty())
2384 return Standard_False;
2386 if (!VEmap.Contains(theVertex1) ||
2387 !VEmap.Contains(theVertex2))
2388 return Standard_False;
2390 TopoDS_Vertex CurVertex = theVertex1;
2393 TopoDS_Edge CurEdge;
2395 CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis);
2396 if (CurEdge.IsNull())
2397 return Standard_False;
2399 TopoDS_Vertex V1, V2;
2400 TopExp::Vertices(CurEdge, V1, V2);
2401 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2403 theElist.Append(CurEdge);
2404 if (CurVertex.IsSame(theVertex2))
2405 return Standard_True;
2409 static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge,
2410 const TopoDS_Edge& theLastEdge,
2411 const TopoDS_Vertex& theFirstVertex,
2412 const TopoDS_Vertex& theLastVertex,
2413 TopoDS_Vertex& theCommonVertex)
2415 if (!theFirstVertex.IsSame(theLastVertex))
2417 Standard_Boolean CommonVertexExists = TopExp::CommonVertex(theFirstEdge,
2420 return CommonVertexExists;
2423 TopoDS_Vertex V1, V2, V3, V4;
2424 TopExp::Vertices(theFirstEdge, V1, V2);
2425 TopExp::Vertices(theLastEdge, V3, V4);
2427 if (V1.IsSame(theFirstVertex))
2429 if (V2.IsSame(V3) ||
2432 theCommonVertex = V2;
2433 return Standard_True;
2438 if (V1.IsSame(V3) ||
2441 theCommonVertex = V1;
2442 return Standard_True;
2446 return Standard_False;