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