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