1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00
occt/src/BOPTools/BOPTools_AlgoTools2D.cxx
pkv 9c0b61f308 0025285: Wrong result of General Fuse operation for an edge and a face.
Changes:
class BOPTools_AlgoTools2D
    method:
void BOPTools_AlgoTools2D::AdjustPCurveOnFace
  (const TopoDS_Face& aF,
   const Standard_Real aFirst,
   const Standard_Real aLast,
   const Handle(Geom2d_Curve)& aC2D,
   Handle(Geom2d_Curve)& aC2DA)

The adjustment value for 2D curve has been calrified with precision value in parametric space

Test case for issue CR25285
2014-10-02 14:11:16 +04:00

840 lines
25 KiB
C++

// Created by: Peter KURNEV
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BOPTools_AlgoTools2D.ixx>
#include <Standard_NotImplemented.hxx>
#include <Precision.hxx>
#include <gp.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2d_Circle.hxx>
#include <Geom2d_Ellipse.hxx>
#include <Geom2d_Parabola.hxx>
#include <Geom2d_Hyperbola.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dAdaptor.hxx>
#include <Geom_Curve.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_Surface.hxx>
#include <Geom_Plane.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <GeomProjLib.hxx>
#include <TopLoc_Location.hxx>
#include <TopExp.hxx>
#include <ProjLib_ProjectedCurve.hxx>
#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_CurveRepresentation.hxx>
#include <BRep_GCurve.hxx>
#include <BRepAdaptor_HSurface.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <BRepTools.hxx>
#include <BOPCol_IndexedMapOfShape.hxx>
#include <BOPTools.hxx>
#include <IntTools_Tools.hxx>
#include <gp_Cylinder.hxx>
#include <TopExp_Explorer.hxx>
#include <GeomInt.hxx>
static
Standard_Boolean CheckEdgeLength (const TopoDS_Edge& );
static
Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& ,
const TopoDS_Face& ,
Standard_Real& ,
Standard_Real& ,
Standard_Boolean& );
static
Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& ,
const Handle(Geom_Surface)& ,
const TopLoc_Location& ,
Standard_Real& ,
Standard_Real& ,
Standard_Boolean& );
static
Standard_Real MaxToleranceEdge (const TopoDS_Face& );
//=======================================================================
//function : BuildPCurveForEdgeOnFace
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
const TopoDS_Face& aF)
{
BRep_Builder aBB;
Handle(Geom2d_Curve) aC2D;
Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast;
Standard_Boolean aHasOld;
aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D,
aFirst, aLast,
aTolEdge);
if (aHasOld) {
return;
}
BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC);
aTolEdge=BRep_Tool::Tolerance(aE);
aTolFact=Max(aTolEdge, aTolPC);
aBB.UpdateEdge(aE, aC2D, aF, aTolFact);
return;
}
//=======================================================================
//function : EdgeTangent
//purpose :
//=======================================================================
Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent
(const TopoDS_Edge& anEdge,
const Standard_Real aT,
gp_Vec& aTau)
{
Standard_Boolean isdgE;
Standard_Real first, last;
isdgE = BRep_Tool::Degenerated(anEdge);
if (isdgE) {
return Standard_False;
}
if (!CheckEdgeLength(anEdge)) {
return Standard_False;
}
Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
gp_Pnt aP;
aC->D1(aT, aP, aTau);
Standard_Real mod = aTau.Magnitude();
if(mod > gp::Resolution()) {
aTau /= mod;
}
else {
return Standard_False;
}
//aTau.Normalize();
if (anEdge.Orientation() == TopAbs_REVERSED){
aTau.Reverse();
}
return Standard_True;
}
//=======================================================================
//function : PointOnOnSurface
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE,
const TopoDS_Face& aF,
const Standard_Real aParameter,
Standard_Real& U,
Standard_Real& V)
{
gp_Pnt2d aP2D;
Handle(Geom2d_Curve) aC2D;
Standard_Real aToler, aFirst, aLast;
BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D,
aFirst, aLast, aToler);
aC2D->D0(aParameter, aP2D);
U=aP2D.X();
V=aP2D.Y();
return;
}
//=======================================================================
//function : CurveOnSurface
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
const TopoDS_Face& aF,
Handle(Geom2d_Curve)& aC2D,
Standard_Real& aToler)
{
Standard_Real aFirst, aLast;
//
BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D,
aFirst, aLast, aToler);
//
return;
}
//=======================================================================
//function : CurveOnSurface
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
const TopoDS_Face& aF,
Handle(Geom2d_Curve)& aC2D,
Standard_Real& aFirst,
Standard_Real& aLast,
Standard_Real& aToler)
{
Standard_Boolean aHasOld;
Handle(Geom2d_Curve) C2D;
aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D,
aFirst, aLast,
aToler);
if (aHasOld) {
aC2D=C2D;
return;
}
BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler);
aC2D=C2D;
return;
}
//=======================================================================
//function : HasCurveOnSurface
//purpose :
//=======================================================================
Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface
(const TopoDS_Edge& aE,
const TopoDS_Face& aF,
Handle(Geom2d_Curve)& aC2D,
Standard_Real& aFirst,
Standard_Real& aLast,
Standard_Real& aToler)
{
Standard_Boolean aHasOld;
aToler=BRep_Tool::Tolerance(aE);
BRep_Tool::Range(aE, aFirst, aLast);
if((aLast - aFirst) < Precision::PConfusion()) {
return Standard_False;
}
aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
aHasOld=!aC2D.IsNull();
return aHasOld;
}
//=======================================================================
//function : HasCurveOnSurface
//purpose :
//=======================================================================
Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface
(const TopoDS_Edge& aE,
const TopoDS_Face& aF)
{
Standard_Boolean bHasOld;
Handle(Geom2d_Curve) aC2D;
Standard_Real aFirst, aLast;
//
BRep_Tool::Range(aE, aFirst, aLast);
//
if((aLast - aFirst) < Precision::PConfusion()) {
return Standard_False;
}
//
aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
bHasOld=!aC2D.IsNull();
//
return bHasOld;
}
//=======================================================================
//function : AdjustPCurveOnFace
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::AdjustPCurveOnFace
(const TopoDS_Face& aF,
const Handle(Geom_Curve)& aC3D,
const Handle(Geom2d_Curve)& aC2D,
Handle(Geom2d_Curve)& aC2DA)
{
Standard_Real first, last;
first = aC3D -> FirstParameter();
last = aC3D -> LastParameter();
BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, first, last, aC2D, aC2DA);
}
//=======================================================================
//function : AdjustPCurveOnFace
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::AdjustPCurveOnFace
(const TopoDS_Face& aF,
const Standard_Real aFirst,
const Standard_Real aLast,
const Handle(Geom2d_Curve)& aC2D,
Handle(Geom2d_Curve)& aC2DA)
{
Standard_Boolean mincond, maxcond;
Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
Standard_Real aUPeriod;
//
aDelta=Precision::PConfusion();
BRepAdaptor_Surface aBAS(aF, Standard_False);
BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
aT =.5*(aFirst+aLast);
gp_Pnt2d pC2D;
aC2D->D0(aT, pC2D);
u2 = pC2D.X();
v2 = pC2D.Y();
//
// du
du = 0.;
if (aBAS.IsUPeriodic()) {
Standard_Real u2x;
aUPeriod = aBAS.UPeriod();
//
// A. drive u2 into the stall [Umin, Umin+aUPeriod] -> u2x
GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2x, du, 0.);
//
// b. try to clarify u2 using the precision (aDelta)
if (fabs(u2x-UMin) < aDelta) {
u2=UMin;
}
else if (fabs(u2x-UMin-aUPeriod) < aDelta) {
u2=UMin+aUPeriod;
}
// C. compute du again using clarified value of u2
GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2x, du, 0.);
//
if (du==0.) {
if (aBAS.GetType()==GeomAbs_Cylinder) {
Standard_Real aR, dFi, aTol;
//
gp_Cylinder aCylinder=aBAS.Cylinder();
aR=aCylinder.Radius();
aTol=MaxToleranceEdge(aF);
dFi=aTol/aR;
if (dFi<aDelta) {
dFi=aDelta;
}
//
mincond = (UMin - u2 > dFi);
maxcond = (u2 - UMax > dFi);
if (mincond || maxcond) {
du = ( mincond ) ? aUPeriod : -aUPeriod;
}
}
}
}
// dv
dv = 0.;
if (aBAS.IsVPeriodic()) {
Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
//
aVPeriod = aBAS.VPeriod();
mincond = (VMin - v2 > aDelta);
maxcond = (v2 - VMax > aDelta);
//
if (mincond || maxcond) {
dv = ( mincond ) ? aVPeriod : -aVPeriod;
}
//
if ((VMax-VMin<aVPeriod) && dv) {
aVm=v2;
aVr=v2+dv;
aVmid=0.5*(VMin+VMax);
dVm=fabs(aVm-aVmid);
dVr=fabs(aVr-aVmid);
if (dVm<dVr) {
dv=0.;
}
}
}
//
{
//check the point with classifier
Standard_Real u,v;
u = u2 + du;
v = v2 + dv;
if (aBAS.IsUPeriodic()) {
aUPeriod = aBAS.UPeriod();
if ((UMax - UMin - 2*aDelta) > aUPeriod) {
if ((u > (UMin + aDelta + aUPeriod)) ||
(u < (UMax - aDelta - aUPeriod))) {
BRepClass_FaceClassifier aClassifier;
aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
TopAbs_State Status = aClassifier.State();
if (Status == TopAbs_OUT) {
du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod;
}
}
}
}
//
u = u2 + du;
if (aBAS.IsVPeriodic()) {
Standard_Real aVPeriod = aBAS.VPeriod();
if ((VMax - VMin - 2*aDelta) > aVPeriod) {
if ((v > (VMin + aDelta + aVPeriod)) ||
(v < (VMax - aDelta - aVPeriod))) {
BRepClass_FaceClassifier aClassifier;
aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
TopAbs_State Status = aClassifier.State();
if (Status == TopAbs_OUT) {
dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod;
}
}
}
}
}
// Translation if necessary
Handle(Geom2d_Curve) aC2Dx=aC2D;
if ( du != 0. || dv != 0.) {
Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
gp_Vec2d aV2D(du,dv);
PCT->Translate(aV2D);
aC2Dx = PCT;
}
aC2DA=aC2Dx;
}
//=======================================================================
//function : IntermediatePoint
//purpose :
//=======================================================================
Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
(const Standard_Real aFirst,
const Standard_Real aLast)
{
//define parameter division number as 10*e^(-PI) = 0.43213918
const Standard_Real PAR_T = 0.43213918;
Standard_Real aParm;
aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
return aParm;
}
//=======================================================================
//function : IntermediatePoint
//purpose :
//=======================================================================
Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
(const TopoDS_Edge& aE)
{
Standard_Real aT, aT1, aT2;
Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
if (aC1.IsNull())
BRep_Tool::Range(aE, aT1, aT2);
aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
return aT;
}
//=======================================================================
//function : BuildPCurveForEdgeOnPlane
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane
(const TopoDS_Edge& aE,
const TopoDS_Face& aF)
{
Standard_Boolean bToUpdate;
Standard_Real aTolE, aT1, aT2;
Handle(Geom2d_Curve) aC2D;
BRep_Builder aBB;
//
aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
if (bToUpdate) {
aTolE=BRep_Tool::Tolerance(aE);
aBB.UpdateEdge(aE, aC2D, aF, aTolE);
}
}
//=======================================================================
// function: BuildPCurveForEdgesOnPlane
// purpose:
//=======================================================================
void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane
(const BOPCol_ListOfShape& aLE,
const TopoDS_Face& aF)
{
BOPCol_ListIteratorOfListOfShape aIt;
//
aIt.Initialize(aLE);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (aE, aF);
}
}
//=======================================================================
//function : Make2D
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
const TopoDS_Face& aF,
Handle(Geom2d_Curve)& aC2D,
Standard_Real& aFirst,
Standard_Real& aLast,
Standard_Real& aToler)
{
Standard_Boolean aLocIdentity;
Standard_Real f3d, l3d;
TopLoc_Location aLoc;
Handle(Geom2d_Curve) C2D;
C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
if (!C2D.IsNull()) {
aC2D=C2D;
return;
}
Handle(Geom_Curve) C3D2, C3D;
C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
//
if (C3D.IsNull()) {
// aE has no 3D curve, so nothing is done
}
//
aLocIdentity=aLoc.IsIdentity();
if (aLocIdentity) {
C3D2 = C3D;
}
else {
C3D2 = Handle(Geom_Curve)::
DownCast(C3D->Transformed(aLoc.Transformation()));
}
//
aToler=.5*BRep_Tool::Tolerance(aE);
BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler);
//
aFirst = f3d;
aLast = l3d;
}
//=======================================================================
//function : MakePCurveOnFace
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
const Handle(Geom_Curve)& aC3D,
Handle(Geom2d_Curve)& aC2D, //->
Standard_Real& TolReached2d)
{
Standard_Real aFirst, aLast;
aFirst = aC3D -> FirstParameter();
aLast = aC3D -> LastParameter();
//
TolReached2d=0.;
//
BOPTools_AlgoTools2D::MakePCurveOnFace (aF, aC3D, aFirst,
aLast, aC2D, TolReached2d);
}
//=======================================================================
//function : MakePCurveOnFace
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::MakePCurveOnFace
(const TopoDS_Face& aF,
const Handle(Geom_Curve)& aC3D,
const Standard_Real aFirst,
const Standard_Real aLast,
Handle(Geom2d_Curve)& aC2D,
Standard_Real& TolReached2d)
{
Standard_Real aTolR;
Handle(Geom2d_Curve) aC2DA;
//
Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
GeomAdaptor_Surface aGAS(aS);
Handle(GeomAdaptor_HSurface) aBAHS=
new GeomAdaptor_HSurface(aGAS);
Handle(GeomAdaptor_HCurve) aBAHC =
new GeomAdaptor_HCurve(aC3D, aFirst, aLast);
//when the type of surface is GeomAbs_SurfaceOfRevolution
if (aGAS.GetType() == GeomAbs_SurfaceOfRevolution) {
Standard_Real aTR = 1.e-7;
ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D);
aTolR = aProj1.GetTolerance();
} else {
ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D);
aTolR=aProjCurv.GetTolerance();
}
//
if (aC2D.IsNull()) {
ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
aTolR = aProjCurvAgain.GetTolerance();
//
if (aC2D.IsNull()) {
Standard_Real aTR=0.0001;
ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D);
aTolR = aProj3.GetTolerance();
}
}
TolReached2d=aTolR;
BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, aFirst, aLast,
aC2D, aC2DA);
aC2D=aC2DA;
}
//=======================================================================
//function : MakePCurveOfType
//purpose :
//=======================================================================
void BOPTools_AlgoTools2D::MakePCurveOfType
(const ProjLib_ProjectedCurve& PC,
Handle(Geom2d_Curve)& C2D)
{
switch (PC.GetType()) {
case GeomAbs_Line :
C2D = new Geom2d_Line(PC.Line());
break;
case GeomAbs_Circle :
C2D = new Geom2d_Circle(PC.Circle());
break;
case GeomAbs_Ellipse :
C2D = new Geom2d_Ellipse(PC.Ellipse());
break;
case GeomAbs_Parabola :
C2D = new Geom2d_Parabola(PC.Parabola());
break;
case GeomAbs_Hyperbola :
C2D = new Geom2d_Hyperbola(PC.Hyperbola());
break;
case GeomAbs_BSplineCurve :
C2D = PC.BSpline();
break;
case GeomAbs_BezierCurve :
case GeomAbs_OtherCurve :
default :
Standard_NotImplemented::Raise
("BOPTools_AlgoTools2D::MakePCurveOfType");
break;
}
}
//=======================================================================
//function : CheckEdgeLength
//purpose :
//=======================================================================
Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
{
BRepAdaptor_Curve BC(E);
BOPCol_IndexedMapOfShape aM;
BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
Standard_Integer i, anExtent, aN=10;
Standard_Real ln=0., d, t, f, l, dt;
anExtent=aM.Extent();
if (anExtent!=1)
return Standard_True;
gp_Pnt p1, p2;
f = BC.FirstParameter();
l = BC.LastParameter();
dt=(l-f)/aN;
BC.D0(f, p1);
for (i=1; i<=aN; i++) {
t=f+i*dt;
if (i==aN)
BC.D0(l, p2);
else
BC.D0(t, p2);
d=p1.Distance(p2);
ln+=d;
p1=p2;
}
//
return (ln > Precision::Confusion());
}
//=======================================================================
//function : BRep_Tool_CurveOnSurface
//purpose :
//=======================================================================
Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E,
const TopoDS_Face& F,
Standard_Real& First,
Standard_Real& Last,
Standard_Boolean& bToUpdate)
{
TopLoc_Location l;
const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
TopoDS_Edge aLocalEdge = E;
if (F.Orientation() == TopAbs_REVERSED) {
aLocalEdge.Reverse();
}
//
return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate);
}
//=======================================================================
//function : BRep_Tool_CurveOnSurface
//purpose :
//=======================================================================
Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
(const TopoDS_Edge& E,
const Handle(Geom_Surface)& S,
const TopLoc_Location& L,
Standard_Real& First,
Standard_Real& Last,
Standard_Boolean& bToUpdate)
{
static const Handle(Geom2d_Curve) nullPCurve;
bToUpdate=Standard_False;
TopLoc_Location loc = L.Predivided(E.Location());
Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
// find the representation
BRep_ListIteratorOfListOfCurveRepresentation itcr
((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
while (itcr.More()) {
const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
if (cr->IsCurveOnSurface(S,loc)) {
const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
GC->Range(First,Last);
if (GC->IsCurveOnClosedSurface() && Eisreversed)
return GC->PCurve2();
else
return GC->PCurve();
}
itcr.Next();
}
// for planar surface and 3d curve try a projection
// modif 21-05-97 : for RectangularTrimmedSurface, try a projection
Handle(Geom_Plane) GP;
Handle(Geom_RectangularTrimmedSurface) GRTS;
GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
if(!GRTS.IsNull())
GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
else
GP = Handle(Geom_Plane)::DownCast(S);
//fin modif du 21-05-97
if (!GP.IsNull()) {
Handle(GeomAdaptor_HCurve) HC;
Handle(GeomAdaptor_HSurface) HS;
HC = new GeomAdaptor_HCurve();
HS = new GeomAdaptor_HSurface();
TopLoc_Location LC;
Standard_Real f, l;// for those who call with (u,u).
Handle(Geom_Curve) C3d =
BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve
// we can loose scale factor of Curve transformation (eap 13 May 2002)
LC = L/*.Predivided(LC)*/;
if (C3d.IsNull()) return nullPCurve;
Handle(Geom_Plane) Plane = GP;
if (!LC.IsIdentity()) {
const gp_Trsf& T = LC.Transformation();
Handle(Geom_Geometry) GPT = GP->Transformed(T);
Plane = *((Handle(Geom_Plane)*)&GPT);
}
GeomAdaptor_Surface& GAS = HS->ChangeSurface();
GAS.Load(Plane);
Handle(Geom_Curve) ProjOnPlane =
GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l),
Plane,
Plane->Position().Direction(),
Standard_True);
GeomAdaptor_Curve& GAC = HC->ChangeCurve();
GAC.Load(ProjOnPlane);
ProjLib_ProjectedCurve Proj(HS,HC);
Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
Handle(Geom2d_TrimmedCurve) TC =
(*((Handle(Geom2d_TrimmedCurve)*)&pc));
pc = TC->BasisCurve();
}
First = f; Last = l;
//
bToUpdate=Standard_True;
//
return pc;
}
return nullPCurve;
}
//=======================================================================
//function : MaxToleranceEdge
//purpose :
//=======================================================================
Standard_Real MaxToleranceEdge (const TopoDS_Face& aF)
{
Standard_Real aTol, aTolMax;
TopExp_Explorer aExp;
//
aTolMax=0.;
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
aTol=BRep_Tool::Tolerance(aE);
if (aTol>aTolMax) {
aTolMax=aTol;
}
}
return aTolMax;
}