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