TriRemesh ScriptEditor Python Example

@DanielPiker

Is it possible to run TriMesh in Rhino Python ScriptEditor (not Grasshopper) as a single function?
If yes, is there any example for mesh with a fix boundary features?

You might go through Rhino.NodeInCode:

@AndersDeleuran nice to hear from you:)

Is there an example for this? I never used NodeInCode

1 Like

I don’t really know of much documentation, but it’s (in theory) pretty straight forward. Here’s a quick go:


250206_TriRemesh_NodeInCode_00.gh (9.0 KB)

That should work with the Rhino EditPythonScript editor as well. Not sure about the new one though :slight_smile:

Is there a way to use outside grasshopper?

Try using the EditPythonScript editor.

Edit: This might also be a CPython 3 issue, where one isn’t allowed to import deep like that (i.e. try just importing Rhino and take it from there). It might also be another .NET incompatibility issue.

1 Like

I see it working, but would be nice if cpython could handle this too:

I guess this is a rare case where ironpython aka c# is actually useful.

I use GHPython for almost everything on a daily basis, so not a rare case for me :wink:

Anywho, if you can’t get the TriRemesh function working in CPython 3 when importing just the Rhino namespace and then calling into NodeInCode from there, it’s likely a Python.NET incompatibility issue that @eirannejad might know how to resolve.

Thank you it really helps :slight_smile: I can still use it in script editor just shifting to python2:

#! python 2

import Rhino.NodeInCode.Components as ncc 

import Rhino

def get_meshes():
    go = Rhino.Input.Custom.GetObject()
    go.SetCommandPrompt("Select Mesh")
    go.GeometryFilter = Rhino.DocObjects.ObjectType.Mesh  # Filter to curves
    go.EnablePreSelect(True, True)
    go.SubObjectSelect = False
    go.DeselectAllBeforePostSelect = False
    res = go.GetMultiple(1, 0)
    
    if go.CommandResult() == Rhino.Commands.Result.Success:
        selected_meshes = [go.Object(i).Mesh() for i in range(go.ObjectCount) if go.Object(i).Mesh()]
        return selected_meshes

meshes = get_meshes()

if len(meshes)>0:
    mesh = meshes[0]
    T,D,C = ncc.NodeInCodeFunctions.Kangaroo2Component_TriRemesh(mesh, None, None, None, 1, 25)
    print(D)
    Rhino.RhinoDoc.ActiveDoc.Objects.AddMesh(T[0])
    # Rhino.RhinoDoc.ActiveDoc.Objects.AddMesh(D[0])
1 Like

@Petras_Vestartas

Rhino.NodeInCode.Components is a Type under Rhino.NodeInCode namespace. In python 3 standard, it is invalid to import a type like it is a namespace. Python 2 allowed that. So:

Instead of:

import Rhino.NodeInCode.Components as ncc

write:

from Rhino.NodeInCode import Components as ncc

Here is the modified script. I also changed if len(meshes) > 0: to if meshes:

#! python 3
from Rhino.NodeInCode import Components as ncc 

import Rhino

def get_meshes():
    go = Rhino.Input.Custom.GetObject()
    go.SetCommandPrompt("Select Mesh")
    go.GeometryFilter = Rhino.DocObjects.ObjectType.Mesh  # Filter to curves
    go.EnablePreSelect(True, True)
    go.SubObjectSelect = False
    go.DeselectAllBeforePostSelect = False
    res = go.GetMultiple(1, 0)
    
    if go.CommandResult() == Rhino.Commands.Result.Success:
        selected_meshes = [go.Object(i).Mesh() for i in range(go.ObjectCount) if go.Object(i).Mesh()]
        return selected_meshes

meshes = get_meshes()

if meshes:
    mesh = meshes[0]
    T,D,C = ncc.NodeInCodeFunctions.Kangaroo2Component_TriRemesh(mesh, None, None, None, 1, 25)
    print(D)
    Rhino.RhinoDoc.ActiveDoc.Objects.AddMesh(T[0])
    # Rhino.RhinoDoc.ActiveDoc.Objects.AddMesh(D[0])

2 Likes

Thank you very much, but it does not work.

Just tried out my Rhino 8 as well. Curiously, I had to edit the GhPython/IronPython call slightly. And neither CPython call appears to work within Grasshopper:


250207_TriRemesh_NodeInCode_00.gh (8.1 KB)

System Info

Rhino 8 SR16 2025-1-28 (Rhino 8, 8.16.25028.13001, Git hash:master @ c7a440a6d57a9b9049cc7a67065ffc95676f010c)
License type: Commercial, build 2025-01-28
License details: Cloud Zoo

Windows 11 (10.0.26100 SR0.0) or greater (Physical RAM: 32GB)
.NET 7.0.20

Computer platform: LAPTOP - Unplugged [31% battery remaining] ~23 minutes left

Hybrid graphics configuration.
Primary display: Intel(R) Iris(R) Xe Graphics (Intel) Memory: 128MB, Driver date: 5-12-2024 (M-D-Y).
> Integrated graphics device with 4 adapter port(s)
- Windows Main Display is laptop’s integrated screen or built-in port
Primary OpenGL: NVIDIA RTX 2000 Ada Generation Laptop GPU (NVidia) Memory: 8GB, Driver date: 6-26-2023 (M-D-Y). OpenGL Ver: 4.6.0 NVIDIA 536.45
> Integrated accelerated graphics device (shares primary device ports)
- Video pass-through to primary display device

OpenGL Settings
Safe mode: Off
Use accelerated hardware modes: On
GPU Tessellation is: On
Redraw scene when viewports are exposed: On
Graphics level being used: OpenGL 4.6 (primary GPU’s maximum)

Anti-alias mode: 8x
Mip Map Filtering: Linear
Anisotropic Filtering Mode: High

Vendor Name: NVIDIA Corporation
Render version: 4.6
Shading Language: 4.60 NVIDIA
Driver Date: 6-26-2023
Driver Version: 31.0.15.3645
Maximum Texture size: 32768 x 32768
Z-Buffer depth: 24 bits
Maximum Viewport size: 32768 x 32768
Total Video Memory: 8188 MB

Rhino plugins that do not ship with Rhino

Rhino plugins that ship with Rhino
C:\Program Files\Rhino 8\Plug-ins\Commands.rhp “Commands” 8.16.25028.13001
C:\Program Files\Rhino 8\Plug-ins\rdk.rhp “Renderer Development Kit”
C:\Program Files\Rhino 8\Plug-ins\RhinoRenderCycles.rhp “Rhino Render” 8.16.25028.13001
C:\Program Files\Rhino 8\Plug-ins\rdk_etoui.rhp “RDK_EtoUI” 8.16.25028.13001
C:\Program Files\Rhino 8\Plug-ins\NamedSnapshots.rhp “Snapshots”
C:\Program Files\Rhino 8\Plug-ins\MeshCommands.rhp “MeshCommands” 8.16.25028.13001
C:\Program Files\Rhino 8\Plug-ins\IronPython\RhinoDLR_Python.rhp “IronPython” 8.16.25028.13001
C:\Program Files\Rhino 8\Plug-ins\RhinoCycles.rhp “RhinoCycles” 8.16.25028.13001
C:\Program Files\Rhino 8\Plug-ins\Grasshopper\GrasshopperPlugin.rhp “Grasshopper” 8.16.25028.13001
C:\Program Files\Rhino 8\Plug-ins\Toolbars\Toolbars.rhp “Toolbars” 8.16.25028.13001
C:\Program Files\Rhino 8\Plug-ins\3dxrhino.rhp “3Dconnexion 3D Mouse”
C:\Program Files\Rhino 8\Plug-ins\Displacement.rhp “Displacement”
C:\Program Files\Rhino 8\Plug-ins\SectionTools.rhp “SectionTools”

1 Like

I have the same problem Rhino without grasshopper…

1 Like

What is the error in Rhino? Same as the one Anders is show in in GH?

Yes the same error.

1 Like

Hmm okay. I get the same error everywhere (Python 3, 2, and legacy editor) in my Rhino. For some reason Kangaroo components are not being loaded in NodeInCode. I am investigating

Huh!. It works like this:

ncc.NodeInCodeFunctions.TriRemesh(mesh, None, None, None, 1, 25)

Now works in legacy and python 2. But not python 3 :thinking:

Okay found the problem in Python 3 and logged here:

RH-85966 Python 3 errors inspecting attribs on a DynamicObject

It works like this in Python 3. Probably safer to access the NodeInCode stuff using ghpythonlib.components handler.

#! python 3
# from Rhino.NodeInCode import Components as ncc
import ghpythonlib.components as ghcomp

import Rhino

def get_meshes():
    go = Rhino.Input.Custom.GetObject()
    go.SetCommandPrompt("Select Mesh")
    go.GeometryFilter = Rhino.DocObjects.ObjectType.Mesh  # Filter to curves
    go.EnablePreSelect(True, True)
    go.SubObjectSelect = False
    go.DeselectAllBeforePostSelect = False
    res = go.GetMultiple(1, 0)
    
    if go.CommandResult() == Rhino.Commands.Result.Success:
        selected_meshes = [go.Object(i).Mesh() for i in range(go.ObjectCount) if go.Object(i).Mesh()]
        return selected_meshes

meshes = get_meshes()

if meshes:
    mesh = meshes[0]
    # T,D,C = ncc.NodeInCodeFunctions.TriRemesh(mesh, None, None, None, 1, 25)
    T,D,C = ghcomp.TriRemesh(mesh, None, None, None, 1, 25)
    print(D)
    Rhino.RhinoDoc.ActiveDoc.Objects.AddMesh(T)

Yup, that’s what I noticed too up here. Hadn’t come across that difference before. Good to know going forward. Also, I think Daniel said that he is working on making TriRemesh exposed as a proper API at some point :crossed_fingers:

1 Like

Important Update:

The error thrown when using ghcomp.Kangaroo2Component_TriRemesh seems to be a regression. I have logged a ticket for this here and will discuss with @kike and @stevebaer to fix. It seems like this changed when Kangaroo was included as a Grasshoper builtin assembly.

RH-85999 Kangaroo component names has changed in NodeInCode

1 Like