tro_annotate: Lagebezug ueber die TeileId, Ablaufbeschreibung CSV/DXF -> SCL
dxf_registration.derive_from_ids: Zeichnungen aus dxfmakros tragen an jedem Layout-Block das Attribut ID = TeileId des CSV. tro_annotate paart CSV- Separatoren mit den Separator-Bloecken gleicher ID (sonst Scanner) und nimmt den Median-Versatz - eindeutig statt Abstimmung, bei jedem Lauf neu, gilt auch fuer eine verschobene Kopie der Zeichnung. Vorrang vor abgelegtem und abgestimmtem Bezug; --offset bleibt. Parameter id_spread_mm, id_min_share in cfg/parameter.ini [dxf_registration]. Dematic: gemeinsame Zeichnung 0/0, Mechanik-Zeichnung dematic.dxf +466,1/-163549,3 mm. Die Abstimmung rastete vorher auf den Scanner-Bloecken ein (Einfuegepunkt 360 mm neben der CSV-Position) und lag 360 mm daneben. Gesperrte Ausgabedatei (in BricsCAD geoeffnet) gibt eine Meldung statt Traceback. Neu: doc/Workflow_CSV_DXF_to_SCL.md - der ganze Ablauf vom CSV-Export und der Zeichnung bis zur SCL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+58
-2
@@ -101,6 +101,7 @@ from dxf_registration import (
|
||||
ANCHOR_BLOCKS,
|
||||
RegistrationError,
|
||||
Transform,
|
||||
derive_from_ids,
|
||||
derive_transform,
|
||||
load_transform,
|
||||
save_transform,
|
||||
@@ -229,14 +230,63 @@ def anchor_points_dxf(msp) -> dict[str, list[tuple[float, float]]]:
|
||||
return dict(points)
|
||||
|
||||
|
||||
def _role_of(block_name: str) -> str:
|
||||
"""Rolle eines Blocks nach ANCHOR_BLOCKS ("" wenn keine)."""
|
||||
name = block_name.upper()
|
||||
for role, patterns in ANCHOR_BLOCKS.items():
|
||||
if any(fnmatch.fnmatchcase(name, p.upper()) for p in patterns):
|
||||
return role
|
||||
return ""
|
||||
|
||||
|
||||
def id_points_csv(elements) -> dict[str, tuple[str, float, float]]:
|
||||
"""TeileId -> (Rolle, x, y) der punktartigen CSV-Objekte."""
|
||||
return {e.teile_id: (e.kind, e.x, e.y) for e in elements
|
||||
if e.kind in ANCHOR_BLOCKS and e.position and e.teile_id}
|
||||
|
||||
|
||||
def id_points_dxf(msp) -> dict[str, tuple[str, float, float]]:
|
||||
"""ID-Attribut -> (Rolle, x, y) der Anker-Bloecke im Modellbereich.
|
||||
|
||||
Nur Bloecke einer Rolle aus ANCHOR_BLOCKS mit einer Ziffern-ID; eine ID,
|
||||
die zweimal vorkommt, ist nicht eindeutig und faellt weg.
|
||||
"""
|
||||
found: dict[str, tuple[str, float, float]] = {}
|
||||
doppelt: set[str] = set()
|
||||
for ref in msp.query("INSERT"):
|
||||
role = _role_of(ref.dxf.name)
|
||||
if not role:
|
||||
continue
|
||||
uid = next(((a.dxf.text or "").strip() for a in ref.attribs
|
||||
if a.dxf.tag.upper() == "ID"), "")
|
||||
if not uid.isdigit():
|
||||
continue
|
||||
if uid in found:
|
||||
doppelt.add(uid)
|
||||
found[uid] = (role, ref.dxf.insert.x, ref.dxf.insert.y)
|
||||
return {k: v for k, v in found.items() if k not in doppelt}
|
||||
|
||||
|
||||
def resolve_transform(
|
||||
args, elements, msp, cfg_dir: Path, csv_name: str, dxf_name: str,
|
||||
warnings: list[str],
|
||||
) -> Transform:
|
||||
"""Lagebezug bestimmen: Kommandozeile, Konfiguration oder Ermittlung."""
|
||||
"""Lagebezug bestimmen: Kommandozeile, TeileId, Konfiguration oder Ermittlung.
|
||||
|
||||
Die TeileId (derive_from_ids) geht vor dem abgelegten und dem ermittelten
|
||||
Bezug: sie ordnet eindeutig zu und gilt auch fuer eine verschobene Kopie
|
||||
der Zeichnung. Sie wird jedes Mal neu gerechnet, nicht abgelegt.
|
||||
"""
|
||||
csv_points = anchor_points_csv(elements)
|
||||
dxf_points = anchor_points_dxf(msp)
|
||||
|
||||
if not args.offset:
|
||||
by_ids = derive_from_ids(id_points_csv(elements), id_points_dxf(msp),
|
||||
csv_name, dxf_name)
|
||||
if by_ids is not None:
|
||||
verify_transform(by_ids, csv_points, dxf_points)
|
||||
return by_ids
|
||||
|
||||
if args.offset:
|
||||
try:
|
||||
dx, dy = (float(v) for v in args.offset.split(","))
|
||||
@@ -1241,7 +1291,13 @@ def main(argv: list[str] | None = None) -> int:
|
||||
args.text_height, csv_file.name)
|
||||
|
||||
out_file = results / (args.out or f"{csv_file.stem}_annotated.dxf")
|
||||
doc.saveas(str(out_file))
|
||||
try:
|
||||
doc.saveas(str(out_file))
|
||||
except PermissionError:
|
||||
print(f"FEHLER: {out_file} laesst sich nicht schreiben - ist die Zeichnung noch "
|
||||
f"in BricsCAD geoeffnet? Schliessen und neu starten, oder --out <name>.",
|
||||
file=sys.stderr)
|
||||
return 1
|
||||
|
||||
reg_file = results / f"{csv_file.stem}_registration.json"
|
||||
reg_file.write_text(
|
||||
|
||||
Reference in New Issue
Block a user