1 // Created on: 2003-10-21
2 // Created by: Mikhail KLOKOV
3 // Copyright (c) 2003-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #include <BRepFill_TrimShellCorner.ixx>
23 #include <BRepAlgoAPI_Section.hxx>
24 #include <BRep_Builder.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRepLib_MakeEdge.hxx>
27 #include <BRepTools_ReShape.hxx>
29 #include <TopoDS_Shell.hxx>
30 #include <TopoDS_Compound.hxx>
32 #include <IntTools_BeanFaceIntersector.hxx>
33 #include <BOPInt_Context.hxx>
34 #include <IntTools_Range.hxx>
36 #include <Geom_Curve.hxx>
37 #include <Geom2d_Curve.hxx>
38 #include <gp_Pnt2d.hxx>
40 #include <TopLoc_Location.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopTools_MapOfShape.hxx>
44 #include <TopTools_ListOfShape.hxx>
45 #include <TopTools_Array1OfListOfShape.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
48 #include <TopTools_DataMapOfShapeListOfShape.hxx>
49 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
52 #include <TopoDS_Iterator.hxx>
53 #include <TColgp_Array1OfPnt.hxx>
54 #include <TColgp_Array2OfPnt.hxx>
55 #include <TColgp_Array1OfDir.hxx>
56 #include <TColStd_ListOfInteger.hxx>
57 #include <TColStd_ListIteratorOfListOfInteger.hxx>
58 #include <GCPnts_UniformAbscissa.hxx>
59 #include <GeomLib.hxx>
60 #include <BRepLib_MakeWire.hxx>
61 #include <TopTools_SequenceOfShape.hxx>
62 #include <TColStd_Array1OfBoolean.hxx>
63 #include <TColgp_SequenceOfPnt.hxx>
64 #include <gce_MakeLin.hxx>
66 #include <BOPInt_Tools.hxx>
67 #include <BOPAlgo_PaveFiller.hxx>
68 #include <BOPDS_DS.hxx>
69 #include <BOPAlgo_BOP.hxx>
71 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
72 #include <BOPCol_ListOfShape.hxx>
74 static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
75 const Standard_Integer theEIndex1,
76 const Standard_Integer theEIndex2,
77 TopoDS_Vertex& theCommonVertex,
78 Standard_Real& theParamOnE1,
79 Standard_Real& theParamOnE2);
81 static Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex,
82 const Handle(TopTools_HArray2OfShape)& theUEdges,
83 const Handle(TopTools_HArray2OfShape)& theBounds,
84 const BOPDS_PDS& theDS,
85 const Standard_Integer theFaceIndex1,
86 const Standard_Integer theFaceIndex2,
87 TopTools_DataMapOfShapeListOfShape& theHistMap);
89 static Standard_Boolean MakeFacesSec(const Standard_Integer theIndex,
90 const Handle(TopTools_HArray2OfShape)& theUEdges,
91 const Handle(TopTools_HArray2OfShape)& theBounds,
92 const BOPDS_PDS& theDS,
93 const Standard_Integer theFaceIndex1,
94 const Standard_Integer theFaceIndex2,
95 const Standard_Integer theSSInterfIndex,
96 const gp_Ax2& AxeOfBisPlane,
97 TopTools_DataMapOfShapeListOfShape& theHistMap);
99 static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
100 const BOPDS_PDS& theDS,
101 TopTools_DataMapOfShapeListOfShape& theHistMap);
103 static void FindFreeVertices(const TopoDS_Shape& theShape,
104 const TopTools_MapOfShape& theVerticesToAvoid,
105 TopTools_ListOfShape& theListOfVertex);
107 static Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList,
108 const gp_Pnt2d& theFirstPoint,
109 const gp_Pnt2d& theLastPoint,
110 const TopoDS_Face& theFace,
111 TopTools_ListOfShape& theOrientedList);
113 static Standard_Boolean FillGap(const TopoDS_Vertex& theFirstVertex,
114 const TopoDS_Vertex& theLastVertex,
115 const gp_Pnt2d& theFirstPoint,
116 const gp_Pnt2d& theLastPoint,
117 const TopoDS_Face& theFace,
118 const TopoDS_Compound& theSectionEdges,
119 TopTools_ListOfShape& theOrderedList);
121 static Standard_Boolean FindNextEdge(const TopoDS_Vertex& theFirstVertex,
122 const TopoDS_Vertex& theLastVertex,
123 const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
124 const TopTools_MapOfShape& theMapToAvoid,
125 TopTools_ListOfShape& theOrderedList);
127 static Standard_Boolean FindVertex(const TopoDS_Edge& theEdge,
128 const Standard_Integer theRank,
129 const BOPDS_PDS& theDS,
130 const TopTools_DataMapOfShapeListOfShape& theHistMap,
131 TopoDS_Vertex& theVertex,
132 BOPDS_Pave& thePave);
134 static Standard_Boolean FindNextVertex(const Standard_Integer theEdgeIndex,
135 const BOPDS_Pave& thePrevPave,
136 const BOPDS_PDS& theDS,
137 TopoDS_Vertex& theNextVertex,
138 BOPDS_Pave& thePave);
140 static Standard_Boolean GetPave(const Standard_Integer theEdgeIndex,
141 const Standard_Boolean isFirst,
142 const BOPDS_PDS& theDS,
143 BOPDS_Pave& thePave);
145 static Standard_Boolean FindFromUEdge(const TopoDS_Edge& theUE1Old,
146 const TopoDS_Edge& theUE2Old,
147 const TopoDS_Edge& theUE1New,
148 const TopoDS_Edge& theUE2New,
149 const TopoDS_Face& theFace,
150 const TopoDS_Compound& theSecEdges,
151 const Standard_Integer theRank,
152 const TopoDS_Edge& theBoundEdge,
153 const Standard_Integer theBoundEdgeIndex,
154 const BOPDS_PDS& theDS,
155 const TopTools_DataMapOfShapeListOfShape& theHistMap,
156 TopoDS_Compound& theSecEdgesNew,
157 TopTools_ListOfShape& theListOfWireEdges,
158 BOPDS_Pave& theFoundPave,
159 Standard_Boolean& isOnUEdge);
161 static Standard_Boolean FindFromVEdge(const BOPDS_Pave& thePrevPave,
162 const Standard_Boolean& isOnUEdge,
163 const TopoDS_Edge& theUE1Old,
164 const TopoDS_Edge& theUE2Old,
165 const TopoDS_Face& theFace,
166 const TopoDS_Compound& theSecEdges,
167 const Standard_Integer theRank,
168 const TopoDS_Edge& theBoundEdge,
169 const Standard_Integer theBoundEdgeIndex,
170 const BOPDS_PDS& theDS,
171 const TopTools_DataMapOfShapeListOfShape& theHistMap,
172 TopTools_ListOfShape& theListOfWireEdges,
173 Standard_Boolean& isSectionFound);
175 static void RemoveEdges(const TopoDS_Compound& theSourceComp,
176 const TopTools_ListOfShape& theListToRemove,
177 TopoDS_Compound& theResultComp);
179 static Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve& theBCurves,
180 const TopoDS_Face& theSecPlane,
181 const BOPDS_PDS& theDS,
182 TopoDS_Compound& theResult);
184 static Standard_Boolean GetUEdges(const Standard_Integer theIndex,
185 const Standard_Integer theRank,
186 const Handle(TopTools_HArray2OfShape)& theUEdges,
187 const TopoDS_Edge& theBoundEdge,
188 const TopoDS_Face& theFace,
189 TopoDS_Edge& theFirstUEdge,
190 TopoDS_Edge& theSecondUEdge);
192 static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
194 Standard_Boolean& IsSingular);
196 static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp,
198 TopoDS_Shape& resWire,
200 Standard_Boolean& IsSingular);
202 // ===========================================================================================
203 // function: Constructor
205 // ===========================================================================================
206 BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
207 const gp_Ax2& theAxeOfBisPlane,
208 const TopoDS_Face& theSecPlane) :
209 myAxeOfBisPlane(theAxeOfBisPlane),
210 myDone(Standard_False),
211 myHasSection(Standard_False)
213 myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(),
214 theFaces->LowerCol(), theFaces->UpperCol());
215 myFaces->ChangeArray2() = theFaces->Array2();
216 mySecPln = theSecPlane;
219 // ===========================================================================================
220 // function: Constructor
222 // ===========================================================================================
223 BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
224 const gp_Ax2& theAxeOfBisPlane,
225 const TopoDS_Wire& theSpine,
226 const TopoDS_Face& theSecPlane):
227 myAxeOfBisPlane(theAxeOfBisPlane),
228 myDone(Standard_False),
229 myHasSection(Standard_False)
231 myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(),
232 theFaces->LowerCol(), theFaces->UpperCol());
233 myFaces->ChangeArray2() = theFaces->Array2();
235 mySecPln = theSecPlane;
238 // ===========================================================================================
239 // function: SetSpine
241 // ===========================================================================================
242 void BRepFill_TrimShellCorner::SetSpine(const TopoDS_Wire& theSpine)
247 // ===========================================================================================
248 // function: AddBounds
250 // ===========================================================================================
251 void BRepFill_TrimShellCorner::AddBounds(const Handle(TopTools_HArray2OfShape)& theBounds)
253 myBounds = new TopTools_HArray2OfShape(theBounds->LowerRow(), theBounds->UpperRow(),
254 theBounds->LowerCol(), theBounds->UpperCol());
255 myBounds->ChangeArray2() = theBounds->Array2();
258 // ===========================================================================================
259 // function: AddUEdges
261 // ===========================================================================================
262 void BRepFill_TrimShellCorner::AddUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges)
264 myUEdges = new TopTools_HArray2OfShape(theUEdges->LowerRow(), theUEdges->UpperRow(),
265 theUEdges->LowerCol(), theUEdges->UpperCol());
266 myUEdges->ChangeArray2() = theUEdges->Array2();
269 // ===========================================================================================
272 // ===========================================================================================
273 void BRepFill_TrimShellCorner::Perform()
275 Standard_Integer anIndex1, anIndex2, nF1, nF2, i, j, aNbP, aNbC;
276 Standard_Boolean bhassec;
278 myDone = Standard_False;
281 if(myFaces->RowLength() != 2)
283 Standard_Integer ii = 0, jj = 0;
286 for(jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++) {
288 aBB.MakeShell(aShell);
290 for(ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
291 aBB.Add(aShell, myFaces->Value(ii, jj));
294 if(jj == myFaces->LowerCol()) {
302 BOPAlgo_PaveFiller aPF;
303 BOPCol_ListOfShape aLS;
304 aLS.Append(myShape1);
305 aLS.Append(myShape2);
306 aPF.SetArguments(aLS);
309 if (aPF.ErrorStatus()) {
313 const BOPDS_PDS& theDS = aPF.PDS();
315 BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
316 Standard_Integer aNbFFs = aFFs.Extent();
318 if(!SplitUEdges(myUEdges, theDS, myHistMap)) {
322 for(ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
323 TopoDS_Shape aF1 = myFaces->Value(ii, myFaces->LowerCol());
324 TopoDS_Shape aF2 = myFaces->Value(ii, myFaces->UpperCol());
326 anIndex1 = theDS->Index(aF1);
327 anIndex2 = theDS->Index(aF2);
329 if((anIndex1 == -1) || (anIndex2 == -1))
332 for (i=0; i < aNbFFs; ++i) {
333 BOPDS_InterfFF& aFFi = aFFs(i);
334 aFFi.Indices(nF1, nF2);
336 BOPDS_VectorOfPoint& aVP=aFFi.ChangePoints();
338 BOPDS_VectorOfCurve& aVC=aFFi.ChangeCurves();
340 if (!aNbP && !aNbC) {
341 if (!theDS->HasInterfSubShapes(nF1, nF2)) {
346 if((nF1 == anIndex1) && (nF2 == anIndex2)) {
347 const BOPDS_VectorOfCurve& aVC = aFFi.Curves();
348 bhassec = Standard_False;
350 for (j = 0; j < aNbC; ++j) {
351 const BOPDS_Curve& aBCurve = aVC(j);
352 const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
354 if (aSectEdges.Extent()) {
355 bhassec = Standard_True;
361 if(!MakeFacesNonSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, myHistMap)) {
367 if(!MakeFacesSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2,
368 i, myAxeOfBisPlane, myHistMap)) {
377 myDone = Standard_True;
380 // ===========================================================================================
383 // ===========================================================================================
384 Standard_Boolean BRepFill_TrimShellCorner::IsDone() const
389 // ===========================================================================================
390 // function: HasSection
392 // ===========================================================================================
393 Standard_Boolean BRepFill_TrimShellCorner::HasSection() const
398 // ===========================================================================================
399 // function: Modified
401 // ===========================================================================================
402 void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape& theShape,
403 TopTools_ListOfShape& theModified)
407 if(myHistMap.IsBound(theShape)) {
408 theModified = myHistMap.Find(theShape);
412 // ----------------------------------------------------------------------------------------------------
413 // static function: MakeFacesNonSec
415 // ----------------------------------------------------------------------------------------------------
416 Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex,
417 const Handle(TopTools_HArray2OfShape)& theUEdges,
418 const Handle(TopTools_HArray2OfShape)& theBounds,
419 const BOPDS_PDS& theDS,
420 const Standard_Integer theFaceIndex1,
421 const Standard_Integer theFaceIndex2,
422 TopTools_DataMapOfShapeListOfShape& theHistMap)
424 Standard_Boolean bHasNewEdge = Standard_False;
425 TopoDS_Edge aNewEdge;
428 const TopoDS_Shape& aE1 = theBounds->Value(theIndex, 1);
429 const TopoDS_Shape& aE2 = theBounds->Value(theIndex, 2);
431 // search common vertex between bounds. begin
432 TopoDS_Vertex aCommonVertex;
433 Standard_Integer anIndex1 = theDS->Index(aE1);
434 Standard_Integer anIndex2 = theDS->Index(aE2);
435 Standard_Real apar1 = 0., apar2 = 0.;
437 Standard_Boolean bvertexfound =
438 FindCommonVertex(theDS, anIndex1, anIndex2, aCommonVertex, apar1, apar2);
439 // search common vertex between bounds. end
441 Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
443 // search common vertices between uedges. begin
444 TopTools_ListOfShape aCommonVertices;
445 Standard_Boolean acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
446 Standard_Integer ueit = 0, eindex = 0;
448 for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
449 const TopoDS_Shape& aShape1 = theUEdges->Value(eindex, theUEdges->LowerCol());
450 const TopoDS_Shape& aShape2 = theUEdges->Value(eindex, theUEdges->UpperCol());
451 TopoDS_Edge aUE1 = TopoDS::Edge(aShape1);
452 TopoDS_Edge aUE2 = TopoDS::Edge(aShape2);
454 if(theHistMap.IsBound(aShape1)) {
455 const TopTools_ListOfShape& lst = theHistMap.Find(aShape1);
458 aUE1 = TopoDS::Edge(lst.First());
461 if(theHistMap.IsBound(aShape2)) {
462 const TopTools_ListOfShape& lst = theHistMap.Find(aShape2);
465 aUE2 = TopoDS::Edge(lst.First());
468 if(!aShape1.IsSame(aUE1))
469 aSubstitutor->Replace(aShape1.Oriented(TopAbs_FORWARD), aUE1.Oriented(TopAbs_FORWARD));
471 if(!aShape2.IsSame(aUE2))
472 aSubstitutor->Replace(aShape2.Oriented(TopAbs_FORWARD), aUE2.Oriented(TopAbs_FORWARD));
474 TopoDS_Vertex V1 = TopExp::LastVertex(aUE1);
475 TopoDS_Vertex V2 = TopExp::FirstVertex(aUE2);
478 acommonflag = (acommonflag == 0) ? ueit : 3;
479 aCommonVertices.Append(V1);
482 // search common vertices between uedges. end
485 if(aCommonVertices.Extent() != 1)
486 return Standard_False;
489 aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()), aCommonVertex);
491 aNewEdge = BRepLib_MakeEdge(aCommonVertex, TopoDS::Vertex(aCommonVertices.First()));
493 bHasNewEdge = Standard_True;
496 if(aCommonVertices.Extent() == 2) {
497 aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()),
498 TopoDS::Vertex(aCommonVertices.Last()));
499 bHasNewEdge = Standard_True;
501 Standard_Integer fit = 0;
503 for(fit = 1; fit <= 2; fit++) {
504 TopoDS_Compound aComp;
505 TopTools_MapOfShape aMapV;
506 aBB.MakeCompound(aComp);
508 for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
509 const TopoDS_Shape& aShape = theUEdges->Value(eindex, theUEdges->LowerCol() + fit - 1);
510 TopoDS_Shape aUE = aShape;
512 if(theHistMap.IsBound(aShape)) {
513 const TopTools_ListOfShape& lst = theHistMap.Find(aShape);
516 aUE = TopoDS::Edge(lst.First());
518 const TopoDS_Shape& aV = (fit == 1) ? TopExp::FirstVertex(TopoDS::Edge(aUE)) : TopExp::LastVertex(TopoDS::Edge(aUE));
523 aBB.Add(aComp, aNewEdge);
525 TopTools_ListOfShape alonevertices;
526 FindFreeVertices(aComp, aMapV, alonevertices);
528 if(!alonevertices.IsEmpty() && (alonevertices.Extent() != 2))
529 return Standard_False;
531 Standard_Integer aFaceIndex = (fit == 1) ? theFaceIndex1 : theFaceIndex2;
532 TopoDS_Shape aFace = theDS->Shape(aFaceIndex);
533 TopAbs_Orientation aFaceOri = aFace.Orientation();
534 TopAbs_Orientation anEdgeOri = TopAbs_FORWARD;
535 aFace.Orientation(TopAbs_FORWARD);
537 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
538 const TopoDS_Shape& aCheckEdge = (fit == 1) ? aE1 : aE2;
540 for(; anExpE.More(); anExpE.Next()) {
541 if(aCheckEdge.IsSame(anExpE.Current()))
542 anEdgeOri = anExpE.Current().Orientation();
546 aNewEdge.Orientation(TopAbs_FORWARD);
549 TopTools_ListOfShape aOrderedList;
551 if(!alonevertices.IsEmpty()) {
552 Standard_Integer anEIndex = (fit == 1) ? anIndex1 : anIndex2;
553 Standard_Boolean bfound1 = Standard_False;
554 Standard_Boolean bfound2 = Standard_False;
555 Standard_Real aparam1 = 0., aparam2 = 0.;
557 BOPDS_ListOfPave aLP;
558 theDS->Paves(anEIndex, aLP);
559 BOPDS_ListIteratorOfListOfPave aIt;
561 for ( ; aIt.More(); aIt.Next()) {
562 const BOPDS_Pave& aPave = aIt.Value();
563 TopoDS_Shape aV = theDS->Shape(aPave.Index());
565 if(aV.IsSame(alonevertices.First())) {
567 aparam1 = aPave.Parameter();
568 bfound1 = Standard_True;
572 if(aV.IsSame(alonevertices.Last())) {
574 aparam2 = aPave.Parameter();
575 bfound2 = Standard_True;
580 if(bfound1 && bfound2) {
581 TopoDS_Edge aNewBoundE;
584 aNewBoundE = TopoDS::Edge(aE1.EmptyCopied());
587 aNewBoundE = TopoDS::Edge(aE2.EmptyCopied());
589 TopoDS_Vertex aV1, aV2;
591 if(aparam1 < aparam2) {
592 aV1 = TopoDS::Vertex(alonevertices.First());
593 aV2 = TopoDS::Vertex(alonevertices.Last());
596 aV1 = TopoDS::Vertex(alonevertices.Last());
597 aV2 = TopoDS::Vertex(alonevertices.First());
598 Standard_Real tmp = aparam1;
602 aV1.Orientation(TopAbs_FORWARD);
603 aV2.Orientation(TopAbs_REVERSED);
604 aBB.Add(aNewBoundE, aV1);
605 aBB.Add(aNewBoundE, aV2);
606 aBB.Range(aNewBoundE, aparam1, aparam2);
607 aNewBoundE.Orientation(TopAbs_FORWARD);
609 aOrderedList.Append(aNewBoundE);
612 TopExp_Explorer anExpV(aNewEdge, TopAbs_VERTEX);
613 Standard_Boolean bfoundv = Standard_False;
615 for(; !bfoundv && anExpV.More(); anExpV.Next()) {
616 if(aV2.IsSame(anExpV.Current()))
617 bfoundv = Standard_True;
621 aOrderedList.Append(aNewEdge);
623 aOrderedList.Prepend(aNewEdge);
627 return Standard_False;
632 aOrderedList.Append(aNewEdge);
636 if(!aOrderedList.IsEmpty()) {
639 TopTools_ListIteratorOfListOfShape anItE(aOrderedList);
641 for(; anItE.More(); anItE.Next()) {
642 aBB.Add(aW, anItE.Value());
645 aSubstitutor->Replace(aE1.Oriented(TopAbs_FORWARD), aW);
647 aSubstitutor->Replace(aE2.Oriented(TopAbs_FORWARD), aW);
650 aSubstitutor->Apply(aFace);
651 TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
652 aNewFace.Orientation(aFaceOri);
653 TopTools_ListOfShape atmpList;
654 atmpList.Append(aNewFace);
655 theHistMap.Bind(aFace, atmpList);
657 anExpE.Init(aFace, TopAbs_EDGE);
659 for(; anExpE.More(); anExpE.Next()) {
660 TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
662 if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
665 if(theHistMap.IsBound(anExpE.Current()))
667 TopTools_ListOfShape aListOfNewEdge;
668 TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
670 for(; anExpE2.More(); anExpE2.Next()) {
671 aListOfNewEdge.Append(anExpE2.Current());
673 theHistMap.Bind(anExpE.Current(), aListOfNewEdge);
677 return Standard_True;
680 // ----------------------------------------------------------------------------------------------------
681 // static function: MakeFacesSec
683 // ----------------------------------------------------------------------------------------------------
684 Standard_Boolean MakeFacesSec(const Standard_Integer theIndex,
685 const Handle(TopTools_HArray2OfShape)& theUEdges,
686 const Handle(TopTools_HArray2OfShape)& theBounds,
687 const BOPDS_PDS& theDS,
688 const Standard_Integer theFaceIndex1,
689 const Standard_Integer theFaceIndex2,
690 const Standard_Integer theSSInterfIndex,
691 const gp_Ax2& AxeOfBisPlane,
692 TopTools_DataMapOfShapeListOfShape& theHistMap)
694 const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
695 const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex);
696 const BOPDS_VectorOfCurve& aBCurves = aFFi.Curves();
698 TopoDS_Compound aSecEdges;
699 TopoDS_Face aSecPlane;
701 if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges))
702 return Standard_False;
704 TopoDS_Shape SecWire;
706 Standard_Boolean IsSingular;
707 Standard_Boolean WireFound = ChooseSection( aSecEdges, AxeOfBisPlane, SecWire, SecPlane, IsSingular );
710 //aSecEdges = SecWire;
711 TopoDS_Compound aComp;
713 BB.MakeCompound(aComp);
714 TopExp_Explorer explo( SecWire, TopAbs_EDGE );
716 for (; explo.More(); explo.Next())
717 BB.Add( aComp, explo.Current() );
721 TopTools_ListOfShape aCommonVertices;
722 // Standard_Boolean acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
723 Standard_Integer fit = 0; //, ueit = 0, eindex = 0, i = 0;
724 Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
726 for(fit = 0; fit < 2; fit++) {
727 Standard_Integer aFaceIndex = (fit == 0) ? theFaceIndex1 : theFaceIndex2;
728 TopoDS_Face aFace = TopoDS::Face(theDS->Shape(aFaceIndex));
729 TopAbs_Orientation aFaceOri = aFace.Orientation();
730 TopoDS_Face aFaceF = aFace;
731 aFaceF.Orientation(TopAbs_FORWARD);
732 TopoDS_Edge aBoundEdge = TopoDS::Edge(theBounds->Value(theIndex, theBounds->LowerCol() +fit));
733 Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge);
737 if(!GetUEdges(theIndex, fit, theUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
738 return Standard_False;
740 TopoDS_Edge aUE1old = aUE1;
741 TopoDS_Edge aUE2old = aUE2;
743 if(theHistMap.IsBound(aUE1)) {
744 const TopTools_ListOfShape& lst = theHistMap.Find(aUE1);
747 const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation());
749 if(!aUE1.IsSame(anEdge))
750 aSubstitutor->Replace(aUE1.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
751 aUE1 = TopoDS::Edge(anEdge);
755 if(theHistMap.IsBound(aUE2)) {
756 const TopTools_ListOfShape& lst = theHistMap.Find(aUE2);
759 const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation());
761 if(!aUE2.IsSame(anEdge))
762 aSubstitutor->Replace(aUE2.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
763 aUE2 = TopoDS::Edge(anEdge);
766 TopoDS_Vertex aPrevVertex, aNextVertex;
767 TopoDS_Compound aCompOfSecEdges = aSecEdges;
768 TopTools_ListOfShape aListOfWireEdges;
771 Standard_Boolean isPave1OnUEdge = Standard_True;
773 if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex,
774 theDS, theHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) {
775 TopTools_ListOfShape aSecondListOfEdges;
776 Standard_Boolean bisSectionFound = Standard_False;
778 if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge,
779 aBoundEdgeIndex, theDS, theHistMap, aSecondListOfEdges, bisSectionFound)) {
780 return Standard_False;
783 if(!bisSectionFound && aListOfWireEdges.IsEmpty()) {
784 return Standard_False;
786 aListOfWireEdges.Append(aSecondListOfEdges);
789 return Standard_False;
792 if(!aListOfWireEdges.IsEmpty()) {
795 TopTools_ListIteratorOfListOfShape aEIt(aListOfWireEdges);
797 for(; aEIt.More(); aEIt.Next()) {
798 if(!aBoundEdge.IsSame(aEIt.Value()))
799 aBB.Add(aW, aEIt.Value());
801 aSubstitutor->Replace(aBoundEdge.Oriented(TopAbs_FORWARD), aW);
804 aSubstitutor->Apply(aFace);
805 TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
806 aNewFace.Orientation(aFaceOri);
807 TopTools_ListOfShape atmpList;
808 atmpList.Append(aNewFace);
809 theHistMap.Bind(aFace, atmpList);
811 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
813 for(; anExpE.More(); anExpE.Next()) {
814 TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
816 if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
819 if(theHistMap.IsBound(anExpE.Current()))
821 TopTools_ListOfShape aListOfNewEdge;
822 TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
824 for(; anExpE2.More(); anExpE2.Next()) {
825 aListOfNewEdge.Append(anExpE2.Current());
827 theHistMap.Bind(anExpE.Current(), aListOfNewEdge);
830 return Standard_True;
834 // ------------------------------------------------------------------------------------------
835 // static function: SplitUEdges
837 // ------------------------------------------------------------------------------------------
838 Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
839 const BOPDS_PDS& theDS,
840 TopTools_DataMapOfShapeListOfShape& theHistMap) {
842 const BOPDS_VectorOfInterfVV& aVVs = theDS->InterfVV();
845 Standard_Integer ueit = 0, upRow, lowCol, upCol;
846 TopTools_Array2OfShape aNewVertices(1,2,1,2);
848 upRow = theUEdges->UpperRow();
849 lowCol = theUEdges->LowerCol();
850 upCol = theUEdges->UpperCol();
852 for(ueit = theUEdges->LowerRow(); ueit <= upRow; ueit++) {
853 const TopoDS_Shape& aE1 = theUEdges->Value(ueit, lowCol);
854 const TopoDS_Shape& aE2 = theUEdges->Value(ueit, upCol);
856 if(theHistMap.IsBound(aE1) || theHistMap.IsBound(aE2))
859 Standard_Integer anEIndex1 = theDS->Index(aE1);
860 Standard_Integer anEIndex2 = theDS->Index(aE2);
862 TopoDS_Vertex aCommonVertex;
863 Standard_Real apar1 = 0., apar2 = 0.;
864 Standard_Boolean bvertexfound =
865 FindCommonVertex(theDS, anEIndex1, anEIndex2, aCommonVertex, apar1, apar2);
868 TopoDS_Vertex V1 = TopExp::LastVertex(TopoDS::Edge(aE1));
869 TopoDS_Vertex V2 = TopExp::FirstVertex(TopoDS::Edge(aE2));
870 Standard_Integer vindex1 = theDS->Index(V1);
871 Standard_Integer vindex2 = theDS->Index(V2);
872 Standard_Integer vvit = 0;
873 Standard_Integer aNbVVs = aVVs.Extent();
875 for(vvit = 0; !bvertexfound && (vvit < aNbVVs); vvit++) {
876 //const BOPTools_VVInterference& aVV = aVVs(vvit);
877 const BOPDS_InterfVV& aVV = aVVs(vvit);
879 if(((vindex1 == aVV.Index1()) && (vindex2 = aVV.Index2())) ||
880 ((vindex1 == aVV.Index2()) && (vindex2 = aVV.Index1()))) {
882 if(!aVV.HasIndexNew()) {
885 aCommonVertex = TopoDS::Vertex(theDS->Shape(aVV.IndexNew()));
886 bvertexfound = Standard_True;
887 apar1 = BRep_Tool::Parameter(V1, TopoDS::Edge(aE1));
888 apar2 = BRep_Tool::Parameter(V2, TopoDS::Edge(aE2));
894 TopoDS_Vertex aV1, aV2;
895 Standard_Real f = 0., l = 0.;
897 TopoDS_Edge aNewE1 = TopoDS::Edge(aE1.EmptyCopied());
898 TopExp::Vertices(TopoDS::Edge(aE1), aV1, aV2);
899 aNewE1.Orientation(TopAbs_FORWARD);
900 aV1.Orientation(TopAbs_FORWARD);
901 aBB.Add(aNewE1, aV1);
902 aCommonVertex.Orientation(TopAbs_REVERSED);
903 aBB.Add(aNewE1, aCommonVertex);
904 BRep_Tool::Range(TopoDS::Edge(aE1), f, l);
905 aBB.Range(aNewE1, f, apar1);
908 TopoDS_Edge aNewE2 = TopoDS::Edge(aE2.EmptyCopied());
909 TopExp::Vertices(TopoDS::Edge(aE2), aV1, aV2);
910 aNewE2.Orientation(TopAbs_FORWARD);
911 aCommonVertex.Orientation(TopAbs_FORWARD);
912 aBB.Add(aNewE2, aCommonVertex);
913 aBB.Add(aNewE2, aV2);
914 BRep_Tool::Range(TopoDS::Edge(aE2), f, l);
915 aBB.Range(aNewE2, apar2, l);
917 TopTools_ListOfShape lst;
919 theHistMap.Bind(aE1, lst);
922 theHistMap.Bind(aE2, lst);
925 return Standard_True;
928 // ------------------------------------------------------------------------------------------
929 // static function: FindFreeVertices
931 // ------------------------------------------------------------------------------------------
932 void FindFreeVertices(const TopoDS_Shape& theShape,
933 const TopTools_MapOfShape& theVerticesToAvoid,
934 TopTools_ListOfShape& theListOfVertex) {
936 theListOfVertex.Clear();
937 TopTools_IndexedDataMapOfShapeListOfShape aMap;
938 TopExp::MapShapesAndAncestors(theShape, TopAbs_VERTEX, TopAbs_EDGE, aMap);
939 Standard_Integer i = 0;
941 for(i = 1; i <= aMap.Extent(); i++) {
942 const TopoDS_Shape& aKey = aMap.FindKey(i);
944 if(theVerticesToAvoid.Contains(aKey))
946 const TopTools_ListOfShape& aList = aMap.FindFromIndex(i);
948 if(aList.Extent() < 2) {
949 theListOfVertex.Append(aKey);
954 // ------------------------------------------------------------------------------------------
955 // static function: FindCommonVertex
957 // ------------------------------------------------------------------------------------------
958 Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
959 const Standard_Integer theEIndex1,
960 const Standard_Integer theEIndex2,
961 TopoDS_Vertex& theCommonVertex,
962 Standard_Real& theParamOnE1,
963 Standard_Real& theParamOnE2) {
965 const BOPDS_VectorOfInterfEE& aEEs = theDS->InterfEE();
967 Standard_Boolean bvertexfound = Standard_False;
968 TopoDS_Vertex aCommonVertex;
969 Standard_Integer eeit = 0;
971 Standard_Integer aNbEEs;
972 aNbEEs = aEEs.Extent();
973 for(eeit = 0; eeit < aNbEEs; ++eeit) {
974 const BOPDS_InterfEE& aEE = aEEs(eeit);
976 if((theEIndex1 == aEE.Index1() && theEIndex2 == aEE.Index2()) ||
977 (theEIndex1 == aEE.Index2() && theEIndex2 == aEE.Index1())) {
979 if(!aEE.HasIndexNew())
982 IntTools_CommonPrt aCP = aEE.CommonPart();
983 if(aCP.Type() == TopAbs_VERTEX) {
984 theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew());
985 if (theEIndex1 == aEE.Index1()) {
986 BOPInt_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2);
988 BOPInt_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1);
991 bvertexfound = Standard_True;
999 // ----------------------------------------------------------------------------------------------------
1000 // static function: GetUEdges
1002 // ----------------------------------------------------------------------------------------------------
1003 Standard_Boolean GetUEdges(const Standard_Integer theIndex,
1004 const Standard_Integer theRank,
1005 const Handle(TopTools_HArray2OfShape)& theUEdges,
1006 const TopoDS_Edge& theBoundEdge,
1007 const TopoDS_Face& theFace,
1008 TopoDS_Edge& theFirstUEdge,
1009 TopoDS_Edge& theSecondUEdge) {
1010 const TopoDS_Shape& aUE1 = theUEdges->Value(theIndex, theUEdges->LowerCol() + theRank);
1011 const TopoDS_Shape& aUE2 = theUEdges->Value(theIndex + 1, theUEdges->LowerCol() + theRank);
1013 TopoDS_Face aFace = theFace;
1014 aFace.Orientation(TopAbs_FORWARD);
1016 TopExp_Explorer anExp(aFace, TopAbs_EDGE);
1018 for(; anExp.More(); anExp.Next()) {
1019 if(E1.IsNull() && aUE1.IsSame(anExp.Current())) {
1020 E1 = TopoDS::Edge(anExp.Current());
1022 else if(E2.IsNull() && aUE2.IsSame(anExp.Current())) {
1023 E2 = TopoDS::Edge(anExp.Current());
1027 if(E1.IsNull() || E2.IsNull())
1028 return Standard_False;
1031 Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1, aFace, f, l);
1034 return Standard_False;
1035 gp_Pnt2d PU1 = (theRank == 0) ? C1->Value(l) : C1->Value(f);
1036 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFace, f, l);
1039 return Standard_False;
1040 BRep_Tool::Range(theBoundEdge, f, l);
1041 gp_Pnt2d pf = C2->Value(f);
1042 TopoDS_Vertex aV = (theRank == 0) ? TopExp::LastVertex(E1) : TopExp::FirstVertex(E1);
1043 Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
1044 BRepAdaptor_Surface aBAS(aFace, Standard_False);
1046 if(pf.Distance(PU1) > aBAS.UResolution(aTolerance)) {
1047 TopoDS_Edge atmpE = E1;
1052 theSecondUEdge = E2;
1053 return Standard_True;
1056 // ----------------------------------------------------------------------------------------------------
1057 // static function: FillGap
1059 // ----------------------------------------------------------------------------------------------------
1060 Standard_Boolean FillGap(const TopoDS_Vertex& theFirstVertex,
1061 const TopoDS_Vertex& theLastVertex,
1062 const gp_Pnt2d& theFirstPoint,
1063 const gp_Pnt2d& theLastPoint,
1064 const TopoDS_Face& theFace,
1065 const TopoDS_Compound& theSectionEdges,
1066 TopTools_ListOfShape& theOrderedList) {
1068 TopTools_IndexedDataMapOfShapeListOfShape aMap;
1069 TopExp::MapShapesAndAncestors(theSectionEdges, TopAbs_VERTEX, TopAbs_EDGE, aMap);
1071 if(aMap.IsEmpty()) {
1072 return Standard_False;
1075 if(!aMap.Contains(theFirstVertex) ||
1076 !aMap.Contains(theLastVertex)) {
1077 return Standard_False;
1079 TopTools_ListOfShape aListOfEdge;
1080 // Standard_Integer i = 0;
1081 // TopoDS_Vertex aCurVertex = theFirstVertex;
1082 TopTools_MapOfShape aMapToAvoid;
1084 if(FindNextEdge(theFirstVertex, theLastVertex, aMap, aMapToAvoid, aListOfEdge)) {
1085 if(!aListOfEdge.IsEmpty()) {
1086 return CheckAndOrientEdges(aListOfEdge, theFirstPoint, theLastPoint, theFace, theOrderedList);
1089 return Standard_False;
1092 // ----------------------------------------------------------------------------------------------------
1093 // static function: FindNextEdge
1095 // ----------------------------------------------------------------------------------------------------
1096 Standard_Boolean FindNextEdge(const TopoDS_Vertex& theFirstVertex,
1097 const TopoDS_Vertex& theLastVertex,
1098 const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
1099 const TopTools_MapOfShape& theMapToAvoid,
1100 TopTools_ListOfShape& theOrderedList) {
1101 TopoDS_Vertex aCurVertex = theFirstVertex;
1102 TopTools_MapOfShape aMapToAvoid;
1103 aMapToAvoid = theMapToAvoid;
1104 TopTools_ListOfShape aListOfEdge;
1105 Standard_Integer i = 0;
1107 for(i = 1; i <= theMapVE.Extent(); i++) {
1108 if(!theMapVE.Contains(aCurVertex))
1110 const TopTools_ListOfShape& lste = theMapVE.FindFromKey(aCurVertex);
1111 Standard_Boolean befound = Standard_False;
1113 TopTools_ListIteratorOfListOfShape anIt(lste);
1115 for(; anIt.More(); anIt.Next()) {
1116 TopoDS_Shape anEdge = anIt.Value();
1117 TopoDS_Vertex aSaveCurVertex = aCurVertex;
1119 if(!aMapToAvoid.Contains(anEdge)) {
1120 TopoDS_Vertex V1, V2;
1121 TopExp::Vertices(TopoDS::Edge(anEdge), V1, V2);
1123 if(!aCurVertex.IsSame(V1)) {
1126 else if(!aCurVertex.IsSame(V2)) {
1129 aMapToAvoid.Add(anEdge);
1130 befound = Standard_True;
1131 aListOfEdge.Append(anEdge);
1133 if(!aCurVertex.IsSame(theLastVertex)) {
1134 TopTools_ListOfShape aListtmp;
1136 if(!FindNextEdge(aCurVertex, theLastVertex, theMapVE, aMapToAvoid, aListtmp)) {
1137 aListOfEdge.Clear();
1138 aCurVertex = aSaveCurVertex;
1142 aListOfEdge.Append(aListtmp);
1143 theOrderedList.Append(aListOfEdge);
1144 return Standard_True;
1151 if(aCurVertex.IsSame(theLastVertex))
1155 return Standard_False;
1159 if(aCurVertex.IsSame(theLastVertex)) {
1160 theOrderedList.Append(aListOfEdge);
1161 return Standard_True;
1163 return Standard_False;
1166 // ----------------------------------------------------------------------------------------------------
1167 // static function: CheckAndOrientEdges
1169 // ----------------------------------------------------------------------------------------------------
1170 Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList,
1171 const gp_Pnt2d& theFirstPoint,
1172 const gp_Pnt2d& theLastPoint,
1173 const TopoDS_Face& theFace,
1174 TopTools_ListOfShape& theOrientedList) {
1175 TopTools_ListIteratorOfListOfShape anIt(theOrderedList);
1178 return Standard_True;
1181 TopoDS_Edge aEPrev = TopoDS::Edge(anIt.Value());
1184 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(aEPrev, theFace, f, l);
1185 TopoDS_Vertex Vf, Vl;
1186 TopExp::Vertices(aEPrev, Vf, Vl);
1187 BRepAdaptor_Surface aBAS(theFace, Standard_False);
1189 Standard_Real aTolerance1 = (Vf.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vf);
1190 Standard_Real aTolerance2 = (Vl.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vl);
1191 Standard_Real utol = aBAS.UResolution(aTolerance1);
1192 Standard_Real vtol = aBAS.VResolution(aTolerance1);
1193 aTolerance1 = (utol > vtol) ? utol : vtol;
1194 utol = aBAS.UResolution(aTolerance2);
1195 vtol = aBAS.VResolution(aTolerance2);
1196 aTolerance2 = (utol > vtol) ? utol : vtol;
1198 gp_Pnt2d ap = aCurve->Value(f);
1199 Standard_Boolean bFirstFound = Standard_False;
1200 Standard_Boolean bLastFound = Standard_False;
1201 Standard_Boolean bforward = Standard_True;
1203 if(ap.Distance(theFirstPoint) < aTolerance1) {
1204 bforward = Standard_True;
1205 if(theOrientedList.IsEmpty())
1206 theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
1207 bFirstFound = Standard_True;
1209 else if(ap.Distance(theLastPoint) < aTolerance1) {
1210 bforward = Standard_False;
1211 if(theOrientedList.IsEmpty())
1212 theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
1213 bLastFound = Standard_True;
1215 ap = aCurve->Value(l);
1217 if(ap.Distance(theLastPoint) < aTolerance2) {
1218 bforward = Standard_True;
1220 if(theOrientedList.IsEmpty())
1221 theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
1222 bLastFound = Standard_True;
1224 else if(ap.Distance(theFirstPoint) < aTolerance2) {
1225 bforward = Standard_False;
1227 if(theOrientedList.IsEmpty())
1228 theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
1229 bFirstFound = Standard_True;
1232 for(; anIt.More(); anIt.Next()) {
1233 const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
1234 TopoDS_Vertex aV11, aV12;
1235 TopExp::Vertices(aEPrev, aV11, aV12);
1236 TopoDS_Vertex aV21, aV22;
1237 TopExp::Vertices(aE, aV21, aV22);
1238 TopAbs_Orientation anOri = TopAbs_FORWARD;
1240 if(aV12.IsSame(aV21) || aV11.IsSame(aV22)) {
1241 anOri = (bforward) ? TopAbs_FORWARD : TopAbs_REVERSED;
1244 anOri = (bforward) ? TopAbs_REVERSED : TopAbs_FORWARD;
1246 theOrientedList.Append(aE.Oriented(anOri));
1248 aTolerance1 = (aV21.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV21);
1249 aTolerance2 = (aV22.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV22);
1250 utol = aBAS.UResolution(aTolerance1);
1251 vtol = aBAS.VResolution(aTolerance1);
1252 aTolerance1 = (utol > vtol) ? utol : vtol;
1253 utol = aBAS.UResolution(aTolerance2);
1254 vtol = aBAS.VResolution(aTolerance2);
1255 aTolerance2 = (utol > vtol) ? utol : vtol;
1256 aCurve = BRep_Tool::CurveOnSurface(aE, theFace, f, l);
1257 ap = aCurve->Value(f);
1259 if(ap.Distance(theFirstPoint) < aTolerance1) {
1260 bFirstFound = Standard_True;
1262 else if(ap.Distance(theLastPoint) < aTolerance1) {
1263 bLastFound = Standard_True;
1265 ap = aCurve->Value(l);
1267 if(ap.Distance(theFirstPoint) < aTolerance2) {
1268 bFirstFound = Standard_True;
1270 else if(ap.Distance(theLastPoint) < aTolerance2) {
1271 bLastFound = Standard_True;
1275 if(!bFirstFound || !bLastFound)
1276 return Standard_False;
1277 return Standard_True;
1280 // ----------------------------------------------------------------------------------------------------
1281 // static function: FindVertex
1283 // ----------------------------------------------------------------------------------------------------
1284 Standard_Boolean FindVertex(const TopoDS_Edge& theEdge,
1285 const Standard_Integer theRank,
1286 const BOPDS_PDS& theDS,
1287 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1288 TopoDS_Vertex& theVertex,
1289 BOPDS_Pave& thePave) {
1291 if(!theHistMap.IsBound(theEdge))
1292 return Standard_False;
1294 const TopTools_ListOfShape& lst = theHistMap.Find(theEdge);
1297 return Standard_False;
1299 TopoDS_Edge aNewEdge = TopoDS::Edge(lst.First());
1301 BRep_Tool::Range(aNewEdge, f, l);
1304 thePave.SetParameter(l);
1305 theVertex = TopExp::LastVertex(aNewEdge);
1308 thePave.SetParameter(f);
1309 theVertex = TopExp::FirstVertex(aNewEdge);
1311 Standard_Integer anIndex = theDS->Index(theVertex);
1312 if (anIndex == -1) {
1313 Standard_Integer i, i1, i2;
1314 i1=theDS->NbSourceShapes();
1315 i2=theDS->NbShapes();
1316 for (i=i1; i<i2; ++i) {
1317 const TopoDS_Shape& aSx=theDS->Shape(i);
1318 if(aSx.IsSame(theVertex)) {
1325 thePave.SetIndex(anIndex);
1327 return Standard_True;
1330 // ----------------------------------------------------------------------------------------------------
1331 // static function: FindNextVertex
1333 // ----------------------------------------------------------------------------------------------------
1334 Standard_Boolean FindNextVertex(const Standard_Integer theEdgeIndex,
1335 const BOPDS_Pave& thePrevPave,
1336 const BOPDS_PDS& theDS,
1337 TopoDS_Vertex& theNextVertex,
1338 BOPDS_Pave& thePave) {
1340 Standard_Boolean bTakePave, bFound;
1341 BOPDS_Pave aTmpPave;
1342 BOPDS_ListIteratorOfListOfPave aItP;
1344 BOPDS_Pave anullpave;
1345 bFound = Standard_False;
1346 bTakePave = thePrevPave.IsEqual(anullpave);
1348 BOPDS_ListOfPave aLP;
1349 theDS->Paves(theEdgeIndex, aLP);
1350 aItP.Initialize(aLP);
1351 for (; aItP.More(); aItP.Next()) {
1352 aTmpPave = aItP.Value();
1355 if (theDS->IsNewShape(aTmpPave.Index())) {
1356 theNextVertex = *(TopoDS_Vertex*)&theDS->Shape(aTmpPave.Index());
1358 bFound = Standard_True;
1363 else if (aTmpPave.IsEqual(thePrevPave)) {
1364 bTakePave = Standard_True;
1371 // ----------------------------------------------------------------------------------------------------
1372 // static function: GetPave
1374 // ----------------------------------------------------------------------------------------------------
1375 Standard_Boolean GetPave(const Standard_Integer theEdgeIndex,
1376 const Standard_Boolean isFirst,
1377 const BOPDS_PDS& theDS,
1378 BOPDS_Pave& thePave) {
1380 Handle(BOPDS_PaveBlock) aPB;
1381 BOPDS_ListOfPave aLP;
1383 theDS->Paves(theEdgeIndex, aLP);
1384 if (!aLP.Extent()) {
1385 return Standard_False;
1389 thePave = aLP.First();
1392 thePave = aLP.Last();
1395 return Standard_True;
1398 // ----------------------------------------------------------------------------------------------------
1399 // static function: FindFromUEdge
1401 // ----------------------------------------------------------------------------------------------------
1402 Standard_Boolean FindFromUEdge(const TopoDS_Edge& theUE1Old,
1403 const TopoDS_Edge& theUE2Old,
1404 const TopoDS_Edge& theUE1New,
1405 const TopoDS_Edge& theUE2New,
1406 const TopoDS_Face& theFace,
1407 const TopoDS_Compound& theSecEdges,
1408 const Standard_Integer theRank,
1409 const TopoDS_Edge& theBoundEdge,
1410 const Standard_Integer theBoundEdgeIndex,
1411 const BOPDS_PDS& theDS,
1412 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1413 TopoDS_Compound& theSecEdgesNew,
1414 TopTools_ListOfShape& theListOfWireEdges,
1415 BOPDS_Pave& theFoundPave,
1416 Standard_Boolean& isOnUEdge) {
1417 theFoundPave.SetIndex(0);
1418 theFoundPave.SetParameter(0.);
1419 isOnUEdge = Standard_True;
1421 TopoDS_Face aFaceF = theFace;
1422 aFaceF.Orientation(TopAbs_FORWARD);
1423 TopoDS_Vertex aPrevVertex, aNextVertex;
1424 TopoDS_Compound aCompOfSecEdges = theSecEdges;
1425 TopTools_ListOfShape aListOfWireEdges;
1426 // BRep_Builder aBB;
1428 BOPDS_Pave aPave1, aPave2;
1429 Standard_Real f = 0., l = 0.;
1431 TopoDS_Vertex aFirstV, aLastV;
1432 BOPDS_Pave atmpPave;
1434 if(!FindVertex(theUE1Old, theRank, theDS, theHistMap, aPrevVertex, atmpPave)) {
1435 return Standard_True;
1438 if(aPrevVertex.IsNull()) {
1439 return Standard_False;
1442 aFirstV = aPrevVertex;
1443 Standard_Boolean bSecFound = Standard_False;
1444 Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1New, aFaceF, f, l);
1445 p1 = (theRank == 0) ? aC1->Value(l) : aC1->Value(f);
1446 BOPDS_Pave afoundpave;
1447 BOPDS_ListOfPave aLP;
1448 theDS->Paves(theBoundEdgeIndex, aLP);
1449 Standard_Integer nbpave = aLP.Extent();
1450 Standard_Integer pit = 0;
1452 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1453 aLastV = aNextVertex;
1454 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
1455 p2 = aC2->Value(aPave2.Parameter());
1456 TopTools_ListOfShape aOrderedList;
1458 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1459 // remove found edges...
1460 TopoDS_Compound aComp;
1461 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1462 aCompOfSecEdges = aComp;
1463 aListOfWireEdges.Append(aOrderedList);
1464 afoundpave = aPave2;
1465 isOnUEdge = Standard_False;
1466 bSecFound = Standard_True;
1469 aPrevVertex = aNextVertex;
1474 if(!bSecFound && FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1475 aLastV = aNextVertex;
1476 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theUE2New, aFaceF, f, l);
1477 p2 = aC2->Value(aPave2.Parameter());
1478 TopTools_ListOfShape aOrderedList;
1480 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1481 // remove found edges...
1482 TopoDS_Compound aComp;
1484 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1485 aCompOfSecEdges = aComp;
1486 aListOfWireEdges.Append(aOrderedList);
1487 afoundpave = aPave2;
1488 bSecFound = Standard_True;
1489 isOnUEdge = Standard_True;
1494 theFoundPave = afoundpave;
1495 theListOfWireEdges = aListOfWireEdges;
1496 theSecEdgesNew = aCompOfSecEdges;
1498 return Standard_True;
1502 // ----------------------------------------------------------------------------------------------------
1503 // static function: FindFromVEdge
1505 // ----------------------------------------------------------------------------------------------------
1506 Standard_Boolean FindFromVEdge(const BOPDS_Pave& thePrevPave,
1507 const Standard_Boolean& isOnUEdge,
1508 const TopoDS_Edge& theUE1Old,
1509 const TopoDS_Edge& theUE2Old,
1510 const TopoDS_Face& theFace,
1511 const TopoDS_Compound& theSecEdges,
1512 const Standard_Integer theRank,
1513 const TopoDS_Edge& theBoundEdge,
1514 const Standard_Integer theBoundEdgeIndex,
1515 const BOPDS_PDS& theDS,
1516 const TopTools_DataMapOfShapeListOfShape& theHistMap,
1517 TopTools_ListOfShape& theListOfWireEdges,
1518 Standard_Boolean& isSectionFound) {
1520 theListOfWireEdges.Clear();
1521 isSectionFound = Standard_False;
1523 TopoDS_Face aFaceF = theFace;
1524 aFaceF.Orientation(TopAbs_FORWARD);
1525 TopoDS_Vertex aPrevVertex, aNextVertex;
1526 TopoDS_Compound aCompOfSecEdges = theSecEdges;
1527 TopTools_ListOfShape aListOfWireEdges;
1528 // BRep_Builder aBB;
1530 BOPDS_Pave aPave1, aPave2;
1533 TopoDS_Vertex atmpVertex;
1534 BOPDS_Pave aPaveOfE2;
1536 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, atmpVertex, aPaveOfE2)) {
1537 if(thePrevPave.IsEqual(aPaveOfE2))
1538 return Standard_True;
1542 Standard_Real f = 0., l = 0.;
1543 gp_Pnt2d p1(0., 0.), p2(0., 0.);
1544 TopoDS_Vertex aFirstV, aLastV;
1545 Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1Old, aFaceF, f, l);
1546 Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
1547 Standard_Boolean bSecFound = Standard_False;
1549 aPave1 = thePrevPave;
1552 BOPDS_Pave atmpPave;
1554 if(!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave)) {
1555 return Standard_False;
1559 p1 = aC2->Value(aPave1.Parameter());
1560 aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
1562 BOPDS_ListOfPave aLP;
1563 theDS->Paves(theBoundEdgeIndex, aLP);
1564 Standard_Integer nbpave = aLP.Extent();
1565 Standard_Integer pit = 0;
1566 TopTools_Array1OfListOfShape anArrayOfListOfSec(1, nbpave);
1568 // by pairs non continuously. begin
1569 Standard_Integer k = 0;
1570 BOPDS_Pave aFirstPave = aPave1;
1571 TopoDS_Vertex aFirstVertex = aPrevVertex;
1572 gp_Pnt2d apfirst = p1;
1573 BOPDS_ListOfPave aFirstPaves, aLastPaves;
1574 TColStd_ListOfInteger aListOfFlags;
1575 Standard_Integer apaircounter = 1;
1577 for(k = 0; k < nbpave; k++) {
1578 aPave1 = aFirstPave;
1580 aPrevVertex = aFirstVertex;
1581 Standard_Boolean bfound = Standard_False;
1584 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1585 aFirstV = aPrevVertex;
1586 aLastV = aNextVertex;
1587 p2 = aC2->Value(aPave2.Parameter());
1589 TopTools_ListOfShape aOrderedList;
1591 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1592 TopoDS_Compound aComp;
1593 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1594 aCompOfSecEdges = aComp;
1596 anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
1597 aFirstPaves.Append(aFirstPave);
1598 aLastPaves.Append(aPave2);
1599 aListOfFlags.Append(1);
1600 aFirstPave = aPave2;
1601 aFirstVertex = aNextVertex;
1603 aPrevVertex = aNextVertex;
1604 bSecFound = Standard_True;
1605 bfound = Standard_True;
1611 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1612 aFirstV = aPrevVertex;
1613 aLastV = aNextVertex;
1614 Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1615 p2 = aC3->Value(aPave2.Parameter());
1617 TopTools_ListOfShape aOrderedList;
1619 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1620 TopoDS_Compound aComp;
1621 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1622 aCompOfSecEdges = aComp;
1623 anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
1624 aFirstPaves.Append(aFirstPave);
1625 aLastPaves.Append(aPave2);
1626 aListOfFlags.Append(0);
1627 bSecFound = Standard_True;
1633 if(!FindNextVertex(theBoundEdgeIndex, aFirstPave, theDS, aNextVertex, aPave2)) {
1636 aFirstPave = aPave2;
1637 apfirst = aC2->Value(aPave2.Parameter());
1638 aFirstVertex = aNextVertex;
1641 // by pairs non continuously. end
1643 // by pairs continuously. begin
1644 aPave1 = thePrevPave;
1647 BOPDS_Pave atmpPave;
1649 if(!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave)) {
1650 return Standard_False;
1654 p1 = aC2->Value(aPave1.Parameter());
1655 aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
1659 while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1660 aFirstV = aPrevVertex;
1661 aLastV = aNextVertex;
1662 p2 = aC2->Value(aPave2.Parameter());
1664 Standard_Boolean bisinside = Standard_False;
1665 Standard_Integer apbindex = 0;
1666 Standard_Integer apbcounter = 1;
1667 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1668 BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
1669 TColStd_ListIteratorOfListOfInteger aFlagIt;
1671 for(aPIt1.Initialize(aFirstPaves), aPIt2.Initialize(aLastPaves), aFlagIt.Initialize(aListOfFlags);
1672 aPIt1.More() && aPIt2.More() && aFlagIt.More();
1673 aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++) {
1675 Standard_Boolean bfin = Standard_False;
1676 Standard_Boolean blin = Standard_False;
1678 if(aPave1.IsEqual(aPIt1.Value())) {
1679 bfin = Standard_True;
1682 bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
1685 if(aFlagIt.Value()) {
1686 if(aPave2.IsEqual(aPIt2.Value())) {
1687 blin = Standard_True;
1690 blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
1694 if((aPave2.Index() == aPIt2.Value().Index()) && (aPave2.Index() > 0)) {
1695 Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1696 gp_Pnt2d p3 = pc->Value(aPIt2.Value().Parameter());
1697 TopoDS_Vertex aV = TopoDS::Vertex(theDS->Shape(aPave2.Index()));
1698 BRepAdaptor_Surface aBAS(aFaceF, Standard_False);
1699 Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
1700 Standard_Real utol = aBAS.UResolution(aTolerance);
1701 Standard_Real vtol = aBAS.VResolution(aTolerance);
1702 aTolerance = (utol > vtol) ? utol : vtol;
1704 if(p2.Distance(p3) < aTolerance)
1705 blin = Standard_True;
1710 apbindex = apbcounter;
1711 bisinside = Standard_True;
1718 TopTools_ListOfShape aOrderedList;
1720 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1721 TopoDS_Compound aComp;
1722 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1723 aCompOfSecEdges = aComp;
1724 aListOfWireEdges.Append(aOrderedList);
1726 bSecFound = Standard_True;
1729 TopoDS_Edge aESplit;
1731 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
1733 for(; aPBIt.More(); aPBIt.Next()) {
1734 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
1735 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
1736 aPB1->Pave1().IsEqual(aPave1) &&
1737 aPB1->Pave2().IsEqual(aPave2) ) {
1738 if(aPB1->Edge() > 0) {
1739 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
1745 if(!aESplit.IsNull()) {
1746 aListOfWireEdges.Append(aESplit);
1752 TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
1753 aListOfWireEdges.Append(aListOfSec);
1757 aPrevVertex = aNextVertex;
1762 if(FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1763 aFirstV = aPrevVertex;
1764 aLastV = aNextVertex;
1765 Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1766 p2 = aC3->Value(aPave2.Parameter());
1768 Standard_Boolean bisinside = Standard_False;
1769 Standard_Integer apbindex = 0;
1770 Standard_Integer apbcounter = 1;
1771 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1772 BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
1773 TColStd_ListIteratorOfListOfInteger aFlagIt;
1775 for(aPIt1.Initialize(aFirstPaves), aPIt2.Initialize(aLastPaves), aFlagIt.Initialize(aListOfFlags);
1776 aPIt1.More() && aPIt2.More() && aFlagIt.More();
1777 aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++) {
1779 Standard_Boolean bfin = Standard_False;
1780 Standard_Boolean blin = Standard_False;
1782 if(aPave1.IsEqual(aPIt1.Value())) {
1783 bfin = Standard_True;
1786 bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
1789 if(aFlagIt.Value()) {
1790 if(aPave2.IsEqual(aPIt2.Value())) {
1791 blin = Standard_True;
1794 blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
1798 blin = Standard_True;
1802 apbindex = apbcounter;
1803 bisinside = Standard_True;
1810 TopTools_ListOfShape aOrderedList;
1812 if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1813 TopoDS_Compound aComp;
1814 RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1815 aCompOfSecEdges = aComp;
1816 aListOfWireEdges.Append(aOrderedList);
1818 bSecFound = Standard_True;
1822 TopoDS_Edge aESplit;
1824 if(!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
1825 return Standard_False;
1827 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
1828 for(; aPBIt.More(); aPBIt.Next()) {
1829 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
1830 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
1831 aPB1->Pave1().IsEqual(aPave1) &&
1832 aPB1->Pave2().IsEqual(aPave2) ) {
1833 if(aPB1->Edge() > 0) {
1834 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
1840 if(!aESplit.IsNull()) {
1841 aListOfWireEdges.Append(aESplit);
1847 TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
1848 aListOfWireEdges.Append(aListOfSec);
1854 TopoDS_Edge aESplit;
1856 if(!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
1857 return Standard_False;
1859 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1860 aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
1861 for(; aPBIt.More(); aPBIt.Next()) {
1862 const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
1863 if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
1864 aPB1->Pave1().IsEqual(aPave1) &&
1865 aPB1->Pave2().IsEqual(aPave2) ) {
1866 if(aPB1->Edge() > 0) {
1867 aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
1873 if(!aESplit.IsNull()) {
1874 aListOfWireEdges.Append(aESplit);
1878 // by pairs continuously. end
1879 theListOfWireEdges = aListOfWireEdges;
1880 isSectionFound = bSecFound;
1881 return Standard_True;
1884 // ----------------------------------------------------------------------------------------------------
1885 // static function: RemoveEdges
1887 // ----------------------------------------------------------------------------------------------------
1888 void RemoveEdges(const TopoDS_Compound& theSourceComp,
1889 const TopTools_ListOfShape& theListToRemove,
1890 TopoDS_Compound& theResultComp) {
1892 TopoDS_Compound aComp;
1893 aBB.MakeCompound(aComp);
1894 TopExp_Explorer anExp(theSourceComp, TopAbs_EDGE);
1896 for(; anExp.More(); anExp.Next()) {
1897 Standard_Boolean bfound = Standard_False;
1898 TopTools_ListIteratorOfListOfShape anIt(theListToRemove);
1900 for(; !bfound && anIt.More(); anIt.Next()) {
1901 bfound = anExp.Current().IsSame(anIt.Value());
1905 aBB.Add(aComp, anExp.Current());
1908 theResultComp = aComp;
1911 // ----------------------------------------------------------------------------------------------------
1912 // static function: FilterSectionEdges
1914 // ----------------------------------------------------------------------------------------------------
1915 Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve& theBCurves,
1916 const TopoDS_Face& theSecPlane,
1917 const BOPDS_PDS& theDS,
1918 TopoDS_Compound& theResult) {
1920 theResult.Nullify();
1923 aBB.MakeCompound(theResult);
1924 Standard_Integer aNbCurves = theBCurves.Extent();
1925 Standard_Integer cit = 0;
1926 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1928 for(cit = 0; cit < aNbCurves; ++cit) {
1929 const BOPDS_Curve& aBCurve = theBCurves(cit);
1930 const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
1932 aPBIt.Initialize(aSectEdges);
1933 for (; aPBIt.More(); aPBIt.Next()) {
1934 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1935 Standard_Integer nSect = aPB->Edge();
1936 const TopoDS_Shape& aS = theDS->Shape(nSect);
1937 TopoDS_Edge anEdge = TopoDS::Edge(aS);
1938 Standard_Boolean bAddEdge = Standard_True;
1940 if(!theSecPlane.IsNull()) {
1941 IntTools_BeanFaceIntersector anIntersector(anEdge, theSecPlane);
1942 Standard_Real f = 0., l = 0.;
1943 BRep_Tool::Range(anEdge, f, l);
1944 anIntersector.SetBeanParameters(f, l);
1946 Handle(BOPInt_Context) aContext = new BOPInt_Context;
1947 anIntersector.SetContext(aContext);
1949 anIntersector.Perform();
1951 if(anIntersector.IsDone()) {
1952 bAddEdge = Standard_False;
1953 Standard_Integer r = 0;
1955 for(r = 1; r <= anIntersector.Result().Length(); r++) {
1956 const IntTools_Range& aRange = anIntersector.Result().Value(r);
1958 if(((aRange.First() - f) < Precision::PConfusion()) &&
1959 ((l - aRange.Last()) < Precision::PConfusion())) {
1960 bAddEdge = Standard_True;
1962 }//if(((aRange.First() - f) < Precision::PConfusion()) &&
1963 }//for(r = 1; r <= anIntersector.Result().Length(); r++) {
1964 }//if(anIntersector.IsDone()) {
1965 }//if(!theSecPlane.IsNull()) {
1968 aBB.Add(theResult, aS);
1970 }//for (; aPBIt.More(); aPBIt.Next()) {
1971 }//for(cit = 0; cit < aNbCurves; ++cit) {
1973 return Standard_True;
1977 //=======================================================================
1978 //function : ComputeAveragePlaneAndMaxDeviation
1980 //=======================================================================
1981 static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
1983 Standard_Boolean& IsSingular)
1985 Standard_Integer N = 40, nedges = 0;
1987 TopoDS_Iterator iter( aWire );
1988 for (; iter.More(); iter.Next())
1991 TColgp_Array1OfPnt Pnts( 1, nedges*N );
1992 Standard_Integer ind = 1, i;
1993 for (iter.Initialize(aWire); iter.More(); iter.Next())
1995 const TopoDS_Edge& anEdge = TopoDS::Edge( iter.Value() );
1996 BRepAdaptor_Curve aCurve(anEdge);
1997 GCPnts_UniformAbscissa Distribution( aCurve, N+1 );
1998 for (i = 1; i <= N; i++)
2000 Standard_Real par = Distribution.Parameter(i);
2001 Pnts( ind++ ) = aCurve.Value(par);
2006 GeomLib::AxeOfInertia( Pnts, Axe, IsSingular );
2010 thePlane = gp_Pln( Axe );
2011 Standard_Real MaxDeviation = 0;
2012 for (i = 1; i <= Pnts.Length(); i++)
2014 Standard_Real dist = thePlane.Distance( Pnts(i) );
2015 if (dist > MaxDeviation)
2016 MaxDeviation = dist;
2018 return MaxDeviation;
2021 //=======================================================================
2022 //function : ChooseSection
2024 //=======================================================================
2025 static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp,
2027 TopoDS_Shape& resWire,
2029 Standard_Boolean& IsSingular)
2031 IsSingular = Standard_False;
2032 Standard_Real TolDeviation = 0.01; //, TolConf = 1.e-4, TolAng = 1.e-5;
2034 // Standard_Integer N = 100;
2035 Standard_Integer ind, i, j;
2038 TopoDS_Compound OldComp;
2040 B.MakeCompound( OldComp );
2041 TopoDS_Iterator iter( Comp );
2042 for (; iter.More(); iter.Next())
2043 B.Add( OldComp, iter.Value() );
2045 Standard_Boolean anError = Standard_False;
2046 //TopoDS_Wire NewWire [2];
2047 TopTools_SequenceOfShape Wseq;
2050 TopExp_Explorer explo( OldComp, TopAbs_EDGE );
2053 TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
2054 TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge );
2055 B.Remove( OldComp, FirstEdge );
2056 if (NewWire.Closed())
2058 Wseq.Append(NewWire);
2064 TopoDS_Vertex Extremity [2];
2065 TopExp::Vertices( NewWire, Extremity[0], Extremity[1] );
2066 if (Extremity[0].IsNull() || Extremity[1].IsNull())
2068 anError = Standard_True;
2071 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
2072 TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
2073 TopTools_ListOfShape Vedges [2];
2074 for (j = 0; j < 2; j++)
2075 if (VEmap.Contains( Extremity[j] ))
2076 Vedges[j] = VEmap.FindFromKey( Extremity[j] );
2077 if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
2078 //no more edges in OldComp to continue NewWire
2080 Standard_Boolean Modified = Standard_False;
2081 for (j = 0; j < 2; j++)
2083 if (Vedges[j].Extent() == 1)
2085 const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() );
2086 NewWire = BRepLib_MakeWire( NewWire, anEdge );
2087 B.Remove( OldComp, anEdge );
2088 Modified = Standard_True;
2091 if (!Modified) //only multiple connections
2093 ind = (Vedges[0].IsEmpty())? 1 : 0;
2094 TopTools_SequenceOfShape Edges;
2095 TopTools_ListIteratorOfListOfShape itl( Vedges[ind] );
2096 for (; itl.More(); itl.Next())
2097 Edges.Append( itl.Value() );
2098 Standard_Integer theind=0;
2099 Standard_Real MinDeviation = RealLast();
2100 for (j = 1; j <= Edges.Length(); j++)
2102 TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) );
2104 Standard_Boolean issing;
2105 Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing );
2106 if (Deviation < MinDeviation)
2108 MinDeviation = Deviation;
2112 NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) );
2113 B.Remove( OldComp, Edges(theind) );
2115 if (NewWire.Closed())
2118 Wseq.Append(NewWire);
2123 Standard_Real Deviation=0.;
2124 Standard_Real MinAngle = RealLast();
2125 TopExp_Explorer Explo( OldComp, TopAbs_EDGE );
2126 if (!anError && !Explo.More())
2128 if (Wseq.Length() == 1)
2130 resWire = Wseq.First();
2131 Deviation = ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular );
2132 return Standard_True;
2136 for (i = 1; i <= Wseq.Length(); i++)
2138 TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) );
2140 Standard_Boolean issing;
2141 Standard_Real aDeviation =
2142 ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
2146 Standard_Real Angle = aPln.Axis().Angle( bis.Axis() );
2148 Angle = M_PI - Angle;
2150 if (Angle < MinAngle)
2155 Deviation = aDeviation;
2158 if (Deviation <= TolDeviation)
2159 return Standard_True;
2162 return Standard_False;
2163 //end of simplest case