1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
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)
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()
21 #include <Adaptor3d_Curve.hxx>
22 #include <BRep_Builder.hxx>
23 #include <BRep_GCurve.hxx>
24 #include <BRepLib_ValidateEdge.hxx>
25 #include <BRep_TEdge.hxx>
26 #include <BRep_Tool.hxx>
27 #include <BRepAdaptor_Curve.hxx>
28 #include <BRepExtrema_DistShapeShape.hxx>
29 #include <Extrema_LocateExtPC.hxx>
30 #include <GCPnts_AbscissaPoint.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom2dAdaptor_Curve.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom2d_TrimmedCurve.hxx>
35 #include <Geom_Plane.hxx>
36 #include <Geom_Surface.hxx>
37 #include <GeomAdaptor_Curve.hxx>
38 #include <GeomAdaptor_Surface.hxx>
40 #include <gp_Pnt2d.hxx>
41 #include <gp_Vec2d.hxx>
42 #include <Precision.hxx>
43 #include <ShapeAnalysis_Edge.hxx>
44 #include <ShapeExtend.hxx>
45 #include <Standard_ErrorHandler.hxx>
47 #include <TopLoc_Location.hxx>
48 #include <TopoDS_Edge.hxx>
49 #include <TopoDS_Face.hxx>
50 #include <TopoDS_Vertex.hxx>
52 //=======================================================================
53 //function : ShapeAnalysis_Edge
55 //=======================================================================
56 ShapeAnalysis_Edge::ShapeAnalysis_Edge()
58 myStatus = 0;//ShapeExtend::EncodeStatus (ShapeExtend_OK);
62 //=======================================================================
65 //=======================================================================
67 Standard_Boolean ShapeAnalysis_Edge::BoundUV (const TopoDS_Edge& edge,
68 const TopoDS_Face& face,
69 gp_Pnt2d& first, gp_Pnt2d& last) const
72 const Handle(Geom_Surface) S = BRep_Tool::Surface(face, L);
73 return BoundUV (edge, S, L, first, last);
77 //=======================================================================
80 //=======================================================================
82 Standard_Boolean ShapeAnalysis_Edge::BoundUV (const TopoDS_Edge& edge,
83 const Handle(Geom_Surface)& surface,
84 const TopLoc_Location& location,
85 gp_Pnt2d& first, gp_Pnt2d& last) const
87 Handle(Geom2d_Curve) c2d;
89 if (!PCurve (edge, surface, location, c2d, uf, ul)) return Standard_False;
90 first = c2d->Value (uf);
91 last = c2d->Value (ul);
96 //=======================================================================
97 //function : HasCurve3d
99 //=======================================================================
101 Standard_Boolean ShapeAnalysis_Edge::HasCurve3d (const TopoDS_Edge& edge) const
103 Standard_Real cf, cl;
104 Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge, cf, cl);
105 return !c3d.IsNull();
109 //=======================================================================
112 //=======================================================================
114 Standard_Boolean ShapeAnalysis_Edge::Curve3d (const TopoDS_Edge& edge,
115 Handle(Geom_Curve)& C3d,
116 Standard_Real& cf, Standard_Real& cl,
117 const Standard_Boolean orient) const
120 C3d = BRep_Tool::Curve (edge, L, cf, cl);
121 if( !C3d.IsNull() && !L.IsIdentity() ) {
122 C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L.Transformation()));
123 cf = C3d->TransformedParameter(cf, L.Transformation());
124 cl = C3d->TransformedParameter(cl, L.Transformation());
127 if (edge.Orientation() == TopAbs_REVERSED)
128 {Standard_Real tmp = cf; cf = cl; cl = tmp;}
130 return !C3d.IsNull();
134 //=======================================================================
135 //function : IsClosed3d
137 //=======================================================================
139 Standard_Boolean ShapeAnalysis_Edge::IsClosed3d (const TopoDS_Edge& edge) const
142 Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,cf,cl);
143 if (c3d.IsNull()) return Standard_False;
144 if (!c3d->IsClosed()) return Standard_False;
145 return FirstVertex (edge).IsSame (LastVertex (edge));
149 //=======================================================================
150 //function : HasPCurve
152 //=======================================================================
154 Standard_Boolean ShapeAnalysis_Edge::HasPCurve (const TopoDS_Edge& edge,
155 const TopoDS_Face& face) const
158 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
159 return HasPCurve (edge, S, L);
163 //=======================================================================
164 //function : HasPCurve
166 //=======================================================================
168 Standard_Boolean ShapeAnalysis_Edge::HasPCurve (const TopoDS_Edge& edge,
169 const Handle(Geom_Surface)& surface,
170 const TopLoc_Location& location) const
172 //try { //szv#4:S4163:12Mar99 waste try
173 Standard_Real cf, cl;
174 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface (edge, surface, location, cf, cl);
175 return !c2d.IsNull();
177 catch (Standard_Failure) {
179 return Standard_False; */
183 //=======================================================================
186 //=======================================================================
188 Standard_Boolean ShapeAnalysis_Edge::PCurve (const TopoDS_Edge& edge,
189 const TopoDS_Face& face,
190 Handle(Geom2d_Curve)& C2d,
191 Standard_Real& cf, Standard_Real& cl,
192 const Standard_Boolean orient) const
194 //:abv 20.05.02: take into account face orientation
195 // COMMENTED BACK - NEEDS MORE CHANGES IN ALL SHAPEHEALING
196 // C2d = BRep_Tool::CurveOnSurface (edge, face, cf, cl);
197 // if (orient && edge.Orientation() == TopAbs_REVERSED) {
198 // Standard_Real tmp = cf; cf = cl; cl = tmp;
200 // return !C2d.IsNull();
202 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
203 return PCurve (edge, S, L, C2d, cf, cl, orient);
207 //=======================================================================
210 //=======================================================================
212 Standard_Boolean ShapeAnalysis_Edge::PCurve (const TopoDS_Edge& edge,
213 const Handle(Geom_Surface)& surface,
214 const TopLoc_Location& location,
215 Handle(Geom2d_Curve)& C2d,
216 Standard_Real& cf, Standard_Real& cl,
217 const Standard_Boolean orient) const
219 C2d = BRep_Tool::CurveOnSurface (edge, surface, location, cf, cl);
220 if ( orient && edge.Orientation() == TopAbs_REVERSED ) {
221 Standard_Real tmp = cf; cf = cl; cl = tmp;
223 return !C2d.IsNull();
227 //=======================================================================
230 //=======================================================================
232 Standard_Boolean ShapeAnalysis_Edge::IsSeam (const TopoDS_Edge& edge,
233 const TopoDS_Face& face) const
235 return BRep_Tool::IsClosed (edge, face);
239 //=======================================================================
242 //=======================================================================
244 Standard_Boolean ShapeAnalysis_Edge::IsSeam (const TopoDS_Edge& edge,
245 const Handle(Geom_Surface)& surface,
246 const TopLoc_Location& location) const
248 return BRep_Tool::IsClosed (edge, surface, location);
252 //=======================================================================
253 //function : FirstVertex
255 //=======================================================================
257 TopoDS_Vertex ShapeAnalysis_Edge::FirstVertex (const TopoDS_Edge& edge) const
260 if (edge.Orientation() == TopAbs_REVERSED) {
261 V = TopExp::LastVertex(edge);
265 V = TopExp::FirstVertex (edge);
271 //=======================================================================
272 //function : LastVertex
274 //=======================================================================
276 TopoDS_Vertex ShapeAnalysis_Edge::LastVertex (const TopoDS_Edge& edge) const
279 if (edge.Orientation() == TopAbs_REVERSED) {
280 V = TopExp::FirstVertex(edge);
284 V = TopExp::LastVertex (edge);
290 //=======================================================================
293 //=======================================================================
295 Standard_Boolean ShapeAnalysis_Edge::Status (const ShapeExtend_Status Status) const
297 return ShapeExtend::DecodeStatus (myStatus, Status);
301 //=======================================================================
302 //function : GetEndTangent2d
304 //=======================================================================
306 Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d (const TopoDS_Edge &edge,
307 const TopoDS_Face &face,
308 const Standard_Boolean atend1, /* skl : change "atend" to "atend1" */
311 const Standard_Real dparam) const
314 const Handle(Geom_Surface) S = BRep_Tool::Surface ( face, L );
315 return GetEndTangent2d ( edge, S, L, atend1, pnt, v, dparam );
319 //=======================================================================
320 //function : GetEndTangent2d
322 //=======================================================================
324 Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d (const TopoDS_Edge &edge,
325 const Handle(Geom_Surface)& S,
326 const TopLoc_Location& L,
327 const Standard_Boolean atend2, /* skl : change "atend" to "atend2" */
330 const Standard_Real dparam) const
332 Standard_Real cf, cl;
333 Handle(Geom2d_Curve) c2d;
334 if ( ! PCurve ( edge, S, L, c2d, cf, cl ) ) {
336 return Standard_False;
338 Standard_Real dpnew = dparam;
340 if(dpnew>Precision::Confusion()) {
342 Standard_Real par1,par2,delta=(cl-cf)*dpnew;
343 if(Abs(delta)<Precision::PConfusion()) {
352 v = pnt.XY() - ptmp.XY();
359 v = ptmp.XY() - pnt.XY();
361 if( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
367 if(dpnew<=Precision::Confusion()) {
368 // get non-null tangency searching until 3rd derivative, or as straight btw ends
369 Standard_Real par = ( atend2 ? cl : cf );
370 c2d->D1 ( par, pnt, v );
371 if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
373 c2d->D2 ( par, pnt, d1, v );
374 if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
376 c2d->D3 ( par, pnt, d1, d2, v );
377 if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
379 c2d->D0 ( ( atend2 ? cf : cl ), p2 );
380 v = p2.XY() - pnt.XY();
381 if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() )
382 return Standard_False;
386 if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse();
389 //if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse();
390 return Standard_True;
394 //=======================================================================
395 //function : CheckCurve3dWithPCurve
397 //=======================================================================
399 Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve (const TopoDS_Edge& edge,
400 const TopoDS_Face& face)
403 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
404 return CheckCurve3dWithPCurve (edge, S, L);
408 //=======================================================================
409 //function : CheckCurve3dWithPCurve
411 //=======================================================================
413 Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve (const TopoDS_Edge& edge,
414 const Handle(Geom_Surface)& surface,
415 const TopLoc_Location& location)
417 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
419 if(surface->IsKind(STANDARD_TYPE(Geom_Plane)))
420 return Standard_False;
422 Handle (Geom2d_Curve) c2d;
423 Standard_Real f2d, l2d; //szv#4:S4163:12Mar99 moved down f3d, l3d
424 if (!PCurve (edge, surface, location, c2d, f2d ,l2d, Standard_False)) {
425 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
426 return Standard_False;
429 Handle (Geom_Curve) c3d; //szv#4:S4163:12Mar99 moved
430 Standard_Real f3d, l3d; //szv#4:S4163:12Mar99 moved
431 if (!Curve3d (edge, c3d, f3d, l3d, Standard_False)) {
432 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
433 return Standard_False;
436 TopoDS_Vertex aFirstVert = FirstVertex (edge);
437 TopoDS_Vertex aLastVert = LastVertex (edge);
439 if (aFirstVert.IsNull() || aLastVert.IsNull())
440 return Standard_False;
442 Standard_Real preci1 = BRep_Tool::Tolerance (aFirstVert),
443 preci2 = BRep_Tool::Tolerance (aLastVert);
445 gp_Pnt2d p2d1 = c2d->Value (f2d),
446 p2d2 = c2d->Value (l2d);
448 //#39 rln 17.11.98 S4054, annie_surf.igs entity 39
449 return CheckPoints (c3d->Value (f3d)/*.Transformed (location.Transformation())*/,
450 c3d->Value (l3d)/*.Transformed (location.Transformation())*/,
451 surface->Value (p2d1.X(), p2d1.Y()).Transformed (location.Transformation()),
452 surface->Value (p2d2.X(), p2d2.Y()).Transformed (location.Transformation()),
457 //=======================================================================
458 //function : CheckPoints
460 //=======================================================================
462 Standard_Boolean ShapeAnalysis_Edge::CheckPoints (const gp_Pnt& P1A,
466 const Standard_Real preci1,
467 const Standard_Real preci2)
469 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
470 if (P1A.SquareDistance (P2A) <= preci1 * preci1 &&
471 P1B.SquareDistance (P2B) <= preci2 * preci2)
472 return Standard_False;
473 else if (P1A.Distance (P2B) + (P1B.Distance (P2A)) <
474 P1A.Distance (P2A) + (P1B.Distance (P2B)))
475 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
476 return Standard_True;
480 //=======================================================================
481 //function : CheckVerticesWithCurve3d
483 //=======================================================================
485 Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithCurve3d (const TopoDS_Edge& edge,
486 const Standard_Real preci,
487 const Standard_Integer vtx)
489 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
491 TopoDS_Vertex V1 = FirstVertex (edge);
492 TopoDS_Vertex V2 = LastVertex (edge);
493 gp_Pnt p1v = BRep_Tool::Pnt (V1);
494 gp_Pnt p2v = BRep_Tool::Pnt (V2);
497 Handle(Geom_Curve) c3d;
498 if ( ! Curve3d (edge,c3d,cf,cl) ) {
499 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
500 return Standard_False;
503 // on va faire les checks ...
506 gp_Pnt p13d = c3d->Value(cf);
507 //szv#4:S4163:12Mar99 optimized
508 if (p1v.Distance(p13d) > (preci < 0 ? BRep_Tool::Tolerance (V1) : preci))
509 myStatus |= ShapeExtend_DONE1;
514 gp_Pnt p23d = c3d->Value(cl);
515 //szv#4:S4163:12Mar99 optimized
516 if (p2v.Distance(p23d) > (preci < 0 ? BRep_Tool::Tolerance (V2) : preci))
517 myStatus |= ShapeExtend_DONE2;
520 return Status ( ShapeExtend_DONE );
524 //=======================================================================
525 //function : CheckVerticesWithPCurve
527 //=======================================================================
529 Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve (const TopoDS_Edge& edge,
530 const TopoDS_Face& face,
531 const Standard_Real preci,
532 const Standard_Integer vtx)
535 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
536 return CheckVerticesWithPCurve (edge, S, L, preci, vtx); //szv#4:S4163:12Mar99 `vtx,preci` wrong parameters order
540 //=======================================================================
541 //function : CheckVerticesWithPCurve
543 //=======================================================================
545 Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve (const TopoDS_Edge& edge,
546 const Handle(Geom_Surface)& surf,
547 const TopLoc_Location& loc,
548 const Standard_Real preci,
549 const Standard_Integer vtx)
551 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
553 TopoDS_Vertex V1 = FirstVertex (edge);
554 TopoDS_Vertex V2 = LastVertex (edge);
555 gp_Pnt p1v = BRep_Tool::Pnt (V1);
556 gp_Pnt p2v = BRep_Tool::Pnt (V2);
558 Standard_Real cf, cl;
559 Handle(Geom2d_Curve) c2d;
560 if ( ! PCurve ( edge, surf, loc, c2d, cf, cl ) ) {
561 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
562 return Standard_False;
565 // on va faire les checks ...
566 if (vtx != 2) { // 1er VTX
567 gp_Pnt2d p1uv = c2d->Value (cf);
568 gp_Pnt p12d = surf->Value (p1uv.X(), p1uv.Y());
569 if (!loc.IsIdentity())
570 p12d.Transform(loc.Transformation());
571 // szv#4:S4163:12Mar99 optimized
572 if ( p1v.Distance(p12d) > (preci < 0 ? BRep_Tool::Tolerance (V1) : preci) )
573 myStatus |= ShapeExtend_DONE1;
576 if (vtx != 1) { // 2me VTX
577 gp_Pnt2d p2uv = c2d->Value (cl);
578 gp_Pnt p22d = surf->Value (p2uv.X(), p2uv.Y());
579 if (!loc.IsIdentity())
580 p22d.Transform(loc.Transformation());
581 // szv#4:S4163:12Mar99 optimized
582 if ( p2v.Distance(p22d) > (preci < 0 ? BRep_Tool::Tolerance (V2) : preci) )
583 myStatus |= ShapeExtend_DONE2;
586 return Status ( ShapeExtend_DONE );
590 //=======================================================================
591 //function : CheckVertexTolerance
593 //=======================================================================
595 static Standard_Integer CheckVertexTolerance(const TopoDS_Edge& edge,
596 const TopoDS_Face& face,
597 const Standard_Boolean checkAll,
598 Standard_Real& toler1,
599 Standard_Real& toler2)
601 Standard_Integer Status = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
603 ShapeAnalysis_Edge sae;
604 TopoDS_Vertex V1 = sae.FirstVertex (edge);
605 TopoDS_Vertex V2 = sae.LastVertex (edge);
606 if ( V1.IsNull() || V2.IsNull() ) { //:p1 abv 22 Feb 99: r76sy.stp
607 Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
611 Standard_Real old1 = BRep_Tool::Tolerance (V1);
612 Standard_Real old2 = BRep_Tool::Tolerance (V2);
613 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
614 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
617 Handle(Geom_Curve) c3d;
618 if ( ! sae.Curve3d(edge, c3d, a, b, Standard_True)) {
619 if ( ! BRep_Tool::Degenerated ( edge ) )
620 Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
621 toler1 = toler2 = 0.;
622 // return Standard_False;
625 toler1 = pnt1.SquareDistance (c3d->Value (a));
626 toler2 = pnt2.SquareDistance (c3d->Value (b));
630 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
631 for (BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); itcr.More(); itcr.Next() ) {
632 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
633 if (GC.IsNull() || !GC->IsCurveOnSurface()) continue;
634 Handle(Geom2d_Curve) pcurve;
635 Handle(Geom_Surface) S = GC->Surface();
636 TopLoc_Location L = edge.Location() * GC->Location();
637 sae.PCurve (edge, S, L, pcurve, a, b, Standard_True);
638 gp_Pnt2d p1 = pcurve->Value (a);
639 gp_Pnt2d p2 = pcurve->Value (b);
640 gp_Pnt P1 = S->Value (p1.X(), p1.Y()).Transformed (L.Transformation());
641 gp_Pnt P2 = S->Value (p2.X(), p2.Y()).Transformed (L.Transformation());
642 toler1 = Max (toler1, pnt1.SquareDistance (P1));
643 toler2 = Max (toler2, pnt2.SquareDistance (P2));
646 //:abv 10.06.02: porting C40 -> dev (CC670-12608.stp)
647 // Check with given face is needed for plane surfaces (if no stored pcurves)
648 else if ( ! face.IsNull() ) {
649 Handle(Geom2d_Curve) pcurve;
651 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
652 if ( sae.PCurve(edge, S, L, pcurve, a, b, Standard_True)) {
653 gp_Pnt2d p1 = pcurve->Value (a);
654 gp_Pnt2d p2 = pcurve->Value (b);
655 gp_Pnt P1 = S->Value (p1.X(), p1.Y()).Transformed (L.Transformation());
656 gp_Pnt P2 = S->Value (p2.X(), p2.Y()).Transformed (L.Transformation());
657 toler1 = Max (toler1, pnt1.SquareDistance (P1));
658 toler2 = Max (toler2, pnt2.SquareDistance (P2));
660 else Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
663 //:o8 abv 19 Feb 99: CTS18541.stp #18559: coeff 1.0001 added
664 //szv 18 Aug 99: edge tolerance is taken in consideration
665 Standard_Real tole = BRep_Tool::Tolerance (edge);
666 toler1 = Max (1.0000001 * Sqrt (toler1), tole);
667 toler2 = Max (1.0000001 * Sqrt (toler2), tole);
669 Status |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
671 Status |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
677 //=======================================================================
678 //function : CheckVertexTolerance
680 //=======================================================================
682 Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge,
683 const TopoDS_Face& face,
684 Standard_Real& toler1,
685 Standard_Real& toler2)
687 myStatus = ::CheckVertexTolerance ( edge, face, Standard_False, toler1, toler2 );
688 return Status ( ShapeExtend_DONE );
692 //=======================================================================
693 //function : CheckVertexTolerance
695 //=======================================================================
697 Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge,
698 Standard_Real& toler1,
699 Standard_Real& toler2)
702 myStatus = ::CheckVertexTolerance ( edge, F, Standard_True, toler1, toler2 );
703 return Status ( ShapeExtend_DONE );
706 //=======================================================================
707 //function : CheckSameParameter
709 //=======================================================================
711 Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge,
712 Standard_Real& maxdev,
713 const Standard_Integer NbControl)
715 TopoDS_Face anEmptyFace;
716 return CheckSameParameter(edge, anEmptyFace, maxdev, NbControl);
720 //=======================================================================
721 //function : CheckSameParameter
723 //=======================================================================
725 Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge,
726 const TopoDS_Face& face,
727 Standard_Real& maxdev,
728 const Standard_Integer NbControl)
730 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
731 if (BRep_Tool::Degenerated (edge)) return Standard_False;
735 // Get same parameter flag
736 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
737 Standard_Boolean SameParameter = TE->SameParameter();
739 // Get 3D curve of the edge
740 Standard_Real aFirst, aLast;
741 TopLoc_Location aCurveLoc;
742 Handle(Geom_Curve) aC3D = BRep_Tool::Curve(edge, aCurveLoc, aFirst, aLast);
744 myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
745 return Standard_False;
748 if (!aCurveLoc.IsIdentity())
750 const gp_Trsf& aTrsf = aCurveLoc.Transformation();
751 aC3D = Handle(Geom_Curve)::DownCast(aC3D->Transformed(aTrsf));
752 aFirst = aC3D->TransformedParameter(aFirst, aTrsf);
753 aLast = aC3D->TransformedParameter(aLast, aTrsf);
756 // Create adaptor for the curve
757 Handle(GeomAdaptor_Curve) aGAC = new GeomAdaptor_Curve(aC3D, aFirst, aLast);
759 Handle(Geom_Surface) aFaceSurf;
760 TopLoc_Location aFaceLoc;
762 aFaceSurf = BRep_Tool::Surface(face, aFaceLoc);
764 Standard_Boolean IsPCurveFound = Standard_False;
765 Standard_Integer i = 1;
767 // Iterate on all curve representations
770 Handle(Geom2d_Curve) aPC;
771 Handle(Geom_Surface) aS;
772 TopLoc_Location aLoc;
775 BRep_Tool::CurveOnSurface(edge, aPC, aS, aLoc, f, l, i);
783 // If the input face is not null, check that the curve is on its surface
784 if (!aFaceSurf.IsNull())
786 if (aFaceSurf != aS || aFaceLoc != aLoc)
792 IsPCurveFound = Standard_True;
794 // Apply transformations for the surface
795 Handle(Geom_Surface) aST = Handle(Geom_Surface)::
796 DownCast(aS->Transformed(aLoc.Transformation()));
798 // Compute deviation between curves
799 Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(aPC, f, l);
800 Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(aST);
802 Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC, GAHS);
804 BRepLib_ValidateEdge aValidateEdge(aGAC, ACS, SameParameter);
805 aValidateEdge.SetControlPointsNumber(NbControl-1);
806 aValidateEdge.Process();
807 aValidateEdge.UpdateTolerance(maxdev);
808 if (!aValidateEdge.IsDone())
810 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
814 // For the planar face and non-existing 2d curve
815 // check the deviation for the projection of the 3d curve on plane
816 if (!IsPCurveFound && !aFaceSurf.IsNull())
819 Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnPlane(edge, aFaceSurf, aFaceLoc, f, l);
822 Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(aPC, aFirst, aLast);
824 Handle(Geom_Surface) aST =
825 Handle(Geom_Surface)::DownCast(aFaceSurf->Transformed(aFaceLoc.Transformation()));
826 Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(aST);
828 Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC, GAHS);
830 BRepLib_ValidateEdge aValidateEdgeOnPlane(aGAC, ACS, SameParameter);
831 aValidateEdgeOnPlane.SetControlPointsNumber(NbControl - 1);
832 aValidateEdgeOnPlane.Process();
833 aValidateEdgeOnPlane.UpdateTolerance(maxdev);
834 if (!aValidateEdgeOnPlane.IsDone())
836 myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
841 if (maxdev > TE->Tolerance())
842 myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1);
844 myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
846 return Status ( ShapeExtend_DONE );
849 //=======================================================================
850 //function : IsOverlapPartEdges
852 //=======================================================================
854 static Standard_Boolean IsOverlapPartEdges(const TopoDS_Edge& theFirstEdge,
855 const TopoDS_Edge& theSecEdge,
856 const Standard_Real& theTolerance,
857 const Standard_Real& theStep,
858 const Standard_Real& theStartLength,
859 const Standard_Real& theEndLength)
861 TColStd_SequenceOfInteger aSeqIntervals;
862 BRepAdaptor_Curve aAdCurve1(theFirstEdge);
864 BRepExtrema_DistShapeShape aMinDist;
865 aMinDist.LoadS1(theSecEdge);
867 for(Standard_Real aS = theStartLength; aS <= theEndLength; aS+=theStep/2) {
870 if(aS <= Precision::Confusion()) {
871 TopoDS_Vertex V1 = TopExp::FirstVertex(theFirstEdge,Standard_True);
872 aPoint = BRep_Tool::Pnt(V1);
875 GCPnts_AbscissaPoint aAbsPoint(Precision::Confusion(),aAdCurve1,aS,aAdCurve1.FirstParameter());
876 if(aAbsPoint.IsDone())
877 aAdCurve1.D0(aAbsPoint.Parameter(),aPoint);
882 aB.MakeVertex(aV,aPoint,Precision::Confusion());
885 if( aMinDist.IsDone() && aMinDist.Value() >= theTolerance)
886 return Standard_False;
888 return Standard_True;
892 //=======================================================================
893 //function : CheckOverlapping
895 //=======================================================================
897 Standard_Boolean ShapeAnalysis_Edge::CheckOverlapping(const TopoDS_Edge& theEdge1,
898 const TopoDS_Edge& theEdge2,
899 Standard_Real& theTolOverlap,
900 const Standard_Real theDomainDist)
902 Standard_Boolean isOverlap = Standard_False;
903 BRepAdaptor_Curve aAdCurve1(theEdge1);
904 Standard_Real aLength1 = GCPnts_AbscissaPoint::Length (aAdCurve1);
905 BRepAdaptor_Curve aAdCurve2(theEdge2);
906 Standard_Real aLength2 = GCPnts_AbscissaPoint::Length (aAdCurve2);
907 TopoDS_Edge aFirstEdge = (aLength1 >= aLength2 ? theEdge2: theEdge1);
908 TopoDS_Edge aSecEdge = (aLength1 >= aLength2 ? theEdge1: theEdge2);
909 Standard_Real aLength = Min(aLength1,aLength2);
911 //check overalpping between edges on whole edges
912 Standard_Real aStep = Min(aLength1,aLength2)/2;
913 isOverlap = IsOverlapPartEdges(aFirstEdge,aSecEdge,theTolOverlap,aStep,0.,Min(aLength1,aLength2));
916 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3);
919 if(theDomainDist ==0.0)
922 //check overalpping between edges on segment with length less than theDomainDist
924 Standard_Real aDomainTol = (theDomainDist > Min( aLength1,aLength2) ? Min( aLength1,aLength2) :theDomainDist);
925 BRepExtrema_DistShapeShape aMinDist(aFirstEdge,aSecEdge,theTolOverlap);
926 Standard_Real aresTol = theTolOverlap;
927 if(aMinDist.IsDone()) {
928 aresTol = aMinDist.Value();
929 if(aresTol >= theTolOverlap) return Standard_False;
930 Standard_Integer NbSol = aMinDist.NbSolution();
931 for(Standard_Integer i =1; i<= NbSol && !isOverlap; i++) {
932 BRepExtrema_SupportType aType1 = aMinDist.SupportTypeShape1(i);
933 Standard_Real aEndLength, aStartLength, aLengthP;
934 if(aType1 == BRepExtrema_IsVertex) {
935 TopoDS_Shape aSupportShape1 = aMinDist.SupportOnShape1(i);
936 TopoDS_Vertex aV1,aV2;
937 TopExp::Vertices (aFirstEdge, aV1, aV2, Standard_True);
938 if( aV1.IsSame(aSupportShape1))
943 else if(aType1 == BRepExtrema_IsOnEdge) {
944 Standard_Real aParam1, aFirst, aLast;
945 aMinDist.ParOnEdgeS1 ( i, aParam1 );
946 BRep_Tool::Range(aFirstEdge,aFirst,aLast);
947 BRepAdaptor_Curve anAdaptor(aFirstEdge);
948 aLengthP = GCPnts_AbscissaPoint::Length(anAdaptor,aFirst,aParam1);
951 aStartLength = aLengthP - aDomainTol/2;
952 if( aStartLength <0.0) {
954 aEndLength = aDomainTol;
956 aEndLength = aLengthP + aDomainTol/2;
957 if(aEndLength > aLength) {
958 aEndLength = aLength;
959 aStartLength = aEndLength - aDomainTol;
961 aStep = (aEndLength - aStartLength)/5;
962 isOverlap = (IsOverlapPartEdges(aFirstEdge,aSecEdge,theTolOverlap,aStep,aStartLength,aEndLength));
966 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4);
968 theTolOverlap = aresTol;
972 //=======================================================================
973 //function : CheckPCurveRange
975 //=======================================================================
977 Standard_Boolean ShapeAnalysis_Edge::CheckPCurveRange (const Standard_Real theFirst,
978 const Standard_Real theLast,
979 const Handle(Geom2d_Curve)& thePC)
981 const Standard_Real eps = Precision::PConfusion();
982 Standard_Boolean isValid = Standard_True;
983 Standard_Boolean IsPeriodic = thePC->IsPeriodic();
984 Standard_Real aPeriod = RealLast();
987 aPeriod = thePC->Period();
989 Standard_Real fp = thePC->FirstParameter(), lp = thePC->LastParameter();
990 if (thePC->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
992 const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (thePC)->BasisCurve();
993 fp = aC->FirstParameter();
994 lp = aC->LastParameter();
995 IsPeriodic = aC->IsPeriodic();
998 aPeriod = aC->Period();
1001 if(IsPeriodic && (theLast - theFirst > aPeriod + eps))
1003 isValid = Standard_False;
1005 else if(!IsPeriodic && (theFirst < fp - eps || theLast > lp + eps))
1007 isValid = Standard_False;