b311480e |
1 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
2 | // |
3 | // The content of this file is subject to the Open CASCADE Technology Public |
4 | // License Version 6.5 (the "License"). You may not use the content of this file |
5 | // except in compliance with the License. Please obtain a copy of the License |
6 | // at http://www.opencascade.org and read it completely before using this file. |
7 | // |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
10 | // |
11 | // The Original Code and all software distributed under the License is |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
13 | // Initial Developer hereby disclaims all such warranties, including without |
14 | // limitation, any warranties of merchantability, fitness for a particular |
15 | // purpose or non-infringement. Please see the License for the specific terms |
16 | // and conditions governing the rights and limitations under the License. |
17 | |
7fd59977 |
18 | // szv 19.08.99: new methods for fixing gaps between edges (3d curves and pcurves) |
19 | #include <ShapeFix_Wire.hxx> |
20 | #include <Standard_ErrorHandler.hxx> |
21 | #include <Standard_Failure.hxx> |
22 | |
23 | #include <Precision.hxx> |
24 | #include <Bnd_Box2d.hxx> |
25 | #include <Geom_Curve.hxx> |
26 | #include <Geom2d_Curve.hxx> |
27 | #include <Geom2d_Line.hxx> |
28 | |
29 | #include <IntRes2d_SequenceOfIntersectionPoint.hxx> |
30 | #include <IntRes2d_IntersectionPoint.hxx> |
31 | #include <TColgp_SequenceOfPnt.hxx> |
32 | |
33 | #include <TopoDS.hxx> |
34 | #include <TopoDS_Vertex.hxx> |
35 | #include <TopoDS_Edge.hxx> |
36 | #include <TopTools_HSequenceOfShape.hxx> |
37 | |
38 | #include <BRep_Tool.hxx> |
39 | #include <BRep_Builder.hxx> |
40 | |
41 | #include <ShapeExtend.hxx> |
42 | #include <ShapeBuild_Edge.hxx> |
43 | #include <ShapeBuild_Vertex.hxx> |
44 | #include <ShapeAnalysis_Curve.hxx> |
45 | #include <ShapeAnalysis_Edge.hxx> |
46 | #include <ShapeAnalysis_Surface.hxx> |
47 | #include <ShapeAnalysis.hxx> |
48 | #include <GeomConvert_CompCurveToBSplineCurve.hxx> |
49 | #include <Geom_TrimmedCurve.hxx> |
50 | #include <gp_Pln.hxx> |
51 | #include <GeomAPI.hxx> |
52 | #include <TColgp_Array1OfPnt.hxx> |
53 | #include <TColStd_Array1OfReal.hxx> |
54 | #include <TColStd_Array1OfInteger.hxx> |
55 | #include <Geom_BSplineCurve.hxx> |
56 | #include <Geom_SphericalSurface.hxx> //S4135 |
57 | #include <Geom2d_BSplineCurve.hxx> |
58 | #include <GeomAdaptor_Curve.hxx> |
59 | #include <GeomAdaptor_HSurface.hxx> |
60 | #include <GeomAdaptor_Surface.hxx> |
61 | #include <TopTools_Array1OfShape.hxx> |
62 | #include <BRepTools.hxx> |
63 | #include <Bnd_Array1OfBox2d.hxx> |
64 | #include <BndLib_Add2dCurve.hxx> |
65 | #include <Geom2dAdaptor_Curve.hxx> |
66 | #include <Geom2dConvert.hxx> |
67 | #include <Geom2d_TrimmedCurve.hxx> |
68 | #include <ShapeBuild_ReShape.hxx> |
b311480e |
69 | |
7fd59977 |
70 | //szv |
71 | #include <TColgp_Array1OfPnt2d.hxx> |
72 | #include <Geom2d_Circle.hxx> |
73 | #include <Geom2d_Ellipse.hxx> |
74 | #include <Geom2d_Parabola.hxx> |
75 | #include <Geom2d_Hyperbola.hxx> |
76 | #include <Geom2d_OffsetCurve.hxx> |
77 | #include <Geom2dInt_GInter.hxx> |
78 | #include <IntRes2d_Domain.hxx> |
79 | #include <IntRes2d_IntersectionSegment.hxx> |
80 | #include <Geom2dAPI_ExtremaCurveCurve.hxx> |
81 | #include <Geom2dAPI_ProjectPointOnCurve.hxx> |
82 | #include <Geom2dAdaptor_HCurve.hxx> |
83 | #include <Approx_Curve2d.hxx> |
84 | #include <Geom2dConvert.hxx> |
85 | |
86 | #include <Geom_Line.hxx> |
87 | #include <Geom_Circle.hxx> |
88 | #include <Geom_Ellipse.hxx> |
89 | #include <Geom_Parabola.hxx> |
90 | #include <Geom_Hyperbola.hxx> |
91 | #include <Geom_OffsetCurve.hxx> |
92 | #include <GeomAPI_ExtremaCurveCurve.hxx> |
93 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
94 | #include <GeomAdaptor_HCurve.hxx> |
95 | #include <Approx_Curve3d.hxx> |
96 | #include <GeomConvert.hxx> |
97 | #include <TopoDS_Iterator.hxx> |
98 | #include <ShapeFix_ShapeTolerance.hxx> |
99 | #include <ShapeAnalysis_TransferParametersProj.hxx> |
100 | //======================================================================= |
101 | //function : FixGaps3d |
102 | //purpose : |
103 | //======================================================================= |
104 | |
b311480e |
105 | Standard_Boolean ShapeFix_Wire::FixGaps3d () |
7fd59977 |
106 | { |
107 | myStatusGaps3d = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
108 | // if ( !IsReady() ) return Standard_False; |
109 | |
110 | Standard_Integer i, start = ( myClosedMode ? 1 : 2 ); |
111 | if (myFixGapsByRanges) |
112 | { |
113 | for ( i = start; i <= NbEdges(); i++ ) |
114 | { |
115 | FixGap3d ( i ); |
116 | myStatusGaps3d |= myLastFixStatus; |
117 | } |
118 | } |
119 | for ( i = start; i <= NbEdges(); i++ ) |
120 | { |
121 | FixGap3d ( i, Standard_True ); |
122 | myStatusGaps3d |= myLastFixStatus; |
123 | } |
124 | |
125 | return StatusGaps3d ( ShapeExtend_DONE ); |
126 | } |
127 | |
128 | //======================================================================= |
129 | //function : FixGaps2d |
130 | //purpose : |
131 | //======================================================================= |
132 | |
133 | Standard_Boolean ShapeFix_Wire::FixGaps2d () |
134 | { |
135 | myStatusGaps2d = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
136 | // if ( !IsReady() ) return Standard_False; |
137 | |
138 | Standard_Integer i, start = ( myClosedMode ? 1 : 2 ); |
139 | if (myFixGapsByRanges) |
140 | { |
141 | for ( i = start; i <= NbEdges(); i++ ) |
142 | { |
143 | FixGap2d ( i ); |
144 | myStatusGaps2d |= myLastFixStatus; |
145 | } |
146 | } |
147 | for ( i = start; i <= NbEdges(); i++ ) |
148 | { |
149 | FixGap2d ( i, Standard_True ); |
150 | myStatusGaps2d |= myLastFixStatus; |
151 | } |
152 | |
153 | return StatusGaps2d ( ShapeExtend_DONE ); |
154 | } |
155 | |
156 | //======================================================================= |
157 | //function : FixGap3d |
158 | //purpose : |
159 | //======================================================================= |
160 | |
161 | static Standard_Real AdjustOnPeriodic3d (const Handle(Geom_Curve)& c, |
162 | const Standard_Boolean takefirst, |
163 | const Standard_Real first, |
164 | const Standard_Real last, |
165 | const Standard_Real param) |
166 | { |
167 | // 15.11.2002 PTV OCC966 |
168 | if (ShapeAnalysis_Curve::IsPeriodic(c)) |
169 | { |
170 | Standard_Real T = c->Period(); |
171 | Standard_Real shift = -IntegerPart(first/T)*T; if (first<0.) shift += T; |
172 | Standard_Real sfirst = first+shift, slast = last+shift; |
173 | if ( takefirst && (param>slast) && (param>sfirst)) return param-T-shift; |
174 | if (!takefirst && (param<slast) && (param<sfirst)) return param+T-shift; |
175 | } |
176 | return param; |
177 | } |
178 | |
179 | Standard_Boolean ShapeFix_Wire::FixGap3d (const Standard_Integer num, |
180 | const Standard_Boolean convert) |
181 | { |
182 | myLastFixStatus = ShapeExtend::EncodeStatus( ShapeExtend_OK ); |
183 | // if ( !IsReady() ) return Standard_False; |
184 | |
185 | //============= |
186 | // First phase: analysis whether the problem (gap) exists |
187 | //============= |
188 | |
189 | if (Context().IsNull()) SetContext(new ShapeBuild_ReShape); |
190 | |
191 | Standard_Real preci = Precision(); |
192 | |
193 | Handle(ShapeExtend_WireData) sbwd = WireData(); |
194 | Standard_Integer n2 = ( num >0 ? num : sbwd->NbEdges() ); |
195 | Standard_Integer n1 = ( n2 >1 ? n2-1 : sbwd->NbEdges() ); |
196 | //smh#8 |
197 | TopoDS_Shape tmp1 = Context()->Apply(sbwd->Edge(n1)), |
198 | tmp2 = Context()->Apply(sbwd->Edge(n2)); |
199 | TopoDS_Edge E1 = TopoDS::Edge(tmp1), |
200 | E2 = TopoDS::Edge(tmp2); |
201 | // TopoDS_Face face = myAnalyzer->Face(); // comment by enk |
202 | |
203 | // Retrieve curves on edges |
204 | Standard_Real cfirst1, clast1, cfirst2, clast2; |
205 | Handle(Geom_Curve) C1, C2; |
206 | ShapeAnalysis_Edge SAE; |
207 | if (!SAE.Curve3d(E1,C1,cfirst1,clast1) || |
208 | !SAE.Curve3d(E2,C2,cfirst2,clast2)) |
209 | { |
210 | myLastFixStatus |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL1 ); |
211 | return Standard_False; |
212 | } |
213 | |
214 | // Check gap in 3d space |
215 | gp_Pnt cpnt1 = C1->Value(clast1), cpnt2 = C2->Value(cfirst2); |
216 | Standard_Real gap = cpnt1.Distance(cpnt2); |
217 | if (!convert && gap<=preci) return Standard_False; |
218 | |
219 | //============= |
220 | // Second phase: collecting data necessary for further analysis |
221 | //============= |
222 | |
223 | Standard_Boolean reversed1 = (E1.Orientation()==TopAbs_REVERSED), |
224 | reversed2 = (E2.Orientation()==TopAbs_REVERSED); |
225 | |
226 | TopoDS_Vertex V1 = SAE.LastVertex(E1), V2 = SAE.FirstVertex(E2); |
227 | gp_Pnt vpnt = (V1.IsSame(V2))? BRep_Tool::Pnt(V1) : |
228 | gp_Pnt((BRep_Tool::Pnt(V1).XYZ()+BRep_Tool::Pnt(V2).XYZ())*0.5); |
229 | |
230 | Standard_Real first1, last1, first2, last2; |
231 | if (reversed1) |
232 | { |
233 | first1 = clast1; last1 = cfirst1; |
234 | } |
235 | else |
236 | { |
237 | first1 = cfirst1; last1 = clast1; |
238 | } |
239 | if (reversed2) |
240 | { |
241 | first2 = clast2; last2 = cfirst2; |
242 | } |
243 | else |
244 | { |
245 | first2 = cfirst2; last2 = clast2; |
246 | } |
247 | |
248 | Handle(Geom_Curve) c1 = C1, c2 = C2; |
249 | |
250 | // Extract basic curves from trimmed and offset |
251 | Standard_Boolean basic = Standard_False; |
252 | Standard_Boolean trimmed1 = Standard_False, offset1 = Standard_False; |
253 | gp_XYZ offval1(0.,0.,0.); |
254 | while (!basic) |
255 | { |
256 | if (c1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) |
257 | { |
258 | c1 = Handle(Geom_TrimmedCurve)::DownCast(c1)->BasisCurve(); |
259 | trimmed1 = Standard_True; |
260 | } |
261 | else if (c1->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) |
262 | { |
263 | Handle(Geom_OffsetCurve) oc = Handle(Geom_OffsetCurve)::DownCast(c1); |
264 | c1 = oc->BasisCurve(); |
265 | offval1 += oc->Offset()*oc->Direction().XYZ(); |
266 | offset1 = Standard_True; |
267 | } |
268 | else basic = Standard_True; |
269 | } |
270 | basic = Standard_False; |
271 | Standard_Boolean trimmed2 = Standard_False, offset2 = Standard_False; |
272 | gp_XYZ offval2(0.,0.,0.); |
273 | while (!basic) |
274 | { |
275 | if (c2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) |
276 | { |
277 | c2 = Handle(Geom_TrimmedCurve)::DownCast(c2)->BasisCurve(); |
278 | trimmed2 = Standard_True; |
279 | } |
280 | else if (c2->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) |
281 | { |
282 | Handle(Geom_OffsetCurve) oc = Handle(Geom_OffsetCurve)::DownCast(c2); |
283 | c2 = oc->BasisCurve(); |
284 | offval2 += oc->Offset()*oc->Direction().XYZ(); |
285 | offset2 = Standard_True; |
286 | } |
287 | else basic = Standard_True; |
288 | } |
289 | // Restore offset curves |
290 | if (offset1) c1 = new Geom_OffsetCurve(c1,offval1.Modulus(),gp_Dir(offval1)); |
291 | if (offset2) c2 = new Geom_OffsetCurve(c2,offval2.Modulus(),gp_Dir(offval2)); |
292 | |
293 | Standard_Boolean done1 = Standard_False, done2 = Standard_False; |
294 | |
295 | if (convert) |
296 | { |
297 | |
298 | Handle(Geom_BSplineCurve) bsp1, bsp2; |
299 | Handle(Geom_Curve) c; |
300 | Standard_Real first, last; |
301 | |
302 | // iterate on curves |
303 | Standard_Integer nbcurv = (n1==n2? 1 : 2); |
304 | for (Standard_Integer j=1; j<=nbcurv; j++) |
305 | { |
306 | //Standard_Boolean trim = Standard_False; // skl |
307 | if (j==1) |
308 | { |
309 | if (cpnt1.Distance(vpnt)<preci) |
310 | { |
311 | if (n1==n2) |
312 | { |
313 | if (cpnt2.Distance(vpnt)<preci) continue; |
314 | } |
315 | else continue; |
316 | } |
317 | c = c1; first = first1; last = last1; /*trim = trimmed1;*/ // skl |
318 | } |
319 | else |
320 | { |
321 | if (cpnt2.Distance(vpnt)<preci) continue; |
322 | c = c2; first = first2; last = last2; /*trim = trimmed2;*/ // skl |
323 | } |
324 | |
325 | Handle(Geom_BSplineCurve) bsp; |
326 | |
327 | // Convert curve to bspline |
328 | if (c->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) |
329 | { |
330 | bsp = Handle(Geom_BSplineCurve)::DownCast(c->Copy()); |
331 | // take segment if trim and range differ |
332 | Standard_Real fbsp = bsp->FirstParameter(), lbsp = bsp->LastParameter(); |
333 | Standard_Boolean segment = Standard_False; |
334 | if (first>fbsp) |
335 | { |
336 | fbsp = first; segment = Standard_True; |
337 | } |
338 | if (last<lbsp) |
339 | { |
340 | lbsp = last; segment = Standard_True; |
341 | } |
342 | if (segment) |
343 | bsp = GeomConvert::SplitBSplineCurve(bsp,fbsp,lbsp, |
344 | ::Precision::Confusion()); |
345 | } |
346 | else if (c->IsKind(STANDARD_TYPE(Geom_Conic))) |
347 | { |
348 | Approx_Curve3d Conv(new GeomAdaptor_HCurve(c,first,last), |
349 | myAnalyzer->Precision(),GeomAbs_C1,9,1000); |
350 | if (Conv.IsDone() || Conv.HasResult()) bsp = Conv.Curve(); |
351 | } |
352 | else |
353 | { |
354 | // Restore trim for pcurve |
355 | Handle(Geom_Curve) tc ; |
356 | try |
357 | { |
358 | OCC_CATCH_SIGNALS |
359 | // 15.11.2002 PTV OCC966 |
360 | if(!ShapeAnalysis_Curve::IsPeriodic(c)) |
361 | tc = new Geom_TrimmedCurve(c,Max(first,c->FirstParameter()),Min(last,c->LastParameter())); |
362 | else tc = new Geom_TrimmedCurve(c,first,last); |
363 | bsp = GeomConvert::CurveToBSplineCurve(tc); |
364 | } |
365 | catch (Standard_Failure) |
366 | { |
367 | #ifdef DEB |
368 | cout << "Warning: ShapeFix_Wire_1::FixGap3d: Exception in TrimmedCurve" <<first<<" " <<last<<endl; |
369 | Standard_Failure::Caught()->Print(cout); cout << endl; |
370 | #endif |
371 | } |
372 | } |
373 | |
374 | if (j==1) bsp1 = bsp; else bsp2 = bsp; |
375 | } |
376 | |
377 | // Take curves ends if could not convert |
378 | if (bsp1.IsNull()) vpnt = cpnt1; |
379 | else if (bsp2.IsNull()) vpnt = cpnt2; |
380 | |
381 | if (!bsp1.IsNull()) |
382 | { |
383 | if(bsp1->Degree() == 1) bsp1->IncreaseDegree(2); //gka |
384 | if (n1==n2) |
385 | { |
386 | bsp1->SetPole(1,vpnt); bsp1->SetPole(bsp1->NbPoles(),vpnt); |
387 | } |
388 | else |
389 | { |
390 | if (reversed1) bsp1->SetPole(1,vpnt); |
391 | else bsp1->SetPole(bsp1->NbPoles(),vpnt); |
392 | } |
393 | first1 = bsp1->FirstParameter(); last1 = bsp1->LastParameter(); |
394 | c1 = bsp1; |
395 | done1 = Standard_True; |
396 | } |
397 | if (!bsp2.IsNull()) |
398 | { |
399 | if(bsp2->Degree() == 1) bsp2->IncreaseDegree(2); //gka |
400 | if (reversed2) bsp2->SetPole(bsp2->NbPoles(),vpnt); |
401 | else bsp2->SetPole(1,vpnt); |
402 | first2 = bsp2->FirstParameter(); last2 = bsp2->LastParameter(); |
403 | c2 = bsp2; |
404 | done2 = Standard_True; |
405 | } |
406 | } |
407 | else |
408 | { |
409 | |
410 | if (n1==n2) |
411 | { |
412 | if (c1->IsKind(STANDARD_TYPE(Geom_Circle)) || |
413 | c1->IsKind(STANDARD_TYPE(Geom_Ellipse))) |
414 | { |
c6541a0c |
415 | Standard_Real diff = M_PI - Abs(clast1-cfirst2)*0.5; |
7fd59977 |
416 | first1 -= diff; last1 += diff; |
417 | done1 = Standard_True; |
418 | } |
419 | } |
420 | else |
421 | { |
422 | |
423 | // Determine domains for extremal points locating |
424 | Standard_Real domfirst1 = first1, domlast1 = last1; |
425 | if (c1->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) || |
426 | c1->IsKind(STANDARD_TYPE(Geom_BezierCurve))) |
427 | { |
428 | domfirst1 = c1->FirstParameter(); |
429 | domlast1 = c1->LastParameter(); |
430 | } |
431 | else if (c1->IsKind(STANDARD_TYPE(Geom_Line)) || |
432 | c1->IsKind(STANDARD_TYPE(Geom_Parabola)) || |
433 | c1->IsKind(STANDARD_TYPE(Geom_Hyperbola))) |
434 | { |
435 | Standard_Real diff = domlast1 - domfirst1; |
436 | if (reversed1) domfirst1 -= 10.*diff; |
437 | else domlast1 += 10.*diff; |
438 | } |
439 | else if (c1->IsKind(STANDARD_TYPE(Geom_Circle)) || |
440 | c1->IsKind(STANDARD_TYPE(Geom_Ellipse))) |
441 | { |
c6541a0c |
442 | domfirst1 = 0.; domlast1 = 2*M_PI; |
7fd59977 |
443 | } |
444 | Standard_Real domfirst2 = first2, domlast2 = last2; |
445 | if (c2->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) || |
446 | c2->IsKind(STANDARD_TYPE(Geom_BezierCurve))) |
447 | { |
448 | domfirst2 = c2->FirstParameter(); |
449 | domlast2 = c2->LastParameter(); |
450 | } |
451 | else if (c2->IsKind(STANDARD_TYPE(Geom_Line)) || |
452 | c2->IsKind(STANDARD_TYPE(Geom_Parabola)) || |
453 | c2->IsKind(STANDARD_TYPE(Geom_Hyperbola))) |
454 | { |
455 | Standard_Real diff = domlast2 - domfirst2; |
456 | if (reversed2) domlast2 += 10.*diff; |
457 | else domfirst2 -= 10.*diff; |
458 | } |
459 | else if (c2->IsKind(STANDARD_TYPE(Geom_Circle)) || |
460 | c2->IsKind(STANDARD_TYPE(Geom_Ellipse))) |
461 | { |
c6541a0c |
462 | domfirst2 = 0.; domlast2 = 2*M_PI; |
7fd59977 |
463 | } |
464 | |
465 | Standard_Real ipar1 = clast1, ipar2 = cfirst2; |
466 | |
467 | // Try to find projections of vertex point |
468 | GeomAPI_ProjectPointOnCurve Proj; |
469 | Standard_Real u1 = ipar1, u2 = ipar2; |
470 | Proj.Init(vpnt,c1,domfirst1,domlast1); |
471 | if (Proj.NbPoints()) |
472 | { |
473 | Standard_Integer index = 1; |
474 | Standard_Real dist, mindist=-1.; |
475 | for (Standard_Integer i=1; i<=Proj.NbPoints(); i++) |
476 | { |
477 | dist = vpnt.Distance(Proj.Point(i)); |
478 | if (mindist>dist || mindist<0.) |
479 | { |
480 | index = i; mindist = dist; |
481 | } |
482 | u1 = Proj.Parameter(index); |
483 | } |
484 | } |
485 | Proj.Init(vpnt,c2,domfirst2,domlast2); |
486 | if (Proj.NbPoints()) |
487 | { |
488 | Standard_Integer index = 1; |
489 | Standard_Real dist, mindist=-1.; |
490 | for (Standard_Integer i=1; i<=Proj.NbPoints(); i++) |
491 | { |
492 | dist = vpnt.Distance(Proj.Point(i)); |
493 | if (mindist>dist || mindist<0.) |
494 | { |
495 | index = i; mindist = dist; |
496 | } |
497 | u2 = Proj.Parameter(index); |
498 | } |
499 | } |
500 | // Ajust parameters on periodic curves |
501 | u1 = AdjustOnPeriodic3d(c1,reversed1,first1,last1,u1); |
502 | u2 = AdjustOnPeriodic3d(c2,!reversed2,first2,last2,u2); |
503 | // Check points to satisfy distance criterium |
504 | gp_Pnt p1 = c1->Value(u1), p2 = c2->Value(u2); |
505 | if (p1.Distance(p2)<=gap && |
506 | Abs(cfirst1-u1) > ::Precision::PConfusion() && |
507 | Abs(clast2-u2) > ::Precision::PConfusion() && |
508 | (((u1>first1) && (u1<last1)) || ((u2>first2) && (u2<last2)) || |
509 | (cpnt1.Distance(p1)<=gap) || (cpnt2.Distance(p2)<=gap))) |
510 | { |
511 | ipar1 = u1; ipar2 = u2; |
512 | done1 = done2 = Standard_True; |
513 | } |
514 | |
515 | // Try to find closest points if nothing yet found |
516 | if (!done1) |
517 | { |
518 | |
519 | // Recompute domains |
520 | if (reversed1) |
521 | { |
522 | domfirst1 = ipar1; domlast1 = last1; |
523 | } |
524 | else |
525 | { |
526 | domfirst1 = first1; domlast1 = ipar1; |
527 | } |
528 | if (reversed2) |
529 | { |
530 | domfirst2 = first2; domlast2 = ipar2; |
531 | } |
532 | else |
533 | { |
534 | domfirst2 = ipar2; domlast2 = last2; |
535 | } |
536 | |
537 | GeomAPI_ExtremaCurveCurve Extr(c1,c2,domfirst1,domlast1,domfirst2,domlast2); |
538 | if (Extr.NbExtrema()) |
539 | { |
540 | try |
541 | { |
542 | OCC_CATCH_SIGNALS |
543 | // First find all intersections |
544 | gp_Pnt pp1, pp2; |
545 | Standard_Integer index1=0, index2=0; |
546 | Standard_Real uu1, uu2, pardist, pardist1=-1., pardist2=-1.; |
547 | for (Standard_Integer i=1; i<=Extr.NbExtrema(); i++) |
548 | { |
549 | Extr.Parameters(i,uu1,uu2); |
550 | // Ajust parameters on periodic curves |
551 | uu1 = AdjustOnPeriodic3d(c1,reversed1,first1,last1,uu1); |
552 | uu2 = AdjustOnPeriodic3d(c2,!reversed2,first2,last2,uu2); |
553 | pp1 = c1->Value(uu1); pp2 = c2->Value(uu2); |
554 | if (pp1.Distance(pp2) < ::Precision::Confusion()) |
555 | { |
556 | // assume intersection |
557 | pardist = Abs(cfirst1-uu1); |
558 | if (pardist1>pardist || pardist1<0.) |
559 | { |
560 | index1 = i; pardist1 = pardist; |
561 | } |
562 | pardist = Abs(clast2-uu2); |
563 | if (pardist2>pardist || pardist2<0.) |
564 | { |
565 | index2 = i; pardist2 = pardist; |
566 | } |
567 | } |
568 | } |
569 | if (index1!=0 && index2!=0) |
570 | { |
571 | if (index1!=index2) |
572 | { |
573 | // take intersection closer to vertex point |
574 | Extr.Parameters(index1,uu1,uu2); |
575 | pp1 = gp_Pnt((c1->Value(uu1).XYZ()+c2->Value(uu2).XYZ())*0.5); |
576 | Extr.Parameters(index2,uu1,uu2); |
577 | pp2 = gp_Pnt((c1->Value(uu1).XYZ()+c2->Value(uu2).XYZ())*0.5); |
578 | if (pp2.Distance(vpnt) < pp1.Distance(vpnt)) index1 = index2; |
579 | } |
580 | Extr.Parameters(index1,uu1,uu2); |
581 | } |
582 | else Extr.LowerDistanceParameters(uu1,uu2); |
583 | // Ajust parameters on periodic curves |
584 | uu1 = AdjustOnPeriodic3d(c1,reversed1,first1,last1,uu1); |
585 | uu2 = AdjustOnPeriodic3d(c2,!reversed2,first2,last2,uu2); |
586 | // Check points to satisfy distance criterium |
587 | pp1 = c1->Value(uu1), pp2 = c2->Value(uu2); |
588 | if (pp1.Distance(pp2)<=gap && |
589 | Abs(cfirst1-uu1) > ::Precision::PConfusion() && |
590 | Abs(clast2-uu2) > ::Precision::PConfusion() && |
591 | (((uu1>first1) && (uu1<last1)) || ((uu2>first2) && (uu2<last2)) || |
592 | (cpnt1.Distance(pp1)<=gap) || (cpnt2.Distance(pp2)<=gap))) |
593 | { |
594 | ipar1 = uu1; ipar2 = uu2; |
595 | done1 = done2 = Standard_True; |
596 | } |
597 | } |
598 | catch ( Standard_Failure ) |
599 | { |
600 | } |
601 | } |
602 | } |
603 | |
604 | try |
605 | { |
606 | OCC_CATCH_SIGNALS |
607 | if (done1) |
608 | { |
609 | if (ipar1==clast1) done1 = Standard_False; |
610 | else |
611 | { |
612 | // Set up new bounds for curve |
613 | if (reversed1) first1 = ipar1; else last1 = ipar1; |
614 | // Set new trim for old curve |
615 | if (trimmed1) |
616 | { |
617 | // Standard_Real ff1 = c1->FirstParameter(); |
618 | // Standard_Real ll1 = c1->LastParameter(); |
619 | c1 = new Geom_TrimmedCurve(c1,first1,last1); |
620 | } |
621 | } |
622 | } |
623 | if (done2) |
624 | { |
625 | if (ipar2==cfirst2) done2 = Standard_False; |
626 | else |
627 | { |
628 | // Set up new bounds for curve |
629 | if (reversed2) last2 = ipar2; else first2 = ipar2; |
630 | // Set new trim for old curve |
631 | if (trimmed2) |
632 | { |
633 | // Standard_Real ff2 = c2->FirstParameter(); |
634 | // Standard_Real ll2 = c2->LastParameter(); |
635 | c2 = new Geom_TrimmedCurve(c2,first2,last2); |
636 | } |
637 | } |
638 | } |
639 | } |
640 | catch (Standard_Failure) |
641 | { |
642 | #ifdef DEB |
643 | cout << "Warning: ShapeFix_Wire_1::FixGap3d: Exception in TrimmedCurve :"<<endl; |
644 | Standard_Failure::Caught()->Print(cout); cout << endl; |
645 | #endif |
646 | } |
647 | } |
648 | } |
649 | |
650 | if (done1 || done2) |
651 | { |
652 | |
653 | BRep_Builder B; |
654 | ShapeBuild_Edge SBE; |
655 | ShapeFix_ShapeTolerance SFST; |
656 | |
657 | // Update vertices |
658 | TopoDS_Vertex nullV, newV1; |
659 | //smh#8 |
660 | TopoDS_Shape emptyCopiedV2 = V2.EmptyCopied(); |
661 | TopoDS_Vertex newV2 = TopoDS::Vertex(emptyCopiedV2); |
662 | SFST.SetTolerance(newV2,::Precision::Confusion()); |
663 | Context()->Replace(V2,newV2); |
664 | if (V1.IsSame(V2)) |
665 | //smh#8 |
666 | { |
667 | TopoDS_Shape tmpV2 = newV2.Oriented(TopAbs_REVERSED); |
668 | newV1 = TopoDS::Vertex(tmpV2); |
669 | } |
670 | else |
671 | { |
672 | //smh#8 |
673 | TopoDS_Shape emptyCopied = V1.EmptyCopied(); |
674 | newV1 = TopoDS::Vertex(emptyCopied); |
675 | SFST.SetTolerance(newV1,::Precision::Confusion()); |
676 | Context()->Replace(V1,newV1); |
677 | } |
678 | |
679 | if (done1) |
680 | { |
681 | // Update first edge |
682 | TopoDS_Edge newE1 = SBE.CopyReplaceVertices(E1,nullV,newV1); |
683 | //smh#8 |
684 | TopoDS_Shape tmpE1 = newE1.Oriented(TopAbs_FORWARD); |
685 | B.UpdateEdge(TopoDS::Edge(tmpE1),c1,0.); |
686 | SBE.SetRange3d(TopoDS::Edge(tmpE1),first1,last1); |
687 | SFST.SetTolerance(newE1,::Precision::Confusion(),TopAbs_EDGE); |
688 | B.SameRange(newE1,Standard_False); |
689 | // B.SameParameter(newE1,Standard_False); |
690 | |
691 | //To keep NM vertices belonging initial edges |
692 | TopoDS_Iterator aItv(E1,Standard_False); |
693 | for( ; aItv.More(); aItv.Next()) { |
694 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
695 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
696 | TopoDS_Vertex aOldV = TopoDS::Vertex(aItv.Value()); |
697 | TopoDS_Vertex anewV = ShapeAnalysis_TransferParametersProj::CopyNMVertex(aOldV,newE1,E1); |
698 | B.Add(newE1,anewV); |
699 | Context()->Replace(aOldV,anewV); |
700 | } |
701 | } |
702 | |
703 | Context()->Replace(E1,newE1); |
704 | sbwd->Set(newE1,n1); |
705 | } |
706 | |
707 | if (done2) |
708 | { |
709 | // Update second edge |
710 | TopoDS_Edge newE2 = SBE.CopyReplaceVertices(E2,newV2,nullV); |
711 | //smh#8 |
712 | TopoDS_Shape tmpE2 = newE2.Oriented(TopAbs_FORWARD); |
713 | B.UpdateEdge(TopoDS::Edge(tmpE2),c2,0.); |
714 | SBE.SetRange3d(TopoDS::Edge(tmpE2),first2,last2); |
715 | SFST.SetTolerance(newE2,::Precision::Confusion(),TopAbs_EDGE); |
716 | B.SameRange(newE2,Standard_False); |
717 | // B.SameParameter(newE2,Standard_False); |
718 | |
719 | //To keep NM vertices belonging initial edges |
720 | TopoDS_Iterator aItv(E2,Standard_False); |
721 | for( ; aItv.More(); aItv.Next()) { |
722 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
723 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
724 | TopoDS_Vertex aOldV = TopoDS::Vertex(aItv.Value()); |
725 | TopoDS_Vertex anewV = ShapeAnalysis_TransferParametersProj::CopyNMVertex(aOldV,newE2,E2); |
726 | B.Add(newE2,anewV); |
727 | Context()->Replace(aOldV,anewV); |
728 | } |
729 | } |
730 | Context()->Replace(E2,newE2); |
731 | sbwd->Set(newE2,n2); |
732 | } |
733 | |
734 | myLastFixStatus |= ShapeExtend::EncodeStatus( ShapeExtend_DONE1 ); |
735 | } |
736 | else |
737 | if (convert) |
738 | myLastFixStatus |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL2 ); |
739 | |
740 | return (done1 || done2); |
741 | } |
742 | |
743 | //======================================================================= |
744 | //function : FixGap2d |
745 | //purpose : |
746 | //======================================================================= |
747 | |
748 | static Standard_Real AdjustOnPeriodic2d (const Handle(Geom2d_Curve)& pc, |
749 | const Standard_Boolean takefirst, |
750 | const Standard_Real first, |
751 | const Standard_Real last, |
752 | const Standard_Real param) |
753 | { |
754 | // 15.11.2002 PTV OCC966 |
755 | if (ShapeAnalysis_Curve::IsPeriodic(pc)) |
756 | { |
757 | Standard_Real T = pc->Period(); |
758 | Standard_Real shift = -IntegerPart(first/T)*T; if (first<0.) shift += T; |
759 | Standard_Real sfirst = first+shift, slast = last+shift; |
760 | if ( takefirst && (param>slast) && (param>sfirst)) return param-T-shift; |
761 | if (!takefirst && (param<slast) && (param<sfirst)) return param+T-shift; |
762 | } |
763 | return param; |
764 | } |
765 | |
766 | Standard_Boolean ShapeFix_Wire::FixGap2d (const Standard_Integer num, |
767 | const Standard_Boolean convert) |
768 | { |
769 | myLastFixStatus = ShapeExtend::EncodeStatus( ShapeExtend_OK ); |
770 | if ( !IsReady() ) return Standard_False; |
771 | |
772 | //============= |
773 | // First phase: analysis whether the problem (gap) exists |
774 | //============= |
775 | |
776 | if (Context().IsNull()) SetContext(new ShapeBuild_ReShape); |
777 | |
778 | Standard_Real preci = ::Precision::PConfusion(); |
779 | //Standard_Real preci = Precision(); |
780 | //GeomAdaptor_Surface& SA = Analyzer().Surface()->Adaptor()->ChangeSurface(); |
781 | //preci = Max(SA.UResolution(preci), SA.VResolution(preci)); |
782 | |
783 | Handle(ShapeExtend_WireData) sbwd = WireData(); |
784 | Standard_Integer n2 = ( num >0 ? num : sbwd->NbEdges() ); |
785 | Standard_Integer n1 = ( n2 >1 ? n2-1 : sbwd->NbEdges() ); |
786 | //smh#8 |
787 | TopoDS_Shape tmp1 = Context()->Apply(sbwd->Edge(n1)), |
788 | tmp2 = Context()->Apply(sbwd->Edge(n2)); |
789 | TopoDS_Edge E1 = TopoDS::Edge(tmp1), |
790 | E2 = TopoDS::Edge(tmp2); |
791 | TopoDS_Face face = myAnalyzer->Face(); |
792 | |
793 | // Retrieve pcurves on edges |
794 | Standard_Real cfirst1, clast1, cfirst2, clast2; |
795 | Handle(Geom2d_Curve) PC1, PC2; |
796 | ShapeAnalysis_Edge SAE; |
797 | if (!SAE.PCurve(E1,face,PC1,cfirst1,clast1) || |
798 | !SAE.PCurve(E2,face,PC2,cfirst2,clast2) || |
799 | sbwd->IsSeam(n1) || sbwd->IsSeam(n2)) |
800 | { |
801 | myLastFixStatus |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL1 ); |
802 | return Standard_False; |
803 | } |
804 | |
805 | // Check gap in 2d space |
806 | gp_Pnt2d cpnt1 = PC1->Value(clast1), cpnt2 = PC2->Value(cfirst2); |
807 | Standard_Real gap = cpnt1.Distance(cpnt2); |
808 | if (gap<=preci) return Standard_False; |
809 | |
810 | //============= |
811 | // Second phase: collecting data necessary for further analysis |
812 | //============= |
813 | |
814 | Standard_Boolean reversed1 = (E1.Orientation()==TopAbs_REVERSED), |
815 | reversed2 = (E2.Orientation()==TopAbs_REVERSED); |
816 | |
817 | Standard_Real first1, last1, first2, last2; |
818 | if (reversed1) |
819 | { |
820 | first1 = clast1; last1 = cfirst1; |
821 | } |
822 | else |
823 | { |
824 | first1 = cfirst1; last1 = clast1; |
825 | } |
826 | if (reversed2) |
827 | { |
828 | first2 = clast2; last2 = cfirst2; |
829 | } |
830 | else |
831 | { |
832 | first2 = cfirst2; last2 = clast2; |
833 | } |
834 | |
835 | Handle(Geom2d_Curve) pc1 = PC1, pc2 = PC2; |
836 | |
837 | // Extract basic curves from trimmed and offset |
838 | Standard_Boolean basic = Standard_False; |
839 | Standard_Boolean trimmed1 = Standard_False, offset1 = Standard_False; |
840 | Standard_Real offval1 = 0.; |
841 | while (!basic) |
842 | { |
843 | if (pc1->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) |
844 | { |
845 | pc1 = Handle(Geom2d_TrimmedCurve)::DownCast(pc1)->BasisCurve(); |
846 | trimmed1 = Standard_True; |
847 | } |
848 | else if (pc1->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) |
849 | { |
850 | Handle(Geom2d_OffsetCurve) oc = Handle(Geom2d_OffsetCurve)::DownCast(pc1); |
851 | pc1 = oc->BasisCurve(); |
852 | offval1 += oc->Offset(); |
853 | offset1 = Standard_True; |
854 | } |
855 | else basic = Standard_True; |
856 | } |
857 | basic = Standard_False; |
858 | Standard_Boolean trimmed2 = Standard_False, offset2 = Standard_False; |
859 | Standard_Real offval2 = 0.; |
860 | while (!basic) |
861 | { |
862 | if (pc2->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) |
863 | { |
864 | pc2 = Handle(Geom2d_TrimmedCurve)::DownCast(pc2)->BasisCurve(); |
865 | trimmed2 = Standard_True; |
866 | } |
867 | else if (pc2->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) |
868 | { |
869 | Handle(Geom2d_OffsetCurve) oc = Handle(Geom2d_OffsetCurve)::DownCast(pc2); |
870 | pc2 = oc->BasisCurve(); |
871 | offval2 += oc->Offset(); |
872 | offset2 = Standard_True; |
873 | } |
874 | else basic = Standard_True; |
875 | } |
876 | // Restore offset curves |
877 | if (offset1) pc1 = new Geom2d_OffsetCurve(pc1,offval1); |
878 | if (offset2) pc2 = new Geom2d_OffsetCurve(pc2,offval2); |
879 | |
880 | Standard_Boolean done1 = Standard_False, done2 = Standard_False; |
881 | |
882 | // Determine same edge case |
883 | if (convert) |
884 | { |
885 | |
886 | Handle(Geom2d_BSplineCurve) bsp1, bsp2; |
887 | Handle(Geom2d_Curve) pc; |
888 | Standard_Real first, last; |
889 | |
890 | // iterate on pcurves |
891 | Standard_Integer nbcurv = (n1==n2? 1 : 2); |
892 | for (Standard_Integer j=1; j<=nbcurv; j++) |
893 | { |
894 | //Standard_Integer trim = Standard_False; // skl |
895 | Handle(Geom2d_BSplineCurve) bsp; |
896 | |
897 | if (j==1) |
898 | { |
899 | pc = pc1; first = first1; last = last1; /*trim = trimmed1;*/ |
900 | } // skl |
901 | else |
902 | { |
903 | pc = pc2; first = first2; last = last2; /*trim = trimmed2;*/ |
904 | } // skl |
905 | |
906 | // Convert pcurve to bspline |
907 | if (pc->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) |
908 | { |
909 | bsp = Handle(Geom2d_BSplineCurve)::DownCast(pc->Copy()); |
910 | // take segment if trim and range differ |
911 | Standard_Real fbsp = bsp->FirstParameter(), lbsp = bsp->LastParameter(); |
912 | Standard_Boolean segment = Standard_False; |
913 | if (first>fbsp) |
914 | { |
915 | fbsp = first; segment = Standard_True; |
916 | } |
917 | if (last<lbsp) |
918 | { |
919 | lbsp = last; segment = Standard_True; |
920 | } |
921 | if (segment) |
922 | bsp = Geom2dConvert::SplitBSplineCurve(bsp,fbsp,lbsp, |
923 | ::Precision::PConfusion()); |
924 | } |
925 | else if (pc->IsKind(STANDARD_TYPE(Geom2d_Conic))) |
926 | { |
927 | GeomAdaptor_Surface& AS = myAnalyzer->Surface()->Adaptor3d()->ChangeSurface(); |
928 | Standard_Real tolu = AS.UResolution(myAnalyzer->Precision()), |
929 | tolv = AS.VResolution(myAnalyzer->Precision()); |
930 | Approx_Curve2d Conv(new Geom2dAdaptor_HCurve(pc,first,last), |
931 | first,last,tolu,tolv,GeomAbs_C1,9,1000); |
932 | if (Conv.IsDone() || Conv.HasResult()) bsp = Conv.Curve(); |
933 | } |
934 | else |
935 | { |
936 | // Restore trim for pcurve |
937 | try |
938 | { |
939 | OCC_CATCH_SIGNALS |
940 | Handle(Geom2d_Curve) c; |
941 | // 15.11.2002 PTV OCC966 |
942 | if(!ShapeAnalysis_Curve::IsPeriodic(pc)) |
943 | c = new Geom2d_TrimmedCurve(pc,Max(first,pc->FirstParameter()),Min(last,pc->LastParameter())); |
944 | else |
945 | c = new Geom2d_TrimmedCurve(pc,first,last); |
946 | bsp = Geom2dConvert::CurveToBSplineCurve(c); |
947 | } |
948 | catch (Standard_Failure) |
949 | { |
950 | #ifdef DEB |
951 | cout << "Warning: ShapeFix_Wire_1::FixGap2d: Exception in TrimmedCurve2d" <<first<<" " <<last<<endl; |
952 | Standard_Failure::Caught()->Print(cout); cout << endl; |
953 | #endif |
954 | } |
955 | } |
956 | |
957 | if (j==1) bsp1 = bsp; else bsp2 = bsp; |
958 | } |
959 | |
960 | // Take curves ends if could not convert |
961 | gp_Pnt2d mpnt((cpnt1.XY()+cpnt2.XY())*0.5); |
962 | if (bsp1.IsNull()) mpnt = cpnt1; |
963 | else if (bsp2.IsNull()) mpnt = cpnt2; |
964 | |
965 | if (!bsp1.IsNull()) |
966 | { |
967 | if(bsp1->Degree() == 1) bsp1->IncreaseDegree(2); |
968 | if (n1==n2) |
969 | { |
970 | bsp1->SetPole(1,mpnt); bsp1->SetPole(bsp1->NbPoles(),mpnt); |
971 | } |
972 | else |
973 | { |
974 | if (reversed1) bsp1->SetPole(1,mpnt); |
975 | else bsp1->SetPole(bsp1->NbPoles(),mpnt); |
976 | } |
977 | first1 = bsp1->FirstParameter(); last1 = bsp1->LastParameter(); |
978 | pc1 = bsp1; |
979 | done1 = Standard_True; |
980 | } |
981 | if (!bsp2.IsNull()) |
982 | { |
983 | if(bsp2->Degree() == 1) bsp2->IncreaseDegree(2); |
984 | if (reversed2) bsp2->SetPole(bsp2->NbPoles(),mpnt); |
985 | else bsp2->SetPole(1,mpnt); |
986 | first2 = bsp2->FirstParameter(); last2 = bsp2->LastParameter(); |
987 | pc2 = bsp2; |
988 | done2 = Standard_True; |
989 | } |
990 | } |
991 | else |
992 | { |
993 | |
994 | if (n1==n2) |
995 | { |
996 | if (pc1->IsKind(STANDARD_TYPE(Geom2d_Circle)) || |
997 | pc1->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) |
998 | { |
c6541a0c |
999 | Standard_Real diff = M_PI - Abs(clast1-cfirst2)*0.5; |
7fd59977 |
1000 | first1 -= diff; last1 += diff; |
1001 | done1 = Standard_True; |
1002 | } |
1003 | } |
1004 | else |
1005 | { |
1006 | |
1007 | // Determine domains for extremal points locating |
1008 | Standard_Real domfirst1 = first1, domlast1 = last1; |
1009 | if (pc1->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) || |
1010 | pc1->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) |
1011 | { |
1012 | domfirst1 = pc1->FirstParameter(); |
1013 | domlast1 = pc1->LastParameter(); |
1014 | } |
1015 | else if (pc1->IsKind(STANDARD_TYPE(Geom2d_Line)) || |
1016 | pc1->IsKind(STANDARD_TYPE(Geom2d_Parabola)) || |
1017 | pc1->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) |
1018 | { |
1019 | Standard_Real diff = domlast1 - domfirst1; |
1020 | if (reversed1) domfirst1 -= 10.*diff; |
1021 | else domlast1 += 10.*diff; |
1022 | } |
1023 | else if (pc1->IsKind(STANDARD_TYPE(Geom2d_Circle)) || |
1024 | pc1->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) |
1025 | { |
c6541a0c |
1026 | domfirst1 = 0.; domlast1 = 2*M_PI; |
7fd59977 |
1027 | } |
1028 | Standard_Real domfirst2 = first2, domlast2 = last2; |
1029 | if (pc2->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) || |
1030 | pc2->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) |
1031 | { |
1032 | domfirst2 = pc2->FirstParameter(); |
1033 | domlast2 = pc2->LastParameter(); |
1034 | } |
1035 | else if (pc2->IsKind(STANDARD_TYPE(Geom2d_Line)) || |
1036 | pc2->IsKind(STANDARD_TYPE(Geom2d_Parabola)) || |
1037 | pc2->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) |
1038 | { |
1039 | Standard_Real diff = domlast2 - domfirst2; |
1040 | if (reversed2) domlast2 += 10.*diff; |
1041 | else domfirst2 -= 10.*diff; |
1042 | } |
1043 | else if (pc2->IsKind(STANDARD_TYPE(Geom2d_Circle)) || |
1044 | pc2->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) |
1045 | { |
c6541a0c |
1046 | domfirst2 = 0.; domlast2 = 2*M_PI; |
7fd59977 |
1047 | } |
1048 | |
1049 | Standard_Real ipar1 = clast1, ipar2 = cfirst2; |
1050 | |
1051 | Geom2dInt_GInter Inter; |
1052 | Standard_Real tolint = ::Precision::PConfusion(); |
1053 | |
1054 | Geom2dAdaptor_Curve AC1(pc1), AC2(pc2); |
1055 | |
1056 | // Try to find intersection points |
1057 | IntRes2d_Domain dom1(pc1->Value(domfirst1),domfirst1,tolint, |
1058 | pc1->Value(domlast1),domlast1,tolint); |
1059 | IntRes2d_Domain dom2(pc2->Value(domfirst2),domfirst2,tolint, |
1060 | pc2->Value(domlast2),domlast2,tolint); |
1061 | Inter.Perform( AC1, dom1, AC2, dom2, tolint, tolint ); |
1062 | if (Inter.IsDone()) |
1063 | { |
1064 | if (Inter.NbPoints() || Inter.NbSegments()) |
1065 | { |
1066 | Standard_Integer i, index1 = 0, index2 = 0; |
1067 | Standard_Real pardist, pardist1=-1., pardist2=-1.; |
1068 | // iterate on intersection points |
1069 | IntRes2d_IntersectionPoint IP; |
1070 | for ( i=1; i<=Inter.NbPoints(); i++ ) |
1071 | { |
1072 | IP = Inter.Point(i); |
1073 | // Adjust parameters on periodic curves |
1074 | Standard_Real u1 = AdjustOnPeriodic2d(pc1,reversed1,first1,last1, |
1075 | IP.ParamOnFirst()); |
1076 | Standard_Real u2 = AdjustOnPeriodic2d(pc2,!reversed2,first2,last2, |
1077 | IP.ParamOnSecond()); |
1078 | pardist = Abs(cfirst1-u1); |
1079 | if (pardist1>pardist || pardist1<0.) |
1080 | { |
1081 | index1 = i; pardist1 = pardist; |
1082 | } |
1083 | pardist = Abs(clast2-u2); |
1084 | if (pardist2>pardist || pardist2<0.) |
1085 | { |
1086 | index2 = i; pardist2 = pardist; |
1087 | } |
1088 | } |
1089 | Standard_Integer flag1 = 0, flag2 = 0; |
1090 | // iterate on intersection segments |
1091 | IntRes2d_IntersectionSegment IS; |
1092 | for ( i=1; i<=Inter.NbSegments(); i++ ) |
1093 | { |
1094 | IS = Inter.Segment(i); |
1095 | for (Standard_Integer j=1; j<=2; j++) |
1096 | { |
1097 | if ((j==1 && IS.HasFirstPoint()) || |
1098 | (j==2 && IS.HasLastPoint())) |
1099 | { |
1100 | if (j==1) IP = IS.FirstPoint(); |
1101 | else IP = IS.LastPoint(); |
1102 | // Adjust parameters on periodic curves |
1103 | Standard_Real u1 = AdjustOnPeriodic2d(pc1,reversed1,first1,last1, |
1104 | IP.ParamOnFirst()); |
1105 | Standard_Real u2 = AdjustOnPeriodic2d(pc2,!reversed2,first2,last2, |
1106 | IP.ParamOnSecond()); |
1107 | pardist = Abs(cfirst1-u1); |
1108 | if (pardist1>pardist || pardist1<0.) |
1109 | { |
1110 | flag1 = j; index1 = i; pardist1 = pardist; |
1111 | } |
1112 | pardist = Abs(clast2-u2); |
1113 | if (pardist2>pardist || pardist2<0.) |
1114 | { |
1115 | flag2 = j; index2 = i; pardist2 = pardist; |
1116 | } |
1117 | } |
1118 | } |
1119 | } |
1120 | if (index1!=index2 || flag1!=flag2) |
1121 | { |
1122 | // take intersection closer to mean point |
1123 | gp_Pnt2d pt1, pt2; |
1124 | if (flag1==0) pt1 = Inter.Point(index1).Value(); |
1125 | else |
1126 | { |
1127 | IS = Inter.Segment(index1); |
1128 | if (flag1==1) pt1 = IS.FirstPoint().Value(); |
1129 | else pt1 = IS.LastPoint().Value(); |
1130 | } |
1131 | if (flag2==0) pt2 = Inter.Point(index2).Value(); |
1132 | else |
1133 | { |
1134 | IS = Inter.Segment(index2); |
1135 | if (flag2==1) pt2 = IS.FirstPoint().Value(); |
1136 | else pt2 = IS.LastPoint().Value(); |
1137 | } |
1138 | gp_Pnt2d mpnt((cpnt1.XY()+cpnt2.XY())*0.5); |
1139 | if (pt2.Distance(mpnt) < pt1.Distance(mpnt)) |
1140 | { |
1141 | index1 = index2; flag1 = flag2; |
1142 | } |
1143 | } |
1144 | if (flag1==0) IP = Inter.Point(index1); |
1145 | else |
1146 | { |
1147 | IS = Inter.Segment(index1); |
1148 | if (flag1==1) IP = IS.FirstPoint(); |
1149 | else IP = IS.LastPoint(); |
1150 | } |
1151 | // Ajust parameters on periodic curves |
1152 | Standard_Real u1 = AdjustOnPeriodic2d(pc1,reversed1,first1,last1, |
1153 | IP.ParamOnFirst()); |
1154 | Standard_Real u2 = AdjustOnPeriodic2d(pc2,!reversed2,first2,last2, |
1155 | IP.ParamOnSecond()); |
1156 | // Check points to satisfy distance criterium |
1157 | gp_Pnt2d p1 = pc1->Value(u1), p2 = pc2->Value(u2); |
1158 | if (p1.Distance(p2)<=gap && |
1159 | Abs(cfirst1-u1) > ::Precision::PConfusion() && |
1160 | Abs(clast2 -u2) > ::Precision::PConfusion() && |
1161 | (((u1>first1) && (u1<last1)) || ((u2>first2) && (u2<last2)) || |
1162 | (cpnt1.Distance(p1)<=gap) || (cpnt2.Distance(p2)<=gap))) |
1163 | { |
1164 | ipar1 = u1; ipar2 = u2; |
1165 | done1 = done2 = Standard_True; |
1166 | } |
1167 | } |
1168 | } |
1169 | |
1170 | // Try to find closest points if nothing yet found |
1171 | if (!done1) |
1172 | { |
1173 | Geom2dAPI_ExtremaCurveCurve Extr(pc1,pc2,domfirst1,domlast1,domfirst2,domlast2); |
1174 | if (Extr.NbExtrema()) |
1175 | { |
1176 | Standard_Real u1, u2; |
1177 | Extr.LowerDistanceParameters(u1,u2); |
1178 | // Ajust parameters on periodic curves |
1179 | u1 = AdjustOnPeriodic2d(pc1,reversed1,first1,last1,u1); |
1180 | u2 = AdjustOnPeriodic2d(pc2,!reversed2,first2,last2,u2); |
1181 | // Check points to satisfy distance criterium |
1182 | gp_Pnt2d p1 = pc1->Value(u1), p2 = pc2->Value(u2); |
1183 | if (p1.Distance(p2)<=gap && |
1184 | Abs(cfirst1-u1) > ::Precision::PConfusion() && |
1185 | Abs(clast2 -u2) > ::Precision::PConfusion() && |
1186 | (((u1>first1) && (u1<last1)) || ((u2>first2) && (u2<last2)) || |
1187 | (cpnt1.Distance(p1)<=gap) || (cpnt2.Distance(p2)<=gap))) |
1188 | { |
1189 | ipar1 = u1; ipar2 = u2; |
1190 | done1 = done2 = Standard_True; |
1191 | } |
1192 | } |
1193 | } |
1194 | |
1195 | // Try to find projections if nothing yet found |
1196 | if (!done1) |
1197 | { |
1198 | Geom2dAPI_ProjectPointOnCurve Proj; |
1199 | gp_Pnt2d ipnt1 = cpnt1, ipnt2 = cpnt2; |
1200 | Standard_Real u1 = ipar1, u2 = ipar2; |
1201 | Proj.Init(cpnt2,pc1,domfirst1,domlast1); |
1202 | if (Proj.NbPoints()) |
1203 | { |
1204 | Standard_Integer index = 1; |
1205 | Standard_Real dist, mindist=-1.; |
1206 | for (Standard_Integer i=1; i<=Proj.NbPoints(); i++) |
1207 | { |
1208 | dist = cpnt2.Distance(Proj.Point(i)); |
1209 | if (mindist>dist || mindist<0.) |
1210 | { |
1211 | index = i; mindist = dist; |
1212 | } |
1213 | ipnt1 = Proj.Point(index); |
1214 | u1 = Proj.Parameter(index); |
1215 | } |
1216 | } |
1217 | Proj.Init(cpnt1,pc2,domfirst2,domlast2); |
1218 | if (Proj.NbPoints()) |
1219 | { |
1220 | Standard_Integer index = 1; |
1221 | Standard_Real dist, mindist=-1.; |
1222 | for (Standard_Integer i=1; i<=Proj.NbPoints(); i++) |
1223 | { |
1224 | dist = cpnt1.Distance(Proj.Point(i)); |
1225 | if (mindist>dist || mindist<0.) |
1226 | { |
1227 | index = i; mindist = dist; |
1228 | } |
1229 | ipnt2 = Proj.Point(index); |
1230 | u2 = Proj.Parameter(index); |
1231 | } |
1232 | } |
1233 | // Ajust parameters on periodic curves |
1234 | u1 = AdjustOnPeriodic2d(pc1,reversed1,first1,last1,u1); |
1235 | u2 = AdjustOnPeriodic2d(pc2,!reversed2,first2,last2,u2); |
1236 | // Process special case of projection |
1237 | if ((((reversed1 && u1>clast1) || (!reversed1 && u1<clast1)) && |
1238 | ((reversed2 && u2<cfirst2) || (!reversed2 && u2>cfirst2))) || |
1239 | (((reversed1 && u1<clast1) || (!reversed1 && u1>clast1)) && |
1240 | ((reversed2 && u2>cfirst2) || (!reversed2 && u2<cfirst2)))) |
1241 | { |
1242 | // both projections lie inside/outside initial domains |
1243 | // project mean point |
1244 | gp_Pnt2d mpnt((cpnt1.XY()+cpnt2.XY())*0.5); |
1245 | u1 = ipar1; u2 = ipar2; |
1246 | Proj.Init(mpnt,pc1,domfirst1,domlast1); |
1247 | if (Proj.NbPoints()) |
1248 | { |
1249 | Standard_Integer index = 1; |
1250 | Standard_Real dist, mindist=-1.; |
1251 | for (Standard_Integer i=1; i<=Proj.NbPoints(); i++) |
1252 | { |
1253 | dist = mpnt.Distance(Proj.Point(i)); |
1254 | if (mindist>dist || mindist<0.) |
1255 | { |
1256 | index = i; mindist = dist; |
1257 | } |
1258 | ipnt1 = Proj.Point(index); |
1259 | u1 = Proj.Parameter(index); |
1260 | } |
1261 | } |
1262 | Proj.Init(mpnt,pc2,domfirst2,domlast2); |
1263 | if (Proj.NbPoints()) |
1264 | { |
1265 | Standard_Integer index = 1; |
1266 | Standard_Real dist, mindist=-1.; |
1267 | for (Standard_Integer i=1; i<=Proj.NbPoints(); i++) |
1268 | { |
1269 | dist = mpnt.Distance(Proj.Point(i)); |
1270 | if (mindist>dist || mindist<0.) |
1271 | { |
1272 | index = i; mindist = dist; |
1273 | } |
1274 | ipnt2 = Proj.Point(index); |
1275 | u2 = Proj.Parameter(index); |
1276 | } |
1277 | } |
1278 | } |
1279 | else |
1280 | { |
1281 | if (cpnt1.Distance(ipnt2)<cpnt2.Distance(ipnt1)) u1 = ipar1; |
1282 | else u2 = ipar2; |
1283 | } |
1284 | // Ajust parameters on periodic curves |
1285 | u1 = AdjustOnPeriodic2d(pc1,reversed1,first1,last1,u1); |
1286 | u2 = AdjustOnPeriodic2d(pc2,!reversed2,first2,last2,u2); |
1287 | // Check points to satisfy distance criterium |
1288 | gp_Pnt2d p1 = pc1->Value(u1), p2 = pc2->Value(u2); |
1289 | if (p1.Distance(p2)<=gap && |
1290 | Abs(cfirst1-u1) > ::Precision::PConfusion() && |
1291 | Abs(clast2 -u2) > ::Precision::PConfusion() && |
1292 | (((u1>first1) && (u1<last1)) || ((u2>first2) && (u2<last2)) || |
1293 | (cpnt1.Distance(p1)<=gap) || (cpnt2.Distance(p2)<=gap))) |
1294 | { |
1295 | ipar1 = u1; ipar2 = u2; |
1296 | done1 = done2 = Standard_True; |
1297 | } |
1298 | } |
1299 | |
1300 | if (done1) |
1301 | { |
1302 | |
1303 | if (ipar1<first1 || ipar1>last1 || ipar2<first2 || ipar2>last2) |
1304 | { |
1305 | |
1306 | // Check whether new points lie inside the surface bounds |
1307 | Standard_Real umin, umax, vmin, vmax; |
1308 | myAnalyzer->Surface()->Surface()->Bounds(umin,umax,vmin,vmax); |
1309 | if (::Precision::IsInfinite(umin) || ::Precision::IsInfinite(umax) || |
1310 | ::Precision::IsInfinite(vmin) || ::Precision::IsInfinite(vmax)) |
1311 | { |
1312 | Standard_Real fumin, fumax, fvmin, fvmax; |
1313 | BRepTools::UVBounds(face,fumin,fumax,fvmin,fvmax); |
1314 | if (::Precision::IsInfinite(umin)) umin = fumin-preci; |
1315 | if (::Precision::IsInfinite(umax)) umax = fumax+preci; |
1316 | if (::Precision::IsInfinite(vmin)) vmin = fvmin-preci; |
1317 | if (::Precision::IsInfinite(vmax)) vmax = fvmax+preci; |
1318 | } |
1319 | |
1320 | gp_Pnt2d ipnt, P1, P2; |
1321 | Standard_Real u, v; |
1322 | Standard_Boolean out; |
1323 | // iterate on curves |
1324 | for (Standard_Integer j=1; j<=2; j++) |
1325 | { |
1326 | |
1327 | if (j==1) |
1328 | { |
1329 | if (ipar1>=first1 && ipar1<=last1) continue; |
1330 | ipnt = pc1->Value(ipar1); |
1331 | } |
1332 | else |
1333 | { |
1334 | if (ipar2>=first2 && ipar2<=last2) continue; |
1335 | ipnt = pc2->Value(ipar2); |
1336 | } |
1337 | |
1338 | // iterate on bounding lines |
1339 | for (Standard_Integer k=1; k<=2; k++) |
1340 | { |
1341 | |
1342 | u = ipnt.X(); v = ipnt.Y(); |
1343 | |
1344 | out = Standard_True; |
1345 | if (k==1) |
1346 | { |
1347 | if (u<umin) |
1348 | { |
1349 | P1 = gp_Pnt2d(umin,vmin); P2 = gp_Pnt2d(umin,vmax); |
1350 | } |
1351 | else if (u>umax) |
1352 | { |
1353 | P1 = gp_Pnt2d(umax,vmin); P2 = gp_Pnt2d(umax,vmax); |
1354 | } |
1355 | else out = Standard_False; |
1356 | } |
1357 | else |
1358 | { |
1359 | if (v<vmin) |
1360 | { |
1361 | P1 = gp_Pnt2d(umin,vmin); P2 = gp_Pnt2d(umax,vmin); |
1362 | } |
1363 | else if (v>vmax) |
1364 | { |
1365 | P1 = gp_Pnt2d(umin,vmax); P2 = gp_Pnt2d(umax,vmax); |
1366 | } |
1367 | else out = Standard_False; |
1368 | } |
1369 | |
1370 | if (out) |
1371 | { |
1372 | // Intersect pcurve with bounding line |
1373 | Handle(Geom2d_Line) lin = new Geom2d_Line(P1,gp_Dir2d(gp_Vec2d(P1,P2))); |
1374 | Geom2dAdaptor_Curve ACL(lin); |
1375 | IntRes2d_Domain dlin(P1,0.,tolint,P2,P1.Distance(P2),tolint); |
1376 | |
1377 | Handle(Geom2d_Curve) pc; |
1378 | Standard_Real fpar, lpar; |
1379 | if (j==1) |
1380 | { |
1381 | if (cfirst1<ipar1) |
1382 | { |
1383 | fpar = cfirst1, lpar = ipar1; |
1384 | } |
1385 | else |
1386 | { |
1387 | fpar = ipar1, lpar = cfirst1; |
1388 | } |
1389 | pc = pc1; |
1390 | } |
1391 | else |
1392 | { |
1393 | if (clast2<ipar2) |
1394 | { |
1395 | fpar = clast2, lpar = ipar2; |
1396 | } |
1397 | else |
1398 | { |
1399 | fpar = ipar2, lpar = clast2; |
1400 | } |
1401 | pc = pc2; |
1402 | } |
1403 | Geom2dAdaptor_Curve ACC(pc); |
1404 | IntRes2d_Domain domc(pc->Value(fpar),fpar,tolint, |
1405 | pc->Value(lpar),lpar,tolint); |
1406 | |
1407 | // Intersect line with the pcurve |
1408 | Inter.Perform( ACL, dlin, ACC, domc, tolint, tolint ); |
1409 | if (Inter.IsDone()) |
1410 | { |
1411 | if (Inter.NbPoints() || Inter.NbSegments()) |
1412 | { |
1413 | Standard_Integer i, index = 1; |
1414 | Standard_Real uu, dist, mindist=-1.; |
1415 | // iterate on intersection points |
1416 | for ( i=1; i<=Inter.NbPoints(); i++ ) |
1417 | { |
1418 | // Adjust parameters on periodic curve |
1419 | uu = AdjustOnPeriodic2d(pc,(j==1? reversed1 : !reversed2), |
1420 | fpar,lpar,Inter.Point(i).ParamOnSecond()); |
1421 | dist = Abs((j==1? cfirst1 : clast2)-uu); |
1422 | if (mindist>dist || mindist<0.) |
1423 | { |
1424 | index = i; mindist = dist; |
1425 | } |
1426 | } |
1427 | // iterate on intersection segments |
1428 | Standard_Integer flag = 0; |
1429 | IntRes2d_IntersectionPoint IP; |
1430 | IntRes2d_IntersectionSegment IS; |
1431 | for ( i=1; i<=Inter.NbSegments(); i++ ) |
1432 | { |
1433 | IS = Inter.Segment(i); |
1434 | for (Standard_Integer jj=1; jj<=2; jj++) |
1435 | { |
1436 | if ((jj==1 && IS.HasFirstPoint()) || |
1437 | (jj==2 && IS.HasLastPoint())) |
1438 | { |
1439 | if (jj==1) IP = IS.FirstPoint(); |
1440 | else IP = IS.LastPoint(); |
1441 | // Adjust parameters on periodic curve |
1442 | uu = AdjustOnPeriodic2d(pc,(jj==1? reversed1 : !reversed2), |
1443 | fpar,lpar,IP.ParamOnSecond()); |
1444 | dist = Abs((jj==1? cfirst1 : clast2)-uu); |
1445 | if (mindist>dist || mindist<0.) |
1446 | { |
1447 | flag = jj; index = i; mindist = dist; |
1448 | } |
1449 | } |
1450 | } |
1451 | } |
1452 | if (flag==0) IP = Inter.Point(index); |
1453 | else |
1454 | { |
1455 | IS = Inter.Segment(index); |
1456 | if (flag==1) IP = IS.FirstPoint(); |
1457 | else IP = IS.LastPoint(); |
1458 | } |
1459 | // Ajust parameters on periodic curve |
1460 | uu = AdjustOnPeriodic2d(pc,(j==1? reversed1 : !reversed2), |
1461 | fpar,lpar,IP.ParamOnSecond()); |
1462 | if (j==1 && Abs(cfirst1-uu) > ::Precision::PConfusion()) |
1463 | { |
1464 | ipar1 = uu; ipnt = IP.Value(); |
1465 | } |
1466 | if (j==2 && Abs(clast2-uu) > ::Precision::PConfusion()) |
1467 | { |
1468 | ipar2 = uu; ipnt = IP.Value(); |
1469 | } |
1470 | } |
1471 | } |
1472 | } |
1473 | } |
1474 | |
1475 | // Adjust if intersection lies inside old bounds |
1476 | if (j==1) |
1477 | { |
1478 | if (reversed1) |
1479 | { |
1480 | if (ipar1>first1) ipar1 = first1; |
1481 | } |
1482 | else |
1483 | { |
1484 | if (ipar1<last1) ipar1 = last1; |
1485 | } |
1486 | } |
1487 | else |
1488 | { |
1489 | if (reversed2) |
1490 | { |
1491 | if (ipar2<last2) ipar2 = last2; |
1492 | } |
1493 | else |
1494 | { |
1495 | if (ipar2>first2) ipar2 = first2; |
1496 | } |
1497 | } |
1498 | } |
1499 | } |
1500 | } |
1501 | try |
1502 | { |
1503 | OCC_CATCH_SIGNALS |
1504 | if (done1) |
1505 | { |
1506 | if (ipar1==clast1) done1 = Standard_False; |
1507 | else |
1508 | { |
1509 | // Set up new bounds for pcurve |
1510 | if (reversed1) first1 = ipar1; else last1 = ipar1; |
1511 | // Set new trim for old pcurve |
1512 | if (trimmed1) pc1 = new Geom2d_TrimmedCurve(pc1,first1,last1); |
1513 | } |
1514 | } |
1515 | if (done2) |
1516 | { |
1517 | if (ipar2==cfirst2) done2 = Standard_False; |
1518 | else |
1519 | { |
1520 | // Set up new bounds for pcurve |
1521 | if (reversed2) last2 = ipar2; else first2 = ipar2; |
1522 | // Set new trim for old pcurve |
1523 | if (trimmed2) pc2 = new Geom2d_TrimmedCurve(pc2,first2,last2); |
1524 | } |
1525 | } |
1526 | } |
1527 | catch (Standard_Failure) |
1528 | { |
1529 | |
1530 | #ifdef DEB |
1531 | cout << "Warning: ShapeFix_Wire_1::FixGap2d: Exception in TrimmedCurve2d :"<<endl; |
1532 | Standard_Failure::Caught()->Print(cout); cout << endl; |
1533 | #endif |
1534 | } |
1535 | } |
1536 | } |
1537 | |
1538 | if (done1 || done2) |
1539 | { |
1540 | |
1541 | BRep_Builder B; |
1542 | ShapeBuild_Edge SBE; |
1543 | ShapeFix_ShapeTolerance SFST; |
1544 | |
1545 | // Update vertices |
1546 | TopoDS_Vertex V1 = SAE.LastVertex(E1), V2 = SAE.FirstVertex(E2); |
1547 | TopoDS_Vertex nullV, newV1; |
1548 | //smh#8 |
1549 | TopoDS_Shape emptyCopiedV2 = V2.EmptyCopied(); |
1550 | TopoDS_Vertex newV2 = TopoDS::Vertex(emptyCopiedV2); |
1551 | SFST.SetTolerance(newV2,::Precision::Confusion()); |
1552 | Context()->Replace(V2,newV2); |
1553 | if (V1.IsSame(V2)) |
1554 | //smh#8 |
1555 | { |
1556 | TopoDS_Shape tmpVertexRev = newV2.Oriented(TopAbs_REVERSED); |
1557 | newV1 = TopoDS::Vertex(tmpVertexRev); |
1558 | } |
1559 | else |
1560 | { |
1561 | //smh#8 |
1562 | TopoDS_Shape emptyCopiedV1 = V1.EmptyCopied(); |
1563 | newV1 = TopoDS::Vertex(emptyCopiedV1); |
1564 | SFST.SetTolerance(newV1,::Precision::Confusion()); |
1565 | Context()->Replace(V1,newV1); |
1566 | } |
1567 | |
1568 | if (done1) |
1569 | { |
1570 | // Update first edge |
1571 | TopoDS_Edge newE1 = SBE.CopyReplaceVertices(E1,nullV,newV1); |
1572 | //smh#8 |
1573 | TopoDS_Shape tmpE1 = newE1.Oriented(TopAbs_FORWARD); |
1574 | B.UpdateEdge(TopoDS::Edge(tmpE1),pc1,face,0.); |
1575 | B.Range(TopoDS::Edge(tmpE1),face,first1,last1); |
1576 | SFST.SetTolerance(newE1,::Precision::Confusion(),TopAbs_EDGE); |
1577 | B.SameRange(newE1,Standard_False); |
1578 | // B.SameParameter(newE1,Standard_False); |
1579 | |
1580 | //To keep NM vertices belonging initial edges |
1581 | TopoDS_Iterator aItv(E1,Standard_False); |
1582 | for( ; aItv.More(); aItv.Next()) { |
1583 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
1584 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
1585 | TopoDS_Vertex aOldV = TopoDS::Vertex(aItv.Value()); |
1586 | TopoDS_Vertex anewV = ShapeAnalysis_TransferParametersProj::CopyNMVertex(aOldV,newE1,E1); |
1587 | B.Add(newE1,anewV); |
1588 | Context()->Replace(aOldV,anewV); |
1589 | } |
1590 | } |
1591 | |
1592 | Context()->Replace(E1,newE1); |
1593 | sbwd->Set(newE1,n1); |
1594 | } |
1595 | |
1596 | if (done2) |
1597 | { |
1598 | // Update second edge |
1599 | TopoDS_Edge newE2 = SBE.CopyReplaceVertices(E2,newV2,nullV); |
1600 | //smh#8 |
1601 | TopoDS_Shape tmpE2 = newE2.Oriented(TopAbs_FORWARD); |
1602 | B.UpdateEdge(TopoDS::Edge(tmpE2),pc2,face,0.); |
1603 | B.Range(TopoDS::Edge(tmpE2),face,first2,last2); |
1604 | SFST.SetTolerance(newE2,::Precision::Confusion(),TopAbs_EDGE); |
1605 | B.SameRange(newE2,Standard_False); |
1606 | // B.SameParameter(newE2,Standard_False); |
1607 | //To keep NM vertices belonging initial edges |
1608 | TopoDS_Iterator aItv(E2,Standard_False); |
1609 | for( ; aItv.More(); aItv.Next()) { |
1610 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
1611 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
1612 | TopoDS_Vertex aOldV = TopoDS::Vertex(aItv.Value()); |
1613 | TopoDS_Vertex anewV = ShapeAnalysis_TransferParametersProj::CopyNMVertex(aOldV,newE2,E2); |
1614 | B.Add(newE2,anewV); |
1615 | Context()->Replace(aOldV,anewV); |
1616 | } |
1617 | } |
1618 | Context()->Replace(E2,newE2); |
1619 | sbwd->Set(newE2,n2); |
1620 | } |
1621 | |
1622 | myLastFixStatus |= ShapeExtend::EncodeStatus( ShapeExtend_DONE1 ); |
1623 | } |
1624 | else |
1625 | if (convert) |
1626 | myLastFixStatus |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL2 ); |
1627 | |
1628 | return (done1 || done2); |
1629 | } |