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