lib/utils.py in lib/omniflo_utils.py umbenannt. elemente/kreisel.py verwendet jetzt auch die elemente/utils.py routinen

This commit is contained in:
2026-06-01 10:27:38 +02:00
parent 4bafc4443f
commit 732daedadd
4 changed files with 19 additions and 143 deletions
+17 -141
View File
@@ -6,7 +6,6 @@
# KreiselLabelSetup, KreiselLabelPos, KreiselLabelHoehe
# ============================================
import os
import math
import PyRx as Rx
@@ -15,6 +14,18 @@ import PyDb as Db
import PyEd as Ed
import wx
from elemente.utils import (
get_block_path,
component_next_number,
merge_attribs,
read_block_attribs,
ensure_layer,
ensure_textstyle,
ensure_block_from_dwg,
create_attrib_defs,
insert_block_with_attribs,
)
# ============================================================
# Konstanten (aus KreiselInsert.lsp)
# ============================================================
@@ -46,7 +57,6 @@ KREISEL_AUSRICHTUNGEN = [
]
# Globaler Zustand (pro Sitzung)
_kreisel_letzte_nr = 0
_kreisel_typ = "STANDARD"
# Beschriftungs-Einstellungen
@@ -59,68 +69,9 @@ _beschriftung_abstand_y = 0.0
# ============================================================
# Hilfsfunktionen
# Kreisel-spezifische Hilfsfunktionen
# ============================================================
def get_block_path():
"""Block-Pfad aus Umgebungsvariable DXFM_BLOCKS lesen."""
bp = os.environ.get("DXFM_BLOCKS", "")
if not bp:
bp = "C:/Users/y.wang/Documents/dxfmakros/Blocks/"
print(f"\nUmgebungsvariable DXFM_BLOCKS nicht gefunden. Nutze Standardpfad: {bp}")
bp = bp.replace("\\", "/").rstrip("/") + "/"
return bp
def kreisel_next_number(db):
"""Naechste freie Kreisel-Nummer ermitteln."""
global _kreisel_letzte_nr
max_nr = 0
model = Db.BlockTableRecord(db.modelSpaceId(), Db.OpenMode.kForRead)
for obj_id in model:
ent = Db.Entity(obj_id, Db.OpenMode.kForRead)
if not ent.isKindOf(Db.BlockReference.desc()):
continue
bref = Db.BlockReference(obj_id, Db.OpenMode.kForRead)
btr = Db.BlockTableRecord(bref.blockTableRecord(), Db.OpenMode.kForRead)
bname = btr.getName()
if not bname.upper().startswith("KREISEL_"):
continue
for att_id in bref.attributeIds():
att = Db.AttributeReference(att_id, Db.OpenMode.kForRead)
if att.tag().upper() == "NUMMER":
try:
val = int(att.textString())
if val > max_nr:
max_nr = val
except ValueError:
pass
if max_nr == 0:
max_nr = _kreisel_letzte_nr
_kreisel_letzte_nr = max_nr + 1
return _kreisel_letzte_nr
def merge_attribs(overrides, attrib_defs):
"""Attribut-Defaults mit Ueberschreibungen zusammenfuehren."""
result = {tag: default for tag, default in attrib_defs}
if overrides:
result.update(overrides)
return result
def read_block_attribs(bref):
"""Alle Attribute einer BlockReference als dict lesen."""
attribs = {}
for att_id in bref.attributeIds():
att = Db.AttributeReference(att_id, Db.OpenMode.kForRead)
attribs[att.tag()] = att.textString()
return attribs
def rotation_to_idx(rot):
"""Rotation (Grad) -> Index in KREISEL_AUSRICHTUNGEN."""
best_idx = 0
@@ -136,49 +87,6 @@ def idx_to_rotation(idx):
return KREISEL_AUSRICHTUNGEN[idx][1]
def ensure_textstyle(db, style_name="Kreisel_Arial", font="Arial"):
"""Textstil 'Kreisel_Arial' anlegen falls nicht vorhanden."""
tst = Db.TextStyleTable(db.textStyleTableId(), Db.OpenMode.kForRead)
if not tst.has(style_name):
tst.upgradeOpen()
ts = Db.TextStyleTableRecord()
ts.setName(style_name)
ts.setFont(font, False, False, 0, 0)
tst.add(ts)
return style_name
def ensure_layer(db, layer_name, color_index, set_active=False):
"""Layer anlegen falls nicht vorhanden, optional aktiv setzen."""
lt = Db.LayerTable(db.layerTableId(), Db.OpenMode.kForRead)
if not lt.has(layer_name):
lt.upgradeOpen()
lr = Db.LayerTableRecord()
lr.setName(layer_name)
c = Db.Color()
c.setColorIndex(int(color_index))
lr.setColor(c)
lt.add(lr)
if set_active:
layer_id = lt.getAt(layer_name)
db.setClayer(layer_id)
def ensure_block_from_dwg(db, dwg_name, block_path):
"""Externen DWG-Block in die Datenbank laden falls nicht vorhanden."""
bt = Db.BlockTable(db.blockTableId(), Db.OpenMode.kForRead)
base_name = os.path.splitext(dwg_name)[0]
if not bt.has(base_name):
dwg_path = block_path + dwg_name
if not os.path.isfile(dwg_path):
print(f"\nFehler: {dwg_name} nicht gefunden unter: {dwg_path}")
return False
aux_db = Db.Database(False, True)
aux_db.readDwg(dwg_path)
db.insert(aux_db, base_name)
return True
# ============================================================
# Kern-Funktion: draw_module (entspricht draw-module in LISP)
# ============================================================
@@ -222,7 +130,7 @@ def draw_module(db, base_point, abstand, rotation_deg, attribs=None):
except ValueError:
kreisel_nummer = 0
if kreisel_nummer <= 0:
kreisel_nummer = kreisel_next_number(db)
kreisel_nummer = component_next_number(db, "KREISEL_")
merged["NUMMER"] = str(kreisel_nummer)
merged["NAME"] = f"Kreisel{kreisel_nummer}"
@@ -326,49 +234,18 @@ def draw_module(db, base_point, abstand, rotation_deg, attribs=None):
new_btr.appendAcDbEntity(txt)
# Unsichtbare Attribut-Definitionen
y_pos = 0.0
text_height = 50.0
for tag, default in KREISEL_ATTRIB_DEFS:
attdef = Db.AttributeDefinition()
attdef.setPosition(Ge.Point3d(0, y_pos, 0))
attdef.setHeight(text_height)
attdef.setTextString(default)
attdef.setPrompt(tag)
attdef.setTag(tag)
attdef.setInvisible(True)
new_btr.appendAcDbEntity(attdef)
y_pos -= text_height * 2.0
create_attrib_defs(new_btr, KREISEL_ATTRIB_DEFS)
print(f"\n-> Neue Blockdefinition: {bname}")
else:
print(f"\n-> Verwende bestehende Blockdefinition: {bname}")
# Block am Zielpunkt einfuegen
block_id = bt.getAt(bname)
model = Db.BlockTableRecord(db.modelSpaceId(), Db.OpenMode.kForWrite)
pt = Ge.Point3d(base_point.x, base_point.y, z_hoehe)
bref = Db.BlockReference(pt, block_id)
bref.setRotation(math.radians(rotation_deg))
model.appendAcDbEntity(bref)
# Attribute erzeugen und Werte setzen
btr = Db.BlockTableRecord(block_id, Db.OpenMode.kForRead)
for ent_id in btr:
ent = Db.Entity(ent_id, Db.OpenMode.kForRead)
if ent.isKindOf(Db.AttributeDefinition.desc()):
attdef = Db.AttributeDefinition(ent_id, Db.OpenMode.kForRead)
attref = Db.AttributeReference()
attref.setPropertiesFrom(attdef)
attref.setTag(attdef.tag())
attref.setInvisible(attdef.isInvisible())
attref.setPosition(attdef.position())
attref.setHeight(attdef.height())
val = merged.get(attdef.tag(), attdef.textString())
attref.setTextString(val)
bref.appendAttribute(attref)
obj_id = insert_block_with_attribs(db, bname, pt, rotation_deg, merged)
print(f"\n-> Kreisel #{kreisel_nummer} eingefuegt: {bname} (Hoehe={z_hoehe:.0f})")
return bref.objectId()
return obj_id
# ============================================================
@@ -378,7 +255,6 @@ def draw_module(db, base_point, abstand, rotation_deg, attribs=None):
@Rx.command("KreiselInsert")
def cmd_kreisel_insert():
"""KreiselInsert: Manuell Position + Parameter."""
global _kreisel_typ
ed = Ed.Editor()
db = Db.HostApplicationServices().workingDatabase()
+1 -1
View File
@@ -31,7 +31,7 @@ import sys
import ezdxf
from utils import (
from omniflo_utils import (
ROW_GROUPS, TEXT_HEIGHT, TEXT_MARGIN, CROSS_SIZE, ROW_LABEL_WIDTH,
SWITCH_FILTERS,
build_row_layout, import_element_as_block, draw_cross,
+1 -1
View File
@@ -53,7 +53,7 @@ import sys
import ezdxf
from ezdxf.math import Matrix44
from utils import (
from omniflo_utils import (
ROW_GROUPS, TEXT_HEIGHT, TEXT_MARGIN, CROSS_SIZE, ROW_LABEL_WIDTH,
SWITCH_FILTERS,
load_omniflo_data, build_row_layout, import_element_as_block,