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