0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / BRepBuilderAPI / BRepBuilderAPI_Sewing.cxx
CommitLineData
b311480e 1// Created on: 1995-03-24
2// Created by: Jing Cheng MEI
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
47980104 16
7fd59977 17// dcl CCI60011 : Correction of degeneratedSection
18// Improvement of SameParameter Edge to treat case of failure in BRepLib::SameParameter
19// dcl Thu Aug 20 09:24:49 1998
20// Suppression of little faces.
21// dcl Fri Aug 7 15:27:46 1998
22// Refection of function SameParameter Edge.
23// Merge on the edge which has the less of poles.
24// Suppression of the Connected Edge function.
25// dcl Tue Jun 9 14:21:53 1998
26// Do not merge edge if they belong the same face
27// Tolerance management in VerticesAssembling
28// Tolerance management in Cutting
29// dcl Thu May 14 15:51:46 1998
30// optimization of cutting
31// dcl Thu May 7 15:51:46 1998
32// Add of cutting option
33// Add of SameParameter call
34
35
0d969553
Y
36//-- lbr April 1 97
37//-- dpf December 10 1997 Processing of pcurve collections
7fd59977 38
39//rln 02.02.99 BUC60449 Making compilable on NT in DEB mode
40//rln 02.02.99 BUC60449 Protection against exception on NT
41
42#define TEST 1
43
7fd59977 44
45#include <Bnd_Box.hxx>
46#include <Bnd_Box2d.hxx>
47#include <Bnd_HArray1OfBox.hxx>
48#include <BndLib_Add2dCurve.hxx>
49#include <BndLib_Add3dCurve.hxx>
50#include <BRep_Builder.hxx>
42cf5bc1 51#include <BRep_ListOfPointRepresentation.hxx>
52#include <BRep_PointOnCurve.hxx>
7fd59977 53#include <BRep_Tool.hxx>
42cf5bc1 54#include <BRep_TVertex.hxx>
55#include <BRepBuilderAPI_BndBoxTreeSelector.hxx>
56#include <BRepBuilderAPI_CellFilter.hxx>
57#include <BRepBuilderAPI_Sewing.hxx>
58#include <BRepBuilderAPI_VertexInspector.hxx>
7fd59977 59#include <BRepLib.hxx>
42cf5bc1 60#include <BRepTools.hxx>
7fd59977 61#include <BRepTools_Quilt.hxx>
42cf5bc1 62#include <BRepTools_ReShape.hxx>
7fd59977 63#include <BSplCLib.hxx>
64#include <Extrema_ExtPC.hxx>
65#include <GCPnts_AbscissaPoint.hxx>
66#include <GCPnts_UniformAbscissa.hxx>
67#include <GCPnts_UniformDeflection.hxx>
68#include <Geom2d_BezierCurve.hxx>
69#include <Geom2d_BSplineCurve.hxx>
70#include <Geom2d_Curve.hxx>
71#include <Geom2d_Line.hxx>
72#include <Geom2d_TrimmedCurve.hxx>
73#include <Geom2dAdaptor_Curve.hxx>
74#include <Geom2dConvert.hxx>
75#include <Geom_BezierCurve.hxx>
76#include <Geom_BSplineCurve.hxx>
77#include <Geom_Curve.hxx>
78#include <Geom_Line.hxx>
42cf5bc1 79#include <Geom_OffsetSurface.hxx>
80#include <Geom_RectangularTrimmedSurface.hxx>
7fd59977 81#include <Geom_Surface.hxx>
82#include <GeomAdaptor_Curve.hxx>
83#include <GeomAdaptor_Surface.hxx>
84#include <GeomLib.hxx>
85#include <gp_Pnt.hxx>
86#include <gp_Vec.hxx>
42cf5bc1 87#include <Message_ProgressIndicator.hxx>
88#include <Message_ProgressSentry.hxx>
89#include <NCollection_UBTreeFiller.hxx>
7fd59977 90#include <Precision.hxx>
91#include <Standard_ErrorHandler.hxx>
92#include <Standard_Failure.hxx>
42cf5bc1 93#include <Standard_NoSuchObject.hxx>
94#include <Standard_OutOfRange.hxx>
95#include <Standard_Type.hxx>
7fd59977 96#include <TColgp_Array1OfVec.hxx>
97#include <TColgp_SequenceOfPnt.hxx>
98#include <TColStd_Array1OfInteger.hxx>
99#include <TColStd_Array1OfReal.hxx>
42cf5bc1 100#include <TColStd_Array2OfReal.hxx>
7fd59977 101#include <TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger.hxx>
102#include <TColStd_DataMapOfIntegerListOfInteger.hxx>
103#include <TColStd_IndexedMapOfInteger.hxx>
104#include <TColStd_ListIteratorOfListOfInteger.hxx>
105#include <TColStd_ListOfInteger.hxx>
42cf5bc1 106#include <TColStd_MapIteratorOfMapOfInteger.hxx>
7fd59977 107#include <TColStd_MapOfInteger.hxx>
108#include <TColStd_SequenceOfReal.hxx>
109#include <TopAbs.hxx>
110#include <TopExp.hxx>
111#include <TopExp_Explorer.hxx>
112#include <TopLoc_Location.hxx>
113#include <TopoDS.hxx>
42cf5bc1 114#include <TopoDS_Compound.hxx>
7fd59977 115#include <TopoDS_Edge.hxx>
42cf5bc1 116#include <TopoDS_Face.hxx>
7fd59977 117#include <TopoDS_Iterator.hxx>
118#include <TopoDS_Shape.hxx>
42cf5bc1 119#include <TopoDS_Shell.hxx>
7fd59977 120#include <TopoDS_Vertex.hxx>
121#include <TopoDS_Wire.hxx>
7fd59977 122#include <TopTools_Array1OfShape.hxx>
123#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
124#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
125#include <TopTools_DataMapOfShapeInteger.hxx>
126#include <TopTools_DataMapOfShapeListOfShape.hxx>
127#include <TopTools_ListIteratorOfListOfShape.hxx>
128#include <TopTools_ListOfShape.hxx>
129#include <TopTools_MapIteratorOfMapOfShape.hxx>
130#include <TopTools_MapOfShape.hxx>
131#include <TopTools_SequenceOfShape.hxx>
7fd59977 132
92efcf78 133IMPLEMENT_STANDARD_RTTIEXT(BRepBuilderAPI_Sewing,MMgt_TShared)
134
42cf5bc1 135//#include <LocalAnalysis_SurfaceContinuity.hxx>
7fd59977 136//=======================================================================
137//function : SameRange
138//purpose :
139//=======================================================================
7fd59977 140Handle(Geom2d_Curve) BRepBuilderAPI_Sewing::SameRange(const Handle(Geom2d_Curve)& CurvePtr,
141 const Standard_Real FirstOnCurve,
142 const Standard_Real LastOnCurve,
143 const Standard_Real RequestedFirst,
144 const Standard_Real RequestedLast) const
145{
146 Handle(Geom2d_Curve) NewCurvePtr;
147 try {
148
149 GeomLib::SameRange(Precision::PConfusion(),CurvePtr,FirstOnCurve,LastOnCurve,
150 RequestedFirst,RequestedLast,NewCurvePtr);
151 }
152 catch (Standard_Failure) {
0797d9d3 153#ifdef OCCT_DEBUG
7fd59977 154 cout << "Exception in BRepBuilderAPI_Sewing::SameRange: ";
155 Standard_Failure::Caught()->Print(cout); cout << endl;
156#endif
157 }
158 return NewCurvePtr;
159}
160
161//=======================================================================
162//function : WhichFace
0d969553 163//purpose : Give the face whose edge is the border
7fd59977 164//=======================================================================
165
166TopoDS_Face BRepBuilderAPI_Sewing::WhichFace(const TopoDS_Edge& theEdg, const Standard_Integer index) const
167{
168 TopoDS_Shape bound = theEdg;
169 if (mySectionBound.IsBound(bound)) bound = mySectionBound(bound);
170 if (myBoundFaces.Contains(bound)) {
171 Standard_Integer i = 1;
172 TopTools_ListIteratorOfListOfShape itf(myBoundFaces.FindFromKey(bound));
173 for (; itf.More(); itf.Next(), i++)
174 if (i == index) return TopoDS::Face(itf.Value());
175 }
176 return TopoDS_Face();
177}
178
179//=======================================================================
180//function : IsClosedShape
181//purpose :
182//=======================================================================
183
184static Standard_Boolean IsClosedShape(const TopoDS_Shape& theshape,
185 const TopoDS_Shape& v1, const TopoDS_Shape& v2)
186{
187 Standard_Real TotLength = 0.0;
188 TopExp_Explorer aexp;
189 for (aexp.Init(theshape,TopAbs_EDGE); aexp.More(); aexp.Next()) {
190 TopoDS_Edge aedge = TopoDS::Edge(aexp.Current());
191 if (aedge.IsNull()) continue;
192 TopoDS_Vertex ve1,ve2;
193 TopExp::Vertices(aedge,ve1,ve2);
194 if (!ve1.IsSame(v1) && !ve1.IsSame(v2)) continue;
195 if (BRep_Tool::Degenerated(aedge)) continue;
196 Standard_Real first,last;
197 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(aedge), first, last);
198 if (!c3d.IsNull()) {
199 GeomAdaptor_Curve cAdapt(c3d);
200 Standard_Real length = GCPnts_AbscissaPoint::Length(cAdapt, first, last);
201 TotLength += length;
202 if (ve2.IsSame(v1) || ve2.IsSame(v2)) break;
203 }
204 }
205 if (TotLength > 0.0) {
206 gp_Pnt p1 = BRep_Tool::Pnt(TopoDS::Vertex(v1));
207 gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(v2));
c6541a0c 208 return (p1.Distance(p2) < TotLength/(1.2 * M_PI));
7fd59977 209 }
210 return Standard_False;
211}
212
213//=======================================================================
214//function : IsClosedByIsos
215//purpose :
216//=======================================================================
217static Standard_Boolean IsClosedByIsos(const Handle(Geom_Surface)& thesurf,
218 const Handle(Geom2d_Curve)& acrv2d,
219 const Standard_Real f2d,
220 const Standard_Real l2d,
221 const Standard_Boolean isUIsos)
222{
223 Standard_Boolean isClosed = Standard_False;
224
225 gp_Pnt2d psurf1 = (acrv2d->IsPeriodic() ?
226 acrv2d->Value(f2d) : acrv2d->Value(Max(f2d,acrv2d->FirstParameter())));
227 gp_Pnt2d psurf2 = (acrv2d->IsPeriodic() ?
228 acrv2d->Value(l2d) : acrv2d->Value(Min(l2d,acrv2d->LastParameter())));
229 Handle(Geom_Curve) aCrv1;
230 Handle(Geom_Curve) aCrv2;
231 if(isUIsos) {
232 aCrv1 = thesurf->UIso(psurf1.X());
233 aCrv2 = thesurf->UIso(psurf2.X());
234 }
235 else {
236 aCrv1 = thesurf->VIso(psurf1.Y());
237 aCrv2 = thesurf->VIso(psurf2.Y());
238 }
239 gp_Pnt p11,p1m,p12,p21,p2m,p22;
240 Standard_Real af1 = aCrv1->FirstParameter();
241 Standard_Real al1 = aCrv1->LastParameter();
242 Standard_Real af2 = aCrv2->FirstParameter();
243 Standard_Real al2 = aCrv2->LastParameter();
244 aCrv1->D0(af1,p11);
245 aCrv1->D0((af1+al1)*0.5,p1m);
246 aCrv1->D0(al1,p12);
247 aCrv2->D0(af2,p21);
248 aCrv2->D0((af2+al2)*0.5,p2m);
249 aCrv2->D0(al2,p22);
250 isClosed = (((p11.XYZ() - p12.XYZ()).Modulus() <
251 (p11.XYZ() - p1m.XYZ()).Modulus() - Precision::Confusion()) &&
252 ((p21.XYZ() - p22.XYZ()).Modulus() <
253 (p21.XYZ() - p2m.XYZ()).Modulus() - Precision::Confusion())) ;
254 return isClosed;
255}
256//=======================================================================
257//function : IsUClosedSurface
258//purpose :
259//=======================================================================
260
261Standard_Boolean BRepBuilderAPI_Sewing::IsUClosedSurface(const Handle(Geom_Surface)& surf,
262 const TopoDS_Shape& theEdge,
263 const TopLoc_Location& theloc) const
264{
265 Handle(Geom_Surface) tmpsurf = surf;
266 if(tmpsurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
267 tmpsurf = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf)->BasisSurface();
268 else if(tmpsurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
269 tmpsurf = Handle(Geom_OffsetSurface)::DownCast(surf)->BasisSurface();
270 else {
271 Standard_Boolean isClosed = tmpsurf->IsUClosed();
272 if(!isClosed) {
273 Standard_Real f2d, l2d;
274 Handle(Geom2d_Curve) acrv2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge), surf,theloc, f2d, l2d);
275 if(!acrv2d.IsNull())
276 isClosed = IsClosedByIsos(tmpsurf,acrv2d,f2d, l2d,Standard_False );
277
278 }
279 return isClosed;
280 }
281 return IsUClosedSurface(tmpsurf,theEdge,theloc);
282 //return surf->IsUClosed();
283}
284
285//=======================================================================
286//function : IsVClosedSurface
287//purpose :
288//=======================================================================
289
290Standard_Boolean BRepBuilderAPI_Sewing::IsVClosedSurface(const Handle(Geom_Surface)& surf,
291 const TopoDS_Shape& theEdge,
292 const TopLoc_Location& theloc) const
293{
294 Handle(Geom_Surface) tmpsurf = surf;
295 if(tmpsurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
296 tmpsurf = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf)->BasisSurface();
297 else if(tmpsurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
298 tmpsurf = Handle(Geom_OffsetSurface)::DownCast(surf)->BasisSurface();
299 else {
300 Standard_Boolean isClosed = tmpsurf->IsVClosed();
301 if(!isClosed) {
302 Standard_Real f2d, l2d;
303 Handle(Geom2d_Curve) acrv2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge), surf,theloc, f2d, l2d);
304 if(!acrv2d.IsNull())
305 isClosed = IsClosedByIsos(tmpsurf,acrv2d,f2d, l2d,Standard_True );
306 }
307 return isClosed;
308 }
309 return IsVClosedSurface(tmpsurf,theEdge,theloc);
310 //return surf->IsVClosed();
311}
312
313//=======================================================================
314//function : SameParameter
315//purpose : internal use
316//=======================================================================
317
318void BRepBuilderAPI_Sewing::SameParameter(const TopoDS_Edge& edge) const
319{
320 try {
321
322 BRepLib::SameParameter(edge);
323 }
324 catch (Standard_Failure) {
0797d9d3 325#ifdef OCCT_DEBUG
7fd59977 326 cout << "Exception in BRepBuilderAPI_Sewing::SameParameter: ";
327 Standard_Failure::Caught()->Print(cout); cout << endl;
328#endif
329 }
330}
331
332//=======================================================================
333//function : SameParameterEdge
334//purpose : internal use
335// Merge the Sequence Of Section on one edge.
336// This function keep the curve3d,curve2d,range and parametrization
337// from the first section, and report and made sameparameter the
338// pcurves of the other function.
339// This function works when the are not more than two Pcurves
340// on a same face.
341//=======================================================================
342
343TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Shape& edge,
344 const TopTools_SequenceOfShape& seqEdges,
dde68833 345 const TColStd_SequenceOfBoolean& seqForward,
7fd59977 346 TopTools_MapOfShape& mapMerged,
347 const Handle(BRepTools_ReShape)& locReShape)
348{
349 // Retrieve reference section
350 TopoDS_Shape aTmpShape = myReShape->Apply(edge); //for porting
351 TopoDS_Edge Edge1 = TopoDS::Edge(aTmpShape);
352 aTmpShape = locReShape->Apply(Edge1);
353 if (locReShape != myReShape) Edge1 = TopoDS::Edge(aTmpShape);
354 Standard_Boolean isDone = Standard_False;
355
356 // Create data structures for temporary merged edges
357 TopTools_ListOfShape listFaces1;
358 TopTools_MapOfShape MergedFaces;
359
360 if (mySewing) {
361
362 // Fill MergedFaces with faces of Edge1
363 TopoDS_Shape bnd1 = edge;
364 if (mySectionBound.IsBound(bnd1)) bnd1 = mySectionBound(bnd1);
365 if (myBoundFaces.Contains(bnd1)) {
366 TopTools_ListIteratorOfListOfShape itf(myBoundFaces.FindFromKey(bnd1));
367 for (; itf.More(); itf.Next())
368 if (MergedFaces.Add(itf.Value()))
369 listFaces1.Append(itf.Value());
370 }
371 }
372 else {
373
374 // Create presentation edge
375 TopoDS_Vertex V1, V2;
376 TopExp::Vertices(Edge1,V1,V2);
377 if (myVertexNode.Contains(V1)) V1 = TopoDS::Vertex(myVertexNode.FindFromKey(V1));
378 if (myVertexNode.Contains(V2)) V2 = TopoDS::Vertex(myVertexNode.FindFromKey(V2));
379
380 TopoDS_Edge NewEdge = Edge1;
381 NewEdge.EmptyCopy();
382
383 // Add the vertices
384 BRep_Builder aBuilder;
385 TopoDS_Shape anEdge = NewEdge.Oriented(TopAbs_FORWARD);
386 aBuilder.Add(anEdge,V1.Oriented(TopAbs_FORWARD));
387 aBuilder.Add(anEdge,V2.Oriented(TopAbs_REVERSED));
388
389 Edge1 = NewEdge;
390 }
391
392 Standard_Boolean isForward = Standard_True;
393
394 // Merge candidate sections
395 for (Standard_Integer i = 1; i <= seqEdges.Length(); i++) {
396
397 // Retrieve candidate section
398 TopoDS_Shape oedge2 = seqEdges(i);
399
400 if (mySewing) {
401
402 aTmpShape = myReShape->Apply(oedge2); //for porting
403 TopoDS_Edge Edge2 = TopoDS::Edge(aTmpShape);
404 aTmpShape = locReShape->Apply(Edge2);
405 if (locReShape != myReShape) Edge2 = TopoDS::Edge(aTmpShape);
406
407 // Calculate relative orientation
dde68833 408 Standard_Boolean Orientation = seqForward(i);
409 if (!isForward) Orientation = !Orientation;
7fd59977 410
411 // Retrieve faces information for the second edge
412 TopoDS_Shape bnd2 = oedge2;
413 if (mySectionBound.IsBound(bnd2)) bnd2 = mySectionBound(bnd2);
414 if (!myBoundFaces.Contains(bnd2)) continue; // Skip floating edge
415 const TopTools_ListOfShape& listFaces2 = myBoundFaces.FindFromKey(bnd2);
416
417 Standard_Integer whichSec = 1; // Indicates on which edge the pCurve has been reported
418 TopoDS_Edge NewEdge = SameParameterEdge(Edge1,Edge2,listFaces1,listFaces2,Orientation,whichSec);
419 if (NewEdge.IsNull()) continue;
420
421 // Record faces information for the temporary merged edge
422 TopTools_ListIteratorOfListOfShape itf(listFaces2);
423 for (; itf.More(); itf.Next())
424 if (MergedFaces.Add(itf.Value()))
425 listFaces1.Append(itf.Value());
426
427 // Record merged section orientation
428 if (!Orientation && whichSec != 1)
429 isForward = isForward? Standard_False : Standard_True;
430 Edge1 = NewEdge;
431 }
432
433 // Append actually merged edge
434 mapMerged.Add(oedge2);
435 isDone = Standard_True;
436
437 if (!myNonmanifold) break;
438 }
439
440 if (isDone) {
441 // Change result orientation
442 Edge1.Orientation(isForward? TopAbs_FORWARD : TopAbs_REVERSED);
443 }
444 else Edge1.Nullify();
445
446 return Edge1;
447}
448
449//=======================================================================
450//function : SameParameterEdge
451//purpose : internal use
452//=======================================================================
453static Standard_Boolean findNMVertices(const TopoDS_Edge& theEdge,
454 TopTools_SequenceOfShape& theSeqNMVert,
455 TColStd_SequenceOfReal& theSeqPars)
456{
457 TopoDS_Iterator aItV(theEdge,Standard_False);
458 for( ; aItV.More(); aItV.Next()) {
459 if(aItV.Value().Orientation() == TopAbs_INTERNAL ||
460 aItV.Value().Orientation() == TopAbs_EXTERNAL)
461 theSeqNMVert.Append(aItV.Value());
462 }
463 Standard_Integer nbV = theSeqNMVert.Length();
464 if(!nbV)
465 return Standard_False;
466 Standard_Real first, last;
467 Handle(Geom_Curve) c3d = BRep_Tool::Curve(theEdge,first, last);
468 GeomAdaptor_Curve GAC(c3d);
469 Extrema_ExtPC locProj;
470 locProj.Initialize(GAC, first, last);
471 gp_Pnt pfirst = GAC.Value(first), plast = GAC.Value(last);
472
473
474 for (Standard_Integer i = 1; i <= nbV; i++) {
475 TopoDS_Vertex aV = TopoDS::Vertex(theSeqNMVert.Value(i));
476 gp_Pnt pt = BRep_Tool::Pnt(aV);
477
478 Standard_Real distF2 = pfirst.SquareDistance(pt);
479 Standard_Real distL2 = plast.SquareDistance(pt);
480 Standard_Real apar = (distF2 > distL2 ? last : first);
481 // Project current point on curve
482 locProj.Perform(pt);
483 if (locProj.IsDone() && locProj.NbExt() > 0) {
484 Standard_Real dist2Min = Min(distF2,distL2);
485 Standard_Integer ind, indMin = 0;
486 for (ind = 1; ind <= locProj.NbExt(); ind++) {
487 Standard_Real dProj2 = locProj.SquareDistance(ind);
488 if (dProj2 < dist2Min) {
489 indMin = ind; dist2Min = dProj2;
490 }
491 }
492 if(indMin)
493 apar = locProj.Point(indMin).Parameter();
494
495 theSeqPars.Append(apar);
496
497 }
498 }
499 return Standard_True;
500}
501
93937391 502static void ComputeToleranceVertex(TopoDS_Vertex theV1, TopoDS_Vertex theV2,
503 TopoDS_Vertex& theNewV)
7fd59977 504{
93937391 505 Standard_Integer m, n;
506 Standard_Real aR[2], dR, aD, aEps;
507 TopoDS_Vertex aV[2];
508 gp_Pnt aP[2];
509 BRep_Builder aBB;
510 //
511 aEps = RealEpsilon();
512 aV[0] = theV1;
513 aV[1] = theV2;
514 for (m = 0; m < 2; ++m) {
515 aP[m] = BRep_Tool::Pnt(aV[m]);
516 aR[m] = BRep_Tool::Tolerance(aV[m]);
517 }
518 //
519 m=0; // max R
520 n=1; // min R
521 if (aR[0] < aR[1]) {
522 m=1;
523 n=0;
524 }
525 //
526 dR = aR[m] - aR[n]; // dR >= 0.
527 gp_Vec aVD(aP[m], aP[n]);
528 aD = aVD.Magnitude();
529 //
530 if (aD <= dR || aD < aEps) {
531 aBB.MakeVertex (theNewV, aP[m], aR[m]);
532 }
533 else {
534 Standard_Real aRr;
535 gp_XYZ aXYZr;
536 gp_Pnt aPr;
537 //
538 aRr = 0.5 * (aR[m] + aR[n] + aD);
539 aXYZr = 0.5 * (aP[m].XYZ() + aP[n].XYZ() - aVD.XYZ() * (dR/aD));
540 aPr.SetXYZ(aXYZr);
541 //
542 aBB.MakeVertex (theNewV, aPr, aRr);
543 }
544 return;
545}
546
547static void ComputeToleranceVertex(TopoDS_Vertex theV1, TopoDS_Vertex theV2,
548 TopoDS_Vertex theV3, TopoDS_Vertex& theNewV)
549{
550 Standard_Real aDi, aDmax;
551 gp_Pnt aCenter;
552 gp_Pnt aP[3];
553 Standard_Real aR[3];
554 TopoDS_Vertex aV[3];
555 gp_XYZ aXYZ(0.,0.,0.);
556 aV[0] = theV1;
557 aV[1] = theV2;
558 aV[2] = theV3;
559 for (Standard_Integer i = 0; i < 3; ++i) {
560 aP[i] = BRep_Tool::Pnt(aV[i]);
561 aR[i] = BRep_Tool::Tolerance(aV[i]);
562 aXYZ = aXYZ + aP[i].XYZ();
563 }
564 //
565 aXYZ.Divide(3.0);
566 aCenter.SetXYZ(aXYZ);
567 //
568 aDmax=-1.;
569 for ( Standard_Integer i = 0; i < 3; ++i) {
570 aDi = aCenter.Distance(aP[i]);
571 aDi += aR[i];
572 if (aDi > aDmax)
573 aDmax = aDi;
574 }
575
576 BRep_Builder aBB;
577 aBB.MakeVertex (theNewV, aCenter, aDmax);
578 return;
7fd59977 579}
2a739b6d 580
7fd59977 581TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirst,
582 const TopoDS_Edge& edgeLast,
583 const TopTools_ListOfShape& listFacesFirst,
584 const TopTools_ListOfShape& listFacesLast,
585 const Standard_Boolean secForward,
586 Standard_Integer& whichSec,
587 const Standard_Boolean firstCall)
588{
589 // Do not process floating edges
590 if (!listFacesFirst.Extent() || !listFacesLast.Extent()) return TopoDS_Edge();
591
592 // Sort input edges
593 TopoDS_Edge edge1, edge2;
594 if (firstCall) {
595 // Take the longest edge as first
596 Standard_Real f, l;
597 Handle(Geom_Curve) c3d1 = BRep_Tool::Curve(TopoDS::Edge(edgeFirst), f, l);
598 GeomAdaptor_Curve cAdapt1(c3d1);
599 Standard_Real len1 = GCPnts_AbscissaPoint::Length(cAdapt1, f, l);
600 Handle(Geom_Curve) c3d2 = BRep_Tool::Curve(TopoDS::Edge(edgeLast), f, l);
601 GeomAdaptor_Curve cAdapt2(c3d2);
602 Standard_Real len2 = GCPnts_AbscissaPoint::Length(cAdapt2, f, l);
603 if (len1 < len2) {
604 edge1 = edgeLast;
605 edge2 = edgeFirst;
606 whichSec = 2;
607 }
608 else {
609 edge1 = edgeFirst;
610 edge2 = edgeLast;
611 whichSec = 1;
612 }
613 }
614 else {
615 if (whichSec == 1) {
616 edge1 = edgeLast;
617 edge2 = edgeFirst;
618 whichSec = 2;
619 }
620 else {
621 edge1 = edgeFirst;
622 edge2 = edgeLast;
623 whichSec = 1;
624 }
625 }
626
627 Standard_Real first, last;
628 BRep_Tool::Range(edge1, first, last);
629 BRep_Builder aBuilder;
630
631 //To keep NM vertices on edge
632 TopTools_SequenceOfShape aSeqNMVert;
633 TColStd_SequenceOfReal aSeqNMPars;
634 findNMVertices(edge1,aSeqNMVert,aSeqNMPars);
635 findNMVertices(edge2,aSeqNMVert,aSeqNMPars);
636
637 // Create new edge
638 TopoDS_Edge edge;
639 aBuilder.MakeEdge(edge);
640 edge.Orientation( edge1.Orientation());
641
642
643 // Retrieve edge curve
644 TopLoc_Location loc3d;
645 Standard_Real first3d, last3d;
646 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge1, loc3d, first3d, last3d);
647 if (!loc3d.IsIdentity()) {
648 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
649 c3d->Transform(loc3d.Transformation());
650 }
651 aBuilder.UpdateEdge(edge,c3d,BRep_Tool::Tolerance(edge1));
652 aBuilder.Range(edge, first, last);
653 aBuilder.SameRange(edge, Standard_False); //Standard_True
654 aBuilder.SameParameter(edge, Standard_False);
655 // Create and add new vertices
656 {
657 TopoDS_Vertex V1New, V2New;
658
659 // Retrieve original vertices from edges
660 TopoDS_Vertex V11,V12,V21,V22;
661 TopExp::Vertices(edge1,V11,V12);
662 TopExp::Vertices(edge2,V21,V22);
663
67ffcad0
G
664 //check that edges merged valid way (for edges having length less than specified
665 //tolerance
9781f215
G
666 // Check if edges are closed
667 Standard_Boolean isClosed1 = V11.IsSame(V12);
668 Standard_Boolean isClosed2 = V21.IsSame(V22);
669 if(!isClosed1 && !isClosed2)
2028d00c 670 {
9781f215
G
671 if(secForward )
672 {
673 if( V11.IsSame(V22) || V12.IsSame(V21) )
674 return TopoDS_Edge();
675 }
676 else
677 {
678 if( V11.IsSame(V21) || V12.IsSame(V22) )
679 return TopoDS_Edge();
680 }
2028d00c
G
681 }
682
7fd59977 683 //szv: do not reshape here!!!
684 //V11 = TopoDS::Vertex(myReShape->Apply(V11));
685 //V12 = TopoDS::Vertex(myReShape->Apply(V12));
686 //V21 = TopoDS::Vertex(myReShape->Apply(V21));
687 //V22 = TopoDS::Vertex(myReShape->Apply(V22));
688
7fd59977 689 //Standard_Boolean isRev = Standard_False;
7fd59977 690 if (isClosed1 || isClosed2) {
691 // at least one of the edges is closed
692 if (isClosed1 && isClosed2) {
67ffcad0 693 // both edges are closed
93937391 694 ComputeToleranceVertex(V11, V21, V1New);
7fd59977 695 }
696 else if (isClosed1) {
67ffcad0 697 // only first edge is closed
93937391 698 ComputeToleranceVertex(V22, V21, V11, V1New);
7fd59977 699 }
700 else {
67ffcad0 701 // only second edge is closed
93937391 702 ComputeToleranceVertex(V11, V12, V21, V1New);
7fd59977 703 }
7fd59977 704 V2New = V1New;
705 }
706 else {
707 // both edges are open
67ffcad0
G
708 Standard_Boolean isOldFirst = ( secForward ? V11.IsSame(V21) : V11.IsSame(V22) );
709 Standard_Boolean isOldLast = ( secForward ? V12.IsSame(V22) : V12.IsSame(V21)) ;
7fd59977 710 if (secForward) {
67ffcad0
G
711 //case if vertices already sewed
712 if(!isOldFirst)
713 {
93937391 714 ComputeToleranceVertex(V11, V21, V1New);
67ffcad0
G
715 }
716 if(!isOldLast)
717 {
93937391 718 ComputeToleranceVertex(V12, V22, V2New);
67ffcad0 719 }
7fd59977 720 }
721 else {
67ffcad0
G
722 if(!isOldFirst)
723 {
93937391 724 ComputeToleranceVertex(V11, V22, V1New);
67ffcad0
G
725 }
726 if(!isOldLast)
727 {
93937391 728 ComputeToleranceVertex(V12, V21, V2New);
67ffcad0 729 }
7fd59977 730 }
93937391 731 if(isOldFirst)
67ffcad0 732 V1New = V11;
67ffcad0 733
93937391 734 if(isOldLast)
67ffcad0 735 V2New = V12;
7fd59977 736 }
7fd59977 737 // Add the vertices in the good sense
738 TopoDS_Shape anEdge = edge.Oriented(TopAbs_FORWARD);
739 TopoDS_Shape aLocalEdge = V1New.Oriented(TopAbs_FORWARD); //(listNode.First()).Oriented(TopAbs_FORWARD);
740 aBuilder.Add(anEdge,aLocalEdge);
741 aLocalEdge = V2New.Oriented(TopAbs_REVERSED); //(listNode.Last()).Oriented(TopAbs_REVERSED);
742 aBuilder.Add(anEdge,aLocalEdge);
743
744 Standard_Integer k =1;
745 for( ; k <= aSeqNMVert.Length(); k++)
746 aBuilder.Add(anEdge,aSeqNMVert.Value(k));
747
748 }
749
750 // Retrieve second PCurves
751 TopLoc_Location loc2;
752 Handle(Geom_Surface) surf2;
47980104 753
7fd59977 754 //Handle(Geom2d_Curve) c2d2, c2d21;
755 // Standard_Real firstOld, lastOld;
756
757 TopTools_ListIteratorOfListOfShape itf2;
758 if (whichSec == 1) itf2.Initialize(listFacesLast);
759 else itf2.Initialize(listFacesFirst);
760 Standard_Boolean isResEdge = Standard_False;
0221b126 761 TopoDS_Face fac2;
7fd59977 762 for (; itf2.More(); itf2.Next()) {
763 Handle(Geom2d_Curve) c2d2, c2d21;
764 Standard_Real firstOld, lastOld;
0221b126 765 fac2 = TopoDS::Face(itf2.Value());
7fd59977 766
767 surf2 = BRep_Tool::Surface(fac2, loc2);
768 Standard_Boolean isSeam2 = ((IsUClosedSurface(surf2,edge2,loc2) || IsVClosedSurface(surf2,edge2,loc2)) &&
67ffcad0 769 BRep_Tool::IsClosed(TopoDS::Edge(edge2),fac2));
7fd59977 770 if (isSeam2) {
771 if (!myNonmanifold) return TopoDS_Edge();
772 TopoDS_Shape aTmpShape = edge2.Reversed(); //for porting
773 c2d21 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aTmpShape), fac2, firstOld, lastOld);
774 }
775 c2d2 = BRep_Tool::CurveOnSurface(edge2, fac2, firstOld, lastOld);
776 if (c2d2.IsNull() && c2d21.IsNull()) continue;
777
778 if (!c2d21.IsNull()) {
779 c2d21 = Handle(Geom2d_Curve)::DownCast(c2d21->Copy());
780 if (!secForward) {
67ffcad0
G
781 if (c2d21->IsKind(STANDARD_TYPE(Geom2d_Line)))
782 c2d21 = new Geom2d_TrimmedCurve(c2d21, firstOld, lastOld);
783 Standard_Real first2d = firstOld; //c2dTmp->FirstParameter(); BUG USA60321
784 Standard_Real last2d = lastOld; //c2dTmp->LastParameter();
785 firstOld = c2d21->ReversedParameter(last2d);
786 lastOld = c2d21->ReversedParameter(first2d);
787 c2d21->Reverse();
7fd59977 788 }
789 c2d21 = SameRange(c2d21,firstOld,lastOld,first,last);
790 }
791
792 // Make second PCurve sameRange with the 3d curve
793 c2d2 = Handle(Geom2d_Curve)::DownCast(c2d2->Copy());
67ffcad0 794
7fd59977 795 if (!secForward) {
796 if (c2d2->IsKind(STANDARD_TYPE(Geom2d_Line)))
67ffcad0
G
797 c2d2 = new Geom2d_TrimmedCurve(c2d2, firstOld, lastOld);
798 Standard_Real first2d = firstOld;
799 Standard_Real last2d = lastOld;
7fd59977 800 firstOld = c2d2->ReversedParameter(last2d);
801 lastOld = c2d2->ReversedParameter(first2d);
802 c2d2->Reverse();
803 }
804
805 c2d2 = SameRange(c2d2,firstOld,lastOld,first,last);
806 if (c2d2.IsNull()) continue;
67ffcad0 807
7fd59977 808 // Add second PCurve
809 Standard_Boolean isSeam = Standard_False;
810 TopAbs_Orientation Ori = TopAbs_FORWARD;
811 //Handle(Geom2d_Curve) c2d1, c2d11;
812
813 TopTools_ListIteratorOfListOfShape itf1;
814 if (whichSec == 1) itf1.Initialize(listFacesFirst);
815 else itf1.Initialize(listFacesLast);
816 for (; itf1.More() && !isSeam; itf1.Next()) {
817 Handle(Geom2d_Curve) c2d1, c2d11;
818 const TopoDS_Face& fac1 = TopoDS::Face(itf1.Value());
819
820 TopLoc_Location loc1;
821 Handle(Geom_Surface) surf1 = BRep_Tool::Surface(fac1, loc1);
47980104 822
7fd59977 823 Standard_Real first2d, last2d;
824 Standard_Boolean isSeam1 = ((IsUClosedSurface(surf1,edge1,loc1) || IsVClosedSurface(surf1,edge1,loc1)) &&
67ffcad0 825 BRep_Tool::IsClosed(TopoDS::Edge(edge1),fac1));
7fd59977 826 c2d1 = BRep_Tool::CurveOnSurface(edge1, fac1, first2d, last2d);
827 Ori = edge1.Orientation();
828 if (fac1.Orientation() == TopAbs_REVERSED)
829 Ori = TopAbs::Reverse(Ori);
67ffcad0 830
7fd59977 831 if (isSeam1) {
67ffcad0 832 if (!myNonmanifold) return TopoDS_Edge();
7fd59977 833 TopoDS_Shape aTmpShape = edge1.Reversed(); //for porting
834 c2d11 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aTmpShape), fac1, first2d, last2d);
835 //if(fac1.Orientation() == TopAbs_REVERSED) //
836 if(Ori == TopAbs_FORWARD)
837 aBuilder.UpdateEdge(edge,c2d1,c2d11,fac1,0);
838 else
839 aBuilder.UpdateEdge(edge,c2d11,c2d1,fac1,0);
840 }
841 else aBuilder.UpdateEdge(edge,c2d1,fac1,0);
7fd59977 842
67ffcad0 843 if (c2d1.IsNull() && c2d11.IsNull()) continue;
7fd59977 844
845 if (surf2 == surf1) {
67ffcad0
G
846 // Merge sections which are on the same face
847 if (!loc2.IsDifferent(loc1)) {
848 Standard_Boolean uclosed = IsUClosedSurface(surf2,edge2,loc2);
849 Standard_Boolean vclosed = IsVClosedSurface(surf2,edge2,loc2);
850 if (uclosed || vclosed) {
851 Standard_Real pf = c2d1->FirstParameter();
852 // Standard_Real pl = c2d1->LastParameter();
853 gp_Pnt2d p1n = c2d1->Value(Max(first,pf));
854 // gp_Pnt2d p2n = c2d1->Value(Min(pl,last));
7fd59977 855 gp_Pnt2d p21n = c2d2->Value(Max(first,c2d2->FirstParameter()));
856 gp_Pnt2d p22n = c2d2->Value(Min(last,c2d2->LastParameter()));
857 Standard_Real aDist = Min(p1n.Distance(p21n), p1n.Distance(p22n));
67ffcad0
G
858 Standard_Real U1, U2, V1, V2;
859 surf2->Bounds(U1, U2, V1, V2);
860 isSeam = ((uclosed && aDist > 0.75*(fabs(U2-U1))) ||
861 (vclosed && aDist > 0.75*(fabs(V2-V1))));
7fd59977 862 if( !isSeam && BRep_Tool::IsClosed(TopoDS::Edge(edge),fac1)) continue;
67ffcad0
G
863 }
864 }
7fd59977 865 }
67ffcad0 866
7fd59977 867 isResEdge = Standard_True;
868 if (isSeam) {
869 if (Ori == TopAbs_FORWARD)
870 aBuilder.UpdateEdge(edge, c2d1, c2d2, surf2, loc2, Precision::Confusion());
871 else
872 aBuilder.UpdateEdge(edge, c2d2, c2d1, surf2, loc2, Precision::Confusion());
873 }
874 else if (isSeam2) {
875 TopAbs_Orientation InitOri = edge2.Orientation();
67ffcad0 876 TopAbs_Orientation SecOri = edge.Orientation();
7fd59977 877 if (fac2.Orientation() == TopAbs_REVERSED) {
67ffcad0 878
7fd59977 879 InitOri = TopAbs::Reverse(InitOri);
880 SecOri = TopAbs::Reverse(SecOri);
881 }
882 if(!secForward)
883 InitOri = TopAbs::Reverse(InitOri);
67ffcad0 884
7fd59977 885 if (InitOri == TopAbs_FORWARD)
886 aBuilder.UpdateEdge(edge, c2d2,c2d21, surf2, loc2, Precision::Confusion());
887 else
888 aBuilder.UpdateEdge(edge, c2d21,c2d2, surf2, loc2, Precision::Confusion());
889 }
890 else {
891 aBuilder.UpdateEdge(edge, c2d2, surf2, loc2, Precision::Confusion());
892 }
67ffcad0 893
7fd59977 894 }
895 }
47980104 896 Standard_Real tolReached = Precision::Infinite();
897 Standard_Boolean isSamePar = Standard_False;
2a739b6d 898 try
47980104 899 {
2a739b6d 900 if( isResEdge)
901 SameParameter(edge);
902
903
47980104 904 if( BRep_Tool::SameParameter(edge))
905 {
906 isSamePar = Standard_True;
907 tolReached = BRep_Tool::Tolerance(edge);
908 }
909 }
2a739b6d 910
911 catch(Standard_Failure)
912 {
913 isSamePar = Standard_False;
914 }
47980104 915
916
917 if (firstCall && ( !isResEdge || !isSamePar || tolReached > myTolerance)) {
7fd59977 918 Standard_Integer whichSecn = whichSec;
919 // Try to merge on the second section
47980104 920 Standard_Boolean second_ok = Standard_False;
7fd59977 921 TopoDS_Edge s_edge = SameParameterEdge(edgeFirst,edgeLast,listFacesFirst,listFacesLast,
67ffcad0 922 secForward,whichSecn,Standard_False);
47980104 923 if( !s_edge.IsNull())
924 {
925 Standard_Real tolReached_2 = BRep_Tool::Tolerance(s_edge);
926 second_ok = ( BRep_Tool::SameParameter(s_edge) && tolReached_2 < tolReached );
927 if( second_ok)
928 {
929 edge = s_edge;
930 whichSec = whichSecn;
0221b126 931 tolReached = tolReached_2;
47980104 932 }
7fd59977 933 }
934
47980104 935 if (!second_ok && !edge.IsNull()) {
7fd59977 936
937 GeomAdaptor_Curve c3dAdapt(c3d);
938
939 // Discretize edge curve
0221b126 940 Standard_Integer i, j, nbp = 23;
2a739b6d 941 Standard_Real deltaT = (last3d - first3d) / (nbp -1);
7fd59977 942 TColgp_Array1OfPnt c3dpnt(1,nbp);
0221b126 943 for (i = 1; i <= nbp; i++)
2a739b6d 944 c3dpnt(i) = c3dAdapt.Value(first3d + (i-1)*deltaT);
7fd59977 945
0221b126 946 Standard_Real dist = 0., maxTol = -1.0;
7fd59977 947 Standard_Boolean more = Standard_True;
948
949 for (j = 1; more; j++) {
950 Handle(Geom2d_Curve) c2d2;
67ffcad0 951 BRep_Tool::CurveOnSurface(edge, c2d2, surf2, loc2, first, last, j);
0221b126 952
67ffcad0
G
953 more = !c2d2.IsNull();
954 if (more) {
0221b126 955 Handle(Geom_Surface) aS = surf2;
956 if(!loc2.IsIdentity())
957 aS = Handle(Geom_Surface)::DownCast(surf2->Transformed ( loc2 ));
67ffcad0 958
0221b126 959 Standard_Real dist2 = 0.;
2a739b6d 960 deltaT = (last - first) / (nbp - 1);
67ffcad0 961 for (i = 1; i <= nbp; i++) {
2a739b6d 962 gp_Pnt2d aP2d = c2d2->Value(first + (i -1)*deltaT);
0221b126 963 gp_Pnt aP2(0.,0.,0.);
964 aS->D0(aP2d.X(),aP2d.Y(), aP2);
965 gp_Pnt aP1 = c3dpnt(i);
966 dist = aP2.SquareDistance(aP1);
967 if (dist > dist2)
968 dist2 = dist;
67ffcad0 969 }
0221b126 970 maxTol = Max(sqrt(dist2), Precision::Confusion());
67ffcad0 971 }
7fd59977 972 }
0221b126 973 if(maxTol >= 0. && maxTol < tolReached)
974 aBuilder.UpdateEdge(edge, maxTol);
7fd59977 975 aBuilder.SameParameter(edge,Standard_True);
976 }
977 }
978
979 BRepLib::EncodeRegularity(edge,0.01);
980 Standard_Real tolEdge1 = BRep_Tool::Tolerance(edge);
981 if (tolEdge1 > MaxTolerance()) edge.Nullify();
982 return edge;
983}
984
985//=======================================================================
986// function : EvaluateAngulars
987// purpose : internal use
988//=======================================================================
989
990void BRepBuilderAPI_Sewing::EvaluateAngulars(TopTools_SequenceOfShape& sequenceSec,
991 TColStd_Array1OfBoolean& secForward,
992 TColStd_Array1OfReal& tabAng,
993 const Standard_Integer indRef) const
994{
995 tabAng.Init(-1.0);
996
997 Standard_Integer i, j, npt = 4, lengSec = sequenceSec.Length();
998
999 TopoDS_Edge edge;
1000 TopoDS_Face face;
1001 TopLoc_Location loc;
1002 Standard_Real first, last;
1003 Handle(Geom_Curve) c3d;
1004 Handle(Geom2d_Curve) c2d;
1005 Handle(Geom_Surface) surf;
1006 TColgp_Array1OfVec normRef(1,npt);
1007
1008 for (i = indRef; i <= lengSec; i++) {
1009
1010 edge = TopoDS::Edge(sequenceSec(i));
1011
1012 TopoDS_Shape bnd = edge;
1013 if (mySectionBound.IsBound(bnd)) bnd = mySectionBound(bnd);
1014 if (myBoundFaces.Contains(bnd)) {
1015 face = TopoDS::Face(myBoundFaces.FindFromKey(bnd).First());
1016 surf = BRep_Tool::Surface(face,loc);
1017 if (!loc.IsIdentity()) {
1018 surf = Handle(Geom_Surface)::DownCast(surf->Copy());
1019 surf->Transform(loc.Transformation());
1020 }
1021 c2d = BRep_Tool::CurveOnSurface(edge, face, first, last);
1022 }
1023 else if (i == indRef) return;
1024 else continue;
1025
1026 c3d = BRep_Tool::Curve(edge, loc, first, last);
1027 if (!loc.IsIdentity()) {
1028 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
1029 c3d->Transform(loc.Transformation());
1030 }
1031
1032 GeomAdaptor_Curve adapt(c3d);
1033 GCPnts_UniformAbscissa uniAbs(adapt, npt, first, last);
1034
1035 Standard_Real cumulateAngular = 0.0;
1036 Standard_Integer nbComputedAngle = 0;
1037
1038 for (j = 1; j <= npt; j++) {
1039 gp_Pnt2d P;
1040 c2d->D0(uniAbs.Parameter((secForward(i) || i == indRef)? j : npt-j+1),P);
1041 gp_Vec w1, w2;
1042 gp_Pnt unused;
1043 surf->D1(P.X(), P.Y(), unused, w1, w2);
1044 gp_Vec n = w1^w2; // Compute the normal vector
1045 if (i == indRef) normRef(j) = n;
1046 else if ((n.Magnitude()>gp::Resolution()) && (normRef(j).Magnitude()>gp::Resolution())) {
1047 nbComputedAngle++;
1048 Standard_Real angular = n.Angle(normRef(j));
c6541a0c 1049 if (angular > M_PI/2.) angular = M_PI - angular;
7fd59977 1050 cumulateAngular += angular;
1051 }
1052 }
1053
1054 if (nbComputedAngle)
1055 tabAng(i) = cumulateAngular/((Standard_Real)nbComputedAngle);
1056 }
1057}
1058
1059//=======================================================================
1060// function : EvaluateDistances
1061// purpose : internal use
1062// Evaluate distance beetween edges with indice indRef and the following edges in the list
1063// Remarks (lengSec - indRef) must be >= 1
1064//=======================================================================
7fd59977 1065void BRepBuilderAPI_Sewing::EvaluateDistances(TopTools_SequenceOfShape& sequenceSec,
1066 TColStd_Array1OfBoolean& secForward,
1067 TColStd_Array1OfReal& tabDst,
1068 TColStd_Array1OfReal& arrLen,
1069 TColStd_Array1OfReal& tabMinDist,
1070 const Standard_Integer indRef) const
1071{
1072 secForward.Init(Standard_True);
1073 tabDst.Init(-1.0);
1074 arrLen.Init(0.);
2028d00c 1075 tabMinDist.Init(Precision::Infinite());
7fd59977 1076 const Standard_Integer npt = 8; // Number of points for curve discretization
1077 TColgp_Array1OfPnt ptsRef(1, npt), ptsSec(1, npt);
1078
1079 Standard_Integer i, j, lengSec = sequenceSec.Length();
1080 TColgp_SequenceOfPnt seqSec;
1081
1082 Handle(Geom_Curve) c3dRef;
1083 Standard_Real firstRef=0., lastRef=0.;
67ffcad0 1084
7fd59977 1085 for (i = indRef; i <= lengSec; i++) {
1086
1087 // reading of the edge (attention for the first one: reference)
1088 const TopoDS_Edge& sec = TopoDS::Edge(sequenceSec(i));
1089
1090 TopLoc_Location loc;
1091 Standard_Real first, last;
1092 Handle(Geom_Curve) c3d = BRep_Tool::Curve(sec, loc, first, last);
de10d8b1 1093 if (c3d.IsNull()) continue;
7fd59977 1094 if (!loc.IsIdentity()) {
1095 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
1096 c3d->Transform(loc.Transformation());
1097 }
1098
1099 if (i == indRef) {
1100 c3dRef = c3d; firstRef = first; lastRef = last;
1101 }
1102
2028d00c 1103 Standard_Real dist = Precision::Infinite(), distFor = -1.0, distRev = -1.0;
7fd59977 1104 Standard_Real aMinDist = Precision::Infinite();
1105
1106 Standard_Real T, deltaT = (last - first) / (npt - 1);
1107 Standard_Real aLenSec2 = 0.;
67ffcad0
G
1108
1109 Standard_Integer nbFound = 0;
7fd59977 1110 for (j = 1; j <= npt; j++) {
1111
1112 // Uniform parameter on curve
1113 if (j == 1) T = first;
1114 else if (j == npt) T = last;
1115 else T = first + (j - 1) * deltaT;
1116
1117 // Take point on curve
1118 gp_Pnt pt = c3d->Value(T);
2028d00c 1119
7fd59977 1120 if (i == indRef) {
1121 ptsRef(j) = pt;
2028d00c
G
1122 if(j > 1)
1123 aLenSec2 += pt.SquareDistance(ptsRef(j-1));
7fd59977 1124 }
1125 else {
1126 ptsSec(j) = pt;
1127 //protection to avoid merging with small sections
2028d00c 1128 if(j > 1)
7fd59977 1129 aLenSec2 += pt.SquareDistance(ptsSec(j-1));
1130 // To evaluate mutual orientation and distance
1131 dist = pt.Distance(ptsRef(j));
1132 if(aMinDist > dist)
1133 aMinDist = dist;
1134 if (distFor < dist) distFor = dist;
1135 dist = pt.Distance(ptsRef(npt-j+1));
2028d00c 1136
7fd59977 1137 if(aMinDist > dist)
1138 aMinDist = dist;
1139 if (distRev < dist) distRev = dist;
2028d00c
G
1140
1141 // Check that point lays between vertices of reference curve
1142 const gp_Pnt &p11 = ptsRef(1);
1143 const gp_Pnt &p12 = ptsRef(npt);
1144 const gp_Vec aVec1(pt,p11);
1145 const gp_Vec aVec2(pt,p12);
1146 const gp_Vec aVecRef(p11,p12);
1147 if((aVecRef * aVec1) * (aVecRef * aVec2) < 0.)
1148 nbFound++;
7fd59977 1149 }
1150 }
1151
1152 Standard_Real aLenSec = sqrt(aLenSec2);
1153
1154 //if(aLenSec < myMinTolerance )
1155 // continue;
1156 arrLen.SetValue(i,aLenSec);
1157 // Record mutual orientation
1158 Standard_Boolean isForward = (distFor < distRev); //szv debug: <=
1159 secForward(i) = isForward;
1160
1161 dist = (isForward? distFor : distRev);
2028d00c
G
1162 if(i == indRef || (dist < myTolerance && nbFound >= npt * 0.5) )
1163 {
7fd59977 1164 tabDst(i) = dist;
1165 tabMinDist(i) = aMinDist;
7fd59977 1166 }
2028d00c
G
1167 else
1168 {
1169 nbFound = 0, aMinDist = Precision::Infinite(), dist = -1;
1170 TColgp_Array1OfPnt arrProj(1, npt);
1171 TColStd_Array1OfReal arrDist(1, npt), arrPara(1, npt);
1172 if( arrLen(indRef) >= arrLen(i))
1173 ProjectPointsOnCurve(ptsSec,c3dRef,firstRef,lastRef,arrDist,arrPara,arrProj,Standard_False);
1174 else
1175 ProjectPointsOnCurve(ptsRef,c3d,first,last,arrDist,arrPara,arrProj,Standard_False);
1176 for( j = 1; j <= npt; j++ )
1177 {
2c896b8f 1178 if(arrDist(j) < 0.)
2028d00c
G
1179 continue;
1180 if(dist < arrDist(j))
1181 dist = arrDist(j);
1182 if( aMinDist > arrDist(j))
1183 aMinDist = arrDist(j);
1184 nbFound++;
1185 }
1186 if(nbFound > 1)
1187 {
1188 tabDst(i) = dist;
1189 tabMinDist(i) = aMinDist;
1190 }
7fd59977 1191 }
1192 }
1193
2028d00c 1194 /*
7fd59977 1195 // Project distant points
1196 Standard_Integer nbFailed = seqSec.Length();
1197 if (!nbFailed) return;
1198
1199 TColgp_Array1OfPnt arrPnt(1, nbFailed), arrProj(1, nbFailed);
1200 for (i = 1; i <= nbFailed; i++) arrPnt(i) = seqSec(i); seqSec.Clear();
1201 TColStd_Array1OfReal arrDist(1, nbFailed), arrPara(1, nbFailed);
1202
2028d00c 1203 ProjectPointsOnCurve(arrPnt,c3dRef,firstRef,lastRef,arrDist,arrPara,arrProj,Standard_False);
7fd59977 1204
1205 // Process distant sections
1206 Standard_Integer idx1 = 1;
1207 for (i = indRef + 1; i <= lengSec; i++) {
1208
1209 // Skip section if already evaluated
1210 if (tabDst(i) >= 0.0) continue;
1211
1212 Standard_Real dist, distMax = -1.0, aMinDist = Precision::Infinite();
1213
1214 Standard_Integer idx2 = (idx1 - 1)*npt;
1215
1216 for (j = 1; j <= npt; j++) {
1217
1218 dist = arrDist(idx2 + j);
1219 // If point is not projected - stop evaluation
1220 if (dist < 0.0) { distMax = -1.0; break; }
1221 if (distMax < dist) distMax = dist;
1222 if(aMinDist > dist) aMinDist = dist;
1223 }
1224
1225 // If section is close - record distance
1226 if (distMax >= 0.0) {
1227 if (secForward(i)) {
1228 dist = arrPnt(idx2+1).Distance(ptsRef(1));
1229 if (distMax < dist) distMax = dist;
1230 if(aMinDist > dist) aMinDist = dist;
1231 dist = arrPnt(idx2+npt).Distance(ptsRef(npt));
1232 if (distMax < dist) distMax = dist;
1233 if(aMinDist > dist) aMinDist = dist;
1234 }
1235 else {
1236 dist = arrPnt(idx2+1).Distance(ptsRef(npt));
1237 if (distMax < dist) distMax = dist;
1238 if(aMinDist > dist) aMinDist = dist;
1239 dist = arrPnt(idx2+npt).Distance(ptsRef(1));
1240 if (distMax < dist) distMax = dist;
1241 if(aMinDist > dist) aMinDist = dist;
1242 }
1243
1244 if (distMax < myTolerance)
1245 {
1246 tabDst(i) = distMax;
1247 tabMinDist(i) = aMinDist;
1248 }
1249 }
1250
1251 idx1++; // To the next distant curve
2028d00c 1252 }*/
7fd59977 1253}
1254
1255//=======================================================================
1256//function : IsMergedClosed
1257//purpose : internal use
1258//=======================================================================
1259
1260Standard_Boolean BRepBuilderAPI_Sewing::IsMergedClosed(const TopoDS_Edge& Edge1,
1261 const TopoDS_Edge& Edge2,
1262 const TopoDS_Face& face) const
1263{
1264 // Check for closed surface
1265 TopLoc_Location loc;
1266 Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc);
1267 Standard_Boolean isUClosed = IsUClosedSurface(surf,Edge1,loc);
1268 Standard_Boolean isVClosed = IsVClosedSurface(surf,Edge1,loc);
1269 if (!isUClosed && !isVClosed) return Standard_False;
1270 // Check condition on closed surface
1271 /*
1272 Standard_Real first1,last1,first2,last2;
1273 Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(Edge1,first1,last1);
1274 Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(Edge2,first2,last2);
1275 if (C3d1.IsNull() || C3d2.IsNull()) return Standard_False;
1276 */
1277 Standard_Real first2d1,last2d1,first2d2,last2d2;
1278 Handle(Geom2d_Curve) C2d1 = BRep_Tool::CurveOnSurface(Edge1,face,first2d1,last2d1);
1279 Handle(Geom2d_Curve) C2d2 = BRep_Tool::CurveOnSurface(Edge2,face,first2d2,last2d2);
1280 if (C2d1.IsNull() || C2d2.IsNull()) return Standard_False;
1281 /*
1282 gp_Pnt p1 = C3d1->Value(0.5*(first1 + last1));
1283 gp_Pnt p2 = C3d1->Value(0.5*(first2 + last2));
1284 Standard_Real dist = p1.Distance(p2);
1285 gp_Pnt2d p12d = C2d1->Value(0.5*(first2d1 + last2d1));
1286 gp_Pnt2d p22d = C2d1->Value(0.5*(first2d2 + last2d2));
1287 Standard_Real dist2d = p12d.Distance(p22d);
1288 GeomAdaptor_Surface Ads(BRep_Tool::Surface(face));
1289 Standard_Real distSurf = Max(Ads.UResolution(dist), Ads.VResolution(dist));
1290 return (dist2d*0.2 >= distSurf);
1291 */
1292 Standard_Integer isULongC1, isULongC2, isVLongC1, isVLongC2;
1293 Standard_Real SUmin, SUmax, SVmin, SVmax;
1294 Standard_Real C1Umin, C1Vmin, C1Umax, C1Vmax;
1295 Standard_Real C2Umin, C2Vmin, C2Umax, C2Vmax;
1296 { //szv: Use brackets to destroy local variables
1297 Bnd_Box2d B1, B2;
1298 Geom2dAdaptor_Curve aC2d1(C2d1), aC2d2(C2d2);
1299 BndLib_Add2dCurve::Add(aC2d1,first2d1,last2d1,Precision::PConfusion(),B1);
1300 BndLib_Add2dCurve::Add(aC2d2,first2d2,last2d2,Precision::PConfusion(),B2);
1301 B1.Get(C1Umin,C1Vmin,C1Umax,C1Vmax);
1302 B2.Get(C2Umin,C2Vmin,C2Umax,C2Vmax);
1303 Standard_Real du, dv;
1304 du = (C1Umax - C1Umin); dv = (C1Vmax - C1Vmin);
1305 isULongC1 = (dv <= du); isVLongC1 = (du <= dv);
1306 du = (C2Umax - C2Umin); dv = (C2Vmax - C2Vmin);
1307 isULongC2 = (dv <= du); isVLongC2 = (du <= dv);
1308 surf->Bounds(SUmin,SUmax,SVmin,SVmax);
1309 }
1310 if (isUClosed && isVLongC1 && isVLongC2) {
1311 // Do not merge if not overlapped by V
1312 Standard_Real dist = Max((C2Vmin - C1Vmax),(C1Vmin - C2Vmax));
1313 if (dist < 0.0) {
1314 Standard_Real distInner = Max((C2Umin - C1Umax),(C1Umin - C2Umax));
1315 Standard_Real distOuter = (SUmax - SUmin) - Max((C2Umax - C1Umin),(C1Umax - C2Umin));
1316 if (distOuter <= distInner) return Standard_True;
1317 }
1318 }
1319 if (isVClosed && isULongC1 && isULongC2) {
1320 // Do not merge if not overlapped by U
1321 Standard_Real dist = Max((C2Umin - C1Umax),(C1Umin - C2Umax));
1322 if (dist < 0.0) {
1323 Standard_Real distInner = Max((C2Vmin - C1Vmax),(C1Vmin - C2Vmax));
1324 Standard_Real distOuter = (SVmax - SVmin) - Max((C2Vmax - C1Vmin),(C1Vmax - C2Vmin));
1325 if (distOuter <= distInner) return Standard_True;
1326 }
1327 }
1328 return Standard_False;
1329}
1330
1331//=======================================================================
1332//function : AnalysisNearestEdges
1333//purpose :
1334//=======================================================================
1335
1336void BRepBuilderAPI_Sewing::AnalysisNearestEdges(const TopTools_SequenceOfShape& sequenceSec,
1337 TColStd_SequenceOfInteger& seqIndCandidate,
dde68833 1338 TColStd_SequenceOfBoolean& seqOrientations,
7fd59977 1339 const Standard_Boolean evalDist)
1340{
1341
1342 Standard_Integer workIndex = seqIndCandidate.First();
1343 TopoDS_Shape workedge = sequenceSec.Value(workIndex);
1344 TopoDS_Shape bnd = workedge;
1345 TopTools_ListOfShape workfaces;
1346 if (mySectionBound.IsBound(bnd)) bnd = mySectionBound(bnd);
1347 if (myBoundFaces.Contains(bnd))
1348 workfaces = myBoundFaces.FindFromKey(bnd);
1349 if(workfaces.IsEmpty()) return;
1350 TopTools_MapOfShape mapFaces;
1351 TopTools_ListIteratorOfListOfShape lIt;
1352 for (lIt.Initialize(workfaces); lIt.More(); lIt.Next())
1353 mapFaces.Add(lIt.Value());
1354 TColStd_SequenceOfInteger seqNotCandidate;
1355 TColStd_SequenceOfInteger seqNewForward;
1356 // Separates edges belonging the same face as work edge
1357 // for exception of edges belonging closed faces
1358
1359 seqNotCandidate.Append(workIndex);
1360 for(Standard_Integer i = 1; i<= seqIndCandidate.Length(); ) {
1361 Standard_Integer index = seqIndCandidate.Value(i);
1362 Standard_Boolean isRemove = Standard_False;
1363 if(index == workIndex) {
1364 seqIndCandidate.Remove(i);
1365 seqOrientations.Remove(i);
1366 isRemove = Standard_True;
1367 }
1368 if(!isRemove) {
1369 TopoDS_Shape bnd2 = sequenceSec.Value(index);
1370 if (mySectionBound.IsBound(bnd2)) bnd2 = mySectionBound(bnd2);
1371
1372 if(myBoundFaces.Contains(bnd2)) {
1373 const TopTools_ListOfShape& listfaces = myBoundFaces.FindFromKey(bnd2);
1374 Standard_Boolean isMerged = Standard_True;
1375 for (lIt.Initialize(listfaces); lIt.More() && isMerged; lIt.Next()) {
1376 if(mapFaces.Contains(lIt.Value())) {
1377 TopLoc_Location loc;
1378 Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(lIt.Value()),loc);
1379 isMerged = ((IsUClosedSurface(surf,bnd2,loc) || IsVClosedSurface(surf,bnd2,loc)) &&
1380 IsMergedClosed(TopoDS::Edge(sequenceSec.Value(index)),TopoDS::Edge(workedge),TopoDS::Face(lIt.Value())));
1381 }
1382 }
1383 if(!isMerged) {
1384 seqNotCandidate.Append(index);
1385 seqIndCandidate.Remove(i);
1386 seqOrientations.Remove(i);
1387 isRemove = Standard_True;
1388 }
1389 }
1390 else {
1391 seqIndCandidate.Remove(i);
1392 seqOrientations.Remove(i);
1393 isRemove = Standard_True;
1394 }
1395 }
1396 if(!isRemove) i++;
1397 }
1398 if(seqIndCandidate.Length() == 0 || seqNotCandidate.Length() == 1) return;
1399 if(!evalDist) return;
1400 TColStd_Array2OfReal TotTabDist(1,seqNotCandidate.Length(),1,seqIndCandidate.Length());
1401 TColStd_MapOfInteger MapIndex;
1402 TColStd_SequenceOfInteger seqForward;
1403
1404 // Definition and removing edges wich are not candidate for work edge
1405 // ( they have other nearest edges belonging to the work face)
1406 for(Standard_Integer k = 1; k<= seqNotCandidate.Length(); k++) {
1407 Standard_Integer index1 = seqNotCandidate.Value(k);
1408 TopoDS_Shape edge = sequenceSec.Value(index1);
1409 TopTools_SequenceOfShape tmpSeq;
1410 tmpSeq.Append(edge);
1411 for(Standard_Integer kk = 1; kk <= seqIndCandidate.Length();kk++)
1412 tmpSeq.Append(sequenceSec.Value(seqIndCandidate.Value(kk)));
1413
1414 Standard_Integer lengSec = tmpSeq.Length();
1415 TColStd_Array1OfBoolean tabForward(1,lengSec);
1416 TColStd_Array1OfReal tabDist(1,lengSec);
1417 TColStd_Array1OfReal arrLen(1,lengSec);
1418 TColStd_Array1OfReal tabMinDist(1,lengSec);
1419 for (Standard_Integer i1 = 1 ; i1 <= lengSec; i1++)
1420 tabDist(i1) =-1;
1421
1422 EvaluateDistances(tmpSeq,tabForward, tabDist,arrLen,tabMinDist,1 );
1423 if(k == 1) {
1424 for(Standard_Integer n = 1; n < lengSec; n++) {
1425 if(tabDist(n+1) == -1 || tabDist(n+1) > myTolerance) {
1426 MapIndex.Add(n);
1427 continue;
1428 }
1429 TotTabDist(k,n) = tabDist(n+1 );
1430 seqForward.Append(tabForward(n+1) ? 1:0);
1431 }
1432 }
1433 else {
1434 for(Standard_Integer n = 1; n < lengSec; n++) {
1435 if(tabDist(n) == -1 || tabDist(n) > myTolerance) continue;
1436 if(tabDist(n+1) < TotTabDist(1,n)) {
1437 MapIndex.Add(n);
1438 }
1439 }
1440 }
1441
1442 }
1443
1444 Standard_Integer i2 = seqIndCandidate.Length();
1445 for( ; i2 >=1 ; i2--)
1446 {
1447 if(MapIndex.Contains(i2))
1448 {
1449 seqIndCandidate.Remove(i2);
1450 seqOrientations.Remove(i2);
1451 }
1452
1453 }
1454 //for(TColStd_MapIteratorOfMapOfInteger IMap(MapIndex); IMap.More(); IMap.Next()) {
1455 // seqIndCandidate.Remove(IMap.Key());
1456 // seqOrientations.Remove(IMap.Key());
1457 //}
1458}
1459
1460//=======================================================================
1461//function : FindCandidates
1462//purpose : internal use
1463//=======================================================================
1464
1465Standard_Boolean BRepBuilderAPI_Sewing::FindCandidates(TopTools_SequenceOfShape& seqSections,
1466 TColStd_IndexedMapOfInteger& mapReference,
1467 TColStd_SequenceOfInteger& seqCandidates,
dde68833 1468 TColStd_SequenceOfBoolean& seqOrientations)
7fd59977 1469{
1470 Standard_Integer i, nbSections = seqSections.Length();
1471 if(nbSections <= 1)
1472 return Standard_False;
1473 // Retrieve last reference index
1474 Standard_Integer indReference = mapReference(mapReference.Extent());
1475 Standard_Integer nbCandidates = 0;
1476 TopTools_MapOfShape Faces1;
1477 //if (nbSections > 1) {
1478
1479 TopoDS_Edge Edge1 = TopoDS::Edge(seqSections(indReference));
1480
1481 // Retrieve faces for reference section
1482
1483 { //szv: Use brackets to destroy local variables
1484 TopoDS_Shape bnd = Edge1;
1485 if (mySectionBound.IsBound(bnd)) bnd = mySectionBound(bnd);
1486 if (myBoundFaces.Contains(bnd)) {
1487 TopTools_ListIteratorOfListOfShape itf1(myBoundFaces.FindFromKey(bnd));
1488 for (; itf1.More(); itf1.Next()) Faces1.Add(itf1.Value());
1489 }
1490 }
1491
1492 // Check merging conditions for candidates and remove unsatisfactory
1493 TopTools_SequenceOfShape seqSectionsNew;
1494 TColStd_SequenceOfInteger seqCandidatesNew;
1495 for (i = 1; i <= nbSections; i++) {
1496 if (i == indReference) {
1497 seqSectionsNew.Prepend(Edge1);
1498 seqCandidatesNew.Prepend(i);
1499 }
1500 else {
1501 const TopoDS_Edge& Edge2 = TopoDS::Edge(seqSections(i));
7fd59977 1502 seqSectionsNew.Append(Edge2);
1503 seqCandidatesNew.Append(i);
7fd59977 1504 }
1505 }
1506
1507 Standard_Integer nbSectionsNew = seqSectionsNew.Length();
1508 if (nbSectionsNew > 1) {
5a29f57e 1509
7fd59977 1510 // Evaluate distances between reference and other sections
1511 TColStd_Array1OfBoolean arrForward(1,nbSectionsNew);
1512 TColStd_Array1OfReal arrDistance(1,nbSectionsNew);
1513 TColStd_Array1OfReal arrLen(1,nbSectionsNew);
1514 TColStd_Array1OfReal arrMinDist(1,nbSectionsNew);
1515 EvaluateDistances(seqSectionsNew,arrForward,arrDistance,arrLen,arrMinDist,1);
5a29f57e 1516
7fd59977 1517 // Fill sequence of candidate indices sorted by distance
1518 for (i = 2; i <= nbSectionsNew; i++) {
5a29f57e 1519 Standard_Real aMaxDist = arrDistance(i);
1520 if (aMaxDist >= 0.0 && aMaxDist <= myTolerance && arrLen(i) > myMinTolerance) {
1521
7fd59977 1522 // Reference section is connected to section #i
1523 Standard_Boolean isInserted = Standard_False;
dde68833 1524 Standard_Boolean ori = arrForward(i);
1525 for (Standard_Integer j = 1; (j <= seqCandidates.Length()) && !isInserted; j++) {
7fd59977 1526 Standard_Real aDelta = arrDistance(i) - arrDistance(seqCandidates.Value(j));
5a29f57e 1527
7fd59977 1528 if( aDelta < Precision::Confusion()) {
1529
1530 if(fabs(aDelta) > RealSmall() ||
1531 arrMinDist(i) < arrMinDist(seqCandidates.Value(j)))
1532 {
1533 seqCandidates.InsertBefore(j,i);
1534 seqOrientations.InsertBefore(j,ori);
1535 isInserted = Standard_True;
1536 }
1537 }
1538 }
1539 if (!isInserted) {
1540 seqCandidates.Append(i);
1541 seqOrientations.Append(ori);
1542 }
1543 }
1544 }
5a29f57e 1545
7fd59977 1546 nbCandidates = seqCandidates.Length();
5a29f57e 1547 if (!nbCandidates)
1548 return Standard_False; // Section has no candidates to merge
1549
1550 // Replace candidate indices
1551
7fd59977 1552 for (i = 1; i <= nbCandidates; i++)
1553 seqCandidates(i) = seqCandidatesNew(seqCandidates(i));
5a29f57e 1554
7fd59977 1555 }
5a29f57e 1556
7fd59977 1557 if (!nbCandidates) return Standard_False; // Section has no candidates to merge
1558
1559 if (myNonmanifold && nbCandidates >1) {
1560 TColStd_SequenceOfInteger seqNewCandidates;
dde68833 1561 TColStd_SequenceOfBoolean seqOrientationsNew;
7fd59977 1562 seqCandidates.Prepend(1);
dde68833 1563 seqOrientations.Prepend(Standard_True);
7fd59977 1564 for(Standard_Integer k = 1; k <= seqSections.Length() && seqCandidates.Length() > 1 ; k++) {
1565 AnalysisNearestEdges(seqSections,seqCandidates,seqOrientations,(k==1));
1566 if(k == 1 && !seqCandidates.Length()) return Standard_False;
1567 if(seqCandidates.Length()) {
1568 seqNewCandidates.Append(seqCandidates.First());
1569 seqOrientationsNew.Append(seqOrientations.First());
1570 }
1571 }
1572 seqCandidates.Prepend(seqNewCandidates);
1573 seqOrientations.Prepend(seqOrientationsNew);
1574 return Standard_True;
1575 }
1576 else {
1577
1578 // For manifold case leave only one candidate from equidistant candidates
1579 /*Standard_Integer minIndex = seqCandidateIndex.First();
1580 Standard_Real minDistance = arrDistance(minIndex);
1581
1582 // Find equidistant candidates
1583 TColStd_SequenceOfInteger seqEqDistantIndex; seqEqDistantIndex.Append(1);
1584 for (i = 2; i <= nbCandidates; i++) {
1585 Standard_Integer index = seqCandidateIndex(i);
1586 if (Abs(minDistance - arrDistance(index)) <= Precision::Confusion())
1587 seqEqDistantIndex.Append(index);
1588 }
1589
1590 Standard_Integer eqLen = seqEqDistantIndex.Length();
1591 if (eqLen > 2) {
1592
1593 // Fill map of faces which equidistant sections belong to
1594 TopTools_MapOfShape mapFace;
1595 for (i = 1; i <= eqLen; i++) {
1596 Standard_Integer index = seqEqDistantIndex.Value(i);
1597 if (isCandidate(index)) {
1598 mapFace.Add(arrFace(index));
1599 }
1600 }
1601
1602 // Non Manifold case
1603 // Edges are merged by pair among a face continuity C1 criterion
1604 if (mapFace.Extent() == eqLen) {
1605
1606 tabDist.Init(-1);
1607 tabMinInd.Init(-1);
1608 min=10000000.;
1609 //indMin = -1;
1610 Standard_Integer indMin = -1;// To check if the edge can be merged.
1611 // Computation of distances between the edges.
1612 TopTools_SequenceOfShape seqSh;
1613 Standard_Integer nbInd = EqDistSeq.Length();
1614 TColStd_Array1OfBoolean tmptabForward(1,nbInd);
1615 seqSh.Append(sequenceSec.Value(1));
1616 for (j = 2; j <= EqDistSeq.Length(); j++) {
1617 Standard_Integer index = EqDistSeq.Value(j);
1618 tmptabForward(j) = tabForward(index);
1619 seqSh.Append(sequenceSec.Value(index));
1620 }
1621
1622 EvaluateAngulars(seqSh, tmptabForward, tabDist,1);
1623
1624 for(j=2; j <= seqSh.Length(); j++) {
1625 if (tabDist(j) > -1.) { // if edge(j) is connected to edge(i)
1626 if (min > tabDist(j)) {
1627 min = tabDist(j);
1628 indMin = j;
1629 }
1630 }
1631 }
1632
1633 // Construct minDist, tabMinInd , tabMinForward(i) = tabForward(j);
1634 if (indMin > 0) {
1635 seqSh.Remove(indMin);
1636 for(j =2; j <= tmpSeq.Length(); ) {
1637 TopoDS_Shape sh = tmpSeq.Value(j);
1638 Standard_Boolean isRem = Standard_False;
1639 for(Standard_Integer k = 1; k<= seqSh.Length();k++) {
1640 if(seqSh.Value(k) == sh) {
1641 isRem = Standard_True;
1642 break;
1643 }
1644 }
1645 if(isRem) {
1646 tmpSeq.Remove(j);
1647 tabMinForward.Remove(j); // = -1;
1648 }
1649 else j++;
1650 }
1651 }
1652 }
1653 }*/
1654
1655 // Find the best approved candidate
1656 while (nbCandidates) {
1657 // Retrieve first candidate
1658 Standard_Integer indCandidate = seqCandidates.First();
1659 // Candidate is approved if it is in the map
1660 if (mapReference.Contains(indCandidate)) break;
1661 // Find candidates for candidate #indCandidate
1662 mapReference.Add(indCandidate); // Push candidate in the map
dde68833 1663 TColStd_SequenceOfInteger seqCandidates1;
1664 TColStd_SequenceOfBoolean seqOrientations1;
7fd59977 1665 Standard_Boolean isFound =
1666 FindCandidates(seqSections,mapReference,seqCandidates1,seqOrientations1);
1667 mapReference.RemoveLast(); // Pop candidate from the map
1668 if (isFound) isFound = (seqCandidates1.Length() > 0);
1669 if (isFound) {
1670 Standard_Integer indCandidate1 = seqCandidates1.First();
1671 // If indReference is the best candidate for indCandidate
1672 // then indCandidate is the best candidate for indReference
1673 if (indCandidate1 == indReference) break;
1674 // If some other reference in the map is the best candidate for indCandidate
1675 // then assume that reference is the best candidate for indReference
1676 if (mapReference.Contains(indCandidate1)) {
1677 seqCandidates.Prepend(indCandidate1);
1678 nbCandidates++;
1679 break;
1680 }
1681 isFound = Standard_False;
1682 }
1683 if (!isFound) {
1684 // Remove candidate #1
1685 seqCandidates.Remove(1);
1686 seqOrientations.Remove(1);
1687 nbCandidates--;
1688 }
1689 }
1690 }
1691 //gka
1692 if(nbCandidates > 0)
1693 {
1694 Standard_Integer anInd = seqCandidates.Value(1);
1695 TopoDS_Edge Edge2 = TopoDS::Edge(seqSections(anInd));
1696 TopoDS_Shape bnd = Edge2;
1697 if (mySectionBound.IsBound(bnd))
1698 bnd = mySectionBound(bnd);
1699 //gka
1700 if (myBoundFaces.Contains(bnd)) {
1701 Standard_Boolean isOK = Standard_True;
1702 TopTools_ListIteratorOfListOfShape itf2(myBoundFaces.FindFromKey(bnd));
1703 for (; itf2.More() && isOK; itf2.Next()) {
1704 const TopoDS_Face& Face2 = TopoDS::Face(itf2.Value());
1705 // Check whether condition is satisfied
1706 isOK = !Faces1.Contains(Face2);
1707 if (!isOK) isOK = IsMergedClosed(Edge1,Edge2,Face2);
1708 }
1709 if(!isOK)
1710 return Standard_False;
1711 }
1712 }
1713 return (nbCandidates > 0);
1714}
1715
1716//=======================================================================
1717//function : Constructor
1718//purpose :
1719//=======================================================================
1720
1721BRepBuilderAPI_Sewing::BRepBuilderAPI_Sewing(const Standard_Real tolerance,
1722 const Standard_Boolean optionSewing,
1723 const Standard_Boolean optionAnalysis,
1724 const Standard_Boolean optionCutting,
1725 const Standard_Boolean optionNonmanifold)
1726{
1727 myReShape = new BRepTools_ReShape;
1728 Init(tolerance, optionSewing, optionAnalysis, optionCutting, optionNonmanifold);
1729}
1730
1731//=======================================================================
1732//function : Init
1733//purpose : Initialise Talerance, and options sewing, faceAnalysis and cutting
1734//=======================================================================
1735
1736void BRepBuilderAPI_Sewing::Init(const Standard_Real tolerance,
1737 const Standard_Boolean optionSewing,
1738 const Standard_Boolean optionAnalysis,
1739 const Standard_Boolean optionCutting,
1740 const Standard_Boolean optionNonmanifold)
1741{
1742 // Set tolerance and Perform options
eb7c351a 1743 myTolerance = Max (tolerance, Precision::Confusion());
7fd59977 1744 mySewing = optionSewing;
1745 myAnalysis = optionAnalysis;
1746 myCutting = optionCutting;
1747 myNonmanifold = optionNonmanifold;
1748 // Set min and max tolerances
eb7c351a 1749 myMinTolerance = myTolerance * 1e-4; //szv: proposal
7fd59977 1750 if (myMinTolerance < Precision::Confusion()) myMinTolerance = Precision::Confusion();
1751 myMaxTolerance = Precision::Infinite();
1752 // Set other modes
1753 myFaceMode = Standard_True;
1754 myFloatingEdgesMode = Standard_False;
1755 //myCuttingFloatingEdgesMode = Standard_False; //gka
1756 mySameParameterMode = Standard_True;
1757 myLocalToleranceMode = Standard_False;
1758 mySewedShape.Nullify();
1759 // Load empty shape
1760 Load(TopoDS_Shape());
1761}
1762
1763//=======================================================================
1764//function : Load
1765//purpose : Loads the context shape
1766//=======================================================================
1767
1768void BRepBuilderAPI_Sewing::Load(const TopoDS_Shape& theShape)
1769{
1770 myReShape->Clear();
1771 if (theShape.IsNull()) myShape.Nullify();
1772 else myShape = myReShape->Apply(theShape);
1773 mySewedShape.Nullify();
1774 // Nullify flags and counters
1775 myNbShapes = myNbEdges = myNbVertices = 0;
1776 // Clear all maps
1777 myOldShapes.Clear();
1778 //myOldFaces.Clear();
1779 myDegenerated.Clear();
1780 myFreeEdges.Clear();
1781 myMultipleEdges.Clear();
1782 myContigousEdges.Clear();
1783 myContigSecBound.Clear();
1784 myBoundFaces.Clear();
1785 myBoundSections.Clear();
1786 myVertexNode.Clear();
1787 myVertexNodeFree.Clear();
1788 myNodeSections.Clear();
1789 myCuttingNode.Clear();
1790 mySectionBound.Clear();
1791 myLittleFace.Clear();
1792}
1793
1794//=======================================================================
1795//function : Add
1796//purpose :
1797//=======================================================================
1798
1799void BRepBuilderAPI_Sewing::Add(const TopoDS_Shape& aShape)
1800{
1801 if (aShape.IsNull()) return;
1802 TopoDS_Shape oShape = myReShape->Apply(aShape);
1803 myOldShapes.Add(aShape,oShape);
1804 myNbShapes = myOldShapes.Extent();
1805}
1806
1807//=======================================================================
1808//function : Perform
1809//purpose :
1810//=======================================================================
1811
0797d9d3 1812#ifdef OCCT_DEBUG
7fd59977 1813#include <OSD_Timer.hxx>
1814#endif
1815
92434a36 1816void BRepBuilderAPI_Sewing::Perform(const Handle(Message_ProgressIndicator)& thePI)
7fd59977 1817{
92434a36
A
1818 const Standard_Integer aNumberOfStages = myAnalysis + myCutting + mySewing + 2;
1819 Message_ProgressSentry aPS (thePI, "Sewing", 0, aNumberOfStages, 1);
0797d9d3 1820#ifdef OCCT_DEBUG
7fd59977 1821 Standard_Real t_total = 0., t_analysis = 0., t_assembling = 0., t_cutting = 0., t_merging = 0.;
1822 OSD_Chronometer chr_total, chr_local;
1823 chr_total.Reset();
1824 chr_total.Start();
1825#endif
1826
1827 // face analysis
92434a36
A
1828 if (myAnalysis)
1829 {
0797d9d3 1830#ifdef OCCT_DEBUG
7fd59977 1831 cout << "Begin face analysis..." << endl;
1832 chr_local.Reset();
1833 chr_local.Start();
1834#endif
92434a36
A
1835 FaceAnalysis (thePI);
1836 if (!aPS.More())
1837 return;
1838 aPS.Next();
0797d9d3 1839#ifdef OCCT_DEBUG
7fd59977 1840 chr_local.Stop();
1841 chr_local.Show(t_analysis);
1842 cout << "Face analysis finished after " << t_analysis << " s" << endl;
1843#endif
1844 }
1845
92434a36
A
1846 if (myNbShapes || !myShape.IsNull())
1847 {
7fd59977 1848
1849 FindFreeBoundaries();
1850
92434a36
A
1851 if (myBoundFaces.Extent())
1852 {
7fd59977 1853
0797d9d3 1854#ifdef OCCT_DEBUG
7fd59977 1855 cout << "Begin vertices assembling..." << endl;
1856 chr_local.Reset();
1857 chr_local.Start();
1858#endif
92434a36
A
1859 VerticesAssembling (thePI);
1860 if (!aPS.More())
1861 return;
1862 aPS.Next();
0797d9d3 1863#ifdef OCCT_DEBUG
7fd59977 1864 chr_local.Stop();
1865 chr_local.Show(t_assembling);
1866 cout << "Vertices assembling finished after " << t_assembling << " s" << endl;
1867#endif
92434a36
A
1868 if (myCutting)
1869 {
0797d9d3 1870#ifdef OCCT_DEBUG
92434a36
A
1871 cout << "Begin cutting..." << endl;
1872 chr_local.Reset();
1873 chr_local.Start();
7fd59977 1874#endif
92434a36
A
1875 Cutting (thePI);
1876 if (!aPS.More())
1877 return;
1878 aPS.Next();
0797d9d3 1879#ifdef OCCT_DEBUG
92434a36
A
1880 chr_local.Stop();
1881 chr_local.Show(t_cutting);
1882 cout << "Cutting finished after " << t_cutting << " s" << endl;
7fd59977 1883#endif
1884 }
0797d9d3 1885#ifdef OCCT_DEBUG
7fd59977 1886 cout << "Begin merging..." << endl;
1887 chr_local.Reset();
1888 chr_local.Start();
1889#endif
92434a36
A
1890 Merging (Standard_True, thePI);
1891 if (!aPS.More())
1892 return;
1893 aPS.Next();
0797d9d3 1894#ifdef OCCT_DEBUG
7fd59977 1895 chr_local.Stop();
1896 chr_local.Show(t_merging);
1897 cout << "Merging finished after " << t_merging << " s" << endl;
1898#endif
1899 }
92434a36
A
1900 else
1901 {
1902 aPS.Next( 1, Handle(TCollection_HAsciiString)());
1903 if (myCutting)
1904 aPS.Next( 1, Handle(TCollection_HAsciiString)());
1905 aPS.Next( 1, Handle(TCollection_HAsciiString)());
1906 if (!aPS.More())
1907 return;
1908 }
7fd59977 1909
92434a36
A
1910 if (mySewing)
1911 {
7fd59977 1912
0797d9d3 1913#ifdef OCCT_DEBUG
7fd59977 1914 cout << "Creating sewed shape..." << endl;
1915#endif
1916 // examine the multiple edges if any and process sameparameter for edges if necessary
92434a36
A
1917 EdgeProcessing (thePI);
1918 if (!aPS.More())
1919 return;
7fd59977 1920 CreateSewedShape();
92434a36
A
1921 if (!aPS.More())
1922 {
1923 mySewedShape.Nullify();
1924 return;
1925 }
1926 if (mySameParameterMode && myFaceMode)
1927 SameParameterShape();
1928 if (!aPS.More())
1929 {
1930 mySewedShape.Nullify();
1931 return;
1932 }
0797d9d3 1933#ifdef OCCT_DEBUG
7fd59977 1934 cout << "Sewed shape created" << endl;
1935#endif
1936 }
92434a36 1937
7fd59977 1938 // create edge informations for output
1939 CreateOutputInformations();
92434a36
A
1940 if (!aPS.More())
1941 {
1942 mySewedShape.Nullify();
1943 return;
1944 }
7fd59977 1945 }
0797d9d3 1946#ifdef OCCT_DEBUG
7fd59977 1947 chr_total.Stop();
1948 chr_total.Show(t_total);
1949 cout << "Sewing finished!" << endl;
1950 cout << " analysis time : " << t_analysis << " s" << endl;
1951 cout << " assembling time : " << t_assembling << " s" << endl;
1952 cout << " cutting time : " << t_cutting << " s" << endl;
1953 cout << " merging time : " << t_merging << " s" << endl;
1954 cout << "Total time : " << t_total << " s" << endl;
1955#endif
1956}
1957
1958//=======================================================================
1959//function : SewedShape
1960//purpose : give the sewed shape
1961// if a null shape, reasons:
1962// -- no useable input shapes : all input shapes are degenerated
1963// -- has multiple edges
1964//=======================================================================
1965
1966const TopoDS_Shape& BRepBuilderAPI_Sewing::SewedShape() const
1967{
1968 return mySewedShape;
1969}
1970
1971//=======================================================================
1972//function : NbFreeEdges
1973//purpose :
1974//=======================================================================
1975
1976Standard_Integer BRepBuilderAPI_Sewing::NbFreeEdges() const
1977{
1978 return myFreeEdges.Extent();
1979}
1980
1981//=======================================================================
1982//function : FreeEdge
1983//purpose :
1984//=======================================================================
1985
1986const TopoDS_Edge& BRepBuilderAPI_Sewing::FreeEdge(const Standard_Integer index) const
1987{
1988 Standard_OutOfRange_Raise_if(index < 0 || index > NbFreeEdges(), "BRepBuilderAPI_Sewing::FreeEdge");
1989 return TopoDS::Edge(myFreeEdges(index));
1990}
1991
1992//=======================================================================
1993//function : NbMultipleEdges
1994//purpose :
1995//=======================================================================
1996
1997Standard_Integer BRepBuilderAPI_Sewing::NbMultipleEdges() const
1998{
1999 return myMultipleEdges.Extent();
2000}
2001
2002//=======================================================================
2003//function : MultipleEdge
2004//purpose :
2005//=======================================================================
2006
2007const TopoDS_Edge& BRepBuilderAPI_Sewing::MultipleEdge(const Standard_Integer index) const
2008{
2009 Standard_OutOfRange_Raise_if(index < 0 || index > NbMultipleEdges(), "BRepBuilderAPI_Sewing::MultipleEdge");
2010 return TopoDS::Edge(myMultipleEdges(index));
2011}
2012
2013//=======================================================================
2014//function : NbContigousEdges
2015//purpose :
2016//=======================================================================
2017
2018Standard_Integer BRepBuilderAPI_Sewing::NbContigousEdges() const
2019{
2020 return myContigousEdges.Extent();
2021}
2022
2023//=======================================================================
2024//function : ContigousEdge
2025//purpose :
2026//=======================================================================
2027
2028const TopoDS_Edge& BRepBuilderAPI_Sewing::ContigousEdge(const Standard_Integer index) const
2029{
2030 Standard_OutOfRange_Raise_if(index < 0 || index > NbContigousEdges(), "BRepBuilderAPI_Sewing::ContigousEdge");
2031 return TopoDS::Edge(myContigousEdges.FindKey(index));
2032}
2033
2034//=======================================================================
2035//function : ContigousEdgeCouple
2036//purpose :
2037//=======================================================================
2038
2039const TopTools_ListOfShape& BRepBuilderAPI_Sewing::ContigousEdgeCouple(const Standard_Integer index) const
2040{
2041 Standard_OutOfRange_Raise_if(index < 0 || index > NbContigousEdges(), "BRepBuilderAPI_Sewing::ContigousEdgeCouple");
2042 return myContigousEdges(index);
2043}
2044
2045//=======================================================================
2046//function : IsSectionBound
2047//purpose :
2048//=======================================================================
2049
2050Standard_Boolean BRepBuilderAPI_Sewing::IsSectionBound(const TopoDS_Edge& section) const
2051{
2052 if(myContigSecBound.IsBound(section)) {
2053 return Standard_True;
2054 }
2055 else {
2056 return Standard_False;
2057 }
2058}
2059
2060//=======================================================================
2061//function : SectionToBoundary
2062//purpose :
2063//=======================================================================
2064
2065const TopoDS_Edge& BRepBuilderAPI_Sewing::SectionToBoundary(const TopoDS_Edge& section) const
2066{
2067 Standard_NoSuchObject_Raise_if(!IsSectionBound(section), "BRepBuilderAPI_Sewing::SectionToBoundary");
2068 return TopoDS::Edge(myContigSecBound(section));
2069}
2070//=======================================================================
2071//function : NbDeletedFaces
2072//purpose :
2073//=======================================================================
2074 Standard_Integer BRepBuilderAPI_Sewing::NbDeletedFaces() const
2075{
2076 return myLittleFace.Extent();
2077}
2078
2079//=======================================================================
2080//function : DeletedFace
2081//purpose :
2082//=======================================================================
2083const TopoDS_Face& BRepBuilderAPI_Sewing::DeletedFace(const Standard_Integer index) const
2084{
2085 Standard_OutOfRange_Raise_if(index < 0 || index > NbDeletedFaces(), "BRepBuilderAPI_Sewing::DeletedFace");
2086 return TopoDS::Face(myLittleFace(index));
2087}
2088
2089//=======================================================================
2090//function : NbDegeneratedShapes
2091//purpose :
2092//=======================================================================
2093
2094Standard_Integer BRepBuilderAPI_Sewing::NbDegeneratedShapes() const
2095{
2096 return myDegenerated.Extent();
2097}
2098
2099//=======================================================================
2100//function : DegeneratedShape
2101//purpose :
2102//=======================================================================
2103
2104const TopoDS_Shape& BRepBuilderAPI_Sewing::DegeneratedShape(const Standard_Integer index) const
2105{
2106 Standard_OutOfRange_Raise_if(index < 0 || index > NbDegeneratedShapes(), "BRepBuilderAPI_Sewing::DegereratedShape");
2107 return myDegenerated(index);
2108}
2109
2110//=======================================================================
2111//function : IsDegenerated
2112//purpose :
2113//=======================================================================
2114
2115Standard_Boolean BRepBuilderAPI_Sewing::IsDegenerated(const TopoDS_Shape& aShape) const
2116{
2117 TopoDS_Shape NewShape = myReShape->Apply(aShape);
2118 // Degenerated face
2119 if (aShape.ShapeType() == TopAbs_FACE)
2120 return NewShape.IsNull();
2121 if (NewShape.IsNull()) return Standard_False;
2122 // Degenerated edge
2123 if (NewShape.ShapeType() == TopAbs_EDGE)
2124 return BRep_Tool::Degenerated(TopoDS::Edge(NewShape));
2125 // Degenerated wire
2126 if (NewShape.ShapeType() == TopAbs_WIRE) {
2127 Standard_Boolean isDegenerated = Standard_True;
2128 for (TopoDS_Iterator aIt(NewShape); aIt.More() && isDegenerated; aIt.Next())
2129 isDegenerated = BRep_Tool::Degenerated(TopoDS::Edge(aIt.Value()));
2130 return isDegenerated;
2131 }
2132 return Standard_False;
2133}
2134
2135//=======================================================================
2136//function : IsModified
2137//purpose :
2138//=======================================================================
2139
2140Standard_Boolean BRepBuilderAPI_Sewing::IsModified(const TopoDS_Shape& aShape) const
2141{
2142 TopoDS_Shape NewShape = aShape;
2143 if (myOldShapes.Contains(aShape))
2144 NewShape = myOldShapes.FindFromKey(aShape);
2145 if(!NewShape.IsSame(aShape)) return Standard_True;
2146 return Standard_False;
2147}
2148
2149//=======================================================================
2150//function : Modified
2151//purpose :
2152//=======================================================================
2153
2154const TopoDS_Shape& BRepBuilderAPI_Sewing::Modified(const TopoDS_Shape& aShape) const
2155{
2156 if (myOldShapes.Contains(aShape)) return myOldShapes.FindFromKey(aShape);
2157 //if (myOldFaces.Contains(aShape)) return myOldFaces.FindFromKey(aShape);
2158 return aShape;
2159}
2160
2161//=======================================================================
2162//function : IsModifiedSubShape
2163//purpose :
2164//=======================================================================
2165
2166Standard_Boolean BRepBuilderAPI_Sewing::IsModifiedSubShape(const TopoDS_Shape& aShape) const
2167{
2168 TopoDS_Shape NewShape = myReShape->Apply(aShape);
2169 if(!NewShape.IsSame(aShape)) return Standard_True;
2170 return Standard_False;
2171}
2172
2173//=======================================================================
2174//function : ModifiedSubShape
2175//purpose :
2176//=======================================================================
2177
2178TopoDS_Shape BRepBuilderAPI_Sewing::ModifiedSubShape(const TopoDS_Shape& aShape) const
2179{
2180 return myReShape->Apply(aShape);
2181}
2182
2183//=======================================================================
2184//function : Dump
2185//purpose :
2186//=======================================================================
2187
2188void BRepBuilderAPI_Sewing::Dump() const
2189{
2190 Standard_Integer i, NbBounds = myBoundFaces.Extent(), NbSections = 0;
2191 TopTools_MapOfShape mapVertices, mapEdges;
2192 for (i = 1; i <= NbBounds; i++) {
2193 TopoDS_Shape bound = myBoundFaces.FindKey(i);
2194 if (myBoundSections.IsBound(bound)) NbSections += myBoundSections(bound).Extent();
2195 else NbSections++;
2196 TopExp_Explorer aExp(myReShape->Apply(bound),TopAbs_EDGE);
2197 for (; aExp.More(); aExp.Next()) {
2198 TopoDS_Edge E = TopoDS::Edge(aExp.Current());
2199 mapEdges.Add(E);
2200 TopoDS_Vertex V1, V2;
2201 TopExp::Vertices(E,V1,V2);
2202 mapVertices.Add(V1);
2203 mapVertices.Add(V2);
2204 }
2205 }
2206 cout << " " << endl;
2207 cout << " Informations " << endl;
2208 cout << " ===========================================================" << endl;
2209 cout << " " << endl;
2210 cout << " Number of input shapes : " << myOldShapes.Extent() << endl;
2211 cout << " Number of actual shapes : " << myNbShapes << endl;
2212 cout << " Number of Bounds : " << NbBounds << endl;
2213 cout << " Number of Sections : " << NbSections << endl;
2214 cout << " Number of Edges : " << mapEdges.Extent() << endl;
2215 cout << " Number of Vertices : " << myNbVertices << endl;
2216 cout << " Number of Nodes : " << mapVertices.Extent() << endl;
2217 cout << " Number of Free Edges : " << myFreeEdges.Extent() << endl;
2218 cout << " Number of Contigous Edges : " << myContigousEdges.Extent() << endl;
2219 cout << " Number of Multiple Edges : " << myMultipleEdges.Extent() << endl;
2220 cout << " Number of Degenerated Edges : " << myDegenerated.Extent() << endl;
2221 cout << " ===========================================================" << endl;
2222 cout << " " << endl;
2223}
2224
2225//=======================================================================
2226//function : FaceAnalysis
2227//purpose : Remove
2228// Modifies:
2229// myNbShapes
2230// myOldShapes
2231//
2232// Constructs:
2233// myDegenerated
2234//=======================================================================
2235
92434a36 2236void BRepBuilderAPI_Sewing::FaceAnalysis(const Handle(Message_ProgressIndicator)& thePI)
7fd59977 2237{
2238 if (!myShape.IsNull() && myOldShapes.IsEmpty()) {
2239 Add(myShape);
2240 myShape.Nullify();
2241 }
2242
2243 BRep_Builder B;
2244 TopTools_MapOfShape SmallEdges;
2245 TopTools_DataMapOfShapeListOfShape GluedVertices;
2246 Standard_Integer i = 1;
92434a36
A
2247 Message_ProgressSentry aPS (thePI, "Shape analysis", 0, myOldShapes.Extent(), 1);
2248 for (i = 1; i <= myOldShapes.Extent() && aPS.More(); i++, aPS.Next()) {
7fd59977 2249 for (TopExp_Explorer fexp(myOldShapes(i),TopAbs_FACE); fexp.More(); fexp.Next()) {
2250
2251 // Retrieve current face
2252 TopoDS_Shape aTmpShape = fexp.Current(); //for porting
2253 TopoDS_Face face = TopoDS::Face(aTmpShape);
2254 Standard_Integer nbEdges = 0, nbSmall = 0;
2255
2256 // Build replacing face
2257 aTmpShape = face.EmptyCopied().Oriented(TopAbs_FORWARD); //for porting
2258 TopoDS_Face nface = TopoDS::Face(aTmpShape);
2259 Standard_Boolean isFaceChanged = Standard_False;
2260
2261 TopoDS_Iterator witer(face.Oriented(TopAbs_FORWARD));
2262 for (; witer.More(); witer.Next()) {
2263
2264 // Retrieve current wire
2265 aTmpShape = witer.Value(); //for porting
2266 if( aTmpShape.ShapeType() != TopAbs_WIRE) continue;
2267 TopoDS_Wire wire = TopoDS::Wire(aTmpShape);
2268
2269 // Build replacing wire
2270 aTmpShape = wire.EmptyCopied().Oriented(TopAbs_FORWARD);
2271 TopoDS_Wire nwire = TopoDS::Wire(aTmpShape);
2272 Standard_Boolean isWireChanged = Standard_False;
2273
2274 TopoDS_Iterator eiter(wire.Oriented(TopAbs_FORWARD));
2275 for (; eiter.More(); eiter.Next()) {
2276
2277 // Retrieve current edge
2278 aTmpShape = eiter.Value(); //for porting
2279 TopoDS_Edge edge = TopoDS::Edge(aTmpShape);
2280 nbEdges++;
2281
2282 // Process degenerated edge
2283 if (BRep_Tool::Degenerated(edge)) {
2284 B.Add(nwire,edge); // Old edge kept
2285 myDegenerated.Add(edge);
2286 nbSmall++;
2287 continue;
2288 }
2289
2290 Standard_Boolean isSmall = SmallEdges.Contains(edge);
2291 if (!isSmall) {
2292
2293 // Check for small edge
2294 Standard_Real first, last;
2295 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,first,last);
2296 if (c3d.IsNull()) {
0797d9d3 2297#ifdef OCCT_DEBUG
7fd59977 2298 cout << "Warning: Possibly small edge can be sewed: No 3D curve" << endl;
2299#endif
2300 }
2301 else {
2302 // Evaluate curve compactness
2303 const Standard_Integer npt = 5;
2304 gp_Pnt cp((c3d->Value(first).XYZ()+c3d->Value(last).XYZ())*0.5);
2305 Standard_Real dist, maxdist = 0.0;
2306 Standard_Real delta = (last - first)/(npt - 1);
2307 for (Standard_Integer idx = 0; idx < npt; idx++) {
2308 dist = cp.Distance(c3d->Value(first + idx*delta));
2309 if (maxdist < dist) maxdist = dist;
2310 }
2311 isSmall = (2.*maxdist <= MinTolerance());
2312 /*try {
2313 GeomAdaptor_Curve cAdapt(c3d);
2314 Standard_Real length = GCPnts_AbscissaPoint::Length(cAdapt,first,last);
2315 isSmall = (length <= MinTolerance());
2316 }
2317 catch (Standard_Failure) {
0797d9d3 2318#ifdef OCCT_DEBUG
7fd59977 2319 cout << "Warning: Possibly small edge can be sewed: ";
2320 Standard_Failure::Caught()->Print(cout); cout << endl;
2321#endif
2322 }*/
2323 }
2324
2325 if (isSmall) {
2326
2327 // Store small edge in the map
2328 SmallEdges.Add(edge);
2329
2330 TopoDS_Vertex v1, v2;
2331 TopExp::Vertices(edge,v1,v2);
2332 TopoDS_Shape nv1 = myReShape->Apply(v1), nv2 = myReShape->Apply(v2);
2333
2334 // Store glued vertices
2335 if (!nv1.IsSame(v1)) {
2336 TopTools_ListOfShape& vlist1 = GluedVertices(nv1);
2337 // First vertex was already glued
2338 if (!nv2.IsSame(v2)) {
2339 // Merge lists of glued vertices
2340 if (!nv1.IsSame(nv2)) {
2341 TopTools_ListIteratorOfListOfShape liter(GluedVertices(nv2));
2342 for (; liter.More(); liter.Next()) {
2343 TopoDS_Shape v = liter.Value();
2344 myReShape->Replace(v,nv1.Oriented(v.Orientation()));
2345 vlist1.Append(v);
2346 }
2347 GluedVertices.UnBind(nv2);
2348 }
2349 }
2350 else {
2351 // Add second vertex to the existing list
2352 vlist1.Append(v2);
2353 myReShape->Replace(v2,nv1.Oriented(v2.Orientation()));
2354 }
2355 }
2356 else if (!nv2.IsSame(v2)) {
2357 // Add first vertex to the existing list
2358 GluedVertices(nv2).Append(v1);
2359 myReShape->Replace(v1,nv2.Oriented(v1.Orientation()));
2360 }
2361 else if (!v1.IsSame(v2)) {
2362 // Record new glued vertices
2363 TopoDS_Vertex nv;
2364 B.MakeVertex(nv);
2365 TopTools_ListOfShape vlist;
2366 vlist.Append(v1);
2367 vlist.Append(v2);
2368 GluedVertices.Bind(nv,vlist);
2369 myReShape->Replace(v1,nv.Oriented(v1.Orientation()));
2370 myReShape->Replace(v2,nv.Oriented(v2.Orientation()));
2371 }
2372 }
2373 }
2374
2375 // Replace small edge
2376 if (isSmall) {
0797d9d3 2377#ifdef OCCT_DEBUG
7fd59977 2378 cout << "Warning: Small edge made degenerated by FaceAnalysis" << endl;
2379#endif
2380 nbSmall++;
2381 // Create new degenerated edge
2382 aTmpShape = edge.Oriented(TopAbs_FORWARD);
2383 TopoDS_Edge fedge = TopoDS::Edge(aTmpShape);
2384 Standard_Real pfirst, plast;
2385 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(fedge,face,pfirst,plast);
2386 if (!c2d.IsNull()) {
2387 TopoDS_Edge nedge;
2388 B.MakeEdge(nedge);
2389 B.UpdateEdge(nedge,c2d,face,Precision::Confusion());
2390 B.Range(nedge,pfirst,plast);
2391 B.Degenerated(nedge,Standard_True);
2392 TopoDS_Vertex v1, v2;
2393 TopExp::Vertices(fedge,v1,v2);
2394 B.Add(nedge,myReShape->Apply(v1).Oriented(v1.Orientation()));
2395 B.Add(nedge,myReShape->Apply(v2).Oriented(v2.Orientation()));
2396 B.Add(nwire,nedge.Oriented(edge.Orientation()));
2397 myDegenerated.Add(nedge);
2398 }
2399 isWireChanged = Standard_True;
2400 }
2401 else B.Add(nwire,edge); // Old edge kept
2402 }
2403
2404 // Record wire in the new face
2405 if (isWireChanged) {
2406 B.Add(nface,nwire.Oriented(wire.Orientation()));
2407 isFaceChanged = Standard_True;
2408 }
2409 else B.Add(nface,wire);
2410 }
2411
2412 // Remove small face
2413 if (nbSmall == nbEdges) {
0797d9d3 2414#ifdef OCCT_DEBUG
7fd59977 2415 cout << "Warning: Small face removed by FaceAnalysis" << endl;
2416#endif
2417 myLittleFace.Add(face);
2418 myReShape->Remove(face);
2419 }
2420 else if (isFaceChanged) {
2421
2422 myReShape->Replace(face,nface.Oriented(face.Orientation()));
2423 }
2424 }
2425 }
2426
2427 // Update glued vertices
2428 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape miter(GluedVertices);
2429 for (; miter.More(); miter.Next()) {
2430 TopoDS_Vertex vnew = TopoDS::Vertex(miter.Key());
2431 gp_XYZ coord(0.,0.,0.);
2432 Standard_Integer nbPoints = 0;
2433 const TopTools_ListOfShape& vlist = miter.Value();
2434 TopTools_ListIteratorOfListOfShape liter1(vlist);
2435 for (; liter1.More(); liter1.Next()) {
2436 coord += BRep_Tool::Pnt(TopoDS::Vertex(liter1.Value())).XYZ();
2437 nbPoints++;
2438 }
2439 if (nbPoints) {
2440 gp_Pnt vp(coord / nbPoints);
2441 Standard_Real tol = 0.0, mtol = 0.0;
2442 TopTools_ListIteratorOfListOfShape liter2(vlist);
2443 for (; liter2.More(); liter2.Next()) {
2444 Standard_Real vtol = BRep_Tool::Tolerance(TopoDS::Vertex(liter2.Value()));
2445 if (mtol < vtol) mtol = vtol;
2446 vtol = vp.Distance(BRep_Tool::Pnt(TopoDS::Vertex(liter2.Value())));
2447 if (tol < vtol) tol = vtol;
2448 }
2449 B.UpdateVertex(vnew,vp,tol+mtol);
2450 }
2451 }
2452
2453 // Update input shapes
2454 for (i = 1; i <= myOldShapes.Extent(); i++)
2455 myOldShapes(i) = myReShape->Apply(myOldShapes(i));
2456}
2457
2458//=======================================================================
2459//function : FindFreeBoundaries
2460//purpose : Constructs :
2461// myBoundFaces (bound = list of faces) - REFERENCE
2462// myVertexNode (vertex = node)
2463// myVertexNodeFree (floating vertex = node)
2464//
2465//=======================================================================
2466
2467void BRepBuilderAPI_Sewing::FindFreeBoundaries()
2468{
2469 // Take into account the context shape if needed
2470 TopTools_IndexedMapOfShape NewShapes;
2471 if (!myShape.IsNull()) {
2472 if (myOldShapes.IsEmpty()) {
2473 Add(myShape);
2474 myShape.Nullify();
2475 }
2476 else {
2477 TopoDS_Shape newShape = myReShape->Apply(myShape);
2478 if (!newShape.IsNull()) NewShapes.Add(newShape);
2479 }
2480 }
2481 // Create map Edge -> Faces
2482 TopTools_IndexedDataMapOfShapeListOfShape EdgeFaces;
2483 Standard_Integer i, nbShapes = myOldShapes.Extent();
2484 for (i = 1; i <= nbShapes; i++) {
2485 // Retrieve new shape
2486 TopoDS_Shape shape = myOldShapes(i);
2487 if (shape.IsNull()) continue;
2488 NewShapes.Add(shape);
2489 // Explore shape to find all boundaries
2490 for (TopExp_Explorer eExp(shape,TopAbs_EDGE); eExp.More(); eExp.Next()) {
2491 TopoDS_Shape edge = eExp.Current();
2492 if (!EdgeFaces.Contains(edge)) {
2493 TopTools_ListOfShape listFaces;
2494 EdgeFaces.Add(edge,listFaces);
2495 }
2496 }
2497 }
2498 // Fill map Edge -> Faces
2499 nbShapes = NewShapes.Extent();
2500 TopTools_MapOfShape mapFaces;
2501 for (i = 1; i <= nbShapes; i++) {
2502 // Explore shape to find all faces
2503 TopExp_Explorer fExp(NewShapes.FindKey(i),TopAbs_FACE);
2504 for (; fExp.More(); fExp.Next()) {
2505 TopoDS_Shape face = fExp.Current();
2506 if(mapFaces.Contains(face)) continue;
2507 else
2508 mapFaces.Add(face);
2509 // Explore face to find all boundaries
2510 for (TopoDS_Iterator aIw(face); aIw.More(); aIw.Next()) {
2511 if(aIw.Value().ShapeType() != TopAbs_WIRE) continue;
2512 for (TopoDS_Iterator aIIe(aIw.Value()); aIIe.More(); aIIe.Next()) {
2513
2514 TopoDS_Shape edge = aIIe.Value();
2515
2516 if (EdgeFaces.Contains(edge)) {
2517 EdgeFaces.ChangeFromKey(edge).Append(face);
2518 //TopTools_ListOfShape& listFaces = EdgeFaces.ChangeFromKey(edge);
2519 //Standard_Boolean isContained = Standard_False;
2520 //TopTools_ListIteratorOfListOfShape itf(listFaces);
2521 //for (; itf.More() && !isContained; itf.Next())
2522 // isContained = face.IsSame(itf.Value());
2523 //if (!isContained) listFaces.Append(face);
2524 }
2525 }
2526 }
2527 }
2528 }
2529 // Find free boundaries
2530 nbShapes = EdgeFaces.Extent();
2531 for (i = 1; i <= nbShapes; i++) {
2532 TopTools_ListOfShape& listFaces = EdgeFaces(i);
2533 Standard_Integer nbFaces = listFaces.Extent();
2534 TopoDS_Shape edge = EdgeFaces.FindKey(i);
2535 if(edge.Orientation() == TopAbs_INTERNAL)
2536 continue;
2537 Standard_Boolean isSeam = Standard_False;
2538 if (nbFaces == 1) {
2539 TopoDS_Face face = TopoDS::Face(listFaces.First());
2540 isSeam = BRep_Tool::IsClosed(TopoDS::Edge(edge),face);
2541 if (isSeam) {
2542 ///Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
2543 //isSeam = (IsUClosedSurface(surf) || IsVClosedSurface(surf));
2544 //if(!isSeam) {
2545 BRep_Builder aB;
2546 TopoDS_Shape anewEdge = edge.EmptyCopied();
2547 TopoDS_Iterator aItV(edge);
2548 for( ; aItV.More() ; aItV.Next())
2549 aB.Add(anewEdge,aItV.Value());
2550
2551
2552
2553 Standard_Real first2d,last2d;
2554 Handle(Geom2d_Curve) c2dold =
2555 BRep_Tool::CurveOnSurface(TopoDS::Edge(edge),TopoDS::Face(listFaces.First()),first2d,last2d);
2556
2557 Handle(Geom2d_Curve) c2d;
2558 BRep_Builder B;
2559 B.UpdateEdge(TopoDS::Edge(anewEdge),c2d,c2d,TopoDS::Face(listFaces.First()),0);
2560 B.UpdateEdge(TopoDS::Edge(anewEdge),c2dold,TopoDS::Face(listFaces.First()),0);
2561
2562 Standard_Real aFirst, aLast;
2563 BRep_Tool::Range(TopoDS::Edge(edge),aFirst, aLast);
2564 aB.Range(TopoDS::Edge(anewEdge),aFirst, aLast);
2565 aB.Range(TopoDS::Edge(anewEdge),TopoDS::Face(listFaces.First()),first2d,last2d);
2566 myReShape->Replace(edge,anewEdge);
2567 edge = anewEdge;
2568
2569 //}
2570 isSeam = Standard_False;
2571 }
2572 }
2573 Standard_Boolean isBoundFloat = (myFloatingEdgesMode && !nbFaces);
2574 Standard_Boolean isBound = (myFaceMode && ((myNonmanifold && nbFaces) || (nbFaces == 1 && !isSeam)));
2575 if (isBound || isBoundFloat) {
2576 // Ignore degenerated edge
2577 if (BRep_Tool::Degenerated(TopoDS::Edge(edge))) continue;
2578 // Ignore edge with internal vertices
2579 // Standard_Integer nbVtx = 0;
2580 // for (TopExp_Explorer vExp(edge,TopAbs_VERTEX); vExp.More(); vExp.Next()) nbVtx++;
2581 // if (nbVtx != 2) continue;
2582 // Add to BoundFaces
2583 TopTools_ListOfShape listFacesCopy;
2584 listFacesCopy.Append(listFaces);
2585 myBoundFaces.Add(edge,listFacesCopy);
2586 // Process edge vertices
2587 TopoDS_Vertex vFirst, vLast;
2588 TopExp::Vertices(TopoDS::Edge(edge), vFirst, vLast);
2589 if(vFirst.IsNull() || vLast.IsNull()) continue;
2590 if(vFirst.Orientation() == TopAbs_INTERNAL || vLast.Orientation() == TopAbs_INTERNAL)
2591 continue;
2592 if (isBound) {
2593 // Add to VertexNode
2594 if (!myVertexNode.Contains(vFirst))
2595 myVertexNode.Add(vFirst,vFirst);
2596 if (!myVertexNode.Contains(vLast))
2597 myVertexNode.Add(vLast,vLast);
2598 }
2599 else {
2600 // Add to VertexNodeFree
2601 if (!myVertexNodeFree.Contains(vFirst))
2602 myVertexNodeFree.Add(vFirst,vFirst);
2603 if (!myVertexNodeFree.Contains(vLast))
2604 myVertexNodeFree.Add(vLast,vLast);
2605 }
2606 }
2607 }
2608}
2609
2610//=======================================================================
2611//function : VerticesAssembling
2612//purpose : Modifies :
2613// myVertexNode (nodes glued)
2614// myVertexNodeFree (nodes glued)
2615// myNodeSections (lists of sections merged for glued nodes)
2616//
2617//=======================================================================
2618
2619static Standard_Boolean CreateNewNodes(const TopTools_IndexedDataMapOfShapeShape& NodeNearestNode,
2620 const TopTools_IndexedDataMapOfShapeListOfShape& NodeVertices,
2621 TopTools_IndexedDataMapOfShapeShape& aVertexNode,
2622 TopTools_DataMapOfShapeListOfShape& aNodeEdges)
2623{
2624 Standard_Integer i, nbNearest = NodeNearestNode.Extent();
2625
2626 // Create new nodes
2627 BRep_Builder B;
2628 TopTools_DataMapOfShapeShape OldNodeNewNode;
2629 TopTools_DataMapOfShapeListOfShape NewNodeOldNodes;
2630 for (i = 1; i <= nbNearest; i++) {
2631 // Retrieve a pair of nodes to merge
2632 TopoDS_Shape oldnode1 = NodeNearestNode.FindKey(i);
2633 TopoDS_Shape oldnode2 = NodeNearestNode(i);
2634 // Second node should also be in the map
2635 if (!NodeNearestNode.Contains(oldnode2)) continue;
2636 // Get new node for old node #1
2637 if (OldNodeNewNode.IsBound(oldnode1)) {
2638 TopoDS_Shape newnode1 = OldNodeNewNode(oldnode1);
2639 if (OldNodeNewNode.IsBound(oldnode2)) {
2640 TopoDS_Shape newnode2 = OldNodeNewNode(oldnode2);
2641 if (!newnode1.IsSame(newnode2)) {
2642 // Change data for new node #2
2643 TopTools_ListOfShape& lnode1 = NewNodeOldNodes(newnode1);
2644 TopTools_ListIteratorOfListOfShape itn(NewNodeOldNodes(newnode2));
2645 for (; itn.More(); itn.Next()) {
2646 TopoDS_Shape node2 = itn.Value();
2647 lnode1.Append(node2);
2648 OldNodeNewNode(node2) = newnode1;
2649 }
2650 NewNodeOldNodes.UnBind(newnode2);
2651 }
2652 }
2653 else {
2654 // Old node #2 is not bound - add to old node #1
2655 OldNodeNewNode.Bind(oldnode2,newnode1);
2656 NewNodeOldNodes(newnode1).Append(oldnode2);
2657 }
2658 }
2659 else {
2660 if (OldNodeNewNode.IsBound(oldnode2)) {
2661 // Old node #1 is not bound - add to old node #2
2662 TopoDS_Shape newnode2 = OldNodeNewNode(oldnode2);
2663 OldNodeNewNode.Bind(oldnode1,newnode2);
2664 NewNodeOldNodes(newnode2).Append(oldnode1);
2665 }
2666 else {
2667 // Nodes are not bound - create new node
2668 TopoDS_Vertex newnode;
2669 B.MakeVertex(newnode);
2670 OldNodeNewNode.Bind(oldnode1,newnode);
2671 OldNodeNewNode.Bind(oldnode2,newnode);
2672 TopTools_ListOfShape lnodes;
2673 lnodes.Append(oldnode1);
2674 lnodes.Append(oldnode2);
2675 NewNodeOldNodes.Bind(newnode,lnodes);
2676 }
2677 }
2678 }
2679
2680 // Stop if no new nodes created
2681 if (!NewNodeOldNodes.Extent()) return Standard_False;
2682
2683 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter1(NewNodeOldNodes);
2684 for (; iter1.More(); iter1.Next()) {
2685 const TopoDS_Vertex& newnode = TopoDS::Vertex(iter1.Key());
2686 // Calculate new node center point
2687 gp_XYZ theCoordinates(0.,0.,0.);
2688 TopTools_ListOfShape lvert; // Accumulate node vertices
2689 TopTools_MapOfShape medge;
2690 TopTools_ListOfShape ledge; // Accumulate node edges
2691 // Iterate on old nodes
2692 TopTools_ListIteratorOfListOfShape itn(iter1.Value());
2693 for (; itn.More(); itn.Next()) {
2694 const TopoDS_Shape& oldnode = itn.Value();
2695 // Iterate on node vertices
2696 TopTools_ListIteratorOfListOfShape itv(NodeVertices.FindFromKey(oldnode));
2697 for (; itv.More(); itv.Next()) {
2698 TopoDS_Vertex vertex = TopoDS::Vertex(itv.Value());
2699 // Change node for vertex
2700 aVertexNode.ChangeFromKey(vertex) = newnode;
2701 // Accumulate coordinates
2702 theCoordinates += BRep_Tool::Pnt(vertex).XYZ();
2703 lvert.Append(vertex);
2704 }
2705 // Iterate on node edges
2706 const TopTools_ListOfShape& edges = aNodeEdges(oldnode);
2707 TopTools_ListIteratorOfListOfShape ite(edges);
2708 for (; ite.More(); ite.Next()) {
2709 TopoDS_Shape edge = ite.Value();
2710 if (!medge.Contains(edge)) { medge.Add(edge); ledge.Append(edge); }
2711 }
2712 // Unbind old node edges
2713 aNodeEdges.UnBind(oldnode);
2714 }
2715 // Bind new node edges
2716 aNodeEdges.Bind(newnode,ledge);
2717 gp_Pnt center(theCoordinates / lvert.Extent());
2718 // Calculate new node tolerance
2719 Standard_Real toler = 0.0;
2720 TopTools_ListIteratorOfListOfShape itv(lvert);
2721 for (; itv.More(); itv.Next()) {
2722 const TopoDS_Vertex& vertex = TopoDS::Vertex(itv.Value());
2723 Standard_Real t = center.Distance(BRep_Tool::Pnt(vertex)) + BRep_Tool::Tolerance(vertex);
2724 if (toler < t) toler = t;
2725 }
2726 // Update new node parameters
2727 B.UpdateVertex(newnode,center,toler);
2728 }
2729
2730 return Standard_True;
2731}
2732
2733static Standard_Integer IsMergedVertices(const TopoDS_Shape& face1,
2734 const TopoDS_Shape& e1, const TopoDS_Shape& e2,
2735 const TopoDS_Shape& vtx1, const TopoDS_Shape& vtx2)
2736{
2737 //Case of floating edges
2738 if (face1.IsNull())
2739 return (!IsClosedShape(e1,vtx1,vtx2));
2740
2741 // Find wires containing given edges
2742 TopoDS_Shape wire1, wire2;
2743 TopExp_Explorer itw(face1,TopAbs_WIRE);
2744 for (; itw.More() && (wire1.IsNull() || wire2.IsNull()); itw.Next()) {
2745 TopoDS_Iterator ite(itw.Current(),Standard_False);
2746 for (; ite.More() && (wire1.IsNull() || wire2.IsNull()); ite.Next()) {
2747 if (wire1.IsNull() && e1.IsSame(ite.Value())) wire1 = itw.Current();
2748 if (wire2.IsNull() && e2.IsSame(ite.Value())) wire2 = itw.Current();
2749 }
2750 }
2751 Standard_Integer Status = 0;
2752 if (!wire1.IsNull() && !wire2.IsNull()) {
2753 if (wire1.IsSame(wire2)) {
2754 for (TopoDS_Iterator aIte(wire1,Standard_False); aIte.More(); aIte.Next()) {
2755 TopoDS_Vertex ve1,ve2;
2756 TopExp::Vertices(TopoDS::Edge(aIte.Value()),ve1,ve2);
2757 if ((ve1.IsSame(vtx1) && ve2.IsSame(vtx2)) ||
2758 (ve2.IsSame(vtx1) && ve1.IsSame(vtx2)))
2759 return (IsClosedShape(aIte.Value(),vtx1,vtx2)? 0 : 1);
2760 }
2761 if (IsClosedShape(wire1,vtx1,vtx2)) {
2762 TopoDS_Vertex V1, V2;
2763 TopExp::Vertices(TopoDS::Wire(wire1),V1,V2);
2764 Standard_Boolean isEndVertex = ((V1.IsSame(vtx1) && V2.IsSame(vtx2)) ||
2765 (V2.IsSame(vtx1) && V1.IsSame(vtx2)));
2766 if (!isEndVertex) Status = 1;
2767 }
2768 else Status = 1;
2769 }
2770 else Status = -1;
2771 }
2772 return Status;
2773}
2774
2775static Standard_Boolean GlueVertices(TopTools_IndexedDataMapOfShapeShape& aVertexNode,
92434a36
A
2776 TopTools_DataMapOfShapeListOfShape& aNodeEdges,
2777 const TopTools_IndexedDataMapOfShapeListOfShape& aBoundFaces,
2778 const Standard_Real Tolerance,
2779 const Handle(Message_ProgressIndicator)& theProgress)
7fd59977 2780{
2781 Standard_Integer i, nbVertices = aVertexNode.Extent();
2782 // Create map of node -> vertices
2783 TopTools_IndexedDataMapOfShapeListOfShape NodeVertices;
a7653f4f 2784 BRepBuilderAPI_CellFilter aFilter (Tolerance);
82192477 2785 BRepBuilderAPI_VertexInspector anInspector (Tolerance);
7fd59977 2786 for (i = 1; i <= nbVertices; i++) {
2787 TopoDS_Shape vertex = aVertexNode.FindKey(i);
2788 TopoDS_Vertex node = TopoDS::Vertex(aVertexNode(i));
2789 if (NodeVertices.Contains(node)) {
2790 NodeVertices.ChangeFromKey(node).Append(vertex);
2791 }
2792 else {
2793 TopTools_ListOfShape vlist;
2794 vlist.Append(vertex);
2795 NodeVertices.Add(node,vlist);
82192477 2796 gp_Pnt aPnt = BRep_Tool::Pnt (TopoDS::Vertex (node));
2797 aFilter.Add (NodeVertices.FindIndex (node), aPnt.XYZ());
2798 anInspector.Add (aPnt.XYZ());
7fd59977 2799 }
2800 }
2801 Standard_Integer nbNodes = NodeVertices.Extent();
0797d9d3 2802#ifdef OCCT_DEBUG
7fd59977 2803 cout << "Glueing " << nbNodes << " nodes..." << endl;
2804#endif
7fd59977 2805 // Merge nearest nodes
2806 TopTools_IndexedDataMapOfShapeShape NodeNearestNode;
92434a36
A
2807 Message_ProgressSentry aPS (theProgress, "Glueing nodes", 0, nbNodes, 1, Standard_True);
2808 for (i = 1; i <= nbNodes && aPS.More(); i++, aPS.Next()) {
7fd59977 2809 TopoDS_Vertex node1 = TopoDS::Vertex(NodeVertices.FindKey(i));
2810 // Find near nodes
82192477 2811 gp_Pnt pt1 = BRep_Tool::Pnt (node1);
2812 anInspector.SetCurrent (pt1.XYZ());
2813 gp_XYZ aPntMin = anInspector.Shift (pt1.XYZ(), -Tolerance);
2814 gp_XYZ aPntMax = anInspector.Shift (pt1.XYZ(), Tolerance);
2815 aFilter.Inspect (aPntMin, aPntMax, anInspector);
2816 if (anInspector.ResInd().IsEmpty()) continue;
7fd59977 2817 // Retrieve list of edges for the first node
2818 const TopTools_ListOfShape& ledges1 = aNodeEdges(node1);
2819 // Explore list of near nodes and fill the sequence of glued nodes
2820 TopTools_SequenceOfShape SeqNodes;
2821 TopTools_ListOfShape listNodesSameEdge;
82192477 2822 //gp_Pnt pt1 = BRep_Tool::Pnt(node1);
2823 TColStd_ListIteratorOfListOfInteger iter1(anInspector.ResInd());
7fd59977 2824 for (; iter1.More(); iter1.Next()) {
2825 TopoDS_Vertex node2 = TopoDS::Vertex(NodeVertices.FindKey(iter1.Value()));
2826 if (node1 == node2) continue;
2827 // Retrieve list of edges for the second node
2828 const TopTools_ListOfShape& ledges2 = aNodeEdges(node2);
2829 // Check merging condition for the pair of nodes
2830 Standard_Integer Status = 0, isSameEdge = Standard_False;
2831 // Explore edges of the first node
2832 TopTools_ListIteratorOfListOfShape Ie1(ledges1);
2833 for (; Ie1.More() && !Status && !isSameEdge; Ie1.Next()) {
2834 const TopoDS_Shape& e1 = Ie1.Value();
2835 // Obtain real vertex from edge
2836 TopoDS_Shape v1 = node1;
2837 { //szv: Use brackets to destroy local variables
2838 TopoDS_Vertex ov1, ov2;
2839 TopExp::Vertices(TopoDS::Edge(e1),ov1,ov2);
2840 if (aVertexNode.Contains(ov1)) {
2841 if (node1.IsSame(aVertexNode.FindFromKey(ov1))) v1 = ov1;
2842 }
2843 if (aVertexNode.Contains(ov2)) {
2844 if (node1.IsSame(aVertexNode.FindFromKey(ov2))) v1 = ov2;
2845 }
2846 }
2847 // Create map of faces for e1
2848 TopTools_MapOfShape Faces1;
2849 const TopTools_ListOfShape& lfac1 = aBoundFaces.FindFromKey(e1);
2850 if (lfac1.Extent()) {
2851 TopTools_ListIteratorOfListOfShape itf(lfac1);
2852 for (; itf.More(); itf.Next())
2853 if (!itf.Value().IsNull())
2854 Faces1.Add(itf.Value());
2855 }
2856 // Explore edges of the second node
2857 TopTools_ListIteratorOfListOfShape Ie2(ledges2);
2858 for (; Ie2.More() && !Status && !isSameEdge; Ie2.Next()) {
2859 const TopoDS_Shape& e2 = Ie2.Value();
2860 // Obtain real vertex from edge
2861 TopoDS_Shape v2 = node2;
2862 { //szv: Use brackets to destroy local variables
2863 TopoDS_Vertex ov1, ov2;
2864 TopExp::Vertices(TopoDS::Edge(e2),ov1,ov2);
2865 if (aVertexNode.Contains(ov1)) {
2866 if (node2.IsSame(aVertexNode.FindFromKey(ov1))) v2 = ov1;
2867 }
2868 if (aVertexNode.Contains(ov2)) {
2869 if (node2.IsSame(aVertexNode.FindFromKey(ov2))) v2 = ov2;
2870 }
2871 }
2872 // Explore faces for e2
2873 const TopTools_ListOfShape& lfac2 = aBoundFaces.FindFromKey(e2);
2874 if (lfac2.Extent()) {
2875 TopTools_ListIteratorOfListOfShape itf(lfac2);
2876 for (; itf.More() && !Status && !isSameEdge; itf.Next()) {
2877 // Check merging conditions for the same face
2878 if (Faces1.Contains(itf.Value())) {
2879 Standard_Integer stat = IsMergedVertices(itf.Value(),e1,e2,v1,v2);
2880 if (stat == 1) isSameEdge = Standard_True;
2881 else Status = stat;
2882 }
2883 }
2884 }
2885 else if (Faces1.IsEmpty() && e1 == e2) {
2886 Standard_Integer stat = IsMergedVertices(TopoDS_Face(),e1,e1,v1,v2);
2887 if (stat == 1) isSameEdge = Standard_True;
2888 else Status = stat;
2889 break;
2890 }
2891 }
2892 }
2893 if (Status) continue;
2894 if (isSameEdge) listNodesSameEdge.Append(node2);
2895 // Append near node to the sequence
2896 gp_Pnt pt2 = BRep_Tool::Pnt(node2);
2897 Standard_Real dist = pt1.Distance(pt2);
2898 if (dist < Tolerance) {
2899 Standard_Boolean isIns = Standard_False;
2900 for (Standard_Integer kk = 1; kk <= SeqNodes.Length() && !isIns; kk++) {
2901 gp_Pnt pt = BRep_Tool::Pnt(TopoDS::Vertex(SeqNodes.Value(kk)));
2902 if (dist < pt1.Distance(pt)) {
2903 SeqNodes.InsertBefore(kk,node2);
2904 isIns = Standard_True;
2905 }
2906 }
2907 if (!isIns) SeqNodes.Append(node2);
2908 }
2909 }
2910 if (SeqNodes.Length()) {
2911 // Remove nodes near to some other from the same edge
2912 if (listNodesSameEdge.Extent()) {
2913 TopTools_ListIteratorOfListOfShape lInt(listNodesSameEdge);
2914 for (; lInt.More(); lInt.Next()) {
2915 const TopoDS_Vertex& n2 = TopoDS::Vertex(lInt.Value());
2916 gp_Pnt p2 = BRep_Tool::Pnt(n2);
2917 for (Standard_Integer k = 1; k <= SeqNodes.Length(); ) {
2918 const TopoDS_Vertex& n1 = TopoDS::Vertex(SeqNodes.Value(k));
2919 if (n1 != n2) {
2920 gp_Pnt p1 = BRep_Tool::Pnt(n1);
2921 if (p2.Distance(p1) >= pt1.Distance(p1)) { k++; continue; }
2922 }
2923 SeqNodes.Remove(k);
2924 }
2925 }
2926 }
2927 // Bind nearest node if at least one exists
2928 if (SeqNodes.Length())
2929 NodeNearestNode.Add(node1,SeqNodes.First());
2930 }
82192477 2931 anInspector.ClearResList();
7fd59977 2932 }
2933
2934 // Create new nodes for chained nearest nodes
2935 if (NodeNearestNode.IsEmpty()) return Standard_False;
7fd59977 2936
2937 return CreateNewNodes(NodeNearestNode,NodeVertices,aVertexNode,aNodeEdges);
2938}
2939
92434a36 2940void BRepBuilderAPI_Sewing::VerticesAssembling(const Handle(Message_ProgressIndicator)& thePI)
7fd59977 2941{
2942 Standard_Integer nbVert = myVertexNode.Extent();
2943 Standard_Integer nbVertFree = myVertexNodeFree.Extent();
92434a36 2944 Message_ProgressSentry aPS (thePI, "Vertices assembling", 0, 2, 1);
7fd59977 2945 if (nbVert || nbVertFree) {
2946 // Fill map node -> sections
2947 Standard_Integer i;
2948 for (i = 1; i <= myBoundFaces.Extent(); i++) {
2949 TopoDS_Shape bound = myBoundFaces.FindKey(i);
2950 for (TopoDS_Iterator itv(bound,Standard_False); itv.More(); itv.Next()) {
2951 TopoDS_Shape node = itv.Value();
2952 if (myNodeSections.IsBound(node))
2953 myNodeSections(node).Append(bound);
2954 else {
2955 TopTools_ListOfShape lbnd;
2956 lbnd.Append(bound);
2957 myNodeSections.Bind(node,lbnd);
2958 }
2959 }
2960 }
2961 // Glue vertices
2962 if (nbVert) {
0797d9d3 2963#ifdef OCCT_DEBUG
7fd59977 2964 cout << "Assemble " << nbVert << " vertices on faces..." << endl;
2965#endif
92434a36 2966 while (GlueVertices(myVertexNode,myNodeSections,myBoundFaces,myTolerance, thePI));
7fd59977 2967 }
92434a36
A
2968 if (!aPS.More())
2969 return;
2970 aPS.Next();
7fd59977 2971 if (nbVertFree) {
0797d9d3 2972#ifdef OCCT_DEBUG
7fd59977 2973 cout << "Assemble " << nbVertFree << " vertices on floating edges..." << endl;
2974#endif
92434a36 2975 while (GlueVertices(myVertexNodeFree,myNodeSections,myBoundFaces,myTolerance, thePI));
7fd59977 2976 }
2977 }
2978}
2979
2980//=======================================================================
2981//function : replaceNMVertices
2982//purpose : internal use (static)
2983//=======================================================================
2984static void replaceNMVertices(const TopoDS_Edge& theEdge,
2985 const TopoDS_Vertex& theV1,
2986 const TopoDS_Vertex& theV2,
2987 const Handle(BRepTools_ReShape)& theReShape)
2988{
2989 //To keep NM vertices on edge
2990 TopTools_SequenceOfShape aSeqNMVert;
2991 TColStd_SequenceOfReal aSeqNMPars;
2992 Standard_Boolean hasNMVert = findNMVertices(theEdge,aSeqNMVert,aSeqNMPars);
2993 if(!hasNMVert)
2994 return;
2995 Standard_Real first, last;
2996 BRep_Tool::Range(theEdge, first, last);
2997 TopLoc_Location aLoc;
2998 Handle(Geom_Curve) c3d = BRep_Tool::Curve(theEdge,aLoc,first, last);
2999 if(c3d.IsNull())
3000 return;
3001 TopTools_SequenceOfShape aEdVert;
3002 TColStd_SequenceOfReal aEdParams;
3003 Standard_Integer i =1, nb = aSeqNMPars.Length();
3004
3005 for( ; i <= nb;i++) {
3006 Standard_Real apar = aSeqNMPars.Value(i);
3007 if(fabs(apar - first) <= Precision::PConfusion()) {
3008 theReShape->Replace(aSeqNMVert.Value(i),theV1);
3009 continue;
3010 }
3011 if(fabs(apar - last) <= Precision::PConfusion()) {
3012 theReShape->Replace(aSeqNMVert.Value(i),theV2);
3013 continue;
3014 }
3015 TopoDS_Shape aV = aSeqNMVert.Value(i);
3016 Standard_Integer j =1;
3017 for( ; j <= aEdParams.Length();j++) {
3018 Standard_Real apar2 = aEdParams.Value(j);
3019 if(fabs(apar - apar2) <= Precision::PConfusion()) {
3020 theReShape->Replace(aV,aEdVert.Value(j));
3021 break;
3022 }
3023 else if(apar < apar2) {
3024 TopoDS_Shape anewV = aV.EmptyCopied();
3025 aEdVert.InsertBefore(j,anewV);
3026 aEdParams.InsertBefore(j,apar);
3027 BRep_ListOfPointRepresentation& alistrep =
3028 (*((Handle(BRep_TVertex)*)&anewV.TShape()))->ChangePoints();
3029 Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(apar,c3d,aLoc);
3030 alistrep.Append(aPRep);
3031 theReShape->Replace(aV,anewV);
3032 break;
3033 }
3034 }
3035 if (j > aEdParams.Length()) {
3036 TopoDS_Shape anewV = aV.EmptyCopied();
3037 aEdVert.Append(anewV);
3038 aEdParams.Append(apar);
3039 BRep_ListOfPointRepresentation& alistrep =
3040 (*((Handle(BRep_TVertex)*) &anewV.TShape()))->ChangePoints();
3041 Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(apar,c3d,aLoc);
3042 alistrep.Append(aPRep);
3043 theReShape->Replace(aV,anewV);
3044 }
3045 }
3046
3047 Standard_Integer newnb = aEdParams.Length();
3048 if(newnb < nb) {
3049
3050 TopoDS_Shape anewEdge = theEdge.EmptyCopied();
3051 TopAbs_Orientation anOri = theEdge.Orientation();
3052 anewEdge.Orientation(TopAbs_FORWARD);
3053 BRep_Builder aB;
3054 aB.Add(anewEdge,theV1);
3055 aB.Add(anewEdge,theV2);
3056
3057 for( i =1; i <= aEdVert.Length();i++)
3058 aB.Add(anewEdge,aEdVert.Value(i));
3059 anewEdge.Orientation(anOri);
3060 theReShape->Replace(theEdge,anewEdge);
3061 }
3062
3063}
3064
3065//=======================================================================
3066//function : ReplaceEdge
3067//purpose : internal use (static)
3068//=======================================================================
3069
3070static void ReplaceEdge(const TopoDS_Shape& oldEdge,
3071 const TopoDS_Shape& theNewShape,
3072 const Handle(BRepTools_ReShape)& aReShape)
3073{
3074 TopoDS_Shape oldShape = aReShape->Apply(oldEdge);
3075 TopoDS_Shape newShape = aReShape->Apply(theNewShape);
3076 if (oldShape.IsSame(newShape)|| aReShape->IsRecorded(newShape)) return;
3077
3078
3079 aReShape->Replace(oldShape,newShape);
3080 TopoDS_Vertex V1old,V2old,V1new,V2new;
3081 TopExp::Vertices(TopoDS::Edge(oldShape),V1old,V2old);
3082 TopAbs_Orientation Orold = oldShape.Orientation();
3083 TopAbs_Orientation Ornew = Orold;
3084 if (newShape.ShapeType() == TopAbs_EDGE) {
3085 TopoDS_Edge aEn = TopoDS::Edge(newShape);
3086 TopExp::Vertices(aEn,V1new,V2new);
3087 Ornew = aEn.Orientation();
3088 replaceNMVertices(aEn,V1new,V2new,aReShape);
3089 }
3090 else if (newShape.ShapeType() == TopAbs_WIRE) {
3091 for (TopExp_Explorer aex(newShape,TopAbs_EDGE); aex.More(); aex.Next()) {
3092 TopoDS_Edge ed = TopoDS::Edge(aex.Current());
3093 Ornew = ed.Orientation();
3094 TopoDS_Vertex aV1,aV2;
3095 TopExp::Vertices(ed,aV1,aV2);
3096 replaceNMVertices(ed,aV1,aV2,aReShape);
3097 if (V1new.IsNull())
3098 V1new = aV1;
3099 V2new =aV2;
3100 }
3101 }
3102
3103 V1new.Orientation(V1old.Orientation());
3104 V2new.Orientation(V2old.Orientation());
3105 if (V1old.IsSame(V2old) && !V1old.IsSame(V1new)&& !aReShape->IsRecorded(V1new)) {
3106 aReShape->Replace(V1old,V1new);
3107 return;
3108 }
3109 if (Orold == Ornew) {
3110 V1new.Orientation(V1old.Orientation());
3111 V2new.Orientation(V2old.Orientation());
3112 if (!V1old.IsSame(V1new) && !V1old.IsSame(V2new)&& !aReShape->IsRecorded(V1new))
3113 aReShape->Replace(V1old,V1new);
3114 if (!V2old.IsSame(V2new) && !V2old.IsSame(V1new)&& !aReShape->IsRecorded(V2new))
3115 aReShape->Replace(V2old,V2new);
3116 }
3117 else {
3118 V1new.Orientation(V2old.Orientation());
3119 V2new.Orientation(V1old.Orientation());
3120 if (!V1old.IsSame(V2new) && !V1old.IsSame(V1new)&& !aReShape->IsRecorded(V2new))
3121 aReShape->Replace(V1old,V2new);
3122 if (!V2old.IsSame(V2new) && !V2old.IsSame(V1new)&& !aReShape->IsRecorded(V1new))
3123 aReShape->Replace(V2old,V1new);
3124 }
3125}
3126
3127//=======================================================================
3128//function : Merging
3129//purpose : Modifies :
3130// myHasFreeBound
3131//
3132//=======================================================================
3133
92434a36
A
3134void BRepBuilderAPI_Sewing::Merging(const Standard_Boolean /* firstTime */,
3135 const Handle(Message_ProgressIndicator)& thePI)
7fd59977 3136{
3137 BRep_Builder B;
3138 // TopTools_MapOfShape MergedEdges;
92434a36
A
3139 Message_ProgressSentry aPS (thePI, "Merging bounds", 0, myBoundFaces.Extent(), 1);
3140 for (Standard_Integer i = 1; i <= myBoundFaces.Extent() && aPS.More(); i++, aPS.Next()) {
7fd59977 3141
3142 TopoDS_Shape bound = myBoundFaces.FindKey(i);
3143
3144 // If bound was already merged - continue
3145 if (myMergedEdges.Contains(bound)) continue;
3146
3147 if (!myBoundFaces(i).Extent()) {
3148 // Merge free edge - only vertices
3149 TopoDS_Vertex no1, no2;
3150 TopExp::Vertices(TopoDS::Edge(bound),no1,no2);
3151 TopoDS_Shape nno1 = no1, nno2 = no2;
3152 if (myVertexNodeFree.Contains(no1))
3153 nno1 = myVertexNodeFree.FindFromKey(no1);
3154 if (myVertexNodeFree.Contains(no2))
3155 nno2 = myVertexNodeFree.FindFromKey(no2);
3156 if (!no1.IsSame(nno1)) {
3157 nno1.Orientation(no1.Orientation());
3158 myReShape->Replace(no1,nno1);
3159 }
3160 if (!no2.IsSame(nno2)) {
3161 nno2.Orientation(no2.Orientation());
3162 myReShape->Replace(no2,nno2);
3163 }
3164 myMergedEdges.Add(bound);
3165 continue;
3166 }
3167
3168 // Check for previous splitting, build replacing wire
3169 TopoDS_Wire BoundWire;
3170 Standard_Boolean isPrevSplit = Standard_False;
3171 Standard_Boolean hasCuttingSections = myBoundSections.IsBound(bound);
3172 if (hasCuttingSections) {
3173 B.MakeWire(BoundWire);
3174 BoundWire.Orientation(bound.Orientation());
3175 // Iterate on cutting sections
3176 TopTools_ListIteratorOfListOfShape its(myBoundSections(bound));
3177 for (; its.More(); its.Next()) {
3178 TopoDS_Shape section = its.Value();
3179 B.Add(BoundWire,section);
3180 if (myMergedEdges.Contains(section)) isPrevSplit = Standard_True;
3181 }
3182 }
3183
3184 // Merge with bound
3185 TopTools_DataMapOfShapeShape MergedWithBound;
3186 if (!isPrevSplit) {
3187 // Obtain sequence of edges merged with bound
3188 TopTools_SequenceOfShape seqMergedWithBound;
dde68833 3189 TColStd_SequenceOfBoolean seqMergedWithBoundOri;
7fd59977 3190 if (MergedNearestEdges(bound,seqMergedWithBound,seqMergedWithBoundOri)) {
3191 // Store bound in the map
3192 MergedWithBound.Bind(bound,bound);
3193 // Iterate on edges merged with bound
3194 Standard_Integer ii = 1;
3195 while (ii <= seqMergedWithBound.Length()) {
3196 TopoDS_Shape iedge = seqMergedWithBound.Value(ii);
3197 // Remove edge if recorded as merged
3198 Standard_Boolean isRejected = (myMergedEdges.Contains(iedge) ||
3199 MergedWithBound.IsBound(iedge));
3200 if (!isRejected) {
3201 if (myBoundSections.IsBound(iedge)) {
3202 // Edge is splitted - check sections
3203 TopTools_ListIteratorOfListOfShape lit(myBoundSections(iedge));
3204 for (; lit.More() && !isRejected; lit.Next()) {
3205 const TopoDS_Shape& sec = lit.Value();
3206 // Remove edge (bound) if at least one of its sections already merged
3207 isRejected = (myMergedEdges.Contains(sec) || MergedWithBound.IsBound(sec));
3208 }
3209 }
3210 if (!isRejected) {
3211 if (mySectionBound.IsBound(iedge)) {
3212 // Edge is a section - check bound
3213 const TopoDS_Shape& bnd = mySectionBound(iedge);
3214 // Remove edge (section) if its bound already merged
3215 isRejected = (myMergedEdges.Contains(bnd) || MergedWithBound.IsBound(bnd));
3216 }
3217 }
3218 }
3219 // To the next merged edge
3220 if (isRejected) {
3221 // Remove rejected edge
3222 seqMergedWithBound.Remove(ii);
3223 seqMergedWithBoundOri.Remove(ii);
3224 }
3225 else {
3226 // Process accepted edge
3227 MergedWithBound.Bind(iedge,iedge);
3228 ii++;
3229 }
3230 }
3231 Standard_Integer nbMerged = seqMergedWithBound.Length();
3232 if (nbMerged) {
3233 // Create same parameter edge
3234 TopTools_MapOfShape ActuallyMerged;
3235 TopoDS_Edge MergedEdge = SameParameterEdge(bound,seqMergedWithBound,
3236 seqMergedWithBoundOri,
3237 ActuallyMerged,myReShape);
3238 Standard_Boolean isForward = Standard_False;
3239 if (!MergedEdge.IsNull()) isForward = (MergedEdge.Orientation() == TopAbs_FORWARD);
3240 // Process actually merged edges
3241 Standard_Integer nbActuallyMerged = 0;
3242 for (ii = 1; ii <= nbMerged; ii++) {
3243 TopoDS_Shape iedge = seqMergedWithBound(ii);
3244 if (ActuallyMerged.Contains(iedge)) {
3245 nbActuallyMerged++;
3246 // Record merged edge in the map
3247 TopAbs_Orientation orient = iedge.Orientation();
3248 if (!isForward) orient = TopAbs::Reverse(orient);
3249 if (!seqMergedWithBoundOri(ii)) orient = TopAbs::Reverse(orient);
3250 MergedWithBound.ChangeFind(iedge) = MergedEdge.Oriented(orient);
3251 }
3252 else MergedWithBound.UnBind(iedge);
3253 }
3254 if (nbActuallyMerged) {
3255 // Record merged bound in the map
3256 TopAbs_Orientation orient = bound.Orientation();
3257 if (!isForward) orient = TopAbs::Reverse(orient);
3258 MergedWithBound.ChangeFind(bound) = MergedEdge.Oriented(orient);
3259 }
3260 nbMerged = nbActuallyMerged;
3261 }
3262 // Remove bound from the map if not finally merged
3263 if (!nbMerged) MergedWithBound.UnBind(bound);
3264 }
3265 }
dde68833 3266 const Standard_Boolean isMerged = !MergedWithBound.IsEmpty();
7fd59977 3267
3268 // Merge with cutting sections
3269 Handle(BRepTools_ReShape) SectionsReShape = new BRepTools_ReShape;
3270 TopTools_DataMapOfShapeShape MergedWithSections;
3271 if (hasCuttingSections) {
3272 // Iterate on cutting sections
3273 TopTools_ListIteratorOfListOfShape its(myBoundSections(bound));
3274 for (; its.More(); its.Next()) {
3275 // Retrieve cutting section
3276 TopoDS_Shape section = its.Value();
3277 // Skip section if already merged
3278 if (myMergedEdges.Contains(section)) continue;
3279 // Merge cutting section
3280 TopTools_SequenceOfShape seqMergedWithSection;
dde68833 3281 TColStd_SequenceOfBoolean seqMergedWithSectionOri;
7fd59977 3282 if (MergedNearestEdges(section,seqMergedWithSection,seqMergedWithSectionOri)) {
3283 // Store section in the map
3284 MergedWithSections.Bind(section,section);
3285 // Iterate on edges merged with section
3286 Standard_Integer ii = 1;
3287 while (ii <= seqMergedWithSection.Length()) {
3288 TopoDS_Shape iedge = seqMergedWithSection.Value(ii);
3289 // Remove edge if recorded as merged
3290 Standard_Boolean isRejected = (myMergedEdges.Contains(iedge) || MergedWithSections.IsBound(iedge));
3291 if (!isRejected) {
3292 if (myBoundSections.IsBound(iedge)) {
3293 // Edge is splitted - check sections
3294 TopTools_ListIteratorOfListOfShape lit(myBoundSections(iedge));
3295 for (; lit.More() && !isRejected; lit.Next()) {
3296 const TopoDS_Shape& sec = lit.Value();
3297 // Remove edge (bound) if at least one of its sections already merged
3298 isRejected = (myMergedEdges.Contains(sec) || MergedWithSections.IsBound(sec));
3299 }
3300 }
3301 if (!isRejected) {
3302 if (mySectionBound.IsBound(iedge)) {
3303 // Edge is a section - check bound
3304 const TopoDS_Shape& bnd = mySectionBound(iedge);
3305 // Remove edge (section) if its bound already merged
3306 isRejected = (myMergedEdges.Contains(bnd) || MergedWithSections.IsBound(bnd));
3307 }
3308 }
3309 }
3310 // To the next merged edge
3311 if (isRejected) {
3312 // Remove rejected edge
3313 seqMergedWithSection.Remove(ii);
3314 seqMergedWithSectionOri.Remove(ii);
3315 }
3316 else {
3317 // Process accepted edge
3318 MergedWithSections.Bind(iedge,iedge);
3319 ii++;
3320 }
3321 }
3322 Standard_Integer nbMerged = seqMergedWithSection.Length();
3323 if (nbMerged) {
3324 // Create same parameter edge
3325 TopTools_MapOfShape ActuallyMerged;
3326 TopoDS_Edge MergedEdge = SameParameterEdge(section,seqMergedWithSection,
3327 seqMergedWithSectionOri,
3328 ActuallyMerged,SectionsReShape);
3329 Standard_Boolean isForward = Standard_False;
3330 if (!MergedEdge.IsNull()) isForward = (MergedEdge.Orientation() == TopAbs_FORWARD);
3331 // Process actually merged edges
3332 Standard_Integer nbActuallyMerged = 0;
3333 for (ii = 1; ii <= nbMerged; ii++) {
3334 TopoDS_Shape iedge = seqMergedWithSection(ii);
3335 if (ActuallyMerged.Contains(iedge)) {
3336 nbActuallyMerged++;
3337 // Record merged edge in the map
3338 TopAbs_Orientation orient = iedge.Orientation();
3339 if (!isForward) orient = TopAbs::Reverse(orient);
3340 if (!seqMergedWithSectionOri(ii)) orient = TopAbs::Reverse(orient);
3341 TopoDS_Shape oedge = MergedEdge.Oriented(orient);
3342 MergedWithSections.ChangeFind(iedge) = oedge;
3343 ReplaceEdge(myReShape->Apply(iedge),oedge,SectionsReShape);
3344 }
3345 else MergedWithSections.UnBind(iedge);
3346 }
3347 if (nbActuallyMerged) {
3348 // Record merged section in the map
3349 TopAbs_Orientation orient = section.Orientation();
3350 if (!isForward) orient = TopAbs::Reverse(orient);
3351 TopoDS_Shape oedge = MergedEdge.Oriented(orient);
3352 MergedWithSections.ChangeFind(section) = oedge;
3353 ReplaceEdge(myReShape->Apply(section),oedge,SectionsReShape);
3354 }
3355 nbMerged = nbActuallyMerged;
3356 }
3357 // Remove section from the map if not finally merged
3358 if (!nbMerged) MergedWithSections.UnBind(section);
3359 }
3360 else if (isMerged) {
3361 // Reject merging of sections
3362 MergedWithSections.Clear();
3363 break;
3364 }
3365 }
3366 }
dde68833 3367 const Standard_Boolean isMergedSplit = !MergedWithSections.IsEmpty();
7fd59977 3368
3369 if (!isMerged && !isMergedSplit) {
3370 // Nothing was merged in this iteration
3371 if (isPrevSplit) {
3372 // Replace previously splitted bound
3373 myReShape->Replace(myReShape->Apply(bound),myReShape->Apply(BoundWire));
3374 }
3375 // else if (hasCuttingSections) {
3376 // myBoundSections.UnBind(bound); //szv: are you sure ???
3377 // }
3378 continue;
3379 }
3380
3381 // Set splitting flag
3382 Standard_Boolean isSplitted = ((!isMerged && isMergedSplit) || isPrevSplit);
3383
3384 // Choose between bound and sections merging
3385 if (isMerged && isMergedSplit && !isPrevSplit) {
3386 // Fill map of merged cutting sections
3387 TopTools_MapOfShape MapSplitEdges;
3388 TopTools_DataMapIteratorOfDataMapOfShapeShape itm;
3389 for (itm.Initialize(MergedWithSections); itm.More(); itm.Next()) {
3390 TopoDS_Shape edge = itm.Key();
3391 MapSplitEdges.Add(edge);
3392 }
3393 // Iterate on edges merged with bound
3394 for (itm.Initialize(MergedWithBound); itm.More(); itm.Next()) {
3395 // Retrieve edge merged with bound