← Commit history

Delete design/gen/stepbox.py

John Lauer ·a286276cb3 ·7d ago ·parent 6eb3d95
1 file changed −156
design/gen/stepbox.pydeleted−156
@@ -1,156 +0,0 @@-#!/usr/bin/env python3-"""Write an AP214 STEP file made of coloured axis-aligned boxes (plain Python, no CAD kernel).--Used for the AI-generated simplified OCuLink receptacle model (Amphenol G14A42111C12HR): dimensions from Amphenol-drawing G14A421X1BXXXHR rev D. Model frame = KiCad footprint frame turned into KiCad's 3D frame:-x right, y = -(pcb y), z up from the board top."""-import datetime---class Step:-    def __init__(self, name):-        self.name = name-        self.lines = []-        self.n = 0-        self.solids = []      # (brep_id, rgb)--    def add(self, s):-        self.n += 1-        self.lines.append(f"#{self.n}={s};")-        return self.n--    def pt(self, x, y, z):-        return self.add(f"CARTESIAN_POINT('',({x:.4f},{y:.4f},{z:.4f}))")--    def dirn(self, x, y, z):-        return self.add(f"DIRECTION('',({x:.1f},{y:.1f},{z:.1f}))")--    def box(self, x0, y0, z0, x1, y1, z1, rgb):-        P = {}-        for i, x in enumerate((x0, x1)):-            for j, y in enumerate((y0, y1)):-                for k, z in enumerate((z0, z1)):-                    P[(i, j, k)] = self.add(f"VERTEX_POINT('',#{self.pt(x, y, z)})")-        coords = {(i, j, k): ((x0, x1)[i], (y0, y1)[j], (z0, z1)[k]) for i in (0, 1) for j in (0, 1) for k in (0, 1)}-        edges = {}--        def edge(a, b):-            key = tuple(sorted((a, b)))-            if key in edges:-                return edges[key], key[0] == a-            pa, pb = coords[key[0]], coords[key[1]]-            d = tuple(pb[t] - pa[t] for t in range(3))-            L = max(abs(c) for c in d)-            dv = self.dirn(*(c / L for c in d))-            vec = self.add(f"VECTOR('',#{dv},{L:.4f})")-            ln = self.add(f"LINE('',#{self.pt(*pa)},#{vec})")-            e = self.add(f"EDGE_CURVE('',#{P[key[0]]},#{P[key[1]]},#{ln},.T.)")-            edges[key] = e-            return e, key[0] == a--        faces = []-        # each face: 4 corners in counter-clockwise order seen from outside, outward normal-        F = [-            ([(0, 0, 0), (0, 1, 0), (1, 1, 0), (1, 0, 0)], (0, 0, -1), (x0, y0, z0)),-            ([(0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1)], (0, 0, 1), (x0, y0, z1)),-            ([(0, 0, 0), (1, 0, 0), (1, 0, 1), (0, 0, 1)], (0, -1, 0), (x0, y0, z0)),-            ([(0, 1, 0), (0, 1, 1), (1, 1, 1), (1, 1, 0)], (0, 1, 0), (x0, y1, z0)),-            ([(0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 0)], (-1, 0, 0), (x0, y0, z0)),-            ([(1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 0, 1)], (1, 0, 0), (x1, y0, z0)),-        ]-        for corners, nrm, org in F:-            oes = []-            for a, b in zip(corners, corners[1:] + corners[:1]):-                e, same = edge(a, b)-                oes.append(self.add(f"ORIENTED_EDGE('',*,*,#{e},{'.T.' if same else '.F.'})"))-            loop = self.add(f"EDGE_LOOP('',({','.join('#%d' % o for o in oes)}))")-            bound = self.add(f"FACE_OUTER_BOUND('',#{loop},.T.)")-            ref = (1, 0, 0) if abs(nrm[0]) < 0.5 else (0, 1, 0)-            ax = self.add(f"AXIS2_PLACEMENT_3D('',#{self.pt(*org)},#{self.dirn(*nrm)},#{self.dirn(*ref)})")-            pl = self.add(f"PLANE('',#{ax})")-            faces.append(self.add(f"ADVANCED_FACE('',(#{bound}),#{pl},.T.)"))-        shell = self.add(f"CLOSED_SHELL('',({','.join('#%d' % f for f in faces)}))")-        brep = self.add(f"MANIFOLD_SOLID_BREP('{self.name}_{len(self.solids)}',#{shell})")-        self.solids.append((brep, rgb))-        return brep--    def write(self, path, description):-        head = self.lines-        self.lines = []-        n0 = self.n-        ctx_ids = []-        # units and context-        lu = self.add("(LENGTH_UNIT()NAMED_UNIT(*)SI_UNIT(.MILLI.,.METRE.))")-        au = self.add("(NAMED_UNIT(*)PLANE_ANGLE_UNIT()SI_UNIT($,.RADIAN.))")-        su = self.add("(NAMED_UNIT(*)SI_UNIT($,.STERADIAN.)SOLID_ANGLE_UNIT())")-        unc = self.add(f"UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#{lu},'distance_accuracy_value','confusion accuracy')")-        ctx = self.add(f"(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#{unc}))GLOBAL_UNIT_ASSIGNED_CONTEXT((#{lu},#{au},#{su}))REPRESENTATION_CONTEXT('Context #1','3D Context with UNIT and UNCERTAINTY'))")-        org = self.add(f"AXIS2_PLACEMENT_3D('',#{self.pt(0, 0, 0)},#{self.dirn(0, 0, 1)},#{self.dirn(1, 0, 0)})")-        appctx = self.add("APPLICATION_CONTEXT('core data for automotive mechanical design processes')")-        self.add(f"APPLICATION_PROTOCOL_DEFINITION('international standard','automotive_design',2000,#{appctx})")-        pctx = self.add(f"PRODUCT_CONTEXT('',#{appctx},'mechanical')")-        prod = self.add(f"PRODUCT('{self.name}','{self.name}','',(#{pctx}))")-        pdfw = self.add(f"PRODUCT_DEFINITION_FORMATION('','',#{prod})")-        pdctx = self.add(f"PRODUCT_DEFINITION_CONTEXT('part definition',#{appctx},'design')")-        pd = self.add(f"PRODUCT_DEFINITION('design','',#{pdfw},#{pdctx})")-        pds = self.add(f"PRODUCT_DEFINITION_SHAPE('','',#{pd})")-        brep_list = ",".join("#%d" % b for b, _ in self.solids)-        rep = self.add(f"ADVANCED_BREP_SHAPE_REPRESENTATION('{self.name}',(#{org},{brep_list}),#{ctx})")-        self.add(f"SHAPE_DEFINITION_REPRESENTATION(#{pds},#{rep})")-        # colours-        styled = []-        for b, (r, g, bl) in self.solids:-            col = self.add(f"COLOUR_RGB('',{r:.3f},{g:.3f},{bl:.3f})")-            fas = self.add(f"FILL_AREA_STYLE_COLOUR('',#{col})")-            fa = self.add(f"FILL_AREA_STYLE('',(#{fas}))")-            ssfa = self.add(f"SURFACE_STYLE_FILL_AREA(#{fa})")-            sss = self.add(f"SURFACE_SIDE_STYLE('',(#{ssfa}))")-            ssu = self.add(f"SURFACE_STYLE_USAGE(.BOTH.,#{sss})")-            psa = self.add(f"PRESENTATION_STYLE_ASSIGNMENT((#{ssu}))")-            styled.append(self.add(f"STYLED_ITEM('color',(#{psa}),#{b})"))-        self.add(f"MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',({','.join('#%d' % s for s in styled)}),#{ctx})")-        body = head + self.lines-        now = datetime.datetime(2026, 10, 12, 22, 0, 0).strftime("%Y-%m-%dT%H:%M:%S")-        with open(path, "w") as fh:-            fh.write("ISO-10303-21;\nHEADER;\n")-            fh.write(f"FILE_DESCRIPTION(('{description}'),'2;1');\n")-            fh.write(f"FILE_NAME('{self.name}.step','{now}',('Adom AI (Claude), generated'),('Adom'),'stepbox.py','stepbox.py','');\n")-            fh.write("FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));\nENDSEC;\nDATA;\n")-            fh.write("\n".join(body))-            fh.write("\nENDSEC;\nEND-ISO-10303-21;\n")---def oculink_model(path):-    """Simplified G14A42111C12HR: dimensions from Amphenol drawing G14A421X1BXXXHR rev D."""-    s = Step("Amphenol_G14A42111C12HR")-    BLACK, NICKEL, GOLD = (0.08, 0.08, 0.09), (0.72, 0.72, 0.70), (0.86, 0.69, 0.25)-    W2 = 13.15 / 2-    # KiCad 3D frame: y3d = -y_pcb. Body from pcb y -1.98 (mating face) to 7.02 -> y3d +1.98 .. -7.02; height 3.90-    s.box(-W2 + 0.25, -7.02, 0.0, W2 - 0.25, 1.70, 3.65, BLACK)            # insulator housing-    s.box(-W2, -6.90, 3.65, W2, 1.98, 3.90, NICKEL)                         # shell top-    s.box(-W2, -6.90, 0.25, -W2 + 0.25, 1.98, 3.65, NICKEL)                 # shell sides-    s.box(W2 - 0.25, -6.90, 0.25, W2, 1.98, 3.65, NICKEL)-    s.box(-W2, 1.73, 0.25, W2, 1.98, 0.75, NICKEL)                          # shell front lip (bottom)-    # shell legs (option C, 2.90 long) at x +/-6.58, pcb y 7.05 and 2.26: 0.5 x 1.1 blades through the board-    for sx in (-6.58, 6.58):-        for py in (7.05, 2.26):-            s.box(sx - 0.25, -py - 0.55, -2.90 + 0.25, sx + 0.25, -py + 0.55, 0.25, NICKEL)-    # SMT contact tails: B row at pcb y 7.37, A row at 5.18 (0.2 x 0.7 x 0.15), pitch 0.5-    for n in range(21):-        xb = 5.25 - 0.5 * n-        xa = 4.75 - 0.5 * n-        s.box(xb - 0.1, -7.37 - 0.35, 0.0, xb + 0.1, -7.37 + 0.35, 0.15, GOLD)-        s.box(xa - 0.1, -5.18 - 0.35, 0.0, xa + 0.1, -5.18 + 0.35, 0.15, GOLD)-    # plastic pegs dia 1.00 (as 0.8 squares) at pcb (+5.41, 4.46) and (-5.94, 4.46)-    for (px, py) in ((5.41, 4.46), (-5.94, 4.46)):-        s.box(px - 0.4, -py - 0.4, -1.2, px + 0.4, -py + 0.4, 0.0, BLACK)-    s.write(path, "AI-generated simplified model of Amphenol G14A42111C12HR OCuLink 4X R/A receptacle; dimensions from Amphenol drawing G14A421X1BXXXHR rev D; not a manufacturer model")-    return path---if __name__ == "__main__":-    import os, sys-    out = os.path.join(os.path.dirname(__file__), "..", "kicad", "3d", "Amphenol_G14A42111C12HR.step")-    os.makedirs(os.path.dirname(out), exist_ok=True)-    oculink_model(out)-    print("wrote", out, os.path.getsize(out), "bytes")