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