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