import argparse import configparser import ezdxf from ezdxf.math import Matrix44 import os import sys """ Dieses Programm: - liest die dxf Datei und holt sich von den Layern der dxf Datei die Positionen + der Motoren, Sensoren und Aktoren + der Unterverteiler + der Polylinien der Kabelpritschen - erzeugt daraus eine .json Datei im Work Ordner """ def write_results(jsnResults, outdir, filename): """ write results to a json file """ print("writing results to a json file ...") outfile = os.path.join(outdir, filename) with open(outfile, 'w', encoding='utf-8') as fh: fh.write(jsnResults) print("done") def get_world_position_of_attribute(insert, attrib): """ Berechnet die echte Weltposition eines Block-Attributs (ATTRIB) unter Berücksichtigung von Skalierung, Drehung und Blockverschiebung. :param insert: Blockreferenz-Entity (INSERT) :param attrib: Attribut-Entity (ATTRIB) :return: Vector (x, y, z) in Weltkoordinaten """ # Lokale Position des Attributs local_pos = attrib.dxf.insert # Blockeinfügepunkt block_pos = insert.dxf.insert # Blockskalierung (Standard = 1.0) xscale = getattr(insert.dxf, 'xscale', 1.0) yscale = getattr(insert.dxf, 'yscale', 1.0) # Rotation des Blocks (in Grad) rotation_deg = insert.dxf.rotation # Transformation aufbauen: Skalierung -> Rotation -> Translation m = ( Matrix44.scale(xscale, yscale, 1) @ Matrix44.z_rotate(rotation_deg * 3.141592653589793 / 180) @ Matrix44.translate(block_pos.x, block_pos.y, block_pos.z) ) # Lokale Position transformieren return m.transform(local_pos) def get_input_positions(doc): """hole alle Positionen der Eingänge """ msp = doc.modelspace() # Über alle Blockreferenzen (INSERT) im Modelspace laufen for insert in msp.query('INSERT'): if len(insert.attribs) == 0: continue # Überspringe Blöcke ohne Attribute for attrib in insert.attribs: # Position des Blocks ist attrib.dxf.insert print(f"Attribut Name: {attrib.dxf.tag}, Wert: {attrib.dxf.text}") if attrib.dxf.tag == "REALE_POSITION" and attrib.dxf.text == "x": print(f"-- coord --: {attrib.dxf.insert}") if attrib.dxf.tag == "B" and "MB" in attrib.dxf.text: print(f"-- coord --: {attrib.dxf.insert}") if attrib.dxf.tag == "B" and "BG" in attrib.dxf.text: print(f"-- coord --: {attrib.dxf.insert}") # attrib.layer world_pos = get_world_position_of_attribute(insert, attrib) # # Attribute abrufen (als Liste von ATTRIB-Objekten) # attribs = {attrib.dxf.tag: attrib.dxf.text for attrib in insert.attribs} # # Hier z.B. filtern: Blocke, die ein "NAME"-Attribut haben # if "NAME" in attribs: # print(f"Blockname: {insert.dxf.name}") # print(f"NAME-Attribut: {attribs['NAME']}") # # Zugriff auf weitere Attribute # # z.B. "ID", "TYP" usw. # if "ID" in attribs: # print(f"ID: {attribs['ID']}") # msp = doc.modelspace() # # Über alle Texte laufen # for text in msp.query('TEXT'): # print(f"Inhalt: {text.dxf.text}") # print(f"Layer: {text.dxf.layer}") # print(f"Einfügepunkt: {text.dxf.insert}") # # print("Farbe:", text.dxf.color) # Achtung: 256 = "ByLayer" # # print("Höhe (height):", text.dxf.height) # # print("Rotation (degrees):", text.dxf.rotation) # # print("Breitenfaktor (width factor):", text.dxf.width) # # print("Style (Schriftart):", text.dxf.style) # # print("Handle:", text.dxf.handle) # print("---") def get_output_positions(doc): """hole alle Positionen der Ausgänge """ pass # helper function def print_entity(e): print("LINE on layer: %s\n" % e.dxf.layer) print("points: %s\n" % repr(e.dxf.points())) #print("y point: %s\n" % e.dxf.y) def get_rack_positions(doc): """hole alle Positionen aller Kabelpritschen """ # iterate over all entities in modelspace msp = doc.modelspace() # for e in msp: # if e.dxftype() == "LWPOLYLINE": # print_entity(e) # # entity query for all LINE entities in modelspace # for e in msp.query("LWPOLYLINE"): # print_entity(e) def get_dxf_file(filepath): """hole das dxf file """ try: doc = ezdxf.readfile(filepath) except IOError: print(f"Not a DXF file or a generic I/O error.") sys.exit(1) except ezdxf.DXFStructureError: print(f"Invalid or corrupted DXF file.") sys.exit(2) return doc if __name__ == '__main__': parser = argparse.ArgumentParser(description='fetches the x/y positions from a dxf file', prog='getpositions') parser.add_argument('-f', '--filename', action='store', required=True, default="ST_6300_Steuerungstestlayout1_neueBloecke.dwg", help='which file should be fetched', metavar='myfile.dwg') parser.add_argument('-i', '--input', action='store_true', help='fetch all position of inputs') parser.add_argument('-o', '--output', action='store_true', help='fetch all positions of outputs') parser.add_argument('-r', '--rack', action='store_true', help='fetch all positions of all cable racks') args = parser.parse_args() out_dir = os.environ.get('PROJECT_DATA') work_dir = os.environ.get('PROJECT_WORK') filename = args.filename doc = get_dxf_file(os.path.join(work_dir, filename)) res = dict() if args.input: res = get_input_positions(doc) if args.output: get_output_positions(doc) if args.rack: get_rack_positions(doc) else: parser.print_help()