1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <ShapeFix_IntersectionTool.ixx>
16 #include <BRep_Builder.hxx>
17 #include <BRep_Tool.hxx>
18 #include <BRepTools.hxx>
19 #include <Bnd_Box2d.hxx>
20 #include <BndLib_Add2dCurve.hxx>
21 #include <Geom_Curve.hxx>
22 #include <Geom_Surface.hxx>
23 #include <Geom2d_BSplineCurve.hxx>
24 #include <Geom2d_Curve.hxx>
25 #include <Geom2d_Line.hxx>
26 #include <Geom2d_TrimmedCurve.hxx>
27 #include <Geom2dAdaptor_Curve.hxx>
28 #include <Geom2dInt_GInter.hxx>
30 #include <IntRes2d_Domain.hxx>
31 #include <IntRes2d_IntersectionPoint.hxx>
32 #include <IntRes2d_IntersectionSegment.hxx>
33 #include <IntRes2d_Position.hxx>
34 #include <ShapeAnalysis.hxx>
35 #include <ShapeAnalysis_Edge.hxx>
36 #include <ShapeAnalysis_Surface.hxx>
37 #include <ShapeAnalysis_TransferParametersProj.hxx>
38 #include <ShapeBuild_Edge.hxx>
39 #include <ShapeFix_DataMapOfShapeBox2d.hxx>
40 #include <TopExp_Explorer.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <TopoDS_Wire.hxx>
44 #include <TopTools_SequenceOfShape.hxx>
45 #include <NCollection_Sequence.hxx>
47 //gka 06.09.04 BUG 6555 shape is modified always independently either intersection was fixed or not
48 //=======================================================================
49 //function : ShapeFix_IntersectionTool
51 //=======================================================================
53 ShapeFix_IntersectionTool::ShapeFix_IntersectionTool(const Handle(ShapeBuild_ReShape)& context,
54 const Standard_Real preci,
55 const Standard_Real maxtol)
63 //=======================================================================
64 //function : GetPointOnEdge
66 //:h0 abv 29 May 98: PRO10105 1949: like in BRepCheck, point is to be taken
67 // from 3d curve (but only if edge is SameParameter)
68 //=======================================================================
69 static gp_Pnt GetPointOnEdge(const TopoDS_Edge &edge,
70 const Handle(ShapeAnalysis_Surface) &surf,
71 const Handle(Geom2d_Curve) &Crv2d,
72 const Standard_Real param )
74 if( BRep_Tool::SameParameter(edge) ) {
77 const Handle(Geom_Curve) ConS = BRep_Tool::Curve ( edge, L, f, l );
79 return ConS->Value(param).Transformed(L.Transformation());
81 return surf->Value(Crv2d->Value(param));
85 //=======================================================================
86 //function : SplitEdge
88 //=======================================================================
90 Standard_Boolean ShapeFix_IntersectionTool::SplitEdge(const TopoDS_Edge& edge,
91 const Standard_Real param,
92 const TopoDS_Vertex& vert,
93 const TopoDS_Face& face,
96 const Standard_Real preci) const
99 ShapeAnalysis_Edge sae;
101 TopoDS_Vertex V1 = sae.FirstVertex(edge);
102 TopoDS_Vertex V2 = sae.LastVertex(edge);
103 if( V1.IsSame(vert) || V2.IsSame(vert) )
104 return Standard_False;
106 Handle(Geom2d_Curve) c2d;
107 sae.PCurve(edge,face,c2d,a,b,Standard_True );
108 if( Abs(a-param)<0.01*preci || Abs(b-param)<0.01*preci )
109 return Standard_False;
110 // check distanse between edge and new vertex
113 if(BRep_Tool::SameParameter(edge) && !BRep_Tool::Degenerated(edge)) {
115 const Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,L,f,l);
117 return Standard_False;
118 P1 = c3d->Value(param);
119 if(!L.IsIdentity()) P1 = P1.Transformed(L.Transformation());
122 Handle(Geom_Surface) surf = BRep_Tool::Surface(face,L);
123 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(surf);
124 P1 = sas->Value(c2d->Value(param));
125 if(!L.IsIdentity()) P1 = P1.Transformed(L.Transformation());
127 gp_Pnt P2 = BRep_Tool::Pnt(vert);
128 if(P1.Distance(P2)>preci) {
129 //return Standard_False;
131 B.UpdateVertex(vert,P1.Distance(P2));
134 Handle(ShapeAnalysis_TransferParametersProj) transferParameters =
135 new ShapeAnalysis_TransferParametersProj;
136 transferParameters->SetMaxTolerance(preci);
137 transferParameters->Init(edge,face);
138 Standard_Real first, last;
149 TopAbs_Orientation orient = edge.Orientation();
151 TopoDS_Edge wE = edge;
152 wE.Orientation ( TopAbs_FORWARD );
153 TopoDS_Shape aTmpShape = vert.Oriented(TopAbs_REVERSED); //for porting
154 newE1 = sbe.CopyReplaceVertices ( wE, sae.FirstVertex(wE), TopoDS::Vertex(aTmpShape) );
155 sbe.CopyPCurves ( newE1, wE );
156 transferParameters->TransferRange(newE1,first,param,Standard_True);
157 B.SameRange(newE1,Standard_False);
158 B.SameParameter(newE1,Standard_False);
159 aTmpShape = vert.Oriented(TopAbs_FORWARD);
160 newE2 = sbe.CopyReplaceVertices ( wE, TopoDS::Vertex(aTmpShape),sae.LastVertex(wE) );
161 sbe.CopyPCurves ( newE2, wE );
162 transferParameters->TransferRange(newE2,param,last,Standard_True);
163 B.SameRange(newE2,Standard_False);
164 B.SameParameter(newE2,Standard_False);
166 newE1.Orientation(orient);
167 newE2.Orientation(orient);
168 if (orient==TopAbs_REVERSED) {
169 TopoDS_Edge tmp = newE2; newE2 = newE1; newE1=tmp;
172 return Standard_True;
176 //=======================================================================
179 //=======================================================================
181 Standard_Boolean ShapeFix_IntersectionTool::CutEdge(const TopoDS_Edge &edge,
182 const Standard_Real pend,
183 const Standard_Real cut,
184 const TopoDS_Face &face,
185 Standard_Boolean &iscutline) const
187 if( Abs(cut-pend)<10.*Precision::PConfusion() ) return Standard_False;
188 Standard_Real aRange = Abs(cut-pend);
190 BRep_Tool::Range(edge, a, b);
192 if( aRange<10.*Precision::PConfusion() ) return Standard_False;
194 // case pcurve is trimm of line
195 if( !BRep_Tool::SameParameter(edge) ) {
196 ShapeAnalysis_Edge sae;
197 Handle(Geom2d_Curve) Crv;
199 if ( sae.PCurve(edge,face,Crv,fp,lp,Standard_False) ) {
200 if(Crv->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
201 Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(Crv);
202 if(tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Line))) {
204 B.Range(edge,Min(pend,cut),Max(pend,cut));
205 if( Abs(pend-lp)<Precision::PConfusion() ) { // cut from the begining
206 Standard_Real cut3d = (cut-fp)*(b-a)/(lp-fp);
207 B.Range(edge, a+cut3d, b, Standard_True);
208 iscutline = Standard_True;
210 else if( Abs(pend-fp)<Precision::PConfusion() ) { // cut from the end
211 Standard_Real cut3d = (lp-cut)*(b-a)/(lp-fp);
212 B.Range(edge, a, b-cut3d, Standard_True);
213 iscutline = Standard_True;
217 return Standard_True;
220 return Standard_False;
223 // det-study on 03/12/01 checking the old and new ranges
224 if( Abs(Abs(a-b)-aRange) < Precision::PConfusion() ) return Standard_False;
225 if( aRange<10.*Precision::PConfusion() ) return Standard_False;
228 B.Range( edge, Min(pend,cut), Max(pend,cut) );
230 return Standard_True;
234 //=======================================================================
235 //function : SplitEdge1
236 //purpose : split edge[a,b] om two part e1[a,param]
237 // and e2[param,b] using vertex vert
238 //=======================================================================
240 Standard_Boolean ShapeFix_IntersectionTool::SplitEdge1(const Handle(ShapeExtend_WireData)& sewd,
241 const TopoDS_Face& face,
242 const Standard_Integer num,
243 const Standard_Real param,
244 const TopoDS_Vertex& vert,
245 const Standard_Real preci,
246 ShapeFix_DataMapOfShapeBox2d& boxes) const
248 TopoDS_Edge edge = sewd->Edge(num);
249 TopoDS_Edge newE1, newE2;
250 if(!SplitEdge(edge,param,vert,face,newE1,newE2,preci)) return Standard_False;
253 Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
256 if(!myContext.IsNull()) myContext->Replace( edge, wd->Wire() );
257 for (TopExp_Explorer exp ( wd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
258 TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
259 BRepTools::Update(E);
263 sewd->Set(newE1,num);
264 if(num==sewd->NbEdges())
267 sewd->Add(newE2,num+1);
272 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
273 Handle(Geom2d_Curve) c2d;
275 ShapeAnalysis_Edge sae;
276 if(sae.PCurve(newE1,S,L,c2d,cf,cl,Standard_False)) {
278 Geom2dAdaptor_Curve gac;
279 Standard_Real aFirst = c2d->FirstParameter();
280 Standard_Real aLast = c2d->LastParameter();
281 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
282 && (cf < aFirst || cl > aLast)) {
283 //pdn avoiding problems with segment in Bnd_Box
288 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
289 boxes.Bind(newE1,box);
291 if(sae.PCurve(newE2,S,L,c2d,cf,cl,Standard_False)) {
293 Geom2dAdaptor_Curve gac;
294 Standard_Real aFirst = c2d->FirstParameter();
295 Standard_Real aLast = c2d->LastParameter();
296 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
297 && (cf < aFirst || cl > aLast)) {
298 //pdn avoiding problems with segment in Bnd_Box
303 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
304 boxes.Bind(newE2,box);
307 return Standard_True;
311 //=======================================================================
312 //function : SplitEdge2
313 //purpose : auxilary: split edge[a,b] om two part e1[a,param1]
314 // and e2[param2,b] using vertex vert
315 // (remove segment (param1,param2) from edge)
316 //=======================================================================
318 Standard_Boolean ShapeFix_IntersectionTool::SplitEdge2(const Handle(ShapeExtend_WireData)& sewd,
319 const TopoDS_Face& face,
320 const Standard_Integer num,
321 const Standard_Real param1,
322 const Standard_Real param2,
323 const TopoDS_Vertex& vert,
324 const Standard_Real preci,
325 ShapeFix_DataMapOfShapeBox2d& boxes) const
327 TopoDS_Edge edge = sewd->Edge(num);
328 TopoDS_Edge newE1, newE2;
329 Standard_Real param = (param1+param2)/2;
330 if(!SplitEdge(edge,param,vert,face,newE1,newE2,preci)) return Standard_False;
331 // cut new edges by param1 and param2
332 Standard_Boolean IsCutLine;
333 Handle(Geom2d_Curve) Crv1, Crv2;
334 Standard_Real fp1,lp1,fp2,lp2;
335 ShapeAnalysis_Edge sae;
336 if(sae.PCurve ( newE1, face, Crv1, fp1, lp1, Standard_False )) {
337 if(sae.PCurve ( newE2, face, Crv2, fp2, lp2, Standard_False )) {
339 if( (lp1-fp1)*(lp1-param1)>0 ) {
340 CutEdge(newE1, fp1, param1, face, IsCutLine);
341 CutEdge(newE2, lp2, param2, face, IsCutLine);
344 CutEdge(newE1, fp1, param2, face, IsCutLine);
345 CutEdge(newE2, lp2, param1, face, IsCutLine);
349 if( (fp1-lp1)*(fp1-param1)>0 ) {
350 CutEdge(newE1, lp1, param1, face, IsCutLine);
351 CutEdge(newE2, fp2, param2, face, IsCutLine);
354 CutEdge(newE1, lp1, param2, face, IsCutLine);
355 CutEdge(newE2, fp2, param1, face, IsCutLine);
362 Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
365 if(!myContext.IsNull()) myContext->Replace( edge, wd->Wire() );
366 for (TopExp_Explorer exp ( wd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
367 TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
368 BRepTools::Update(E);
372 sewd->Set(newE1,num);
373 if(num==sewd->NbEdges())
376 sewd->Add(newE2,num+1);
381 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
382 Handle(Geom2d_Curve) c2d;
384 if(sae.PCurve(newE1,S,L,c2d,cf,cl,Standard_False)) {
386 Geom2dAdaptor_Curve gac;
387 Standard_Real aFirst = c2d->FirstParameter();
388 Standard_Real aLast = c2d->LastParameter();
389 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
390 && (cf < aFirst || cl > aLast)) {
391 //pdn avoiding problems with segment in Bnd_Box
396 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
397 boxes.Bind(newE1,box);
399 if(sae.PCurve(newE2,S,L,c2d,cf,cl,Standard_False)) {
401 Geom2dAdaptor_Curve gac;
402 Standard_Real aFirst = c2d->FirstParameter();
403 Standard_Real aLast = c2d->LastParameter();
404 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
405 && (cf < aFirst || cl > aLast)) {
406 //pdn avoiding problems with segment in Bnd_Box
411 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
412 boxes.Bind(newE2,box);
415 return Standard_True;
419 //=======================================================================
420 //function : UnionVertexes
422 //=======================================================================
424 Standard_Boolean ShapeFix_IntersectionTool::UnionVertexes(const Handle(ShapeExtend_WireData)& sewd,
427 const Standard_Integer num2,
428 ShapeFix_DataMapOfShapeBox2d& boxes,
429 const Bnd_Box2d& B2) const
432 Standard_Boolean res = Standard_False;
434 ShapeAnalysis_Edge sae;
437 TopoDS_Vertex V1F = sae.FirstVertex(edge1);
438 gp_Pnt PV1F = BRep_Tool::Pnt(V1F);
439 TopoDS_Vertex V1L = sae.LastVertex(edge1);
440 gp_Pnt PV1L = BRep_Tool::Pnt(V1L);
441 TopoDS_Vertex V2F = sae.FirstVertex(edge2);
442 gp_Pnt PV2F = BRep_Tool::Pnt(V2F);
443 TopoDS_Vertex V2L = sae.LastVertex(edge2);
444 gp_Pnt PV2L = BRep_Tool::Pnt(V2L);
445 Standard_Real d11 = PV1F.Distance(PV2F);
446 Standard_Real d12 = PV1F.Distance(PV2L);
447 Standard_Real d21 = PV1L.Distance(PV2F);
448 Standard_Real d22 = PV1L.Distance(PV2L);
449 if(d11<d12 && d11<d21 && d11<d22) {
450 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F),BRep_Tool::Tolerance(V2F));
451 if( !V2F.IsSame(V1F) && d11<tolv ) {
452 // union vertexes V1F and V2F
453 B.UpdateVertex(V1F,tolv);
454 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V1F,V2L);
455 // cout<<"union vertexes V1F and V2F"<<endl;
456 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
457 // B.MakeVertex(V,Ptmp,tolv);
458 // myContext->Replace(V1F,V);
459 // myContext->Replace(V2F,V);
460 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
461 myContext->Replace(edge2,NewE);
462 sewd->Set(NewE,num2);
464 boxes.Bind(NewE,B2); // update boxes
465 // replace vertex in other edge
466 Standard_Integer num21,num22;
467 if(num2>1) num21=num2-1;
468 else num21=sewd->NbEdges();
469 if(num2<sewd->NbEdges()) num22=num2+1;
471 TopoDS_Edge edge21 = sewd->Edge(num21);
472 TopoDS_Edge edge22 = sewd->Edge(num22);
473 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
474 TopoDS_Vertex V21L = sae.LastVertex(edge21);
475 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
476 TopoDS_Vertex V22L = sae.LastVertex(edge22);
477 if(V21F.IsSame(V2F)) {
478 NewE = sbe.CopyReplaceVertices(edge21,V1F,V21L);
479 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
480 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
481 myContext->Replace(edge21,NewE);
482 sewd->Set(NewE,num21);
484 if(V21L.IsSame(V2F)) {
485 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1F);
486 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
487 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
488 myContext->Replace(edge21,NewE);
489 sewd->Set(NewE,num21);
491 if(V22F.IsSame(V2F)) {
492 NewE = sbe.CopyReplaceVertices(edge22,V1F,V22L);
493 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
494 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
495 myContext->Replace(edge22,NewE);
496 sewd->Set(NewE,num22);
498 if(V22L.IsSame(V2F)) {
499 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1F);
500 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
501 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
502 myContext->Replace(edge22,NewE);
503 sewd->Set(NewE,num22);
508 else if(d12<d21 && d12<d22) {
509 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F),BRep_Tool::Tolerance(V2L));
510 if( !V2L.IsSame(V1F) && d12<tolv ) {
511 // union vertexes V1F and V2L
512 B.UpdateVertex(V1F,tolv);
513 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V1F);
514 // cout<<"union vertexes V1F and V2L"<<endl;
515 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
516 // B.MakeVertex(V,Ptmp,tolv);
517 // myContext->Replace(V1F,V);
518 // myContext->Replace(V2L,V);
519 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
520 myContext->Replace(edge2,NewE);
521 sewd->Set(NewE,num2);
523 //boxes.Bind(NewE,boxes.Find(edge2)); // update boxes
524 boxes.Bind(NewE,B2); // update boxes
525 // replace vertex in other edge
526 Standard_Integer num21,num22;
527 if(num2>1) num21=num2-1;
528 else num21=sewd->NbEdges();
529 if(num2<sewd->NbEdges()) num22=num2+1;
531 TopoDS_Edge edge21 = sewd->Edge(num21);
532 TopoDS_Edge edge22 = sewd->Edge(num22);
533 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
534 TopoDS_Vertex V21L = sae.LastVertex(edge21);
535 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
536 TopoDS_Vertex V22L = sae.LastVertex(edge22);
537 if(V21F.IsSame(V2L)) {
538 NewE = sbe.CopyReplaceVertices(edge21,V1F,V21L);
539 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
540 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
541 myContext->Replace(edge21,NewE);
542 sewd->Set(NewE,num21);
544 if(V21L.IsSame(V2L)) {
545 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1F);
546 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
547 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
548 myContext->Replace(edge21,NewE);
549 sewd->Set(NewE,num21);
551 if(V22F.IsSame(V2L)) {
552 NewE = sbe.CopyReplaceVertices(edge22,V1F,V22L);
553 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
554 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
555 myContext->Replace(edge22,NewE);
556 sewd->Set(NewE,num22);
558 if(V22L.IsSame(V2L)) {
559 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1F);
560 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
561 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
562 myContext->Replace(edge22,NewE);
563 sewd->Set(NewE,num22);
569 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L),BRep_Tool::Tolerance(V2F));
570 if( !V2F.IsSame(V1L) && d21<tolv ) {
571 // union vertexes V1L and V2F
572 B.UpdateVertex(V1L,tolv);
573 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V1L,V2L);
574 // cout<<"union vertexes V1L and V2F"<<endl;
575 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
576 // B.MakeVertex(V,Ptmp,tolv);
577 // myContext->Replace(V1L,V);
578 // myContext->Replace(V2F,V);
579 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
580 myContext->Replace(edge2,NewE);
581 sewd->Set(NewE,num2);
583 boxes.Bind(NewE,B2); // update boxes
584 // replace vertex in other edge
585 Standard_Integer num21,num22;
586 if(num2>1) num21=num2-1;
587 else num21=sewd->NbEdges();
588 if(num2<sewd->NbEdges()) num22=num2+1;
590 TopoDS_Edge edge21 = sewd->Edge(num21);
591 TopoDS_Edge edge22 = sewd->Edge(num22);
592 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
593 TopoDS_Vertex V21L = sae.LastVertex(edge21);
594 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
595 TopoDS_Vertex V22L = sae.LastVertex(edge22);
596 if(V21F.IsSame(V2F)) {
597 NewE = sbe.CopyReplaceVertices(edge21,V1L,V21L);
598 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
599 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
600 myContext->Replace(edge21,NewE);
601 sewd->Set(NewE,num21);
603 if(V21L.IsSame(V2F)) {
604 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1L);
605 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
606 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
607 myContext->Replace(edge21,NewE);
608 sewd->Set(NewE,num21);
610 if(V22F.IsSame(V2F)) {
611 NewE = sbe.CopyReplaceVertices(edge22,V1L,V22L);
612 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
613 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
614 myContext->Replace(edge22,NewE);
615 sewd->Set(NewE,num22);
617 if(V22L.IsSame(V2F)) {
618 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1L);
619 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
620 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
621 myContext->Replace(edge22,NewE);
622 sewd->Set(NewE,num22);
628 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L),BRep_Tool::Tolerance(V2L));
629 if( !V2L.IsSame(V1L) && d22<tolv ) {
630 // union vertexes V1L and V2L
631 B.UpdateVertex(V1L,tolv);
632 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V1L);
633 // cout<<"union vertexes V1L and V2L"<<endl;
634 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
635 // B.MakeVertex(V,Ptmp,tolv);
636 // myContext->Replace(V1L,V);
637 // myContext->Replace(V2L,V);
638 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
639 myContext->Replace(edge2,NewE);
640 sewd->Set(NewE,num2);
642 boxes.Bind(NewE,B2); // update boxes
643 // replace vertex in other edge
644 Standard_Integer num21,num22;
645 if(num2>1) num21=num2-1;
646 else num21=sewd->NbEdges();
647 if(num2<sewd->NbEdges()) num22=num2+1;
649 TopoDS_Edge edge21 = sewd->Edge(num21);
650 TopoDS_Edge edge22 = sewd->Edge(num22);
651 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
652 TopoDS_Vertex V21L = sae.LastVertex(edge21);
653 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
654 TopoDS_Vertex V22L = sae.LastVertex(edge22);
655 if(V21F.IsSame(V2L)) {
656 NewE = sbe.CopyReplaceVertices(edge21,V1L,V21L);
657 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
658 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
659 myContext->Replace(edge21,NewE);
660 sewd->Set(NewE,num21);
662 if(V21L.IsSame(V2L)) {
663 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1L);
664 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
665 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
666 myContext->Replace(edge21,NewE);
667 sewd->Set(NewE,num21);
669 if(V22F.IsSame(V2L)) {
670 NewE = sbe.CopyReplaceVertices(edge22,V1L,V22L);
671 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
672 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
673 myContext->Replace(edge22,NewE);
674 sewd->Set(NewE,num22);
676 if(V22L.IsSame(V2L)) {
677 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1L);
678 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
679 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
680 myContext->Replace(edge22,NewE);
681 sewd->Set(NewE,num22);
691 //=======================================================================
692 //function : CreateBoxes2d
694 //=======================================================================
695 static Bnd_Box2d CreateBoxes2d(const Handle(ShapeExtend_WireData)& sewd,
696 const TopoDS_Face& face,
697 ShapeFix_DataMapOfShapeBox2d& boxes)
699 // create box2d for edges from wire
702 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
703 Handle(Geom2d_Curve) c2d;
705 ShapeAnalysis_Edge sae;
706 for(Standard_Integer i=1; i<=sewd->NbEdges(); i++){
707 TopoDS_Edge E = sewd->Edge(i);
708 if(sae.PCurve(E,S,L,c2d,cf,cl,Standard_False)) {
710 Geom2dAdaptor_Curve gac;
711 Standard_Real aFirst = c2d->FirstParameter();
712 Standard_Real aLast = c2d->LastParameter();
713 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
714 && (cf < aFirst || cl > aLast)) {
715 //pdn avoiding problems with segment in Bnd_Box
720 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
729 //=======================================================================
730 //function : SelectIntPnt
732 //=======================================================================
733 static void SelectIntPnt(const Geom2dInt_GInter& Inter,
734 IntRes2d_IntersectionPoint& IP,
735 IntRes2d_Transition& Tr1,
736 IntRes2d_Transition& Tr2)
739 Tr1 = IP.TransitionOfFirst();
740 Tr2 = IP.TransitionOfSecond();
741 if(Inter.NbPoints()==2) {
742 // possible second point is better?
743 Standard_Integer status1=0,status2=0;
744 if(Tr1.PositionOnCurve()==IntRes2d_Middle) status1+=1;
745 if(Tr2.PositionOnCurve()==IntRes2d_Middle) status1+=2;
746 IntRes2d_IntersectionPoint IP2;
747 IntRes2d_Transition Tr12, Tr22;
748 IP2 = Inter.Point(2);
749 Tr12 = IP2.TransitionOfFirst();
750 Tr22 = IP2.TransitionOfSecond();
751 if(Tr12.PositionOnCurve()==IntRes2d_Middle) status2+=1;
752 if(Tr22.PositionOnCurve()==IntRes2d_Middle) status2+=2;
753 if(status2>status1) {
754 IP=IP2; Tr1=Tr12; Tr2=Tr22;
760 //=======================================================================
761 //function : FindVertAndSplitEdge
763 //=======================================================================
764 Standard_Boolean ShapeFix_IntersectionTool::FindVertAndSplitEdge
765 (const Standard_Real param1,
766 const TopoDS_Edge& edge1, const TopoDS_Edge& edge2,
767 const Handle(Geom2d_Curve)& Crv1,
768 Standard_Real& MaxTolVert,
769 Standard_Integer& num1,
770 const Handle(ShapeExtend_WireData)& sewd,
771 const TopoDS_Face& face,
772 ShapeFix_DataMapOfShapeBox2d& boxes,
773 const Standard_Boolean aTmpKey) const
775 // find needed vertex from edge2 and split edge1 using it
776 ShapeAnalysis_Edge sae;
777 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
778 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
782 TopoDS_Vertex V1 = sae.FirstVertex(edge2);
783 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
784 TopoDS_Vertex V2 = sae.LastVertex(edge2);
785 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
786 TopoDS_Vertex V11 = sae.FirstVertex(edge1);
787 TopoDS_Vertex V12 = sae.LastVertex(edge1);
788 Standard_Boolean NeedSplit = Standard_True;
789 if(pi1.Distance(PV1)<pi1.Distance(PV2)) {
790 if( V1.IsSame(V11) || V1.IsSame(V12) ) {
791 NeedSplit = Standard_False;
794 tolV = Max( (pi1.Distance(PV1)/2)*1.00001, BRep_Tool::Tolerance(V1) );
797 if( V2.IsSame(V11) || V2.IsSame(V12) ) {
798 NeedSplit = Standard_False;
801 tolV = Max( (pi1.Distance(PV2)/2)*1.00001, BRep_Tool::Tolerance(V2) );
803 if( NeedSplit || aTmpKey ) {
804 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
805 B.UpdateVertex(V,tolV);
806 MaxTolVert = Max(MaxTolVert,tolV);
809 return Standard_True;
813 return Standard_False;
817 //=======================================================================
818 //function : FixSelfIntersectWire
820 //=======================================================================
822 Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
823 (Handle(ShapeExtend_WireData)& sewd, const TopoDS_Face& face,
824 Standard_Integer& NbSplit, Standard_Integer& NbCut,
825 Standard_Integer& NbRemoved) const
827 if(myContext.IsNull() || face.IsNull()) return Standard_False;
829 //Standard_Real area2d = ShapeAnalysis::TotCross2D(sewd,face);
830 //if(area2d<Precision::PConfusion()*Precision::PConfusion()) return Standard_False; //gka 06.09.04 BUG 6555
832 TopoDS_Shape SF = face;
833 Standard_Real MaxTolVert=0.0;
834 for(TopExp_Explorer exp(SF,TopAbs_VERTEX); exp.More(); exp.Next()) {
835 Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
836 MaxTolVert = Max(MaxTolVert,tolV);
838 MaxTolVert = Min(MaxTolVert,myMaxTol);
839 ShapeAnalysis_Edge sae;
841 // step 1 : intersection of adjacent edges
843 // step 2 : intersection of non-adjacent edges
844 ShapeFix_DataMapOfShapeBox2d boxes;
845 (void)CreateBoxes2d(sewd,face,boxes);
846 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
850 Standard_Integer nbReplaced =0;
851 Standard_Boolean isDone = Standard_False;
852 for(Standard_Integer num1=1; num1<sewd->NbEdges() && NbSplit<30; num1++) {
853 // for each edge from first wire
854 for(Standard_Integer num2=num1+2; num2<=sewd->NbEdges() && NbSplit<30; num2++) {
855 // for each edge from second wire
856 if( num1==1 && num2==sewd->NbEdges() ) continue;
857 TopoDS_Edge edge1 = sewd->Edge(num1);
858 TopoDS_Edge edge2 = sewd->Edge(num2);
859 if(edge1.IsSame(edge2)) continue;
860 if( BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2) ) continue;
861 if( !boxes.IsBound(edge1) || !boxes.IsBound(edge2) ) continue;
862 Bnd_Box2d B1 = boxes.Find(edge1);
863 Bnd_Box2d B2 = boxes.Find(edge2);
865 // intersection is possible...
866 Standard_Real a1, b1, a2, b2;
867 Handle(Geom2d_Curve) Crv1, Crv2;
868 if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) ) return Standard_False;
869 if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) ) return Standard_False;
870 Standard_Real tolint = 1.0e-10;
871 IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
872 IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
873 Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
874 Geom2dInt_GInter Inter;
875 Inter.Perform( C1, d1, C2, d2, tolint, tolint );
876 if(!Inter.IsDone()) continue;
877 // intersection is point
878 if( Inter.NbPoints()>0 && Inter.NbPoints()<3 ) {
879 IntRes2d_IntersectionPoint IP;
880 IntRes2d_Transition Tr1, Tr2;
881 SelectIntPnt(Inter,IP,Tr1,Tr2);
882 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
883 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
884 Standard_Real param1 = IP.ParamOnFirst();
885 Standard_Real param2 = IP.ParamOnSecond();
886 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
887 gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
890 Standard_Real tolV=0;
891 // analysis for edge1
892 Standard_Boolean ModifE1 = Standard_False;
893 TopoDS_Vertex VF1 = sae.FirstVertex(edge1);
894 gp_Pnt PVF1 = BRep_Tool::Pnt(VF1);
895 TopoDS_Vertex VL1 = sae.LastVertex(edge1);
896 gp_Pnt PVL1 = BRep_Tool::Pnt(VL1);
897 Standard_Real dist1 = pi1.Distance(PVF1);
898 Standard_Real dist2 = pi1.Distance(PVL1);
899 Standard_Real distmin = Min(dist1, dist2);
900 if( dist1 != dist2 && distmin < MaxTolVert ) {
902 tolV = Max( dist1*1.00001, BRep_Tool::Tolerance(VF1) );
903 B.UpdateVertex(VF1,tolV);
906 tolV = Max( dist2*1.00001, BRep_Tool::Tolerance(VL1) );
907 B.UpdateVertex(VL1,tolV);
911 Standard_Real dista = Abs(a1-param1);
912 Standard_Real distb = Abs(b1-param1);
913 Standard_Boolean IsCutLine;
914 ModifE1 = CutEdge(edge1, (( dista > distb ) ? a1 : b1 ), param1, face, IsCutLine);
917 //not needed split edge, if one of parts is too small
918 ModifE1 = ModifE1 || distmin < Precision::Confusion();
920 // analysis for edge2
921 Standard_Boolean ModifE2 = Standard_False;
922 TopoDS_Vertex VF2 = sae.FirstVertex(edge2);
923 gp_Pnt PVF2 = BRep_Tool::Pnt(VF2);
924 TopoDS_Vertex VL2 = sae.LastVertex(edge2);
925 gp_Pnt PVL2 = BRep_Tool::Pnt(VL2);
926 dist1 = pi2.Distance(PVF2);
927 dist2 = pi2.Distance(PVL2);
928 distmin = Min(dist1, dist2);
929 if( dist1 != dist2 && distmin < MaxTolVert ) {
931 tolV = Max( dist1*1.00001, BRep_Tool::Tolerance(VF2) );
932 B.UpdateVertex(VF2,tolV);
935 tolV = Max( dist2*1.00001, BRep_Tool::Tolerance(VL2) );
936 B.UpdateVertex(VL2,tolV);
940 Standard_Real dista = Abs(a2-param2);
941 Standard_Real distb = Abs(b2-param2);
942 Standard_Boolean IsCutLine;
943 ModifE2 = CutEdge(edge2, (( dista > distb ) ? a2 : b2 ), param2, face, IsCutLine);
946 //not needed split edge, if one of parts is too small
947 ModifE2 = ModifE2 || distmin < Precision::Confusion();
949 if( ModifE1 && !ModifE2 ) {
950 if(SplitEdge1(sewd, face, num2, param2, V, tolV, boxes)) {
957 if( !ModifE1 && ModifE2 ) {
958 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
964 if( !ModifE1 && !ModifE2 ) {
965 gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
966 tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
967 B.MakeVertex(V,P0,tolV);
968 MaxTolVert = Max(MaxTolVert,tolV);
969 Standard_Boolean isEdgeSplit2 = SplitEdge1(sewd, face, num2, param2,
975 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
984 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
985 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
986 // find needed vertex from edge2 and split edge1 using it
987 Standard_Real param1 = IP.ParamOnFirst();
988 if(FindVertAndSplitEdge(param1, edge1, edge2, Crv1, MaxTolVert,
989 num1, sewd, face, boxes, Standard_False) ) {
994 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
995 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
996 // find needed vertex from edge1 and split edge2 using it
997 Standard_Real param2 = IP.ParamOnSecond();
998 if(FindVertAndSplitEdge(param2, edge2, edge1, Crv2, MaxTolVert,
999 num2, sewd, face, boxes, Standard_False) ) {
1004 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1005 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1007 if( UnionVertexes(sewd, edge1, edge2, num2, boxes, B2) )
1008 nbReplaced ++; //gka 06.09.04
1011 // intersection is segment
1012 if( Inter.NbSegments()==1 ) {
1013 IntRes2d_IntersectionSegment IS = Inter.Segment(1);
1014 if ( IS.HasFirstPoint() && IS.HasLastPoint() ) {
1015 Standard_Boolean IsModified1 = Standard_False;
1016 Standard_Boolean IsModified2 = Standard_False;
1019 Standard_Real newtol=0.0;
1020 IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
1021 Standard_Real p11 = IPF.ParamOnFirst();
1022 Standard_Real p21 = IPF.ParamOnSecond();
1023 IntRes2d_IntersectionPoint IPL = IS.LastPoint();
1024 Standard_Real p12 = IPL.ParamOnFirst();
1025 Standard_Real p22 = IPL.ParamOnSecond();
1026 gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
1027 gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
1028 gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
1029 gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
1030 // next string commented by skl 29.12.2004 for OCC7624
1031 //if( Pnt11.Distance(Pnt21)>myPreci || Pnt12.Distance(Pnt22)>myPreci ) continue;
1032 if( Pnt11.Distance(Pnt21)>MaxTolVert || Pnt12.Distance(Pnt22)>MaxTolVert ) continue;
1033 // analysis for edge1
1034 TopoDS_Vertex V1 = sae.FirstVertex(edge1);
1035 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
1036 TopoDS_Vertex V2 = sae.LastVertex(edge1);
1037 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
1038 //Standard_Real tol1 = BRep_Tool::Tolerance(V1);
1039 //Standard_Real tol2 = BRep_Tool::Tolerance(V2);
1040 //Standard_Real maxtol = Max(tol1,tol2);
1041 Standard_Real dist1 = Pnt11.Distance(PV1);
1042 Standard_Real dist2 = Pnt12.Distance(PV1);
1043 Standard_Real maxdist = Max(dist1,dist2);
1044 Standard_Real pdist;
1045 if(edge1.Orientation()==TopAbs_REVERSED)
1046 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1048 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1049 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1050 //if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
1053 IsModified1 = Standard_True;
1055 dist1 = Pnt11.Distance(PV2);
1056 dist2 = Pnt12.Distance(PV2);
1057 maxdist = Max(dist1,dist2);
1058 if(edge1.Orientation()==TopAbs_REVERSED)
1059 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1061 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1062 //if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
1063 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1064 if( ( IsModified1 && maxdist<newtol ) || !IsModified1 ) {
1067 IsModified1 = Standard_True;
1071 // cut edge1 and update tolerance NewV
1072 Standard_Real dista = Abs(a1-p11)+Abs(a1-p12);
1073 Standard_Real distb = Abs(b1-p11)+Abs(b1-p12);
1074 Standard_Real pend,cut;
1075 if(dista>distb) pend=a1;
1077 if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
1079 Standard_Boolean IsCutLine;
1080 if (CutEdge(edge1, pend, cut, face, IsCutLine))
1082 if(newtol>BRep_Tool::Tolerance(NewV)) {
1083 B.UpdateVertex(NewV,newtol);
1085 else newtol = BRep_Tool::Tolerance(NewV);
1087 // analysis for edge2
1088 TopoDS_Vertex V12 = sae.FirstVertex(edge2);
1089 gp_Pnt PV12 = BRep_Tool::Pnt(V12);
1090 TopoDS_Vertex V22 = sae.LastVertex(edge2);
1091 gp_Pnt PV22 = BRep_Tool::Pnt(V22);
1092 //tol1 = BRep_Tool::Tolerance(V1);
1093 //tol2 = BRep_Tool::Tolerance(V2);
1094 //maxtol = Max(tol1,tol2);
1095 dist1 = Pnt21.Distance(PV12);
1096 dist2 = Pnt22.Distance(PV12);
1097 maxdist = Max(dist1,dist2);
1098 if(edge2.Orientation()==TopAbs_REVERSED)
1099 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1101 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1102 //if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
1103 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1106 IsModified2 = Standard_True;
1108 dist1 = Pnt21.Distance(PV22);
1109 dist2 = Pnt22.Distance(PV22);
1110 maxdist = Max(dist1,dist2);
1111 if(edge2.Orientation()==TopAbs_REVERSED)
1112 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1114 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1115 //if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
1116 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1117 if( ( IsModified2 && maxdist<newtol ) || !IsModified2 ) {
1120 IsModified2 = Standard_True;
1124 // cut edge1 and update tolerance NewV
1125 Standard_Real dista = Abs(a2-p21)+Abs(a2-p22);
1126 Standard_Real distb = Abs(b2-p21)+Abs(b2-p22);
1127 Standard_Real pend,cut;
1128 if(dista>distb) pend=a2;
1130 if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
1132 Standard_Boolean IsCutLine;
1133 if (CutEdge(edge2, pend, cut, face, IsCutLine))
1135 if(newtol>BRep_Tool::Tolerance(NewV)) {
1136 B.UpdateVertex(NewV,newtol);
1138 else newtol = BRep_Tool::Tolerance(NewV);
1141 if( IsModified1 && !IsModified2 ) {
1142 if(SplitEdge2(sewd, face, num2, p21, p22, NewV, newtol, boxes)) {
1148 if( !IsModified1 && IsModified2 ) {
1149 if(SplitEdge2(sewd, face, num1, p11, p12, NewV, newtol, boxes)) {
1155 if( !IsModified1 && !IsModified2 ) {
1156 Standard_Real param1 = (p11+p12)/2;
1157 Standard_Real param2 = (p21+p22)/2;
1158 gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
1159 gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
1160 gp_Pnt P0( (Pnt10.X()+Pnt20.X())/2, (Pnt10.Y()+Pnt20.Y())/2,
1161 (Pnt10.Z()+Pnt20.Z())/2 );
1162 dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(P0));
1163 dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(P0));
1164 Standard_Real tolV = Max(dist1,dist2);
1165 tolV = Max(tolV,Pnt10.Distance(Pnt20))*1.00001;
1166 Standard_Boolean FixSegment = Standard_True;
1167 if(tolV<MaxTolVert) {
1168 // create new vertex and split each intersecting edge on two edges
1169 B.MakeVertex(NewV,Pnt10,tolV);
1170 if(SplitEdge2(sewd, face, num2, p21, p22, NewV, tolV, boxes)) {
1174 if(SplitEdge2(sewd, face, num1, p11, p12, NewV, tolV, boxes)) {
1180 else if(FixSegment) {
1181 //if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
1182 // segment is big and we have to split each intersecting edge
1183 // on 3 edges --> middle edge - edge based on segment
1184 // after we can remove edges maked from segment
1185 gp_Pnt P01( (Pnt11.X()+Pnt21.X())/2, (Pnt11.Y()+Pnt21.Y())/2,
1186 (Pnt11.Z()+Pnt21.Z())/2 );
1187 gp_Pnt P02( (Pnt12.X()+Pnt22.X())/2, (Pnt12.Y()+Pnt22.Y())/2,
1188 (Pnt12.Z()+Pnt22.Z())/2 );
1189 Standard_Real tolV1 = Max(Pnt11.Distance(P01),Pnt21.Distance(P01));
1190 tolV1 = Max(tolV1,Precision::Confusion())*1.00001;
1191 Standard_Real tolV2 = Max(Pnt12.Distance(P02),Pnt22.Distance(P02));
1192 tolV2 = Max(tolV2,Precision::Confusion())*1.00001;
1193 if( tolV1>MaxTolVert || tolV2>MaxTolVert ) continue;
1194 TopoDS_Vertex NewV1,NewV2;
1196 // parameters for splitting: a1..p11..p12..b1 and a2..p21..p22..b2 ???
1197 Standard_Integer nbseg1=3, nbseg2=3, kv1=0, kv2=0;
1198 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1200 if(tolV1>BRep_Tool::Tolerance(V1))
1201 B.UpdateVertex(NewV1,tolV1);
1206 else if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1208 if(tolV1>BRep_Tool::Tolerance(V2))
1209 B.UpdateVertex(NewV1,tolV1);
1215 TopoDS_Edge tmpE,SegE;
1217 Standard_Integer akey1=0, akey2=0;
1218 Standard_Real newTolerance;
1220 newTolerance = Max(tolV1,BRep_Tool::Tolerance(V1));
1221 if(P01.Distance(PV1)<newTolerance) {
1222 B.MakeVertex(NewV1,BRep_Tool::Pnt(V1),newTolerance);
1223 NewV1.Orientation(V1.Orientation());
1226 newTolerance = Max(tolV1,BRep_Tool::Tolerance(V2));
1227 if(P01.Distance(PV2)<newTolerance) {
1228 B.MakeVertex(NewV1,BRep_Tool::Pnt(V2),newTolerance);
1229 NewV1.Orientation(V2.Orientation());
1233 newTolerance = Max(tolV2,BRep_Tool::Tolerance(V1));
1234 if(P02.Distance(PV1)<newTolerance) {
1235 B.MakeVertex(NewV2,BRep_Tool::Pnt(V1),newTolerance);
1236 NewV2.Orientation(V1.Orientation());
1239 newTolerance = Max(tolV2,BRep_Tool::Tolerance(V2));
1240 if(P02.Distance(PV2)<newTolerance) {
1241 B.MakeVertex(NewV2,BRep_Tool::Pnt(V2),newTolerance);
1242 NewV2.Orientation(V2.Orientation());
1245 if( akey1>1 || akey2>1 ) continue;
1246 Standard_Integer dnum1=0, numseg1=num1;
1248 if(akey1==0) B.MakeVertex(NewV1,P01,tolV1);
1249 if(akey2==0) B.MakeVertex(NewV2,P02,tolV2);
1251 if( akey1==0 && akey2>0 ) {
1252 if(SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes)) {
1258 if( akey1>0 && akey2==0 ) {
1259 if(SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes) ) {
1265 if( akey1==0 && akey2==0 ) {
1266 if(SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes)) {
1270 tmpE = sewd->Edge(num1);
1272 Handle(Geom2d_Curve) c2d;
1273 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1274 if( (a-p12)*(b-p12)>0 ) { // p12 - external for [a,b] => split next edge
1275 if(SplitEdge1(sewd, face, num1+1, p12, NewV2, tolV2, boxes) ) {
1282 if(SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes) ) {
1289 //SegE = sewd->Edge(numseg1); // get edge from segment
1291 // replace vertices if it is necessary
1292 ShapeBuild_Edge sbe;
1295 if(P01.Distance(PV12)<tolV1) {
1296 tolV1 += P01.Distance(PV12);
1297 B.UpdateVertex(NewV1,tolV1);
1298 if(V12.Orientation()==NewV1.Orientation()) {
1299 myContext->Replace(V12,NewV1);
1303 myContext->Replace(V12,NewV1.Reversed());
1304 V12 = TopoDS::Vertex(NewV1.Reversed());
1306 nbReplaced++; //gka 06.09.04
1307 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
1308 myContext->Replace(edge2,NewE);
1309 sewd->Set(NewE,num2+dnum1);
1310 boxes.Bind(NewE,B2); // update boxes
1314 if(P01.Distance(PV22)<tolV1) {
1315 tolV1 += P01.Distance(PV22);
1316 B.UpdateVertex(NewV1,tolV1);
1317 if(V22.Orientation()==NewV1.Orientation()) {
1318 myContext->Replace(V22,NewV1);
1322 myContext->Replace(V22,NewV1.Reversed());
1323 V22 = TopoDS::Vertex(NewV1.Reversed());
1325 nbReplaced++; //gka 06.09.04
1326 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
1327 myContext->Replace(edge2,NewE);
1328 sewd->Set(NewE,num2+dnum1);
1329 boxes.Bind(NewE,B2); // update boxes
1333 if(P02.Distance(PV12)<tolV2) {
1334 tolV2 += P02.Distance(PV12);
1335 B.UpdateVertex(NewV2,tolV2);
1336 if(V12.Orientation()==NewV2.Orientation()) {
1337 myContext->Replace(V12,NewV2);
1341 myContext->Replace(V12,NewV2.Reversed());
1342 V12 = TopoDS::Vertex(NewV2.Reversed());
1344 nbReplaced++; //gka 06.09.04
1345 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
1346 myContext->Replace(edge2,NewE);
1347 sewd->Set(NewE,num2+dnum1);
1348 boxes.Bind(NewE,B2); // update boxes
1352 if(P02.Distance(PV22)<tolV2) {
1353 tolV2 += P02.Distance(PV22);
1354 B.UpdateVertex(NewV2,tolV2);
1355 if(V22.Orientation()==NewV2.Orientation()) {
1356 myContext->Replace(V22,NewV2);
1360 myContext->Replace(V22,NewV2.Reversed());
1361 V22 = TopoDS::Vertex(NewV2.Reversed());
1363 nbReplaced++; //gka 06.09.04
1364 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
1365 myContext->Replace(edge2,NewE);
1366 sewd->Set(NewE,num2+dnum1);
1367 boxes.Bind(NewE,B2); // update boxes
1371 Standard_Integer dnum2=0, numseg2=num2+dnum1;
1373 if( akey1==0 && akey2>0 ) {
1374 if(SplitEdge1(sewd, face, num2+dnum1, p21, NewV1, tolV1, boxes)) {
1377 //numseg2=num2+dnum1+1;
1381 if( akey1>0 && akey2==0 ) {
1382 if(SplitEdge1(sewd, face, num2+dnum1, p22, NewV2, tolV2, boxes)) {
1385 //numseg2=num2+dnum1;
1386 numseg2=num2+dnum1+1;
1389 if( akey1==0 && akey2==0 ) {
1390 if(SplitEdge1(sewd, face, num2+dnum1, p21, NewV1, tolV1, boxes)) {
1394 tmpE = sewd->Edge(num2+dnum1);
1396 Handle(Geom2d_Curve) c2d;
1397 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1398 if( (a-p22)*(b-p22)>0 ) { // p22 - external for [a,b] => split next edge
1399 if(SplitEdge1(sewd, face, num2+dnum1+dnum2, p22, NewV2, tolV2, boxes) ) {
1401 numseg2=num2+dnum1+dnum2;
1406 if(SplitEdge1(sewd, face, num2+dnum1, p22, NewV2, tolV2, boxes) ) {
1409 numseg2=num2+dnum1+1;
1414 sewd->Remove(numseg2);
1415 sewd->Remove(numseg1);
1416 NbRemoved = NbRemoved+2;
1426 isDone = (NbSplit || NbCut || nbReplaced || NbRemoved);
1431 //=======================================================================
1432 //function : FixIntersectingWires
1434 //=======================================================================
1436 Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
1437 (TopoDS_Face& face) const
1439 if(myContext.IsNull() || face.IsNull()) return Standard_False;
1440 //TopoDS_Shape S = context->Apply(face);
1441 //TopoDS_Shape SF = TopoDS::Face(S);
1442 TopoDS_Shape SF = face;
1443 TopAbs_Orientation ori = face.Orientation();
1444 TopTools_SequenceOfShape SeqWir;
1445 TopTools_SequenceOfShape SeqNMShapes;
1446 for( TopoDS_Iterator iter(SF,Standard_False); iter.More(); iter.Next() ) {
1447 if(iter.Value().ShapeType() != TopAbs_WIRE ||
1448 (iter.Value().Orientation() != TopAbs_FORWARD &&
1449 iter.Value().Orientation() != TopAbs_REVERSED)) {
1450 SeqNMShapes.Append(iter.Value());
1453 TopoDS_Wire wire = TopoDS::Wire(iter.Value());
1454 SeqWir.Append(wire);
1456 if(SeqWir.Length()<2) return Standard_False;//gka 06.09.04
1458 Standard_Real MaxTolVert=0.0;
1459 for(TopExp_Explorer exp(SF,TopAbs_VERTEX); exp.More(); exp.Next()) {
1460 Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
1461 MaxTolVert = Max(MaxTolVert,tolV);
1463 Standard_Boolean isDone = Standard_False; //gka 06.09.04
1464 ShapeAnalysis_Edge sae;
1465 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface (BRep_Tool::Surface (face));
1467 // precompute edge boxes for all wires
1468 NCollection_Sequence<ShapeFix_DataMapOfShapeBox2d> aSeqWirEdgeBoxes;
1469 NCollection_Sequence<Bnd_Box2d> aSeqWirBoxes;
1470 for (Standard_Integer n = 1; n <= SeqWir.Length(); n++)
1472 const TopoDS_Wire& aWire = TopoDS::Wire (SeqWir.Value (n));
1473 Handle(ShapeExtend_WireData) aSewd = new ShapeExtend_WireData (aWire);
1474 ShapeFix_DataMapOfShapeBox2d aBoxes;
1475 Bnd_Box2d aTotalBox = CreateBoxes2d (aSewd, face, aBoxes);
1476 aSeqWirEdgeBoxes.Append (aBoxes);
1477 aSeqWirBoxes.Append (aTotalBox);
1480 for(Standard_Integer n1=1; n1<=SeqWir.Length()-1; n1++) {
1481 TopoDS_Wire wire1 = TopoDS::Wire(SeqWir.Value(n1));
1482 Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData(wire1);
1483 ShapeFix_DataMapOfShapeBox2d& boxes1 = aSeqWirEdgeBoxes.ChangeValue (n1);
1484 Bnd_Box2d aBox1 = aSeqWirBoxes (n1);
1485 for(Standard_Integer n2=n1+1; n2<=SeqWir.Length(); n2++) {
1486 TopoDS_Wire wire2 = TopoDS::Wire(SeqWir.Value(n2));
1487 Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData(wire2);
1488 ShapeFix_DataMapOfShapeBox2d& boxes2 = aSeqWirEdgeBoxes.ChangeValue (n2);
1489 Bnd_Box2d aBox2 = aSeqWirBoxes (n2);
1490 if (!aBox1.IsVoid() && !aBox2.IsVoid() && aBox1.IsOut (aBox2))
1494 // detect possible intersections:
1495 Standard_Integer NbModif=0;
1496 Standard_Integer nbReplaced =0;//gka 06.09.04
1497 Standard_Boolean hasModifWire = Standard_False; //gka 06.09.04
1498 for(Standard_Integer num1 = 1; num1<=sewd1->NbEdges() && NbModif<30; num1++) {
1499 // for each edge from first wire
1500 TopoDS_Edge edge1 = sewd1->Edge(num1); //gka 06.09.04
1502 for(Standard_Integer num2 = 1; num2<=sewd2->NbEdges() && NbModif<30; num2++) {
1503 // for each edge from second wire
1504 TopoDS_Edge edge2 = sewd2->Edge(num2);
1505 if(edge1.IsSame(edge2)) continue;
1506 if( BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2) ) continue;
1507 if( !boxes1.IsBound(edge1) || !boxes2.IsBound(edge2) ) continue;
1508 Bnd_Box2d B1 = boxes1.Find(edge1);
1509 Bnd_Box2d B2 = boxes2.Find(edge2);
1511 // intersection is possible...
1512 Standard_Real a1, b1, a2, b2;
1513 Handle(Geom2d_Curve) Crv1, Crv2;
1514 if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) )
1515 continue; //return Standard_False; gka 06.09.04
1516 if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) )
1517 continue; //return Standard_False;gka 06.09.04
1518 Standard_Real tolint = 1.0e-10;
1519 IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
1520 IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
1521 Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
1522 Geom2dInt_GInter Inter;
1523 Inter.Perform( C1, d1, C2, d2, tolint, tolint );
1524 if(!Inter.IsDone()) continue;
1525 // intersection is point
1526 if( Inter.NbPoints()>0 && Inter.NbPoints()<3 ) {
1527 IntRes2d_IntersectionPoint IP;
1528 IntRes2d_Transition Tr1, Tr2;
1529 SelectIntPnt(Inter,IP,Tr1,Tr2);
1530 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1531 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1532 // create new vertex and split both edges
1533 Standard_Real param1 = IP.ParamOnFirst();
1534 Standard_Real param2 = IP.ParamOnSecond();
1535 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
1536 gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
1537 gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
1540 Standard_Real tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
1541 B.MakeVertex(V,P0,tolV);
1542 MaxTolVert = Max(MaxTolVert,tolV);
1543 Standard_Boolean isSplitEdge2 = SplitEdge1(sewd2, face, num2, param2,
1549 if(SplitEdge1(sewd1, face, num1, param1, V, tolV, boxes1)) {
1557 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1558 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1559 // find needed vertex from edge2 and split edge1 using it
1560 Standard_Real param1 = IP.ParamOnFirst();
1561 if(FindVertAndSplitEdge(param1, edge1, edge2, Crv1, MaxTolVert,
1562 num1, sewd1, face, boxes1, Standard_True) ) {
1567 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1568 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1569 // find needed vertex from edge1 and split edge2 using it
1570 Standard_Real param2 = IP.ParamOnSecond();
1571 if(FindVertAndSplitEdge(param2, edge2, edge1, Crv2, MaxTolVert,
1572 num2, sewd2, face, boxes2, Standard_True) ) {
1577 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1578 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1580 if( UnionVertexes(sewd2, edge1, edge2, num2, boxes2, B2) )
1581 nbReplaced ++; //gka 06.09.04
1584 hasModifWire = (hasModifWire || NbModif || nbReplaced);
1585 // intersection is segment
1586 if( Inter.NbSegments()==1 ) {
1587 IntRes2d_IntersectionSegment IS = Inter.Segment(1);
1588 if ( IS.HasFirstPoint() && IS.HasLastPoint() ) {
1589 Standard_Boolean IsModified1 = Standard_False;
1590 Standard_Boolean IsModified2 = Standard_False;
1593 Standard_Real newtol=0.0;
1594 IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
1595 Standard_Real p11 = IPF.ParamOnFirst();
1596 Standard_Real p21 = IPF.ParamOnSecond();
1597 IntRes2d_IntersectionPoint IPL = IS.LastPoint();
1598 Standard_Real p12 = IPL.ParamOnFirst();
1599 Standard_Real p22 = IPL.ParamOnSecond();
1600 gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
1601 gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
1602 gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
1603 gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
1605 // analysis for edge1
1606 TopoDS_Vertex V1 = sae.FirstVertex(edge1);
1607 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
1608 TopoDS_Vertex V2 = sae.LastVertex(edge1);
1609 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
1610 Standard_Real dist1 = Pnt11.Distance(PV1);
1611 Standard_Real dist2 = Pnt12.Distance(PV1);
1612 Standard_Real maxdist = Max(dist1,dist2);
1613 Standard_Real pdist;
1614 if(edge1.Orientation()==TopAbs_REVERSED)
1615 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1617 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1618 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1621 IsModified1 = Standard_True;
1623 dist1 = Pnt11.Distance(PV2);
1624 dist2 = Pnt12.Distance(PV2);
1625 maxdist = Max(dist1,dist2);
1626 if(edge1.Orientation()==TopAbs_REVERSED)
1627 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1629 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1630 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1631 if( ( IsModified1 && maxdist<newtol ) || !IsModified1 ) {
1634 IsModified1 = Standard_True;
1638 // cut edge1 and update tolerance NewV
1639 Standard_Real dista = Abs(a1-p11)+Abs(a1-p12);
1640 Standard_Real distb = Abs(b1-p11)+Abs(b1-p12);
1641 Standard_Real pend,cut;
1642 if(dista>distb) pend=a1;
1644 if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
1646 Standard_Boolean IsCutLine;
1647 CutEdge(edge1, pend, cut, face, IsCutLine);
1648 if(newtol>BRep_Tool::Tolerance(NewV)) {
1649 B.UpdateVertex(NewV,newtol*1.00001);
1653 // analysis for edge2
1654 TopoDS_Vertex V12 = sae.FirstVertex(edge2);
1655 gp_Pnt PV12 = BRep_Tool::Pnt(V12);
1656 TopoDS_Vertex V22 = sae.LastVertex(edge2);
1657 gp_Pnt PV22 = BRep_Tool::Pnt(V22);
1658 dist1 = Pnt21.Distance(PV12);
1659 dist2 = Pnt22.Distance(PV12);
1660 maxdist = Max(dist1,dist2);
1661 if(edge2.Orientation()==TopAbs_REVERSED)
1662 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1664 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1665 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1668 IsModified2 = Standard_True;
1670 dist1 = Pnt21.Distance(PV22);
1671 dist2 = Pnt22.Distance(PV22);
1672 maxdist = Max(dist1,dist2);
1673 if(edge2.Orientation()==TopAbs_REVERSED)
1674 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1676 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1677 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1678 if( ( IsModified2 && maxdist<newtol ) || !IsModified2 ) {
1681 IsModified2 = Standard_True;
1685 // cut edge1 and update tolerance NewV
1686 Standard_Real dista = Abs(a2-p21)+Abs(a2-p22);
1687 Standard_Real distb = Abs(b2-p21)+Abs(b2-p22);
1688 Standard_Real pend,cut;
1689 if(dista>distb) pend=a2;
1691 if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
1693 Standard_Boolean IsCutLine;
1694 CutEdge(edge2, pend, cut, face, IsCutLine);
1695 if(newtol>BRep_Tool::Tolerance(NewV)) {
1696 B.UpdateVertex(NewV,newtol*1.00001);
1700 if( IsModified1 || IsModified2 ) {
1702 hasModifWire = Standard_True; //gka 06.09.04
1706 // create new vertex and split edge1 and edge2 using it
1707 if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
1708 // segment is big and we have to split each intersecting edge
1709 // on 3 edges --> middle edge - edge based on segment
1710 gp_Pnt P01( (Pnt11.X()+Pnt21.X())/2, (Pnt11.Y()+Pnt21.Y())/2,
1711 (Pnt11.Z()+Pnt21.Z())/2 );
1712 gp_Pnt P02( (Pnt12.X()+Pnt22.X())/2, (Pnt12.Y()+Pnt22.Y())/2,
1713 (Pnt12.Z()+Pnt22.Z())/2 );
1714 Standard_Real tolV1 = Max(Pnt11.Distance(P01),Pnt21.Distance(P01));
1715 tolV1 = Max(tolV1,Precision::Confusion())*1.00001;
1716 Standard_Real tolV2 = Max(Pnt12.Distance(P02),Pnt22.Distance(P02));
1717 tolV2 = Max(tolV2,Precision::Confusion())*1.00001;
1718 if( tolV1>MaxTolVert || tolV2>MaxTolVert ) continue;
1720 hasModifWire = Standard_True; //gka 06.09.04
1721 TopoDS_Vertex NewV1,NewV2;
1722 TopoDS_Edge tmpE,SegE;
1724 Standard_Integer akey1=0, akey2=0;
1726 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1728 if(tolV1>BRep_Tool::Tolerance(V1))
1729 B.UpdateVertex(NewV1,tolV1);
1732 if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1734 if(tolV1>BRep_Tool::Tolerance(V2))
1735 B.UpdateVertex(NewV1,tolV1);
1739 if(P02.Distance(PV1)<Max(tolV2,BRep_Tool::Tolerance(V1))) {
1741 if(tolV2>BRep_Tool::Tolerance(V1))
1742 B.UpdateVertex(NewV2,tolV2);
1745 if(P02.Distance(PV2)<Max(tolV2,BRep_Tool::Tolerance(V2))) {
1747 if(tolV2>BRep_Tool::Tolerance(V2))
1748 B.UpdateVertex(NewV2,tolV2);
1751 if( akey1>1 || akey2>1 ) continue;
1753 if(akey1==0) B.MakeVertex(NewV1,P01,tolV1);
1754 if(akey2==0) B.MakeVertex(NewV2,P02,tolV2);
1756 Standard_Integer numseg1=num1;
1757 if( akey1==0 && akey2>0 ) {
1758 if(SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1)) {
1763 if( akey1>0 && akey2==0 ) {
1764 if(SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1) ) {
1769 if( akey1==0 && akey2==0 ) {
1770 if(SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1)) {
1773 tmpE = sewd1->Edge(num1);
1775 Handle(Geom2d_Curve) c2d;
1776 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1777 if( (a-p12)*(b-p12)>0 ) { // p12 - external for [a,b] => split next edge
1778 if(SplitEdge1(sewd1, face, num1+1, p12, NewV2, tolV2, boxes1) ) {
1784 if(SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1) ) {
1790 SegE = sewd1->Edge(numseg1); // get edge from segment
1792 // replace vertices if it is necessary
1793 ShapeBuild_Edge sbe;
1795 if(P01.Distance(PV12)<tolV1) {
1796 tolV1 += P01.Distance(PV12);
1797 B.UpdateVertex(NewV1,tolV1);
1799 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
1800 myContext->Replace(edge2,NewE);
1801 sewd2->Set(NewE,num2);
1802 boxes2.Bind(NewE,B2); // update boxes2
1806 if(P01.Distance(PV22)<tolV1) {
1807 tolV1 += P01.Distance(PV22);
1808 B.UpdateVertex(NewV1,tolV1);
1810 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
1811 myContext->Replace(edge2,NewE);
1812 sewd2->Set(NewE,num2);
1813 boxes2.Bind(NewE,B2); // update boxes2
1817 if(P02.Distance(PV12)<tolV2) {
1818 tolV2 += P02.Distance(PV12);
1819 B.UpdateVertex(NewV2,tolV2);
1821 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
1822 myContext->Replace(edge2,NewE);
1823 sewd2->Set(NewE,num2);
1824 boxes2.Bind(NewE,B2); // update boxes2
1828 if(P02.Distance(PV22)<tolV2) {
1829 tolV2 += P02.Distance(PV22);
1830 B.UpdateVertex(NewV2,tolV2);
1832 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
1833 myContext->Replace(edge2,NewE);
1834 sewd2->Set(NewE,num2);
1835 boxes2.Bind(NewE,B2); // update boxes2
1840 Standard_Integer numseg2=num2;
1841 if( akey1==0 && akey2>0 ) {
1842 if(SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2)) {
1847 if( akey1>0 && akey2==0 ) {
1848 if(SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2)) {
1853 if( akey1==0 && akey2==0 ) {
1854 if(SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2)) {
1858 tmpE = sewd2->Edge(num2);
1860 Handle(Geom2d_Curve) c2d;
1861 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1862 if( (a-p22)*(b-p22)>0 ) { // p22 - external for [a,b] => split next edge
1863 if(SplitEdge1(sewd2, face, num2+1, p22, NewV2, tolV2, boxes2) ) {
1869 if(SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2) ) {
1875 tmpE = sewd2->Edge(numseg2);
1876 boxes2.Bind(tmpE,boxes1.Find(SegE)); // update boxes2
1877 if(!sae.FirstVertex(SegE).IsSame(sae.FirstVertex(tmpE))) {
1880 myContext->Replace(tmpE,SegE);
1881 sewd2->Set(SegE,numseg2);
1886 // split each intersecting edge on two edges
1887 gp_Pnt P0( (Pnt11.X()+Pnt12.X())/2, (Pnt11.Y()+Pnt12.Y())/2,
1888 (Pnt11.Z()+Pnt12.Z())/2 );
1889 Standard_Real param1 = (p11+p12)/2;
1890 Standard_Real param2 = (p21+p22)/2;
1891 gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
1892 gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
1893 dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(Pnt10));
1894 dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(Pnt10));
1895 Standard_Real tolV = Max(dist1,dist2);
1896 tolV = Max(tolV,Pnt10.Distance(Pnt20))*1.00001;
1897 B.MakeVertex(NewV,Pnt10,tolV);
1898 MaxTolVert = Max(MaxTolVert,tolV);
1899 hasModifWire = Standard_True;
1900 if(SplitEdge2(sewd2, face, num2, p21, p22, NewV, tolV, boxes2)) {
1904 if(SplitEdge2(sewd1, face, num1, p11, p12, NewV, tolV, boxes1)) {
1912 } // end if(Inter.NbSegments()==1)
1918 isDone = Standard_True;
1919 SeqWir.SetValue(n1,sewd1->Wire());
1920 myContext->Replace( wire1, sewd1->Wire() );
1921 wire1 = sewd1->Wire();
1922 //recompute boxes for wire1
1924 Bnd_Box2d aNewBox1 = CreateBoxes2d (sewd1, face, boxes1);
1925 aSeqWirBoxes.SetValue (n1, aNewBox1);
1926 SeqWir.SetValue(n2,sewd2->Wire());
1927 myContext->Replace( wire2, sewd2->Wire() );
1928 wire2 = sewd2->Wire();
1929 //recompute boxes for wire2
1931 Bnd_Box2d aNewBox2 = CreateBoxes2d (sewd2, face, boxes2);
1932 aSeqWirBoxes.SetValue (n2, aNewBox2);
1940 TopoDS_Shape emptyCopied = face.EmptyCopied();
1941 TopoDS_Face newface = TopoDS::Face (emptyCopied);
1942 newface.Orientation(TopAbs_FORWARD);
1944 Standard_Integer i=1;
1945 for(i=1 ; i<=SeqWir.Length(); i++) {
1946 TopoDS_Wire wire = TopoDS::Wire(SeqWir.Value(i));
1947 B.Add(newface,wire);
1949 for(i=1 ; i<=SeqNMShapes.Length(); i++) {
1950 TopoDS_Shape aNMS = SeqNMShapes.Value(i);
1951 B.Add(newface,aNMS);
1953 newface.Orientation(ori);
1954 myContext->Replace(face,newface);