Closed vicky8989 closed 2 years ago
It sounds like the problem you are having is that you do not have enough RAM to complete the drawing of the entire file. You could try drawing each layer individually with a transparent background and compositing the result afterwards? Also the matplotlib backend converts the DXF entities to plotting entities and only rasterises at the end. Drawing pixels onto a canvas immediately would probably require a lot less ram so you could implement a backend using openCV or something that can draw pixels.
Maybe you can upload the dxf file?
This example script shows how to render the model space in multiple tiles, it's the result of this stackoverflow question. The script always loads the whole DXF file, but renders only a certain area of the model space, this may need less memory than a full rendering. You can stitch the tiles afterwards with an image library like Pillow
automatically (I guess).
Maybe you can upload the dxf file?
uploaded!
This example script shows how to render the model space in multiple tiles, it's the result of this stackoverflow question. The script always loads the whole DXF file, but renders only a certain area of the model space, this may need less memory than a full rendering. You can stitch the tiles afterwards with an image library like
Pillow
automatically (I guess).
Appricatiate your suggestion, i will try. Added on my question, i've uploaded my dxf file. i guess this problem is caused by the insert entity. i've debug the source code, the code will invoke explode.js , i think this may get an endlessloop. i tried to explode this file in autocad software,it will get 100 0000 + virtual entites , it has so many blocks. i think your answer may work, i will find how to use this solution. thanks so much!
This example script shows how to render the model space in multiple tiles, it's the result of this stackoverflow question. The script always loads the whole DXF file, but renders only a certain area of the model space, this may need less memory than a full rendering. You can stitch the tiles afterwards with an image library like
Pillow
automatically (I guess).
i tried this way to export pngs。i think this way can improve the render performance in frontend,e.g. Web except exporting a png。 Maybe i have to find another better way to analyse INSERT entity。o(╥﹏╥)o
The good news are, ezdxf
can now render this file (unexpected matplotlib
errors are handled now), the bad news are, it requires ~24.1 GB (overall) on a Windows 11 machine. Rendering the model space in tiles reduces the memory usage, but unfortunately does this method not work for that complex drawings, there are no exact cutting edges between the tiles:
The good news are,
ezdxf
can now render this file (unexpectedmatplotlib
errors are handled now), the bad news are, it requires ~24.1 GB (overall) on a Windows 11 machine. Rendering the model space in tiles reduces the memory usage, but unfortunately does this method not work for that complex drawings, there are no exact cutting edges between the tiles:
Thanks a lot! I wonder if I can change the INSERT analyser method instead explode it. Can I read blocks first, use INSERT attributes to rewrite blocks to entities.
`msp = doc.modelspace()
for insert in msp.query('INSERT'): block = doc.blocks[insert.dxf.name] for e in block: msp.add_entity(e) msp.delete_entity(insert)`
I have tried the above way. Maybe something is wrong, it lost so many INSERT.
This problem is so hard. it bothers me for several days!
Insert.explode()
: https://ezdxf.mozman.at/docs/blocks/insert.html#ezdxf.entities.Insert.explode
Collect INSERT
entities before exploding them, because exploding the entities alters the layout content:
inserts = msp.query("INSERT")
for insert in inserts:
insert.explode()
Added a proof of concept for a Pillow
backend:
This image took only ~100 sec with not much memory usage, the backend draws direct to the canvas.
Backend: https://github.com/mozman/ezdxf/blob/master/src/ezdxf/addons/drawing/pillow.py Example: https://github.com/mozman/ezdxf/blob/master/examples/addons/drawing/pillow.py
Not ready for usage, see limitations:
what an excellent news! it fits my requirements totally except text. it will be better includes text .Thanks so much!
i use the commond:
python testPillow.py f397.dxf -o f397.png -i 1920,1080 -r 2 --dpi 300
I got a 11kb png file without any graphic...
is it a lib version problem?
The current state creates this:
You have to keep your cloned repository updated!
The current state creates this:
You have to keep your cloned repository updated!
yes,i got the image after updating all codes! the cpu will also go 100% for seconds,the good news is it will not kill my computer, after 279s ,i got the image. there are some other things i need to research. such as text layer, style,faster ... 。 Thanks so much for helping!
The process in which the python interpreter is running will always reach 100%, the important part is not to run out of memory.
I tried to add text support but wasn't successful. Instead I added an option to draw a rectangle as text placeholder. The CADKitSample "Wood Details.dxf" looks like this:
Without placeholder:
With text placeholder:
Your DXF with text placeholder:
what doesn't work about your attempt at pillow text drawing? It looks like pillow supports drawing with ttf fonts so was it something like the sizing?
Pillow
has only support for horizontal text. So you have to create the horizontal text in a separated image and then transform and paste the image which was very slow. And that's just the beginning... coordinate transformation (inverted y-axis), text sizing (you can't render a small text size and scale it by a large factor) and maybe more issues I don't want to bother with.
Added a (dead) branch "pillow-backend" to preserve the current state: it's slow and rotation doesn't work properly
This is "Wood Details.dxf" with 4x oversampling, which takes >105 seconds to render with text and <1 second without text:
A test file with rotated text:
But should look like this:
Added PillowDelayedDraw()
as 2nd backend.
This backend does not need to know the layout extents in advance. The layout extents are calculated on the fly while drawing commands are queued. The pending drawing commands are executed during image export.
This needs more memory but avoids the bounding box detection, measurements for F397.dxf
(i7-12700K):
Backend | Runtime | Memory Usage |
---|---|---|
PillowBackend() incl. bbox detection | ~85 seconds | ~16 MiB |
PillowDelayedDraw() | ~70 seconds | ~1088 MiB |
If you know the layout region to export (e.g. (0, 0) to (1000, 1000)) and don't need the bounding box detection, the PillowBackend()
is faster and uses less memory than the PillowDelayedDraw()
backend.
Added text support by reusing the TextRenderer()
from the matplotlib
backend (branch: pillow-backend):
python3 pillow.py '.\WOOD DETAILS.dxf' -o wood.png -r 6 -i 3840x2160
This implementation renders the text as outline paths and slows the execution speed drastically if there is much text.
The WOOD DETAILS.dxf
sample file needs 9.4 seconds for rendering with text and 1.0 seconds for rendering with placeholders.
I will merge this changes into the main-branch and add a new command quickdraw
to the ezdxf
launcher.
ezdxf quickdraw '.\WOOD DETAILS.dxf' -o wood.png -r 6 -i 3840x2160
This command could be useful to create overviews or thumbnails of the modelspace. The default text mode will be text-placeholder
to justify the term "quickdraw".
The remaining limitations are:
UPDATE for v0.18.1
pillow
ezdxf pillow '.\WOOD DETAILS.dxf' -r3 -o wood.png
i want to export an png with dxf。This dxf is very complicated,it may have 50000+ entites, when i export dxf to png, use the code below:
Frontend(ctx, out).draw_layout(msp, finalize=True)
the cpu of my computer 8G is going 100%。I put this to a unix server, 16G ,cpu is also going to 100%。
did anyone meet this problem? is there any other way to invoid this question. it kills my application... Appriciate your help.
The test dxf file below:
F397.dxf.zip