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