component
XL-1606UYC
Public Made by Adomby adom
XINGLIGHT LED Indication - Discrete, SMD,1.7x1.1mm. KiCad symbol, footprint and 3D as used on Adom boards.
main
#!/usr/bin/env python3
"""ortho.py <step> <view> <px_per_mm> <out.png> : orthographic hidden-line view of a STEP at an exact scale.
view: top (looking down -Z, +X right, +Y up) | bottom (looking up +Z, mirrored: +X left... drawn as seen from below,
+X right, -Y up i.e. flipped about X) | front (looking +Y from -Y: +X right, +Z up) | back | right (from +X: +Y right, +Z up) | left (from -X: -Y right).
Writes out.png and out.json {px_per_mm, origin_px: pixel of (0,0) in the view plane, extents}."""
import json, re, sys
import cadquery as cq, cairosvg
step, view, ppm, out = sys.argv[1], sys.argv[2], float(sys.argv[3]), sys.argv[4]
s = cq.importers.importStep(step)
shape = cq.Compound.makeCompound(s.vals())
# rotate the shape so that the requested view becomes a top view (camera on +Z looking down, +X right, +Y up)
R = {'top': [], 'bottom': [((1, 0, 0), 180)], 'front': [((1, 0, 0), -90)], 'back': [((1, 0, 0), -90), ((0, 0, 1), 180)],
'right': [((0, 1, 0), -90), ((0, 0, 1), -90)], 'left': [((0, 1, 0), 90), ((0, 0, 1), 90)]}[view]
for ax, ang in R:
shape = shape.rotate(cq.Vector(0, 0, 0), cq.Vector(*ax), ang)
bb = shape.BoundingBox()
pad = 2.0
W, H = int((bb.xlen + 2 * pad) * ppm), int((bb.ylen + 2 * pad) * ppm)
# draw edges of a top view ourselves (cadquery's SVG autoscale is not exact); hidden-line removal via OCP HLR
from OCP.HLRBRep import HLRBRep_Algo, HLRBRep_HLRToShape
from OCP.HLRAlgo import HLRAlgo_Projector
from OCP.gp import gp_Ax2, gp_Pnt, gp_Dir
algo = HLRBRep_Algo(); algo.Add(shape.wrapped)
algo.Projector(HLRAlgo_Projector(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1), gp_Dir(1, 0, 0))))
algo.Update(); algo.Hide()
hl = HLRBRep_HLRToShape(algo)
paths = []
for comp in (hl.VCompound(), hl.OutLineVCompound(), hl.Rg1LineVCompound(), hl.RgNLineVCompound()):
if comp is None or comp.IsNull(): continue
for e in cq.Shape.cast(comp).Edges():
pts = [e.positionAt(t / 40) for t in range(41)]
d = 'M ' + ' L '.join(f'{(p.x - bb.xmin + pad) * ppm:.2f},{(bb.ymax + pad - p.y) * ppm:.2f}' for p in pts)
paths.append(f'<path d="{d}" fill="none" stroke="#d00000" stroke-width="1.5"/>')
svg = f'<svg xmlns="http://www.w3.org/2000/svg" width="{W}" height="{H}">' + ''.join(paths) + '</svg>'
cairosvg.svg2png(bytestring=svg.encode(), write_to=out)
json.dump({'view': view, 'px_per_mm': ppm, 'origin_px': [(-bb.xmin + pad) * ppm, (bb.ymax + pad) * ppm],
'extents_mm': [round(bb.xlen, 3), round(bb.ylen, 3)], 'x_mm': [bb.xmin, bb.xmax], 'y_mm': [bb.ymin, bb.ymax]},
open(out.rsplit('.', 1)[0] + '.json', 'w'), indent=1)
print(out, W, H)