0028710: Implement 'BRepTools_History' history for algorithm 'ShapeUpgrade_UnifySameD...
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_UnifySameDomain.cxx
CommitLineData
973c2be1 1// Created on: 2012-06-09
2// Created by: jgv@ROLEX
3// Copyright (c) 2012-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
2277323d 15
42cf5bc1 16
2277323d 17#include <BRep_Builder.hxx>
42cf5bc1 18#include <BRep_CurveRepresentation.hxx>
2277323d 19#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
20#include <BRep_TEdge.hxx>
42cf5bc1 21#include <BRep_Tool.hxx>
22#include <BRepLib.hxx>
23#include <BRepLib_MakeEdge.hxx>
24#include <BRepTopAdaptor_TopolTool.hxx>
25#include <GC_MakeCircle.hxx>
26#include <Geom2d_Line.hxx>
2277323d 27#include <Geom2d_TrimmedCurve.hxx>
2277323d 28#include <Geom2dConvert.hxx>
2277323d 29#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
2277323d 30#include <Geom_BezierCurve.hxx>
42cf5bc1 31#include <Geom_BSplineCurve.hxx>
32#include <Geom_Circle.hxx>
33#include <Geom_CylindricalSurface.hxx>
34#include <Geom_ElementarySurface.hxx>
35#include <Geom_Line.hxx>
36#include <Geom_OffsetSurface.hxx>
37#include <Geom_RectangularTrimmedSurface.hxx>
38#include <Geom_Surface.hxx>
39#include <Geom_SurfaceOfLinearExtrusion.hxx>
40#include <Geom_SurfaceOfRevolution.hxx>
41#include <Geom_SweptSurface.hxx>
42#include <Geom_TrimmedCurve.hxx>
43#include <GeomAdaptor_HSurface.hxx>
44#include <GeomConvert.hxx>
45#include <GeomConvert_CompCurveToBSplineCurve.hxx>
46#include <GeomLib_IsPlanarSurface.hxx>
47#include <gp_Cylinder.hxx>
48#include <gp_Dir.hxx>
49#include <gp_Lin.hxx>
50#include <IntPatch_ImpImpIntersection.hxx>
51#include <ShapeAnalysis_Edge.hxx>
2277323d 52#include <ShapeAnalysis_WireOrder.hxx>
53#include <ShapeBuild_Edge.hxx>
42cf5bc1 54#include <ShapeBuild_ReShape.hxx>
2277323d 55#include <ShapeExtend_CompositeSurface.hxx>
56#include <ShapeFix_ComposeShell.hxx>
2277323d 57#include <ShapeFix_Edge.hxx>
42cf5bc1 58#include <ShapeFix_Face.hxx>
59#include <ShapeFix_SequenceOfWireSegment.hxx>
2277323d 60#include <ShapeFix_Shell.hxx>
42cf5bc1 61#include <ShapeFix_Wire.hxx>
62#include <ShapeFix_WireSegment.hxx>
2277323d 63#include <ShapeUpgrade_RemoveLocations.hxx>
42cf5bc1 64#include <ShapeUpgrade_UnifySameDomain.hxx>
65#include <Standard_Type.hxx>
66#include <TColGeom2d_Array1OfBSplineCurve.hxx>
67#include <TColGeom2d_HArray1OfBSplineCurve.hxx>
68#include <TColGeom2d_SequenceOfBoundedCurve.hxx>
69#include <TColGeom_Array1OfBSplineCurve.hxx>
70#include <TColGeom_HArray1OfBSplineCurve.hxx>
71#include <TColGeom_HArray2OfSurface.hxx>
72#include <TColGeom_SequenceOfSurface.hxx>
73#include <TColStd_Array1OfReal.hxx>
74#include <TColStd_MapOfInteger.hxx>
75#include <TopExp.hxx>
76#include <TopExp_Explorer.hxx>
77#include <TopoDS.hxx>
78#include <TopoDS_Edge.hxx>
79#include <TopoDS_Face.hxx>
80#include <TopoDS_Shape.hxx>
81#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
82#include <TopTools_IndexedMapOfShape.hxx>
83#include <TopTools_ListIteratorOfListOfShape.hxx>
b4d4dbe8 84#include <TopTools_MapOfShape.hxx>
42cf5bc1 85#include <TopTools_SequenceOfShape.hxx>
f7d70540 86#include <gp_Circ.hxx>
87#include <BRepAdaptor_Curve.hxx>
6a0c0b14 88#include <BRepClass_FaceClassifier.hxx>
f0144633 89#include <BRepAdaptor_Curve2d.hxx>
90#include <gp_Vec2d.hxx>
f7d70540 91
92efcf78 92IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_UnifySameDomain,MMgt_TShared)
93
f7d70540 94struct SubSequenceOfEdges
95{
96 TopTools_SequenceOfShape SeqsEdges;
97 TopoDS_Edge UnionEdges;
98};
99
f0144633 100static Standard_Boolean IsLikeSeam(const TopoDS_Edge& anEdge,
101 const TopoDS_Face& aFace,
102 const Handle(Geom_Surface)& aBaseSurface)
103{
104 if (!aBaseSurface->IsUPeriodic() && !aBaseSurface->IsVPeriodic())
105 return Standard_False;
106
107 BRepAdaptor_Curve2d BAcurve2d(anEdge, aFace);
108 gp_Pnt2d FirstPoint, LastPoint;
109 gp_Vec2d FirstDir, LastDir;
110 BAcurve2d.D1(BAcurve2d.FirstParameter(), FirstPoint, FirstDir);
111 BAcurve2d.D1(BAcurve2d.LastParameter(), LastPoint, LastDir);
112 Standard_Real Length = FirstDir.Magnitude();
113 if (Length <= gp::Resolution())
114 return Standard_False;
115 else
116 FirstDir /= Length;
117 Length = LastDir.Magnitude();
118 if (Length <= gp::Resolution())
119 return Standard_False;
120 else
121 LastDir /= Length;
122
123 Standard_Real Tol = 1.e-7;
124 if (aBaseSurface->IsUPeriodic() &&
125 (Abs(FirstDir.X()) < Tol) &&
126 (Abs(LastDir.X()) < Tol))
127 return Standard_True;
128
129 if (aBaseSurface->IsVPeriodic() &&
130 (Abs(FirstDir.Y()) < Tol) &&
131 (Abs(LastDir.Y()) < Tol))
132 return Standard_True;
133
134 return Standard_False;
135}
2277323d 136
56091b56 137static Standard_Boolean CheckSharedEdgeOri(const TopoDS_Face& theF1,
138 const TopoDS_Face& theF2,
139 const TopoDS_Edge& theE)
140{
141 TopAbs_Orientation anEOri = theE.Orientation();
142 if (anEOri == TopAbs_EXTERNAL || anEOri == TopAbs_INTERNAL)
143 return Standard_False;
144
145 TopExp_Explorer Exp(theF1, TopAbs_EDGE);
146 for (;Exp.More();Exp.Next())
147 {
148 const TopoDS_Shape& aCE = Exp.Current();
149 if (aCE.IsSame(theE))
150 {
151 anEOri = aCE.Orientation();
152 break;
153 }
154 }
155
156 for (Exp.Init(theF2, TopAbs_EDGE);Exp.More();Exp.Next())
157 {
158 const TopoDS_Shape& aCE = Exp.Current();
159 if (aCE.IsSame(theE))
160 {
161 if (aCE.Orientation() == TopAbs::Reverse(anEOri))
162 return Standard_True;
163 else
164 return Standard_False;
165 }
166 }
167
168 return Standard_False;
169
170}
171
2277323d 172//=======================================================================
173//function : AddOrdinaryEdges
174//purpose : auxilary
175//=======================================================================
176// adds edges from the shape to the sequence
177// seams and equal edges are dropped
178// Returns true if one of original edges dropped
179static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges,
180 const TopoDS_Shape aShape,
181 Standard_Integer& anIndex)
182{
183 //map of edges
184 TopTools_IndexedMapOfShape aNewEdges;
185 //add edges without seams
186 for(TopExp_Explorer exp(aShape,TopAbs_EDGE); exp.More(); exp.Next()) {
187 TopoDS_Shape edge = exp.Current();
188 if(aNewEdges.Contains(edge))
3f5aa017 189 aNewEdges.RemoveKey(edge);
2277323d 190 else
191 aNewEdges.Add(edge);
192 }
193
194 Standard_Boolean isDropped = Standard_False;
195 //merge edges and drop seams
196 Standard_Integer i;
197 for (i = 1; i <= edges.Length(); i++) {
198 TopoDS_Shape current = edges(i);
199 if(aNewEdges.Contains(current)) {
200
3f5aa017 201 aNewEdges.RemoveKey(current);
2277323d 202 edges.Remove(i);
203 i--;
204
205 if(!isDropped) {
206 isDropped = Standard_True;
207 anIndex = i;
208 }
209 }
210 }
211
9ed6494b 212 //add edges to the sequence
2277323d 213 for (i = 1; i <= aNewEdges.Extent(); i++)
214 edges.Append(aNewEdges(i));
215
216 return isDropped;
217}
218
219//=======================================================================
220//function : getCylinder
221//purpose : auxilary
222//=======================================================================
223static Standard_Boolean getCylinder(Handle(Geom_Surface)& theInSurface,
224 gp_Cylinder& theOutCylinder)
225{
226 Standard_Boolean isCylinder = Standard_False;
227
228 if (theInSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
229 Handle(Geom_CylindricalSurface) aGC = Handle(Geom_CylindricalSurface)::DownCast(theInSurface);
230
231 theOutCylinder = aGC->Cylinder();
232 isCylinder = Standard_True;
233 }
234 else if (theInSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
235 Handle(Geom_SurfaceOfRevolution) aRS =
236 Handle(Geom_SurfaceOfRevolution)::DownCast(theInSurface);
237 Handle(Geom_Curve) aBasis = aRS->BasisCurve();
238 if (aBasis->IsKind(STANDARD_TYPE(Geom_Line))) {
239 Handle(Geom_Line) aBasisLine = Handle(Geom_Line)::DownCast(aBasis);
240 gp_Dir aDir = aRS->Direction();
241 gp_Dir aBasisDir = aBasisLine->Position().Direction();
242 if (aBasisDir.IsParallel(aDir, Precision::Angular())) {
243 // basis line is parallel to the revolution axis: it is a cylinder
244 gp_Pnt aLoc = aRS->Location();
245 Standard_Real aR = aBasisLine->Lin().Distance(aLoc);
246 gp_Ax3 aCylAx (aLoc, aDir);
247
248 theOutCylinder = gp_Cylinder(aCylAx, aR);
249 isCylinder = Standard_True;
250 }
251 }
252 }
253 else if (theInSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
254 Handle(Geom_SurfaceOfLinearExtrusion) aLES =
255 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(theInSurface);
256 Handle(Geom_Curve) aBasis = aLES->BasisCurve();
257 if (aBasis->IsKind(STANDARD_TYPE(Geom_Circle))) {
258 Handle(Geom_Circle) aBasisCircle = Handle(Geom_Circle)::DownCast(aBasis);
259 gp_Dir aDir = aLES->Direction();
260 gp_Dir aBasisDir = aBasisCircle->Position().Direction();
261 if (aBasisDir.IsParallel(aDir, Precision::Angular())) {
262 // basis circle is normal to the extrusion axis: it is a cylinder
263 gp_Pnt aLoc = aBasisCircle->Location();
264 Standard_Real aR = aBasisCircle->Radius();
265 gp_Ax3 aCylAx (aLoc, aDir);
266
267 theOutCylinder = gp_Cylinder(aCylAx, aR);
268 isCylinder = Standard_True;
269 }
270 }
271 }
272 else {
273 }
274
275 return isCylinder;
276}
277
278//=======================================================================
279//function : ClearRts
280//purpose : auxilary
281//=======================================================================
282static Handle(Geom_Surface) ClearRts(const Handle(Geom_Surface)& aSurface)
283{
284 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
285 Handle(Geom_RectangularTrimmedSurface) rts =
286 Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
287 return rts->BasisSurface();
288 }
289 return aSurface;
290}
291
10ce3246 292//=======================================================================
293//function : GetNormalToSurface
294//purpose : Gets the normal to surface by the given parameter on edge.
295// Returns True if normal was computed.
296//=======================================================================
297static Standard_Boolean GetNormalToSurface(const TopoDS_Face& theFace,
298 const TopoDS_Edge& theEdge,
299 const Standard_Real theP,
300 gp_Dir& theNormal)
301{
302 Standard_Real f, l;
303 // get 2d curve to get point in 2d
304 const Handle(Geom2d_Curve)& aC2d = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
305 if (aC2d.IsNull()) {
306 return Standard_False;
307 }
308 //
309 // 2d point
310 gp_Pnt2d aP2d;
311 aC2d->D0(theP, aP2d);
312 //
313 // get D1
314 gp_Vec aDU, aDV;
315 gp_Pnt aP3d;
316 TopLoc_Location aLoc;
317 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(theFace, aLoc);
318 aS->D1(aP2d.X(), aP2d.Y(), aP3d, aDU, aDV);
319 //
320 // compute normal
321 gp_Vec aVNormal = aDU.Crossed(aDV);
322 if (aVNormal.Magnitude() < Precision::Confusion()) {
323 return Standard_False;
324 }
325 //
326 if (theFace.Orientation() == TopAbs_REVERSED) {
327 aVNormal.Reverse();
328 }
329 //
330 aVNormal.Transform(aLoc.Transformation());
331 theNormal = gp_Dir(aVNormal);
332 return Standard_True;
333}
334
2277323d 335//=======================================================================
336//function : IsSameDomain
337//purpose :
338//=======================================================================
339static Standard_Boolean IsSameDomain(const TopoDS_Face& aFace,
2ba9eb30 340 const TopoDS_Face& aCheckedFace,
341 const Standard_Real theLinTol,
342 const Standard_Real theAngTol)
2277323d 343{
344 //checking the same handles
345 TopLoc_Location L1, L2;
346 Handle(Geom_Surface) S1, S2;
347
348 S1 = BRep_Tool::Surface(aFace,L1);
349 S2 = BRep_Tool::Surface(aCheckedFace,L2);
350
351 if (S1 == S2 && L1 == L2)
352 return Standard_True;
353
2277323d 354 S1 = BRep_Tool::Surface(aFace);
355 S2 = BRep_Tool::Surface(aCheckedFace);
356
357 S1 = ClearRts(S1);
358 S2 = ClearRts(S2);
359
360 //Handle(Geom_OffsetSurface) aGOFS1, aGOFS2;
361 //aGOFS1 = Handle(Geom_OffsetSurface)::DownCast(S1);
362 //aGOFS2 = Handle(Geom_OffsetSurface)::DownCast(S2);
363 //if (!aGOFS1.IsNull()) S1 = aGOFS1->BasisSurface();
364 //if (!aGOFS2.IsNull()) S2 = aGOFS2->BasisSurface();
365
2ba9eb30 366 // case of two planar surfaces:
367 // all kinds of surfaces checked, including b-spline and bezier
368 GeomLib_IsPlanarSurface aPlanarityChecker1(S1, theLinTol);
369 if (aPlanarityChecker1.IsPlanar()) {
370 GeomLib_IsPlanarSurface aPlanarityChecker2(S2, theLinTol);
371 if (aPlanarityChecker2.IsPlanar()) {
372 gp_Pln aPln1 = aPlanarityChecker1.Plan();
373 gp_Pln aPln2 = aPlanarityChecker2.Plan();
374
375 if (aPln1.Position().Direction().IsParallel(aPln2.Position().Direction(), theAngTol) &&
376 aPln1.Distance(aPln2) < theLinTol) {
377 return Standard_True;
378 }
379 }
380 }
381
2277323d 382 // case of two elementary surfaces: use OCCT tool
383 // elementary surfaces: ConicalSurface, CylindricalSurface,
384 // Plane, SphericalSurface and ToroidalSurface
385 if (S1->IsKind(STANDARD_TYPE(Geom_ElementarySurface)) &&
386 S2->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
387 {
388 Handle(GeomAdaptor_HSurface) aGA1 = new GeomAdaptor_HSurface(S1);
389 Handle(GeomAdaptor_HSurface) aGA2 = new GeomAdaptor_HSurface(S2);
390
391 Handle(BRepTopAdaptor_TopolTool) aTT1 = new BRepTopAdaptor_TopolTool();
392 Handle(BRepTopAdaptor_TopolTool) aTT2 = new BRepTopAdaptor_TopolTool();
393
394 try {
2ba9eb30 395 IntPatch_ImpImpIntersection anIIInt(aGA1, aTT1, aGA2, aTT2, theLinTol, theLinTol);
2277323d 396 if (!anIIInt.IsDone() || anIIInt.IsEmpty())
397 return Standard_False;
398
399 return anIIInt.TangentFaces();
400 }
401 catch (Standard_Failure) {
402 return Standard_False;
403 }
404 }
405
2277323d 406 // case of two cylindrical surfaces, at least one of which is a swept surface
407 // swept surfaces: SurfaceOfLinearExtrusion, SurfaceOfRevolution
408 if ((S1->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
409 S1->IsKind(STANDARD_TYPE(Geom_SweptSurface))) &&
410 (S2->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
411 S2->IsKind(STANDARD_TYPE(Geom_SweptSurface))))
412 {
413 gp_Cylinder aCyl1, aCyl2;
414 if (getCylinder(S1, aCyl1) && getCylinder(S2, aCyl2)) {
2ba9eb30 415 if (fabs(aCyl1.Radius() - aCyl2.Radius()) < theLinTol) {
2277323d 416 gp_Dir aDir1 = aCyl1.Position().Direction();
417 gp_Dir aDir2 = aCyl2.Position().Direction();
418 if (aDir1.IsParallel(aDir2, Precision::Angular())) {
419 gp_Pnt aLoc1 = aCyl1.Location();
420 gp_Pnt aLoc2 = aCyl2.Location();
421 gp_Vec aVec12 (aLoc1, aLoc2);
2ba9eb30 422 if (aVec12.SquareMagnitude() < theLinTol*theLinTol ||
2277323d 423 aVec12.IsParallel(aDir1, Precision::Angular())) {
424 return Standard_True;
425 }
426 }
427 }
428 }
429 }
430
431 return Standard_False;
432}
433
632175c3 434//=======================================================================
435//function : UpdateMapEdgeFaces
436//purpose :
437//=======================================================================
438static void UpdateMapEdgeFaces(const TopoDS_Face& theFace,
439 Handle(ShapeBuild_ReShape)& theContext,
440 TopTools_IndexedDataMapOfShapeListOfShape& theMapEdgeFaces)
441{
442 for (TopExp_Explorer anExp(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
443 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
444 TopoDS_Edge aContextEdge = TopoDS::Edge(theContext->Apply(anEdge));
445 if (aContextEdge == anEdge)
446 continue;
447 Standard_Integer anIndex = theMapEdgeFaces.FindIndex(aContextEdge);
448 if (anIndex == 0)
449 theMapEdgeFaces.Add(aContextEdge,
450 theMapEdgeFaces.FindFromKey(anEdge));
451 else
452 theMapEdgeFaces.ChangeFromIndex(anIndex).Append(theFace);
453 }
454}
455
456//=======================================================================
457//function : UpdateMapOfShapes
458//purpose :
459//=======================================================================
460static void UpdateMapOfShapes(TopTools_MapOfShape& theMapOfShapes,
461 Handle(ShapeBuild_ReShape)& theContext)
462{
463 for (TopTools_MapIteratorOfMapOfShape it(theMapOfShapes); it.More(); it.Next()) {
464 const TopoDS_Shape& aShape = it.Value();
465 TopoDS_Shape aContextShape = theContext->Apply(aShape);
466 if (!aContextShape.IsSame(aShape))
467 theMapOfShapes.Add(aContextShape);
468 }
469}
470
2277323d 471//=======================================================================
472//function : MovePCurves
473//purpose :
474//=======================================================================
475static void MovePCurves(TopoDS_Face& aTarget,
632175c3 476 const TopoDS_Face& aSource,
477 Standard_Boolean isSafeInputMode,
478 Handle(ShapeBuild_ReShape)& theContext)
2277323d 479{
480 BRep_Builder B;
481 for(TopExp_Explorer wexp(aSource,TopAbs_WIRE);wexp.More();wexp.Next()) {
482 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(TopoDS::Wire(wexp.Current()),
483 aTarget, Precision::Confusion());
632175c3 484 if (isSafeInputMode)
485 sfw->SetContext(theContext);
2277323d 486 sfw->FixReorder();
487 Standard_Boolean isReoredFailed = sfw->StatusReorder ( ShapeExtend_FAIL );
488 sfw->FixEdgeCurves();
489 if(isReoredFailed)
490 continue;
491
492 sfw->FixShifted();
493 sfw->FixDegenerated();
494
495 // remove degenerated edges from not degenerated points
496 ShapeAnalysis_Edge sae;
497 Handle(ShapeExtend_WireData) sewd = sfw->WireData();
498 for(Standard_Integer i = 1; i<=sewd->NbEdges();i++) {
499 TopoDS_Edge E = sewd->Edge(i);
500 if(BRep_Tool::Degenerated(E)&&!sae.HasPCurve(E,aTarget)) {
501 sewd->Remove(i);
502 i--;
503 }
504 }
505
506 TopoDS_Wire ResWire = sfw->Wire();
507 B.Add(aTarget,ResWire);
508 }
509}
510
511//=======================================================================
512//function : GlueEdgesWithPCurves
513//purpose : Glues the pcurves of the sequence of edges
514// and glues their 3d curves
515//=======================================================================
516static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain,
517 const TopoDS_Vertex& FirstVertex,
518 const TopoDS_Vertex& LastVertex)
519{
520 Standard_Integer i, j;
521
522 TopoDS_Edge FirstEdge = TopoDS::Edge(aChain(1));
523 //TColGeom2d_SequenceOfCurve PCurveSeq;
524 TColGeom_SequenceOfSurface SurfSeq;
525 //TopTools_SequenceOfShape LocSeq;
526
527 BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(FirstEdge.TShape()))->Curves() );
528 for (; itr.More(); itr.Next())
529 {
530 Handle(BRep_CurveRepresentation) CurveRep = itr.Value();
531 if (CurveRep->IsCurveOnSurface())
532 {
533 //PCurveSeq.Append(CurveRep->PCurve());
534 SurfSeq.Append(CurveRep->Surface());
535 /*
536 TopoDS_Shape aLocShape;
537 aLocShape.Location(CurveRep->Location());
538 LocSeq.Append(aLocShape);
539 */
540 }
541 }
542
543 Standard_Real fpar, lpar;
544 BRep_Tool::Range(FirstEdge, fpar, lpar);
545 TopoDS_Edge PrevEdge = FirstEdge;
546 TopoDS_Vertex CV;
547 Standard_Real MaxTol = 0.;
548
549 TopoDS_Edge ResEdge;
550 BRep_Builder BB;
551
552 Standard_Integer nb_curve = aChain.Length(); //number of curves
553 TColGeom_Array1OfBSplineCurve tab_c3d(0,nb_curve-1); //array of the curves
554 TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2); //array of the tolerances
555
556 TopoDS_Vertex PrevVertex = FirstVertex;
557 for (i = 1; i <= nb_curve; i++)
558 {
559 TopoDS_Edge anEdge = TopoDS::Edge(aChain(i));
560 TopoDS_Vertex VF, VL;
561 TopExp::Vertices(anEdge, VF, VL);
562 Standard_Boolean ToReverse = (!VF.IsSame(PrevVertex));
563
564 Standard_Real Tol1 = BRep_Tool::Tolerance(VF);
565 Standard_Real Tol2 = BRep_Tool::Tolerance(VL);
566 if (Tol1 > MaxTol)
567 MaxTol = Tol1;
568 if (Tol2 > MaxTol)
569 MaxTol = Tol2;
570
571 if (i > 1)
572 {
573 TopExp::CommonVertex(PrevEdge, anEdge, CV);
574 Standard_Real Tol = BRep_Tool::Tolerance(CV);
575 tabtolvertex(i-2) = Tol;
576 }
577
578 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
579 Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, fpar, lpar);
580 tab_c3d(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
581 GeomConvert::C0BSplineToC1BSplineCurve(tab_c3d(i-1), Precision::Confusion());
582 if (ToReverse)
583 tab_c3d(i-1)->Reverse();
584 PrevVertex = (ToReverse)? VF : VL;
585 PrevEdge = anEdge;
586 }
587 Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves
588 Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex
589 GeomConvert::ConcatC1(tab_c3d,
590 tabtolvertex,
591 ArrayOfIndices,
592 concatcurve,
593 Standard_False,
594 Precision::Confusion()); //C1 concatenation
595
596 if (concatcurve->Length() > 1)
597 {
598 GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
599
600 for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
601 Concat.Add( concatcurve->Value(i), MaxTol, Standard_True );
602
603 concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
604 }
605 Handle(Geom_BSplineCurve) ResCurve = concatcurve->Value(concatcurve->Lower());
606
607 TColGeom2d_SequenceOfBoundedCurve ResPCurves;
608 TopLoc_Location aLoc;
609 for (j = 1; j <= SurfSeq.Length(); j++)
610 {
611 TColGeom2d_Array1OfBSplineCurve tab_c2d(0,nb_curve-1); //array of the pcurves
612
613 PrevVertex = FirstVertex;
614 PrevEdge = FirstEdge;
615 //TopLoc_Location theLoc = LocSeq(j).Location();
616 for (i = 1; i <= nb_curve; i++)
617 {
618 TopoDS_Edge anEdge = TopoDS::Edge(aChain(i));
619 TopoDS_Vertex VF, VL;
620 TopExp::Vertices(anEdge, VF, VL);
621 Standard_Boolean ToReverse = (!VF.IsSame(PrevVertex));
622
623 /*
624 Handle(Geom2d_Curve) aPCurve =
625 BRep_Tool::CurveOnSurface(anEdge, SurfSeq(j), anEdge.Location()*theLoc, fpar, lpar);
626 */
627 Handle(Geom2d_Curve) aPCurve =
628 BRep_Tool::CurveOnSurface(anEdge, SurfSeq(j), aLoc, fpar, lpar);
629 Handle(Geom2d_TrimmedCurve) aTrPCurve = new Geom2d_TrimmedCurve(aPCurve, fpar, lpar);
630 tab_c2d(i-1) = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
631 Geom2dConvert::C0BSplineToC1BSplineCurve(tab_c2d(i-1), Precision::Confusion());
632 if (ToReverse)
633 tab_c2d(i-1)->Reverse();
634 PrevVertex = (ToReverse)? VF : VL;
635 PrevEdge = anEdge;
636 }
637 Handle(TColGeom2d_HArray1OfBSplineCurve) concatc2d; //array of the concatenated curves
638 Handle(TColStd_HArray1OfInteger) ArrayOfInd2d; //array of the remining Vertex
639 Geom2dConvert::ConcatC1(tab_c2d,
640 tabtolvertex,
641 ArrayOfInd2d,
642 concatc2d,
643 Standard_False,
644 Precision::Confusion()); //C1 concatenation
645
646 if (concatc2d->Length() > 1)
647 {
648 Geom2dConvert_CompCurveToBSplineCurve Concat2d(concatc2d->Value(concatc2d->Lower()));
649
650 for (i = concatc2d->Lower()+1; i <= concatc2d->Upper(); i++)
651 Concat2d.Add( concatc2d->Value(i), MaxTol, Standard_True );
652
653 concatc2d->SetValue(concatc2d->Lower(), Concat2d.BSplineCurve());
654 }
655 Handle(Geom2d_BSplineCurve) aResPCurve = concatc2d->Value(concatc2d->Lower());
656 ResPCurves.Append(aResPCurve);
657 }
658
659 ResEdge = BRepLib_MakeEdge(ResCurve,
660 FirstVertex, LastVertex,
661 ResCurve->FirstParameter(), ResCurve->LastParameter());
662 BB.SameRange(ResEdge, Standard_False);
663 BB.SameParameter(ResEdge, Standard_False);
664 for (j = 1; j <= ResPCurves.Length(); j++)
665 {
666 BB.UpdateEdge(ResEdge, ResPCurves(j), SurfSeq(j), aLoc, MaxTol);
667 BB.Range(ResEdge, SurfSeq(j), aLoc, ResPCurves(j)->FirstParameter(), ResPCurves(j)->LastParameter());
668 }
669
670 BRepLib::SameParameter(ResEdge, MaxTol, Standard_True);
671
672 return ResEdge;
673}
674
cef6867c 675//=======================================================================
676//function : MergeSubSeq
677//purpose : Merges a sequence of edges into one edge if possible
678//=======================================================================
679
632175c3 680static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& aChain,
681 TopoDS_Edge& OutEdge,
682 double theAngTol,
683 Standard_Boolean ConcatBSplines,
684 Standard_Boolean isSafeInputMode,
685 Handle(ShapeBuild_ReShape)& theContext)
2277323d 686{
2277323d 687 ShapeAnalysis_Edge sae;
f7d70540 688 BRep_Builder B;
2277323d 689 // union edges in chain
f7d70540 690 int j;
2277323d 691 Standard_Real fp1,lp1,fp2,lp2;
f7d70540 692 Standard_Boolean IsUnionOfLinesPossible = Standard_True;
693 Standard_Boolean IsUnionOfCirclesPossible = Standard_True;
694 Handle(Geom_Curve) c3d1, c3d2;
695 for(j=1; j<aChain.Length(); j++)
696 {
2277323d 697 TopoDS_Edge edge1 = TopoDS::Edge(aChain.Value(j));
f7d70540 698 c3d1 = BRep_Tool::Curve(edge1,fp1,lp1);
699
700 TopoDS_Edge edge2 = TopoDS::Edge(aChain.Value(j+1));
701 c3d2 = BRep_Tool::Curve(edge2,fp2,lp2);
702
703 if(c3d1.IsNull() || c3d2.IsNull())
704 return Standard_False;
b4d4dbe8 705
2277323d 706 while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
707 Handle(Geom_TrimmedCurve) tc =
708 Handle(Geom_TrimmedCurve)::DownCast(c3d1);
709 c3d1 = tc->BasisCurve();
710 }
2277323d 711 while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
712 Handle(Geom_TrimmedCurve) tc =
713 Handle(Geom_TrimmedCurve)::DownCast(c3d2);
714 c3d2 = tc->BasisCurve();
715 }
716 if( c3d1->IsKind(STANDARD_TYPE(Geom_Line)) && c3d2->IsKind(STANDARD_TYPE(Geom_Line)) ) {
2277323d 717 Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(c3d1);
718 Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(c3d2);
719 gp_Dir Dir1 = L1->Position().Direction();
720 gp_Dir Dir2 = L2->Position().Direction();
632175c3 721 if(!Dir1.IsParallel(Dir2,theAngTol))
f7d70540 722 IsUnionOfLinesPossible = Standard_False;
2277323d 723 }
f7d70540 724 else
725 IsUnionOfLinesPossible = Standard_False;
2277323d 726 if( c3d1->IsKind(STANDARD_TYPE(Geom_Circle)) && c3d2->IsKind(STANDARD_TYPE(Geom_Circle)) ) {
2277323d 727 Handle(Geom_Circle) C1 = Handle(Geom_Circle)::DownCast(c3d1);
728 Handle(Geom_Circle) C2 = Handle(Geom_Circle)::DownCast(c3d2);
729 gp_Pnt P01 = C1->Location();
730 gp_Pnt P02 = C2->Location();
b4d4dbe8 731 if (P01.Distance(P02) > Precision::Confusion())
f7d70540 732 IsUnionOfCirclesPossible = Standard_False;
733 }
734 else
735 IsUnionOfCirclesPossible = Standard_False;
736 }
737 if (IsUnionOfLinesPossible && IsUnionOfCirclesPossible)
738 return Standard_False;
739
740 //union of lines is possible
741 if (IsUnionOfLinesPossible)
742 {
632175c3 743 TopoDS_Vertex V[2];
744 V[0] = sae.FirstVertex(TopoDS::Edge(aChain.First()));
745 gp_Pnt PV1 = BRep_Tool::Pnt(V[0]);
746 V[1] = sae.LastVertex(TopoDS::Edge(aChain.Last()));
747 gp_Pnt PV2 = BRep_Tool::Pnt(V[1]);
f7d70540 748 gp_Vec Vec(PV1, PV2);
632175c3 749 if (isSafeInputMode) {
750 for (int k = 0; k < 2; k++) {
751 if (!theContext->IsRecorded(V[k])) {
752 TopoDS_Vertex Vcopy = TopoDS::Vertex(V[k].EmptyCopied());
753 theContext->Replace(V[k], Vcopy);
754 V[k] = Vcopy;
755 }
756 else
757 V[k] = TopoDS::Vertex(theContext->Apply(V[k]));
758 }
759 }
f7d70540 760 Handle(Geom_Line) L = new Geom_Line(gp_Ax1(PV1,Vec));
761 Standard_Real dist = PV1.Distance(PV2);
762 Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(L,0.0,dist);
763 TopoDS_Edge E;
764 B.MakeEdge (E, tc ,Precision::Confusion());
632175c3 765 B.Add (E,V[0]); B.Add (E,V[1]);
766 B.UpdateVertex(V[0], 0., E, 0.);
767 B.UpdateVertex(V[1], dist, E, 0.);
f7d70540 768 OutEdge = E;
769 return Standard_True;
770 }
771
772 if (IsUnionOfCirclesPossible)
773 {
774 double f,l;
775 TopoDS_Edge FE = TopoDS::Edge(aChain.First());
776 Handle(Geom_Curve) c3d = BRep_Tool::Curve(FE,f,l);
777
778 while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
779 Handle(Geom_TrimmedCurve) tc =
780 Handle(Geom_TrimmedCurve)::DownCast(c3d);
781 c3d = tc->BasisCurve();
782 }
783 Handle(Geom_Circle) Cir = Handle(Geom_Circle)::DownCast(c3d);
784
632175c3 785 TopoDS_Vertex V[2];
786 V[0] = sae.FirstVertex(FE);
787 V[1] = sae.LastVertex(TopoDS::Edge(aChain.Last()));
f7d70540 788 TopoDS_Edge E;
632175c3 789 if (V[0].IsSame(V[1])) {
f7d70540 790 // closed chain
dd2f1b75 791 BRepAdaptor_Curve adef(FE);
792 Handle(Geom_Circle) Cir1;
793 double FP, LP;
794 if ( FE.Orientation() == TopAbs_FORWARD)
795 {
796 FP = adef.FirstParameter();
797 LP = adef.LastParameter();
798 }
799 else
800 {
801 FP = adef.LastParameter();
802 LP = adef.FirstParameter();
803 }
804 if (Abs(FP) < Precision::PConfusion())
805 {
f0144633 806 B.MakeEdge (E,Cir, Precision::Confusion());
632175c3 807 B.Add(E,V[0]);
808 B.Add(E,V[1]);
f0144633 809 E.Orientation(FE.Orientation());
810 }
dd2f1b75 811 else
812 {
813 GC_MakeCircle MC1 (adef.Value(FP), adef.Value((FP + LP) * 0.5), adef.Value(LP));
814 if (MC1.IsDone())
815 Cir1 = MC1.Value();
816 else
817 return Standard_False;
818 B.MakeEdge (E, Cir1, Precision::Confusion());
632175c3 819 B.Add(E,V[0]);
820 B.Add(E,V[1]);
dd2f1b75 821 }
f7d70540 822 }
823 else {
632175c3 824 if (isSafeInputMode) {
825 for (int k = 0; k < 2; k++) {
826 if (!theContext->IsRecorded(V[k])) {
827 TopoDS_Vertex Vcopy = TopoDS::Vertex(V[k].EmptyCopied());
828 theContext->Replace(V[k], Vcopy);
829 V[k] = Vcopy;
830 }
831 else
832 V[k] = TopoDS::Vertex(theContext->Apply(V[k]));
833 }
834 }
835 gp_Pnt PV1 = BRep_Tool::Pnt(V[0]);
836 gp_Pnt PV2 = BRep_Tool::Pnt(V[1]);
dd2f1b75 837 TopoDS_Vertex VM = sae.LastVertex(FE);
838 gp_Pnt PVM = BRep_Tool::Pnt(VM);
839 GC_MakeCircle MC (PV1,PVM,PV2);
f7d70540 840 Handle(Geom_Circle) C = MC.Value();
841 gp_Pnt P0 = C->Location();
842 gp_Dir D1(gp_Vec(P0,PV1));
843 gp_Dir D2(gp_Vec(P0,PV2));
844 Standard_Real fpar = C->XAxis().Direction().Angle(D1);
845 if(fabs(fpar)>Precision::Confusion()) {
846 // check orientation
847 gp_Dir ND = C->XAxis().Direction().Crossed(D1);
848 if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) {
849 fpar = -fpar;
2277323d 850 }
f7d70540 851 }
852 Standard_Real lpar = C->XAxis().Direction().Angle(D2);
853 if(fabs(lpar)>Precision::Confusion()) {
854 // check orientation
855 gp_Dir ND = C->XAxis().Direction().Crossed(D2);
856 if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) {
857 lpar = -lpar;
2277323d 858 }
2277323d 859 }
f7d70540 860 if (lpar < fpar) lpar += 2*M_PI;
861 Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar);
862 B.MakeEdge (E,tc,Precision::Confusion());
632175c3 863 B.Add(E,V[0]);
864 B.Add(E,V[1]);
865 B.UpdateVertex(V[0], fpar, E, 0.);
866 B.UpdateVertex(V[1], lpar, E, 0.);
2277323d 867 }
f7d70540 868 OutEdge = E;
869 return Standard_True;
2277323d 870 }
871 if (aChain.Length() > 1 && ConcatBSplines) {
872 // second step: union edges with various curves
873 // skl for bug 0020052 from Mantis: perform such unions
874 // only if curves are bspline or bezier
f7d70540 875
876 TopoDS_Vertex VF = sae.FirstVertex(TopoDS::Edge(aChain.First()));
877 TopoDS_Vertex VL = sae.LastVertex(TopoDS::Edge(aChain.Last()));
878 Standard_Boolean NeedUnion = Standard_True;
2277323d 879 for(j=1; j<=aChain.Length(); j++) {
880 TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j));
b4d4dbe8 881 TopLoc_Location Loc;
2277323d 882 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,Loc,fp1,lp1);
883 if(c3d.IsNull()) continue;
884 while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
885 Handle(Geom_TrimmedCurve) tc =
886 Handle(Geom_TrimmedCurve)::DownCast(c3d);
887 c3d = tc->BasisCurve();
888 }
889 if( ( c3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) ||
890 c3d->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ) ) continue;
f7d70540 891 NeedUnion = Standard_False;
2277323d 892 break;
893 }
894 if(NeedUnion) {
0797d9d3 895#ifdef OCCT_DEBUG
2277323d 896 cout<<"can not make analitical union => make approximation"<<endl;
897#endif
898 TopoDS_Edge E = GlueEdgesWithPCurves(aChain, VF, VL);
f7d70540 899 OutEdge = E;
900 return Standard_True;
2277323d 901 }
902 else {
0797d9d3 903#ifdef OCCT_DEBUG
2277323d 904 cout<<"can not make approximation for such types of curves"<<endl;
905#endif
906 return Standard_False;
907 }
908 }
f7d70540 909 return Standard_False;
910}
911
cef6867c 912//=======================================================================
913//function : IsMergingPossible
914//purpose : Checks if merging of two edges is possible
915//=======================================================================
916
f7d70540 917static Standard_Boolean IsMergingPossible(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2,
632175c3 918 double theAngTol, const TopTools_MapOfShape& AvoidEdgeVrt)
f7d70540 919{
920 TopoDS_Vertex CV = TopExp::LastVertex(edge1, Standard_True);
9ed6494b 921 if (CV.IsNull() || AvoidEdgeVrt.Contains(CV))
f7d70540 922 return Standard_False;
923
924 BRepAdaptor_Curve ade1(edge1);
925 BRepAdaptor_Curve ade2(edge2);
926
927 GeomAbs_CurveType t1 = ade1.GetType();
928 GeomAbs_CurveType t2 = ade2.GetType();
929
930 if( t1 == GeomAbs_Circle && t2 == GeomAbs_Circle)
931 {
932 if (ade1.Circle().Location().Distance(ade2.Circle().Location()) > Precision::Confusion())
933 return Standard_False;
934 }
935
936 if( ( (t1 != GeomAbs_BezierCurve && t1 != GeomAbs_BSplineCurve) ||
937 (t2 != GeomAbs_BezierCurve && t2 != GeomAbs_BSplineCurve)) && t1 != t2)
938 return Standard_False;
939
940 gp_Vec Diff1, Diff2;
941 gp_Pnt P1, P2;
942 if (edge1.Orientation() == TopAbs_FORWARD)
943 ade1.D1(ade1.LastParameter(), P1, Diff1);
944 else
945 {
946 ade1.D1(ade1.FirstParameter(), P1, Diff1);
947 Diff1 = -Diff1;
948 }
949
950 if (edge2.Orientation() == TopAbs_FORWARD)
951 ade2.D1(ade2.FirstParameter(), P2, Diff2);
952 else
953 {
954 ade2.D1(ade2.LastParameter(), P2, Diff2);
955 Diff2 = -Diff2;
956 }
957
632175c3 958 if (Diff1.Angle(Diff2) > theAngTol)
f7d70540 959 return Standard_False;
960
961 return Standard_True;
962}
963
cef6867c 964//=======================================================================
965//function : GenerateSubSeq
966//purpose : Generates sub-sequences of edges from sequence of edges
967//Edges from each subsequences can be merged into the one edge
968//=======================================================================
969
f7d70540 970static void GenerateSubSeq (const TopTools_SequenceOfShape& anInpEdgeSeq,
971 NCollection_Sequence<SubSequenceOfEdges>& SeqOfSubSeqOfEdges,
632175c3 972 Standard_Boolean IsClosed, double theAngTol, const TopTools_MapOfShape& AvoidEdgeVrt)
f7d70540 973{
974 Standard_Boolean isOk = Standard_False;
975 TopoDS_Edge edge1, edge2;
976
977 SubSequenceOfEdges SubSeq;
978 SubSeq.SeqsEdges.Append(TopoDS::Edge(anInpEdgeSeq(1)));
979 SeqOfSubSeqOfEdges.Append(SubSeq);
980
981 for (int i = 1; i < anInpEdgeSeq.Length(); i++)
982 {
983 edge1 = TopoDS::Edge(anInpEdgeSeq(i));
984 edge2 = TopoDS::Edge(anInpEdgeSeq(i+1));
632175c3 985 isOk = IsMergingPossible(edge1, edge2, theAngTol, AvoidEdgeVrt);
f7d70540 986 if (!isOk)
987 {
51740958 988 SubSequenceOfEdges aSubSeq;
989 aSubSeq.SeqsEdges.Append(edge2);
990 SeqOfSubSeqOfEdges.Append(aSubSeq);
f7d70540 991 }
992 else
993 SeqOfSubSeqOfEdges.ChangeLast().SeqsEdges.Append(edge2);
994 }
995 /// check first and last chain segments
996 if (IsClosed && SeqOfSubSeqOfEdges.Length() > 1)
997 {
998 edge1 = TopoDS::Edge(anInpEdgeSeq.Last());
999 edge2 = TopoDS::Edge(anInpEdgeSeq.First());
632175c3 1000 if (IsMergingPossible(edge1, edge2, theAngTol, AvoidEdgeVrt))
f7d70540 1001 {
1002 SeqOfSubSeqOfEdges.ChangeLast().SeqsEdges.Append(SeqOfSubSeqOfEdges.ChangeFirst().SeqsEdges);
1003 SeqOfSubSeqOfEdges.Remove(1);
1004 }
1005 }
1006}
1007
f7d70540 1008//=======================================================================
1009//function : MergeEdges
1010//purpose : auxilary
1011//=======================================================================
f98965d2 1012static Standard_Boolean MergeEdges(TopTools_SequenceOfShape& SeqEdges,
632175c3 1013 const Standard_Real theAngTol,
f7d70540 1014 const Standard_Boolean ConcatBSplines,
632175c3 1015 const Standard_Boolean isSafeInputMode,
1016 Handle(ShapeBuild_ReShape)& theContext,
f7d70540 1017 NCollection_Sequence<SubSequenceOfEdges>& SeqOfSubSeqOfEdges,
9ed6494b 1018 const TopTools_MapOfShape& NonMergVrt)
f7d70540 1019{
f98965d2 1020 // skip degenerated edges, and forbid merging through them
1021 TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
f7d70540 1022 Standard_Integer j;
1023 TopTools_MapOfShape VerticesToAvoid;
f7d70540 1024 for (j = 1; j <= SeqEdges.Length(); j++)
1025 {
1026 TopoDS_Edge anEdge = TopoDS::Edge(SeqEdges(j));
1027 if (BRep_Tool::Degenerated(anEdge))
1028 {
1029 TopoDS_Vertex V1, V2;
1030 TopExp::Vertices(anEdge, V1, V2);
1031 VerticesToAvoid.Add(V1);
1032 VerticesToAvoid.Add(V2);
f98965d2 1033 SeqEdges.Remove(j--);
1034 }
1035 else
1036 {
1037 // fill in the map V-E
1038 for (TopoDS_Iterator it(anEdge.Oriented(TopAbs_FORWARD)); it.More(); it.Next())
1039 {
1040 TopoDS_Shape aV = it.Value();
1041 if (aV.Orientation() == TopAbs_FORWARD || aV.Orientation() == TopAbs_REVERSED)
1042 {
1043 if (!aMapVE.Contains(aV))
1044 aMapVE.Add(aV, TopTools_ListOfShape());
1045 aMapVE.ChangeFromKey(aV).Append(anEdge);
38c2acd4 1046 }
f98965d2 1047 }
f7d70540 1048 }
f7d70540 1049 }
f98965d2 1050 VerticesToAvoid.Unite(NonMergVrt);
f7d70540 1051
f98965d2 1052 // do loop while there are unused edges
1053 TopTools_MapOfShape aUsedEdges;
1054 for (;;)
1055 {
1056 TopoDS_Edge edge;
1057 for(j=1; j <= SeqEdges.Length(); j++)
1058 {
1059 edge = TopoDS::Edge(SeqEdges.Value(j));
1060 if (!aUsedEdges.Contains(edge))
1061 break;
1062 }
1063 if (j > SeqEdges.Length())
1064 break; // all edges have been used
1065
1066 // make chain for unite
1067 TopTools_SequenceOfShape aChain;
38c2acd4 1068 aChain.Append(edge);
f98965d2 1069 aUsedEdges.Add(edge);
1070 TopoDS_Vertex V[2];
1071 TopExp::Vertices(edge, V[0], V[1], Standard_True);
1072
1073 // connect more edges to the chain in both directions
1074 for (j = 0; j < 2; j++)
1075 {
1076 Standard_Boolean isAdded = Standard_True;
1077 while (isAdded)
1078 {
1079 isAdded = Standard_False;
1080 if (V[j].IsNull())
1081 break;
1082 const TopTools_ListOfShape& aLE = aMapVE.FindFromKey(V[j]);
1083 for (TopTools_ListIteratorOfListOfShape itL(aLE); itL.More(); itL.Next())
1084 {
1085 edge = TopoDS::Edge(itL.Value());
1086 if (!aUsedEdges.Contains(edge))
1087 {
38c2acd4 1088 TopoDS_Vertex V2[2];
1089 TopExp::Vertices(edge, V2[0], V2[1], Standard_True);
1090 // the neighboring edge must have V[j] reversed and located on the opposite end
1091 if (V2[1 - j].IsEqual(V[j].Reversed()))
1092 {
1093 if (j == 0)
1094 aChain.Prepend(edge);
1095 else
1096 aChain.Append(edge);
1097 aUsedEdges.Add(edge);
1098 V[j] = V2[j];
1099 isAdded = Standard_True;
1100 break;
1101 }
1102 }
1103 }
f7d70540 1104 }
1105 }
f7d70540 1106
f98965d2 1107 if (aChain.Length() < 2)
1108 continue;
2277323d 1109
38c2acd4 1110 Standard_Boolean IsClosed = Standard_False;
f98965d2 1111 if (V[0].IsSame ( V[1] ))
38c2acd4 1112 IsClosed = Standard_True;
f98965d2 1113
1114 // split chain by vertices at which merging is not possible
1115 NCollection_Sequence<SubSequenceOfEdges> aOneSeq;
632175c3 1116 GenerateSubSeq(aChain, aOneSeq, IsClosed, theAngTol, VerticesToAvoid);
f98965d2 1117
1118 // put sub-chains in the result
1119 SeqOfSubSeqOfEdges.Append(aOneSeq);
1120 }
f7d70540 1121
1122 for (int i = 1; i <= SeqOfSubSeqOfEdges.Length(); i++)
1123 {
1124 TopoDS_Edge UE;
1125 if (SeqOfSubSeqOfEdges(i).SeqsEdges.Length() < 2)
1126 continue;
632175c3 1127 if (MergeSubSeq(SeqOfSubSeqOfEdges(i).SeqsEdges, UE, theAngTol,
1128 ConcatBSplines, isSafeInputMode, theContext))
f7d70540 1129 SeqOfSubSeqOfEdges(i).UnionEdges = UE;
1130 }
2277323d 1131 return Standard_True;
1132}
1133
cef6867c 1134//=======================================================================
1135//function : MergeSeq
1136//purpose : Tries to unify the sequence of edges with the set of another edges
1137//which lies on the same geometry
1138//=======================================================================
1139
f98965d2 1140static Standard_Boolean MergeSeq (TopTools_SequenceOfShape& SeqEdges,
632175c3 1141 const Standard_Real theAngTol,
f7d70540 1142 const Standard_Boolean ConcatBSplines,
632175c3 1143 const Standard_Boolean isSafeInputMode,
f7d70540 1144 Handle(ShapeBuild_ReShape)& theContext,
f7d70540 1145 const TopTools_MapOfShape& nonMergVert,
654c48b2 1146 TopTools_MapOfShape& theRemovedVertices)
f7d70540 1147{
1148 NCollection_Sequence<SubSequenceOfEdges> SeqOfSubsSeqOfEdges;
632175c3 1149 if (MergeEdges(SeqEdges, theAngTol, ConcatBSplines, isSafeInputMode,
1150 theContext, SeqOfSubsSeqOfEdges, nonMergVert))
f7d70540 1151 {
1152 for (Standard_Integer i = 1; i <= SeqOfSubsSeqOfEdges.Length(); i++ )
1153 {
1154 if (SeqOfSubsSeqOfEdges(i).UnionEdges.IsNull())
1155 continue;
654c48b2 1156
1157 theContext->Merge(SeqOfSubsSeqOfEdges(i).SeqsEdges,
1158 SeqOfSubsSeqOfEdges(i).UnionEdges);
1159
20aa0d3f 1160 ShapeAnalysis_Edge sae;
1161 TopoDS_Vertex VF = sae.FirstVertex(SeqOfSubsSeqOfEdges(i).UnionEdges);
1162 TopoDS_Vertex VL = sae.LastVertex(SeqOfSubsSeqOfEdges(i).UnionEdges);
1163 for (Standard_Integer j = 1; j <= SeqOfSubsSeqOfEdges(i).SeqsEdges.Length(); j++)
f7d70540 1164 {
2ba9eb30 1165 const TopoDS_Shape& anOldEdge = SeqOfSubsSeqOfEdges(i).SeqsEdges(j);
20aa0d3f 1166 TopoDS_Vertex V[2];
1167 TopExp::Vertices(TopoDS::Edge(anOldEdge), V[0], V[1]);
654c48b2 1168 for (int k = 0; k < 2; k++)
20aa0d3f 1169 {
654c48b2 1170 TopoDS_Vertex aV = V[k];
632175c3 1171 if (isSafeInputMode) // vertex might be changed and replaced
654c48b2 1172 aV = TopoDS::Vertex(theContext->Apply(aV));
1173 if (!aV.IsEqual(VF) && !aV.IsEqual(VL))
1174 theRemovedVertices.Add(V[k]);
20aa0d3f 1175 }
f7d70540 1176 }
1177 }
1178 return Standard_True;
1179 }
1180 else
1181 return Standard_False;
1182}
1183
cef6867c 1184//=======================================================================
1185//function : CheckSharedVertices
1186//purpose : Checks the sequence of edges on the presence of shared vertex
1187//=======================================================================
1188
f7d70540 1189static void CheckSharedVertices(const TopTools_SequenceOfShape& theSeqEdges,
1190 const TopTools_IndexedDataMapOfShapeListOfShape& theMapEdgesVertex,
9ed6494b 1191 const TopTools_MapOfShape& theMapKeepShape,
f7d70540 1192 TopTools_MapOfShape& theShareVertMap)
1193{
1194 ShapeAnalysis_Edge sae;
1195 TopTools_SequenceOfShape SeqVertexes;
1196 TopTools_MapOfShape MapVertexes;
1197 for (Standard_Integer k = 1; k <= theSeqEdges.Length(); k++ )
1198 {
1199 TopoDS_Vertex aV1 = sae.FirstVertex(TopoDS::Edge(theSeqEdges(k)));
1200 TopoDS_Vertex aV2 = sae.LastVertex(TopoDS::Edge(theSeqEdges(k)));
1201 if (!MapVertexes.Add(aV1))
1202 SeqVertexes.Append(aV1);
1203 if (!MapVertexes.Add(aV2))
1204 SeqVertexes.Append(aV2);
1205 }
1206
1207 for (Standard_Integer k = 1; k <= SeqVertexes.Length()/* && !IsSharedVertexPresent*/; k++ )
1208 {
1209 const TopTools_ListOfShape& ListEdgesV1 = theMapEdgesVertex.FindFromKey(SeqVertexes(k));
f1191d30 1210 if (ListEdgesV1.Extent() > 2 || theMapKeepShape.Contains(SeqVertexes(k)))
f7d70540 1211 theShareVertMap.Add(SeqVertexes(k));
1212 }
1213 //return theShareVertMap.IsEmpty() ? false : true;
1214}
1215
2277323d 1216//=======================================================================
1217//function : ShapeUpgrade_UnifySameDomain
1218//purpose : Constructor
1219//=======================================================================
1220
1221ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain()
2ba9eb30 1222 : myLinTol(Precision::Confusion()),
1223 myAngTol(Precision::Angular()),
1224 myUnifyFaces(Standard_True),
fe1a6e4e 1225 myUnifyEdges (Standard_True),
1226 myConcatBSplines (Standard_False),
632175c3 1227 myAllowInternal (Standard_False),
654c48b2 1228 mySafeInputMode(Standard_True),
1229 myHistory(new BRepTools_History)
2277323d 1230{
2277323d 1231 myContext = new ShapeBuild_ReShape;
1232}
1233
1234//=======================================================================
1235//function : ShapeUpgrade_UnifySameDomain
1236//purpose : Constructor
1237//=======================================================================
1238
1239ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain(const TopoDS_Shape& aShape,
1240 const Standard_Boolean UnifyEdges,
1241 const Standard_Boolean UnifyFaces,
1242 const Standard_Boolean ConcatBSplines)
fe1a6e4e 1243 : myInitShape (aShape),
2ba9eb30 1244 myLinTol(Precision::Confusion()),
1245 myAngTol(Precision::Angular()),
1246 myUnifyFaces(UnifyFaces),
fe1a6e4e 1247 myUnifyEdges (UnifyEdges),
1248 myConcatBSplines (ConcatBSplines),
1249 myAllowInternal (Standard_False),
632175c3 1250 mySafeInputMode (Standard_True),
654c48b2 1251 myShape (aShape),
1252 myHistory(new BRepTools_History)
2277323d 1253{
2277323d 1254 myContext = new ShapeBuild_ReShape;
1255}
1256
1257//=======================================================================
1258//function : Initialize
1259//purpose :
1260//=======================================================================
1261
1262void ShapeUpgrade_UnifySameDomain::Initialize(const TopoDS_Shape& aShape,
1263 const Standard_Boolean UnifyEdges,
1264 const Standard_Boolean UnifyFaces,
1265 const Standard_Boolean ConcatBSplines)
1266{
1267 myInitShape = aShape;
1268 myShape = aShape;
1269 myUnifyEdges = UnifyEdges;
1270 myUnifyFaces = UnifyFaces;
1271 myConcatBSplines = ConcatBSplines;
1272
1273 myContext->Clear();
654c48b2 1274 myRemoved.Clear();
9ed6494b 1275 myKeepShapes.Clear();
fe1a6e4e 1276}
1277
1278//=======================================================================
1279//function : AllowInternalEdges
1280//purpose :
1281//=======================================================================
1282
1283void ShapeUpgrade_UnifySameDomain::AllowInternalEdges (const Standard_Boolean theValue)
1284{
1285 myAllowInternal = theValue;
2277323d 1286}
1287
632175c3 1288//=======================================================================
1289//function : SetSafeInputMode
1290//purpose :
1291//=======================================================================
1292
1293void ShapeUpgrade_UnifySameDomain::SetSafeInputMode(Standard_Boolean theValue)
1294{
1295 mySafeInputMode = theValue;
1296}
1297
9ed6494b 1298//=======================================================================
1299//function : KeepShape
1300//purpose :
1301//=======================================================================
1302
1303void ShapeUpgrade_UnifySameDomain::KeepShape(const TopoDS_Shape& theShape)
1304{
1305 if (theShape.ShapeType() == TopAbs_EDGE || theShape.ShapeType() == TopAbs_VERTEX)
1306 myKeepShapes.Add(theShape);
1307}
1308
1309//=======================================================================
1310//function : KeepShapes
1311//purpose :
1312//=======================================================================
1313
1314void ShapeUpgrade_UnifySameDomain::KeepShapes(const TopTools_MapOfShape& theShapes)
1315{
1316 for (TopTools_MapIteratorOfMapOfShape it(theShapes); it.More(); it.Next()) {
1317 if (it.Value().ShapeType() == TopAbs_EDGE || it.Value().ShapeType() == TopAbs_VERTEX)
1318 myKeepShapes.Add(it.Value());
1319 }
1320}
1321
6a0c0b14 1322//=======================================================================
1323//function : putIntWires
1324//purpose : Add internal wires that are classified inside the face as a subshape,
1325// and remove them from the sequence
1326//=======================================================================
1327static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWires)
1328{
1329 TopoDS_Face& aFace = TopoDS::Face(theFace);
1330 for (Standard_Integer i=1; i <= theWires.Length(); i++)
1331 {
1332 TopoDS_Shape aWire = theWires(i);
1333 gp_Pnt2d aP2d;
1334 Standard_Boolean isP2d = Standard_False;
1335 for (TopoDS_Iterator it(aWire); it.More() && !isP2d; it.Next())
1336 {
1337 const TopoDS_Edge& anEdge = TopoDS::Edge(it.Value());
1338 Standard_Real aFirst, aLast;
1339 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aFace, aFirst, aLast);
1340 aC2d->D0((aFirst + aLast) * 0.5, aP2d);
1341 isP2d = Standard_True;
1342 }
1343 BRepClass_FaceClassifier aClass(aFace, aP2d, Precision::PConfusion());
1344 if (aClass.State() == TopAbs_IN)
1345 {
1346 BRep_Builder().Add(aFace, aWire);
1347 theWires.Remove(i);
1348 i--;
1349 }
1350 }
1351}
1352
2277323d 1353//=======================================================================
1354//function : UnifyFaces
1355//purpose :
1356//=======================================================================
1357
1358void ShapeUpgrade_UnifySameDomain::UnifyFaces()
1359{
fe1a6e4e 1360 // creating map of edge faces for the whole shape
1361 TopTools_IndexedDataMapOfShapeListOfShape aGMapEdgeFaces;
1362 TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aGMapEdgeFaces);
56091b56 1363
1364 // unify faces in each shell separately
2277323d 1365 TopExp_Explorer exps;
56091b56 1366 for (exps.Init(myShape, TopAbs_SHELL); exps.More(); exps.Next())
1367 IntUnifyFaces(exps.Current(), aGMapEdgeFaces, Standard_False);
1368
1369 // gather all faces out of shells in one compound and unify them at once
1370 BRep_Builder aBB;
1371 TopoDS_Compound aCmp;
1372 aBB.MakeCompound(aCmp);
1373 Standard_Integer nbf = 0;
1374 for (exps.Init(myShape, TopAbs_FACE, TopAbs_SHELL); exps.More(); exps.Next(), nbf++)
1375 aBB.Add(aCmp, exps.Current());
1376
1377 if (nbf > 0)
1378 IntUnifyFaces(aCmp, aGMapEdgeFaces, Standard_True);
1379
1380 myShape = myContext->Apply(myShape);
1381}
2277323d 1382
632175c3 1383//=======================================================================
1384//function : IntUnifyFaces
1385//purpose :
1386//=======================================================================
2277323d 1387
56091b56 1388void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape,
632175c3 1389 TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces,
56091b56 1390 Standard_Boolean IsCheckSharedEdgeOri)
1391{
1392 // creating map of edge faces for the shape
1393 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
1394 TopExp::MapShapesAndAncestors(theInpShape, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
1395
1396 // map of processed shapes
1397 TopTools_MapOfShape aProcessed;
1398
1399 Standard_Integer NbModif = 0;
1400 Standard_Boolean hasFailed = Standard_False;
1401 Standard_Real tol = Precision::Confusion();
1402
1403 // count faces
1404 Standard_Integer nbf = 0;
1405 TopExp_Explorer exp;
1406 TopTools_MapOfShape mapF;
1407 for (exp.Init(theInpShape, TopAbs_FACE); exp.More(); exp.Next()) {
1408 if (mapF.Add(exp.Current()))
1409 nbf++;
1410 }
2277323d 1411
56091b56 1412 // processing each face
1413 mapF.Clear();
1414 for (exp.Init(theInpShape, TopAbs_FACE); exp.More(); exp.Next()) {
10ce3246 1415 const TopoDS_Face& aFaceOriginal = TopoDS::Face(exp.Current());
1416 TopoDS_Face aFace = TopoDS::Face(aFaceOriginal.Oriented(TopAbs_FORWARD));
2277323d 1417
56091b56 1418 if (aProcessed.Contains(aFace))
1419 continue;
2277323d 1420
56091b56 1421 Standard_Integer dummy;
1422 TopTools_SequenceOfShape edges;
1423 AddOrdinaryEdges(edges,aFace,dummy);
2277323d 1424
56091b56 1425 TopTools_SequenceOfShape faces;
1426 faces.Append(aFace);
1427
1428 //surface and location to construct result
1429 TopLoc_Location aBaseLocation;
1430 Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(aFace,aBaseLocation);
1431 aBaseSurface = ClearRts(aBaseSurface);
1432
1433 // find adjacent faces to union
1434 Standard_Integer i;
1435 for (i = 1; i <= edges.Length(); i++) {
1436 TopoDS_Edge edge = TopoDS::Edge(edges(i));
1437 if (BRep_Tool::Degenerated(edge))
1438 continue;
2277323d 1439
56091b56 1440 // get connectivity of the edge in the global shape
1441 const TopTools_ListOfShape& aGList = theGMapEdgeFaces.FindFromKey(edge);
9ed6494b 1442 if (!myAllowInternal && (aGList.Extent() != 2 || myKeepShapes.Contains(edge))) {
56091b56 1443 // non mainfold case is not processed unless myAllowInternal
1444 continue;
1445 }
10ce3246 1446 //
1447 // get normal of the face to compare it with normals of other faces
1448 gp_Dir aDN1;
1449 //
1450 // take intermediate point on edge to compute the normal
1451 Standard_Real f, l;
1452 BRep_Tool::Range(edge, f, l);
1453 Standard_Real aTMid = (f + l) * .5;
1454 //
1455 Standard_Boolean bCheckNormals = GetNormalToSurface(aFaceOriginal, edge, aTMid, aDN1);
1456 //
56091b56 1457 // process faces connected through the edge in the current shape
1458 const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
1459 TopTools_ListIteratorOfListOfShape anIter(aList);
1460 for (; anIter.More(); anIter.Next()) {
10ce3246 1461 const TopoDS_Face& aCheckedFaceOriginal = TopoDS::Face(anIter.Value());
1462 TopoDS_Face anCheckedFace = TopoDS::Face(aCheckedFaceOriginal.Oriented(TopAbs_FORWARD));
56091b56 1463 if (anCheckedFace.IsSame(aFace))
fe1a6e4e 1464 continue;
2277323d 1465
56091b56 1466 if (aProcessed.Contains(anCheckedFace))
1467 continue;
2277323d 1468
56091b56 1469 if (IsCheckSharedEdgeOri && !CheckSharedEdgeOri(aFace, anCheckedFace, edge) )
1470 continue;
2277323d 1471
10ce3246 1472 if (bCheckNormals) {
1473 // get normal of checked face using the same parameter on edge
1474 gp_Dir aDN2;
1475 if (GetNormalToSurface(aCheckedFaceOriginal, edge, aTMid, aDN2)) {
1476 // and check if the adjacent faces are having approximately same normals
1477 Standard_Real anAngle = aDN1.Angle(aDN2);
1478 if (anAngle > myAngTol) {
1479 continue;
1480 }
1481 }
1482 }
1483 //
2ba9eb30 1484 if (IsSameDomain(aFace,anCheckedFace, myLinTol, myAngTol)) {
f0144633 1485
56091b56 1486 // hotfix for 27271: prevent merging along periodic direction.
d3dadd23 1487 if (IsLikeSeam(edge, anCheckedFace, aBaseSurface))
56091b56 1488 continue;
2277323d 1489
56091b56 1490 // replacing pcurves
1491 TopoDS_Face aMockUpFace;
1492 BRep_Builder B;
1493 B.MakeFace(aMockUpFace,aBaseSurface,aBaseLocation,0.);
632175c3 1494 MovePCurves(aMockUpFace, anCheckedFace, mySafeInputMode,
1495 myContext);
1496
1497 if (mySafeInputMode) {
1498 UpdateMapEdgeFaces(anCheckedFace, myContext, theGMapEdgeFaces);
1499 UpdateMapEdgeFaces(anCheckedFace, myContext, aMapEdgeFaces);
1500 }
2277323d 1501
56091b56 1502 if (AddOrdinaryEdges(edges,aMockUpFace,dummy)) {
1503 // sequence edges is modified
1504 i = dummy;
2277323d 1505 }
56091b56 1506
1507 faces.Append(anCheckedFace);
1508 aProcessed.Add(anCheckedFace);
1509 break;
2277323d 1510 }
1511 }
56091b56 1512 }
2277323d 1513
56091b56 1514 if (faces.Length() > 1) {
1515 // fill in the connectivity map for selected faces
1516 TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1517 for (i = 1; i <= faces.Length(); i++) {
1518 TopExp::MapShapesAndAncestors(faces(i), TopAbs_EDGE, TopAbs_FACE, aMapEF);
1519 }
632175c3 1520 if (mySafeInputMode)
1521 UpdateMapOfShapes(myKeepShapes, myContext);
9ed6494b 1522 // Collect keep edges and multiconnected edges, i.e. edges that are internal to
56091b56 1523 // the set of selected faces and have connections to other faces.
9ed6494b 1524 TopTools_ListOfShape aKeepEdges;
56091b56 1525 for (i = 1; i <= aMapEF.Extent(); i++) {
1526 const TopTools_ListOfShape& aLF = aMapEF(i);
1527 if (aLF.Extent() == 2) {
1528 const TopoDS_Shape& aE = aMapEF.FindKey(i);
1529 const TopTools_ListOfShape& aGLF = theGMapEdgeFaces.FindFromKey(aE);
9ed6494b 1530 if (aGLF.Extent() > 2 || myKeepShapes.Contains(aE)) {
1531 aKeepEdges.Append(aE);
fe1a6e4e 1532 }
1533 }
9ed6494b 1534 }
1535 if (!aKeepEdges.IsEmpty()) {
1536 if (!myAllowInternal) {
1537 // Remove from the selection the faces which have no other connect edges
1538 // and contain multiconnected edges and/or keep edges.
56091b56 1539 TopTools_MapOfShape anAvoidFaces;
9ed6494b 1540 TopTools_ListIteratorOfListOfShape it(aKeepEdges);
56091b56 1541 for (; it.More(); it.Next()) {
1542 const TopoDS_Shape& aE = it.Value();
1543 const TopTools_ListOfShape& aLF = aMapEF.FindFromKey(aE);
1544 anAvoidFaces.Add(aLF.First());
1545 anAvoidFaces.Add(aLF.Last());
1546 }
9ed6494b 1547 for (i = 1; i <= faces.Length(); i++) {
56091b56 1548 if (anAvoidFaces.Contains(faces(i))) {
1549 // update the boundaries of merged area, for that
1550 // remove from 'edges' the edges of this face and add to 'edges'
1551 // the edges of this face that were not present in 'edges' before
9ed6494b 1552 Standard_Boolean hasConnectAnotherFaces = Standard_False;
56091b56 1553 TopExp_Explorer ex(faces(i), TopAbs_EDGE);
9ed6494b 1554 for (; ex.More() && !hasConnectAnotherFaces; ex.Next()) {
56091b56 1555 TopoDS_Shape aE = ex.Current();
9ed6494b 1556 const TopTools_ListOfShape& aLF = aMapEF.FindFromKey(aE);
1557 if (aLF.Extent() > 1) {
1558 for (it.Init(aLF); it.More() && !hasConnectAnotherFaces; it.Next()) {
1559 if (!anAvoidFaces.Contains(it.Value()))
1560 hasConnectAnotherFaces = Standard_True;
1561 }
1562 }
1563 }
1564 if (!hasConnectAnotherFaces) {
1565 AddOrdinaryEdges(edges, faces(i), dummy);
1566 faces.Remove(i);
1567 i--;
1568 }
1569 }
1570 }
1571 // check if the faces with keep edges contained in
1572 // already updated the boundaries of merged area
1573 if (!faces.IsEmpty()) {
1574 TopTools_MapOfShape aMapFaces;
1575 for (i = 1; i <= faces.Length(); i++) {
1576 aMapFaces.Add(faces(i));
1577 }
1578 for (it.Init(aKeepEdges); it.More(); it.Next()) {
1579 const TopoDS_Shape& aE = it.Value();
1580 const TopTools_ListOfShape& aLF = aMapEF.FindFromKey(aE);
1581 if (aLF.Extent() < 2)
1582 continue;
1583 if (aMapFaces.Contains(aLF.First()) &&
1584 aMapFaces.Contains(aLF.Last())) {
1585 for (i = 1; i <= faces.Length(); i++) {
1586 if (faces(i).IsEqual(aLF.First()) ||
1587 faces(i).IsEqual(aLF.Last())) {
1588 AddOrdinaryEdges(edges, faces(i), dummy);
1589 faces.Remove(i);
1590 i--;
1591 }
cb120537 1592 }
cb120537 1593 }
fe1a6e4e 1594 }
1595 }
56091b56 1596 }
1597 else {
9ed6494b 1598 // add multiconnected and keep edges as internal in new face
1599 TopTools_ListIteratorOfListOfShape it(aKeepEdges);
56091b56 1600 for (; it.More(); it.Next()) {
1601 const TopoDS_Shape& aE = it.Value();
1602 edges.Append(aE.Oriented(TopAbs_INTERNAL));
fe1a6e4e 1603 }
1604 }
1605 }
56091b56 1606 }
fe1a6e4e 1607
56091b56 1608 // all faces collected in the sequence. Perform union of faces
1609 if (faces.Length() > 1) {
1610 NbModif++;
1611 TopoDS_Face aResult;
1612 BRep_Builder B;
1613 B.MakeFace(aResult,aBaseSurface,aBaseLocation,0);
1614 Standard_Integer nbWires = 0;
1615
1616 TopoDS_Face tmpF = TopoDS::Face(myContext->Apply(faces(1).Oriented(TopAbs_FORWARD)));
20aa0d3f 1617
1618 TopTools_IndexedMapOfShape anOldEdges;
1619 for (int j = 1; j <= faces.Length(); j++) {
1620 TopExp::MapShapes(faces(j), TopAbs_EDGE, anOldEdges);
1621 }
1622 TopTools_IndexedMapOfShape aMapEdgesAndVertexes;
1623 for (int j = 1; j <= edges.Length(); j++) {
1624 TopExp::MapShapes(edges(j), aMapEdgesAndVertexes);
1625 }
654c48b2 1626
1627 for (int j = 1; j <= anOldEdges.Extent(); j++)
1628 {
20aa0d3f 1629 const TopoDS_Edge& anEdge = TopoDS::Edge(anOldEdges(j));
654c48b2 1630 if (!aMapEdgesAndVertexes.Contains(anEdge))
1631 {
1632 myRemoved.Add(anEdge);
1633
20aa0d3f 1634 TopoDS_Vertex V[2];
1635 TopExp::Vertices(anEdge, V[0], V[1]);
654c48b2 1636 for (int k = 0; k < 2; k++)
1637 {
20aa0d3f 1638 if (!aMapEdgesAndVertexes.Contains(V[k]))
654c48b2 1639 {
1640 myRemoved.Add(V[k]);
1641 }
20aa0d3f 1642 }
1643 }
1644 }
1645
56091b56 1646 // connecting wires
1647 while (edges.Length()>0) {
1648
1649 Standard_Boolean isEdge3d = Standard_False;
1650 nbWires++;
1651 TopTools_MapOfShape aVertices;
1652 TopoDS_Wire aWire;
1653 B.MakeWire(aWire);
1654
1655 TopoDS_Edge anEdge = TopoDS::Edge(edges(1));
1656 edges.Remove(1);
1657 // collect internal edges in separate wires
1658 Standard_Boolean isInternal = (anEdge.Orientation() == TopAbs_INTERNAL);
1659
1660 isEdge3d |= !BRep_Tool::Degenerated(anEdge);
1661 B.Add(aWire,anEdge);
1662 TopoDS_Vertex V1,V2;
1663 TopExp::Vertices(anEdge,V1,V2);
1664 aVertices.Add(V1);
1665 aVertices.Add(V2);
1666
1667 Standard_Boolean isNewFound = Standard_False;
1668 do {
1669 isNewFound = Standard_False;
1670 for(Standard_Integer j = 1; j <= edges.Length(); j++) {
1671 anEdge = TopoDS::Edge(edges(j));
1672 // check if the current edge orientation corresponds to the first one
1673 Standard_Boolean isCurrInternal = (anEdge.Orientation() == TopAbs_INTERNAL);
1674 if (isCurrInternal != isInternal)
1675 continue;
1676 TopExp::Vertices(anEdge,V1,V2);
1677 if(aVertices.Contains(V1) || aVertices.Contains(V2)) {
1678 isEdge3d |= !BRep_Tool::Degenerated(anEdge);
1679 aVertices.Add(V1);
1680 aVertices.Add(V2);
1681 B.Add(aWire,anEdge);
1682 edges.Remove(j);
1683 j--;
1684 isNewFound = Standard_True;
2277323d 1685 }
2277323d 1686 }
56091b56 1687 } while (isNewFound);
1688
1689 // sorting any type of edges
1690 aWire.Closed (BRep_Tool::IsClosed (aWire));
1691 aWire = TopoDS::Wire(myContext->Apply(aWire));
1692
1693 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(aWire,tmpF,Precision::Confusion());
632175c3 1694 if (mySafeInputMode)
1695 sfw->SetContext(myContext);
56091b56 1696 sfw->FixReorder();
1697 Standard_Boolean isDegRemoved = Standard_False;
1698 if(!sfw->StatusReorder ( ShapeExtend_FAIL )) {
1699 // clear degenerated edges if at least one with 3d curve exist
2277323d 1700 if(isEdge3d) {
56091b56 1701 Handle(ShapeExtend_WireData) sewd = sfw->WireData();
1702 for(Standard_Integer j = 1; j<=sewd->NbEdges();j++) {
1703 TopoDS_Edge E = sewd->Edge(j);
1704 if(BRep_Tool::Degenerated(E)) {
1705 sewd->Remove(j);
1706 isDegRemoved = Standard_True;
654c48b2 1707 myRemoved.Add(E);
56091b56 1708 j--;
2277323d 1709 }
2277323d 1710 }
2277323d 1711 }
56091b56 1712 sfw->FixShifted();
1713 if(isDegRemoved)
1714 sfw->FixDegenerated();
2277323d 1715 }
56091b56 1716 TopoDS_Wire aWireFixed = sfw->Wire();
56091b56 1717 myContext->Replace(aWire,aWireFixed);
2277323d 1718
56091b56 1719 // add resulting wire
1720 if(isEdge3d) {
1721 B.Add(aResult,aWireFixed);
1722 }
1723 else {
1724 // sorting edges
1725 Handle(ShapeExtend_WireData) sbwd = sfw->WireData();
1726 Standard_Integer nbEdges = sbwd->NbEdges();
1727 // sort degenerated edges and create one edge instead of several ones
1728 ShapeAnalysis_WireOrder sawo(Standard_False, 0);
1729 ShapeAnalysis_Edge sae;
1730 Standard_Integer aLastEdge = nbEdges;
1731 for(Standard_Integer j = 1; j <= nbEdges; j++) {
1732 Standard_Real f,l;
1733 //smh protection on NULL pcurve
1734 Handle(Geom2d_Curve) c2d;
1735 if(!sae.PCurve(sbwd->Edge(j),tmpF,c2d,f,l)) {
1736 aLastEdge--;
1737 continue;
38c2acd4 1738 }
56091b56 1739 sawo.Add(c2d->Value(f).XY(),c2d->Value(l).XY());
2277323d 1740 }
d3dadd23 1741 if (sawo.NbEdges() == 0)
1742 continue;
56091b56 1743 sawo.Perform();
1744
1745 // constructind one degenerative edge
1746 gp_XY aStart, anEnd, tmp;
1747 Standard_Integer nbFirst = sawo.Ordered(1);
1748 TopoDS_Edge anOrigE = TopoDS::Edge(sbwd->Edge(nbFirst).Oriented(TopAbs_FORWARD));
1749 ShapeBuild_Edge sbe;
1750 TopoDS_Vertex aDummyV;
1751 TopoDS_Edge E = sbe.CopyReplaceVertices(anOrigE,aDummyV,aDummyV);
1752 sawo.XY(nbFirst,aStart,tmp);
1753 sawo.XY(sawo.Ordered(aLastEdge),tmp,anEnd);
1754
1755 gp_XY aVec = anEnd-aStart;
1756 Handle(Geom2d_Line) aLine = new Geom2d_Line(aStart,gp_Dir2d(anEnd-aStart));
1757
1758 B.UpdateEdge(E,aLine,tmpF,0.);
1759 B.Range(E,tmpF,0.,aVec.Modulus());
1760 Handle(Geom_Curve) C3d;
1761 B.UpdateEdge(E,C3d,0.);
1762 B.Degenerated(E,Standard_True);
1763 TopoDS_Wire aW;
1764 B.MakeWire(aW);
1765 B.Add(aW,E);
1766 aW.Closed (Standard_True);
1767 B.Add(aResult,aW);
1768 }
1769 }
2277323d 1770
56091b56 1771 // perform substitution of face
56091b56 1772 myContext->Replace(myContext->Apply(aFace),aResult);
2277323d 1773
56091b56 1774 ShapeFix_Face sff (aResult);
1775 //Intializing by tolerances
1776 sff.SetPrecision(Precision::Confusion());
1777 sff.SetMinTolerance(tol);
1778 sff.SetMaxTolerance(1.);
1779 //Setting modes
1780 sff.FixOrientationMode() = 0;
1781 //sff.FixWireMode() = 0;
56091b56 1782 sff.SetContext(myContext);
1783 // Applying the fixes
1784 sff.Perform();
1785 if(sff.Status(ShapeExtend_FAIL))
1786 hasFailed = Standard_True;
2277323d 1787
56091b56 1788 // breaking down to several faces
56091b56 1789 TopoDS_Shape theResult = myContext->Apply(aResult);
1790 for (TopExp_Explorer aFaceExp (theResult,TopAbs_FACE); aFaceExp.More(); aFaceExp.Next()) {
1791 TopoDS_Face aCurrent = TopoDS::Face(aFaceExp.Current().Oriented(TopAbs_FORWARD));
1792 Handle(TColGeom_HArray2OfSurface) grid = new TColGeom_HArray2OfSurface ( 1, 1, 1, 1 );
1793 grid->SetValue ( 1, 1, aBaseSurface );
1794 Handle(ShapeExtend_CompositeSurface) G = new ShapeExtend_CompositeSurface ( grid );
1795 ShapeFix_ComposeShell CompShell;
1796 CompShell.Init ( G, aBaseLocation, aCurrent, ::Precision::Confusion() );//myPrecision
56091b56 1797 CompShell.SetContext( myContext );
1798
1799 TopTools_SequenceOfShape parts, anIntWires;
1800 ShapeFix_SequenceOfWireSegment wires;
1801 for(TopExp_Explorer W_Exp(aCurrent,TopAbs_WIRE);W_Exp.More();W_Exp.Next()) {
1802 const TopoDS_Wire& aWire = TopoDS::Wire(W_Exp.Current());
1803 // check if the wire is ordinary (contains non-internal edges)
1804 Standard_Boolean isInternal = Standard_True;
1805 for (TopoDS_Iterator it(aWire); it.More() && isInternal; it.Next())
1806 isInternal = (it.Value().Orientation() == TopAbs_INTERNAL);
1807 if (isInternal)
1808 {
1809 // place internal wire separately
1810 anIntWires.Append(aWire);
1811 }
1812 else
2277323d 1813 {
56091b56 1814 Handle(ShapeExtend_WireData) sbwd =
1815 new ShapeExtend_WireData (aWire);
1816 ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
1817 wires.Append(seg);
2277323d 1818 }
2277323d 1819 }
1820
632175c3 1821 CompShell.DispatchWires( parts, wires );
56091b56 1822 for (Standard_Integer j=1; j <= parts.Length(); j++ ) {
1823 ShapeFix_Face aFixOrient(TopoDS::Face(parts(j)));
56091b56 1824 aFixOrient.SetContext(myContext);
1825 aFixOrient.FixOrientation();
1826 // put internal wires to faces
1827 putIntWires(parts(j), anIntWires);
f7d70540 1828 }
2277323d 1829
56091b56 1830 TopoDS_Shape CompRes;
1831 if ( parts.Length() !=1 ) {
1832 TopoDS_Shell S;
1833 B.MakeShell ( S );
1834 for ( i=1; i <= parts.Length(); i++ )
1835 B.Add ( S, parts(i) );
1836 S.Closed (BRep_Tool::IsClosed (S));
1837 CompRes = S;
1838 }
1839 else CompRes = parts(1);
1840
56091b56 1841 myContext->Replace(aCurrent,CompRes);
2277323d 1842 }
56091b56 1843
654c48b2 1844 const TopoDS_Shape aResult3 = myContext->Apply(theResult);
1845 myContext->Merge(faces, aResult3);
56091b56 1846 }
1847 } // end processing each face
1848
1849 //TopoDS_Shape aResult = Shape;
1850 if (NbModif > 0 && !hasFailed) {
56091b56 1851 TopoDS_Shape aResult = myContext->Apply(theInpShape);
1852
1853 ShapeFix_Edge sfe;
1854 if (!myContext.IsNull()) sfe.SetContext(myContext);
1855 for (exp.Init(aResult,TopAbs_EDGE); exp.More(); exp.Next()) {
1856 TopoDS_Edge E = TopoDS::Edge(exp.Current());
1857 sfe.FixVertexTolerance (E);
1858 // ptv add fix same parameter
1859 sfe.FixSameParameter(E, Precision::Confusion());
2277323d 1860 }
56091b56 1861
1862 myContext->Replace(theInpShape, aResult);
56091b56 1863 }
1864 //else
1865 {
1866 for (exp.Init(theInpShape, TopAbs_FACE); exp.More(); exp.Next()) {
1867 TopoDS_Face aFace = TopoDS::Face(exp.Current().Oriented(TopAbs_FORWARD));
1868 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
1869 sfw->SetContext(myContext);
1870 sfw->SetPrecision(Precision::Confusion());
1871 sfw->SetMinTolerance(Precision::Confusion());
1872 sfw->SetMaxTolerance(1.);
1873 sfw->SetFace(aFace);
1874 for (TopoDS_Iterator iter (aFace,Standard_False); iter.More(); iter.Next()) {
1875 TopoDS_Wire wire = TopoDS::Wire(iter.Value());
1876 sfw->Load(wire);
1877 sfw->FixReorder();
1878 sfw->FixShifted();
2277323d 1879 }
1880 }
56091b56 1881 }
2277323d 1882
2277323d 1883}
1884
1885//=======================================================================
1886//function : UnifyEdges
1887//purpose :
1888//=======================================================================
2277323d 1889void ShapeUpgrade_UnifySameDomain::UnifyEdges()
1890{
632175c3 1891 TopoDS_Shape aRes = myContext->Apply(myShape);
2277323d 1892
ce41efde 1893 TopTools_IndexedMapOfShape ChangedFaces;
2277323d 1894
ce41efde 1895 // creating map of edge faces
1896 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
632175c3 1897 TopExp::MapShapesAndAncestors(aRes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
ce41efde 1898
1899 // creating map of vertex edges
1900 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgesVertex;
632175c3 1901 TopExp::MapShapesAndUniqueAncestors(aRes, TopAbs_VERTEX, TopAbs_EDGE, aMapEdgesVertex);
f7d70540 1902
1903 TopTools_MapOfShape SharedVert;
1904
f7d70540 1905 TopTools_IndexedMapOfShape anOldEdges;
1906 TopExp::MapShapes(myInitShape, TopAbs_EDGE, anOldEdges);
1907
1908 TopTools_DataMapOfShapeShape NewEdges2OldEdges;
1909 for (int i = 1; i <= anOldEdges.Extent(); i++)
1910 {
632175c3 1911 const TopoDS_Shape& anOldEdge = anOldEdges(i);
1912 TopoDS_Shape aNewEdge = myContext->Apply(anOldEdge);
1913 if (!aNewEdge.IsNull() && !aNewEdge.IsSame(anOldEdge))
1914 NewEdges2OldEdges.Bind(aNewEdge, anOldEdge);
f7d70540 1915 }
ce41efde 1916
632175c3 1917 if (mySafeInputMode)
1918 UpdateMapOfShapes(myKeepShapes, myContext);
1919
ce41efde 1920 TopExp_Explorer exp;
f7d70540 1921 // processing separate wires
1922 for (exp.Init(aRes, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next())
1923 {
1924 TopTools_SequenceOfShape SeqEdges;
1925 TopExp_Explorer expE(exp.Current(), TopAbs_EDGE);
1926 for (; expE.More(); expE.Next())
1927 SeqEdges.Append(expE.Current());
1928 SharedVert.Clear();
9ed6494b 1929 CheckSharedVertices(SeqEdges, aMapEdgesVertex, myKeepShapes, SharedVert);
654c48b2 1930 MergeSeq(SeqEdges, myAngTol, myConcatBSplines, mySafeInputMode, myContext,
1931 SharedVert, myRemoved);
f7d70540 1932 }
1933
1934 // processing each face
ce41efde 1935 for (exp.Init(aRes, TopAbs_FACE); exp.More(); exp.Next()) {
632175c3 1936 TopoDS_Shape aFace = exp.Current().Oriented(TopAbs_FORWARD);
ce41efde 1937 TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges;
f7d70540 1938 TopTools_SequenceOfShape aNonSharedEdges;
ce41efde 1939 for (TopExp_Explorer expe(aFace,TopAbs_EDGE); expe.More(); expe.Next()) {
1940 TopoDS_Edge edge = TopoDS::Edge(expe.Current());
ce41efde 1941 const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
1942 TopTools_ListIteratorOfListOfShape anIter(aList);
f7d70540 1943 Standard_Integer NbFacesPerEdge = aList.Extent();
ce41efde 1944 for ( ; anIter.More(); anIter.Next()) {
632175c3 1945 const TopoDS_Shape& aFace1 = anIter.Value();
1946 if (aFace1.IsSame(aFace) && NbFacesPerEdge != 1)
f7d70540 1947 continue;
1948 if (NbFacesPerEdge == 1)
1949 //store non-shared edges separately
1950 aNonSharedEdges.Append(edge);
1951 else
1952 {
632175c3 1953 if (aMapFacesEdges.Contains(aFace1))
1954 aMapFacesEdges.ChangeFromKey(aFace1).Append(edge);
f7d70540 1955 else
1956 {
1957 TopTools_ListOfShape ListEdges;
1958 ListEdges.Append(edge);
632175c3 1959 aMapFacesEdges.Add(aFace1, ListEdges);
f7d70540 1960 }
2277323d 1961 }
1962 }
ce41efde 1963 }
f7d70540 1964
1965 for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++)
1966 {
ce41efde 1967 const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
1968 TopTools_SequenceOfShape SeqEdges;
ce41efde 1969 TopTools_ListIteratorOfListOfShape anIter(ListEdges);
ce41efde 1970 for ( ; anIter.More(); anIter.Next())
1971 SeqEdges.Append(anIter.Value());
1972 if (SeqEdges.Length()==1)
1973 continue;
2277323d 1974
f7d70540 1975 SharedVert.Clear();
9ed6494b 1976 CheckSharedVertices(SeqEdges, aMapEdgesVertex, myKeepShapes, SharedVert);
632175c3 1977 if (MergeSeq(SeqEdges, myAngTol, myConcatBSplines, mySafeInputMode,
654c48b2 1978 myContext, SharedVert, myRemoved))
2277323d 1979 {
ce41efde 1980 TopoDS_Face tmpF = TopoDS::Face(exp.Current());
1981 if ( !ChangedFaces.Contains(tmpF) )
1982 ChangedFaces.Add(tmpF);
1983 tmpF = TopoDS::Face(aMapFacesEdges.FindKey(i));
1984 if ( !ChangedFaces.Contains(tmpF) )
1985 ChangedFaces.Add(tmpF);
2277323d 1986 }
ce41efde 1987 }
f7d70540 1988
1989 if ( aNonSharedEdges.Length() > 1 )
1990 {
1991 SharedVert.Clear();
9ed6494b 1992 CheckSharedVertices(aNonSharedEdges, aMapEdgesVertex, myKeepShapes, SharedVert);
632175c3 1993 if (MergeSeq(aNonSharedEdges, myAngTol, myConcatBSplines, mySafeInputMode,
654c48b2 1994 myContext, SharedVert, myRemoved))
f7d70540 1995 {
1996 TopoDS_Face tmpF = TopoDS::Face(exp.Current());
1997 if ( !ChangedFaces.Contains(tmpF) )
1998 ChangedFaces.Add(tmpF);
1999 }
2000 }
ce41efde 2001
2002 } // end processing each face
2003
2004 // fix changed faces and replace them in the local context
632175c3 2005 Standard_Real aPrec = Precision::Confusion();
2006 for (Standard_Integer i = 1; i <= ChangedFaces.Extent(); i++) {
ce41efde 2007 TopoDS_Face aFace = TopoDS::Face(myContext->Apply(ChangedFaces.FindKey(i)));
f7d70540 2008 if (aFace.IsNull())
2009 continue;
ce41efde 2010 Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFace);
2011 sff->SetContext(myContext);
632175c3 2012 sff->SetPrecision(aPrec);
2013 sff->SetMinTolerance(aPrec);
2014 sff->SetMaxTolerance(Max(1., aPrec*1000.));
ce41efde 2015 sff->Perform();
2016 TopoDS_Shape aNewFace = sff->Face();
ce41efde 2017 myContext->Replace(aFace,aNewFace);
ce41efde 2018 }
2019
2020 if (ChangedFaces.Extent() > 0) {
2021 // fix changed shell and replace it in the local context
ce41efde 2022 TopoDS_Shape aRes1 = myContext->Apply(aRes);
632175c3 2023 Standard_Boolean isChanged = Standard_False;
ce41efde 2024 TopExp_Explorer expsh;
2025 for (expsh.Init(aRes1, TopAbs_SHELL); expsh.More(); expsh.Next()) {
2026 TopoDS_Shell aShell = TopoDS::Shell(expsh.Current());
2027 Handle(ShapeFix_Shell) sfsh = new ShapeFix_Shell;
2028 sfsh->FixFaceOrientation(aShell);
2029 TopoDS_Shape aNewShell = sfsh->Shell();
632175c3 2030 if (!aNewShell.IsSame(aShell)) {
2031 myContext->Replace(aShell, aNewShell);
2032 isChanged = Standard_True;
2277323d 2033 }
ce41efde 2034 }
632175c3 2035 if (isChanged)
2036 aRes1 = myContext->Apply(aRes1);
2037 myContext->Replace(myShape, aRes1);
ce41efde 2038 }
2277323d 2039
2040 myShape = myContext->Apply(myShape);
2041}
2042
2043//=======================================================================
2044//function : UnifyFacesAndEdges
2045//purpose :
2046//=======================================================================
2047
2048void ShapeUpgrade_UnifySameDomain::UnifyFacesAndEdges()
2049{
2050 UnifyFaces();
2051
2052 /*
2053 ShapeUpgrade_RemoveLocations RemLoc;
2054 RemLoc.Remove(myShape);
2055 myShape = RemLoc.GetResult();
2056 */
2057
2058 UnifyEdges();
2059}
2060
2061//=======================================================================
2062//function : Build
2063//purpose : builds the resulting shape
2064//======================================================================
2065void ShapeUpgrade_UnifySameDomain::Build()
2066{
2067 if (myUnifyFaces && myUnifyEdges)
2068 UnifyFacesAndEdges();
2069
2070 else if (myUnifyEdges)
2071 UnifyEdges();
2072 else if (myUnifyFaces)
2073 UnifyFaces();
2074
654c48b2 2075 if (!myHistory.IsNull())
2076 {
2077 myHistory->Merge(myContext->History());
2078 for (TopTools_MapOfShape::Iterator aIt(myRemoved);
2079 aIt.More(); aIt.Next())
2080 {
2081 myHistory->Remove(aIt.Value());
2082 }
20aa0d3f 2083 }
f7d70540 2084
654c48b2 2085 //Done();
2277323d 2086}