Warnings on vc14 were eliminated
[occt.git] / src / ShapeFix / ShapeFix_IntersectionTool.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 14
42cf5bc1 15#include <Bnd_Box2d.hxx>
16#include <BndLib_Add2dCurve.hxx>
7fd59977 17#include <BRep_Builder.hxx>
18#include <BRep_Tool.hxx>
19#include <BRepTools.hxx>
7fd59977 20#include <Geom2d_BSplineCurve.hxx>
21#include <Geom2d_Curve.hxx>
22#include <Geom2d_Line.hxx>
23#include <Geom2d_TrimmedCurve.hxx>
24#include <Geom2dAdaptor_Curve.hxx>
25#include <Geom2dInt_GInter.hxx>
42cf5bc1 26#include <Geom_Curve.hxx>
27#include <Geom_Surface.hxx>
28#include <GeomAdaptor_Curve.hxx>
29#include <GeomAdaptor_HSurface.hxx>
7fd59977 30#include <gp_Pnt.hxx>
31#include <IntRes2d_Domain.hxx>
32#include <IntRes2d_IntersectionPoint.hxx>
33#include <IntRes2d_IntersectionSegment.hxx>
34#include <IntRes2d_Position.hxx>
42cf5bc1 35#include <NCollection_Sequence.hxx>
7fd59977 36#include <ShapeAnalysis.hxx>
37#include <ShapeAnalysis_Edge.hxx>
38#include <ShapeAnalysis_Surface.hxx>
39#include <ShapeAnalysis_TransferParametersProj.hxx>
40#include <ShapeBuild_Edge.hxx>
42cf5bc1 41#include <ShapeBuild_ReShape.hxx>
42#include <ShapeExtend_WireData.hxx>
7fd59977 43#include <ShapeFix_DataMapOfShapeBox2d.hxx>
42cf5bc1 44#include <ShapeFix_IntersectionTool.hxx>
7fd59977 45#include <TopExp_Explorer.hxx>
46#include <TopoDS.hxx>
42cf5bc1 47#include <TopoDS_Edge.hxx>
48#include <TopoDS_Face.hxx>
7fd59977 49#include <TopoDS_Iterator.hxx>
42cf5bc1 50#include <TopoDS_Vertex.hxx>
7fd59977 51#include <TopoDS_Wire.hxx>
52#include <TopTools_SequenceOfShape.hxx>
53
54//gka 06.09.04 BUG 6555 shape is modified always independently either intersection was fixed or not
55//=======================================================================
56//function : ShapeFix_IntersectionTool
57//purpose :
58//=======================================================================
7fd59977 59ShapeFix_IntersectionTool::ShapeFix_IntersectionTool(const Handle(ShapeBuild_ReShape)& context,
60 const Standard_Real preci,
61 const Standard_Real maxtol)
62{
63 myContext = context;
64 myPreci = preci;
65 myMaxTol = maxtol;
66}
67
68
69//=======================================================================
70//function : GetPointOnEdge
71//purpose : auxiliary
72//:h0 abv 29 May 98: PRO10105 1949: like in BRepCheck, point is to be taken
73// from 3d curve (but only if edge is SameParameter)
74//=======================================================================
75static gp_Pnt GetPointOnEdge(const TopoDS_Edge &edge,
76 const Handle(ShapeAnalysis_Surface) &surf,
94f71cad 77 const Geom2dAdaptor_Curve &Crv2d,
7fd59977 78 const Standard_Real param )
79{
80 if( BRep_Tool::SameParameter(edge) ) {
81 Standard_Real f,l;
82 TopLoc_Location L;
83 const Handle(Geom_Curve) ConS = BRep_Tool::Curve ( edge, L, f, l );
84 if( !ConS.IsNull() )
85 return ConS->Value(param).Transformed(L.Transformation());
86 }
94f71cad 87 gp_Pnt2d aP2d = Crv2d.Value(param);
88 return surf->Adaptor3d()->Value(aP2d.X(), aP2d.Y());
7fd59977 89}
90
91
92//=======================================================================
93//function : SplitEdge
94//purpose :
95//=======================================================================
96
97Standard_Boolean ShapeFix_IntersectionTool::SplitEdge(const TopoDS_Edge& edge,
98 const Standard_Real param,
99 const TopoDS_Vertex& vert,
100 const TopoDS_Face& face,
101 TopoDS_Edge& newE1,
102 TopoDS_Edge& newE2,
103 const Standard_Real preci) const
104{
105 Standard_Real a, b;
106 ShapeAnalysis_Edge sae;
107
108 TopoDS_Vertex V1 = sae.FirstVertex(edge);
109 TopoDS_Vertex V2 = sae.LastVertex(edge);
110 if( V1.IsSame(vert) || V2.IsSame(vert) )
111 return Standard_False;
112
113 Handle(Geom2d_Curve) c2d;
114 sae.PCurve(edge,face,c2d,a,b,Standard_True );
115 if( Abs(a-param)<0.01*preci || Abs(b-param)<0.01*preci )
116 return Standard_False;
117 // check distanse between edge and new vertex
118 gp_Pnt P1;
119 TopLoc_Location L;
9cbe6290 120 if(BRep_Tool::SameParameter(edge) && !BRep_Tool::Degenerated(edge)) {
7fd59977 121 Standard_Real f,l;
122 const Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,L,f,l);
123 if(c3d.IsNull())
124 return Standard_False;
125 P1 = c3d->Value(param);
126 if(!L.IsIdentity()) P1 = P1.Transformed(L.Transformation());
127 }
128 else {
129 Handle(Geom_Surface) surf = BRep_Tool::Surface(face,L);
130 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(surf);
131 P1 = sas->Value(c2d->Value(param));
132 if(!L.IsIdentity()) P1 = P1.Transformed(L.Transformation());
133 }
134 gp_Pnt P2 = BRep_Tool::Pnt(vert);
135 if(P1.Distance(P2)>preci) {
136 //return Standard_False;
137 BRep_Builder B;
138 B.UpdateVertex(vert,P1.Distance(P2));
139 }
140
141 Handle(ShapeAnalysis_TransferParametersProj) transferParameters =
142 new ShapeAnalysis_TransferParametersProj;
143 transferParameters->SetMaxTolerance(preci);
144 transferParameters->Init(edge,face);
145 Standard_Real first, last;
146 if (a < b ) {
147 first = a;
148 last = b;
149 }
150 else {
151 first = b;
152 last = a;
153 }
154
155 ShapeBuild_Edge sbe;
156 TopAbs_Orientation orient = edge.Orientation();
157 BRep_Builder B;
158 TopoDS_Edge wE = edge;
159 wE.Orientation ( TopAbs_FORWARD );
160 TopoDS_Shape aTmpShape = vert.Oriented(TopAbs_REVERSED); //for porting
161 newE1 = sbe.CopyReplaceVertices ( wE, sae.FirstVertex(wE), TopoDS::Vertex(aTmpShape) );
162 sbe.CopyPCurves ( newE1, wE );
163 transferParameters->TransferRange(newE1,first,param,Standard_True);
164 B.SameRange(newE1,Standard_False);
165 B.SameParameter(newE1,Standard_False);
166 aTmpShape = vert.Oriented(TopAbs_FORWARD);
167 newE2 = sbe.CopyReplaceVertices ( wE, TopoDS::Vertex(aTmpShape),sae.LastVertex(wE) );
168 sbe.CopyPCurves ( newE2, wE );
169 transferParameters->TransferRange(newE2,param,last,Standard_True);
170 B.SameRange(newE2,Standard_False);
171 B.SameParameter(newE2,Standard_False);
172
173 newE1.Orientation(orient);
174 newE2.Orientation(orient);
175 if (orient==TopAbs_REVERSED) {
176 TopoDS_Edge tmp = newE2; newE2 = newE1; newE1=tmp;
177 }
178
179 return Standard_True;
180}
181
182
183//=======================================================================
184//function : CutEdge
185//purpose :
186//=======================================================================
187
188Standard_Boolean ShapeFix_IntersectionTool::CutEdge(const TopoDS_Edge &edge,
189 const Standard_Real pend,
190 const Standard_Real cut,
191 const TopoDS_Face &face,
192 Standard_Boolean &iscutline) const
193{
194 if( Abs(cut-pend)<10.*Precision::PConfusion() ) return Standard_False;
195 Standard_Real aRange = Abs(cut-pend);
196 Standard_Real a, b;
197 BRep_Tool::Range(edge, a, b);
198
199 if( aRange<10.*Precision::PConfusion() ) return Standard_False;
200
201 // case pcurve is trimm of line
202 if( !BRep_Tool::SameParameter(edge) ) {
203 ShapeAnalysis_Edge sae;
204 Handle(Geom2d_Curve) Crv;
205 Standard_Real fp,lp;
206 if ( sae.PCurve(edge,face,Crv,fp,lp,Standard_False) ) {
207 if(Crv->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
208 Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(Crv);
209 if(tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Line))) {
210 BRep_Builder B;
211 B.Range(edge,Min(pend,cut),Max(pend,cut));
212 if( Abs(pend-lp)<Precision::PConfusion() ) { // cut from the begining
213 Standard_Real cut3d = (cut-fp)*(b-a)/(lp-fp);
214 B.Range(edge, a+cut3d, b, Standard_True);
215 iscutline = Standard_True;
216 }
217 else if( Abs(pend-fp)<Precision::PConfusion() ) { // cut from the end
218 Standard_Real cut3d = (lp-cut)*(b-a)/(lp-fp);
219 B.Range(edge, a, b-cut3d, Standard_True);
220 iscutline = Standard_True;
221 }
222 }
9cbe6290 223
224 return Standard_True;
7fd59977 225 }
0d3d226e 226
7fd59977 227 }
9cbe6290 228 return Standard_False;
7fd59977 229 }
230
231 // det-study on 03/12/01 checking the old and new ranges
232 if( Abs(Abs(a-b)-aRange) < Precision::PConfusion() ) return Standard_False;
233 if( aRange<10.*Precision::PConfusion() ) return Standard_False;
234
235 BRep_Builder B;
236 B.Range( edge, Min(pend,cut), Max(pend,cut) );
237
238 return Standard_True;
239}
240
241
242//=======================================================================
243//function : SplitEdge1
244//purpose : split edge[a,b] om two part e1[a,param]
245// and e2[param,b] using vertex vert
246//=======================================================================
247
248Standard_Boolean ShapeFix_IntersectionTool::SplitEdge1(const Handle(ShapeExtend_WireData)& sewd,
249 const TopoDS_Face& face,
250 const Standard_Integer num,
251 const Standard_Real param,
252 const TopoDS_Vertex& vert,
253 const Standard_Real preci,
254 ShapeFix_DataMapOfShapeBox2d& boxes) const
255{
256 TopoDS_Edge edge = sewd->Edge(num);
257 TopoDS_Edge newE1, newE2;
258 if(!SplitEdge(edge,param,vert,face,newE1,newE2,preci)) return Standard_False;
259
260 // change context
261 Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
262 wd->Add(newE1);
263 wd->Add(newE2);
264 if(!myContext.IsNull()) myContext->Replace( edge, wd->Wire() );
265 for (TopExp_Explorer exp ( wd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
266 TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
267 BRepTools::Update(E);
268 }
269
270 // change sewd
271 sewd->Set(newE1,num);
272 if(num==sewd->NbEdges())
273 sewd->Add(newE2);
274 else
275 sewd->Add(newE2,num+1);
276
277 // change boxes
278 boxes.UnBind(edge);
279 TopLoc_Location L;
280 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
281 Handle(Geom2d_Curve) c2d;
282 Standard_Real cf,cl;
283 ShapeAnalysis_Edge sae;
284 if(sae.PCurve(newE1,S,L,c2d,cf,cl,Standard_False)) {
285 Bnd_Box2d box;
286 Geom2dAdaptor_Curve gac;
287 Standard_Real aFirst = c2d->FirstParameter();
288 Standard_Real aLast = c2d->LastParameter();
289 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
290 && (cf < aFirst || cl > aLast)) {
291 //pdn avoiding problems with segment in Bnd_Box
292 gac.Load(c2d);
293 }
294 else
295 gac.Load(c2d,cf,cl);
296 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
297 boxes.Bind(newE1,box);
298 }
299 if(sae.PCurve(newE2,S,L,c2d,cf,cl,Standard_False)) {
300 Bnd_Box2d box;
301 Geom2dAdaptor_Curve gac;
302 Standard_Real aFirst = c2d->FirstParameter();
303 Standard_Real aLast = c2d->LastParameter();
304 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
305 && (cf < aFirst || cl > aLast)) {
306 //pdn avoiding problems with segment in Bnd_Box
307 gac.Load(c2d);
308 }
309 else
310 gac.Load(c2d,cf,cl);
311 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
312 boxes.Bind(newE2,box);
313 }
314
315 return Standard_True;
316}
317
318
319//=======================================================================
320//function : SplitEdge2
321//purpose : auxilary: split edge[a,b] om two part e1[a,param1]
322// and e2[param2,b] using vertex vert
323// (remove segment (param1,param2) from edge)
324//=======================================================================
325
326Standard_Boolean ShapeFix_IntersectionTool::SplitEdge2(const Handle(ShapeExtend_WireData)& sewd,
327 const TopoDS_Face& face,
328 const Standard_Integer num,
329 const Standard_Real param1,
330 const Standard_Real param2,
331 const TopoDS_Vertex& vert,
332 const Standard_Real preci,
333 ShapeFix_DataMapOfShapeBox2d& boxes) const
334{
335 TopoDS_Edge edge = sewd->Edge(num);
336 TopoDS_Edge newE1, newE2;
337 Standard_Real param = (param1+param2)/2;
338 if(!SplitEdge(edge,param,vert,face,newE1,newE2,preci)) return Standard_False;
339 // cut new edges by param1 and param2
340 Standard_Boolean IsCutLine;
341 Handle(Geom2d_Curve) Crv1, Crv2;
342 Standard_Real fp1,lp1,fp2,lp2;
343 ShapeAnalysis_Edge sae;
344 if(sae.PCurve ( newE1, face, Crv1, fp1, lp1, Standard_False )) {
345 if(sae.PCurve ( newE2, face, Crv2, fp2, lp2, Standard_False )) {
346 if(lp1==param) {
347 if( (lp1-fp1)*(lp1-param1)>0 ) {
348 CutEdge(newE1, fp1, param1, face, IsCutLine);
349 CutEdge(newE2, lp2, param2, face, IsCutLine);
350 }
351 else {
352 CutEdge(newE1, fp1, param2, face, IsCutLine);
353 CutEdge(newE2, lp2, param1, face, IsCutLine);
354 }
355 }
356 else {
357 if( (fp1-lp1)*(fp1-param1)>0 ) {
358 CutEdge(newE1, lp1, param1, face, IsCutLine);
359 CutEdge(newE2, fp2, param2, face, IsCutLine);
360 }
361 else {
362 CutEdge(newE1, lp1, param2, face, IsCutLine);
363 CutEdge(newE2, fp2, param1, face, IsCutLine);
364 }
365 }
366 }
367 }
368
369 // change context
370 Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
371 wd->Add(newE1);
372 wd->Add(newE2);
373 if(!myContext.IsNull()) myContext->Replace( edge, wd->Wire() );
374 for (TopExp_Explorer exp ( wd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
375 TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
376 BRepTools::Update(E);
377 }
378
379 // change sewd
380 sewd->Set(newE1,num);
381 if(num==sewd->NbEdges())
382 sewd->Add(newE2);
383 else
384 sewd->Add(newE2,num+1);
385
386 // change boxes
387 boxes.UnBind(edge);
388 TopLoc_Location L;
389 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
390 Handle(Geom2d_Curve) c2d;
391 Standard_Real cf,cl;
392 if(sae.PCurve(newE1,S,L,c2d,cf,cl,Standard_False)) {
393 Bnd_Box2d box;
394 Geom2dAdaptor_Curve gac;
395 Standard_Real aFirst = c2d->FirstParameter();
396 Standard_Real aLast = c2d->LastParameter();
397 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
398 && (cf < aFirst || cl > aLast)) {
399 //pdn avoiding problems with segment in Bnd_Box
400 gac.Load(c2d);
401 }
402 else
403 gac.Load(c2d,cf,cl);
404 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
405 boxes.Bind(newE1,box);
406 }
407 if(sae.PCurve(newE2,S,L,c2d,cf,cl,Standard_False)) {
408 Bnd_Box2d box;
409 Geom2dAdaptor_Curve gac;
410 Standard_Real aFirst = c2d->FirstParameter();
411 Standard_Real aLast = c2d->LastParameter();
412 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
413 && (cf < aFirst || cl > aLast)) {
414 //pdn avoiding problems with segment in Bnd_Box
415 gac.Load(c2d);
416 }
417 else
418 gac.Load(c2d,cf,cl);
419 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
420 boxes.Bind(newE2,box);
421 }
422
423 return Standard_True;
424}
425
426
427//=======================================================================
428//function : UnionVertexes
429//purpose :
430//=======================================================================
431
432Standard_Boolean ShapeFix_IntersectionTool::UnionVertexes(const Handle(ShapeExtend_WireData)& sewd,
433 TopoDS_Edge& edge1,
434 TopoDS_Edge& edge2,
435 const Standard_Integer num2,
436 ShapeFix_DataMapOfShapeBox2d& boxes,
437 const Bnd_Box2d& B2) const
438{
439 // union vertexes
9cbe6290 440 Standard_Boolean res = Standard_False;
7fd59977 441 ShapeBuild_Edge sbe;
442 ShapeAnalysis_Edge sae;
443 BRep_Builder B;
444 TopoDS_Vertex V;
445 TopoDS_Vertex V1F = sae.FirstVertex(edge1);
446 gp_Pnt PV1F = BRep_Tool::Pnt(V1F);
447 TopoDS_Vertex V1L = sae.LastVertex(edge1);
448 gp_Pnt PV1L = BRep_Tool::Pnt(V1L);
449 TopoDS_Vertex V2F = sae.FirstVertex(edge2);
450 gp_Pnt PV2F = BRep_Tool::Pnt(V2F);
451 TopoDS_Vertex V2L = sae.LastVertex(edge2);
452 gp_Pnt PV2L = BRep_Tool::Pnt(V2L);
453 Standard_Real d11 = PV1F.Distance(PV2F);
454 Standard_Real d12 = PV1F.Distance(PV2L);
455 Standard_Real d21 = PV1L.Distance(PV2F);
456 Standard_Real d22 = PV1L.Distance(PV2L);
457 if(d11<d12 && d11<d21 && d11<d22) {
458 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F),BRep_Tool::Tolerance(V2F));
459 if( !V2F.IsSame(V1F) && d11<tolv ) {
460 // union vertexes V1F and V2F
461 B.UpdateVertex(V1F,tolv);
462 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V1F,V2L);
463// cout<<"union vertexes V1F and V2F"<<endl;
464// gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
465// B.MakeVertex(V,Ptmp,tolv);
466// myContext->Replace(V1F,V);
467// myContext->Replace(V2F,V);
468// TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
469 myContext->Replace(edge2,NewE);
470 sewd->Set(NewE,num2);
471 edge2 = NewE;
472 boxes.Bind(NewE,B2); // update boxes
473 // replace vertex in other edge
474 Standard_Integer num21,num22;
475 if(num2>1) num21=num2-1;
476 else num21=sewd->NbEdges();
477 if(num2<sewd->NbEdges()) num22=num2+1;
478 else num22=1;
479 TopoDS_Edge edge21 = sewd->Edge(num21);
480 TopoDS_Edge edge22 = sewd->Edge(num22);
481 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
482 TopoDS_Vertex V21L = sae.LastVertex(edge21);
483 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
484 TopoDS_Vertex V22L = sae.LastVertex(edge22);
485 if(V21F.IsSame(V2F)) {
486 NewE = sbe.CopyReplaceVertices(edge21,V1F,V21L);
487 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
b846d1e0 488 if (boxes.IsBound(edge21))
489 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
7fd59977 490 myContext->Replace(edge21,NewE);
491 sewd->Set(NewE,num21);
492 }
493 if(V21L.IsSame(V2F)) {
494 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1F);
495 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
b846d1e0 496 if (boxes.IsBound(edge21))
497 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
7fd59977 498 myContext->Replace(edge21,NewE);
499 sewd->Set(NewE,num21);
500 }
501 if(V22F.IsSame(V2F)) {
502 NewE = sbe.CopyReplaceVertices(edge22,V1F,V22L);
503 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
b846d1e0 504 if (boxes.IsBound(edge22))
505 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
7fd59977 506 myContext->Replace(edge22,NewE);
507 sewd->Set(NewE,num22);
508 }
509 if(V22L.IsSame(V2F)) {
510 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1F);
511 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
b846d1e0 512 if (boxes.IsBound(edge22))
513 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
7fd59977 514 myContext->Replace(edge22,NewE);
515 sewd->Set(NewE,num22);
516 }
9cbe6290 517 res = Standard_True;
7fd59977 518 }
519 }
520 else if(d12<d21 && d12<d22) {
521 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F),BRep_Tool::Tolerance(V2L));
522 if( !V2L.IsSame(V1F) && d12<tolv ) {
523 // union vertexes V1F and V2L
524 B.UpdateVertex(V1F,tolv);
525 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V1F);
526// cout<<"union vertexes V1F and V2L"<<endl;
527// gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
528// B.MakeVertex(V,Ptmp,tolv);
529// myContext->Replace(V1F,V);
530// myContext->Replace(V2L,V);
531// TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
532 myContext->Replace(edge2,NewE);
533 sewd->Set(NewE,num2);
534 edge2 = NewE;
535 //boxes.Bind(NewE,boxes.Find(edge2)); // update boxes
536 boxes.Bind(NewE,B2); // update boxes
537 // replace vertex in other edge
538 Standard_Integer num21,num22;
539 if(num2>1) num21=num2-1;
540 else num21=sewd->NbEdges();
541 if(num2<sewd->NbEdges()) num22=num2+1;
542 else num22=1;
543 TopoDS_Edge edge21 = sewd->Edge(num21);
544 TopoDS_Edge edge22 = sewd->Edge(num22);
545 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
546 TopoDS_Vertex V21L = sae.LastVertex(edge21);
547 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
548 TopoDS_Vertex V22L = sae.LastVertex(edge22);
549 if(V21F.IsSame(V2L)) {
550 NewE = sbe.CopyReplaceVertices(edge21,V1F,V21L);
551 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
b846d1e0 552 if (boxes.IsBound(edge21))
553 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
7fd59977 554 myContext->Replace(edge21,NewE);
555 sewd->Set(NewE,num21);
556 }
557 if(V21L.IsSame(V2L)) {
558 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1F);
559 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
b846d1e0 560 if (boxes.IsBound(edge21))
561 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
7fd59977 562 myContext->Replace(edge21,NewE);
563 sewd->Set(NewE,num21);
564 }
565 if(V22F.IsSame(V2L)) {
566 NewE = sbe.CopyReplaceVertices(edge22,V1F,V22L);
567 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
b846d1e0 568 if (boxes.IsBound(edge22))
569 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
7fd59977 570 myContext->Replace(edge22,NewE);
571 sewd->Set(NewE,num22);
572 }
573 if(V22L.IsSame(V2L)) {
574 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1F);
575 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
b846d1e0 576 if (boxes.IsBound(edge22))
577 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
7fd59977 578 myContext->Replace(edge22,NewE);
579 sewd->Set(NewE,num22);
580 }
9cbe6290 581 res = Standard_True;
7fd59977 582 }
583 }
584 else if(d21<d22) {
585 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L),BRep_Tool::Tolerance(V2F));
586 if( !V2F.IsSame(V1L) && d21<tolv ) {
587 // union vertexes V1L and V2F
588 B.UpdateVertex(V1L,tolv);
589 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V1L,V2L);
590// cout<<"union vertexes V1L and V2F"<<endl;
591// gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
592// B.MakeVertex(V,Ptmp,tolv);
593// myContext->Replace(V1L,V);
594// myContext->Replace(V2F,V);
595// TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
596 myContext->Replace(edge2,NewE);
597 sewd->Set(NewE,num2);
598 edge2 = NewE;
599 boxes.Bind(NewE,B2); // update boxes
600 // replace vertex in other edge
601 Standard_Integer num21,num22;
602 if(num2>1) num21=num2-1;
603 else num21=sewd->NbEdges();
604 if(num2<sewd->NbEdges()) num22=num2+1;
605 else num22=1;
606 TopoDS_Edge edge21 = sewd->Edge(num21);
607 TopoDS_Edge edge22 = sewd->Edge(num22);
608 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
609 TopoDS_Vertex V21L = sae.LastVertex(edge21);
610 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
611 TopoDS_Vertex V22L = sae.LastVertex(edge22);
612 if(V21F.IsSame(V2F)) {
613 NewE = sbe.CopyReplaceVertices(edge21,V1L,V21L);
614 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
b846d1e0 615 if (boxes.IsBound(edge21))
616 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
7fd59977 617 myContext->Replace(edge21,NewE);
618 sewd->Set(NewE,num21);
619 }
620 if(V21L.IsSame(V2F)) {
621 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1L);
622 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
b846d1e0 623 if (boxes.IsBound(edge21))
624 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
7fd59977 625 myContext->Replace(edge21,NewE);
626 sewd->Set(NewE,num21);
627 }
628 if(V22F.IsSame(V2F)) {
629 NewE = sbe.CopyReplaceVertices(edge22,V1L,V22L);
630 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
b846d1e0 631 if (boxes.IsBound(edge22))
632 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
7fd59977 633 myContext->Replace(edge22,NewE);
634 sewd->Set(NewE,num22);
635 }
636 if(V22L.IsSame(V2F)) {
637 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1L);
638 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
b846d1e0 639 if (boxes.IsBound(edge22))
640 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
7fd59977 641 myContext->Replace(edge22,NewE);
642 sewd->Set(NewE,num22);
643 }
9cbe6290 644 res = Standard_True;
7fd59977 645 }
646 }
647 else {
648 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L),BRep_Tool::Tolerance(V2L));
649 if( !V2L.IsSame(V1L) && d22<tolv ) {
650 // union vertexes V1L and V2L
651 B.UpdateVertex(V1L,tolv);
652 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V1L);
653// cout<<"union vertexes V1L and V2L"<<endl;
654// gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
655// B.MakeVertex(V,Ptmp,tolv);
656// myContext->Replace(V1L,V);
657// myContext->Replace(V2L,V);
658// TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
659 myContext->Replace(edge2,NewE);
660 sewd->Set(NewE,num2);
661 edge2 = NewE;
662 boxes.Bind(NewE,B2); // update boxes
663 // replace vertex in other edge
664 Standard_Integer num21,num22;
665 if(num2>1) num21=num2-1;
666 else num21=sewd->NbEdges();
667 if(num2<sewd->NbEdges()) num22=num2+1;
668 else num22=1;
669 TopoDS_Edge edge21 = sewd->Edge(num21);
670 TopoDS_Edge edge22 = sewd->Edge(num22);
671 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
672 TopoDS_Vertex V21L = sae.LastVertex(edge21);
673 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
674 TopoDS_Vertex V22L = sae.LastVertex(edge22);
675 if(V21F.IsSame(V2L)) {
676 NewE = sbe.CopyReplaceVertices(edge21,V1L,V21L);
677 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
b846d1e0 678 if (boxes.IsBound(edge21))
679 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
7fd59977 680 myContext->Replace(edge21,NewE);
681 sewd->Set(NewE,num21);
682 }
683 if(V21L.IsSame(V2L)) {
684 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1L);
685 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
b846d1e0 686 if (boxes.IsBound(edge21))
687 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
7fd59977 688 myContext->Replace(edge21,NewE);
689 sewd->Set(NewE,num21);
690 }
691 if(V22F.IsSame(V2L)) {
692 NewE = sbe.CopyReplaceVertices(edge22,V1L,V22L);
693 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
b846d1e0 694 if (boxes.IsBound(edge22))
695 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
7fd59977 696 myContext->Replace(edge22,NewE);
697 sewd->Set(NewE,num22);
698 }
699 if(V22L.IsSame(V2L)) {
700 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1L);
701 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
b846d1e0 702 if (boxes.IsBound(edge22))
703 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
7fd59977 704 myContext->Replace(edge22,NewE);
705 sewd->Set(NewE,num22);
706 }
9cbe6290 707 res = Standard_True;
7fd59977 708 }
709 }
710
9cbe6290 711 return res;
7fd59977 712}
713
714
715//=======================================================================
716//function : CreateBoxes2d
717//purpose : auxilary
718//=======================================================================
7c8090aa 719static Bnd_Box2d CreateBoxes2d(const Handle(ShapeExtend_WireData)& sewd,
7fd59977 720 const TopoDS_Face& face,
721 ShapeFix_DataMapOfShapeBox2d& boxes)
722{
723 // create box2d for edges from wire
7c8090aa 724 Bnd_Box2d aTotalBox;
7fd59977 725 TopLoc_Location L;
726 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
727 Handle(Geom2d_Curve) c2d;
728 Standard_Real cf,cl;
729 ShapeAnalysis_Edge sae;
730 for(Standard_Integer i=1; i<=sewd->NbEdges(); i++){
731 TopoDS_Edge E = sewd->Edge(i);
732 if(sae.PCurve(E,S,L,c2d,cf,cl,Standard_False)) {
733 Bnd_Box2d box;
734 Geom2dAdaptor_Curve gac;
735 Standard_Real aFirst = c2d->FirstParameter();
736 Standard_Real aLast = c2d->LastParameter();
737 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
738 && (cf < aFirst || cl > aLast)) {
739 //pdn avoiding problems with segment in Bnd_Box
740 gac.Load(c2d);
741 }
742 else
743 gac.Load(c2d,cf,cl);
744 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
745 boxes.Bind(E,box);
7c8090aa 746 aTotalBox.Add (box);
7fd59977 747 }
748 }
7c8090aa 749 return aTotalBox;
7fd59977 750}
751
752
753//=======================================================================
754//function : SelectIntPnt
755//purpose : auxilary
756//=======================================================================
757static void SelectIntPnt(const Geom2dInt_GInter& Inter,
758 IntRes2d_IntersectionPoint& IP,
759 IntRes2d_Transition& Tr1,
760 IntRes2d_Transition& Tr2)
761{
762 IP = Inter.Point(1);
763 Tr1 = IP.TransitionOfFirst();
764 Tr2 = IP.TransitionOfSecond();
765 if(Inter.NbPoints()==2) {
766 // possible second point is better?
767 Standard_Integer status1=0,status2=0;
768 if(Tr1.PositionOnCurve()==IntRes2d_Middle) status1+=1;
769 if(Tr2.PositionOnCurve()==IntRes2d_Middle) status1+=2;
770 IntRes2d_IntersectionPoint IP2;
771 IntRes2d_Transition Tr12, Tr22;
772 IP2 = Inter.Point(2);
773 Tr12 = IP2.TransitionOfFirst();
774 Tr22 = IP2.TransitionOfSecond();
775 if(Tr12.PositionOnCurve()==IntRes2d_Middle) status2+=1;
776 if(Tr22.PositionOnCurve()==IntRes2d_Middle) status2+=2;
777 if(status2>status1) {
778 IP=IP2; Tr1=Tr12; Tr2=Tr22;
779 }
780 }
781}
782
783
784//=======================================================================
785//function : FindVertAndSplitEdge
786//purpose : auxilary
787//=======================================================================
788Standard_Boolean ShapeFix_IntersectionTool::FindVertAndSplitEdge
789 (const Standard_Real param1,
790 const TopoDS_Edge& edge1, const TopoDS_Edge& edge2,
791 const Handle(Geom2d_Curve)& Crv1,
792 Standard_Real& MaxTolVert,
793 Standard_Integer& num1,
794 const Handle(ShapeExtend_WireData)& sewd,
795 const TopoDS_Face& face,
796 ShapeFix_DataMapOfShapeBox2d& boxes,
797 const Standard_Boolean aTmpKey) const
798{
799 // find needed vertex from edge2 and split edge1 using it
800 ShapeAnalysis_Edge sae;
801 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
802 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
803 BRep_Builder B;
804 TopoDS_Vertex V;
805 Standard_Real tolV;
806 TopoDS_Vertex V1 = sae.FirstVertex(edge2);
807 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
808 TopoDS_Vertex V2 = sae.LastVertex(edge2);
809 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
810 TopoDS_Vertex V11 = sae.FirstVertex(edge1);
811 TopoDS_Vertex V12 = sae.LastVertex(edge1);
812 Standard_Boolean NeedSplit = Standard_True;
813 if(pi1.Distance(PV1)<pi1.Distance(PV2)) {
814 if( V1.IsSame(V11) || V1.IsSame(V12) ) {
815 NeedSplit = Standard_False;
816 }
817 V = V1;
818 tolV = Max( (pi1.Distance(PV1)/2)*1.00001, BRep_Tool::Tolerance(V1) );
819 }
820 else {
821 if( V2.IsSame(V11) || V2.IsSame(V12) ) {
822 NeedSplit = Standard_False;
823 }
824 V = V2;
825 tolV = Max( (pi1.Distance(PV2)/2)*1.00001, BRep_Tool::Tolerance(V2) );
826 }
827 if( NeedSplit || aTmpKey ) {
828 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
829 B.UpdateVertex(V,tolV);
830 MaxTolVert = Max(MaxTolVert,tolV);
831// NbSplit++;
832 num1--;
833 return Standard_True;
834 //break;
835 }
836 }
837 return Standard_False;
838}
839
840
841//=======================================================================
842//function : FixSelfIntersectWire
843//purpose :
844//=======================================================================
845
846Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
847 (Handle(ShapeExtend_WireData)& sewd, const TopoDS_Face& face,
848 Standard_Integer& NbSplit, Standard_Integer& NbCut,
849 Standard_Integer& NbRemoved) const
850{
851 if(myContext.IsNull() || face.IsNull()) return Standard_False;
852
853 //Standard_Real area2d = ShapeAnalysis::TotCross2D(sewd,face);
854 //if(area2d<Precision::PConfusion()*Precision::PConfusion()) return Standard_False; //gka 06.09.04 BUG 6555
855
ed5ca017 856 TopoDS_Shape SF = Context()->Apply(face);
7fd59977 857 Standard_Real MaxTolVert=0.0;
858 for(TopExp_Explorer exp(SF,TopAbs_VERTEX); exp.More(); exp.Next()) {
859 Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
860 MaxTolVert = Max(MaxTolVert,tolV);
861 }
862 MaxTolVert = Min(MaxTolVert,myMaxTol);
863 ShapeAnalysis_Edge sae;
864
865 // step 1 : intersection of adjacent edges
866
867 // step 2 : intersection of non-adjacent edges
868 ShapeFix_DataMapOfShapeBox2d boxes;
276130e7 869 (void)CreateBoxes2d(sewd,face,boxes);
7fd59977 870 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
871
872 NbSplit=0;
873 NbCut=0;
874 Standard_Integer nbReplaced =0;
875 Standard_Boolean isDone = Standard_False;
876 for(Standard_Integer num1=1; num1<sewd->NbEdges() && NbSplit<30; num1++) {
877 // for each edge from first wire
878 for(Standard_Integer num2=num1+2; num2<=sewd->NbEdges() && NbSplit<30; num2++) {
879 // for each edge from second wire
880 if( num1==1 && num2==sewd->NbEdges() ) continue;
881 TopoDS_Edge edge1 = sewd->Edge(num1);
882 TopoDS_Edge edge2 = sewd->Edge(num2);
883 if(edge1.IsSame(edge2)) continue;
884 if( BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2) ) continue;
885 if( !boxes.IsBound(edge1) || !boxes.IsBound(edge2) ) continue;
886 Bnd_Box2d B1 = boxes.Find(edge1);
887 Bnd_Box2d B2 = boxes.Find(edge2);
888 if(!B1.IsOut(B2)) {
889 // intersection is possible...
890 Standard_Real a1, b1, a2, b2;
891 Handle(Geom2d_Curve) Crv1, Crv2;
892 if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) ) return Standard_False;
893 if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) ) return Standard_False;
894 Standard_Real tolint = 1.0e-10;
7fd59977 895 Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
94f71cad 896 IntRes2d_Domain d1(C1.Value(a1),a1,tolint,C1.Value(b1),b1,tolint);
897 IntRes2d_Domain d2(C2.Value(a2),a2,tolint,C2.Value(b2),b2,tolint);
7fd59977 898 Geom2dInt_GInter Inter;
899 Inter.Perform( C1, d1, C2, d2, tolint, tolint );
900 if(!Inter.IsDone()) continue;
901 // intersection is point
902 if( Inter.NbPoints()>0 && Inter.NbPoints()<3 ) {
903 IntRes2d_IntersectionPoint IP;
904 IntRes2d_Transition Tr1, Tr2;
905 SelectIntPnt(Inter,IP,Tr1,Tr2);
906 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
907 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
908 Standard_Real param1 = IP.ParamOnFirst();
909 Standard_Real param2 = IP.ParamOnSecond();
94f71cad 910 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,C1,param1);
911 gp_Pnt pi2 = GetPointOnEdge(edge2,sas,C2,param2);
7fd59977 912 BRep_Builder B;
913 TopoDS_Vertex V;
914 Standard_Real tolV=0;
915 // analysis for edge1
916 Standard_Boolean ModifE1 = Standard_False;
917 TopoDS_Vertex VF1 = sae.FirstVertex(edge1);
918 gp_Pnt PVF1 = BRep_Tool::Pnt(VF1);
919 TopoDS_Vertex VL1 = sae.LastVertex(edge1);
920 gp_Pnt PVL1 = BRep_Tool::Pnt(VL1);
921 Standard_Real dist1 = pi1.Distance(PVF1);
922 Standard_Real dist2 = pi1.Distance(PVL1);
9cbe6290 923 Standard_Real distmin = Min(dist1, dist2);
924 if( dist1 != dist2 && distmin < MaxTolVert ) {
925 if (dist1 < dist2) {
926 tolV = Max( dist1*1.00001, BRep_Tool::Tolerance(VF1) );
927 B.UpdateVertex(VF1,tolV);
928 V = VF1;
929 } else {
930 tolV = Max( dist2*1.00001, BRep_Tool::Tolerance(VL1) );
931 B.UpdateVertex(VL1,tolV);
932 V = VL1;
933 }
934
7fd59977 935 Standard_Real dista = Abs(a1-param1);
936 Standard_Real distb = Abs(b1-param1);
937 Standard_Boolean IsCutLine;
9cbe6290 938 ModifE1 = CutEdge(edge1, (( dista > distb ) ? a1 : b1 ), param1, face, IsCutLine);
939 if (ModifE1)
940 NbCut++;
941 //not needed split edge, if one of parts is too small
942 ModifE1 = ModifE1 || distmin < Precision::Confusion();
7fd59977 943 }
944 // analysis for edge2
945 Standard_Boolean ModifE2 = Standard_False;
946 TopoDS_Vertex VF2 = sae.FirstVertex(edge2);
947 gp_Pnt PVF2 = BRep_Tool::Pnt(VF2);
948 TopoDS_Vertex VL2 = sae.LastVertex(edge2);
949 gp_Pnt PVL2 = BRep_Tool::Pnt(VL2);
950 dist1 = pi2.Distance(PVF2);
951 dist2 = pi2.Distance(PVL2);
9cbe6290 952 distmin = Min(dist1, dist2);
953 if( dist1 != dist2 && distmin < MaxTolVert ) {
954 if (dist1 < dist2) {
955 tolV = Max( dist1*1.00001, BRep_Tool::Tolerance(VF2) );
956 B.UpdateVertex(VF2,tolV);
957 V = VF2;
958 } else {
959 tolV = Max( dist2*1.00001, BRep_Tool::Tolerance(VL2) );
960 B.UpdateVertex(VL2,tolV);
961 V = VL2;
962 }
963
7fd59977 964 Standard_Real dista = Abs(a2-param2);
965 Standard_Real distb = Abs(b2-param2);
966 Standard_Boolean IsCutLine;
9cbe6290 967 ModifE2 = CutEdge(edge2, (( dista > distb ) ? a2 : b2 ), param2, face, IsCutLine);
968 if (ModifE2)
969 NbCut++;
970 //not needed split edge, if one of parts is too small
971 ModifE2 = ModifE2 || distmin < Precision::Confusion();
7fd59977 972 }
973 if( ModifE1 && !ModifE2 ) {
974 if(SplitEdge1(sewd, face, num2, param2, V, tolV, boxes)) {
975 NbSplit++;
976 num2--;
977 continue;
978
979 }
980 }
981 if( !ModifE1 && ModifE2 ) {
982 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
983 NbSplit++;
984 num1--;
985 break;
986 }
987 }
988 if( !ModifE1 && !ModifE2 ) {
989 gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
990 tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
991 B.MakeVertex(V,P0,tolV);
992 MaxTolVert = Max(MaxTolVert,tolV);
993 Standard_Boolean isEdgeSplit2 = SplitEdge1(sewd, face, num2, param2,
994 V, tolV, boxes);
995 if(isEdgeSplit2) {
996 NbSplit++;
997 num2--;
998 }
999 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
1000 NbSplit++;
1001 num1--;
1002 break;
1003 }
1004 if(isEdgeSplit2)
1005 continue;
1006 }
1007 }
1008 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1009 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1010 // find needed vertex from edge2 and split edge1 using it
1011 Standard_Real param1 = IP.ParamOnFirst();
1012 if(FindVertAndSplitEdge(param1, edge1, edge2, Crv1, MaxTolVert,
1013 num1, sewd, face, boxes, Standard_False) ) {
1014 NbSplit++;
1015 break;
1016 }
1017 }
1018 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1019 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1020 // find needed vertex from edge1 and split edge2 using it
1021 Standard_Real param2 = IP.ParamOnSecond();
1022 if(FindVertAndSplitEdge(param2, edge2, edge1, Crv2, MaxTolVert,
1023 num2, sewd, face, boxes, Standard_False) ) {
1024 NbSplit++;
1025 continue;
1026 }
1027 }
1028 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1029 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1030 // union vertexes
1031 if( UnionVertexes(sewd, edge1, edge2, num2, boxes, B2) )
1032 nbReplaced ++; //gka 06.09.04
1033 }
1034 }
1035 // intersection is segment
1036 if( Inter.NbSegments()==1 ) {
1037 IntRes2d_IntersectionSegment IS = Inter.Segment(1);
1038 if ( IS.HasFirstPoint() && IS.HasLastPoint() ) {
1039 Standard_Boolean IsModified1 = Standard_False;
1040 Standard_Boolean IsModified2 = Standard_False;
1041 TopoDS_Vertex NewV;
1042 BRep_Builder B;
1043 Standard_Real newtol=0.0;
1044 IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
1045 Standard_Real p11 = IPF.ParamOnFirst();
1046 Standard_Real p21 = IPF.ParamOnSecond();
1047 IntRes2d_IntersectionPoint IPL = IS.LastPoint();
1048 Standard_Real p12 = IPL.ParamOnFirst();
1049 Standard_Real p22 = IPL.ParamOnSecond();
94f71cad 1050 gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,C1,p11);
1051 gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,C1,p12);
1052 gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,C2,p21);
1053 gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,C2,p22);
7fd59977 1054 // next string commented by skl 29.12.2004 for OCC7624
1055 //if( Pnt11.Distance(Pnt21)>myPreci || Pnt12.Distance(Pnt22)>myPreci ) continue;
1056 if( Pnt11.Distance(Pnt21)>MaxTolVert || Pnt12.Distance(Pnt22)>MaxTolVert ) continue;
1057 // analysis for edge1
1058 TopoDS_Vertex V1 = sae.FirstVertex(edge1);
1059 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
1060 TopoDS_Vertex V2 = sae.LastVertex(edge1);
1061 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
1062 //Standard_Real tol1 = BRep_Tool::Tolerance(V1);
1063 //Standard_Real tol2 = BRep_Tool::Tolerance(V2);
1064 //Standard_Real maxtol = Max(tol1,tol2);
1065 Standard_Real dist1 = Pnt11.Distance(PV1);
1066 Standard_Real dist2 = Pnt12.Distance(PV1);
1067 Standard_Real maxdist = Max(dist1,dist2);
1068 Standard_Real pdist;
1069 if(edge1.Orientation()==TopAbs_REVERSED)
1070 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1071 else
1072 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1073 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1074 //if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
1075 newtol = maxdist;
1076 NewV = V1;
1077 IsModified1 = Standard_True;
1078 }
1079 dist1 = Pnt11.Distance(PV2);
1080 dist2 = Pnt12.Distance(PV2);
1081 maxdist = Max(dist1,dist2);
1082 if(edge1.Orientation()==TopAbs_REVERSED)
1083 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1084 else
1085 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1086 //if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
1087 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1088 if( ( IsModified1 && maxdist<newtol ) || !IsModified1 ) {
1089 newtol = maxdist;
1090 NewV = V2;
1091 IsModified1 = Standard_True;
1092 }
1093 }
1094 if(IsModified1) {
1095 // cut edge1 and update tolerance NewV
1096 Standard_Real dista = Abs(a1-p11)+Abs(a1-p12);
1097 Standard_Real distb = Abs(b1-p11)+Abs(b1-p12);
1098 Standard_Real pend,cut;
1099 if(dista>distb) pend=a1;
1100 else pend=b1;
1101 if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
1102 else cut=p11;
1103 Standard_Boolean IsCutLine;
9cbe6290 1104 if (CutEdge(edge1, pend, cut, face, IsCutLine))
1105 NbCut++;
7fd59977 1106 if(newtol>BRep_Tool::Tolerance(NewV)) {
1107 B.UpdateVertex(NewV,newtol);
1108 }
1109 else newtol = BRep_Tool::Tolerance(NewV);
1110 }
1111 // analysis for edge2
1112 TopoDS_Vertex V12 = sae.FirstVertex(edge2);
1113 gp_Pnt PV12 = BRep_Tool::Pnt(V12);
1114 TopoDS_Vertex V22 = sae.LastVertex(edge2);
1115 gp_Pnt PV22 = BRep_Tool::Pnt(V22);
1116 //tol1 = BRep_Tool::Tolerance(V1);
1117 //tol2 = BRep_Tool::Tolerance(V2);
1118 //maxtol = Max(tol1,tol2);
1119 dist1 = Pnt21.Distance(PV12);
1120 dist2 = Pnt22.Distance(PV12);
1121 maxdist = Max(dist1,dist2);
1122 if(edge2.Orientation()==TopAbs_REVERSED)
1123 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1124 else
1125 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1126 //if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
1127 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1128 newtol = maxdist;
1129 NewV = V12;
1130 IsModified2 = Standard_True;
1131 }
1132 dist1 = Pnt21.Distance(PV22);
1133 dist2 = Pnt22.Distance(PV22);
1134 maxdist = Max(dist1,dist2);
1135 if(edge2.Orientation()==TopAbs_REVERSED)
1136 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1137 else
1138 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1139 //if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
1140 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1141 if( ( IsModified2 && maxdist<newtol ) || !IsModified2 ) {
1142 newtol = maxdist;
1143 NewV = V22;
1144 IsModified2 = Standard_True;
1145 }
1146 }
1147 if(IsModified2) {
1148 // cut edge1 and update tolerance NewV
1149 Standard_Real dista = Abs(a2-p21)+Abs(a2-p22);
1150 Standard_Real distb = Abs(b2-p21)+Abs(b2-p22);
1151 Standard_Real pend,cut;
1152 if(dista>distb) pend=a2;
1153 else pend=b2;
1154 if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
1155 else cut=p21;
1156 Standard_Boolean IsCutLine;
9cbe6290 1157 if (CutEdge(edge2, pend, cut, face, IsCutLine))
1158 NbCut++;
7fd59977 1159 if(newtol>BRep_Tool::Tolerance(NewV)) {
1160 B.UpdateVertex(NewV,newtol);
1161 }
1162 else newtol = BRep_Tool::Tolerance(NewV);
1163 }
1164
1165 if( IsModified1 && !IsModified2 ) {
1166 if(SplitEdge2(sewd, face, num2, p21, p22, NewV, newtol, boxes)) {
1167 NbSplit++;
1168 num2--;
1169 continue;
1170 }
1171 }
1172 if( !IsModified1 && IsModified2 ) {
1173 if(SplitEdge2(sewd, face, num1, p11, p12, NewV, newtol, boxes)) {
1174 NbSplit++;
1175 num1--;
1176 break;
1177 }
1178 }
1179 if( !IsModified1 && !IsModified2 ) {
1180 Standard_Real param1 = (p11+p12)/2;
1181 Standard_Real param2 = (p21+p22)/2;
94f71cad 1182 gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,C1,param1);
1183 gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,C2,param2);
7fd59977 1184 gp_Pnt P0( (Pnt10.X()+Pnt20.X())/2, (Pnt10.Y()+Pnt20.Y())/2,
1185 (Pnt10.Z()+Pnt20.Z())/2 );
1186 dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(P0));
1187 dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(P0));
1188 Standard_Real tolV = Max(dist1,dist2);
1189 tolV = Max(tolV,Pnt10.Distance(Pnt20))*1.00001;
1190 Standard_Boolean FixSegment = Standard_True;
1191 if(tolV<MaxTolVert) {
1192 // create new vertex and split each intersecting edge on two edges
1193 B.MakeVertex(NewV,Pnt10,tolV);
1194 if(SplitEdge2(sewd, face, num2, p21, p22, NewV, tolV, boxes)) {
1195 NbSplit++;
1196 num2--;
1197 }
1198 if(SplitEdge2(sewd, face, num1, p11, p12, NewV, tolV, boxes)) {
1199 NbSplit++;
1200 num1--;
1201 break;
1202 }
1203 }
1204 else if(FixSegment) {
1205 //if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
1206 // segment is big and we have to split each intersecting edge
1207 // on 3 edges --> middle edge - edge based on segment
1208 // after we can remove edges maked from segment
1209 gp_Pnt P01( (Pnt11.X()+Pnt21.X())/2, (Pnt11.Y()+Pnt21.Y())/2,
1210 (Pnt11.Z()+Pnt21.Z())/2 );
1211 gp_Pnt P02( (Pnt12.X()+Pnt22.X())/2, (Pnt12.Y()+Pnt22.Y())/2,
1212 (Pnt12.Z()+Pnt22.Z())/2 );
1213 Standard_Real tolV1 = Max(Pnt11.Distance(P01),Pnt21.Distance(P01));
1214 tolV1 = Max(tolV1,Precision::Confusion())*1.00001;
1215 Standard_Real tolV2 = Max(Pnt12.Distance(P02),Pnt22.Distance(P02));
1216 tolV2 = Max(tolV2,Precision::Confusion())*1.00001;
1217 if( tolV1>MaxTolVert || tolV2>MaxTolVert ) continue;
1218 TopoDS_Vertex NewV1,NewV2;
1219/*
1220 // parameters for splitting: a1..p11..p12..b1 and a2..p21..p22..b2 ???
1221 Standard_Integer nbseg1=3, nbseg2=3, kv1=0, kv2=0;
1222 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1223 NewV1 = V1;
1224 if(tolV1>BRep_Tool::Tolerance(V1))
1225 B.UpdateVertex(NewV1,tolV1);
1226 //akey1++;
1227 nbseg1--;
1228 kv1 = 1;
1229 }
1230 else if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1231 NewV1 = V2;
1232 if(tolV1>BRep_Tool::Tolerance(V2))
1233 B.UpdateVertex(NewV1,tolV1);
1234 //akey1++;
1235 nbseg1--;
1236 kv1 = 1;
1237 }
1238*/
1239 TopoDS_Edge tmpE,SegE;
1240 // split edge1
1241 Standard_Integer akey1=0, akey2=0;
163ef250 1242 Standard_Real newTolerance;
7fd59977 1243 // analysis fo P01
163ef250 1244 newTolerance = Max(tolV1,BRep_Tool::Tolerance(V1));
1245 if(P01.Distance(PV1)<newTolerance) {
1246 B.MakeVertex(NewV1,BRep_Tool::Pnt(V1),newTolerance);
1247 NewV1.Orientation(V1.Orientation());
7fd59977 1248 akey1++;
1249 }
163ef250 1250 newTolerance = Max(tolV1,BRep_Tool::Tolerance(V2));
1251 if(P01.Distance(PV2)<newTolerance) {
1252 B.MakeVertex(NewV1,BRep_Tool::Pnt(V2),newTolerance);
1253 NewV1.Orientation(V2.Orientation());
7fd59977 1254 akey1++;
1255 }
1256 // analysis fo P02
163ef250 1257 newTolerance = Max(tolV2,BRep_Tool::Tolerance(V1));
1258 if(P02.Distance(PV1)<newTolerance) {
1259 B.MakeVertex(NewV2,BRep_Tool::Pnt(V1),newTolerance);
1260 NewV2.Orientation(V1.Orientation());
7fd59977 1261 akey2++;
1262 }
163ef250 1263 newTolerance = Max(tolV2,BRep_Tool::Tolerance(V2));
1264 if(P02.Distance(PV2)<newTolerance) {
1265 B.MakeVertex(NewV2,BRep_Tool::Pnt(V2),newTolerance);
1266 NewV2.Orientation(V2.Orientation());
7fd59977 1267 akey2++;
1268 }
1269 if( akey1>1 || akey2>1 ) continue;
1270 Standard_Integer dnum1=0, numseg1=num1;
1271 // prepare vertices
1272 if(akey1==0) B.MakeVertex(NewV1,P01,tolV1);
1273 if(akey2==0) B.MakeVertex(NewV2,P02,tolV2);
1274 // split
1275 if( akey1==0 && akey2>0 ) {
1276 if(SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes)) {
1277 NbSplit++;
1278 dnum1=1;
1279 numseg1=num1+1;
1280 }
1281 }
1282 if( akey1>0 && akey2==0 ) {
1283 if(SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes) ) {
1284 NbSplit++;
1285 dnum1=1;
1286 numseg1=num1;
1287 }
1288 }
1289 if( akey1==0 && akey2==0 ) {
1290 if(SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes)) {
1291 NbSplit++;
1292 dnum1=1;
1293 }
1294 tmpE = sewd->Edge(num1);
1295 Standard_Real a,b;
1296 Handle(Geom2d_Curve) c2d;
1297 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1298 if( (a-p12)*(b-p12)>0 ) { // p12 - external for [a,b] => split next edge
1299 if(SplitEdge1(sewd, face, num1+1, p12, NewV2, tolV2, boxes) ) {
1300 NbSplit++;
1301 dnum1++;
1302 numseg1=num1+1;
1303 }
1304 }
1305 else {
1306 if(SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes) ) {
1307 NbSplit++;
1308 dnum1++;
1309 numseg1=num1+1;
1310 }
1311 }
1312 }
1313 //SegE = sewd->Edge(numseg1); // get edge from segment
1314 // split edge2
1315 // replace vertices if it is necessary
1316 ShapeBuild_Edge sbe;
1317 akey1=0, akey2=0;
1318
1319 if(P01.Distance(PV12)<tolV1) {
1320 tolV1 += P01.Distance(PV12);
1321 B.UpdateVertex(NewV1,tolV1);
1322 if(V12.Orientation()==NewV1.Orientation()) {
1323 myContext->Replace(V12,NewV1);
1324 V12 = NewV1;
1325 }
1326 else {
1327 myContext->Replace(V12,NewV1.Reversed());
1328 V12 = TopoDS::Vertex(NewV1.Reversed());
1329 }
1330 nbReplaced++; //gka 06.09.04
1331 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
1332 myContext->Replace(edge2,NewE);
1333 sewd->Set(NewE,num2+dnum1);
1334 boxes.Bind(NewE,B2); // update boxes
1335 edge2 = NewE;
1336 akey1 = 1;
1337 }
1338 if(P01.Distance(PV22)<tolV1) {
1339 tolV1 += P01.Distance(PV22);
1340 B.UpdateVertex(NewV1,tolV1);
1341 if(V22.Orientation()==NewV1.Orientation()) {
1342 myContext->Replace(V22,NewV1);
1343 V22 = NewV1;
1344 }
1345 else {
1346 myContext->Replace(V22,NewV1.Reversed());
1347 V22 = TopoDS::Vertex(NewV1.Reversed());
1348 }
1349 nbReplaced++; //gka 06.09.04
1350 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
1351 myContext->Replace(edge2,NewE);
1352 sewd->Set(NewE,num2+dnum1);
1353 boxes.Bind(NewE,B2); // update boxes
1354 edge2 = NewE;
1355 akey1 = 2;
1356 }
1357 if(P02.Distance(PV12)<tolV2) {
1358 tolV2 += P02.Distance(PV12);
1359 B.UpdateVertex(NewV2,tolV2);
1360 if(V12.Orientation()==NewV2.Orientation()) {
1361 myContext->Replace(V12,NewV2);
1362 V12 = NewV2;
1363 }
1364 else {
1365 myContext->Replace(V12,NewV2.Reversed());
1366 V12 = TopoDS::Vertex(NewV2.Reversed());
1367 }
1368 nbReplaced++; //gka 06.09.04
1369 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
1370 myContext->Replace(edge2,NewE);
1371 sewd->Set(NewE,num2+dnum1);
1372 boxes.Bind(NewE,B2); // update boxes
1373 edge2 = NewE;
1374 akey2 = 1;
1375 }
1376 if(P02.Distance(PV22)<tolV2) {
1377 tolV2 += P02.Distance(PV22);
1378 B.UpdateVertex(NewV2,tolV2);
1379 if(V22.Orientation()==NewV2.Orientation()) {
1380 myContext->Replace(V22,NewV2);
1381 V22 = NewV2;
1382 }
1383 else {
1384 myContext->Replace(V22,NewV2.Reversed());
1385 V22 = TopoDS::Vertex(NewV2.Reversed());
1386 }
1387 nbReplaced++; //gka 06.09.04
1388 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
1389 myContext->Replace(edge2,NewE);
1390 sewd->Set(NewE,num2+dnum1);
1391 boxes.Bind(NewE,B2); // update boxes
1392 edge2 = NewE;
1393 akey2 = 2;
1394 }
1395 Standard_Integer dnum2=0, numseg2=num2+dnum1;
1396 // split
1397 if( akey1==0 && akey2>0 ) {
1398 if(SplitEdge1(sewd, face, num2+dnum1, p21, NewV1, tolV1, boxes)) {
1399 NbSplit++;
1400 dnum2=1;
1401 //numseg2=num2+dnum1+1;
1402 numseg2=num2+dnum1;
1403 }
1404 }
1405 if( akey1>0 && akey2==0 ) {
1406 if(SplitEdge1(sewd, face, num2+dnum1, p22, NewV2, tolV2, boxes)) {
1407 NbSplit++;
1408 dnum2=1;
1409 //numseg2=num2+dnum1;
1410 numseg2=num2+dnum1+1;
1411 }
1412 }
1413 if( akey1==0 && akey2==0 ) {
1414 if(SplitEdge1(sewd, face, num2+dnum1, p21, NewV1, tolV1, boxes)) {
1415 NbSplit++;
1416 dnum2=1;
1417 }
1418 tmpE = sewd->Edge(num2+dnum1);
1419 Standard_Real a,b;
1420 Handle(Geom2d_Curve) c2d;
1421 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1422 if( (a-p22)*(b-p22)>0 ) { // p22 - external for [a,b] => split next edge
1423 if(SplitEdge1(sewd, face, num2+dnum1+dnum2, p22, NewV2, tolV2, boxes) ) {
1424 NbSplit++;
1425 numseg2=num2+dnum1+dnum2;
1426 dnum2++;
1427 }
1428 }
1429 else {
1430 if(SplitEdge1(sewd, face, num2+dnum1, p22, NewV2, tolV2, boxes) ) {
1431 NbSplit++;
1432 dnum2++;
1433 numseg2=num2+dnum1+1;
1434 }
1435 }
1436 }
1437 // remove segment
1438 sewd->Remove(numseg2);
1439 sewd->Remove(numseg1);
1440 NbRemoved = NbRemoved+2;
1441 //num1--;
1442 //break;
1443 }
1444 }
1445 }
1446 }
1447 }
1448 }
1449 }
1450 isDone = (NbSplit || NbCut || nbReplaced || NbRemoved);
1451 return isDone;
1452}
1453
1454
1455//=======================================================================
1456//function : FixIntersectingWires
1457//purpose :
1458//=======================================================================
1459
1460Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
1461 (TopoDS_Face& face) const
1462{
1463 if(myContext.IsNull() || face.IsNull()) return Standard_False;
1464 //TopoDS_Shape S = context->Apply(face);
1465 //TopoDS_Shape SF = TopoDS::Face(S);
1466 TopoDS_Shape SF = face;
1467 TopAbs_Orientation ori = face.Orientation();
1468 TopTools_SequenceOfShape SeqWir;
1469 TopTools_SequenceOfShape SeqNMShapes;
1470 for( TopoDS_Iterator iter(SF,Standard_False); iter.More(); iter.Next() ) {
1471 if(iter.Value().ShapeType() != TopAbs_WIRE ||
1472 (iter.Value().Orientation() != TopAbs_FORWARD &&
1473 iter.Value().Orientation() != TopAbs_REVERSED)) {
1474 SeqNMShapes.Append(iter.Value());
1475 continue;
1476 }
1477 TopoDS_Wire wire = TopoDS::Wire(iter.Value());
1478 SeqWir.Append(wire);
1479 }
1480 if(SeqWir.Length()<2) return Standard_False;//gka 06.09.04
1481
1482 Standard_Real MaxTolVert=0.0;
1483 for(TopExp_Explorer exp(SF,TopAbs_VERTEX); exp.More(); exp.Next()) {
1484 Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
1485 MaxTolVert = Max(MaxTolVert,tolV);
1486 }
1487 Standard_Boolean isDone = Standard_False; //gka 06.09.04
1488 ShapeAnalysis_Edge sae;
7c8090aa 1489 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface (BRep_Tool::Surface (face));
1490
1491 // precompute edge boxes for all wires
1492 NCollection_Sequence<ShapeFix_DataMapOfShapeBox2d> aSeqWirEdgeBoxes;
1493 NCollection_Sequence<Bnd_Box2d> aSeqWirBoxes;
1494 for (Standard_Integer n = 1; n <= SeqWir.Length(); n++)
1495 {
1496 const TopoDS_Wire& aWire = TopoDS::Wire (SeqWir.Value (n));
1497 Handle(ShapeExtend_WireData) aSewd = new ShapeExtend_WireData (aWire);
1498 ShapeFix_DataMapOfShapeBox2d aBoxes;
1499 Bnd_Box2d aTotalBox = CreateBoxes2d (aSewd, face, aBoxes);
1500 aSeqWirEdgeBoxes.Append (aBoxes);
1501 aSeqWirBoxes.Append (aTotalBox);
1502 }
7fd59977 1503
1504 for(Standard_Integer n1=1; n1<=SeqWir.Length()-1; n1++) {
1505 TopoDS_Wire wire1 = TopoDS::Wire(SeqWir.Value(n1));
1506 Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData(wire1);
7c8090aa 1507 ShapeFix_DataMapOfShapeBox2d& boxes1 = aSeqWirEdgeBoxes.ChangeValue (n1);
1508 Bnd_Box2d aBox1 = aSeqWirBoxes (n1);
7fd59977 1509 for(Standard_Integer n2=n1+1; n2<=SeqWir.Length(); n2++) {
1510 TopoDS_Wire wire2 = TopoDS::Wire(SeqWir.Value(n2));
1511 Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData(wire2);
7c8090aa 1512 ShapeFix_DataMapOfShapeBox2d& boxes2 = aSeqWirEdgeBoxes.ChangeValue (n2);
1513 Bnd_Box2d aBox2 = aSeqWirBoxes (n2);
1514 if (!aBox1.IsVoid() && !aBox2.IsVoid() && aBox1.IsOut (aBox2))
1515 {
1516 continue;
1517 }
7fd59977 1518 // detect possible intersections:
7fd59977 1519 Standard_Integer NbModif=0;
1520 Standard_Integer nbReplaced =0;//gka 06.09.04
1521 Standard_Boolean hasModifWire = Standard_False; //gka 06.09.04
1522 for(Standard_Integer num1 = 1; num1<=sewd1->NbEdges() && NbModif<30; num1++) {
1523 // for each edge from first wire
1524 TopoDS_Edge edge1 = sewd1->Edge(num1); //gka 06.09.04
1525
1526 for(Standard_Integer num2 = 1; num2<=sewd2->NbEdges() && NbModif<30; num2++) {
1527 // for each edge from second wire
1528 TopoDS_Edge edge2 = sewd2->Edge(num2);
1529 if(edge1.IsSame(edge2)) continue;
1530 if( BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2) ) continue;
1531 if( !boxes1.IsBound(edge1) || !boxes2.IsBound(edge2) ) continue;
1532 Bnd_Box2d B1 = boxes1.Find(edge1);
1533 Bnd_Box2d B2 = boxes2.Find(edge2);
1534 if(!B1.IsOut(B2)) {
1535 // intersection is possible...
1536 Standard_Real a1, b1, a2, b2;
1537 Handle(Geom2d_Curve) Crv1, Crv2;
1538 if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) )
1539 continue; //return Standard_False; gka 06.09.04
1540 if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) )
1541 continue; //return Standard_False;gka 06.09.04
1542 Standard_Real tolint = 1.0e-10;
7fd59977 1543 Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
94f71cad 1544 IntRes2d_Domain d1(C1.Value(a1),a1,tolint,C1.Value(b1),b1,tolint);
1545 IntRes2d_Domain d2(C2.Value(a2),a2,tolint,C2.Value(b2),b2,tolint);
7fd59977 1546 Geom2dInt_GInter Inter;
1547 Inter.Perform( C1, d1, C2, d2, tolint, tolint );
1548 if(!Inter.IsDone()) continue;
1549 // intersection is point
1550 if( Inter.NbPoints()>0 && Inter.NbPoints()<3 ) {
1551 IntRes2d_IntersectionPoint IP;
1552 IntRes2d_Transition Tr1, Tr2;
1553 SelectIntPnt(Inter,IP,Tr1,Tr2);
1554 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1555 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1556 // create new vertex and split both edges
1557 Standard_Real param1 = IP.ParamOnFirst();
1558 Standard_Real param2 = IP.ParamOnSecond();
94f71cad 1559 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,C1,param1);
1560 gp_Pnt pi2 = GetPointOnEdge(edge2,sas,C2,param2);
7fd59977 1561 gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
1562 BRep_Builder B;
1563 TopoDS_Vertex V;
1564 Standard_Real tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
1565 B.MakeVertex(V,P0,tolV);
1566 MaxTolVert = Max(MaxTolVert,tolV);
1567 Standard_Boolean isSplitEdge2 = SplitEdge1(sewd2, face, num2, param2,
1568 V, tolV, boxes2);
1569 if(isSplitEdge2) {
1570 NbModif++;
1571 num2--;
1572 }
1573 if(SplitEdge1(sewd1, face, num1, param1, V, tolV, boxes1)) {
1574 NbModif++;
1575 num1--;
1576 break;
1577 }
1578 if(isSplitEdge2)
1579 continue;
1580 }
1581 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1582 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1583 // find needed vertex from edge2 and split edge1 using it
1584 Standard_Real param1 = IP.ParamOnFirst();
1585 if(FindVertAndSplitEdge(param1, edge1, edge2, Crv1, MaxTolVert,
1586 num1, sewd1, face, boxes1, Standard_True) ) {
1587 NbModif++;
1588 break;
1589 }
1590 }
1591 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1592 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1593 // find needed vertex from edge1 and split edge2 using it
1594 Standard_Real param2 = IP.ParamOnSecond();
1595 if(FindVertAndSplitEdge(param2, edge2, edge1, Crv2, MaxTolVert,
1596 num2, sewd2, face, boxes2, Standard_True) ) {
1597 NbModif++;
1598 continue;
1599 }
1600 }
1601 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1602 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1603 // union vertexes
1604 if( UnionVertexes(sewd2, edge1, edge2, num2, boxes2, B2) )
1605 nbReplaced ++; //gka 06.09.04
1606 }
1607 }
1608 hasModifWire = (hasModifWire || NbModif || nbReplaced);
1609 // intersection is segment
1610 if( Inter.NbSegments()==1 ) {
1611 IntRes2d_IntersectionSegment IS = Inter.Segment(1);
1612 if ( IS.HasFirstPoint() && IS.HasLastPoint() ) {
1613 Standard_Boolean IsModified1 = Standard_False;
1614 Standard_Boolean IsModified2 = Standard_False;
1615 TopoDS_Vertex NewV;
1616 BRep_Builder B;
1617 Standard_Real newtol=0.0;
1618 IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
1619 Standard_Real p11 = IPF.ParamOnFirst();
1620 Standard_Real p21 = IPF.ParamOnSecond();
1621 IntRes2d_IntersectionPoint IPL = IS.LastPoint();
1622 Standard_Real p12 = IPL.ParamOnFirst();
1623 Standard_Real p22 = IPL.ParamOnSecond();
94f71cad 1624 gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,C1,p11);
1625 gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,C1,p12);
1626 gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,C2,p21);
1627 gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,C2,p22);
7fd59977 1628
1629 // analysis for edge1
1630 TopoDS_Vertex V1 = sae.FirstVertex(edge1);
1631 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
1632 TopoDS_Vertex V2 = sae.LastVertex(edge1);
1633 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
1634 Standard_Real dist1 = Pnt11.Distance(PV1);
1635 Standard_Real dist2 = Pnt12.Distance(PV1);
1636 Standard_Real maxdist = Max(dist1,dist2);
1637 Standard_Real pdist;
1638 if(edge1.Orientation()==TopAbs_REVERSED)
1639 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1640 else
1641 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1642 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1643 newtol = maxdist;
1644 NewV = V1;
1645 IsModified1 = Standard_True;
1646 }
1647 dist1 = Pnt11.Distance(PV2);
1648 dist2 = Pnt12.Distance(PV2);
1649 maxdist = Max(dist1,dist2);
1650 if(edge1.Orientation()==TopAbs_REVERSED)
1651 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1652 else
1653 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1654 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1655 if( ( IsModified1 && maxdist<newtol ) || !IsModified1 ) {
1656 newtol = maxdist;
1657 NewV = V2;
1658 IsModified1 = Standard_True;
1659 }
1660 }
1661 if(IsModified1) {
1662 // cut edge1 and update tolerance NewV
1663 Standard_Real dista = Abs(a1-p11)+Abs(a1-p12);
1664 Standard_Real distb = Abs(b1-p11)+Abs(b1-p12);
1665 Standard_Real pend,cut;
1666 if(dista>distb) pend=a1;
1667 else pend=b1;
1668 if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
1669 else cut=p11;
1670 Standard_Boolean IsCutLine;
0d3d226e 1671 if(!CutEdge(edge1, pend, cut, face, IsCutLine))
1672 {
1673 IsModified1 = Standard_False;
1674 continue;
1675 }
7fd59977 1676 if(newtol>BRep_Tool::Tolerance(NewV)) {
1677 B.UpdateVertex(NewV,newtol*1.00001);
1678 }
1679 }
1680
1681 // analysis for edge2
1682 TopoDS_Vertex V12 = sae.FirstVertex(edge2);
1683 gp_Pnt PV12 = BRep_Tool::Pnt(V12);
1684 TopoDS_Vertex V22 = sae.LastVertex(edge2);
1685 gp_Pnt PV22 = BRep_Tool::Pnt(V22);
1686 dist1 = Pnt21.Distance(PV12);
1687 dist2 = Pnt22.Distance(PV12);
1688 maxdist = Max(dist1,dist2);
1689 if(edge2.Orientation()==TopAbs_REVERSED)
1690 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1691 else
1692 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1693 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1694 newtol = maxdist;
1695 NewV = V12;
1696 IsModified2 = Standard_True;
1697 }
1698 dist1 = Pnt21.Distance(PV22);
1699 dist2 = Pnt22.Distance(PV22);
1700 maxdist = Max(dist1,dist2);
1701 if(edge2.Orientation()==TopAbs_REVERSED)
1702 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1703 else
1704 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1705 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1706 if( ( IsModified2 && maxdist<newtol ) || !IsModified2 ) {
1707 newtol = maxdist;
1708 NewV = V22;
1709 IsModified2 = Standard_True;
1710 }
1711 }
1712 if(IsModified2) {
1713 // cut edge1 and update tolerance NewV
1714 Standard_Real dista = Abs(a2-p21)+Abs(a2-p22);
1715 Standard_Real distb = Abs(b2-p21)+Abs(b2-p22);
1716 Standard_Real pend,cut;
1717 if(dista>distb) pend=a2;
1718 else pend=b2;
1719 if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
1720 else cut=p21;
1721 Standard_Boolean IsCutLine;
0d3d226e 1722 if(!CutEdge(edge2, pend, cut, face, IsCutLine))
1723 {
1724 IsModified2 = Standard_False;
1725 continue;
1726
1727 }
7fd59977 1728 if(newtol>BRep_Tool::Tolerance(NewV)) {
1729 B.UpdateVertex(NewV,newtol*1.00001);
1730 }
1731 }
1732
1733 if( IsModified1 || IsModified2 ) {
0d3d226e 1734 //necessary to make intersect with the same pair of the edges once again with modified ranges
1735 num2--;
7fd59977 1736 hasModifWire = Standard_True; //gka 06.09.04
1737 continue;
1738 }
1739 else {
1740 // create new vertex and split edge1 and edge2 using it
1741 if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
1742 // segment is big and we have to split each intersecting edge
1743 // on 3 edges --> middle edge - edge based on segment
1744 gp_Pnt P01( (Pnt11.X()+Pnt21.X())/2, (Pnt11.Y()+Pnt21.Y())/2,
1745 (Pnt11.Z()+Pnt21.Z())/2 );
1746 gp_Pnt P02( (Pnt12.X()+Pnt22.X())/2, (Pnt12.Y()+Pnt22.Y())/2,
1747 (Pnt12.Z()+Pnt22.Z())/2 );
1748 Standard_Real tolV1 = Max(Pnt11.Distance(P01),Pnt21.Distance(P01));
1749 tolV1 = Max(tolV1,Precision::Confusion())*1.00001;
1750 Standard_Real tolV2 = Max(Pnt12.Distance(P02),Pnt22.Distance(P02));
1751 tolV2 = Max(tolV2,Precision::Confusion())*1.00001;
1752 if( tolV1>MaxTolVert || tolV2>MaxTolVert ) continue;
1753
1754 hasModifWire = Standard_True; //gka 06.09.04
1755 TopoDS_Vertex NewV1,NewV2;
1756 TopoDS_Edge tmpE,SegE;
1757 // split edge1
1758 Standard_Integer akey1=0, akey2=0;
1759 // analysis fo P01
1760 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1761 NewV1 = V1;
1762 if(tolV1>BRep_Tool::Tolerance(V1))
1763 B.UpdateVertex(NewV1,tolV1);
1764 akey1++;
1765 }
1766 if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1767 NewV1 = V2;
1768 if(tolV1>BRep_Tool::Tolerance(V2))
1769 B.UpdateVertex(NewV1,tolV1);
1770 akey1++;
1771 }
1772 // analysis fo P02
1773 if(P02.Distance(PV1)<Max(tolV2,BRep_Tool::Tolerance(V1))) {
1774 NewV2 = V1;
1775 if(tolV2>BRep_Tool::Tolerance(V1))
1776 B.UpdateVertex(NewV2,tolV2);
1777 akey2++;
1778 }
1779 if(P02.Distance(PV2)<Max(tolV2,BRep_Tool::Tolerance(V2))) {
1780 NewV2 = V2;
1781 if(tolV2>BRep_Tool::Tolerance(V2))
1782 B.UpdateVertex(NewV2,tolV2);
1783 akey2++;
1784 }
1785 if( akey1>1 || akey2>1 ) continue;
1786 // prepare vertices
1787 if(akey1==0) B.MakeVertex(NewV1,P01,tolV1);
1788 if(akey2==0) B.MakeVertex(NewV2,P02,tolV2);
1789 // split
1790 Standard_Integer numseg1=num1;
1791 if( akey1==0 && akey2>0 ) {
1792 if(SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1)) {
1793 NbModif++;
1794 numseg1=num1+1;
1795 }
1796 }
1797 if( akey1>0 && akey2==0 ) {
1798 if(SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1) ) {
1799 NbModif++;
1800 numseg1=num1;
1801 }
1802 }
1803 if( akey1==0 && akey2==0 ) {
1804 if(SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1)) {
1805 NbModif++;
1806 }
1807 tmpE = sewd1->Edge(num1);
1808 Standard_Real a,b;
1809 Handle(Geom2d_Curve) c2d;
1810 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1811 if( (a-p12)*(b-p12)>0 ) { // p12 - external for [a,b] => split next edge
1812 if(SplitEdge1(sewd1, face, num1+1, p12, NewV2, tolV2, boxes1) ) {
1813 NbModif++;
1814 numseg1=num1+1;
1815 }
1816 }
1817 else {
1818 if(SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1) ) {
1819 NbModif++;
1820 numseg1=num1+1;
1821 }
1822 }
1823 }
1824 SegE = sewd1->Edge(numseg1); // get edge from segment
1825 // split edge2
1826 // replace vertices if it is necessary
1827 ShapeBuild_Edge sbe;
1828 akey1=0, akey2=0;
1829 if(P01.Distance(PV12)<tolV1) {
1830 tolV1 += P01.Distance(PV12);
1831 B.UpdateVertex(NewV1,tolV1);
1832 V12 = NewV1;
1833 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
1834 myContext->Replace(edge2,NewE);
1835 sewd2->Set(NewE,num2);
1836 boxes2.Bind(NewE,B2); // update boxes2
1837 edge2 = NewE;
1838 akey1 = 1;
1839 }
1840 if(P01.Distance(PV22)<tolV1) {
1841 tolV1 += P01.Distance(PV22);
1842 B.UpdateVertex(NewV1,tolV1);
1843 V22 = NewV1;
1844 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
1845 myContext->Replace(edge2,NewE);
1846 sewd2->Set(NewE,num2);
1847 boxes2.Bind(NewE,B2); // update boxes2
1848 edge2 = NewE;
1849 akey1 = 2;
1850 }
1851 if(P02.Distance(PV12)<tolV2) {
1852 tolV2 += P02.Distance(PV12);
1853 B.UpdateVertex(NewV2,tolV2);
1854 V12 = NewV2;
1855 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
1856 myContext->Replace(edge2,NewE);
1857 sewd2->Set(NewE,num2);
1858 boxes2.Bind(NewE,B2); // update boxes2
1859 edge2 = NewE;
1860 akey2 = 1;
1861 }
1862 if(P02.Distance(PV22)<tolV2) {
1863 tolV2 += P02.Distance(PV22);
1864 B.UpdateVertex(NewV2,tolV2);
1865 V22 = NewV2;
1866 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
1867 myContext->Replace(edge2,NewE);
1868 sewd2->Set(NewE,num2);
1869 boxes2.Bind(NewE,B2); // update boxes2
1870 edge2 = NewE;
1871 akey2 = 2;
1872 }
1873 // split
1874 Standard_Integer numseg2=num2;
1875 if( akey1==0 && akey2>0 ) {
1876 if(SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2)) {
1877 NbModif++;
1878 numseg2=num2+1;
1879 }
1880 }
1881 if( akey1>0 && akey2==0 ) {
1882 if(SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2)) {
1883 NbModif++;
1884 numseg2=num2;
1885 }
1886 }
1887 if( akey1==0 && akey2==0 ) {
1888 if(SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2)) {
1889 NbModif++;
1890 numseg2=num2+1;
1891 }
1892 tmpE = sewd2->Edge(num2);
1893 Standard_Real a,b;
1894 Handle(Geom2d_Curve) c2d;
1895 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1896 if( (a-p22)*(b-p22)>0 ) { // p22 - external for [a,b] => split next edge
1897 if(SplitEdge1(sewd2, face, num2+1, p22, NewV2, tolV2, boxes2) ) {
1898 NbModif++;
1899 numseg2=num2+1;
1900 }
1901 }
1902 else {
1903 if(SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2) ) {
1904 NbModif++;
1905 numseg2=num2+1;
1906 }
1907 }
1908 }
1909 tmpE = sewd2->Edge(numseg2);
1910 boxes2.Bind(tmpE,boxes1.Find(SegE)); // update boxes2
1911 if(!sae.FirstVertex(SegE).IsSame(sae.FirstVertex(tmpE))) {
1912 SegE.Reverse();
1913 }
1914 myContext->Replace(tmpE,SegE);
1915 sewd2->Set(SegE,numseg2);
1916 num1--;
1917 break;
1918 }
1919 else {
1920 // split each intersecting edge on two edges
1921 gp_Pnt P0( (Pnt11.X()+Pnt12.X())/2, (Pnt11.Y()+Pnt12.Y())/2,
1922 (Pnt11.Z()+Pnt12.Z())/2 );
1923 Standard_Real param1 = (p11+p12)/2;
1924 Standard_Real param2 = (p21+p22)/2;
94f71cad 1925 gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,C1,param1);
1926 gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,C2,param2);
7fd59977 1927 dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(Pnt10));
1928 dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(Pnt10));
1929 Standard_Real tolV = Max(dist1,dist2);
1930 tolV = Max(tolV,Pnt10.Distance(Pnt20))*1.00001;
1931 B.MakeVertex(NewV,Pnt10,tolV);
1932 MaxTolVert = Max(MaxTolVert,tolV);
1933 hasModifWire = Standard_True;
1934 if(SplitEdge2(sewd2, face, num2, p21, p22, NewV, tolV, boxes2)) {
1935 NbModif++;
1936 num2--;
1937 }
1938 if(SplitEdge2(sewd1, face, num1, p11, p12, NewV, tolV, boxes1)) {
1939 NbModif++;
1940 num1--;
1941 break;
1942 }
1943 }
1944 }
1945 }
1946 } // end if(Inter.NbSegments()==1)
1947
1948 }
1949 }
1950 }
1951 if(hasModifWire) {
1952 isDone = Standard_True;
1953 SeqWir.SetValue(n1,sewd1->Wire());
1954 myContext->Replace( wire1, sewd1->Wire() );
1955 wire1 = sewd1->Wire();
7c8090aa 1956 //recompute boxes for wire1
1957 boxes1.Clear();
1958 Bnd_Box2d aNewBox1 = CreateBoxes2d (sewd1, face, boxes1);
1959 aSeqWirBoxes.SetValue (n1, aNewBox1);
7fd59977 1960 SeqWir.SetValue(n2,sewd2->Wire());
1961 myContext->Replace( wire2, sewd2->Wire() );
1962 wire2 = sewd2->Wire();
7c8090aa 1963 //recompute boxes for wire2
1964 boxes2.Clear();
1965 Bnd_Box2d aNewBox2 = CreateBoxes2d (sewd2, face, boxes2);
1966 aSeqWirBoxes.SetValue (n2, aNewBox2);
7fd59977 1967 }
1968
1969 }
1970 }
1971
1972 if(isDone) {
1973 // update face
1974 TopoDS_Shape emptyCopied = face.EmptyCopied();
1975 TopoDS_Face newface = TopoDS::Face (emptyCopied);
1976 newface.Orientation(TopAbs_FORWARD);
1977 BRep_Builder B;
1978 Standard_Integer i=1;
9cbe6290 1979 for(i=1 ; i<=SeqWir.Length(); i++) {
7fd59977 1980 TopoDS_Wire wire = TopoDS::Wire(SeqWir.Value(i));
1981 B.Add(newface,wire);
1982 }
9cbe6290 1983 for(i=1 ; i<=SeqNMShapes.Length(); i++) {
7fd59977 1984 TopoDS_Shape aNMS = SeqNMShapes.Value(i);
1985 B.Add(newface,aNMS);
1986 }
1987 newface.Orientation(ori);
1988 myContext->Replace(face,newface);
1989 face = newface;
1990 }
1991 return isDone;
1992}
1993