diff --git a/doc/Python_Scripts.md b/doc/Python_Scripts.md index c011626..cc8b7a3 100644 --- a/doc/Python_Scripts.md +++ b/doc/Python_Scripts.md @@ -337,19 +337,21 @@ overridden. | `--legend` | — | off | Draw a legend of the color groups. | | `--marker-size` | `MM` (float) | `300.0` | Marker radius in mm. | | `--text-height` | `MM` (float) | `220.0` | Text height in mm. | -| `--layer-prefix` | `P` | `TRO_` | Prefix for the layers this tool creates. | -| `--offset` | `DX,DY` | — | Set the CSV↔DXF offset by hand instead of deriving/loading it. | +| `--offset` | `DX,DY` | — | Set the CSV↔DXF offset by hand instead of deriving/loading it. For a drawing built with dxfmakros (CSV exported from the same drawing) this is `0,0`. | | `--re-register` | — | off | Re-derive the coordinate offset even if a verified one is already cached in `%SKEL_CFG%`. | -| `--max-residual` | `MM` (float) | `600.0` | Largest residual error of the coordinate registration that is still accepted; above it the run fails (exit 4). | | `--check` | — | off | Dry run: only analyze and report, write no output file. | | `--emit-lisp` | — | off | Regenerate `cad/tro_types.lsp` (the type list for the `TRO_INSERT`/`TRO_EDIT` dialogs) from `tro_catalog.py` and exit — no `--dxf` needed. Written under `%DXFM_LISP%` if set (next to the `dxfmakros` SSG_LIB modules that provide the dialogs), otherwise under `/cad`. | +Layers always carry the prefix `TRO_`. `cfg/tro_overrides.ini` is never read, +so the markers always match `tro_flow.py` (which reads it only with +`--use-overrides`). + **Output** (in `%SKEL_RESULTS%`, unless `--check`): `_annotated.dxf`, `_registration.json` (the coordinate transform used, with its proof). **Exit codes:** `0` ok · `1` input/CLI error · `4` coordinate registration -could not be proven (or exceeds `--max-residual`) — resolve with `--offset` or -by raising `--max-residual`. +could not be proven (or its residual error exceeds 600 mm) — resolve with +`--offset`. ## 5a. `tro_extract.py` — read the TROs back out of the drawing into JSON @@ -534,13 +536,12 @@ Three kinds of entry, deliberately different in weight: flow node is primary, the rest stay attached so the linking still sees both sides of a transition. Like splits, this renumbers. - **`openpoint`** — a spot reported in a review that is **not** turned into a - TRO. The structure stays untouched; the point is only marked, in the doc - (section 6) and in the annotated drawing on layer `TRO_OPENPOINT` as a red - crossed circle with plain-text label. This keeps "derived" and "asserted" - distinguishable until the spot has been checked in BricsCAD. + TRO. The structure stays untouched; the point is only marked in the doc + (section 6). This keeps "derived" and "asserted" distinguishable until the + spot has been checked in BricsCAD. -Consumers: `tro_flow.py` (type corrections + doc section 6), `tro_annotate.py` -(corrected marker types + open-point markers), `material_flow.py` (writes the +Consumers: `tro_flow.py` (only with `--use-overrides`: type corrections + doc +section 6), `material_flow.py` (writes the `[.manual]` section into `connect.ini`). Unknown TRO IDs and types are not applied silently — they are reported as warnings in the console output and in doc section 6.3, which catches the common trap: **TRO IDs are running diff --git a/lib/tro_annotate.py b/lib/tro_annotate.py index fe62a04..d2eaa1c 100644 --- a/lib/tro_annotate.py +++ b/lib/tro_annotate.py @@ -109,7 +109,6 @@ from tro_flow import ( _station_positionen, analyse_tros, ) -from tro_overrides import Overrides, load_overrides # --------------------------------------------------------------------------- # Konstanten @@ -319,15 +318,13 @@ def build_layers(doc, prefix: str) -> dict[str, str]: doc.layers.add(name, dxfattribs={ "true_color": ezdxf.rgb2int(hex_to_rgb(style.stroke)), }) - # openpoint: im Review gemeldete Stellen, die noch KEIN TRO sind. Kraeftiges - # Rot, damit sie sich von den abgeleiteten Markern klar abheben. # Kantenfarben wie im TRO-Fluss-SVG (tro_flow.render_dot): Uebergabe blau, # Weiche orange, Materialeingang gruen, Materialausgang rot. for key, colour in (("label", "#404040"), ("flow", "#2f5597"), ("weiche", "#cc8800"), ("eingang", STATION_FARBE[BOUNDARY_ENTRY]), ("ausgang", STATION_FARBE[BOUNDARY_EXIT]), - ("legend", "#808080"), ("openpoint", "#e00000")): + ("legend", "#808080")): name = f"{prefix}{key.upper()}" names[key] = name if name not in doc.layers: @@ -530,47 +527,6 @@ def place_markers( return placed, internal -def draw_open_points( - msp, analysis: Analysis, transform: Transform, layers: dict[str, str], - marker: float, text: float, -) -> int: - """Offene Punkte aus cfg/tro_overrides.ini als Fragezeichen-Marker setzen. - - Das sind im Review gemeldete Stellen, die noch kein TRO sind. Sie werden - bewusst NICHT als TRO-Symbol gezeichnet, sondern als durchgestrichener - Kreis mit Klartext daneben - damit in der Zeichnung sofort erkennbar ist, - dass hier eine Entscheidung aussteht und nichts abgeleitet wurde. - """ - drawn = 0 - radius = marker * 1.35 - for point in analysis.overrides.open_points: - x, y = transform.to_dxf(point.x, point.y) - ring = msp.add_circle((x, y), radius, - dxfattribs={"layer": layers["openpoint"]}) - tag(ring, f"OFFEN:{point.name}") - diag = radius * 0.7071 - for (x1, y1), (x2, y2) in (((-diag, -diag), (diag, diag)), - ((-diag, diag), (diag, -diag))): - line = msp.add_line((x + x1, y + y1), (x + x2, y + y2), - dxfattribs={"layer": layers["openpoint"]}) - tag(line, f"OFFEN:{point.name}") - - lines = [f"OFFEN - noch kein TRO: {point.name}"] - if point.expect: - lines.append(f"erwartet: {point.expect}") - if point.belongs_to: - lines.append(f"heute Teil von: {point.belongs_to}") - lines.append(f"Anlage x/y: {point.describe_position()}") - label = msp.add_mtext("\\P".join(lines), dxfattribs={ - "layer": layers["openpoint"], - "char_height": text, - }) - label.set_location((x + radius * 1.3, y + radius)) - tag(label, f"OFFEN:{point.name}") - drawn += 1 - return drawn - - def place_stations( msp, analysis: Analysis, placed: dict[str, tuple[float, float]], layers: dict[str, str], text: float, @@ -826,13 +782,6 @@ def report( if counts.get("first_id"): print(f"Interne IDs ab = {format_internal_id(counts['first_id'])} " f"(ID-Raum von SSG_LIB, siehe IDSCHECK)") - print(f"Offene Punkte = {counts['openpoints']} (Layer TRO_OPENPOINT, " - f"noch kein TRO)") - if analysis.overrides.applied: - print(f"Typkorrekturen = {len(analysis.overrides.applied)} aus " - f"{analysis.overrides.source}") - for entry in analysis.overrides.applied: - print(f" * {entry}") print(f"Entfernte Objekte= {counts['removed']} (aus frueherem Lauf)") print(f"Layer = {counts['layers']}, Bloecke: {counts['blocks']}") print(f"DXF = {out_file if out_file else '- (--check)'}") @@ -887,26 +836,16 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace: metavar="MM", help="Markerradius in mm. Standard: %(default)s") parser.add_argument("--text-height", type=float, default=DEFAULT_TEXT, metavar="MM", help="Texthoehe in mm. Standard: %(default)s") - parser.add_argument("--layer-prefix", default=LAYER_PREFIX, metavar="P", - help="Praefix der erzeugten Layer. Standard: %(default)s") parser.add_argument("--offset", metavar="DX,DY", help="Lagebezug von Hand setzen statt ermitteln.") parser.add_argument("--re-register", action="store_true", help="Lagebezug neu ermitteln, auch wenn in %%SKEL_CFG%% " "einer abgelegt ist.") - parser.add_argument("--max-residual", type=float, default=DEFAULT_MAX_RESIDUAL, - metavar="MM", - help="Groesster zugelassener Restfehler des Lagebezugs. " - "Standard: %(default)s") parser.add_argument("--check", action="store_true", help="Nur pruefen und berichten, keine Datei schreiben.") parser.add_argument("--emit-lisp", action="store_true", help="cad/tro_types.lsp aus dem Typkatalog neu schreiben " "(Auswahlliste des Dialogs TROEDIT) und beenden.") - parser.add_argument("--use-overrides", action="store_true", - help="Manuelle Korrekturen aus cfg/tro_overrides.ini " - "anwenden. Standard ist AUS - wie bei tro_flow, " - "damit Marker und Flussdiagramm zusammenpassen.") return parser.parse_args(argv) @@ -959,9 +898,9 @@ def main(argv: list[str] | None = None) -> int: print(f"FEHLER: {csv_file} nicht lesbar: {exc}", file=sys.stderr) return 1 graph = build_graph(elements, csv_file.name, read_warnings) - overrides = (load_overrides(csv_file.name, cfg_dir) if args.use_overrides - else Overrides()) - analysis = analyse_tros(graph, elements, overrides) + # Ohne cfg/tro_overrides.ini - wie tro_flow, damit Marker und + # Flussdiagramm zusammenpassen. + analysis = analyse_tros(graph, elements) if not analysis.tros: print(f"FEHLER: keine TROs aus {csv_file} ableitbar.", file=sys.stderr) return 1 @@ -981,16 +920,15 @@ def main(argv: list[str] | None = None) -> int: except RegistrationError as exc: print(f"FEHLER: Lagebezug nicht bestimmbar: {exc}", file=sys.stderr) return 4 - if transform.residual_max > args.max_residual: + if transform.residual_max > DEFAULT_MAX_RESIDUAL: print(f"FEHLER: Restfehler des Lagebezugs {transform.residual_max:.1f} mm " - f"ueber der Grenze von {args.max_residual:.1f} mm.", file=sys.stderr) + f"ueber der Grenze von {DEFAULT_MAX_RESIDUAL:.1f} mm.", file=sys.stderr) print(f" {transform.describe()}", file=sys.stderr) - print(" Mit --offset von Hand setzen oder --max-residual anheben.", - file=sys.stderr) + print(" Mit --offset von Hand setzen.", file=sys.stderr) return 4 counts = {"marker": 0, "flow": 0, "removed": 0, "layers": 0, "blocks": 0, - "openpoints": 0, "first_id": 0} + "first_id": 0} if args.check: counts["marker"] = sum(1 for t in analysis.tros if t.position) @@ -999,7 +937,7 @@ def main(argv: list[str] | None = None) -> int: ensure_appid(doc) counts["removed"] = remove_previous(msp) - layers = build_layers(doc, args.layer_prefix) + layers = build_layers(doc, LAYER_PREFIX) counts["layers"] = len({v for v in layers.values()}) # Interne IDs erst NACH remove_previous suchen: die Marker des letzten Laufs @@ -1013,8 +951,6 @@ def main(argv: list[str] | None = None) -> int: counts["blocks"] = sum(1 for b in doc.blocks if b.name.startswith(BLOCK_PREFIX)) counts["first_id"] = next_id - counts["openpoints"] = draw_open_points(msp, analysis, transform, layers, - args.marker_size, args.text_height) if args.flow: # Stationen nur mit --flow: sie bestehen aus ihrem Zu-/Ablaufpfeil