Recognize cylinder in imported data from STEP file

Hi,

I have a STEP file which I import and which contains several solids. Is there a straightforward way to check if a TopoDS_Solid is a cylinder volume?

Best regards

Kirill Gavrilov's picture

There is no "IsCylinder" tool in OCCT as far as I know, so I guess you will have to explode your Solid and identify it to be cylinder if it matches expected definition (number of faces, number of edges, seam edges / circle edges, surface type Geom_CylindricalSurface, etc.) depending on what you want to be called "cylinder" (any cylindrical shapes or cylinder without holes?).

In addition, STEP file might define cylindrical surfaces implicitly via general B-Spline. In this case, identification might become more complicated, though you may rely on Canonical Recognition component for this task.

Here is a code snippet that could be used to identify a whole sphere to give some idea on how to identify a cylnder:

bool IsSphere (const TopoDS_Solid& theSolid)
{
  // sphere's Solid consists of a single Shell
  if (theSolid.NbChildren() != 1) { return false; }
  const TopoDS_Shape aShellSh = TopoDS_Iterator (theSolid).Value();
  if (aShellSh.ShapeType() != TopAbs_SHELL) { return false; }

  // sphere's Shell consists of a single Face
  if (aShellSh.NbChildren() != 1) { return false; }
  const TopoDS_Shape aFaceSh = TopoDS_Iterator (aShellSh).Value();
  if (aFaceSh.ShapeType() != TopAbs_FACE) { return false; }

  // sphere's Face should define SphericalSurface
  const TopoDS_Face aFace = TopoDS::Face (aFaceSh);
  TopLoc_Location aLocSurf;
  const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aLocSurf);
  Handle(Geom_SphericalSurface) aGeomSphere = Handle (Geom_SphericalSurface)::DownCast (aSurf);
  if (aGeomSphere.IsNull())
  {
    return false;
  }

  bool isFullSphere = aFace.NbChildren() == 0;
  if (aFace.NbChildren() != 1)
  {
    // sphere boundaries should be defined by 2 seam Edges and 2 degenerate Edges
    const TopoDS_Iterator aWireIter (aFace);
    const TopoDS_Wire& aWire = TopoDS::Wire (aWireIter.Value());
    if (aWire.NbChildren() == 4)
    {
      Standard_Integer aNbSeamEdges = 0, aNbDegenEdges = 0;
      for (TopoDS_Iterator anEdgeIter (aWire); anEdgeIter.More(); anEdgeIter.Next())
      {
        const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Value());
        aNbSeamEdges += BRep_Tool::IsClosed (anEdge, aFace);
        aNbDegenEdges += BRep_Tool::Degenerated (anEdge);
      }
      isFullSphere = aNbSeamEdges == 2 && aNbDegenEdges == 2;
    }
  }
  if (isFullSphere)
  {
    //gp_Sphere aSphere = BRepAdaptor_Surface (aFace).Sphere();
    return true;
  }
  return false;
}