1 #include <ShapeFix_IntersectionTool.ixx>
3 #include <BRep_Builder.hxx>
4 #include <BRep_Tool.hxx>
5 #include <BRepTools.hxx>
6 #include <Bnd_Box2d.hxx>
7 #include <BndLib_Add2dCurve.hxx>
8 #include <Geom_Curve.hxx>
9 #include <Geom_Surface.hxx>
10 #include <Geom2d_BSplineCurve.hxx>
11 #include <Geom2d_Curve.hxx>
12 #include <Geom2d_Line.hxx>
13 #include <Geom2d_TrimmedCurve.hxx>
14 #include <Geom2dAdaptor_Curve.hxx>
15 #include <Geom2dInt_GInter.hxx>
17 #include <IntRes2d_Domain.hxx>
18 #include <IntRes2d_IntersectionPoint.hxx>
19 #include <IntRes2d_IntersectionSegment.hxx>
20 #include <IntRes2d_Position.hxx>
21 #include <ShapeAnalysis.hxx>
22 #include <ShapeAnalysis_Edge.hxx>
23 #include <ShapeAnalysis_Surface.hxx>
24 #include <ShapeAnalysis_TransferParametersProj.hxx>
25 #include <ShapeBuild_Edge.hxx>
26 #include <ShapeFix_DataMapOfShapeBox2d.hxx>
27 #include <TopExp_Explorer.hxx>
29 #include <TopoDS_Iterator.hxx>
30 #include <TopoDS_Wire.hxx>
31 #include <TopTools_SequenceOfShape.hxx>
33 //gka 06.09.04 BUG 6555 shape is modified always independently either intersection was fixed or not
34 //=======================================================================
35 //function : ShapeFix_IntersectionTool
37 //=======================================================================
39 ShapeFix_IntersectionTool::ShapeFix_IntersectionTool(const Handle(ShapeBuild_ReShape)& context,
40 const Standard_Real preci,
41 const Standard_Real maxtol)
49 //=======================================================================
50 //function : GetPointOnEdge
52 //:h0 abv 29 May 98: PRO10105 1949: like in BRepCheck, point is to be taken
53 // from 3d curve (but only if edge is SameParameter)
54 //=======================================================================
55 static gp_Pnt GetPointOnEdge(const TopoDS_Edge &edge,
56 const Handle(ShapeAnalysis_Surface) &surf,
57 const Handle(Geom2d_Curve) &Crv2d,
58 const Standard_Real param )
60 if( BRep_Tool::SameParameter(edge) ) {
63 const Handle(Geom_Curve) ConS = BRep_Tool::Curve ( edge, L, f, l );
65 return ConS->Value(param).Transformed(L.Transformation());
67 return surf->Value(Crv2d->Value(param));
71 //=======================================================================
72 //function : SplitEdge
74 //=======================================================================
76 Standard_Boolean ShapeFix_IntersectionTool::SplitEdge(const TopoDS_Edge& edge,
77 const Standard_Real param,
78 const TopoDS_Vertex& vert,
79 const TopoDS_Face& face,
82 const Standard_Real preci) const
85 ShapeAnalysis_Edge sae;
87 TopoDS_Vertex V1 = sae.FirstVertex(edge);
88 TopoDS_Vertex V2 = sae.LastVertex(edge);
89 if( V1.IsSame(vert) || V2.IsSame(vert) )
90 return Standard_False;
92 Handle(Geom2d_Curve) c2d;
93 sae.PCurve(edge,face,c2d,a,b,Standard_True );
94 if( Abs(a-param)<0.01*preci || Abs(b-param)<0.01*preci )
95 return Standard_False;
96 // check distanse between edge and new vertex
99 if(BRep_Tool::SameParameter(edge)) {
101 const Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,L,f,l);
103 return Standard_False;
104 P1 = c3d->Value(param);
105 if(!L.IsIdentity()) P1 = P1.Transformed(L.Transformation());
108 Handle(Geom_Surface) surf = BRep_Tool::Surface(face,L);
109 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(surf);
110 P1 = sas->Value(c2d->Value(param));
111 if(!L.IsIdentity()) P1 = P1.Transformed(L.Transformation());
113 gp_Pnt P2 = BRep_Tool::Pnt(vert);
114 if(P1.Distance(P2)>preci) {
115 //return Standard_False;
117 B.UpdateVertex(vert,P1.Distance(P2));
120 Handle(ShapeAnalysis_TransferParametersProj) transferParameters =
121 new ShapeAnalysis_TransferParametersProj;
122 transferParameters->SetMaxTolerance(preci);
123 transferParameters->Init(edge,face);
124 Standard_Real first, last;
135 TopAbs_Orientation orient = edge.Orientation();
137 TopoDS_Edge wE = edge;
138 wE.Orientation ( TopAbs_FORWARD );
139 TopoDS_Shape aTmpShape = vert.Oriented(TopAbs_REVERSED); //for porting
140 newE1 = sbe.CopyReplaceVertices ( wE, sae.FirstVertex(wE), TopoDS::Vertex(aTmpShape) );
141 sbe.CopyPCurves ( newE1, wE );
142 transferParameters->TransferRange(newE1,first,param,Standard_True);
143 B.SameRange(newE1,Standard_False);
144 B.SameParameter(newE1,Standard_False);
145 aTmpShape = vert.Oriented(TopAbs_FORWARD);
146 newE2 = sbe.CopyReplaceVertices ( wE, TopoDS::Vertex(aTmpShape),sae.LastVertex(wE) );
147 sbe.CopyPCurves ( newE2, wE );
148 transferParameters->TransferRange(newE2,param,last,Standard_True);
149 B.SameRange(newE2,Standard_False);
150 B.SameParameter(newE2,Standard_False);
152 newE1.Orientation(orient);
153 newE2.Orientation(orient);
154 if (orient==TopAbs_REVERSED) {
155 TopoDS_Edge tmp = newE2; newE2 = newE1; newE1=tmp;
158 return Standard_True;
162 //=======================================================================
165 //=======================================================================
167 Standard_Boolean ShapeFix_IntersectionTool::CutEdge(const TopoDS_Edge &edge,
168 const Standard_Real pend,
169 const Standard_Real cut,
170 const TopoDS_Face &face,
171 Standard_Boolean &iscutline) const
173 if( Abs(cut-pend)<10.*Precision::PConfusion() ) return Standard_False;
174 Standard_Real aRange = Abs(cut-pend);
176 BRep_Tool::Range(edge, a, b);
178 if( aRange<10.*Precision::PConfusion() ) return Standard_False;
180 // case pcurve is trimm of line
181 if( !BRep_Tool::SameParameter(edge) ) {
182 ShapeAnalysis_Edge sae;
183 Handle(Geom2d_Curve) Crv;
185 if ( sae.PCurve(edge,face,Crv,fp,lp,Standard_False) ) {
186 if(Crv->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
187 Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(Crv);
188 if(tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Line))) {
190 B.Range(edge,Min(pend,cut),Max(pend,cut));
191 if( Abs(pend-lp)<Precision::PConfusion() ) { // cut from the begining
192 Standard_Real cut3d = (cut-fp)*(b-a)/(lp-fp);
193 B.Range(edge, a+cut3d, b, Standard_True);
194 iscutline = Standard_True;
196 else if( Abs(pend-fp)<Precision::PConfusion() ) { // cut from the end
197 Standard_Real cut3d = (lp-cut)*(b-a)/(lp-fp);
198 B.Range(edge, a, b-cut3d, Standard_True);
199 iscutline = Standard_True;
204 return Standard_True;
207 // det-study on 03/12/01 checking the old and new ranges
208 if( Abs(Abs(a-b)-aRange) < Precision::PConfusion() ) return Standard_False;
209 if( aRange<10.*Precision::PConfusion() ) return Standard_False;
212 B.Range( edge, Min(pend,cut), Max(pend,cut) );
214 return Standard_True;
218 //=======================================================================
219 //function : SplitEdge1
220 //purpose : split edge[a,b] om two part e1[a,param]
221 // and e2[param,b] using vertex vert
222 //=======================================================================
224 Standard_Boolean ShapeFix_IntersectionTool::SplitEdge1(const Handle(ShapeExtend_WireData)& sewd,
225 const TopoDS_Face& face,
226 const Standard_Integer num,
227 const Standard_Real param,
228 const TopoDS_Vertex& vert,
229 const Standard_Real preci,
230 ShapeFix_DataMapOfShapeBox2d& boxes) const
232 TopoDS_Edge edge = sewd->Edge(num);
233 TopoDS_Edge newE1, newE2;
234 if(!SplitEdge(edge,param,vert,face,newE1,newE2,preci)) return Standard_False;
237 Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
240 if(!myContext.IsNull()) myContext->Replace( edge, wd->Wire() );
241 for (TopExp_Explorer exp ( wd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
242 TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
243 BRepTools::Update(E);
247 sewd->Set(newE1,num);
248 if(num==sewd->NbEdges())
251 sewd->Add(newE2,num+1);
256 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
257 Handle(Geom2d_Curve) c2d;
259 ShapeAnalysis_Edge sae;
260 if(sae.PCurve(newE1,S,L,c2d,cf,cl,Standard_False)) {
262 Geom2dAdaptor_Curve gac;
263 Standard_Real aFirst = c2d->FirstParameter();
264 Standard_Real aLast = c2d->LastParameter();
265 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
266 && (cf < aFirst || cl > aLast)) {
267 //pdn avoiding problems with segment in Bnd_Box
272 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
273 boxes.Bind(newE1,box);
275 if(sae.PCurve(newE2,S,L,c2d,cf,cl,Standard_False)) {
277 Geom2dAdaptor_Curve gac;
278 Standard_Real aFirst = c2d->FirstParameter();
279 Standard_Real aLast = c2d->LastParameter();
280 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
281 && (cf < aFirst || cl > aLast)) {
282 //pdn avoiding problems with segment in Bnd_Box
287 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
288 boxes.Bind(newE2,box);
291 return Standard_True;
295 //=======================================================================
296 //function : SplitEdge2
297 //purpose : auxilary: split edge[a,b] om two part e1[a,param1]
298 // and e2[param2,b] using vertex vert
299 // (remove segment (param1,param2) from edge)
300 //=======================================================================
302 Standard_Boolean ShapeFix_IntersectionTool::SplitEdge2(const Handle(ShapeExtend_WireData)& sewd,
303 const TopoDS_Face& face,
304 const Standard_Integer num,
305 const Standard_Real param1,
306 const Standard_Real param2,
307 const TopoDS_Vertex& vert,
308 const Standard_Real preci,
309 ShapeFix_DataMapOfShapeBox2d& boxes) const
311 TopoDS_Edge edge = sewd->Edge(num);
312 TopoDS_Edge newE1, newE2;
313 Standard_Real param = (param1+param2)/2;
314 if(!SplitEdge(edge,param,vert,face,newE1,newE2,preci)) return Standard_False;
315 // cut new edges by param1 and param2
316 Standard_Boolean IsCutLine;
317 Handle(Geom2d_Curve) Crv1, Crv2;
318 Standard_Real fp1,lp1,fp2,lp2;
319 ShapeAnalysis_Edge sae;
320 if(sae.PCurve ( newE1, face, Crv1, fp1, lp1, Standard_False )) {
321 if(sae.PCurve ( newE2, face, Crv2, fp2, lp2, Standard_False )) {
323 if( (lp1-fp1)*(lp1-param1)>0 ) {
324 CutEdge(newE1, fp1, param1, face, IsCutLine);
325 CutEdge(newE2, lp2, param2, face, IsCutLine);
328 CutEdge(newE1, fp1, param2, face, IsCutLine);
329 CutEdge(newE2, lp2, param1, face, IsCutLine);
333 if( (fp1-lp1)*(fp1-param1)>0 ) {
334 CutEdge(newE1, lp1, param1, face, IsCutLine);
335 CutEdge(newE2, fp2, param2, face, IsCutLine);
338 CutEdge(newE1, lp1, param2, face, IsCutLine);
339 CutEdge(newE2, fp2, param1, face, IsCutLine);
346 Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData;
349 if(!myContext.IsNull()) myContext->Replace( edge, wd->Wire() );
350 for (TopExp_Explorer exp ( wd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
351 TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
352 BRepTools::Update(E);
356 sewd->Set(newE1,num);
357 if(num==sewd->NbEdges())
360 sewd->Add(newE2,num+1);
365 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
366 Handle(Geom2d_Curve) c2d;
368 if(sae.PCurve(newE1,S,L,c2d,cf,cl,Standard_False)) {
370 Geom2dAdaptor_Curve gac;
371 Standard_Real aFirst = c2d->FirstParameter();
372 Standard_Real aLast = c2d->LastParameter();
373 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
374 && (cf < aFirst || cl > aLast)) {
375 //pdn avoiding problems with segment in Bnd_Box
380 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
381 boxes.Bind(newE1,box);
383 if(sae.PCurve(newE2,S,L,c2d,cf,cl,Standard_False)) {
385 Geom2dAdaptor_Curve gac;
386 Standard_Real aFirst = c2d->FirstParameter();
387 Standard_Real aLast = c2d->LastParameter();
388 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
389 && (cf < aFirst || cl > aLast)) {
390 //pdn avoiding problems with segment in Bnd_Box
395 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
396 boxes.Bind(newE2,box);
399 return Standard_True;
403 //=======================================================================
404 //function : UnionVertexes
406 //=======================================================================
408 Standard_Boolean ShapeFix_IntersectionTool::UnionVertexes(const Handle(ShapeExtend_WireData)& sewd,
411 const Standard_Integer num2,
412 ShapeFix_DataMapOfShapeBox2d& boxes,
413 const Bnd_Box2d& B2) const
417 ShapeAnalysis_Edge sae;
420 TopoDS_Vertex V1F = sae.FirstVertex(edge1);
421 gp_Pnt PV1F = BRep_Tool::Pnt(V1F);
422 TopoDS_Vertex V1L = sae.LastVertex(edge1);
423 gp_Pnt PV1L = BRep_Tool::Pnt(V1L);
424 TopoDS_Vertex V2F = sae.FirstVertex(edge2);
425 gp_Pnt PV2F = BRep_Tool::Pnt(V2F);
426 TopoDS_Vertex V2L = sae.LastVertex(edge2);
427 gp_Pnt PV2L = BRep_Tool::Pnt(V2L);
428 Standard_Real d11 = PV1F.Distance(PV2F);
429 Standard_Real d12 = PV1F.Distance(PV2L);
430 Standard_Real d21 = PV1L.Distance(PV2F);
431 Standard_Real d22 = PV1L.Distance(PV2L);
432 if(d11<d12 && d11<d21 && d11<d22) {
433 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F),BRep_Tool::Tolerance(V2F));
434 if( !V2F.IsSame(V1F) && d11<tolv ) {
435 // union vertexes V1F and V2F
436 B.UpdateVertex(V1F,tolv);
437 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V1F,V2L);
438 // cout<<"union vertexes V1F and V2F"<<endl;
439 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
440 // B.MakeVertex(V,Ptmp,tolv);
441 // myContext->Replace(V1F,V);
442 // myContext->Replace(V2F,V);
443 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
444 myContext->Replace(edge2,NewE);
445 sewd->Set(NewE,num2);
447 boxes.Bind(NewE,B2); // update boxes
448 // replace vertex in other edge
449 Standard_Integer num21,num22;
450 if(num2>1) num21=num2-1;
451 else num21=sewd->NbEdges();
452 if(num2<sewd->NbEdges()) num22=num2+1;
454 TopoDS_Edge edge21 = sewd->Edge(num21);
455 TopoDS_Edge edge22 = sewd->Edge(num22);
456 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
457 TopoDS_Vertex V21L = sae.LastVertex(edge21);
458 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
459 TopoDS_Vertex V22L = sae.LastVertex(edge22);
460 if(V21F.IsSame(V2F)) {
461 NewE = sbe.CopyReplaceVertices(edge21,V1F,V21L);
462 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
463 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
464 myContext->Replace(edge21,NewE);
465 sewd->Set(NewE,num21);
467 if(V21L.IsSame(V2F)) {
468 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1F);
469 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
470 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
471 myContext->Replace(edge21,NewE);
472 sewd->Set(NewE,num21);
474 if(V22F.IsSame(V2F)) {
475 NewE = sbe.CopyReplaceVertices(edge22,V1F,V22L);
476 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
477 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
478 myContext->Replace(edge22,NewE);
479 sewd->Set(NewE,num22);
481 if(V22L.IsSame(V2F)) {
482 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1F);
483 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
484 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
485 myContext->Replace(edge22,NewE);
486 sewd->Set(NewE,num22);
490 else if(d12<d21 && d12<d22) {
491 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1F),BRep_Tool::Tolerance(V2L));
492 if( !V2L.IsSame(V1F) && d12<tolv ) {
493 // union vertexes V1F and V2L
494 B.UpdateVertex(V1F,tolv);
495 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V1F);
496 // cout<<"union vertexes V1F and V2L"<<endl;
497 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1F);
498 // B.MakeVertex(V,Ptmp,tolv);
499 // myContext->Replace(V1F,V);
500 // myContext->Replace(V2L,V);
501 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
502 myContext->Replace(edge2,NewE);
503 sewd->Set(NewE,num2);
505 //boxes.Bind(NewE,boxes.Find(edge2)); // update boxes
506 boxes.Bind(NewE,B2); // update boxes
507 // replace vertex in other edge
508 Standard_Integer num21,num22;
509 if(num2>1) num21=num2-1;
510 else num21=sewd->NbEdges();
511 if(num2<sewd->NbEdges()) num22=num2+1;
513 TopoDS_Edge edge21 = sewd->Edge(num21);
514 TopoDS_Edge edge22 = sewd->Edge(num22);
515 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
516 TopoDS_Vertex V21L = sae.LastVertex(edge21);
517 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
518 TopoDS_Vertex V22L = sae.LastVertex(edge22);
519 if(V21F.IsSame(V2L)) {
520 NewE = sbe.CopyReplaceVertices(edge21,V1F,V21L);
521 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
522 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
523 myContext->Replace(edge21,NewE);
524 sewd->Set(NewE,num21);
526 if(V21L.IsSame(V2L)) {
527 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1F);
528 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
529 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
530 myContext->Replace(edge21,NewE);
531 sewd->Set(NewE,num21);
533 if(V22F.IsSame(V2L)) {
534 NewE = sbe.CopyReplaceVertices(edge22,V1F,V22L);
535 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
536 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
537 myContext->Replace(edge22,NewE);
538 sewd->Set(NewE,num22);
540 if(V22L.IsSame(V2L)) {
541 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1F);
542 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
543 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
544 myContext->Replace(edge22,NewE);
545 sewd->Set(NewE,num22);
550 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L),BRep_Tool::Tolerance(V2F));
551 if( !V2F.IsSame(V1L) && d21<tolv ) {
552 // union vertexes V1L and V2F
553 B.UpdateVertex(V1L,tolv);
554 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V1L,V2L);
555 // cout<<"union vertexes V1L and V2F"<<endl;
556 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
557 // B.MakeVertex(V,Ptmp,tolv);
558 // myContext->Replace(V1L,V);
559 // myContext->Replace(V2F,V);
560 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V,V2L);
561 myContext->Replace(edge2,NewE);
562 sewd->Set(NewE,num2);
564 boxes.Bind(NewE,B2); // update boxes
565 // replace vertex in other edge
566 Standard_Integer num21,num22;
567 if(num2>1) num21=num2-1;
568 else num21=sewd->NbEdges();
569 if(num2<sewd->NbEdges()) num22=num2+1;
571 TopoDS_Edge edge21 = sewd->Edge(num21);
572 TopoDS_Edge edge22 = sewd->Edge(num22);
573 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
574 TopoDS_Vertex V21L = sae.LastVertex(edge21);
575 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
576 TopoDS_Vertex V22L = sae.LastVertex(edge22);
577 if(V21F.IsSame(V2F)) {
578 NewE = sbe.CopyReplaceVertices(edge21,V1L,V21L);
579 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
580 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
581 myContext->Replace(edge21,NewE);
582 sewd->Set(NewE,num21);
584 if(V21L.IsSame(V2F)) {
585 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1L);
586 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
587 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
588 myContext->Replace(edge21,NewE);
589 sewd->Set(NewE,num21);
591 if(V22F.IsSame(V2F)) {
592 NewE = sbe.CopyReplaceVertices(edge22,V1L,V22L);
593 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
594 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
595 myContext->Replace(edge22,NewE);
596 sewd->Set(NewE,num22);
598 if(V22L.IsSame(V2F)) {
599 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1L);
600 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
601 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
602 myContext->Replace(edge22,NewE);
603 sewd->Set(NewE,num22);
608 Standard_Real tolv = Max(BRep_Tool::Tolerance(V1L),BRep_Tool::Tolerance(V2L));
609 if( !V2L.IsSame(V1L) && d22<tolv ) {
610 // union vertexes V1L and V2L
611 B.UpdateVertex(V1L,tolv);
612 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V1L);
613 // cout<<"union vertexes V1L and V2L"<<endl;
614 // gp_Pnt Ptmp = BRep_Tool::Pnt(V1L);
615 // B.MakeVertex(V,Ptmp,tolv);
616 // myContext->Replace(V1L,V);
617 // myContext->Replace(V2L,V);
618 // TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V2F,V);
619 myContext->Replace(edge2,NewE);
620 sewd->Set(NewE,num2);
622 boxes.Bind(NewE,B2); // update boxes
623 // replace vertex in other edge
624 Standard_Integer num21,num22;
625 if(num2>1) num21=num2-1;
626 else num21=sewd->NbEdges();
627 if(num2<sewd->NbEdges()) num22=num2+1;
629 TopoDS_Edge edge21 = sewd->Edge(num21);
630 TopoDS_Edge edge22 = sewd->Edge(num22);
631 TopoDS_Vertex V21F = sae.FirstVertex(edge21);
632 TopoDS_Vertex V21L = sae.LastVertex(edge21);
633 TopoDS_Vertex V22F = sae.FirstVertex(edge22);
634 TopoDS_Vertex V22L = sae.LastVertex(edge22);
635 if(V21F.IsSame(V2L)) {
636 NewE = sbe.CopyReplaceVertices(edge21,V1L,V21L);
637 //NewE = sbe.CopyReplaceVertices(edge21,V,V21L);
638 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
639 myContext->Replace(edge21,NewE);
640 sewd->Set(NewE,num21);
642 if(V21L.IsSame(V2L)) {
643 NewE = sbe.CopyReplaceVertices(edge21,V21F,V1L);
644 //NewE = sbe.CopyReplaceVertices(edge21,V21F,V);
645 boxes.Bind(NewE,boxes.Find(edge21)); // update boxes
646 myContext->Replace(edge21,NewE);
647 sewd->Set(NewE,num21);
649 if(V22F.IsSame(V2L)) {
650 NewE = sbe.CopyReplaceVertices(edge22,V1L,V22L);
651 //NewE = sbe.CopyReplaceVertices(edge22,V,V22L);
652 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
653 myContext->Replace(edge22,NewE);
654 sewd->Set(NewE,num22);
656 if(V22L.IsSame(V2L)) {
657 NewE = sbe.CopyReplaceVertices(edge22,V22F,V1L);
658 //NewE = sbe.CopyReplaceVertices(edge22,V22F,V);
659 boxes.Bind(NewE,boxes.Find(edge22)); // update boxes
660 myContext->Replace(edge22,NewE);
661 sewd->Set(NewE,num22);
666 return Standard_True;
670 //=======================================================================
671 //function : CreateBoxes2d
673 //=======================================================================
674 static Standard_Boolean CreateBoxes2d(const Handle(ShapeExtend_WireData)& sewd,
675 const TopoDS_Face& face,
676 ShapeFix_DataMapOfShapeBox2d& boxes)
678 // create box2d for edges from wire
680 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
681 Handle(Geom2d_Curve) c2d;
683 ShapeAnalysis_Edge sae;
684 for(Standard_Integer i=1; i<=sewd->NbEdges(); i++){
685 TopoDS_Edge E = sewd->Edge(i);
686 if(sae.PCurve(E,S,L,c2d,cf,cl,Standard_False)) {
688 Geom2dAdaptor_Curve gac;
689 Standard_Real aFirst = c2d->FirstParameter();
690 Standard_Real aLast = c2d->LastParameter();
691 if(c2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
692 && (cf < aFirst || cl > aLast)) {
693 //pdn avoiding problems with segment in Bnd_Box
698 BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
702 return Standard_True;
706 //=======================================================================
707 //function : SelectIntPnt
709 //=======================================================================
710 static void SelectIntPnt(const Geom2dInt_GInter& Inter,
711 IntRes2d_IntersectionPoint& IP,
712 IntRes2d_Transition& Tr1,
713 IntRes2d_Transition& Tr2)
716 Tr1 = IP.TransitionOfFirst();
717 Tr2 = IP.TransitionOfSecond();
718 if(Inter.NbPoints()==2) {
719 // possible second point is better?
720 Standard_Integer status1=0,status2=0;
721 if(Tr1.PositionOnCurve()==IntRes2d_Middle) status1+=1;
722 if(Tr2.PositionOnCurve()==IntRes2d_Middle) status1+=2;
723 IntRes2d_IntersectionPoint IP2;
724 IntRes2d_Transition Tr12, Tr22;
725 IP2 = Inter.Point(2);
726 Tr12 = IP2.TransitionOfFirst();
727 Tr22 = IP2.TransitionOfSecond();
728 if(Tr12.PositionOnCurve()==IntRes2d_Middle) status2+=1;
729 if(Tr22.PositionOnCurve()==IntRes2d_Middle) status2+=2;
730 if(status2>status1) {
731 IP=IP2; Tr1=Tr12; Tr2=Tr22;
737 //=======================================================================
738 //function : FindVertAndSplitEdge
740 //=======================================================================
741 Standard_Boolean ShapeFix_IntersectionTool::FindVertAndSplitEdge
742 (const Standard_Real param1,
743 const TopoDS_Edge& edge1, const TopoDS_Edge& edge2,
744 const Handle(Geom2d_Curve)& Crv1,
745 Standard_Real& MaxTolVert,
746 Standard_Integer& num1,
747 const Handle(ShapeExtend_WireData)& sewd,
748 const TopoDS_Face& face,
749 ShapeFix_DataMapOfShapeBox2d& boxes,
750 const Standard_Boolean aTmpKey) const
752 // find needed vertex from edge2 and split edge1 using it
753 ShapeAnalysis_Edge sae;
754 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
755 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
759 TopoDS_Vertex V1 = sae.FirstVertex(edge2);
760 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
761 TopoDS_Vertex V2 = sae.LastVertex(edge2);
762 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
763 TopoDS_Vertex V11 = sae.FirstVertex(edge1);
764 TopoDS_Vertex V12 = sae.LastVertex(edge1);
765 Standard_Boolean NeedSplit = Standard_True;
766 if(pi1.Distance(PV1)<pi1.Distance(PV2)) {
767 if( V1.IsSame(V11) || V1.IsSame(V12) ) {
768 NeedSplit = Standard_False;
771 tolV = Max( (pi1.Distance(PV1)/2)*1.00001, BRep_Tool::Tolerance(V1) );
774 if( V2.IsSame(V11) || V2.IsSame(V12) ) {
775 NeedSplit = Standard_False;
778 tolV = Max( (pi1.Distance(PV2)/2)*1.00001, BRep_Tool::Tolerance(V2) );
780 if( NeedSplit || aTmpKey ) {
781 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
782 B.UpdateVertex(V,tolV);
783 MaxTolVert = Max(MaxTolVert,tolV);
786 return Standard_True;
790 return Standard_False;
794 //=======================================================================
795 //function : FixSelfIntersectWire
797 //=======================================================================
799 Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
800 (Handle(ShapeExtend_WireData)& sewd, const TopoDS_Face& face,
801 Standard_Integer& NbSplit, Standard_Integer& NbCut,
802 Standard_Integer& NbRemoved) const
804 if(myContext.IsNull() || face.IsNull()) return Standard_False;
806 //Standard_Real area2d = ShapeAnalysis::TotCross2D(sewd,face);
807 //if(area2d<Precision::PConfusion()*Precision::PConfusion()) return Standard_False; //gka 06.09.04 BUG 6555
809 TopoDS_Shape SF = face;
810 Standard_Real MaxTolVert=0.0;
811 for(TopExp_Explorer exp(SF,TopAbs_VERTEX); exp.More(); exp.Next()) {
812 Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
813 MaxTolVert = Max(MaxTolVert,tolV);
815 MaxTolVert = Min(MaxTolVert,myMaxTol);
816 ShapeAnalysis_Edge sae;
818 // step 1 : intersection of adjacent edges
820 // step 2 : intersection of non-adjacent edges
821 ShapeFix_DataMapOfShapeBox2d boxes;
822 CreateBoxes2d(sewd,face,boxes);
823 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
827 Standard_Integer nbReplaced =0;
828 Standard_Boolean isDone = Standard_False;
829 for(Standard_Integer num1=1; num1<sewd->NbEdges() && NbSplit<30; num1++) {
830 // for each edge from first wire
831 for(Standard_Integer num2=num1+2; num2<=sewd->NbEdges() && NbSplit<30; num2++) {
832 // for each edge from second wire
833 if( num1==1 && num2==sewd->NbEdges() ) continue;
834 TopoDS_Edge edge1 = sewd->Edge(num1);
835 TopoDS_Edge edge2 = sewd->Edge(num2);
836 if(edge1.IsSame(edge2)) continue;
837 if( BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2) ) continue;
838 if( !boxes.IsBound(edge1) || !boxes.IsBound(edge2) ) continue;
839 Bnd_Box2d B1 = boxes.Find(edge1);
840 Bnd_Box2d B2 = boxes.Find(edge2);
842 // intersection is possible...
843 Standard_Real a1, b1, a2, b2;
844 Handle(Geom2d_Curve) Crv1, Crv2;
845 if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) ) return Standard_False;
846 if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) ) return Standard_False;
847 Standard_Real tolint = 1.0e-10;
848 IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
849 IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
850 Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
851 Geom2dInt_GInter Inter;
852 Inter.Perform( C1, d1, C2, d2, tolint, tolint );
853 if(!Inter.IsDone()) continue;
854 // intersection is point
855 if( Inter.NbPoints()>0 && Inter.NbPoints()<3 ) {
856 IntRes2d_IntersectionPoint IP;
857 IntRes2d_Transition Tr1, Tr2;
858 SelectIntPnt(Inter,IP,Tr1,Tr2);
859 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
860 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
861 Standard_Real param1 = IP.ParamOnFirst();
862 Standard_Real param2 = IP.ParamOnSecond();
863 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
864 gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
867 Standard_Real tolV=0;
868 // analysis for edge1
869 Standard_Boolean ModifE1 = Standard_False;
870 TopoDS_Vertex VF1 = sae.FirstVertex(edge1);
871 gp_Pnt PVF1 = BRep_Tool::Pnt(VF1);
872 TopoDS_Vertex VL1 = sae.LastVertex(edge1);
873 gp_Pnt PVL1 = BRep_Tool::Pnt(VL1);
874 Standard_Real dist1 = pi1.Distance(PVF1);
875 Standard_Real dist2 = pi1.Distance(PVL1);
876 if( dist1<dist2 && dist1<MaxTolVert ) {
877 tolV = Max( dist1*1.00001, BRep_Tool::Tolerance(VF1) );
878 B.UpdateVertex(VF1,tolV);
880 //gp_Pnt Ptmp = BRep_Tool::Pnt(VF1);
881 //B.MakeVertex(V,Ptmp,tolV);
882 //myContext->Replace(VF1,V);
883 Standard_Real dista = Abs(a1-param1);
884 Standard_Real distb = Abs(b1-param1);
885 Standard_Boolean IsCutLine;
887 CutEdge(edge1, a1, param1, face, IsCutLine);
889 CutEdge(edge1, b1, param1, face, IsCutLine);
891 ModifE1 = Standard_True;
893 if( dist2<dist1 && dist2<MaxTolVert ) {
894 tolV = Max( dist2*1.00001, BRep_Tool::Tolerance(VL1) );
895 B.UpdateVertex(VL1,tolV);
897 Standard_Real dista = Abs(a1-param1);
898 Standard_Real distb = Abs(b1-param1);
899 Standard_Boolean IsCutLine;
901 CutEdge(edge1, a1, param1, face, IsCutLine);
903 CutEdge(edge1, b1, param1, face, IsCutLine);
905 ModifE1 = Standard_True;
907 // analysis for edge2
908 Standard_Boolean ModifE2 = Standard_False;
909 TopoDS_Vertex VF2 = sae.FirstVertex(edge2);
910 gp_Pnt PVF2 = BRep_Tool::Pnt(VF2);
911 TopoDS_Vertex VL2 = sae.LastVertex(edge2);
912 gp_Pnt PVL2 = BRep_Tool::Pnt(VL2);
913 dist1 = pi2.Distance(PVF2);
914 dist2 = pi2.Distance(PVL2);
915 if( dist1<dist2 && dist1<MaxTolVert ) {
916 tolV = Max( dist1*1.00001, BRep_Tool::Tolerance(VF2) );
917 B.UpdateVertex(VF2,tolV);
919 Standard_Real dista = Abs(a2-param2);
920 Standard_Real distb = Abs(b2-param2);
921 Standard_Boolean IsCutLine;
923 CutEdge(edge2, a2, param2, face, IsCutLine);
925 CutEdge(edge2, b2, param2, face, IsCutLine);
927 ModifE2 = Standard_True;
929 if( dist2<dist1 && dist2<MaxTolVert ) {
930 tolV = Max( dist2*1.00001, BRep_Tool::Tolerance(VL2) );
931 B.UpdateVertex(VL2,tolV);
933 Standard_Real dista = Abs(a2-param2);
934 Standard_Real distb = Abs(b2-param2);
935 Standard_Boolean IsCutLine;
937 CutEdge(edge2, a2, param2, face, IsCutLine);
939 CutEdge(edge2, b2, param2, face, IsCutLine);
941 ModifE2 = Standard_True;
943 if( ModifE1 && !ModifE2 ) {
944 if(SplitEdge1(sewd, face, num2, param2, V, tolV, boxes)) {
951 if( !ModifE1 && ModifE2 ) {
952 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
958 if( !ModifE1 && !ModifE2 ) {
959 gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
960 tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
961 B.MakeVertex(V,P0,tolV);
962 MaxTolVert = Max(MaxTolVert,tolV);
963 Standard_Boolean isEdgeSplit2 = SplitEdge1(sewd, face, num2, param2,
969 if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
978 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
979 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
980 // find needed vertex from edge2 and split edge1 using it
981 Standard_Real param1 = IP.ParamOnFirst();
982 if(FindVertAndSplitEdge(param1, edge1, edge2, Crv1, MaxTolVert,
983 num1, sewd, face, boxes, Standard_False) ) {
988 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
989 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
990 // find needed vertex from edge1 and split edge2 using it
991 Standard_Real param2 = IP.ParamOnSecond();
992 if(FindVertAndSplitEdge(param2, edge2, edge1, Crv2, MaxTolVert,
993 num2, sewd, face, boxes, Standard_False) ) {
998 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
999 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1001 if( UnionVertexes(sewd, edge1, edge2, num2, boxes, B2) )
1002 nbReplaced ++; //gka 06.09.04
1005 // intersection is segment
1006 if( Inter.NbSegments()==1 ) {
1007 IntRes2d_IntersectionSegment IS = Inter.Segment(1);
1008 if ( IS.HasFirstPoint() && IS.HasLastPoint() ) {
1009 Standard_Boolean IsModified1 = Standard_False;
1010 Standard_Boolean IsModified2 = Standard_False;
1013 Standard_Real newtol=0.0;
1014 IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
1015 Standard_Real p11 = IPF.ParamOnFirst();
1016 Standard_Real p21 = IPF.ParamOnSecond();
1017 IntRes2d_IntersectionPoint IPL = IS.LastPoint();
1018 Standard_Real p12 = IPL.ParamOnFirst();
1019 Standard_Real p22 = IPL.ParamOnSecond();
1020 gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
1021 gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
1022 gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
1023 gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
1024 // next string commented by skl 29.12.2004 for OCC7624
1025 //if( Pnt11.Distance(Pnt21)>myPreci || Pnt12.Distance(Pnt22)>myPreci ) continue;
1026 if( Pnt11.Distance(Pnt21)>MaxTolVert || Pnt12.Distance(Pnt22)>MaxTolVert ) continue;
1027 // analysis for edge1
1028 TopoDS_Vertex V1 = sae.FirstVertex(edge1);
1029 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
1030 TopoDS_Vertex V2 = sae.LastVertex(edge1);
1031 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
1032 //Standard_Real tol1 = BRep_Tool::Tolerance(V1);
1033 //Standard_Real tol2 = BRep_Tool::Tolerance(V2);
1034 //Standard_Real maxtol = Max(tol1,tol2);
1035 Standard_Real dist1 = Pnt11.Distance(PV1);
1036 Standard_Real dist2 = Pnt12.Distance(PV1);
1037 Standard_Real maxdist = Max(dist1,dist2);
1038 Standard_Real pdist;
1039 if(edge1.Orientation()==TopAbs_REVERSED)
1040 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1042 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1043 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1044 //if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
1047 IsModified1 = Standard_True;
1049 dist1 = Pnt11.Distance(PV2);
1050 dist2 = Pnt12.Distance(PV2);
1051 maxdist = Max(dist1,dist2);
1052 if(edge1.Orientation()==TopAbs_REVERSED)
1053 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1055 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1056 //if(maxdist<maxtol || pdist<Abs(b1-a1)*0.01) {
1057 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1058 if( ( IsModified1 && maxdist<newtol ) || !IsModified1 ) {
1061 IsModified1 = Standard_True;
1065 // cut edge1 and update tolerance NewV
1066 Standard_Real dista = Abs(a1-p11)+Abs(a1-p12);
1067 Standard_Real distb = Abs(b1-p11)+Abs(b1-p12);
1068 Standard_Real pend,cut;
1069 if(dista>distb) pend=a1;
1071 if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
1073 Standard_Boolean IsCutLine;
1074 CutEdge(edge1, pend, cut, face, IsCutLine);
1076 if(newtol>BRep_Tool::Tolerance(NewV)) {
1077 B.UpdateVertex(NewV,newtol);
1079 else newtol = BRep_Tool::Tolerance(NewV);
1081 // analysis for edge2
1082 TopoDS_Vertex V12 = sae.FirstVertex(edge2);
1083 gp_Pnt PV12 = BRep_Tool::Pnt(V12);
1084 TopoDS_Vertex V22 = sae.LastVertex(edge2);
1085 gp_Pnt PV22 = BRep_Tool::Pnt(V22);
1086 //tol1 = BRep_Tool::Tolerance(V1);
1087 //tol2 = BRep_Tool::Tolerance(V2);
1088 //maxtol = Max(tol1,tol2);
1089 dist1 = Pnt21.Distance(PV12);
1090 dist2 = Pnt22.Distance(PV12);
1091 maxdist = Max(dist1,dist2);
1092 if(edge2.Orientation()==TopAbs_REVERSED)
1093 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1095 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1096 //if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
1097 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1100 IsModified2 = Standard_True;
1102 dist1 = Pnt21.Distance(PV22);
1103 dist2 = Pnt22.Distance(PV22);
1104 maxdist = Max(dist1,dist2);
1105 if(edge2.Orientation()==TopAbs_REVERSED)
1106 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1108 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1109 //if(maxdist<maxtol || pdist<Abs(b2-a2)*0.01) {
1110 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1111 if( ( IsModified2 && maxdist<newtol ) || !IsModified2 ) {
1114 IsModified2 = Standard_True;
1118 // cut edge1 and update tolerance NewV
1119 Standard_Real dista = Abs(a2-p21)+Abs(a2-p22);
1120 Standard_Real distb = Abs(b2-p21)+Abs(b2-p22);
1121 Standard_Real pend,cut;
1122 if(dista>distb) pend=a2;
1124 if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
1126 Standard_Boolean IsCutLine;
1127 CutEdge(edge2, pend, cut, face, IsCutLine);
1129 if(newtol>BRep_Tool::Tolerance(NewV)) {
1130 B.UpdateVertex(NewV,newtol);
1132 else newtol = BRep_Tool::Tolerance(NewV);
1135 if( IsModified1 && !IsModified2 ) {
1136 if(SplitEdge2(sewd, face, num2, p21, p22, NewV, newtol, boxes)) {
1142 if( !IsModified1 && IsModified2 ) {
1143 if(SplitEdge2(sewd, face, num1, p11, p12, NewV, newtol, boxes)) {
1149 if( !IsModified1 && !IsModified2 ) {
1150 Standard_Real param1 = (p11+p12)/2;
1151 Standard_Real param2 = (p21+p22)/2;
1152 gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
1153 gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
1154 gp_Pnt P0( (Pnt10.X()+Pnt20.X())/2, (Pnt10.Y()+Pnt20.Y())/2,
1155 (Pnt10.Z()+Pnt20.Z())/2 );
1156 dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(P0));
1157 dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(P0));
1158 Standard_Real tolV = Max(dist1,dist2);
1159 tolV = Max(tolV,Pnt10.Distance(Pnt20))*1.00001;
1160 Standard_Boolean FixSegment = Standard_True;
1161 if(tolV<MaxTolVert) {
1162 // create new vertex and split each intersecting edge on two edges
1163 B.MakeVertex(NewV,Pnt10,tolV);
1164 if(SplitEdge2(sewd, face, num2, p21, p22, NewV, tolV, boxes)) {
1168 if(SplitEdge2(sewd, face, num1, p11, p12, NewV, tolV, boxes)) {
1174 else if(FixSegment) {
1175 //if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
1176 // segment is big and we have to split each intersecting edge
1177 // on 3 edges --> middle edge - edge based on segment
1178 // after we can remove edges maked from segment
1179 gp_Pnt P01( (Pnt11.X()+Pnt21.X())/2, (Pnt11.Y()+Pnt21.Y())/2,
1180 (Pnt11.Z()+Pnt21.Z())/2 );
1181 gp_Pnt P02( (Pnt12.X()+Pnt22.X())/2, (Pnt12.Y()+Pnt22.Y())/2,
1182 (Pnt12.Z()+Pnt22.Z())/2 );
1183 Standard_Real tolV1 = Max(Pnt11.Distance(P01),Pnt21.Distance(P01));
1184 tolV1 = Max(tolV1,Precision::Confusion())*1.00001;
1185 Standard_Real tolV2 = Max(Pnt12.Distance(P02),Pnt22.Distance(P02));
1186 tolV2 = Max(tolV2,Precision::Confusion())*1.00001;
1187 if( tolV1>MaxTolVert || tolV2>MaxTolVert ) continue;
1188 TopoDS_Vertex NewV1,NewV2;
1190 // parameters for splitting: a1..p11..p12..b1 and a2..p21..p22..b2 ???
1191 Standard_Integer nbseg1=3, nbseg2=3, kv1=0, kv2=0;
1192 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1194 if(tolV1>BRep_Tool::Tolerance(V1))
1195 B.UpdateVertex(NewV1,tolV1);
1200 else if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1202 if(tolV1>BRep_Tool::Tolerance(V2))
1203 B.UpdateVertex(NewV1,tolV1);
1209 TopoDS_Edge tmpE,SegE;
1211 Standard_Integer akey1=0, akey2=0;
1213 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1215 if(tolV1>BRep_Tool::Tolerance(V1))
1216 B.UpdateVertex(NewV1,tolV1);
1219 if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1221 if(tolV1>BRep_Tool::Tolerance(V2))
1222 B.UpdateVertex(NewV1,tolV1);
1226 if(P02.Distance(PV1)<Max(tolV2,BRep_Tool::Tolerance(V1))) {
1228 if(tolV2>BRep_Tool::Tolerance(V1))
1229 B.UpdateVertex(NewV2,tolV2);
1232 if(P02.Distance(PV2)<Max(tolV2,BRep_Tool::Tolerance(V2))) {
1234 if(tolV2>BRep_Tool::Tolerance(V2))
1235 B.UpdateVertex(NewV2,tolV2);
1238 if( akey1>1 || akey2>1 ) continue;
1239 Standard_Integer dnum1=0, numseg1=num1;
1241 if(akey1==0) B.MakeVertex(NewV1,P01,tolV1);
1242 if(akey2==0) B.MakeVertex(NewV2,P02,tolV2);
1244 if( akey1==0 && akey2>0 ) {
1245 if(SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes)) {
1251 if( akey1>0 && akey2==0 ) {
1252 if(SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes) ) {
1258 if( akey1==0 && akey2==0 ) {
1259 if(SplitEdge1(sewd, face, num1, p11, NewV1, tolV1, boxes)) {
1263 tmpE = sewd->Edge(num1);
1265 Handle(Geom2d_Curve) c2d;
1266 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1267 if( (a-p12)*(b-p12)>0 ) { // p12 - external for [a,b] => split next edge
1268 if(SplitEdge1(sewd, face, num1+1, p12, NewV2, tolV2, boxes) ) {
1275 if(SplitEdge1(sewd, face, num1, p12, NewV2, tolV2, boxes) ) {
1282 //SegE = sewd->Edge(numseg1); // get edge from segment
1284 // replace vertices if it is necessary
1285 ShapeBuild_Edge sbe;
1288 if(P01.Distance(PV12)<tolV1) {
1289 tolV1 += P01.Distance(PV12);
1290 B.UpdateVertex(NewV1,tolV1);
1291 if(V12.Orientation()==NewV1.Orientation()) {
1292 myContext->Replace(V12,NewV1);
1296 myContext->Replace(V12,NewV1.Reversed());
1297 V12 = TopoDS::Vertex(NewV1.Reversed());
1299 nbReplaced++; //gka 06.09.04
1300 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
1301 myContext->Replace(edge2,NewE);
1302 sewd->Set(NewE,num2+dnum1);
1303 boxes.Bind(NewE,B2); // update boxes
1307 if(P01.Distance(PV22)<tolV1) {
1308 tolV1 += P01.Distance(PV22);
1309 B.UpdateVertex(NewV1,tolV1);
1310 if(V22.Orientation()==NewV1.Orientation()) {
1311 myContext->Replace(V22,NewV1);
1315 myContext->Replace(V22,NewV1.Reversed());
1316 V22 = TopoDS::Vertex(NewV1.Reversed());
1318 nbReplaced++; //gka 06.09.04
1319 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
1320 myContext->Replace(edge2,NewE);
1321 sewd->Set(NewE,num2+dnum1);
1322 boxes.Bind(NewE,B2); // update boxes
1326 if(P02.Distance(PV12)<tolV2) {
1327 tolV2 += P02.Distance(PV12);
1328 B.UpdateVertex(NewV2,tolV2);
1329 if(V12.Orientation()==NewV2.Orientation()) {
1330 myContext->Replace(V12,NewV2);
1334 myContext->Replace(V12,NewV2.Reversed());
1335 V12 = TopoDS::Vertex(NewV2.Reversed());
1337 nbReplaced++; //gka 06.09.04
1338 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
1339 myContext->Replace(edge2,NewE);
1340 sewd->Set(NewE,num2+dnum1);
1341 boxes.Bind(NewE,B2); // update boxes
1345 if(P02.Distance(PV22)<tolV2) {
1346 tolV2 += P02.Distance(PV22);
1347 B.UpdateVertex(NewV2,tolV2);
1348 if(V22.Orientation()==NewV2.Orientation()) {
1349 myContext->Replace(V22,NewV2);
1353 myContext->Replace(V22,NewV2.Reversed());
1354 V22 = TopoDS::Vertex(NewV2.Reversed());
1356 nbReplaced++; //gka 06.09.04
1357 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
1358 myContext->Replace(edge2,NewE);
1359 sewd->Set(NewE,num2+dnum1);
1360 boxes.Bind(NewE,B2); // update boxes
1364 Standard_Integer dnum2=0, numseg2=num2+dnum1;
1366 if( akey1==0 && akey2>0 ) {
1367 if(SplitEdge1(sewd, face, num2+dnum1, p21, NewV1, tolV1, boxes)) {
1370 //numseg2=num2+dnum1+1;
1374 if( akey1>0 && akey2==0 ) {
1375 if(SplitEdge1(sewd, face, num2+dnum1, p22, NewV2, tolV2, boxes)) {
1378 //numseg2=num2+dnum1;
1379 numseg2=num2+dnum1+1;
1382 if( akey1==0 && akey2==0 ) {
1383 if(SplitEdge1(sewd, face, num2+dnum1, p21, NewV1, tolV1, boxes)) {
1387 tmpE = sewd->Edge(num2+dnum1);
1389 Handle(Geom2d_Curve) c2d;
1390 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1391 if( (a-p22)*(b-p22)>0 ) { // p22 - external for [a,b] => split next edge
1392 if(SplitEdge1(sewd, face, num2+dnum1+dnum2, p22, NewV2, tolV2, boxes) ) {
1394 numseg2=num2+dnum1+dnum2;
1399 if(SplitEdge1(sewd, face, num2+dnum1, p22, NewV2, tolV2, boxes) ) {
1402 numseg2=num2+dnum1+1;
1407 sewd->Remove(numseg2);
1408 sewd->Remove(numseg1);
1409 NbRemoved = NbRemoved+2;
1419 isDone = (NbSplit || NbCut || nbReplaced || NbRemoved);
1424 //=======================================================================
1425 //function : FixIntersectingWires
1427 //=======================================================================
1429 Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
1430 (TopoDS_Face& face) const
1432 if(myContext.IsNull() || face.IsNull()) return Standard_False;
1433 //TopoDS_Shape S = context->Apply(face);
1434 //TopoDS_Shape SF = TopoDS::Face(S);
1435 TopoDS_Shape SF = face;
1436 TopAbs_Orientation ori = face.Orientation();
1437 TopTools_SequenceOfShape SeqWir;
1438 TopTools_SequenceOfShape SeqNMShapes;
1439 for( TopoDS_Iterator iter(SF,Standard_False); iter.More(); iter.Next() ) {
1440 if(iter.Value().ShapeType() != TopAbs_WIRE ||
1441 (iter.Value().Orientation() != TopAbs_FORWARD &&
1442 iter.Value().Orientation() != TopAbs_REVERSED)) {
1443 SeqNMShapes.Append(iter.Value());
1446 TopoDS_Wire wire = TopoDS::Wire(iter.Value());
1447 SeqWir.Append(wire);
1449 if(SeqWir.Length()<2) return Standard_False;//gka 06.09.04
1451 Standard_Real MaxTolVert=0.0;
1452 for(TopExp_Explorer exp(SF,TopAbs_VERTEX); exp.More(); exp.Next()) {
1453 Standard_Real tolV = BRep_Tool::Tolerance(TopoDS::Vertex(exp.Current()));
1454 MaxTolVert = Max(MaxTolVert,tolV);
1456 Standard_Boolean isDone = Standard_False; //gka 06.09.04
1457 ShapeAnalysis_Edge sae;
1459 for(Standard_Integer n1=1; n1<=SeqWir.Length()-1; n1++) {
1460 TopoDS_Wire wire1 = TopoDS::Wire(SeqWir.Value(n1));
1461 Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData(wire1);
1462 for(Standard_Integer n2=n1+1; n2<=SeqWir.Length(); n2++) {
1463 TopoDS_Wire wire2 = TopoDS::Wire(SeqWir.Value(n2));
1464 Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData(wire2);
1465 // detect possible intersections:
1466 ShapeFix_DataMapOfShapeBox2d boxes1,boxes2;
1467 CreateBoxes2d(sewd1,face,boxes1);
1468 CreateBoxes2d(sewd2,face,boxes2);
1469 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
1471 Standard_Integer NbModif=0;
1472 Standard_Integer nbReplaced =0;//gka 06.09.04
1473 Standard_Boolean hasModifWire = Standard_False; //gka 06.09.04
1474 for(Standard_Integer num1 = 1; num1<=sewd1->NbEdges() && NbModif<30; num1++) {
1475 // for each edge from first wire
1476 TopoDS_Edge edge1 = sewd1->Edge(num1); //gka 06.09.04
1478 for(Standard_Integer num2 = 1; num2<=sewd2->NbEdges() && NbModif<30; num2++) {
1479 // for each edge from second wire
1480 TopoDS_Edge edge2 = sewd2->Edge(num2);
1481 if(edge1.IsSame(edge2)) continue;
1482 if( BRep_Tool::Degenerated(edge1) || BRep_Tool::Degenerated(edge2) ) continue;
1483 if( !boxes1.IsBound(edge1) || !boxes2.IsBound(edge2) ) continue;
1484 Bnd_Box2d B1 = boxes1.Find(edge1);
1485 Bnd_Box2d B2 = boxes2.Find(edge2);
1487 // intersection is possible...
1488 Standard_Real a1, b1, a2, b2;
1489 Handle(Geom2d_Curve) Crv1, Crv2;
1490 if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) )
1491 continue; //return Standard_False; gka 06.09.04
1492 if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) )
1493 continue; //return Standard_False;gka 06.09.04
1494 Standard_Real tolint = 1.0e-10;
1495 IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
1496 IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
1497 Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
1498 Geom2dInt_GInter Inter;
1499 Inter.Perform( C1, d1, C2, d2, tolint, tolint );
1500 if(!Inter.IsDone()) continue;
1501 // intersection is point
1502 if( Inter.NbPoints()>0 && Inter.NbPoints()<3 ) {
1503 IntRes2d_IntersectionPoint IP;
1504 IntRes2d_Transition Tr1, Tr2;
1505 SelectIntPnt(Inter,IP,Tr1,Tr2);
1506 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1507 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1508 // create new vertex and split both edges
1509 Standard_Real param1 = IP.ParamOnFirst();
1510 Standard_Real param2 = IP.ParamOnSecond();
1511 gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
1512 gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
1513 gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
1516 Standard_Real tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
1517 B.MakeVertex(V,P0,tolV);
1518 MaxTolVert = Max(MaxTolVert,tolV);
1519 Standard_Boolean isSplitEdge2 = SplitEdge1(sewd2, face, num2, param2,
1525 if(SplitEdge1(sewd1, face, num1, param1, V, tolV, boxes1)) {
1533 if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
1534 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1535 // find needed vertex from edge2 and split edge1 using it
1536 Standard_Real param1 = IP.ParamOnFirst();
1537 if(FindVertAndSplitEdge(param1, edge1, edge2, Crv1, MaxTolVert,
1538 num1, sewd1, face, boxes1, Standard_True) ) {
1543 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1544 Tr2.PositionOnCurve() == IntRes2d_Middle ) {
1545 // find needed vertex from edge1 and split edge2 using it
1546 Standard_Real param2 = IP.ParamOnSecond();
1547 if(FindVertAndSplitEdge(param2, edge2, edge1, Crv2, MaxTolVert,
1548 num2, sewd2, face, boxes2, Standard_True) ) {
1553 if( Tr1.PositionOnCurve() != IntRes2d_Middle &&
1554 Tr2.PositionOnCurve() != IntRes2d_Middle ) {
1556 if( UnionVertexes(sewd2, edge1, edge2, num2, boxes2, B2) )
1557 nbReplaced ++; //gka 06.09.04
1560 hasModifWire = (hasModifWire || NbModif || nbReplaced);
1561 // intersection is segment
1562 if( Inter.NbSegments()==1 ) {
1563 IntRes2d_IntersectionSegment IS = Inter.Segment(1);
1564 if ( IS.HasFirstPoint() && IS.HasLastPoint() ) {
1565 Standard_Boolean IsModified1 = Standard_False;
1566 Standard_Boolean IsModified2 = Standard_False;
1569 Standard_Real newtol=0.0;
1570 IntRes2d_IntersectionPoint IPF = IS.FirstPoint();
1571 Standard_Real p11 = IPF.ParamOnFirst();
1572 Standard_Real p21 = IPF.ParamOnSecond();
1573 IntRes2d_IntersectionPoint IPL = IS.LastPoint();
1574 Standard_Real p12 = IPL.ParamOnFirst();
1575 Standard_Real p22 = IPL.ParamOnSecond();
1576 gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
1577 gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
1578 gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
1579 gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
1581 // analysis for edge1
1582 TopoDS_Vertex V1 = sae.FirstVertex(edge1);
1583 gp_Pnt PV1 = BRep_Tool::Pnt(V1);
1584 TopoDS_Vertex V2 = sae.LastVertex(edge1);
1585 gp_Pnt PV2 = BRep_Tool::Pnt(V2);
1586 Standard_Real dist1 = Pnt11.Distance(PV1);
1587 Standard_Real dist2 = Pnt12.Distance(PV1);
1588 Standard_Real maxdist = Max(dist1,dist2);
1589 Standard_Real pdist;
1590 if(edge1.Orientation()==TopAbs_REVERSED)
1591 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1593 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1594 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1597 IsModified1 = Standard_True;
1599 dist1 = Pnt11.Distance(PV2);
1600 dist2 = Pnt12.Distance(PV2);
1601 maxdist = Max(dist1,dist2);
1602 if(edge1.Orientation()==TopAbs_REVERSED)
1603 pdist = Max(Abs(a1-p11),Abs(a1-p12));
1605 pdist = Max(Abs(b1-p11),Abs(b1-p12));
1606 if(maxdist<MaxTolVert || pdist<Abs(b1-a1)*0.01) {
1607 if( ( IsModified1 && maxdist<newtol ) || !IsModified1 ) {
1610 IsModified1 = Standard_True;
1614 // cut edge1 and update tolerance NewV
1615 Standard_Real dista = Abs(a1-p11)+Abs(a1-p12);
1616 Standard_Real distb = Abs(b1-p11)+Abs(b1-p12);
1617 Standard_Real pend,cut;
1618 if(dista>distb) pend=a1;
1620 if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
1622 Standard_Boolean IsCutLine;
1623 CutEdge(edge1, pend, cut, face, IsCutLine);
1624 if(newtol>BRep_Tool::Tolerance(NewV)) {
1625 B.UpdateVertex(NewV,newtol*1.00001);
1629 // analysis for edge2
1630 TopoDS_Vertex V12 = sae.FirstVertex(edge2);
1631 gp_Pnt PV12 = BRep_Tool::Pnt(V12);
1632 TopoDS_Vertex V22 = sae.LastVertex(edge2);
1633 gp_Pnt PV22 = BRep_Tool::Pnt(V22);
1634 dist1 = Pnt21.Distance(PV12);
1635 dist2 = Pnt22.Distance(PV12);
1636 maxdist = Max(dist1,dist2);
1637 if(edge2.Orientation()==TopAbs_REVERSED)
1638 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1640 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1641 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1644 IsModified2 = Standard_True;
1646 dist1 = Pnt21.Distance(PV22);
1647 dist2 = Pnt22.Distance(PV22);
1648 maxdist = Max(dist1,dist2);
1649 if(edge2.Orientation()==TopAbs_REVERSED)
1650 pdist = Max(Abs(a2-p21),Abs(a2-p22));
1652 pdist = Max(Abs(b2-p21),Abs(b2-p22));
1653 if(maxdist<MaxTolVert || pdist<Abs(b2-a2)*0.01) {
1654 if( ( IsModified2 && maxdist<newtol ) || !IsModified2 ) {
1657 IsModified2 = Standard_True;
1661 // cut edge1 and update tolerance NewV
1662 Standard_Real dista = Abs(a2-p21)+Abs(a2-p22);
1663 Standard_Real distb = Abs(b2-p21)+Abs(b2-p22);
1664 Standard_Real pend,cut;
1665 if(dista>distb) pend=a2;
1667 if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
1669 Standard_Boolean IsCutLine;
1670 CutEdge(edge2, pend, cut, face, IsCutLine);
1671 if(newtol>BRep_Tool::Tolerance(NewV)) {
1672 B.UpdateVertex(NewV,newtol*1.00001);
1676 if( IsModified1 || IsModified2 ) {
1678 hasModifWire = Standard_True; //gka 06.09.04
1682 // create new vertex and split edge1 and edge2 using it
1683 if( Abs(p12-p11)>Abs(b1-a1)/2 || Abs(p22-p21)>Abs(b2-a2)/2 ) {
1684 // segment is big and we have to split each intersecting edge
1685 // on 3 edges --> middle edge - edge based on segment
1686 gp_Pnt P01( (Pnt11.X()+Pnt21.X())/2, (Pnt11.Y()+Pnt21.Y())/2,
1687 (Pnt11.Z()+Pnt21.Z())/2 );
1688 gp_Pnt P02( (Pnt12.X()+Pnt22.X())/2, (Pnt12.Y()+Pnt22.Y())/2,
1689 (Pnt12.Z()+Pnt22.Z())/2 );
1690 Standard_Real tolV1 = Max(Pnt11.Distance(P01),Pnt21.Distance(P01));
1691 tolV1 = Max(tolV1,Precision::Confusion())*1.00001;
1692 Standard_Real tolV2 = Max(Pnt12.Distance(P02),Pnt22.Distance(P02));
1693 tolV2 = Max(tolV2,Precision::Confusion())*1.00001;
1694 if( tolV1>MaxTolVert || tolV2>MaxTolVert ) continue;
1696 hasModifWire = Standard_True; //gka 06.09.04
1697 TopoDS_Vertex NewV1,NewV2;
1698 TopoDS_Edge tmpE,SegE;
1700 Standard_Integer akey1=0, akey2=0;
1702 if(P01.Distance(PV1)<Max(tolV1,BRep_Tool::Tolerance(V1))) {
1704 if(tolV1>BRep_Tool::Tolerance(V1))
1705 B.UpdateVertex(NewV1,tolV1);
1708 if(P01.Distance(PV2)<Max(tolV1,BRep_Tool::Tolerance(V2))) {
1710 if(tolV1>BRep_Tool::Tolerance(V2))
1711 B.UpdateVertex(NewV1,tolV1);
1715 if(P02.Distance(PV1)<Max(tolV2,BRep_Tool::Tolerance(V1))) {
1717 if(tolV2>BRep_Tool::Tolerance(V1))
1718 B.UpdateVertex(NewV2,tolV2);
1721 if(P02.Distance(PV2)<Max(tolV2,BRep_Tool::Tolerance(V2))) {
1723 if(tolV2>BRep_Tool::Tolerance(V2))
1724 B.UpdateVertex(NewV2,tolV2);
1727 if( akey1>1 || akey2>1 ) continue;
1729 if(akey1==0) B.MakeVertex(NewV1,P01,tolV1);
1730 if(akey2==0) B.MakeVertex(NewV2,P02,tolV2);
1732 Standard_Integer numseg1=num1;
1733 if( akey1==0 && akey2>0 ) {
1734 if(SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1)) {
1739 if( akey1>0 && akey2==0 ) {
1740 if(SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1) ) {
1745 if( akey1==0 && akey2==0 ) {
1746 if(SplitEdge1(sewd1, face, num1, p11, NewV1, tolV1, boxes1)) {
1749 tmpE = sewd1->Edge(num1);
1751 Handle(Geom2d_Curve) c2d;
1752 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1753 if( (a-p12)*(b-p12)>0 ) { // p12 - external for [a,b] => split next edge
1754 if(SplitEdge1(sewd1, face, num1+1, p12, NewV2, tolV2, boxes1) ) {
1760 if(SplitEdge1(sewd1, face, num1, p12, NewV2, tolV2, boxes1) ) {
1766 SegE = sewd1->Edge(numseg1); // get edge from segment
1768 // replace vertices if it is necessary
1769 ShapeBuild_Edge sbe;
1771 if(P01.Distance(PV12)<tolV1) {
1772 tolV1 += P01.Distance(PV12);
1773 B.UpdateVertex(NewV1,tolV1);
1775 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
1776 myContext->Replace(edge2,NewE);
1777 sewd2->Set(NewE,num2);
1778 boxes2.Bind(NewE,B2); // update boxes2
1782 if(P01.Distance(PV22)<tolV1) {
1783 tolV1 += P01.Distance(PV22);
1784 B.UpdateVertex(NewV1,tolV1);
1786 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
1787 myContext->Replace(edge2,NewE);
1788 sewd2->Set(NewE,num2);
1789 boxes2.Bind(NewE,B2); // update boxes2
1793 if(P02.Distance(PV12)<tolV2) {
1794 tolV2 += P02.Distance(PV12);
1795 B.UpdateVertex(NewV2,tolV2);
1797 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
1798 myContext->Replace(edge2,NewE);
1799 sewd2->Set(NewE,num2);
1800 boxes2.Bind(NewE,B2); // update boxes2
1804 if(P02.Distance(PV22)<tolV2) {
1805 tolV2 += P02.Distance(PV22);
1806 B.UpdateVertex(NewV2,tolV2);
1808 TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
1809 myContext->Replace(edge2,NewE);
1810 sewd2->Set(NewE,num2);
1811 boxes2.Bind(NewE,B2); // update boxes2
1816 Standard_Integer numseg2=num2;
1817 if( akey1==0 && akey2>0 ) {
1818 if(SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2)) {
1823 if( akey1>0 && akey2==0 ) {
1824 if(SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2)) {
1829 if( akey1==0 && akey2==0 ) {
1830 if(SplitEdge1(sewd2, face, num2, p21, NewV1, tolV1, boxes2)) {
1834 tmpE = sewd2->Edge(num2);
1836 Handle(Geom2d_Curve) c2d;
1837 sae.PCurve(tmpE,face,c2d,a,b,Standard_False);
1838 if( (a-p22)*(b-p22)>0 ) { // p22 - external for [a,b] => split next edge
1839 if(SplitEdge1(sewd2, face, num2+1, p22, NewV2, tolV2, boxes2) ) {
1845 if(SplitEdge1(sewd2, face, num2, p22, NewV2, tolV2, boxes2) ) {
1851 tmpE = sewd2->Edge(numseg2);
1852 boxes2.Bind(tmpE,boxes1.Find(SegE)); // update boxes2
1853 if(!sae.FirstVertex(SegE).IsSame(sae.FirstVertex(tmpE))) {
1856 myContext->Replace(tmpE,SegE);
1857 sewd2->Set(SegE,numseg2);
1862 // split each intersecting edge on two edges
1863 gp_Pnt P0( (Pnt11.X()+Pnt12.X())/2, (Pnt11.Y()+Pnt12.Y())/2,
1864 (Pnt11.Z()+Pnt12.Z())/2 );
1865 Standard_Real param1 = (p11+p12)/2;
1866 Standard_Real param2 = (p21+p22)/2;
1867 gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
1868 gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
1869 dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(Pnt10));
1870 dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(Pnt10));
1871 Standard_Real tolV = Max(dist1,dist2);
1872 tolV = Max(tolV,Pnt10.Distance(Pnt20))*1.00001;
1873 B.MakeVertex(NewV,Pnt10,tolV);
1874 MaxTolVert = Max(MaxTolVert,tolV);
1875 hasModifWire = Standard_True;
1876 if(SplitEdge2(sewd2, face, num2, p21, p22, NewV, tolV, boxes2)) {
1880 if(SplitEdge2(sewd1, face, num1, p11, p12, NewV, tolV, boxes1)) {
1888 } // end if(Inter.NbSegments()==1)
1894 isDone = Standard_True;
1895 SeqWir.SetValue(n1,sewd1->Wire());
1896 myContext->Replace( wire1, sewd1->Wire() );
1897 wire1 = sewd1->Wire();
1898 SeqWir.SetValue(n2,sewd2->Wire());
1899 myContext->Replace( wire2, sewd2->Wire() );
1900 wire2 = sewd2->Wire();
1908 TopoDS_Shape emptyCopied = face.EmptyCopied();
1909 TopoDS_Face newface = TopoDS::Face (emptyCopied);
1910 newface.Orientation(TopAbs_FORWARD);
1912 Standard_Integer i=1;
1913 for( ; i<=SeqWir.Length(); i++) {
1914 TopoDS_Wire wire = TopoDS::Wire(SeqWir.Value(i));
1915 B.Add(newface,wire);
1917 for( ; i<=SeqWir.Length(); i++) {
1918 TopoDS_Shape aNMS = SeqNMShapes.Value(i);
1919 B.Add(newface,aNMS);
1921 newface.Orientation(ori);
1922 myContext->Replace(face,newface);