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