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