Logo Search packages:      
Sourcecode: opencascade version File versions  Download package

ShapeAnalysis_Edge.cxx

//:o8 abv 19.02.99: CTS18541.stp #18559: coeff 1.0001 added in CheckVertexTol
//:p1 abv 22.02.99: protection against edges with no vertices (infinite)
//szv#4 S4163
//:s1 abv 22.04.99: PRO7226 #489490: protect against Null 3d curve
//:s4 abv 26.04.99: sim6049.igs 21677: copy of curve is necessary to get True SP
//    abv 06.05.99: S4137: adding methods GetTangent2d()
#include <ShapeAnalysis_Edge.ixx>

#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>

#include <Precision.hxx>

#include <GCPnts_AbscissaPoint.hxx>
#include <Adaptor3d_Curve.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepExtrema_DistShapeShape.hxx>

#include <BRep_Tool.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_GCurve.hxx>
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
#include <BRep_Builder.hxx>

#include <Extrema_LocateExtPC.hxx>

#include <ShapeExtend.hxx>
#include <TopExp.hxx>
#include <TopoDS_Vertex.hxx>
#include <Geom_Plane.hxx>


//=======================================================================
//function : ShapeAnalysis_Edge
//purpose  : 
//=======================================================================

00042 ShapeAnalysis_Edge::ShapeAnalysis_Edge()
{
  myStatus = 0;//ShapeExtend::EncodeStatus (ShapeExtend_OK);
}


//=======================================================================
//function : BoundUV
//purpose  : 
//=======================================================================

Standard_Boolean ShapeAnalysis_Edge::BoundUV (const TopoDS_Edge& edge,
                                    const TopoDS_Face& face,
                                    gp_Pnt2d& first, gp_Pnt2d& last) const
{
  TopLoc_Location L;
  const Handle(Geom_Surface) S = BRep_Tool::Surface(face, L);
  return BoundUV (edge, S, L, first, last);
}


//=======================================================================
//function : BoundUV
//purpose  : 
//=======================================================================

00068 Standard_Boolean ShapeAnalysis_Edge::BoundUV (const TopoDS_Edge& edge,
                                    const Handle(Geom_Surface)& surface,
                                    const TopLoc_Location& location,
                                    gp_Pnt2d& first, gp_Pnt2d& last) const
{
  Handle(Geom2d_Curve) c2d;
  Standard_Real uf,ul;
  if (!PCurve (edge, surface, location, c2d, uf, ul)) return Standard_False;
  first = c2d->Value (uf);
  last  = c2d->Value (ul);
  return Standard_True;
}


//=======================================================================
//function : HasCurve3d
//purpose  : 
//=======================================================================

00087 Standard_Boolean ShapeAnalysis_Edge::HasCurve3d (const TopoDS_Edge& edge) const
{
  Standard_Real cf, cl;
  Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge, cf, cl);
  return !c3d.IsNull();
}


//=======================================================================
//function : Curve3d
//purpose  : 
//=======================================================================

00100 Standard_Boolean ShapeAnalysis_Edge::Curve3d (const TopoDS_Edge& edge,
                                    Handle(Geom_Curve)& C3d,
                                    Standard_Real& cf, Standard_Real& cl,
                                    const Standard_Boolean orient) const
{
  TopLoc_Location L;
  C3d = BRep_Tool::Curve (edge, L, cf, cl);
  if( !C3d.IsNull() && !L.IsIdentity() ) {
    C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L.Transformation()));
    cf = C3d->TransformedParameter(cf, L.Transformation());
    cl = C3d->TransformedParameter(cl, L.Transformation());
  }
  if (orient) {
    if (edge.Orientation() == TopAbs_REVERSED)
      {Standard_Real tmp = cf; cf = cl; cl = tmp;}
  }
  return !C3d.IsNull();
}


//=======================================================================
//function : IsClosed3d
//purpose  : 
//=======================================================================

00125 Standard_Boolean ShapeAnalysis_Edge::IsClosed3d (const TopoDS_Edge& edge) const
{
  Standard_Real cf,cl;
  Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,cf,cl);
  if (c3d.IsNull()) return Standard_False;
  if (!c3d->IsClosed()) return Standard_False;
  return FirstVertex (edge).IsSame (LastVertex (edge));
}


//=======================================================================
//function : HasPCurve
//purpose  : 
//=======================================================================

00140 Standard_Boolean ShapeAnalysis_Edge::HasPCurve (const TopoDS_Edge& edge,
                                    const TopoDS_Face& face) const
{
  TopLoc_Location L;
  const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
  return HasPCurve (edge, S, L);
}


//=======================================================================
//function : HasPCurve
//purpose  : 
//=======================================================================

00154 Standard_Boolean ShapeAnalysis_Edge::HasPCurve (const TopoDS_Edge& edge,
                                    const Handle(Geom_Surface)& surface,
                                    const TopLoc_Location& location) const
{
  //try { //szv#4:S4163:12Mar99 waste try
    Standard_Real cf, cl;
    Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface (edge, surface, location, cf, cl);
    return !c2d.IsNull();
  /* }
  catch (Standard_Failure) {
  }
  return Standard_False; */
}


//=======================================================================
//function : PCurve
//purpose  : 
//=======================================================================

Standard_Boolean ShapeAnalysis_Edge::PCurve (const TopoDS_Edge& edge,
                                   const TopoDS_Face& face,
                                   Handle(Geom2d_Curve)& C2d,
                                   Standard_Real& cf, Standard_Real& cl,
                                   const Standard_Boolean orient) const
{
  //:abv 20.05.02: take into account face orientation
  // COMMENTED BACK - NEEDS MORE CHANGES IN ALL SHAPEHEALING
//   C2d = BRep_Tool::CurveOnSurface (edge, face, cf, cl);
//   if (orient && edge.Orientation() == TopAbs_REVERSED) {
//     Standard_Real tmp = cf; cf = cl; cl = tmp;
//   }
//   return !C2d.IsNull();
  TopLoc_Location L;
  const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
  return PCurve (edge, S, L, C2d, cf, cl, orient);
}


//=======================================================================
//function : PCurve
//purpose  : 
//=======================================================================

00198 Standard_Boolean ShapeAnalysis_Edge::PCurve (const TopoDS_Edge& edge,
                                   const Handle(Geom_Surface)& surface,
                                   const TopLoc_Location& location,
                                   Handle(Geom2d_Curve)& C2d,
                                   Standard_Real& cf, Standard_Real& cl,
                                   const Standard_Boolean orient) const
{
  C2d = BRep_Tool::CurveOnSurface (edge, surface, location, cf, cl);
  if ( orient && edge.Orientation() == TopAbs_REVERSED ) {
    Standard_Real tmp = cf; cf = cl; cl = tmp;
  }
  return !C2d.IsNull();
}


//=======================================================================
//function : IsSeam
//purpose  : 
//=======================================================================

Standard_Boolean ShapeAnalysis_Edge::IsSeam (const TopoDS_Edge& edge,
                                   const TopoDS_Face& face) const
{
  return BRep_Tool::IsClosed (edge, face);
}


//=======================================================================
//function : IsSeam
//purpose  : 
//=======================================================================

00230 Standard_Boolean ShapeAnalysis_Edge::IsSeam (const TopoDS_Edge& edge,
                                   const Handle(Geom_Surface)& surface,
                                   const TopLoc_Location& location) const
{
  return BRep_Tool::IsClosed (edge, surface, location);
}


//=======================================================================
//function : FirstVertex
//purpose  : 
//=======================================================================

00243 TopoDS_Vertex ShapeAnalysis_Edge::FirstVertex (const TopoDS_Edge& edge) const
{
  TopoDS_Vertex V;
  if (edge.Orientation() == TopAbs_REVERSED) {
    V = TopExp::LastVertex(edge);
    V.Reverse();
  }
  else {
    V = TopExp::FirstVertex (edge);
  }
  return V;
}


//=======================================================================
//function : LastVertex
//purpose  : 
//=======================================================================

00262 TopoDS_Vertex ShapeAnalysis_Edge::LastVertex (const TopoDS_Edge& edge) const
{
  TopoDS_Vertex V;
  if (edge.Orientation() == TopAbs_REVERSED) {
    V = TopExp::FirstVertex(edge);
    V.Reverse();
  }
  else {
    V = TopExp::LastVertex (edge);
  }
  return V;
}


//=======================================================================
//function : Status
//purpose  : 
//=======================================================================

00281 Standard_Boolean ShapeAnalysis_Edge::Status (const ShapeExtend_Status Status) const
{
  return ShapeExtend::DecodeStatus (myStatus, Status);
}


//=======================================================================
//function : GetEndTangent2d
//purpose  : 
//=======================================================================

Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d (const TopoDS_Edge &edge, 
                                          const TopoDS_Face &face,
                                          const Standard_Boolean atend1, /* skl : change "atend" to "atend1" */ 
                                          gp_Pnt2d &pnt, 
                                          gp_Vec2d &v,
                                                      const Standard_Real dparam) const
{
  TopLoc_Location L;
  const Handle(Geom_Surface) S = BRep_Tool::Surface ( face, L );
  return GetEndTangent2d ( edge, S, L, atend1, pnt, v, dparam );
}


//=======================================================================
//function : GetEndTangent2d
//purpose  : 
//=======================================================================

00310 Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d (const TopoDS_Edge &edge, 
                                          const Handle(Geom_Surface)& S,
                                          const TopLoc_Location& L,
                                          const Standard_Boolean atend2, /* skl : change "atend" to "atend2" */
                                          gp_Pnt2d &pnt, 
                                          gp_Vec2d &v,
                                                      const Standard_Real dparam) const
{
  Standard_Real cf, cl;
  Handle(Geom2d_Curve) c2d;
  if ( ! PCurve ( edge, S, L, c2d, cf, cl ) ) {
    v = gp_Vec2d(0,0);
    return Standard_False;
  }
  Standard_Real dpnew = dparam;

  if(dpnew>Precision::Confusion()) {
    gp_Pnt2d ptmp;
    Standard_Real par1,par2,delta=(cl-cf)*dpnew;
    if(Abs(delta)<Precision::PConfusion()) {
      dpnew=0.0;
    }
    else {
      if(atend2) {
        par1 = cl;
        par2 = cl - delta;
        c2d->D0(par1,pnt);
        c2d->D0(par2,ptmp);
        v = pnt.XY() - ptmp.XY();
      }
      else {
        par1 = cf;
        par2 = cf + delta;
        c2d->D0(par1,pnt);
        c2d->D0(par2,ptmp);
        v = ptmp.XY() - pnt.XY();
      }
      if( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
        dpnew=0.0;
      }
    }
  }
  
  if(dpnew<=Precision::Confusion()) {
    // get non-null tangency searching until 3rd derivative, or as straight btw ends
    Standard_Real par = ( atend2 ? cl : cf );
    c2d->D1 ( par, pnt, v );
    if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
      gp_Vec2d d1;
      c2d->D2 ( par, pnt, d1, v );
      if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
        gp_Vec2d d2;
        c2d->D3 ( par, pnt, d1, d2, v );
        if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
          gp_Pnt2d p2;
          c2d->D0 ( ( atend2 ? cf : cl ), p2 );
          v = p2.XY() - pnt.XY();
          if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() )
            return Standard_False;
        }
      }
    }
    if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse();
  }

  //if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse();
  return Standard_True;
}
          

//=======================================================================
//function : CheckCurve3dWithPCurve
//purpose  : 
//=======================================================================

Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve (const TopoDS_Edge& edge,
                                               const TopoDS_Face& face) 
{
  TopLoc_Location L;
  const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
  return CheckCurve3dWithPCurve (edge, S, L);
}


//=======================================================================
//function : CheckCurve3dWithPCurve
//purpose  : 
//=======================================================================

00399 Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve (const TopoDS_Edge& edge,
                                               const Handle(Geom_Surface)& surface,
                                               const TopLoc_Location& location) 
{
  myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);

  if(surface->IsKind(STANDARD_TYPE(Geom_Plane)))
     return Standard_False;
  
  Handle (Geom2d_Curve) c2d;
  Standard_Real f2d, l2d; //szv#4:S4163:12Mar99 moved down f3d, l3d
  if (!PCurve (edge, surface, location, c2d, f2d ,l2d, Standard_False)) {
    myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
    return Standard_False;
  }

  Handle (Geom_Curve) c3d; //szv#4:S4163:12Mar99 moved
  Standard_Real f3d, l3d; //szv#4:S4163:12Mar99 moved
  if (!Curve3d (edge, c3d, f3d, l3d, Standard_False)) {
    myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
    return Standard_False;
  }

  Standard_Real preci1 = BRep_Tool::Tolerance (FirstVertex (edge)),
                preci2 = BRep_Tool::Tolerance (LastVertex (edge));

  gp_Pnt2d p2d1 = c2d->Value (f2d),
           p2d2 = c2d->Value (l2d);

  //#39 rln 17.11.98 S4054, annie_surf.igs entity 39
  return CheckPoints (c3d->Value (f3d)/*.Transformed (location.Transformation())*/,
                  c3d->Value (l3d)/*.Transformed (location.Transformation())*/,
                  surface->Value (p2d1.X(), p2d1.Y()).Transformed (location.Transformation()),
                  surface->Value (p2d2.X(), p2d2.Y()).Transformed (location.Transformation()),
                  preci1, preci2);
}


//=======================================================================
//function : CheckPoints
//purpose  : 
//=======================================================================

00442 Standard_Boolean ShapeAnalysis_Edge::CheckPoints (const gp_Pnt& P1A,
                                      const gp_Pnt& P1B,
                                      const gp_Pnt& P2A,
                                      const gp_Pnt& P2B,
                                      const Standard_Real preci1,
                                      const Standard_Real preci2) 
{
  myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
  if (P1A.SquareDistance (P2A) <= preci1 * preci1 &&
      P1B.SquareDistance (P2B) <= preci2 * preci2)
    return Standard_False;
  else if (P1A.Distance (P2B) + (P1B.Distance (P2A)) <
         P1A.Distance (P2A) + (P1B.Distance (P2B)))
    myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
  return Standard_True;
}


//=======================================================================
//function : CheckVerticesWithCurve3d
//purpose  : 
//=======================================================================

00465 Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithCurve3d (const TopoDS_Edge& edge,
                                                 const Standard_Real preci,
                                                 const Standard_Integer vtx)
{
  myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);

  TopoDS_Vertex V1 = FirstVertex (edge);
  TopoDS_Vertex V2 = LastVertex (edge);
  gp_Pnt p1v = BRep_Tool::Pnt (V1);
  gp_Pnt p2v = BRep_Tool::Pnt (V2);

  Standard_Real cf,cl;
  Handle(Geom_Curve) c3d;
  if ( ! Curve3d (edge,c3d,cf,cl) ) {
    myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
    return Standard_False;
  }

  //  on va faire les checks ...
  if (vtx != 2) {
    //  1er VTX
    gp_Pnt p13d = c3d->Value(cf);
    //szv#4:S4163:12Mar99 optimized
    if (p1v.Distance(p13d) > (preci < 0 ? BRep_Tool::Tolerance (V1) : preci))
      myStatus |= ShapeExtend_DONE1;
  }

  if (vtx != 1) {
    //  2me VTX
    gp_Pnt p23d = c3d->Value(cl);
    //szv#4:S4163:12Mar99 optimized
    if (p2v.Distance(p23d) > (preci < 0 ? BRep_Tool::Tolerance (V2) : preci))
      myStatus |= ShapeExtend_DONE2;
  }

  return Status ( ShapeExtend_DONE );
}


//=======================================================================
//function : CheckVerticesWithPCurve
//purpose  : 
//=======================================================================

Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve (const TopoDS_Edge& edge,
                                                const TopoDS_Face& face,
                                                const Standard_Real preci,
                                                const Standard_Integer vtx)
{
  TopLoc_Location L;
  const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
  return CheckVerticesWithPCurve (edge, S, L, preci, vtx); //szv#4:S4163:12Mar99 `vtx,preci` wrong parameters order
}


//=======================================================================
//function : CheckVerticesWithPCurve
//purpose  : 
//=======================================================================

00525 Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve (const TopoDS_Edge& edge,
                                                const Handle(Geom_Surface)& surf,
                                                const TopLoc_Location& loc,
                                                const Standard_Real preci,
                                                const Standard_Integer vtx)
{
  myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);

  TopoDS_Vertex V1 = FirstVertex (edge);
  TopoDS_Vertex V2 = LastVertex (edge);
  gp_Pnt p1v = BRep_Tool::Pnt (V1);
  gp_Pnt p2v = BRep_Tool::Pnt (V2);

  Standard_Real cf, cl;
  Handle(Geom2d_Curve) c2d;
  if ( ! PCurve ( edge, surf, loc, c2d, cf, cl ) ) {
    myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
    return Standard_False;
  }

  // on va faire les checks ...
  if (vtx != 2) { //  1er VTX
    gp_Pnt2d p1uv = c2d->Value (cf);  
    gp_Pnt p12d = surf->Value (p1uv.X(), p1uv.Y());
    // szv#4:S4163:12Mar99 optimized
    if ( p1v.Distance(p12d) > (preci < 0 ? BRep_Tool::Tolerance (V1) : preci) )
      myStatus |= ShapeExtend_DONE1;
  }

  if (vtx != 1) { //  2me VTX
    gp_Pnt2d p2uv = c2d->Value (cl);  
    gp_Pnt p22d = surf->Value (p2uv.X(), p2uv.Y());
    // szv#4:S4163:12Mar99 optimized
    if ( p2v.Distance(p22d) > (preci < 0 ? BRep_Tool::Tolerance (V2) : preci) )
      myStatus |= ShapeExtend_DONE2;
  }

  return Status ( ShapeExtend_DONE );
}


//=======================================================================
//function : CheckVertexTolerance
//purpose  : 
//=======================================================================

static Standard_Integer CheckVertexTolerance(const TopoDS_Edge& edge,
                                             const TopoDS_Face& face,
                                             const Standard_Boolean checkAll,
                                             Standard_Real& toler1,
                                             Standard_Real& toler2)
{
  Standard_Integer Status = ShapeExtend::EncodeStatus ( ShapeExtend_OK );

  ShapeAnalysis_Edge sae;
  TopoDS_Vertex V1 = sae.FirstVertex (edge);
  TopoDS_Vertex V2 = sae.LastVertex (edge);
  if ( V1.IsNull() || V2.IsNull() ) { //:p1 abv 22 Feb 99: r76sy.stp
    Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
    return Status;
  }

  Standard_Real old1 = BRep_Tool::Tolerance (V1);
  Standard_Real old2 = BRep_Tool::Tolerance (V2);
  gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
  gp_Pnt pnt2 = BRep_Tool::Pnt (V2);

  Standard_Real a, b;
  Handle(Geom_Curve) c3d;
  if ( ! sae.Curve3d(edge, c3d, a, b, Standard_True)) {
    if ( ! BRep_Tool::Degenerated ( edge ) ) 
      Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
    toler1 = toler2 = 0.;
//    return Standard_False;
  }
  else {
    toler1 = pnt1.SquareDistance (c3d->Value (a));
    toler2 = pnt2.SquareDistance (c3d->Value (b));
  }

  if ( checkAll ) {
    Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
    for (BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); itcr.More(); itcr.Next() ) {
      Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
      if (GC.IsNull() || !GC->IsCurveOnSurface()) continue;
      Handle(Geom2d_Curve) pcurve;
      Handle(Geom_Surface) S = GC->Surface();
      TopLoc_Location L = edge.Location() * GC->Location();
      sae.PCurve (edge, S, L, pcurve, a, b, Standard_True);
      gp_Pnt2d p1 = pcurve->Value (a);
      gp_Pnt2d p2 = pcurve->Value (b);
      gp_Pnt P1 = S->Value (p1.X(), p1.Y()).Transformed (L.Transformation());
      gp_Pnt P2 = S->Value (p2.X(), p2.Y()).Transformed (L.Transformation());
      toler1 = Max (toler1, pnt1.SquareDistance (P1));
      toler2 = Max (toler2, pnt2.SquareDistance (P2));
    }
  }
  //:abv 10.06.02: porting C40 -> dev (CC670-12608.stp)
  // Check with given face is needed for plane surfaces (if no stored pcurves)
  else if ( ! face.IsNull() ) {
    Handle(Geom2d_Curve) pcurve;
    TopLoc_Location L;
    const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
    if ( sae.PCurve(edge, S, L, pcurve, a, b, Standard_True)) {
      gp_Pnt2d p1 = pcurve->Value (a);
      gp_Pnt2d p2 = pcurve->Value (b);
      gp_Pnt P1 = S->Value (p1.X(), p1.Y()).Transformed (L.Transformation());
      gp_Pnt P2 = S->Value (p2.X(), p2.Y()).Transformed (L.Transformation());
      toler1 = Max (toler1, pnt1.SquareDistance (P1));
      toler2 = Max (toler2, pnt2.SquareDistance (P2));
    }
    else Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
  }

  //:o8 abv 19 Feb 99: CTS18541.stp #18559: coeff 1.0001 added
  //szv 18 Aug 99: edge tolerance is taken in consideration
  Standard_Real tole = BRep_Tool::Tolerance (edge);
  toler1 = Max (1.0000001 * Sqrt (toler1), tole);
  toler2 = Max (1.0000001 * Sqrt (toler2), tole);
  if ( toler1 > old1) 
    Status |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
  if ( toler2 > old2) 
    Status |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2);

  return Status;
}


//=======================================================================
//function : CheckVertexTolerance
//purpose  : 
//=======================================================================

Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge,
                                            const TopoDS_Face& face,
                                                          Standard_Real& toler1,
                                                          Standard_Real& toler2)
{
  myStatus = ::CheckVertexTolerance ( edge, face, Standard_False, toler1, toler2 );
  return Status ( ShapeExtend_DONE );
}


//=======================================================================
//function : CheckVertexTolerance
//purpose  : 
//=======================================================================

00673 Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge,
                                                          Standard_Real& toler1,
                                                          Standard_Real& toler2)
{
  TopoDS_Face F;
  myStatus = ::CheckVertexTolerance ( edge, F, Standard_True, toler1, toler2 );
  return Status ( ShapeExtend_DONE );
}


//=======================================================================
//static : Validate
//purpose: For SameParameter: compute it for two curves
//note: This function is made from Validate() in BRepCheck_Edge.cxx
//=======================================================================

static Standard_Boolean ComputeDeviation (const Adaptor3d_Curve& CRef,
                                const Adaptor3d_Curve& Other,
                                const Standard_Boolean SameParameter,
                                Standard_Real &dev,
                                const Standard_Integer NCONTROL)
{
  Standard_Boolean OK = Standard_True;
  Standard_Real dev2 = dev*dev;
  
  Standard_Real First = CRef.FirstParameter(), Last = CRef.LastParameter();
  Standard_Real OFirst = Other.FirstParameter(), OLast  = Other.LastParameter(); //szv#4:S4163:12Mar99 moved

  Standard_Boolean proj = (!SameParameter || First != OFirst || Last != OLast); //szv#4:S4163:12Mar99 optimized

  Standard_Integer NCtrl = ( NCONTROL < 1 )? 1 : NCONTROL; //szv#4:S4163:12Mar99 anti-exception

  if (!proj) {
    for (Standard_Integer i = 0; i <= NCtrl; i++) {
      Standard_Real prm = ((NCtrl-i)*First + i*Last)/NCtrl;
      gp_Pnt pref = CRef.Value(prm);
      gp_Pnt pother = Other.Value(prm);
      Standard_Real dist2 = pref.SquareDistance(pother);
      if ( dev2 < dist2 ) dev2 = dist2; 
    }
    dev = Sqrt ( dev2 );
  }
  else {
    gp_Pnt pd = CRef.Value(First);
    gp_Pnt pdo = Other.Value(OFirst);
    Standard_Real dist2 = pd.SquareDistance(pdo);
    if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 );

    pd = CRef.Value(Last);
    pdo = Other.Value(OLast);
    dist2 = pd.SquareDistance(pdo);
    if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 );

    Extrema_LocateExtPC refd, otherd; //szv#4:S4163:12Mar99 warning
    refd.Initialize(CRef,First,Last,Precision::PConfusion());
    otherd.Initialize(Other,OFirst,OLast,Precision::PConfusion());

    for (Standard_Integer i = 1; i < NCtrl; i++) { //szv#4:S4163:12Mar99 was bug
      Standard_Real rprm = ((NCtrl-i)*First + i*Last)/NCtrl;
      gp_Pnt pref = CRef.Value(rprm);
      Standard_Real oprm = ((NCtrl-i)*OFirst + i*OLast)/NCtrl;
      gp_Pnt pother = Other.Value(oprm);

      refd.Perform(pother,rprm);
      if ( ! refd.IsDone() ) OK = Standard_False;
      else if ( dev < refd.Value() ) dev = refd.Value();

      otherd.Perform(pref,oprm);
      if ( ! otherd.IsDone() ) OK = Standard_False;
      else if ( dev < otherd.Value() ) dev = otherd.Value();
    }
  }
  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
  
  return OK;
}


//=======================================================================
//function : CheckSameParameter
//purpose  : 
//=======================================================================

00756 Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge,
                                              Standard_Real& maxdev,
                                              const Standard_Integer NbControl)
{
  myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
  if (BRep_Tool::Degenerated (edge)) return Standard_False;

  maxdev = 0;
  
  Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
  Standard_Boolean SameParameter = TE->SameParameter();

  GeomAdaptor_Curve AC3d;

  // find 3d curve
  BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
  for ( ; itcr.More(); itcr.Next() ) {
    Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
    if ( GC.IsNull() || ! GC->IsCurve3D() ) continue;
    Handle(Geom_Curve) C3d = GC->Curve3D();
    if ( C3d.IsNull() ) continue; //:s1 abv 22 Apr 99: PRO7226 #489490
    TopLoc_Location loc = GC->Location();
    if ( ! loc.IsIdentity() )
      C3d = Handle(Geom_Curve)::DownCast ( C3d->Transformed ( loc ) );
    else C3d = Handle(Geom_Curve)::DownCast ( C3d->Copy() ); //:s4 abv 26 Apr 99: sim6049.igs 21677: necessary to get True SP (!!?)
    Standard_Real First, Last;
    GC->Range ( First, Last );
    AC3d.Load ( C3d, First, Last );
    break;
  }

  if ( ! itcr.More() ) {
    myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
    return Standard_False;
  }

  // iterate on pcurves
  itcr.Initialize ( TE->Curves() );
  for ( ; itcr.More(); itcr.Next() ) {
    Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
    if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;

    Standard_Real f, l;
    GC->Range ( f, l );
    Handle(Geom_Surface) Su = GC->Surface();
    TopLoc_Location loc = GC->Location();
    if (!loc.IsIdentity())
      Su = Handle(Geom_Surface)::DownCast ( Su->Transformed ( loc ) );
    Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Su);
    
    Handle(Geom2d_Curve) PC = GC->PCurve();
    Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
    //Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
    Adaptor3d_CurveOnSurface ACS;
    ACS.Load(GHPC);
    ACS.Load(GAHS);
    if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) ) {
      myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
    }

    if ( GC->IsCurveOnClosedSurface() ) {
      GHPC->ChangeCurve2d().Load ( GC->PCurve2(), f, l ); // same bounds
      ACS.Load(GAHS); // sans doute inutile
      ACS.Load(GHPC); // meme remarque...
      if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) ) {
      myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
      }
    }
  }
  
  if ( maxdev > TE->Tolerance() ) 
    myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
  if ( ! SameParameter ) 
    myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );

  return Status ( ShapeExtend_DONE );
}


//=======================================================================
//function : IsOverlapPartEdges
//purpose  : 
//=======================================================================

static Standard_Boolean IsOverlapPartEdges(const TopoDS_Edge& theFirstEdge,
                                           const TopoDS_Edge& theSecEdge,
                                           const Standard_Real& theTolerance,
                                           const Standard_Real& theStep,
                                           const Standard_Real& theStartLength,
                                           const Standard_Real& theEndLenght)
{
  TColStd_SequenceOfInteger aSeqIntervals;
  BRepAdaptor_Curve aAdCurve1(theFirstEdge);

  BRepExtrema_DistShapeShape aMinDist;
  aMinDist.LoadS1(theSecEdge);

  for(Standard_Real aS = theStartLength; aS <= theEndLenght; aS+=theStep/2) {
    
    gp_Pnt aPoint;
    if(aS <= Precision::Confusion()) {
      TopoDS_Vertex V1 =  TopExp::FirstVertex(theFirstEdge,Standard_True);
      aPoint = BRep_Tool::Pnt(V1);
    }
    else {
      GCPnts_AbscissaPoint aAbsPoint(Precision::Confusion(),aAdCurve1,aS,aAdCurve1.FirstParameter());
      if(aAbsPoint.IsDone()) 
        aAdCurve1.D0(aAbsPoint.Parameter(),aPoint);
      else continue;
    }
    BRep_Builder aB;
    TopoDS_Vertex aV;
    aB.MakeVertex(aV,aPoint,Precision::Confusion());
    aMinDist.LoadS2(aV);
    aMinDist.Perform();
    if( aMinDist.IsDone() && aMinDist.Value() >= theTolerance)
      return Standard_False;
  }
  return Standard_True;
}


//=======================================================================
//function : CheckOverlapping
//purpose  : 
//=======================================================================

00883 Standard_Boolean ShapeAnalysis_Edge::CheckOverlapping(const TopoDS_Edge& theEdge1,
                                                      const TopoDS_Edge& theEdge2,
                                                      Standard_Real& theTolOverlap,
                                                      const Standard_Real theDomainDist) 
{
  Standard_Boolean isOverlap = Standard_False;
  BRepAdaptor_Curve aAdCurve1(theEdge1);
  Standard_Real aLength1 = GCPnts_AbscissaPoint::Length (aAdCurve1);
  BRepAdaptor_Curve aAdCurve2(theEdge2);
  Standard_Real aLength2 = GCPnts_AbscissaPoint::Length (aAdCurve2);
  TopoDS_Edge aFirstEdge = (aLength1 >= aLength2 ? theEdge2: theEdge1);
  TopoDS_Edge aSecEdge = (aLength1 >= aLength2 ? theEdge1: theEdge2);
  Standard_Real aLength = Min(aLength1,aLength2);
  
  //check overalpping between edges on whole edges
  Standard_Real aStep = Min(aLength1,aLength2)/2;
  isOverlap = IsOverlapPartEdges(aFirstEdge,aSecEdge,theTolOverlap,aStep,0.,Min(aLength1,aLength2)); 
  
  if(isOverlap)    {
    myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3);
    return isOverlap;
  }
  if(theDomainDist ==0.0)
    return isOverlap;
  
  //check overalpping between edges on segment with length less than theDomainDist
  
  Standard_Real aDomainTol = (theDomainDist > Min( aLength1,aLength2) ? Min( aLength1,aLength2) :theDomainDist);
  BRepExtrema_DistShapeShape aMinDist(aFirstEdge,aSecEdge,theTolOverlap);
  Standard_Real aresTol = theTolOverlap;
  if(aMinDist.IsDone()) {
    aresTol = aMinDist.Value();
    if(aresTol >= theTolOverlap) return Standard_False;
    Standard_Integer NbSol = aMinDist.NbSolution();
    for(Standard_Integer i =1; i<= NbSol && !isOverlap; i++) {
      BRepExtrema_SupportType aType1 = aMinDist.SupportTypeShape1(i);
      Standard_Real aEndLength, aStartLength, aLengthP; 
      if(aType1 == BRepExtrema_IsVertex) {
        TopoDS_Shape aSupportShape1 = aMinDist.SupportOnShape1(i);
        TopoDS_Vertex aV1,aV2;
        TopExp::Vertices (aFirstEdge, aV1, aV2, Standard_True);
        if( aV1.IsSame(aSupportShape1)) 
          aLengthP = 0.0;
        else
          aLengthP =aLength;
      }
      else if(aType1 == BRepExtrema_IsOnEdge) {
        Standard_Real aParam1, aFirst, aLast;
        aMinDist.ParOnEdgeS1 ( i, aParam1 );
        BRep_Tool::Range(aFirstEdge,aFirst,aLast);
        BRepAdaptor_Curve anAdaptor(aFirstEdge);
        aLengthP = GCPnts_AbscissaPoint::Length(anAdaptor,aFirst,aParam1);
      }
      else continue;
      aStartLength = aLengthP - aDomainTol/2;
      if( aStartLength <0.0) {
        aStartLength =0;
        aEndLength = aDomainTol;
      }
      aEndLength = aLengthP + aDomainTol/2;
      if(aEndLength > aLength) {
        aEndLength = aLength;
        aStartLength = aEndLength - aDomainTol;
      }
      aStep = (aEndLength - aStartLength)/5;
      isOverlap = (IsOverlapPartEdges(aFirstEdge,aSecEdge,theTolOverlap,aStep,aStartLength,aEndLength));
    }
  }
  if(isOverlap)    
    myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4);
   
  theTolOverlap = aresTol;
   return isOverlap;
}

Generated by  Doxygen 1.6.0   Back to index