by adom
0603 SMD Green LED · 3.2 V drop · 25 mA max
master
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
#!/usr/bin/env python3
"""Seat a flat laser_etch mark on the surface directly beneath it (Z-up STEP): the etch service puts the
mark at the part's bbox top, which floats above a body that is lower than its terminations (MLCC).
Casts vertical rays through the mark footprint, takes the highest surface hit (excluding the mark) and
moves the mark to that height + lift. Colours and names kept (XCAF).
Usage: seat_mark.py in.step out.step [lift_mm=0.005]"""
import sys
from OCP.STEPCAFControl import STEPCAFControl_Reader, STEPCAFControl_Writer
from OCP.STEPControl import STEPControl_AsIs
from OCP.TDocStd import TDocStd_Document
from OCP.TCollection import TCollection_ExtendedString
from OCP.XCAFDoc import XCAFDoc_DocumentTool
from OCP.TDF import TDF_ChildIterator, TDF_Label
from OCP.TopLoc import TopLoc_Location
from OCP.TDataStd import TDataStd_Name
from OCP.Bnd import Bnd_Box
from OCP.BRepBndLib import BRepBndLib
from OCP.IntCurvesFace import IntCurvesFace_ShapeIntersector
from OCP.gp import gp_Lin, gp_Pnt, gp_Dir, gp_Trsf, gp_Vec
from OCP.BRepBuilderAPI import BRepBuilderAPI_Transform
from OCP.TopoDS import TopoDS_Compound
from OCP.BRep import BRep_Builder
src, out = sys.argv[1:3]; lift = float(sys.argv[3]) if len(sys.argv) > 3 else 0.005
doc = TDocStd_Document(TCollection_ExtendedString("d"))
r = STEPCAFControl_Reader(); r.SetColorMode(True); r.SetNameMode(True); r.SetLayerMode(True); r.ReadFile(src); r.Transfer(doc)
st = XCAFDoc_DocumentTool.ShapeTool_s(doc.Main())
def name(l):
nm = TDataStd_Name(); return nm.Get().ToExtString() if l.FindAttribute(TDataStd_Name.GetID_s(), nm) else ''
found = []; others = TopoDS_Compound(); bb = BRep_Builder(); bb.MakeCompound(others)
def walk(l, loc, named):
if st.IsReference_s(l):
ref = TDF_Label(); st.GetReferredShape_s(l, ref)
return walk(ref, loc.Multiplied(st.GetLocation_s(l)), named or name(l) == 'laser_etch')
if st.IsAssembly_s(l):
it = TDF_ChildIterator(l, False)
while it.More(): c = it.Value(); it.Next(); walk(c, loc, named)
return
s = st.GetShape_s(l)
if named or name(l) == 'laser_etch': found.append((l, loc))
else: bb.Add(others, s.Moved(loc))
it = TDF_ChildIterator(st.Label(), False)
while it.More():
l = it.Value(); it.Next()
if st.IsFree_s(l) and st.IsTopLevel(l): walk(l, TopLoc_Location(), False)
assert len(found) == 1, len(found); ml, mloc = found[0]; ms = st.GetShape_s(ml).Moved(mloc)
b = Bnd_Box(); BRepBndLib.Add_s(ms, b); mn, mx = b.CornerMin(), b.CornerMax()
inter = IntCurvesFace_ShapeIntersector(); inter.Load(others, 1e-6)
hits = []
for fx in (0.1, 0.3, 0.5, 0.7, 0.9):
for fy in (0.25, 0.5, 0.75):
x = mn.X() + (mx.X()-mn.X())*fx; y = mn.Y() + (mx.Y()-mn.Y())*fy
inter.Perform(gp_Lin(gp_Pnt(x, y, mx.Z()+5), gp_Dir(0, 0, -1)), -1e9, 1e9)
zs = [inter.Pnt(k).Z() for k in range(1, inter.NbPnt()+1)]
if zs: hits.append(max(zs))
top = max(hits); dz = top + lift - mn.Z()
v = gp_Vec(0, 0, dz).Transformed(mloc.Transformation().Inverted()) # world lift expressed in the part's own frame
t = gp_Trsf(); t.SetTranslation(v)
from OCP.XCAFDoc import XCAFDoc_ColorType
from OCP.Quantity import Quantity_Color
from OCP.TopExp import TopExp_Explorer
from OCP.TopAbs import TopAbs_FACE
ct = XCAFDoc_DocumentTool.ColorTool_s(doc.Main()); col = None
for src_ in [st.GetShape_s(ml)]:
c = Quantity_Color()
if ct.GetColor_s(ml, XCAFDoc_ColorType.XCAFDoc_ColorSurf, c) or ct.GetColor_s(ml, XCAFDoc_ColorType.XCAFDoc_ColorGen, c): col = c
ex = TopExp_Explorer(src_, TopAbs_FACE)
while col is None and ex.More():
c = Quantity_Color()
if ct.GetColor(ex.Current(), XCAFDoc_ColorType.XCAFDoc_ColorSurf, c) or ct.GetColor(ex.Current(), XCAFDoc_ColorType.XCAFDoc_ColorGen, c): col = c
ex.Next()
assert col is not None, 'mark colour not found'
st.SetShape(ml, BRepBuilderAPI_Transform(st.GetShape_s(ml), t, True).Shape())
ct.SetColor(ml, col, XCAFDoc_ColorType.XCAFDoc_ColorSurf); ct.SetColor(ml, col, XCAFDoc_ColorType.XCAFDoc_ColorGen)
ex = TopExp_Explorer(st.GetShape_s(ml), TopAbs_FACE); nf = 0 # face-level colour too, as the etch tool wrote it (some renderers read only that)
while ex.More():
sub = st.AddSubShape(ml, ex.Current()); ex.Next()
if not sub.IsNull(): ct.SetColor(sub, col, XCAFDoc_ColorType.XCAFDoc_ColorSurf); nf += 1
print("face colours", nf)
print(f"mark colour kept {col.Red():.3f},{col.Green():.3f},{col.Blue():.3f}")
st.UpdateAssemblies()
w = STEPCAFControl_Writer(); w.SetColorMode(True); w.SetNameMode(True); w.SetLayerMode(True)
w.Transfer(doc, STEPControl_AsIs); w.Write(out)
print(f"surface under mark z {min(hits):.4f}..{top:.4f}; mark z {mn.Z():.4f} -> {mn.Z()+dz:.4f} (moved {dz*1000:+.1f} um)")