Automatic exporting a series of .STL files

Oh this is nice. I’ve been using @Helvetosaur scripts for a while and I’m struggling to implement different export options. It looks as this new approach could solve all my problems. So for exporting *.dxf, you’d also have to use the File.DwgWriteOptions?

Yes, File.DwgWriteOptions will do both DWG and DXF. It is keyed off the file extension given.


import scriptcontext
import Rhino
import os
 
if scriptcontext.doc is not None:
    options = Rhino.FileIO.FileDwgWriteOptions()
    options.UseLWPolylines = True
    options.Version = Rhino.FileIO.FileDwgWriteOptions.AutocadVersion.Acad2000
    options_dictionary = options.ToDictionary()
 
    path = os.path.expanduser("~/Desktop/sample_py.dxf")
    success = scriptcontext.doc.Export(path, options_dictionary)
    if success:
        print("Successfully exported sample_py.dxf")
    else:
        print("Error while trying to export sample_py.dxf")

Thanks Scott.

I have 3 different *.stl export options. Can I access the mesh quality presets I see in this dialog:

No presets. Set the invidual mesh properties.

This is how I set the meshing options recently:

scheme = rs.GetString("select mesh settings", defaultString=None, strings=('quick', 'medium', 'fine'))
        
        print(scheme)
        
        if scheme == 'quick':
            rs.Command("-_Export "+path+" _Enter _Enter", False)

        if scheme == 'medium':
            rs.Command("-_Export "+path+" _Enter d a a 0 s 0 d 0.1 g 4 m 0 i 0.02 u 4 _Enter _Enter", False)
        
        if scheme == 'fine':
            rs.Command("-_Export "+path+" _Enter d a a 0 s 0 d 0.005 g 4 m 0 i 0.02 u 4 _Enter _Enter", False)

So, the code looks like this for the medium above:

import scriptcontext
import Rhino
import os
 
if scriptcontext.doc is not None:
    meshop: Rhino.Geometry.MeshingParameters = Rhino.Geometry.MeshingParameters()
    meshop.RefineAngleInDegrees = 0
    meshop.GridAspectRatio = 0
    meshop.Tolerance = 0.1
    meshop.GridMinCount = 4
    meshop.MinimumEdgeLength = 0.0001
    meshop.RefineGrid = True

    options = Rhino.FileIO.FileStlWriteOptions()
    options.BinaryFile = False
    options.ExportOpenObjects = True
    options.MeshingParameters = meshop
    options_dictionary = options.ToDictionary()
 
    path = os.path.expanduser("~/Desktop/sample_py.stl")
    success = scriptcontext.doc.Export(path, options_dictionary)
    if success:
        print("Successfully exported sample.stl")
    else:
        print("Error while trying to export sample.stl")

This is a quick sample. I expect creating preset classes for schemes would make the most sense in this case.

The Mesh parameters class also comes with a lot of different properties and constructors: https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.meshingparameters#properties

The orginal request, coded up in Rhino 8 this might look like this:

#! python3

import scriptcontext
import Rhino
import os

    
meshop: Rhino.Geometry.MeshingParameters = Rhino.Geometry.MeshingParameters()
meshop.RefineAngleInDegrees = 0
meshop.GridAspectRatio = 0
meshop.Tolerance = 0.1
meshop.GridMinCount = 4
meshop.MinimumEdgeLength = 0.0001
meshop.RefineGrid = True


def writeselectedstl(filename):
    if scriptcontext.doc is not None:
        options = Rhino.FileIO.FileStlWriteOptions()
        options.BinaryFile = False
        options.ExportOpenObjects = True
        options.MeshingParameters = meshop
        options_dictionary = options.ToDictionary()
    
        path = os.path.expanduser(filename)
        success = scriptcontext.doc.ExportSelected(path, options_dictionary)
        if success:
            print("Successfully exported sample.stl")
        else:
            print("Error while trying to export sample.stl")

def fun():

    cdoc = Rhino.RhinoDoc.ActiveDoc
    cnt = 0

    for rObj in cdoc.Objects:
        if rObj.IsNormal and rObj.IsMeshable:
            cnt += 1
            cdoc.Objects.Select(rObj.Id,True)
            obj = rObj.Select
            writeselectedstl(f'~/Desktop/sample_py{cnt}.stl')
            cdoc.Objects.UnselectAll()

fun()

I get this error:

I think that line should read:
meshop=Rhino.Geometry.MeshingParameters()

filepath = f'~/Downloads/export/sample_py{cnt}.stl'

Somehow this f-string doesn’t work…

I replaced it with the following line:

filepath = '~/Downloads/export/sample_py' + str(cnt) + '.stl'

Which script editor is being used? This is a Python type hint syntax that is supported in the Rhino 8 ScriptEditor. It works well to give the Editor and Runtime engine more information about what is expected.

Python’s string shortcuts are so varied.

The F-string syntax was introduced in Python 3.6. It does work in Rhino 8 and CPython 3.9.

Python F-String and other string manipulation

I’m pretty sure my Rhino is up to date.

System Info

Rhino 8 SR7 2024-4-30 (Rhino 8, 8.7.24121.13001, Git hash:master @ 44b9af795a5996a2a877659c9d5ef63b0da7ecfa)
License type: Kommerziell, build 2024-04-30
License details: Cloud Zoo

Windows 11 (10.0.22631 SR0.0) or greater (Physical RAM: 128GB)
.NET 7.0.18

Computer platform: DESKTOP

Standard graphics configuration.
Primary display and OpenGL: NVIDIA RTX A5000 (NVidia) Memory: 22GB, Driver date: 3-12-2024 (M-D-Y). OpenGL Ver: 4.6.0 NVIDIA 551.86
> Accelerated graphics device with 4 adapter port(s)
- Secondary monitor attached to adapter port #0
- Windows Main Display attached to adapter port #1

Secondary graphics devices.
NVIDIA Quadro K2200 (NVidia) Memory: 4GB, Driver date: 3-12-2024 (M-D-Y).
> Accelerated graphics device with 4 adapter port(s)
- There are no monitors attached to this device!

OpenGL Settings
Safe mode: Off
Use accelerated hardware modes: 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: 3-12-2024
Driver Version: 31.0.15.5186
Maximum Texture size: 32768 x 32768
Z-Buffer depth: 24 bits
Maximum Viewport size: 32768 x 32768
Total Video Memory: 23028 MB

Rhino plugins that do not ship with Rhino
C:\Users\martinsiegrist\AppData\Roaming\McNeel\Rhinoceros\packages\8.0\NVIDIADenoiser\0.4.3\NVIDIADenoiser.Windows.rhp “NVIDIADenoiser.Windows” 0.4.3.0

Rhino plugins that ship with Rhino
C:\Program Files\Rhino 8\Plug-ins\Commands.rhp “Commands” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\WebBrowser.rhp “WebBrowser”
C:\Program Files\Rhino 8\Plug-ins\rdk.rhp “Renderer Development Kit”
C:\Program Files\Rhino 8\Plug-ins\RhinoScript.rhp “RhinoScript”
C:\Program Files\Rhino 8\Plug-ins\IdleProcessor.rhp “IdleProcessor”
C:\Program Files\Rhino 8\Plug-ins\RhinoRenderCycles.rhp “Rhino Render” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\RhinoRender.rhp “Legacy Rhino Render”
C:\Program Files\Rhino 8\Plug-ins\rdk_etoui.rhp “RDK_EtoUI” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\import_ACAD.rhp “AutoCAD file import: import_ACAD”
C:\Program Files\Rhino 8\Plug-ins\NamedSnapshots.rhp “Snapshots”
C:\Program Files\Rhino 8\Plug-ins\MeshCommands.rhp “MeshCommands” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\IronPython\RhinoDLR_Python.rhp “IronPython” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\RhinoCycles.rhp “RhinoCycles” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\SectionTools.rhp “SectionTools”
C:\Program Files\Rhino 8\Plug-ins\Grasshopper\GrasshopperPlugin.rhp “Grasshopper” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\Toolbars\Toolbars.rhp “Toolbars” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\3dxrhino.rhp “3Dconnexion 3D Mouse”
C:\Program Files\Rhino 8\Plug-ins\BlockEdit.rhp “BlockEdit” 8.7.24121.13001
C:\Program Files\Rhino 8\Plug-ins\Displacement.rhp “Displacement”

Yes Rhino is up to date. Which Script Editor is being used?

I am in 8.8, but I did not think this would have been any part of a change.

Looing at Tools > Advanced > Language Status panel will show what is running:

image

Looks good. Can you try this one:
Fstring test.gh (6.0 KB)

I’m sorry, I don’t get it just yet.

But that syntax is working in that case.

Then:

Why does that version not work?

Good question…