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