# TriRemesh ScriptEditor Python Example

**URL:** <https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133>\
**Category:** Scripting\
**Tags:** windows, mac\
**Created:** [February 6, 2025, 5:34pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133 "2025-02-06T17:34:55Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [February 6, 2025, 5:34pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/1 "2025-02-06T17:34:55Z")

</div>

@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?

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [February 6, 2025, 5:46pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/2 "2025-02-06T17:46:42Z")

</div>

You might go through `Rhino.NodeInCode`:

> [@Introducing TriRemesh - high quality triangular and hexagonal remeshing and shrink wrapping](https://discourse.mcneel.com/t/introducing-triremesh-high-quality-triangular-and-hexagonal-remeshing-and-shrink-wrapping/115434/81):
>
> Thanks @Anders, I was forgetting about this way with NodeInCode. I’ll still work on exposing the remeshing methods directly too, as I think there are some options in there that didn’t make sense to have on the component, but might be useful in a script, such as separating the different topology update steps from the vertex smoothing and projection steps. @mdesign For your point 1. - yes curves set as features should always be preserved. Just set Sharp=True. About point 2. - Combining this r…

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [February 6, 2025, 5:51pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/3 "2025-02-06T17:51:51Z")

</div>

@AndersDeleuran nice to hear from you:)

Is there an example for this? I never used NodeInCode

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [February 6, 2025, 6:06pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/4 "2025-02-06T18:06:50Z")

</div>

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

 ![2025-02-06 19_03_03-Grasshopper Python Script Editor](https://global.discourse-cdn.com/mcneel/uploads/default/original/4X/d/5/e/d5e62df8a9f2d95a0aa99e5fe8c1a3ccf1e5f9c2.png)  
[250206\_TriRemesh\_NodeInCode\_00.gh](https://discourse.mcneel.com/uploads/short-url/ewximhJ3H5nFIwPTNyUopIuU2YS.gh) (9.0 KB)

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

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [February 6, 2025, 6:25pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/5 "2025-02-06T18:25:39Z")

</div>

Is there a way to use outside grasshopper?

 ![image](https://global.discourse-cdn.com/mcneel/uploads/default/original/4X/7/e/f/7effe3b23c5667f190cd206470b57c29e7bad891.png)

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [February 6, 2025, 6:26pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/6 "2025-02-06T18:26:54Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [February 6, 2025, 6:40pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/7 "2025-02-06T18:40:12Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [February 6, 2025, 6:59pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/8 "2025-02-06T18:59:01Z")

</div>

> [@Petras\_Vestartas](#):
>
> 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 😉

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.

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [February 6, 2025, 7:07pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/9 "2025-02-06T19:07:39Z")

</div>

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

```python
#! 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])

```

---

<div class="post-metadata">

**Author:** ![eirannejad](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/eirannejad/32/477962_2.png) [@eirannejad](https://discourse.mcneel.com/u/eirannejad)\
**Post date:** [February 7, 2025, 12:41am UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/10 "2025-02-07T00:41:23Z")

</div>

@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
#! 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])

```

 ![Screenshot 2025-02-06 at 4.42.34 PM](https://global.discourse-cdn.com/mcneel/uploads/default/original/4X/f/0/c/f0c65ed4390d1d5fdcf1b4e4f956a5c219f06f52.png)

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [February 7, 2025, 8:08am UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/11 "2025-02-07T08:08:23Z")

</div>

Thank you very much, but it does not work.

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [February 7, 2025, 10:26am UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/12 "2025-02-07T10:26:58Z")

</div>

> [@eirannejad](#):
>
> Here is the modified script…

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:

 ![2025-02-07 11_23_52-](https://global.discourse-cdn.com/mcneel/uploads/default/original/4X/9/3/b/93b88bc7212c3059aa461bd79b0d9bbf22a1e922.png)  
[250207\_TriRemesh\_NodeInCode\_00.gh](https://discourse.mcneel.com/uploads/short-url/y3eeUO6EL0NYDcnQ7FBRJ7CmXV5.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”

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [February 7, 2025, 10:30am UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/13 "2025-02-07T10:30:29Z")

</div>

> [@eirannejad](#):
>
> ```auto
> #! 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])
> 
> ```

I have the same problem Rhino without grasshopper…

---

<div class="post-metadata">

**Author:** ![eirannejad](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/eirannejad/32/477962_2.png) [@eirannejad](https://discourse.mcneel.com/u/eirannejad)\
**Post date:** [February 7, 2025, 5:25pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/14 "2025-02-07T17:25:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [February 7, 2025, 5:53pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/15 "2025-02-07T17:53:18Z")

</div>

Yes the same error.

---

<div class="post-metadata">

**Author:** ![eirannejad](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/eirannejad/32/477962_2.png) [@eirannejad](https://discourse.mcneel.com/u/eirannejad)\
**Post date:** [February 7, 2025, 6:35pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/16 "2025-02-07T18:35:46Z")

</div>

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

 ![Rhino_82OVzgg7Jr](https://global.discourse-cdn.com/mcneel/uploads/default/original/4X/4/3/b/43b065f86cd3e8643998611e86924be8c59a59b6.png)

---

<div class="post-metadata">

**Author:** ![eirannejad](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/eirannejad/32/477962_2.png) [@eirannejad](https://discourse.mcneel.com/u/eirannejad)\
**Post date:** [February 7, 2025, 6:42pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/17 "2025-02-07T18:42:25Z")

</div>

Huh!. It works like this:

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

```

Now works in legacy and python 2. But not python 3 🤔

---

<div class="post-metadata">

**Author:** ![eirannejad](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/eirannejad/32/477962_2.png) [@eirannejad](https://discourse.mcneel.com/u/eirannejad)\
**Post date:** [February 7, 2025, 6:50pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/18 "2025-02-07T18:50:43Z")

</div>

Okay found the problem in Python 3 and logged here:

[RH-85966](https://mcneel.myjetbrains.com/youtrack/issue/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
#! 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)

```

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [February 7, 2025, 7:12pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/19 "2025-02-07T19:12:56Z")

</div>

Yup, that’s what I noticed too [up here](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/12). 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 🤞

---

<div class="post-metadata">

**Author:** ![eirannejad](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/eirannejad/32/477962_2.png) [@eirannejad](https://discourse.mcneel.com/u/eirannejad)\
**Post date:** [February 11, 2025, 9:43pm UTC](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133/20 "2025-02-11T21:43:04Z")

</div>

**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](https://mcneel.myjetbrains.com/youtrack/issue/RH-85999) Kangaroo component names has changed in NodeInCode

[Next page](https://discourse.mcneel.com/t/triremesh-scripteditor-python-example/199133.md?page=2)
