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