0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / BRepBuilderAPI / BRepBuilderAPI_Sewing.cxx
CommitLineData
b311480e 1// Created on: 1995-03-24
2// Created by: Jing Cheng MEI
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
47980104 16
7fd59977 17// dcl CCI60011 : Correction of degeneratedSection
18// Improvement of SameParameter Edge to treat case of failure in BRepLib::SameParameter
19// dcl Thu Aug 20 09:24:49 1998
20// Suppression of little faces.
21// dcl Fri Aug 7 15:27:46 1998
22// Refection of function SameParameter Edge.
23// Merge on the edge which has the less of poles.
24// Suppression of the Connected Edge function.
25// dcl Tue Jun 9 14:21:53 1998
26// Do not merge edge if they belong the same face
27// Tolerance management in VerticesAssembling
28// Tolerance management in Cutting
29// dcl Thu May 14 15:51:46 1998
30// optimization of cutting
31// dcl Thu May 7 15:51:46 1998
32// Add of cutting option
33// Add of SameParameter call
34
35
0d969553
Y
36//-- lbr April 1 97
37//-- dpf December 10 1997 Processing of pcurve collections
7fd59977 38
39//rln 02.02.99 BUC60449 Making compilable on NT in DEB mode
40//rln 02.02.99 BUC60449 Protection against exception on NT
41
42#define TEST 1
43
44#include <BRepBuilderAPI_Sewing.ixx>
45
46#include <Bnd_Box.hxx>
47#include <Bnd_Box2d.hxx>
48#include <Bnd_HArray1OfBox.hxx>
49#include <BndLib_Add2dCurve.hxx>
50#include <BndLib_Add3dCurve.hxx>
51#include <BRep_Builder.hxx>
52#include <BRep_Tool.hxx>
53#include <BRepLib.hxx>
54#include <BRepTools_Quilt.hxx>
55#include <BSplCLib.hxx>
56#include <Extrema_ExtPC.hxx>
57#include <GCPnts_AbscissaPoint.hxx>
58#include <GCPnts_UniformAbscissa.hxx>
59#include <GCPnts_UniformDeflection.hxx>
60#include <Geom2d_BezierCurve.hxx>
61#include <Geom2d_BSplineCurve.hxx>
62#include <Geom2d_Curve.hxx>
63#include <Geom2d_Line.hxx>
64#include <Geom2d_TrimmedCurve.hxx>
65#include <Geom2dAdaptor_Curve.hxx>
66#include <Geom2dConvert.hxx>
67#include <Geom_BezierCurve.hxx>
68#include <Geom_BSplineCurve.hxx>
69#include <Geom_Curve.hxx>
70#include <Geom_Line.hxx>
71#include <Geom_Surface.hxx>
72#include <GeomAdaptor_Curve.hxx>
73#include <GeomAdaptor_Surface.hxx>
74#include <GeomLib.hxx>
75#include <gp_Pnt.hxx>
76#include <gp_Vec.hxx>
77//#include <LocalAnalysis_SurfaceContinuity.hxx>
78#include <Precision.hxx>
79#include <Standard_ErrorHandler.hxx>
80#include <Standard_Failure.hxx>
81#include <TColgp_Array1OfVec.hxx>
82#include <TColgp_SequenceOfPnt.hxx>
83#include <TColStd_Array1OfInteger.hxx>
84#include <TColStd_Array1OfReal.hxx>
85#include <TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger.hxx>
86#include <TColStd_DataMapOfIntegerListOfInteger.hxx>
87#include <TColStd_IndexedMapOfInteger.hxx>
88#include <TColStd_ListIteratorOfListOfInteger.hxx>
89#include <TColStd_ListOfInteger.hxx>
90#include <TColStd_MapOfInteger.hxx>
91#include <TColStd_SequenceOfReal.hxx>
92#include <TopAbs.hxx>
93#include <TopExp.hxx>
94#include <TopExp_Explorer.hxx>
95#include <TopLoc_Location.hxx>
96#include <TopoDS.hxx>
97#include <TopoDS_Edge.hxx>
98#include <TopoDS_Iterator.hxx>
99#include <TopoDS_Shape.hxx>
100#include <TopoDS_Vertex.hxx>
101#include <TopoDS_Wire.hxx>
102#include <TopoDS_Shell.hxx>
103#include <TopTools_Array1OfShape.hxx>
104#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
105#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
106#include <TopTools_DataMapOfShapeInteger.hxx>
107#include <TopTools_DataMapOfShapeListOfShape.hxx>
108#include <TopTools_ListIteratorOfListOfShape.hxx>
109#include <TopTools_ListOfShape.hxx>
110#include <TopTools_MapIteratorOfMapOfShape.hxx>
111#include <TopTools_MapOfShape.hxx>
112#include <TopTools_SequenceOfShape.hxx>
113#include <TopoDS_Compound.hxx>
114#include <TColStd_Array2OfReal.hxx>
115#include <TColStd_MapIteratorOfMapOfInteger.hxx>
116#include <BRepTools.hxx>
117#include <Geom_RectangularTrimmedSurface.hxx>
118#include <Geom_OffsetSurface.hxx>
119#include <BRep_PointOnCurve.hxx>
120#include <BRep_ListOfPointRepresentation.hxx>
121#include <BRep_TVertex.hxx>
92434a36 122#include <Message_ProgressSentry.hxx>
82192477 123#include <BRepBuilderAPI_VertexInspector.hxx>
124#include <BRepBuilderAPI_CellFilter.hxx>
125#include <BRepBuilderAPI_BndBoxTreeSelector.hxx>
126#include <NCollection_UBTreeFiller.hxx>
7fd59977 127
7fd59977 128//=======================================================================
129//function : SameRange
130//purpose :
131//=======================================================================
132
133Handle(Geom2d_Curve) BRepBuilderAPI_Sewing::SameRange(const Handle(Geom2d_Curve)& CurvePtr,
134 const Standard_Real FirstOnCurve,
135 const Standard_Real LastOnCurve,
136 const Standard_Real RequestedFirst,
137 const Standard_Real RequestedLast) const
138{
139 Handle(Geom2d_Curve) NewCurvePtr;
140 try {
141
142 GeomLib::SameRange(Precision::PConfusion(),CurvePtr,FirstOnCurve,LastOnCurve,
143 RequestedFirst,RequestedLast,NewCurvePtr);
144 }
145 catch (Standard_Failure) {
146#ifdef DEB
147 cout << "Exception in BRepBuilderAPI_Sewing::SameRange: ";
148 Standard_Failure::Caught()->Print(cout); cout << endl;
149#endif
150 }
151 return NewCurvePtr;
152}
153
154//=======================================================================
155//function : WhichFace
0d969553 156//purpose : Give the face whose edge is the border
7fd59977 157//=======================================================================
158
159TopoDS_Face BRepBuilderAPI_Sewing::WhichFace(const TopoDS_Edge& theEdg, const Standard_Integer index) const
160{
161 TopoDS_Shape bound = theEdg;
162 if (mySectionBound.IsBound(bound)) bound = mySectionBound(bound);
163 if (myBoundFaces.Contains(bound)) {
164 Standard_Integer i = 1;
165 TopTools_ListIteratorOfListOfShape itf(myBoundFaces.FindFromKey(bound));
166 for (; itf.More(); itf.Next(), i++)
167 if (i == index) return TopoDS::Face(itf.Value());
168 }
169 return TopoDS_Face();
170}
171
172//=======================================================================
173//function : IsClosedShape
174//purpose :
175//=======================================================================
176
177static Standard_Boolean IsClosedShape(const TopoDS_Shape& theshape,
178 const TopoDS_Shape& v1, const TopoDS_Shape& v2)
179{
180 Standard_Real TotLength = 0.0;
181 TopExp_Explorer aexp;
182 for (aexp.Init(theshape,TopAbs_EDGE); aexp.More(); aexp.Next()) {
183 TopoDS_Edge aedge = TopoDS::Edge(aexp.Current());
184 if (aedge.IsNull()) continue;
185 TopoDS_Vertex ve1,ve2;
186 TopExp::Vertices(aedge,ve1,ve2);
187 if (!ve1.IsSame(v1) && !ve1.IsSame(v2)) continue;
188 if (BRep_Tool::Degenerated(aedge)) continue;
189 Standard_Real first,last;
190 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(aedge), first, last);
191 if (!c3d.IsNull()) {
192 GeomAdaptor_Curve cAdapt(c3d);
193 Standard_Real length = GCPnts_AbscissaPoint::Length(cAdapt, first, last);
194 TotLength += length;
195 if (ve2.IsSame(v1) || ve2.IsSame(v2)) break;
196 }
197 }
198 if (TotLength > 0.0) {
199 gp_Pnt p1 = BRep_Tool::Pnt(TopoDS::Vertex(v1));
200 gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(v2));
c6541a0c 201 return (p1.Distance(p2) < TotLength/(1.2 * M_PI));
7fd59977 202 }
203 return Standard_False;
204}
205
206//=======================================================================
207//function : IsClosedByIsos
208//purpose :
209//=======================================================================
210static Standard_Boolean IsClosedByIsos(const Handle(Geom_Surface)& thesurf,
211 const Handle(Geom2d_Curve)& acrv2d,
212 const Standard_Real f2d,
213 const Standard_Real l2d,
214 const Standard_Boolean isUIsos)
215{
216 Standard_Boolean isClosed = Standard_False;
217
218 gp_Pnt2d psurf1 = (acrv2d->IsPeriodic() ?
219 acrv2d->Value(f2d) : acrv2d->Value(Max(f2d,acrv2d->FirstParameter())));
220 gp_Pnt2d psurf2 = (acrv2d->IsPeriodic() ?
221 acrv2d->Value(l2d) : acrv2d->Value(Min(l2d,acrv2d->LastParameter())));
222 Handle(Geom_Curve) aCrv1;
223 Handle(Geom_Curve) aCrv2;
224 if(isUIsos) {
225 aCrv1 = thesurf->UIso(psurf1.X());
226 aCrv2 = thesurf->UIso(psurf2.X());
227 }
228 else {
229 aCrv1 = thesurf->VIso(psurf1.Y());
230 aCrv2 = thesurf->VIso(psurf2.Y());
231 }
232 gp_Pnt p11,p1m,p12,p21,p2m,p22;
233 Standard_Real af1 = aCrv1->FirstParameter();
234 Standard_Real al1 = aCrv1->LastParameter();
235 Standard_Real af2 = aCrv2->FirstParameter();
236 Standard_Real al2 = aCrv2->LastParameter();
237 aCrv1->D0(af1,p11);
238 aCrv1->D0((af1+al1)*0.5,p1m);
239 aCrv1->D0(al1,p12);
240 aCrv2->D0(af2,p21);
241 aCrv2->D0((af2+al2)*0.5,p2m);
242 aCrv2->D0(al2,p22);
243 isClosed = (((p11.XYZ() - p12.XYZ()).Modulus() <
244 (p11.XYZ() - p1m.XYZ()).Modulus() - Precision::Confusion()) &&
245 ((p21.XYZ() - p22.XYZ()).Modulus() <
246 (p21.XYZ() - p2m.XYZ()).Modulus() - Precision::Confusion())) ;
247 return isClosed;
248}
249//=======================================================================
250//function : IsUClosedSurface
251//purpose :
252//=======================================================================
253
254Standard_Boolean BRepBuilderAPI_Sewing::IsUClosedSurface(const Handle(Geom_Surface)& surf,
255 const TopoDS_Shape& theEdge,
256 const TopLoc_Location& theloc) const
257{
258 Handle(Geom_Surface) tmpsurf = surf;
259 if(tmpsurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
260 tmpsurf = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf)->BasisSurface();
261 else if(tmpsurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
262 tmpsurf = Handle(Geom_OffsetSurface)::DownCast(surf)->BasisSurface();
263 else {
264 Standard_Boolean isClosed = tmpsurf->IsUClosed();
265 if(!isClosed) {
266 Standard_Real f2d, l2d;
267 Handle(Geom2d_Curve) acrv2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge), surf,theloc, f2d, l2d);
268 if(!acrv2d.IsNull())
269 isClosed = IsClosedByIsos(tmpsurf,acrv2d,f2d, l2d,Standard_False );
270
271 }
272 return isClosed;
273 }
274 return IsUClosedSurface(tmpsurf,theEdge,theloc);
275 //return surf->IsUClosed();
276}
277
278//=======================================================================
279//function : IsVClosedSurface
280//purpose :
281//=======================================================================
282
283Standard_Boolean BRepBuilderAPI_Sewing::IsVClosedSurface(const Handle(Geom_Surface)& surf,
284 const TopoDS_Shape& theEdge,
285 const TopLoc_Location& theloc) const
286{
287 Handle(Geom_Surface) tmpsurf = surf;
288 if(tmpsurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
289 tmpsurf = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf)->BasisSurface();
290 else if(tmpsurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
291 tmpsurf = Handle(Geom_OffsetSurface)::DownCast(surf)->BasisSurface();
292 else {
293 Standard_Boolean isClosed = tmpsurf->IsVClosed();
294 if(!isClosed) {
295 Standard_Real f2d, l2d;
296 Handle(Geom2d_Curve) acrv2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge), surf,theloc, f2d, l2d);
297 if(!acrv2d.IsNull())
298 isClosed = IsClosedByIsos(tmpsurf,acrv2d,f2d, l2d,Standard_True );
299 }
300 return isClosed;
301 }
302 return IsVClosedSurface(tmpsurf,theEdge,theloc);
303 //return surf->IsVClosed();
304}
305
306//=======================================================================
307//function : SameParameter
308//purpose : internal use
309//=======================================================================
310
311void BRepBuilderAPI_Sewing::SameParameter(const TopoDS_Edge& edge) const
312{
313 try {
314
315 BRepLib::SameParameter(edge);
316 }
317 catch (Standard_Failure) {
318#ifdef DEB
319 cout << "Exception in BRepBuilderAPI_Sewing::SameParameter: ";
320 Standard_Failure::Caught()->Print(cout); cout << endl;
321#endif
322 }
323}
324
325//=======================================================================
326//function : SameParameterEdge
327//purpose : internal use
328// Merge the Sequence Of Section on one edge.
329// This function keep the curve3d,curve2d,range and parametrization
330// from the first section, and report and made sameparameter the
331// pcurves of the other function.
332// This function works when the are not more than two Pcurves
333// on a same face.
334//=======================================================================
335
336TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Shape& edge,
337 const TopTools_SequenceOfShape& seqEdges,
338 const TColStd_SequenceOfInteger& seqForward,
339 TopTools_MapOfShape& mapMerged,
340 const Handle(BRepTools_ReShape)& locReShape)
341{
342 // Retrieve reference section
343 TopoDS_Shape aTmpShape = myReShape->Apply(edge); //for porting
344 TopoDS_Edge Edge1 = TopoDS::Edge(aTmpShape);
345 aTmpShape = locReShape->Apply(Edge1);
346 if (locReShape != myReShape) Edge1 = TopoDS::Edge(aTmpShape);
347 Standard_Boolean isDone = Standard_False;
348
349 // Create data structures for temporary merged edges
350 TopTools_ListOfShape listFaces1;
351 TopTools_MapOfShape MergedFaces;
352
353 if (mySewing) {
354
355 // Fill MergedFaces with faces of Edge1
356 TopoDS_Shape bnd1 = edge;
357 if (mySectionBound.IsBound(bnd1)) bnd1 = mySectionBound(bnd1);
358 if (myBoundFaces.Contains(bnd1)) {
359 TopTools_ListIteratorOfListOfShape itf(myBoundFaces.FindFromKey(bnd1));
360 for (; itf.More(); itf.Next())
361 if (MergedFaces.Add(itf.Value()))
362 listFaces1.Append(itf.Value());
363 }
364 }
365 else {
366
367 // Create presentation edge
368 TopoDS_Vertex V1, V2;
369 TopExp::Vertices(Edge1,V1,V2);
370 if (myVertexNode.Contains(V1)) V1 = TopoDS::Vertex(myVertexNode.FindFromKey(V1));
371 if (myVertexNode.Contains(V2)) V2 = TopoDS::Vertex(myVertexNode.FindFromKey(V2));
372
373 TopoDS_Edge NewEdge = Edge1;
374 NewEdge.EmptyCopy();
375
376 // Add the vertices
377 BRep_Builder aBuilder;
378 TopoDS_Shape anEdge = NewEdge.Oriented(TopAbs_FORWARD);
379 aBuilder.Add(anEdge,V1.Oriented(TopAbs_FORWARD));
380 aBuilder.Add(anEdge,V2.Oriented(TopAbs_REVERSED));
381
382 Edge1 = NewEdge;
383 }
384
385 Standard_Boolean isForward = Standard_True;
386
387 // Merge candidate sections
388 for (Standard_Integer i = 1; i <= seqEdges.Length(); i++) {
389
390 // Retrieve candidate section
391 TopoDS_Shape oedge2 = seqEdges(i);
392
393 if (mySewing) {
394
395 aTmpShape = myReShape->Apply(oedge2); //for porting
396 TopoDS_Edge Edge2 = TopoDS::Edge(aTmpShape);
397 aTmpShape = locReShape->Apply(Edge2);
398 if (locReShape != myReShape) Edge2 = TopoDS::Edge(aTmpShape);
399
400 // Calculate relative orientation
401 Standard_Integer Orientation = seqForward(i);
402 if (!isForward) Orientation = (Orientation? 0 : 1);
403
404 // Retrieve faces information for the second edge
405 TopoDS_Shape bnd2 = oedge2;
406 if (mySectionBound.IsBound(bnd2)) bnd2 = mySectionBound(bnd2);
407 if (!myBoundFaces.Contains(bnd2)) continue; // Skip floating edge
408 const TopTools_ListOfShape& listFaces2 = myBoundFaces.FindFromKey(bnd2);
409
410 Standard_Integer whichSec = 1; // Indicates on which edge the pCurve has been reported
411 TopoDS_Edge NewEdge = SameParameterEdge(Edge1,Edge2,listFaces1,listFaces2,Orientation,whichSec);
412 if (NewEdge.IsNull()) continue;
413
414 // Record faces information for the temporary merged edge
415 TopTools_ListIteratorOfListOfShape itf(listFaces2);
416 for (; itf.More(); itf.Next())
417 if (MergedFaces.Add(itf.Value()))
418 listFaces1.Append(itf.Value());
419
420 // Record merged section orientation
421 if (!Orientation && whichSec != 1)
422 isForward = isForward? Standard_False : Standard_True;
423 Edge1 = NewEdge;
424 }
425
426 // Append actually merged edge
427 mapMerged.Add(oedge2);
428 isDone = Standard_True;
429
430 if (!myNonmanifold) break;
431 }
432
433 if (isDone) {
434 // Change result orientation
435 Edge1.Orientation(isForward? TopAbs_FORWARD : TopAbs_REVERSED);
436 }
437 else Edge1.Nullify();
438
439 return Edge1;
440}
441
442//=======================================================================
443//function : SameParameterEdge
444//purpose : internal use
445//=======================================================================
446static Standard_Boolean findNMVertices(const TopoDS_Edge& theEdge,
447 TopTools_SequenceOfShape& theSeqNMVert,
448 TColStd_SequenceOfReal& theSeqPars)
449{
450 TopoDS_Iterator aItV(theEdge,Standard_False);
451 for( ; aItV.More(); aItV.Next()) {
452 if(aItV.Value().Orientation() == TopAbs_INTERNAL ||
453 aItV.Value().Orientation() == TopAbs_EXTERNAL)
454 theSeqNMVert.Append(aItV.Value());
455 }
456 Standard_Integer nbV = theSeqNMVert.Length();
457 if(!nbV)
458 return Standard_False;
459 Standard_Real first, last;
460 Handle(Geom_Curve) c3d = BRep_Tool::Curve(theEdge,first, last);
461 GeomAdaptor_Curve GAC(c3d);
462 Extrema_ExtPC locProj;
463 locProj.Initialize(GAC, first, last);
464 gp_Pnt pfirst = GAC.Value(first), plast = GAC.Value(last);
465
466
467 for (Standard_Integer i = 1; i <= nbV; i++) {
468 TopoDS_Vertex aV = TopoDS::Vertex(theSeqNMVert.Value(i));
469 gp_Pnt pt = BRep_Tool::Pnt(aV);
470
471 Standard_Real distF2 = pfirst.SquareDistance(pt);
472 Standard_Real distL2 = plast.SquareDistance(pt);
473 Standard_Real apar = (distF2 > distL2 ? last : first);
474 // Project current point on curve
475 locProj.Perform(pt);
476 if (locProj.IsDone() && locProj.NbExt() > 0) {
477 Standard_Real dist2Min = Min(distF2,distL2);
478 Standard_Integer ind, indMin = 0;
479 for (ind = 1; ind <= locProj.NbExt(); ind++) {
480 Standard_Real dProj2 = locProj.SquareDistance(ind);
481 if (dProj2 < dist2Min) {
482 indMin = ind; dist2Min = dProj2;
483 }
484 }
485 if(indMin)
486 apar = locProj.Point(indMin).Parameter();
487
488 theSeqPars.Append(apar);
489
490 }
491 }
492 return Standard_True;
493}
494
2028d00c 495static inline Standard_Real ComputeToleranceVertex(const Standard_Real dist, const Standard_Real Tol1, const Standard_Real Tol2)
7fd59977 496{
2028d00c 497 return (dist * 0.5 + Tol1 + Tol2);
7fd59977 498}
499TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirst,
500 const TopoDS_Edge& edgeLast,
501 const TopTools_ListOfShape& listFacesFirst,
502 const TopTools_ListOfShape& listFacesLast,
503 const Standard_Boolean secForward,
504 Standard_Integer& whichSec,
505 const Standard_Boolean firstCall)
506{
507 // Do not process floating edges
508 if (!listFacesFirst.Extent() || !listFacesLast.Extent()) return TopoDS_Edge();
509
510 // Sort input edges
511 TopoDS_Edge edge1, edge2;
512 if (firstCall) {
513 // Take the longest edge as first
514 Standard_Real f, l;
515 Handle(Geom_Curve) c3d1 = BRep_Tool::Curve(TopoDS::Edge(edgeFirst), f, l);
516 GeomAdaptor_Curve cAdapt1(c3d1);
517 Standard_Real len1 = GCPnts_AbscissaPoint::Length(cAdapt1, f, l);
518 Handle(Geom_Curve) c3d2 = BRep_Tool::Curve(TopoDS::Edge(edgeLast), f, l);
519 GeomAdaptor_Curve cAdapt2(c3d2);
520 Standard_Real len2 = GCPnts_AbscissaPoint::Length(cAdapt2, f, l);
521 if (len1 < len2) {
522 edge1 = edgeLast;
523 edge2 = edgeFirst;
524 whichSec = 2;
525 }
526 else {
527 edge1 = edgeFirst;
528 edge2 = edgeLast;
529 whichSec = 1;
530 }
531 }
532 else {
533 if (whichSec == 1) {
534 edge1 = edgeLast;
535 edge2 = edgeFirst;
536 whichSec = 2;
537 }
538 else {
539 edge1 = edgeFirst;
540 edge2 = edgeLast;
541 whichSec = 1;
542 }
543 }
544
545 Standard_Real first, last;
546 BRep_Tool::Range(edge1, first, last);
547 BRep_Builder aBuilder;
548
549 //To keep NM vertices on edge
550 TopTools_SequenceOfShape aSeqNMVert;
551 TColStd_SequenceOfReal aSeqNMPars;
552 findNMVertices(edge1,aSeqNMVert,aSeqNMPars);
553 findNMVertices(edge2,aSeqNMVert,aSeqNMPars);
554
555 // Create new edge
556 TopoDS_Edge edge;
557 aBuilder.MakeEdge(edge);
558 edge.Orientation( edge1.Orientation());
559
560
561 // Retrieve edge curve
562 TopLoc_Location loc3d;
563 Standard_Real first3d, last3d;
564 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge1, loc3d, first3d, last3d);
565 if (!loc3d.IsIdentity()) {
566 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
567 c3d->Transform(loc3d.Transformation());
568 }
569 aBuilder.UpdateEdge(edge,c3d,BRep_Tool::Tolerance(edge1));
570 aBuilder.Range(edge, first, last);
571 aBuilder.SameRange(edge, Standard_False); //Standard_True
572 aBuilder.SameParameter(edge, Standard_False);
573 // Create and add new vertices
574 {
575 TopoDS_Vertex V1New, V2New;
576
577 // Retrieve original vertices from edges
578 TopoDS_Vertex V11,V12,V21,V22;
579 TopExp::Vertices(edge1,V11,V12);
580 TopExp::Vertices(edge2,V21,V22);
581
67ffcad0
G
582 //check that edges merged valid way (for edges having length less than specified
583 //tolerance
9781f215
G
584 // Check if edges are closed
585 Standard_Boolean isClosed1 = V11.IsSame(V12);
586 Standard_Boolean isClosed2 = V21.IsSame(V22);
587 if(!isClosed1 && !isClosed2)
2028d00c 588 {
9781f215
G
589 if(secForward )
590 {
591 if( V11.IsSame(V22) || V12.IsSame(V21) )
592 return TopoDS_Edge();
593 }
594 else
595 {
596 if( V11.IsSame(V21) || V12.IsSame(V22) )
597 return TopoDS_Edge();
598 }
2028d00c
G
599 }
600
7fd59977 601 //szv: do not reshape here!!!
602 //V11 = TopoDS::Vertex(myReShape->Apply(V11));
603 //V12 = TopoDS::Vertex(myReShape->Apply(V12));
604 //V21 = TopoDS::Vertex(myReShape->Apply(V21));
605 //V22 = TopoDS::Vertex(myReShape->Apply(V22));
606
607 gp_Pnt p11 = BRep_Tool::Pnt(V11);
608 gp_Pnt p12 = BRep_Tool::Pnt(V12);
609 gp_Pnt p21 = BRep_Tool::Pnt(V21);
610 gp_Pnt p22 = BRep_Tool::Pnt(V22);
611
9781f215 612
7fd59977 613
614 //Standard_Boolean isRev = Standard_False;
615 gp_Pnt pfirst;
616 Standard_Real Tol1 = 0.;
617 if (isClosed1 || isClosed2) {
618 // at least one of the edges is closed
619 if (isClosed1 && isClosed2) {
67ffcad0
G
620 // both edges are closed
621 pfirst.SetXYZ(0.5*(p11.XYZ() + p21.XYZ()));
7fd59977 622 gp_Vec v1 = p21.XYZ() - p11.XYZ();
623 Standard_Real d1 = v1.Magnitude();
624 Tol1 = ComputeToleranceVertex(d1,BRep_Tool::Tolerance(V11),BRep_Tool::Tolerance(V21));
67ffcad0 625 //Tol1 = Max(pfirst.Distance(p11),pfirst.Distance(p21));
7fd59977 626 }
627 else if (isClosed1) {
67ffcad0 628 // only first edge is closed
7fd59977 629 gp_XYZ pt =0.5*(p21.XYZ()+ p22.XYZ());
67ffcad0 630 pfirst.SetXYZ(0.5*(p11.XYZ() + pt));
7fd59977 631 gp_Vec v1 = p22.XYZ() - p21.XYZ();
632 Standard_Real d1 = v1.Magnitude();
633 Tol1= ComputeToleranceVertex(d1,BRep_Tool::Tolerance(V22),BRep_Tool::Tolerance(V21));
634 gp_Vec v2 = p11.XYZ() - pt;
635 Standard_Real d2 = v2.Magnitude();
636 Tol1= ComputeToleranceVertex(d2,Tol1,BRep_Tool::Tolerance(V11));
67ffcad0
G
637 //Tol1 = Max(pfirst.Distance(p21),pfirst.Distance(p22));
638 //Tol1 = Max(pfirst.Distance(p11),Tol1);
7fd59977 639 }
640 else {
67ffcad0 641 // only second edge is closed
7fd59977 642 gp_XYZ pt = 0.5*(p11.XYZ()+ p12.XYZ());
67ffcad0 643 pfirst.SetXYZ(0.5*(p21.XYZ() + pt));
7fd59977 644 gp_Vec v1 = p11.XYZ() - p12.XYZ();
645 Standard_Real d1 = v1.Magnitude();
646 Tol1 = ComputeToleranceVertex(d1,BRep_Tool::Tolerance(V11),BRep_Tool::Tolerance(V12));
647 gp_Vec v2 = p21.XYZ() - pt;
648 Standard_Real d2 = v2.Magnitude();
649 Tol1 = ComputeToleranceVertex(d2,Tol1,BRep_Tool::Tolerance(V21));
67ffcad0
G
650 //Tol1 = Max(pfirst.Distance(p11),pfirst.Distance(p12));
651 //Tol1 = Max(pfirst.Distance(p21),Tol1);
7fd59977 652 }
653 aBuilder.MakeVertex(V1New,pfirst,Tol1);
654 V2New = V1New;
655 }
656 else {
657 // both edges are open
658 gp_Pnt plast;
659 Standard_Real Tol2 = 0.;
67ffcad0
G
660 Standard_Boolean isOldFirst = ( secForward ? V11.IsSame(V21) : V11.IsSame(V22) );
661 Standard_Boolean isOldLast = ( secForward ? V12.IsSame(V22) : V12.IsSame(V21)) ;
7fd59977 662 if (secForward) {
67ffcad0
G
663 //case if vertices already sewed
664 if(!isOldFirst)
665 {
666 pfirst.SetXYZ(0.5*(p11.XYZ() + p21.XYZ()));
667 gp_Vec v1 = p21.XYZ() - p11.XYZ();
668 Standard_Real d1 = v1.Magnitude();
669 Tol1 = ComputeToleranceVertex(d1,BRep_Tool::Tolerance(V11),BRep_Tool::Tolerance(V21));
670 }
671 if(!isOldLast)
672 {
673 plast.SetXYZ(0.5*(p12.XYZ() + p22.XYZ()));
674
675 gp_Vec v2 = p22.XYZ() - p12.XYZ();
676 Standard_Real d2 = v2.Magnitude();
677
678 Tol2 = ComputeToleranceVertex(d2,BRep_Tool::Tolerance(V12),BRep_Tool::Tolerance(V22));
679 }
7fd59977 680
7fd59977 681 }
682 else {
67ffcad0
G
683 if(!isOldFirst)
684 {
685 pfirst.SetXYZ(0.5*(p11.XYZ() + p22.XYZ()));
686 gp_Vec v1 = p22.XYZ() - p11.XYZ();
687 Standard_Real d1 = v1.Magnitude();
688 Tol1 = ComputeToleranceVertex(d1,BRep_Tool::Tolerance(V11),BRep_Tool::Tolerance(V22));
689 }
690 if(!isOldLast)
691 {
692 plast.SetXYZ(0.5*(p12.XYZ() + p21.XYZ()));
693 gp_Vec v2 = p21.XYZ() - p12.XYZ();
694 Standard_Real d2 = v2.Magnitude();
695 Tol2 = ComputeToleranceVertex(d2,BRep_Tool::Tolerance(V12),BRep_Tool::Tolerance(V21));
696 }
697
7fd59977 698 }
67ffcad0
G
699 if(!isOldFirst)
700 aBuilder.MakeVertex(V1New,pfirst,Tol1);
701 else
702 V1New = V11;
703
704
705 if(!isOldLast)
706 aBuilder.MakeVertex(V2New,plast,Tol2);
707 else
708 V2New = V12;
709
7fd59977 710 }
711
712 // Add the vertices in the good sense
713 TopoDS_Shape anEdge = edge.Oriented(TopAbs_FORWARD);
714 TopoDS_Shape aLocalEdge = V1New.Oriented(TopAbs_FORWARD); //(listNode.First()).Oriented(TopAbs_FORWARD);
715 aBuilder.Add(anEdge,aLocalEdge);
716 aLocalEdge = V2New.Oriented(TopAbs_REVERSED); //(listNode.Last()).Oriented(TopAbs_REVERSED);
717 aBuilder.Add(anEdge,aLocalEdge);
718
719 Standard_Integer k =1;
720 for( ; k <= aSeqNMVert.Length(); k++)
721 aBuilder.Add(anEdge,aSeqNMVert.Value(k));
722
723 }
724
725 // Retrieve second PCurves
726 TopLoc_Location loc2;
727 Handle(Geom_Surface) surf2;
47980104 728
7fd59977 729 //Handle(Geom2d_Curve) c2d2, c2d21;
730 // Standard_Real firstOld, lastOld;
731
732 TopTools_ListIteratorOfListOfShape itf2;
733 if (whichSec == 1) itf2.Initialize(listFacesLast);
734 else itf2.Initialize(listFacesFirst);
735 Standard_Boolean isResEdge = Standard_False;
0221b126 736 TopoDS_Face fac2;
7fd59977 737 for (; itf2.More(); itf2.Next()) {
738 Handle(Geom2d_Curve) c2d2, c2d21;
739 Standard_Real firstOld, lastOld;
0221b126 740 fac2 = TopoDS::Face(itf2.Value());
7fd59977 741
742 surf2 = BRep_Tool::Surface(fac2, loc2);
743 Standard_Boolean isSeam2 = ((IsUClosedSurface(surf2,edge2,loc2) || IsVClosedSurface(surf2,edge2,loc2)) &&
67ffcad0 744 BRep_Tool::IsClosed(TopoDS::Edge(edge2),fac2));
7fd59977 745 if (isSeam2) {
746 if (!myNonmanifold) return TopoDS_Edge();
747 TopoDS_Shape aTmpShape = edge2.Reversed(); //for porting
748 c2d21 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aTmpShape), fac2, firstOld, lastOld);
749 }
750 c2d2 = BRep_Tool::CurveOnSurface(edge2, fac2, firstOld, lastOld);
751 if (c2d2.IsNull() && c2d21.IsNull()) continue;
752
753 if (!c2d21.IsNull()) {
754 c2d21 = Handle(Geom2d_Curve)::DownCast(c2d21->Copy());
755 if (!secForward) {
67ffcad0
G
756 if (c2d21->IsKind(STANDARD_TYPE(Geom2d_Line)))
757 c2d21 = new Geom2d_TrimmedCurve(c2d21, firstOld, lastOld);
758 Standard_Real first2d = firstOld; //c2dTmp->FirstParameter(); BUG USA60321
759 Standard_Real last2d = lastOld; //c2dTmp->LastParameter();
760 firstOld = c2d21->ReversedParameter(last2d);
761 lastOld = c2d21->ReversedParameter(first2d);
762 c2d21->Reverse();
7fd59977 763 }
764 c2d21 = SameRange(c2d21,firstOld,lastOld,first,last);
765 }
766
767 // Make second PCurve sameRange with the 3d curve
768 c2d2 = Handle(Geom2d_Curve)::DownCast(c2d2->Copy());
67ffcad0 769
7fd59977 770 if (!secForward) {
771 if (c2d2->IsKind(STANDARD_TYPE(Geom2d_Line)))
67ffcad0
G
772 c2d2 = new Geom2d_TrimmedCurve(c2d2, firstOld, lastOld);
773 Standard_Real first2d = firstOld;
774 Standard_Real last2d = lastOld;
7fd59977 775 firstOld = c2d2->ReversedParameter(last2d);
776 lastOld = c2d2->ReversedParameter(first2d);
777 c2d2->Reverse();
778 }
779
780 c2d2 = SameRange(c2d2,firstOld,lastOld,first,last);
781 if (c2d2.IsNull()) continue;
67ffcad0 782
7fd59977 783 // Add second PCurve
784 Standard_Boolean isSeam = Standard_False;
785 TopAbs_Orientation Ori = TopAbs_FORWARD;
786 //Handle(Geom2d_Curve) c2d1, c2d11;
787
788 TopTools_ListIteratorOfListOfShape itf1;
789 if (whichSec == 1) itf1.Initialize(listFacesFirst);
790 else itf1.Initialize(listFacesLast);
791 for (; itf1.More() && !isSeam; itf1.Next()) {
792 Handle(Geom2d_Curve) c2d1, c2d11;
793 const TopoDS_Face& fac1 = TopoDS::Face(itf1.Value());
794
795 TopLoc_Location loc1;
796 Handle(Geom_Surface) surf1 = BRep_Tool::Surface(fac1, loc1);
47980104 797
7fd59977 798 Standard_Real first2d, last2d;
799 Standard_Boolean isSeam1 = ((IsUClosedSurface(surf1,edge1,loc1) || IsVClosedSurface(surf1,edge1,loc1)) &&
67ffcad0 800 BRep_Tool::IsClosed(TopoDS::Edge(edge1),fac1));
7fd59977 801 c2d1 = BRep_Tool::CurveOnSurface(edge1, fac1, first2d, last2d);
802 Ori = edge1.Orientation();
803 if (fac1.Orientation() == TopAbs_REVERSED)
804 Ori = TopAbs::Reverse(Ori);
67ffcad0 805
7fd59977 806 if (isSeam1) {
67ffcad0 807 if (!myNonmanifold) return TopoDS_Edge();
7fd59977 808 TopoDS_Shape aTmpShape = edge1.Reversed(); //for porting
809 c2d11 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aTmpShape), fac1, first2d, last2d);
810 //if(fac1.Orientation() == TopAbs_REVERSED) //
811 if(Ori == TopAbs_FORWARD)
812 aBuilder.UpdateEdge(edge,c2d1,c2d11,fac1,0);
813 else
814 aBuilder.UpdateEdge(edge,c2d11,c2d1,fac1,0);
815 }
816 else aBuilder.UpdateEdge(edge,c2d1,fac1,0);
7fd59977 817
67ffcad0 818 if (c2d1.IsNull() && c2d11.IsNull()) continue;
7fd59977 819
820 if (surf2 == surf1) {
67ffcad0
G
821 // Merge sections which are on the same face
822 if (!loc2.IsDifferent(loc1)) {
823 Standard_Boolean uclosed = IsUClosedSurface(surf2,edge2,loc2);
824 Standard_Boolean vclosed = IsVClosedSurface(surf2,edge2,loc2);
825 if (uclosed || vclosed) {
826 Standard_Real pf = c2d1->FirstParameter();
827 // Standard_Real pl = c2d1->LastParameter();
828 gp_Pnt2d p1n = c2d1->Value(Max(first,pf));
829 // gp_Pnt2d p2n = c2d1->Value(Min(pl,last));
7fd59977 830 gp_Pnt2d p21n = c2d2->Value(Max(first,c2d2->FirstParameter()));
831 gp_Pnt2d p22n = c2d2->Value(Min(last,c2d2->LastParameter()));
832 Standard_Real aDist = Min(p1n.Distance(p21n), p1n.Distance(p22n));
67ffcad0
G
833 Standard_Real U1, U2, V1, V2;
834 surf2->Bounds(U1, U2, V1, V2);
835 isSeam = ((uclosed && aDist > 0.75*(fabs(U2-U1))) ||
836 (vclosed && aDist > 0.75*(fabs(V2-V1))));
7fd59977 837 if( !isSeam && BRep_Tool::IsClosed(TopoDS::Edge(edge),fac1)) continue;
67ffcad0
G
838 }
839 }
7fd59977 840 }
67ffcad0 841
7fd59977 842 isResEdge = Standard_True;
843 if (isSeam) {
844 if (Ori == TopAbs_FORWARD)
845 aBuilder.UpdateEdge(edge, c2d1, c2d2, surf2, loc2, Precision::Confusion());
846 else
847 aBuilder.UpdateEdge(edge, c2d2, c2d1, surf2, loc2, Precision::Confusion());
848 }
849 else if (isSeam2) {
850 TopAbs_Orientation InitOri = edge2.Orientation();
67ffcad0 851 TopAbs_Orientation SecOri = edge.Orientation();
7fd59977 852 if (fac2.Orientation() == TopAbs_REVERSED) {
67ffcad0 853
7fd59977 854 InitOri = TopAbs::Reverse(InitOri);
855 SecOri = TopAbs::Reverse(SecOri);
856 }
857 if(!secForward)
858 InitOri = TopAbs::Reverse(InitOri);
67ffcad0 859
7fd59977 860 if (InitOri == TopAbs_FORWARD)
861 aBuilder.UpdateEdge(edge, c2d2,c2d21, surf2, loc2, Precision::Confusion());
862 else
863 aBuilder.UpdateEdge(edge, c2d21,c2d2, surf2, loc2, Precision::Confusion());
864 }
865 else {
866 aBuilder.UpdateEdge(edge, c2d2, surf2, loc2, Precision::Confusion());
867 }
67ffcad0 868
7fd59977 869 }
870 }
47980104 871 Standard_Real tolReached = Precision::Infinite();
872 Standard_Boolean isSamePar = Standard_False;
873 if( isResEdge)
874 {
7fd59977 875 SameParameter(edge);
47980104 876 if( BRep_Tool::SameParameter(edge))
877 {
878 isSamePar = Standard_True;
879 tolReached = BRep_Tool::Tolerance(edge);
880 }
881 }
882
883
884 if (firstCall && ( !isResEdge || !isSamePar || tolReached > myTolerance)) {
7fd59977 885 Standard_Integer whichSecn = whichSec;
886 // Try to merge on the second section
47980104 887 Standard_Boolean second_ok = Standard_False;
7fd59977 888 TopoDS_Edge s_edge = SameParameterEdge(edgeFirst,edgeLast,listFacesFirst,listFacesLast,
67ffcad0 889 secForward,whichSecn,Standard_False);
47980104 890 if( !s_edge.IsNull())
891 {
892 Standard_Real tolReached_2 = BRep_Tool::Tolerance(s_edge);
893 second_ok = ( BRep_Tool::SameParameter(s_edge) && tolReached_2 < tolReached );
894 if( second_ok)
895 {
896 edge = s_edge;
897 whichSec = whichSecn;
0221b126 898 tolReached = tolReached_2;
47980104 899 }
7fd59977 900 }
901
47980104 902 if (!second_ok && !edge.IsNull()) {
7fd59977 903
904 GeomAdaptor_Curve c3dAdapt(c3d);
905
906 // Discretize edge curve
0221b126 907 Standard_Integer i, j, nbp = 23;
7fd59977 908 Standard_Real deltaT = (last3d - first3d) / (nbp + 1);
909 TColgp_Array1OfPnt c3dpnt(1,nbp);
0221b126 910 for (i = 1; i <= nbp; i++)
911 c3dpnt(i) = c3dAdapt.Value(first3d + i*deltaT);
7fd59977 912
0221b126 913 Standard_Real dist = 0., maxTol = -1.0;
7fd59977 914 Standard_Boolean more = Standard_True;
915
916 for (j = 1; more; j++) {
917 Handle(Geom2d_Curve) c2d2;
67ffcad0 918 BRep_Tool::CurveOnSurface(edge, c2d2, surf2, loc2, first, last, j);
0221b126 919
67ffcad0
G
920 more = !c2d2.IsNull();
921 if (more) {
0221b126 922 Handle(Geom_Surface) aS = surf2;
923 if(!loc2.IsIdentity())
924 aS = Handle(Geom_Surface)::DownCast(surf2->Transformed ( loc2 ));
67ffcad0 925
0221b126 926 Standard_Real dist2 = 0.;
67ffcad0
G
927 deltaT = (last - first) / (nbp + 1);
928 for (i = 1; i <= nbp; i++) {
0221b126 929 gp_Pnt2d aP2d = c2d2->Value(first + i*deltaT);
930 gp_Pnt aP2(0.,0.,0.);
931 aS->D0(aP2d.X(),aP2d.Y(), aP2);
932 gp_Pnt aP1 = c3dpnt(i);
933 dist = aP2.SquareDistance(aP1);
934 if (dist > dist2)
935 dist2 = dist;
67ffcad0 936 }
0221b126 937 maxTol = Max(sqrt(dist2), Precision::Confusion());
67ffcad0 938 }
7fd59977 939 }
0221b126 940 if(maxTol >= 0. && maxTol < tolReached)
941 aBuilder.UpdateEdge(edge, maxTol);
7fd59977 942 aBuilder.SameParameter(edge,Standard_True);
943 }
944 }
945
946 BRepLib::EncodeRegularity(edge,0.01);
947 Standard_Real tolEdge1 = BRep_Tool::Tolerance(edge);
948 if (tolEdge1 > MaxTolerance()) edge.Nullify();
949 return edge;
950}
951
952//=======================================================================
953// function : EvaluateAngulars
954// purpose : internal use
955//=======================================================================
956
957void BRepBuilderAPI_Sewing::EvaluateAngulars(TopTools_SequenceOfShape& sequenceSec,
958 TColStd_Array1OfBoolean& secForward,
959 TColStd_Array1OfReal& tabAng,
960 const Standard_Integer indRef) const
961{
962 tabAng.Init(-1.0);
963
964 Standard_Integer i, j, npt = 4, lengSec = sequenceSec.Length();
965
966 TopoDS_Edge edge;
967 TopoDS_Face face;
968 TopLoc_Location loc;
969 Standard_Real first, last;
970 Handle(Geom_Curve) c3d;
971 Handle(Geom2d_Curve) c2d;
972 Handle(Geom_Surface) surf;
973 TColgp_Array1OfVec normRef(1,npt);
974
975 for (i = indRef; i <= lengSec; i++) {
976
977 edge = TopoDS::Edge(sequenceSec(i));
978
979 TopoDS_Shape bnd = edge;
980 if (mySectionBound.IsBound(bnd)) bnd = mySectionBound(bnd);
981 if (myBoundFaces.Contains(bnd)) {
982 face = TopoDS::Face(myBoundFaces.FindFromKey(bnd).First());
983 surf = BRep_Tool::Surface(face,loc);
984 if (!loc.IsIdentity()) {
985 surf = Handle(Geom_Surface)::DownCast(surf->Copy());
986 surf->Transform(loc.Transformation());
987 }
988 c2d = BRep_Tool::CurveOnSurface(edge, face, first, last);
989 }
990 else if (i == indRef) return;
991 else continue;
992
993 c3d = BRep_Tool::Curve(edge, loc, first, last);
994 if (!loc.IsIdentity()) {
995 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
996 c3d->Transform(loc.Transformation());
997 }
998
999 GeomAdaptor_Curve adapt(c3d);
1000 GCPnts_UniformAbscissa uniAbs(adapt, npt, first, last);
1001
1002 Standard_Real cumulateAngular = 0.0;
1003 Standard_Integer nbComputedAngle = 0;
1004
1005 for (j = 1; j <= npt; j++) {
1006 gp_Pnt2d P;
1007 c2d->D0(uniAbs.Parameter((secForward(i) || i == indRef)? j : npt-j+1),P);
1008 gp_Vec w1, w2;
1009 gp_Pnt unused;
1010 surf->D1(P.X(), P.Y(), unused, w1, w2);
1011 gp_Vec n = w1^w2; // Compute the normal vector
1012 if (i == indRef) normRef(j) = n;
1013 else if ((n.Magnitude()>gp::Resolution()) && (normRef(j).Magnitude()>gp::Resolution())) {
1014 nbComputedAngle++;
1015 Standard_Real angular = n.Angle(normRef(j));
c6541a0c 1016 if (angular > M_PI/2.) angular = M_PI - angular;
7fd59977 1017 cumulateAngular += angular;
1018 }
1019 }
1020
1021 if (nbComputedAngle)
1022 tabAng(i) = cumulateAngular/((Standard_Real)nbComputedAngle);
1023 }
1024}
1025
1026//=======================================================================
1027// function : EvaluateDistances
1028// purpose : internal use
1029// Evaluate distance beetween edges with indice indRef and the following edges in the list
1030// Remarks (lengSec - indRef) must be >= 1
1031//=======================================================================
7fd59977 1032void BRepBuilderAPI_Sewing::EvaluateDistances(TopTools_SequenceOfShape& sequenceSec,
1033 TColStd_Array1OfBoolean& secForward,
1034 TColStd_Array1OfReal& tabDst,
1035 TColStd_Array1OfReal& arrLen,
1036 TColStd_Array1OfReal& tabMinDist,
1037 const Standard_Integer indRef) const
1038{
1039 secForward.Init(Standard_True);
1040 tabDst.Init(-1.0);
1041 arrLen.Init(0.);
2028d00c 1042 tabMinDist.Init(Precision::Infinite());
7fd59977 1043 const Standard_Integer npt = 8; // Number of points for curve discretization
1044 TColgp_Array1OfPnt ptsRef(1, npt), ptsSec(1, npt);
1045
1046 Standard_Integer i, j, lengSec = sequenceSec.Length();
1047 TColgp_SequenceOfPnt seqSec;
1048
1049 Handle(Geom_Curve) c3dRef;
1050 Standard_Real firstRef=0., lastRef=0.;
67ffcad0 1051
7fd59977 1052 for (i = indRef; i <= lengSec; i++) {
1053
1054 // reading of the edge (attention for the first one: reference)
1055 const TopoDS_Edge& sec = TopoDS::Edge(sequenceSec(i));
1056
1057 TopLoc_Location loc;
1058 Standard_Real first, last;
1059 Handle(Geom_Curve) c3d = BRep_Tool::Curve(sec, loc, first, last);
de10d8b1 1060 if (c3d.IsNull()) continue;
7fd59977 1061 if (!loc.IsIdentity()) {
1062 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
1063 c3d->Transform(loc.Transformation());
1064 }
1065
1066 if (i == indRef) {
1067 c3dRef = c3d; firstRef = first; lastRef = last;
1068 }
1069
2028d00c 1070 Standard_Real dist = Precision::Infinite(), distFor = -1.0, distRev = -1.0;
7fd59977 1071 Standard_Real aMinDist = Precision::Infinite();
1072
1073 Standard_Real T, deltaT = (last - first) / (npt - 1);
1074 Standard_Real aLenSec2 = 0.;
67ffcad0
G
1075
1076 Standard_Integer nbFound = 0;
7fd59977 1077 for (j = 1; j <= npt; j++) {
1078
1079 // Uniform parameter on curve
1080 if (j == 1) T = first;
1081 else if (j == npt) T = last;
1082 else T = first + (j - 1) * deltaT;
1083
1084 // Take point on curve
1085 gp_Pnt pt = c3d->Value(T);
2028d00c 1086
7fd59977 1087 if (i == indRef) {
1088 ptsRef(j) = pt;
2028d00c
G
1089 if(j > 1)
1090 aLenSec2 += pt.SquareDistance(ptsRef(j-1));
7fd59977 1091 }
1092 else {
1093 ptsSec(j) = pt;
1094 //protection to avoid merging with small sections
2028d00c 1095 if(j > 1)
7fd59977 1096 aLenSec2 += pt.SquareDistance(ptsSec(j-1));
1097 // To evaluate mutual orientation and distance
1098 dist = pt.Distance(ptsRef(j));
1099 if(aMinDist > dist)
1100 aMinDist = dist;
1101 if (distFor < dist) distFor = dist;
1102 dist = pt.Distance(ptsRef(npt-j+1));
2028d00c 1103
7fd59977 1104 if(aMinDist > dist)
1105 aMinDist = dist;
1106 if (distRev < dist) distRev = dist;
2028d00c
G
1107
1108 // Check that point lays between vertices of reference curve
1109 const gp_Pnt &p11 = ptsRef(1);
1110 const gp_Pnt &p12 = ptsRef(npt);
1111 const gp_Vec aVec1(pt,p11);
1112 const gp_Vec aVec2(pt,p12);
1113 const gp_Vec aVecRef(p11,p12);
1114 if((aVecRef * aVec1) * (aVecRef * aVec2) < 0.)
1115 nbFound++;
7fd59977 1116 }
1117 }
1118
1119 Standard_Real aLenSec = sqrt(aLenSec2);
1120
1121 //if(aLenSec < myMinTolerance )
1122 // continue;
1123 arrLen.SetValue(i,aLenSec);
1124 // Record mutual orientation
1125 Standard_Boolean isForward = (distFor < distRev); //szv debug: <=
1126 secForward(i) = isForward;
1127
1128 dist = (isForward? distFor : distRev);
2028d00c
G
1129 if(i == indRef || (dist < myTolerance && nbFound >= npt * 0.5) )
1130 {
7fd59977 1131 tabDst(i) = dist;
1132 tabMinDist(i) = aMinDist;
7fd59977 1133 }
2028d00c
G
1134 else
1135 {
1136 nbFound = 0, aMinDist = Precision::Infinite(), dist = -1;
1137 TColgp_Array1OfPnt arrProj(1, npt);
1138 TColStd_Array1OfReal arrDist(1, npt), arrPara(1, npt);
1139 if( arrLen(indRef) >= arrLen(i))
1140 ProjectPointsOnCurve(ptsSec,c3dRef,firstRef,lastRef,arrDist,arrPara,arrProj,Standard_False);
1141 else
1142 ProjectPointsOnCurve(ptsRef,c3d,first,last,arrDist,arrPara,arrProj,Standard_False);
1143 for( j = 1; j <= npt; j++ )
1144 {
2c896b8f 1145 if(arrDist(j) < 0.)
2028d00c
G
1146 continue;
1147 if(dist < arrDist(j))
1148 dist = arrDist(j);
1149 if( aMinDist > arrDist(j))
1150 aMinDist = arrDist(j);
1151 nbFound++;
1152 }
1153 if(nbFound > 1)
1154 {
1155 tabDst(i) = dist;
1156 tabMinDist(i) = aMinDist;
1157 }
7fd59977 1158 }
1159 }
1160
2028d00c 1161 /*
7fd59977 1162 // Project distant points
1163 Standard_Integer nbFailed = seqSec.Length();
1164 if (!nbFailed) return;
1165
1166 TColgp_Array1OfPnt arrPnt(1, nbFailed), arrProj(1, nbFailed);
1167 for (i = 1; i <= nbFailed; i++) arrPnt(i) = seqSec(i); seqSec.Clear();
1168 TColStd_Array1OfReal arrDist(1, nbFailed), arrPara(1, nbFailed);
1169
2028d00c 1170 ProjectPointsOnCurve(arrPnt,c3dRef,firstRef,lastRef,arrDist,arrPara,arrProj,Standard_False);
7fd59977 1171
1172 // Process distant sections
1173 Standard_Integer idx1 = 1;
1174 for (i = indRef + 1; i <= lengSec; i++) {
1175
1176 // Skip section if already evaluated
1177 if (tabDst(i) >= 0.0) continue;
1178
1179 Standard_Real dist, distMax = -1.0, aMinDist = Precision::Infinite();
1180
1181 Standard_Integer idx2 = (idx1 - 1)*npt;
1182
1183 for (j = 1; j <= npt; j++) {
1184
1185 dist = arrDist(idx2 + j);
1186 // If point is not projected - stop evaluation
1187 if (dist < 0.0) { distMax = -1.0; break; }
1188 if (distMax < dist) distMax = dist;
1189 if(aMinDist > dist) aMinDist = dist;
1190 }
1191
1192 // If section is close - record distance
1193 if (distMax >= 0.0) {
1194 if (secForward(i)) {
1195 dist = arrPnt(idx2+1).Distance(ptsRef(1));
1196 if (distMax < dist) distMax = dist;
1197 if(aMinDist > dist) aMinDist = dist;
1198 dist = arrPnt(idx2+npt).Distance(ptsRef(npt));
1199 if (distMax < dist) distMax = dist;
1200 if(aMinDist > dist) aMinDist = dist;
1201 }
1202 else {
1203 dist = arrPnt(idx2+1).Distance(ptsRef(npt));
1204 if (distMax < dist) distMax = dist;
1205 if(aMinDist > dist) aMinDist = dist;
1206 dist = arrPnt(idx2+npt).Distance(ptsRef(1));
1207 if (distMax < dist) distMax = dist;
1208 if(aMinDist > dist) aMinDist = dist;
1209 }
1210
1211 if (distMax < myTolerance)
1212 {
1213 tabDst(i) = distMax;
1214 tabMinDist(i) = aMinDist;
1215 }
1216 }
1217
1218 idx1++; // To the next distant curve
2028d00c 1219 }*/
7fd59977 1220}
1221
1222//=======================================================================
1223//function : IsMergedClosed
1224//purpose : internal use
1225//=======================================================================
1226
1227Standard_Boolean BRepBuilderAPI_Sewing::IsMergedClosed(const TopoDS_Edge& Edge1,
1228 const TopoDS_Edge& Edge2,
1229 const TopoDS_Face& face) const
1230{
1231 // Check for closed surface
1232 TopLoc_Location loc;
1233 Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc);
1234 Standard_Boolean isUClosed = IsUClosedSurface(surf,Edge1,loc);
1235 Standard_Boolean isVClosed = IsVClosedSurface(surf,Edge1,loc);
1236 if (!isUClosed && !isVClosed) return Standard_False;
1237 // Check condition on closed surface
1238 /*
1239 Standard_Real first1,last1,first2,last2;
1240 Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(Edge1,first1,last1);
1241 Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(Edge2,first2,last2);
1242 if (C3d1.IsNull() || C3d2.IsNull()) return Standard_False;
1243 */
1244 Standard_Real first2d1,last2d1,first2d2,last2d2;
1245 Handle(Geom2d_Curve) C2d1 = BRep_Tool::CurveOnSurface(Edge1,face,first2d1,last2d1);
1246 Handle(Geom2d_Curve) C2d2 = BRep_Tool::CurveOnSurface(Edge2,face,first2d2,last2d2);
1247 if (C2d1.IsNull() || C2d2.IsNull()) return Standard_False;
1248 /*
1249 gp_Pnt p1 = C3d1->Value(0.5*(first1 + last1));
1250 gp_Pnt p2 = C3d1->Value(0.5*(first2 + last2));
1251 Standard_Real dist = p1.Distance(p2);
1252 gp_Pnt2d p12d = C2d1->Value(0.5*(first2d1 + last2d1));
1253 gp_Pnt2d p22d = C2d1->Value(0.5*(first2d2 + last2d2));
1254 Standard_Real dist2d = p12d.Distance(p22d);
1255 GeomAdaptor_Surface Ads(BRep_Tool::Surface(face));
1256 Standard_Real distSurf = Max(Ads.UResolution(dist), Ads.VResolution(dist));
1257 return (dist2d*0.2 >= distSurf);
1258 */
1259 Standard_Integer isULongC1, isULongC2, isVLongC1, isVLongC2;
1260 Standard_Real SUmin, SUmax, SVmin, SVmax;
1261 Standard_Real C1Umin, C1Vmin, C1Umax, C1Vmax;
1262 Standard_Real C2Umin, C2Vmin, C2Umax, C2Vmax;
1263 { //szv: Use brackets to destroy local variables
1264 Bnd_Box2d B1, B2;
1265 Geom2dAdaptor_Curve aC2d1(C2d1), aC2d2(C2d2);
1266 BndLib_Add2dCurve::Add(aC2d1,first2d1,last2d1,Precision::PConfusion(),B1);
1267 BndLib_Add2dCurve::Add(aC2d2,first2d2,last2d2,Precision::PConfusion(),B2);
1268 B1.Get(C1Umin,C1Vmin,C1Umax,C1Vmax);
1269 B2.Get(C2Umin,C2Vmin,C2Umax,C2Vmax);
1270 Standard_Real du, dv;
1271 du = (C1Umax - C1Umin); dv = (C1Vmax - C1Vmin);
1272 isULongC1 = (dv <= du); isVLongC1 = (du <= dv);
1273 du = (C2Umax - C2Umin); dv = (C2Vmax - C2Vmin);
1274 isULongC2 = (dv <= du); isVLongC2 = (du <= dv);
1275 surf->Bounds(SUmin,SUmax,SVmin,SVmax);
1276 }
1277 if (isUClosed && isVLongC1 && isVLongC2) {
1278 // Do not merge if not overlapped by V
1279 Standard_Real dist = Max((C2Vmin - C1Vmax),(C1Vmin - C2Vmax));
1280 if (dist < 0.0) {
1281 Standard_Real distInner = Max((C2Umin - C1Umax),(C1Umin - C2Umax));
1282 Standard_Real distOuter = (SUmax - SUmin) - Max((C2Umax - C1Umin),(C1Umax - C2Umin));
1283 if (distOuter <= distInner) return Standard_True;
1284 }
1285 }
1286 if (isVClosed && isULongC1 && isULongC2) {
1287 // Do not merge if not overlapped by U
1288 Standard_Real dist = Max((C2Umin - C1Umax),(C1Umin - C2Umax));
1289 if (dist < 0.0) {
1290 Standard_Real distInner = Max((C2Vmin - C1Vmax),(C1Vmin - C2Vmax));
1291 Standard_Real distOuter = (SVmax - SVmin) - Max((C2Vmax - C1Vmin),(C1Vmax - C2Vmin));
1292 if (distOuter <= distInner) return Standard_True;
1293 }
1294 }
1295 return Standard_False;
1296}
1297
1298//=======================================================================
1299//function : AnalysisNearestEdges
1300//purpose :
1301//=======================================================================
1302
1303void BRepBuilderAPI_Sewing::AnalysisNearestEdges(const TopTools_SequenceOfShape& sequenceSec,
1304 TColStd_SequenceOfInteger& seqIndCandidate,
1305 TColStd_SequenceOfInteger& seqOrientations,
1306 const Standard_Boolean evalDist)
1307{
1308
1309 Standard_Integer workIndex = seqIndCandidate.First();
1310 TopoDS_Shape workedge = sequenceSec.Value(workIndex);
1311 TopoDS_Shape bnd = workedge;
1312 TopTools_ListOfShape workfaces;
1313 if (mySectionBound.IsBound(bnd)) bnd = mySectionBound(bnd);
1314 if (myBoundFaces.Contains(bnd))
1315 workfaces = myBoundFaces.FindFromKey(bnd);
1316 if(workfaces.IsEmpty()) return;
1317 TopTools_MapOfShape mapFaces;
1318 TopTools_ListIteratorOfListOfShape lIt;
1319 for (lIt.Initialize(workfaces); lIt.More(); lIt.Next())
1320 mapFaces.Add(lIt.Value());
1321 TColStd_SequenceOfInteger seqNotCandidate;
1322 TColStd_SequenceOfInteger seqNewForward;
1323 // Separates edges belonging the same face as work edge
1324 // for exception of edges belonging closed faces
1325
1326 seqNotCandidate.Append(workIndex);
1327 for(Standard_Integer i = 1; i<= seqIndCandidate.Length(); ) {
1328 Standard_Integer index = seqIndCandidate.Value(i);
1329 Standard_Boolean isRemove = Standard_False;
1330 if(index == workIndex) {
1331 seqIndCandidate.Remove(i);
1332 seqOrientations.Remove(i);
1333 isRemove = Standard_True;
1334 }
1335 if(!isRemove) {
1336 TopoDS_Shape bnd2 = sequenceSec.Value(index);
1337 if (mySectionBound.IsBound(bnd2)) bnd2 = mySectionBound(bnd2);
1338
1339 if(myBoundFaces.Contains(bnd2)) {
1340 const TopTools_ListOfShape& listfaces = myBoundFaces.FindFromKey(bnd2);
1341 Standard_Boolean isMerged = Standard_True;
1342 for (lIt.Initialize(listfaces); lIt.More() && isMerged; lIt.Next()) {
1343 if(mapFaces.Contains(lIt.Value())) {
1344 TopLoc_Location loc;
1345 Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(lIt.Value()),loc);
1346 isMerged = ((IsUClosedSurface(surf,bnd2,loc) || IsVClosedSurface(surf,bnd2,loc)) &&
1347 IsMergedClosed(TopoDS::Edge(sequenceSec.Value(index)),TopoDS::Edge(workedge),TopoDS::Face(lIt.Value())));
1348 }
1349 }
1350 if(!isMerged) {
1351 seqNotCandidate.Append(index);
1352 seqIndCandidate.Remove(i);
1353 seqOrientations.Remove(i);
1354 isRemove = Standard_True;
1355 }
1356 }
1357 else {
1358 seqIndCandidate.Remove(i);
1359 seqOrientations.Remove(i);
1360 isRemove = Standard_True;
1361 }
1362 }
1363 if(!isRemove) i++;
1364 }
1365 if(seqIndCandidate.Length() == 0 || seqNotCandidate.Length() == 1) return;
1366 if(!evalDist) return;
1367 TColStd_Array2OfReal TotTabDist(1,seqNotCandidate.Length(),1,seqIndCandidate.Length());
1368 TColStd_MapOfInteger MapIndex;
1369 TColStd_SequenceOfInteger seqForward;
1370
1371 // Definition and removing edges wich are not candidate for work edge
1372 // ( they have other nearest edges belonging to the work face)
1373 for(Standard_Integer k = 1; k<= seqNotCandidate.Length(); k++) {
1374 Standard_Integer index1 = seqNotCandidate.Value(k);
1375 TopoDS_Shape edge = sequenceSec.Value(index1);
1376 TopTools_SequenceOfShape tmpSeq;
1377 tmpSeq.Append(edge);
1378 for(Standard_Integer kk = 1; kk <= seqIndCandidate.Length();kk++)
1379 tmpSeq.Append(sequenceSec.Value(seqIndCandidate.Value(kk)));
1380
1381 Standard_Integer lengSec = tmpSeq.Length();
1382 TColStd_Array1OfBoolean tabForward(1,lengSec);
1383 TColStd_Array1OfReal tabDist(1,lengSec);
1384 TColStd_Array1OfReal arrLen(1,lengSec);
1385 TColStd_Array1OfReal tabMinDist(1,lengSec);
1386 for (Standard_Integer i1 = 1 ; i1 <= lengSec; i1++)
1387 tabDist(i1) =-1;
1388
1389 EvaluateDistances(tmpSeq,tabForward, tabDist,arrLen,tabMinDist,1 );
1390 if(k == 1) {
1391 for(Standard_Integer n = 1; n < lengSec; n++) {
1392 if(tabDist(n+1) == -1 || tabDist(n+1) > myTolerance) {
1393 MapIndex.Add(n);
1394 continue;
1395 }
1396 TotTabDist(k,n) = tabDist(n+1 );
1397 seqForward.Append(tabForward(n+1) ? 1:0);
1398 }
1399 }
1400 else {
1401 for(Standard_Integer n = 1; n < lengSec; n++) {
1402 if(tabDist(n) == -1 || tabDist(n) > myTolerance) continue;
1403 if(tabDist(n+1) < TotTabDist(1,n)) {
1404 MapIndex.Add(n);
1405 }
1406 }
1407 }
1408
1409 }
1410
1411 Standard_Integer i2 = seqIndCandidate.Length();
1412 for( ; i2 >=1 ; i2--)
1413 {
1414 if(MapIndex.Contains(i2))
1415 {
1416 seqIndCandidate.Remove(i2);
1417 seqOrientations.Remove(i2);
1418 }
1419
1420 }
1421 //for(TColStd_MapIteratorOfMapOfInteger IMap(MapIndex); IMap.More(); IMap.Next()) {
1422 // seqIndCandidate.Remove(IMap.Key());
1423 // seqOrientations.Remove(IMap.Key());
1424 //}
1425}
1426
1427//=======================================================================
1428//function : FindCandidates
1429//purpose : internal use
1430//=======================================================================
1431
1432Standard_Boolean BRepBuilderAPI_Sewing::FindCandidates(TopTools_SequenceOfShape& seqSections,
1433 TColStd_IndexedMapOfInteger& mapReference,
1434 TColStd_SequenceOfInteger& seqCandidates,
1435 TColStd_SequenceOfInteger& seqOrientations)
1436{
1437 Standard_Integer i, nbSections = seqSections.Length();
1438 if(nbSections <= 1)
1439 return Standard_False;
1440 // Retrieve last reference index
1441 Standard_Integer indReference = mapReference(mapReference.Extent());
1442 Standard_Integer nbCandidates = 0;
1443 TopTools_MapOfShape Faces1;
1444 //if (nbSections > 1) {
1445
1446 TopoDS_Edge Edge1 = TopoDS::Edge(seqSections(indReference));
1447
1448 // Retrieve faces for reference section
1449
1450 { //szv: Use brackets to destroy local variables
1451 TopoDS_Shape bnd = Edge1;
1452 if (mySectionBound.IsBound(bnd)) bnd = mySectionBound(bnd);
1453 if (myBoundFaces.Contains(bnd)) {
1454 TopTools_ListIteratorOfListOfShape itf1(myBoundFaces.FindFromKey(bnd));
1455 for (; itf1.More(); itf1.Next()) Faces1.Add(itf1.Value());
1456 }
1457 }
1458
1459 // Check merging conditions for candidates and remove unsatisfactory
1460 TopTools_SequenceOfShape seqSectionsNew;
1461 TColStd_SequenceOfInteger seqCandidatesNew;
1462 for (i = 1; i <= nbSections; i++) {
1463 if (i == indReference) {
1464 seqSectionsNew.Prepend(Edge1);
1465 seqCandidatesNew.Prepend(i);
1466 }
1467 else {
1468 const TopoDS_Edge& Edge2 = TopoDS::Edge(seqSections(i));
7fd59977 1469 seqSectionsNew.Append(Edge2);
1470 seqCandidatesNew.Append(i);
7fd59977 1471 }
1472 }
1473
1474 Standard_Integer nbSectionsNew = seqSectionsNew.Length();
1475 if (nbSectionsNew > 1) {
5a29f57e 1476
7fd59977 1477 // Evaluate distances between reference and other sections
1478 TColStd_Array1OfBoolean arrForward(1,nbSectionsNew);
1479 TColStd_Array1OfReal arrDistance(1,nbSectionsNew);
1480 TColStd_Array1OfReal arrLen(1,nbSectionsNew);
1481 TColStd_Array1OfReal arrMinDist(1,nbSectionsNew);
1482 EvaluateDistances(seqSectionsNew,arrForward,arrDistance,arrLen,arrMinDist,1);
5a29f57e 1483
7fd59977 1484 // Fill sequence of candidate indices sorted by distance
1485 for (i = 2; i <= nbSectionsNew; i++) {
5a29f57e 1486 Standard_Real aMaxDist = arrDistance(i);
1487 if (aMaxDist >= 0.0 && aMaxDist <= myTolerance && arrLen(i) > myMinTolerance) {
1488
7fd59977 1489 // Reference section is connected to section #i
1490 Standard_Boolean isInserted = Standard_False;
1491 Standard_Integer j, ori = (arrForward(i)? 1 : 0);
1492 for (j = 1; (j <= seqCandidates.Length()) && !isInserted; j++) {
7fd59977 1493 Standard_Real aDelta = arrDistance(i) - arrDistance(seqCandidates.Value(j));
5a29f57e 1494
7fd59977 1495 if( aDelta < Precision::Confusion()) {
1496
1497 if(fabs(aDelta) > RealSmall() ||
1498 arrMinDist(i) < arrMinDist(seqCandidates.Value(j)))
1499 {
1500 seqCandidates.InsertBefore(j,i);
1501 seqOrientations.InsertBefore(j,ori);
1502 isInserted = Standard_True;
1503 }
1504 }
1505 }
1506 if (!isInserted) {
1507 seqCandidates.Append(i);
1508 seqOrientations.Append(ori);
1509 }
1510 }
1511 }
5a29f57e 1512
7fd59977 1513 nbCandidates = seqCandidates.Length();
5a29f57e 1514 if (!nbCandidates)
1515 return Standard_False; // Section has no candidates to merge
1516
1517 // Replace candidate indices
1518
7fd59977 1519 for (i = 1; i <= nbCandidates; i++)
1520 seqCandidates(i) = seqCandidatesNew(seqCandidates(i));
5a29f57e 1521
7fd59977 1522 }
5a29f57e 1523
7fd59977 1524 if (!nbCandidates) return Standard_False; // Section has no candidates to merge
1525
1526 if (myNonmanifold && nbCandidates >1) {
1527 TColStd_SequenceOfInteger seqNewCandidates;
1528 TColStd_SequenceOfInteger seqOrientationsNew;
1529 seqCandidates.Prepend(1);
1530 seqOrientations.Prepend(1);
1531 for(Standard_Integer k = 1; k <= seqSections.Length() && seqCandidates.Length() > 1 ; k++) {
1532 AnalysisNearestEdges(seqSections,seqCandidates,seqOrientations,(k==1));
1533 if(k == 1 && !seqCandidates.Length()) return Standard_False;
1534 if(seqCandidates.Length()) {
1535 seqNewCandidates.Append(seqCandidates.First());
1536 seqOrientationsNew.Append(seqOrientations.First());
1537 }
1538 }
1539 seqCandidates.Prepend(seqNewCandidates);
1540 seqOrientations.Prepend(seqOrientationsNew);
1541 return Standard_True;
1542 }
1543 else {
1544
1545 // For manifold case leave only one candidate from equidistant candidates
1546 /*Standard_Integer minIndex = seqCandidateIndex.First();
1547 Standard_Real minDistance = arrDistance(minIndex);
1548
1549 // Find equidistant candidates
1550 TColStd_SequenceOfInteger seqEqDistantIndex; seqEqDistantIndex.Append(1);
1551 for (i = 2; i <= nbCandidates; i++) {
1552 Standard_Integer index = seqCandidateIndex(i);
1553 if (Abs(minDistance - arrDistance(index)) <= Precision::Confusion())
1554 seqEqDistantIndex.Append(index);
1555 }
1556
1557 Standard_Integer eqLen = seqEqDistantIndex.Length();
1558 if (eqLen > 2) {
1559
1560 // Fill map of faces which equidistant sections belong to
1561 TopTools_MapOfShape mapFace;
1562 for (i = 1; i <= eqLen; i++) {
1563 Standard_Integer index = seqEqDistantIndex.Value(i);
1564 if (isCandidate(index)) {
1565 mapFace.Add(arrFace(index));
1566 }
1567 }
1568
1569 // Non Manifold case
1570 // Edges are merged by pair among a face continuity C1 criterion
1571 if (mapFace.Extent() == eqLen) {
1572
1573 tabDist.Init(-1);
1574 tabMinInd.Init(-1);
1575 min=10000000.;
1576 //indMin = -1;
1577 Standard_Integer indMin = -1;// To check if the edge can be merged.
1578 // Computation of distances between the edges.
1579 TopTools_SequenceOfShape seqSh;
1580 Standard_Integer nbInd = EqDistSeq.Length();
1581 TColStd_Array1OfBoolean tmptabForward(1,nbInd);
1582 seqSh.Append(sequenceSec.Value(1));
1583 for (j = 2; j <= EqDistSeq.Length(); j++) {
1584 Standard_Integer index = EqDistSeq.Value(j);
1585 tmptabForward(j) = tabForward(index);
1586 seqSh.Append(sequenceSec.Value(index));
1587 }
1588
1589 EvaluateAngulars(seqSh, tmptabForward, tabDist,1);
1590
1591 for(j=2; j <= seqSh.Length(); j++) {
1592 if (tabDist(j) > -1.) { // if edge(j) is connected to edge(i)
1593 if (min > tabDist(j)) {
1594 min = tabDist(j);
1595 indMin = j;
1596 }
1597 }
1598 }
1599
1600 // Construct minDist, tabMinInd , tabMinForward(i) = tabForward(j);
1601 if (indMin > 0) {
1602 seqSh.Remove(indMin);
1603 for(j =2; j <= tmpSeq.Length(); ) {
1604 TopoDS_Shape sh = tmpSeq.Value(j);
1605 Standard_Boolean isRem = Standard_False;
1606 for(Standard_Integer k = 1; k<= seqSh.Length();k++) {
1607 if(seqSh.Value(k) == sh) {
1608 isRem = Standard_True;
1609 break;
1610 }
1611 }
1612 if(isRem) {
1613 tmpSeq.Remove(j);
1614 tabMinForward.Remove(j); // = -1;
1615 }
1616 else j++;
1617 }
1618 }
1619 }
1620 }*/
1621
1622 // Find the best approved candidate
1623 while (nbCandidates) {
1624 // Retrieve first candidate
1625 Standard_Integer indCandidate = seqCandidates.First();
1626 // Candidate is approved if it is in the map
1627 if (mapReference.Contains(indCandidate)) break;
1628 // Find candidates for candidate #indCandidate
1629 mapReference.Add(indCandidate); // Push candidate in the map
1630 TColStd_SequenceOfInteger seqCandidates1, seqOrientations1;
1631 Standard_Boolean isFound =
1632 FindCandidates(seqSections,mapReference,seqCandidates1,seqOrientations1);
1633 mapReference.RemoveLast(); // Pop candidate from the map
1634 if (isFound) isFound = (seqCandidates1.Length() > 0);
1635 if (isFound) {
1636 Standard_Integer indCandidate1 = seqCandidates1.First();
1637 // If indReference is the best candidate for indCandidate
1638 // then indCandidate is the best candidate for indReference
1639 if (indCandidate1 == indReference) break;
1640 // If some other reference in the map is the best candidate for indCandidate
1641 // then assume that reference is the best candidate for indReference
1642 if (mapReference.Contains(indCandidate1)) {
1643 seqCandidates.Prepend(indCandidate1);
1644 nbCandidates++;
1645 break;
1646 }
1647 isFound = Standard_False;
1648 }
1649 if (!isFound) {
1650 // Remove candidate #1
1651 seqCandidates.Remove(1);
1652 seqOrientations.Remove(1);
1653 nbCandidates--;
1654 }
1655 }
1656 }
1657 //gka
1658 if(nbCandidates > 0)
1659 {
1660 Standard_Integer anInd = seqCandidates.Value(1);
1661 TopoDS_Edge Edge2 = TopoDS::Edge(seqSections(anInd));
1662 TopoDS_Shape bnd = Edge2;
1663 if (mySectionBound.IsBound(bnd))
1664 bnd = mySectionBound(bnd);
1665 //gka
1666 if (myBoundFaces.Contains(bnd)) {
1667 Standard_Boolean isOK = Standard_True;
1668 TopTools_ListIteratorOfListOfShape itf2(myBoundFaces.FindFromKey(bnd));
1669 for (; itf2.More() && isOK; itf2.Next()) {
1670 const TopoDS_Face& Face2 = TopoDS::Face(itf2.Value());
1671 // Check whether condition is satisfied
1672 isOK = !Faces1.Contains(Face2);
1673 if (!isOK) isOK = IsMergedClosed(Edge1,Edge2,Face2);
1674 }
1675 if(!isOK)
1676 return Standard_False;
1677 }
1678 }
1679 return (nbCandidates > 0);
1680}
1681
1682//=======================================================================
1683//function : Constructor
1684//purpose :
1685//=======================================================================
1686
1687BRepBuilderAPI_Sewing::BRepBuilderAPI_Sewing(const Standard_Real tolerance,
1688 const Standard_Boolean optionSewing,
1689 const Standard_Boolean optionAnalysis,
1690 const Standard_Boolean optionCutting,
1691 const Standard_Boolean optionNonmanifold)
1692{
1693 myReShape = new BRepTools_ReShape;
1694 Init(tolerance, optionSewing, optionAnalysis, optionCutting, optionNonmanifold);
1695}
1696
1697//=======================================================================
1698//function : Init
1699//purpose : Initialise Talerance, and options sewing, faceAnalysis and cutting
1700//=======================================================================
1701
1702void BRepBuilderAPI_Sewing::Init(const Standard_Real tolerance,
1703 const Standard_Boolean optionSewing,
1704 const Standard_Boolean optionAnalysis,
1705 const Standard_Boolean optionCutting,
1706 const Standard_Boolean optionNonmanifold)
1707{
1708 // Set tolerance and Perform options
eb7c351a 1709 myTolerance = Max (tolerance, Precision::Confusion());
7fd59977 1710 mySewing = optionSewing;
1711 myAnalysis = optionAnalysis;
1712 myCutting = optionCutting;
1713 myNonmanifold = optionNonmanifold;
1714 // Set min and max tolerances
eb7c351a 1715 myMinTolerance = myTolerance * 1e-4; //szv: proposal
7fd59977 1716 if (myMinTolerance < Precision::Confusion()) myMinTolerance = Precision::Confusion();
1717 myMaxTolerance = Precision::Infinite();
1718 // Set other modes
1719 myFaceMode = Standard_True;
1720 myFloatingEdgesMode = Standard_False;
1721 //myCuttingFloatingEdgesMode = Standard_False; //gka
1722 mySameParameterMode = Standard_True;
1723 myLocalToleranceMode = Standard_False;
1724 mySewedShape.Nullify();
1725 // Load empty shape
1726 Load(TopoDS_Shape());
1727}
1728
1729//=======================================================================
1730//function : Load
1731//purpose : Loads the context shape
1732//=======================================================================
1733
1734void BRepBuilderAPI_Sewing::Load(const TopoDS_Shape& theShape)
1735{
1736 myReShape->Clear();
1737 if (theShape.IsNull()) myShape.Nullify();
1738 else myShape = myReShape->Apply(theShape);
1739 mySewedShape.Nullify();
1740 // Nullify flags and counters
1741 myNbShapes = myNbEdges = myNbVertices = 0;
1742 // Clear all maps
1743 myOldShapes.Clear();
1744 //myOldFaces.Clear();
1745 myDegenerated.Clear();
1746 myFreeEdges.Clear();
1747 myMultipleEdges.Clear();
1748 myContigousEdges.Clear();
1749 myContigSecBound.Clear();
1750 myBoundFaces.Clear();
1751 myBoundSections.Clear();
1752 myVertexNode.Clear();
1753 myVertexNodeFree.Clear();
1754 myNodeSections.Clear();
1755 myCuttingNode.Clear();
1756 mySectionBound.Clear();
1757 myLittleFace.Clear();
1758}
1759
1760//=======================================================================
1761//function : Add
1762//purpose :
1763//=======================================================================
1764
1765void BRepBuilderAPI_Sewing::Add(const TopoDS_Shape& aShape)
1766{
1767 if (aShape.IsNull()) return;
1768 TopoDS_Shape oShape = myReShape->Apply(aShape);
1769 myOldShapes.Add(aShape,oShape);
1770 myNbShapes = myOldShapes.Extent();
1771}
1772
1773//=======================================================================
1774//function : Perform
1775//purpose :
1776//=======================================================================
1777
63c629aa 1778#ifdef BREPBUILDERAPI_DEB
7fd59977 1779#include <OSD_Timer.hxx>
1780#endif
1781
92434a36 1782void BRepBuilderAPI_Sewing::Perform(const Handle(Message_ProgressIndicator)& thePI)
7fd59977 1783{
92434a36
A
1784 const Standard_Integer aNumberOfStages = myAnalysis + myCutting + mySewing + 2;
1785 Message_ProgressSentry aPS (thePI, "Sewing", 0, aNumberOfStages, 1);
63c629aa 1786#ifdef BREPBUILDERAPI_DEB
7fd59977 1787 Standard_Real t_total = 0., t_analysis = 0., t_assembling = 0., t_cutting = 0., t_merging = 0.;
1788 OSD_Chronometer chr_total, chr_local;
1789 chr_total.Reset();
1790 chr_total.Start();
1791#endif
1792
1793 // face analysis
92434a36
A
1794 if (myAnalysis)
1795 {
63c629aa 1796#if BREPBUILDERAPI_DEB
7fd59977 1797 cout << "Begin face analysis..." << endl;
1798 chr_local.Reset();
1799 chr_local.Start();
1800#endif
92434a36
A
1801 FaceAnalysis (thePI);
1802 if (!aPS.More())
1803 return;
1804 aPS.Next();
63c629aa 1805#if BREPBUILDERAPI_DEB
7fd59977 1806 chr_local.Stop();
1807 chr_local.Show(t_analysis);
1808 cout << "Face analysis finished after " << t_analysis << " s" << endl;
1809#endif
1810 }
1811
92434a36
A
1812 if (myNbShapes || !myShape.IsNull())
1813 {
7fd59977 1814
1815 FindFreeBoundaries();
1816
92434a36
A
1817 if (myBoundFaces.Extent())
1818 {
7fd59977 1819
63c629aa 1820#if BREPBUILDERAPI_DEB
7fd59977 1821 cout << "Begin vertices assembling..." << endl;
1822 chr_local.Reset();
1823 chr_local.Start();
1824#endif
92434a36
A
1825 VerticesAssembling (thePI);
1826 if (!aPS.More())
1827 return;
1828 aPS.Next();
63c629aa 1829#if BREPBUILDERAPI_DEB
7fd59977 1830 chr_local.Stop();
1831 chr_local.Show(t_assembling);
1832 cout << "Vertices assembling finished after " << t_assembling << " s" << endl;
1833#endif
92434a36
A
1834 if (myCutting)
1835 {
63c629aa 1836#if BREPBUILDERAPI_DEB
92434a36
A
1837 cout << "Begin cutting..." << endl;
1838 chr_local.Reset();
1839 chr_local.Start();
7fd59977 1840#endif
92434a36
A
1841 Cutting (thePI);
1842 if (!aPS.More())
1843 return;
1844 aPS.Next();
63c629aa 1845#if BREPBUILDERAPI_DEB
92434a36
A
1846 chr_local.Stop();
1847 chr_local.Show(t_cutting);
1848 cout << "Cutting finished after " << t_cutting << " s" << endl;
7fd59977 1849#endif
1850 }
63c629aa 1851#if BREPBUILDERAPI_DEB
7fd59977 1852 cout << "Begin merging..." << endl;
1853 chr_local.Reset();
1854 chr_local.Start();
1855#endif
92434a36
A
1856 Merging (Standard_True, thePI);
1857 if (!aPS.More())
1858 return;
1859 aPS.Next();
63c629aa 1860#if BREPBUILDERAPI_DEB
7fd59977 1861 chr_local.Stop();
1862 chr_local.Show(t_merging);
1863 cout << "Merging finished after " << t_merging << " s" << endl;
1864#endif
1865 }
92434a36
A
1866 else
1867 {
1868 aPS.Next( 1, Handle(TCollection_HAsciiString)());
1869 if (myCutting)
1870 aPS.Next( 1, Handle(TCollection_HAsciiString)());
1871 aPS.Next( 1, Handle(TCollection_HAsciiString)());
1872 if (!aPS.More())
1873 return;
1874 }
7fd59977 1875
92434a36
A
1876 if (mySewing)
1877 {
7fd59977 1878
63c629aa 1879#if BREPBUILDERAPI_DEB
7fd59977 1880 cout << "Creating sewed shape..." << endl;
1881#endif
1882 // examine the multiple edges if any and process sameparameter for edges if necessary
92434a36
A
1883 EdgeProcessing (thePI);
1884 if (!aPS.More())
1885 return;
7fd59977 1886 CreateSewedShape();
92434a36
A
1887 if (!aPS.More())
1888 {
1889 mySewedShape.Nullify();
1890 return;
1891 }
1892 if (mySameParameterMode && myFaceMode)
1893 SameParameterShape();
1894 if (!aPS.More())
1895 {
1896 mySewedShape.Nullify();
1897 return;
1898 }
63c629aa 1899#if BREPBUILDERAPI_DEB
7fd59977 1900 cout << "Sewed shape created" << endl;
1901#endif
1902 }
92434a36 1903
7fd59977 1904 // create edge informations for output
1905 CreateOutputInformations();
92434a36
A
1906 if (!aPS.More())
1907 {
1908 mySewedShape.Nullify();
1909 return;
1910 }
7fd59977 1911 }
63c629aa 1912#if BREPBUILDERAPI_DEB
7fd59977 1913 chr_total.Stop();
1914 chr_total.Show(t_total);
1915 cout << "Sewing finished!" << endl;
1916 cout << " analysis time : " << t_analysis << " s" << endl;
1917 cout << " assembling time : " << t_assembling << " s" << endl;
1918 cout << " cutting time : " << t_cutting << " s" << endl;
1919 cout << " merging time : " << t_merging << " s" << endl;
1920 cout << "Total time : " << t_total << " s" << endl;
1921#endif
1922}
1923
1924//=======================================================================
1925//function : SewedShape
1926//purpose : give the sewed shape
1927// if a null shape, reasons:
1928// -- no useable input shapes : all input shapes are degenerated
1929// -- has multiple edges
1930//=======================================================================
1931
1932const TopoDS_Shape& BRepBuilderAPI_Sewing::SewedShape() const
1933{
1934 return mySewedShape;
1935}
1936
1937//=======================================================================
1938//function : NbFreeEdges
1939//purpose :
1940//=======================================================================
1941
1942Standard_Integer BRepBuilderAPI_Sewing::NbFreeEdges() const
1943{
1944 return myFreeEdges.Extent();
1945}
1946
1947//=======================================================================
1948//function : FreeEdge
1949//purpose :
1950//=======================================================================
1951
1952const TopoDS_Edge& BRepBuilderAPI_Sewing::FreeEdge(const Standard_Integer index) const
1953{
1954 Standard_OutOfRange_Raise_if(index < 0 || index > NbFreeEdges(), "BRepBuilderAPI_Sewing::FreeEdge");
1955 return TopoDS::Edge(myFreeEdges(index));
1956}
1957
1958//=======================================================================
1959//function : NbMultipleEdges
1960//purpose :
1961//=======================================================================
1962
1963Standard_Integer BRepBuilderAPI_Sewing::NbMultipleEdges() const
1964{
1965 return myMultipleEdges.Extent();
1966}
1967
1968//=======================================================================
1969//function : MultipleEdge
1970//purpose :
1971//=======================================================================
1972
1973const TopoDS_Edge& BRepBuilderAPI_Sewing::MultipleEdge(const Standard_Integer index) const
1974{
1975 Standard_OutOfRange_Raise_if(index < 0 || index > NbMultipleEdges(), "BRepBuilderAPI_Sewing::MultipleEdge");
1976 return TopoDS::Edge(myMultipleEdges(index));
1977}
1978
1979//=======================================================================
1980//function : NbContigousEdges
1981//purpose :
1982//=======================================================================
1983
1984Standard_Integer BRepBuilderAPI_Sewing::NbContigousEdges() const
1985{
1986 return myContigousEdges.Extent();
1987}
1988
1989//=======================================================================
1990//function : ContigousEdge
1991//purpose :
1992//=======================================================================
1993
1994const TopoDS_Edge& BRepBuilderAPI_Sewing::ContigousEdge(const Standard_Integer index) const
1995{
1996 Standard_OutOfRange_Raise_if(index < 0 || index > NbContigousEdges(), "BRepBuilderAPI_Sewing::ContigousEdge");
1997 return TopoDS::Edge(myContigousEdges.FindKey(index));
1998}
1999
2000//=======================================================================
2001//function : ContigousEdgeCouple
2002//purpose :
2003//=======================================================================
2004
2005const TopTools_ListOfShape& BRepBuilderAPI_Sewing::ContigousEdgeCouple(const Standard_Integer index) const
2006{
2007 Standard_OutOfRange_Raise_if(index < 0 || index > NbContigousEdges(), "BRepBuilderAPI_Sewing::ContigousEdgeCouple");
2008 return myContigousEdges(index);
2009}
2010
2011//=======================================================================
2012//function : IsSectionBound
2013//purpose :
2014//=======================================================================
2015
2016Standard_Boolean BRepBuilderAPI_Sewing::IsSectionBound(const TopoDS_Edge& section) const
2017{
2018 if(myContigSecBound.IsBound(section)) {
2019 return Standard_True;
2020 }
2021 else {
2022 return Standard_False;
2023 }
2024}
2025
2026//=======================================================================
2027//function : SectionToBoundary
2028//purpose :
2029//=======================================================================
2030
2031const TopoDS_Edge& BRepBuilderAPI_Sewing::SectionToBoundary(const TopoDS_Edge& section) const
2032{
2033 Standard_NoSuchObject_Raise_if(!IsSectionBound(section), "BRepBuilderAPI_Sewing::SectionToBoundary");
2034 return TopoDS::Edge(myContigSecBound(section));
2035}
2036//=======================================================================
2037//function : NbDeletedFaces
2038//purpose :
2039//=======================================================================
2040 Standard_Integer BRepBuilderAPI_Sewing::NbDeletedFaces() const
2041{
2042 return myLittleFace.Extent();
2043}
2044
2045//=======================================================================
2046//function : DeletedFace
2047//purpose :
2048//=======================================================================
2049const TopoDS_Face& BRepBuilderAPI_Sewing::DeletedFace(const Standard_Integer index) const
2050{
2051 Standard_OutOfRange_Raise_if(index < 0 || index > NbDeletedFaces(), "BRepBuilderAPI_Sewing::DeletedFace");
2052 return TopoDS::Face(myLittleFace(index));
2053}
2054
2055//=======================================================================
2056//function : NbDegeneratedShapes
2057//purpose :
2058//=======================================================================
2059
2060Standard_Integer BRepBuilderAPI_Sewing::NbDegeneratedShapes() const
2061{
2062 return myDegenerated.Extent();
2063}
2064
2065//=======================================================================
2066//function : DegeneratedShape
2067//purpose :
2068//=======================================================================
2069
2070const TopoDS_Shape& BRepBuilderAPI_Sewing::DegeneratedShape(const Standard_Integer index) const
2071{
2072 Standard_OutOfRange_Raise_if(index < 0 || index > NbDegeneratedShapes(), "BRepBuilderAPI_Sewing::DegereratedShape");
2073 return myDegenerated(index);
2074}
2075
2076//=======================================================================
2077//function : IsDegenerated
2078//purpose :
2079//=======================================================================
2080
2081Standard_Boolean BRepBuilderAPI_Sewing::IsDegenerated(const TopoDS_Shape& aShape) const
2082{
2083 TopoDS_Shape NewShape = myReShape->Apply(aShape);
2084 // Degenerated face
2085 if (aShape.ShapeType() == TopAbs_FACE)
2086 return NewShape.IsNull();
2087 if (NewShape.IsNull()) return Standard_False;
2088 // Degenerated edge
2089 if (NewShape.ShapeType() == TopAbs_EDGE)
2090 return BRep_Tool::Degenerated(TopoDS::Edge(NewShape));
2091 // Degenerated wire
2092 if (NewShape.ShapeType() == TopAbs_WIRE) {
2093 Standard_Boolean isDegenerated = Standard_True;
2094 for (TopoDS_Iterator aIt(NewShape); aIt.More() && isDegenerated; aIt.Next())
2095 isDegenerated = BRep_Tool::Degenerated(TopoDS::Edge(aIt.Value()));
2096 return isDegenerated;
2097 }
2098 return Standard_False;
2099}
2100
2101//=======================================================================
2102//function : IsModified
2103//purpose :
2104//=======================================================================
2105
2106Standard_Boolean BRepBuilderAPI_Sewing::IsModified(const TopoDS_Shape& aShape) const
2107{
2108 TopoDS_Shape NewShape = aShape;
2109 if (myOldShapes.Contains(aShape))
2110 NewShape = myOldShapes.FindFromKey(aShape);
2111 if(!NewShape.IsSame(aShape)) return Standard_True;
2112 return Standard_False;
2113}
2114
2115//=======================================================================
2116//function : Modified
2117//purpose :
2118//=======================================================================
2119
2120const TopoDS_Shape& BRepBuilderAPI_Sewing::Modified(const TopoDS_Shape& aShape) const
2121{
2122 if (myOldShapes.Contains(aShape)) return myOldShapes.FindFromKey(aShape);
2123 //if (myOldFaces.Contains(aShape)) return myOldFaces.FindFromKey(aShape);
2124 return aShape;
2125}
2126
2127//=======================================================================
2128//function : IsModifiedSubShape
2129//purpose :
2130//=======================================================================
2131
2132Standard_Boolean BRepBuilderAPI_Sewing::IsModifiedSubShape(const TopoDS_Shape& aShape) const
2133{
2134 TopoDS_Shape NewShape = myReShape->Apply(aShape);
2135 if(!NewShape.IsSame(aShape)) return Standard_True;
2136 return Standard_False;
2137}
2138
2139//=======================================================================
2140//function : ModifiedSubShape
2141//purpose :
2142//=======================================================================
2143
2144TopoDS_Shape BRepBuilderAPI_Sewing::ModifiedSubShape(const TopoDS_Shape& aShape) const
2145{
2146 return myReShape->Apply(aShape);
2147}
2148
2149//=======================================================================
2150//function : Dump
2151//purpose :
2152//=======================================================================
2153
2154void BRepBuilderAPI_Sewing::Dump() const
2155{
2156 Standard_Integer i, NbBounds = myBoundFaces.Extent(), NbSections = 0;
2157 TopTools_MapOfShape mapVertices, mapEdges;
2158 for (i = 1; i <= NbBounds; i++) {
2159 TopoDS_Shape bound = myBoundFaces.FindKey(i);
2160 if (myBoundSections.IsBound(bound)) NbSections += myBoundSections(bound).Extent();
2161 else NbSections++;
2162 TopExp_Explorer aExp(myReShape->Apply(bound),TopAbs_EDGE);
2163 for (; aExp.More(); aExp.Next()) {
2164 TopoDS_Edge E = TopoDS::Edge(aExp.Current());
2165 mapEdges.Add(E);
2166 TopoDS_Vertex V1, V2;
2167 TopExp::Vertices(E,V1,V2);
2168 mapVertices.Add(V1);
2169 mapVertices.Add(V2);
2170 }
2171 }
2172 cout << " " << endl;
2173 cout << " Informations " << endl;
2174 cout << " ===========================================================" << endl;
2175 cout << " " << endl;
2176 cout << " Number of input shapes : " << myOldShapes.Extent() << endl;
2177 cout << " Number of actual shapes : " << myNbShapes << endl;
2178 cout << " Number of Bounds : " << NbBounds << endl;
2179 cout << " Number of Sections : " << NbSections << endl;
2180 cout << " Number of Edges : " << mapEdges.Extent() << endl;
2181 cout << " Number of Vertices : " << myNbVertices << endl;
2182 cout << " Number of Nodes : " << mapVertices.Extent() << endl;
2183 cout << " Number of Free Edges : " << myFreeEdges.Extent() << endl;
2184 cout << " Number of Contigous Edges : " << myContigousEdges.Extent() << endl;
2185 cout << " Number of Multiple Edges : " << myMultipleEdges.Extent() << endl;
2186 cout << " Number of Degenerated Edges : " << myDegenerated.Extent() << endl;
2187 cout << " ===========================================================" << endl;
2188 cout << " " << endl;
2189}
2190
2191//=======================================================================
2192//function : FaceAnalysis
2193//purpose : Remove
2194// Modifies:
2195// myNbShapes
2196// myOldShapes
2197//
2198// Constructs:
2199// myDegenerated
2200//=======================================================================
2201
92434a36 2202void BRepBuilderAPI_Sewing::FaceAnalysis(const Handle(Message_ProgressIndicator)& thePI)
7fd59977 2203{
2204 if (!myShape.IsNull() && myOldShapes.IsEmpty()) {
2205 Add(myShape);
2206 myShape.Nullify();
2207 }
2208
2209 BRep_Builder B;
2210 TopTools_MapOfShape SmallEdges;
2211 TopTools_DataMapOfShapeListOfShape GluedVertices;
2212 Standard_Integer i = 1;
92434a36
A
2213 Message_ProgressSentry aPS (thePI, "Shape analysis", 0, myOldShapes.Extent(), 1);
2214 for (i = 1; i <= myOldShapes.Extent() && aPS.More(); i++, aPS.Next()) {
7fd59977 2215 for (TopExp_Explorer fexp(myOldShapes(i),TopAbs_FACE); fexp.More(); fexp.Next()) {
2216
2217 // Retrieve current face
2218 TopoDS_Shape aTmpShape = fexp.Current(); //for porting
2219 TopoDS_Face face = TopoDS::Face(aTmpShape);
2220 Standard_Integer nbEdges = 0, nbSmall = 0;
2221
2222 // Build replacing face
2223 aTmpShape = face.EmptyCopied().Oriented(TopAbs_FORWARD); //for porting
2224 TopoDS_Face nface = TopoDS::Face(aTmpShape);
2225 Standard_Boolean isFaceChanged = Standard_False;
2226
2227 TopoDS_Iterator witer(face.Oriented(TopAbs_FORWARD));
2228 for (; witer.More(); witer.Next()) {
2229
2230 // Retrieve current wire
2231 aTmpShape = witer.Value(); //for porting
2232 if( aTmpShape.ShapeType() != TopAbs_WIRE) continue;
2233 TopoDS_Wire wire = TopoDS::Wire(aTmpShape);
2234
2235 // Build replacing wire
2236 aTmpShape = wire.EmptyCopied().Oriented(TopAbs_FORWARD);
2237 TopoDS_Wire nwire = TopoDS::Wire(aTmpShape);
2238 Standard_Boolean isWireChanged = Standard_False;
2239
2240 TopoDS_Iterator eiter(wire.Oriented(TopAbs_FORWARD));
2241 for (; eiter.More(); eiter.Next()) {
2242
2243 // Retrieve current edge
2244 aTmpShape = eiter.Value(); //for porting
2245 TopoDS_Edge edge = TopoDS::Edge(aTmpShape);
2246 nbEdges++;
2247
2248 // Process degenerated edge
2249 if (BRep_Tool::Degenerated(edge)) {
2250 B.Add(nwire,edge); // Old edge kept
2251 myDegenerated.Add(edge);
2252 nbSmall++;
2253 continue;
2254 }
2255
2256 Standard_Boolean isSmall = SmallEdges.Contains(edge);
2257 if (!isSmall) {
2258
2259 // Check for small edge
2260 Standard_Real first, last;
2261 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,first,last);
2262 if (c3d.IsNull()) {
2263#ifdef DEB
2264 cout << "Warning: Possibly small edge can be sewed: No 3D curve" << endl;
2265#endif
2266 }
2267 else {
2268 // Evaluate curve compactness
2269 const Standard_Integer npt = 5;
2270 gp_Pnt cp((c3d->Value(first).XYZ()+c3d->Value(last).XYZ())*0.5);
2271 Standard_Real dist, maxdist = 0.0;
2272 Standard_Real delta = (last - first)/(npt - 1);
2273 for (Standard_Integer idx = 0; idx < npt; idx++) {
2274 dist = cp.Distance(c3d->Value(first + idx*delta));
2275 if (maxdist < dist) maxdist = dist;
2276 }
2277 isSmall = (2.*maxdist <= MinTolerance());
2278 /*try {
2279 GeomAdaptor_Curve cAdapt(c3d);
2280 Standard_Real length = GCPnts_AbscissaPoint::Length(cAdapt,first,last);
2281 isSmall = (length <= MinTolerance());
2282 }
2283 catch (Standard_Failure) {
2284#ifdef DEB
2285 cout << "Warning: Possibly small edge can be sewed: ";
2286 Standard_Failure::Caught()->Print(cout); cout << endl;
2287#endif
2288 }*/
2289 }
2290
2291 if (isSmall) {
2292
2293 // Store small edge in the map
2294 SmallEdges.Add(edge);
2295
2296 TopoDS_Vertex v1, v2;
2297 TopExp::Vertices(edge,v1,v2);
2298 TopoDS_Shape nv1 = myReShape->Apply(v1), nv2 = myReShape->Apply(v2);
2299
2300 // Store glued vertices
2301 if (!nv1.IsSame(v1)) {
2302 TopTools_ListOfShape& vlist1 = GluedVertices(nv1);
2303 // First vertex was already glued
2304 if (!nv2.IsSame(v2)) {
2305 // Merge lists of glued vertices
2306 if (!nv1.IsSame(nv2)) {
2307 TopTools_ListIteratorOfListOfShape liter(GluedVertices(nv2));
2308 for (; liter.More(); liter.Next()) {
2309 TopoDS_Shape v = liter.Value();
2310 myReShape->Replace(v,nv1.Oriented(v.Orientation()));
2311 vlist1.Append(v);
2312 }
2313 GluedVertices.UnBind(nv2);
2314 }
2315 }
2316 else {
2317 // Add second vertex to the existing list
2318 vlist1.Append(v2);
2319 myReShape->Replace(v2,nv1.Oriented(v2.Orientation()));
2320 }
2321 }
2322 else if (!nv2.IsSame(v2)) {
2323 // Add first vertex to the existing list
2324 GluedVertices(nv2).Append(v1);
2325 myReShape->Replace(v1,nv2.Oriented(v1.Orientation()));
2326 }
2327 else if (!v1.IsSame(v2)) {
2328 // Record new glued vertices
2329 TopoDS_Vertex nv;
2330 B.MakeVertex(nv);
2331 TopTools_ListOfShape vlist;
2332 vlist.Append(v1);
2333 vlist.Append(v2);
2334 GluedVertices.Bind(nv,vlist);
2335 myReShape->Replace(v1,nv.Oriented(v1.Orientation()));
2336 myReShape->Replace(v2,nv.Oriented(v2.Orientation()));
2337 }
2338 }
2339 }
2340
2341 // Replace small edge
2342 if (isSmall) {
2343#ifdef DEB
2344 cout << "Warning: Small edge made degenerated by FaceAnalysis" << endl;
2345#endif
2346 nbSmall++;
2347 // Create new degenerated edge
2348 aTmpShape = edge.Oriented(TopAbs_FORWARD);
2349 TopoDS_Edge fedge = TopoDS::Edge(aTmpShape);
2350 Standard_Real pfirst, plast;
2351 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(fedge,face,pfirst,plast);
2352 if (!c2d.IsNull()) {
2353 TopoDS_Edge nedge;
2354 B.MakeEdge(nedge);
2355 B.UpdateEdge(nedge,c2d,face,Precision::Confusion());
2356 B.Range(nedge,pfirst,plast);
2357 B.Degenerated(nedge,Standard_True);
2358 TopoDS_Vertex v1, v2;
2359 TopExp::Vertices(fedge,v1,v2);
2360 B.Add(nedge,myReShape->Apply(v1).Oriented(v1.Orientation()));
2361 B.Add(nedge,myReShape->Apply(v2).Oriented(v2.Orientation()));
2362 B.Add(nwire,nedge.Oriented(edge.Orientation()));
2363 myDegenerated.Add(nedge);
2364 }
2365 isWireChanged = Standard_True;
2366 }
2367 else B.Add(nwire,edge); // Old edge kept
2368 }
2369
2370 // Record wire in the new face
2371 if (isWireChanged) {
2372 B.Add(nface,nwire.Oriented(wire.Orientation()));
2373 isFaceChanged = Standard_True;
2374 }
2375 else B.Add(nface,wire);
2376 }
2377
2378 // Remove small face
2379 if (nbSmall == nbEdges) {
2380#ifdef DEB
2381 cout << "Warning: Small face removed by FaceAnalysis" << endl;
2382#endif
2383 myLittleFace.Add(face);
2384 myReShape->Remove(face);
2385 }
2386 else if (isFaceChanged) {
2387
2388 myReShape->Replace(face,nface.Oriented(face.Orientation()));
2389 }
2390 }
2391 }
2392
2393 // Update glued vertices
2394 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape miter(GluedVertices);
2395 for (; miter.More(); miter.Next()) {
2396 TopoDS_Vertex vnew = TopoDS::Vertex(miter.Key());
2397 gp_XYZ coord(0.,0.,0.);
2398 Standard_Integer nbPoints = 0;
2399 const TopTools_ListOfShape& vlist = miter.Value();
2400 TopTools_ListIteratorOfListOfShape liter1(vlist);
2401 for (; liter1.More(); liter1.Next()) {
2402 coord += BRep_Tool::Pnt(TopoDS::Vertex(liter1.Value())).XYZ();
2403 nbPoints++;
2404 }
2405 if (nbPoints) {
2406 gp_Pnt vp(coord / nbPoints);
2407 Standard_Real tol = 0.0, mtol = 0.0;
2408 TopTools_ListIteratorOfListOfShape liter2(vlist);
2409 for (; liter2.More(); liter2.Next()) {
2410 Standard_Real vtol = BRep_Tool::Tolerance(TopoDS::Vertex(liter2.Value()));
2411 if (mtol < vtol) mtol = vtol;
2412 vtol = vp.Distance(BRep_Tool::Pnt(TopoDS::Vertex(liter2.Value())));
2413 if (tol < vtol) tol = vtol;
2414 }
2415 B.UpdateVertex(vnew,vp,tol+mtol);
2416 }
2417 }
2418
2419 // Update input shapes
2420 for (i = 1; i <= myOldShapes.Extent(); i++)
2421 myOldShapes(i) = myReShape->Apply(myOldShapes(i));
2422}
2423
2424//=======================================================================
2425//function : FindFreeBoundaries
2426//purpose : Constructs :
2427// myBoundFaces (bound = list of faces) - REFERENCE
2428// myVertexNode (vertex = node)
2429// myVertexNodeFree (floating vertex = node)
2430//
2431//=======================================================================
2432
2433void BRepBuilderAPI_Sewing::FindFreeBoundaries()
2434{
2435 // Take into account the context shape if needed
2436 TopTools_IndexedMapOfShape NewShapes;
2437 if (!myShape.IsNull()) {
2438 if (myOldShapes.IsEmpty()) {
2439 Add(myShape);
2440 myShape.Nullify();
2441 }
2442 else {
2443 TopoDS_Shape newShape = myReShape->Apply(myShape);
2444 if (!newShape.IsNull()) NewShapes.Add(newShape);
2445 }
2446 }
2447 // Create map Edge -> Faces
2448 TopTools_IndexedDataMapOfShapeListOfShape EdgeFaces;
2449 Standard_Integer i, nbShapes = myOldShapes.Extent();
2450 for (i = 1; i <= nbShapes; i++) {
2451 // Retrieve new shape
2452 TopoDS_Shape shape = myOldShapes(i);
2453 if (shape.IsNull()) continue;
2454 NewShapes.Add(shape);
2455 // Explore shape to find all boundaries
2456 for (TopExp_Explorer eExp(shape,TopAbs_EDGE); eExp.More(); eExp.Next()) {
2457 TopoDS_Shape edge = eExp.Current();
2458 if (!EdgeFaces.Contains(edge)) {
2459 TopTools_ListOfShape listFaces;
2460 EdgeFaces.Add(edge,listFaces);
2461 }
2462 }
2463 }
2464 // Fill map Edge -> Faces
2465 nbShapes = NewShapes.Extent();
2466 TopTools_MapOfShape mapFaces;
2467 for (i = 1; i <= nbShapes; i++) {
2468 // Explore shape to find all faces
2469 TopExp_Explorer fExp(NewShapes.FindKey(i),TopAbs_FACE);
2470 for (; fExp.More(); fExp.Next()) {
2471 TopoDS_Shape face = fExp.Current();
2472 if(mapFaces.Contains(face)) continue;
2473 else
2474 mapFaces.Add(face);
2475 // Explore face to find all boundaries
2476 for (TopoDS_Iterator aIw(face); aIw.More(); aIw.Next()) {
2477 if(aIw.Value().ShapeType() != TopAbs_WIRE) continue;
2478 for (TopoDS_Iterator aIIe(aIw.Value()); aIIe.More(); aIIe.Next()) {
2479
2480 TopoDS_Shape edge = aIIe.Value();
2481
2482 if (EdgeFaces.Contains(edge)) {
2483 EdgeFaces.ChangeFromKey(edge).Append(face);
2484 //TopTools_ListOfShape& listFaces = EdgeFaces.ChangeFromKey(edge);
2485 //Standard_Boolean isContained = Standard_False;
2486 //TopTools_ListIteratorOfListOfShape itf(listFaces);
2487 //for (; itf.More() && !isContained; itf.Next())
2488 // isContained = face.IsSame(itf.Value());
2489 //if (!isContained) listFaces.Append(face);
2490 }
2491 }
2492 }
2493 }
2494 }
2495 // Find free boundaries
2496 nbShapes = EdgeFaces.Extent();
2497 for (i = 1; i <= nbShapes; i++) {
2498 TopTools_ListOfShape& listFaces = EdgeFaces(i);
2499 Standard_Integer nbFaces = listFaces.Extent();
2500 TopoDS_Shape edge = EdgeFaces.FindKey(i);
2501 if(edge.Orientation() == TopAbs_INTERNAL)
2502 continue;
2503 Standard_Boolean isSeam = Standard_False;
2504 if (nbFaces == 1) {
2505 TopoDS_Face face = TopoDS::Face(listFaces.First());
2506 isSeam = BRep_Tool::IsClosed(TopoDS::Edge(edge),face);
2507 if (isSeam) {
2508 ///Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
2509 //isSeam = (IsUClosedSurface(surf) || IsVClosedSurface(surf));
2510 //if(!isSeam) {
2511 BRep_Builder aB;
2512 TopoDS_Shape anewEdge = edge.EmptyCopied();
2513 TopoDS_Iterator aItV(edge);
2514 for( ; aItV.More() ; aItV.Next())
2515 aB.Add(anewEdge,aItV.Value());
2516
2517
2518
2519 Standard_Real first2d,last2d;
2520 Handle(Geom2d_Curve) c2dold =
2521 BRep_Tool::CurveOnSurface(TopoDS::Edge(edge),TopoDS::Face(listFaces.First()),first2d,last2d);
2522
2523 Handle(Geom2d_Curve) c2d;
2524 BRep_Builder B;
2525 B.UpdateEdge(TopoDS::Edge(anewEdge),c2d,c2d,TopoDS::Face(listFaces.First()),0);
2526 B.UpdateEdge(TopoDS::Edge(anewEdge),c2dold,TopoDS::Face(listFaces.First()),0);
2527
2528 Standard_Real aFirst, aLast;
2529 BRep_Tool::Range(TopoDS::Edge(edge),aFirst, aLast);
2530 aB.Range(TopoDS::Edge(anewEdge),aFirst, aLast);
2531 aB.Range(TopoDS::Edge(anewEdge),TopoDS::Face(listFaces.First()),first2d,last2d);
2532 myReShape->Replace(edge,anewEdge);
2533 edge = anewEdge;
2534
2535 //}
2536 isSeam = Standard_False;
2537 }
2538 }
2539 Standard_Boolean isBoundFloat = (myFloatingEdgesMode && !nbFaces);
2540 Standard_Boolean isBound = (myFaceMode && ((myNonmanifold && nbFaces) || (nbFaces == 1 && !isSeam)));
2541 if (isBound || isBoundFloat) {
2542 // Ignore degenerated edge
2543 if (BRep_Tool::Degenerated(TopoDS::Edge(edge))) continue;
2544 // Ignore edge with internal vertices
2545 // Standard_Integer nbVtx = 0;
2546 // for (TopExp_Explorer vExp(edge,TopAbs_VERTEX); vExp.More(); vExp.Next()) nbVtx++;
2547 // if (nbVtx != 2) continue;
2548 // Add to BoundFaces
2549 TopTools_ListOfShape listFacesCopy;
2550 listFacesCopy.Append(listFaces);
2551 myBoundFaces.Add(edge,listFacesCopy);
2552 // Process edge vertices
2553 TopoDS_Vertex vFirst, vLast;
2554 TopExp::Vertices(TopoDS::Edge(edge), vFirst, vLast);
2555 if(vFirst.IsNull() || vLast.IsNull()) continue;
2556 if(vFirst.Orientation() == TopAbs_INTERNAL || vLast.Orientation() == TopAbs_INTERNAL)
2557 continue;
2558 if (isBound) {
2559 // Add to VertexNode
2560 if (!myVertexNode.Contains(vFirst))
2561 myVertexNode.Add(vFirst,vFirst);
2562 if (!myVertexNode.Contains(vLast))
2563 myVertexNode.Add(vLast,vLast);
2564 }
2565 else {
2566 // Add to VertexNodeFree
2567 if (!myVertexNodeFree.Contains(vFirst))
2568 myVertexNodeFree.Add(vFirst,vFirst);
2569 if (!myVertexNodeFree.Contains(vLast))
2570 myVertexNodeFree.Add(vLast,vLast);
2571 }
2572 }
2573 }
2574}
2575
2576//=======================================================================
2577//function : VerticesAssembling
2578//purpose : Modifies :
2579// myVertexNode (nodes glued)
2580// myVertexNodeFree (nodes glued)
2581// myNodeSections (lists of sections merged for glued nodes)
2582//
2583//=======================================================================
2584
2585static Standard_Boolean CreateNewNodes(const TopTools_IndexedDataMapOfShapeShape& NodeNearestNode,
2586 const TopTools_IndexedDataMapOfShapeListOfShape& NodeVertices,
2587 TopTools_IndexedDataMapOfShapeShape& aVertexNode,
2588 TopTools_DataMapOfShapeListOfShape& aNodeEdges)
2589{
2590 Standard_Integer i, nbNearest = NodeNearestNode.Extent();
2591
2592 // Create new nodes
2593 BRep_Builder B;
2594 TopTools_DataMapOfShapeShape OldNodeNewNode;
2595 TopTools_DataMapOfShapeListOfShape NewNodeOldNodes;
2596 for (i = 1; i <= nbNearest; i++) {
2597 // Retrieve a pair of nodes to merge
2598 TopoDS_Shape oldnode1 = NodeNearestNode.FindKey(i);
2599 TopoDS_Shape oldnode2 = NodeNearestNode(i);
2600 // Second node should also be in the map
2601 if (!NodeNearestNode.Contains(oldnode2)) continue;
2602 // Get new node for old node #1
2603 if (OldNodeNewNode.IsBound(oldnode1)) {
2604 TopoDS_Shape newnode1 = OldNodeNewNode(oldnode1);
2605 if (OldNodeNewNode.IsBound(oldnode2)) {
2606 TopoDS_Shape newnode2 = OldNodeNewNode(oldnode2);
2607 if (!newnode1.IsSame(newnode2)) {
2608 // Change data for new node #2
2609 TopTools_ListOfShape& lnode1 = NewNodeOldNodes(newnode1);
2610 TopTools_ListIteratorOfListOfShape itn(NewNodeOldNodes(newnode2));
2611 for (; itn.More(); itn.Next()) {
2612 TopoDS_Shape node2 = itn.Value();
2613 lnode1.Append(node2);
2614 OldNodeNewNode(node2) = newnode1;
2615 }
2616 NewNodeOldNodes.UnBind(newnode2);
2617 }
2618 }
2619 else {
2620 // Old node #2 is not bound - add to old node #1
2621 OldNodeNewNode.Bind(oldnode2,newnode1);
2622 NewNodeOldNodes(newnode1).Append(oldnode2);
2623 }
2624 }
2625 else {
2626 if (OldNodeNewNode.IsBound(oldnode2)) {
2627 // Old node #1 is not bound - add to old node #2
2628 TopoDS_Shape newnode2 = OldNodeNewNode(oldnode2);
2629 OldNodeNewNode.Bind(oldnode1,newnode2);
2630 NewNodeOldNodes(newnode2).Append(oldnode1);
2631 }
2632 else {
2633 // Nodes are not bound - create new node
2634 TopoDS_Vertex newnode;
2635 B.MakeVertex(newnode);
2636 OldNodeNewNode.Bind(oldnode1,newnode);
2637 OldNodeNewNode.Bind(oldnode2,newnode);
2638 TopTools_ListOfShape lnodes;
2639 lnodes.Append(oldnode1);
2640 lnodes.Append(oldnode2);
2641 NewNodeOldNodes.Bind(newnode,lnodes);
2642 }
2643 }
2644 }
2645
2646 // Stop if no new nodes created
2647 if (!NewNodeOldNodes.Extent()) return Standard_False;
2648
2649 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter1(NewNodeOldNodes);
2650 for (; iter1.More(); iter1.Next()) {
2651 const TopoDS_Vertex& newnode = TopoDS::Vertex(iter1.Key());
2652 // Calculate new node center point
2653 gp_XYZ theCoordinates(0.,0.,0.);
2654 TopTools_ListOfShape lvert; // Accumulate node vertices
2655 TopTools_MapOfShape medge;
2656 TopTools_ListOfShape ledge; // Accumulate node edges
2657 // Iterate on old nodes
2658 TopTools_ListIteratorOfListOfShape itn(iter1.Value());
2659 for (; itn.More(); itn.Next()) {
2660 const TopoDS_Shape& oldnode = itn.Value();
2661 // Iterate on node vertices
2662 TopTools_ListIteratorOfListOfShape itv(NodeVertices.FindFromKey(oldnode));
2663 for (; itv.More(); itv.Next()) {
2664 TopoDS_Vertex vertex = TopoDS::Vertex(itv.Value());
2665 // Change node for vertex
2666 aVertexNode.ChangeFromKey(vertex) = newnode;
2667 // Accumulate coordinates
2668 theCoordinates += BRep_Tool::Pnt(vertex).XYZ();
2669 lvert.Append(vertex);
2670 }
2671 // Iterate on node edges
2672 const TopTools_ListOfShape& edges = aNodeEdges(oldnode);
2673 TopTools_ListIteratorOfListOfShape ite(edges);
2674 for (; ite.More(); ite.Next()) {
2675 TopoDS_Shape edge = ite.Value();
2676 if (!medge.Contains(edge)) { medge.Add(edge); ledge.Append(edge); }
2677 }
2678 // Unbind old node edges
2679 aNodeEdges.UnBind(oldnode);
2680 }
2681 // Bind new node edges
2682 aNodeEdges.Bind(newnode,ledge);
2683 gp_Pnt center(theCoordinates / lvert.Extent());
2684 // Calculate new node tolerance
2685 Standard_Real toler = 0.0;
2686 TopTools_ListIteratorOfListOfShape itv(lvert);
2687 for (; itv.More(); itv.Next()) {
2688 const TopoDS_Vertex& vertex = TopoDS::Vertex(itv.Value());
2689 Standard_Real t = center.Distance(BRep_Tool::Pnt(vertex)) + BRep_Tool::Tolerance(vertex);
2690 if (toler < t) toler = t;
2691 }
2692 // Update new node parameters
2693 B.UpdateVertex(newnode,center,toler);
2694 }
2695
2696 return Standard_True;
2697}
2698
2699static Standard_Integer IsMergedVertices(const TopoDS_Shape& face1,
2700 const TopoDS_Shape& e1, const TopoDS_Shape& e2,
2701 const TopoDS_Shape& vtx1, const TopoDS_Shape& vtx2)
2702{
2703 //Case of floating edges
2704 if (face1.IsNull())
2705 return (!IsClosedShape(e1,vtx1,vtx2));
2706
2707 // Find wires containing given edges
2708 TopoDS_Shape wire1, wire2;
2709 TopExp_Explorer itw(face1,TopAbs_WIRE);
2710 for (; itw.More() && (wire1.IsNull() || wire2.IsNull()); itw.Next()) {
2711 TopoDS_Iterator ite(itw.Current(),Standard_False);
2712 for (; ite.More() && (wire1.IsNull() || wire2.IsNull()); ite.Next()) {
2713 if (wire1.IsNull() && e1.IsSame(ite.Value())) wire1 = itw.Current();
2714 if (wire2.IsNull() && e2.IsSame(ite.Value())) wire2 = itw.Current();
2715 }
2716 }
2717 Standard_Integer Status = 0;
2718 if (!wire1.IsNull() && !wire2.IsNull()) {
2719 if (wire1.IsSame(wire2)) {
2720 for (TopoDS_Iterator aIte(wire1,Standard_False); aIte.More(); aIte.Next()) {
2721 TopoDS_Vertex ve1,ve2;
2722 TopExp::Vertices(TopoDS::Edge(aIte.Value()),ve1,ve2);
2723 if ((ve1.IsSame(vtx1) && ve2.IsSame(vtx2)) ||
2724 (ve2.IsSame(vtx1) && ve1.IsSame(vtx2)))
2725 return (IsClosedShape(aIte.Value(),vtx1,vtx2)? 0 : 1);
2726 }
2727 if (IsClosedShape(wire1,vtx1,vtx2)) {
2728 TopoDS_Vertex V1, V2;
2729 TopExp::Vertices(TopoDS::Wire(wire1),V1,V2);
2730 Standard_Boolean isEndVertex = ((V1.IsSame(vtx1) && V2.IsSame(vtx2)) ||
2731 (V2.IsSame(vtx1) && V1.IsSame(vtx2)));
2732 if (!isEndVertex) Status = 1;
2733 }
2734 else Status = 1;
2735 }
2736 else Status = -1;
2737 }
2738 return Status;
2739}
2740
2741static Standard_Boolean GlueVertices(TopTools_IndexedDataMapOfShapeShape& aVertexNode,
92434a36
A
2742 TopTools_DataMapOfShapeListOfShape& aNodeEdges,
2743 const TopTools_IndexedDataMapOfShapeListOfShape& aBoundFaces,
2744 const Standard_Real Tolerance,
2745 const Handle(Message_ProgressIndicator)& theProgress)
7fd59977 2746{
2747 Standard_Integer i, nbVertices = aVertexNode.Extent();
2748 // Create map of node -> vertices
2749 TopTools_IndexedDataMapOfShapeListOfShape NodeVertices;
82192477 2750 BRepBuilderAPI_CellFilter aFilter (Tolerance);
2751 BRepBuilderAPI_VertexInspector anInspector (Tolerance);
7fd59977 2752 for (i = 1; i <= nbVertices; i++) {
2753 TopoDS_Shape vertex = aVertexNode.FindKey(i);
2754 TopoDS_Vertex node = TopoDS::Vertex(aVertexNode(i));
2755 if (NodeVertices.Contains(node)) {
2756 NodeVertices.ChangeFromKey(node).Append(vertex);
2757 }
2758 else {
2759 TopTools_ListOfShape vlist;
2760 vlist.Append(vertex);
2761 NodeVertices.Add(node,vlist);
82192477 2762 gp_Pnt aPnt = BRep_Tool::Pnt (TopoDS::Vertex (node));
2763 aFilter.Add (NodeVertices.FindIndex (node), aPnt.XYZ());
2764 anInspector.Add (aPnt.XYZ());
7fd59977 2765 }
2766 }
2767 Standard_Integer nbNodes = NodeVertices.Extent();
2768#ifdef DEB
2769 cout << "Glueing " << nbNodes << " nodes..." << endl;
2770#endif
7fd59977 2771 // Merge nearest nodes
2772 TopTools_IndexedDataMapOfShapeShape NodeNearestNode;
92434a36
A
2773 Message_ProgressSentry aPS (theProgress, "Glueing nodes", 0, nbNodes, 1, Standard_True);
2774 for (i = 1; i <= nbNodes && aPS.More(); i++, aPS.Next()) {
7fd59977 2775 TopoDS_Vertex node1 = TopoDS::Vertex(NodeVertices.FindKey(i));
2776 // Find near nodes
82192477 2777 gp_Pnt pt1 = BRep_Tool::Pnt (node1);
2778 anInspector.SetCurrent (pt1.XYZ());
2779 gp_XYZ aPntMin = anInspector.Shift (pt1.XYZ(), -Tolerance);
2780 gp_XYZ aPntMax = anInspector.Shift (pt1.XYZ(), Tolerance);
2781 aFilter.Inspect (aPntMin, aPntMax, anInspector);
2782 if (anInspector.ResInd().IsEmpty()) continue;
7fd59977 2783 // Retrieve list of edges for the first node
2784 const TopTools_ListOfShape& ledges1 = aNodeEdges(node1);
2785 // Explore list of near nodes and fill the sequence of glued nodes
2786 TopTools_SequenceOfShape SeqNodes;
2787 TopTools_ListOfShape listNodesSameEdge;
82192477 2788 //gp_Pnt pt1 = BRep_Tool::Pnt(node1);
2789 TColStd_ListIteratorOfListOfInteger iter1(anInspector.ResInd());
7fd59977 2790 for (; iter1.More(); iter1.Next()) {
2791 TopoDS_Vertex node2 = TopoDS::Vertex(NodeVertices.FindKey(iter1.Value()));
2792 if (node1 == node2) continue;
2793 // Retrieve list of edges for the second node
2794 const TopTools_ListOfShape& ledges2 = aNodeEdges(node2);
2795 // Check merging condition for the pair of nodes
2796 Standard_Integer Status = 0, isSameEdge = Standard_False;
2797 // Explore edges of the first node
2798 TopTools_ListIteratorOfListOfShape Ie1(ledges1);
2799 for (; Ie1.More() && !Status && !isSameEdge; Ie1.Next()) {
2800 const TopoDS_Shape& e1 = Ie1.Value();
2801 // Obtain real vertex from edge
2802 TopoDS_Shape v1 = node1;
2803 { //szv: Use brackets to destroy local variables
2804 TopoDS_Vertex ov1, ov2;
2805 TopExp::Vertices(TopoDS::Edge(e1),ov1,ov2);
2806 if (aVertexNode.Contains(ov1)) {
2807 if (node1.IsSame(aVertexNode.FindFromKey(ov1))) v1 = ov1;
2808 }
2809 if (aVertexNode.Contains(ov2)) {
2810 if (node1.IsSame(aVertexNode.FindFromKey(ov2))) v1 = ov2;
2811 }
2812 }
2813 // Create map of faces for e1
2814 TopTools_MapOfShape Faces1;
2815 const TopTools_ListOfShape& lfac1 = aBoundFaces.FindFromKey(e1);
2816 if (lfac1.Extent()) {
2817 TopTools_ListIteratorOfListOfShape itf(lfac1);
2818 for (; itf.More(); itf.Next())
2819 if (!itf.Value().IsNull())
2820 Faces1.Add(itf.Value());
2821 }
2822 // Explore edges of the second node
2823 TopTools_ListIteratorOfListOfShape Ie2(ledges2);
2824 for (; Ie2.More() && !Status && !isSameEdge; Ie2.Next()) {
2825 const TopoDS_Shape& e2 = Ie2.Value();
2826 // Obtain real vertex from edge
2827 TopoDS_Shape v2 = node2;
2828 { //szv: Use brackets to destroy local variables
2829 TopoDS_Vertex ov1, ov2;
2830 TopExp::Vertices(TopoDS::Edge(e2),ov1,ov2);
2831 if (aVertexNode.Contains(ov1)) {
2832 if (node2.IsSame(aVertexNode.FindFromKey(ov1))) v2 = ov1;
2833 }
2834 if (aVertexNode.Contains(ov2)) {
2835 if (node2.IsSame(aVertexNode.FindFromKey(ov2))) v2 = ov2;
2836 }
2837 }
2838 // Explore faces for e2
2839 const TopTools_ListOfShape& lfac2 = aBoundFaces.FindFromKey(e2);
2840 if (lfac2.Extent()) {
2841 TopTools_ListIteratorOfListOfShape itf(lfac2);
2842 for (; itf.More() && !Status && !isSameEdge; itf.Next()) {
2843 // Check merging conditions for the same face
2844 if (Faces1.Contains(itf.Value())) {
2845 Standard_Integer stat = IsMergedVertices(itf.Value(),e1,e2,v1,v2);
2846 if (stat == 1) isSameEdge = Standard_True;
2847 else Status = stat;
2848 }
2849 }
2850 }
2851 else if (Faces1.IsEmpty() && e1 == e2) {
2852 Standard_Integer stat = IsMergedVertices(TopoDS_Face(),e1,e1,v1,v2);
2853 if (stat == 1) isSameEdge = Standard_True;
2854 else Status = stat;
2855 break;
2856 }
2857 }
2858 }
2859 if (Status) continue;
2860 if (isSameEdge) listNodesSameEdge.Append(node2);
2861 // Append near node to the sequence
2862 gp_Pnt pt2 = BRep_Tool::Pnt(node2);
2863 Standard_Real dist = pt1.Distance(pt2);
2864 if (dist < Tolerance) {
2865 Standard_Boolean isIns = Standard_False;
2866 for (Standard_Integer kk = 1; kk <= SeqNodes.Length() && !isIns; kk++) {
2867 gp_Pnt pt = BRep_Tool::Pnt(TopoDS::Vertex(SeqNodes.Value(kk)));
2868 if (dist < pt1.Distance(pt)) {
2869 SeqNodes.InsertBefore(kk,node2);
2870 isIns = Standard_True;
2871 }
2872 }
2873 if (!isIns) SeqNodes.Append(node2);
2874 }
2875 }
2876 if (SeqNodes.Length()) {
2877 // Remove nodes near to some other from the same edge
2878 if (listNodesSameEdge.Extent()) {
2879 TopTools_ListIteratorOfListOfShape lInt(listNodesSameEdge);
2880 for (; lInt.More(); lInt.Next()) {
2881 const TopoDS_Vertex& n2 = TopoDS::Vertex(lInt.Value());
2882 gp_Pnt p2 = BRep_Tool::Pnt(n2);
2883 for (Standard_Integer k = 1; k <= SeqNodes.Length(); ) {
2884 const TopoDS_Vertex& n1 = TopoDS::Vertex(SeqNodes.Value(k));
2885 if (n1 != n2) {
2886 gp_Pnt p1 = BRep_Tool::Pnt(n1);
2887 if (p2.Distance(p1) >= pt1.Distance(p1)) { k++; continue; }
2888 }
2889 SeqNodes.Remove(k);
2890 }
2891 }
2892 }
2893 // Bind nearest node if at least one exists
2894 if (SeqNodes.Length())
2895 NodeNearestNode.Add(node1,SeqNodes.First());
2896 }
82192477 2897 anInspector.ClearResList();
7fd59977 2898 }
2899
2900 // Create new nodes for chained nearest nodes
2901 if (NodeNearestNode.IsEmpty()) return Standard_False;
7fd59977 2902
2903 return CreateNewNodes(NodeNearestNode,NodeVertices,aVertexNode,aNodeEdges);
2904}
2905
92434a36 2906void BRepBuilderAPI_Sewing::VerticesAssembling(const Handle(Message_ProgressIndicator)& thePI)
7fd59977 2907{
2908 Standard_Integer nbVert = myVertexNode.Extent();
2909 Standard_Integer nbVertFree = myVertexNodeFree.Extent();
92434a36 2910 Message_ProgressSentry aPS (thePI, "Vertices assembling", 0, 2, 1);
7fd59977 2911 if (nbVert || nbVertFree) {
2912 // Fill map node -> sections
2913 Standard_Integer i;
2914 for (i = 1; i <= myBoundFaces.Extent(); i++) {
2915 TopoDS_Shape bound = myBoundFaces.FindKey(i);
2916 for (TopoDS_Iterator itv(bound,Standard_False); itv.More(); itv.Next()) {
2917 TopoDS_Shape node = itv.Value();
2918 if (myNodeSections.IsBound(node))
2919 myNodeSections(node).Append(bound);
2920 else {
2921 TopTools_ListOfShape lbnd;
2922 lbnd.Append(bound);
2923 myNodeSections.Bind(node,lbnd);
2924 }
2925 }
2926 }
2927 // Glue vertices
2928 if (nbVert) {
2929#ifdef DEB
2930 cout << "Assemble " << nbVert << " vertices on faces..." << endl;
2931#endif
92434a36 2932 while (GlueVertices(myVertexNode,myNodeSections,myBoundFaces,myTolerance, thePI));
7fd59977 2933 }
92434a36
A
2934 if (!aPS.More())
2935 return;
2936 aPS.Next();
7fd59977 2937 if (nbVertFree) {
2938#ifdef DEB
2939 cout << "Assemble " << nbVertFree << " vertices on floating edges..." << endl;
2940#endif
92434a36 2941 while (GlueVertices(myVertexNodeFree,myNodeSections,myBoundFaces,myTolerance, thePI));
7fd59977 2942 }
2943 }
2944}
2945
2946//=======================================================================
2947//function : replaceNMVertices
2948//purpose : internal use (static)
2949//=======================================================================
2950static void replaceNMVertices(const TopoDS_Edge& theEdge,
2951 const TopoDS_Vertex& theV1,
2952 const TopoDS_Vertex& theV2,
2953 const Handle(BRepTools_ReShape)& theReShape)
2954{
2955 //To keep NM vertices on edge
2956 TopTools_SequenceOfShape aSeqNMVert;
2957 TColStd_SequenceOfReal aSeqNMPars;
2958 Standard_Boolean hasNMVert = findNMVertices(theEdge,aSeqNMVert,aSeqNMPars);
2959 if(!hasNMVert)
2960 return;
2961 Standard_Real first, last;
2962 BRep_Tool::Range(theEdge, first, last);
2963 TopLoc_Location aLoc;
2964 Handle(Geom_Curve) c3d = BRep_Tool::Curve(theEdge,aLoc,first, last);
2965 if(c3d.IsNull())
2966 return;
2967 TopTools_SequenceOfShape aEdVert;
2968 TColStd_SequenceOfReal aEdParams;
2969 Standard_Integer i =1, nb = aSeqNMPars.Length();
2970
2971 for( ; i <= nb;i++) {
2972 Standard_Real apar = aSeqNMPars.Value(i);
2973 if(fabs(apar - first) <= Precision::PConfusion()) {
2974 theReShape->Replace(aSeqNMVert.Value(i),theV1);
2975 continue;
2976 }
2977 if(fabs(apar - last) <= Precision::PConfusion()) {
2978 theReShape->Replace(aSeqNMVert.Value(i),theV2);
2979 continue;
2980 }
2981 TopoDS_Shape aV = aSeqNMVert.Value(i);
2982 Standard_Integer j =1;
2983 for( ; j <= aEdParams.Length();j++) {
2984 Standard_Real apar2 = aEdParams.Value(j);
2985 if(fabs(apar - apar2) <= Precision::PConfusion()) {
2986 theReShape->Replace(aV,aEdVert.Value(j));
2987 break;
2988 }
2989 else if(apar < apar2) {
2990 TopoDS_Shape anewV = aV.EmptyCopied();
2991 aEdVert.InsertBefore(j,anewV);
2992 aEdParams.InsertBefore(j,apar);
2993 BRep_ListOfPointRepresentation& alistrep =
2994 (*((Handle(BRep_TVertex)*)&anewV.TShape()))->ChangePoints();
2995 Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(apar,c3d,aLoc);
2996 alistrep.Append(aPRep);
2997 theReShape->Replace(aV,anewV);
2998 break;
2999 }
3000 }
3001 if (j > aEdParams.Length()) {
3002 TopoDS_Shape anewV = aV.EmptyCopied();
3003 aEdVert.Append(anewV);
3004 aEdParams.Append(apar);
3005 BRep_ListOfPointRepresentation& alistrep =
3006 (*((Handle(BRep_TVertex)*) &anewV.TShape()))->ChangePoints();
3007 Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(apar,c3d,aLoc);
3008 alistrep.Append(aPRep);
3009 theReShape->Replace(aV,anewV);
3010 }
3011 }
3012
3013 Standard_Integer newnb = aEdParams.Length();
3014 if(newnb < nb) {
3015
3016 TopoDS_Shape anewEdge = theEdge.EmptyCopied();
3017 TopAbs_Orientation anOri = theEdge.Orientation();
3018 anewEdge.Orientation(TopAbs_FORWARD);
3019 BRep_Builder aB;
3020 aB.Add(anewEdge,theV1);
3021 aB.Add(anewEdge,theV2);
3022
3023 for( i =1; i <= aEdVert.Length();i++)
3024 aB.Add(anewEdge,aEdVert.Value(i));
3025 anewEdge.Orientation(anOri);
3026 theReShape->Replace(theEdge,anewEdge);
3027 }
3028
3029}
3030
3031//=======================================================================
3032//function : ReplaceEdge
3033//purpose : internal use (static)
3034//=======================================================================
3035
3036static void ReplaceEdge(const TopoDS_Shape& oldEdge,
3037 const TopoDS_Shape& theNewShape,
3038 const Handle(BRepTools_ReShape)& aReShape)
3039{
3040 TopoDS_Shape oldShape = aReShape->Apply(oldEdge);
3041 TopoDS_Shape newShape = aReShape->Apply(theNewShape);
3042 if (oldShape.IsSame(newShape)|| aReShape->IsRecorded(newShape)) return;
3043
3044
3045 aReShape->Replace(oldShape,newShape);
3046 TopoDS_Vertex V1old,V2old,V1new,V2new;
3047 TopExp::Vertices(TopoDS::Edge(oldShape),V1old,V2old);
3048 TopAbs_Orientation Orold = oldShape.Orientation();
3049 TopAbs_Orientation Ornew = Orold;
3050 if (newShape.ShapeType() == TopAbs_EDGE) {
3051 TopoDS_Edge aEn = TopoDS::Edge(newShape);
3052 TopExp::Vertices(aEn,V1new,V2new);
3053 Ornew = aEn.Orientation();
3054 replaceNMVertices(aEn,V1new,V2new,aReShape);
3055 }
3056 else if (newShape.ShapeType() == TopAbs_WIRE) {
3057 for (TopExp_Explorer aex(newShape,TopAbs_EDGE); aex.More(); aex.Next()) {
3058 TopoDS_Edge ed = TopoDS::Edge(aex.Current());
3059 Ornew = ed.Orientation();
3060 TopoDS_Vertex aV1,aV2;
3061 TopExp::Vertices(ed,aV1,aV2);
3062 replaceNMVertices(ed,aV1,aV2,aReShape);
3063 if (V1new.IsNull())
3064 V1new = aV1;
3065 V2new =aV2;
3066 }
3067 }
3068
3069 V1new.Orientation(V1old.Orientation());
3070 V2new.Orientation(V2old.Orientation());
3071 if (V1old.IsSame(V2old) && !V1old.IsSame(V1new)&& !aReShape->IsRecorded(V1new)) {
3072 aReShape->Replace(V1old,V1new);
3073 return;
3074 }
3075 if (Orold == Ornew) {
3076 V1new.Orientation(V1old.Orientation());
3077 V2new.Orientation(V2old.Orientation());
3078 if (!V1old.IsSame(V1new) && !V1old.IsSame(V2new)&& !aReShape->IsRecorded(V1new))
3079 aReShape->Replace(V1old,V1new);
3080 if (!V2old.IsSame(V2new) && !V2old.IsSame(V1new)&& !aReShape->IsRecorded(V2new))
3081 aReShape->Replace(V2old,V2new);
3082 }
3083 else {
3084 V1new.Orientation(V2old.Orientation());
3085 V2new.Orientation(V1old.Orientation());
3086 if (!V1old.IsSame(V2new) && !V1old.IsSame(V1new)&& !aReShape->IsRecorded(V2new))
3087 aReShape->Replace(V1old,V2new);
3088 if (!V2old.IsSame(V2new) && !V2old.IsSame(V1new)&& !aReShape->IsRecorded(V1new))
3089 aReShape->Replace(V2old,V1new);
3090 }
3091}
3092
3093//=======================================================================
3094//function : Merging
3095//purpose : Modifies :
3096// myHasFreeBound
3097//
3098//=======================================================================
3099
92434a36
A
3100void BRepBuilderAPI_Sewing::Merging(const Standard_Boolean /* firstTime */,
3101 const Handle(Message_ProgressIndicator)& thePI)
7fd59977 3102{
3103 BRep_Builder B;
3104 // TopTools_MapOfShape MergedEdges;
92434a36
A
3105 Message_ProgressSentry aPS (thePI, "Merging bounds", 0, myBoundFaces.Extent(), 1);
3106 for (Standard_Integer i = 1; i <= myBoundFaces.Extent() && aPS.More(); i++, aPS.Next()) {
7fd59977 3107
3108 TopoDS_Shape bound = myBoundFaces.FindKey(i);
3109
3110 // If bound was already merged - continue
3111 if (myMergedEdges.Contains(bound)) continue;
3112
3113 if (!myBoundFaces(i).Extent()) {
3114 // Merge free edge - only vertices
3115 TopoDS_Vertex no1, no2;
3116 TopExp::Vertices(TopoDS::Edge(bound),no1,no2);
3117 TopoDS_Shape nno1 = no1, nno2 = no2;
3118 if (myVertexNodeFree.Contains(no1))
3119 nno1 = myVertexNodeFree.FindFromKey(no1);
3120 if (myVertexNodeFree.Contains(no2))
3121 nno2 = myVertexNodeFree.FindFromKey(no2);
3122 if (!no1.IsSame(nno1)) {
3123 nno1.Orientation(no1.Orientation());
3124 myReShape->Replace(no1,nno1);
3125 }
3126 if (!no2.IsSame(nno2)) {
3127 nno2.Orientation(no2.Orientation());
3128 myReShape->Replace(no2,nno2);
3129 }
3130 myMergedEdges.Add(bound);
3131 continue;
3132 }
3133
3134 // Check for previous splitting, build replacing wire
3135 TopoDS_Wire BoundWire;
3136 Standard_Boolean isPrevSplit = Standard_False;
3137 Standard_Boolean hasCuttingSections = myBoundSections.IsBound(bound);
3138 if (hasCuttingSections) {
3139 B.MakeWire(BoundWire);
3140 BoundWire.Orientation(bound.Orientation());
3141 // Iterate on cutting sections
3142 TopTools_ListIteratorOfListOfShape its(myBoundSections(bound));
3143 for (; its.More(); its.Next()) {
3144 TopoDS_Shape section = its.Value();
3145 B.Add(BoundWire,section);
3146 if (myMergedEdges.Contains(section)) isPrevSplit = Standard_True;
3147 }
3148 }
3149
3150 // Merge with bound
3151 TopTools_DataMapOfShapeShape MergedWithBound;
3152 if (!isPrevSplit) {
3153 // Obtain sequence of edges merged with bound
3154 TopTools_SequenceOfShape seqMergedWithBound;
3155 TColStd_SequenceOfInteger seqMergedWithBoundOri;
3156 if (MergedNearestEdges(bound,seqMergedWithBound,seqMergedWithBoundOri)) {
3157 // Store bound in the map
3158 MergedWithBound.Bind(bound,bound);
3159 // Iterate on edges merged with bound
3160 Standard_Integer ii = 1;
3161 while (ii <= seqMergedWithBound.Length()) {
3162 TopoDS_Shape iedge = seqMergedWithBound.Value(ii);
3163 // Remove edge if recorded as merged
3164 Standard_Boolean isRejected = (myMergedEdges.Contains(iedge) ||
3165 MergedWithBound.IsBound(iedge));
3166 if (!isRejected) {
3167 if (myBoundSections.IsBound(iedge)) {
3168 // Edge is splitted - check sections
3169 TopTools_ListIteratorOfListOfShape lit(myBoundSections(iedge));
3170 for (; lit.More() && !isRejected; lit.Next()) {
3171 const TopoDS_Shape& sec = lit.Value();
3172 // Remove edge (bound) if at least one of its sections already merged
3173 isRejected = (myMergedEdges.Contains(sec) || MergedWithBound.IsBound(sec));
3174 }
3175 }
3176 if (!isRejected) {
3177 if (mySectionBound.IsBound(iedge)) {
3178 // Edge is a section - check bound
3179 const TopoDS_Shape& bnd = mySectionBound(iedge);
3180 // Remove edge (section) if its bound already merged
3181 isRejected = (myMergedEdges.Contains(bnd) || MergedWithBound.IsBound(bnd));
3182 }
3183 }
3184 }
3185 // To the next merged edge
3186 if (isRejected) {
3187 // Remove rejected edge
3188 seqMergedWithBound.Remove(ii);
3189 seqMergedWithBoundOri.Remove(ii);
3190 }
3191 else {
3192 // Process accepted edge
3193 MergedWithBound.Bind(iedge,iedge);
3194 ii++;
3195 }
3196 }
3197 Standard_Integer nbMerged = seqMergedWithBound.Length();
3198 if (nbMerged) {
3199 // Create same parameter edge
3200 TopTools_MapOfShape ActuallyMerged;
3201 TopoDS_Edge MergedEdge = SameParameterEdge(bound,seqMergedWithBound,
3202 seqMergedWithBoundOri,
3203 ActuallyMerged,myReShape);
3204 Standard_Boolean isForward = Standard_False;
3205 if (!MergedEdge.IsNull()) isForward = (MergedEdge.Orientation() == TopAbs_FORWARD);
3206 // Process actually merged edges
3207 Standard_Integer nbActuallyMerged = 0;
3208 for (ii = 1; ii <= nbMerged; ii++) {
3209 TopoDS_Shape iedge = seqMergedWithBound(ii);
3210 if (ActuallyMerged.Contains(iedge)) {
3211 nbActuallyMerged++;
3212 // Record merged edge in the map
3213 TopAbs_Orientation orient = iedge.Orientation();
3214 if (!isForward) orient = TopAbs::Reverse(orient);
3215 if (!seqMergedWithBoundOri(ii)) orient = TopAbs::Reverse(orient);
3216 MergedWithBound.ChangeFind(iedge) = MergedEdge.Oriented(orient);
3217 }
3218 else MergedWithBound.UnBind(iedge);
3219 }
3220 if (nbActuallyMerged) {
3221 // Record merged bound in the map
3222 TopAbs_Orientation orient = bound.Orientation();
3223 if (!isForward) orient = TopAbs::Reverse(orient);
3224 MergedWithBound.ChangeFind(bound) = MergedEdge.Oriented(orient);
3225 }
3226 nbMerged = nbActuallyMerged;
3227 }
3228 // Remove bound from the map if not finally merged
3229 if (!nbMerged) MergedWithBound.UnBind(bound);
3230 }
3231 }
3232 Standard_Boolean isMerged = MergedWithBound.Extent();
3233
3234 // Merge with cutting sections
3235 Handle(BRepTools_ReShape) SectionsReShape = new BRepTools_ReShape;
3236 TopTools_DataMapOfShapeShape MergedWithSections;
3237 if (hasCuttingSections) {
3238 // Iterate on cutting sections
3239 TopTools_ListIteratorOfListOfShape its(myBoundSections(bound));
3240 for (; its.More(); its.Next()) {
3241 // Retrieve cutting section
3242 TopoDS_Shape section = its.Value();
3243 // Skip section if already merged
3244 if (myMergedEdges.Contains(section)) continue;
3245 // Merge cutting section
3246 TopTools_SequenceOfShape seqMergedWithSection;
3247 TColStd_SequenceOfInteger seqMergedWithSectionOri;
3248 if (MergedNearestEdges(section,seqMergedWithSection,seqMergedWithSectionOri)) {
3249 // Store section in the map
3250 MergedWithSections.Bind(section,section);
3251 // Iterate on edges merged with section
3252 Standard_Integer ii = 1;
3253 while (ii <= seqMergedWithSection.Length()) {
3254 TopoDS_Shape iedge = seqMergedWithSection.Value(ii);
3255 // Remove edge if recorded as merged
3256 Standard_Boolean isRejected = (myMergedEdges.Contains(iedge) || MergedWithSections.IsBound(iedge));
3257 if (!isRejected) {
3258 if (myBoundSections.IsBound(iedge)) {
3259 // Edge is splitted - check sections
3260 TopTools_ListIteratorOfListOfShape lit(myBoundSections(iedge));
3261 for (; lit.More() && !isRejected; lit.Next()) {
3262 const TopoDS_Shape& sec = lit.Value();
3263 // Remove edge (bound) if at least one of its sections already merged
3264 isRejected = (myMergedEdges.Contains(sec) || MergedWithSections.IsBound(sec));
3265 }
3266 }
3267 if (!isRejected) {
3268 if (mySectionBound.IsBound(iedge)) {
3269 // Edge is a section - check bound
3270 const TopoDS_Shape& bnd = mySectionBound(iedge);
3271 // Remove edge (section) if its bound already merged
3272 isRejected = (myMergedEdges.Contains(bnd) || MergedWithSections.IsBound(bnd));
3273 }
3274 }
3275 }
3276 // To the next merged edge
3277 if (isRejected) {
3278 // Remove rejected edge
3279 seqMergedWithSection.Remove(ii);
3280 seqMergedWithSectionOri.Remove(ii);
3281 }
3282 else {
3283 // Process accepted edge
3284 MergedWithSections.Bind(iedge,iedge);
3285 ii++;
3286 }
3287 }
3288 Standard_Integer nbMerged = seqMergedWithSection.Length();
3289 if (nbMerged) {
3290 // Create same parameter edge
3291 TopTools_MapOfShape ActuallyMerged;
3292 TopoDS_Edge MergedEdge = SameParameterEdge(section,seqMergedWithSection,
3293 seqMergedWithSectionOri,
3294 ActuallyMerged,SectionsReShape);
3295 Standard_Boolean isForward = Standard_False;
3296 if (!MergedEdge.IsNull()) isForward = (MergedEdge.Orientation() == TopAbs_FORWARD);
3297 // Process actually merged edges
3298 Standard_Integer nbActuallyMerged = 0;
3299 for (ii = 1; ii <= nbMerged; ii++) {
3300 TopoDS_Shape iedge = seqMergedWithSection(ii);
3301 if (ActuallyMerged.Contains(iedge)) {
3302 nbActuallyMerged++;
3303 // Record merged edge in the map
3304 TopAbs_Orientation orient = iedge.Orientation();
3305 if (!isForward) orient = TopAbs::Reverse(orient);
3306 if (!seqMergedWithSectionOri(ii)) orient = TopAbs::Reverse(orient);
3307 TopoDS_Shape oedge = MergedEdge.Oriented(orient);
3308 MergedWithSections.ChangeFind(iedge) = oedge;
3309 ReplaceEdge(myReShape->Apply(iedge),oedge,SectionsReShape);
3310 }
3311 else MergedWithSections.UnBind(iedge);
3312 }
3313 if (nbActuallyMerged) {
3314 // Record merged section in the map
3315 TopAbs_Orientation orient = section.Orientation();
3316 if (!isForward) orient = TopAbs::Reverse(orient);
3317 TopoDS_Shape oedge = MergedEdge.Oriented(orient);
3318 MergedWithSections.ChangeFind(section) = oedge;
3319 ReplaceEdge(myReShape->Apply(section),oedge,SectionsReShape);
3320 }
3321 nbMerged = nbActuallyMerged;
3322 }
3323 // Remove section from the map if not finally merged
3324 if (!nbMerged) MergedWithSections.UnBind(section);
3325 }
3326 else if (isMerged) {
3327 // Reject merging of sections
3328 MergedWithSections.Clear();
3329 break;
3330 }
3331 }
3332 }
3333 Standard_Boolean isMergedSplit = MergedWithSections.Extent();
3334
3335 if (!isMerged && !isMergedSplit) {
3336 // Nothing was merged in this iteration
3337 if (isPrevSplit) {
3338 // Replace previously splitted bound
3339 myReShape->Replace(myReShape->Apply(bound),myReShape->Apply(BoundWire));
3340 }
3341 // else if (hasCuttingSections) {
3342 // myBoundSections.UnBind(bound); //szv: are you sure ???
3343 // }
3344 continue;
3345 }
3346
3347 // Set splitting flag
3348 Standard_Boolean isSplitted = ((!isMerged && isMergedSplit) || isPrevSplit);
3349
3350 // Choose between bound and sections merging
3351 if (isMerged && isMergedSplit && !isPrevSplit) {
3352 // Fill map of merged cutting sections
3353 TopTools_MapOfShape MapSplitEdges;
3354 TopTools_DataMapIteratorOfDataMapOfShapeShape itm;
3355 for (itm.Initialize(MergedWithSections); itm.More(); itm.Next()) {
3356 TopoDS_Shape edge = itm.Key();
3357 MapSplitEdges.Add(edge);
3358 }
3359 // Iterate on edges merged with bound
3360 for (itm.Initialize(MergedWithBound); itm.More(); itm.Next()) {
3361 // Retrieve edge merged with bound
3362 TopoDS_Shape edge = itm.Key();
3363 // Remove edge from the map
3364 if (MapSplitEdges.Contains(edge)) MapSplitEdges.Remove(edge);
3365 if (myBoundSections.IsBound(edge)) {
3366 // Edge has cutting sections
3367 TopTools_ListIteratorOfListOfShape its(myBoundSections(edge));
3368 for (; its.More(); its.Next()) {
3369 TopoDS_Shape sec = its.Value();
3370 // Remove section from the map
3371 if (MapSplitEdges.Contains(sec)) MapSplitEdges.Remove(sec);
3372 }
3373 }
3374 }
3375 // Calculate section merging tolerance
3376 Standard_Real MinSplitTol = RealLast();
3377 TopTools_MapIteratorOfMapOfShape im(MapSplitEdges);
3378 for (; im.More(); im.Next()) {
3379 TopoDS_Edge edge = TopoDS::Edge(MergedWithSections(im.Key()));
3380 MinSplitTol = Min(MinSplitTol,BRep_Tool::Tolerance(edge));
3381 }
3382 // Calculate bound merging tolerance
3383 TopoDS_Edge BoundEdge = TopoDS::Edge(MergedWithBound(bound));
3384 Standard_Real BoundEdgeTol = BRep_Tool::Tolerance(BoundEdge);
3385 isSplitted = ((MinSplitTol < BoundEdgeTol+MinTolerance()) || myNonmanifold);
3386 isSplitted = (!MapSplitEdges.IsEmpty() && isSplitted);
3387 }
3388
3389 if (isSplitted) {
3390 // Merging of cutting sections
3391 //myMergedEdges.Add(bound);
3392 myReShape->Replace(myReShape->Apply(bound),myReShape->Apply(BoundWire));
3393 TopTools_DataMapIteratorOfDataMapOfShapeShape itm(MergedWithSections);
3394 for (; itm.More(); itm.Next()) {
3395 TopoDS_Shape oldedge = itm.Key();
3396 TopoDS_Shape newedge = SectionsReShape->Apply(itm.Value());
3397 ReplaceEdge(myReShape->Apply(oldedge),newedge,myReShape);
3398 myMergedEdges.Add(oldedge);
3399 if (myBoundSections.IsBound(oldedge)) myBoundSections.UnBind(oldedge);
3400
3401 }
3402 }
3403 else {
3404 // Merging of initial bound
3405 TopTools_DataMapIteratorOfDataMapOfShapeShape itm(MergedWithBound);
3406 //myMergedEdges.Add(bound);
3407 for (; itm.More(); itm.Next()) {
3408 TopoDS_Shape oldedge = itm.Key();
3409 TopoDS_Shape newedge = itm.Value();
3410 ReplaceEdge(myReShape->Apply(oldedge),newedge,myReShape);
3411 myMergedEdges.Add(oldedge);
3412 if (myBoundSections.IsBound(oldedge)) myBoundSections.UnBind(oldedge);
3413 }
3414 if (myBoundSections.IsBound(bound)) myBoundSections.UnBind(bound);
3415 if(!myMergedEdges.Contains(bound))
3416 myMergedEdges.Add(bound);
3417 }
3418 }
3419
3420 myNbVertices = myVertexNode.Extent() + myVertexNodeFree.Extent();
3421 myNodeSections.Clear();
3422 myVertexNode.Clear();
3423 myVertexNodeFree.Clear();
3424 myCuttingNode.Clear();
3425}
3426
3427//=======================================================================
3428//function : MergedNearestEdges
3429//purpose :
3430//=======================================================================
3431
3432Standard_Boolean BRepBuilderAPI_Sewing::MergedNearestEdges(const TopoDS_Shape& edge,
3433 TopTools_SequenceOfShape& SeqMergedEdge,
3434 TColStd_SequenceOfInteger& SeqMergedOri)
3435{
3436 // Retrieve edge nodes
3437 TopoDS_Vertex no1, no2;
3438 TopExp::Vertices(TopoDS::Edge(edge),no1,no2);
3439 TopoDS_Shape nno1 = no1, nno2 = no2;
3440 Standard_Boolean isNode1 = myVertexNode.Contains(no1);
3441 Standard_Boolean isNode2 = myVertexNode.Contains(no2);
3442 if (isNode1) nno1 = myVertexNode.FindFromKey(no1);
3443 if (isNode2) nno2 = myVertexNode.FindFromKey(no2);
3444
3445 // Fill map of nodes connected to the node #1
3446 TopTools_MapOfShape mapVert1;
3447 mapVert1.Add(nno1);
3448 if (myCuttingNode.IsBound(nno1)) {
3449 TopTools_ListIteratorOfListOfShape ilv(myCuttingNode(nno1));
3450 for (; ilv.More(); ilv.Next()) {
3451 TopoDS_Shape v1 = ilv.Value();
3452 mapVert1.Add(v1);
3453 if (!isNode1 && myCuttingNode.IsBound(v1)) {
3454 TopTools_ListIteratorOfListOfShape ilvn(myCuttingNode(v1));
3455 for (; ilvn.More(); ilvn.Next()) {
3456 TopoDS_Shape vn = ilvn.Value();
3457 mapVert1.Add(vn);
3458 }
3459 }
3460 }
3461 }
3462
3463 // Fill map of nodes connected to the node #2
3464 TopTools_MapOfShape mapVert2;
3465 mapVert2.Add(nno2);
3466 if (myCuttingNode.IsBound(nno2)) {
3467 TopTools_ListIteratorOfListOfShape ilv(myCuttingNode(nno2));
3468 for (; ilv.More(); ilv.Next()) {
3469 TopoDS_Shape v1 = ilv.Value();
3470 mapVert2.Add(v1);
3471 if (!isNode2 && myCuttingNode.IsBound(v1)) {
3472 TopTools_ListIteratorOfListOfShape ilvn(myCuttingNode(v1));
3473 for (; ilvn.More(); ilvn.Next()) {
3474 TopoDS_Shape vn = ilvn.Value();
3475 mapVert2.Add(vn);
3476 }
3477 }
3478 }
3479 }
3480
3481 // Find all possible contigous edges
3482 TopTools_SequenceOfShape seqEdges;
3483 seqEdges.Append(edge);
3484 TopTools_MapOfShape mapEdges;
3485 mapEdges.Add(edge);
3486 for (TopTools_MapIteratorOfMapOfShape imv1(mapVert1); imv1.More(); imv1.Next()) {
3487 TopoDS_Shape node1 = imv1.Key();
3488 if (!myNodeSections.IsBound(node1)) continue;
3489 TopTools_ListIteratorOfListOfShape ilsec(myNodeSections(node1));
3490 for (; ilsec.More(); ilsec.Next()) {
3491 TopoDS_Shape sec = ilsec.Value();
3492 if (sec.IsSame(edge)) continue;
3493 // Retrieve section nodes
3494 TopoDS_Vertex vs1, vs2;
3495 TopExp::Vertices(TopoDS::Edge(sec),vs1,vs2);
3496 TopoDS_Shape vs1n = vs1, vs2n = vs2;
3497 if (myVertexNode.Contains(vs1)) vs1n = myVertexNode.FindFromKey(vs1);
3498 if (myVertexNode.Contains(vs2)) vs2n = myVertexNode.FindFromKey(vs2);
3499 if ((mapVert1.Contains(vs1n) && mapVert2.Contains(vs2n)) ||
3500 (mapVert1.Contains(vs2n) && mapVert2.Contains(vs1n)))
3501 if (mapEdges.Add(sec)) {
3502 // Check for rejected cutting
3503 Standard_Boolean isRejected = myMergedEdges.Contains(sec);
3504 if(!isRejected && myBoundSections.IsBound(sec))
3505 {
3506 TopTools_ListIteratorOfListOfShape its(myBoundSections(sec));
3507 for (; its.More() && !isRejected; its.Next()) {
3508 TopoDS_Shape section = its.Value();
3509
3510 if (myMergedEdges.Contains(section))
3511 isRejected = Standard_True;
3512 }
3513 }
3514 if( !isRejected && mySectionBound.IsBound(sec)) {
3515 const TopoDS_Shape& bnd = mySectionBound(sec);
3516 isRejected = (!myBoundSections.IsBound(bnd) ||
3517 myMergedEdges.Contains(bnd));
3518 }
3519
3520 if (!isRejected) seqEdges.Append(sec);
3521 }
3522 }
3523 }
3524
3525 mapEdges.Clear();
3526
3527 Standard_Boolean success = Standard_False;
3528
3529 Standard_Integer nbSection = seqEdges.Length();
3530 if (nbSection > 1) {
3531 // Find the longest edge CCI60011
3532 Standard_Integer i, indRef = 1;
3533 if (myNonmanifold) {
3534 Standard_Real lenRef = 0.;
3535 for (i = 1; i <= nbSection; i++) {
3536 Standard_Real f, l;
3537 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(seqEdges(i)), f, l);
3538 GeomAdaptor_Curve cAdapt(c3d);
3539 Standard_Real len = GCPnts_AbscissaPoint::Length(cAdapt, f, l);
3540 if (len > lenRef) { indRef = i; lenRef = len; }
3541 }
3542 if (indRef != 1) {
3543 TopoDS_Shape longEdge = seqEdges(indRef);
3544 seqEdges(indRef) = seqEdges(1);
3545 seqEdges(1) = longEdge;
3546 }
3547 }
3548
3549 // Find merging candidates
3550 TColStd_SequenceOfInteger seqForward;
3551 TColStd_SequenceOfInteger seqCandidates;
3552 TColStd_IndexedMapOfInteger mapReference;
5b14f800 3553 mapReference.Add(indRef); // Add index of reference section
7fd59977 3554 if (FindCandidates(seqEdges,mapReference,seqCandidates,seqForward)) {
3555 Standard_Integer nbCandidates = seqCandidates.Length();
7fd59977 3556 // Record candidate sections
3557 for (i = 1; i <= nbCandidates; i++) {
3558 // Retrieve merged edge
3559 TopoDS_Shape iedge = seqEdges(seqCandidates(i));
5b14f800 3560 Standard_Integer ori = (seqForward(i))? 1 : 0;
7fd59977 3561 SeqMergedEdge.Append(iedge);
3562 SeqMergedOri.Append(ori);
3563 if (!myNonmanifold) break;
3564 }
3565 success = nbCandidates;
3566 }
3567 }
3568
3569 return success;
3570}
3571
3572//=======================================================================
3573//function : Cutting
3574//purpose : Modifies :
3575// myBoundSections
3576// myNodeSections
3577// myCuttingNode
3578//=======================================================================
3579
92434a36 3580void BRepBuilderAPI_Sewing::Cutting(const Handle(Message_ProgressIndicator)& thePI)
7fd59977 3581{
3582 Standard_Integer i, nbVertices = myVertexNode.Extent();
3583 if (!nbVertices) return;
82192477 3584 // Create a box tree with vertices
7fd59977 3585 Standard_Real eps = myTolerance*0.5;
82192477 3586 BRepBuilderAPI_BndBoxTree aTree;
3587 NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller (aTree);
3588 BRepBuilderAPI_BndBoxTreeSelector aSelector;
7fd59977 3589 for (i = 1; i <= nbVertices; i++) {
3590 gp_Pnt pt = BRep_Tool::Pnt(TopoDS::Vertex(myVertexNode.FindKey(i)));
3591 Bnd_Box aBox;
3592 aBox.Set(pt);
3593 aBox.Enlarge(eps);
82192477 3594 aTreeFiller.Add (i, aBox);
7fd59977 3595 }
82192477 3596 aTreeFiller.Fill();
3597
7fd59977 3598 Handle(Geom_Curve) c3d;
3599 TopLoc_Location loc;
3600 Standard_Real first, last;
3601 // Iterate on all boundaries
3602 Standard_Integer nbBounds = myBoundFaces.Extent();
92434a36
A
3603 Message_ProgressSentry aPS (thePI, "Cutting bounds", 0, nbBounds, 1);
3604 for (i = 1; i <= nbBounds && aPS.More(); i++, aPS.Next()) {
7fd59977 3605 const TopoDS_Edge& bound = TopoDS::Edge(myBoundFaces.FindKey(i));
3606 // Do not cut floating edges
3607 if (!myBoundFaces(i).Extent()) continue;
de10d8b1 3608 // Obtain bound curve
3609 c3d = BRep_Tool::Curve(bound, loc, first, last);
3610 if (c3d.IsNull()) continue;
3611 if (!loc.IsIdentity()) {
3612 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
3613 c3d->Transform(loc.Transformation());
3614 }
7fd59977 3615 // Create cutting sections
3616 TopTools_ListOfShape listSections;
3617 { //szv: Use brackets to destroy local variables
7fd59977 3618 // Obtain candidate vertices
3619 TopoDS_Vertex V1, V2;
3620 TopTools_IndexedMapOfShape CandidateVertices;
3621 { //szv: Use brackets to destroy local variables
3622 // Create bounding box around curve
3623 Bnd_Box aGlobalBox;
3624 GeomAdaptor_Curve adptC(c3d,first,last);
3625 BndLib_Add3dCurve::Add(adptC,myTolerance,aGlobalBox);
3626 // Sort vertices to find candidates
82192477 3627 aSelector.SetCurrent (aGlobalBox);
3628 aTree.Select (aSelector);
7fd59977 3629 // Skip bound if no node is in the boundind box
82192477 3630 if (!aSelector.ResInd().Extent()) continue;
7fd59977 3631 // Retrieve bound nodes
3632 TopExp::Vertices(bound,V1,V2);
3633 const TopoDS_Shape& Node1 = myVertexNode.FindFromKey(V1);
3634 const TopoDS_Shape& Node2 = myVertexNode.FindFromKey(V2);
3635 // Fill map of candidate vertices
82192477 3636 TColStd_ListIteratorOfListOfInteger itl(aSelector.ResInd());
7fd59977 3637 for (; itl.More(); itl.Next()) {
3638 const Standard_Integer index = itl.Value();
3639 const TopoDS_Shape& Node = myVertexNode.FindFromIndex(index);
3640 if (!Node.IsSame(Node1) && !Node.IsSame(Node2)) {
3641 TopoDS_Shape vertex = myVertexNode.FindKey(index);
3642 CandidateVertices.Add(vertex);
3643 }
3644 }
82192477 3645 aSelector.ClearResList();
7fd59977 3646 }
3647 Standard_Integer nbCandidates = CandidateVertices.Extent();
3648 if (!nbCandidates) continue;
3649 // Project vertices on curve
3650 TColStd_Array1OfReal arrPara(1,nbCandidates), arrDist(1,nbCandidates);
3651 TColgp_Array1OfPnt arrPnt(1,nbCandidates), arrProj(1,nbCandidates);
3652 for (Standard_Integer j = 1; j <= nbCandidates; j++)
3653 arrPnt(j) = BRep_Tool::Pnt(TopoDS::Vertex(CandidateVertices(j)));
2028d00c 3654 ProjectPointsOnCurve(arrPnt,c3d,first,last,arrDist,arrPara,arrProj,Standard_True);
7fd59977 3655 // Create cutting nodes
3656 TopTools_SequenceOfShape seqNode;
3657 TColStd_SequenceOfReal seqPara;
3658 CreateCuttingNodes(CandidateVertices,bound,
3659 V1,V2,arrDist,arrPara,arrProj,seqNode,seqPara);
3660 if (!seqPara.Length()) continue;
3661 // Create cutting sections
3662 CreateSections(bound, seqNode, seqPara, listSections);
3663 }
3664 if (listSections.Extent() > 1) {
3665 // modification of maps:
3666 // myBoundSections
3667 TopTools_ListIteratorOfListOfShape its(listSections);
3668 for (; its.More(); its.Next()) {
3669 TopoDS_Shape section = its.Value();
3670 // Iterate on section vertices
3671 for (TopoDS_Iterator itv(section); itv.More(); itv.Next()) {
3672 TopoDS_Shape vertex = itv.Value();
3673 // Convert vertex to node
3674 if (myVertexNode.Contains(vertex))
3675 vertex = TopoDS::Vertex(myVertexNode.FindFromKey(vertex));
3676 // Update node sections
3677 if (myNodeSections.IsBound(vertex))
3678 myNodeSections.ChangeFind(vertex).Append(section);
3679 else {
3680 TopTools_ListOfShape lsec;
3681 lsec.Append(section);
3682 myNodeSections.Bind(vertex,lsec);
3683 }
3684 }
3685 // Store bound for section
3686 mySectionBound.Bind(section,bound);
3687 }
3688 // Store splitted bound
3689 myBoundSections.Bind(bound,listSections);
3690 }
3691 }
3692#ifdef DEB
3693 cout << "From " << nbBounds << " bounds " << myBoundSections.Extent()
3694 << " were cut into " << mySectionBound.Extent() << " sections" << endl;
3695#endif
3696}
3697
3698//=======================================================================
3699//function : GetSeqEdges
3700//purpose :
3701//=======================================================================
3702
3703static void GetSeqEdges(const TopoDS_Shape& edge,
3704 TopTools_SequenceOfShape& seqEdges,
3705 TopTools_DataMapOfShapeListOfShape& VertEdge)
3706{
3707 Standard_Integer numV = 0;
3708 for (TopoDS_Iterator Iv(edge,Standard_False); Iv.More(); Iv.Next()) {
3709 TopoDS_Vertex V1 = TopoDS::Vertex(Iv.Value());
3710 numV++;
3711 if (VertEdge.IsBound(V1)) {
3712 const TopTools_ListOfShape& listEdges = VertEdge.Find(V1);
3713 for (TopTools_ListIteratorOfListOfShape lIt(listEdges); lIt.More(); lIt.Next()) {
3714 TopoDS_Shape edge1 = lIt.Value();
3715 if (edge1.IsSame(edge)) continue;
3716 Standard_Boolean isContained = Standard_False;
3717 Standard_Integer i, index = 1;
3718 for (i = 1; i <= seqEdges.Length() && !isContained; i++) {
3719 isContained = seqEdges.Value(i).IsSame(edge1);
3720 if (!isContained && seqEdges.Value(i).IsSame(edge)) index = i;
3721 }
3722 if (!isContained) {
3723 if (numV == 1) seqEdges.InsertBefore(index,edge1);
3724 else seqEdges.InsertAfter(index,edge1);
3725 GetSeqEdges(edge1,seqEdges,VertEdge);
3726 }
3727 }
3728 }
3729 }
3730}
3731
3732//=======================================================================
3733//function : GetFreeWires
3734//purpose :
3735//=======================================================================
3736
3737void BRepBuilderAPI_Sewing::GetFreeWires(TopTools_MapOfShape& MapFreeEdges, TopTools_SequenceOfShape& seqWires)
3738{
3739 TopTools_DataMapOfShapeListOfShape VertEdge;
3740 TopTools_MapIteratorOfMapOfShape itMap(MapFreeEdges);
3741 TopTools_SequenceOfShape seqFreeEdges;
3742 for (; itMap.More(); itMap.Next()) {
3743 TopoDS_Shape edge = itMap.Key();
3744 seqFreeEdges.Append(edge);
3745 for (TopoDS_Iterator Iv(edge,Standard_False); Iv.More(); Iv.Next()) {
3746 TopoDS_Vertex V1 = TopoDS::Vertex(Iv.Value());
3747 if (VertEdge.IsBound(V1))
3748 VertEdge.ChangeFind(V1).Append(edge);
3749 else {
3750 TopTools_ListOfShape ls;
3751 ls.Append(edge);
3752 VertEdge.Bind(V1,ls);
3753 }
3754 }
3755 }
3756 BRep_Builder B;
3757 Standard_Integer i, j;
3758 for (i = 1; i <= seqFreeEdges.Length(); i++) {
3759 TopTools_SequenceOfShape seqEdges;
3760 TopoDS_Shape edge = seqFreeEdges.Value(i);
3761 if (!MapFreeEdges.Contains(edge)) continue;
3762 seqEdges.Append(edge);
3763 GetSeqEdges(edge,seqEdges,VertEdge);
3764 TopoDS_Wire wire;
3765 B.MakeWire(wire);
3766 for (j = 1; j <= seqEdges.Length(); j++) {
3767 B.Add(wire,seqEdges.Value(j));
3768 MapFreeEdges.Remove(seqEdges.Value(j));
3769 }
3770 seqWires.Append(wire);
3771 if (MapFreeEdges.IsEmpty()) break;
3772 }
3773}
3774
3775//=======================================================================
3776//function : IsDegeneratedWire
3777//purpose : internal use
3778//=======================================================================
3779
3780static Standard_Boolean IsDegeneratedWire(const TopoDS_Shape& wire)
3781{
3782 if (wire.ShapeType() != TopAbs_WIRE) return Standard_False;
3783 // Get maximal vertices tolerance
3784 TopoDS_Vertex V1,V2;
3785 //TopExp::Vertices(TopoDS::Wire(wire),V1,V2);
3786 //Standard_Real tol = Max(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2));
3787 Standard_Real wireLength = 0.0;
3788 TopLoc_Location loc;
3789 Standard_Real first, last;
3790 Standard_Integer nume = 0;
3791 Standard_Integer isSmall = 0;
3792 for (TopoDS_Iterator aIt(wire,Standard_False); aIt.More(); aIt.Next()) {
3793 nume++;
3794 TopoDS_Shape edge = aIt.Value();
3795 TopoDS_Vertex Ve1,Ve2;
3796 TopExp::Vertices(TopoDS::Edge(edge),Ve1,Ve2);
3797 if(nume == 1) {
3798 V1 = Ve1;
3799 V2 = Ve2;
3800 }
3801 else {
3802 if(Ve1.IsSame(V1))
3803 V1 = Ve2;
3804 else if(Ve1.IsSame(V2))
3805 V2 = Ve2;
3806 if(Ve2.IsSame(V1))
3807 V1 = Ve1;
3808 else if(Ve2.IsSame(V2))
3809 V2 = Ve1;
3810 }
3811 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(aIt.Value()),loc,first,last);
3812 if (!c3d.IsNull()) {
3813 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
3814 if (!loc.IsIdentity()) {
3815 //c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
3816 c3d->Transform(loc.Transformation());
3817 }
3818 gp_Pnt pfirst = c3d->Value(first);
3819 gp_Pnt plast = c3d->Value(last);
3820 gp_Pnt pmid = c3d->Value((first +last)*0.5);
3821 Standard_Real length =0;
3822 if(pfirst.Distance(plast) > pfirst.Distance(pmid)) {
3823 length = pfirst.Distance(plast);
3824 }
3825 else {
3826 GeomAdaptor_Curve cAdapt(c3d);
3827 length = GCPnts_AbscissaPoint::Length(cAdapt, first, last);
3828 }
3829 Standard_Real tole = BRep_Tool::Tolerance(Ve1)+BRep_Tool::Tolerance(Ve2);
3830 if(length <= tole) isSmall++;
3831 wireLength += length;
3832 }
3833 }
3834 if(isSmall == nume) return Standard_True;
3835 Standard_Real tol = BRep_Tool::Tolerance(V1)+BRep_Tool::Tolerance(V2);//Max(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2));
3836 if (wireLength > tol) return Standard_False;
3837 return Standard_True;
3838}
3839
3840//=======================================================================
3841//function : DegeneratedSection
3842//purpose : internal use
3843// create a new degenerated edge if the section is degenerated
3844//=======================================================================
3845
3846static TopoDS_Edge DegeneratedSection(const TopoDS_Shape& section, const TopoDS_Shape& face)
3847{
3848 // Return if section is already degenerated
3849 if (BRep_Tool::Degenerated(TopoDS::Edge(section))) return TopoDS::Edge(section);
3850
3851 // Retrieve edge curve
3852 TopLoc_Location loc;
3853 Standard_Real first, last;
3854 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(section), loc, first, last);
3855 if (c3d.IsNull()) { //gka
3856 BRep_Builder aB;
3857 TopoDS_Edge edge1 = TopoDS::Edge(section);
3858 aB.Degenerated(edge1, Standard_True);
3859 return edge1;
3860 }
3861 if (!loc.IsIdentity()) {
3862 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
3863 c3d->Transform(loc.Transformation());
3864 }
3865
3866 // Test if the new edge is degenerated
3867 TopoDS_Vertex v1,v2;
3868 TopExp::Vertices(TopoDS::Edge(section),v1,v2);
3869 //Standard_Real tol = Max(BRep_Tool::Tolerance(v1),BRep_Tool::Tolerance(v2));
3870 //tol = Max(tolerance,tol);
3871
3872 gp_Pnt p1, p2, p3;
3873 p1 = BRep_Tool::Pnt(v1);
3874 p3 = BRep_Tool::Pnt(v2);
3875 c3d->D0(0.5*(first + last),p2);
3876
3877 //Standard_Boolean isDegenerated = Standard_False;
3878 //if (p1.Distance(p3) < tol) {
3879 //GeomAdaptor_Curve cAdapt(c3d);
3880 //Standard_Real length = GCPnts_AbscissaPoint::Length(cAdapt, first, last);
3881 //isDegenerated = Standard_True; //(length < tol);
3882 //}
3883
3884 TopoDS_Edge edge;
3885 //if (!isDegenerated) return edge;
3886
3887 // processing
3888 BRep_Builder aBuilder;
3889 edge = TopoDS::Edge(section);
3890 edge.EmptyCopy();
3891 if (v1.IsSame(v2)) {
3892 TopoDS_Shape anEdge = edge.Oriented(TopAbs_FORWARD);
3893 aBuilder.Add(anEdge, v1.Oriented(TopAbs_FORWARD));
3894 aBuilder.Add(anEdge, v2.Oriented(TopAbs_REVERSED));
3895 }
3896 else {
3897 TopoDS_Vertex newVertex;
3898 if (p1.Distance(p3) < BRep_Tool::Tolerance(v1))
3899 newVertex = v1;
3900 else if (p1.Distance(p3) < BRep_Tool::Tolerance(v2))
3901 newVertex = v2;
3902 else {
3903 Standard_Real d1 = BRep_Tool::Tolerance(v1) + p2.Distance(p1);
3904 Standard_Real d2 = BRep_Tool::Tolerance(v2) + p2.Distance(p3);
3905 Standard_Real newTolerance = Max(d1,d2);
3906 aBuilder.MakeVertex(newVertex, p2, newTolerance);
3907 }
3908 TopoDS_Shape anEdge = edge.Oriented(TopAbs_FORWARD);
3909 aBuilder.Add(anEdge, newVertex.Oriented(TopAbs_FORWARD));
3910 aBuilder.Add(anEdge, newVertex.Oriented(TopAbs_REVERSED));
3911 }
3912
3913 BRep_Tool::Range(TopoDS::Edge(section), first, last);
3914 TopoDS_Shape anEdge = edge.Oriented(TopAbs_FORWARD);
3915 aBuilder.Range(TopoDS::Edge(anEdge), first, last);
3916 aBuilder.Degenerated(edge, Standard_True);
3917 Handle(Geom_Curve) aC3dNew;
3918 if (!face.IsNull()) {
3919 Standard_Real af,al;
3920 Handle(Geom2d_Curve) aC2dt = BRep_Tool::CurveOnSurface(TopoDS::Edge(section),TopoDS::Face(face),af,al);
3921 aBuilder.UpdateEdge(edge,aC3dNew,0);
3922 Handle(Geom2d_Curve) aC2dn = BRep_Tool::CurveOnSurface(edge,TopoDS::Face(face),af,al);
3923 if (aC2dn.IsNull())
3924 aBuilder.UpdateEdge(edge,aC2dt,TopoDS::Face(face),0);
3925 }
3926
3927 return edge;
3928}
3929
3930//=======================================================================
3931//function : EdgeProcessing
3932//purpose : modifies :
3933// myNbEdges
3934// myHasMultipleEdge
3935// myHasFreeBound
3936// . if multiple edge
3937// - length < 100.*myTolerance -> several free edge
3938// . if no multiple edge
3939// - make the contigous edges sameparameter
3940//=======================================================================
3941
92434a36 3942void BRepBuilderAPI_Sewing::EdgeProcessing(const Handle(Message_ProgressIndicator)& thePI)
7fd59977 3943{
3944 // constructs sectionEdge
3945 TopTools_MapOfShape MapFreeEdges;
3946 TopTools_DataMapOfShapeShape EdgeFace;
92434a36
A
3947 Message_ProgressSentry aPS (thePI, "Edge processing", 0, myBoundFaces.Extent(), 1);
3948 for (Standard_Integer i = 1; i <= myBoundFaces.Extent() && aPS.More(); i++, aPS.Next()) {
7fd59977 3949 const TopoDS_Shape& bound = myBoundFaces.FindKey(i);
3950 const TopTools_ListOfShape& listFaces = myBoundFaces(i);
3951 if (listFaces.Extent() == 1) {
3952 if (myBoundSections.IsBound(bound)) {
3953 TopTools_ListIteratorOfListOfShape liter(myBoundSections(bound));
3954 for (; liter.More(); liter.Next()) {
3955 if (!myMergedEdges.Contains(liter.Value())) { //myReShape->IsRecorded(liter.Value())) {
3956 TopoDS_Shape edge = myReShape->Apply(liter.Value());
3957 if (!MapFreeEdges.Contains(edge)) {
3958 TopoDS_Shape face = listFaces.First();
3959 EdgeFace.Bind(edge,face);
3960 MapFreeEdges.Add(edge);
3961 }
3962 }
3963 }
3964 }
3965 else {
3966 if (!myMergedEdges.Contains(bound)) {
3967 TopoDS_Shape edge = myReShape->Apply(bound);
3968 if (!MapFreeEdges.Contains(edge)) {
3969 TopoDS_Shape face = listFaces.First();
3970 EdgeFace.Bind(edge,face);
3971 MapFreeEdges.Add(edge);
3972 }
3973 }
3974 }
3975 }
3976 }
3977
3978 if (!MapFreeEdges.IsEmpty()) {
3979 TopTools_SequenceOfShape seqWires;
3980 GetFreeWires(MapFreeEdges,seqWires);
3981 for (Standard_Integer j = 1; j <= seqWires.Length(); j++) {
3982 TopoDS_Wire wire = TopoDS::Wire(seqWires.Value(j));
3983 if (!IsDegeneratedWire(wire)) continue;
3984 for (TopoDS_Iterator Ie(wire,Standard_False); Ie.More(); Ie.Next()) {
3985 TopoDS_Shape aTmpShape = myReShape->Apply(Ie.Value()); //for porting
3986 TopoDS_Edge edge = TopoDS::Edge(aTmpShape);
3987 TopoDS_Shape face;
3988 if (EdgeFace.IsBound(edge))
3989 face = EdgeFace.Find(edge);
3990 TopoDS_Shape degedge = DegeneratedSection(edge,face);
3991 if (degedge.IsNull()) continue;
3992 if (!degedge.IsSame(edge))
3993 ReplaceEdge(edge,degedge,myReShape);
3994 if (BRep_Tool::Degenerated(TopoDS::Edge(degedge)))
3995 myDegenerated.Add(degedge);
3996 }
3997 }
3998 }
3999 myMergedEdges.Clear();
4000}
4001
4002//=======================================================================
4003//function : CreateSewedShape
4004//purpose :
4005//=======================================================================
4006
4007void BRepBuilderAPI_Sewing::CreateSewedShape()
4008{
4009 // ---------------------
4010 // create the new shapes
4011 // ---------------------
4012 BRepTools_Quilt aQuilt;
4013 Standard_Boolean isLocal = !myShape.IsNull();
4014 if (isLocal) {
4015 // Local sewing
4016 TopoDS_Shape ns = myReShape->Apply(myShape);
4017 aQuilt.Add(ns);
4018 }
4019 Standard_Integer i;
4020 for (i = 1; i <= myOldShapes.Extent(); i++) {
4021 TopoDS_Shape sh = myOldShapes(i);
4022 if (!sh.IsNull()) {
4023 sh = myReShape->Apply(sh);
4024 myOldShapes(i) = sh;
4025 if (!isLocal) aQuilt.Add(sh);
4026 }
4027 }
4028 TopoDS_Shape aNewShape = aQuilt.Shells();
4029 Standard_Integer numsh = 0;
4030
4031 TopTools_IndexedMapOfShape OldShells;
4032
4033 BRep_Builder aB;
4034 TopoDS_Compound aComp;
4035 aB.MakeCompound(aComp);
4036 for (TopoDS_Iterator aExpSh(aNewShape,Standard_False); aExpSh.More(); aExpSh.Next()) {
4037 TopoDS_Shape sh = aExpSh.Value();
4038 Standard_Boolean hasEdges = Standard_False;
4039 if (sh.ShapeType() == TopAbs_SHELL) {
4040 if (myNonmanifold)
4041 hasEdges = !OldShells.Contains(sh);
4042 else {
4043 TopoDS_Shape face;
4044 Standard_Integer numf = 0;
4045 for (TopExp_Explorer aExpF(sh,TopAbs_FACE); aExpF.More() && (numf < 2); aExpF.Next()) {
4046 face = aExpF.Current();
4047 numf++;
4048 }
4049 if (numf == 1) aB.Add(aComp,face);
4050 else if (numf > 1) aB.Add(aComp,sh);
4051 if (numf) numsh++;
4052 }
4053 }
4054 else if (sh.ShapeType() == TopAbs_FACE) {
4055 if (myNonmanifold) {
4056 TopoDS_Shell ss;
4057 aB.MakeShell(ss);
4058 aB.Add(ss,sh);
4059 sh = ss;
4060 hasEdges = Standard_True;
4061 }
4062 else { aB.Add(aComp,sh); numsh++; }
4063 }
4064 else { aB.Add(aComp,sh); numsh++; }
4065 if (hasEdges) OldShells.Add(sh);
4066 }
4067 // Process collected shells
4068 if (myNonmanifold) {
4069 Standard_Integer nbOldShells = OldShells.Extent();
4070 if (nbOldShells == 1) {
4071 // Single shell - check for single face
4072 TopoDS_Shape sh = OldShells.FindKey(1);
4073 TopoDS_Shape face;
4074 Standard_Integer numf = 0;
4075 for (TopExp_Explorer aExpF(sh,TopAbs_FACE); aExpF.More() && (numf < 2); aExpF.Next()) {
4076 face = aExpF.Current();
4077 numf++;
4078 }
4079 if (numf == 1) aB.Add(aComp,face);
4080 else if (numf > 1) aB.Add(aComp,sh);
4081 if (numf) numsh++;
4082 }
4083 else if (nbOldShells) {
4084 // Several shells should be merged
4085 TColStd_MapOfInteger IndexMerged;
4086 while (IndexMerged.Extent() < nbOldShells) {
4087 TopoDS_Shell NewShell;
4088 TopTools_MapOfShape NewEdges;
4089 for (i = 1; i <= nbOldShells; i++) {
4090 if (IndexMerged.Contains(i)) continue;
4091 TopoDS_Shell shell = TopoDS::Shell(OldShells.FindKey(i));
4092 if (NewShell.IsNull()) {
4093 BRep_Builder aB;
4094 aB.MakeShell(NewShell);
4095 TopoDS_Iterator aItSS(shell) ;
4096 for( ; aItSS.More(); aItSS.Next())
4097 aB.Add(NewShell,aItSS.Value())
4098 ;
4099 // Fill map of edges
4100 for (TopExp_Explorer eexp(shell,TopAbs_EDGE); eexp.More(); eexp.Next()) {
4101 TopoDS_Shape edge = eexp.Current();
4102 NewEdges.Add(edge);
4103 }
4104 IndexMerged.Add(i);
4105 }
4106 else {
4107 Standard_Boolean hasSharedEdge = Standard_False;
4108 TopExp_Explorer eexp(shell,TopAbs_EDGE);
4109 for (; eexp.More() && !hasSharedEdge; eexp.Next())
4110 hasSharedEdge = NewEdges.Contains(eexp.Current());
4111 if (hasSharedEdge) {
4112 // Add edges to the map
4113 for (TopExp_Explorer eexp1(shell,TopAbs_EDGE); eexp1.More(); eexp1.Next()) {
4114 TopoDS_Shape edge = eexp1.Current();
4115 NewEdges.Add(edge);
4116 }
4117 // Add faces to the shell
4118 for (TopExp_Explorer fexp(shell,TopAbs_FACE); fexp.More(); fexp.Next()) {
4119 TopoDS_Shape face = fexp.Current();
4120 aB.Add(NewShell,face);
4121 }
4122 IndexMerged.Add(i);
4123 }
4124 }
4125 }
4126 // Process new shell
4127 TopoDS_Shape face;
4128 Standard_Integer numf = 0;
4129 TopExp_Explorer aExpF(NewShell,TopAbs_FACE);
4130 for (; aExpF.More() && (numf < 2); aExpF.Next()) {
4131 face = aExpF.Current();
4132 numf++;
4133 }
4134 if (numf == 1) aB.Add(aComp,face);
4135 else if (numf > 1) aB.Add(aComp,NewShell);
4136 if (numf) numsh++;
4137 }
4138 }
4139 }
4140 if (numsh == 1) {
4141 // Extract single component
4142 TopoDS_Iterator aIt(aComp,Standard_False);
4143 mySewedShape = aIt.Value();
4144 }
4145 else
4146 mySewedShape = aComp;
4147}
4148
4149//=======================================================================
4150//function : CreateOutputInformations
4151//purpose : constructs :
4152// myEdgeSections
4153// mySectionBound
4154// myNbFreeEdges
4155// myNbContigousEdges
4156// myNbMultipleEdges
4157// myNbDegenerated
4158//=======================================================================
4159
4160void BRepBuilderAPI_Sewing::CreateOutputInformations()
4161{
4162 // Construct edgeSections
4163 Standard_Integer i;
4164 //TopTools_DataMapOfShapeListOfShape edgeSections;
4165 TopTools_IndexedDataMapOfShapeListOfShape edgeSections; //use index map for regulating free edges
4166 for (i = 1; i <= myBoundFaces.Extent(); i++) {
4167 const TopoDS_Shape& bound = myBoundFaces.FindKey(i);
4168 TopTools_ListOfShape lsect;
4169 if (myBoundSections.IsBound(bound)) lsect = myBoundSections(bound);
4170 TopExp_Explorer aExp(myReShape->Apply(bound),TopAbs_EDGE);
4171 for (; aExp.More(); aExp.Next()) {
4172 TopoDS_Shape sec = bound, edge = aExp.Current();
4173 TopTools_ListIteratorOfListOfShape aI(lsect);
4174 for (; aI.More(); aI.Next()) {
4175 const TopoDS_Shape& section = aI.Value();
4176 if (edge.IsSame(myReShape->Apply(section))) { sec = section; break; }
4177 }
4178 if (edgeSections.Contains(edge))
4179 edgeSections.ChangeFromKey(edge).Append(sec);
4180 else {
4181 TopTools_ListOfShape listSec;
4182 listSec.Append(sec);
4183 edgeSections.Add(edge,listSec);
4184 }
4185 }
4186 }
4187
4188 // Fill maps of Free, Contigous and Multiple edges
4189 //TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter2(edgeSections);
4190 for (i = 1; i <= edgeSections.Extent(); i++) {
4191 const TopoDS_Shape& edge = edgeSections.FindKey(i);
4192 const TopTools_ListOfShape& listSection = edgeSections(i);
4193 if (listSection.Extent() == 1) {
4194 if (BRep_Tool::Degenerated(TopoDS::Edge(edge)))
4195 myDegenerated.Add(edge);
4196 else
4197 myFreeEdges.Add(edge);
4198 }
4199 else if (listSection.Extent() == 2) {
4200 myContigousEdges.Add(edge,listSection);
4201 }
4202 else {
4203 myMultipleEdges.Add(edge);
4204 }
4205 }
4206
4207 // constructs myContigSectBound
4208 TopTools_DataMapOfShapeListOfShape aEdgeMap; //gka
4209 for (i = 1; i <= myBoundFaces.Extent(); i++) {
4210 TopoDS_Shape bound = myBoundFaces.FindKey(i);
4211 if (myBoundSections.IsBound(bound)) {
4212 TopTools_ListIteratorOfListOfShape iter(myBoundSections(bound));
4213 for (; iter.More(); iter.Next()) {
4214 TopoDS_Shape section = iter.Value();
4215 if(!myMergedEdges.Contains(section)) continue;
4216 //if (!myReShape->IsRecorded(section)) continue; // section is free
4217 TopoDS_Shape nedge = myReShape->Apply(section);
4218 if (nedge.IsNull()) continue; //szv debug
4219 if (!bound.IsSame(section))
4220 if (myContigousEdges.Contains(nedge))
4221 myContigSecBound.Bind(section, bound);
4222 }
4223 }
4224 }
4225}
4226
4227//=======================================================================
4228//function : ProjectPointsOnCurve
4229//purpose : internal use
4230//=======================================================================
4231
4232void BRepBuilderAPI_Sewing::ProjectPointsOnCurve(const TColgp_Array1OfPnt& arrPnt,
4233 const Handle(Geom_Curve)& c3d,
4234 const Standard_Real first,
4235 const Standard_Real last,
4236 TColStd_Array1OfReal& arrDist,
4237 TColStd_Array1OfReal& arrPara,
2028d00c
G
4238 TColgp_Array1OfPnt& arrProj,
4239 const Standard_Boolean isConsiderEnds) const
7fd59977 4240{
4241 arrDist.Init(-1.0);
4242
4243 GeomAdaptor_Curve GAC(c3d);
4244 Extrema_ExtPC locProj;
4245 locProj.Initialize(GAC, first, last);
4246 gp_Pnt pfirst = GAC.Value(first), plast = GAC.Value(last);
47980104 4247 Standard_Integer find = 1;//(isConsiderEnds ? 1 : 2);
4248 Standard_Integer lind = arrPnt.Length();//(isConsiderEnds ? arrPnt.Length() : arrPnt.Length() -1);
4249
4250 for (Standard_Integer i1 = find; i1 <= lind ; i1++) {
7fd59977 4251 gp_Pnt pt = arrPnt(i1);
4252 Standard_Real worktol = myTolerance;
4253 Standard_Real distF2 = pfirst.SquareDistance(pt);
4254 Standard_Real distL2 = plast.SquareDistance(pt);
4255 Standard_Boolean isProjected = Standard_False;
4256 try {
4257
4258 // Project current point on curve
4259 locProj.Perform(pt);
4260 if (locProj.IsDone() && locProj.NbExt() > 0) {
47980104 4261 Standard_Real dist2Min = (isConsiderEnds || i1 == find || i1 == lind ? Min(distF2,distL2) : Precision::Infinite());
7fd59977 4262 Standard_Integer ind, indMin = 0;
4263 for (ind = 1; ind <= locProj.NbExt(); ind++) {
4264 Standard_Real dProj2 = locProj.SquareDistance(ind);
4265 if (dProj2 < dist2Min) { indMin = ind; dist2Min = dProj2; }
4266 }
4267 if (indMin) {
4268 isProjected = Standard_True;
4269 Extrema_POnCurv pOnC = locProj.Point(indMin);
4270 Standard_Real paramProj = pOnC.Parameter();
4271 gp_Pnt ptProj = GAC.Value(paramProj);
4272 Standard_Real distProj2 = ptProj.SquareDistance(pt);
4273 if (!locProj.IsMin(indMin)) {
4274 if (Min(distF2,distL2) < dist2Min) {
4275 if (distF2 < distL2) {
4276 paramProj = first;
4277 distProj2 = distF2;
4278 ptProj = pfirst;
4279 }
4280 else {
4281 paramProj = last;
4282 distProj2 = distL2;
4283 ptProj = plast;
4284 }
4285 }
4286 }
2c896b8f 4287 if (distProj2 < worktol * worktol || !isConsiderEnds) {
7fd59977 4288 arrDist(i1) = sqrt (distProj2);
4289 arrPara(i1) = paramProj;
4290 arrProj(i1) = ptProj;
4291 }
4292 }
4293 }
4294 }
4295 catch (Standard_Failure) {
4296 worktol = MinTolerance();
4297#ifdef DEB
4298 cout << "Exception in BRepBuilderAPI_Sewing::ProjectPointsOnCurve: ";
4299 Standard_Failure::Caught()->Print(cout); cout << endl;
4300#endif
4301 }
2028d00c 4302 if (!isProjected && isConsiderEnds) {
7fd59977 4303 if (Min(distF2,distL2) < worktol * worktol) {
4304 if (distF2 < distL2) {
4305 arrDist(i1) = sqrt (distF2);
4306 arrPara(i1) = first;
4307 arrProj(i1) = pfirst;
4308 }
4309 else {
4310 arrDist(i1) = sqrt (distL2);
4311 arrPara(i1) = last;
4312 arrProj(i1) = plast;
4313 }
4314 }
4315 }
4316 }
4317}
4318
4319//=======================================================================
4320//function : CreateCuttingNodes
4321//purpose : internal use
4322//=======================================================================
4323
4324void BRepBuilderAPI_Sewing::CreateCuttingNodes(const TopTools_IndexedMapOfShape& MapVert,
4325 const TopoDS_Shape& bound,
4326 const TopoDS_Shape& vfirst,
4327 const TopoDS_Shape& vlast,
4328 const TColStd_Array1OfReal& arrDist,
4329 const TColStd_Array1OfReal& arrPara,
4330 const TColgp_Array1OfPnt& arrPnt,
4331 TopTools_SequenceOfShape& seqVert,
4332 TColStd_SequenceOfReal& seqPara)
4333{
4334 Standard_Integer i, j, nbProj = MapVert.Extent();
4335
4336 // Reorder projections by distance
4337 TColStd_SequenceOfInteger seqOrderedIndex;
4338 { //szv: Use brackets to destroy local variables
4339 TColStd_SequenceOfReal seqOrderedDistance;
4340 for (i = 1; i <= nbProj; i++) {
4341 Standard_Real distProj = arrDist(i);
4342 if (distProj < 0.0) continue; // Skip vertex if not projected
4343 Standard_Boolean isInserted = Standard_False;
4344 for (j = 1; j <= seqOrderedIndex.Length() && !isInserted; j++) {
4345 isInserted = (distProj < seqOrderedDistance(j));
4346 if (isInserted) {
4347 seqOrderedIndex.InsertBefore(j,i);
4348 seqOrderedDistance.InsertBefore(j,distProj);
4349 }
4350 }
4351 if (!isInserted) {
4352 seqOrderedIndex.Append(i);
4353 seqOrderedDistance.Append(distProj);
4354 }
4355 }
4356 }
4357 nbProj = seqOrderedIndex.Length();
4358 if (!nbProj) return;
4359
4360 BRep_Builder aBuilder;
4361
4362 // Insert two initial vertices (to be removed later)
4363 TColStd_SequenceOfReal seqDist;
4364 TColgp_SequenceOfPnt seqPnt;
4365 { //szv: Use brackets to destroy local variables
4366 // Retrieve bound curve
4367 TopLoc_Location loc;
4368 Standard_Real first,last;
4369 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(bound), loc, first, last);
4370 if (!loc.IsIdentity()) {
4371 c3d = Handle(Geom_Curve)::DownCast(c3d->Copy());
4372 c3d->Transform(loc.Transformation());
4373 }
4374 GeomAdaptor_Curve GAC(c3d);
4375 seqVert.Prepend(vfirst); seqVert.Append(vlast);
4376 seqPara.Prepend(first); seqPara.Append(last);
4377 seqDist.Prepend(-1.0); seqDist.Append(-1.0);
4378 seqPnt.Prepend(GAC.Value(first)); seqPnt.Append(GAC.Value(last));
4379 }
4380
4381 TopTools_DataMapOfShapeShape NodeCuttingVertex;
4382 for (i = 1; i <= nbProj; i++) {
4383
4384 const Standard_Integer index = seqOrderedIndex(i);
4385 Standard_Real disProj = arrDist(index);
4386 gp_Pnt pntProj = arrPnt(index);
4387
4388 // Skip node if already bound to cutting vertex
4389 TopoDS_Shape node = myVertexNode.FindFromKey(MapVert(index));
4390 if (NodeCuttingVertex.IsBound(node)) continue;
4391
4392 // Find the closest vertex
4393 Standard_Integer indexMin = 1;
4394 Standard_Real dist, distMin = pntProj.Distance(seqPnt(1));
4395 for (j = 2; j <= seqPnt.Length(); j++) {
4396 dist = pntProj.Distance(seqPnt(j));
4397 if (dist < distMin) { distMin = dist; indexMin = j; }
4398 }
4399
4400 // Check if current point is close to one of the existent
4401 if (distMin <= Max(disProj*0.1,MinTolerance())) {
4402 // Check distance if close
4403 Standard_Real jdist = seqDist.Value(indexMin);
4404 if (jdist < 0.0) {
4405 // Bind new cutting node (end vertex only)
4406 seqDist.SetValue(indexMin,disProj);
4407 TopoDS_Shape cvertex = seqVert.Value(indexMin);
4408 NodeCuttingVertex.Bind(node,cvertex);
4409 }
4410 else {
4411 // Bind secondary cutting nodes
4412 NodeCuttingVertex.Bind(node,TopoDS_Vertex());
4413 }
4414 }
4415 else {
4416 // Build new cutting vertex
4417 TopoDS_Vertex cvertex;
4418 aBuilder.MakeVertex(cvertex, pntProj, Precision::Confusion());
4419 // Bind new cutting vertex
4420 NodeCuttingVertex.Bind(node,cvertex);
4421 // Insert cutting vertex in the sequences
4422 Standard_Real parProj = arrPara(index);
4423 for (j = 2; j <= seqPara.Length(); j++) {
4424 if (parProj <= seqPara.Value(j)) {
4425 seqVert.InsertBefore(j,cvertex);
4426 seqPara.InsertBefore(j,parProj);
4427 seqDist.InsertBefore(j,disProj);
4428 seqPnt.InsertBefore (j,pntProj);
4429 break;
4430 }
4431 }
4432 }
4433 }
4434
4435 // filling map for cutting nodes
4436 TopTools_DataMapIteratorOfDataMapOfShapeShape mit(NodeCuttingVertex);
4437 for (; mit.More(); mit.Next()) {
4438 TopoDS_Shape cnode = mit.Value();
4439 // Skip secondary nodes
4440 if (cnode.IsNull()) continue;
4441 // Obtain vertex node
4442 TopoDS_Shape node = mit.Key();
4443 if (myVertexNode.Contains(cnode)) {
4444 // This is an end vertex
4445 cnode = myVertexNode.FindFromKey(cnode);
4446 }
4447 else {
4448 // Create link: cutting vertex -> node
4449 TopTools_ListOfShape ls;
4450 ls.Append(node);
4451 myCuttingNode.Bind(cnode,ls);
4452 }
4453 // Create link: node -> cutting vertex
4454 if (myCuttingNode.IsBound(node)) {
4455 myCuttingNode.ChangeFind(node).Append(cnode);
4456 }
4457 else {
4458 TopTools_ListOfShape ls;
4459 ls.Append(cnode);
4460 myCuttingNode.Bind(node,ls);
4461 }
4462 }
4463
4464 // Remove two initial vertices
4465 seqVert.Remove(1); seqVert.Remove(seqVert.Length());
4466 seqPara.Remove(1); seqPara.Remove(seqPara.Length());
4467}
4468
4469//=======================================================================
4470//function : CreateSections
4471//purpose : internal use
4472//=======================================================================
4473
4474void BRepBuilderAPI_Sewing::CreateSections(const TopoDS_Shape& section,
4475 const TopTools_SequenceOfShape& seqNode,
4476 const TColStd_SequenceOfReal& seqPara,
4477 TopTools_ListOfShape& listEdge)
4478{
4479 const TopoDS_Edge& sec = TopoDS::Edge(section);
4480 // TopAbs_Orientation aInitOr = sec.Orientation();
4481
4482
4483 //To keep NM vertices on edge
4484 TopTools_SequenceOfShape aSeqNMVert;
4485 TColStd_SequenceOfReal aSeqNMPars;
4486 findNMVertices(sec,aSeqNMVert,aSeqNMPars);
4487
4488 BRep_Builder aBuilder;
4489
4490 Standard_Real first, last;
4491 BRep_Tool::Range(sec, first, last);
4492
4493 // Create cutting sections
4494 Standard_Real par1, par2;
4495 TopoDS_Shape V1, V2;
4496 Standard_Integer i, len = seqPara.Length() + 1;
4497 for (i = 1; i <= len; i++) {
4498
4499 TopoDS_Edge edge = sec;
4500 edge.EmptyCopy();
4501
4502 if (i == 1) {
4503 par1 = first;
4504 par2 = seqPara(i);
4505 V1 = TopExp::FirstVertex(sec);
4506 V2 = seqNode(i);
4507 }
4508 else if (i == len) {
4509 par1 = seqPara(i-1);
4510 par2 = last;
4511 V1 = seqNode(i-1);
4512 V2 = TopExp::LastVertex(sec);
4513 }
4514 else {
4515 par1 = seqPara(i-1);
4516 par2 = seqPara(i);
4517 V1 = seqNode(i-1);
4518 V2 = seqNode(i);
4519 }
4520
4521 TopoDS_Shape aTmpShape = edge.Oriented(TopAbs_FORWARD);
4522 TopoDS_Edge aTmpEdge = TopoDS::Edge (aTmpShape); // for porting
4523 aTmpShape = V1.Oriented(TopAbs_FORWARD);
4524 aBuilder.Add(aTmpEdge, aTmpShape);
4525 aTmpShape = V2.Oriented(TopAbs_REVERSED);
4526 aBuilder.Add(aTmpEdge, aTmpShape);
4527 aBuilder.Range(aTmpEdge, par1, par2);
4528 // if(aInitOr == TopAbs_REVERSED)
4529 // listEdge.Prepend(edge);
4530 // else
4531
4532 Standard_Integer k =1;
4533 for( ; k <= aSeqNMPars.Length() ; k++) {
4534 Standard_Real apar = aSeqNMPars.Value(k);
4535 if(apar >= par1 && apar <= par2) {
4536 aBuilder.Add(aTmpEdge,aSeqNMVert.Value(k));
4537 aSeqNMVert.Remove(k);
4538 aSeqNMPars.Remove(k);
4539 k--;
4540 }
4541 }
4542 listEdge.Append(edge);
4543 }
4544
4545 const TopTools_ListOfShape& listFaces = myBoundFaces.FindFromKey(sec);
4546 if (!listFaces.Extent()) return;
4547
4548 Standard_Real tolEdge = BRep_Tool::Tolerance(sec);
4549
4550 // Add cutting pcurves
4551 TopTools_ListIteratorOfListOfShape itf(listFaces);
4552 for (; itf.More(); itf.Next()) {
4553
4554 const TopoDS_Face& fac = TopoDS::Face(itf.Value());
4555
4556 // Retrieve curve on surface
4557 Standard_Real first2d=0., last2d=0.,first2d1=0,last2d1=0.;
4558 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(sec, fac, first2d, last2d);
4559 if (c2d.IsNull()) continue;
4560 Handle(Geom2d_Curve) c2d1;
4561 Standard_Boolean isSeam = BRep_Tool::IsClosed(sec,fac);
4562
4563 //gka - Convert to BSpline was commented because
4564 //it is not necessary to create BSpline instead of Lines or cIrcles.
4565 //Besides after conversion circles to BSpline
4566 //it is necessary to recompute parameters of cutting because paramerization of created
4567 //BSpline curve differs from parametrization of circle.
4568
4569 // Convert pcurve to BSpline
4570 /*Handle(Geom2d_BSplineCurve) c2dBSP,c2dBSP1;
4571 if (c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
4572 c2dBSP = Handle(Geom2d_BSplineCurve)::DownCast(c2d);
4573 }
4574 else {
4575 if (first > (c2d->FirstParameter() + Precision::PConfusion()) ||
4576 last < (c2d->LastParameter() - Precision::PConfusion())) {
4577 Handle(Geom2d_TrimmedCurve) TC = new Geom2d_TrimmedCurve(c2d, first, last);
4578 c2dBSP = Geom2dConvert::CurveToBSplineCurve(TC);
4579 }
4580 else c2dBSP = Geom2dConvert::CurveToBSplineCurve(c2d);
4581 }
4582 if (c2dBSP.IsNull()) continue;*/
4583 //gka fix for bug OCC12203 21.04.06 addition second curve for seam edges
4584
4585 if(isSeam)
4586 {
4587 TopoDS_Edge secRev = TopoDS::Edge(sec.Reversed());
4588
4589 c2d1 = BRep_Tool::CurveOnSurface(secRev, fac, first2d1, last2d1);
4590 if (c2d1.IsNull()) continue;
4591
4592 /*if (c2d1->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
4593 c2dBSP1 = Handle(Geom2d_BSplineCurve)::DownCast(c2d1);
4594 }
4595 else {
4596 if (first > (c2d1->FirstParameter() + Precision::PConfusion()) ||
4597 last < (c2d1->LastParameter() - Precision::PConfusion())) {
4598 Handle(Geom2d_TrimmedCurve) TC = new Geom2d_TrimmedCurve(c2d1, first, last);
4599 //c2dBSP1 = Geom2dConvert::CurveToBSplineCurve(TC);
4600 }
4601 //else c2dBSP1 = Geom2dConvert::CurveToBSplineCurve(c2d);
4602
4603 }*/
4604 }
4605
4606 /*first2d = c2dBSP->FirstParameter();
4607 last2d = c2dBSP->LastParameter();
4608
4609 if(!c2dBSP1.IsNull()) {
4610 first2d1 = c2dBSP1->FirstParameter();
4611 last2d1 = c2dBSP1->LastParameter();
4612 }*/
4613
4614 // Update cutting sections
4615 Handle(Geom2d_Curve) c2dNew,c2d1New;
4616 TopTools_ListIteratorOfListOfShape ite(listEdge);
4617 for (; ite.More(); ite.Next()) {
4618
4619 // Retrieve cutting section
4620 const TopoDS_Edge& edge = TopoDS::Edge(ite.Value());
4621 BRep_Tool::Range(edge, par1, par2);
4622
4623 // Cut BSpline pcurve
4624 // try {
4625 c2dNew = Handle(Geom2d_Curve)::DownCast(c2d->Copy());
4626 //c2dNew = Handle(Geom2d_Curve)::DownCast(c2dBSP->Copy());
4627 //Handle(Geom2d_BSplineCurve)::DownCast(c2dNew)->Segment(Max(first2d,par1),Min(par2,last2d));
4628 if(!c2d1.IsNull()) { //if(!c2dBSP1.IsNull()) {
4629 c2d1New = Handle(Geom2d_Curve)::DownCast(c2d1->Copy());
4630 //c2d1New = Handle(Geom2d_Curve)::DownCast(c2dBSP1->Copy());
4631 //Handle(Geom2d_BSplineCurve)::DownCast(c2d1New)->Segment(Max(first2d1,par1),Min(par2,last2d1));
4632 }
4633 //}
4634 /*catch (Standard_Failure) {
4635 #ifdef DEB
4636 cout << "Exception in CreateSections: segment [" << par1 << "," << par2 << "]: ";
4637 Standard_Failure::Caught()->Print(cout); cout << endl;
4638 #endif
4639 Handle(Geom2d_TrimmedCurve) c2dT = new Geom2d_TrimmedCurve(c2dNew,Max(first2d,par1),Min(par2,last2d));
4640 c2dNew = c2dT;
4641 }*/
4642
4643
4644 if(!isSeam && c2d1New.IsNull())
4645 aBuilder.UpdateEdge(edge, c2dNew, fac, tolEdge);
4646 else {
4647 TopAbs_Orientation Ori = edge.Orientation();
4648 if(fac.Orientation() == TopAbs_REVERSED)
4649 Ori = TopAbs::Reverse(Ori);
4650
4651 if(Ori == TopAbs_FORWARD)
4652 aBuilder.UpdateEdge(edge, c2dNew,c2d1New ,fac, tolEdge);
4653 else
4654 aBuilder.UpdateEdge(edge, c2d1New,c2dNew ,fac, tolEdge);
4655 }
4656 }
4657 }
4658}
4659
4660//=======================================================================
4661//function : SameParameterShape
4662//purpose :
4663//=======================================================================
4664
4665void BRepBuilderAPI_Sewing::SameParameterShape()
4666{
4667 if (!mySameParameterMode) return;
4668 TopExp_Explorer exp(mySewedShape, TopAbs_EDGE);
4669 // Le flag sameparameter est a false pour chaque edge cousue
4670 for (; exp.More(); exp.Next()) {
4671 const TopoDS_Edge& sec = TopoDS::Edge(exp.Current());
4672 try {
4673
4674 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
4675 }
4676 catch (Standard_Failure) {
4677#ifdef DEB
4678 cout << "Fail: BRepBuilderAPI_Sewing::SameParameterShape exception in BRepLib::SameParameter" << endl;
4679#endif
4680 continue;
4681 }
4682 }
4683}
82192477 4684
4685//=======================================================================
4686//function : Inspect
4687//purpose : Used for selection and storage of coinciding points
4688//=======================================================================
4689
4690NCollection_CellFilter_Action BRepBuilderAPI_VertexInspector::Inspect (const Standard_Integer theTarget)
4691{
4692 /*gp_Pnt aPnt = gp_Pnt (myPoints.Value (theTarget - 1));
4693 if (aPnt.SquareDistance (gp_Pnt (myCurrent)) <= myTol)
4694 myResInd.Append (theTarget);*/
4695
4696 const gp_XYZ& aPnt = myPoints.Value (theTarget - 1);
4697 Standard_Real aDx, aDy, aDz;
4698 aDx = myCurrent.X() - aPnt.X();
4699 aDy = myCurrent.Y() - aPnt.Y();
4700 aDz = myCurrent.Z() - aPnt.Z();
4701
4702 if ((aDx*aDx <= myTol) && (aDy*aDy <= myTol) && (aDz*aDz <= myTol))
4703 myResInd.Append (theTarget);
4704 return CellFilter_Keep;
4705}
0794c042 4706
4707//=======================================================================
4708//function : Context
4709//purpose :
4710//=======================================================================
4711const Handle(BRepTools_ReShape)& BRepBuilderAPI_Sewing::GetContext() const
4712{
4713 return myReShape;
4714}
4715
4716//=======================================================================
4717//function : SetContext
4718//purpose :
4719//=======================================================================
4720void BRepBuilderAPI_Sewing::SetContext(const Handle(BRepTools_ReShape)& theContext)
4721{
4722 myReShape = theContext;
4723}
4724