0027235: Export GDT: Annotation plane and Presentation.
[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>
f7d70540 89
92efcf78 90IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_UnifySameDomain,MMgt_TShared)
91
f7d70540 92struct SubSequenceOfEdges
93{
94 TopTools_SequenceOfShape SeqsEdges;
95 TopoDS_Edge UnionEdges;
96};
97
2277323d 98
99//=======================================================================
100//function : AddOrdinaryEdges
101//purpose : auxilary
102//=======================================================================
103// adds edges from the shape to the sequence
104// seams and equal edges are dropped
105// Returns true if one of original edges dropped
106static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges,
107 const TopoDS_Shape aShape,
108 Standard_Integer& anIndex)
109{
110 //map of edges
111 TopTools_IndexedMapOfShape aNewEdges;
112 //add edges without seams
113 for(TopExp_Explorer exp(aShape,TopAbs_EDGE); exp.More(); exp.Next()) {
114 TopoDS_Shape edge = exp.Current();
115 if(aNewEdges.Contains(edge))
116 {
117 //aNewEdges.Remove(edge);
118 TopoDS_Shape LastEdge = aNewEdges(aNewEdges.Extent());
119 aNewEdges.RemoveLast();
120 if (aNewEdges.FindIndex(edge) != 0)
121 aNewEdges.Substitute(aNewEdges.FindIndex(edge), LastEdge);
122 /////////////////////////
123 }
124 else
125 aNewEdges.Add(edge);
126 }
127
128 Standard_Boolean isDropped = Standard_False;
129 //merge edges and drop seams
130 Standard_Integer i;
131 for (i = 1; i <= edges.Length(); i++) {
132 TopoDS_Shape current = edges(i);
133 if(aNewEdges.Contains(current)) {
134
135 //aNewEdges.Remove(current);
136 TopoDS_Shape LastEdge = aNewEdges(aNewEdges.Extent());
137 aNewEdges.RemoveLast();
138 if (aNewEdges.FindIndex(current) != 0)
139 aNewEdges.Substitute(aNewEdges.FindIndex(current), LastEdge);
140 /////////////////////////
141 edges.Remove(i);
142 i--;
143
144 if(!isDropped) {
145 isDropped = Standard_True;
146 anIndex = i;
147 }
148 }
149 }
150
151 //add edges to the sequemce
152 for (i = 1; i <= aNewEdges.Extent(); i++)
153 edges.Append(aNewEdges(i));
154
155 return isDropped;
156}
157
158//=======================================================================
159//function : getCylinder
160//purpose : auxilary
161//=======================================================================
162static Standard_Boolean getCylinder(Handle(Geom_Surface)& theInSurface,
163 gp_Cylinder& theOutCylinder)
164{
165 Standard_Boolean isCylinder = Standard_False;
166
167 if (theInSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
168 Handle(Geom_CylindricalSurface) aGC = Handle(Geom_CylindricalSurface)::DownCast(theInSurface);
169
170 theOutCylinder = aGC->Cylinder();
171 isCylinder = Standard_True;
172 }
173 else if (theInSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
174 Handle(Geom_SurfaceOfRevolution) aRS =
175 Handle(Geom_SurfaceOfRevolution)::DownCast(theInSurface);
176 Handle(Geom_Curve) aBasis = aRS->BasisCurve();
177 if (aBasis->IsKind(STANDARD_TYPE(Geom_Line))) {
178 Handle(Geom_Line) aBasisLine = Handle(Geom_Line)::DownCast(aBasis);
179 gp_Dir aDir = aRS->Direction();
180 gp_Dir aBasisDir = aBasisLine->Position().Direction();
181 if (aBasisDir.IsParallel(aDir, Precision::Angular())) {
182 // basis line is parallel to the revolution axis: it is a cylinder
183 gp_Pnt aLoc = aRS->Location();
184 Standard_Real aR = aBasisLine->Lin().Distance(aLoc);
185 gp_Ax3 aCylAx (aLoc, aDir);
186
187 theOutCylinder = gp_Cylinder(aCylAx, aR);
188 isCylinder = Standard_True;
189 }
190 }
191 }
192 else if (theInSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
193 Handle(Geom_SurfaceOfLinearExtrusion) aLES =
194 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(theInSurface);
195 Handle(Geom_Curve) aBasis = aLES->BasisCurve();
196 if (aBasis->IsKind(STANDARD_TYPE(Geom_Circle))) {
197 Handle(Geom_Circle) aBasisCircle = Handle(Geom_Circle)::DownCast(aBasis);
198 gp_Dir aDir = aLES->Direction();
199 gp_Dir aBasisDir = aBasisCircle->Position().Direction();
200 if (aBasisDir.IsParallel(aDir, Precision::Angular())) {
201 // basis circle is normal to the extrusion axis: it is a cylinder
202 gp_Pnt aLoc = aBasisCircle->Location();
203 Standard_Real aR = aBasisCircle->Radius();
204 gp_Ax3 aCylAx (aLoc, aDir);
205
206 theOutCylinder = gp_Cylinder(aCylAx, aR);
207 isCylinder = Standard_True;
208 }
209 }
210 }
211 else {
212 }
213
214 return isCylinder;
215}
216
217//=======================================================================
218//function : ClearRts
219//purpose : auxilary
220//=======================================================================
221static Handle(Geom_Surface) ClearRts(const Handle(Geom_Surface)& aSurface)
222{
223 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
224 Handle(Geom_RectangularTrimmedSurface) rts =
225 Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
226 return rts->BasisSurface();
227 }
228 return aSurface;
229}
230
231//=======================================================================
232//function : IsSameDomain
233//purpose :
234//=======================================================================
235static Standard_Boolean IsSameDomain(const TopoDS_Face& aFace,
236 const TopoDS_Face& aCheckedFace)
237{
238 //checking the same handles
239 TopLoc_Location L1, L2;
240 Handle(Geom_Surface) S1, S2;
241
242 S1 = BRep_Tool::Surface(aFace,L1);
243 S2 = BRep_Tool::Surface(aCheckedFace,L2);
244
245 if (S1 == S2 && L1 == L2)
246 return Standard_True;
247
248 // planar and cylindrical cases (IMP 20052)
249 Standard_Real aPrec = Precision::Confusion();
250
251 S1 = BRep_Tool::Surface(aFace);
252 S2 = BRep_Tool::Surface(aCheckedFace);
253
254 S1 = ClearRts(S1);
255 S2 = ClearRts(S2);
256
257 //Handle(Geom_OffsetSurface) aGOFS1, aGOFS2;
258 //aGOFS1 = Handle(Geom_OffsetSurface)::DownCast(S1);
259 //aGOFS2 = Handle(Geom_OffsetSurface)::DownCast(S2);
260 //if (!aGOFS1.IsNull()) S1 = aGOFS1->BasisSurface();
261 //if (!aGOFS2.IsNull()) S2 = aGOFS2->BasisSurface();
262
263 // case of two elementary surfaces: use OCCT tool
264 // elementary surfaces: ConicalSurface, CylindricalSurface,
265 // Plane, SphericalSurface and ToroidalSurface
266 if (S1->IsKind(STANDARD_TYPE(Geom_ElementarySurface)) &&
267 S2->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
268 {
269 Handle(GeomAdaptor_HSurface) aGA1 = new GeomAdaptor_HSurface(S1);
270 Handle(GeomAdaptor_HSurface) aGA2 = new GeomAdaptor_HSurface(S2);
271
272 Handle(BRepTopAdaptor_TopolTool) aTT1 = new BRepTopAdaptor_TopolTool();
273 Handle(BRepTopAdaptor_TopolTool) aTT2 = new BRepTopAdaptor_TopolTool();
274
275 try {
276 IntPatch_ImpImpIntersection anIIInt (aGA1, aTT1, aGA2, aTT2, aPrec, aPrec);
277 if (!anIIInt.IsDone() || anIIInt.IsEmpty())
278 return Standard_False;
279
280 return anIIInt.TangentFaces();
281 }
282 catch (Standard_Failure) {
283 return Standard_False;
284 }
285 }
286
287 // case of two planar surfaces:
288 // all kinds of surfaces checked, including b-spline and bezier
289 GeomLib_IsPlanarSurface aPlanarityChecker1 (S1, aPrec);
290 if (aPlanarityChecker1.IsPlanar()) {
291 GeomLib_IsPlanarSurface aPlanarityChecker2 (S2, aPrec);
292 if (aPlanarityChecker2.IsPlanar()) {
293 gp_Pln aPln1 = aPlanarityChecker1.Plan();
294 gp_Pln aPln2 = aPlanarityChecker2.Plan();
295
296 if (aPln1.Position().Direction().IsParallel(aPln2.Position().Direction(),Precision::Angular()) &&
297 aPln1.Distance(aPln2) < aPrec) {
298 return Standard_True;
299 }
300 }
301 }
302
303 // case of two cylindrical surfaces, at least one of which is a swept surface
304 // swept surfaces: SurfaceOfLinearExtrusion, SurfaceOfRevolution
305 if ((S1->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
306 S1->IsKind(STANDARD_TYPE(Geom_SweptSurface))) &&
307 (S2->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
308 S2->IsKind(STANDARD_TYPE(Geom_SweptSurface))))
309 {
310 gp_Cylinder aCyl1, aCyl2;
311 if (getCylinder(S1, aCyl1) && getCylinder(S2, aCyl2)) {
312 if (fabs(aCyl1.Radius() - aCyl2.Radius()) < aPrec) {
313 gp_Dir aDir1 = aCyl1.Position().Direction();
314 gp_Dir aDir2 = aCyl2.Position().Direction();
315 if (aDir1.IsParallel(aDir2, Precision::Angular())) {
316 gp_Pnt aLoc1 = aCyl1.Location();
317 gp_Pnt aLoc2 = aCyl2.Location();
318 gp_Vec aVec12 (aLoc1, aLoc2);
319 if (aVec12.SquareMagnitude() < aPrec*aPrec ||
320 aVec12.IsParallel(aDir1, Precision::Angular())) {
321 return Standard_True;
322 }
323 }
324 }
325 }
326 }
327
328 return Standard_False;
329}
330
331//=======================================================================
332//function : MovePCurves
333//purpose :
334//=======================================================================
335static void MovePCurves(TopoDS_Face& aTarget,
336 const TopoDS_Face& aSource)
337{
338 BRep_Builder B;
339 for(TopExp_Explorer wexp(aSource,TopAbs_WIRE);wexp.More();wexp.Next()) {
340 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(TopoDS::Wire(wexp.Current()),
341 aTarget, Precision::Confusion());
342 sfw->FixReorder();
343 Standard_Boolean isReoredFailed = sfw->StatusReorder ( ShapeExtend_FAIL );
344 sfw->FixEdgeCurves();
345 if(isReoredFailed)
346 continue;
347
348 sfw->FixShifted();
349 sfw->FixDegenerated();
350
351 // remove degenerated edges from not degenerated points
352 ShapeAnalysis_Edge sae;
353 Handle(ShapeExtend_WireData) sewd = sfw->WireData();
354 for(Standard_Integer i = 1; i<=sewd->NbEdges();i++) {
355 TopoDS_Edge E = sewd->Edge(i);
356 if(BRep_Tool::Degenerated(E)&&!sae.HasPCurve(E,aTarget)) {
357 sewd->Remove(i);
358 i--;
359 }
360 }
361
362 TopoDS_Wire ResWire = sfw->Wire();
363 B.Add(aTarget,ResWire);
364 }
365}
366
367//=======================================================================
368//function : GlueEdgesWithPCurves
369//purpose : Glues the pcurves of the sequence of edges
370// and glues their 3d curves
371//=======================================================================
372static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain,
373 const TopoDS_Vertex& FirstVertex,
374 const TopoDS_Vertex& LastVertex)
375{
376 Standard_Integer i, j;
377
378 TopoDS_Edge FirstEdge = TopoDS::Edge(aChain(1));
379 //TColGeom2d_SequenceOfCurve PCurveSeq;
380 TColGeom_SequenceOfSurface SurfSeq;
381 //TopTools_SequenceOfShape LocSeq;
382
383 BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(FirstEdge.TShape()))->Curves() );
384 for (; itr.More(); itr.Next())
385 {
386 Handle(BRep_CurveRepresentation) CurveRep = itr.Value();
387 if (CurveRep->IsCurveOnSurface())
388 {
389 //PCurveSeq.Append(CurveRep->PCurve());
390 SurfSeq.Append(CurveRep->Surface());
391 /*
392 TopoDS_Shape aLocShape;
393 aLocShape.Location(CurveRep->Location());
394 LocSeq.Append(aLocShape);
395 */
396 }
397 }
398
399 Standard_Real fpar, lpar;
400 BRep_Tool::Range(FirstEdge, fpar, lpar);
401 TopoDS_Edge PrevEdge = FirstEdge;
402 TopoDS_Vertex CV;
403 Standard_Real MaxTol = 0.;
404
405 TopoDS_Edge ResEdge;
406 BRep_Builder BB;
407
408 Standard_Integer nb_curve = aChain.Length(); //number of curves
409 TColGeom_Array1OfBSplineCurve tab_c3d(0,nb_curve-1); //array of the curves
410 TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2); //array of the tolerances
411
412 TopoDS_Vertex PrevVertex = FirstVertex;
413 for (i = 1; i <= nb_curve; i++)
414 {
415 TopoDS_Edge anEdge = TopoDS::Edge(aChain(i));
416 TopoDS_Vertex VF, VL;
417 TopExp::Vertices(anEdge, VF, VL);
418 Standard_Boolean ToReverse = (!VF.IsSame(PrevVertex));
419
420 Standard_Real Tol1 = BRep_Tool::Tolerance(VF);
421 Standard_Real Tol2 = BRep_Tool::Tolerance(VL);
422 if (Tol1 > MaxTol)
423 MaxTol = Tol1;
424 if (Tol2 > MaxTol)
425 MaxTol = Tol2;
426
427 if (i > 1)
428 {
429 TopExp::CommonVertex(PrevEdge, anEdge, CV);
430 Standard_Real Tol = BRep_Tool::Tolerance(CV);
431 tabtolvertex(i-2) = Tol;
432 }
433
434 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
435 Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, fpar, lpar);
436 tab_c3d(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
437 GeomConvert::C0BSplineToC1BSplineCurve(tab_c3d(i-1), Precision::Confusion());
438 if (ToReverse)
439 tab_c3d(i-1)->Reverse();
440 PrevVertex = (ToReverse)? VF : VL;
441 PrevEdge = anEdge;
442 }
443 Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves
444 Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex
445 GeomConvert::ConcatC1(tab_c3d,
446 tabtolvertex,
447 ArrayOfIndices,
448 concatcurve,
449 Standard_False,
450 Precision::Confusion()); //C1 concatenation
451
452 if (concatcurve->Length() > 1)
453 {
454 GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
455
456 for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
457 Concat.Add( concatcurve->Value(i), MaxTol, Standard_True );
458
459 concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
460 }
461 Handle(Geom_BSplineCurve) ResCurve = concatcurve->Value(concatcurve->Lower());
462
463 TColGeom2d_SequenceOfBoundedCurve ResPCurves;
464 TopLoc_Location aLoc;
465 for (j = 1; j <= SurfSeq.Length(); j++)
466 {
467 TColGeom2d_Array1OfBSplineCurve tab_c2d(0,nb_curve-1); //array of the pcurves
468
469 PrevVertex = FirstVertex;
470 PrevEdge = FirstEdge;
471 //TopLoc_Location theLoc = LocSeq(j).Location();
472 for (i = 1; i <= nb_curve; i++)
473 {
474 TopoDS_Edge anEdge = TopoDS::Edge(aChain(i));
475 TopoDS_Vertex VF, VL;
476 TopExp::Vertices(anEdge, VF, VL);
477 Standard_Boolean ToReverse = (!VF.IsSame(PrevVertex));
478
479 /*
480 Handle(Geom2d_Curve) aPCurve =
481 BRep_Tool::CurveOnSurface(anEdge, SurfSeq(j), anEdge.Location()*theLoc, fpar, lpar);
482 */
483 Handle(Geom2d_Curve) aPCurve =
484 BRep_Tool::CurveOnSurface(anEdge, SurfSeq(j), aLoc, fpar, lpar);
485 Handle(Geom2d_TrimmedCurve) aTrPCurve = new Geom2d_TrimmedCurve(aPCurve, fpar, lpar);
486 tab_c2d(i-1) = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
487 Geom2dConvert::C0BSplineToC1BSplineCurve(tab_c2d(i-1), Precision::Confusion());
488 if (ToReverse)
489 tab_c2d(i-1)->Reverse();
490 PrevVertex = (ToReverse)? VF : VL;
491 PrevEdge = anEdge;
492 }
493 Handle(TColGeom2d_HArray1OfBSplineCurve) concatc2d; //array of the concatenated curves
494 Handle(TColStd_HArray1OfInteger) ArrayOfInd2d; //array of the remining Vertex
495 Geom2dConvert::ConcatC1(tab_c2d,
496 tabtolvertex,
497 ArrayOfInd2d,
498 concatc2d,
499 Standard_False,
500 Precision::Confusion()); //C1 concatenation
501
502 if (concatc2d->Length() > 1)
503 {
504 Geom2dConvert_CompCurveToBSplineCurve Concat2d(concatc2d->Value(concatc2d->Lower()));
505
506 for (i = concatc2d->Lower()+1; i <= concatc2d->Upper(); i++)
507 Concat2d.Add( concatc2d->Value(i), MaxTol, Standard_True );
508
509 concatc2d->SetValue(concatc2d->Lower(), Concat2d.BSplineCurve());
510 }
511 Handle(Geom2d_BSplineCurve) aResPCurve = concatc2d->Value(concatc2d->Lower());
512 ResPCurves.Append(aResPCurve);
513 }
514
515 ResEdge = BRepLib_MakeEdge(ResCurve,
516 FirstVertex, LastVertex,
517 ResCurve->FirstParameter(), ResCurve->LastParameter());
518 BB.SameRange(ResEdge, Standard_False);
519 BB.SameParameter(ResEdge, Standard_False);
520 for (j = 1; j <= ResPCurves.Length(); j++)
521 {
522 BB.UpdateEdge(ResEdge, ResPCurves(j), SurfSeq(j), aLoc, MaxTol);
523 BB.Range(ResEdge, SurfSeq(j), aLoc, ResPCurves(j)->FirstParameter(), ResPCurves(j)->LastParameter());
524 }
525
526 BRepLib::SameParameter(ResEdge, MaxTol, Standard_True);
527
528 return ResEdge;
529}
530
cef6867c 531//=======================================================================
532//function : MergeSubSeq
533//purpose : Merges a sequence of edges into one edge if possible
534//=======================================================================
535
f7d70540 536static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& aChain, TopoDS_Edge& OutEdge, double Tol, Standard_Boolean ConcatBSplines)
2277323d 537{
2277323d 538 ShapeAnalysis_Edge sae;
f7d70540 539 BRep_Builder B;
2277323d 540 // union edges in chain
f7d70540 541 int j;
2277323d 542 Standard_Real fp1,lp1,fp2,lp2;
f7d70540 543 Standard_Boolean IsUnionOfLinesPossible = Standard_True;
544 Standard_Boolean IsUnionOfCirclesPossible = Standard_True;
545 Handle(Geom_Curve) c3d1, c3d2;
546 for(j=1; j<aChain.Length(); j++)
547 {
2277323d 548 TopoDS_Edge edge1 = TopoDS::Edge(aChain.Value(j));
f7d70540 549 c3d1 = BRep_Tool::Curve(edge1,fp1,lp1);
550
551 TopoDS_Edge edge2 = TopoDS::Edge(aChain.Value(j+1));
552 c3d2 = BRep_Tool::Curve(edge2,fp2,lp2);
553
554 if(c3d1.IsNull() || c3d2.IsNull())
555 return Standard_False;
b4d4dbe8 556
2277323d 557 while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
558 Handle(Geom_TrimmedCurve) tc =
559 Handle(Geom_TrimmedCurve)::DownCast(c3d1);
560 c3d1 = tc->BasisCurve();
561 }
2277323d 562 while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
563 Handle(Geom_TrimmedCurve) tc =
564 Handle(Geom_TrimmedCurve)::DownCast(c3d2);
565 c3d2 = tc->BasisCurve();
566 }
567 if( c3d1->IsKind(STANDARD_TYPE(Geom_Line)) && c3d2->IsKind(STANDARD_TYPE(Geom_Line)) ) {
2277323d 568 Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(c3d1);
569 Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(c3d2);
570 gp_Dir Dir1 = L1->Position().Direction();
571 gp_Dir Dir2 = L2->Position().Direction();
f7d70540 572 if(!Dir1.IsParallel(Dir2,Tol))
573 IsUnionOfLinesPossible = Standard_False;
2277323d 574 }
f7d70540 575 else
576 IsUnionOfLinesPossible = Standard_False;
2277323d 577 if( c3d1->IsKind(STANDARD_TYPE(Geom_Circle)) && c3d2->IsKind(STANDARD_TYPE(Geom_Circle)) ) {
2277323d 578 Handle(Geom_Circle) C1 = Handle(Geom_Circle)::DownCast(c3d1);
579 Handle(Geom_Circle) C2 = Handle(Geom_Circle)::DownCast(c3d2);
580 gp_Pnt P01 = C1->Location();
581 gp_Pnt P02 = C2->Location();
b4d4dbe8 582 if (P01.Distance(P02) > Precision::Confusion())
f7d70540 583 IsUnionOfCirclesPossible = Standard_False;
584 }
585 else
586 IsUnionOfCirclesPossible = Standard_False;
587 }
588 if (IsUnionOfLinesPossible && IsUnionOfCirclesPossible)
589 return Standard_False;
590
591 //union of lines is possible
592 if (IsUnionOfLinesPossible)
593 {
594 TopoDS_Vertex V1 = sae.FirstVertex(TopoDS::Edge(aChain.First()));
595 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
596 TopoDS_Vertex V2 = sae.LastVertex(TopoDS::Edge(aChain.Last()));
597 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
598 gp_Vec Vec(PV1, PV2);
599 Handle(Geom_Line) L = new Geom_Line(gp_Ax1(PV1,Vec));
600 Standard_Real dist = PV1.Distance(PV2);
601 Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(L,0.0,dist);
602 TopoDS_Edge E;
603 B.MakeEdge (E, tc ,Precision::Confusion());
604 B.Add (E,V1); B.Add (E,V2);
605 B.UpdateVertex(V1, 0., E, 0.);
606 B.UpdateVertex(V2, dist, E, 0.);
607 OutEdge = E;
608 return Standard_True;
609 }
610
611 if (IsUnionOfCirclesPossible)
612 {
613 double f,l;
614 TopoDS_Edge FE = TopoDS::Edge(aChain.First());
615 Handle(Geom_Curve) c3d = BRep_Tool::Curve(FE,f,l);
616
617 while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
618 Handle(Geom_TrimmedCurve) tc =
619 Handle(Geom_TrimmedCurve)::DownCast(c3d);
620 c3d = tc->BasisCurve();
621 }
622 Handle(Geom_Circle) Cir = Handle(Geom_Circle)::DownCast(c3d);
623
624 TopoDS_Vertex V1 = sae.FirstVertex(FE);
f7d70540 625 TopoDS_Vertex V2 = sae.LastVertex(TopoDS::Edge(aChain.Last()));
f7d70540 626 TopoDS_Edge E;
dd2f1b75 627 if (V1.IsSame(V2)) {
f7d70540 628 // closed chain
dd2f1b75 629 BRepAdaptor_Curve adef(FE);
630 Handle(Geom_Circle) Cir1;
631 double FP, LP;
632 if ( FE.Orientation() == TopAbs_FORWARD)
633 {
634 FP = adef.FirstParameter();
635 LP = adef.LastParameter();
636 }
637 else
638 {
639 FP = adef.LastParameter();
640 LP = adef.FirstParameter();
641 }
642 if (Abs(FP) < Precision::PConfusion())
643 {
fe1a6e4e 644 B.MakeEdge (E,Cir,Precision::Confusion());
645 B.Add(E,V1);
646 B.Add(E,V2);
647 E.Orientation(FE.Orientation());
648 }
dd2f1b75 649 else
650 {
651 GC_MakeCircle MC1 (adef.Value(FP), adef.Value((FP + LP) * 0.5), adef.Value(LP));
652 if (MC1.IsDone())
653 Cir1 = MC1.Value();
654 else
655 return Standard_False;
656 B.MakeEdge (E, Cir1, Precision::Confusion());
657 B.Add(E,V1);
658 B.Add(E,V2);
659 }
f7d70540 660 }
661 else {
dd2f1b75 662 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
663 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
664 TopoDS_Vertex VM = sae.LastVertex(FE);
665 gp_Pnt PVM = BRep_Tool::Pnt(VM);
666 GC_MakeCircle MC (PV1,PVM,PV2);
f7d70540 667 Handle(Geom_Circle) C = MC.Value();
668 gp_Pnt P0 = C->Location();
669 gp_Dir D1(gp_Vec(P0,PV1));
670 gp_Dir D2(gp_Vec(P0,PV2));
671 Standard_Real fpar = C->XAxis().Direction().Angle(D1);
672 if(fabs(fpar)>Precision::Confusion()) {
673 // check orientation
674 gp_Dir ND = C->XAxis().Direction().Crossed(D1);
675 if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) {
676 fpar = -fpar;
2277323d 677 }
f7d70540 678 }
679 Standard_Real lpar = C->XAxis().Direction().Angle(D2);
680 if(fabs(lpar)>Precision::Confusion()) {
681 // check orientation
682 gp_Dir ND = C->XAxis().Direction().Crossed(D2);
683 if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) {
684 lpar = -lpar;
2277323d 685 }
2277323d 686 }
f7d70540 687 if (lpar < fpar) lpar += 2*M_PI;
688 Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar);
689 B.MakeEdge (E,tc,Precision::Confusion());
690 B.Add(E,V1);
691 B.Add(E,V2);
692 B.UpdateVertex(V1, fpar, E, 0.);
693 B.UpdateVertex(V2, lpar, E, 0.);
2277323d 694 }
f7d70540 695 OutEdge = E;
696 return Standard_True;
2277323d 697 }
698 if (aChain.Length() > 1 && ConcatBSplines) {
699 // second step: union edges with various curves
700 // skl for bug 0020052 from Mantis: perform such unions
701 // only if curves are bspline or bezier
f7d70540 702
703 TopoDS_Vertex VF = sae.FirstVertex(TopoDS::Edge(aChain.First()));
704 TopoDS_Vertex VL = sae.LastVertex(TopoDS::Edge(aChain.Last()));
705 Standard_Boolean NeedUnion = Standard_True;
2277323d 706 for(j=1; j<=aChain.Length(); j++) {
707 TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j));
b4d4dbe8 708 TopLoc_Location Loc;
2277323d 709 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,Loc,fp1,lp1);
710 if(c3d.IsNull()) continue;
711 while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
712 Handle(Geom_TrimmedCurve) tc =
713 Handle(Geom_TrimmedCurve)::DownCast(c3d);
714 c3d = tc->BasisCurve();
715 }
716 if( ( c3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) ||
717 c3d->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ) ) continue;
f7d70540 718 NeedUnion = Standard_False;
2277323d 719 break;
720 }
721 if(NeedUnion) {
0797d9d3 722#ifdef OCCT_DEBUG
2277323d 723 cout<<"can not make analitical union => make approximation"<<endl;
724#endif
725 TopoDS_Edge E = GlueEdgesWithPCurves(aChain, VF, VL);
f7d70540 726 OutEdge = E;
727 return Standard_True;
2277323d 728 }
729 else {
0797d9d3 730#ifdef OCCT_DEBUG
2277323d 731 cout<<"can not make approximation for such types of curves"<<endl;
732#endif
733 return Standard_False;
734 }
735 }
f7d70540 736 return Standard_False;
737}
738
cef6867c 739//=======================================================================
740//function : IsMergingPossible
741//purpose : Checks if merging of two edges is possible
742//=======================================================================
743
f7d70540 744static Standard_Boolean IsMergingPossible(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2,
745 double Tol, const TopTools_MapOfShape& DegEdgeVrt)
746{
747 TopoDS_Vertex CV = TopExp::LastVertex(edge1, Standard_True);
748 if (CV.IsNull() || DegEdgeVrt.Contains(CV))
749 return Standard_False;
750
751 BRepAdaptor_Curve ade1(edge1);
752 BRepAdaptor_Curve ade2(edge2);
753
754 GeomAbs_CurveType t1 = ade1.GetType();
755 GeomAbs_CurveType t2 = ade2.GetType();
756
757 if( t1 == GeomAbs_Circle && t2 == GeomAbs_Circle)
758 {
759 if (ade1.Circle().Location().Distance(ade2.Circle().Location()) > Precision::Confusion())
760 return Standard_False;
761 }
762
763 if( ( (t1 != GeomAbs_BezierCurve && t1 != GeomAbs_BSplineCurve) ||
764 (t2 != GeomAbs_BezierCurve && t2 != GeomAbs_BSplineCurve)) && t1 != t2)
765 return Standard_False;
766
767 gp_Vec Diff1, Diff2;
768 gp_Pnt P1, P2;
769 if (edge1.Orientation() == TopAbs_FORWARD)
770 ade1.D1(ade1.LastParameter(), P1, Diff1);
771 else
772 {
773 ade1.D1(ade1.FirstParameter(), P1, Diff1);
774 Diff1 = -Diff1;
775 }
776
777 if (edge2.Orientation() == TopAbs_FORWARD)
778 ade2.D1(ade2.FirstParameter(), P2, Diff2);
779 else
780 {
781 ade2.D1(ade2.LastParameter(), P2, Diff2);
782 Diff2 = -Diff2;
783 }
784
785 if (Diff1.Angle(Diff2) > Tol)
786 return Standard_False;
787
788 return Standard_True;
789}
790
cef6867c 791//=======================================================================
792//function : GenerateSubSeq
793//purpose : Generates sub-sequences of edges from sequence of edges
794//Edges from each subsequences can be merged into the one edge
795//=======================================================================
796
f7d70540 797static void GenerateSubSeq (const TopTools_SequenceOfShape& anInpEdgeSeq,
798 NCollection_Sequence<SubSequenceOfEdges>& SeqOfSubSeqOfEdges,
799 Standard_Boolean IsClosed, double Tol, const TopTools_MapOfShape& DegEdgeVrt )
800{
801 Standard_Boolean isOk = Standard_False;
802 TopoDS_Edge edge1, edge2;
803
804 SubSequenceOfEdges SubSeq;
805 SubSeq.SeqsEdges.Append(TopoDS::Edge(anInpEdgeSeq(1)));
806 SeqOfSubSeqOfEdges.Append(SubSeq);
807
808 for (int i = 1; i < anInpEdgeSeq.Length(); i++)
809 {
810 edge1 = TopoDS::Edge(anInpEdgeSeq(i));
811 edge2 = TopoDS::Edge(anInpEdgeSeq(i+1));
812 isOk = IsMergingPossible(edge1, edge2, Tol, DegEdgeVrt);
813 if (!isOk)
814 {
51740958 815 SubSequenceOfEdges aSubSeq;
816 aSubSeq.SeqsEdges.Append(edge2);
817 SeqOfSubSeqOfEdges.Append(aSubSeq);
f7d70540 818 }
819 else
820 SeqOfSubSeqOfEdges.ChangeLast().SeqsEdges.Append(edge2);
821 }
822 /// check first and last chain segments
823 if (IsClosed && SeqOfSubSeqOfEdges.Length() > 1)
824 {
825 edge1 = TopoDS::Edge(anInpEdgeSeq.Last());
826 edge2 = TopoDS::Edge(anInpEdgeSeq.First());
827 if (IsMergingPossible(edge1, edge2, Tol, DegEdgeVrt))
828 {
829 SeqOfSubSeqOfEdges.ChangeLast().SeqsEdges.Append(SeqOfSubSeqOfEdges.ChangeFirst().SeqsEdges);
830 SeqOfSubSeqOfEdges.Remove(1);
831 }
832 }
833}
834
835
836//=======================================================================
837//function : MergeEdges
838//purpose : auxilary
839//=======================================================================
840static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
841 const Standard_Real Tol,
842 const Standard_Boolean ConcatBSplines,
843 NCollection_Sequence<SubSequenceOfEdges>& SeqOfSubSeqOfEdges,
844 const TopTools_MapOfShape& NonMergVrt )
845{
846 // make chain for union
847 //BRep_Builder B;
848 ShapeAnalysis_Edge sae;
849 TopoDS_Edge FirstE = TopoDS::Edge(SeqEdges.Value(1));
850 TopoDS_Edge LastE = FirstE;
851 TopoDS_Vertex VF = sae.FirstVertex(FirstE);
852 TopoDS_Vertex VL = sae.LastVertex(LastE);
853 TopTools_SequenceOfShape aChain;
854 aChain.Append(FirstE);
855 TColStd_MapOfInteger IndUsedEdges;
856 IndUsedEdges.Add(1);
857 Standard_Integer j;
858 TopTools_MapOfShape VerticesToAvoid;
859 TopTools_SequenceOfShape SeqEdges1;
860 for (j = 1; j <= SeqEdges.Length(); j++)
861 {
862 TopoDS_Edge anEdge = TopoDS::Edge(SeqEdges(j));
863 if (BRep_Tool::Degenerated(anEdge))
864 {
865 TopoDS_Vertex V1, V2;
866 TopExp::Vertices(anEdge, V1, V2);
867 VerticesToAvoid.Add(V1);
868 VerticesToAvoid.Add(V2);
869 continue;
870 }
871 SeqEdges1.Append(anEdge);
872 }
873
874 for(j=2; j<=SeqEdges1.Length(); j++) {
875 for(Standard_Integer k=2; k<=SeqEdges1.Length(); k++) {
876 if(IndUsedEdges.Contains(k)) continue;
877 TopoDS_Edge edge = TopoDS::Edge(SeqEdges1.Value(k));
878 TopoDS_Vertex VF2 = sae.FirstVertex(edge);
879 TopoDS_Vertex VL2 = sae.LastVertex(edge);
880 if(VF2.IsSame(VL)) {
881 aChain.Append(edge);
882 LastE = edge;
883 VL = sae.LastVertex(LastE);
884 IndUsedEdges.Add(k);
885 }
886 else if(VL2.IsSame(VF)) {
887 aChain.Prepend(edge);
888 FirstE = edge;
889 VF = sae.FirstVertex(FirstE);
890 IndUsedEdges.Add(k);
891 }
892 }
893 }
f7d70540 894
895 Standard_Boolean IsClosed = Standard_False;
896 if (VF.IsSame ( VL ))
897 IsClosed = Standard_True;
2277323d 898
f7d70540 899 VerticesToAvoid.Unite(NonMergVrt);
900 GenerateSubSeq(aChain, SeqOfSubSeqOfEdges, IsClosed, Tol, VerticesToAvoid);
901
902 for (int i = 1; i <= SeqOfSubSeqOfEdges.Length(); i++)
903 {
904 TopoDS_Edge UE;
905 if (SeqOfSubSeqOfEdges(i).SeqsEdges.Length() < 2)
906 continue;
907 if (MergeSubSeq(SeqOfSubSeqOfEdges(i).SeqsEdges, UE, Tol, ConcatBSplines))
908 SeqOfSubSeqOfEdges(i).UnionEdges = UE;
909 }
2277323d 910 return Standard_True;
911}
912
cef6867c 913//=======================================================================
914//function : MergeSeq
915//purpose : Tries to unify the sequence of edges with the set of another edges
916//which lies on the same geometry
917//=======================================================================
918
f7d70540 919static Standard_Boolean MergeSeq (const TopTools_SequenceOfShape& SeqEdges,
920 const Standard_Real Tol,
921 const Standard_Boolean ConcatBSplines,
922 Handle(ShapeBuild_ReShape)& theContext,
923 TopTools_DataMapOfShapeShape& theOldShapes,
924 const TopTools_MapOfShape& nonMergVert,
925 const TopTools_DataMapOfShapeShape& NewEdges2OldEdges)
926{
927 NCollection_Sequence<SubSequenceOfEdges> SeqOfSubsSeqOfEdges;
928 int k = 1;
929 if ( MergeEdges(SeqEdges, Tol, ConcatBSplines, SeqOfSubsSeqOfEdges, nonMergVert) )
930 {
931 for (Standard_Integer i = 1; i <= SeqOfSubsSeqOfEdges.Length(); i++ )
932 {
933 if (SeqOfSubsSeqOfEdges(i).UnionEdges.IsNull())
934 continue;
935 theContext->Replace(SeqOfSubsSeqOfEdges(i).SeqsEdges(1), SeqOfSubsSeqOfEdges(i).UnionEdges);
936 k++;
937 for (Standard_Integer j = 2; j <= SeqOfSubsSeqOfEdges(i).SeqsEdges.Length(); j++)
938 {
939 TopoDS_Shape OldEdge = NewEdges2OldEdges(SeqOfSubsSeqOfEdges(i).SeqsEdges(j));
940 theOldShapes.Bind(OldEdge, SeqOfSubsSeqOfEdges(i).UnionEdges);
941 theContext->Remove(SeqOfSubsSeqOfEdges(i).SeqsEdges(j));
942 }
943 }
944 return Standard_True;
945 }
946 else
947 return Standard_False;
948}
949
cef6867c 950//=======================================================================
951//function : CheckSharedVertices
952//purpose : Checks the sequence of edges on the presence of shared vertex
953//=======================================================================
954
f7d70540 955static void CheckSharedVertices(const TopTools_SequenceOfShape& theSeqEdges,
956 const TopTools_IndexedDataMapOfShapeListOfShape& theMapEdgesVertex,
957 TopTools_MapOfShape& theShareVertMap)
958{
959 ShapeAnalysis_Edge sae;
960 TopTools_SequenceOfShape SeqVertexes;
961 TopTools_MapOfShape MapVertexes;
962 for (Standard_Integer k = 1; k <= theSeqEdges.Length(); k++ )
963 {
964 TopoDS_Vertex aV1 = sae.FirstVertex(TopoDS::Edge(theSeqEdges(k)));
965 TopoDS_Vertex aV2 = sae.LastVertex(TopoDS::Edge(theSeqEdges(k)));
966 if (!MapVertexes.Add(aV1))
967 SeqVertexes.Append(aV1);
968 if (!MapVertexes.Add(aV2))
969 SeqVertexes.Append(aV2);
970 }
971
972 for (Standard_Integer k = 1; k <= SeqVertexes.Length()/* && !IsSharedVertexPresent*/; k++ )
973 {
974 const TopTools_ListOfShape& ListEdgesV1 = theMapEdgesVertex.FindFromKey(SeqVertexes(k));
975 TopTools_MapOfShape aMapOfEdges;
976 TopTools_ListIteratorOfListOfShape iter(ListEdgesV1);
977 for (; iter.More(); iter.Next())
978 aMapOfEdges.Add(iter.Value());
979 if (aMapOfEdges.Extent() > 2)
980 theShareVertMap.Add(SeqVertexes(k));
981 }
982 //return theShareVertMap.IsEmpty() ? false : true;
983}
984
2277323d 985//=======================================================================
986//function : ShapeUpgrade_UnifySameDomain
987//purpose : Constructor
988//=======================================================================
989
990ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain()
fe1a6e4e 991 : myUnifyFaces (Standard_True),
992 myUnifyEdges (Standard_True),
993 myConcatBSplines (Standard_False),
994 myAllowInternal (Standard_False)
2277323d 995{
2277323d 996 myContext = new ShapeBuild_ReShape;
997}
998
999//=======================================================================
1000//function : ShapeUpgrade_UnifySameDomain
1001//purpose : Constructor
1002//=======================================================================
1003
1004ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain(const TopoDS_Shape& aShape,
1005 const Standard_Boolean UnifyEdges,
1006 const Standard_Boolean UnifyFaces,
1007 const Standard_Boolean ConcatBSplines)
fe1a6e4e 1008 : myInitShape (aShape),
1009 myUnifyFaces (UnifyFaces),
1010 myUnifyEdges (UnifyEdges),
1011 myConcatBSplines (ConcatBSplines),
1012 myAllowInternal (Standard_False),
1013 myShape (aShape)
2277323d 1014{
2277323d 1015 myContext = new ShapeBuild_ReShape;
1016}
1017
1018//=======================================================================
1019//function : Initialize
1020//purpose :
1021//=======================================================================
1022
1023void ShapeUpgrade_UnifySameDomain::Initialize(const TopoDS_Shape& aShape,
1024 const Standard_Boolean UnifyEdges,
1025 const Standard_Boolean UnifyFaces,
1026 const Standard_Boolean ConcatBSplines)
1027{
1028 myInitShape = aShape;
1029 myShape = aShape;
1030 myUnifyEdges = UnifyEdges;
1031 myUnifyFaces = UnifyFaces;
1032 myConcatBSplines = ConcatBSplines;
1033
1034 myContext->Clear();
f7d70540 1035 myOldShapes.Clear();
fe1a6e4e 1036}
1037
1038//=======================================================================
1039//function : AllowInternalEdges
1040//purpose :
1041//=======================================================================
1042
1043void ShapeUpgrade_UnifySameDomain::AllowInternalEdges (const Standard_Boolean theValue)
1044{
1045 myAllowInternal = theValue;
2277323d 1046}
1047
6a0c0b14 1048//=======================================================================
1049//function : putIntWires
1050//purpose : Add internal wires that are classified inside the face as a subshape,
1051// and remove them from the sequence
1052//=======================================================================
1053static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWires)
1054{
1055 TopoDS_Face& aFace = TopoDS::Face(theFace);
1056 for (Standard_Integer i=1; i <= theWires.Length(); i++)
1057 {
1058 TopoDS_Shape aWire = theWires(i);
1059 gp_Pnt2d aP2d;
1060 Standard_Boolean isP2d = Standard_False;
1061 for (TopoDS_Iterator it(aWire); it.More() && !isP2d; it.Next())
1062 {
1063 const TopoDS_Edge& anEdge = TopoDS::Edge(it.Value());
1064 Standard_Real aFirst, aLast;
1065 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aFace, aFirst, aLast);
1066 aC2d->D0((aFirst + aLast) * 0.5, aP2d);
1067 isP2d = Standard_True;
1068 }
1069 BRepClass_FaceClassifier aClass(aFace, aP2d, Precision::PConfusion());
1070 if (aClass.State() == TopAbs_IN)
1071 {
1072 BRep_Builder().Add(aFace, aWire);
1073 theWires.Remove(i);
1074 i--;
1075 }
1076 }
1077}
1078
2277323d 1079//=======================================================================
1080//function : UnifyFaces
1081//purpose :
1082//=======================================================================
1083
1084void ShapeUpgrade_UnifySameDomain::UnifyFaces()
1085{
fe1a6e4e 1086 // creating map of edge faces for the whole shape
1087 TopTools_IndexedDataMapOfShapeListOfShape aGMapEdgeFaces;
1088 TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aGMapEdgeFaces);
1089
2277323d 1090 // processing each shell
1091 TopExp_Explorer exps;
1092 for (exps.Init(myShape, TopAbs_SHELL); exps.More(); exps.Next()) {
1093 TopoDS_Shell aShell = TopoDS::Shell(exps.Current());
ed5ca017 1094
fe1a6e4e 1095 // creating map of edge faces for the shell
1096 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
1097 TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
1098
2277323d 1099 // map of processed shapes
1100 TopTools_MapOfShape aProcessed;
1101
2277323d 1102 Standard_Integer NbModif = 0;
1103 Standard_Boolean hasFailed = Standard_False;
1104 Standard_Real tol = Precision::Confusion();
1105
1106 // count faces
1107 Standard_Integer nbf = 0;
1108 TopExp_Explorer exp;
1109 TopTools_MapOfShape mapF;
1110 for (exp.Init(aShell, TopAbs_FACE); exp.More(); exp.Next()) {
1111 if (mapF.Add(exp.Current()))
1112 nbf++;
1113 }
1114
1115 // processing each face
1116 mapF.Clear();
1117 for (exp.Init(aShell, TopAbs_FACE); exp.More(); exp.Next()) {
1118 TopoDS_Face aFace = TopoDS::Face(exp.Current().Oriented(TopAbs_FORWARD));
1119
1120 if (aProcessed.Contains(aFace))
1121 continue;
1122
1123 Standard_Integer dummy;
1124 TopTools_SequenceOfShape edges;
1125 AddOrdinaryEdges(edges,aFace,dummy);
1126
1127 TopTools_SequenceOfShape faces;
1128 faces.Append(aFace);
1129
1130 //surface and location to construct result
1131 TopLoc_Location aBaseLocation;
1132 Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(aFace,aBaseLocation);
1133 aBaseSurface = ClearRts(aBaseSurface);
1134
1135 // find adjacent faces to union
1136 Standard_Integer i;
1137 for (i = 1; i <= edges.Length(); i++) {
1138 TopoDS_Edge edge = TopoDS::Edge(edges(i));
1139 if (BRep_Tool::Degenerated(edge))
1140 continue;
1141
fe1a6e4e 1142 // get connectivity of the edge in the global shape
1143 const TopTools_ListOfShape& aGList = aGMapEdgeFaces.FindFromKey(edge);
1144 if (!myAllowInternal && aGList.Extent() != 2) {
1145 // non mainfold case is not processed unless myAllowInternal
1146 continue;
1147 }
1148 // process faces connected through the edge in the current shell
2277323d 1149 const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
1150 TopTools_ListIteratorOfListOfShape anIter(aList);
1151 for (; anIter.More(); anIter.Next()) {
1152 TopoDS_Face anCheckedFace = TopoDS::Face(anIter.Value().Oriented(TopAbs_FORWARD));
1153 if (anCheckedFace.IsSame(aFace))
1154 continue;
1155
1156 if (aProcessed.Contains(anCheckedFace))
1157 continue;
1158
1159 if (IsSameDomain(aFace,anCheckedFace)) {
1160
2277323d 1161 // replacing pcurves
1162 TopoDS_Face aMockUpFace;
1163 BRep_Builder B;
1164 B.MakeFace(aMockUpFace,aBaseSurface,aBaseLocation,0.);
1165 MovePCurves(aMockUpFace,anCheckedFace);
1166
1167 if (AddOrdinaryEdges(edges,aMockUpFace,dummy)) {
1168 // sequence edges is modified
1169 i = dummy;
1170 }
1171
1172 faces.Append(anCheckedFace);
1173 aProcessed.Add(anCheckedFace);
1174 break;
1175 }
1176 }
1177 }
1178
fe1a6e4e 1179 if (faces.Length() > 1) {
1180 // fill in the connectivity map for selected faces
1181 TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1182 for (i = 1; i <= faces.Length(); i++) {
1183 TopExp::MapShapesAndAncestors(faces(i), TopAbs_EDGE, TopAbs_FACE, aMapEF);
1184 }
1185
1186 // Collect multiconnected edges, i.e. edges that are internal to
1187 // the set of selected faces and have connections to other faces.
1188 TopTools_ListOfShape aMultEdges;
1189 for (i = 1; i <= aMapEF.Extent(); i++) {
1190 const TopTools_ListOfShape& aLF = aMapEF(i);
1191 if (aLF.Extent() == 2) {
1192 const TopoDS_Shape& aE = aMapEF.FindKey(i);
1193 const TopTools_ListOfShape& aGLF = aGMapEdgeFaces.FindFromKey(aE);
1194 if (aGLF.Extent() > 2) {
1195 aMultEdges.Append(aE);
1196 }
1197 }
1198 }
1199 if (!aMultEdges.IsEmpty()) {
1200 if (!myAllowInternal) {
1201 // Remove from the selection the faces containing multiconnected edges
1202 TopTools_MapOfShape anAvoidFaces;
1203 TopTools_ListIteratorOfListOfShape it(aMultEdges);
1204 for (; it.More(); it.Next()) {
1205 const TopoDS_Shape& aE = it.Value();
1206 const TopTools_ListOfShape& aLF = aMapEF.FindFromKey(aE);
1207 anAvoidFaces.Add(aLF.First());
1208 anAvoidFaces.Add(aLF.Last());
1209 }
1210 for (i = 1; i <= faces.Length(); ) {
1211 if (anAvoidFaces.Contains(faces(i)))
1212 faces.Remove(i);
1213 else
1214 i++;
1215 }
1216 }
1217 else {
1218 // add multiconnected edges as internal in new face
1219 TopTools_ListIteratorOfListOfShape it(aMultEdges);
1220 for (; it.More(); it.Next()) {
1221 const TopoDS_Shape& aE = it.Value();
1222 edges.Append(aE.Oriented(TopAbs_INTERNAL));
1223 }
1224 }
1225 }
1226 }
1227
2277323d 1228 // all faces collected in the sequence. Perform union of faces
1229 if (faces.Length() > 1) {
1230 NbModif++;
1231 TopoDS_Face aResult;
1232 BRep_Builder B;
1233 B.MakeFace(aResult,aBaseSurface,aBaseLocation,0);
1234 Standard_Integer nbWires = 0;
1235
26ca3bd5 1236 TopoDS_Face tmpF = TopoDS::Face(myContext->Apply(faces(1).Oriented(TopAbs_FORWARD)));
2277323d 1237 // connecting wires
1238 while (edges.Length()>0) {
1239
1240 Standard_Boolean isEdge3d = Standard_False;
1241 nbWires++;
1242 TopTools_MapOfShape aVertices;
1243 TopoDS_Wire aWire;
1244 B.MakeWire(aWire);
1245
1246 TopoDS_Edge anEdge = TopoDS::Edge(edges(1));
1247 edges.Remove(1);
6a0c0b14 1248 // collect internal edges in separate wires
1249 Standard_Boolean isInternal = (anEdge.Orientation() == TopAbs_INTERNAL);
2277323d 1250
1251 isEdge3d |= !BRep_Tool::Degenerated(anEdge);
1252 B.Add(aWire,anEdge);
1253 TopoDS_Vertex V1,V2;
1254 TopExp::Vertices(anEdge,V1,V2);
1255 aVertices.Add(V1);
1256 aVertices.Add(V2);
1257
1258 Standard_Boolean isNewFound = Standard_False;
1259 do {
1260 isNewFound = Standard_False;
1261 for(Standard_Integer j = 1; j <= edges.Length(); j++) {
1262 anEdge = TopoDS::Edge(edges(j));
6a0c0b14 1263 // check if the current edge orientation corresponds to the first one
1264 Standard_Boolean isCurrInternal = (anEdge.Orientation() == TopAbs_INTERNAL);
1265 if (isCurrInternal != isInternal)
1266 continue;
2277323d 1267 TopExp::Vertices(anEdge,V1,V2);
1268 if(aVertices.Contains(V1) || aVertices.Contains(V2)) {
1269 isEdge3d |= !BRep_Tool::Degenerated(anEdge);
1270 aVertices.Add(V1);
1271 aVertices.Add(V2);
1272 B.Add(aWire,anEdge);
1273 edges.Remove(j);
1274 j--;
1275 isNewFound = Standard_True;
1276 }
1277 }
1278 } while (isNewFound);
1279
1280 // sorting any type of edges
ab860031 1281 aWire.Closed (BRep_Tool::IsClosed (aWire));
2277323d 1282 aWire = TopoDS::Wire(myContext->Apply(aWire));
1283
2277323d 1284 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(aWire,tmpF,Precision::Confusion());
1285 sfw->FixReorder();
1286 Standard_Boolean isDegRemoved = Standard_False;
1287 if(!sfw->StatusReorder ( ShapeExtend_FAIL )) {
1288 // clear degenerated edges if at least one with 3d curve exist
1289 if(isEdge3d) {
1290 Handle(ShapeExtend_WireData) sewd = sfw->WireData();
1291 for(Standard_Integer j = 1; j<=sewd->NbEdges();j++) {
1292 TopoDS_Edge E = sewd->Edge(j);
1293 if(BRep_Tool::Degenerated(E)) {
1294 sewd->Remove(j);
1295 isDegRemoved = Standard_True;
1296 j--;
1297 }
1298 }
1299 }
1300 sfw->FixShifted();
1301 if(isDegRemoved)
1302 sfw->FixDegenerated();
1303 }
1304 TopoDS_Wire aWireFixed = sfw->Wire();
1305 //aContext->Replace(aWire,aWireFixed);
1306 myContext->Replace(aWire,aWireFixed);
1307 //for history
1308 /*
1309 if (!myOldNewMap.IsBound(aWire))
1310 {
1311 TopTools_ListOfShape EmptyList;
1312 myOldNewMap.Bind(aWire, EmptyList);
1313 }
1314 myOldNewMap(aWire).Clear();
1315 myOldNewMap(aWire).Append(aWireFixed);
1316 */
1317 /////////////
1318
1319 // add resulting wire
1320 if(isEdge3d) {
1321 B.Add(aResult,aWireFixed);
1322 }
1323 else {
1324 // sorting edges
1325 Handle(ShapeExtend_WireData) sbwd = sfw->WireData();
1326 Standard_Integer nbEdges = sbwd->NbEdges();
1327 // sort degenerated edges and create one edge instead of several ones
1328 ShapeAnalysis_WireOrder sawo(Standard_False, 0);
1329 ShapeAnalysis_Edge sae;
1330 Standard_Integer aLastEdge = nbEdges;
1331 for(Standard_Integer j = 1; j <= nbEdges; j++) {
1332 Standard_Real f,l;
1333 //smh protection on NULL pcurve
1334 Handle(Geom2d_Curve) c2d;
1335 if(!sae.PCurve(sbwd->Edge(j),tmpF,c2d,f,l)) {
1336 aLastEdge--;
1337 continue;
1338 }
1339 sawo.Add(c2d->Value(f).XY(),c2d->Value(l).XY());
1340 }
1341 sawo.Perform();
1342
1343 // constructind one degenerative edge
1344 gp_XY aStart, anEnd, tmp;
1345 Standard_Integer nbFirst = sawo.Ordered(1);
1346 TopoDS_Edge anOrigE = TopoDS::Edge(sbwd->Edge(nbFirst).Oriented(TopAbs_FORWARD));
1347 ShapeBuild_Edge sbe;
1348 TopoDS_Vertex aDummyV;
1349 TopoDS_Edge E = sbe.CopyReplaceVertices(anOrigE,aDummyV,aDummyV);
1350 sawo.XY(nbFirst,aStart,tmp);
1351 sawo.XY(sawo.Ordered(aLastEdge),tmp,anEnd);
1352
1353 gp_XY aVec = anEnd-aStart;
1354 Handle(Geom2d_Line) aLine = new Geom2d_Line(aStart,gp_Dir2d(anEnd-aStart));
1355
1356 B.UpdateEdge(E,aLine,tmpF,0.);
1357 B.Range(E,tmpF,0.,aVec.Modulus());
1358 Handle(Geom_Curve) C3d;
1359 B.UpdateEdge(E,C3d,0.);
1360 B.Degenerated(E,Standard_True);
1361 TopoDS_Wire aW;
1362 B.MakeWire(aW);
1363 B.Add(aW,E);
ab860031 1364 aW.Closed (Standard_True);
2277323d 1365 B.Add(aResult,aW);
1366 }
1367 }
1368
1369 // perform substitution of face
1370 //aContext->Replace(aContext->Apply(aFace),aResult);
1371 myContext->Replace(myContext->Apply(aFace),aResult);
1372 //for history
1373 /*
1374 if (!myOldNewMap.IsBound(aFace))
1375 {
1376 TopTools_ListOfShape EmptyList;
1377 myOldNewMap.Bind(aFace, EmptyList);
1378 }
1379 myOldNewMap(aFace).Clear();
1380 myOldNewMap(aFace).Append(aResult);
1381 */
1382 /////////////
1383
1384 ShapeFix_Face sff (aResult);
1385 //Intializing by tolerances
1386 sff.SetPrecision(Precision::Confusion());
1387 sff.SetMinTolerance(tol);
1388 sff.SetMaxTolerance(1.);
1389 //Setting modes
1390 sff.FixOrientationMode() = 0;
1391 //sff.FixWireMode() = 0;
1392 //sff.SetContext(aContext);
1393 sff.SetContext(myContext);
1394 // Applying the fixes
1395 sff.Perform();
1396 if(sff.Status(ShapeExtend_FAIL))
1397 hasFailed = Standard_True;
1398
1399 // breaking down to several faces
1400 //TopoDS_Shape theResult = aContext->Apply(aResult);
1401 TopoDS_Shape theResult = myContext->Apply(aResult);
1402 for (TopExp_Explorer aFaceExp (theResult,TopAbs_FACE); aFaceExp.More(); aFaceExp.Next()) {
1403 TopoDS_Face aCurrent = TopoDS::Face(aFaceExp.Current().Oriented(TopAbs_FORWARD));
1404 Handle(TColGeom_HArray2OfSurface) grid = new TColGeom_HArray2OfSurface ( 1, 1, 1, 1 );
1405 grid->SetValue ( 1, 1, aBaseSurface );
1406 Handle(ShapeExtend_CompositeSurface) G = new ShapeExtend_CompositeSurface ( grid );
1407 ShapeFix_ComposeShell CompShell;
1408 CompShell.Init ( G, aBaseLocation, aCurrent, ::Precision::Confusion() );//myPrecision
1409 //CompShell.SetContext( aContext );
1410 CompShell.SetContext( myContext );
1411
6a0c0b14 1412 TopTools_SequenceOfShape parts, anIntWires;
2277323d 1413 ShapeFix_SequenceOfWireSegment wires;
1414 for(TopExp_Explorer W_Exp(aCurrent,TopAbs_WIRE);W_Exp.More();W_Exp.Next()) {
6a0c0b14 1415 const TopoDS_Wire& aWire = TopoDS::Wire(W_Exp.Current());
1416 // check if the wire is ordinary (contains non-internal edges)
1417 Standard_Boolean isInternal = Standard_True;
1418 for (TopoDS_Iterator it(aWire); it.More() && isInternal; it.Next())
1419 isInternal = (it.Value().Orientation() == TopAbs_INTERNAL);
1420 if (isInternal)
1421 {
1422 // place internal wire separately
1423 anIntWires.Append(aWire);
1424 }
1425 else
1426 {
fe1a6e4e 1427 Handle(ShapeExtend_WireData) sbwd =
6a0c0b14 1428 new ShapeExtend_WireData (aWire);
fe1a6e4e 1429 ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
1430 wires.Append(seg);
1431 }
2277323d 1432 }
1433
1434 CompShell.DispatchWires ( parts,wires );
1435 for (Standard_Integer j=1; j <= parts.Length(); j++ ) {
1436 ShapeFix_Face aFixOrient(TopoDS::Face(parts(j)));
1437 //aFixOrient.SetContext(aContext);
1438 aFixOrient.SetContext(myContext);
1439 aFixOrient.FixOrientation();
6a0c0b14 1440 // put internal wires to faces
1441 putIntWires(parts(j), anIntWires);
2277323d 1442 }
1443
1444 TopoDS_Shape CompRes;
6a0c0b14 1445 if ( parts.Length() !=1 ) {
2277323d 1446 TopoDS_Shell S;
1447 B.MakeShell ( S );
1448 for ( i=1; i <= parts.Length(); i++ )
1449 B.Add ( S, parts(i) );
ab860031 1450 S.Closed (BRep_Tool::IsClosed (S));
2277323d 1451 CompRes = S;
1452 }
1453 else CompRes = parts(1);
1454
1455 //aContext->Replace(aCurrent,CompRes);
1456 myContext->Replace(aCurrent,CompRes);
1457 //for history
1458 /*
1459 if (!myOldNewMap.IsBound(aCurrent))
1460 {
1461 TopTools_ListOfShape EmptyList;
1462 myOldNewMap.Bind(aCurrent, EmptyList);
1463 }
1464 myOldNewMap(aCurrent).Clear();
1465 myOldNewMap(aCurrent).Append(CompRes);
1466 */
1467 /////////////
1468 }
1469
1470 // remove the remaining faces
1471 for(i = 2; i <= faces.Length(); i++)
f7d70540 1472 {
1473 myOldShapes.Bind(faces(i), theResult);
2277323d 1474 myContext->Remove(faces(i));
f7d70540 1475 }
2277323d 1476 }
1477 } // end processing each face
1478
1479 //TopoDS_Shape aResult = Shape;
1480 if (NbModif > 0 && !hasFailed) {
1481 //TopoDS_Shape aResult = aContext->Apply(aShell);
1482 TopoDS_Shape aResult = myContext->Apply(aShell);
1483
1484 ShapeFix_Edge sfe;
ed5ca017 1485 if (!myContext.IsNull()) sfe.SetContext(myContext);
2277323d 1486 for (exp.Init(aResult,TopAbs_EDGE); exp.More(); exp.Next()) {
1487 TopoDS_Edge E = TopoDS::Edge(exp.Current());
1488 sfe.FixVertexTolerance (E);
1489 // ptv add fix same parameter
1490 sfe.FixSameParameter(E, Precision::Confusion());
1491 }
1492
1493 myContext->Replace(aShell, aResult);
1494 //for history
1495 /*
1496 if (!myOldNewMap.IsBound(aShell))
1497 {
1498 TopTools_ListOfShape EmptyList;
1499 myOldNewMap.Bind(aShell, EmptyList);
1500 }
1501 myOldNewMap(aShell).Clear();
1502 myOldNewMap(aShell).Append(aResult);
1503 */
1504 /////////////
1505 }
1506 //else
1507 {
1508 for (exp.Init(aShell, TopAbs_FACE); exp.More(); exp.Next()) {
1509 TopoDS_Face aFace = TopoDS::Face(exp.Current().Oriented(TopAbs_FORWARD));
1510 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
1511 sfw->SetContext(myContext);
1512 sfw->SetPrecision(Precision::Confusion());
1513 sfw->SetMinTolerance(Precision::Confusion());
1514 sfw->SetMaxTolerance(1.);
1515 sfw->SetFace(aFace);
1516 for (TopoDS_Iterator iter (aFace,Standard_False); iter.More(); iter.Next()) {
1517 TopoDS_Wire wire = TopoDS::Wire(iter.Value());
1518 sfw->Load(wire);
1519 sfw->FixReorder();
1520 sfw->FixShifted();
1521 }
1522 }
1523 }
1524 } // end processing each shell
1525
1526 myShape = myContext->Apply(myShape);
1527}
1528
1529//=======================================================================
1530//function : UnifyEdges
1531//purpose :
1532//=======================================================================
2277323d 1533void ShapeUpgrade_UnifySameDomain::UnifyEdges()
1534{
1535 Standard_Real Tol = Precision::Confusion();
1536
1537 //Handle(ShapeBuild_ReShape) myContext = new ShapeBuild_ReShape;
1538 Standard_Real myTolerance = Precision::Confusion();
1539 TopoDS_Shape aResult = myContext->Apply(myShape);
1540
ce41efde 1541 TopTools_IndexedMapOfShape ChangedFaces;
2277323d 1542
ce41efde 1543 // creating map of edge faces
1544 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
1545 TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
1546
1547 // creating map of vertex edges
1548 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgesVertex;
1549 TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMapEdgesVertex);
1550
1551 //Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
1552 TopoDS_Shape aRes = myShape;
1553 //aRes = aContext->Apply(aSolid);
1554 aRes = myContext->Apply(myShape);
f7d70540 1555
1556 TopTools_MapOfShape SharedVert;
1557
1558
1559 TopTools_IndexedMapOfShape anOldEdges;
1560 TopExp::MapShapes(myInitShape, TopAbs_EDGE, anOldEdges);
1561
1562 TopTools_DataMapOfShapeShape NewEdges2OldEdges;
1563 for (int i = 1; i <= anOldEdges.Extent(); i++)
1564 {
1565 TopoDS_Shape NewEdge = myContext->Apply(anOldEdges(i));
1566 if (!NewEdge.IsNull())
1567 NewEdges2OldEdges.Bind(NewEdge, anOldEdges(i));
1568 }
ce41efde 1569
ce41efde 1570 TopExp_Explorer exp;
f7d70540 1571 // processing separate wires
1572 for (exp.Init(aRes, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next())
1573 {
1574 TopTools_SequenceOfShape SeqEdges;
1575 TopExp_Explorer expE(exp.Current(), TopAbs_EDGE);
1576 for (; expE.More(); expE.Next())
1577 SeqEdges.Append(expE.Current());
1578 SharedVert.Clear();
1579 CheckSharedVertices(SeqEdges, aMapEdgesVertex, SharedVert);
1580 MergeSeq(SeqEdges, Tol, myConcatBSplines, myContext, myOldShapes, SharedVert, NewEdges2OldEdges);
1581 }
1582
26ca3bd5 1583 TopTools_DataMapOfShapeShape oldFaces2NewFaces;
1584 for (exp.Init(myShape, TopAbs_FACE); exp.More(); exp.Next())
1585 {
1586 const TopoDS_Face& f = TopoDS::Face(exp.Current());
1587 TopoDS_Face NewF = TopoDS::Face(myContext->Apply(f));
1588 if (!NewF.IsNull())
1589 oldFaces2NewFaces.Bind(f, NewF);
1590 }
1591
f7d70540 1592 // processing each face
ce41efde 1593 for (exp.Init(aRes, TopAbs_FACE); exp.More(); exp.Next()) {
1594 //TopoDS_Face aFace = TopoDS::Face(aContext->Apply(exp.Current().Oriented(TopAbs_FORWARD)));
1595 TopoDS_Face aFace = TopoDS::Face(myContext->Apply(exp.Current().Oriented(TopAbs_FORWARD)));
1596 TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges;
f7d70540 1597 TopTools_SequenceOfShape aNonSharedEdges;
ce41efde 1598 for (TopExp_Explorer expe(aFace,TopAbs_EDGE); expe.More(); expe.Next()) {
1599 TopoDS_Edge edge = TopoDS::Edge(expe.Current());
1600 if (!aMapEdgeFaces.Contains(edge)) continue;
1601 const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
1602 TopTools_ListIteratorOfListOfShape anIter(aList);
f7d70540 1603 Standard_Integer NbFacesPerEdge = aList.Extent();
ce41efde 1604 for ( ; anIter.More(); anIter.Next()) {
1605 TopoDS_Face face = TopoDS::Face(anIter.Value());
26ca3bd5 1606 TopoDS_Face face1 = TopoDS::Face(oldFaces2NewFaces(anIter.Value()));
f7d70540 1607 if (face1.IsSame(aFace) && NbFacesPerEdge != 1)
1608 continue;
1609 if (NbFacesPerEdge == 1)
1610 //store non-shared edges separately
1611 aNonSharedEdges.Append(edge);
1612 else
1613 {
1614 if (aMapFacesEdges.Contains(face))
1615 aMapFacesEdges.ChangeFromKey(face).Append(edge);
1616 else
1617 {
1618 TopTools_ListOfShape ListEdges;
1619 ListEdges.Append(edge);
1620 aMapFacesEdges.Add(face,ListEdges);
1621 }
2277323d 1622 }
1623 }
ce41efde 1624 }
f7d70540 1625
1626 for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++)
1627 {
ce41efde 1628 const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
1629 TopTools_SequenceOfShape SeqEdges;
ce41efde 1630 TopTools_ListIteratorOfListOfShape anIter(ListEdges);
ce41efde 1631 for ( ; anIter.More(); anIter.Next())
1632 SeqEdges.Append(anIter.Value());
1633 if (SeqEdges.Length()==1)
1634 continue;
2277323d 1635
f7d70540 1636 SharedVert.Clear();
1637 CheckSharedVertices(SeqEdges, aMapEdgesVertex, SharedVert);
1638 //if (!SharedVert.IsEmpty())
1639 // continue;
1640 if ( MergeSeq(SeqEdges,Tol,myConcatBSplines, myContext, myOldShapes, SharedVert, NewEdges2OldEdges) )
2277323d 1641 {
2277323d 1642 //for history
1643 /*
ce41efde 1644 for (j = 1; j <= SeqEdges.Length(); j++)
2277323d 1645 {
ce41efde 1646 if (!myOldNewMap.IsBound(SeqEdges(j)))
1647 {
1648 TopTools_ListOfShape EmptyList;
1649 myOldNewMap.Bind(SeqEdges(j), EmptyList);
1650 }
1651 myOldNewMap(SeqEdges(j)).Clear();
1652 myOldNewMap(SeqEdges(j)).Append(E);
2277323d 1653 }
2277323d 1654 */
1655 /////////////
ce41efde 1656
1657 TopoDS_Face tmpF = TopoDS::Face(exp.Current());
1658 if ( !ChangedFaces.Contains(tmpF) )
1659 ChangedFaces.Add(tmpF);
1660 tmpF = TopoDS::Face(aMapFacesEdges.FindKey(i));
1661 if ( !ChangedFaces.Contains(tmpF) )
1662 ChangedFaces.Add(tmpF);
2277323d 1663 }
ce41efde 1664 }
f7d70540 1665
1666 if ( aNonSharedEdges.Length() > 1 )
1667 {
1668 SharedVert.Clear();
1669 CheckSharedVertices(aNonSharedEdges, aMapEdgesVertex, SharedVert);
1670 if ( MergeSeq(aNonSharedEdges, Tol, myConcatBSplines, myContext, myOldShapes, SharedVert, NewEdges2OldEdges) )
1671 {
1672 TopoDS_Face tmpF = TopoDS::Face(exp.Current());
1673 if ( !ChangedFaces.Contains(tmpF) )
1674 ChangedFaces.Add(tmpF);
1675 }
1676 }
ce41efde 1677
1678 } // end processing each face
1679
1680 // fix changed faces and replace them in the local context
1681 for (Standard_Integer i=1; i<=ChangedFaces.Extent(); i++) {
1682 //TopoDS_Face aFace = TopoDS::Face(aContext->Apply(ChangedFaces.FindKey(i)));
1683 TopoDS_Face aFace = TopoDS::Face(myContext->Apply(ChangedFaces.FindKey(i)));
f7d70540 1684 if (aFace.IsNull())
1685 continue;
ce41efde 1686 Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFace);
1687 sff->SetContext(myContext);
1688 sff->SetPrecision(myTolerance);
1689 sff->SetMinTolerance(myTolerance);
1690 sff->SetMaxTolerance(Max(1.,myTolerance*1000.));
1691 sff->Perform();
1692 TopoDS_Shape aNewFace = sff->Face();
1693 //aContext->Replace(aFace,aNewFace);
1694 myContext->Replace(aFace,aNewFace);
1695 //for history
1696 /*
1697 if (!myOldNewMap.IsBound(aFace))
1698 {
1699 TopTools_ListOfShape EmptyList;
1700 myOldNewMap.Bind(aFace, EmptyList);
1701 }
1702 myOldNewMap(aFace).Clear();
1703 myOldNewMap(aFace).Append(aNewFace);
1704 */
1705 /////////////
1706 }
1707
1708 if (ChangedFaces.Extent() > 0) {
1709 // fix changed shell and replace it in the local context
1710 //TopoDS_Shape aRes1 = aContext->Apply(aRes);
1711 TopoDS_Shape aRes1 = myContext->Apply(aRes);
1712 TopExp_Explorer expsh;
1713 for (expsh.Init(aRes1, TopAbs_SHELL); expsh.More(); expsh.Next()) {
1714 TopoDS_Shell aShell = TopoDS::Shell(expsh.Current());
1715 Handle(ShapeFix_Shell) sfsh = new ShapeFix_Shell;
1716 sfsh->FixFaceOrientation(aShell);
1717 TopoDS_Shape aNewShell = sfsh->Shell();
1718 //aContext->Replace(aShell,aNewShell);
1719 myContext->Replace(aShell,aNewShell);
2277323d 1720 //for history
1721 /*
ce41efde 1722 if (!myOldNewMap.IsBound(aShell))
2277323d 1723 {
1724 TopTools_ListOfShape EmptyList;
ce41efde 1725 myOldNewMap.Bind(aShell, EmptyList);
2277323d 1726 }
ce41efde 1727 myOldNewMap(aShell).Clear();
1728 myOldNewMap(aShell).Append(aNewShell);
2277323d 1729 */
1730 /////////////
1731 }
ce41efde 1732 //TopoDS_Shape aRes2 = aContext->Apply(aRes1);
1733 TopoDS_Shape aRes2 = myContext->Apply(aRes1);
1734 myContext->Replace(myShape,aRes2);
1735 //for history
1736 /*
1737 if (!myOldNewMap.IsBound(aSolid))
1738 {
1739 TopTools_ListOfShape EmptyList;
1740 myOldNewMap.Bind(aSolid, EmptyList);
1741 }
1742 myOldNewMap(aSolid).Clear();
1743 myOldNewMap(aSolid).Append(aRes2);
1744 */
1745 /////////////
1746 }
2277323d 1747
1748 myShape = myContext->Apply(myShape);
1749}
1750
1751//=======================================================================
1752//function : UnifyFacesAndEdges
1753//purpose :
1754//=======================================================================
1755
1756void ShapeUpgrade_UnifySameDomain::UnifyFacesAndEdges()
1757{
1758 UnifyFaces();
1759
1760 /*
1761 ShapeUpgrade_RemoveLocations RemLoc;
1762 RemLoc.Remove(myShape);
1763 myShape = RemLoc.GetResult();
1764 */
1765
1766 UnifyEdges();
1767}
1768
1769//=======================================================================
1770//function : Build
1771//purpose : builds the resulting shape
1772//======================================================================
1773void ShapeUpgrade_UnifySameDomain::Build()
1774{
1775 if (myUnifyFaces && myUnifyEdges)
1776 UnifyFacesAndEdges();
1777
1778 else if (myUnifyEdges)
1779 UnifyEdges();
1780 else if (myUnifyFaces)
1781 UnifyFaces();
1782
1783 //Done();
1784}
1785
1786//=======================================================================
1787//function : Shape
1788//purpose : give the resulting shape
1789//=======================================================================
1790const TopoDS_Shape& ShapeUpgrade_UnifySameDomain::Shape() const
1791{
1792 return myShape;
1793}
1794
1795//=======================================================================
1796//function : Generated
1797//purpose : returns the new shape from the old one
1798//=======================================================================
1799TopoDS_Shape ShapeUpgrade_UnifySameDomain::Generated(const TopoDS_Shape& aShape) const
1800{
1801 TopoDS_Shape aNewShape = myContext->Apply(aShape);
f7d70540 1802
2277323d 1803 if (aNewShape.IsNull())
f7d70540 1804 aNewShape = myContext->Apply(myOldShapes(aShape));
2277323d 1805
1806 return aNewShape;
1807}