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