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)) {
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;
218 return Standard_True;
221 // det-study on 03/12/01 checking the old and new ranges
222 if( Abs(Abs(a-b)-aRange) < Precision::PConfusion() ) return Standard_False;
223 if( aRange<10.*Precision::PConfusion() ) return Standard_False;
226 B.Range( edge, Min(pend,cut), Max(pend,cut) );
228 return Standard_True;
232 //=======================================================================
233 //function : SplitEdge1
234 //purpose : split edge[a,b] om two part e1[a,param]
235 // and e2[param,b] using vertex vert
236 //=======================================================================
238 Standard_Boolean ShapeFix_IntersectionTool::SplitEdge1(const Handle(ShapeExtend_WireData)& sewd,
239 const TopoDS_Face& face,
240 const Standard_Integer num,
241 const Standard_Real param,
242 const TopoDS_Vertex& vert,
243 const Standard_Real preci,
244 ShapeFix_DataMapOfShapeBox2d& boxes) const
246 TopoDS_Edge edge = sewd->Edge(num);
247 TopoDS_Edge newE1, newE2;
248 if(!SplitEdge(edge,param,vert,face,newE1,newE2,preci)) return Standard_False;
251 Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
254 if(!myContext.IsNull()) myContext->Replace( edge, wd->Wire() );
255 for (TopExp_Explorer exp ( wd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
256 TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
257 BRepTools::Update(E);
261 sewd->Set(newE1,num);
262 if(num==sewd->NbEdges())
265 sewd->Add(newE2,num+1);
270 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
271 Handle(Geom2d_Curve) c2d;
273 ShapeAnalysis_Edge sae;
274 if(sae.PCurve(newE1,S,L,c2d,cf,cl,Standard_False)) {
276 Geom2dAdaptor_Curve gac;
277 Standard_Real aFirst = c2d->FirstParameter();
278 Standard_Real aLast = c2d->LastParameter();
279 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
280 && (cf < aFirst || cl > aLast)) {
281 //pdn avoiding problems with segment in Bnd_Box
286 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
287 boxes.Bind(newE1,box);
289 if(sae.PCurve(newE2,S,L,c2d,cf,cl,Standard_False)) {
291 Geom2dAdaptor_Curve gac;
292 Standard_Real aFirst = c2d->FirstParameter();
293 Standard_Real aLast = c2d->LastParameter();
294 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
295 && (cf < aFirst || cl > aLast)) {
296 //pdn avoiding problems with segment in Bnd_Box
301 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
302 boxes.Bind(newE2,box);
305 return Standard_True;
309 //=======================================================================
310 //function : SplitEdge2
311 //purpose : auxilary: split edge[a,b] om two part e1[a,param1]
312 // and e2[param2,b] using vertex vert
313 // (remove segment (param1,param2) from edge)
314 //=======================================================================
316 Standard_Boolean ShapeFix_IntersectionTool::SplitEdge2(const Handle(ShapeExtend_WireData)& sewd,
317 const TopoDS_Face& face,
318 const Standard_Integer num,
319 const Standard_Real param1,
320 const Standard_Real param2,
321 const TopoDS_Vertex& vert,
322 const Standard_Real preci,
323 ShapeFix_DataMapOfShapeBox2d& boxes) const
325 TopoDS_Edge edge = sewd->Edge(num);
326 TopoDS_Edge newE1, newE2;
327 Standard_Real param = (param1+param2)/2;
328 if(!SplitEdge(edge,param,vert,face,newE1,newE2,preci)) return Standard_False;
329 // cut new edges by param1 and param2
330 Standard_Boolean IsCutLine;
331 Handle(Geom2d_Curve) Crv1, Crv2;
332 Standard_Real fp1,lp1,fp2,lp2;
333 ShapeAnalysis_Edge sae;
334 if(sae.PCurve ( newE1, face, Crv1, fp1, lp1, Standard_False )) {
335 if(sae.PCurve ( newE2, face, Crv2, fp2, lp2, Standard_False )) {
337 if( (lp1-fp1)*(lp1-param1)>0 ) {
338 CutEdge(newE1, fp1, param1, face, IsCutLine);
339 CutEdge(newE2, lp2, param2, face, IsCutLine);
342 CutEdge(newE1, fp1, param2, face, IsCutLine);
343 CutEdge(newE2, lp2, param1, face, IsCutLine);
347 if( (fp1-lp1)*(fp1-param1)>0 ) {
348 CutEdge(newE1, lp1, param1, face, IsCutLine);
349 CutEdge(newE2, fp2, param2, face, IsCutLine);
352 CutEdge(newE1, lp1, param2, face, IsCutLine);
353 CutEdge(newE2, fp2, param1, face, IsCutLine);
360 Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
363 if(!myContext.IsNull()) myContext->Replace( edge, wd->Wire() );
364 for (TopExp_Explorer exp ( wd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
365 TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
366 BRepTools::Update(E);
370 sewd->Set(newE1,num);
371 if(num==sewd->NbEdges())
374 sewd->Add(newE2,num+1);
379 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
380 Handle(Geom2d_Curve) c2d;
382 if(sae.PCurve(newE1,S,L,c2d,cf,cl,Standard_False)) {
384 Geom2dAdaptor_Curve gac;
385 Standard_Real aFirst = c2d->FirstParameter();
386 Standard_Real aLast = c2d->LastParameter();
387 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
388 && (cf < aFirst || cl > aLast)) {
389 //pdn avoiding problems with segment in Bnd_Box
394 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
395 boxes.Bind(newE1,box);
397 if(sae.PCurve(newE2,S,L,c2d,cf,cl,Standard_False)) {
399 Geom2dAdaptor_Curve gac;
400 Standard_Real aFirst = c2d->FirstParameter();
401 Standard_Real aLast = c2d->LastParameter();
402 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
403 && (cf < aFirst || cl > aLast)) {
404 //pdn avoiding problems with segment in Bnd_Box
409 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
410 boxes.Bind(newE2,box);
413 return Standard_True;
417 //=======================================================================
418 //function : UnionVertexes
420 //=======================================================================
422 Standard_Boolean ShapeFix_IntersectionTool::UnionVertexes(const Handle(ShapeExtend_WireData)& sewd,
425 const Standard_Integer num2,
426 ShapeFix_DataMapOfShapeBox2d& boxes,
427 const Bnd_Box2d& B2) const
431 ShapeAnalysis_Edge sae;
434 TopoDS_Vertex V1F = sae.FirstVertex(edge1);
435 gp_Pnt PV1F = BRep_Tool::Pnt(V1F);
436 TopoDS_Vertex V1L = sae.LastVertex(edge1);
437 gp_Pnt PV1L = BRep_Tool::Pnt(V1L);
438 TopoDS_Vertex V2F = sae.FirstVertex(edge2);
439 gp_Pnt PV2F = BRep_Tool::Pnt(V2F);
440 TopoDS_Vertex V2L = sae.LastVertex(edge2);
441 gp_Pnt PV2L = BRep_Tool::Pnt(V2L);
442 Standard_Real d11 = PV1F.Distance(PV2F);
443 Standard_Real d12 = PV1F.Distance(PV2L);
444 Standard_Real d21 = PV1L.Distance(PV2F);
445 Standard_Real d22 = PV1L.Distance(PV2L);
446 if(d11<d12 && d11<d21 && d11<d22) {
447 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F),BRep_Tool::Tolerance(V2F));
448 if( !V2F.IsSame(V1F) && d11<tolv ) {
449 // union vertexes V1F and V2F
450 B.UpdateVertex(V1F,tolv);
451 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V1F,V2L);
452 // cout<<"union vertexes V1F and V2F"<<endl;
453 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
454 // B.MakeVertex(V,Ptmp,tolv);
455 // myContext->Replace(V1F,V);
456 // myContext->Replace(V2F,V);
457 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
458 myContext->Replace(edge2,NewE);
459 sewd->Set(NewE,num2);
461 boxes.Bind(NewE,B2); // update boxes
462 // replace vertex in other edge
463 Standard_Integer num21,num22;
464 if(num2>1) num21=num2-1;
465 else num21=sewd->NbEdges();
466 if(num2<sewd->NbEdges()) num22=num2+1;
468 TopoDS_Edge edge21 = sewd->Edge(num21);
469 TopoDS_Edge edge22 = sewd->Edge(num22);
470 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
471 TopoDS_Vertex V21L = sae.LastVertex(edge21);
472 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
473 TopoDS_Vertex V22L = sae.LastVertex(edge22);
474 if(V21F.IsSame(V2F)) {
475 NewE = sbe.CopyReplaceVertices(edge21,V1F,V21L);
476 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
477 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
478 myContext->Replace(edge21,NewE);
479 sewd->Set(NewE,num21);
481 if(V21L.IsSame(V2F)) {
482 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1F);
483 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
484 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
485 myContext->Replace(edge21,NewE);
486 sewd->Set(NewE,num21);
488 if(V22F.IsSame(V2F)) {
489 NewE = sbe.CopyReplaceVertices(edge22,V1F,V22L);
490 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
491 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
492 myContext->Replace(edge22,NewE);
493 sewd->Set(NewE,num22);
495 if(V22L.IsSame(V2F)) {
496 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1F);
497 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
498 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
499 myContext->Replace(edge22,NewE);
500 sewd->Set(NewE,num22);
504 else if(d12<d21 && d12<d22) {
505 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F),BRep_Tool::Tolerance(V2L));
506 if( !V2L.IsSame(V1F) && d12<tolv ) {
507 // union vertexes V1F and V2L
508 B.UpdateVertex(V1F,tolv);
509 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V1F);
510 // cout<<"union vertexes V1F and V2L"<<endl;
511 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
512 // B.MakeVertex(V,Ptmp,tolv);
513 // myContext->Replace(V1F,V);
514 // myContext->Replace(V2L,V);
515 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
516 myContext->Replace(edge2,NewE);
517 sewd->Set(NewE,num2);
519 //boxes.Bind(NewE,boxes.Find(edge2)); // update boxes
520 boxes.Bind(NewE,B2); // update boxes
521 // replace vertex in other edge
522 Standard_Integer num21,num22;
523 if(num2>1) num21=num2-1;
524 else num21=sewd->NbEdges();
525 if(num2<sewd->NbEdges()) num22=num2+1;
527 TopoDS_Edge edge21 = sewd->Edge(num21);
528 TopoDS_Edge edge22 = sewd->Edge(num22);
529 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
530 TopoDS_Vertex V21L = sae.LastVertex(edge21);
531 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
532 TopoDS_Vertex V22L = sae.LastVertex(edge22);
533 if(V21F.IsSame(V2L)) {
534 NewE = sbe.CopyReplaceVertices(edge21,V1F,V21L);
535 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
536 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
537 myContext->Replace(edge21,NewE);
538 sewd->Set(NewE,num21);
540 if(V21L.IsSame(V2L)) {
541 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1F);
542 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
543 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
544 myContext->Replace(edge21,NewE);
545 sewd->Set(NewE,num21);
547 if(V22F.IsSame(V2L)) {
548 NewE = sbe.CopyReplaceVertices(edge22,V1F,V22L);
549 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
550 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
551 myContext->Replace(edge22,NewE);
552 sewd->Set(NewE,num22);
554 if(V22L.IsSame(V2L)) {
555 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1F);
556 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
557 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
558 myContext->Replace(edge22,NewE);
559 sewd->Set(NewE,num22);
564 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L),BRep_Tool::Tolerance(V2F));
565 if( !V2F.IsSame(V1L) && d21<tolv ) {
566 // union vertexes V1L and V2F
567 B.UpdateVertex(V1L,tolv);
568 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V1L,V2L);
569 // cout<<"union vertexes V1L and V2F"<<endl;
570 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
571 // B.MakeVertex(V,Ptmp,tolv);
572 // myContext->Replace(V1L,V);
573 // myContext->Replace(V2F,V);
574 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
575 myContext->Replace(edge2,NewE);
576 sewd->Set(NewE,num2);
578 boxes.Bind(NewE,B2); // update boxes
579 // replace vertex in other edge
580 Standard_Integer num21,num22;
581 if(num2>1) num21=num2-1;
582 else num21=sewd->NbEdges();
583 if(num2<sewd->NbEdges()) num22=num2+1;
585 TopoDS_Edge edge21 = sewd->Edge(num21);
586 TopoDS_Edge edge22 = sewd->Edge(num22);
587 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
588 TopoDS_Vertex V21L = sae.LastVertex(edge21);
589 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
590 TopoDS_Vertex V22L = sae.LastVertex(edge22);
591 if(V21F.IsSame(V2F)) {
592 NewE = sbe.CopyReplaceVertices(edge21,V1L,V21L);
593 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
594 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
595 myContext->Replace(edge21,NewE);
596 sewd->Set(NewE,num21);
598 if(V21L.IsSame(V2F)) {
599 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1L);
600 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
601 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
602 myContext->Replace(edge21,NewE);
603 sewd->Set(NewE,num21);
605 if(V22F.IsSame(V2F)) {
606 NewE = sbe.CopyReplaceVertices(edge22,V1L,V22L);
607 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
608 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
609 myContext->Replace(edge22,NewE);
610 sewd->Set(NewE,num22);
612 if(V22L.IsSame(V2F)) {
613 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1L);
614 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
615 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
616 myContext->Replace(edge22,NewE);
617 sewd->Set(NewE,num22);
622 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L),BRep_Tool::Tolerance(V2L));
623 if( !V2L.IsSame(V1L) && d22<tolv ) {
624 // union vertexes V1L and V2L
625 B.UpdateVertex(V1L,tolv);
626 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V1L);
627 // cout<<"union vertexes V1L and V2L"<<endl;
628 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
629 // B.MakeVertex(V,Ptmp,tolv);
630 // myContext->Replace(V1L,V);
631 // myContext->Replace(V2L,V);
632 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
633 myContext->Replace(edge2,NewE);
634 sewd->Set(NewE,num2);
636 boxes.Bind(NewE,B2); // update boxes
637 // replace vertex in other edge
638 Standard_Integer num21,num22;
639 if(num2>1) num21=num2-1;
640 else num21=sewd->NbEdges();
641 if(num2<sewd->NbEdges()) num22=num2+1;
643 TopoDS_Edge edge21 = sewd->Edge(num21);
644 TopoDS_Edge edge22 = sewd->Edge(num22);
645 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
646 TopoDS_Vertex V21L = sae.LastVertex(edge21);
647 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
648 TopoDS_Vertex V22L = sae.LastVertex(edge22);
649 if(V21F.IsSame(V2L)) {
650 NewE = sbe.CopyReplaceVertices(edge21,V1L,V21L);
651 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
652 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
653 myContext->Replace(edge21,NewE);
654 sewd->Set(NewE,num21);
656 if(V21L.IsSame(V2L)) {
657 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1L);
658 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
659 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
660 myContext->Replace(edge21,NewE);
661 sewd->Set(NewE,num21);
663 if(V22F.IsSame(V2L)) {
664 NewE = sbe.CopyReplaceVertices(edge22,V1L,V22L);
665 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
666 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
667 myContext->Replace(edge22,NewE);
668 sewd->Set(NewE,num22);
670 if(V22L.IsSame(V2L)) {
671 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1L);
672 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
673 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
674 myContext->Replace(edge22,NewE);
675 sewd->Set(NewE,num22);
680 return Standard_True;
684 //=======================================================================
685 //function : CreateBoxes2d
687 //=======================================================================
688 static Bnd_Box2d CreateBoxes2d(const Handle(ShapeExtend_WireData)& sewd,
689 const TopoDS_Face& face,
690 ShapeFix_DataMapOfShapeBox2d& boxes)
692 // create box2d for edges from wire
695 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
696 Handle(Geom2d_Curve) c2d;
698 ShapeAnalysis_Edge sae;
699 for(Standard_Integer i=1; i<=sewd->NbEdges(); i++){
700 TopoDS_Edge E = sewd->Edge(i);
701 if(sae.PCurve(E,S,L,c2d,cf,cl,Standard_False)) {
703 Geom2dAdaptor_Curve gac;
704 Standard_Real aFirst = c2d->FirstParameter();
705 Standard_Real aLast = c2d->LastParameter();
706 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
707 && (cf < aFirst || cl > aLast)) {
708 //pdn avoiding problems with segment in Bnd_Box
713 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
722 //=======================================================================
723 //function : SelectIntPnt
725 //=======================================================================
726 static void SelectIntPnt(const Geom2dInt_GInter& Inter,
727 IntRes2d_IntersectionPoint& IP,
728 IntRes2d_Transition& Tr1,
729 IntRes2d_Transition& Tr2)
732 Tr1 = IP.TransitionOfFirst();
733 Tr2 = IP.TransitionOfSecond();
734 if(Inter.NbPoints()==2) {
735 // possible second point is better?
736 Standard_Integer status1=0,status2=0;
737 if(Tr1.PositionOnCurve()==IntRes2d_Middle) status1+=1;
738 if(Tr2.PositionOnCurve()==IntRes2d_Middle) status1+=2;
739 IntRes2d_IntersectionPoint IP2;
740 IntRes2d_Transition Tr12, Tr22;
741 IP2 = Inter.Point(2);
742 Tr12 = IP2.TransitionOfFirst();
743 Tr22 = IP2.TransitionOfSecond();
744 if(Tr12.PositionOnCurve()==IntRes2d_Middle) status2+=1;
745 if(Tr22.PositionOnCurve()==IntRes2d_Middle) status2+=2;
746 if(status2>status1) {
747 IP=IP2; Tr1=Tr12; Tr2=Tr22;
753 //=======================================================================
754 //function : FindVertAndSplitEdge
756 //=======================================================================
757 Standard_Boolean ShapeFix_IntersectionTool::FindVertAndSplitEdge
758 (const Standard_Real param1,
759 const TopoDS_Edge& edge1, const TopoDS_Edge& edge2,
760 const Handle(Geom2d_Curve)& Crv1,
761 Standard_Real& MaxTolVert,
762 Standard_Integer& num1,
763 const Handle(ShapeExtend_WireData)& sewd,
764 const TopoDS_Face& face,
765 ShapeFix_DataMapOfShapeBox2d& boxes,
766 const Standard_Boolean aTmpKey) const
768 // find needed vertex from edge2 and split edge1 using it
769 ShapeAnalysis_Edge sae;
770 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
771 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
775 TopoDS_Vertex V1 = sae.FirstVertex(edge2);
776 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
777 TopoDS_Vertex V2 = sae.LastVertex(edge2);
778 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
779 TopoDS_Vertex V11 = sae.FirstVertex(edge1);
780 TopoDS_Vertex V12 = sae.LastVertex(edge1);
781 Standard_Boolean NeedSplit = Standard_True;
782 if(pi1.Distance(PV1)<pi1.Distance(PV2)) {
783 if( V1.IsSame(V11) || V1.IsSame(V12) ) {
784 NeedSplit = Standard_False;
787 tolV = Max( (pi1.Distance(PV1)/2)*1.00001, BRep_Tool::Tolerance(V1) );
790 if( V2.IsSame(V11) || V2.IsSame(V12) ) {
791 NeedSplit = Standard_False;
794 tolV = Max( (pi1.Distance(PV2)/2)*1.00001, BRep_Tool::Tolerance(V2) );
796 if( NeedSplit || aTmpKey ) {
797 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
798 B.UpdateVertex(V,tolV);
799 MaxTolVert = Max(MaxTolVert,tolV);
802 return Standard_True;
806 return Standard_False;
810 //=======================================================================
811 //function : FixSelfIntersectWire
813 //=======================================================================
815 Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
816 (Handle(ShapeExtend_WireData)& sewd, const TopoDS_Face& face,
817 Standard_Integer& NbSplit, Standard_Integer& NbCut,
818 Standard_Integer& NbRemoved) const
820 if(myContext.IsNull() || face.IsNull()) return Standard_False;
822 //Standard_Real area2d = ShapeAnalysis::TotCross2D(sewd,face);
823 //if(area2d<Precision::PConfusion()*Precision::PConfusion()) return Standard_False; //gka 06.09.04 BUG 6555
825 TopoDS_Shape SF = face;
826 Standard_Real MaxTolVert=0.0;
827 for(TopExp_Explorer exp(SF,TopAbs_VERTEX); exp.More(); exp.Next()) {
828 Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
829 MaxTolVert = Max(MaxTolVert,tolV);
831 MaxTolVert = Min(MaxTolVert,myMaxTol);
832 ShapeAnalysis_Edge sae;
834 // step 1 : intersection of adjacent edges
836 // step 2 : intersection of non-adjacent edges
837 ShapeFix_DataMapOfShapeBox2d boxes;
838 (void)CreateBoxes2d(sewd,face,boxes);
839 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
843 Standard_Integer nbReplaced =0;
844 Standard_Boolean isDone = Standard_False;
845 for(Standard_Integer num1=1; num1<sewd->NbEdges() && NbSplit<30; num1++) {
846 // for each edge from first wire
847 for(Standard_Integer num2=num1+2; num2<=sewd->NbEdges() && NbSplit<30; num2++) {
848 // for each edge from second wire
849 if( num1==1 && num2==sewd->NbEdges() ) continue;
850 TopoDS_Edge edge1 = sewd->Edge(num1);
851 TopoDS_Edge edge2 = sewd->Edge(num2);
852 if(edge1.IsSame(edge2)) continue;
853 if( BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2) ) continue;
854 if( !boxes.IsBound(edge1) || !boxes.IsBound(edge2) ) continue;
855 Bnd_Box2d B1 = boxes.Find(edge1);
856 Bnd_Box2d B2 = boxes.Find(edge2);
858 // intersection is possible...
859 Standard_Real a1, b1, a2, b2;
860 Handle(Geom2d_Curve) Crv1, Crv2;
861 if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) ) return Standard_False;
862 if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) ) return Standard_False;
863 Standard_Real tolint = 1.0e-10;
864 IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
865 IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
866 Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
867 Geom2dInt_GInter Inter;
868 Inter.Perform( C1, d1, C2, d2, tolint, tolint );
869 if(!Inter.IsDone()) continue;
870 // intersection is point
871 if( Inter.NbPoints()>0 && Inter.NbPoints()<3 ) {
872 IntRes2d_IntersectionPoint IP;
873 IntRes2d_Transition Tr1, Tr2;
874 SelectIntPnt(Inter,IP,Tr1,Tr2);
875 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
876 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
877 Standard_Real param1 = IP.ParamOnFirst();
878 Standard_Real param2 = IP.ParamOnSecond();
879 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
880 gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
883 Standard_Real tolV=0;
884 // analysis for edge1
885 Standard_Boolean ModifE1 = Standard_False;
886 TopoDS_Vertex VF1 = sae.FirstVertex(edge1);
887 gp_Pnt PVF1 = BRep_Tool::Pnt(VF1);
888 TopoDS_Vertex VL1 = sae.LastVertex(edge1);
889 gp_Pnt PVL1 = BRep_Tool::Pnt(VL1);
890 Standard_Real dist1 = pi1.Distance(PVF1);
891 Standard_Real dist2 = pi1.Distance(PVL1);
892 if( dist1<dist2 && dist1<MaxTolVert ) {
893 tolV = Max( dist1*1.00001, BRep_Tool::Tolerance(VF1) );
894 B.UpdateVertex(VF1,tolV);
896 //gp_Pnt Ptmp = BRep_Tool::Pnt(VF1);
897 //B.MakeVertex(V,Ptmp,tolV);
898 //myContext->Replace(VF1,V);
899 Standard_Real dista = Abs(a1-param1);
900 Standard_Real distb = Abs(b1-param1);
901 Standard_Boolean IsCutLine;
903 CutEdge(edge1, a1, param1, face, IsCutLine);
905 CutEdge(edge1, b1, param1, face, IsCutLine);
907 ModifE1 = Standard_True;
909 if( dist2<dist1 && dist2<MaxTolVert ) {
910 tolV = Max( dist2*1.00001, BRep_Tool::Tolerance(VL1) );
911 B.UpdateVertex(VL1,tolV);
913 Standard_Real dista = Abs(a1-param1);
914 Standard_Real distb = Abs(b1-param1);
915 Standard_Boolean IsCutLine;
917 CutEdge(edge1, a1, param1, face, IsCutLine);
919 CutEdge(edge1, b1, param1, face, IsCutLine);
921 ModifE1 = Standard_True;
923 // analysis for edge2
924 Standard_Boolean ModifE2 = Standard_False;
925 TopoDS_Vertex VF2 = sae.FirstVertex(edge2);
926 gp_Pnt PVF2 = BRep_Tool::Pnt(VF2);
927 TopoDS_Vertex VL2 = sae.LastVertex(edge2);
928 gp_Pnt PVL2 = BRep_Tool::Pnt(VL2);
929 dist1 = pi2.Distance(PVF2);
930 dist2 = pi2.Distance(PVL2);
931 if( dist1<dist2 && dist1<MaxTolVert ) {
932 tolV = Max( dist1*1.00001, BRep_Tool::Tolerance(VF2) );
933 B.UpdateVertex(VF2,tolV);
935 Standard_Real dista = Abs(a2-param2);
936 Standard_Real distb = Abs(b2-param2);
937 Standard_Boolean IsCutLine;
939 CutEdge(edge2, a2, param2, face, IsCutLine);
941 CutEdge(edge2, b2, param2, face, IsCutLine);
943 ModifE2 = Standard_True;
945 if( dist2<dist1 && dist2<MaxTolVert ) {
946 tolV = Max( dist2*1.00001, BRep_Tool::Tolerance(VL2) );
947 B.UpdateVertex(VL2,tolV);
949 Standard_Real dista = Abs(a2-param2);
950 Standard_Real distb = Abs(b2-param2);
951 Standard_Boolean IsCutLine;
953 CutEdge(edge2, a2, param2, face, IsCutLine);
955 CutEdge(edge2, b2, param2, face, IsCutLine);
957 ModifE2 = Standard_True;
959 if( ModifE1 && !ModifE2 ) {
960 if(SplitEdge1(sewd, face, num2, param2, V, tolV, boxes)) {
967 if( !ModifE1 && ModifE2 ) {
968 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
974 if( !ModifE1 && !ModifE2 ) {
975 gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
976 tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
977 B.MakeVertex(V,P0,tolV);
978 MaxTolVert = Max(MaxTolVert,tolV);
979 Standard_Boolean isEdgeSplit2 = SplitEdge1(sewd, face, num2, param2,
985 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
994 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
995 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
996 // find needed vertex from edge2 and split edge1 using it
997 Standard_Real param1 = IP.ParamOnFirst();
998 if(FindVertAndSplitEdge(param1, edge1, edge2, Crv1, MaxTolVert,
999 num1, sewd, face, boxes, Standard_False) ) {
1004 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1005 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1006 // find needed vertex from edge1 and split edge2 using it
1007 Standard_Real param2 = IP.ParamOnSecond();
1008 if(FindVertAndSplitEdge(param2, edge2, edge1, Crv2, MaxTolVert,
1009 num2, sewd, face, boxes, Standard_False) ) {
1014 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1015 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1017 if( UnionVertexes(sewd, edge1, edge2, num2, boxes, B2) )
1018 nbReplaced ++; //gka 06.09.04
1021 // intersection is segment
1022 if( Inter.NbSegments()==1 ) {
1023 IntRes2d_IntersectionSegment IS = Inter.Segment(1);
1024 if ( IS.HasFirstPoint() && IS.HasLastPoint() ) {
1025 Standard_Boolean IsModified1 = Standard_False;
1026 Standard_Boolean IsModified2 = Standard_False;
1029 Standard_Real newtol=0.0;
1030 IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
1031 Standard_Real p11 = IPF.ParamOnFirst();
1032 Standard_Real p21 = IPF.ParamOnSecond();
1033 IntRes2d_IntersectionPoint IPL = IS.LastPoint();
1034 Standard_Real p12 = IPL.ParamOnFirst();
1035 Standard_Real p22 = IPL.ParamOnSecond();
1036 gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
1037 gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
1038 gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
1039 gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
1040 // next string commented by skl 29.12.2004 for OCC7624
1041 //if( Pnt11.Distance(Pnt21)>myPreci || Pnt12.Distance(Pnt22)>myPreci ) continue;
1042 if( Pnt11.Distance(Pnt21)>MaxTolVert || Pnt12.Distance(Pnt22)>MaxTolVert ) continue;
1043 // analysis for edge1
1044 TopoDS_Vertex V1 = sae.FirstVertex(edge1);
1045 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
1046 TopoDS_Vertex V2 = sae.LastVertex(edge1);
1047 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
1048 //Standard_Real tol1 = BRep_Tool::Tolerance(V1);
1049 //Standard_Real tol2 = BRep_Tool::Tolerance(V2);
1050 //Standard_Real maxtol = Max(tol1,tol2);
1051 Standard_Real dist1 = Pnt11.Distance(PV1);
1052 Standard_Real dist2 = Pnt12.Distance(PV1);
1053 Standard_Real maxdist = Max(dist1,dist2);
1054 Standard_Real pdist;
1055 if(edge1.Orientation()==TopAbs_REVERSED)
1056 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1058 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1059 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1060 //if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
1063 IsModified1 = Standard_True;
1065 dist1 = Pnt11.Distance(PV2);
1066 dist2 = Pnt12.Distance(PV2);
1067 maxdist = Max(dist1,dist2);
1068 if(edge1.Orientation()==TopAbs_REVERSED)
1069 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1071 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1072 //if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
1073 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1074 if( ( IsModified1 && maxdist<newtol ) || !IsModified1 ) {
1077 IsModified1 = Standard_True;
1081 // cut edge1 and update tolerance NewV
1082 Standard_Real dista = Abs(a1-p11)+Abs(a1-p12);
1083 Standard_Real distb = Abs(b1-p11)+Abs(b1-p12);
1084 Standard_Real pend,cut;
1085 if(dista>distb) pend=a1;
1087 if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
1089 Standard_Boolean IsCutLine;
1090 CutEdge(edge1, pend, cut, face, IsCutLine);
1092 if(newtol>BRep_Tool::Tolerance(NewV)) {
1093 B.UpdateVertex(NewV,newtol);
1095 else newtol = BRep_Tool::Tolerance(NewV);
1097 // analysis for edge2
1098 TopoDS_Vertex V12 = sae.FirstVertex(edge2);
1099 gp_Pnt PV12 = BRep_Tool::Pnt(V12);
1100 TopoDS_Vertex V22 = sae.LastVertex(edge2);
1101 gp_Pnt PV22 = BRep_Tool::Pnt(V22);
1102 //tol1 = BRep_Tool::Tolerance(V1);
1103 //tol2 = BRep_Tool::Tolerance(V2);
1104 //maxtol = Max(tol1,tol2);
1105 dist1 = Pnt21.Distance(PV12);
1106 dist2 = Pnt22.Distance(PV12);
1107 maxdist = Max(dist1,dist2);
1108 if(edge2.Orientation()==TopAbs_REVERSED)
1109 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1111 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1112 //if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
1113 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1116 IsModified2 = Standard_True;
1118 dist1 = Pnt21.Distance(PV22);
1119 dist2 = Pnt22.Distance(PV22);
1120 maxdist = Max(dist1,dist2);
1121 if(edge2.Orientation()==TopAbs_REVERSED)
1122 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1124 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1125 //if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
1126 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1127 if( ( IsModified2 && maxdist<newtol ) || !IsModified2 ) {
1130 IsModified2 = Standard_True;
1134 // cut edge1 and update tolerance NewV
1135 Standard_Real dista = Abs(a2-p21)+Abs(a2-p22);
1136 Standard_Real distb = Abs(b2-p21)+Abs(b2-p22);
1137 Standard_Real pend,cut;
1138 if(dista>distb) pend=a2;
1140 if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
1142 Standard_Boolean IsCutLine;
1143 CutEdge(edge2, pend, cut, face, IsCutLine);
1145 if(newtol>BRep_Tool::Tolerance(NewV)) {
1146 B.UpdateVertex(NewV,newtol);
1148 else newtol = BRep_Tool::Tolerance(NewV);
1151 if( IsModified1 && !IsModified2 ) {
1152 if(SplitEdge2(sewd, face, num2, p21, p22, NewV, newtol, boxes)) {
1158 if( !IsModified1 && IsModified2 ) {
1159 if(SplitEdge2(sewd, face, num1, p11, p12, NewV, newtol, boxes)) {
1165 if( !IsModified1 && !IsModified2 ) {
1166 Standard_Real param1 = (p11+p12)/2;
1167 Standard_Real param2 = (p21+p22)/2;
1168 gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
1169 gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
1170 gp_Pnt P0( (Pnt10.X()+Pnt20.X())/2, (Pnt10.Y()+Pnt20.Y())/2,
1171 (Pnt10.Z()+Pnt20.Z())/2 );
1172 dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(P0));
1173 dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(P0));
1174 Standard_Real tolV = Max(dist1,dist2);
1175 tolV = Max(tolV,Pnt10.Distance(Pnt20))*1.00001;
1176 Standard_Boolean FixSegment = Standard_True;
1177 if(tolV<MaxTolVert) {
1178 // create new vertex and split each intersecting edge on two edges
1179 B.MakeVertex(NewV,Pnt10,tolV);
1180 if(SplitEdge2(sewd, face, num2, p21, p22, NewV, tolV, boxes)) {
1184 if(SplitEdge2(sewd, face, num1, p11, p12, NewV, tolV, boxes)) {
1190 else if(FixSegment) {
1191 //if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
1192 // segment is big and we have to split each intersecting edge
1193 // on 3 edges --> middle edge - edge based on segment
1194 // after we can remove edges maked from segment
1195 gp_Pnt P01( (Pnt11.X()+Pnt21.X())/2, (Pnt11.Y()+Pnt21.Y())/2,
1196 (Pnt11.Z()+Pnt21.Z())/2 );
1197 gp_Pnt P02( (Pnt12.X()+Pnt22.X())/2, (Pnt12.Y()+Pnt22.Y())/2,
1198 (Pnt12.Z()+Pnt22.Z())/2 );
1199 Standard_Real tolV1 = Max(Pnt11.Distance(P01),Pnt21.Distance(P01));
1200 tolV1 = Max(tolV1,Precision::Confusion())*1.00001;
1201 Standard_Real tolV2 = Max(Pnt12.Distance(P02),Pnt22.Distance(P02));
1202 tolV2 = Max(tolV2,Precision::Confusion())*1.00001;
1203 if( tolV1>MaxTolVert || tolV2>MaxTolVert ) continue;
1204 TopoDS_Vertex NewV1,NewV2;
1206 // parameters for splitting: a1..p11..p12..b1 and a2..p21..p22..b2 ???
1207 Standard_Integer nbseg1=3, nbseg2=3, kv1=0, kv2=0;
1208 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1210 if(tolV1>BRep_Tool::Tolerance(V1))
1211 B.UpdateVertex(NewV1,tolV1);
1216 else if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1218 if(tolV1>BRep_Tool::Tolerance(V2))
1219 B.UpdateVertex(NewV1,tolV1);
1225 TopoDS_Edge tmpE,SegE;
1227 Standard_Integer akey1=0, akey2=0;
1228 Standard_Real newTolerance;
1230 newTolerance = Max(tolV1,BRep_Tool::Tolerance(V1));
1231 if(P01.Distance(PV1)<newTolerance) {
1232 B.MakeVertex(NewV1,BRep_Tool::Pnt(V1),newTolerance);
1233 NewV1.Orientation(V1.Orientation());
1236 newTolerance = Max(tolV1,BRep_Tool::Tolerance(V2));
1237 if(P01.Distance(PV2)<newTolerance) {
1238 B.MakeVertex(NewV1,BRep_Tool::Pnt(V2),newTolerance);
1239 NewV1.Orientation(V2.Orientation());
1243 newTolerance = Max(tolV2,BRep_Tool::Tolerance(V1));
1244 if(P02.Distance(PV1)<newTolerance) {
1245 B.MakeVertex(NewV2,BRep_Tool::Pnt(V1),newTolerance);
1246 NewV2.Orientation(V1.Orientation());
1249 newTolerance = Max(tolV2,BRep_Tool::Tolerance(V2));
1250 if(P02.Distance(PV2)<newTolerance) {
1251 B.MakeVertex(NewV2,BRep_Tool::Pnt(V2),newTolerance);
1252 NewV2.Orientation(V2.Orientation());
1255 if( akey1>1 || akey2>1 ) continue;
1256 Standard_Integer dnum1=0, numseg1=num1;
1258 if(akey1==0) B.MakeVertex(NewV1,P01,tolV1);
1259 if(akey2==0) B.MakeVertex(NewV2,P02,tolV2);
1261 if( akey1==0 && akey2>0 ) {
1262 if(SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes)) {
1268 if( akey1>0 && akey2==0 ) {
1269 if(SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes) ) {
1275 if( akey1==0 && akey2==0 ) {
1276 if(SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes)) {
1280 tmpE = sewd->Edge(num1);
1282 Handle(Geom2d_Curve) c2d;
1283 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1284 if( (a-p12)*(b-p12)>0 ) { // p12 - external for [a,b] => split next edge
1285 if(SplitEdge1(sewd, face, num1+1, p12, NewV2, tolV2, boxes) ) {
1292 if(SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes) ) {
1299 //SegE = sewd->Edge(numseg1); // get edge from segment
1301 // replace vertices if it is necessary
1302 ShapeBuild_Edge sbe;
1305 if(P01.Distance(PV12)<tolV1) {
1306 tolV1 += P01.Distance(PV12);
1307 B.UpdateVertex(NewV1,tolV1);
1308 if(V12.Orientation()==NewV1.Orientation()) {
1309 myContext->Replace(V12,NewV1);
1313 myContext->Replace(V12,NewV1.Reversed());
1314 V12 = TopoDS::Vertex(NewV1.Reversed());
1316 nbReplaced++; //gka 06.09.04
1317 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
1318 myContext->Replace(edge2,NewE);
1319 sewd->Set(NewE,num2+dnum1);
1320 boxes.Bind(NewE,B2); // update boxes
1324 if(P01.Distance(PV22)<tolV1) {
1325 tolV1 += P01.Distance(PV22);
1326 B.UpdateVertex(NewV1,tolV1);
1327 if(V22.Orientation()==NewV1.Orientation()) {
1328 myContext->Replace(V22,NewV1);
1332 myContext->Replace(V22,NewV1.Reversed());
1333 V22 = TopoDS::Vertex(NewV1.Reversed());
1335 nbReplaced++; //gka 06.09.04
1336 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
1337 myContext->Replace(edge2,NewE);
1338 sewd->Set(NewE,num2+dnum1);
1339 boxes.Bind(NewE,B2); // update boxes
1343 if(P02.Distance(PV12)<tolV2) {
1344 tolV2 += P02.Distance(PV12);
1345 B.UpdateVertex(NewV2,tolV2);
1346 if(V12.Orientation()==NewV2.Orientation()) {
1347 myContext->Replace(V12,NewV2);
1351 myContext->Replace(V12,NewV2.Reversed());
1352 V12 = TopoDS::Vertex(NewV2.Reversed());
1354 nbReplaced++; //gka 06.09.04
1355 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
1356 myContext->Replace(edge2,NewE);
1357 sewd->Set(NewE,num2+dnum1);
1358 boxes.Bind(NewE,B2); // update boxes
1362 if(P02.Distance(PV22)<tolV2) {
1363 tolV2 += P02.Distance(PV22);
1364 B.UpdateVertex(NewV2,tolV2);
1365 if(V22.Orientation()==NewV2.Orientation()) {
1366 myContext->Replace(V22,NewV2);
1370 myContext->Replace(V22,NewV2.Reversed());
1371 V22 = TopoDS::Vertex(NewV2.Reversed());
1373 nbReplaced++; //gka 06.09.04
1374 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
1375 myContext->Replace(edge2,NewE);
1376 sewd->Set(NewE,num2+dnum1);
1377 boxes.Bind(NewE,B2); // update boxes
1381 Standard_Integer dnum2=0, numseg2=num2+dnum1;
1383 if( akey1==0 && akey2>0 ) {
1384 if(SplitEdge1(sewd, face, num2+dnum1, p21, NewV1, tolV1, boxes)) {
1387 //numseg2=num2+dnum1+1;
1391 if( akey1>0 && akey2==0 ) {
1392 if(SplitEdge1(sewd, face, num2+dnum1, p22, NewV2, tolV2, boxes)) {
1395 //numseg2=num2+dnum1;
1396 numseg2=num2+dnum1+1;
1399 if( akey1==0 && akey2==0 ) {
1400 if(SplitEdge1(sewd, face, num2+dnum1, p21, NewV1, tolV1, boxes)) {
1404 tmpE = sewd->Edge(num2+dnum1);
1406 Handle(Geom2d_Curve) c2d;
1407 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1408 if( (a-p22)*(b-p22)>0 ) { // p22 - external for [a,b] => split next edge
1409 if(SplitEdge1(sewd, face, num2+dnum1+dnum2, p22, NewV2, tolV2, boxes) ) {
1411 numseg2=num2+dnum1+dnum2;
1416 if(SplitEdge1(sewd, face, num2+dnum1, p22, NewV2, tolV2, boxes) ) {
1419 numseg2=num2+dnum1+1;
1424 sewd->Remove(numseg2);
1425 sewd->Remove(numseg1);
1426 NbRemoved = NbRemoved+2;
1436 isDone = (NbSplit || NbCut || nbReplaced || NbRemoved);
1441 //=======================================================================
1442 //function : FixIntersectingWires
1444 //=======================================================================
1446 Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
1447 (TopoDS_Face& face) const
1449 if(myContext.IsNull() || face.IsNull()) return Standard_False;
1450 //TopoDS_Shape S = context->Apply(face);
1451 //TopoDS_Shape SF = TopoDS::Face(S);
1452 TopoDS_Shape SF = face;
1453 TopAbs_Orientation ori = face.Orientation();
1454 TopTools_SequenceOfShape SeqWir;
1455 TopTools_SequenceOfShape SeqNMShapes;
1456 for( TopoDS_Iterator iter(SF,Standard_False); iter.More(); iter.Next() ) {
1457 if(iter.Value().ShapeType() != TopAbs_WIRE ||
1458 (iter.Value().Orientation() != TopAbs_FORWARD &&
1459 iter.Value().Orientation() != TopAbs_REVERSED)) {
1460 SeqNMShapes.Append(iter.Value());
1463 TopoDS_Wire wire = TopoDS::Wire(iter.Value());
1464 SeqWir.Append(wire);
1466 if(SeqWir.Length()<2) return Standard_False;//gka 06.09.04
1468 Standard_Real MaxTolVert=0.0;
1469 for(TopExp_Explorer exp(SF,TopAbs_VERTEX); exp.More(); exp.Next()) {
1470 Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
1471 MaxTolVert = Max(MaxTolVert,tolV);
1473 Standard_Boolean isDone = Standard_False; //gka 06.09.04
1474 ShapeAnalysis_Edge sae;
1475 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface (BRep_Tool::Surface (face));
1477 // precompute edge boxes for all wires
1478 NCollection_Sequence<ShapeFix_DataMapOfShapeBox2d> aSeqWirEdgeBoxes;
1479 NCollection_Sequence<Bnd_Box2d> aSeqWirBoxes;
1480 for (Standard_Integer n = 1; n <= SeqWir.Length(); n++)
1482 const TopoDS_Wire& aWire = TopoDS::Wire (SeqWir.Value (n));
1483 Handle(ShapeExtend_WireData) aSewd = new ShapeExtend_WireData (aWire);
1484 ShapeFix_DataMapOfShapeBox2d aBoxes;
1485 Bnd_Box2d aTotalBox = CreateBoxes2d (aSewd, face, aBoxes);
1486 aSeqWirEdgeBoxes.Append (aBoxes);
1487 aSeqWirBoxes.Append (aTotalBox);
1490 for(Standard_Integer n1=1; n1<=SeqWir.Length()-1; n1++) {
1491 TopoDS_Wire wire1 = TopoDS::Wire(SeqWir.Value(n1));
1492 Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData(wire1);
1493 ShapeFix_DataMapOfShapeBox2d& boxes1 = aSeqWirEdgeBoxes.ChangeValue (n1);
1494 Bnd_Box2d aBox1 = aSeqWirBoxes (n1);
1495 for(Standard_Integer n2=n1+1; n2<=SeqWir.Length(); n2++) {
1496 TopoDS_Wire wire2 = TopoDS::Wire(SeqWir.Value(n2));
1497 Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData(wire2);
1498 ShapeFix_DataMapOfShapeBox2d& boxes2 = aSeqWirEdgeBoxes.ChangeValue (n2);
1499 Bnd_Box2d aBox2 = aSeqWirBoxes (n2);
1500 if (!aBox1.IsVoid() && !aBox2.IsVoid() && aBox1.IsOut (aBox2))
1504 // detect possible intersections:
1505 Standard_Integer NbModif=0;
1506 Standard_Integer nbReplaced =0;//gka 06.09.04
1507 Standard_Boolean hasModifWire = Standard_False; //gka 06.09.04
1508 for(Standard_Integer num1 = 1; num1<=sewd1->NbEdges() && NbModif<30; num1++) {
1509 // for each edge from first wire
1510 TopoDS_Edge edge1 = sewd1->Edge(num1); //gka 06.09.04
1512 for(Standard_Integer num2 = 1; num2<=sewd2->NbEdges() && NbModif<30; num2++) {
1513 // for each edge from second wire
1514 TopoDS_Edge edge2 = sewd2->Edge(num2);
1515 if(edge1.IsSame(edge2)) continue;
1516 if( BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2) ) continue;
1517 if( !boxes1.IsBound(edge1) || !boxes2.IsBound(edge2) ) continue;
1518 Bnd_Box2d B1 = boxes1.Find(edge1);
1519 Bnd_Box2d B2 = boxes2.Find(edge2);
1521 // intersection is possible...
1522 Standard_Real a1, b1, a2, b2;
1523 Handle(Geom2d_Curve) Crv1, Crv2;
1524 if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) )
1525 continue; //return Standard_False; gka 06.09.04
1526 if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) )
1527 continue; //return Standard_False;gka 06.09.04
1528 Standard_Real tolint = 1.0e-10;
1529 IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
1530 IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
1531 Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
1532 Geom2dInt_GInter Inter;
1533 Inter.Perform( C1, d1, C2, d2, tolint, tolint );
1534 if(!Inter.IsDone()) continue;
1535 // intersection is point
1536 if( Inter.NbPoints()>0 && Inter.NbPoints()<3 ) {
1537 IntRes2d_IntersectionPoint IP;
1538 IntRes2d_Transition Tr1, Tr2;
1539 SelectIntPnt(Inter,IP,Tr1,Tr2);
1540 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1541 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1542 // create new vertex and split both edges
1543 Standard_Real param1 = IP.ParamOnFirst();
1544 Standard_Real param2 = IP.ParamOnSecond();
1545 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
1546 gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
1547 gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
1550 Standard_Real tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
1551 B.MakeVertex(V,P0,tolV);
1552 MaxTolVert = Max(MaxTolVert,tolV);
1553 Standard_Boolean isSplitEdge2 = SplitEdge1(sewd2, face, num2, param2,
1559 if(SplitEdge1(sewd1, face, num1, param1, V, tolV, boxes1)) {
1567 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1568 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1569 // find needed vertex from edge2 and split edge1 using it
1570 Standard_Real param1 = IP.ParamOnFirst();
1571 if(FindVertAndSplitEdge(param1, edge1, edge2, Crv1, MaxTolVert,
1572 num1, sewd1, face, boxes1, Standard_True) ) {
1577 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1578 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1579 // find needed vertex from edge1 and split edge2 using it
1580 Standard_Real param2 = IP.ParamOnSecond();
1581 if(FindVertAndSplitEdge(param2, edge2, edge1, Crv2, MaxTolVert,
1582 num2, sewd2, face, boxes2, Standard_True) ) {
1587 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1588 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1590 if( UnionVertexes(sewd2, edge1, edge2, num2, boxes2, B2) )
1591 nbReplaced ++; //gka 06.09.04
1594 hasModifWire = (hasModifWire || NbModif || nbReplaced);
1595 // intersection is segment
1596 if( Inter.NbSegments()==1 ) {
1597 IntRes2d_IntersectionSegment IS = Inter.Segment(1);
1598 if ( IS.HasFirstPoint() && IS.HasLastPoint() ) {
1599 Standard_Boolean IsModified1 = Standard_False;
1600 Standard_Boolean IsModified2 = Standard_False;
1603 Standard_Real newtol=0.0;
1604 IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
1605 Standard_Real p11 = IPF.ParamOnFirst();
1606 Standard_Real p21 = IPF.ParamOnSecond();
1607 IntRes2d_IntersectionPoint IPL = IS.LastPoint();
1608 Standard_Real p12 = IPL.ParamOnFirst();
1609 Standard_Real p22 = IPL.ParamOnSecond();
1610 gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
1611 gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
1612 gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
1613 gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
1615 // analysis for edge1
1616 TopoDS_Vertex V1 = sae.FirstVertex(edge1);
1617 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
1618 TopoDS_Vertex V2 = sae.LastVertex(edge1);
1619 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
1620 Standard_Real dist1 = Pnt11.Distance(PV1);
1621 Standard_Real dist2 = Pnt12.Distance(PV1);
1622 Standard_Real maxdist = Max(dist1,dist2);
1623 Standard_Real pdist;
1624 if(edge1.Orientation()==TopAbs_REVERSED)
1625 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1627 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1628 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1631 IsModified1 = Standard_True;
1633 dist1 = Pnt11.Distance(PV2);
1634 dist2 = Pnt12.Distance(PV2);
1635 maxdist = Max(dist1,dist2);
1636 if(edge1.Orientation()==TopAbs_REVERSED)
1637 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1639 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1640 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1641 if( ( IsModified1 && maxdist<newtol ) || !IsModified1 ) {
1644 IsModified1 = Standard_True;
1648 // cut edge1 and update tolerance NewV
1649 Standard_Real dista = Abs(a1-p11)+Abs(a1-p12);
1650 Standard_Real distb = Abs(b1-p11)+Abs(b1-p12);
1651 Standard_Real pend,cut;
1652 if(dista>distb) pend=a1;
1654 if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
1656 Standard_Boolean IsCutLine;
1657 CutEdge(edge1, pend, cut, face, IsCutLine);
1658 if(newtol>BRep_Tool::Tolerance(NewV)) {
1659 B.UpdateVertex(NewV,newtol*1.00001);
1663 // analysis for edge2
1664 TopoDS_Vertex V12 = sae.FirstVertex(edge2);
1665 gp_Pnt PV12 = BRep_Tool::Pnt(V12);
1666 TopoDS_Vertex V22 = sae.LastVertex(edge2);
1667 gp_Pnt PV22 = BRep_Tool::Pnt(V22);
1668 dist1 = Pnt21.Distance(PV12);
1669 dist2 = Pnt22.Distance(PV12);
1670 maxdist = Max(dist1,dist2);
1671 if(edge2.Orientation()==TopAbs_REVERSED)
1672 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1674 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1675 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1678 IsModified2 = Standard_True;
1680 dist1 = Pnt21.Distance(PV22);
1681 dist2 = Pnt22.Distance(PV22);
1682 maxdist = Max(dist1,dist2);
1683 if(edge2.Orientation()==TopAbs_REVERSED)
1684 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1686 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1687 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1688 if( ( IsModified2 && maxdist<newtol ) || !IsModified2 ) {
1691 IsModified2 = Standard_True;
1695 // cut edge1 and update tolerance NewV
1696 Standard_Real dista = Abs(a2-p21)+Abs(a2-p22);
1697 Standard_Real distb = Abs(b2-p21)+Abs(b2-p22);
1698 Standard_Real pend,cut;
1699 if(dista>distb) pend=a2;
1701 if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
1703 Standard_Boolean IsCutLine;
1704 CutEdge(edge2, pend, cut, face, IsCutLine);
1705 if(newtol>BRep_Tool::Tolerance(NewV)) {
1706 B.UpdateVertex(NewV,newtol*1.00001);
1710 if( IsModified1 || IsModified2 ) {
1712 hasModifWire = Standard_True; //gka 06.09.04
1716 // create new vertex and split edge1 and edge2 using it
1717 if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
1718 // segment is big and we have to split each intersecting edge
1719 // on 3 edges --> middle edge - edge based on segment
1720 gp_Pnt P01( (Pnt11.X()+Pnt21.X())/2, (Pnt11.Y()+Pnt21.Y())/2,
1721 (Pnt11.Z()+Pnt21.Z())/2 );
1722 gp_Pnt P02( (Pnt12.X()+Pnt22.X())/2, (Pnt12.Y()+Pnt22.Y())/2,
1723 (Pnt12.Z()+Pnt22.Z())/2 );
1724 Standard_Real tolV1 = Max(Pnt11.Distance(P01),Pnt21.Distance(P01));
1725 tolV1 = Max(tolV1,Precision::Confusion())*1.00001;
1726 Standard_Real tolV2 = Max(Pnt12.Distance(P02),Pnt22.Distance(P02));
1727 tolV2 = Max(tolV2,Precision::Confusion())*1.00001;
1728 if( tolV1>MaxTolVert || tolV2>MaxTolVert ) continue;
1730 hasModifWire = Standard_True; //gka 06.09.04
1731 TopoDS_Vertex NewV1,NewV2;
1732 TopoDS_Edge tmpE,SegE;
1734 Standard_Integer akey1=0, akey2=0;
1736 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1738 if(tolV1>BRep_Tool::Tolerance(V1))
1739 B.UpdateVertex(NewV1,tolV1);
1742 if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1744 if(tolV1>BRep_Tool::Tolerance(V2))
1745 B.UpdateVertex(NewV1,tolV1);
1749 if(P02.Distance(PV1)<Max(tolV2,BRep_Tool::Tolerance(V1))) {
1751 if(tolV2>BRep_Tool::Tolerance(V1))
1752 B.UpdateVertex(NewV2,tolV2);
1755 if(P02.Distance(PV2)<Max(tolV2,BRep_Tool::Tolerance(V2))) {
1757 if(tolV2>BRep_Tool::Tolerance(V2))
1758 B.UpdateVertex(NewV2,tolV2);
1761 if( akey1>1 || akey2>1 ) continue;
1763 if(akey1==0) B.MakeVertex(NewV1,P01,tolV1);
1764 if(akey2==0) B.MakeVertex(NewV2,P02,tolV2);
1766 Standard_Integer numseg1=num1;
1767 if( akey1==0 && akey2>0 ) {
1768 if(SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1)) {
1773 if( akey1>0 && akey2==0 ) {
1774 if(SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1) ) {
1779 if( akey1==0 && akey2==0 ) {
1780 if(SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1)) {
1783 tmpE = sewd1->Edge(num1);
1785 Handle(Geom2d_Curve) c2d;
1786 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1787 if( (a-p12)*(b-p12)>0 ) { // p12 - external for [a,b] => split next edge
1788 if(SplitEdge1(sewd1, face, num1+1, p12, NewV2, tolV2, boxes1) ) {
1794 if(SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1) ) {
1800 SegE = sewd1->Edge(numseg1); // get edge from segment
1802 // replace vertices if it is necessary
1803 ShapeBuild_Edge sbe;
1805 if(P01.Distance(PV12)<tolV1) {
1806 tolV1 += P01.Distance(PV12);
1807 B.UpdateVertex(NewV1,tolV1);
1809 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
1810 myContext->Replace(edge2,NewE);
1811 sewd2->Set(NewE,num2);
1812 boxes2.Bind(NewE,B2); // update boxes2
1816 if(P01.Distance(PV22)<tolV1) {
1817 tolV1 += P01.Distance(PV22);
1818 B.UpdateVertex(NewV1,tolV1);
1820 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
1821 myContext->Replace(edge2,NewE);
1822 sewd2->Set(NewE,num2);
1823 boxes2.Bind(NewE,B2); // update boxes2
1827 if(P02.Distance(PV12)<tolV2) {
1828 tolV2 += P02.Distance(PV12);
1829 B.UpdateVertex(NewV2,tolV2);
1831 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
1832 myContext->Replace(edge2,NewE);
1833 sewd2->Set(NewE,num2);
1834 boxes2.Bind(NewE,B2); // update boxes2
1838 if(P02.Distance(PV22)<tolV2) {
1839 tolV2 += P02.Distance(PV22);
1840 B.UpdateVertex(NewV2,tolV2);
1842 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
1843 myContext->Replace(edge2,NewE);
1844 sewd2->Set(NewE,num2);
1845 boxes2.Bind(NewE,B2); // update boxes2
1850 Standard_Integer numseg2=num2;
1851 if( akey1==0 && akey2>0 ) {
1852 if(SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2)) {
1857 if( akey1>0 && akey2==0 ) {
1858 if(SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2)) {
1863 if( akey1==0 && akey2==0 ) {
1864 if(SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2)) {
1868 tmpE = sewd2->Edge(num2);
1870 Handle(Geom2d_Curve) c2d;
1871 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1872 if( (a-p22)*(b-p22)>0 ) { // p22 - external for [a,b] => split next edge
1873 if(SplitEdge1(sewd2, face, num2+1, p22, NewV2, tolV2, boxes2) ) {
1879 if(SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2) ) {
1885 tmpE = sewd2->Edge(numseg2);
1886 boxes2.Bind(tmpE,boxes1.Find(SegE)); // update boxes2
1887 if(!sae.FirstVertex(SegE).IsSame(sae.FirstVertex(tmpE))) {
1890 myContext->Replace(tmpE,SegE);
1891 sewd2->Set(SegE,numseg2);
1896 // split each intersecting edge on two edges
1897 gp_Pnt P0( (Pnt11.X()+Pnt12.X())/2, (Pnt11.Y()+Pnt12.Y())/2,
1898 (Pnt11.Z()+Pnt12.Z())/2 );
1899 Standard_Real param1 = (p11+p12)/2;
1900 Standard_Real param2 = (p21+p22)/2;
1901 gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
1902 gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
1903 dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(Pnt10));
1904 dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(Pnt10));
1905 Standard_Real tolV = Max(dist1,dist2);
1906 tolV = Max(tolV,Pnt10.Distance(Pnt20))*1.00001;
1907 B.MakeVertex(NewV,Pnt10,tolV);
1908 MaxTolVert = Max(MaxTolVert,tolV);
1909 hasModifWire = Standard_True;
1910 if(SplitEdge2(sewd2, face, num2, p21, p22, NewV, tolV, boxes2)) {
1914 if(SplitEdge2(sewd1, face, num1, p11, p12, NewV, tolV, boxes1)) {
1922 } // end if(Inter.NbSegments()==1)
1928 isDone = Standard_True;
1929 SeqWir.SetValue(n1,sewd1->Wire());
1930 myContext->Replace( wire1, sewd1->Wire() );
1931 wire1 = sewd1->Wire();
1932 //recompute boxes for wire1
1934 Bnd_Box2d aNewBox1 = CreateBoxes2d (sewd1, face, boxes1);
1935 aSeqWirBoxes.SetValue (n1, aNewBox1);
1936 SeqWir.SetValue(n2,sewd2->Wire());
1937 myContext->Replace( wire2, sewd2->Wire() );
1938 wire2 = sewd2->Wire();
1939 //recompute boxes for wire2
1941 Bnd_Box2d aNewBox2 = CreateBoxes2d (sewd2, face, boxes2);
1942 aSeqWirBoxes.SetValue (n2, aNewBox2);
1950 TopoDS_Shape emptyCopied = face.EmptyCopied();
1951 TopoDS_Face newface = TopoDS::Face (emptyCopied);
1952 newface.Orientation(TopAbs_FORWARD);
1954 Standard_Integer i=1;
1955 for( ; i<=SeqWir.Length(); i++) {
1956 TopoDS_Wire wire = TopoDS::Wire(SeqWir.Value(i));
1957 B.Add(newface,wire);
1959 for( ; i<=SeqWir.Length(); i++) {
1960 TopoDS_Shape aNMS = SeqNMShapes.Value(i);
1961 B.Add(newface,aNMS);
1963 newface.Orientation(ori);
1964 myContext->Replace(face,newface);