Script needed: export 3D curves to a text file?

Hi All,

I’m trying to come up with a way to export 3D curves to Modo. The modo team said that they coudl script an import on their end if I have a text file of selected 3D curves. what they requested is:

“To build 3D NURBS Curves in modo they would need to output each curve as a list of 3D points, each one with a weight value.”

anyone willing to help with this? I’ll bring back both scripts to the rest of Rhino+Modo users.

Thanks!

G

Hi Gustavo,

Well, this isn’t difficult. But formatting is key, of course. Do you (or someone) have a sample file that we could review?

– Dale

Hi Dale,

here’s a sample of the intended use case:

export the extracted curves that are visible in a ‘technical view’ for visualization. Like this:

I also made a file with just one part and no key holes for easier testing:

This is the single part model:
apple_keyboard_bare_body_only.3dm (2.5 MB)

This is the whole model zipped:
apple_keyboard.zip (5.7 MB)

EDIT: those models have the polysurface objects but also the duplicated curves that want to be exported (each extracted curves cluster are named and in a layer)

But Dale would need a file showing how the formatting should be - i.e. the Rhino output. Are such samples available?

oooh, ok. I asked Arnie Cachelin from Modo team and sent him a link to this topic come over here and chat.

G

1 Like

Hi Guys, I made it.
We don’t actually have any existing text file format for curves, so it is in all of our interests to so something very easy to read and write.
Maybe CSV is too simple, we could do XML or JSON… all the cool kids do JSON these days I think.
I guess we only need 4 numbers per point, and a way to distinguish curves from each other. If they have names, we could use them.
Any preferences?

JSON Proposal:
{"NURBSCurves" : [
    { "Curve" : [
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
    ]},
    { "Curve" : [
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
    ]},
    { "Curve" : [
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
        { "Point" :[1.2,3.4,5.6,0.0]},
    ]},
}

Note that in the above example, I had indenting, and I didn’t bother changing all the numbers.

Nice! Give me a few…

Couldn’t you just use SVG? SVG export was just added to the Rhino 6 WIP.

SVG is only flattened 2D:

one more view in case that Modo import one wasn’t clear:

Yes, sorry. I had gotten the impression that this was a Make2D-type thingy…

1 Like

What about the modo team reading .3dm directly? You could use rhino3dmio which is meant specifically for reading/writing .3dm files. Here is a doc explaining the process.

Edit: @Arnie_Cachelin I’d be happy to help!

1 Like

@fraguada does bring up a good point. We provide a free toolkit, openNURBS, that will read and write Rhino’s 3dm file format. The toolkit comes in both C++ and .NET form. Perhaps this is useful to you.

But as I promised, here is a simple Python script, that will work in Rhino 5 and the current Rhino WIP, that will export the NURBS form of selected curves in my home-brewed JSON format.

https://github.com/mcneel/rhino-developer-samples/blob/master/rhinopython/SampleExportCurvesAsJSON.py

Attached is a sample file that contains three curves.

sample.json.txt (1.0 KB)

Let me know if this helps.

– Dale

2 Likes

Thanks Dale that’s really helpful. I’ll dig into it, let you know if I have any questions.

Hi guys, FYI Modo does read .3dm files but the importer only looks for meshed geometry (actual meshed objects, not render-meshes). So for example, I took this keyboard chunk file in Rhino, meshed it, and saved as V5’s .3dm.

and this does show up:

Maybe @Arnie_Cachelin can lobby inside Foundry to read more of that file, like curves, etc.

1 Like

Apologies for not checking…it’s been a few years since I opened up modo :frowning:

no need to apologize, I think that’s the case for a lot of people :frowning:

I still hope we can come up with a solution that does not require waiting for an updated importer in a new version of Modo from Foundry. It looks like Arnie was going to hack something for us :slight_smile:

G

I only added NURBS curve support last year, the 3dm importer is much older than that. We can probably consider it a bug that it doesn’t load the curves. I didn’t actually work on the 3dm support, and totally forgot we even had it…

2 Likes

Here’s the NURBS JSON loader so far, it could use some polish on the loading part, which is commented out…

#!/usr/bin/env python 
#Import NURBS curves exported from Rhino into ad hoc JSON format

import json
import modo
import lx
import lxu

json_str = '{"curves": [{"closed": false, "knots": [0.0, 0.0, 0.0, 19.270446242706978, 38.540892485413949, 57.81133872812093, 57.81133872812093, 57.81133872812093], "id": "28f0ad8a-8e03-4061-9c33-ef251963b16f", "cvs": [[-11.0, -6.0, 0.0, 1.0], [-19.0, 3.0, 0.0, 1.0], [-13.0, 10.0, 0.0, 1.0], [1.0, 7.0, 0.0, 1.0], [16.0, 3.0, 0.0, 1.0], [19.0, 9.0, 0.0, 1.0]], "dim": 3, "rational": false, "knot_count": 8, "periodic": false, "cv_count": 6, "planar": true, "degree": 3}, {"closed": false, "knots": [0.0, 6.324555320336759, 14.926880587379387, 22.137983138307366, 28.462538458644126, 37.896519590700727, 44.9675874025662, 60.100333352987761], "id": "8048255a-18eb-43af-97bb-2d257edf311f", "cvs": [[-2.0, 0.0, 0.0, 1.0], [-4.0, -6.0, 0.0, 1.0], [3.0, -1.0, 0.0, 1.0], [7.0, -7.0, 0.0, 1.0], [9.0, -1.0, 0.0, 1.0], [17.0, -6.0, 0.0, 1.0], [18.0, 1.0, 0.0, 1.0], [3.0, 3.0, 0.0, 1.0]], "dim": 3, "rational": false, "knot_count": 8, "periodic": false, "cv_count": 8, "planar": true, "degree": 1}], "curve_count": 2, "rhino": 5, "version": 1.0, "date": "15/03/2017"}'
data = json.loads(json_str)

#data = json.load(open('/Users/arnie/Documents/sampleNURBSCurves.json', 'r'))
curves = data['curves']
print 'Number of curves: ',len(curves)

scene = modo.Scene()
mesh = scene.addMesh("Mesh")
vmap_BSPL = lxu.lxID4('BSPL')
maps = mesh.geometry.vmaps.getMapsByType(vmap_BSPL)
wmap = maps[0]

storage = lx.object.storage()
storage.setType('f')
storage.setSize(1)

geo = mesh.geometry
with mesh.geometry as geo:
    for crv in curves:
        v=[]
        for cv in crv['cvs']:
            nv = geo.vertices.new((cv[0],cv[1],cv[2]))
            v.append(nv)
            pa = lx.object.Point(nv._accessor)
            pa.Select(nv._id)
            storage.set([cv[3],])
            pa.SetMapValue(wmap._id,storage)

        if crv['closed']:
            v.append(v[0])
        print len(v)
        poly = geo.polygons.new(v,False,lx.symbol.iPTYP_BSPL)
        poly.setTag (lx.symbol.i_POLYTAG_PART,crv['id'])
1 Like