1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00
Files
occt/src/ChFi2d/ChFi2d_Builder_0.cxx
2012-03-05 19:23:40 +04:00

792 lines
25 KiB
C++
Executable File

// File: ChFi2d_Builder_1.cxx
// Created: Fri Jul 7 16:43:30 1995
// Author: Philippe DERVIEUX
// <phd@tlefon>
// Modified : 08/07/97 : JPI : traitement des edges degeneres comme pour les fillets 2D
// Modified: Fri Sep 25 09:38:04 1998
// Author: Joelle CHAUVET
// <jct@sgi64>
// status = ChFi2d_NotAuthorized si les aretes ne sont pas
// des droites ou des cercles; fonction IsLineOrCircle
// (BUC60288)
#include <ChFi2d.hxx>
#include <ChFi2d_Builder.ixx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepLib_MakeEdge.hxx>
#include <BRepLib_MakeFace.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <ElCLib.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAPI.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2d_Circle.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2dInt_GInter.hxx>
#include <IntRes2d_IntersectionPoint.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <Precision.hxx>
#include <TopAbs_Orientation.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Shape.hxx>
gp_Pnt ComputePoint(const TopoDS_Vertex& V,const TopoDS_Edge& E,
const Standard_Real D1, Standard_Real& Param1);
gp_Pnt ComputePoint(const TopoDS_Face& F, const Handle(Geom_Line)& L,
const TopoDS_Edge& E, Standard_Real& Param);
void OrientChamfer(TopoDS_Edge& chamfer,
const TopoDS_Edge& E,
const TopoDS_Vertex& V);
static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
const TopoDS_Face& F);
//=======================================================================
//function : AddChamfer
//purpose :
//=======================================================================
TopoDS_Edge ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E1,
const TopoDS_Edge& E2,
const Standard_Real D1,
const Standard_Real D2)
{
TopoDS_Vertex commonVertex;
TopoDS_Edge basisEdge1, basisEdge2;
TopoDS_Edge E1Mod, E2Mod, chamfer;
Standard_Boolean hasConnection = ChFi2d::CommonVertex(E1, E2, commonVertex);
if (!hasConnection) return chamfer;
if (IsAFillet(E1) || IsAChamfer(E1) ||
IsAFillet(E2) || IsAChamfer(E2)) {
status = ChFi2d_NotAuthorized;
return chamfer;
} // if (IsAChamfer ...
if (!IsLineOrCircle(E1,newFace)
|| !IsLineOrCircle(E2,newFace) ) {
status = ChFi2d_NotAuthorized;
return chamfer;
} // if (!IsLineOrCircle ...
// EE1 and EE2 are copies of E1 and E2 with the good orientation
// on <newFace>
TopoDS_Edge EE1, EE2;
status = ChFi2d::FindConnectedEdges(newFace, commonVertex, EE1, EE2);
if (EE1.IsSame(E2)) {
TopAbs_Orientation orient = EE1.Orientation();
EE1 = EE2;
EE2 = E2;
EE2.Orientation(orient);
}
ComputeChamfer(commonVertex, EE1, EE2, D1, D2,
E1Mod, E2Mod, chamfer);
if (status == ChFi2d_IsDone
|| status == ChFi2d_FirstEdgeDegenerated
|| status == ChFi2d_LastEdgeDegenerated
|| status == ChFi2d_BothEdgesDegenerated) {
// if (status == ChFi2d_IsDone) {
BuildNewWire(EE1, EE2, E1Mod, chamfer, E2Mod);
basisEdge1 = BasisEdge(EE1);
basisEdge2 = BasisEdge(EE2);
UpDateHistory(basisEdge1, basisEdge2,
E1Mod, E2Mod, chamfer, 2);
status = ChFi2d_IsDone;
return TopoDS::Edge(chamfers.Value(chamfers.Length()));
}
return chamfer;
} // AddChamfer
//=======================================================================
//function : AddChamfer
//purpose :
//=======================================================================
TopoDS_Edge ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E,
const TopoDS_Vertex& V,
const Standard_Real D,
const Standard_Real Ang)
{
TopoDS_Edge aChamfer, adjEdge1, adjEdge2;
status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2);
if (status == ChFi2d_ConnexionError) return aChamfer;
// adjEdge1 is a copy of E with the good orientation
// on <newFace>
if (adjEdge2.IsSame(E)) {
TopAbs_Orientation orient = adjEdge2.Orientation();
adjEdge2 = adjEdge1;
adjEdge1 = E;
adjEdge1.Orientation(orient);
}
if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) ||
IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) {
status = ChFi2d_NotAuthorized;
return aChamfer;
} // if (IsAChamfer ...
if (!IsLineOrCircle(adjEdge1,newFace)
|| !IsLineOrCircle(adjEdge1,newFace) ) {
status = ChFi2d_NotAuthorized;
return aChamfer;
} // if (!IsLineOrCircle ...
TopoDS_Edge E1, E2;
ComputeChamfer(V, adjEdge1, D, Ang,
adjEdge2, E1, E2, aChamfer);
TopoDS_Edge basisEdge1, basisEdge2;
if (status == ChFi2d_IsDone
|| status == ChFi2d_FirstEdgeDegenerated
|| status == ChFi2d_LastEdgeDegenerated
|| status == ChFi2d_BothEdgesDegenerated) {
// if (status == ChFi2d_IsDone) {
BuildNewWire(adjEdge1, adjEdge2, E1, aChamfer, E2);
basisEdge1 = BasisEdge(adjEdge1);
basisEdge2 = BasisEdge(adjEdge2);
UpDateHistory(basisEdge1, basisEdge2,
E1, E2, aChamfer, 2);
status = ChFi2d_IsDone;
return TopoDS::Edge(chamfers.Value(chamfers.Length()));
}
return aChamfer;
}
//=======================================================================
//function : ComputeChamfer
//purpose :
//=======================================================================
void ChFi2d_Builder::ComputeChamfer(const TopoDS_Vertex& V,
const TopoDS_Edge& E1,
const TopoDS_Edge& E2,
const Standard_Real D1,
const Standard_Real D2,
TopoDS_Edge& TrimE1,
TopoDS_Edge& TrimE2,
TopoDS_Edge& Chamfer)
{
TopoDS_Vertex newExtr1, newExtr2;
Standard_Boolean Degen1, Degen2;
Chamfer = BuildChamferEdge(V, E1, E2, D1, D2, newExtr1, newExtr2);
if ( status != ChFi2d_IsDone) return;
TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
// TrimE1 = BuildNewEdge(E1, V, newExtr1);
// TrimE2 = BuildNewEdge(E2, V, newExtr2);
} // ComputeChamfer
//=======================================================================
//function : ComputeChamfer
//purpose :
//=======================================================================
void ChFi2d_Builder::ComputeChamfer(const TopoDS_Vertex& V,
const TopoDS_Edge& E1,
const Standard_Real D,
const Standard_Real Ang,
const TopoDS_Edge& E2,
TopoDS_Edge& TrimE1,
TopoDS_Edge& TrimE2,
TopoDS_Edge& Chamfer)
{
TopoDS_Vertex newExtr1, newExtr2;
Standard_Boolean Degen1, Degen2;
Chamfer = BuildChamferEdge(V, E1, D, Ang, E2, newExtr1, newExtr2);
if ( status != ChFi2d_IsDone) return;
TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
// TrimE1 = BuildNewEdge(E1, V, newExtr1);
// TrimE2 = BuildNewEdge(E2, V, newExtr2);
} // ComputeChamfer
//=======================================================================
//function : ModifyFillet
//purpose :
//=======================================================================
TopoDS_Edge ChFi2d_Builder::ModifyChamfer(const TopoDS_Edge& Chamfer,
const TopoDS_Edge& E1,
const TopoDS_Edge& E2,
const Standard_Real D1,
const Standard_Real D2)
{
TopoDS_Vertex aVertex = RemoveChamfer(Chamfer);
TopoDS_Edge adjEdge1, adjEdge2;
status = ChFi2d::FindConnectedEdges(newFace, aVertex, adjEdge1, adjEdge2);
TopoDS_Edge aChamfer;
if (status == ChFi2d_ConnexionError) return aChamfer;
// adjEdge1 and adjEdge2 are copies of E1 and E2 with the good orientation
// on <newFace>
if (adjEdge1.IsSame(E2)) {
TopAbs_Orientation orient = adjEdge1.Orientation();
adjEdge1 = adjEdge2;
adjEdge2 = E2;
adjEdge2.Orientation(orient);
}
aChamfer = AddChamfer(adjEdge1, adjEdge2, D1, D2);
return aChamfer;
} // ModifyChamfer
//=======================================================================
//function : ModifyFillet
//purpose :
//=======================================================================
TopoDS_Edge ChFi2d_Builder::ModifyChamfer(const TopoDS_Edge& Chamfer,
const TopoDS_Edge& E,
const Standard_Real D,
const Standard_Real Ang)
{
TopoDS_Vertex aVertex = RemoveChamfer(Chamfer);
TopoDS_Edge adjEdge1, adjEdge2;
status = ChFi2d::FindConnectedEdges(newFace, aVertex, adjEdge1, adjEdge2);
TopoDS_Edge aChamfer;
if (status == ChFi2d_ConnexionError) return aChamfer;
if (adjEdge1.IsSame(E))
aChamfer = AddChamfer(adjEdge1, aVertex, D, Ang);
else aChamfer = AddChamfer(adjEdge2, aVertex, D, Ang);
return aChamfer;
} // ModifyChamfer
//=======================================================================
//function : RemoveChamfer
//purpose :
//=======================================================================
TopoDS_Vertex ChFi2d_Builder::RemoveChamfer(const TopoDS_Edge& Chamfer)
{
TopoDS_Vertex commonVertex;
Standard_Integer i = 1;
Standard_Integer IsFind = Standard_False;
while (i <= chamfers.Length()) {
const TopoDS_Edge& aChamfer = TopoDS::Edge(chamfers.Value(i));
if (aChamfer.IsSame(Chamfer)) {
chamfers.Remove(i);
IsFind = Standard_True;
break;
}
i++;
}
if (!IsFind) return commonVertex;
TopoDS_Vertex firstVertex, lastVertex;
TopExp::Vertices(Chamfer, firstVertex, lastVertex);
TopoDS_Edge adjEdge1, adjEdge2;
status = ChFi2d::FindConnectedEdges(newFace, firstVertex,
adjEdge1, adjEdge2);
if (status == ChFi2d_ConnexionError) return commonVertex;
TopoDS_Edge basisEdge1, basisEdge2, E1, E2;
// E1 and E2 are the adjacentes edges to Chamfer
if (adjEdge1.IsSame(Chamfer)) E1 = adjEdge2;
else E1 = adjEdge1;
basisEdge1 = BasisEdge(E1);
status = ChFi2d::FindConnectedEdges(newFace, lastVertex,adjEdge1, adjEdge2);
if (status == ChFi2d_ConnexionError) return commonVertex;
if (adjEdge1.IsSame(Chamfer)) E2 = adjEdge2;
else E2 = adjEdge1;
basisEdge2 = BasisEdge(E2);
TopoDS_Vertex connectionE1Chamfer, connectionE2Chamfer;
Standard_Boolean hasConnection =
ChFi2d::CommonVertex(basisEdge1, basisEdge2, commonVertex);
if (!hasConnection) {
status = ChFi2d_ConnexionError;
return commonVertex;
}
hasConnection = ChFi2d::CommonVertex(E1, Chamfer, connectionE1Chamfer);
if (!hasConnection) {
status = ChFi2d_ConnexionError;
return commonVertex;
}
hasConnection = ChFi2d::CommonVertex(E2, Chamfer, connectionE2Chamfer);
if (!hasConnection) {
status = ChFi2d_ConnexionError;
return commonVertex;
}
// rebuild edges on wire
TopoDS_Edge newEdge1, newEdge2;
TopoDS_Vertex v, v1, v2;
BRepLib_MakeEdge makeEdge;
TopLoc_Location loc;
Standard_Real first, last;
TopExp::Vertices(E1, firstVertex, lastVertex);
TopExp::Vertices(basisEdge1, v1, v2);
if (v1.IsSame(commonVertex)) v = v2;
else v = v1;
if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
// It means the edge support only one fillet. In this case
// the new edge must be the basis edge.
newEdge1 = basisEdge1;
else {
// It means the edge support one fillet on each end.
if (firstVertex.IsSame(connectionE1Chamfer)) {
// syntaxe invalide sur NT
// const Handle(Geom_Curve)& curve =
// BRep_Tool::Curve(E1, loc, first, last);
Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
makeEdge.Init(curve, commonVertex, lastVertex);
newEdge1 = makeEdge.Edge();
newEdge1.Orientation(basisEdge1.Orientation());
newEdge1.Location(basisEdge1.Location());
} // if (firstVertex ...
else if (lastVertex.IsSame(connectionE1Chamfer)) {
// syntaxe invalide sur NT
// const Handle(Geom_Curve)& curve =
// BRep_Tool::Curve(E1, loc, first, last);
Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
makeEdge.Init(curve, firstVertex, commonVertex);
newEdge1 = makeEdge.Edge();
newEdge1.Orientation(basisEdge1.Orientation());
newEdge1.Location(basisEdge1.Location());
} // else if (lastVertex ...
} // else ...
TopExp::Vertices(basisEdge2, v1, v2);
if (v1.IsSame(commonVertex)) v = v2;
else v = v1;
TopExp::Vertices(E2, firstVertex, lastVertex);
if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
// It means the edge support only one fillet. In this case
// the new edge must be the basis edge.
newEdge2 = basisEdge2;
else {
// It means the edge support one fillet on each end.
if (firstVertex.IsSame(connectionE2Chamfer)) {
// syntaxe invalide sur NT
// const Handle(Geom_Curve)& curve =
// BRep_Tool::Curve(E2, loc, first, last);
Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
makeEdge.Init(curve, commonVertex, lastVertex);
newEdge2 = makeEdge.Edge();
newEdge2.Orientation(basisEdge2.Orientation());
newEdge2.Location(basisEdge2.Location());
} // if (firstVertex ...
else if (lastVertex.IsSame(connectionE2Chamfer)) {
// syntaxe invalide sur NT
// const Handle(Geom_Curve)& curve =
// BRep_Tool::Curve(E2, loc, first, last);
Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
makeEdge.Init(curve, firstVertex, commonVertex);
newEdge2 = makeEdge.Edge();
newEdge2.Orientation(basisEdge2.Orientation());
newEdge2.Location(basisEdge2.Location());
} // else if (lastVertex ...
} // else ...
// rebuild the newFace
TopExp_Explorer Ex(newFace, TopAbs_EDGE);
TopoDS_Wire newWire;
BRep_Builder B;
B.MakeWire(newWire);
while (Ex.More()) {
const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
if (!theEdge.IsSame(E1) &&
!theEdge.IsSame(E2) &&
!theEdge.IsSame(Chamfer) )
B.Add(newWire, theEdge);
else {
if (theEdge == E1)
B.Add(newWire, newEdge1);
else if (theEdge == E2)
B.Add(newWire, newEdge2);
} // else
Ex.Next();
} // while ...
BRepAdaptor_Surface Adaptor3dSurface(refFace);
BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
newFace.Nullify();
newFace = mFace;
UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2);
return commonVertex;
} // RemoveChamfer
//=======================================================================
//function : BuildChamferEdge
//purpose :
//=======================================================================
TopoDS_Edge ChFi2d_Builder::BuildChamferEdge(const TopoDS_Vertex& V,
const TopoDS_Edge& AdjEdge1,
const TopoDS_Edge& AdjEdge2,
const Standard_Real D1,
const Standard_Real D2,
TopoDS_Vertex& NewExtr1,
TopoDS_Vertex& NewExtr2)
{
TopoDS_Edge chamfer;
if ( D1 <= 0 || D2 <= 0) {
status = ChFi2d_ParametersError;
return chamfer;
} // if ( D1 <=0 ...
Standard_Real param1, param2;
gp_Pnt p1 = ComputePoint(V, AdjEdge1, D1, param1);
gp_Pnt p2 = ComputePoint(V, AdjEdge2, D2, param2);
Standard_Real tol = Precision::Confusion();
BRep_Builder B;
B.MakeVertex(NewExtr1, p1, tol);
B.MakeVertex(NewExtr2, p2, tol);
NewExtr1.Orientation(TopAbs_FORWARD);
NewExtr2.Orientation(TopAbs_REVERSED);
// chamfer edge construction
TopLoc_Location loc;
const Handle(Geom_Surface) refSurf = BRep_Tool::Surface(refFace, loc);
gp_Vec myVec( p1, p2);
gp_Dir myDir(myVec);
Handle(Geom_Line) newLine = new Geom_Line( p1, myDir);
Standard_Real param = ElCLib::Parameter(newLine->Lin(), p2);
B.MakeEdge(chamfer, newLine, tol);
B.Range(chamfer,0., param);
B.Add(chamfer, NewExtr1);
B.UpdateVertex(NewExtr1,0., chamfer, tol);
B.Add(chamfer, NewExtr2);
B.UpdateVertex(NewExtr2,param, chamfer, tol);
OrientChamfer(chamfer, AdjEdge1, V);
// set the orientation of NewExtr1 and NewExtr2 for the adjacent edges
TopoDS_Vertex V1 = TopExp::FirstVertex(AdjEdge1);
TopoDS_Vertex V2 = TopExp::LastVertex(AdjEdge1);
if (V1.IsSame(V)) NewExtr1.Orientation(V1.Orientation());
else NewExtr1.Orientation(V2.Orientation());
V1 = TopExp::FirstVertex(AdjEdge2);
V2 = TopExp::LastVertex(AdjEdge2);
if (V1.IsSame(V)) NewExtr2.Orientation(V1.Orientation());
else NewExtr2.Orientation(V2.Orientation());
B.UpdateVertex(NewExtr1, param1, AdjEdge1, tol);
B.UpdateVertex(NewExtr2, param2, AdjEdge2, tol);
status = ChFi2d_IsDone;
return chamfer;
} // BuildChamferEdge
//=======================================================================
//function : BuildFilletEdge
//purpose :
//=======================================================================
TopoDS_Edge ChFi2d_Builder::BuildChamferEdge(const TopoDS_Vertex& V,
const TopoDS_Edge& AdjEdge1,
const Standard_Real D,
const Standard_Real Ang,
const TopoDS_Edge& AdjEdge2,
TopoDS_Vertex& NewExtr1,
TopoDS_Vertex& NewExtr2)
{
TopoDS_Edge chamfer;
if ( D <= 0 || Ang <= 0) {
status = ChFi2d_ParametersError;
return chamfer;
} // if ( D <= 0 ...
Standard_Real param1, param2;
gp_Pnt p1 = ComputePoint(V, AdjEdge1, D, param1);
gp_Pnt p = BRep_Tool::Pnt(V);
gp_Vec myVec( p1, p);
// compute the tangent vector on AdjEdge2 at the vertex V.
BRepAdaptor_Curve c(AdjEdge2, refFace);
Standard_Real first, last;
first = c.FirstParameter();
last = c.LastParameter();
gp_Pnt aPoint;
gp_Vec tan;
c.D1(first, aPoint, tan);
if (aPoint.Distance(p) > Precision::Confusion()) {
c.D1(last, aPoint, tan);
}
// tangent orientation
TopoDS_Vertex v1, v2;
TopExp::Vertices(AdjEdge2, v1, v2);
TopAbs_Orientation orient;
if (v1.IsSame(V)) orient = v1.Orientation();
else orient = v2.Orientation();
if (orient == TopAbs_REVERSED) tan *= -1;
// compute the chamfer geometric support
gp_Ax1 RotAxe(p1, tan^myVec);
gp_Vec vecLin = myVec.Rotated(RotAxe, -Ang);
gp_Dir myDir(vecLin);
Handle(Geom_Line) newLine = new Geom_Line( p1, myDir);
BRep_Builder B1;
B1.MakeEdge(chamfer, newLine, Precision::Confusion());
gp_Pnt p2 = ComputePoint(refFace, newLine, AdjEdge2, param2);
Standard_Real tol = Precision::Confusion();
BRep_Builder B;
B.MakeVertex(NewExtr1, p1, tol);
B.MakeVertex(NewExtr2, p2, tol);
NewExtr1.Orientation(TopAbs_FORWARD);
NewExtr2.Orientation(TopAbs_REVERSED);
// chamfer edge construction
Standard_Real param = ElCLib::Parameter(newLine->Lin(), p2);
B.MakeEdge(chamfer, newLine, tol);
B.Range(chamfer,0., param);
B.Add(chamfer, NewExtr1);
B.UpdateVertex(NewExtr1,0., chamfer, tol);
B.Add(chamfer, NewExtr2);
B.UpdateVertex(NewExtr2,param, chamfer, tol);
OrientChamfer(chamfer, AdjEdge1, V);
// set the orientation of NewExtr1 and NewExtr2 for the adjacent edges
TopoDS_Vertex V1 = TopExp::FirstVertex(AdjEdge1);
TopoDS_Vertex V2 = TopExp::LastVertex(AdjEdge1);
if (V1.IsSame(V)) NewExtr1.Orientation(V1.Orientation());
else NewExtr1.Orientation(V2.Orientation());
V1 = TopExp::FirstVertex(AdjEdge2);
V2 = TopExp::LastVertex(AdjEdge2);
if (V1.IsSame(V)) NewExtr2.Orientation(V1.Orientation());
else NewExtr2.Orientation(V2.Orientation());
B.UpdateVertex(NewExtr1, param1, AdjEdge1, tol);
B.UpdateVertex(NewExtr2, param2, AdjEdge2, tol);
status = ChFi2d_IsDone;
return chamfer;
}
//=======================================================================
//function : ComputePoint
//purpose :
//=======================================================================
gp_Pnt ComputePoint(const TopoDS_Vertex& V,const TopoDS_Edge& E,
const Standard_Real D, Standard_Real& Param)
{
// geometric support
BRepAdaptor_Curve c(E);
Standard_Real first, last;
first = c.FirstParameter();
last = c.LastParameter();
gp_Pnt thePoint;
if (c.GetType() == GeomAbs_Line) {
gp_Pnt p1, p2;
TopoDS_Vertex v1, v2;
TopExp::Vertices(E, v1, v2);
p1 = BRep_Tool::Pnt(v1);
p2 = BRep_Tool::Pnt(v2);
gp_Vec myVec( p1, p2);
myVec.Normalize();
myVec *= D;
if (v2.IsSame(V)) {
myVec *= -1; // change the sense of myVec
thePoint = p2.Translated(myVec);
} // if (v2 ...
else thePoint = p1.Translated(myVec);
Param = ElCLib::Parameter(c.Line(), thePoint);
//szv:OCC20823-begin
c.D0(Param, thePoint);
//szv:OCC20823-end
return thePoint;
} // if (C->IsKind(TYPE ...
if (c.GetType() == GeomAbs_Circle) {
gp_Circ cir = c.Circle();
Standard_Real radius = cir.Radius();
TopoDS_Vertex v1, v2;
TopExp::Vertices(E, v1, v2);
Standard_Real param1,param2;
if (V.IsSame(v1)) {
param1 = BRep_Tool::Parameter(v1,E);
param2 = BRep_Tool::Parameter(v2,E);
}
else {
param1 = BRep_Tool::Parameter(v2,E);
param2 = BRep_Tool::Parameter(v1,E);
}
Standard_Real deltaAlpha = D/radius;
if (param1 > param2) Param = param1 - deltaAlpha;
else Param = param1 + deltaAlpha;
c.D0(Param, thePoint);
return thePoint;
} // if (C->IsKind(TYPE ...
else {
// in all other case than lines and circles.
gp_Pnt p;
TopoDS_Vertex v1, v2;
TopExp::Vertices(E, v1, v2);
if (V.IsSame(v1)) {
p = BRep_Tool::Pnt(v1);
}
else {
p = BRep_Tool::Pnt(v2);
}
GeomAdaptor_Curve cc = c.Curve();
if (p.Distance(c.Value(first)) <= Precision::Confusion()) {
GCPnts_AbscissaPoint computePoint(cc, D, first);
Param = computePoint.Parameter();
}
else {
GCPnts_AbscissaPoint computePoint(cc, D, last);
Param = computePoint.Parameter();
}
thePoint = cc.Value(Param);
return thePoint;
} // else ...
return thePoint;
} // ComputePoint
//=======================================================================
//function : ComputePoint
//purpose :
//=======================================================================
gp_Pnt ComputePoint(const TopoDS_Face& F,
const Handle(Geom_Line)& L,
const TopoDS_Edge& E,
Standard_Real& Param)
{
BRepAdaptor_Surface Adaptor3dSurface(F);
Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane());
Handle(Geom2d_Curve) lin2d = GeomAPI::To2d(L, refSurf->Pln());
Handle(Geom2d_Curve) c2d;
Standard_Real first, last;
c2d = BRep_Tool::CurveOnSurface(E, F, first, last);
Geom2dAdaptor_Curve adaptorL(lin2d);
Geom2dAdaptor_Curve adaptorC(c2d);
Geom2dInt_GInter Intersection(adaptorL, adaptorC,
Precision::PIntersection(),
Precision::PIntersection());
Standard_Real paramOnLine = 1E300;
gp_Pnt2d p2d;
if (Intersection.IsDone()) {
Standard_Integer i = 1;
while ( i <= Intersection.NbPoints()) {
IntRes2d_IntersectionPoint iP = Intersection.Point(i);
if (iP.ParamOnFirst() < paramOnLine) {
p2d = iP.Value();
paramOnLine = iP.ParamOnFirst();
Param = iP.ParamOnSecond();
} // if (iP.ParamOnFirst ...
i++;
} // while ( i <= ...
} // if (Intersection.IsDone ...
gp_Pnt thePoint = Adaptor3dSurface.Value(p2d.X(), p2d.Y());
return thePoint;
} // ComputePoint
//=======================================================================
//function : OrientChamfer
//purpose :
//=======================================================================
void OrientChamfer(TopoDS_Edge& chamfer,
const TopoDS_Edge& E,
const TopoDS_Vertex& V)
{
TopAbs_Orientation vOrient, orient = E.Orientation();
TopoDS_Vertex v1, v2;
TopExp::Vertices(E, v1, v2);
if (v1.IsSame(V)) vOrient = v2.Orientation();
else vOrient = v1.Orientation();
if ((orient == TopAbs_FORWARD && vOrient == TopAbs_FORWARD) ||
(orient == TopAbs_REVERSED && vOrient == TopAbs_REVERSED))
chamfer.Orientation(TopAbs_FORWARD);
else chamfer.Orientation(TopAbs_REVERSED);
} // OrientChamfer
//=======================================================================
//function : IsLineOrCircle
//purpose :
//=======================================================================
Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
const TopoDS_Face& F)
{
Standard_Real first, last;
TopLoc_Location loc;
// syntaxe invalide sur NT
// const Handle(Geom2d_Curve)& C =
// BRep_Tool::CurveOnSurface(E,F,first,last);
Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last);
Handle(Geom2d_Curve) basisC;
Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
if (!TC.IsNull())
basisC = Handle(Geom2d_Curve)::DownCast(TC->BasisCurve());
else
basisC = Handle(Geom2d_Curve)::DownCast(C);
if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
|| basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
return Standard_True;
}
else {
return Standard_False;
} // else ...
} // IsLineOrCircle