Files
kabellaengen/lib/getpositions.py
T

177 lines
5.8 KiB
Python

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()