Closed yoriyouriri closed 1 year ago
I need the DXF file, otherwise i can't help.
Thank you for your reply, here is my DXF file Drawing1.zip
I don't understand what you mean by:
i'm trying to convert a dxf file which contains some INSERT entities, but i got some (0,0,0) coordinates in results
This is shown by the view
command of the current beta version of v1.1:
This doesn't get any better as this is a 3D model made of thickened 2D elements and the drawing
add-on is not designed to render 3D objects.
Even BricsCAD has problems with this model:
and Trueview 2023 is not better:
Sorry, I didn't make my question clear. I'm using ezdxf to extract coordinates of elements in this DXF file (such as LINE, POLYLINE, CIRCLE, INSERT) ,but i‘ve got some abnormal coordinates. These abnormal coordinates are located at the origin of the coordinate system. Is this related to the 3D model thing you mentioned above?
I still don't know what you are doing, please post a script.
test_20230721.zip here is my script, and i've printed points of entities in get_vectors() , i have no idea why there are lots of [0,0,0]
` def readDXF(filepath, filename, png_path, length_unit=None):
if str(length_unit) == '0':
length_fold = 1
elif str(length_unit) == '1':
length_fold = 10
elif str(length_unit) == '2':
length_fold = 1000
else:
length_fold = 1
dxf_doc = ezdxf.readfile(filepath)
msp = dxf_doc.modelspace()
x_min = dxf_doc.header['$EXTMIN'][0]
y_min = dxf_doc.header['$EXTMIN'][1]
x_max = dxf_doc.header['$EXTMAX'][0]
y_max = dxf_doc.header['$EXTMAX'][1]
dxf_range = [x_min, y_min, x_max, y_max]
load(dxf_doc=dxf_doc, dxf_range=dxf_range)
`
` def resolve(entry, layer): if layer == '': layer = entry.dxf.layer else: layer = layer type = entry.DXFTYPE
if type == 'INSERT':
if list(entry.virtual_entities()):
for value in entry.virtual_entities():
if value.DXFTYPE == 'INSERT':
continue
resolve(value, layer)
return
elif type == 'POLYLINE' or type == 'LWPOLYLINE':
if type == 'LWPOLYLINE' and entry.has_arc:
bulge, vectors_l, vectors_t = [], [], []
vectors_t = get_vectors(type, entry)
vector_s = vectors_t[0:-1]
vector_e = vectors_t[1:len(vectors_t)]
else:
vectors_t = get_vectors(type, entry)
vector_s = vectors_t[0:-1]
vector_e = vectors_t[1:len(vectors_t)]
`
` def load(dxf_doc, dxf_range): msp = dxf_doc.modelspace()
xmin = dxf_range[0]
ymin = dxf_range[1]
xmax = dxf_range[2]
ymax = dxf_range[3]
ll = tuple((xmin, ymin))
ur = tuple((xmax, ymax))
ul = (ll[0], ur[1])
lr = (ur[0], ll[1])
# xmin,ymin,xmax,ymax
dxf_coordinate_range = [ll[0], ll[1], ur[0], ur[1]]
extent = [[]]
extent[0].append(ul)
extent[0].append(ur)
extent[0].append(lr)
extent[0].append(ll)
extent[0].append(ul)
# print ("EXTMAX ", dxf_doc.header['$EXTMAX'])
# print ("EXTMIN ", dxf_doc.header['$EXTMIN'])
# print ("LIMMAX ", dxf_doc.header['$LIMMAX'])
# print ("LIMMIN ", dxf_doc.header['$LIMMIN'])
# print ("LTSCALE ", dxf_doc.header['$LTSCALE'])
# print ("LUNITS ", dxf_doc.header['$LUNITS'])
group = msp.groupby(dxfattrib='layer')
for layer_name, entities in group.items():
layer = dxf_doc.layers.get(layer_name)
if layer.is_off() or layer.color < 0:
continue
for entity in entities:
resolve(entity, '')
# print(self.text)
# print(self.point)
def get_vectors(type, entry):
vectors_t = []
if type == 'POLYLINE':
vectors = list(entry.points())
else:
vectors = list(entry.vertices_in_wcs())
if entry.is_closed:
for v in vectors:
if isinstance(v, tuple):
vectors_t.append(v)
else:
vectors_t.append(v.xyz)
vectors_t.append(vectors_t[0])
else:
for v in vectors:
if isinstance(v, tuple):
vectors_t.append(v)
else:
vectors_t.append(v.xyz)
print(vectors_t)
return vectors_t`
So you want to write a DXF renderer, check out the drawing
addon for how to do that and yes it's complicated: https://github.com/mozman/ezdxf/tree/master/src/ezdxf/addons/drawing
The POLYLINE entity can represents 2D and 3D lines, 3D polyfaces and 3D meshes. In your code you are processing a 3D polyface like a 2D/3D polyline, which does not work because some points are vertices and some points are face records, the points which have an insert location at (0, 0, 0).
This is the compact code how to exclude 3D POLYLINE entities from processing:
from ezdxf import query
...
def resolve(entry, layer):
dxftype = entry.dxftype()
if dxftype == "INSERT":
entities = query.EntityQuery(entry.virtual_entities())
for pline in entities.query("POLYLINE LWPOLYLINE"):
resolve(pline, layer)
elif dxftype == "POLYLINE" and entry.is_2d_polyline:
get_vectors(dxftype, entry)
elif dxftype == "LWPOLYLINE":
get_vectors(dxftype, entry)
This is a simplified version of your code that uses the disassemble module to recursively decompose INSERT entities and the path
module to create Path objects:
import ezdxf
from ezdxf import query, disassemble, path
def load(doc):
msp = doc.modelspace()
plines = query.EntityQuery(
disassemble.recursive_decompose(msp), query="POLYLINE LWPOLYLINE"
)
for layer_name, entities in plines.groupby(dxfattrib="layer").items():
try:
layer = doc.layers.get(layer_name)
if layer.is_off():
continue
except ezdxf.DXFTableEntryError:
# a layer table entry is not mandatory and may not exist
pass
for entity in entities:
try:
entity_path = path.make_path(entity)
except TypeError: # ignore unsupported types: polyface and polymesh
continue
print(str(entity))
print(list(p.xyz for p in entity_path.control_vertices()))
if __name__ == "__main__":
doc = ezdxf.readfile("910.dxf")
load(doc)
I don't quite understand the meaning of control_vertices, are they releated to the actual location of the points which have an insert location at (0, 0, 0) ?
For 3D POLYLINE entities, is there something i can do to handle them as 2d entities? I don't mind losing the value of z
The Path
class represents ARC and ELLIPSE entities as approximated cubic Bézier-curves. The control vertices define the geometry of Bézier curve: https://pomax.github.io/bezierinfo/
For linear elements the control vertices are the points of the line e.g. LWPOLYLINE without bulge values.
The projection onto the xy-plane is easy:
list((p.x, p.y) for p in entity_path.control_vertices())
thank u for your reply, it helps me a lot
Describe the bug A clear and concise description of what the bug is. i'm trying to convert a dxf file which contains some INSERT entities, but i got some (0,0,0) coordinates in results To Reproduce Information and data needed to reproduce the error:
Confidential Data If you have sensitive files that you can't disclose, try to remove everything sensitive from an existing file or create a brand new one which still triggers the error. Alternatively, you can send the zipped files to confidential@mozman.at, this data is only saved locally (no cloud upload of any kind) and the files are deleted after the error has been fixed.
Expected behavior A clear and concise description of what you expected to happen.
Screenshots If applicable, add screenshots to help explain your problem. convert result :
origin file: