Search code examples
pythonautocadcoordinate-systemscaddxf

How to modify an existing dxf file using ezdxf python package?


I'm trying to add entites to the modelspace of an existing .dxf file using ezdxf. The location of the inserted entities is completely off from where I expect them to be.

For a circle, I got the location coordinates of an entity using by e.dxf.insert and used this point as the center of a circle. I've used the following code:

import ezdxf
dwg = ezdxf.readfile("drainage.dxf")

msp = dwg.modelspace()
dwg.layers.new(name='MyCircles', dxfattribs={'color': 7})

def encircle_entity(e):
    if e.dxftype()=='INSERT':
        circleCenter = e.dxf.insert
        msp.add_circle(circleCenter, 10, dxfattribs={'layer': 'MyCircles'})
        print("Circle entity added")

washBasins = msp.query('*[layer=="WASH BASINS"]')
for e in washBasins:
    encircle_entity(e)

dwg.saveas('encircle.dxf')

Link to drainage.dxf (input) and encircle.dxf (output) files: https://drive.google.com/open?id=1aIhZiuEdClt0warjPPcKiz4XJ7A7QWf_

This creates a circle, but at an incorrect position.

Where is the origin in the dxf file and the origin that ezdxf uses? How do I get the correct positions of all entities, especially INSERT, LINES and CIRCLES? How do I place my entities at the desired positions in an already existing dxf file using ezdxf? Where are the e.dxf.start and e.dxf.end points of a line with respect to the coordinates?

I think I'm missing something in coordinates here. Kindly explain how the coordinates work.


Solution

  • Python version of @LeeMac solution, but ignoring OCS:

    import ezdxf
    from ezdxf.math import Vector
    
    DXFFILE = 'drainage.dxf'
    OUTFILE = 'encircle.dxf'
    
    dwg = ezdxf.readfile(DXFFILE)
    msp = dwg.modelspace()
    dwg.layers.new(name='MyCircles', dxfattribs={'color': 4})
    
    
    def get_first_circle_center(block_layout):
        block = block_layout.block
        base_point = Vector(block.dxf.base_point)
        circles = block_layout.query('CIRCLE')
        if len(circles):
            circle = circles[0]  # take first circle
            center = Vector(circle.dxf.center)
            return center - base_point
        else:
            return Vector(0, 0, 0)
    
    
    # block definition to examine
    block_layout = dwg.blocks.get('WB')
    offset = get_first_circle_center(block_layout)
    
    for e in msp.query('INSERT[name=="WB"]'):
        scale = e.get_dxf_attrib('xscale', 1)  # assume uniform scaling
        _offset = offset.rotate_deg(e.get_dxf_attrib('rotation', 0)) * scale
        location = e.dxf.insert + _offset
    
        msp.add_circle(center=location, radius=1, dxfattribs={'layer': 'MyCircles'})
    
    dwg.saveas(OUTFILE)