exec(open(r"D:\HADAL - The Descent\models\dnr-cnc\build\lib2.py").read()) root = bpy.data.objects["DNR_CNC_Root"] C_STATIC = get_coll("CNC_Static"); C_MOVE = get_coll("CNC_Moving") for n in ("SM_DNR_ChipConveyor", "SM_DNR_PendantArm", "SM_DNR_Pendant", "SM_DNR_PendantScreen", "SM_DNR_AirGun", "SM_DNR_CoolantHose"): if n in bpy.data.objects: bpy.data.objects.remove(bpy.data.objects[n]) gm, bd, ti, td = MAT("Body_Gunmetal"), MAT("Body_Dark"), MAT("Titanium"), MAT("Titanium_Dark") cy, rd, am, gw = MAT("Glow_Cyan"), MAT("Glow_Red"), MAT("Glow_Amber"), MAT("Glow_White") bz = MAT("Bezel_Black"); cg = MAT("Cast_Grey") pw = MAT("Paint_White", (0.78, 0.80, 0.82), metal=0.5, rough=0.32) ly = MAT("Label_Yellow", (0.95, 0.80, 0.05), rough=0.6) hb_ = MAT("Hose_Blue") er = MAT("Estop_Red", (0.75, 0.02, 0.02), rough=0.3) rb = MAT("Rubber_Black") # ======================================================================= chip conveyor (left side, front half) CY = -0.55 # conveyor centre line (Y) cv = MB("SM_DNR_ChipConveyor", [pw, td, am, bz, bd]) # horizontal base trough leaving the left wall, just under the left plates (z < 0.45) cgy = MAT("Conveyor_Grey") cv.box((0.55, 0.52, 0.28), (-2.025, CY, 0.26), cgy, bevel=0.02, drop=('+x',)) # incline: a slanted band with horizontal ends, flush to the trough top (z .40) and the discharge box (z .93) cv.prism([(-2.04, 0.40), (-1.78, 0.40), (-2.18, 0.93), (-2.44, 0.93)], 0.46, ctr=(0, CY - 0.23, 0), mat=cgy, bevel=0.012) # discharge box cv.box((1.00, 0.56, 0.43), (-2.66, CY, 1.145), pw, bevel=0.03) cv.box((0.60, 0.008, 0.012), (-2.66, CY - 0.284, 1.29), am, drop=('+y',)) # electrical box on the incline's front face cv.box((0.37, 0.18, 0.42), (-2.265, CY - 0.23 - 0.09, 0.67), pw, bevel=0.015, drop=('+y',)) cv.box((0.10, 0.012, 0.05), (-2.265, CY - 0.23 - 0.18 - 0.006, 0.80), bz, drop=('+y',)) # latch window cv.cyl(0.018, 0.018, 0.05, (-2.265, CY - 0.23 - 0.09, 0.435), bz, segs=10, caps='bottom') # cable gland o_cv = cv.build(C_STATIC, parent=root) # ======================================================================= pendant arm (tube from the right plinth to the post) PX, PY, PZ = 2.10, -1.80, 0.93 ctrl = [(1.7215, -1.15, 0.20), (1.78, -1.15, 0.20), (1.90, -1.18, 0.20), (2.03, -1.30, 0.21), (2.10, -1.50, 0.25), (2.10, -1.70, 0.40), (2.10, PY, 0.62), (2.10, PY, PZ - 0.044)] path = catmull(ctrl, per=5) arm = MB("SM_DNR_PendantArm", [td, gm]) arm.sweep([tuple(p) for p in path], 0.040, td, sides=12, caps=False) o_arm = arm.build(C_STATIC, parent=root) # ======================================================================= pendant (swivels about the post axis) pd = MB("SM_DNR_Pendant", [ti, bz, td, cy, am, ly, er, bd]) Wd, Dp, Hd = 0.60, 0.20, 0.79 hb = cube_bm((Wd, Dp, Hd), (0, 0, Hd / 2), bevel=0.03) for x in (-0.26, 0.26): loopcut(hb, 'x', x) for z in (0.10, 0.36, 0.42, 0.74): loopcut(hb, 'z', z) def cell(x0, x1, z0, z1): return faces_where(hb, (0, -1, 0), 1, -Dp / 2, (x0, x1), (z0, z1)) scr = cell(-0.26, 0.26, 0.42, 0.74)[0] key = cell(-0.26, 0.26, 0.10, 0.36)[0] scr_floor = sink(hb, scr, 0.012) key_floor = sink(hb, key, 0.008) hb.normal_update() for f in hb.faces: f.material_index = pd.mi(ti) for fl in (scr_floor, key_floor): fl.material_index = pd.mi(bz) for e in fl.edges: for f in e.link_faces: f.material_index = pd.mi(bz) pd.add_bm(hb, None) # keys (5 rows x 8 cols) on the keypad floor, back faces dropped; a few glowing accent keys ky = -Dp / 2 + 0.008 for r_ in range(3): for c_ in range(9): kx = -0.215 + c_ * 0.036 + 0.0 kz = 0.135 + r_ * 0.068 - 0.0 m = cy if (r_, c_) in ((2, 0), (2, 1), (0, 8)) else (am if (r_, c_) == (1, 8) else td) pd.box((0.030, 0.010, 0.050), (kx, ky - 0.005, kz + 0.02), m, bevel=0.003, drop=('+y',)) # e-stop (yellow collar + red mushroom) sits right of the keys on the frame pd.cyl(0.050, 0.050, 0.012, (0.20, ky - 0.006, 0.23), ly, rot=(math.radians(90), 0, 0), segs=20, caps='top') pd.cyl(0.036, 0.030, 0.030, (0.20, ky - 0.027, 0.23), er, rot=(math.radians(90), 0, 0), segs=20, caps='top') # top status light and collar towards the arm pd.box((0.30, 0.008, 0.010), (0.0, -Dp / 2 - 0.004, Hd - 0.045), cy, drop=('+y',)) pd.cyl(0.060, 0.060, 0.04, (0, 0, -0.02), td, segs=20, caps='bottom') pd.transform(Matrix.Rotation(math.radians(-20), 4, 'Z')) o_pd = pd.build(C_MOVE, parent=root, loc=(PX, PY, PZ)) # HUD screen quad (own object so its UV is a clean 0-1 rectangle for the screen texture) sc_ = MB("SM_DNR_PendantScreen", [MAT("Screen_HUD", (0.02, 0.05, 0.07), emit=(0.2, 0.9, 1.0), emit_str=1.5)]) yq = -Dp / 2 + 0.012 - 0.0008 sc_.quad((-0.255, yq, 0.425), (0.255, yq, 0.425), (0.255, yq, 0.735), (-0.255, yq, 0.735), sc_.mats[0]) sc_.transform(Matrix.Rotation(math.radians(-20), 4, 'Z')) o_sc = sc_.build(C_MOVE, parent=o_pd, loc=(PX, PY, PZ)) # explicit UVs 0..1 across the quad me = o_sc.data uvl = me.uv_layers.new(name="UVMap") loops = [l for l in me.loops] cors = {0: (0, 0), 1: (1, 0), 2: (1, 1), 3: (0, 1)} for i, l in enumerate(loops): uvl.data[i].uv = cors[i] # ======================================================================= coolant hose + air gun (hangs on the front, right of the door) HX, HY = 1.26, -1.50 hs = MB("SM_DNR_AirGun", [td, rb, bd, ti, MAT("Hose_Blue")]) hz = MB("SM_DNR_CoolantHose", [hb_]) hs.box((0.10, 0.03, 0.16), (HX, -1.415, 1.58), bd, bevel=0.006, drop=('+y',)) # bracket hs.cyl(0.010, 0.010, 0.052, (HX, -1.456, 1.58), td, rot=(math.radians(90), 0, 0), segs=8, caps='none') # hook pin hs.box((0.036, 0.036, 0.11), (HX, HY, 1.53), rb, bevel=0.008) # grip hs.box((0.044, 0.044, 0.060), (HX, HY, 1.615), td, bevel=0.008) # body hs.cyl(0.009, 0.007, 0.22, (HX - 0.075, HY, 1.716), ti, rot=(0, math.radians(-50), 0), segs=10, caps='top') # nozzle (up/left) # coil start = Vector((HX, HY, 1.470)); end = Vector((1.50, HY, 0.27)) pts = [] turns, per = 16, 12 for i in range(turns * per + 1): t = i / (turns * per) c = start + (end - start) * t + Vector((0.10 * math.sin(math.pi * t), 0, 0)) ph = 2 * math.pi * turns * t amp = 0.040 * min(1.0, t * 12, (1 - t) * 12) pts.append(tuple(c + Vector((amp * math.cos(ph), amp * math.sin(ph) * 0.8, 0)))) pts += [(1.50, -1.45, 0.24), (1.50, -1.4005, 0.225)] pts = [(HX, HY, 1.475)] + pts hz.sweep(pts, 0.011, hb_, sides=6, caps=True) hs.cyl(0.032, 0.032, 0.03, (1.50, -1.385, 0.225), td, rot=(math.radians(90), 0, 0), segs=12, caps='top') o_hs = hs.build(C_STATIC, parent=root) o_hz = hz.build(C_STATIC, parent=root) result = {"audit": [audit(o) for o in (o_cv, o_arm, o_pd, o_sc, o_hs, o_hz)]}