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 | //:o8 abv 19.02.99: CTS18541.stp #18559: coeff 1.0001 added in CheckVertexTol |
19 | //:p1 abv 22.02.99: protection against edges with no vertices (infinite) |
20 | //szv#4 S4163 |
21 | //:s1 abv 22.04.99: PRO7226 #489490: protect against Null 3d curve |
22 | //:s4 abv 26.04.99: sim6049.igs 21677: copy of curve is necessary to get True SP |
23 | // abv 06.05.99: S4137: adding methods GetTangent2d() |
24 | #include <ShapeAnalysis_Edge.ixx> |
25 | |
26 | #include <Standard_ErrorHandler.hxx> |
27 | #include <Standard_Failure.hxx> |
28 | |
29 | #include <Precision.hxx> |
30 | |
31 | #include <GCPnts_AbscissaPoint.hxx> |
32 | #include <Adaptor3d_Curve.hxx> |
33 | #include <Adaptor3d_CurveOnSurface.hxx> |
34 | #include <Geom2dAdaptor_HCurve.hxx> |
35 | #include <GeomAdaptor_Curve.hxx> |
36 | #include <GeomAdaptor_HSurface.hxx> |
37 | #include <BRepAdaptor_Curve.hxx> |
38 | #include <BRepExtrema_DistShapeShape.hxx> |
39 | |
40 | #include <BRep_Tool.hxx> |
41 | #include <BRep_TEdge.hxx> |
42 | #include <BRep_GCurve.hxx> |
43 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
44 | #include <BRep_Builder.hxx> |
45 | |
46 | #include <Extrema_LocateExtPC.hxx> |
47 | |
48 | #include <ShapeExtend.hxx> |
49 | #include <TopExp.hxx> |
50 | #include <TopoDS_Vertex.hxx> |
51 | #include <Geom_Plane.hxx> |
52 | |
53 | |
54 | //======================================================================= |
55 | //function : ShapeAnalysis_Edge |
56 | //purpose : |
57 | //======================================================================= |
58 | |
59 | ShapeAnalysis_Edge::ShapeAnalysis_Edge() |
60 | { |
61 | myStatus = 0;//ShapeExtend::EncodeStatus (ShapeExtend_OK); |
62 | } |
63 | |
64 | |
65 | //======================================================================= |
66 | //function : BoundUV |
67 | //purpose : |
68 | //======================================================================= |
69 | |
70 | Standard_Boolean ShapeAnalysis_Edge::BoundUV (const TopoDS_Edge& edge, |
71 | const TopoDS_Face& face, |
72 | gp_Pnt2d& first, gp_Pnt2d& last) const |
73 | { |
74 | TopLoc_Location L; |
75 | const Handle(Geom_Surface) S = BRep_Tool::Surface(face, L); |
76 | return BoundUV (edge, S, L, first, last); |
77 | } |
78 | |
79 | |
80 | //======================================================================= |
81 | //function : BoundUV |
82 | //purpose : |
83 | //======================================================================= |
84 | |
85 | Standard_Boolean ShapeAnalysis_Edge::BoundUV (const TopoDS_Edge& edge, |
86 | const Handle(Geom_Surface)& surface, |
87 | const TopLoc_Location& location, |
88 | gp_Pnt2d& first, gp_Pnt2d& last) const |
89 | { |
90 | Handle(Geom2d_Curve) c2d; |
91 | Standard_Real uf,ul; |
92 | if (!PCurve (edge, surface, location, c2d, uf, ul)) return Standard_False; |
93 | first = c2d->Value (uf); |
94 | last = c2d->Value (ul); |
95 | return Standard_True; |
96 | } |
97 | |
98 | |
99 | //======================================================================= |
100 | //function : HasCurve3d |
101 | //purpose : |
102 | //======================================================================= |
103 | |
104 | Standard_Boolean ShapeAnalysis_Edge::HasCurve3d (const TopoDS_Edge& edge) const |
105 | { |
106 | Standard_Real cf, cl; |
107 | Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge, cf, cl); |
108 | return !c3d.IsNull(); |
109 | } |
110 | |
111 | |
112 | //======================================================================= |
113 | //function : Curve3d |
114 | //purpose : |
115 | //======================================================================= |
116 | |
117 | Standard_Boolean ShapeAnalysis_Edge::Curve3d (const TopoDS_Edge& edge, |
118 | Handle(Geom_Curve)& C3d, |
119 | Standard_Real& cf, Standard_Real& cl, |
120 | const Standard_Boolean orient) const |
121 | { |
122 | TopLoc_Location L; |
123 | C3d = BRep_Tool::Curve (edge, L, cf, cl); |
124 | if( !C3d.IsNull() && !L.IsIdentity() ) { |
125 | C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L.Transformation())); |
126 | cf = C3d->TransformedParameter(cf, L.Transformation()); |
127 | cl = C3d->TransformedParameter(cl, L.Transformation()); |
128 | } |
129 | if (orient) { |
130 | if (edge.Orientation() == TopAbs_REVERSED) |
131 | {Standard_Real tmp = cf; cf = cl; cl = tmp;} |
132 | } |
133 | return !C3d.IsNull(); |
134 | } |
135 | |
136 | |
137 | //======================================================================= |
138 | //function : IsClosed3d |
139 | //purpose : |
140 | //======================================================================= |
141 | |
142 | Standard_Boolean ShapeAnalysis_Edge::IsClosed3d (const TopoDS_Edge& edge) const |
143 | { |
144 | Standard_Real cf,cl; |
145 | Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,cf,cl); |
146 | if (c3d.IsNull()) return Standard_False; |
147 | if (!c3d->IsClosed()) return Standard_False; |
148 | return FirstVertex (edge).IsSame (LastVertex (edge)); |
149 | } |
150 | |
151 | |
152 | //======================================================================= |
153 | //function : HasPCurve |
154 | //purpose : |
155 | //======================================================================= |
156 | |
157 | Standard_Boolean ShapeAnalysis_Edge::HasPCurve (const TopoDS_Edge& edge, |
158 | const TopoDS_Face& face) const |
159 | { |
160 | TopLoc_Location L; |
161 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L); |
162 | return HasPCurve (edge, S, L); |
163 | } |
164 | |
165 | |
166 | //======================================================================= |
167 | //function : HasPCurve |
168 | //purpose : |
169 | //======================================================================= |
170 | |
171 | Standard_Boolean ShapeAnalysis_Edge::HasPCurve (const TopoDS_Edge& edge, |
172 | const Handle(Geom_Surface)& surface, |
173 | const TopLoc_Location& location) const |
174 | { |
175 | //try { //szv#4:S4163:12Mar99 waste try |
176 | Standard_Real cf, cl; |
177 | Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface (edge, surface, location, cf, cl); |
178 | return !c2d.IsNull(); |
179 | /* } |
180 | catch (Standard_Failure) { |
181 | } |
182 | return Standard_False; */ |
183 | } |
184 | |
185 | |
186 | //======================================================================= |
187 | //function : PCurve |
188 | //purpose : |
189 | //======================================================================= |
190 | |
191 | Standard_Boolean ShapeAnalysis_Edge::PCurve (const TopoDS_Edge& edge, |
192 | const TopoDS_Face& face, |
193 | Handle(Geom2d_Curve)& C2d, |
194 | Standard_Real& cf, Standard_Real& cl, |
195 | const Standard_Boolean orient) const |
196 | { |
197 | //:abv 20.05.02: take into account face orientation |
198 | // COMMENTED BACK - NEEDS MORE CHANGES IN ALL SHAPEHEALING |
199 | // C2d = BRep_Tool::CurveOnSurface (edge, face, cf, cl); |
200 | // if (orient && edge.Orientation() == TopAbs_REVERSED) { |
201 | // Standard_Real tmp = cf; cf = cl; cl = tmp; |
202 | // } |
203 | // return !C2d.IsNull(); |
204 | TopLoc_Location L; |
205 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L); |
206 | return PCurve (edge, S, L, C2d, cf, cl, orient); |
207 | } |
208 | |
209 | |
210 | //======================================================================= |
211 | //function : PCurve |
212 | //purpose : |
213 | //======================================================================= |
214 | |
215 | Standard_Boolean ShapeAnalysis_Edge::PCurve (const TopoDS_Edge& edge, |
216 | const Handle(Geom_Surface)& surface, |
217 | const TopLoc_Location& location, |
218 | Handle(Geom2d_Curve)& C2d, |
219 | Standard_Real& cf, Standard_Real& cl, |
220 | const Standard_Boolean orient) const |
221 | { |
222 | C2d = BRep_Tool::CurveOnSurface (edge, surface, location, cf, cl); |
223 | if ( orient && edge.Orientation() == TopAbs_REVERSED ) { |
224 | Standard_Real tmp = cf; cf = cl; cl = tmp; |
225 | } |
226 | return !C2d.IsNull(); |
227 | } |
228 | |
229 | |
230 | //======================================================================= |
231 | //function : IsSeam |
232 | //purpose : |
233 | //======================================================================= |
234 | |
235 | Standard_Boolean ShapeAnalysis_Edge::IsSeam (const TopoDS_Edge& edge, |
236 | const TopoDS_Face& face) const |
237 | { |
238 | return BRep_Tool::IsClosed (edge, face); |
239 | } |
240 | |
241 | |
242 | //======================================================================= |
243 | //function : IsSeam |
244 | //purpose : |
245 | //======================================================================= |
246 | |
247 | Standard_Boolean ShapeAnalysis_Edge::IsSeam (const TopoDS_Edge& edge, |
248 | const Handle(Geom_Surface)& surface, |
249 | const TopLoc_Location& location) const |
250 | { |
251 | return BRep_Tool::IsClosed (edge, surface, location); |
252 | } |
253 | |
254 | |
255 | //======================================================================= |
256 | //function : FirstVertex |
257 | //purpose : |
258 | //======================================================================= |
259 | |
260 | TopoDS_Vertex ShapeAnalysis_Edge::FirstVertex (const TopoDS_Edge& edge) const |
261 | { |
262 | TopoDS_Vertex V; |
263 | if (edge.Orientation() == TopAbs_REVERSED) { |
264 | V = TopExp::LastVertex(edge); |
265 | V.Reverse(); |
266 | } |
267 | else { |
268 | V = TopExp::FirstVertex (edge); |
269 | } |
270 | return V; |
271 | } |
272 | |
273 | |
274 | //======================================================================= |
275 | //function : LastVertex |
276 | //purpose : |
277 | //======================================================================= |
278 | |
279 | TopoDS_Vertex ShapeAnalysis_Edge::LastVertex (const TopoDS_Edge& edge) const |
280 | { |
281 | TopoDS_Vertex V; |
282 | if (edge.Orientation() == TopAbs_REVERSED) { |
283 | V = TopExp::FirstVertex(edge); |
284 | V.Reverse(); |
285 | } |
286 | else { |
287 | V = TopExp::LastVertex (edge); |
288 | } |
289 | return V; |
290 | } |
291 | |
292 | |
293 | //======================================================================= |
294 | //function : Status |
295 | //purpose : |
296 | //======================================================================= |
297 | |
298 | Standard_Boolean ShapeAnalysis_Edge::Status (const ShapeExtend_Status Status) const |
299 | { |
300 | return ShapeExtend::DecodeStatus (myStatus, Status); |
301 | } |
302 | |
303 | |
304 | //======================================================================= |
305 | //function : GetEndTangent2d |
306 | //purpose : |
307 | //======================================================================= |
308 | |
309 | Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d (const TopoDS_Edge &edge, |
310 | const TopoDS_Face &face, |
311 | const Standard_Boolean atend1, /* skl : change "atend" to "atend1" */ |
312 | gp_Pnt2d &pnt, |
313 | gp_Vec2d &v, |
314 | const Standard_Real dparam) const |
315 | { |
316 | TopLoc_Location L; |
317 | const Handle(Geom_Surface) S = BRep_Tool::Surface ( face, L ); |
318 | return GetEndTangent2d ( edge, S, L, atend1, pnt, v, dparam ); |
319 | } |
320 | |
321 | |
322 | //======================================================================= |
323 | //function : GetEndTangent2d |
324 | //purpose : |
325 | //======================================================================= |
326 | |
327 | Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d (const TopoDS_Edge &edge, |
328 | const Handle(Geom_Surface)& S, |
329 | const TopLoc_Location& L, |
330 | const Standard_Boolean atend2, /* skl : change "atend" to "atend2" */ |
331 | gp_Pnt2d &pnt, |
332 | gp_Vec2d &v, |
333 | const Standard_Real dparam) const |
334 | { |
335 | Standard_Real cf, cl; |
336 | Handle(Geom2d_Curve) c2d; |
337 | if ( ! PCurve ( edge, S, L, c2d, cf, cl ) ) { |
338 | v = gp_Vec2d(0,0); |
339 | return Standard_False; |
340 | } |
341 | Standard_Real dpnew = dparam; |
342 | |
343 | if(dpnew>Precision::Confusion()) { |
344 | gp_Pnt2d ptmp; |
345 | Standard_Real par1,par2,delta=(cl-cf)*dpnew; |
346 | if(Abs(delta)<Precision::PConfusion()) { |
347 | dpnew=0.0; |
348 | } |
349 | else { |
350 | if(atend2) { |
351 | par1 = cl; |
352 | par2 = cl - delta; |
353 | c2d->D0(par1,pnt); |
354 | c2d->D0(par2,ptmp); |
355 | v = pnt.XY() - ptmp.XY(); |
356 | } |
357 | else { |
358 | par1 = cf; |
359 | par2 = cf + delta; |
360 | c2d->D0(par1,pnt); |
361 | c2d->D0(par2,ptmp); |
362 | v = ptmp.XY() - pnt.XY(); |
363 | } |
364 | if( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) { |
365 | dpnew=0.0; |
366 | } |
367 | } |
368 | } |
369 | |
370 | if(dpnew<=Precision::Confusion()) { |
371 | // get non-null tangency searching until 3rd derivative, or as straight btw ends |
372 | Standard_Real par = ( atend2 ? cl : cf ); |
373 | c2d->D1 ( par, pnt, v ); |
374 | if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) { |
375 | gp_Vec2d d1; |
376 | c2d->D2 ( par, pnt, d1, v ); |
377 | if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) { |
378 | gp_Vec2d d2; |
379 | c2d->D3 ( par, pnt, d1, d2, v ); |
380 | if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) { |
381 | gp_Pnt2d p2; |
382 | c2d->D0 ( ( atend2 ? cf : cl ), p2 ); |
383 | v = p2.XY() - pnt.XY(); |
384 | if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) |
385 | return Standard_False; |
386 | } |
387 | } |
388 | } |
389 | if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse(); |
390 | } |
391 | |
392 | //if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse(); |
393 | return Standard_True; |
394 | } |
395 | |
396 | |
397 | //======================================================================= |
398 | //function : CheckCurve3dWithPCurve |
399 | //purpose : |
400 | //======================================================================= |
401 | |
402 | Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve (const TopoDS_Edge& edge, |
403 | const TopoDS_Face& face) |
404 | { |
405 | TopLoc_Location L; |
406 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L); |
407 | return CheckCurve3dWithPCurve (edge, S, L); |
408 | } |
409 | |
410 | |
411 | //======================================================================= |
412 | //function : CheckCurve3dWithPCurve |
413 | //purpose : |
414 | //======================================================================= |
415 | |
416 | Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve (const TopoDS_Edge& edge, |
417 | const Handle(Geom_Surface)& surface, |
418 | const TopLoc_Location& location) |
419 | { |
420 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); |
421 | |
422 | if(surface->IsKind(STANDARD_TYPE(Geom_Plane))) |
423 | return Standard_False; |
424 | |
425 | Handle (Geom2d_Curve) c2d; |
426 | Standard_Real f2d, l2d; //szv#4:S4163:12Mar99 moved down f3d, l3d |
427 | if (!PCurve (edge, surface, location, c2d, f2d ,l2d, Standard_False)) { |
428 | myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); |
429 | return Standard_False; |
430 | } |
431 | |
432 | Handle (Geom_Curve) c3d; //szv#4:S4163:12Mar99 moved |
433 | Standard_Real f3d, l3d; //szv#4:S4163:12Mar99 moved |
434 | if (!Curve3d (edge, c3d, f3d, l3d, Standard_False)) { |
435 | myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2); |
436 | return Standard_False; |
437 | } |
438 | |
439 | Standard_Real preci1 = BRep_Tool::Tolerance (FirstVertex (edge)), |
440 | preci2 = BRep_Tool::Tolerance (LastVertex (edge)); |
441 | |
442 | gp_Pnt2d p2d1 = c2d->Value (f2d), |
443 | p2d2 = c2d->Value (l2d); |
444 | |
445 | //#39 rln 17.11.98 S4054, annie_surf.igs entity 39 |
446 | return CheckPoints (c3d->Value (f3d)/*.Transformed (location.Transformation())*/, |
447 | c3d->Value (l3d)/*.Transformed (location.Transformation())*/, |
448 | surface->Value (p2d1.X(), p2d1.Y()).Transformed (location.Transformation()), |
449 | surface->Value (p2d2.X(), p2d2.Y()).Transformed (location.Transformation()), |
450 | preci1, preci2); |
451 | } |
452 | |
453 | |
454 | //======================================================================= |
455 | //function : CheckPoints |
456 | //purpose : |
457 | //======================================================================= |
458 | |
459 | Standard_Boolean ShapeAnalysis_Edge::CheckPoints (const gp_Pnt& P1A, |
460 | const gp_Pnt& P1B, |
461 | const gp_Pnt& P2A, |
462 | const gp_Pnt& P2B, |
463 | const Standard_Real preci1, |
464 | const Standard_Real preci2) |
465 | { |
466 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); |
467 | if (P1A.SquareDistance (P2A) <= preci1 * preci1 && |
468 | P1B.SquareDistance (P2B) <= preci2 * preci2) |
469 | return Standard_False; |
470 | else if (P1A.Distance (P2B) + (P1B.Distance (P2A)) < |
471 | P1A.Distance (P2A) + (P1B.Distance (P2B))) |
472 | myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1); |
473 | return Standard_True; |
474 | } |
475 | |
476 | |
477 | //======================================================================= |
478 | //function : CheckVerticesWithCurve3d |
479 | //purpose : |
480 | //======================================================================= |
481 | |
482 | Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithCurve3d (const TopoDS_Edge& edge, |
483 | const Standard_Real preci, |
484 | const Standard_Integer vtx) |
485 | { |
486 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); |
487 | |
488 | TopoDS_Vertex V1 = FirstVertex (edge); |
489 | TopoDS_Vertex V2 = LastVertex (edge); |
490 | gp_Pnt p1v = BRep_Tool::Pnt (V1); |
491 | gp_Pnt p2v = BRep_Tool::Pnt (V2); |
492 | |
493 | Standard_Real cf,cl; |
494 | Handle(Geom_Curve) c3d; |
495 | if ( ! Curve3d (edge,c3d,cf,cl) ) { |
496 | myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); |
497 | return Standard_False; |
498 | } |
499 | |
500 | // on va faire les checks ... |
501 | if (vtx != 2) { |
502 | // 1er VTX |
503 | gp_Pnt p13d = c3d->Value(cf); |
504 | //szv#4:S4163:12Mar99 optimized |
505 | if (p1v.Distance(p13d) > (preci < 0 ? BRep_Tool::Tolerance (V1) : preci)) |
506 | myStatus |= ShapeExtend_DONE1; |
507 | } |
508 | |
509 | if (vtx != 1) { |
510 | // 2me VTX |
511 | gp_Pnt p23d = c3d->Value(cl); |
512 | //szv#4:S4163:12Mar99 optimized |
513 | if (p2v.Distance(p23d) > (preci < 0 ? BRep_Tool::Tolerance (V2) : preci)) |
514 | myStatus |= ShapeExtend_DONE2; |
515 | } |
516 | |
517 | return Status ( ShapeExtend_DONE ); |
518 | } |
519 | |
520 | |
521 | //======================================================================= |
522 | //function : CheckVerticesWithPCurve |
523 | //purpose : |
524 | //======================================================================= |
525 | |
526 | Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve (const TopoDS_Edge& edge, |
527 | const TopoDS_Face& face, |
528 | const Standard_Real preci, |
529 | const Standard_Integer vtx) |
530 | { |
531 | TopLoc_Location L; |
532 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L); |
533 | return CheckVerticesWithPCurve (edge, S, L, preci, vtx); //szv#4:S4163:12Mar99 `vtx,preci` wrong parameters order |
534 | } |
535 | |
536 | |
537 | //======================================================================= |
538 | //function : CheckVerticesWithPCurve |
539 | //purpose : |
540 | //======================================================================= |
541 | |
542 | Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve (const TopoDS_Edge& edge, |
543 | const Handle(Geom_Surface)& surf, |
544 | const TopLoc_Location& loc, |
545 | const Standard_Real preci, |
546 | const Standard_Integer vtx) |
547 | { |
548 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); |
549 | |
550 | TopoDS_Vertex V1 = FirstVertex (edge); |
551 | TopoDS_Vertex V2 = LastVertex (edge); |
552 | gp_Pnt p1v = BRep_Tool::Pnt (V1); |
553 | gp_Pnt p2v = BRep_Tool::Pnt (V2); |
554 | |
555 | Standard_Real cf, cl; |
556 | Handle(Geom2d_Curve) c2d; |
557 | if ( ! PCurve ( edge, surf, loc, c2d, cf, cl ) ) { |
558 | myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); |
559 | return Standard_False; |
560 | } |
561 | |
562 | // on va faire les checks ... |
563 | if (vtx != 2) { // 1er VTX |
564 | gp_Pnt2d p1uv = c2d->Value (cf); |
565 | gp_Pnt p12d = surf->Value (p1uv.X(), p1uv.Y()); |
566 | // szv#4:S4163:12Mar99 optimized |
567 | if ( p1v.Distance(p12d) > (preci < 0 ? BRep_Tool::Tolerance (V1) : preci) ) |
568 | myStatus |= ShapeExtend_DONE1; |
569 | } |
570 | |
571 | if (vtx != 1) { // 2me VTX |
572 | gp_Pnt2d p2uv = c2d->Value (cl); |
573 | gp_Pnt p22d = surf->Value (p2uv.X(), p2uv.Y()); |
574 | // szv#4:S4163:12Mar99 optimized |
575 | if ( p2v.Distance(p22d) > (preci < 0 ? BRep_Tool::Tolerance (V2) : preci) ) |
576 | myStatus |= ShapeExtend_DONE2; |
577 | } |
578 | |
579 | return Status ( ShapeExtend_DONE ); |
580 | } |
581 | |
582 | |
583 | //======================================================================= |
584 | //function : CheckVertexTolerance |
585 | //purpose : |
586 | //======================================================================= |
587 | |
588 | static Standard_Integer CheckVertexTolerance(const TopoDS_Edge& edge, |
589 | const TopoDS_Face& face, |
590 | const Standard_Boolean checkAll, |
591 | Standard_Real& toler1, |
592 | Standard_Real& toler2) |
593 | { |
594 | Standard_Integer Status = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
595 | |
596 | ShapeAnalysis_Edge sae; |
597 | TopoDS_Vertex V1 = sae.FirstVertex (edge); |
598 | TopoDS_Vertex V2 = sae.LastVertex (edge); |
599 | if ( V1.IsNull() || V2.IsNull() ) { //:p1 abv 22 Feb 99: r76sy.stp |
600 | Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); |
601 | return Status; |
602 | } |
603 | |
604 | Standard_Real old1 = BRep_Tool::Tolerance (V1); |
605 | Standard_Real old2 = BRep_Tool::Tolerance (V2); |
606 | gp_Pnt pnt1 = BRep_Tool::Pnt (V1); |
607 | gp_Pnt pnt2 = BRep_Tool::Pnt (V2); |
608 | |
609 | Standard_Real a, b; |
610 | Handle(Geom_Curve) c3d; |
611 | if ( ! sae.Curve3d(edge, c3d, a, b, Standard_True)) { |
612 | if ( ! BRep_Tool::Degenerated ( edge ) ) |
613 | Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2); |
614 | toler1 = toler2 = 0.; |
615 | // return Standard_False; |
616 | } |
617 | else { |
618 | toler1 = pnt1.SquareDistance (c3d->Value (a)); |
619 | toler2 = pnt2.SquareDistance (c3d->Value (b)); |
620 | } |
621 | |
622 | if ( checkAll ) { |
623 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape()); |
624 | for (BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); itcr.More(); itcr.Next() ) { |
625 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
626 | if (GC.IsNull() || !GC->IsCurveOnSurface()) continue; |
627 | Handle(Geom2d_Curve) pcurve; |
628 | Handle(Geom_Surface) S = GC->Surface(); |
629 | TopLoc_Location L = edge.Location() * GC->Location(); |
630 | sae.PCurve (edge, S, L, pcurve, a, b, Standard_True); |
631 | gp_Pnt2d p1 = pcurve->Value (a); |
632 | gp_Pnt2d p2 = pcurve->Value (b); |
633 | gp_Pnt P1 = S->Value (p1.X(), p1.Y()).Transformed (L.Transformation()); |
634 | gp_Pnt P2 = S->Value (p2.X(), p2.Y()).Transformed (L.Transformation()); |
635 | toler1 = Max (toler1, pnt1.SquareDistance (P1)); |
636 | toler2 = Max (toler2, pnt2.SquareDistance (P2)); |
637 | } |
638 | } |
639 | //:abv 10.06.02: porting C40 -> dev (CC670-12608.stp) |
640 | // Check with given face is needed for plane surfaces (if no stored pcurves) |
641 | else if ( ! face.IsNull() ) { |
642 | Handle(Geom2d_Curve) pcurve; |
643 | TopLoc_Location L; |
644 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L); |
645 | if ( sae.PCurve(edge, S, L, pcurve, a, b, Standard_True)) { |
646 | gp_Pnt2d p1 = pcurve->Value (a); |
647 | gp_Pnt2d p2 = pcurve->Value (b); |
648 | gp_Pnt P1 = S->Value (p1.X(), p1.Y()).Transformed (L.Transformation()); |
649 | gp_Pnt P2 = S->Value (p2.X(), p2.Y()).Transformed (L.Transformation()); |
650 | toler1 = Max (toler1, pnt1.SquareDistance (P1)); |
651 | toler2 = Max (toler2, pnt2.SquareDistance (P2)); |
652 | } |
653 | else Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3); |
654 | } |
655 | |
656 | //:o8 abv 19 Feb 99: CTS18541.stp #18559: coeff 1.0001 added |
657 | //szv 18 Aug 99: edge tolerance is taken in consideration |
658 | Standard_Real tole = BRep_Tool::Tolerance (edge); |
659 | toler1 = Max (1.0000001 * Sqrt (toler1), tole); |
660 | toler2 = Max (1.0000001 * Sqrt (toler2), tole); |
661 | if ( toler1 > old1) |
662 | Status |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1); |
663 | if ( toler2 > old2) |
664 | Status |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2); |
665 | |
666 | return Status; |
667 | } |
668 | |
669 | |
670 | //======================================================================= |
671 | //function : CheckVertexTolerance |
672 | //purpose : |
673 | //======================================================================= |
674 | |
675 | Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge, |
676 | const TopoDS_Face& face, |
677 | Standard_Real& toler1, |
678 | Standard_Real& toler2) |
679 | { |
680 | myStatus = ::CheckVertexTolerance ( edge, face, Standard_False, toler1, toler2 ); |
681 | return Status ( ShapeExtend_DONE ); |
682 | } |
683 | |
684 | |
685 | //======================================================================= |
686 | //function : CheckVertexTolerance |
687 | //purpose : |
688 | //======================================================================= |
689 | |
690 | Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge, |
691 | Standard_Real& toler1, |
692 | Standard_Real& toler2) |
693 | { |
694 | TopoDS_Face F; |
695 | myStatus = ::CheckVertexTolerance ( edge, F, Standard_True, toler1, toler2 ); |
696 | return Status ( ShapeExtend_DONE ); |
697 | } |
698 | |
699 | |
700 | //======================================================================= |
701 | //static : Validate |
702 | //purpose: For SameParameter: compute it for two curves |
703 | //note: This function is made from Validate() in BRepCheck_Edge.cxx |
704 | //======================================================================= |
705 | |
706 | static Standard_Boolean ComputeDeviation (const Adaptor3d_Curve& CRef, |
707 | const Adaptor3d_Curve& Other, |
708 | const Standard_Boolean SameParameter, |
709 | Standard_Real &dev, |
710 | const Standard_Integer NCONTROL) |
711 | { |
712 | Standard_Boolean OK = Standard_True; |
713 | Standard_Real dev2 = dev*dev; |
714 | |
715 | Standard_Real First = CRef.FirstParameter(), Last = CRef.LastParameter(); |
716 | Standard_Real OFirst = Other.FirstParameter(), OLast = Other.LastParameter(); //szv#4:S4163:12Mar99 moved |
717 | |
718 | Standard_Boolean proj = (!SameParameter || First != OFirst || Last != OLast); //szv#4:S4163:12Mar99 optimized |
719 | |
720 | Standard_Integer NCtrl = ( NCONTROL < 1 )? 1 : NCONTROL; //szv#4:S4163:12Mar99 anti-exception |
721 | |
722 | if (!proj) { |
723 | for (Standard_Integer i = 0; i <= NCtrl; i++) { |
724 | Standard_Real prm = ((NCtrl-i)*First + i*Last)/NCtrl; |
725 | gp_Pnt pref = CRef.Value(prm); |
726 | gp_Pnt pother = Other.Value(prm); |
727 | Standard_Real dist2 = pref.SquareDistance(pother); |
728 | if ( dev2 < dist2 ) dev2 = dist2; |
729 | } |
730 | dev = Sqrt ( dev2 ); |
731 | } |
732 | else { |
733 | gp_Pnt pd = CRef.Value(First); |
734 | gp_Pnt pdo = Other.Value(OFirst); |
735 | Standard_Real dist2 = pd.SquareDistance(pdo); |
736 | if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 ); |
737 | |
738 | pd = CRef.Value(Last); |
739 | pdo = Other.Value(OLast); |
740 | dist2 = pd.SquareDistance(pdo); |
741 | if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 ); |
742 | |
743 | Extrema_LocateExtPC refd, otherd; //szv#4:S4163:12Mar99 warning |
744 | refd.Initialize(CRef,First,Last,Precision::PConfusion()); |
745 | otherd.Initialize(Other,OFirst,OLast,Precision::PConfusion()); |
746 | |
747 | for (Standard_Integer i = 1; i < NCtrl; i++) { //szv#4:S4163:12Mar99 was bug |
748 | Standard_Real rprm = ((NCtrl-i)*First + i*Last)/NCtrl; |
749 | gp_Pnt pref = CRef.Value(rprm); |
750 | Standard_Real oprm = ((NCtrl-i)*OFirst + i*OLast)/NCtrl; |
751 | gp_Pnt pother = Other.Value(oprm); |
752 | |
753 | refd.Perform(pother,rprm); |
754 | if ( ! refd.IsDone() ) OK = Standard_False; |
755 | else if ( dev2 < refd.SquareDistance() ) {dev2 = refd.SquareDistance(); dev = sqrt (dev2);} |
756 | |
757 | otherd.Perform(pref,oprm); |
758 | if ( ! otherd.IsDone() ) OK = Standard_False; |
759 | else if ( dev2 < otherd.SquareDistance() ) {dev2 = otherd.SquareDistance(); dev = sqrt (dev2);} |
760 | } |
761 | } |
762 | dev *= 1.00001;//ims007 entity 8067 edge 3; 1e-07USA60022 (4255, 4-th edge) SA_Check and BRepCh find distinct points001; // ensure that dev*dev >= dev2 |
763 | |
764 | return OK; |
765 | } |
766 | |
767 | |
768 | //======================================================================= |
769 | //function : CheckSameParameter |
770 | //purpose : |
771 | //======================================================================= |
772 | |
773 | Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge, |
774 | Standard_Real& maxdev, |
775 | const Standard_Integer NbControl) |
776 | { |
777 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
778 | if (BRep_Tool::Degenerated (edge)) return Standard_False; |
779 | |
780 | maxdev = 0; |
781 | |
782 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape()); |
783 | Standard_Boolean SameParameter = TE->SameParameter(); |
784 | |
785 | GeomAdaptor_Curve AC3d; |
786 | |
787 | // find 3d curve |
788 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); |
789 | for ( ; itcr.More(); itcr.Next() ) { |
790 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
791 | if ( GC.IsNull() || ! GC->IsCurve3D() ) continue; |
792 | Handle(Geom_Curve) C3d = GC->Curve3D(); |
793 | if ( C3d.IsNull() ) continue; //:s1 abv 22 Apr 99: PRO7226 #489490 |
794 | TopLoc_Location loc = GC->Location(); |
795 | if ( ! loc.IsIdentity() ) |
796 | C3d = Handle(Geom_Curve)::DownCast ( C3d->Transformed ( loc ) ); |
797 | else C3d = Handle(Geom_Curve)::DownCast ( C3d->Copy() ); //:s4 abv 26 Apr 99: sim6049.igs 21677: necessary to get True SP (!!?) |
798 | Standard_Real First, Last; |
799 | GC->Range ( First, Last ); |
800 | AC3d.Load ( C3d, First, Last ); |
801 | break; |
802 | } |
803 | |
804 | if ( ! itcr.More() ) { |
805 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); |
806 | return Standard_False; |
807 | } |
808 | |
809 | // iterate on pcurves |
810 | itcr.Initialize ( TE->Curves() ); |
811 | for ( ; itcr.More(); itcr.Next() ) { |
812 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
813 | if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue; |
814 | |
815 | Standard_Real f, l; |
816 | GC->Range ( f, l ); |
817 | Handle(Geom_Surface) Su = GC->Surface(); |
818 | TopLoc_Location loc = GC->Location(); |
819 | if (!loc.IsIdentity()) |
820 | Su = Handle(Geom_Surface)::DownCast ( Su->Transformed ( loc ) ); |
821 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Su); |
822 | |
823 | Handle(Geom2d_Curve) PC = GC->PCurve(); |
824 | Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l); |
825 | //Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); |
826 | Adaptor3d_CurveOnSurface ACS; |
827 | ACS.Load(GHPC); |
828 | ACS.Load(GAHS); |
829 | if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) ) { |
830 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); |
831 | } |
832 | |
833 | if ( GC->IsCurveOnClosedSurface() ) { |
834 | GHPC->ChangeCurve2d().Load ( GC->PCurve2(), f, l ); // same bounds |
835 | ACS.Load(GAHS); // sans doute inutile |
836 | ACS.Load(GHPC); // meme remarque... |
837 | if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) ) { |
838 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); |
839 | } |
840 | } |
841 | } |
842 | |
843 | if ( maxdev > TE->Tolerance() ) |
844 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); |
845 | if ( ! SameParameter ) |
846 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); |
847 | |
848 | return Status ( ShapeExtend_DONE ); |
849 | } |
850 | |
851 | |
852 | //======================================================================= |
853 | //function : IsOverlapPartEdges |
854 | //purpose : |
855 | //======================================================================= |
856 | |
857 | static Standard_Boolean IsOverlapPartEdges(const TopoDS_Edge& theFirstEdge, |
858 | const TopoDS_Edge& theSecEdge, |
859 | const Standard_Real& theTolerance, |
860 | const Standard_Real& theStep, |
861 | const Standard_Real& theStartLength, |
862 | const Standard_Real& theEndLenght) |
863 | { |
864 | TColStd_SequenceOfInteger aSeqIntervals; |
865 | BRepAdaptor_Curve aAdCurve1(theFirstEdge); |
866 | |
867 | BRepExtrema_DistShapeShape aMinDist; |
868 | aMinDist.LoadS1(theSecEdge); |
869 | |
870 | for(Standard_Real aS = theStartLength; aS <= theEndLenght; aS+=theStep/2) { |
871 | |
872 | gp_Pnt aPoint; |
873 | if(aS <= Precision::Confusion()) { |
874 | TopoDS_Vertex V1 = TopExp::FirstVertex(theFirstEdge,Standard_True); |
875 | aPoint = BRep_Tool::Pnt(V1); |
876 | } |
877 | else { |
878 | GCPnts_AbscissaPoint aAbsPoint(Precision::Confusion(),aAdCurve1,aS,aAdCurve1.FirstParameter()); |
879 | if(aAbsPoint.IsDone()) |
880 | aAdCurve1.D0(aAbsPoint.Parameter(),aPoint); |
881 | else continue; |
882 | } |
883 | BRep_Builder aB; |
884 | TopoDS_Vertex aV; |
885 | aB.MakeVertex(aV,aPoint,Precision::Confusion()); |
886 | aMinDist.LoadS2(aV); |
887 | aMinDist.Perform(); |
888 | if( aMinDist.IsDone() && aMinDist.Value() >= theTolerance) |
889 | return Standard_False; |
890 | } |
891 | return Standard_True; |
892 | } |
893 | |
894 | |
895 | //======================================================================= |
896 | //function : CheckOverlapping |
897 | //purpose : |
898 | //======================================================================= |
899 | |
900 | Standard_Boolean ShapeAnalysis_Edge::CheckOverlapping(const TopoDS_Edge& theEdge1, |
901 | const TopoDS_Edge& theEdge2, |
902 | Standard_Real& theTolOverlap, |
903 | const Standard_Real theDomainDist) |
904 | { |
905 | Standard_Boolean isOverlap = Standard_False; |
906 | BRepAdaptor_Curve aAdCurve1(theEdge1); |
907 | Standard_Real aLength1 = GCPnts_AbscissaPoint::Length (aAdCurve1); |
908 | BRepAdaptor_Curve aAdCurve2(theEdge2); |
909 | Standard_Real aLength2 = GCPnts_AbscissaPoint::Length (aAdCurve2); |
910 | TopoDS_Edge aFirstEdge = (aLength1 >= aLength2 ? theEdge2: theEdge1); |
911 | TopoDS_Edge aSecEdge = (aLength1 >= aLength2 ? theEdge1: theEdge2); |
912 | Standard_Real aLength = Min(aLength1,aLength2); |
913 | |
914 | //check overalpping between edges on whole edges |
915 | Standard_Real aStep = Min(aLength1,aLength2)/2; |
916 | isOverlap = IsOverlapPartEdges(aFirstEdge,aSecEdge,theTolOverlap,aStep,0.,Min(aLength1,aLength2)); |
917 | |
918 | if(isOverlap) { |
919 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3); |
920 | return isOverlap; |
921 | } |
922 | if(theDomainDist ==0.0) |
923 | return isOverlap; |
924 | |
925 | //check overalpping between edges on segment with length less than theDomainDist |
926 | |
927 | Standard_Real aDomainTol = (theDomainDist > Min( aLength1,aLength2) ? Min( aLength1,aLength2) :theDomainDist); |
928 | BRepExtrema_DistShapeShape aMinDist(aFirstEdge,aSecEdge,theTolOverlap); |
929 | Standard_Real aresTol = theTolOverlap; |
930 | if(aMinDist.IsDone()) { |
931 | aresTol = aMinDist.Value(); |
932 | if(aresTol >= theTolOverlap) return Standard_False; |
933 | Standard_Integer NbSol = aMinDist.NbSolution(); |
934 | for(Standard_Integer i =1; i<= NbSol && !isOverlap; i++) { |
935 | BRepExtrema_SupportType aType1 = aMinDist.SupportTypeShape1(i); |
936 | Standard_Real aEndLength, aStartLength, aLengthP; |
937 | if(aType1 == BRepExtrema_IsVertex) { |
938 | TopoDS_Shape aSupportShape1 = aMinDist.SupportOnShape1(i); |
939 | TopoDS_Vertex aV1,aV2; |
940 | TopExp::Vertices (aFirstEdge, aV1, aV2, Standard_True); |
941 | if( aV1.IsSame(aSupportShape1)) |
942 | aLengthP = 0.0; |
943 | else |
944 | aLengthP =aLength; |
945 | } |
946 | else if(aType1 == BRepExtrema_IsOnEdge) { |
947 | Standard_Real aParam1, aFirst, aLast; |
948 | aMinDist.ParOnEdgeS1 ( i, aParam1 ); |
949 | BRep_Tool::Range(aFirstEdge,aFirst,aLast); |
950 | BRepAdaptor_Curve anAdaptor(aFirstEdge); |
951 | aLengthP = GCPnts_AbscissaPoint::Length(anAdaptor,aFirst,aParam1); |
952 | } |
953 | else continue; |
954 | aStartLength = aLengthP - aDomainTol/2; |
955 | if( aStartLength <0.0) { |
956 | aStartLength =0; |
957 | aEndLength = aDomainTol; |
958 | } |
959 | aEndLength = aLengthP + aDomainTol/2; |
960 | if(aEndLength > aLength) { |
961 | aEndLength = aLength; |
962 | aStartLength = aEndLength - aDomainTol; |
963 | } |
964 | aStep = (aEndLength - aStartLength)/5; |
965 | isOverlap = (IsOverlapPartEdges(aFirstEdge,aSecEdge,theTolOverlap,aStep,aStartLength,aEndLength)); |
966 | } |
967 | } |
968 | if(isOverlap) |
969 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4); |
970 | |
971 | theTolOverlap = aresTol; |
972 | return isOverlap; |
973 | } |