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