Extract and save trimmed surfaces from brep (solid)

Hi,

There is a solid as closed solid polysurface prepared in Rhino 7 in three steps:

  • Surfaces have been created.
  • The surfaces have been trimmed on each other.
  • The remained trimmed surfaces have been Union in final closed solid polysurface object (see picture “Source solid.png” and file “T2_closed_solid_polysurface.3dm”).

Using rhinoinside (RhinoCommon API) in Python 3.7 the idea was:

  1. To read the “T2_closed_solid_polysurface.3dm”).
  2. Extract all faces with their real boundaries (not surfaces extended outside the solid object).
  3. Then analyze if the one face intersects other one. (In this request it can be omitted).
  4. Finally output all faces in a new 3dm file for further processing.

Unfortunately, the below code provides a result with untrimmed surfaces (see “Result_1.png”):

import rhinoinside
rhinoinside.load()
import System
import Rhino

def extract_faces_of_solid(file_path, output_filename):
    model = Rhino.FileIO.File3dm.Read(file_path)
    output_file = Rhino.FileIO.File3dm()

    for obj in model.Objects:
        brep = Rhino.Geometry.Brep.TryConvertBrep(obj.Geometry)
        if brep:
            for face in brep.Faces:
                if isinstance(face, Rhino.Geometry.BrepFace):
                    trimmed_surface = face.ToNurbsSurface()
                    output_file.Objects.AddSurface(trimmed_surface)

    output_file.Write(output_filename, 6)
    model.Dispose()
    output_file.Dispose()

if __name__ == "__main__":
    file_path = "T2_closed_solid_polysurface.3dm"
    output_filename = 'output.3dm'
    extract_faces_of_solid(file_path, output_filename)

More complicated code gives us the same result - surfaces extended outside the solid object.

The second code is:

import rhinoinside
rhinoinside.load()
import System
import Rhino

def extract_trimmed_surfaces(file_path, output_filename):

    model = Rhino.FileIO.File3dm.Read(file_path)
    output_file = Rhino.FileIO.File3dm()

    layers = {}
    for layer in model.Layers:
        layers[layer.Name] = []

    for obj in model.Objects:
        if obj.Attributes.LayerIndex != -1:
            layer_name = model.Layers[obj.Attributes.LayerIndex].Name
            layers[layer_name].append(obj)

    for layer_name, objs in layers.items():
        for obj1 in objs:
            print(f"Objects on layer {layer_name}:")
            print(f"  {obj1.Geometry.ObjectType} with ID {obj1.Attributes.ObjectId}")
            brep = Rhino.Geometry.Brep.TryConvertBrep(obj1.Geometry)
            if brep:
                for face in brep.Faces:
                    if isinstance(face, Rhino.Geometry.BrepFace):
                        print("face is a BrepFace")
                        # Add each face (not right shape. It is an untrimmed surface).
                        boundary_curves = brep.DuplicateEdgeCurves(False)
                        split_breps = brep.Split(boundary_curves, 0.0000001)
                        print(f"split_breps = {repr(split_breps)}")
                        for split_brep in split_breps:
                            for split_face in split_brep.Faces:
                                print(f"split_face = {repr(split_face)}")
                                if isinstance(split_face, Rhino.Geometry.BrepFace):
                                    trimmed_surface = split_face.ToNurbsSurface()
                                    print(f"trimmed_surface = {repr(trimmed_surface)}")
                                    if output_file.Objects.AddSurface(trimmed_surface):
                                        print(f"trimmed_surface has been added to output_file!")
                    else:
                        print("face is not a BrepFace")
    output_file.Write(output_filename, 6)
    model.Dispose()
    output_file.Dispose()

if __name__ == "__main__":
    file_path = "T2_closed_solid_polysurface.3dm"
    output_filename = 'Output.3dm'
    extract_trimmed_surfaces(file_path, output_filename)

Which function is more suitable to extract surfaces (or faces of brep object) with their real trimmed shapes? (It seems to be few lines of code only to do this).


T2_closed_solid_polysurface.3dm (69.5 KB)
Result_1

Hi Victor,
I believe the issue you’re encountering is due to the ToNurbsSurface() method. This method takes a BrepFace and returns a NurbsSurface, but it doesn’t preserve the trimming information.
Instead of using ToNurbsSurface() you should use the DuplicateFace() method which duplicates the face as a new Brep preserving the trimming information.
Try and let me know, I’m not sure but I believe this is the issue.

Hi @farouk.serragedine,

Try using BrepFace.DuplicateFace.

– Dale

1 Like

Guess I was right then :rofl: @dale

Hi Farouk,
Thank you very much for your reply. The code is working:

import rhinoinside
rhinoinside.load()
import System
import Rhino

def extract_faces_of_solid(file_path, output_filename):
    model = Rhino.FileIO.File3dm.Read(file_path)
    output_file = Rhino.FileIO.File3dm()

    for obj in model.Objects:
        brep = Rhino.Geometry.Brep.TryConvertBrep(obj.Geometry)
        if brep:
            for face in brep.Faces:
                if isinstance(face, Rhino.Geometry.BrepFace):
                    trimmed_surface = face.DuplicateFace(True)
                    output_file.Objects.AddBrep(trimmed_surface)

    output_file.Write(output_filename, 6)
    model.Dispose()
    output_file.Dispose()

if __name__ == "__main__":
    file_path = "T2_closed_solid_polysurface.3dm"
    output_filename = 'output.3dm'
    extract_faces_of_solid(file_path, output_filename)

Two lines have been changed.

 trimmed_surface = face.DuplicateFace(True)
 output_file.Objects.AddBrep(trimmed_surface)

Many thanks to Dale and the entire community for taking the time to read the long post and support.