最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Controlling line width in ezdxf output to PDF - Stack Overflow

programmeradmin2浏览0评论

I'm trying to draw some basic circles and squares in ezdxf, then write to pdf. Things look fine when I draw just a few units. But when I draw many, the line gets thicker. No amount of messing around with dfxattribs={'lineweight':0} does the trick. I think ezdxf or the pdf converter is somehow scaling stuff. It seems to fix the size of the PDF, then scale things down to fit, but the line width is stuck to some other scaling, and the net result is thick lines.

Here are some examples.

def test():
    from numpy import arange
    doc = ezdxf.new(dxfversion="R2010")
    doc.units = units.MM
    doc.header['$LWDISPLAY'] = 1
    msp = doc.modelspace()
    blk = doc.blocks.new(name='MYBLOCK')
    blk.add_circle((0,0), 1, dxfattribs={'lineweight':0})
    blk.add_polyline2d(((-1,-1),(1,-1),(1,1),(-1,1)))

    pos_step = 2.0
    blockscale = 1.0
    for x in arange(0, pos_step*5, pos_step):
        for y in arange(0, pos_step*3, pos_step):
            msp.add_blockref('MYBLOCK', 
                            (x, y),
                            dxfattribs={'xscale': blockscale,
                                        'yscale': blockscale})

    msp.add_linear_dim(
        base = (0,-pos_step/2),
        p1   = (0,0),
        p2   = (pos_step,0),
        override = {'dimblk': ezdxf.ARROWS.closed_filled}
        ).render()
    matplotlib.qsave(msp, 'test.pdf')

The output here looks fine. pdf is 6.5x4.8 [in]:

If I do 50 units across:

for x in arange(0, pos_step*50, pos_step):

I think the lines are getting thicker but it looks fine. pdf is 16x2 [in]:

If I do 500 units across:

for x in arange(0, pos_step*500, pos_step):

The lines are visibly thicker. pdf is 16x2 [in]:

If we go crazy with 5000 units across:

    for x in arange(0, pos_step*5000, pos_step):

The lines are so thick it's just a block of white. pdf is 16x2 [in]:

So I think this has something to do with the pdf sheet size staying the same even with more and more blocks being placed. How do I get the some thickness lines for all versions of this test? Is it possible to scale the size of the PDF output manually, or set some better automatic parameters?

I'm trying to draw some basic circles and squares in ezdxf, then write to pdf. Things look fine when I draw just a few units. But when I draw many, the line gets thicker. No amount of messing around with dfxattribs={'lineweight':0} does the trick. I think ezdxf or the pdf converter is somehow scaling stuff. It seems to fix the size of the PDF, then scale things down to fit, but the line width is stuck to some other scaling, and the net result is thick lines.

Here are some examples.

def test():
    from numpy import arange
    doc = ezdxf.new(dxfversion="R2010")
    doc.units = units.MM
    doc.header['$LWDISPLAY'] = 1
    msp = doc.modelspace()
    blk = doc.blocks.new(name='MYBLOCK')
    blk.add_circle((0,0), 1, dxfattribs={'lineweight':0})
    blk.add_polyline2d(((-1,-1),(1,-1),(1,1),(-1,1)))

    pos_step = 2.0
    blockscale = 1.0
    for x in arange(0, pos_step*5, pos_step):
        for y in arange(0, pos_step*3, pos_step):
            msp.add_blockref('MYBLOCK', 
                            (x, y),
                            dxfattribs={'xscale': blockscale,
                                        'yscale': blockscale})

    msp.add_linear_dim(
        base = (0,-pos_step/2),
        p1   = (0,0),
        p2   = (pos_step,0),
        override = {'dimblk': ezdxf.ARROWS.closed_filled}
        ).render()
    matplotlib.qsave(msp, 'test.pdf')

The output here looks fine. pdf is 6.5x4.8 [in]:

If I do 50 units across:

for x in arange(0, pos_step*50, pos_step):

I think the lines are getting thicker but it looks fine. pdf is 16x2 [in]:

If I do 500 units across:

for x in arange(0, pos_step*500, pos_step):

The lines are visibly thicker. pdf is 16x2 [in]:

If we go crazy with 5000 units across:

    for x in arange(0, pos_step*5000, pos_step):

The lines are so thick it's just a block of white. pdf is 16x2 [in]:

So I think this has something to do with the pdf sheet size staying the same even with more and more blocks being placed. How do I get the some thickness lines for all versions of this test? Is it possible to scale the size of the PDF output manually, or set some better automatic parameters?

Share Improve this question asked Nov 21, 2024 at 5:41 SonicsmoothSonicsmooth 2,7772 gold badges24 silver badges40 bronze badges 1
  • I changed the test code to do stuff using Matplotlib more directly and set the block lineweight to 100. Changing LWDISPLAY didn't make a difference. The PDF output kept the thick lines. I used ezdxf.readthedocs.io/en/stable/addons/drawing.html , github/mozman/ezdxf/discussions/797 , ezdxf.mozman.at/docs/howto/… – Sonicsmooth Commented Nov 24, 2024 at 1:29
Add a comment  | 

1 Answer 1

Reset to default 0

The new test code, derived from:

https://ezdxf.mozman.at/docs/howto/drawing-addon.html#how-to-set-the-page-size-in-inches https://github/mozman/ezdxf/discussions/797

def export_to_scale(doc, msp, filename, paper_size, minxy, maxxy, dpi = 300):
    """Render the modelspace content with to a specific paper size and scale.
    Args:
        doc -- the ezpdf doc
        msp -- the modelspace
        filename -- the filename
        paper_size: paper size in inches
        minxy: lower left corner tuple of the modelspace area to render
        maxxy: upper right corner tuple of the modelspace area to render
        dpi: pixel density on paper as dots per inch
    """
    ctx = RenderContext(doc)
    fig: plt.Figure = plt.figure(dpi=dpi)
    ax: plt.Axes = fig.add_axes([0, 0, 1, 1])

    # disable all margins
    ax.margins(0)

    # Set the final render limits in drawing units:
    ax.set_xlim(minxy[0], maxxy[0])
    ax.set_ylim(minxy[1], maxxy[1])

    mspp = LayoutProperties.from_layout(msp)
    mspp.set_colors("#eaeaea")
    config = Configuration.defaults()
    config = config.with_changes(min_lineweight = 0.1)


    out = MatplotlibBackend(ax)
    # finalizing invokes auto-scaling by default!
    Frontend(ctx, out, config=config).draw_layout(msp, finalize=False, layout_properties=mspp)
    fig.set_size_inches(paper_size[0], paper_size[1], forward=True)
    fig.savefig(filename, dpi=dpi)
    plt.close(fig)

def test():
    from numpy import arange
    doc = ezdxf.new(dxfversion="R2010")
    doc.units = units.MM
    doc.header['$LWDISPLAY'] = 0
    msp = doc.modelspace()

    blk = doc.blocks.new(name='MYBLOCK')
    blk.add_circle((0,0), 1, dxfattribs={'lineweight': -2})
    blk.add_polyline2d(((-1,-1),(1,-1),(1,1),(-1,1)), close=True, dxfattribs={'lineweight': -2})

    pos_step = 2.0
    blockscale = 1.0
    for x in arange(0, pos_step*500, pos_step):
        for y in arange(0, pos_step*3, pos_step):
            msp.add_blockref('MYBLOCK', 
                            (x, y),
                            dxfattribs={'xscale': blockscale,
                                        'yscale': blockscale,
                                        'lineweight': 100})

    msp.add_linear_dim(
        base = (0,-pos_step),
        p1   = (0, 0),
        p2   = (pos_step,0),
        override = {'dimblk': ezdxf.ARROWS.closed_filled}
        ).render()

    export_to_scale(doc, msp, 'test.pdf', (17,11), (-10,-10), (pos_step*501,pos_step*4), 300)

The output with lineweight = 100:

The output with lineweight = 0:

Incidentally adding close=True to the polyline didn't quite work in the real (not test) application. It closed the polyline but the final corner rendered with a notch, ie where the centerlines meet. Probably not incorrect, but also not aesthetically pleasing. I repeated the last two points to get properly mitered corners.

发布评论

评论列表(0)

  1. 暂无评论