Access userdata created by DXF import

Hi,

I imported some client’s data from a DXF file. I contains some mesh objects with additional attributes assigned to them. By pressing the Details button in the object property window I get this output:

mesh  
  ID: fc9d0dc4-90cd-48eb-8055-5e33a79d661c (2076)
  Layer name: MROOT_OPTION 3TR_STO_01 JAN 2018
  Render Material: 
    source = from layer
    index = -1
  Geometry:
    Valid mesh.
    Closed double precision polygon mesh: 140 vertices, 60 polygons with normals
      bounding box: (116026,219029,9385.28) to (9415.11,219044,)
    Geometry UserData:
      UserData ID: 17F24E75-21BE-4a7b-9F3D-7F85225247E3
      Plug-in: c8cda597-d957-4625-a4b3-a0b510fc30d4
        description: ON_Mesh double precision vertices
        saved in file: yes
        copy count: 3

How can I access (read) this additional data? I tried RhinoPython:

>>> data = myMeshObj.Attributes.UserData
>>> print data.Count
1
>>> print data
<Rhino.DocObjects.Custom.UserDataList object ....

but there seems to be no way to get the actual data

I also tried VB - RhinoScript but here the data did not show up at all:

Rhino.IsObjectData(strObject); Rhino.IsAttributeData(strObject); Rhino.IsUserText(strObject)

did not show anything.

Any idea?

Regards, Gero.

Hi Gero,

Could you post a file or parts of it ? Did Rhino.IsObjectData return False ?

c.

Hi clement,

thanks for looking into this.

Yes, Rhino.IsObjectData(strObject), Rhino.IsAttributeData(strObject) (and Rhino.IsUserText(strObject)) all return False.

I can’t easily post the DXF file because of it’s size (and I doubt my client would be happy with me publishing his data). I could try to extract a relevant chunk as the DXF is ascii. But I’m not very familiar with the DXF format.

Gero.

Here is an excerpt of the DXF data which looks to me like the definition of one of those objects for which I’d like to read the user data. I don’t know if that is of any help… I would be interested in those data pieces initiated by number 1000 and 1001.

  0
POLYLINE
  5
5595
330
7214
100
AcDbEntity
  8
MROOT_OPTION 3TR_STO_01 FEB 2015
 62
    24
440
 33554687
100
AcDbPolyFaceMesh
 66
     1
 10
0.0
 20
0.0
 30
0.0
 70
    64
 71
    36
 72
    68
1001
SEGMENT
1000
D_00378002
1001
M4DNUM
1000
195
1001
M4DDESC
1000
SLC Stope
1001
ACTIVITY
1000
STO
1001
TONNES
1000
2184.09485462
1001
PERIOD
1000
01 Feb 2015

Hi Gero,

Rhino.IsObjectData and Rhino.IsAttributeData only return True if the object or it’s attributes contain RhinoScript user data, not just any old user data. Also the data you are seeing (from the What command) is not user text, so this function will return false too.

ON_Mesh double precision vertices is created automatically by Rhino when it detects a mesh that is far from the world origin (0,0,0). There is no to access this data directly. If you need the vertices, just go through the Rhino.Geometry.Mesh object as you normally would.

– Dale

Aha, thanks for clarifying. So this extra data from the DXF file is actually not imported at all.

This might be a nice feature in the future then, if there was such an option that data that is not recognized by the import is stored as user data (preferably in a Python-accessible way).

Kind regards,
Gero.

Correct.

If I understand correctly, you want to add custom data to DXF files, and hen have Rhino read in the DXF file and (somehow) interpret this custom DXF data as Rhino user data? Why do you need this?

It seems that at least the program of my client (don’t know the name or anything) when exporting geometry data also adds some extra data to those objects.

In my case this is an underground excavation. The geometrical data defines the shape and location of this excavation. And it seems that there is also data about the type of excavation (you find “SLC Stope” in the data excerpt I pasted in earlier), a date and other stuff that would be very useful. I’m using some Rhino-Python scripts to generate input data for numerical simulations.

I hope this explains my motivation. And I can imagine that this is not the only case where non-standard data items are attached to objects in a DXF file in similar ways. I think it might be worth while trying to map any (or some) otherwise unrecognized data in a DXF file to the Rhino user data and therefore make it accessible from within the Rhino scripting framework.

It’s often a frustrating task to get complex data from one program to another and Rhino very often is very handy in this.

Since Rhino currently just ignores the extra data, the only way for me to get it would be to write my own DXF import function. I can imagine that it’s much easier for the developers of the Rhino DXF import to add such an “extra data to user data” feature.

To avoid importing megabytes of generally not useful data this might better be an option like “import unrecognized data as user data”.

Kind regards, Gero.

Hi Gero,

Its possible that the extra data is from AutoCAD. It has a user data called extended entity data. Its been a while since I’ve goofed with AutoCAD, but I will bet those DXF codes are for “xdata”. The best we could ever hope to do is to add this xdata to objects as user text.

Would this help?

@lowell, what are you thoughts on this?

I guess it would be possible to read at least some extended data from dxf files. Its pretty well documented.

Here’s a link to some of that:
http://www.autodesk.com/techpubs/autocad/acad2000/dxf/extended_data_dxf_ab.htm

As you can see from that documentation and the dxf example above, the data in the dxf is incorrectly written as it uses the 1001 group code for field names and doesn’t appear to delineate by application.
Its pretty easy for a human to see what’s going on, but stuff like that would make it pretty hard to get a useful result with a general extended data reader.

Excerpt from the tech pub at the link above:
The group code 1001 indicates the beginning of extended data. In contrast to normal entity data, with extended data the same group code can appear multiple times, and order is important.

Extended data are grouped by registered application name. Each registered application’s group begins with a 1001 group code with the application name as the string value. Registered application names correspond to APPID symbol table entries.

An application can use as many APPID names as needed. APPID names are permanent, although they can be purged if they aren’t currently used in the drawing. Each APPID name can have no more than one data group attached to each entity. Within an application’s group, the sequence of extended data groups and their meaning is defined by the application.

The extended data group codes are listed in the following table.

Extended data group codes and descriptions
Entity name Group code Description
String

1000

Strings in extended data can be up to 255 bytes long (with the 256th byte reserved for the null character).

Application
name

1001
also a string value

Application names can be up to 31 bytes long (the 32nd byte is reserved for the null character).

NOTE Do not add a 1001 group into your extended data because AutoCAD assumes it is the beginning of a new application extended data group.

Hi Dale, hi Lowell,

Yes, this would be awesome. Extracting the data I need from a string would be easy with Python.

Btw. I do not know which software created that data, but it’s not been Autocad. From my experience DXF seems to be a rather popular means to transfer 3D geometrical (and some attached) data.

I understand your point. But I do think that any representation of the DXF data in a user data text string might be better than not importing it in any way. Maybe only in some cases and only to some users I must admit. That’s another reason to make this import of extra data a non default option.

What about that: Just add any chunk (that you can’t interpret/convert more reasonably) to some simple key : value representation in a string. I.e. the chunk that I posted as an example would result in a string like:

1001:"SEGMENT", 1000:"D_00378002", 1001:"M4DNUM", 1000:"195", ....

Of course this might not be suitable in all cases, like what happens if there is a quote in the data strings. But if you just ignore this problem for me and maybe 90% of similar cases this would be sufficient and perfect. Same if you worry about binary data: Any transformation (e.g. to hex code or whatever) is better than not having the data in Rhino at all and ultimately being forced to write a whole DXF importer from scratch.

Yes, something like that would be possible. Its a matter of scheduling priorities and typing time.

@lowell and @dale I added this as a comment here rather than a new topic since this topic was actually briefly mentioned in this thread.

As gero asked in his first post:
How are Userdata instances accessed from the userDataList. It seems that that class does not derive from any collection type and thus I cannot just write myObject.Attributes.Userdata[0]. Or loop though with foreach all the custom data in the (what i assume is supposed to be) list.

I assume that there is a simple answer to this which I am just not aware of…

With best regards
Matti Pirinen

Hi @Matti_Pirinen,

This is true. The UserDataList class stores custom objects that inherit from UserData. And unless you have the class definition of what is stored in the user data list, you won’t be able to access it.

With that said, what problem are you trying to solve?

– Dale

A post was split to a new topic: RhinoCommon and UserData issue