Files
autocad-mcp-pro/engineering/mech/__init__.py
T
Umut CANandClaude Opus 5 04d269318a feat(task-2): the mechanical part model - RevolvedPart, PrismaticPart, build_part
engineering/mech/part.py is the model the whole track draws from: a revolved
stack of segments along +X, or a closed prismatic outline plus a thickness, each
carrying a list of typed features. Pure arithmetic - no backend, no async, no
DXF - which is what lets the view engine be tested without a drawing.

Every refusal fires before anything is drawn and names the offending path the
way pid_from_spec does: a non-finite or non-positive number as
segments[2].d_outer, a bore that is not smaller than its outside (a bore that
changes diameter is two segments), an outline with fewer than three distinct
vertices, an outline that crosses itself (engineering.measure.is_self_intersecting
- the shoelace cancels crossed lobes rather than failing, so a bowtie would
otherwise measure 0.0), an unknown material, an unknown segment key, a duplicate
feature id.

Two gates are the reason this is a model rather than a dict: a feature whose
placement is off the part is refused by its own name and by the range it missed,
and two features that would remove the same material are refused with both names
and the overlapping box. Neither is clamped.

part_to_dict round-trips through build_part, which is what lets mech_part_draw
write the model onto the drawing as ACADMCP_MECH XDATA and mech_view_add read it
back months later without the caller re-describing the part.

Two fixes to the plan's own code and test list, both recorded in deviations:
_features_from imported engineering.mech.features unconditionally, so a
featureless part - every fixture in this module, and both round-trips - died on
ModuleNotFoundError until Task 3 lands; the import now happens only when there
is a feature dict to build. And the plan's test file omitted
test_a_duplicate_feature_id_is_refused while its own gate deselects it by name,
so the duplicate-id refusal the commit message claims went unpinned; the test is
written here and Task 3 turns it green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
2026-09-22 18:52:39 +03:00

80 lines
1.3 KiB
Python

"""The mechanical part model, view engine and standards tables.
Merge rule for the four track-B/G branches: the re-exports below are additive
and alphabetical — keep every side's names.
"""
from __future__ import annotations
from .part import (
PART_KINDS,
PrismaticPart,
RevolvedPart,
Segment,
build_part,
inner_radius_at,
outer_radius_at,
outline_bbox,
part_length,
part_max_diameter,
part_to_dict,
point_in_outline,
segment_bounds,
validate_part,
)
from .primitives import (
ROLE_LAYER,
ROLES,
Arc,
Circle,
DimIntent,
HatchArea,
Line,
Poly,
Prim,
Pt,
Role,
Text,
bbox,
layer_for,
points_of,
rotate,
scale,
translate,
)
__all__ = [
"PART_KINDS",
"ROLES",
"ROLE_LAYER",
"Arc",
"Circle",
"DimIntent",
"HatchArea",
"Line",
"Poly",
"Prim",
"PrismaticPart",
"Pt",
"RevolvedPart",
"Role",
"Segment",
"Text",
"bbox",
"build_part",
"inner_radius_at",
"layer_for",
"outer_radius_at",
"outline_bbox",
"part_length",
"part_max_diameter",
"part_to_dict",
"point_in_outline",
"points_of",
"rotate",
"scale",
"segment_bounds",
"translate",
"validate_part",
]