Closed chibai closed 3 years ago
I'm Mr Bug-Producer
I think I'm Mr Bug-Presentor, not Mr Bug-Producer
What is your workflow to create your CAD drawings?
What is your workflow to create your CAD drawings?
test_simplified.zip I'm sorry. I'm not the auther of dxf file and the workflow is not recordable. I smiplified the dxf to the bug HATCH entity, hope it can be helpful.
I just wanted to know how this HATCH was created because this is not a result that a human would create on purpose.
I just wanted to know how this HATCH was created because this is not a result that a human would create on purpose.
Well, I guess it's a work of my unskilled colleague. But I really don't know how the HATCH is created......
This is the degenerated path boundary paths which causes the problem. I have no idea how to filter out such (erroneous) boundary paths like AutoCAD and BricsCAD do.
This is the edge path (path of single lines) without connection lines added by ezdxf:
Ezdxf is designed to create always connected paths, if the following line element has no common point with the previous line element, ezdxf adds automatically a line segment from the previous end to the following start.
I don't think I will add a logic to detect these degenerated paths, there are infinite possibilities for such paths and frankly I also have no idea how to do that.
Got it, thank your for telling me this!
Not so fast young padawan - maybe I have an idea later.
Not so fast young padawan - maybe I have an idea later.
I think you could foucus more on some general problems. And I don't want this specific rare bug to waste your time.
But this is real programming task, most of the other problems are: how to write the damn DXF tags to make AutoCAD happy, or how to interpret or render a special or undocumented DXF tag.
Some new insights:
from pathlib import Path
import ezdxf
DIR = Path("~/Desktop/Outbox").expanduser()
doc = ezdxf.new()
msp = doc.modelspace()
msp.add_lwpolyline([(0, 0), (1, 0), (1, 1), (0, 1)], close = True)
hatch = msp.add_hatch(1)
p = hatch.paths.add_edge_path()
# 2 open segments
p.add_line((1, 0), (1, 1))
p.add_line((1, 1), (0, 1)) # break in continuity
p.add_line((1, 0), (0, 0))
p.add_line((0, 0), (0, 1))
doc.set_modelspace_vport(2, center=(0.5, 0.5))
doc.saveas(DIR / "hatch_edge_with_open_segments.dxf")
hatch = msp.add_hatch(1)
p = hatch.paths.add_edge_path()
# 1st loop: closed segments
p.add_line((0, 0), (1, 0)) # edit2
p.add_line((1, 0), (1, 1)) # edit2
p.add_line((1, 1), (0, 1))
p.add_line((0, 1), (0, 0)) # edit: fixed continuity break
doc.saveas(DIR / "hatch_edge_with_one_closed_loop.dxf")
# 2nd loop: closed segments
p.add_line((2, 0), (3, 0))
p.add_line((3, 0), (3, 1))
p.add_line((3, 1), (2, 1))
p.add_line((2, 1), (2, 0))
doc.saveas(DIR / "hatch_edge_with_two_closed_loops.dxf")
hatch_with_open_segments.dxf
does not render a HATCH
:
hatch_edge_with_one_closed_loop.dxf
renders the expected HATCH
:
hatch_edge_with_two_closed_loops.dxf
renders the weird and unexpected HATCH
, same result in AutoCAD and BricsCAD:
I can can easily remove open segments from the edge path, and render only closed loops, but I think I can not reproduce the result for the two closed loops at the same edge path. My solution will render two separated squares/loops.
Edit: error in two closed loops, but result isn't really better:
Edit2: found another error and now the result is at least understandable:
The current solution renders this for the two loops:
and this for the example DXF:
Thanks very much!!
I leave this issue open for a while. I am afraid this is not the end of the road!
Where do you live/work?
I leave this issue open for a while. I am afraid this is not the end of the road!
Where do you live/work?
I was born and grew up in small citi of Dongyang, Zhejiang province of China And now I'm living and working in Shanghai, China How about U?
I am from Austria, Graz.
I only asked because I was surprised by your quick answers during my work day that didn't quite match my assumption that you were from China.
test_hatch.zip I think I found another hatch bug? ezdxf drawing AutoCad showing
I only answer in my work time, which is 10:am to 7:pm(GMT+8). I hope one day I can have time to dig into this code and make contribution on this dxf community!
BricsCAD shows also another result:
I'll look at the DXF file later.
AutoCAD renders a line where no line should be. BricsCAD perfectly subtracts the inner rectangle from the outer shape, as I would expect. Maybe that is a battleground for a war about "boundary" conditions :)
Matplotlib and PyQt handle overlapping paths differently than CAD applications. This are the same boundary paths and even the simple island detection of ezdxf works as expected for this example, but the rendering of the Qt-backend is different to BricsCAD:
I'm afraid there is nothing I can do about it.
This code snippet shows how I isolated such entities form the source document:
from pathlib import Path
import ezdxf
DIR = Path("~/Desktop/Now/ezdxf").expanduser()
doc = ezdxf.readfile(DIR / "chibai04.dxf")
hatch = doc.entitydb.get("1D19") # get entity by handle
doc2 = ezdxf.new()
msp2 = doc2.modelspace()
msp2.add_foreign_entity(hatch) # unlinks and unbinds hatch from the source doc!
doc2.saveas(DIR / "isolated_hatch.dxf")
This is not a general recommendation to do this, because this is only sometimes useful if the context is not important for the issue like for the last example and zipped DXF files are really small. And it only works if the CAD application shows the entity handle like BricsCAD:
got it!
test_missing_hatch.zip Dear mozman @mozman found another one Missing Circle Hatch EZDXF drawing result autocad showing
This should be fixed.
This should be fixed. @mozman
from ezdxf import recover from ezdxf.entities import Insert, Hatch, EdgePath, LineEdge
def process_hatch(entity: Hatch): available_boudPaths = list(entity.paths.rendering_paths(hatch_style=entity.dxf.hatch_style)) for path in available_boudPaths: if isinstance(path, EdgePath): for edge in path.edges: if isinstance(edge, LineEdge): print(entity.ocs().to_wcs(edge.start))
def process_insert(entity: Insert): for e in entity.virtual_entities(): entity_type = e.dxftype() if entity_type == 'INSERT': process_insert(e) elif entity_type == 'HATCH': process_hatch(e)
dxf_doc, dxf_auditor= recover.readfile('test_missing_hatch.dxf')
for e in dxf_doc.modelspace(): if e.dxf.invisible == 0: entity_type = e.dxftype() if entity_type == 'HATCH': process_hatch(e) elif entity_type == 'INSERT': process_insert(e)
Please try this code , must be something wrong by #454
![1623230617(1)](https://user-images.githubusercontent.com/5702248/121329131-81a70600-c947-11eb-8b2d-cd6dfaf7a0a9.png)
ocs.to_wcs()
requires a vector with x-, y- and and z-axis, wrap it by ezdxf.matzh.Vec3()
.
ocs.to_wcs()
requires a vector with x-, y- and and z-axis, wrap it byezdxf.math.Vec3()
.
ok!
Added safety castings to Vec3()
to the transformation methods of Matrix44()
for the pure Python implementation to get the same behavior as for the C-extension.
test.zip
This is the code result:
This is the AutoCad result: