Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1993-06-17
// Created by: Jean Yves LEBEY
// Copyright (c) 1993-1999 Matra Datavision
// 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 <TopOpeBRepDS_BuildTool.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <ElCLib.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Conic.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2d_OffsetCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Plane.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <GeomLib.hxx>
#include <gp.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <Precision.hxx>
#include <Standard_ProgramError.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopOpeBRepDS_Dumper.hxx>
#include <TopOpeBRepDS_HDataStructure.hxx>
#include <TopOpeBRepDS_Point.hxx>
#include <TopOpeBRepDS_Surface.hxx>
#include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
#include <TopOpeBRepTool_GeomTool.hxx>
#include <TopOpeBRepTool_OutCurveType.hxx>
#include <TopOpeBRepTool_ShapeTool.hxx>
// includes especially needed by the static Project function
Standard_EXPORT occ::handle<Geom2d_Curve> BASISCURVE2D(const occ::handle<Geom2d_Curve>& C);
bool FUN_UisoLineOnSphe(const TopoDS_Shape& F, const occ::handle<Geom2d_Curve>& PC)
{
if (PC.IsNull())
{
return false;
}
occ::handle<Geom_Surface> SSS = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
occ::handle<Geom2d_Curve> LLL = ::BASISCURVE2D(PC);
occ::handle<Standard_Type> TS = SSS->DynamicType();
occ::handle<Standard_Type> T2 = LLL->DynamicType();
bool issphere = (TS == STANDARD_TYPE(Geom_SphericalSurface));
bool isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
bool isisoU = false;
if (issphere && isline2d)
{
occ::handle<Geom2d_Line> L = occ::down_cast<Geom2d_Line>(LLL);
const gp_Dir2d& d = L->Direction();
isisoU = (std::abs(d.X()) < Precision::Parametric(Precision::Confusion()));
}
return isisoU;
}
//=================================================================================================
TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool()
: myCurveTool(TopOpeBRepTool_APPROX),
myOverWrite(true),
myTranslate(true)
{
}
//=================================================================================================
TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool(const TopOpeBRepTool_OutCurveType O)
: myCurveTool(O),
myOverWrite(true),
myTranslate(true)
{
}
//=================================================================================================
TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool(const TopOpeBRepTool_GeomTool& GT)
: myCurveTool(GT),
myOverWrite(true),
myTranslate(true)
{
}
bool TopOpeBRepDS_BuildTool::OverWrite() const
{
return myOverWrite;
}
void TopOpeBRepDS_BuildTool::OverWrite(const bool O)
{
myOverWrite = O;
}
bool TopOpeBRepDS_BuildTool::Translate() const
{
return myTranslate;
}
void TopOpeBRepDS_BuildTool::Translate(const bool T)
{
myTranslate = T;
}
//=================================================================================================
const TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::GetGeomTool() const
{
const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
return GT;
}
//=================================================================================================
TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::ChangeGeomTool()
{
TopOpeBRepTool_GeomTool& GT = myCurveTool.ChangeGeomTool();
return GT;
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeVertex(TopoDS_Shape& V, const TopOpeBRepDS_Point& P) const
{
myBuilder.MakeVertex(TopoDS::Vertex(V), P.Point(), P.Tolerance());
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E, const TopOpeBRepDS_Curve& C) const
{
// Gestion des courbes nulles pour carreaux pointus
// RLE 28-6-94
if (C.Curve().IsNull())
{
myBuilder.MakeEdge(TopoDS::Edge(E));
myBuilder.Degenerated(TopoDS::Edge(E), true);
return;
}
const occ::handle<Geom_Curve>& GC = C.Curve();
myBuilder.MakeEdge(TopoDS::Edge(E), GC, C.Tolerance());
bool addorigin = false;
bool setrange = false;
if (addorigin)
{
if (GC->IsClosed())
{
// in case of a closed curve, insert in E a vertex located at the origin
// of the curve C.
TopoDS_Vertex V;
double first = GC->FirstParameter();
gp_Pnt P = GC->Value(first);
myBuilder.MakeVertex(V, P, C.Tolerance());
myBuilder.Add(E, V);
V.Reverse();
myBuilder.Add(E, V);
// If the curve is a degree 1 bspline set the range to 1 .. NbPoles
occ::handle<Geom_BSplineCurve> BSC = occ::down_cast<Geom_BSplineCurve>(GC);
if (!BSC.IsNull())
{
if (BSC->Degree() == 1)
{
myBuilder.Range(TopoDS::Edge(E), 1, BSC->NbPoles());
}
}
}
}
if (setrange)
{
double first, last;
bool rangedef = C.Range(first, last);
if (rangedef)
{
Range(E, first, last);
}
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E,
const TopOpeBRepDS_Curve& C,
const TopOpeBRepDS_DataStructure& BDS) const
{
// Gestion des courbes nulles pour carreaux pointus
// RLE 28-6-94
TopoDS_Edge& EE = TopoDS::Edge(E);
if (C.Curve().IsNull())
{
myBuilder.MakeEdge(EE);
myBuilder.Degenerated(EE, true);
// Creation d'une arete avec PCurve connectee a la BDS Curve
// JYL 22-09-94
const occ::handle<TopOpeBRepDS_Interference>& I = C.GetSCI1();
occ::handle<TopOpeBRepDS_SurfaceCurveInterference> SCI;
SCI = occ::down_cast<TopOpeBRepDS_SurfaceCurveInterference>(I);
int iS = SCI->Support();
const TopOpeBRepDS_Surface& DSS = BDS.Surface(iS);
const occ::handle<Geom_Surface>& GS = DSS.Surface();
const occ::handle<Geom2d_Curve>& PC = SCI->PCurve();
myBuilder.UpdateEdge(EE, PC, GS, TopLoc_Location(), DSS.Tolerance());
return;
}
else
{
const occ::handle<Geom_Curve>& GC = C.Curve();
myBuilder.MakeEdge(EE, GC, C.Tolerance());
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E,
const occ::handle<Geom_Curve>& C,
const double Tol) const
{
myBuilder.MakeEdge(TopoDS::Edge(E), C, Tol);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E) const
{
myBuilder.MakeEdge(TopoDS::Edge(E));
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeWire(TopoDS_Shape& W) const
{
myBuilder.MakeWire(TopoDS::Wire(W));
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeFace(TopoDS_Shape& F, const TopOpeBRepDS_Surface& S) const
{
myBuilder.MakeFace(TopoDS::Face(F), S.Surface(), S.Tolerance());
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeShell(TopoDS_Shape& Sh) const
{
myBuilder.MakeShell(TopoDS::Shell(Sh));
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::MakeSolid(TopoDS_Shape& S) const
{
myBuilder.MakeSolid(TopoDS::Solid(S));
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::CopyEdge(const TopoDS_Shape& Ein, TopoDS_Shape& Eou) const
{
// Splendide evolution de BRep_Curve3D::BRep_Curve3D(Geom_Curve,Location)
// apres modification de la primitive Sphere pour parametrisation de
// l'arete meridienne en -pi/2,+pi/2.
// Ein est l'arete de couture complete d'une sphere complete
// BRep_Tool::Range(Ein) --> -pi/2,+pi/2
// BRep_Tool::Range(Ein.EmptyCopied()) --> 0,2pi
// NYI reflexion sur la notion de Range d'une arete et de la geometrie
// NYI sous jacente dans le cas ou, par construction, les vertex d'une
// NYI arete on des valeurs de parametre HORS des bornes [first,last] de la
// NYI courbe 3D support de l'arete (cas de l'arete de couture d'une sphere)
// On redefinit desormais le range de l'arete Eou, a la place de se
// contenter du simplissime Eou = Ein.EmptyCopied();
// merci les amis : correction bug PRO2586
double f, l;
TopoDS_Edge E1 = TopoDS::Edge(Ein);
BRep_Tool::Range(E1, f, l);
Eou = Ein.EmptyCopied();
TopoDS_Edge E2 = TopoDS::Edge(Eou);
myBuilder.Range(E2, f, l);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::GetOrientedEdgeVertices(TopoDS_Edge& E,
TopoDS_Vertex& Vmin,
TopoDS_Vertex& Vmax,
double& Parmin,
double& Parmax) const
{
if (E.Orientation() == TopAbs_FORWARD)
{
TopExp::Vertices(E, Vmin, Vmax);
}
else
{
TopExp::Vertices(E, Vmax, Vmin);
}
if (!Vmin.IsNull() && !Vmax.IsNull())
{
Parmin = BRep_Tool::Parameter(Vmin, E);
Parmax = BRep_Tool::Parameter(Vmax, E);
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::UpdateEdgeCurveTol
//(const TopoDS_Face& F1,const TopoDS_Face& F2,
(const TopoDS_Face&,
const TopoDS_Face&,
TopoDS_Edge& E,
const occ::handle<Geom_Curve>& C3Dnew,
// const double tol3d,
const double,
// const double tol2d1,
const double,
// const double tol2d2,
const double,
double& newtol,
double& newparmin,
double& newparmax) const
{
if (C3Dnew.IsNull())
{
return;
}
BRep_Builder BB;
// newtol = max des tolerances atteintes en 3d
// JMB le 06 Juillet 1999
// les valeurs tol3d et tol2d1,tol2d2 proviennent des approx. Dans la version 2.0 de CasCade,
// elles n'etaient pas calculees et on renvoyait systematiquement les valeurs initiales (a savoir)
// 1.E-7. Dans la version 2.1 de CasCade, ces valeurs sont desormais calculees selon un calcul
// d'erreur dans les Approx. Malheureusement, il apparait que ce calcul d'erreur renvoit dans la
// plupart des cas de tres grosses valeurs (parfois de l'ordre de 1.E-1). Ce qui amenait la
// topologie a coder des tolerances enormes dans les pieces resultats rendant celles-ci
// inexpoitables. De plus on essayait de rafiner la tolerance en appelant les UResolution sur les
// surfaces support. sur des surfaces tres particulieres, ce UREsolution n'a plus aucun sens et
// peut amener a des valeurs abberantes. On decide donc de laisser la tolerance de l'edge telle
// qu'elle est afin d'avoir un comportement similaire a 2.0. Jusqu'a present on a constate que des
// problemes avec la methode de calcul d'erreur des approx.
newtol = 1.E-7;
// double r1,r2;
// r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tol2d1);
// r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tol2d2);
// newtol=tol3d;
// if (r1>newtol) newtol=r1;
// if (r2>newtol) newtol=r2;
// newtol *= 1.5;
TopoDS_Vertex Vmin, Vmax;
double parmin = 0.0, parmax = 0.0;
GetOrientedEdgeVertices(E, Vmin, Vmax, parmin, parmax);
double tolmin = BRep_Tool::Tolerance(Vmin);
if (newtol > tolmin)
{
tolmin = newtol;
}
double tolmax = BRep_Tool::Tolerance(Vmax);
if (newtol > tolmax)
{
tolmax = newtol;
}
// newparmin=C3Dnew->FirstParameter(); // -merge 04-07-97
// newparmax=C3Dnew->LastParameter(); // -merge 04-07-97
// +merge 04-07-97
occ::handle<Geom_TrimmedCurve> GTC = occ::down_cast<Geom_TrimmedCurve>(C3Dnew);
if (GTC.IsNull())
{
occ::handle<Geom_BSplineCurve> GBSC = occ::down_cast<Geom_BSplineCurve>(C3Dnew);
if (GBSC.IsNull())
{
newparmin = parmin;
newparmax = parmax;
}
else
{
newparmin = C3Dnew->FirstParameter();
newparmax = C3Dnew->LastParameter();
}
}
else
{
newparmin = C3Dnew->FirstParameter();
newparmax = C3Dnew->LastParameter();
} // +merge 04-07-97
if (Vmin.Orientation() == TopAbs_FORWARD)
{
BB.UpdateVertex(Vmin, newparmin, E, tolmin);
BB.UpdateVertex(Vmax, newparmax, E, tolmax);
}
else
{
BB.UpdateVertex(Vmin, newparmax, E, tolmin);
BB.UpdateVertex(Vmax, newparmin, E, tolmax);
}
// DSBT.Curve3D(E,C3Dnew,newtol); // -merge 04-07-97
Curve3D(E, C3Dnew, newtol);
// projection des vertex INTERNAL de E pour parametrage
// sur la nouvelle courbe C3Dnew de l'arete E
TopExp_Explorer exi(E, TopAbs_VERTEX);
for (; exi.More(); exi.Next())
{
const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
if (vi.Orientation() != TopAbs_INTERNAL)
{
continue;
}
gp_Pnt P = BRep_Tool::Pnt(vi);
double tolvi = TopOpeBRepTool_ShapeTool::Tolerance(vi);
GeomAPI_ProjectPointOnCurve dm(P, C3Dnew, newparmin, newparmax);
bool dmdone = dm.Extrema().IsDone();
if (dmdone)
{
if (dm.NbPoints())
{
double newpar = dm.LowerDistanceParameter();
BB.UpdateVertex(vi, newpar, E, tolvi);
}
}
} // INTERNAL vertex
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::ApproxCurves(const TopOpeBRepDS_Curve& C,
TopoDS_Edge& E,
int& inewC,
const occ::handle<TopOpeBRepDS_HDataStructure>& HDS) const
{
TopOpeBRepDS_Curve newC1;
inewC = HDS->MakeCurve(C, newC1);
TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
// C1 curves have been approximated by BSplines of degree 1 :
// compute new geometry on curves.
const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
const occ::handle<Geom_Curve>& C3D = C.Curve();
const occ::handle<Geom2d_Curve>& PC1 = C.Curve1();
const occ::handle<Geom2d_Curve>& PC2 = C.Curve2();
// Vmin,Vmax = bounding vertices of edge <E>
// and their parameters parmin,parmax .
TopoDS_Vertex Vmin, Vmax;
double parmin = 0.0, parmax = 0.0;
GetOrientedEdgeVertices(E, Vmin, Vmax, parmin, parmax);
occ::handle<Geom_Curve> C3Dnew;
occ::handle<Geom2d_Curve> PC1new;
occ::handle<Geom2d_Curve> PC2new;
double tolreached3d = 0.0, tolreached2d = 0.0;
bool approxMade = myCurveTool.MakeCurves(parmin,
parmax,
C3D,
PC1,
PC2,
F1,
F2,
C3Dnew,
PC1new,
PC2new,
tolreached3d,
tolreached2d);
double newtol = 0.0, newparmin = 0.0, newparmax = 0.0;
// MSV Nov 12, 2001: if approx failed than leave old curves of degree 1
if (!approxMade)
{
newtol = BRep_Tool::Tolerance(E);
newparmin = parmin;
newparmax = parmax;
C3Dnew = C3D;
PC1new = PC1;
PC2new = PC2;
}
else
{
UpdateEdgeCurveTol(F1,
F2,
E,
C3Dnew,
tolreached3d,
tolreached2d,
tolreached2d,
newtol,
newparmin,
newparmax);
}
if (!C3Dnew.IsNull())
{
newC.DefineCurve(C3Dnew, newtol, false);
newC.SetRange(newparmin, newparmax);
}
if (!PC1new.IsNull())
{
newC.Curve1(PC1new);
}
if (!PC2new.IsNull())
{
newC.Curve2(PC2new);
}
}
//=================================================================================================
bool FUN_getUV(const occ::handle<Geom_Surface>& surf,
const occ::handle<Geom_Curve>& C3D,
const double par3d,
double& u0,
double& v0)
{
gp_Pnt P3d;
C3D->D0(par3d, P3d);
GeomAPI_ProjectPointOnSurf pons(P3d, surf);
if (pons.NbPoints() < 1)
{
return false;
}
pons.LowerDistanceParameters(u0, v0);
return true;
}
bool FUN_reversePC(const occ::handle<Geom2d_Curve>& PCnew,
const TopoDS_Face& F,
const gp_Pnt& P3DC3D,
const double par2d,
const double tol)
{
gp_Pnt2d P2D;
PCnew->D0(par2d, P2D);
BRepAdaptor_Surface BAS(F, false);
gp_Pnt P3D = BAS.Value(P2D.X(), P2D.Y());
bool PCreversed = false;
bool sam = P3D.IsEqual(P3DC3D, tol);
PCreversed = !sam;
if (PCreversed)
{
occ::handle<Geom2d_Curve> PC = ::BASISCURVE2D(PCnew);
if (!PC.IsNull())
{
occ::handle<Geom2d_Line> L = occ::down_cast<Geom2d_Line>(PC);
gp_Dir2d d = L->Direction();
d.Reverse();
L->SetDirection(d);
}
}
return PCreversed;
}
bool FUN_makeUisoLineOnSphe(const TopoDS_Face& F, // with geometry the spherical surface
const occ::handle<Geom_Curve>& C3D,
const occ::handle<Geom2d_Curve>& PCnew,
const double tol3d)
{
// p3df,p3dl : C3d first and last parameters
double p3df = C3D->FirstParameter();
double p3dl = C3D->LastParameter();
// u0,v0 : C3d(par3d) UV parameters
double deltainf = 0.243234, deltasup = 0.543345;
double par3dinf = (1 - deltainf) * p3df + deltainf * p3dl;
double par3dsup = (1 - deltasup) * p3df + deltasup * p3dl;
double uinf, vinf, usup, vsup;
occ::handle<Geom_Surface> surf = BRep_Tool::Surface(F);
if (!FUN_getUV(surf, C3D, par3dinf, uinf, vinf))
{
return false;
}
if (!FUN_getUV(surf, C3D, par3dsup, usup, vsup))
{
return false;
}
double tol = Precision::Parametric(tol3d);
if (std::abs(uinf - usup) > tol)
{
return false;
}
bool isvgrowing = (vsup - vinf > -tol);
gp_Dir2d vdir;
if (isvgrowing)
{
vdir = gp_Dir2d(gp_Dir2d::D::Y);
}
else
{
vdir = gp_Dir2d(gp_Dir2d::D::NY);
}
gp_Pnt2d origin(uinf, vinf);
origin.Translate(gp_Vec2d(vdir).Scaled(p3df - par3dinf));
occ::handle<Geom2d_Curve> PC = ::BASISCURVE2D(PCnew);
if (!PC.IsNull())
{
occ::handle<Geom2d_Line> L = occ::down_cast<Geom2d_Line>(PC);
L->SetLin2d(gp_Lin2d(origin, vdir));
} // (!PC.IsNull())
return true;
}
void TopOpeBRepDS_BuildTool::ComputePCurves(const TopOpeBRepDS_Curve& C,
TopoDS_Edge& E,
TopOpeBRepDS_Curve& newC,
const bool comppc1,
const bool comppc2,
const bool compc3d) const
{
const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
const occ::handle<Geom_Curve>& C3D = C.Curve();
// get bounding vertices Vmin,Vmax supported by the new edge <E>
// and their corresponding parameters parmin,parmax .
TopoDS_Vertex Vmin, Vmax;
double parmin = 0.0, parmax = 0.0;
GetOrientedEdgeVertices(E, Vmin, Vmax, parmin, parmax);
occ::handle<Geom2d_Curve> PC1new, PC2new;
if (C3D.IsNull())
{
double tolreached2d1 = Precision::Confusion(), tolreached2d2 = Precision::Confusion(),
tol = Precision::Confusion();
if (comppc1)
{
PC1new = TopOpeBRepTool_CurveTool::MakePCurveOnFace(F1, C3D, tolreached2d1);
}
if (comppc2)
{
PC2new = TopOpeBRepTool_CurveTool::MakePCurveOnFace(F2, C3D, tolreached2d2);
}
double r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1, tolreached2d1);
double r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2, tolreached2d2);
tol = std::max(tol, r1);
tol = std::max(tol, r2);
newC.Tolerance(tol);
if (!PC1new.IsNull())
{
newC.Curve1(PC1new);
}
if (!PC2new.IsNull())
{
newC.Curve2(PC2new);
}
return;
}
occ::handle<Geom_Curve> C3Dnew = C3D;
if (C3D->IsPeriodic())
{
// ellipse on cone : periodize parmin,parmax
double period = C3D->LastParameter() - C3D->FirstParameter();
double f, l;
if (Vmin.Orientation() == TopAbs_FORWARD)
{
f = parmin;
l = parmax;
}
else
{
f = parmax;
l = parmin;
}
parmin = f;
parmax = l;
ElCLib::AdjustPeriodic(f, f + period, Precision::PConfusion(), parmin, parmax);
if (compc3d)
{
C3Dnew = new Geom_TrimmedCurve(C3D, parmin, parmax);
}
}
double tolreached3d = C.Tolerance();
double tolreached2d1 = C.Tolerance();
double tolreached2d2 = C.Tolerance();
if (comppc1)
{
PC1new = TopOpeBRepTool_CurveTool::MakePCurveOnFace(F1, C3Dnew, tolreached2d1);
}
if (comppc2)
{
PC2new = TopOpeBRepTool_CurveTool::MakePCurveOnFace(F2, C3Dnew, tolreached2d2);
}
double newtol, newparmin, newparmax;
UpdateEdgeCurveTol(F1,
F2,
E,
C3Dnew,
tolreached3d,
tolreached2d1,
tolreached2d2,
newtol,
newparmin,
newparmax);
// xpu : suite merge : 07-07-97
// xpu : 17-06-97
// Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
// est une isos de la sphere
// NYI : enlever FUN_reversePC
bool UisoLineOnSphe1 = false;
UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1, PC1new);
if (UisoLineOnSphe1)
{
::FUN_makeUisoLineOnSphe(F1, C3Dnew, PC1new, newtol);
}
bool UisoLineOnSphe2 = false;
UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2, PC2new);
if (UisoLineOnSphe2)
{
::FUN_makeUisoLineOnSphe(F2, C3Dnew, PC2new, newtol);
}
// xpu : 17-06-97
// xpu : suite merge : 07-07-97
if (!C3Dnew.IsNull())
{
newC.Curve(C3Dnew, newtol);
newC.SetRange(newparmin, newparmax);
}
if (!PC1new.IsNull())
{
newC.Curve1(PC1new);
}
if (!PC2new.IsNull())
{
newC.Curve2(PC2new);
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::PutPCurves(const TopOpeBRepDS_Curve& newC,
TopoDS_Edge& E,
const bool comppc1,
const bool comppc2) const
{
TopoDS_Face& F1 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape1())));
const occ::handle<Geom2d_Curve>& PC1 = newC.Curve1();
if (!PC1.IsNull() && comppc1)
{
PCurve(F1, E, PC1);
}
TopoDS_Face& F2 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape2())));
const occ::handle<Geom2d_Curve>& PC2 = newC.Curve2();
if (!PC2.IsNull() && comppc2)
{
PCurve(F2, E, PC2);
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::RecomputeCurves(
const TopOpeBRepDS_Curve& C,
// const TopoDS_Edge& oldE,
const TopoDS_Edge&,
TopoDS_Edge& E,
int& inewC,
const occ::handle<TopOpeBRepDS_HDataStructure>& HDS) const
{
const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
const bool compc3d = GT.CompC3D();
const bool comppc1 = GT.CompPC1();
const bool comppc2 = GT.CompPC2();
const bool comppc = comppc1 || comppc2;
const bool iswalk = C.IsWalk();
const bool approx = Approximation();
const occ::handle<Geom_Curve>& C3D = C.Curve();
if (comppc1 && C.Shape1().IsNull())
{
throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
}
if (comppc2 && C.Shape2().IsNull())
{
throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
}
TopoDS_Vertex Vmin, Vmax;
TopExp::Vertices(E, Vmin, Vmax);
if (Vmin.IsNull())
{
throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
}
if (Vmax.IsNull())
{
throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
}
if (iswalk && approx)
{
if (compc3d && C3D.IsNull())
{
throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
}
ApproxCurves(C, E, inewC, HDS);
TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
PutPCurves(newC, E, comppc1, comppc2);
}
// else if (iswalk && interpol) {
// InterpolCurves(C, E, inewC, comppc1, comppc2, HDS);
// TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
// PutPCurves(newC, E, comppc1, comppc2);
// }
else
{
if (comppc)
{
TopOpeBRepDS_Curve newC1;
inewC = HDS->MakeCurve(C, newC1);
TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
if (iswalk && !approx)
{
if (compc3d && C3D.IsNull())
{
throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
}
newC.Curve1(C.Curve1());
newC.Curve2(C.Curve2());
}
else
{
ComputePCurves(C, E, newC, comppc1, comppc2, compc3d);
}
PutPCurves(newC, E, comppc1, comppc2);
}
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::CopyFace(const TopoDS_Shape& Fin, TopoDS_Shape& Fou) const
{
Fou = Fin.EmptyCopied();
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::AddEdgeVertex(const TopoDS_Shape& Ein,
TopoDS_Shape& Eou,
const TopoDS_Shape& V) const
{
TopoDS_Edge e1 = TopoDS::Edge(Ein);
TopoDS_Edge e2 = TopoDS::Edge(Eou);
TopoDS_Vertex v1 = TopoDS::Vertex(V);
if (e1.Orientation() == TopAbs_REVERSED)
{
v1.Reverse();
}
e1.Orientation(TopAbs_FORWARD);
e2.Orientation(TopAbs_FORWARD);
myBuilder.Add(e2, v1);
myBuilder.Transfert(e1, e2, v1, v1);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::AddEdgeVertex(TopoDS_Shape& E, const TopoDS_Shape& V) const
{
myBuilder.Add(E, V);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::AddWireEdge(TopoDS_Shape& W, const TopoDS_Shape& E) const
{
myBuilder.Add(W, E);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::AddFaceWire(TopoDS_Shape& F, const TopoDS_Shape& W) const
{
myBuilder.Add(F, W);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::AddShellFace(TopoDS_Shape& Sh, const TopoDS_Shape& F) const
{
myBuilder.Add(Sh, F);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::AddSolidShell(TopoDS_Shape& S, const TopoDS_Shape& Sh) const
{
myBuilder.Add(S, Sh);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::Parameter(const TopoDS_Shape& E,
const TopoDS_Shape& V,
const double P) const
{
const TopoDS_Edge& e = TopoDS::Edge(E);
const TopoDS_Vertex& v = TopoDS::Vertex(V);
double p = P;
// 13/07/95 :
TopLoc_Location loc;
double f, l;
occ::handle<Geom_Curve> C = BRep_Tool::Curve(e, loc, f, l);
if (!C.IsNull() && C->IsPeriodic())
{
double per = C->Period();
TopAbs_Orientation oV = TopAbs_FORWARD;
TopExp_Explorer exV(e, TopAbs_VERTEX);
for (; exV.More(); exV.Next())
{
const TopoDS_Vertex& vofe = TopoDS::Vertex(exV.Current());
if (vofe.IsSame(v))
{
oV = vofe.Orientation();
break;
}
}
if (exV.More())
{
if (oV == TopAbs_REVERSED)
{
if (p < f)
{
double pp = ElCLib::InPeriod(p, f, f + per);
p = pp;
}
}
}
}
myBuilder.UpdateVertex(v, p, e,
0); // NYI : Tol on new vertex ??
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::Range(const TopoDS_Shape& E,
const double first,
const double last) const
{
myBuilder.Range(TopoDS::Edge(E), first, last);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::UpdateEdge(const TopoDS_Shape& Ein, TopoDS_Shape& Eou) const
{
TopLoc_Location loc;
double f1, l1;
double f2, l2;
occ::handle<Geom_Curve> Cin = BRep_Tool::Curve(TopoDS::Edge(Ein), loc, f1, l1);
occ::handle<Geom_Curve> Cou = BRep_Tool::Curve(TopoDS::Edge(Eou), loc, f2, l2);
if (Cin.IsNull() || Cou.IsNull())
{
return;
}
if (Cou->IsPeriodic())
{
double f2n = f2, l2n = l2;
if (l2n <= f2n)
{
ElCLib::AdjustPeriodic(f1, l1, Precision::PConfusion(), f2n, l2n);
Range(Eou, f2n, l2n);
}
}
}
//=================================================================================================
static bool Project(const occ::handle<Geom_Curve>& C, const TopoDS_Vertex& V, double& p)
{
gp_Pnt P = BRep_Tool::Pnt(V);
double tol = BRep_Tool::Tolerance(V);
GeomAdaptor_Curve GAC(C);
Extrema_ExtPC extrema(P, GAC);
if (extrema.IsDone())
{
int i, n = extrema.NbExt();
for (i = 1; i <= n; i++)
{
if (extrema.IsMin(i))
{
Extrema_POnCurv EPOC = extrema.Point(i);
if (P.Distance(EPOC.Value()) <= tol)
{
p = EPOC.Parameter();
return true;
}
}
}
}
return false;
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::Parameter(const TopOpeBRepDS_Curve& C,
TopoDS_Shape& E,
TopoDS_Shape& V) const
{
double newparam;
Project(C.Curve(), TopoDS::Vertex(V), newparam);
Parameter(E, V, newparam);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::Curve3D(TopoDS_Shape& E,
const occ::handle<Geom_Curve>& C,
const double Tol) const
{
myBuilder.UpdateEdge(TopoDS::Edge(E), C, Tol);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::TranslateOnPeriodic(TopoDS_Shape& F,
TopoDS_Shape& E,
occ::handle<Geom2d_Curve>& PC) const
{
// get range C3Df,C3Dl of 3d curve C3D of E
TopLoc_Location L;
double C3Df, C3Dl;
// occ::handle<Geom_Curve> C3D = BRep_Tool::Curve(TopoDS::Edge(E),L,C3Df,C3Dl);
occ::handle<Geom_Curve> C3D = BRep_Tool::Curve(TopoDS::Edge(E), C3Df, C3Dl); // 13-07-97: xpu
double first = C3Df, last = C3Dl;
if (C3D->IsPeriodic())
{
if (last < first)
{
last += std::abs(first - last);
}
}
// jyl-xpu : 13-06-97 :
// if <PC> is U isoline on sphere, a special parametrization
// is to provide, we compute <PC> (which is a line) bounds
// with C3D bounds.
bool UisoLineOnSphe = FUN_UisoLineOnSphe(F, PC);
bool newv = true;
double du, dv;
gp_Pnt2d ptest;
double t = (first + last) * .5;
PC->D0(t, ptest);
double u1 = ptest.X(), u2 = u1;
double v1 = ptest.Y(), v2 = v1;
if (newv)
{
if (UisoLineOnSphe)
{
occ::handle<Geom_Curve> c3d = BRep_Tool::Curve(TopoDS::Edge(E), C3Df, C3Dl);
GeomAdaptor_Curve GC(c3d);
gp_Pnt p3dtest = GC.Value(t);
occ::handle<Geom_Surface> surf = BRep_Tool::Surface(TopoDS::Face(F));
GeomAPI_ProjectPointOnSurf pons(p3dtest, surf);
if (!(pons.NbPoints() < 1))
{
pons.LowerDistanceParameters(u2, v2);
}
}
else
{
TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F, u2, v2);
}
}
if (!newv)
{
TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F, u2, v2);
}
du = u2 - u1, dv = v2 - v1;
if (du != 0. || dv != 0.)
{
// translate curve PC of du,dv
occ::handle<Geom2d_Curve> PCT = occ::down_cast<Geom2d_Curve>(PC->Copy());
PCT->Translate(gp_Vec2d(du, dv));
PC = PCT;
}
}
// RLE - IAB 16 june 94
// should be provided by the BRep_Builder
Standard_EXPORT void TopOpeBRepDS_SetThePCurve(const BRep_Builder& B,
TopoDS_Edge& E,
const TopoDS_Face& F,
const TopAbs_Orientation O,
const occ::handle<Geom2d_Curve>& C)
{
// check if there is already a pcurve on non planar faces
double f, l;
occ::handle<Geom2d_Curve> OC;
TopLoc_Location SL;
occ::handle<Geom_Plane> GP = occ::down_cast<Geom_Plane>(BRep_Tool::Surface(F, SL));
if (GP.IsNull())
{
OC = BRep_Tool::CurveOnSurface(E, F, f, l);
}
if (OC.IsNull())
{
B.UpdateEdge(E, C, F, Precision::Confusion());
}
else
{
bool degen = BRep_Tool::Degenerated(E);
if (!degen)
{
if (O == TopAbs_REVERSED)
{
B.UpdateEdge(E, OC, C, F, Precision::Confusion());
}
else
{
B.UpdateEdge(E, C, OC, F, Precision::Confusion());
}
}
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
TopoDS_Shape& E,
const occ::handle<Geom2d_Curve>& PC) const
{
if (!PC.IsNull())
{
TopoDS_Face FF = TopoDS::Face(F);
TopoDS_Edge EE = TopoDS::Edge(E);
occ::handle<Geom2d_Curve> PCT = PC;
// pour iab, ajout de Translate
bool tran = myTranslate;
// xpu : 13-06-97 :
// recompute twice the pcurve boundaries if OverWrite
// if the pcurve <PC> is U isoline on sphere -> to avoid.
bool UisoLineOnSphe = FUN_UisoLineOnSphe(F, PC);
bool overwrite = UisoLineOnSphe ? false : myOverWrite;
// xpu : 13-06-97
if (tran)
{
TranslateOnPeriodic(F, E, PCT);
}
if (overwrite)
{
myBuilder.UpdateEdge(EE, PCT, FF, 0);
}
else
{
TopOpeBRepDS_SetThePCurve(myBuilder, EE, FF, E.Orientation(), PCT);
}
// parametrage sur la nouvelle courbe 2d
TopExp_Explorer exi(E, TopAbs_VERTEX);
for (; exi.More(); exi.Next())
{
const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
if (vi.Orientation() != TopAbs_INTERNAL)
{
continue;
}
double tolvi = TopOpeBRepTool_ShapeTool::Tolerance(vi);
// NYI tester l'existence d'au moins
// NYI un parametrage de vi sur EE (en 3d ou en 2d)
// NYI --> a faire dans BRep_Tool
double newpar = BRep_Tool::Parameter(vi, EE);
myBuilder.UpdateVertex(vi, newpar, EE, FF, tolvi);
} // INTERNAL vertex
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
TopoDS_Shape& E,
const TopOpeBRepDS_Curve& CDS,
const occ::handle<Geom2d_Curve>& PC) const
{
if (!PC.IsNull())
{
TopoDS_Face FF = TopoDS::Face(F);
TopoDS_Edge EE = TopoDS::Edge(E);
occ::handle<Geom2d_Curve> PCT = PC;
double CDSmin, CDSmax;
bool rangedef = CDS.Range(CDSmin, CDSmax);
TopLoc_Location L;
double Cf, Cl;
occ::handle<Geom_Curve> C = BRep_Tool::Curve(EE, L, Cf, Cl);
if (!C.IsNull())
{
if (rangedef && (CDS.IsExistingEdgeReversed() || CDS.IsEquivalentCurveReversed()))
{
occ::handle<Geom2d_TrimmedCurve> aReversedPCurve =
new Geom2d_TrimmedCurve(PCT, CDSmin, CDSmax);
aReversedPCurve->Reverse();
GeomLib::SameRange(Precision::PConfusion(),
aReversedPCurve,
aReversedPCurve->FirstParameter(),
aReversedPCurve->LastParameter(),
Cf,
Cl,
PCT);
}
else
{
bool deca = (std::abs(Cf - CDSmin) > Precision::PConfusion());
occ::handle<Geom2d_Line> line2d = occ::down_cast<Geom2d_Line>(PCT);
bool isline2d = !line2d.IsNull();
bool tran = (rangedef && deca && C->IsPeriodic() && isline2d);
if (tran)
{
TopLoc_Location Loc;
const occ::handle<Geom_Surface> Surf = BRep_Tool::Surface(FF, Loc);
bool isUperio = Surf->IsUPeriodic();
bool isVperio = Surf->IsVPeriodic();
gp_Dir2d dir2d = line2d->Direction();
double delta;
if (isUperio && dir2d.IsParallel(gp::DX2d(), Precision::Angular()))
{
delta = (CDSmin - Cf) * dir2d.X();
PCT->Translate(gp_Vec2d(delta, 0.));
}
else if (isVperio && dir2d.IsParallel(gp::DY2d(), Precision::Angular()))
{
delta = (CDSmin - Cf) * dir2d.Y();
PCT->Translate(gp_Vec2d(0., delta));
}
}
}
}
TopOpeBRepDS_SetThePCurve(myBuilder, EE, FF, E.Orientation(), PCT);
}
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::Orientation(TopoDS_Shape& S, const TopAbs_Orientation O) const
{
S.Orientation(O);
}
//=================================================================================================
TopAbs_Orientation TopOpeBRepDS_BuildTool::Orientation(const TopoDS_Shape& S) const
{
return S.Orientation();
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::Closed(TopoDS_Shape& S, const bool B) const
{
S.Closed(B);
}
//=================================================================================================
bool TopOpeBRepDS_BuildTool::Approximation() const
{
return myCurveTool.GetGeomTool().TypeC3D() != TopOpeBRepTool_BSPLINE1;
}
void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& F,
const occ::handle<Geom_Surface>& SU) const
{
BRep_Builder BB;
TopLoc_Location L;
double tol = BRep_Tool::Tolerance(TopoDS::Face(F));
BB.UpdateFace(TopoDS::Face(F), SU, L, tol);
}
void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& E,
const TopoDS_Shape& oldF,
const TopoDS_Shape& newF) const
{
BRep_Builder BB;
double f, l;
const occ::handle<Geom2d_Curve>& PC =
BRep_Tool::CurveOnSurface(TopoDS::Edge(E), TopoDS::Face(oldF), f, l);
double tol = BRep_Tool::Tolerance(TopoDS::Face(oldF));
BB.UpdateEdge(TopoDS::Edge(E), PC, TopoDS::Face(newF), tol);
}
/* // - merge 04-07-97
//=================================================================================================
void TopOpeBRepDS_BuildTool::RecomputeCurve
(const TopOpeBRepDS_Curve& C1,
TopoDS_Shape& E,
TopOpeBRepDS_Curve& C2 ) const
{
// - C1 curves have been approximated by BSplines of degree 1 :
// or
// - C1.Curve() is non projectable on at least one of the original
// intersecting faces.
const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
bool compc3d = GT.CompC3D();
bool comppc1 = GT.CompPC1();
bool comppc2 = GT.CompPC2();
const occ::handle<Geom_Curve>& C3D = C1.Curve();
if (compc3d && C3D.IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve
1"); if (comppc1 && C2.Shape1().IsNull()) throw
Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 2"); if (comppc2 &&
C2.Shape2().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(TopoDS::Edge(E),Vmin,Vmax);
if ( Vmin.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
if ( Vmax.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
bool kbspl1 = false;
occ::handle<Geom_BSplineCurve> BS = occ::down_cast<Geom_BSplineCurve>(C3D);
if (!BS.IsNull()) kbspl1 = (BS->Degree() == 1);
if (kbspl1) RecomputeBSpline1Curve(C1,E,C2);
else RecomputeCurveOnCone(C1,E,C2);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::RecomputeBSpline1Curve
(const TopOpeBRepDS_Curve& C1,
TopoDS_Shape& EE,
TopOpeBRepDS_Curve& C2) const
{
// C1 curves have been approximated by BSplines of degree 1 :
// compute new geometry on curves.
TopoDS_Edge& E = TopoDS::Edge(EE);
const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
bool compc3d = GT.CompC3D();
bool comppc1 = GT.CompPC1();
bool comppc2 = GT.CompPC2();
const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
const occ::handle<Geom_Curve>& C3D = C1.Curve();
const occ::handle<Geom2d_Curve>& PC1 = C1.Curve1();
const occ::handle<Geom2d_Curve>& PC2 = C1.Curve2();
// Vmin,Vmax = bounding vertices of edge <E>
// and their parameters parmin,parmax .
TopoDS_Vertex Vmin, Vmax;
double parmin = 0.0, parmax = 0.0;
::GetOrientedEdgeVertices (E, Vmin, Vmax, parmin, parmax);
occ::handle<Geom_Curve> C3Dnew;
occ::handle<Geom2d_Curve> PC1new;
occ::handle<Geom2d_Curve> PC2new;
double tolreached3d,tolreached2d;
if ( typec3d == TopOpeBRepTool_BSPLINE1 ) {
if ( compc3d ) {
C3Dnew = occ::down_cast<Geom_BSplineCurve>(C3D->Copy());
(occ::down_cast<Geom_BSplineCurve>(C3Dnew))->Segment(parmin,parmax);
}
if ( comppc1 && (!PC1.IsNull()) ) {
PC1new = occ::down_cast<Geom2d_BSplineCurve>(PC1->Copy());
(occ::down_cast<Geom2d_BSplineCurve>(PC1new))->Segment(parmin,parmax);
}
if ( comppc2 && (!PC2.IsNull()) ) {
PC2new = occ::down_cast<Geom2d_BSplineCurve>(PC2->Copy());
(occ::down_cast<Geom2d_BSplineCurve>(PC2new))->Segment(parmin,parmax);
}
}
else if ( typec3d == TopOpeBRepTool_APPROX ) {
if (!comppc1 || !comppc2) throw Standard_NotImplemented("DSBuildToolAPPROX");
myCurveTool.MakeCurves(parmin,parmax,
C3D,PC1,PC2,F1,F2,
C3Dnew,PC1new,PC2new,
tolreached3d,tolreached2d);
}
else if ( typec3d == TopOpeBRepTool_INTERPOL ) {
throw Standard_NotImplemented("DSBuildToolINTERPOL");
}
double newtol,newparmin,newparmax;
::FUN_updateEDGECURVETOL
(*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
newtol,newparmin,newparmax);
if (!C3Dnew.IsNull()) {
C2.DefineCurve(C3Dnew,newtol,false);
C2.SetRange(newparmin,newparmax);
}
if (!PC1new.IsNull()) C2.Curve1(PC1new);
if (!PC2new.IsNull()) C2.Curve2(PC2new);
}
//=================================================================================================
void TopOpeBRepDS_BuildTool::RecomputeCurveOnCone
(const TopOpeBRepDS_Curve& C1,
TopoDS_Shape& EE,
TopOpeBRepDS_Curve& C2 ) const
{
// C1 Pcurves have not been computed because C1 Curve is not projectable
// on one at least of the intersecting faces giving C1 Curve.
// (see TopOpeBRepTool_CurveTool::IsProjectable())
TopoDS_Edge& E = TopoDS::Edge(EE);
const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
bool compc3d = GT.CompC3D();
bool comppc1 = GT.CompPC1();
bool comppc2 = GT.CompPC2();
const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
const occ::handle<Geom_Curve>& C3D = C1.Curve();
const occ::handle<Geom2d_Curve>& PC1 = C1.Curve1();
const occ::handle<Geom2d_Curve>& PC2 = C1.Curve2();
// get bounding vertices Vmin,Vmax supported by the new edge <E>
// and their corresponding parameters parmin,parmax .
TopoDS_Vertex Vmin, Vmax;
double parmin = 0.0, parmax = 0.0;
::GetOrientedEdgeVertices (E, Vmin, Vmax, parmin, parmax);
if ( C3D->IsPeriodic() ) {
// ellipse on cone : periodize parmin,parmax
double period = C3D->LastParameter() - C3D->FirstParameter();
double f,l;
if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
else { f = parmax; l = parmin; }
parmin = f; parmax = l;
ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
}
occ::handle<Geom_TrimmedCurve> C3Dnew;
occ::handle<Geom2d_Curve> PC1new;
occ::handle<Geom2d_Curve> PC2new;
double tolreached3d = C1.Tolerance();
double tolreached2d1 = C1.Tolerance();
double tolreached2d2 = C1.Tolerance();
if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
double newtol,newparmin,newparmax;
FUN_updateEDGECURVETOL
(*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
newtol,newparmin,newparmax);
// jyl : 16-06-97
// double fac = 0.3798123578771;
// double tol = newtol;
// double par3d = (1-fac)*newparmin + (fac)*newparmax;
// double par2d = par3d - newparmin;
//
// gp_Pnt P3DC3D; C3D->D0(par3d,P3DC3D);
//
// bool UisoLineOnSphe1 = false;
// UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
// if (UisoLineOnSphe1) {
// double isrev1 =
// ::FUN_reversePC(PC1new,F1,P3DC3D,par2d,tol);
//
//
// }
//
// bool UisoLineOnSphe2 = false;
// UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
// if (UisoLineOnSphe2) {
// double isrev2 =
// ::FUN_reversePC(PC2new,F2,P3DC3D,par2d,tol);
//
// }
// xpu : 17-06-97
// Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
// est une isos de la sphere
// NYI : enlever FUN_reversePC
bool UisoLineOnSphe1 = false;
UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
if (UisoLineOnSphe1) {
::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
}
bool UisoLineOnSphe2 = false;
UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
if (UisoLineOnSphe2) {
::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
} // xpu : 17-06-97
if (!C3Dnew.IsNull()) C2.Curve(C3Dnew,newtol);
if (!PC1new.IsNull()) C2.Curve1(PC1new);
if (!PC2new.IsNull()) C2.Curve2(PC2new);
}*/ // - merge 04-07-97