Export geometries from GH to CAD

Hi everyone,

I am trying to create a Python component capable of exporting geometries directly from GH to CAD without baking them into Rhino canvas.

I found this useful script on the forum made by Djordje Spasic some years ago, however instead of using geometries as input it uses object names baked on rhino canvas. Would it be possible to modify the code to use Geometries?

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino


def exportObjectsByName(fileType, filePath, names):
    
    # check the input data
    if fileType:
        if fileType.startswith("."):
            pass
        else:
            fileType = "." + fileType
            
        supportedFileTypes = [".3dm", ".3ds", ".sat", ".ai", ".dwg", ".dxf", ".dae", ".cd", ".x", ".emf", ".gf", ".pm", ".kmz", ".gts", ".igs", ".iges", ".udo", ".fbx", ".obj", ".csv", ".x_t", ".pdf", ".ply", ".txt", ".pov", ".raw", ".rib", ".skp", ".step", ".stl", ".tsm", ".tss", ".vda", ".wrl", ".vmrl", ".gdf", ".wmf", ".x3dv", ".xaml", ".xgl", ".zpr"]
        if fileType in supportedFileTypes:
            pass
        else:
            print "File type %s is not supported" % fileType
            return
    else:
        print "Please input fileType_"
        return
    
    if filePath:
        if filePath.endswith("\\"):
            pass
        else:
            filePath = filePath + "\\"
    else:
        print "Please input filePath_"
        return
    
    if names:
        pass
    else:
        print "Please input names_"
        return
    
    
    sc.doc = Rhino.RhinoDoc.ActiveDoc
    allObjsIds = rs.AllObjects()
    rs.UnselectObjects(allObjsIds)
    sc.doc = ghdoc
    
    for name in names:
        fileNameAndType = name + fileType
        finalPath = chr(34) + filePath + fileNameAndType + chr(34)
        
        commandString = "_-Export " + "_-SelName " + name + " _Enter " + finalPath + " _Enter _Enter _Enter"
        echo = True
        done = rs.Command(commandString, echo)
        if done:
            print "%s file successfully exported to: %s" % (fileNameAndType, filePath)
        else:
            print "Something went wrong. Export terminated"
        
        rs.Command("_-SelNone ")
    
    return


if _export:
    exportObjectsByName(_fileType, _filePath, _names)

Thanks in advance :slight_smile:

Hey @bbalbastre,

Yes this is certainly possible. Let’s break down what changes we’ll need to make.

Currently the script exports from the Document using the _-Export command.
We’ll need to either;
1. Add to the Document and remove later
2. Maybe we could Create a separate headless document and work in that

Option 1 is easier, is that acceptable?

– cs

Hi @csykes

Thank you very much for your answer.

By adding to the document you mean to bake the geometries to Rhino, make the export and then remove the geometries? If you mean that yes, that is okay :slight_smile:

Hey @bbalbastre,

I wrote this, which should work. But it doesn’t seem to want to run in my Rhino :disappointed_relieved:. I’m a bit rusty when it comes to python in Rhino, so I might be missing something obvious. I’m just going to put it here for now in case I forget about this and fall off of the face of the Earth.

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino


def exportObjectsByName(fileType, filePath, names):
    
    # check the input data
    if fileType:
        if fileType.startswith("."):
            pass
        else:
            fileType = "." + fileType
            
        supportedFileTypes = [".3dm", ".3ds", ".sat", ".ai", ".dwg", ".dxf", ".dae", ".cd", ".x", ".emf", ".gf", ".pm", ".kmz", ".gts", ".igs", ".iges", ".udo", ".fbx", ".obj", ".csv", ".x_t", ".pdf", ".ply", ".txt", ".pov", ".raw", ".rib", ".skp", ".step", ".stl", ".tsm", ".tss", ".vda", ".wrl", ".vmrl", ".gdf", ".wmf", ".x3dv", ".xaml", ".xgl", ".zpr"]
        if fileType in supportedFileTypes:
            pass
        else:
            print "File type %s is not supported" % fileType
            return
    else:
        print "Please input fileType_"
        return
    
    if filePath:
        if filePath.endswith("\\"):
            pass
        else:
            filePath = filePath + "\\"
    else:
        print "Please input filePath_"
        return
    
    if names:
        pass
    else:
        print "Please input names_"
        return
    
    
    sc.doc = Rhino.RhinoDoc.ActiveDoc
    allObjsIds = rs.AllObjects()
    rs.UnselectObjects(allObjsIds)
    sc.doc = ghdoc
    
    for name in names:
        fileNameAndType = name + fileType
        finalPath = chr(34) + filePath + fileNameAndType + chr(34)
        
        commandString = "_-Export " + "_-SelName " + name + " _Enter " + finalPath + " _Enter _Enter _Enter"
        echo = True
        done = rs.Command(commandString, echo)
        if done:
            print "%s file successfully exported to: %s" % (fileNameAndType, filePath)
        else:
            print "Something went wrong. Export terminated"
        
        rs.Command("_-SelNone ")
    
    return

def addGeometry(geometries):
    for geometry in geometries:
        yield sc.doc.Objects.Add(geometry)

def removeGeometry(guids):
    for guid in guids:
        sc.doc.Objects.Delete(guid, True)

if _export:
    print("Exporting " + str(len(_geometries)) + " elements")
    guids = addGeometry(_geometries)
    exportObjectsByName(_fileType, _filePath, _names)
    removeGeometry(guids)

– cs

Hi @csykes

I really appreciate your effort.

Maybe all the definition with the names has to be removed

But it seems that script it is beyond my python knowledge

Maybe the solution @clement provided in another post can be applied here.

Get an exported list of ID’s of selected objects - Scripting - McNeel Forum

:slight_smile:

Hi @bbalbastre, a similar question was asked here

_
c.

2 Likes

Thank you for the info, although the topic was unsolved :frowning:

Pancake plugin was usually to import the files since the code didn’t work

just use the File3dm class…

EDIT:
sorry - looks like you need a .dxf, not a .3dm

@Tom_P

Thank you for your reply.

It really seems a simple problem to solve but with my programming skills it is quite difficult for me to understand it, that’s why I asked for help.

Anyway, thanks again for your answer

@magicteddy any idea on this?

Not really… and definitely not in Python.

When I need that kind of stuff I use Elefront in two steps. First bake to Rhino, then Export file to whatever format I need. That’s two clics, with no line of fancy code :smiley:

Okay, thanks for the answer :slight_smile:

Just in case anyone is interested I finally managed to do it without using plugins.

# Author__ = "Balbastre"
# Version__ = "2023.05.10"

# Import the necessary Rhino modules
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

# Check if 'Create' variable is True
if Create_dwg:
    # Loop through each Section and assign its ID to geo_id
    for i in range(len(Section)):
        geo_id = Section[i]

        # Set the RhinoScript context to ghdoc
        sc.doc = ghdoc

        # Get the Rhino object based on its ID
        doc_object = rs.coercerhinoobject(geo_id)

        # Retrieve the object's geometry and attributes
        geometry = doc_object.Geometry
        attributes = doc_object.Attributes

        # Set the RhinoScript context to the active document
        sc.doc = Rhino.RhinoDoc.ActiveDoc

        # Add the geometry to the Rhino document with the specified attributes
        rhino_ref = sc.doc.Objects.Add(geometry, attributes)

        # Set the object layer to "Default"
        rs.ObjectLayer(rhino_ref, "Default")

    # Select all objects on the "Default" layer
    rs.ObjectsByLayer("Default", True)

    # Export the selected objects to the specified DWG file
    rs.Command('-_Export "{}" _Enter'.format(Filename), True)

    # Delete all objects on the "Default" layer
    rs.DeleteObjects(rs.ObjectsByLayer("Default", True))

I am pretty sure there are more elegant ways such as avoid using Rhino Commands but at least it works :slight_smile:

1 Like