在Open CASCADE Technology(OCCT)中,几何模型是由拓扑(Topology)和几何(Geometry)两部分组成的。拓扑部分描述了形状的拓扑结构,比如边、面、体等,而几何部分则定义了这些拓扑元素的形状。TopoDS_Edge 是拓扑边的一个类,它代表了模型中的一个边界。
TopoDS_Edge 的底层数据是 Geom_Curve,这意味着 TopoDS_Edge 的几何形状是由一个 Geom_Curve 对象来描述的。Geom_Curve 是一个抽象基类,它代表了一个几何曲线,可以是直线、圆弧、二次曲线等。
当你想要截取 TopoDS_Edge 的一部分时,你实际上是在操作其底层的 Geom_Curve。你可以通过指定 Geom_Curve 的参数区间来截取曲线的一部分。参数区间通常是由两个参数值定义的,一个起始参数和一个结束参数,这两个参数都在曲线的参数范围内。曲线的参数范围通常是从0到1,但也可能有不同的范围,具体取决于曲线的类型。
#include <Geom_BezierCurve.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <TopoDS_Edge.hxx>
#include <BRep_Tool.hxx>
#include <BRepLib.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include"Viewer.h"
int main(int argc, char* argv[])
{
//Non Rational B-Spline
gp_Pnt points1[8] = {
gp_Pnt(0.0,-100.0,0.0),
gp_Pnt(10.0,10.0,0.0),
gp_Pnt(30.0,-100.0,0.0),
gp_Pnt(100.0,0.0,0.0),
gp_Pnt(150.0,50.0,0.0),
gp_Pnt(200.0,0.0,0.0),
gp_Pnt(400.0,200.0,0.0),
gp_Pnt(450.0,0.0,0.0)
};
NCollection_Array1<gp_Pnt> points(points1[0], 1, 8);//Control points
Standard_Real realsWeight[8] = { 1.0,1.0,1.0,1.0,1.0,1.0,10.0,1.0 };
NCollection_Array1<Standard_Real> weight(realsWeight[0], 1, 8);//权系数,倒数第二个点的权系数是其他的10倍。
Geom_BezierCurve bezier(points); //Non-Rational
Handle(Geom_BezierCurve) bezier1 = &bezier;
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(bezier1);
gp_Pnt pnt = gp_Pnt(150.0, 50.0, 0.0);
TopoDS_Edge E1, E2;
Standard_Real startParam(0.), endParam(0.);
Handle(Geom_Curve) c = BRep_Tool::Curve(E, startParam, endParam);//得到底层曲线
//有时底层曲线没有创建,要手动创建
if (c.IsNull())
{
BRepLib::BuildCurves3d(E, 1.0e-5, GeomAbs_C1);//创建曲线
c = BRep_Tool::Curve(E, startParam, endParam);
}
if (!c.IsNull())
{
//投影点到曲线上,并获取投影点处的参数
GeomAPI_ProjectPointOnCurve ppc(pnt, c);
Standard_Real param = ppc.LowerDistanceParameter();
//如果投影点参数小于起始参数或大于终止参数,则分割失败
if (startParam - param > 0.00001 || param - endParam > 0.00001)
return false;
//如果正好等于起始参数或等于终止参数,则一边是原始边,另一边为NULL
else if (Abs(param - startParam) <= Precision::Confusion())
E1 = E;
else if (Abs(param - endParam) <= Precision::Confusion())
E2 = E;
//处于起始和终止参数中间,则构建两个新边
else
{
E1 = BRepBuilderAPI_MakeEdge(c, startParam, param);
E1.Orientation(E.Orientation());//同向
E2 = BRepBuilderAPI_MakeEdge(c, param, endParam);
E2.Orientation(E.Orientation());//同向
if (E.Orientation() == TopAbs_REVERSED)
{
TopoDS_Edge e = E1;
E1 = E2;
E2 = e;
}
}
}
Viewer vout(50, 50, 500, 500);
vout << E;
vout << E1;
vout << E2;
vout.StartMessageLoop();
return 0;
}