parsingtransformationdxfdata-importer

DXF importer, not sure in which order to do transformations, how to handle units and base point of a block?


I am implementing a DXF importer, for now I am taking into consideration the HEADER section and only one variable from it INSUNITS, TABLES section only one table BLOCK_RECORD table, BLOCKS section, ENTITIES section (INSERT, LINE, LWPOLYLINE, ARC, CIRCLE).

When importing I don't know if I need to take into consideration units, and if I need to, I don't know how exactly to take this into consideration. My file is not imported in the correct way now, it is most likely due to these units as I think I am doing my INSERT transformations correctly:

EXTRUSIONDIRECTIONTRANSFORMATION * 
     INSERTIONPOINTTRANSLATION * 
     ROTATION * SCALING * BASEPOINTTRANSLATION

A file I am importing is imported in the correct way when I remove the BASEPOINTTRANSLATION, but some other files are not imported in the right way and some parts of the drawing get imported very far away from rest.

It looks to me like the base point of a block is in inches and when I convert it to meters it becomes a bit better. So if someone knows in which order I should do the transformations and how to handle units in DXF files I would be really grateful as I am stuck now.


Solution

  • In the Python ezdxf package, I do it that way:

    1. Start matrix M0 = OCS transformation matrix including the scaling of the x-, y- and z-axis; same as OCS transformation matrix * scaling matrix
    2. rotation matrix M1 about the extrusion vector
    3. transformation matrix M= M0 * M1
    4. adding the translation to the insert point
      • transform the insert point from the OCS to WCS
      • transform the block_base_point by the current matrix M without translation, the current state of M doesn't have a translation yet, so a full transformation wouldn't be a problem but a "direction only" transformation is faster in my code
      • subtract the block_base_point from the insert point
      • set last row of M to (insert.x, insert.y, insert.z, 1) if row major order, last column if column major order, which is basically M * translation matrix

    the Python code at github

    The unit scaling can be ignored, the CAD application has to set the correct scaling values to match parent layout units and block reference units in the INSERT scaling attributes. E.g. if you insert a block with mm-units into a modelspace with m-units, the scaling values of the INSERT entity have to be 0.001 to convert the millimeters into meters (1mm = 0.001m).