There are two important cases if you want to get a TopoDS_Solid
object from a TopoDS_Shape
:
A: The TopoDS_Shape
is a solid
You can check if that is the case using
#include <TopoDS_Shape.hxx> TopoDS_Shape myShape = /* ... */ bool isSolid = myShape.ShapeType() == TopAbs_SOLID;
Alternatively, you can use the Shape::IsSolid()
function from OCCUtils:
#include <occutils/Shape.hxx> using namespace OCCUtils; TopoDS_Shape myShape = /* ... */; if(Shape::IsSolid(myShape)) { /* ... */ }
If it’s a solid, you can convert it to a TopoDS_Solid
directly using:
TopoDS::Solid(myShape);
Full example:
#include <TopoDS_Shape.hxx> #include <TopoDS.hxx> #include <occutils/Shape.hxx> using namespace OCCUtils; TopoDS_Shape myShape = /* ... */; if (Shape::IsSolid(myShape)) { TopoDS_Solid solid = TopoDS::Solid(myShape); /* ... */ }
B: The shape is not itself a TopoDS_Solid
but contains one or more TopoDS_Solid
s
This is often the case for TopoDS_Compounds. Use Shape::IsCompound()
from OCCUtils to check if your TopoDS_Shape
is actually a TopoDS_Compound
.
#include <occutils/Shape.hxx> using namespace OCCUtils; TopoDS_Shape myShape = /* ... */; if(Shape::IsCompound(myShape)) { /* ... */ }
Using OCCUtils, you have now several options to get the TopoDS_Solid
s from the Compound:
If there is a chance that there are zero or more than one TopoDS_Solid
s in your compound:
Use ShapeComponents::AllSolidsWithin()
from OCCUtils to get a std::vector<TopoDS_Solid>
of all solids within the TopoDS_Compound
:
#include <occutils/Shape.hxx> #include <occutils/ShapeComponents.hxx> using namespace OCCUtils; TopoDS_Shape myShape = /* ... */; auto solids = ShapeComponents::AllSolidsWithin(myShape); // Iterate all solids for(const TopoDS_Solid& solid : solids) { /* ... */ }
If you are sure the compound only contains one solid (also works if it’s a solid itself):
Use ShapeComponents::TryGetSingleSolid(shape)
which returns a std::optional<TopoDS_Solid>
(no value if there is no solid or there are multiple solids in shape) or ShapeComponents::GetSingleSolid(shape)
which throws an exception if there is no solid or there are multiple solids in the shape.
Example:
#include <occutils/ShapeComponents.hxx> #include <iostream> // cerr, endl using namespace std; using namespace OCCUtils; TopoDS_Shape myShape = /* ... */; auto solidOpt = ShapeComponents::TryGetSingleSolid(myShape); if(solidOpt.has_value()) { TopoDS_Solid solid = solidOpt.value(); } else { cerr << "No solid or multiple solids in shape!" << endl; }
If you want to use pure OpenCASCADE without OCCUtils:
Use this snippet to directly iterate the TopoDS_Solid
instances in the shape
TopTools_IndexedMapOfShape solidShapes; TopExp::MapShapes (myShape, TopAbs_SOLID, solidShapes); for (int i = 1; i <= solidShapes.Extent (); i++) { TopoDS_Solid solid = TopoDS::Solid(solidShapes(i)); /* Do what you need with the solid here ! */ }