Curve and support points

Hello,

I traverse with the help of some TopExp_Explorer instances: TopoDS_Shape, TopAbs_FACE, TopAbs_WIRE, TopAbs_EDGE, TopAbs_VERTEX. Each vertex I transform into a gp_Pnt by BRep_Tool::Pnt(). I need all the points of a TopAbs_FACE for further works. Now is my problem that I only get two vertices per edge, but what I need is: if the edge is not a line (so it has to be a curve) then create support points in a step width of x, which are in line with the edge (I have to represent the curve by a line through some points). Is there anything in OpenCascade what I can use for this task? Has anybody an example? Thanks at the moment.

Here is some code:

TopExp_Explorer vertexExplorer;
// Here I need something like if edge is curve then generate support points. But I don't know how to do this.

// Process each vertex of an edge.
for (vertexExplorer.Init(edge, TopAbs_VERTEX); vertexExplorer.More(); vertexExplorer.Next())
{
TopoDS_Vertex vertex = TopoDS::Vertex(vertexExplorer.Current());
// Get the 3D point for the vertex.
gp_Pnt p = BRep_Tool::Pnt(vertex);
// If the point does not exist already then create a new one.
std::vector::iterator iter = std::find(points.begin(), points.end(), p);
if (iter == points.end())
{
// Point does not exist already.
points.push_back(p);
}
}

Greets
Patrick

Jan Brüninghaus's picture

I think the class GCPnts_UniformAbscissa or GCPnts_UniformDeflection is something for you. There are examples of using this classes somewhere in the samples provided with OCC.

pkoeppe's picture

How do I find out whether a TopAbs_EDGE is a line or a curve?

Daniel Kelley's picture

I convert the TopoDS_Edge to GeomCurve and test the curve DynamicType:

string
edge2string(const TopoDS_Edge &e)
{
Standard_Real c_start;
Standard_Real c_end;
Handle(Geom_Curve) c = BRep_Tool::Curve(e,c_start,c_end);
string s;

if (c->DynamicType() == STANDARD_TYPE(Geom_BezierCurve)) {
s = "Geom_BezierCurve";
} else if (c->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) {
s = "Geom_BSplineCurve";
} else if (c->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
s = "Geom_TrimmedCurve";
} else if (c->DynamicType() == STANDARD_TYPE(Geom_Circle)) {
s = "Geom_Circle";
} else if (c->DynamicType() == STANDARD_TYPE(Geom_Ellipse)) {
s = "Geom_Ellipse";
} else if (c->DynamicType() == STANDARD_TYPE(Geom_Hyperbola)) {
s = "Geom_Hyperbola";
} else if (c->DynamicType() == STANDARD_TYPE(Geom_Parabola)) {
s = "Geom_Parabola";
} else if (c->DynamicType() == STANDARD_TYPE(Geom_Line)) {
s = "Geom_Line";
} else if (c->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) {
s = "Geom_OffsetCurve";
} else {
s = "Unknown";
}
return s;
}

pkoeppe's picture

Thanks for your replies. I use the DynamicType test, if the type is not a line then I need support points.

1. How can I generate support points so that the length of the partial edges is less than a defined step width and all partial edge lengths are equal?
I get the length of the edge with GProp_GProps and Mass(). By dividing the length through the step width (and rounding up) I get the number of needed support points. So I need anything to say generate x equidistant points on the edge. How to do this?

2. How can I generate support points so that the approximation of the edge has a deflection of x?

Greets
Patrick

pkoeppe's picture

Has nobody an idea???

Bearloga's picture

See the reply of Jan Brüninghaus above in this thread.

pkoeppe's picture

I get an error "Unhandled exception at 0x0042eaac in test.exe: 0xC0000005: Access violation when reading at position 0xfefd0000.", has anybody an idea why?

// Determine the type of the edge.
Standard_Real c_start;
Standard_Real c_end;
Handle(Geom_Curve) c = BRep_Tool::Curve(TopoDS::Edge(shape), c_start, c_end); // shape is a TopoDS_Shape
// If the edge is not a line then calculate support points.
if (c->DynamicType() != STANDARD_TYPE(Geom_Line)) // here I get the error
{
...
}

Bearloga's picture

Your edge does not contain 3d curve. You can build 3d curves in the shape using ShapeFix package.

pkoeppe's picture

Ok, I tried something with GCPnts_UniformAbscissa. But I get an error, here is the code:

TopoDS_Edge edge = TopoDS::Edge(shape); // shape is a TopoDS_Shape
Standard_Real c_start;
Standard_Real c_end;
Handle(Geom_Curve) c = BRep_Tool::Curve(edge, c_start, c_end);
gp_Pnt p;

if (c->DynamicType() != STANDARD_TYPE(Geom_Line))
{
GProp_GProps system;
BRepGProp::LinearProperties(crEdge, system);
Standard_Real length = system.Mass();
Standard_Real stepWidth = 10;
int n = length / stepWidth;

GeomAdaptor_Curve gac(c);
GCPnts_UniformAbscissa algo(gac, n); // create n new points
if (algo.IsDone())
{
// show the new points
for (int i = 0; i < algo.NbPoints(); i++)
{
c->D0(algo.Parameter(i), p); // here I get: Standard_OutOfRange
cout << p.X() << " " << p.Y() << " " << p.Z() << "\n";
}
}
}

Can anybody help?

Bearloga's picture

Argument of algo.Parameter() must start from 1 rather than 0.

BTW, replace
GeomAdaptor_Curve gac(c);
with
BRepAdaptor_Curve gac(edge);
or
GeomAdaptor_Curve gac(c, c_start, c_end);
in order to work on a bounded curve.

pkoeppe's picture

Thanks. How can I get the radius of a curve? Is there any function in OCC?

Bearloga's picture

If the curve is a circle then cast to Geom_Circle and get the radius. Otherwise, use GeomLProp_CLProps to get curvature in a given point.