Forum archiveIssue archiveModeling Data and Algorithms

Archived discussion

BRepPrimAPI_MakeRevol -> no wire/edges in result shape... Why?

Modeling Data and AlgorithmsThu, 04/27/2023 - 13:1716 replies

Browse this forum
QuestionAuthor

Guys, i produce BRepPrimAPI_MakeRevol of simple rect profile and after i can't find any normal wires/edges data inside shape entity, why? In case of BRepPrimAPI_MakePrism -> all ok, but BRepPrimAPI_MakeRevol doesn't work properly for wires/edges...

I do:
BRepPrimAPI_MakeRevol -> shape
...

uint32_t c1 = 0;
for (TopExp_Explorer ex0(shape, TopAbs_WIRE); ex0.More(); ex0.Next())
{
TopoDS_Wire wire = TopoDS::Wire(ex0.Current());
std::cout << "=========WIRE: " << c1++ << std::endl;
int c2 = 0;
for (TopExp_Explorer ex1(wire, TopAbs_EDGE); ex1.More(); ex1.Next())
{
std::cout << "+++++++EDGE: " << c2++ << std::endl;
TopoDS_Edge edge = TopoDS::Edge(ex1.Current());
for (TopExp_Explorer ex2(edge, TopAbs_VERTEX); ex2.More(); ex2.Next())
{
TopoDS_Vertex vertex = TopoDS::Vertex(ex2.Current());
gp_Pnt p = BRep_Tool::Pnt(vertex);
std::cout << "\t" << p.X() << " " << p.Y() << " " << p.Z() << std::endl;
}
}
}

and result looks like crap... No desired circular edges... Hmm, any ideas?

=========WIRE: 0
+++++++EDGE: 0
-100 0 200
-100 0 200
+++++++EDGE: 1
100 0 200
100 0 200
+++++++EDGE: 2
-100 0 200
100 0 200
+++++++EDGE: 3
-100 0 200
100 0 200
=========WIRE: 1
+++++++EDGE: 0
-100 0 100
-100 0 100
=========WIRE: 2
+++++++EDGE: 0
-100 0 200
-100 0 200
=========WIRE: 3
+++++++EDGE: 0
100 0 100
100 0 100
+++++++EDGE: 1
-100 0 100
-100 0 100
+++++++EDGE: 2
100 0 100
-100 0 100
+++++++EDGE: 3
100 0 100
-100 0 100
=========WIRE: 4
+++++++EDGE: 0
100 0 200
100 0 200
=========WIRE: 5
+++++++EDGE: 0
100 0 100
100 0 100

Discussion

16 archived replies

Posts are displayed in their archived order.

01Commenter-1

Hello, unfortunately, I'm not very familiar with the BRepPrimAPI_MakeRevol function. However, I think your result is valid.

As far as I can see, you have received a surface of revolution. The faces built using this type of surface have natural boundaries and do not require any additional boundaries such as wires.

Best regards, Commenter-1

02Author

Well, i guess i have to additionally rotate my vertices of sketch profile by BRepPrimAPI_MakeRevol to get edges. I'll try it now and let you know what happens.

03Author

It looks like a bug, nothing works. Vertices also don't rotate around axis to form edges... I do this:

int ccc = 0;
std::unordered_map<glm::dvec3, TopoDS_Vertex> ds;
for (TopExp_Explorer ex0(face, TopAbs_VERTEX); ex0.More(); ex0.Next())
{
TopoDS_Vertex vertex = TopoDS::Vertex(ex0.Current());
gp_Pnt p = BRep_Tool::Pnt(vertex);
ccc++;
glm::dvec3 dp(p.X(), p.Y(), p.Z());
ds.insert({ dp, vertex });
}

int vc = 0;
for (auto& it : ds)
{
BRepPrimAPI_MakeRevol revolve(it.second, revAxis, Standard_True);
if (!revolve.IsDone())
return false;
TopoDS_Shape revEdge = revolve.Shape();

TopAbs_ShapeEnum revEdgeType = revEdge.ShapeType();

int ec = 0;
//std::vector<glm::dvec3> edgeVertices;
for (TopExp_Explorer ex0(revEdge, TopAbs_VERTEX); ex0.More(); ex0.Next())
{
TopoDS_Vertex vertex = TopoDS::Vertex(ex0.Current());
gp_Pnt p = BRep_Tool::Pnt(vertex);
glm::dvec3 dp(p.X(), p.Y(), p.Z());
//edgeVertices.emplace_back(dp);

std::cout << "ROTATED VERTEX#" << vc << " DOT#" << ec << "\t:" << dp.x << " " << dp.y << " " << dp.z << std::endl;
ec++;
}

vc++;
}

and taking:
ROTATED VERTEX#0 DOT#0 :100 0 100
ROTATED VERTEX#0 DOT#1 :100 0 100
ROTATED VERTEX#1 DOT#0 :-100 0 200
ROTATED VERTEX#1 DOT#1 :-100 0 200
ROTATED VERTEX#2 DOT#0 :-100 0 100
ROTATED VERTEX#2 DOT#1 :-100 0 100
ROTATED VERTEX#3 DOT#0 :100 0 200
ROTATED VERTEX#3 DOT#1 :100 0 200

Look at attached image

04Commenter-1

Im very interested on type if Edge curve, that generated.

Can you share result brep file after generation? You can just Write TopoDS_Shape into file using follow code:

 Handle(DEBRepCascade_ConfigurationNode) aNode = new DEBRepCascade_ConfigurationNode();
 // You can modify export setting by aNode->InternalParameters
 Handle(DE_Provider) aProvider = aNode->BuildProvider();
 aProvider->Write("Path",aShape);

Im interested in full result and rotating of vertexes. Can you share types of generated edges? It looks like a circle. If it is a circle, you be able to recieve a point on curve by getting value from pereodic (for example aCircle->Value(Pi))

Best regards, Commenter-1.

05Author

ok, look at my revovle-dump files, i don't understand them :)

06Commenter-1

I was right. It is a circle. Now you be able to recieve a "gp_Pnt aPont = aCurve->Value(M_PI)"; or any other pereodic values.

Circle shareds one vertex for start and end with different orientation. So, as a result you recieve a start and end point in the same place.

Draw[3]> dump res


*********** Dump of res *************
Shape : 2, FORWARD

Dump of 2 TShapes

-----------------

Flags : Free, Modified, Checked, Orientable, Closed, Infinite, Convex, Locked

TShape # 1 : EDGE      11010000 00000251E1F6F390
    +2 -2
    Tolerance : 1e-07
     same parametrisation of curves
     same range on curves
    - Curve 3D : 1, range : 0 6.28318530717959

TShape # 2 : VERTEX    01011010 00000251E1F71700

    Tolerance : 1e-07
    - Point 3D : -100, 0, 100


 -------
Dump of 0 Curve2ds
 -------


 -------
Dump of 1 Curves
 -------

   1 : Circle
  Center :-100, 0, 0
  Axis   :-1, 0, 0
  XAxis  :0, 0, 1
  YAxis  :0, 1, -0
  Radius :100

 -------
Dump of 0 Polygon3Ds
 -------
 -------
Dump of 0 PolygonOnTriangulations
 -------

 -------
Dump of 0 surfaces
 -------

 -------
Dump of 0 Triangulations
 -------



 -------
 Dump of 0 Locations
 -------

Best regards, Commenter-1.

07Author

"Circle shareds one vertex for start and end with different orientation. So, as a result you recieve a start and end point in the same place."
Aha!! Now I begin to understand :) Thank's man, but how to convert WIRE to CURVE?

Here is "shape" -> full revolve result, now i scan it for a wires...
for (TopExp_Explorer ex0(shape, TopAbs_WIRE); ex0.More(); ex0.Next())
{
TopoDS_Wire wire = TopoDS::Wire(ex0.Current());
//1) how to get aCurve from wire?
//2) and how to check "is wire a circle-curve or simple segment"?
gp_Pnt aPont = aCurve->Value(M_PI);
}

08Commenter-1

To get a Handle(Geom_Curve) from a TopoDS_Edge that is contained in a TopoDS_Wire, you need to first extract the TopoDS_Edge from the TopoDS_Wire and then get the Handle(Geom_Curve) from the TopoDS_Edge.

Here is an example code to get a Handle(Geom_Curve) from a TopoDS_Edge that is contained in a TopoDS_Wire:

// Get the TopoDS_Wire aWire
TopoDS_Wire aWire = ...;

// Iterate over all the edges in the wire
for (TopExp_Explorer expWireEdges(aWire, TopAbs_EDGE); expWireEdges.More(); expWireEdges.Next())
{
    // Get the TopoDS_Edge from the wire
    TopoDS_Edge anEdge = TopoDS::Edge(expWireEdges.Current());

    // Get the Handle(Geom_Curve) from the TopoDS_Edge
    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge);
    // Use the Handle(Geom_Curve) here
}

Best regards, Commenter-1.

09Author

"Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge);"
Wow, cool, so easy, but how to determinate is aCurve a circle or simple segment or spline or something else?
I mean, if aCurve is just a segment, i don't need to interpolate it by aCurve->Value(M_PI)...

10Commenter-1
// Get the TopoDS_Edge anEdge
TopoDS_Edge anEdge = ...;

// Get the curve from the TopoDS_Edge
Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge);

// Determine the type of curve
if(aCurve->DynamicType() == STANDARD_TYPE(Geom_Line))
{
    // Curve is a line
}
else if(aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
{
    // Curve is a circle
}
else if(aCurve->DynamicType() == STANDARD_TYPE(Geom_Ellipse))
{
    // Curve is an ellipse
}
else if(aCurve->DynamicType() == STANDARD_TYPE(Geom_Hyperbola))
{
    // Curve is a hyperbola
}
else if(aCurve->DynamicType() == STANDARD_TYPE(Geom_Parabola))
{
    // Curve is a parabola
}
else if(aCurve->DynamicType() == STANDARD_TYPE(Geom_BezierCurve))
{
    // Curve is a Bezier curve
}
else if(aCurve->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
{
    // Curve is a BSpline curve
}
11Author

Ohh man, thank you very much! Your OCCT level - THE GOD! :-)

Last question:
In OCCT paradigm, Handle(Geom_Curve) -> self destroying smart pointer, which will deleted out of scope, right?

12Commenter-1

Yes, but it has a little different from std::shared_pointer or other std smart pointeres. It it the same with boost::intrusive_ptr

In any case, as you said, the Handle object will be destroyed as soon as it's no longer needed.

Regarding Geom_Curve, it can be a simple curve, as described earlier, but in some cases it can also be a Handle(Geom_TrimmedCurve), which has additional UV limitations and a basic simple curve that you might need.

Best regards, Commenter-1.

13Author

I made it! But how to exclude base profile from existing wires in revolve resulting shape? 

Archived image: external image

14Commenter-1

It is possible only in visualization part to disable render edge.

Unfortunatelly, I don't know the Vis API.

Best regards, Commenter-1.

15Author

I don't use built-in OCCT visualizer, I write my own render on Vulkan API.
Thanks again for help, I will find solution myself, most likely i just need to compare wires with the base profile and if it matches completely, exclude it.

16Author

Thank you more buddy!