compas-dev / compas_occ

COMPAS wrapper for the Python bindings of OCC
http://compas.dev/compas_occ/
MIT License
15 stars 7 forks source link

from_step(cls, filepath) Desired behavior #14

Open MacGros opened 2 years ago

MacGros commented 2 years ago

Hey,

As from_step(cls, filepath) raises a NotImplemented Error I was wondering which behavior is sought for this method ? As it could be quite a complex I/O, my take on it is fairly simple, relying on Paviot's Extend snippets, it gets the first valid surface and retrieve it as a NurbsSurface :

import sys
import logging
import pathlib

from OCC.Core.GeomAbs import GeomAbs_Plane, GeomAbs_BSplineSurface
from OCC.Core.GeomConvert import geomconvert_SurfaceToBSplineSurface

from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.TopologyUtils import TopologyExplorer
from OCC.Core.BRep import BRep_Tool
from OCC.Core.BRepAdaptor import BRepAdaptor_Surface
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_NurbsConvert
from OCC.Core.TopoDS import topods

from compas_occ.geometry import OCCNurbsSurface as NurbsSurface

def read_bsplinesrf_from_stp_file(input_file):
    shp = read_step_file(input_file)

    t = TopologyExplorer(shp)
    if t.number_of_faces() == 0:
        raise ValueError(f"Input step file must contain at least one face to import")
    elif t.number_of_faces() > 1:
        logging.warning("Too much faces unpacked, retrieving the first valid one")

    for f in t.faces():
        adasurf = BRepAdaptor_Surface(f, True)
        surf_type = adasurf.GetType()
        if surf_type == GeomAbs_Plane:    
            gp_pln = adasurf.Plane() # look for the properties of the plane, first get the related gp_Pln
            location = gp_pln.Location()  # a point of the plane
            normal = gp_pln.Axis().Direction()  # the plane normal
            logging.info(f"face is GeomAbs_Plane: {location.X(), location.Y(), location.Z()}, normal: {normal.X(), normal.Y(), normal.Z()}")

            nurbs_converter = BRepBuilderAPI_NurbsConvert(f)
            nurbs_converter.Perform(f)
            nurbs_face = nurbs_converter.Shape()
            h_geomsurface = BRep_Tool.Surface(topods.Face(nurbs_face))
            h_bsurface = geomconvert_SurfaceToBSplineSurface(h_geomsurface)

            return h_bsurface # nbs = OCCNurbsSurface.from_occ(h_bsurface)
        elif surf_type == GeomAbs_BSplineSurface:
            nurbs_converter = BRepBuilderAPI_NurbsConvert(f)
            nurbs_converter.Perform(f)
            nurbs_face = nurbs_converter.Shape()
            h_geomsurface = BRep_Tool.Surface(topods.Face(nurbs_face))
            h_bsurface = geomconvert_SurfaceToBSplineSurface(h_geomsurface)

            return h_bsurface # nbs = OCCNurbsSurface.from_occ(h_bsurface)
        else:
            raise NotImplementedError("Face type is %s in GeomAbs enum" % str(surf_type))
            # 0:GeomAbs_Plane, 1:GeomAbs_Cylinder, 2:GeomAbs_Cone, 3:GeomAbs_Sphere, 4:GeomAbs_Torus, 5:GeomAbs_BSplineSurface, 6:GeomAbs_SurfaceOfRevolution
            # 7:GeomAbs_SurfaceOfExtrusion, 8:GeomAbs_OffsetSurface, 9:GeomAbs_OtherSurface

If it can be of any use, I'd be glad to contribute 🚀

Best regards, Antoine Gros

tomvanmele commented 2 years ago

hi there,

yes that would be great!

thanks for contributing...