Bug: Brep.CreateTrimmedSurface only uses face[0] as trimSource

Run this script
#! python 2 
from __future__ import absolute_import, division, print_function, unicode_literals

import Rhino
import scriptcontext as sc

def main():
    
    res, objref = Rhino.Input.RhinoGet.GetOneObject(
        prompt="Select brep",
        acceptNothing=False,
        filter=Rhino.DocObjects.ObjectType.Brep)
    if res != Rhino.Commands.Result.Success: return
    
    tolerance = sc.doc.ModelAbsoluteTolerance
    
    iFs_TrimFail = []
    iFs_InvalidRes = []
    sLogs = []
    iFs_Success = []
    
    rdB_In = objref.Object()
    rgB_In = rdB_In.BrepGeometry
    rgB_WIP = rgB_In.DuplicateBrep()
    
    for iF in range(rgB_In.Faces.Count):
        Rhino.RhinoApp.Wait()
        Rhino.RhinoApp.SetCommandPromptMessage(
            "Processing face {} of {}...".format(iF+1, rgB_In.Faces.Count))
        rgF_WIP = rgB_WIP.Faces[iF]
        rgS = rgF_WIP.DuplicateSurface()
        
        rgB_Res = Rhino.Geometry.Brep.CreateTrimmedSurface(
            trimSource=rgF_WIP,
            surfaceSource=rgS,
            tolerance=tolerance)
        
        if rgB_Res is None:
            iFs_TrimFail.append(iF)
            continue
        
        bIsValid, sLog = rgB_Res.IsValidWithLog()
        if not bIsValid:
            rgB_Res.Dispose()
            iFs_InvalidRes.append(iF)
            sLogs.append(sLog)
            continue
        
        rgB_WIP.Dispose()
        rgB_WIP = rgB_Res
        iFs_Success.append(iF)
        
    sc.doc.Objects.AddBrep(rgB_WIP)
    
    sc.doc.Views.Redraw()
    
    print("Retrimmed {} out of {} faces. {}".format(
        len(iFs_Success), rgB_In.Faces.Count, iFs_Success[:10]))
    sEval="len(iFs_TrimFail)"; print(sEval,'=',eval(sEval))
    sEval="len(iFs_InvalidRes)"; print(sEval,'=',eval(sEval))
    if sLogs:
        print("Logs of invalid breps:")
        print(*sLogs)

if __name__ == '__main__': main()

on
Brep_CreateTrimmedSurface_Test.3dm (71.2 KB)

Retrimmed 1 out of 4 faces. [0]
len(iFs_TrimFail) = 0
len(iFs_InvalidRes) = 3
Logs of invalid breps:
Distance from start of ON_Brep.m_T[4] to 3d edge is 30.  (edge tol = 0, trim tol ~ 0).
 Distance from start of ON_Brep.m_T[4] to 3d edge is 40.  (edge tol = 0, trim tol ~ 0).
 Distance from start of ON_Brep.m_T[4] to 3d edge is 50.  (edge tol = 0, trim tol ~ 0).

It appears that only face[0] of a polyfaced brep is used for the trimSource argument.

Also, the output of CreateTrimmedSurface is the brep containing all the faces of trimSource’s brep, while the output of Brep.CopyTrimCurves, which doesn’t have the above bug, is only a monofaced brep. Is it possible to fix the bug and still allow the polyfaced output?

8.17.25066.7001, 2025-03-07

Hi @spb,

In my brief glance at the source, that does not appear to be the case. But I’ll dig deeper when I have a chance.

The underlying C++ SDK function, RhinoRetrimSurface, transfers trims from a Brep face to another surface roughly the same shape and in the same location as the original face, and returns the result in a single surface Brep. This is useful for re-trimming a trimmed surface after rebuild or refit. FWIW.

Thanks,

– Dale

RH-86795 is fixed in Rhino 8 Service Release 19 Release Candidate