Files
Robot_Arm/src/arm_model.py
T

1937 lines
121 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""�箏膥鈭箸���楛摨血�閫雴��𣇉� V2嚗𡁜蝠摨閙��斗��㗇ㄠ閫�
��笆�冽��漤����憭折䔮憸睃躹�蠘�銵峕楛摨虫��吔�
1. �肽𠧧�嗡辣嚗㇊04�拙�嚗厰▲�冽䲮敶Y�韏� �� �典�閫鍦���
2. 蝏輯𠧧/�坿𠧧�嗡辣嚗㇊05/P08嚗匧��典�靘折𢒰璉梯� �� Loft憭𤥁蔭撱枏�閫�
3. ���㕑��亙�����鞱�皜� �� 憭批�閫鍦像皛𤏸�皜�
4. 璈躰𠧧�嗡辣嚗㇊06/P07嚗㗇��㗇䲮敶Z器蝻� �� 摰峕㟲���蝟餌�
"""
import math
import os
import sys
import time
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import cadquery as cq
import arm_build as AB
from armcore import (M, C, cyl, box, ring, place, trs, bb, bbox_str, solids_of, OUT, WEB, DOCS)
from arm_build import (Joint, add, bx, Ycyl, Ybox, Yplate, prism, dogbone, sector,
FLANGE_Z, COVER_Z, HUB_FACE_Z, CLAMP_SPAN, HUB_M2_CLOCK,
BORE_R, CB_R, PCB_W, D2R, T, R, PARTS)
import human_layout as HL
from OCP.BRepAlgoAPI import BRepAlgoAPI_Common
from human_layout import (HUB, PLATE_T, R_MOT, Z_TIP, Z_WR, Z_EI, Z_SH, Z_RL, Z_R1,
Z_R3, Z_HUB3, Z_EL, Z_R6, Z_HUB6,
Z_R4, Z_CAP, Z_M6, Z_CHEST0, Z_CHEST1, X_J1_HUB, X_ARM, L1,
X_FORK_GAP, X_BAY_EXT,
Y_AXIS, Y_HUB, Y_REAR, Y_COVER, Y_H, Y_R_IN, Y_R_OUT,
Y_M6, Y_CHEST, X_CHEST, FOOT_H)
VERSION = os.environ.get("ARMVER", "v2")
ITER = int(os.environ.get("ARMITER", "3"))
AB.VERSION = VERSION
AB.ITER = ITER
Y_MID = Y_AXIS
BOSS = COVER_Z + 0.2
DISC_R = 40.0
SLEEVE_R = 35.0
# 瘛勗漲���隡睃���㺭
CLEARANCE_GAP = 2.0 # �唾��湧� 2.0mm
FILLET_TINY = 1.5 # 敺桀����嚗�卽摮磰器蝻矋�
FILLET_SMALL = 3.0 # 撠誩�閫𡜐��蠘��g�
FILLET_MEDIUM = 6.0 # 銝剖�閫𡜐�蝏𤘪�餈�腹嚗�
FILLET_LARGE = 10.0 # 憭批�閫𡜐�銝餉�頧桀�嚗�
FILLET_XLARGE = 15.0 # 頞�之���嚗��閫劐蜓撖澆躹���
CHAMFER_EDGE = 2.0 # 颲寧��坿�
def Xcyl(r, x0, x1, py, pz):
return place(place(cyl(r, 0.0, x1 - x0, 0.0, 0.0), R(90, 0, 1, 0)), T(x0, py, pz))
def Xplate(pts_yz, x0, x1):
prof = [(-p[1], p[0]) for p in pts_yz]
return place(place(prism(prof, 0.0, x1 - x0), R(90, 0, 1, 0)), T(x0, 0.0, 0.0))
def XB(a0, a1, y0, y1, z0, z1):
return bx(X_ARM + a0, X_ARM + a1, y0, y1, z0, z1)
# ------------------------------------------------------------------ �誯�嚗��蝛綽�--------
# 銝劐葵�𧢲�隞塚�P04/P06/P07嚗匧銁�唾��寥��賜���銝�憭批�"摰𧼮�餈�腹��"嚗𡁜��𡁏�瘛勗� 15~17.5mm嚗�
# �� gyroid 憛怠��芣� 25~35%嚗𣬚�鈭𡒊鍂�游�摰𧼮��餅�銝�銝芸��函頂�� 19~122 ��⏛�U��
# 銝钅𢒰銝支葵 helper �𡃏��埈��𤩺�嚗諹��嗘� P03 ��"撣鞟窈敶W��滨�"銝��湛�
# 1) 銝滨�撠�𡡒蝛箄� �婙�� �誯��磰�銋��銝𦠜�撘�嚗諹�銋�糓�㕑��箏藁���嚗峕��唬��𧢲����蝘舀�嚗�
# 2) �𣈯𢒰�芣𣈲�� �婙�� �𣈯𢒰銝擧偌撟喲𢒰憭寡� >= 52簞嚗��蝡𣇉凒�W允閫� <= 38簞嚗㚁��齿𣈲�𡢅�
# 3) ��� R4 ��� �婙�� �硋枂�亦�瘣硺��𠰴��芷𢒰�䀹�撠𤥁�嚗㕙t 隞� ~1.2 �砍� ~2.5嚗�
# ����𠰴��偦�銝剖��𧼮縧嚗�
# 4) �芸�"頝肽”�� > 8mm"����辷��𥕦𪂹�喳��� 8mm 憯� �婙�� �堒�蝥斤輕銝��嫣�蝣啜��
HOLLOW_WALL = 8.0 # �誯��𥪯��笔�銵券𢒰���撠誯𡢿頝嘅�= �嗘����撠誩��𡄯�
HOLLOW_FILLET = 4.0 # �誯��𥪜�閫鍦�閫𡜐�銝� P03 蝡𡝗踎�誯�蝒𦯀���
# 銝匧��誯��𠉛�撘�摨艾���銝劐葵隞園��舐� Y 頧游摩嚗�摩�拙銁 X �孵��匧�嚗諹�銝剜�折𢒰頞𡃏����
# 韐∠讃頞𠰴之嚗峕�隞�"撠烐����蝒�"�舀�憭滚撩摨行�������瘜𨰻��
# �啣�潛眏 scratch/tune_hollow.py ��"瑽賢躹��撌桀��函頂�� >= �䭾局�箇瑪�� 95%"�怠枂�伐�
# P04 獢�1 X23..35 Y102..154 Z>=525 -> 95% �箇瑪嚗䔶��� 69% ����漤�
# P07 獢�1 X��3..43 Y103..153 Z>=255 -> 96% �箇瑪嚗䔶��� 76%
# P06 獢�1 �祇�蝒堒��� Z362嚗���舀𤣰蝒�� -> 100% �箇瑪嚗䔶��� 56%
# 蝒堒���䔉�见銁 Z358嚗諹�諹砲憭�⏛�W��函頂�唳�雿𠬍��祇� 4mm 瘥娍赤�烐𤣰蝒� 8mm �垍�敺堒���
P04_CH = dict(x0=23.0, x1=35.0, y0=102.0, y1=154.0, z_floor=525.0) # �拙�蝡𧢲�
P07_CH = dict(x0=-3.0, x1=43.0, y0=103.0, y1=153.0, z_floor=255.0) # 撠讛�憿嗆踎
P06_WIN_XZ = [(3.0, 362.0), (37.0, 362.0), (37.0, 371.0),
(28.0, 374.0), (12.0, 374.0), (3.0, 371.0)] # 憭扯�餈�腹��
P06_HOLLOW_WIN = False # 2026-10-03 韏瑕��哨��勗耦蝒埈迤�Y��航敞�𡁻�瘣痹�銝漤�閫��霂西� p_upper_bone 5c嚗�
def hollow_channel(x0, x1, y0, y1, z_floor, z_open, tag="", fil=HOLLOW_FILLET):
"""�苷��𧼮�����齿局嚗帋� z_open 敺�銝见��� z_floor嚗峕局摨閙偌撟喉��苷��埈𣈲�𡢅���儒憯���氬��
蝡𡝗�嚗�芋�� Z = �枏㫲 Z嚗劐�餈嗘葵敶Y𠶖�舫妟�舀����瑽賢��舀偌撟喲𢒰��局憯���舐��湧𢒰嚗�
憿園�摰���𧼮��㰘�䔶����撠�𡡒蝛箄����摰諹砲隞嗅��� U 敶X局�Z�䔶��臬�敹��嚗�
�堒摩�牐舅靘� X �𤏸��選�甇�末�賢銁撘舐畆�匧��綽�嚗䔶葉�港葉�批��讐征�牐�銝齿�憭� I��
x0/x1/y0/y1 �其�������z_open �碶�銝芯�霂�敞�𡁻▲�Y��潦��
"""
tool = bx(x0, x1, y0, y1, z_floor, z_open)
if fil > 0:
try:
tool = cq.Workplane(obj=tool).edges("|Z").fillet(fil).val()
except Exception as e:
print(" [�誯�瑽稽 %s ������頝唾�: %s" % (tag, e), flush=True)
print(" [�誯�瑽稽 %s: X%.1f..%.1f Y%.1f..%.1f �� Z%.1f �睲��𧼮� (�𥕦𪂹�坔� >=%.0fmm)"
% (tag, x0, x1, y0, y1, z_floor, HOLLOW_WALL), flush=True)
return tool
def hollow_tent_window(pts_xz, y0, y1, tag="", fil=HOLLOW_FILLET):
"""撣鞟窈敶W��滨�嚗䧥Z 撟喲𢒰�餉蔭撱橒�瘝� Y �����忽��
頧桀�銝见捐銝羓�嚗�㘚敶g��婙�𠉛�憿嗡��寧��坔耦�𣂷�銝芸�憿塚��𣈯𢒰銝擧偌撟喳允閫� >= 52簞 �芣𣈲�𡢅�
�芣�憿園�銝�撠𤩺挾撟喲▲��閬�‘�伐�<=20mm嚗䔶� P03 �䕘���蔭撱枏銁 X �孵�銝滩���說�港葵�芷𢒰嚗�
銝支儒敹�◆�坔�嚗�炏�躰砲擃睃漲銝𢠃妟隞嗡�鋡怠��准��仃�餃�摰硺���
"""
# XZ 撌乩�撟喲𢒰���蝥踵糓 -Y嚗𨫪xtrude 隡𡁏� -Y 韏堆���隞亥絲�寞𦆮�� y1 �滩�閬�� y0..y1
tool = (cq.Workplane("XZ", origin=(0, y1, 0)).polyline(pts_xz).close()
.extrude(y1 - y0).val())
if fil > 0:
try:
tool = cq.Workplane(obj=tool).edges("|Y").fillet(fil).val()
except Exception as e:
print(" [�誯�蝒㻩 %s ������頝唾�: %s" % (tag, e), flush=True)
print(" [�誯�蝒㻩 %s: XZ 頧桀� %d ��, 瘝� Y %.1f..%.1f ��忽 (撣鞟窈敶�, �𣈯𢒰�芣𣈲��)"
% (tag, len(pts_xz), y0, y1), flush=True)
return cq.Shape(tool.wrapped)
# �����"�菜㦤�滨垢憭寧揮"蝏煺��齿䲮嚗㇇2/J3/J4/J5 �𡁶鍂嚗𥇍1 �� P03 �芸楛��� S04 �詨蝱摰䂿緵嚗剹��
# �菜㦤�滨垢�硋�蝡舫𢒰嚗枠 頧游����J2/J4/J5嚗匧銁 Y_COVER=156嚗���𡝗� +Y �罸鵭嚗�
# Z 頧游����J3嚗丯oll �菜㦤嚗諹蓬�� -Z嚗匧銁 Z_R-56嚗���𡝗� -Z �罸鵭嚗�-Z 靘扳糓隞𤾸𢆡隞塚���
# �讠��屸𢒰銝𦒘� 0.0 �湧��W�嚗諹卽�匧蘨�𣂷��讠揮�䜘��
# 瘝匧��訾��剹�𣂼�����函㮾雿溻�穃�銋㚁�BCD55嚗�72.2簞+90k嚗㚁��Y��啣�撅��� Y 頧游���糓
# 17.8簞+90k嚗�� P03�𣛮1 �� S04 銝��湛�嚗琂 頧游���糓�䔶�蝏�㺭�賢銁�典� (x,y) 撟喲𢒰嚗�
# 銝斤�頧游��������穃��其��� �婙�� �冽㦤�䔶�憟堒�雿滨漲摰𡄯��嫣�憭��憿餃�甇亙𡖂銝�憭���
CLAMP_BCD = 27.5
CLAMP_CLOCK = (17.8, 107.8, 197.8, 287.8) # Y 頧游�����典� (x,z) �訾�
CLAMP_CLOCK_LOCAL = tuple((360.0 - a) % 360.0 for a in CLAMP_CLOCK) # = 72.2+90k
CLAMP_ROOT = 0.5 # �寥���㴓�𡁜漲嚗帋��滨垢摰帋��臬�蝡舫𢒰�梢𢒰嚗䔶�霂���交�銝�雿�
CLAMP_T = 5.0 # �讠��砌��𡁜漲
CLAMP_CLR = 1.0 # 隞𤾸𢆡隞嗉悟雿漤𡢿�辷�銝� Y 頧游��� hub_gap=6.0 �䔶�銝芷���
CLAMP_BACKOFF = CLAMP_T + CLAMP_CLR - CLAMP_ROOT # =5.5 隞𤾸𢆡隞嗆��X㟲雿枏�蝘駁�
# ��2026-10-05e��"�菜㦤�滨垢�湔𣏹"蝏煺��湔㺿撘��喉�雿𦦵鍂鈭𤾸��� 5 憭�㩞�箏�蝡荔�J2/J3/J4/J5/J6嚗剹��
# �湔𣏹�砌� = ��妟隞嗅�蝡舐� **�滨垢摰帋���**嚗Ǒfront_collar_pocket` �𠰴漣摮𥪯� R30.15 �拙�
# R30.25 �嗥�銝讠���� r30.25..35��6mm 擃条��臬�嚗剹���瘥𠉛㩞�箏�蝡舐� �60.3 �詨枂 4.75mm嚗�
# �羓㩞�箏�蝡舐��游��港�嚗桕2/J3/J4/J5 銝𡃏�撉𤑳�銝��� R35 �滨垢�讠�嚗��70 �滚瑌 3.2mm嚗剹��
# �冽� 2026-10-05 ��銁 J3/M3 撠暸���枂嚗�2026-10-05d �芸��𧼮藁�����圾�喉��祆活�𠰴�銝���
# �典嘀�啣�雿坔�憭��J2/M2��4/M4��5/M5��6/M6嚗㚁��牐�摰���峕���
# 銝箔�銋���游��𠰴�銝𡒊㩞�粹�撟喉�R35 -> R31.8嚗㚁�
# 1. ���憯���砌��其舅銝芣䲮雿滢�憭硋�**�詨�**嚗峕㟲���摰屸�銝斤����璆𥪜耦隡朞�蝛箸�摮斤�蝣𤾸�
# 嚗��瘚� 1.32mm3嚗㚁��游��訫�雿𤘪��𡢅�
# 2. �讠��寥��芣� 0.5mm �娍𦻖撣佗��臬�蝒��餈墧𦻖�V� 2.37mm2 �匧� 0.78mm2嚗�
# 4xM3x8 ��允蝝批�隡𡁏��讠�隞擧𧋦雿㮖��劐��乓��
# ��隞亙蘨��**�𧼮藁�����**嚗朞��𠹺儒摰帋��舐誧蝏剖�雿滨㩞�箏�蝡舐���僎雿靝蛹�讠��臭�銝磰雲憭笔撩��
# �舀�/�娍𦻖�g��讠��砌����37 霈拐�摮𢛵��4xM3x8 瘝匧�������瘝踹��其��具��
# ��藁雿滨蔭閫� cut_motor_fence()��挽 False �𡝗�嚗��憭滚��亦��游��湔𣏹嚗剹��
FENCE_OPEN_CUT = True
def cut_motor_fence(shape, j, tag, name3, z0=49.4, z1=56.1):
"""��2026-10-05e�穃蘨����菜㦤�滨垢�湔𣏹嚗��蝡臬�雿滨㴓嚗匧銁**�𧼮藁�����**��㴓憓踺��
銝� 2026-10-05d 蝏� P05/M3 �����摰���峕� �婙�� 敶𤘪𧒄��扇�典��鍦�
(X_ARM簣40, Y_AXIS-40..Y_AXIS+3, Z388.9..395.6) �Y��� J3 撅��函頂甇�末��
x簣40 / y -3..+40 / z 49.4..56.1��𧋦�賣㺭�𠰴�隞�"P05 銝梶鍂�典���"瘜𥕦���
"�匧�����典�����𠹺葵��"嚗𥇍2/J4/J5/J6 鈭擧糓�䔶����𡁶鍂��
撅��典���漲摰𡄯�閫� trs/place嚗㚁�z 瘝輻㩞�箄蓬����𤑳㩞�箏�蝡舐�嚗��蝡舫𢒰�� z=COVER_Z=56嚗㚁�
x/y �典��港�頧渡�撟喲𢒰����**撅��� +y 銝�敺𧢲糓�𠰴��𧼮藁靘�** �婙�� 摰墧� 5 憭�㩞�箄���
�砌�嚗�㴓憭� r=37/40 �㗇�憭� = �諹�靘改��嫣�閫鍦��刻氜�典��刻� 180..360 = 撅��� -y 靘改�
J2/M2 �諹� 240..315 J3/M3 �諹� 225..315 J4/M4 �諹� 210..330
J5/M5 �諹� 210..330 J6/M6 �諹� 195..345
�����䲮�烐����𣂷辣�滨蔭嚗𣬚�銝��硋��� +y��
銝箔�銋��撖� z ��㺭�質��硋��綽�5 憭�㩞�箇��滨垢摰帋��舫��啣末�賢銁**撅��� z 49.5..56**
嚗À 頧渡㩞�箏�蝡舐㴓 Y150..156 -> z50..56嚗暿oll �菜㦤 Z395.5..389 -> z49.5..56嚗剹��
鋡怠��厩��芣� r30.25..35 �����㴓憓坔銁�𧼮藁靘抒��典�嚗𥕦��𡝗𧋦雿橒�4xM3x8 瘝匧�畾蛛���
�37 霈拐�摮𢛵������瘝踴����𠹺儒�游�摰帋��臬��其��具��
��藁颲寧��硋銁撅��� y=-3.0 �䔶��� 0嚗𡁶㴓憯�銁撅��� y=-3 憭��銝舘��𠹺儒摰硺�餈鮋�𡄯�
��枂�亦��舐�甇��蝻箏藁�䔶��舫妟�𡁜漲蝻嘅��訫�雿𤘪��穃予�嗡���
嚗㇊05 摰墧���� solids=1嚗�2026-10-05c �游��� R31.8 ���隡𡁏��� 1.32mm3 蝣𤾸�嚗剹��
"""
if not FENCE_OPEN_CUT:
return shape
shape = shape.cut(j.L(bx(-40.0, 40.0, -3.0, 40.0, z0, z1)))
print(" [�湔𣏹] %s: �芸��𧼮藁靘折�銝����蝡臬�雿滨㴓嚗���� y -3..+40, z %.1f..%.1f嚗㚁�"
"�諹�靘扳㟲����坔�雿滚�蝡舐�撟嗆𣈲�穃��吔��讠��砌�/瘝匧�/�𥪜藁銝𧢲窒銝滚�"
% (name3, z0, z1), flush=True)
return shape
def motor_front_clamp(px, pz, plate_t=CLAMP_T, tag="", axis="Y", py=0.0, z_face=None):
"""�菜㦤�滨垢�讠�嚗𡁏�"�芾◤�𡒊垢摰㕑��踹��a�甇�"�寞��滚�����W�憭寧揮��
�蠘挽霈⊿�瘥譍葵�唾���㩞�粹��芣��𡒊垢�� 4xM3x10嚗𠄎02嚗厰��典偏蝡舫𢒰銝𠺪��滨垢�硋��刻ㄧ�莎�
憭扳酞�拐��菜㦤蝏閗䌊頨怨蓬�� �60.3 摨批��𣬚�憭�/蝧䁅絲�����銁�菜㦤�滨垢�硋�蝡舫𢒰�牐���
銝𤾸�蝡舀踎����� R35 �讠�嚗𣬚鍂 4xM3x8嚗㇂CD55嚗匧銁�滨垢�碶��滚允銝�甈� �婙�� �菜㦤鋡怠��𦒘舅��
��� �60.3 蝡舫𢒰���憭寞香嚗��暹��芰眏摨血��塚�憭寧揮�𥕦��刻粥�W�嚗諹卽�劐����摰帋���
銝支葵頧游��梁鍂�䔶�憟堒偕撖賂��芣揢���瑚�蝟鳴�銝漤�憭滚��唬遙雿訫�敺�/�訾�嚗㚁�
axis="Y"嚗㇇2/J4/J5嚗㚁��唾�頧渲� (px, pz)嚗��蝡舐�憭𣇉垢�W銁 Y_COVER嚗���𡝗� +Y �選�
axis="Z"嚗㇇3 roll嚗諹蓬�� -Z嚗㚁��唾�頧渲� (px, py)嚗��蝡舐�憭𣇉垢�W銁 z_face嚗���𡝗� -Z �踴��
撅��典����s 隞𤾸�蝡舐�憭𣇉垢�Z絲蝞梹�s>0 銝�敺�"�𣬚氖�菜㦤"嚗䔶舅銝芾蓬�穃��瘀�嚗�
- �讠� R35嚗众 隞� -CLAMP_ROOT嚗���滨垢摰帋��臬�蝡舫𢒰�梢𢒰嚗䔶�霂���交�銝�雿橒��� plate_t嚗�
- �屸𢒰蝎曄&�賢銁 s=0嚗䔶�霈拇覔�券� 0.5mm ���蝡舐� R30.15 ������
- �37 銝剖亢霈拐�摮䈑�R18.5嚗㕑悟撘�隞𤾸𢆡隞嗥��湧��詨蝱 R17.8 銝� 3xS01 颲枏枂�粹�憭湛�
- 4xM3x8嚗煳�3.4 �𡁜� + �6.0 瘝匧�瘛� 3.0嚗�䌊�滨垢�X��� s=2嚗㚁����憭游�瘝匧�嚗�
憭湧𢒰�见���蝱�塚�銝剝𡢿 2.0mm �讠��砌��堒���
"""
if axis == "Y":
def C(r, s0, s1, du=0.0, dv=0.0):
return Ycyl(r, Y_COVER + s0, Y_COVER + s1, px + du, pz + dv)
elif axis == "Z":
def C(r, s0, s1, du=0.0, dv=0.0):
return cyl(r, z_face - s1, z_face - s0, px + du, py + dv)
else:
raise ValueError("motor_front_clamp: axis �芾��� Y �� Z嚗峕𤣰�� %r" % (axis,))
s0, s1 = -CLAMP_ROOT, plate_t
fp = C(35.0, s0, s1)
fp = fp.cut(C(18.5, s0 - 0.5, s1 + 0.5)) # �37 銝剖亢霈拐�摮�
fp = fp.cut(C(30.15, s0 - 0.5, 0.0)) # �60.3 霈拐�瑽�
for deg in CLAMP_CLOCK_LOCAL:
rad = math.radians(-deg) # �典��訾� = -撅��函㮾雿�
fu, fv = CLAMP_BCD * math.cos(rad), CLAMP_BCD * math.sin(rad)
fp = fp.cut(C(3.0, 2.0, s1 + 0.5, fu, fv)) # �6.0 瘝匧�
fp = fp.cut(C(1.7, s0 - 0.5, 2.0, fu, fv)) # �3.4 �𡁜�
where = ("Y%.1f..%.1f" % (Y_COVER - CLAMP_ROOT, Y_COVER + plate_t)) if axis == "Y" \
else ("Z%.1f..%.1f" % (z_face - plate_t, z_face + CLAMP_ROOT))
print(" [�滨垢�讠�] %s: R35 %s, 4xM3x8 BCD55@%s (%s 頧�)"
% (tag, where, "/".join("%.1f" % d for d in CLAMP_CLOCK), axis), flush=True)
return fp
def hub_m2_holes(shape, j, cb_z1, th_z1=58.0, th_z0=54.0, cb_z0=58.0,
th_r=1.4, cb_r=2.8):
"""�其��冽�銝𠰴� 4x M2 �湧��粹�摮䈑��2.8 �𡁜� + �5.6 瘝匧�嚗𩱳CD 閫� AB.M["m2_bcd"]��
�冽㦤 5 憭��J1 �㗇踎 / J2+J3 �渲�瘥� / J4+J5 �渲�瘥����𧋦���銝�隞賢��瑞�敺芰㴓嚗�
�芣�瘝匧�憿� z 銝𡡞�摮娪▲ z 銝文��譍辣��� �婙�� ���甈⊿�銝�憭�停�臭�憭�� bug��
�啣銁蝏煺�韏啗��䕘�����函��芯��芸楛��舅銝� z��
cb_z0 暺䁅恕 58.0 = th_z1嚗�蝱�嗅�甇方氜�券�𡁜�憿嗥垢嚗𢏺03 �㗇踎���憭��憭�
嚗��摮𥪜蝱�嗅𤐄摰𡁜銁 63.0 銝漤��詨蝱�滨宏嚗諹� p_fork ��釣�𠺪�嚗峕�銝支葵 z �賢虾隡𨬭��
"""
for a in AB.HUB_M2_CLOCK:
u = AB.M["m2_bcd"] / 2.0 * math.cos(a * AB.D2R)
v = AB.M["m2_bcd"] / 2.0 * math.sin(a * AB.D2R)
shape = shape.cut(j.L(cyl(th_r, th_z0, th_z1, u, v)))
shape = shape.cut(j.L(cyl(cb_r, cb_z0, cb_z1, u, v)))
return shape
def make_direct_hub(shape, j, r_disc=35.0, z_out=74.0):
"""隡睃��渲�瘜訫�嚗𡁜��惩紡�穃�坿�"""
disc = cyl(r_disc, 56.5, z_out)
boss = cyl(17.8, 54.942, 56.5)
chamfer_cone = cyl(18.5, 54.5, 54.942)
shape = shape.fuse(j.L(disc)).fuse(j.L(boss)).cut(j.L(chamfer_cone))
shape = shape.cut(j.L(cyl(3.5, 54.0, z_out + 30.0)))
return hub_m2_holes(shape, j, cb_z1=z_out + 40.0)
# ========== 頨臬僕�典� ==========
# ========== 頨臬僕/瘚贝��唳沲�典� (�𡒊蔭�脣�曄蕃擃睃��扳㦤��) ==========
X_COL = -115.0
Y_COL = Y_AXIS # 128.0
Z_LOCK = 463.0 # 璅芸��脰���揮�粹�擃睃漲嚗���勗�憯� �� 璁怠仍嚗愢4x16 �芣𤫇嚗�
def p_chest():
"""P01_�貉��舀�蝡𧢲� (High-Rigidity Box Mast Tower - �𡒊蔭�唳沲蝡𧢲�):
1. 66x66mm 撠�𡡒銝剔征�𡁜�蝞勗��梧�憯�� 11mm嚗���� 44x44嚗㚁�銝剖��� (-115.0, 128.0)嚗䔶�鈭擧���迤�擧䲮嚗�
2. 憿園��交𤣰 P03 43.4x43.4x15mm 摰帋�璁怠仍嚗�44x44 R4 ���嚗剹��4x 蝡硋�摰㕑�摮� + 1x 璅芸��脰���揮摮�
嚗���� �3.9 �游�嚗鐝4x16 隞𤾸��函凒�交𠾶�亥䌊�餅��页��㰘�摮�/�䭾�摮�/�𣳇��页�嚗�
3. 摨閖� 50x50x12mm �嗆0璁怠仍�鍦� P02 璁怠漣嚗𡁶㴓敶W蝱��(66->50)�X㗁頧質蓬�穃�嚗峕局憯���冽㗁頧賢����
4. �滚�撘�霈曆舅蝏�之���韏啁瑪撌亥䰾蝒堒藁嚗Ē=60~150mm 銝� Z=330~420mm嚗㚁�
5. 憭𡝗ㄠ閫鍦��券��� R=6mm �����
"""
z_bot = 22.0
z_top = Z_CHEST1 # 470.0
col = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_bot))
.rect(66.0, 66.0)
.extrude(z_top - z_bot)
.edges("|Z").fillet(6.0)).val()
s = cq.Shape(col.wrapped)
cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_bot + 10.0))
.rect(44.0, 44.0)
.extrude(z_top - z_bot + 1.0)
.edges("|Z").fillet(4.0)).val()
s = s.cut(cav)
# 摨閖��嗆0璁怠仍嚗𡁏��� P02 璁怠漣�𡒊㴓敶W蝱�拙�摰痹�頧游��𥡝粥�W��屸� M5 �箇犒
tenon = (cq.Workplane("XY", origin=(X_COL, Y_COL, 10.0))
.rect(50.0, 50.0).extrude(z_bot - 10.0)
.edges("|Z").fillet(4.0)).val()
s = s.fuse(tenon)
# 摨閖� M5 憭寧揮摮䈑�韐舫�𡁏托憭湛�嚗䧥 �煾�撖寧妍 (��20/+16) 銝擧托摨批�雿漤�撖寥俈�滩�/�脰蓮 90簞
for xx in (X_COL - 20.0, X_COL + 16.0):
for yy in (Y_COL - 18.0, Y_COL + 18.0):
s = s.cut(cyl(2.75, 9.99, z_bot + 15.0, xx, yy))
# 憿園� 4x 摰㕑�摮䈑�蝏煺� �3.9 �游�嚗㇈4x16 �湔𦻖�批��芣𤫇�𣂼�嚗𥕦蘨�栞�銝�銝芸�嚗峕�餈��/�䭾�摮䈑�嚗峕楛 20mm
# 雿滢� 66x66 憿嗥㴓 11mm 摰硺�憯��嚗���� 22 �� 憭硋� 33嚗㚁��踹� 44x44 ���銝� R4 ������嚗�
for xx in (X_COL - 27.5, X_COL + 27.5):
for yy in (Y_COL - 13.5, Y_COL + 13.5):
s = s.cut(cyl(1.95, z_top - 20.0, z_top + 0.01, xx, yy))
# 璅芸��脰���揮摮䈑��𤾸� �� 璁怠仍嚗㚁��3.9 韐舐忽 11mm �𤾸� + 璁怠仍���嚗㇈4x16 �批��芣𤫇嚗�
s = s.cut(Xcyl(1.95, X_COL - 34.0, X_COL - 20.0, Y_COL, Z_LOCK))
w_bot = (cq.Workplane("YZ", origin=(X_COL + 33.5, Y_COL, 105.0))
.rect(34.0, 70.0)
.extrude(-20.0)).val()
s = s.cut(w_bot)
w_top = (cq.Workplane("YZ", origin=(X_COL + 33.5, Y_COL, 375.0))
.rect(34.0, 70.0)
.extrude(-20.0)).val()
s = s.cut(w_top)
return s
def split_p01_poka_yoke(p01):
"""��� P01 銝� A/B/C 銝㗇挾嚗�艇�潮��� 200x200mm �枏㫲�綽�蝡𣇉凒�齿𣈲�烐��堆�嚗�
撣� 16mm �嗆0鈭㘾�璁怠晓嚗��憟㛖�憯� 3.6 + �祆托憯� 6.9嚗���娍𤣰蝒� 51->44 �W����憯��
�閗器�滚��湧� 0.5嚗剹��誑�羓�銝� �3.9 �游����畾萄笆���嚗㇈4x16 隞𤾸��Y凒�交𠾶�亥䌊�餅��页�
瘥滚藁憯���祆托憯��敺���㰘�摮�/瘝匧�/憸��嚗���𦒘舅�W笆蝘啣�銝�憸梹�嚗�
摮𥪯��詨笆蝡𧢲�銝剖� ��16 / +22 �𧼮笆蝘堆��拍��脣�鋆�俈���嚗𥟇𧋦雿� 3D �孵��嘥������
"""
z_bot = 22.0
z_s1 = 172.0
z_s2 = 321.0
z_top = 470.0
h_lap = 16.0
# �𧼮笆蝘啣笆���雿㵪��詨笆蝡𧢲�銝剖��誩� -16mm 銝� +22mm嚗��敹�榆 6mm嚗��鋆��瘜閧忽�亥卽�橒�
xx_bolts = (X_COL - 16.0, X_COL + 22.0)
# ��挾撖寥�摮䈑�蝏煺� �3.9 �游�嚗㇈4x16 隞𤾸��Y凒�交𠾶�亥䌊�餅��页�瘥滚藁憯���祆托憯��敺��
# 瘝⊥�餈��/瘝匧�蝑匧�摰��嚗㚁��滚�銝日𢒰撖寧妍嚗𥟇�撠碶撓餈�托憯��銝�畾萄銁���靘抒� �4.5 霈拐���
def _seam_holes(part, xx, z):
return (part.cut(Ycyl(1.95, Y_COL - 33.6, Y_COL - 21.4, xx, z))
.cut(Ycyl(1.95, Y_COL + 21.4, Y_COL + 33.6, xx, z))
.cut(Ycyl(2.25, Y_COL - 21.7, Y_COL - 15.5, xx, z))
.cut(Ycyl(2.25, Y_COL + 15.5, Y_COL + 21.7, xx, z)))
# --- P01_A (銝𧢲挾) ---
cut_above_s1 = bx(X_COL - 50.0, X_COL + 50.0, Y_COL - 50.0, Y_COL + 50.0, z_s1, z_top + 10.0)
p01_a_base = p01.cut(cut_above_s1)
tongue1_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s1))
.rect(57.8, 57.8).extrude(h_lap)
.edges("|Z").fillet(3.4).edges(">Z").chamfer(1.5)).val()
tongue1_cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s1 - 1.0))
.rect(44.0, 44.0).extrude(h_lap + 2.0)).val()
tongue1 = cq.Shape(tongue1_outer.wrapped).cut(tongue1_cav)
p01_a = p01_a_base.fuse(tongue1)
z_bolt1 = z_s1 + h_lap / 2.0 # 180.0
for xx in xx_bolts:
p01_a = _seam_holes(p01_a, xx, z_bolt1) # A-B 蝻嘥笆���嚗��3.9嚗���𦒘舅�g�
# Engrave the front (-Y) flat face, reading VERTICALLY bottom-to-top along
# the column (user request): local +X = world +Z, local +Y = world -X, so
# the trailing "��" glyph renders pointing world-up (+Z).
front_label_plane_a = cq.Plane(
origin=(X_COL, Y_COL - 33.0, 120.0),
xDir=(0, 0, 1), normal=(0, -1, 0),
)
label_a = (cq.Workplane(front_label_plane_a)
.text("P01-A TOP ��", 9.0, -0.8)).val()
p01_a = p01_a.cut(cq.Shape(label_a.wrapped))
# --- P01_B (銝剜挾) ---
cut_below_s1 = bx(X_COL - 50.0, X_COL + 50.0, Y_COL - 50.0, Y_COL + 50.0, z_bot - 14.0, z_s1)
cut_above_s2 = bx(X_COL - 50.0, X_COL + 50.0, Y_COL - 50.0, Y_COL + 50.0, z_s2, z_top + 10.0)
p01_b_base = p01.cut(cut_below_s1).cut(cut_above_s2)
pocket1 = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s1 - 0.1))
.rect(58.8, 58.8).extrude(h_lap + 0.6).edges("|Z").fillet(3.9)).val()
p01_b_base = p01_b_base.cut(pocket1)
tongue2_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s2))
.rect(57.8, 57.8).extrude(h_lap)
.edges("|Z").fillet(3.4).edges(">Z").chamfer(1.5)).val()
tongue2_cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s2 - 1.0))
.rect(44.0, 44.0).extrude(h_lap + 2.0)).val()
tongue2 = cq.Shape(tongue2_outer.wrapped).cut(tongue2_cav)
p01_b = p01_b_base.fuse(tongue2)
z_bolt2 = z_s2 + h_lap / 2.0 # 329.0
for xx in xx_bolts:
p01_b = _seam_holes(p01_b, xx, z_bolt1) # A-B 蝻嘥笆���嚗��3.9嚗���𦒘舅�g�
p01_b = _seam_holes(p01_b, xx, z_bolt2) # B-C 蝻嘥笆���嚗��3.9嚗���𦒘舅�g�
front_label_plane_b = cq.Plane(
origin=(X_COL, Y_COL - 33.0, 240.0),
xDir=(0, 0, 1), normal=(0, -1, 0),
)
label_b = (cq.Workplane(front_label_plane_b)
.text("P01-B TOP ��", 9.0, -0.8)).val()
p01_b = p01_b.cut(cq.Shape(label_b.wrapped))
# --- P01_C (銝𦠜挾) ---
cut_below_s2 = bx(X_COL - 50.0, X_COL + 50.0, Y_COL - 50.0, Y_COL + 50.0, z_bot - 14.0, z_s2)
p01_c_base = p01.cut(cut_below_s2)
pocket2 = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s2 - 0.1))
.rect(58.8, 58.8).extrude(h_lap + 0.6).edges("|Z").fillet(3.9)).val()
p01_c = p01_c_base.cut(pocket2)
for xx in xx_bolts:
p01_c = _seam_holes(p01_c, xx, z_bolt2) # B-C 蝻嘥笆���嚗��3.9嚗���𦒘舅�g�
front_label_plane_c = cq.Plane(
origin=(X_COL, Y_COL - 33.0, 390.0),
xDir=(0, 0, 1), normal=(0, -1, 0),
)
label_c = (cq.Workplane(front_label_plane_c)
.text("P01-C TOP ��", 9.0, -0.8)).val()
p01_c = p01_c.cut(cq.Shape(label_c.wrapped))
return p01_a, p01_b, p01_c
def make_p02_poka_yoke():
"""撠� P02 ���銝箔�隞嗆芋�堒�蝏�辣嚗��銝交聢 <= 195x190mm嚗屸��� 200x200mm �枏㫲摨𠺪�嚗�
1. P02_Center (摨訫漣銝剜瓲敹�): 195x190x70mm嚗���游捆蝥喟��勗�蝑雴��滚�銝㕑��𨀣�蝑页��詨�摨𥪜��箸��亦�嚗�
2. P02_Front (�滚��𥡝�): 145x190x22mm嚗�捐頝刻� 104mm �峕托憭� + 憸�� M5 �箸�瑽踝�
3. P02_Rear (�𤾸��𥡝�): 45x190x22mm嚗𣬚�頝刻� 80mm �峕托憭湛�頝刻�撌株噢 24mm �拍��脣�嚗𣬚�銝齿毽鋆����
"""
z0 = 0.0
z1 = 22.0
y_width = 190.0
f_tenon_w = 44.0
f_tenon_y_span = 52.0
r_tenon_w = 32.0
r_tenon_y_span = 40.0
# 1. P02_Center (X = -195.0 .. 0.0, 195x190mm)
x_c_min = -195.0
x_c_max = 0.0
x_c_len = x_c_max - x_c_min
x_c_mid = (x_c_min + x_c_max) / 2.0
c_plate = (cq.Workplane("XY", origin=(x_c_mid, Y_COL, z0))
.rect(x_c_len, y_width).extrude(z1)
.edges("|Z and <X").fillet(8.0).edges("|Z and >X").fillet(8.0)
.edges(">Z").fillet(2.0)).val()
p02_c = cq.Shape(c_plate.wrapped)
# Socket collar (Z: 22..70mm)
z_collar_top = 70.0
collar_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z1))
.rect(80.0, 80.0).extrude(z_collar_top - z1)
.edges("|Z").fillet(8.0).edges(">Z").chamfer(2.0)).val()
p02_c = p02_c.fuse(cq.Shape(collar_outer.wrapped))
# Front & Rear triangular gusset ribs
f_pts = [(-75.0, z1), (-15.0, z1), (-15.0, z1 + 4.0), (-75.0, 68.0)]
f_rib = (cq.Workplane("XZ", origin=(0, Y_COL, 0)).polyline(f_pts).close().extrude(19.0, both=True)).val()
p02_c = p02_c.fuse(cq.Shape(f_rib.wrapped))
r_pts = [(-155.0, z1), (-195.0, z1), (-195.0, z1 + 14.0), (-155.0, 70.0)]
r_rib = (cq.Workplane("XZ", origin=(0, Y_COL, 0)).polyline(r_pts).close().extrude(19.0, both=True)).val()
p02_c = p02_c.fuse(cq.Shape(r_rib.wrapped))
# Front wire guide
wg_pts = [(-75.5, z1 + 1.0), (-14.0, z1 + 1.0), (-14.0, z1 + 4.0), (-75.5, 68.5)]
wire_guide = (cq.Workplane("XZ", origin=(0, Y_COL, 0)).polyline(wg_pts).close().extrude(9.0, both=True)).val()
p02_c = p02_c.cut(wire_guide)
# Column socket �� stepped mortise: upper 66.6 bore for the 66 box walls,
# lower 50.6 recess (floor 0.6 low) for the 50x50 bottom tenon; the recess
# rim at z=22 is the axial seat, so column weight bears on face, not threads.
socket_upper = (cq.Workplane("XY", origin=(X_COL, Y_COL, z1))
.rect(66.6, 66.6).extrude(z_collar_top - z1 + 1.0)
.edges("|Z").fillet(6.3)).val()
p02_c = p02_c.cut(socket_upper)
socket_lower = (cq.Workplane("XY", origin=(X_COL, Y_COL, 9.4))
.rect(50.6, 50.6).extrude(z1 - 9.4)
.edges("|Z").fillet(4.3)).val()
p02_c = p02_c.cut(socket_lower)
# Vertical M5 clamp bolts (offsets match the asymmetric column tenon holes:
# X ��20/+16 blocks 180簞 flip, the 簣18 Y span blocks 90簞 rotation).
# Threads engage the tenon 15mm �� clamp only, axial load rides on the seat.
for xx in (X_COL - 20.0, X_COL + 16.0):
for yy in (Y_COL - 18.0, Y_COL + 18.0):
p02_c = p02_c.cut(cyl(2.75, -0.01, 10.5, xx, yy)).cut(cyl(5.0, -0.01, 6.0, xx, yy))
# Center clamp slots
for cy in (Y_COL - 75.0, Y_COL + 75.0):
plane = cq.Plane(origin=(x_c_mid, cy, -0.01), xDir=(0, 1, 0), normal=(0, 0, 1))
slot = cq.Workplane(plane).slot2D(28.0, 7.0).extrude(z1 + 1.0).val()
p02_c = p02_c.cut(slot)
p02_c = p02_c.cut((cq.Workplane("XY", origin=(X_COL, Y_COL - 70.0, -0.01)).rect(28.0, 80.0).extrude(6.0)).val())
# Front mortise pockets
for sign in (-1, 1):
yy = Y_COL + sign * f_tenon_y_span
front_mortise = (cq.Workplane("XY", origin=(-10.0, yy, 4.8))
.rect(21.0, f_tenon_w + 0.8).extrude(12.6).edges("|Z and <X").fillet(3.0)).val()
p02_c = p02_c.cut(front_mortise)
p02_c = p02_c.cut(cyl(2.75, -0.01, z1 + 1.0, -10.0, yy))
p02_c = p02_c.cut(cyl(5.0, z1 - 5.0, z1 + 1.0, -10.0, yy))
# Rear mortise pockets
for sign in (-1, 1):
yy = Y_COL + sign * r_tenon_y_span
rear_mortise = (cq.Workplane("XY", origin=(-185.0, yy, 4.8))
.rect(21.0, r_tenon_w + 0.8).extrude(12.6).edges("|Z and >X").fillet(3.0)).val()
p02_c = p02_c.cut(rear_mortise)
p02_c = p02_c.cut(cyl(2.75, -0.01, z1 + 1.0, -185.0, yy))
p02_c = p02_c.cut(cyl(5.0, z1 - 5.0, z1 + 1.0, -185.0, yy))
# Debossed text on P02_Center top face. The mid-plate line (y=Y_COL) is
# hidden behind the column collar and the gusset ribs, so both labels sit on
# the flat -Y side strip (y = Y_COL-68) where they stay in full view from the
# label side: REAR on the rear half, FRONT on the front half, clear of the
# clamp slot (x -101..-94) and the M5 screw counterbores.
txt_c_f = (cq.Workplane("XY", origin=(-49.0, Y_COL - 68.0, z1)).text("�� FRONT (�滚�) ��", 9.0, -0.8)).val()
txt_c_r = (cq.Workplane("XY", origin=(-146.0, Y_COL - 68.0, z1)).text("�� REAR (�𤾸�) ��", 9.0, -0.8)).val()
p02_c = p02_c.cut(cq.Shape(txt_c_f.wrapped)).cut(cq.Shape(txt_c_r.wrapped))
# 2. P02_Front (X = 0.0 .. 145.0, 145x190mm)
x_f_len = 145.0
x_f_mid = 72.5
f_plate = (cq.Workplane("XY", origin=(x_f_mid, Y_COL, z0))
.rect(x_f_len, y_width).extrude(z1)
.edges("|Z and >X").fillet(16.0).edges(">Z").fillet(2.0)).val()
p02_f = cq.Shape(f_plate.wrapped)
for cy in (Y_COL - 70.0, Y_COL + 70.0):
plane = cq.Plane(origin=(120.0, cy, -0.01), xDir=(0, 1, 0), normal=(0, 0, 1))
slot = cq.Workplane(plane).slot2D(28.0, 7.0).extrude(z1 + 1.0).val()
p02_f = p02_f.cut(slot)
for sign in (-1, 1):
yy = Y_COL + sign * f_tenon_y_span
tongue = (cq.Workplane("XY", origin=(-9.5, yy, 5.25))
.rect(20.0, f_tenon_w - 0.2).extrude(11.5).edges("|Z and <X").fillet(2.5).edges("<X").chamfer(1.5)).val()
p02_f = p02_f.fuse(cq.Shape(tongue.wrapped))
p02_f = p02_f.cut(cyl(2.75, -0.01, z1 + 1.0, -10.0, yy))
nut_pocket = (cq.Workplane("XY", origin=(-10.0, yy, -0.01)).polygon(6, 9.2).extrude(5.0)).val()
p02_f = p02_f.cut(nut_pocket)
# Top-face engraving rotated 90 deg to run across the plate along +Y (user
# request): letter tops face -X, so it reads upright from the front (+X).
# "��" points local +Y = world -X, i.e. toward the centre joint.
txt_f = (cq.Workplane(cq.Plane(origin=(x_f_mid, Y_COL, z1), xDir=(0, 1, 0),
normal=(0, 0, 1)))
.text("P02-FRONT �� JOIN", 8.0, -0.8)).val()
p02_f = p02_f.cut(cq.Shape(txt_f.wrapped))
# 3. P02_Rear (X = -240.0 .. -195.0, 45x190mm)
x_r_len = 45.0
x_r_mid = -217.5
r_plate = (cq.Workplane("XY", origin=(x_r_mid, Y_COL, z0))
.rect(x_r_len, y_width).extrude(z1)
.edges("|Z and <X").fillet(16.0).edges(">Z").fillet(2.0)).val()
p02_r = cq.Shape(r_plate.wrapped)
for cy in (Y_COL - 70.0, Y_COL + 70.0):
plane = cq.Plane(origin=(-215.0, cy, -0.01), xDir=(0, 1, 0), normal=(0, 0, 1))
slot = cq.Workplane(plane).slot2D(28.0, 7.0).extrude(z1 + 1.0).val()
p02_r = p02_r.cut(slot)
for sign in (-1, 1):
yy = Y_COL + sign * r_tenon_y_span
tongue = (cq.Workplane("XY", origin=(-185.5, yy, 5.25))
.rect(20.0, r_tenon_w - 0.2).extrude(11.5).edges("|Z and >X").fillet(2.5).edges(">X").chamfer(1.5)).val()
p02_r = p02_r.fuse(cq.Shape(tongue.wrapped))
p02_r = p02_r.cut(cyl(2.75, -0.01, z1 + 1.0, -185.0, yy))
nut_pocket = (cq.Workplane("XY", origin=(-185.0, yy, -0.01)).polygon(6, 9.2).extrude(5.0)).val()
p02_r = p02_r.cut(nut_pocket)
# Same +Y rotation as the front plate; "��" points local -Y = world +X,
# i.e. toward the centre joint. Along +Y the ~73 mm text fits the 190 mm
# plate width instead of overhanging its 45 mm X span.
txt_r = (cq.Workplane(cq.Plane(origin=(x_r_mid, Y_COL, z1), xDir=(0, 1, 0),
normal=(0, 0, 1)))
.text("P02-REAR �� JOIN", 7.5, -0.8)).val()
p02_r = p02_r.cut(cq.Shape(txt_r.wrapped))
return p02_c, p02_f, p02_r
def p_base_foot():
"""P02_摨閗� (�滚��脣�曄蕃頞�鵭�𥡝�摨訫漣 + ���憭扳⏛�V�閫鍦�撘箸��𤑳�):
1. 摨閧�撠箏站憭批��拙�銝� 385x240x22mm (X: -240.0..+145.0, Y: 8.0..248.0)嚗�
- �滚�撱嗡撓�� X = +145.0mm (�冽�����湔�敶勗��� 91.5mm)嚗�蝠摨閙�蝏脲����隡訾��𤘪𨘥�滨��嗥��滚�曄蕃嚗�
- �𤾸�撱嗡撓�� X = -240.0mm (�函��勗��� 92.0mm)嚗峕𠽌敺∪之�冽���蝔见�隞啣��抬�
2. 蝡𧢲��埝𦻖憟㛖��� 12mm 瘚�局憭批���漣銝� 48mm 擃睃��箏�蝑� (Z: 22.0..70.0mm嚗��憯�� 7mm)嚗�
3. �滚�憭找�閫鍦�撘箸��𤑳� (Z: 68.0->22.0mm, X: -75.0->-15.0mm, 摰� 38mm)嚗峕�撘臬���鵭颲� 60mm嚗𣬚�頞喳��券𡢿�嗘�撟脫��贝�餈𣂼𢆡嚗�
4. �𤾸�憭找�閫鍦�撘箸��𤑳� (Z: 70.0->22.0mm, X: -155.0->-225.0mm, 摰� 38mm)嚗峕��𦒘趕�𥡝��輯噢 70mm嚗�
5. �齿��𤏸”�Z挽 18mm 摰賢像皛𤏸粥蝥踹紡瑽踝�銝� P01 銝钅�韏啁瑪蝒堒藁�芰�韐舫�𡄯�
6. 6 蝏� M6 撌乩�撌乩��啁揮�箄�瑽� (28x7mm) + 摨閖��鞱𤪖韏啁瑪瑽踝�
7. �𥕦𪂹 R=18mm 憭批�閫坿�皜∩� 2.5mm 銝𡃏器蝻睃�坿���
"""
z0 = 0.0
z1 = 22.0
x_rear = -240.0
x_front = 145.0
x_len = x_front - x_rear # 385.0
x_mid = (x_rear + x_front) / 2.0 # -47.5
y_width = 240.0
# 1. 銝餃��� (385 x 240 x 22 mm)
base_plate = (cq.Workplane("XY", origin=(x_mid, Y_COL, z0))
.rect(x_len, y_width)
.extrude(z1)
.edges("|Z").fillet(18.0)
.edges(">Z").fillet(2.5)).val()
s = cq.Shape(base_plate.wrapped)
# 2. 蝡𧢲�憭硋��惩𤐄憟㛖� (Z: 22.0..70.0 mm, 憭硋� 80x80mm)
z_collar_top = 70.0
collar_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z1))
.rect(80.0, 80.0)
.extrude(z_collar_top - z1)
.edges("|Z").fillet(8.0)
.edges(">Z").chamfer(2.0)).val()
s = s.fuse(cq.Shape(collar_outer.wrapped))
# 3. �滚��堒�曄蕃銝㕑��惩撩�𨀣�蝑� (Front Triangular Gusset Rib)
f_pts = [
(-75.0, z1),
(-15.0, z1),
(-15.0, z1 + 4.0),
(-75.0, 68.0),
]
f_rib = (cq.Workplane("XZ", origin=(0, Y_COL, 0))
.polyline(f_pts).close()
.extrude(19.0, both=True)).val()
s = s.fuse(cq.Shape(f_rib.wrapped))
# 4. �𤾸��堒�曄蕃銝㕑��惩撩�𨀣�蝑� (Rear Triangular Gusset Rib)
r_pts = [
(-155.0, z1),
(-225.0, z1),
(-225.0, z1 + 4.0),
(-155.0, 70.0),
]
r_rib = (cq.Workplane("XZ", origin=(0, Y_COL, 0))
.polyline(r_pts).close()
.extrude(19.0, both=True)).val()
s = s.fuse(cq.Shape(r_rib.wrapped))
# 5. �齿��𤏸”�Z粥蝥踹紡瑽� (銝� P01 �滩粥蝥輻� Z=70..140mm �芰�憿箸𦻖)
wire_guide_pts = [
(-75.5, z1 + 1.0),
(-14.0, z1 + 1.0),
(-14.0, z1 + 4.0),
(-75.5, 68.5),
]
wire_guide = (cq.Workplane("XZ", origin=(0, Y_COL, 0))
.polyline(wire_guide_pts).close()
.extrude(9.0, both=True)).val()
s = s.cut(wire_guide)
# 6. 蝡𧢲�瘛望�瑽賢��� (Pocket: 66.6 x 66.6 mm, �� 0.3mm 蝎曉�皛煾��湧�)
socket_box = (cq.Workplane("XY", origin=(X_COL, Y_COL, 10.0))
.rect(66.6, 66.6)
.extrude(z_collar_top - 10.0 + 1.0)
.edges("|Z").fillet(6.3)).val()
s = s.cut(socket_box)
# 7. 4x M5 摨閖���凒蝝批𤐄�箸�摮𥪯�瘝匧�
for xx in (X_COL - 21.0, X_COL + 21.0):
for yy in (Y_COL - 21.0, Y_COL + 21.0):
th = cyl(2.75, -0.01, 10.5, xx, yy)
cb = cyl(5.0, -0.01, 6.0, xx, yy)
s = s.cut(th).cut(cb)
# 8. 6 蝏� M6 撌乩�撌乩��啁揮�箄�瑽� (28 x 7 mm)
slot_positions = [
(-215.0, Y_COL - 85.0), (-215.0, Y_COL + 85.0), # �𡡞�銝方�
(-47.5, Y_COL - 95.0), (-47.5, Y_COL + 95.0), # 銝剝�銝支儒
(120.0, Y_COL - 85.0), (120.0, Y_COL + 85.0), # �漤�銝方�
]
for cx, cy in slot_positions:
plane = cq.Plane(origin=(cx, cy, -0.01), xDir=(0, 1, 0), normal=(0, 0, 1))
slot = cq.Workplane(plane).slot2D(28.0, 7.0).extrude(z1 + 1.0).val()
s = s.cut(slot)
# 9. 摨閖��鞱𤪖韏啁瑪�𡁏局
wire_ch = (cq.Workplane("XY", origin=(X_COL, Y_COL - 80.0, -0.01))
.rect(28.0, 100.0)
.extrude(6.0)).val()
s = s.cut(wire_ch)
return s
def p_girdle(j1):
"""P03_�拙����鋆���� (頧駁��𡝗踎撘𤩺��嗥� + 靘批�撘讐㩞�箸���):
1. 10mm �𡒊垢�滩蝸瘜訫��� (X: -61.0..-51.0, 74x74mm)嚗�
2. 銝餃僕�� 66mm 摰𧼮��埈㺿銝箏�靘� 6mm 獢�沲蝡𡝗踎 (Y = Y_ARM 簣 27..33)嚗��頧桀�靽脲��抒�
"銝餃僕 �� 靘抒�"撟園�銝滚� �婙�� �芸��鞉�銝滚�雿梶妖嚗屸妟�啣�撟脫�憌𡡞埯嚗𥕦�敹� 728 -> 286 cm糧 (-61%)嚗�
3. 蝡𡝗踎撣鞟窈敶W��滨� (憿�/摨閙��� ��52簞嚗諹䌊�舀�嚗𥕢� 20mm 撟喲▲�舀‘��)嚗�
4. 摨閖� 9mm �踹��滚漣 + 43.4x43.4 摰帋�璁怠仍 (�� P01_C 44x44 ���嚗��颲� 0.3mm �湧�)嚗�
�滚漣摨閖𢒰 66x66 銝𡒊��梢▲�臬蒂�踹��Y妖 2403mm簡 �婙�� 蝡硋�頧質㭘韏圈𢒰�页��箸��芷俈銝𦠜䠋/�脫�嚗�
5. 4x 摰㕑�摮� (X_COL簣27.5, Y_COL簣13.5)嚗煳�3.9 �游�嚗愢4x16 隞𦒘��寧凒�交𠾶�亥䌊�餅���
嚗��摨找�蝡𧢲�憿嗥㴓���嚗峕�餈��/瘝匧�/憸��嚗㚁��舀�鋆��
6. 銝贝�銝剖亢樴䠷爸蝑� (12mm 銝凋��寞踎嚗諹䌊�滚漣�𨀣��單��唬�蝻�) + 憿園�璅芸���揮�舀�蝑� (66x9x10mm嚗�
銝𦒘舅靘抒��踹��a�撟喋��▲�W��函��輯�蝥蹂�嚗䔶�憿嗅�璉曹��� 2mm �坿�)嚗�
7. 靘批�撘讐㩞�箸��� (+Y靘批�撘�, X: -51.0..11.5嚗��蝡舫� X_BAY_EXT �滚辣 3mm)嚗�
M1 �菜㦤�臭�靘扳䲮�𨀣��∪�鋆��嚗��瑽賣��菜㦤�� 3mm嚗㚁��勗�蝡舀��� 4xM3x16 ��香嚗�
�菜㦤�� �60.7 隞𤾸�蝡舐凒�𡁜��滨垢�g�2026-10-02 �冽�鋆��"�餅��圈𧫴�寞�撟喟�"嚗𡁏��臬耦�圈𧫴��
�惩��剝𤣳嚗𥕦��滨蔭甇Z���揮瘜訫� 4xM3 �譍��𡝗�嚗𣬚㩞�箄蓬�𤑳眏�𡒊垢 4xM3x16 蝥行�嚗㚁�
9. 銝支儒憭折𢒰蝘舀袇�剛�蝒� (34x20mm) + 憿園��峕��穃笆瘚���剜局 (30x6.5mm)嚗𣬚&靽脲袇�剔��𡄯�
10. �26mm 銝剖亢韏啁瑪摮䈑�蝡𡝗踎�港蛹撘��曇�雿橒��惩��剔征�䈑�嚗愢3 �箔����𡁻��湔𦻖韏啗�雿橒��抒揮�湧◇�卝��
"""
X_MOUNT = Z_R1 # -51.0 (Rear face of M1)
T_FLANGE = 10.0 # 10mm thick high-strength mounting flange
X_BACK = X_MOUNT - T_FLANGE # -61.0
Y_ARM = Y_AXIS # 128.0
Z_ARM = Z_RL # 610.0
Y_P_IN = 27.0 # 獢�沲蝡𡝗踎��”�� (Y_ARM 簣 27)
Y_P_OUT = 33.0 # 獢�沲蝡𡝗踎憭𤥁”�� (銝擧唂銝餃僕朣𣂼像)
T_SADDLE = 9.0 # 摨閖��滚漣�𡁜漲
TENON = 43.4 # 摰帋�璁怠仍颲寥鵭嚗㇊01_C ��� 44x44 R4嚗��颲寧� 0.3mm嚗�
WIN_R = 4.0 # 蝡𡝗踎�誯�蝒堒�閫鍦�閫𡜐�瘨�膄���閫鍦��偦�銝哨�Kt �� ~2.5 �滚� ~1.2嚗�
BOLT_DX, BOLT_DY = 27.5, 13.5 # 4x 摰㕑�摮𠉛㮾撖寧��曹葉敹��蝘鳴��賢銁憿嗥㴓 11mm 摰硺�憯��
# 1. 銝餃�鋆���啁� (74x74mm, �𥡝��鍦� R=8mm)
# �屸𢒰��� 2mm �坿�撌脣縧�㚁��踵��芯撓餈𥟇��� 0.1mm嚗��坿��V��輯��Y㮾鈭支���
# Z��574.9 �文枂銝��� 2mm �剜ㄠ嚗峕迤�航��寧�璉梯悟�湔辺鈭斗𦻖��ㄠ蝵𤑳��雴��箏�閫𡜐�
# �峕𧒄摰�楊餈� R8 閫㘾���憫嚗�停�航�銝𢠃���"�瑁絲��"���芸�坿���
flange = (cq.Workplane("YZ", origin=(X_BACK, Y_ARM, Z_ARM))
.rect(74.0, 74.0)
.extrude(T_FLANGE)
.edges("|X").fillet(8.0)).val()
s = cq.Shape(flange.wrapped)
# 2. �䔶儒獢�沲蝡𡝗踎 (6mm)嚗𡁏唂"�𨀣��舀�銝餃僕"銝�"憭找�閫鍦�撘箇�"頧桀��峕挾�文枂 �� �芸𢆡撟園��𣂼��𦯀儒��
# 銝餃僕���蝻䀝舅�孵��典�撘箇��𡏭器��辣�輻瑪銝𠺪�雿踹�頧桀�憿園��𣂷蛹銝��湔辺�渡瑪
# 嚗�炏�坔�蝻� (-148,550) 憭�� 5簞 �条����銝� 5mm �圈𧫴嚗剹��
# Z_CREST = 靘抒��羓瑪擃睃漲嚗���嗆糓憿嗥� 2mm 憿嗅��坿����瘝選��坿�隞� (X-71,Z_CREST)
# �靝��� (X-69,Z_CREST+2) = 憿嗥�憿園𢒰嚗峕��⊿𢒰銝𤾸�坿��W�銋𡒊㮾���憿園�霂餉絲�交糓銝��游��U��
Z_CREST = Z_ARM + 33.0 # 643嚗���� 642嚗偦▲蝑𧢲㟲雿㮖�蝘� 3mm 霈拙枂�單�蝛粹𡢿�舘����穿�
RIB_SLOPE = (Z_CREST - 575.0) / ((X_BACK - 10.0) - (X_COL - 15.0))
def rib_line_z(x):
return Z_CREST + RIB_SLOPE * (x - (X_BACK - 10.0))
trunk_pts = [
(X_COL - 33.0, Z_CHEST1),
(X_COL + 33.0, Z_CHEST1),
(X_COL + 33.0, 505.0),
(X_BACK + 0.1, 565.0),
(X_BACK + 0.1, Z_ARM - 5.0),
(X_COL - 10.0, rib_line_z(X_COL - 10.0)),
(X_COL - 33.0, rib_line_z(X_COL - 33.0)),
]
rib_pts = [
(X_COL - 33.0, Z_CHEST1), # 摨閗器銝斤垢銝𦒘蜓撟�/�滚漣撖寥� (簣33)嚗𡁜��交𤣰餈� 3mm嚗�
(X_COL + 33.0, Z_CHEST1), # 隡𡁜銁�滚漣憿園𢒰銝羓�銝� 0.7/3mm �剜ㄠ嚗�㨃雿𤩺㟲�∪�璉勗�閫�
(X_BACK + 0.1, 565.0),
(X_BACK + 0.1, Z_CREST),
(X_BACK - 10.0, Z_CREST), # �羓瑪 (-71,643)嚗𡁏迤憟質氜�券▲蝑见��V� 2mm �坿�銝𧢲窒��漱��
(X_COL - 15.0, 575.0),
(X_COL - 30.0, 530.0),
]
for sign in (-1, 1):
ya = Y_ARM + sign * Y_P_IN
yb = Y_ARM + sign * Y_P_OUT
y0, y1 = min(ya, yb), max(ya, yb)
for prof in (trunk_pts, rib_pts):
s = s.fuse(cq.Shape(Yplate(prof, y0, y1).wrapped))
# 3. 蝡𡝗踎�誯�蝒� (撣鞟窈敶g��𣈯𢒰 ��52簞 �芣𣈲�㻫��� 20mm 撟喲▲�舀‘�伐��踹��滚漣銝� M5 �箸���)
# 6 銝芸�閫鍦��� R4 ���嚗𡁏����閫鍦��偦�銝� (Kt��2.5) �滚� ��1.2嚗���嗅�閫㘾𢒰隞齿糓蝡𣇉凒/�芣𣈲�煾𢒰
win_pts = [
(X_COL - 24.0, 498.0), (X_COL + 23.0, 498.0), (X_COL + 25.0, 522.0),
(X_COL + 10.0, 545.0), (X_COL - 10.0, 545.0), (X_COL - 25.0, 524.0),
]
for sign in (-1, 1):
yc = Y_ARM + sign * 0.5 * (Y_P_IN + Y_P_OUT)
tool = (cq.Workplane("XZ", origin=(0, yc, 0)).polyline(win_pts).close()
.extrude(Y_P_OUT - Y_P_IN + 1.0, both=True)
.edges("|Y").fillet(WIN_R).val())
s = s.cut(cq.Shape(tool.wrapped))
# 4. 摨閖��踹��滚漣嚗𡁜�摰䂿��梢▲�g��𠹺舅蝡𡝗踎���撉其�璁怠仍餈墧��港�
s = s.fuse(bx(X_COL - 33.0, X_COL + 33.0, Y_ARM - Y_P_OUT, Y_ARM + Y_P_OUT,
Z_CHEST1, Z_CHEST1 + T_SADDLE))
# 5. 銝贝��函熊�烐�撘舫�撉函� (12mm 銝凋��寞踎嚗諹䌊�滚漣�𨀣��單��啗��g�鈭斗𦻖��ㄠ�刻�����𡁶� 3D ���)
keel_pts = [
(X_COL + 33.0, Z_CHEST1), # (-82, 470)
(X_COL + 33.0, 495.0), # (-82, 495)
(X_BACK + 0.1, 573.0), # (-60.9, 573) �𨀣��單��啗���
(X_BACK + 0.1, 594.4), # (-60.9, 594.4) 憿嗥垢韐湔���
(X_COL + 42.1, 585.0), # (-72.9, 585)
(X_COL + 20.0, Z_CHEST1), # (-95, 470) �屸𢒰銝�頝舀��啣�嚗𡁜��亙銁 (-95,480) �劐葵�条�嚗�
] # �条�蝳駁�摨折▲�W蘨 1mm嚗朙2.5 ����砌�銝𠰴縧 �� 樴䠷爸摨閙ㄠ�渡��雴���
s = s.fuse(cq.Shape(Yplate(keel_pts, Y_ARM - 6.0, Y_ARM + 6.0).wrapped))
# 7. 憿園�璅芸���揮�舀�璅芰�嚗枠 �睲�銝斤��踹��a�撟� (Y_ARM簣33)����V�蝑𧢲踎�羓瑪�梢𢒰 (X=-71)��
# 憿園𢒰 Z=645 �衤��羓瑪 (Z=643) 撟嗡� 2mm 憿嗅��坿��詨� �� 憿嗥�銝𦒘舅靘扯�蝥踹��𣂷��游���
# �港�瘥𥪜���䠋擃� 3mm (摨閖𢒰 633��636)嚗�4x M3 �𡒊垢瘝匧� �6.5 頝典銁 Z 627.2..633.7 銝𠺪�
# 摨閖𢒰 633 隡𡁜�雿誩����瘝� 0.7mm����贝悟雿滚蘨�抵��湧�嚗𥟇䠋�� 636 �𡡞���啣������ 2.3mm��
# 蝳餉卽�㕑蓬蝥� 5.55mm��▲�� 645 銝滩�餈���� R8 閫㘾���憫�� Y=95 憭�� 645.9 銝羓���
tie_rib = (cq.Workplane("YZ", origin=(X_BACK - 10.0, Y_ARM, Z_ARM + 30.5))
.rect(66.0, 9.0)
.extrude(10.0)
.edges(cq.selectors.BoxSelector((X_BACK - 10.5, Y_ARM - 34.0, Z_ARM + 34.5),
(X_BACK - 9.5, Y_ARM + 34.0, Z_ARM + 35.5)))
.chamfer(2.0)).val()
s = s.fuse(cq.Shape(tie_rib.wrapped))
# 6.y 雿�-雿㮖漱�亙篅璉梧��滚�摰峕��𤾸笆"�寞ㄠ"�湔𦻖�𡁶� 3D �����
# �笔�餈䠷��舀�撌交窒璉� fuse �� 10 ��"甇�䲮敶T��𥕦�銋衤���"�羓�撠譍�嚗Ócove嚗㚁�撌脫㟲雿枏��歹�
# �羓�蝡舫𢒰�臬像������典�蝛綽�銝斗辺鈭垍㮾��凒����惩銁閫雴�鈭雴��剜𦻖 �� ���"蝻箔���"嚗�
# 撟嗡��賊�雿梶�璉曹��貊忽�垍� 1~3mm簡 蝣𡡞𢒰�������券𢒰颲寧��芰��嗅藁���璉梁㮾鈭文��� OCC
# ���閫㘾�銵亦���
from cadquery import selectors as _sel
from OCP.BRepAdaptor import BRepAdaptor_Surface
from OCP.GeomAbs import GeomAbs_Plane
from OCP.TopAbs import TopAbs_REVERSED
def _outward(f, sh):
"""撟喲𢒰�Y�憭𡝗��𡢅���� Orientation 靽格迤嚗����"�V葉敹��蝘� 1mm �臬炏隞滚銁摰硺���"�𨀣䲮�㻫��"""
ad = BRepAdaptor_Surface(f.wrapped)
if ad.GetType() != GeomAbs_Plane:
return None
ax = ad.Plane().Axis().Direction()
n = cq.Vector(ax.X(), ax.Y(), ax.Z())
if f.wrapped.Orientation() == TopAbs_REVERSED:
n = n * -1.0
c = f.Center()
if cq.Solid(sh.wrapped).isInside(cq.Vector(c.x + n.x, c.y + n.y, c.z + n.z), 1e-6):
n = n * -1.0
return n
def _fillet_reflex(lo, hi, radii, tag, eps=0.9):
"""�鍦枂 lo~hi �箏�����寞ㄠ嚗�舅�W允 270簞 �鞉�嚗剹��ế�殷�隞擧ㄠ銝剔�瘝� (n1-n2) 憭𡝗䔝 eps嚗�
�賢銁摰硺��� = �嫘��氜�典� = �詻��躹�笔��寞ㄠ��㟲�嫣�甈∪�𡜐��𠰴��鞟漣�滨漣嚗䔶��鍦�撉峕��𡢅�
OCC 隡𡁶���"瘝⊥�撘�虜雿�𢒰撌脣�"����頣�嚗�遣銝滚枂�嗆��貉�璉勗�蝏��鞟��鉝��"""
nonlocal s
def _pick(sh):
edges = sh.Edges()
idx = {}
for i, e in enumerate(edges):
idx[e.hashCode()] = i
adj = [[] for _ in edges]
for f in sh.Faces():
for ee in f.Edges():
k = idx.get(ee.hashCode())
if k is not None:
adj[k].append(f)
box = _sel.BoxSelector(lo, hi)
out = []
for i, e in enumerate(edges):
if e.Length() <= 6.0 or len(adj[i]) != 2 or not box.filter([e]):
continue
n1 = _outward(adj[i][0], sh)
n2 = _outward(adj[i][1], sh)
if n1 is None or n2 is None:
continue
dx, dy, dz = n1.x - n2.x, n1.y - n2.y, n1.z - n2.z
ln = math.sqrt(dx * dx + dy * dy + dz * dz)
if ln < 1e-6:
continue
p = e.Center()
if cq.Solid(sh.wrapped).isInside(
cq.Vector(p.x + dx / ln * eps, p.y + dy / ln * eps,
p.z + dz / ln * eps), 1e-6):
out.append(e)
return out
es0 = _pick(s)
if not es0:
print(" [P03 �笔�閫哋 %-14s �箏�����寞ㄠ嚗諹歲餈�" % tag, flush=True)
return
def _groups(ee):
"""�匧�蝡舐��𠰴篅璉梯��鞾曎/蝵𤑳�嚗帋�蝏��甈∪�𡜐�OCC �滩��其漱瘙�����閫㘾�銵亦�嚗�
�鞉辺�雴��其漱瘙���嗘��剖藁嚗����撠勗�����雴��𠰴�鈭����"""
pts = [e.Vertices() or [e.Center()] for e in ee]
par = list(range(len(ee)))
def find(a):
while par[a] != a:
par[a] = par[par[a]]
a = par[a]
return a
for i in range(len(ee)):
for j in range(i + 1, len(ee)):
if any(pi.distance(pj) < 0.05 for pi in pts[i] for pj in pts[j]):
par[find(i)] = find(j)
g = {}
for i in range(len(ee)):
g.setdefault(find(i), []).append(ee[i])
return list(g.values())
def _do(edges_, rr):
"""�鍦�蝡见�撉峕��𡢅�OCC 隡𡁶���"瘝⊥�撘�虜雿�𢒰撌脣�"����頣�敹�◆�∩��乓��"""
try:
ns = cq.Shape(cq.Solid(s.wrapped).fillet(rr, edges_).wrapped)
except Exception:
return None
return ns if cq.Solid(ns.wrapped).isValid() else None
# ���"�箏�����典篅璉曹�甈∪��"嚗�䔝���瘚贝��瑁��湔鸌�𣂼�嚗䔶��芷�撱箔�甈∴�
# 銝滢��誩��寥��瑟��䔶�撘𣳇𢒰�滚��滨��𤩺�嚗㚁�銝滩��齿��貉�璉勗�蝏��鞟��鉝��
for rr in radii:
ns = _do(es0, rr)
if ns is not None:
s = ns
print(" [P03 �笔�閫哋 %-14s %d �∪篅璉� R%.1f �� �湔鸌銝�甈⊥���"
% (tag, len(es0), rr), flush=True)
return
n_ok, n_grp, left = 0, 0, len(es0)
for _ in range(24):
es = _pick(s)
if not es:
break
got = False
for g in sorted(_groups(es), key=lambda g: -sum(e.Length() for e in g)):
for rr in radii:
ns = _do(g, rr)
if ns is None:
continue
s = ns
n_ok += len(g)
n_grp += 1
print(" [P03 �笔�閫哋 %-14s 蝚�%d蝏� %d �� R%.1f ��"
% (tag, n_grp, len(g), rr), flush=True)
got = True
break
if got:
break
if not got:
left = len(es)
break
print(" [P03 �笔�閫哋 %-14s �� %d 蝏� %d �∪篅璉勗�鍦�嚗�� %d �∩����璉�"
% (tag, n_grp, n_ok, left), flush=True)
XR, YC, ZS = X_BACK, Y_ARM, Z_CHEST1 + T_SADDLE # -61, 128, 479
# �婙�� �滚漣憿園𢒰 (Z=479) 銝羓�鈭斗𦻖��ㄠ嚗𡁻�撉其��� + 銝斤��踹�靘找舅�∴�銝�甈∠���� �婙��
# �𠰴�銝𢠃� 2.0嚗𡁻�撉其儒�� Y=122 銝� M5 �粹�憭游�蝻� Y=118.75 �芷� 3.25mm嚗�
# ��䔉�� R3 �羓�隡𡁻▲�啗卽撣賣㗁�贝器嚗朙2.0 �� 1.25mm��
_fillet_reflex((X_COL - 34.0, Y_ARM - 40.0, ZS - 3.0),
(X_COL + 34.0, Y_ARM + 40.0, ZS + 7.0),
(2.0, 1.5), "�滚漣憿園𢒰鈭斗𦻖")
# �婙�� 瘜訫��屸𢒰 (X=-61) 銝羓�鈭斗𦻖��ㄠ嚗𡁜蘨�垍���/樴䠷爸����湔ㄠ �婙��
# 憿嗥�摨閖𢒰��辺瘞游像璉� (Z=636) 銝滚�𡜐�4x M3 瘝匧� �6.5 �� Z 627.2..633.7嚗�
# �雴� R2.5 隡𡁏��粹�銝𦠜䲮 5.55mm ����贝悟雿滚��� 2.5mm��
# 銝羓��� 631嚗𡁶��踹�璉梯◤憿嗥�摨閖𢒰��� 573..636 / 636..643 銝斗挾嚗�蘨�雴��a鵭���畾�
# �婙�娍� 636..643 �� 7mm �剜挾撟嗉��伐��湔鸌撠曹�"銝�甈⊥���"���𡝗��鞟����撠穃�� 6 �~��
_fillet_reflex((X_BACK - 3.0, Y_ARM - 40.0, 570.0),
(X_BACK + 3.0, Y_ARM + 40.0, 631.0),
(2.5, 2.0, 1.5), "蝡𡝗踎/樴䠷爸�娍���")
_fillet_reflex((X_BACK - 3.0, Y_ARM - 40.0, Z_ARM + 34.5),
(X_BACK + 3.0, Y_ARM + 40.0, Z_ARM + 35.5),
(1.5, 1.0), "憿嗥�憿嗯�瘜訫�")
# 銝𡒊��梢▲�券����摰帋�璁怠仍 (43.4x43.4x15mm)嚗𡁻� P01_C 44x44 R4 ���嚗��颲� 0.3mm 皛煾�
boss = (cq.Workplane("XY", origin=(X_COL, Y_COL, Z_CHEST1 - 15.0))
.rect(TENON, TENON)
.extrude(15.0)
.edges("|Z").fillet(4.2)).val()
s = s.fuse(cq.Shape(boss.wrapped))
# 4x 摰㕑�摮䈑�蝏煺� �3.9 �游�嚗㇈4x16 隞舘�雿𤘪迤銝𦠜䲮�批��芣𤫇�𣂼�嚗偦�摨找�蝡𧢲�憿嗥㴓������瘝匧�嚗�
# 摮𥪯� (X_COL簣27.5, Y_COL簣13.5) �峕𧒄皛∟雲嚗尠��函��梢▲�臬�雿枏������� 22 �� 憭硋� 33嚗㚁�
# �∪銁 P03 銝斤��蹂��氬���撘�銝剝𡢿樴䠷爸嚗䔶��𥪯�甇���寧鍂�單��舐凒�交𠾶蝝扼��
for xx in (X_COL - BOLT_DX, X_COL + BOLT_DX):
for yy in (Y_COL - BOLT_DY, Y_COL + BOLT_DY):
s = s.cut(cyl(1.95, Z_CHEST1 - 0.5, Z_CHEST1 + T_SADDLE + 0.5, xx, yy))
# 1x 璅芸��脰���揮嚗𡁏托憭� �𣜿 靘批��� �3.9x14 �游�嚗��蝡𧢲��𤾸� �3.9 摮𥪜�頧湛�M4x16 �批��芣𤫇嚗�
s = s.cut(Xcyl(1.95, X_COL - TENON / 2.0 - 1.0, X_COL - TENON / 2.0 + 14.0, Y_COL, Z_LOCK))
# 4x M3 餈墧𦻖�箏�嚗�卽銝嘥��𡁻��湔𦻖韏唬舅蝡𡝗踎銋钅𡢿����曇�雿橒��𣳇��漤凃 �8.5 �湧�𡁻银�橒�
# 摮𥪯� = �菜㦤撠曄垢 4x M3 �箇犒敺��瑽賢�瘚衤�嚗�㩞��.STEP嚗㚁�BCD55��㮾雿� 39.9簞+90k��
# �� 35.1�40.9 �拙耦摮磰�銝𤾸���局雿滚榆 ~4.7mm嚗�笆閫雴舅憸𡑒卽�㗇�憭�俥���嚗�
# 2026-10-02 �冽���枂"�粹�瘝⊥�撖寥�"�擧� STEP 摰墧�靽格迤��
for dy, dz in ((21.06, 17.65), (-17.65, 21.06), (-21.06, -17.65), (17.65, -21.06)):
py = Y_ARM + dy
pz = Z_ARM + dz
th = Xcyl(1.7, X_BACK - 0.5, X_MOUNT + 4.0, py, pz)
cb = Xcyl(3.25, X_BACK - 0.5, X_BACK + 4.5, py, pz)
s = s.cut(th).cut(cb)
# 銝剖亢韏啁瑪摮� (�26mm)
wire_hole = Xcyl(13.0, X_COL - 40.0, X_MOUNT + 2.0, Y_ARM, Z_ARM)
s = s.cut(wire_hole)
# 6. �滚��菜㦤�典��䀹沲 (X: -51.0..8.5+X_BAY_EXT=11.5嚗䁱�60.7 �勗�撟喟凒韐舫�𡁜�蝡舫𢒰)
# 蝡舫𢒰�𤩺�瑽賢��踹�撱� X_BAY_EXT嚗𥕦��輯���(10.5+X_FORK_GAP=11.5)銝𡒊垢�� 0.0 蝖祈斐撟�
# 嚗�鍂�瑚舅甈∟�瘙�"�墧�撟喟�"嚗桕1 頧砍𢆡�拇𣑐�梁鍂�瑞䰻�㚁��烐隆�嗅虾敺格𠹭 M2嚗�
X_FRONT = 8.5 + X_BAY_EXT
R_POD = 36.5
R_BORE = 30.35
cradle_outer = (cq.Workplane("YZ", origin=(X_MOUNT - 0.1, Y_ARM, Z_ARM))
.circle(R_POD)
.extrude(X_FRONT - X_MOUNT + 0.1)
.edges(">X").chamfer(1.5)).val()
s = s.fuse(cq.Shape(cradle_outer.wrapped))
# �菜㦤摰𡁜��滚����嚗��蝏�𠶖���2026-10-02 �冽�鋆��"�餅��圈𧫴�寞�撟喟�+靽萘��箏��菜㦤��𢒰"嚗㚁�
# �60.7 ���摮𥪜�隞𤾸�蝡舫𢒰撟喟凒韐舫�𡁜��勗�嚗��蝒������圈𧫴�����号�伐�嚗�
# �勗� = 銝�銝芸��渡�撟喳繿�舫𢒰嚗Ǎ=5.06+X_BAY_EXT=8.06嚗䔶��埝局�怎垢憓坔��g�銝剖� �39 �詨蝱餈��嚗�
# �婙�𥪜朖�菜㦤�漤�雿漤𢒰��㩞�箄蓬�𤑳眏�𡒊垢瘜訫� 4xM3x16 蝥行�嚗�
# �滨垢��揮�� 4 銝� �10 撅��典瑌�唬��� M3 ���憭渲卽�㗇㗁���閫���孵瑌�唳挾嚗剹��
motor_pocket = Xcyl(R_BORE, X_MOUNT - 0.2, 5.06 + X_BAY_EXT, Y_ARM, Z_ARM)
s = s.cut(motor_pocket)
# 4x �滨蔭 M3 ��揮�粹��詨蝱嚗㇂CD=55mm嚗�17.8簞/107.8簞/197.8簞/287.8簞嚗㚁�
# 撟喟凒�勗����憭游漣雿滨眏 4 銝� �10 撅��典瑌�唳㗁頧賤�婙�𥪜瑌�唬�鈭舘�摮𥪜�畾� 8.06..11.5嚗�
# �菜㦤�滨垢��(5.0)銋见� 3mm嚗𣬚㩞�箸��坿楝敺��蝏讛�嚗㛈3x8 ���憭游��典瑌�唳�摮�
# 摨�(x=9.5)�见��菜㦤�滨垢�g��砍� 3.5mm嚗��雿𦦵㩞�箏�蝡舫俈頧砍�雿溻��
for deg in (17.8, 107.8, 197.8, 287.8):
rad = math.radians(deg)
fy = Y_ARM + 27.5 * math.cos(rad)
fz = Z_ARM + 27.5 * math.sin(rad)
s = s.fuse(Xcyl(5.0, 5.06 + X_BAY_EXT, X_FRONT, fy, fz))
th = Xcyl(1.6, 5.06 + X_BAY_EXT, X_FRONT, fy, fz)
cb = Xcyl(3.0, X_FRONT - 2.0, X_FRONT, fy, fz)
s = s.cut(th).cut(cb)
# J1 颲枏枂�詨蝱餈�� (�39 � 3.44�婙�渄1 �詨蝱銝� 3xM2 颲枏枂�粹����蝏誩�嚗屸��圈𧫴嚗�
# �� 6.7mm �輸�銝𤾸���蝱�拙歇�讛�摨訫�蝘颱�撟嗆���)
hub_clearance = Xcyl(19.5, 4.8, X_FRONT + 0.5, Y_ARM, Z_ARM)
s = s.cut(hub_clearance)
# 8. �菜㦤�䀹沲 +Y 靘批�撘�嚗�儒撘�撘誩�����蹂誨�笔��剖����嚗㚁�
# M1 �菜㦤�臭� +Y 靘扳䲮�渡瑪皛穃��䀹沲摰峕�鋆���婙�𥪜�撠�𡡒蝑垍㩞�箇�����䭾�鋆����
# 頧游�蝥行�嚗𡁜�蝡舀��� 4xM3嚗�㩞�箏偏蝡舫𢒰嚗匧��煾�甇鳴��滨蔭甇Z�瘜訫��誩像�渲�摮磰�瘙��瘨��嚗�
# 敺��蝥行�嚗煳�60.7 蝎曉�皛煾��䀹沲摨� + �滚�韐游�������蝡航秐 5.06+X_BAY_EXT=8.06
# 嚗���菜㦤�滨垢�W� 3mm �𨀣�雿䠷�嚗𣬚㩞�箏虾�暹��∪�嚗㚁�甇Z�瘜訫��舫�銋见�蝘颯��㴓摰賭��� 3.44mm��
s = s.cut(bx(X_MOUNT, 5.06 + X_BAY_EXT, Y_ARM, Y_ARM + 60.0, Z_ARM - 60.0, Z_ARM + 60.0))
# 7. ���蝟餌�嚗𡁜�靘批之閫�� + 憿園��𨅯�撖寞��垍�瑽�
for sign in (-1, 1):
win_plane = cq.Plane(
origin=(-24.5, Y_ARM + sign * 35.0, Z_ARM),
xDir=(1, 0, 0),
normal=(0, sign, 0)
)
win_cut = cq.Workplane(win_plane).slot2D(34.0, 20.0).extrude(16.0, both=True).val()
s = s.cut(win_cut)
for deg in (45, 135):
rad = math.radians(deg)
slot_plane = cq.Plane(
origin=(-24.5, Y_ARM + 33.0 * math.cos(rad), Z_ARM + 33.0 * math.sin(rad)),
xDir=(1, 0, 0),
normal=(0, math.cos(rad), math.sin(rad))
)
slot_cut = cq.Workplane(slot_plane).slot2D(30.0, 6.5).extrude(15.0, both=True).val()
s = s.cut(slot_cut)
return s
def p_fork(j1, j2):
"""P04_�拙�_�箸�雿�30%_憓�5摨�5_蝡𡝗� (Shoulder Fork / L-Bracket) - �𣳇鵭�輯悟憿箸�瘚�瑪��:
1. 憭湧�銝舘澈摮鞱絲�寡䌊 X=5.5 �滨宏�𣳇鵭�� X=10.5+X_FORK_GAP=11.5嚗���輯��V� P03 �䀹沲蝡舫𢒰
(X=8.5+X_BAY_EXT=11.5) 0.0 蝖祈斐撟喉�2026-10-02 �冽�銝斗活閬��"�墧�撟喟�"嚗�
P03 靘扳�瑽賜𡠺蝡见��� 3mm 靘蹂� M1 �菜㦤�𨀣��∪�嚗㚁�
2. J1 隞𤾸𢆡瘜訫����撌脣���(�㗛𢒰�� column �滨�敶X�曌𤘪�)嚗麿1 �� boss(�35.6)韐舫�� P03 �滨�銝剖�摮𠉛凒餈䂿㩞�箄��箇�嚗𢲷olumn 憿嗉器靽脲� Z=646.5 銝� P03 �舫�擃矋�R=18mm 憭批�撘折◇皛𤏸�皜∴�
3. 憭湧�頧祆𦻖�詨蝱�𣳇鵭韐舫�� P03 �滨�銝剖�摮� (R=19.5mm)嚗𣬚凒餈� J1 �贝蓮瘜訫��矋�
4. M2 靽萘��𡒊垢摰㕑���(R=35mm, 撣� rear_mount_holes �粹�摮�)嚗��蝡臬�雿滨㴓曌枏枂���撌脣���(�滨垢摰帋��� column 蝡舫𢒰 pocket �踵�)嚗䔶葉�湧�蝛箸袇�哨�
4b. ��2026-10-02 �啣��餹2 �滨垢�讠�嚗𡁜��寞��菜㦤�芾◤�𡒊垢摰㕑���(S02 4xM3x10)�閖𢒰��香嚗�
憭扳酞�拐��菜㦤蝏� Y 頧游銁 �60.3 摨批��𣬚�憭�/蝧䁅絲嚗�𤐄摰帋��U��緵�典�蝡舐�憭𣇉垢��
(Y=156.0) �滚�銝��𡁜�敺� R35 �讠�嚗𣬚鍂 4x M3x8 �函㩞�箏�蝡舐� BCD55 銝𦠜��菜㦤
隞𤾸�蝡臬允銝�甈� �婙�� �菜㦤鋡怠��𦒘舅�堒�敹� �60.3 蝡舫𢒰���憭寧揮嚗��暹��芰眏摨血��塚�
�粹�瘝匧銁�讠�瘝匧����憭硋瑌嚗䔶��删鍂 J2 頧游��湧�嚗㇊05 瘜訫��睃歇�詨��𡒊宏嚗㚁�
5. 銝交聢皛∟雲 single-solid 瘚�耦�𤘪�銝� 360簞 �刻��湧妟撟脫� (COLLISION pairs = 0)��
"""
# 1. M2 �𡒊垢摰㕑�瘜訫��� (Y: 92..100, R=35mm)
rear_plate = Ycyl(35.0, Y_REAR - 8.0, Y_REAR, X_ARM, Z_SH)
# 2. M2 �滨垢摰帋��� (Y: 149.5..155.5, R=35mm)
front_collar = Ycyl(35.0, Y_COVER - 6.5, Y_COVER - 0.5, X_ARM, Z_SH)
s = rear_plate.fuse(front_collar)
# 2b. ��2026-10-02 �啣��餹2 �滨垢�讠�嚗��雿蓥���眏閫� motor_front_clamp嚗剹��
# 敹�◆�函洵 6/7 甇交��� R30.15~30.5 ������瑁粥摰䔶��擧��娍𦻖嚗�炏�坔��𡝗覔�其�鋡�
# front_collar_pocket / c_m2 ���銝��� 0.1mm ��器嚗�� 7b嚗剹��
fp = motor_front_clamp(X_ARM, Z_SH, tag="P04/M2")
# 3. J1 隞𤾸𢆡瘜訫����撌脣��歹��� R=36.5 ����㗛𢒰�� column �滨�敶X����曌𤘪�嚗�
# J1 銝� P04 ����亦眏 boss(�35.6 韐舫�� P03 �滨�銝剖�摮� R=19.5)�渲��菜㦤颲枏枂��
# �踵�嚗諹卽�㕑粥 boss 蝡舫𢒰 4xB 摮䈑�����牐��𥕦��賢歇�駁膄��
# 4. XZ 撟喲𢒰�㗇㦤餈䂿賒瘚�瑪頧桀�嚗�� X_FORK_GAP �港��滨宏嚗屸�霈拚◇皛𤏸�皜∴�嚗�
x_b, z_b = -12.65 + X_FORK_GAP, 506.0
x_a, z_a = 10.5 + X_FORK_GAP, 545.0
Lz = z_a - z_b
d0 = 0.514 * Lz
d1 = 0.0
hermite_pts = []
N_h = 16
for i in range(N_h + 1):
t = i / N_h
h00 = 2.0 * (t**3) - 3.0 * (t**2) + 1.0
h10 = t**3 - 2.0 * (t**2) + t
h01 = -2.0 * (t**3) + 3.0 * (t**2)
h11 = t**3 - t**2
xh = x_b * h00 + d0 * h10 + x_a * h01 + d1 * h11
zh = z_b + t * Lz
hermite_pts.append((xh, zh))
dx_flare = (53.5 + X_FORK_GAP) - (44.0 + X_FORK_GAP)
dz_flare = 545.0 - 490.0
R_flare = (dx_flare**2 + dz_flare**2) / (2.0 * dx_flare)
xz_wire = (cq.Workplane("XZ", origin=(0, Y_AXIS, 0))
.moveTo(10.5 + X_FORK_GAP, 545.0)
.lineTo(10.5 + X_FORK_GAP, Z_RL + 36.5)
.lineTo(28.0 + X_FORK_GAP, Z_RL + 36.5)
.radiusArc((44.0 + X_FORK_GAP, 630.0), 18.0)
.lineTo(44.0 + X_FORK_GAP, 545.0)
.radiusArc((53.5 + X_FORK_GAP, 490.0), -R_flare)
.lineTo(18.5 + X_FORK_GAP, 490.0)
.lineTo(-16.5 + X_FORK_GAP, 490.0)
.threePointArc((-15.1 + X_FORK_GAP, 498.5), (-12.65 + X_FORK_GAP, 506.0)))
for pt in hermite_pts[1:]:
xz_wire = xz_wire.lineTo(pt[0], pt[1])
xz_wire = xz_wire.close()
xz_shape = cq.Shape(xz_wire.extrude(100.0, both=True).val().wrapped)
# 5. YZ 撟喲𢒰���
# ��2026-10-04 閫���湔㺿�𤑳㩞�箔��寥��� 4048mm2 ��之撟喲𢒰�寞� Hermite 撘折𢒰��
# ��䔉蝚� 2->3 �嫣��湔糓銝��∠凒蝥� (164.5,646.5)->(155.5,526)嚗峕窒 X �孵��㗇�
# 4048mm2 ��像�選�摰墧�瘜訫� (0,1,-0.07)嚗�蒂 4 摨行�摨佗�嚗峕迤撖寧㩞�箔��� �婙��
# 銝支儒鋡� xz_wire �� R18 ��憫�文枂�鳴�敶X�"銝剝𡢿銝��堒像��舅颲寥�"����麄��
# �寞�嚗𡁏�餈蹱挾�渡瑪�X�銝㗇活 Hermite �脩瑪嚗䔶舅蝡臬�蝥踹��急窒 Y嚗�𦻖銝𢠃𢒰 Z=646.5
# ��▲畾蛛�銝擧窒 Z嚗�𦻖銝钅𢒰 Y=155.5 ����湔挾嚗㚁�靽肽� G1 餈䂿賒�删�嚗�
# 銝剝��� +Y 憭硋瑌蝥� 3mm嚗�憫摨西��煺�銝支儒 R18 銝��氬��
# 銝箔�銋���典�畾萄�撘改�A 憭��蝥輯�瘝� Y�� 憭��瘝� Z嚗��銝芸�敹��瘜訫��嗆說頞�
# 嚗�圾�箸䔉 R=9 銝� R=120.5 �𤤿㦛嚗㚁�敹�◆�� Hermite/Bezier �婙�� 銝� P05/P06
# �� Loft 餈�腹�䔶�憟堒�瘜𨰻��
# 瘜冽�嚗𡁻▲�寧�摨誩�憿颱��笔�銵其��湛��� y_b �� y_a嚗㚁��血�憭朞器敶Z䌊鈭扎��
# 撣���𡡞妟隞嗡�蝣擧�嚗��瘚衤��匧� 48cm3 / 3 �堒�雿橒���
y_a = (Y_COVER - 0.5, Z_SH + 36.0) # (155.5, 526.0) �脩瑪蝏��
y_b = (Y_AXIS + 36.5, Z_RL + 36.5) # (164.5, 646.5) �脩瑪韏瑞�
_d = math.hypot(y_b[0] - y_a[0], y_b[1] - y_a[1])
_m0y, _m1z = -0.5 * _d * 0.35, 0.5 * _d * 0.5 # ��瑪嚗朞絲�寞窒 -Y嚗𣬚��寞窒 +Z
yz_pts = [(Y_AXIS - 36.5, Z_RL + 36.5)]
for k in range(13):
t = k / 12.0
h00 = 2 * t ** 3 - 3 * t ** 2 + 1
h10 = t ** 3 - 2 * t ** 2 + t
h01 = -2 * t ** 3 + 3 * t ** 2
h11 = t ** 3 - t ** 2
yz_pts.append((h00 * y_b[0] + h10 * _m0y + h01 * y_a[0],
h00 * y_b[1] + h11 * _m1z + h01 * y_a[1]))
yz_pts += [(Y_COVER - 0.5, Z_SH),
(Y_REAR - 8.0, Z_SH),
(Y_REAR - 8.0, Z_SH + 36.0)]
yz_solid = Xplate(yz_pts, -20.0, 60.0)
c_int = BRepAlgoAPI_Common(yz_solid.wrapped, xz_shape.wrapped)
c_int.Build()
column = cq.Shape(c_int.Shape())
s = s.fuse(column)
# 6. 銝剝��菜㦤摰𡁜������膄
s = s.cut(Ycyl(30.5, Y_REAR + 0.5, Y_COVER - 6.5, X_ARM, Z_SH))
# 7. M2 �亙藁�𣂼�
# �踹��Z絲�寧鍂 AB.REAR_SEAT嚗�=0.6 �啗� + 2.0 �砍榆嚗㚁�銝� Joint.pocket �峕�嚗�
# P04 韏啁��航䌊撌梢�憟� BORE_R ������瘀�瘝∟� Joint.pocket嚗㚁�餈䠷�敹�◆�峕郊�對�
# �血� J2 �唾���㩞�箏�撌桐�隞齿糓�抒� 0.6嚗䔶� J3~J6 銝滢��氬��
# ��2026-10-05�烐㗁�钅𢒰畾萄�銝��� SEAT_R(=R35) ���嚗玺EAT_TOP=+1.0��
# �𡝗說 R35 �滩�霈拇㗁�钅𢒰銝𤾸�憯��撟單�**銝�銝芸像��**嚗�鍂�瑁�瘙���𠰴瑌�啜��凒��
# 銝�韏瑕�撟喉��𡁏��𣬚㩞�箔舅憭湧�撟喟�撟喲𢒰嚗剹���撠譍� R35 敹���嗘�銝���瑌韏�
# 2.6mm ��凒�∠㴓憓� �婙�� 霂西� Joint.pocket �� docstring��
s = j2.front_collar_pocket(s, r_bore=30.25, z0=50.0, z1=56.5)
s = j2.rear_mount_holes(s, t_plate=8.0, hole_d=2.8, cb_d=5.5, cb_depth=4.0)
c_m2 = [cyl(BORE_R, -AB.REAR_SEAT, COVER_Z - 3.5), cyl(CB_R, COVER_Z - 3.5, COVER_Z + 0.6),
cyl(AB.SEAT_R, -AB.REAR_SEAT, AB.SEAT_TOP)]
s = s.cut(*[j2.L(item) for item in c_m2])
# 7b. M2 �滨垢�讠��娍𦻖嚗�� 2b嚗㚁�敹�◆�� 6/7 甇交��� R30.15~30.5 ������瑁粥摰䔶��𠬍�
# �血��讠��寥�隡朞◤ front_collar_pocket / c_m2 ���銝��� 0.1mm ��器��
s = s.fuse(fp)
# 7b2.��2026-10-05e�穃��匧�蝡�"�湔𣏹"�冽���儒����𠰴��臬�嚗�� FENCE_OPEN_CUT嚗剹��
# �湔𣏹 = front_collar_pocket �𠰴漣摮娍��� R30.25 �𡒊�銝讠���� r30.25..35��6mm 擃�
# �臬�嚗À149.5..155.5嚗㚁�瘥𠉛㩞�箏�蝡舐� �60.3 �� 4.75mm嚗峕��滨垢�𡝗㟲��凒雿𧶏�
# 銝𢠃𢒰餈㗛��� R35 �讠�嚗��70 �滚瑌 3.2mm嚗剹����𧼮藁嚗���� +y = �典� -Z嚗厰��𠰴��𠬍�
# �諹�嚗���� -y = �典� +Z嚗劐儒�游�靽萘�嚗𡁶誧蝏剖�雿滚�蝡舐���僎雿靝蛹�讠��臭�銝磰雲憭笔撩
# ��𣈲�煾𢒰嚗�4.75mm 摰� x 0.5mm �娍𦻖撣佗��祆活摰��銝滨1嚗争� M2 隞齿糓
# �𡒊垢�� 4xM3x10 + �滨垢�讠� 4xM3x8 ����W�嚗𥕦��𡝗𧋦雿�/�37 摮�/4xM3x8 瘝匧�/
# �𥪜藁銝𧢲窒 Y155.5 �券�銝滚𢆡��
s = cut_motor_fence(s, j2, "P04/M2", "P04")
# 7c. ��2026-10-02 �啣��𤑳��勗��齿局嚗�� hollow_channel嚗剹��
# 蝡𧢲� Z525..635 �湔挾�臬��𡁏�瘛勗�颲� 17.5mm ���敹��嚗諹�� J2 �� z=560/600 ��
# 摰匧�蝟餅㺭�� 19����鞉�銝𦠜�撘��� U 敶X局�𡒊��勗��鞉局�g��堒摩��舅�� X �𤏸���
# 甇�末�賢銁撘舐畆�匧��綽�z=560 �芷𢒰 X13..45嚗䔶葉�折𢒰�� X29嚗諹��踹� X13~23/X35~45嚗㚁�
# 鋡急��厩�甇�糓銝剜�批�����牐�銝滚�銝擧�撘舐��踺��
# 瑽賢� Z525 隞乩�靽萘��游�摰𧼮�餈�腹�啁㩞�箏漣嚗偦▲�冽�撘����撠�𡡒�𢛵����舀���
# 敹�◆�� 8 甇� J1 �詨蝱/�粹�摮𥪯��滚�嚗𡁏局�� X23..35 ��凒蝳� J1 �詨蝱(X<=11.5)銝�
# 3xS01 瘝匧�(X12..14)�賣�撖䔶�嚗䔶�����臭誑靽肽��𡡞𢒰������瑚�隡𡁏�瑽賢��栞���
s = s.cut(hollow_channel(P04_CH["x0"], P04_CH["x1"], P04_CH["y0"], P04_CH["y1"],
P04_CH["z_floor"], 660.0, tag="P04蝡𧢲�"))
# 8. 憭湧�頧祆𦻖�詨蝱�𣳇鵭嚗�敞�� P03 �滨�銝剖�摮䈑�頝刻�鋆��蝻萘凒餈� J1 颲枏枂�矋�
boss = cyl(17.8, 54.942, 61.5 + X_FORK_GAP)
s = s.fuse(j1.L(boss))
s = s.cut(j1.L(cyl(3.5, 54.0, 74.0 + 30.0)))
# 瘝匧��圈𧫴�箏��� 63.0嚗���誩�蝘鳴�嚗鐝2x10 �见��菜㦤颲枏枂瘥���砍��譍��孵�銝��湛�
# �粹�憭�(63..65)�詨笆�㗇踎�屸𢒰(64.5)憭㚚蠧 0.5mm嚗䔶�鈭� 2mm �厩�蝛粹�����惩僕瘨剹��
s = hub_m2_holes(s, j1, cb_z1=74.0 + 40.0 + X_FORK_GAP,
th_z1=63.0 + X_FORK_GAP, cb_z0=63.0)
return s
def make_pitch_to_roll_bracket(j_pitch, j_roll, z_pitch, z_r, name="bracket", hub_gap=1.0,
roll_clamp=False):
"""Half-wrapped (�𠰴�) �峕𤩅�X��箸�蝥踹� Pitch-to-Roll 蝏𤘪�摨� (P05 & P08):
1. 憿園�隞𤾸𢆡瘜訫�銝𤾸�靘� Loft �芰��詨�憿箸𦻖嚗�
2. 銝交聢皜�膄 z_plate 憿園𢒰隞乩�銝𦒘�蝥扳�頧砌辣韐湧𢒰���雿蹱��� (cut_top_solid)嚗䔶�霂����之��凒��𢆡�冽�� 0 撟脫�嚗�
3. 銝𧢲䲮�菜㦤摰噼��𠰴����霈曇恣嚗�-Y靘扳�撘�嚗�+Y靘扯��𠹺����銝�雿枏��滚�嚗�
4. 銝交聢皛∟雲 single-solid 瘚�耦�𤘪�銝𡡞妟撟脫� (COLLISION pairs = 0)��
hub_gap = 隞𤾸𢆡瘜訫��䁅��V�銝羓漣�菜㦤�滨垢�碶��渡�頧游�霈拐��湧���
暺䁅恕 1.0嚗�斐��俈蝤剁���05 隡� 6.0嚗麿2 憭� P04 �啣�鈭� M2 �滨垢�讠�
嚗À 155.5..161.0嚗㚁�敹�◆霈拙枂餈� 6.0mm �滩�鋆��嚗𥡝� p_shoulder_roll_base��
roll_clamp = �砌辣雿靝蛹 roll �菜㦤�𣂼�蝡臬允蝝找辣�烐𧒄銝� True嚗㇇3/P05 憭� M3嚗剹��
roll �菜㦤嚗㇇3/J6嚗㕑蓬�烐糓 -Z嚗��蝡舐�憭𣇉垢�W銁 z_r-56嚗�-Z 靘扳糓隞𤾸𢆡隞塚�
�讠��� -Z �選�Z_COVER-5..Z_COVER嚗㚁�隞𤾸𢆡隞嗆��W�憿餅㟲雿枏�蝘� CLAMP_BACKOFF=5.5
霈拐�嚗�� Y 頧游��� hub_gap=6.0 �䔶�銝芷�����芣糓�箏��湧� 0.5 �屸� 1.0嚗剹��
P08 隡� False嚗麿6 �� M6 �滨垢�讠�撠𡁏𧊋�𡄯�隞𤾸𢆡隞� P09 霈拐�閬�㺿撌亙�瘜訫��湧��詨蝱嚗剹��
"""
z_bot = z_r - 56.0 # roll �菜㦤摨閧垢 (front collar)
z_plate = z_r + 8.0 # roll �菜㦤憿嗥垢摰㕑��� (rear plate top)嚗𥡝�蝚� 8 甇� t_plate 霂湔�
y_out = HL.Y_HUB + HL.PLATE_T # 174.0 (靽臭趕�渲�瘜訫�憭碶儒��)
y_hub_in = HL.Y_COVER + hub_gap # 157.0 / (P05) 162.0 隞𤾸𢆡瘜訫���儒��
z_hub_in = y_hub_in - HL.Y_REAR # 瘜訫��䁅��Y��菜㦤撅��� z嚗�瑌�圈鵭摨西���摰�粥嚗�
y_cyl_max = HL.Y_AXIS + 35.0 # 163.0 (銝𧢲䲮�菜㦤憭𤥁蔭撱𤘪���)
# 1. �箇�蝡𧢲�嚗煳�70mm 摰𧼮���� (Z: z_bot .. z_plate, R=35mm)
s = cyl(35.0, z_bot, z_plate, HL.X_ARM, HL.Y_AXIS)
# 2. 靽臭趕頧渡凒餈墧��啁�嚗𡁜����摰硺� (Y: y_hub_in .. y_out, R=35mm)
disc = Ycyl(35.0, y_hub_in, y_out, HL.X_ARM, z_pitch)
s = s.fuse(disc)
# 3. �滢儒隞𤾸�蝡� �70mm ����圈▲蝡舀��啁��㗇㦤�詨�撟單�皜𣂼�餈�腹雿� (Loft Morph)
Z_top = z_pitch - 35.0
z_start = z_bot
N = 16
wp = cq.Workplane("XY")
for i in range(N + 1):
t = i / float(N)
z_curr = z_start + t * (Z_top - z_start)
st = 3.0 * (t**2) - 2.0 * (t**3)
y_center = y_cyl_max + st * (y_out - y_cyl_max)
y_side = HL.Y_AXIS + st * (y_out - HL.Y_AXIS)
v_c = y_center - HL.Y_AXIS
v_s = y_side - HL.Y_AXIS
v_mid = max(v_c, v_s + 0.02)
# �𡒊�銝方� R2 ���嚗𡁏� y=123 �詨�銝� R35 �梢𢒰鈭斗���舅�� 90簞 蝡𡝗ㄠ��隋��
# 嚗�ㄗ��"�貉絲�亦�"撠𤥁�嚗䔶��典�蝻㗛�摨�/雿滨蔭嚗峕��唳��祆�嚗�
FR = 2.0
w = (cq.Workplane("XY", origin=(HL.X_ARM, HL.Y_AXIS, z_curr))
.moveTo(-35.0, v_s)
.threePointArc((0.0, v_mid), (35.0, v_s))
.lineTo(35.0, -5.0 + FR)
.radiusArc((35.0 - FR, -5.0), FR)
.lineTo(-35.0 + FR, -5.0)
.radiusArc((-35.0, -5.0 + FR), FR)
.lineTo(-35.0, v_s)
.close())
wp = wp.add(w)
loft = wp.toPending().loft()
s = s.fuse(loft.val())
# 4. 憿園�憛怠�嚗��靽萘� y >= y_hub_in 銝擧��啁�撖寥��������踹�靘萄�銝羓漣�唾��贝蓮�急��箏�嚗�
top_fill = (cq.Workplane("YZ", origin=(HL.X_ARM, 0, 0))
.moveTo(y_hub_in, Z_top)
.lineTo(y_out, Z_top)
.lineTo(y_out, z_pitch)
.lineTo(y_hub_in, z_pitch)
.close()
.extrude(35.0, both=True))
s = s.fuse(top_fill.val())
# 5. �贝蓮皜�悟��膄嚗𡁜蝠摨閙��� z >= z_plate 銝� y <= y_hub_in ��凒���憭帋��鞉�嚗�
# 瘨�膄撖潸稲銝𦒘�皜豢�頧砌辣嚗㇊04/P07嚗劐艇�滚僕瘨厩�蝡见�銝𤾸�閫𡜐�靽脲�憿園𢒰撟單㟲閫�㟲嚗�
cut_top_solid = (cq.Workplane("YZ", origin=(HL.X_ARM, 0, 0))
.moveTo(-999.0, z_plate)
.lineTo(y_hub_in, z_plate)
.lineTo(y_hub_in, z_pitch + 50.0)
.lineTo(-999.0, z_pitch + 50.0)
.close()
.extrude(60.0, both=True))
s = s.cut(cut_top_solid.val())
# 6. �菜㦤�𠰴�憭�� (Half-Enclosure)嚗�-Y靘扳�撘����嚗�+Y靘扯��𠰴ㄢ雿枏�撘�
cut_open = bx(HL.X_ARM - 40.0, HL.X_ARM + 40.0, HL.Y_AXIS - 40.0, HL.Y_AXIS + 3.0, z_bot + 6.0, z_r - 1.0)
s = s.cut(cut_open)
# 7. 銝羓漣�菜㦤�����憫�輯悟
clearance = Ycyl(35.5, HL.Y_AXIS - 40.0, HL.Y_COVER + 0.1, HL.X_ARM, z_pitch)
s = s.cut(clearance)
# 8. 銝𧢲䲮�菜㦤摰㕑�摮𥪯�銝𤾸�雿齿迫��
# t_plate=8.0嚗麿oint.pocket ��偏蝡舫𢒰�踹��Z悟蝛箔� MOTOR_TOL=2.0嚗峕㗁�钅𢒰�啗卽�㗇�摮�
# �圈𧫴�芸� t_plate-cb_depth-REAR_SEAT = 8-4-2.6 = 1.4mm �𨅯�嚗𤤿��� 8 �䔶��臬��亦�
# 7嚗峕糓銝箔�銝滩悟餈坔��𣈯���𡝗� 0.4mm��7->8 霈� P05/P08 ��𡟵雿枏�憯喲▲ z_plate �� 1mm��
s = j_roll.rear_mount_holes(s, t_plate=8.0, hole_d=2.8, cb_d=5.5, cb_depth=4.0)
s = j_roll.front_collar_pocket(s, r_bore=30.25, z0=50.0, z1=56.5)
s = j_roll.pocket(s)
# 9. �菜㦤摰𡁜��滚�蝛箄�
s = s.cut(cyl(30.5, z_r - 49.5, z_r - 0.5, HL.X_ARM, HL.Y_AXIS))
# 10. 靽臭趕頧渡凒餈墧��啁�����詨蝱撱嗡撓�單��啁��屸𢒰銋见� 2.5mm嚗諹楊餈�𡢿�嗘�瘜訫��条糼�箇��伐�
# 靽脲��訫�雿橒���瑌�圈鵭摨西��� y_hub_in 韏堆�瘜訫��睃�蝘餅𧒄�詨蝱�峕郊�𣳇鵭嚗�
# 3xS01 颲枏枂�粹���仍�W蝱��(撅��� z=58)����踴��俥���銝擧㺿�滚��其��氬��
boss = cyl(17.8, 54.942, z_hub_in + 2.5)
s = s.fuse(j_pitch.L(boss))
s = s.cut(j_pitch.L(cyl(3.5, 54.0, 74.0 + 30.0)))
s = hub_m2_holes(s, j_pitch, cb_z1=74.0 + 40.0)
# 11. L �贝蓮閫坿��亙����餈�腹嚗��閫� R=2.0mm嚗㚁�
# 撟單�瘨�膄蝡𧢲�憿園𢒰銝𡒊��渲�鈭斗�憭�� 90簞 撠𤥁�銝𤾸��偦�銝�
try:
wp_s = cq.Workplane(obj=s)
sel_l = cq.NearestToPointSelector((HL.X_ARM, y_hub_in, z_plate))
s = wp_s.edges(sel_l).fillet(2.0).val()
except Exception as e:
print(f"[{name}] L�贝蓮閫鍦�閫鍦�撣�: {e}")
# 12. roll �菜㦤嚗㇈3嚗匧�蝡臬��吔�銝� P04/P06/P07 �� M2/M4/M5 �讠��䔶�憟烾��對�
# �芣糓 roll �菜㦤頧游�銝� -Z嚗���𡝗� -Z �選�閫� motor_front_clamp �� axis="Z"嚗剹��
# �娍𦻖敹�◆�曉銁���𠬍�蝚� 6/7/8/9 甇交��� R30.15~30.5 ������琿�韏啣�銋见��齿𦻖嚗�
# �血��讠��寥��� 0.5mm ��㴓隡朞◤ front_collar_pocket / 摰𡁜�摮𥪜��劐�����
if roll_clamp:
s = s.fuse(motor_front_clamp(HL.X_ARM, 0.0, tag="%s/M3" % name[:3],
axis="Z", py=HL.Y_AXIS, z_face=z_r - COVER_Z))
# 13.��2026-10-05d�穃蘨��"�湔𣏹"�������𧼮藁嚗�-Y嚗劐儒���蝡臬�雿滨㴓 + �讠��寥���㴓��
# �冽� 2026-10-05 ��枂餈坔��臬��� M3 �滨垢�硋� P06 �� J3 �詨蝱�游銁銝剝𡢿嚗𥟇�蝚砌���
# �𦠜㟲銝芸�蝡荔�摰帋��� + �讠� + �𥪜藁銝𧢲窒 389->395嚗厰����嚗𣬚㩞�箏�蝡舀瓷鈭�𣈲�煾𢒰 �婙��
# 餈�漲��緵�典蘨������銝����Y �屸�銝𡒊洵 6 甇� cut_open 摰��銝���
# 嚗À_AXIS-40 .. Y_AXIS+3嚗㚁�靽肽� -Y �𠰴�隞� Z=395.5 銝�頝臬��啣��𤥁��� Z=389嚗�
# �諹�嚗�+Y嚗劐儒�游�摰帋��臭��辷�
# - 蝏抒賒摰帋� M3 �滨垢�吔���� r30.25嚗��蝡舐� �60.3 -> �閗器 0.10mm嚗㚁�
# - 蝏抒賒敶� R35 �讠��臭�銝磰雲憭笔撩��𣈲�煾𢒰嚗�4.75mm 摰� x 0.5mm �娍𦻖撣佗��祆活�孵𢆡
# 摰��銝滨1嚗争� M3 隞齿糓�𡒊垢�� 4xM3x10 + �滨垢�讠� 4xM3x8 ����W�憭寧揮嚗�
# - �讠��砌� / �37 霈拐�摮� / 4xM3x8 瘝匧� / �𥪜藁銝𧢲窒 z_bot=389 �券�銝滚𢆡嚗�
# �讠��𧼮藁靘抒�蝡舫𢒰隞� Z=389.5 �滚� 389 銝舘��a�撟喉�閫��銝𠹺��滚瑌�箝��
# 銝箔�銋���賣㟲����唬��菜㦤朣𣂼像嚗㇌35->R31.8嚗諹� FENCE_OPEN_CUT 憭��霂湔�嚗㚁�
# �� 餈坔�憯��蝚� 3 甇� Loft �� X=簣35 憭�� �70 �梢𢒰**�詨�**嚗峕㟲���摰屸�銝斤����璆𥪜耦
# 嚗��瘚� 1.32mm3嚗劐��梁征�𣂼迨蝡讠��梹��游��訫�雿𤘪��𡢅�
# �� �讠��寥��芣� 0.5mm �娍𦻖撣佗��臬��� 1.55mm 摰賢�餈墧𦻖�V� 2.37mm2 �匧� 0.78mm2嚗�
# 4xM3x8 ��允蝝批�隡𡁏��讠�隞擧𧋦雿㮖��劐��乓��
# ��蒂���嚗𡁶���� Loft �� X=簣35 銝� �70 �梢𢒰�詨����銝斤����璆𥪜耦銝�韏瑕蒂韏�
# 嚗��敶V�鈭� Y_AXIS ��� < Y_AXIS+3嚗㚁�銝滢��嗘�摮斤�蝣𤾸� -> �訫�雿𤘪��睲�����
# 13.��2026-10-05e�穃��匧�蝡�"�湔𣏹"�冽���儒����𠰴��臬�嚗�� FENCE_OPEN_CUT嚗剹��
# P05(M3) �匧�蝡臬��硔��㴓銝𢠃����讠�嚗𢏺08(M6) 餈䀹瓷�� M6 �滨垢�讠�嚗ǐoll_clamp=False嚗㚁�
# �舀糓�㗇踎 �婙�� 銝方����芸��𧼮藁嚗���� +y嚗厰��𠰴�摰帋��荔��諹�靘扳㟲����辷�
# 蝏抒賒摰帋��菜㦤�滨垢�硔��05 ����硋�甇支��� 4.75mm x 0.5mm ����亙蒂雿𨀣𣈲�煾𢒰��
if roll_clamp or FENCE_OPEN_CUT:
s = cut_motor_fence(s, j_roll, "%s/M3" % name[:3], name[:3])
return s
def p_shoulder_roll_base(j2, j3, half=None):
"""P05_憭扯��贝蓮摨否�箸�雿�30%_憓�4摨�5_蝡𡝗�嚗�楛摨血�閫雴��𣇉�嚗�
�砌辣�券曎頝臭��劐舅�滩澈隞踝�銝文�霈拐��賣糓銝箏�蝡臬��吔�
1. hub_gap=6.0嚗���其儒嚗㚁�J2 憭� P04 �啣�鈭� M2 �滨垢�讠�嚗��蝡臬允蝝抒㩞�綽�瘨�膄憭扳酞�拐���
�暹�嚗㚁��讠��� Y 155.5..161.0嚗峕�隞乩��冽��啁��屸𢒰敹�◆隞� Y=157 �𡒊宏�� Y=162
嚗�� 1.0mm �券𡢿�辷���
2. roll_clamp=True嚗��蝡臬允蝝找儒嚗㚁�P05 �芸楛�梁� M3嚗㇇3嚗�-Z 頧湛�嚗���乩��芣��𡒊垢��
4xM3x10 �閖𢒰��香嚗𤤿緵�冽� motor_front_clamp ���銝��齿䲮�� M3 �滨垢�硋�蝡舫𢒰
嚗Ē=389嚗匧�銝��� R35 �讠�嚗Ē 384..389嚗�4xM3x8 BCD55嚗㚁�銝𤾸�蝡舀踎�滚�����W�嚗�
�暹��芰眏摨血��嗚��誨隞瑟糓撖嫣儒隞𤾸𢆡隞� P06 �� J3 瘥�𢒰�港��𡒊宏 CLAMP_BACKOFF=5.5
嚗Ē 388.5��383.0嚗㚁�閫� p_humerus_bone��
P08 靽脲�暺䁅恕 �婙�� J5 憭� P07 ���蝡臬��硋歇�𡄯��芷� 6.0 �� hub_gap嚗㚁��� J6 �� M6
�滨垢�讠�撠𡁏𧊋�𡄯��� roll_clamp 隡� False��
"""
return make_pitch_to_roll_bracket(j2, j3, Z_SH, Z_R3,
name="P05_憭扯��贝蓮摨否�箸�雿�30%_憓�4摨�5_蝡𡝗�",
hub_gap=6.0, roll_clamp=True)
def p_humerus_bone(j3, j4):
"""P06_憭扯�撉冽沲_�箸�雿�25%_憓�4摨�5_蝡𡝗� (Humerus Bone - Loft ��憫頧祆䲮�㗇㦤餈�腹��):
�� J3 (憭扯��芾蓮, -Z頧�, hub@Z_HUB3=380) 撽勗𢆡嚗�
�睲�撱嗡撓���憭扯�銝颱�撉冽沲嚗��蝡舀�蝝� M4 (�㗛�靽臭趕�菜㦤, +Y頧�, 頧渡瑪雿滢� Z_EL=332.0)��
1. �罸� P05 憭扯��贝蓮摨批�雿閙𦆮�瑞�瘜𤏪�
- 憿嗥垢蝏枏��� (Z = 383.0mm)嚗帋� J3 頧游�銝交聢�詨��� �70mm 甇��敶Z蔭撱橒�敶餃�瘨�膄�笔�憭𣇉���䲮敶X偌撟喲𧫴璇荔�
- 摨閧垢蝏枏��� (Z = 367.0mm)嚗𡁜像皛穃�撘��滚� M4 �菜㦤憟㛖��� 70x63.5mm �孵耦�芷𢒰嚗�
- 餈�腹�� (Z: 367.0..383.0mm)嚗𡁻��� Hermite s(t) = 3t簡 - 2t糧 撽勗𢆡 20 撅�𦆮�瑕����蝏剜��矋�
2. 銝钅��梁揮憟㛖�銝𤾸�鋆�踎 (R=35mm)嚗𣬚㩞�箏�摮� 100% 鋆賊蠧���撘�蝒梹�
3.��2026-10-03�飦3 瘥�𢒰�港��𡒊宏 CLAMP_BACKOFF=5.5嚗�▲蝡� 388.5��383.0嚗𣬚凒��瑌��
59.5��65.0嚗㚁�P05 �啣� M3 �滨垢�讠�嚗�� Z 384..389嚗���� 388.5 ����W蘨�� 0.5mm
霈拐��曆�銝见��硔����嫣� Y 頧港�憭��J2/J4/J5 隞支��冽��啁� Y157��162嚗匧��典�皞琜�
�讠� 5.0 + �券𡢿�� 1.0 - �笔抅�� 0.5 = 5.5��瑌�啣�甇亙��選�3xS01 颲枏枂�粹���仍��
�圈𧫴(撅��� s=58)����踴��俥���銝擧㺿�滚��其��湛�J3 �湧�銝𡡞妟撟脫�銝滚�敶勗���
�讠�銝剖亢 �37 霈拐�摮䈑�R18.5嚗劐�霈拙� R17.8 �詨蝱嚗��颲嫣� 0.7mm��
4. 銝交聢�訫�雿� (solids = 1) 銝𥪯�銝𠹺�蝥扳�頧祆�隞嗅��菜㦤摰䂿緵�冽�� 0 蝣唳�撟脫���
"""
# 1. M4 摨閖��梁揮憟㛖�銝𤾸�蝡臬�鋆�踎 (R=35mm)
rear_m4 = Ycyl(35.0, Y_REAR - 8.0, Y_REAR, X_ARM, Z_EL)
front_m4 = Ycyl(35.0, Y_COVER - 6.0, Y_COVER - 0.5, X_ARM, Z_EL)
s = rear_m4.fuse(front_m4)
# 憿嗥垢蝏枏��V�餈�腹擃睃漲
# z_top �� M3 �滨垢�硋�蝡舫𢒰�齿綫嚗𡁜��硋� [Z_COVER-CLAMP_T, Z_COVER]嚗���� CLAMP_CLR
# �券𡢿�� -> 383.0嚗�㺿�� 388.5嚗䔶��滨垢�硋蘨�� 0.5mm嚗峕𦆮銝滢��讠�嚗剹��
z_cover3 = Z_R3 - COVER_Z # 389.0 M3 �滨垢�硋�蝡舫𢒰
z_top = z_cover3 - CLAMP_T - CLAMP_CLR # 383.0 J3 瘥�𢒰嚗�= 388.5 - CLAMP_BACKOFF嚗�
z_bot = Z_EL + 35.0 # 367.0
# 2. 銝钅�摰𧼮��箏漣�� (Z: Z_EL..z_bot + 0.5)
lower_block = bx(X_ARM - 35.0, X_ARM + 35.0, Y_REAR - 8.0, Y_COVER - 0.5, Z_EL, z_bot + 0.5)
s = s.fuse(lower_block)
# 3. �罸� P05 �� Loft �暹甅餈�腹雿橒���憫�䀹䲮敶g�20 撅�像皛烐𦆮�瘀�靽脲�銝交聢撖寧妍 4 畾萄��芷𢒰�𤘪�嚗�
N = 20
wp = cq.Workplane("XY")
for i in range(N + 1):
t = i / float(N)
z_curr = z_bot + t * (z_top - z_bot)
st = 3.0 * (t**2) - 2.0 * (t**3)
# �滢儒嚗魩=0 銝箏像�湧𢒰 (Y=155.5, v=27.5)嚗龨=1 皜𣂼�銝箔� �70 甇�����撘折▲�� (Y=163.0, v=35.0)
v_sf = 27.5 * (1.0 - st) + 0.05 * st
v_cf = max(27.5 * (1.0 - st) + 35.0 * st, v_sf + 0.05)
# �𦒘儒嚗帋� t=0 ��像�湧𢒰 (Y=92.0, v=-36.0) 皜𣂼��� t=1 ���撘� (Y=93.0, v=-35.0)
v_sr = -36.0 * (1.0 - st) - 0.05 * st
v_cr = min(-36.0 * (1.0 - st) - 35.0 * st, v_sr - 0.05)
w = (cq.Workplane("XY", origin=(X_ARM, Y_AXIS, z_curr))
.moveTo(-35.0, v_sf)
.threePointArc((0.0, v_cf), (35.0, v_sf))
.lineTo(35.0, v_sr)
.threePointArc((0.0, v_cr), (-35.0, v_sr))
.close())
wp = wp.add(w)
loft = wp.toPending().loft()
s = s.fuse(loft.val())
# 4. �菜㦤銝剝𡢿摰𡁜����鋆賊蠧��膄 (100% 鋆賊蠧)
s = s.cut(Ycyl(30.5, Y_REAR + 0.5, Y_COVER - 6.5, X_ARM, Z_EL))
# 5. M4 �亙藁�𣂼�
s = j4.front_collar_pocket(s, r_bore=30.25, z0=50.0, z1=56.5)
s = j4.rear_mount_holes(s, t_plate=8.0, hole_d=2.8, cb_d=5.5, cb_depth=4.0)
s = j4.pocket(s)
# 5b. ��2026-10-02 �啣��餹4 �滨垢�讠� 4xM3x8(BCD55)嚗鐝4 ��䔉�芾◤�𡒊垢�踹��a�甇鳴�
# 憭扳酞�拐�隡𡁶� J4 頧游銁 �60.3 摨批��𣬚�憭氬��緵�典�蝡臭��W�憭嫣�甈∴�閫� motor_front_clamp嚗剹��
# �娍𦻖�曉銁���� R30.15~30.5 ������瑚��𠬍���眏�� p_fork 7b��07 �� J4 隞𤾸𢆡靘�
# 撌脩㮾摨𥪜�蝘餃� Y>=162嚗�� p_forearm_bone �� J4_CLEAR嚗㚁�銝𤾸��硋�蝡舫𢒰�� 1.0mm��
s = s.fuse(motor_front_clamp(X_ARM, Z_EL, tag="P06/M4"))
# 5b2.��2026-10-05e�穃��匧�蝡�"�湔𣏹"�冽���儒����𠰴��臬�嚗�� FENCE_OPEN_CUT嚗剹��
# �齿䲮銝� P04/P07 �� M2/M5 摰���峕�嚗��銝�憟� front_collar_pocket + motor_front_clamp嚗㚁�
# 撅��� z 50..56 �� r30.25..35 �臬�����𧼮藁嚗���� +y = �典� -Z嚗厰��𠰴�嚗𥡝��𠹺儒�游�
# 靽萘�嚗𣬚誧蝏剖�雿� M4 �滨垢�硋僎�舀��讠� �� M4 �滚�����W�銝滚���
s = cut_motor_fence(s, j4, "P06/M4", "P06")
# 5c. ��2026-10-02 �啣��𤑳㩞�箔��寡�皜∪��誯�蝒梹�閫� hollow_tent_window嚗剹��
# Z360..385 餈蹱挾 Loft 餈�腹�堒��𡁏�瘛� 15.8mm嚗峕糓 P06 �臭�銝��堒虾�讐��𡁏�
# 嚗Ē332..367 ����冽𧋦雿枏歇蝏讛◤ �61 摰𡁜�摮娍��� 4.5mm ���嚗峕瓷敺堒��𧶏���
# 雿��甇���� J3 瘥���g���隞乩��∠滯蝥選�
# 1) 蝒烾▲��擃睃蘨�� Z374 �婙�� J3 �� �70 瘥�𢒰�� Z380..388.5嚗𣬚�憿嗥� 6mm �游�
# 摰𧼮��䀝�瘥�𢒰�踹�嚗𣬚�銝滨1瘥�𢒰����𡡞𢒰�� 3xS01 �湧��粹�嚗�
# 2) 蝒㛖� X ��凒 3..37 �婙�� �芷𢒰�砌� X-15..55嚗䔶舅靘批��� 18mm 蝡硋�嚗�
# 霂仿�摨虫��嗡辣�滢�隡朞◤���銝文�嚗��憿餃�摰硺�嚗㚁�
# 3) �勗耦嚗��摰賭�蝒��頧桀�嚗峕��V�瘞游像 >= 52簞 �芣𣈲�𡢅��芣�憿園� X12..28 ��
# 16mm 撟喲▲��閬�‘�伐�銝� P03 �屸�蝥改���
# 蝒堒��� Z362 �䔶��舀凒雿𠬍�Z360 ����臬�畾萄��函頂�唳�雿𡒊��芷𢒰嚗�
# �祇�蝒堒� 4mm 瘥娍赤�烐𤣰蝒� 8mm �游�蝞梹��誯��誩蘨撠� 3cm3嚗���函頂�唬� 92% �𧼮� 100%嚗剹��
# 蝒埈窒 Y �����忽嚗À87..172 頞�枂�砌�嚗���𡡞�韐舫�𡄯�嚗屸◇撣行�餈蹱挾���摮鞉袇�剖藁
# 銝�韏瑟�撘���
# ��2026-10-03 �喲𡡒�𤑳鍂�瑕��箄��寧&霈方�銝芣㘚敶Y��冽迤�Y�撠望糓銝�銝芾敞�𡁶��拙耦暺烐�嚗�
# 雿滢�J4 �唾�甇���嫘��㟲�箸��曄尐��氜�𡁶�嚗諹�閫劐���"�嗡辣�港�銝芣�"嚗屸�撣訾������
# ��﹛�擧�憭滚�敹��隞�遠�芣� 161->183cm3(+22cm3 / +27g PLA)嚗諹��撩摨行𧋦�亙停撌脩���
# �删��箇瑪�� 100%嚗��畾菜𧋦�亙停銝滨撩撘箏漲嚗㚁��誯��嗥�蝥臬��虫�瘛餉���
# 靽萘� P06_WIN_XZ 銝擧𧋦畾菜釣�𠺪���閬���齿𧒄�𠰴��單㺿�� True �喳虾憭滚���
if P06_HOLLOW_WIN:
s = s.cut(hollow_tent_window(P06_WIN_XZ, 80.0, 175.0, tag="P06餈�腹��"))
else:
print(" [�誯�蝒㻩 P06餈�腹��: 撌脣���(2026-10-03 閫���湔㺿)嚗諹砲畾菜�憭滚�敹�", flush=True)
# 6. J3 �渲�瘜訫�蝏𤘪�嚗�瑌�啣辣隡貉秐 65.0 頝刻�蝏枏��Y糼�箇��伐�靽脲��訫�雿㮖��嗅僕瘨㚁�
# �詨蝱�� J3 瘥�𢒰銝�韏瑕�蝘� CLAMP_BACKOFF=5.5嚗�59.5��65.0嚗㚁�餈𥕦��菜㦤颲枏枂瘥��瘛勗漲
# 隞齿糓 s54.942..56.0 �� 1.06mm嚗�3xS01 ��仍�W蝱��(s=58)/��鵭/�砍��譍�敺衤��塩��
boss = cyl(17.8, 54.942, 59.5 + CLAMP_BACKOFF)
chamfer_cone = cyl(18.5, 54.5, 54.942)
s = s.fuse(j3.L(boss)).cut(j3.L(chamfer_cone))
s = s.cut(j3.L(cyl(3.5, 54.0, 58.0 + 30.0)))
s = hub_m2_holes(s, j3, cb_z1=58.0 + 40.0)
return s
def p_forearm_bone(j4, j5, half=None):
"""P07_撠讛�撉冽沲_�箸�雿�30%_憓�5摨�5_蝡𡝗� L�钅��𡁜漲�惩僕瘨厩�嚗�楛摨血�閫雴��𣇉�嚗�
霈曇恣閬��嚗�
1. �嫣蛹銝� P05/P08 蝏煺��� L �讠����L-bracket嚗㚁�
- +Y靘批��渲��羓��梧�Y: y_hub_in..y_out嚗㚁��踹�銝羓漣憭扯�撉冽沲 P06嚗À <= 155.5嚗�
- 敶餃�瘨�膄�笔�瘛崆撘臬銁J4頧港��孵�銝方器蝒�枂��僕瘨厩����銝方器蝒�枂�������典縧�歹�
- ��凒蝡𧢲�銝𦒘��� M5 �菜㦤瘞游像摨找��湧��刻��蹱�閫𡜐�Corner Chamfer/Gusset嚗匧��扯���
2. 銝𧢲䲮 M5 �菜㦤摰噼��𠰴����蝏𤘪�嚗���其����撘�蝒埈袇��
3. J4 頧港膳隞啣𢆡���蝔衤��烾��� 簣54簞 憭批��𦠜𦆮�單�甇餉�憭扯��湔��剁��嗅僕瘨㚁�
4. 皛∟雲�訫�雿� (solids=1) 銝舘��漤妟蝣唳���
5.��2026-10-02�餹5 �滨垢�讠�嚗�4xM3x8 BCD55嚗㗇���"�菜㦤�芾◤�𡒊垢�踹��a�甇�"���暹��鞉�嚗�
J4 隞𤾸𢆡靘扳㟲雿栞悟雿㵪�y_hub_in �� 158.5 �𡒊宏�� J4_CLEAR=162.0嚗諹悟�� P06 �� M4 �滨垢�讠�
嚗��蝡舫𢒰 Y=161.0嚗㚁��� 1.0mm �券𡢿�踺��4 �渲��詨蝱�峕郊�𣳇鵭嚗�3xS01 颲枏枂�粹��砍��譍��塩��
"""
y_out = Y_HUB + PLATE_T # 174.0
# J4 隞𤾸𢆡靘扯悟雿滚抅���敹�◆ >= P06 �� M4 �滨垢�讠��滨垢��(Y_COVER+5.0=161.0) + 1.0mm
J4_CLEAR = Y_COVER + 6.0 # 162.0
y_hub_in = J4_CLEAR
y_front = Y_COVER - 0.5 # 155.5
y_rear = Y_REAR - 8.0 # 92.0
z_top_housing = Z_WR + 39.0 # 261.0 (憿園𢒰�惩� 4.0mm嚗峕��方���聦�a䔮憸�)
z_roof_top = z_top_housing + 19.0 # 280.0 (憿嗆踎�湔辺�𣳇� 19mm嚗𣬚鍂�瑞&霈斗䲮獢�4)
# 1. J5 �菜㦤�滚�摰㕑���
collar_front = Ycyl(35.0, HL.Y_COVER - 6.0, HL.Y_COVER - 0.5, X_ARM, Z_WR)
rear_plate = Ycyl(35.0, HL.Y_REAR - 8.0, HL.Y_REAR, X_ARM, Z_WR)
s = collar_front.fuse(rear_plate)
# 2. J4 憿園�隞𤾸𢆡瘜訫��� (Y: y_hub_in..y_out, R=35mm, Z: Z_EL)
disc = Ycyl(35.0, y_hub_in, y_out, X_ARM, Z_EL)
s = s.fuse(disc)
# 3. M5 �菜㦤憯喃�瘞游像憿園�憿嗆踎 (Z: Z_WR..z_top_housing, Y: y_rear..y_front)
roof_w = (cq.Workplane("YZ", origin=(X_ARM, 0, 0))
.moveTo(y_rear, Z_WR)
.lineTo(y_rear, z_roof_top)
.lineTo(y_front - 3.0, z_roof_top)
.threePointArc((y_front - 3.0 + 3.0 * math.cos(math.pi / 4),
z_roof_top - 3.0 + 3.0 * math.sin(math.pi / 4)),
(y_front, z_roof_top - 3.0))
.lineTo(y_front, Z_WR)
.close()
.extrude(35.0, both=True))
s = s.fuse(roof_w.val())
# 4. L�见��渡��梯� (+Y靘改�Y: y_hub_in..y_out嚗䔶� Z_EL 憿嗥垢撱嗡撓�喃��寧㩞�箏漣)
vert_leg = (cq.Workplane("YZ", origin=(X_ARM, 0, 0))
.moveTo(y_hub_in, z_top_housing)
.lineTo(y_out, z_top_housing)
.lineTo(y_out, Z_EL)
.lineTo(y_hub_in, Z_EL)
.close()
.extrude(35.0, both=True))
s = s.fuse(vert_leg.val())
# 5. L�见�靘批�撘批�撘箄�皜∴�Circular Arc Gusset嚗𣬚鍂�瑁�瘙�"�寞���憫�䔶��舀�閫𡜐�瘨���祉征撠誩�"嚗�
# 敶餃��碶誨�渲��䁅�銝𡒊凒�𦦵瑪�䁅�嚗屸��其�憿園𢒰�𣬚��勗��詨���像皛穃��孵之��憫 (R=28.0mm)
# 韏瑞��券▲�踹像�湧𢒰 (y_arc_start, z_roof_top)嚗𣬚移蝖桃㮾��秐蝡𧢲���儒�� (y_hub_in, z_arc_end)
# 銝交綉�典� Z >= z_top_housing嚗�蝠摨閙��支噩�乩��寞�頧砍����蝛箏��孵�銝𤾸�雿嗵�韏瘀�
# 瘜剁�憿嗆踎�湔辺�𣳇�19mm(z_roof_top=280)�𠬍�R28�鄗14雿踹憫隞滢�憿嗆踎�W�皛𤑳㮾���銝滚枂�唳�閫�
R_arc = 14.0 # �誯▲�踹�擃䁅��券�摰𡄯��詨�韏瑞�(144.5,280)->蝏��(158.5,294)嚗屸�撘�P06�臬�z=297��3mm
y_arc_start = y_hub_in - R_arc
z_arc_end = z_roof_top + R_arc
p_mid_arc = (y_arc_start + R_arc * math.cos(math.pi / 4),
z_arc_end - R_arc * math.sin(math.pi / 4))
gusset_w = (cq.Workplane("YZ", origin=(X_ARM, 0, 0))
.moveTo(y_arc_start, z_roof_top)
.threePointArc(p_mid_arc, (y_hub_in, z_arc_end))
.lineTo(y_out, z_arc_end)
.lineTo(y_out, z_top_housing)
.lineTo(y_arc_start, z_top_housing)
.close()
.extrude(35.0, both=True))
s = s.fuse(gusset_w.val())
# 6. 銝讠漣 P08 �贝蓮����冽���霈拙��歹�R=35.5mm嚗屸��� 0.5mm �湧�嚗�
p08_clearance = Ycyl(35.5, 156.0, y_out + 2.0, X_ARM, Z_WR)
s = s.cut(p08_clearance)
# 6b. ��2026-10-02 �啣��煾▲�踵覔�典��齿局嚗�� hollow_channel嚗剹��
# 憿嗆踎�� Z255..280 銝��湔挾�臬��𡁏�瘛� 15mm ���敹��嚗諹�� J4 �� z=245 ����函頂��
# 擃䁅噢 122��=195 銋�� 24����鞉�銝𦠜�撘��� U 敶X局嚗屸▲�踹��鞉局�g�
# 瑽賢� Z255 隞乩�靽萘��游�摰𧼮��啁㩞�箏漣嚗峕�撘舐�銝斤� X �𤏸���(X-15..-7 / X47..55)
# �坔銁撘舐畆�匧��箝�� 銝𢠃��� 156 �屸��詨��� 166嚗峕糓銝箔��踹� y_hub_in=158.5 韏瑞�
# 蝡𣇉凒蝡𧢲��砌�嚗���望糓 J4 隞𤾸𢆡瘜訫���㗁�𥟇�嚗䔶��賣�嚗剹��
# 瑽賡▲ Z280 撠望糓憿嗆踎銝𡃏”�g��𧼮藁�睲�嚗���舀����撠�𡡒�𢛵��
s = s.cut(hollow_channel(P07_CH["x0"], P07_CH["x1"], P07_CH["y0"], P07_CH["y1"],
P07_CH["z_floor"], 300.0, tag="P07憿嗆踎"))
# 7. M5 �菜㦤摰㕑��亙藁銝𤾸�摮鞟征��
s = j5.front_collar_pocket(s, r_bore=30.25 + CLEARANCE_GAP, z0=50.0, z1=56.5)
s = j5.rear_mount_holes(s, t_plate=8.0, hole_d=2.8, cb_d=5.5, cb_depth=4.0)
s = j5.pocket(s)
s = s.cut(Ycyl(30.5 + CLEARANCE_GAP, HL.Y_REAR - 0.5, y_front - 6.0, X_ARM, Z_WR))
# �𠰴����霈曇恣嚗�-Z摨閖��菜㦤摰𡁜��𡁻���
vent_cut = bx(X_ARM - 40.0, X_ARM + 40.0, y_rear + 8.0, y_front - 6.0, Z_WR - 40.0, Z_WR - 25.0)
s = s.cut(vent_cut)
# 7b. ��2026-10-02 �啣��餹5 �滨垢�讠� 4xM3x8(BCD55)嚗鐝5 ��䔉�芾◤�𡒊垢�踹��a�甇鳴�
# 憭扳酞�拐�隡𡁶� J5 頧游銁摨批��𣬚�憭氬��緵�典�蝡臭��W�憭嫣�甈∴�閫� motor_front_clamp嚗剹��
# 敹�◆�函洵 6 甇� p08_clearance嚗㇌35.5 霈拐�摮䈑�Y>=156嚗劐��𡒊��伐��血��讠�隡朞◤�𦠜���
# P08 �� J5 隞𤾸𢆡靘批歇�詨��𡒊宏�� Y>=162嚗éake_pitch_to_roll_bracket �� hub_gap=6.0嚗剹��
s = s.fuse(motor_front_clamp(X_ARM, Z_WR, tag="P07/M5"))
# 7c2.��2026-10-05e�穃��匧�蝡�"�湔𣏹"�冽���儒����𠰴��臬�嚗�� FENCE_OPEN_CUT嚗剹��
# 銝� P04/P06 �峕���釣�𤩺𧋦隞嗥� front_collar_pocket �其� r_bore=30.25+CLEARANCE_GAP
# =32.25嚗�2.0mm �唾��湧�嚗㚁��臬��䭾迨�渲�嚗ǐ32.25..35嚗㚁����銝𡡞��孵��其��氬��
s = cut_motor_fence(s, j5, "P07/M5", "P07")
# 8. J4 �渲�瘜訫�蝏𤘪�嚗�瑌�啣辣隡詨�瘜訫��䁅��V��� 2.0mm 頝刻��湧�銝擧��啁��W𤐄�娍𦻖嚗�
# 靽脲��訫�雿橒���瑌�圈鵭摨西��� y_hub_in 韏堆�瘜訫��睃�蝘餅𧒄�詨蝱�峕郊�𣳇鵭嚗�
# 3xS01 颲枏枂�粹���仍�W蝱��(撅��� z=58)����踴��俥���銝擧㺿�滚��其��氬��
boss = cyl(17.8, 54.942, (y_hub_in - HL.Y_REAR) + 2.0)
s = s.fuse(j4.L(boss))
s = s.cut(j4.L(cyl(3.5, 54.0, 74.0 + 30.0)))
s = hub_m2_holes(s, j4, cb_z1=74.0 + 30.0)
# 9. 撌亥䰾韏啁瑪�𡁜�
slot_z = (Z_EL + z_top_housing) / 2.0
slot = Ycyl(7.0, y_hub_in - 2.0, y_out + 2.0, X_ARM, slot_z)
s = s.cut(slot)
# ========== �喲睸���隡睃� ==========
try:
# �𦒘儒憿嗆踎憭𤥁器蝻睃�閫𡜐�撟單�瘨�膄瘞游像憿嗆踎銝𤾸��典��渡垢�V漱瘙���� 90簞 撠𤥁�嚗𣬚鍂�瑁�瘙��坿��孵�閫𡜐�
wp_s = cq.Workplane(obj=s)
sel_rear = cq.selectors.BoxSelector(
(X_ARM - 40, y_rear - 1.0, z_roof_top - 1.0),
(X_ARM + 40, y_rear + 1.0, z_roof_top + 1.0)
)
s = wp_s.edges(sel_rear).fillet(FILLET_SMALL).val()
except Exception as e:
print(f"P07 憿嗆踎�舘器蝻睃�閫鍦�撣�: {e}")
return s
def p_wrist_bracket(j5, j6):
"""P08_�訫�頧砍漣_�箸�雿�25%_憓�4摨�5_蝡𡝗�嚗�楛摨血�閫雴��𣇉�嚗�
hub_gap=6.0嚗麿5 憭� P07 �啣�鈭� M5 �滨垢�讠�嚗À 155.5..161.0嚗㚁�隞𤾸𢆡瘜訫��䁅��W�憿�
隞� Y=157 �𡒊宏�� Y=162 霈拐�嚗桕5 �湧��詨蝱�峕郊�𣳇鵭嚗�3xS01 颲枏枂�粹��砍��譍��塩��
"""
return make_pitch_to_roll_bracket(j5, j6, Z_WR, Z_R6,
name="P08_�訫�頧砍漣_�箸�雿�25%_憓�4摨�5_蝡𡝗�",
hub_gap=6.0)
def p_tool_flange(j6):
"""P09_撌亙�瘜訫�_�箸�雿�30%_憓�4摨�5_蝡𡝗� 瘛勗漲���隡睃���
�喲睸�寡�嚗�
1. 憭𤥁蔭撱枏����嚗㇌=4mm嚗�
2. 瘜訫��W�坿�嚗�2mm嚗�
3. �箏�颲寧��坿�嚗�1.5mm嚗�
"""
z_bot = Z_HUB6 - PLATE_T - 9.0
s = cyl(35.0, z_bot, Z_HUB6, X_ARM, Y_AXIS)
P09_M4 = []
# 4x M4�箸�摮�
#
# ������敺� 20 -> 22嚗㇂CD 40 -> 44嚗㚁�R20 銝� 3xS01 颲枏枂�粹��� �5.6 �箔����𡁻�
# 嚗éake_direct_hub �� cyl(2.8, 58.0, z_out+40) �� BCD29=R14.5��㮾雿� 351.4/232.3/112.1簞嚗�
# �祉忽瘝匧���0簞 ��葵摮𥪯葉敹� (39.5,128) �� 351.4簞 �𡁻�銝剖� (33.84,125.83) �芣� 6.06mm嚗�
# �䔶舅摮𥪜�敺���峕糓 3.5+2.8=6.30 �婙�� 撌� 0.24mm嚗䁱�7.0 瘝匧�憯�◤���銝��梹�
# 摰峕㟲�����(88mm簡)鋆�� 45.7+35.4 銝斤�嚗�朖�冽��芸㦛�𣬚����摮𢛵��
# 霂亦㮾雿滚榆�芣� 8.6簞嚗諹蓮�� M4 摮𠉛㮾雿齿�瘜閗熔撘�嚗�0/90/180/270 銝� 45 摨阡�撘��券�隞� <6.30嚗㚁�
# �芾��惩之������敺��R22 �嗆�撠譍葉敹�� 7.96mm嚗䔶��� 1.66mm��
# 颲孵�隞滚�頞喉�R35 瘜訫�憭硋� - (R22 + 瘝匧� 3.5) = 9.5mm��
for a in (0, 90, 180, 270):
rad = 22.0
u = rad * math.cos(a * D2R)
v = rad * math.sin(a * D2R)
# 摰鮋���𠧧�刻��� make_direct_hub 銋见�嚗��銝页������蘨蝞堒枂 4 銝芸�雿溻��
P09_M4.append((X_ARM + u, Y_AXIS + v))
# 摰帋�甇W藁 + 韏啁瑪摮�
pilot = cyl(10.0, z_bot - 1.0, z_bot + 2.5, X_ARM, Y_AXIS)
thru = cyl(5.0, z_bot - 1.0, Z_HUB6 + 1.0, X_ARM, Y_AXIS)
s = s.cut(pilot).cut(thru)
# �渲�瘜訫�
s = make_direct_hub(s, j6, r_disc=35.0, z_out=74.0)
# 4x M4 摮䈑�敹�◆�� make_direct_hub 銋见����
#
# �渲�瘜訫���郊 fuse 鈭� R35 ���嚗���� z=56.5..74 -> �典� z=102..121 銝�靘改�嚗�
# 隡𡁏��������齿鰵憛急香嚗𡁜�畾菜�鈭斗遬蝷� z=97..102 �惩僕瘨剹��=102 隞乩��湔覔����见銁�䠷�
# 嚗��畾� 12.57 mm^3 = pi*2^2*1嚗���芷𢒰鋡怠�嚗剹��
#
# 摮𥪜�銝擧楛摨血��嗡耨甇���批�� �3.7 瘥� M4 �� �4.0 餈条�嚗䔶��芸� z=105嚗�
# �� M4x16 憭湧𢒰�� z=97���閬�粥�� z=113 �婙�� ��偏 8mm �惩��臬縧嚗�僕瘨� 147.3 mm^3嚗剹��
# �4.4 �� M4 ����湧�摮䈑�ISO 273 medium �� �4.3嚗剹��
# 摮娪▲閬��餈� M4x16 ���撠橘�憭湧𢒰 z=97 + ��鵭 16 = z=113嚗峕�撘��� Z_HUB6+4=115嚗�
# 瘥娍�撠曉��� 2mm嚗��瘚见��� 112 �嗆��� 1mm ��偏隞齿��� 37.7mm糧嚗剹��
for (fx, fy) in P09_M4:
s = s.cut(cyl(2.2, z_bot - 1.0, Z_HUB6 + 4.0, fx, fy))
s = s.cut(cyl(3.5, z_bot - 1.0, z_bot + 4.0, fx, fy))
# ========== �喲睸���隡睃� ==========
try:
# 憭𤥁蔭撱枏�閫�
s = s.edges("|Z").fillet(FILLET_SMALL)
except:
pass
try:
# 瘜訫��W�坿�
s = s.edges("<Z").chamfer(CHAMFER_EDGE)
except:
pass
try:
# 憿園�颲寧����
s = s.edges(">Z").fillet(FILLET_TINY)
except:
pass
return s
# ---------------------------------------------------------------- assembly ----------------
def build():
print("=" * 80, flush=True)
print("�鞟洵銝��嗆挾 1/5�穃�憪讠��鞉����蝥扳�隞� 3D �牐�摰硺�璅∪�...", flush=True)
print("=" * 80, flush=True)
t_stage1 = time.time()
print(" [0/9] 頧賢��菜㦤���隞嗆芋蝏� (STEP)...", end="", flush=True)
t0 = time.time()
motor = cq.importers.importStep(AB.SRC_STEP).val()
motor = place(motor, T(0, 0, -2.57))
AB.MOTOR, AB.HALF, AB.CLAMP = motor, None, None
print(f" 摰峕� ({time.time()-t0:.2f}s) ��", flush=True)
JS = {}
for tag, cn, rear, d, xd, holder, driven in HL.JOINTS:
JS[tag] = Joint(tag, cn, rear, d, xd, lug_phase=90.0 if tag == "J1" else 0.0)
j1, j2, j3, j4, j5, j6 = (JS["J%d" % k] for k in range(1, 7))
PARTS[:] = []
AB.CENTS.clear()
AB.GRP = {}
par = {"J1": "root", "J2": "J1", "J3": "J2", "J4": "J3", "J5": "J4", "J6": "J5"}
driven = {"J1": "P04_�拙�_�箸�雿�30%_憓�5摨�5_蝡𡝗�", "J2": "P05_憭扯��贝蓮摨否�箸�雿�30%_憓�4摨�5_蝡𡝗�", "J3": "P06_憭扯�撉冽沲_�箸�雿�25%_憓�4摨�5_蝡𡝗�",
"J4": "P07_撠讛�撉冽沲_�箸�雿�30%_憓�5摨�5_蝡𡝗�", "J5": "P08_�訫�頧砍漣_�箸�雿�25%_憓�4摨�5_蝡𡝗�", "J6": "P09_撌亙�瘜訫�_�箸�雿�30%_憓�4摨�5_蝡𡝗�"}
motor_of = {"J1": "M1_J1", "J2": "M2_J2", "J3": "M3_J3",
"J4": "M4_J4", "J5": "M5_J5", "J6": "M6_J6"}
for t in ("J1", "J2", "J3", "J4", "J5", "J6"):
AB.GRP[motor_of[t]] = par[t]
AB.GRP[driven[t]] = t
AB.GRP.update({
"P01_A_蝡𧢲�銝𧢲挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�": "root", "P01_B_蝡𧢲�銝剜挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�": "root", "P01_C_蝡𧢲�銝𦠜挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�": "root",
"P02_Center_摨訫漣銝剜瓲敹��箸�雿�30%_憓�5摨�6_撟單�": "root", "P02_Front_�滚��脩蕃�𥡝�_�箸�雿�30%_憓�4摨�5_撟單�": "root", "P02_Rear_�𤾸��脩蕃�𥡝�_�箸�雿�30%_憓�4摨�5_撟單�": "root",
"P03_�拙����箸�雿�35%_憓�5摨�5_蝡𡝗�": "root"
})
AB.JAW = {}
p01_full = p_chest()
p01_a, p01_b, p01_c = split_p01_poka_yoke(p01_full)
p02_c, p02_f, p02_r = make_p02_poka_yoke()
parts_to_build = [
("P01_A_蝡𧢲�銝𧢲挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�", "蝡𧢲�銝𧢲挾", lambda: p01_a, 0x0284c7,
"200mm�����挾A嚗𡁻�166mm+16mm�嗆0�祆托+憿嗥垢 2x �3.9 撖寥�摮�(M4x16 �芣𤫇)+摨閖�50x50x12璁怠仍+P01-A 蝡𡝗�TOP�餃�"),
("P01_B_蝡𧢲�銝剜挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�", "蝡𧢲�銝剜挾", lambda: p01_b, 0x2563eb,
"200mm�����挾B嚗𡁻�165mm+�𣬚垢�祆�璁�+銝斤垢�� 2x �3.9 撖寥�摮�(M4x16 �芣𤫇嚗屸�撖寧妍摮𥪯��脣�鋆�)+P01-B 蝡𡝗�TOP�餃�"),
("P01_C_蝡𧢲�銝𦠜挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�", "蝡𧢲�銝𦠜挾", lambda: p01_c, 0x1d4ed8,
"200mm�����挾C嚗𡁻�149mm+摨閧垢瘥齿托+摨閧垢 2x �3.9 撖寥�摮�(�𧼮笆蝘啣�雿漤俈�滩�)+憿園𢒰P03摰㕑���(4x �3.9 摰㕑�摮� + 1x �3.9 璅芸���揮摮�)+P01-C 蝡𡝗�TOP�餃�"),
("P02_Center_摨訫漣銝剜瓲敹��箸�雿�30%_憓�5摨�6_撟單�", "摨訫漣�詨��踹�摨�", lambda: p02_c, 0x475569,
"200mm���銝剖漣嚗�195x190mm�詨��踹�摨�+48mm憟㛖�+12mm�嗆0璁怠漣(頧游��X㗁頧�)+�滚�銝㕑��惩撩蝑�+�滚��𧼮笆蝘圈俈���璁急局+�餃�"),
("P02_Front_�滚��脩蕃�𥡝�_�箸�雿�30%_憓�4摨�5_撟單�", "�滚��脩蕃�𥡝�", lambda: p02_f, 0xe11d48,
"200mm����滩�嚗�145x190mm�拙��𥡝�+104mm摰質楊頝嘥��祆托+摨閖�M5憸���箸�瘝㗇局+P02-FRONT�餃�"),
("P02_Rear_�𤾸��脩蕃�𥡝�_�箸�雿�30%_憓�4摨�5_撟單�", "�𤾸��脩蕃�𥡝�", lambda: p02_r, 0xd97706,
"200mm����舘�嚗�45x190mm�拙��𥡝�+80mm蝒�楊頝嘥��祆托+摨閖�M5憸���箸�瘝㗇局+P02-REAR�餃�"),
("P03_�拙����箸�雿�35%_憓�5摨�5_蝡𡝗�", "�拙����鋆����", lambda: p_girdle(j1), 0x4b5563,
"頧駁��𡝗踎撘𤩺��嗥�嚗帋蜓撟脩眏 66mm 摰𧼮��埈㺿銝箏�靘� 6mm 獢�沲蝡𡝗踎+撣鞟窈�誯�蝒�(�𣈯𢒰��52簞�芣𣈲��)+R4���嚗��頧桀�銝擧唂��僎����其��湛�摰𧼮� 728->286cm糧嚗𥕦��� 9mm �踹��滚漣(�3.9 摰㕑�摮�)+12mm 銝凋�樴䠷爸蝑�(�芷�摨扳��㕑秐瘜訫�銝讠�)+40~45簞憭𡝗��𨀣�嚗𥕢��� 10mm �𡒊蔭瘜訫���儒撘�撘讐㩞�箸��嗚���60.7 �湧�𡁶㩞�箄�(撟喳��惩蝱��)(M1 隞�+Y皛穃�,�𡒊垢 4xM3x16 ��香)��之���蝒𦯀�撖寞�瑽踝��惩��剔征�𢛵����舀�"),
("P04_�拙�_�箸�雿�30%_憓�5摨�5_蝡𡝗�", "�拙�", lambda: p_fork(j1, j2), 0x2563eb,
"朣𣂼像�埝局+ M2 �滨垢�讠�+ 蝡𧢲��誯�瑽賜�嚗𡁜��輯��V�P03�䀹沲蝡舫𢒰(11.5)0.0蝖祈斐撟喉��冽�閬��憭𤥁�朣𣂼像嚗㚁�P03靘扳�瑽賜𡠺蝡见���3mm嚗愢1�菜㦤�臬�暹��∪�嚗𥇍1颲枏枂�詨蝱韐舫�𡁶凒餈䂿㩞�綽�J1隞𤾸𢆡瘜訫����曌𤘪�撌脣�嚗�𦻖蝻嘥躹銝窰03甇Z��舫�敺��擃𤇼36.5/憿�646.5嚗㚁��訫�雿枏�閫鍦漲�嗅僕瘨㚁���2026-10-02�餹2 �滨垢�讠�(R35, Y155.5..161.0)嚗𡁶㩞�箏�蝡舐�憭𣇉垢�W� 4xM3x8 瘝匧�(BCD55)憭寧揮嚗䔶��𡒊垢摰㕑��� 4xM3x10 敶X��滚�����W�嚗峕��文之�剔畆銝讠㩞�箏銁摨批��𣬚��暹�嚗䜘��2026-10-02�𤑳��勗��齿局(X23~35 / Y102~154 / �武525�睲��𧼮�)嚗𡁶��崔525~635�湔挾憯��撜啣��17.5mm嚗𥇍2�肛=560/600����函頂�唳�19嚗峕㺿�䤪敶X局�W�361->289cm3(-20%)嚗峕�撘舐�銝斤�X�𤏸��踵迤憟質氜�典摩�拇��见躹(z=560�芷𢒰X13~45��葉�折𢒰X29嚗諹��踹�X13~23/X35~45)嚗峕��厩�甇�糓銝剜�批�����牐�銝滚�銝擧�撘舐��辷�瑽賢�Z525隞乩�靽萘��游�摰𧼮�餈�腹�啁㩞�箏漣嚗峕局摨閙偌撟單�銝𨳍��儒憯���氬��▲�冽�撘���妟�舀�銝娪�撠�𡡒�䈑�撘�摨行�����滚躹��撌桀��函頂�� >= �䭾局�箇瑪 95%�漤�匧�嚗Ǎ23~35 瘥娍��萘� X21~37 �嗥� 2mm嚗�撩摨虫� 88% �𧼮� 95%嚗㚁���2026-10-04 閫���湔㺿�𤑳㩞�箔��寥��� 4048mm2 ��之撟喲𢒰�寞� Hermite 撘折𢒰嚗��銵𣬚��齿醌 907s 蝖株恕 J1~J6 銵𣬚��鞾★銝滚�嚗㚁���䔉 yz_pts ��(164.5,646.5)->(155.5,526) �臭��∠凒蝥選�瘝� X �㗇� 4048mm2 撟單踎嚗���� (0,1,-0.07)��蒂 4簞 �𨅯漲嚗㚁�甇�笆�菜㦤銝𦠜䲮嚗䔶舅靘扯◤ xz_wire �� R18 ��憫�文枂�鳴�敶X��䔶葉�港��堒像��舅颲寥��滨�閫����㺿�𣂷�甈� Hermite嚗�舅蝡臬�蝥踹��急窒 Y/Z嚗䔶�銝𠹺�瘞游像畾� G1 餈䂿賒嚗㚁�銝剝��� +Y 憭硋瑌蝥� 3mm嚗�憫摨虫�銝支儒 R18 銝��湛��閙挾��憫�䭾��峕𧒄皛∟雲銝斤垢��瑪嚗�圾�� R=9 銝� R=120.5 �𤤿㦛嚗㗇��� Hermite��04 雿梶妖 282.1->274.3cm糧嚗�憫�X𤜯隞�像�W��厩��辷�嚗䜘��2026-10-05 �踹��Z悟雿滩��嫣蛹 R35 �����瑌�唬��湔𣏹銝�撟嗆��扎�𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)�典��娍��箸㗁�钅𢒰��**���𠰴�敹�◆蝑劐�憭硋� R35**嚗Òrm_build.SEAT_R嚗㚁��硋�鈭� R35嚗�㦛霂� 32.2 = 64.4 �寡��������塚����𠰴�銝𤾸�憯���湧��� 2.8mm �臬�摰峕㟲靽萘�嚗諹�峕㗁�钅𢒰�芣��啣��𠰴�嚗䔶��航砲�臬��詨笆�踹��U�𣂼瑌韏瑯�穃僎�羓㩞�箏偏蝡舫𢒰�港� �婙�� 餈坔停�舐鍂�瑟⏛�暸������凒�∴�P08 摰墧� 1536.9mm3嚗剹���銝齿糓畾讠�嚗諹�峕糓 SEAT_R<R35 ����嗡漣�押��緵 SEAT_R=35.0��EAT_TOP=+1.0嚗��餈�偏蝡舫𢒰 1mm嚗���匧���������⏛0.052cm3 畾讠�嚗㚁��踹��X挾�游��硋�憭硋�嚗峕㗁�钅𢒰�𣂷蛹摰峕㟲 R35 撟喳��矋��詨蝱銝𤾸凒�∩�韏瑟�憭梧��菜㦤撠曄垢�V��踹��V��游��惩瑌韏瑯��㗁�𥟇㺿�梯�頨急𧋦雿𤘪㗁���band 畾� r36..58 �㗇��嫣� P04 10/36���雿坔� 15/36嚗��雿蹱䲮雿漤� z>+1.0 �臭�餈墧𦻖嚗峕��游��𡁏局嚗剹���摮� z �粹𡢿(-8..-4)銝𤾸���(-2.6..+1.0)銝漤��𩤃�S02 摰�末���撣佗��踹��舐眏�峕䲮�𥪜��� 32.2 �� 瘝匧�憭𣇉� 30.25 = 1.95mm 蝒�㴓�滚�銝箝����� R35 ��㴓 4.75mm�㵪��堒��Y妖 383->974mm簡(2.5 ��)����2026-10-04 �踹��Z悟雿滩��嫣蛹 32.2 ����𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)銋见��� 64.4 **��**�娍��箸䔉嚗峕䲮�𥪜�隞亙� z=-2.6..0 ����嗵㮾撖寞鰵�踹��W瑌韏� 2.6mm嚗峕��唳𧒄�舀�蝛箄�憯���冽��漤�嚗𡁻𠗕�枏㫲����舀����撌桀榆嚗剹��緵�踹��X挾�寧鍂**SEAT_R=32.2 ���**嚗�= 64.4 �寡��������𠰴�嚗庒=-2.6..0 銝擧䲮�𥪜像�伐��𦠜㟲����唳㗁�钅𢒰擃睃漲嚗�瑌�圈妟畾讠�嚗𣜖=0 隞乩� PCBA �𥪯�靽脲� 64.4 �對�PCB �舀䲮���憿餅䲮�䈑���**�喲睸嚗𡁜��𠰴�敹�◆�� 32.2 �䔶��� R35** �婙�� 銝剝𡢿霂閗� R35嚗𣬚��𨀣� r=32.2..35 ����亙��游���鱏嚗𡁜�瘚� P04 �� z=-2.6..+1.0 �芸� 240~320簞 �嫣��㗇�嚗��雿� 360簞 �冽�蝛綽��𡒊垢瘜訫�銝擧𡟵憯���游枂�� 3.6mm 摰賡�𡁏局 + 225簞 銝��� 0.5mm 摮斤����嚗�鍂�瑟⏛�橘��拙�憿園��峕瓷餈硺��㵪���� 32.2 �� r=32.2..35 餈坔� 2.8mm �𡁜�摰峕㟲靽萘�嚗�360簞 餈䂿賒嚗峕𠳿�惩瑌�啣�銝𦒘��寡�頨怨��𣂷�雿橒�摰墧� 5/5 隞嗉��亙��游�餈
("P05_憭扯��贝蓮摨否�箸�雿�30%_憓�4摨�5_蝡𡝗�", "憭扯��贝蓮摨�", lambda: p_shoulder_roll_base(j2, j3, None), 0x059669,
"V3���+ J2�滨垢憭寧揮�滚�嚗匁oft憭𤥁蔭撱𣫮=10mm嚗𥴰�贝蓮閫鍦���2mm�坿�嚗��蝻睃瑌��舅閫�90簞蝡𡝗ㄠ蝤沖2���嚗����/�𡒊�擃睃漲銝滚�嚗峕��唳��祆�嚗㚁�J2 隞𤾸𢆡瘜訫��䁅��Y眏 Y=157 �𡒊宏�� Y=162嚗áub_gap=6.0嚗𣬚� P04 �啣��� M2 �滨垢�讠�霈拐�嚗𥇍2 �湧��詨蝱�峕郊�𣳇鵭�� Y=165.5嚗�3xS01 颲枏枂�粹��砍��譍��矋�嚗𥕢�霂� J2 �刻�摨� 0 撟脫�嚗䜘��2026-10-05d �芸��𧼮藁�����凒�~�𤑳鍂�瑟��� M3 �菜㦤�滨垢(�虫�憭�)銋��銝���凒�∴�Z389.0~395.5 �� r30.25~35 �滨垢摰帋���(6mm 擃条㴓憓�) + 撉穃銁摰���Y� R35 �讠�憭硋�(�70 瘥𠉛㩞�� �63.6 �� 3.2mm)嚗峕� M3 �滨垢�𤥁��𣬚忽餈� �37 摮𠉛� P06 J3 �詨蝱�游銁銝剝𡢿��洵銝�����港葵�滨垢(摰帋���+�讠�+�𥪜藁銝𧢲窒 389->395)�賢�鈭��餈�漲(�菜㦤�滨垢憭勗縧�舀��U��3 ���𧼮��a�甇�)嚗�歇�鮋��嚗𤤿緵�芸��𧼮藁(-Y)�����(�鍦�嚗磤 �屸�銝� cut_open 銝���)嚗�-Y �𠰴�隞� Z=395.5 銝�頝臬��啣��𤥁��� Z=389嚗諹���(+Y)靘扳㟲����嗘��滨垢�硋�雿滢��讠��臭�銝磰雲憭笔撩��𣈲�煾𢒰(4.75mm 摰� x 0.5mm �娍𦻖撣�)嚗𥕦��𡝗𧋦雿�/�37 摮�/4xM3x8 瘝匧�/�𥪜藁銝𧢲窒 389.0 �券�銝滚𢆡嚗釶05 �芸� 3.2cm3(154.8->151.6)嚗䔶��訫�雿瓐����游��𠰴� R31.8 ����𩤃����憯�� Loft �� X=簣35 憭�� �70 �梢𢒰�詨�嚗峕㟲���摰䔶��梁征�� 1.32mm3 蝣𤾸��游��訫�雿橒�銝𥪜��𡝗覔�函��仿𢒰隡帋� 2.37mm2 蝻拙� 0.78mm2嚗�4xM3x8 憭寧揮�𥕢��𠰴��𡝗�銝𧢲䔉����� FENCE_OPEN_CUT嚗�2026-10-05e 韏瑚蛹�冽㦤 5 憭���剁�����2026-10-03�餹3 �滨垢�讠�(R35, Z384.0..389.0)嚗麿3 roll �菜㦤��䔉銋笔蘨�匧�蝡舀踎 4xM3x10 �閖𢒰��香(S02)嚗�之�剔畆銝讠� J3 頧游銁 �60.3 摨批��𣬚�憭湛��唳� P04/P06/P07 �䔶��齿䲮�� M3 �滨垢�硋�蝡舫𢒰(Z=389)�� 4xM3x8(BCD55)瘝匧��讠�嚗䔶��𡒊垢�踹��𤾸��煾𢒰�页��暹��芰眏摨血��塚��齿䲮�臭�撌桀��� roll �菜㦤頧游� -Z嚗���𡝗� -Z �選�閫� motor_front_clamp axis=\"Z\"嚗㚁�隞�遠�臬笆靘� P06 �� J3 瘥�𢒰�港��𡒊宏 5.5mm 霈拐�嚗䜘��2026-10-05 �踹��Z悟雿滩��嫣蛹 R35 �����瑌�唬��湔𣏹銝�撟嗆��扎�𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)�典��娍��箸㗁�钅𢒰��**���𠰴�敹�◆蝑劐�憭硋� R35**嚗Òrm_build.SEAT_R嚗㚁��硋�鈭� R35嚗�㦛霂� 32.2 = 64.4 �寡��������塚����𠰴�銝𤾸�憯���湧��� 2.8mm �臬�摰峕㟲靽萘�嚗諹�峕㗁�钅𢒰�芣��啣��𠰴�嚗䔶��航砲�臬��詨笆�踹��U�𣂼瑌韏瑯�穃僎�羓㩞�箏偏蝡舫𢒰�港� �婙�� 餈坔停�舐鍂�瑟⏛�暸������凒�∴�P08 摰墧� 1536.9mm3嚗剹���銝齿糓畾讠�嚗諹�峕糓 SEAT_R<R35 ����嗡漣�押��緵 SEAT_R=35.0��EAT_TOP=+1.0嚗��餈�偏蝡舫𢒰 1mm嚗���匧���������⏛0.052cm3 畾讠�嚗㚁��踹��X挾�游��硋�憭硋�嚗峕㗁�钅𢒰�𣂷蛹摰峕㟲 R35 撟喳��矋��詨蝱銝𤾸凒�∩�韏瑟�憭梧��菜㦤撠曄垢�V��踹��V��游��惩瑌韏瑯��㗁�𥟇㺿�梯�頨急𧋦雿𤘪㗁���band 畾� r36..58 �㗇��嫣� P04 10/36���雿坔� 15/36嚗��雿蹱䲮雿漤� z>+1.0 �臭�餈墧𦻖嚗峕��游��𡁏局嚗剹���摮� z �粹𡢿(-8..-4)銝𤾸���(-2.6..+1.0)銝漤��𩤃�S02 摰�末���撣佗��踹��舐眏�峕䲮�𥪜��� 32.2 �� 瘝匧�憭𣇉� 30.25 = 1.95mm 蝒�㴓�滚�銝箝����� R35 ��㴓 4.75mm�㵪��堒��Y妖 383->974mm簡(2.5 ��)����2026-10-04 �踹��Z悟雿滩��嫣蛹 32.2 ����𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)銋见��� 64.4 **��**�娍��箸䔉嚗峕䲮�𥪜�隞亙� z=-2.6..0 ����嗵㮾撖寞鰵�踹��W瑌韏� 2.6mm嚗峕��唳𧒄�舀�蝛箄�憯���冽��漤�嚗𡁻𠗕�枏㫲����舀����撌桀榆嚗剹��緵�踹��X挾�寧鍂**SEAT_R=32.2 ���**嚗�= 64.4 �寡��������𠰴�嚗庒=-2.6..0 銝擧䲮�𥪜像�伐��𦠜㟲����唳㗁�钅𢒰擃睃漲嚗�瑌�圈妟畾讠�嚗𣜖=0 隞乩� PCBA �𥪯�靽脲� 64.4 �對�PCB �舀䲮���憿餅䲮�䈑���**�喲睸嚗𡁜��𠰴�敹�◆�� 32.2 �䔶��� R35** �婙�� 銝剝𡢿霂閗� R35嚗𣬚��𨀣� r=32.2..35 ����亙��游���鱏嚗𡁜�瘚� P04 �� z=-2.6..+1.0 �芸� 240~320簞 �嫣��㗇�嚗��雿� 360簞 �冽�蝛綽��𡒊垢瘜訫�銝擧𡟵憯���游枂�� 3.6mm 摰賡�𡁏局 + 225簞 銝��� 0.5mm 摮斤����嚗�鍂�瑟⏛�橘��拙�憿園��峕瓷餈硺��㵪���� 32.2 �� r=32.2..35 餈坔� 2.8mm �𡁜�摰峕�
("P06_憭扯�撉冽沲_�箸�雿�25%_憓�4摨�5_蝡𡝗�", "憭扯�撉冽沲", lambda: p_humerus_bone(j3, j4), 0x0d9488,
"Loft�㗇㦤餈�腹����罸�P05��憫�䀹䲮敶X𦆮�瑞�瘜𤏪�憿嗥垢�70甇��銝𥣡3撟喲��惩蝱�塚�摨閧垢皜𣂼��滚�M4�梁揮憟㛖�銝𤾸ㄢ雿橒���2026-10-03�穃�瘨�㩞�箔��過oft餈�腹��(Z360~385)��㘚敶W��滨�嚗峕�憭滚�敹��霂亦�瘝璣韐舫�𡄯�甇�𢒰�𧢲糓�湔㦤���曄尐憭���拙耦暺烐�(�冽�閫���湔㺿)嚗䔶誨隞瑚� +22cm3/+27g嚗�撩摨虫�銝箸�蝒堒抅蝥�100%嚗䜘��2026-10-03�飦3 瘥�𢒰�港��𡒊宏 5.5mm(憿嗥垢 388.5��383.0嚗𣬚凒��瑌�� 59.5��65.0)嚗𡁶� P05 �啣��� M3 �滨垢�讠�(Z384..389)霈拐�嚗𣬚� 1.0mm �券𡢿�仮�婙�𥪯� Y 頧港�憭�(J2/J4/J5 隞支��冽��啁� Y157��162)摰���峕�嚗峕揢蝞堒��䔶蛹����� 5.0 + �券𡢿�� 1.0 - �笔抅�� 0.5�㵪��詨蝱�峕郊�𣳇鵭嚗�3xS01 憭湧𢒰�圈𧫴(s=58)/��鵭/�砍��譍� J3 �湧��喟頂銝�敺衤��矋���2026-10-05 �踹��Z悟雿滩��嫣蛹 R35 �����瑌�唬��湔𣏹銝�撟嗆��扎�𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)�典��娍��箸㗁�钅𢒰��**���𠰴�敹�◆蝑劐�憭硋� R35**嚗Òrm_build.SEAT_R嚗㚁��硋�鈭� R35嚗�㦛霂� 32.2 = 64.4 �寡��������塚����𠰴�銝𤾸�憯���湧��� 2.8mm �臬�摰峕㟲靽萘�嚗諹�峕㗁�钅𢒰�芣��啣��𠰴�嚗䔶��航砲�臬��詨笆�踹��U�𣂼瑌韏瑯�穃僎�羓㩞�箏偏蝡舫𢒰�港� �婙�� 餈坔停�舐鍂�瑟⏛�暸������凒�∴�P08 摰墧� 1536.9mm3嚗剹���銝齿糓畾讠�嚗諹�峕糓 SEAT_R<R35 ����嗡漣�押��緵 SEAT_R=35.0��EAT_TOP=+1.0嚗��餈�偏蝡舫𢒰 1mm嚗���匧���������⏛0.052cm3 畾讠�嚗㚁��踹��X挾�游��硋�憭硋�嚗峕㗁�钅𢒰�𣂷蛹摰峕㟲 R35 撟喳��矋��詨蝱銝𤾸凒�∩�韏瑟�憭梧��菜㦤撠曄垢�V��踹��V��游��惩瑌韏瑯��㗁�𥟇㺿�梯�頨急𧋦雿𤘪㗁���band 畾� r36..58 �㗇��嫣� P04 10/36���雿坔� 15/36嚗��雿蹱䲮雿漤� z>+1.0 �臭�餈墧𦻖嚗峕��游��𡁏局嚗剹���摮� z �粹𡢿(-8..-4)銝𤾸���(-2.6..+1.0)銝漤��𩤃�S02 摰�末���撣佗��踹��舐眏�峕䲮�𥪜��� 32.2 �� 瘝匧�憭𣇉� 30.25 = 1.95mm 蝒�㴓�滚�銝箝����� R35 ��㴓 4.75mm�㵪��堒��Y妖 383->974mm簡(2.5 ��)����2026-10-04 �踹��Z悟雿滩��嫣蛹 32.2 ����𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)銋见��� 64.4 **��**�娍��箸䔉嚗峕䲮�𥪜�隞亙� z=-2.6..0 ����嗵㮾撖寞鰵�踹��W瑌韏� 2.6mm嚗峕��唳𧒄�舀�蝛箄�憯���冽��漤�嚗𡁻𠗕�枏㫲����舀����撌桀榆嚗剹��緵�踹��X挾�寧鍂**SEAT_R=32.2 ���**嚗�= 64.4 �寡��������𠰴�嚗庒=-2.6..0 銝擧䲮�𥪜像�伐��𦠜㟲����唳㗁�钅𢒰擃睃漲嚗�瑌�圈妟畾讠�嚗𣜖=0 隞乩� PCBA �𥪯�靽脲� 64.4 �對�PCB �舀䲮���憿餅䲮�䈑���**�喲睸嚗𡁜��𠰴�敹�◆�� 32.2 �䔶��� R35** �婙�� 銝剝𡢿霂閗� R35嚗𣬚��𨀣� r=32.2..35 ����亙��游���鱏嚗𡁜�瘚� P04 �� z=-2.6..+1.0 �芸� 240~320簞 �嫣��㗇�嚗��雿� 360簞 �冽�蝛綽��𡒊垢瘜訫�銝擧𡟵憯���游枂�� 3.6mm 摰賡�𡁏局 + 225簞 銝��� 0.5mm 摮斤����嚗�鍂�瑟⏛�橘��拙�憿園��峕瓷餈硺��㵪���� 32.2 �� r=32.2..35 餈坔� 2.8mm �𡁜�摰峕㟲靽萘�嚗�360簞 餈䂿賒嚗峕𠳿�惩瑌�啣�銝𦒘��寡�頨怨��𣂷�雿橒�摰墧� 5/5 隞嗉��亙��游�餈䂿賒���摰硺�嚗�"),
("P07_撠讛�撉冽沲_�箸�雿�30%_憓�5摨�5_蝡𡝗�", "撠讛�撉冽沲", lambda: p_forearm_bone(j4, j5, None), 0x7c3aed,
"V2 L�讠��� + 憿嗆踎�誯�瑽踝�+Y靘扯��羓��梢�霈拙之��爸�塚�餈�腹�粹��其�憿嗆踎�𣬚��勗��詨���=28mm撟單���篅憭批�撘改�敶餃�瘨�膄�湔�蝥踵�閫雴��祉征�嗆0撠誩�嚗屸▲�踹��𤾸�蝻�2mm�坿��鄗3���嚗屸▲�踵㟲�∪�擃�19mm(z261->280)�惩撩餈墧𦻖銝𣼵usset撘刪28->R14�滚��詨��滚�嚗𥇍4���憭𡝗窒銝𡒊��勗�璉曹��鍦�靽脲��笔�撠𤥁�嚗䔶��遍5�菜㦤�𠰴����嚗䔶膳隞啣之��凒�芰眏餈𣂼𢆡�嗅僕瘨㚁���2026-10-02�煾▲�踵覔�汶255~280撘��苷��𧼮�����齿局(X-3~43 / Y103~153, Y銝𢠃���153�踹�y_hub_in=158.5韏瑞�蝡𣇉凒蝡𧢲��砌�)嚗𡁻▲�輻眏摰𧼮��䀹局�g�288->230cm3(-20%)嚗峕局摨蓥誑銝衤��蹱㟲�堒�敹���菜㦤摨改��堒摩�牐舅靘批�10mm���𤏸��選�瑽賢�瘞游像�苷���儒憯���氬��▲�冽�撘���妟�舀�銝娪�撠�𡡒�䈑�撘�摨行�����滚躹��撌桀��函頂�� >= �䭾局�箇瑪 95%�漤�匧�嚗Ǎ-3~43 瘥娍��萘� X-7~47 �嗥� 4mm嚗�撩摨虫� 88% �𧼮� 96%嚗㚁���2026-10-05 �踹��Z悟雿滩��嫣蛹 R35 �����瑌�唬��湔𣏹銝�撟嗆��扎�𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)�典��娍��箸㗁�钅𢒰��**���𠰴�敹�◆蝑劐�憭硋� R35**嚗Òrm_build.SEAT_R嚗㚁��硋�鈭� R35嚗�㦛霂� 32.2 = 64.4 �寡��������塚����𠰴�銝𤾸�憯���湧��� 2.8mm �臬�摰峕㟲靽萘�嚗諹�峕㗁�钅𢒰�芣��啣��𠰴�嚗䔶��航砲�臬��詨笆�踹��U�𣂼瑌韏瑯�穃僎�羓㩞�箏偏蝡舫𢒰�港� �婙�� 餈坔停�舐鍂�瑟⏛�暸������凒�∴�P08 摰墧� 1536.9mm3嚗剹���銝齿糓畾讠�嚗諹�峕糓 SEAT_R<R35 ����嗡漣�押��緵 SEAT_R=35.0��EAT_TOP=+1.0嚗��餈�偏蝡舫𢒰 1mm嚗���匧���������⏛0.052cm3 畾讠�嚗㚁��踹��X挾�游��硋�憭硋�嚗峕㗁�钅𢒰�𣂷蛹摰峕㟲 R35 撟喳��矋��詨蝱銝𤾸凒�∩�韏瑟�憭梧��菜㦤撠曄垢�V��踹��V��游��惩瑌韏瑯��㗁�𥟇㺿�梯�頨急𧋦雿𤘪㗁���band 畾� r36..58 �㗇��嫣� P04 10/36���雿坔� 15/36嚗��雿蹱䲮雿漤� z>+1.0 �臭�餈墧𦻖嚗峕��游��𡁏局嚗剹���摮� z �粹𡢿(-8..-4)銝𤾸���(-2.6..+1.0)銝漤��𩤃�S02 摰�末���撣佗��踹��舐眏�峕䲮�𥪜��� 32.2 �� 瘝匧�憭𣇉� 30.25 = 1.95mm 蝒�㴓�滚�銝箝����� R35 ��㴓 4.75mm�㵪��堒��Y妖 383->974mm簡(2.5 ��)����2026-10-04 �踹��Z悟雿滩��嫣蛹 32.2 ����𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)銋见��� 64.4 **��**�娍��箸䔉嚗峕䲮�𥪜�隞亙� z=-2.6..0 ����嗵㮾撖寞鰵�踹��W瑌韏� 2.6mm嚗峕��唳𧒄�舀�蝛箄�憯���冽��漤�嚗𡁻𠗕�枏㫲����舀����撌桀榆嚗剹��緵�踹��X挾�寧鍂**SEAT_R=32.2 ���**嚗�= 64.4 �寡��������𠰴�嚗庒=-2.6..0 銝擧䲮�𥪜像�伐��𦠜㟲����唳㗁�钅𢒰擃睃漲嚗�瑌�圈妟畾讠�嚗𣜖=0 隞乩� PCBA �𥪯�靽脲� 64.4 �對�PCB �舀䲮���憿餅䲮�䈑���**�喲睸嚗𡁜��𠰴�敹�◆�� 32.2 �䔶��� R35** �婙�� 銝剝𡢿霂閗� R35嚗𣬚��𨀣� r=32.2..35 ����亙��游���鱏嚗𡁜�瘚� P04 �� z=-2.6..+1.0 �芸� 240~320簞 �嫣��㗇�嚗��雿� 360簞 �冽�蝛綽��𡒊垢瘜訫�銝擧𡟵憯���游枂�� 3.6mm 摰賡�𡁏局 + 225簞 銝��� 0.5mm 摮斤����嚗�鍂�瑟⏛�橘��拙�憿園��峕瓷餈硺��㵪���� 32.2 �� r=32.2..35 餈坔� 2.8mm �𡁜�摰峕㟲靽萘�嚗�360簞 餈䂿賒嚗峕𠳿�惩瑌�啣�銝𦒘��寡�頨怨��𣂷�雿橒�摰墧� 5/5 隞嗉��亙��游�餈䂿賒���摰硺�嚗�"),
("P08_�訫�頧砍漣_�箸�雿�25%_憓�4摨�5_蝡𡝗�", "�閖�頧祆𦻖摨�", lambda: p_wrist_bracket(j5, j6), 0xd97706,
"V2���嚗匁oft憭𤥁蔭撱𣫮=10mm嚗𥴰�贝蓮閫鍦���2mm�坿�嚗�蝠摨閙��斤�憯��霂�5�刻�摨�0撟脫�嚗䜘��2026-10-05 �踹��Z悟雿滩��嫣蛹 R35 �����瑌�唬��湔𣏹銝�撟嗆��扎�𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)�典��娍��箸㗁�钅𢒰��**���𠰴�敹�◆蝑劐�憭硋� R35**嚗Òrm_build.SEAT_R嚗㚁��硋�鈭� R35嚗�㦛霂� 32.2 = 64.4 �寡��������塚����𠰴�銝𤾸�憯���湧��� 2.8mm �臬�摰峕㟲靽萘�嚗諹�峕㗁�钅𢒰�芣��啣��𠰴�嚗䔶��航砲�臬��詨笆�踹��U�𣂼瑌韏瑯�穃僎�羓㩞�箏偏蝡舫𢒰�港� �婙�� 餈坔停�舐鍂�瑟⏛�暸������凒�∴�P08 摰墧� 1536.9mm3嚗剹���銝齿糓畾讠�嚗諹�峕糓 SEAT_R<R35 ����嗡漣�押��緵 SEAT_R=35.0��EAT_TOP=+1.0嚗��餈�偏蝡舫𢒰 1mm嚗���匧���������⏛0.052cm3 畾讠�嚗㚁��踹��X挾�游��硋�憭硋�嚗峕㗁�钅𢒰�𣂷蛹摰峕㟲 R35 撟喳��矋��詨蝱銝𤾸凒�∩�韏瑟�憭梧��菜㦤撠曄垢�V��踹��V��游��惩瑌韏瑯��㗁�𥟇㺿�梯�頨急𧋦雿𤘪㗁���band 畾� r36..58 �㗇��嫣� P04 10/36���雿坔� 15/36嚗��雿蹱䲮雿漤� z>+1.0 �臭�餈墧𦻖嚗峕��游��𡁏局嚗剹���摮� z �粹𡢿(-8..-4)銝𤾸���(-2.6..+1.0)銝漤��𩤃�S02 摰�末���撣佗��踹��舐眏�峕䲮�𥪜��� 32.2 �� 瘝匧�憭𣇉� 30.25 = 1.95mm 蝒�㴓�滚�銝箝����� R35 ��㴓 4.75mm�㵪��堒��Y妖 383->974mm簡(2.5 ��)����2026-10-04 �踹��Z悟雿滩��嫣蛹 32.2 ����𤑳㩞�箏偏蝡臬𠿭���(REAR_SEAT=2.6)銋见��� 64.4 **��**�娍��箸䔉嚗峕䲮�𥪜�隞亙� z=-2.6..0 ����嗵㮾撖寞鰵�踹��W瑌韏� 2.6mm嚗峕��唳𧒄�舀�蝛箄�憯���冽��漤�嚗𡁻𠗕�枏㫲����舀����撌桀榆嚗剹��緵�踹��X挾�寧鍂**SEAT_R=32.2 ���**嚗�= 64.4 �寡��������𠰴�嚗庒=-2.6..0 銝擧䲮�𥪜像�伐��𦠜㟲����唳㗁�钅𢒰擃睃漲嚗�瑌�圈妟畾讠�嚗𣜖=0 隞乩� PCBA �𥪯�靽脲� 64.4 �對�PCB �舀䲮���憿餅䲮�䈑���**�喲睸嚗𡁜��𠰴�敹�◆�� 32.2 �䔶��� R35** �婙�� 銝剝𡢿霂閗� R35嚗𣬚��𨀣� r=32.2..35 ����亙��游���鱏嚗𡁜�瘚� P04 �� z=-2.6..+1.0 �芸� 240~320簞 �嫣��㗇�嚗��雿� 360簞 �冽�蝛綽��𡒊垢瘜訫�銝擧𡟵憯���游枂�� 3.6mm 摰賡�𡁏局 + 225簞 銝��� 0.5mm 摮斤����嚗�鍂�瑟⏛�橘��拙�憿園��峕瓷餈硺��㵪���� 32.2 �� r=32.2..35 餈坔� 2.8mm �𡁜�摰峕㟲靽萘�嚗�360簞 餈䂿賒嚗峕𠳿�惩瑌�啣�銝𦒘��寡�頨怨��𣂷�雿橒�摰墧� 5/5 隞嗉��亙��游�餈䂿賒���摰硺�嚗�"),
("P09_撌亙�瘜訫�_�箸�雿�30%_憓�4摨�5_蝡𡝗�", "�怎垢撌亙�瘜訫�", lambda: p_tool_flange(j6), 0xdc2626,
"V2���嚗𡁜�頧桀�R=3mm嚗峕��圈𢒰�坿�2mm嚗䜘��2026-10-02�烐��啣‵��眏100%�滚�30%嚗朞砲�芷𢒰摰匧�蝟餅㺭288�臬��箄�摨行�憭抒�隞塚�皛∪‵��滲撅墧答韐對�隞嗅噡�峕郊�嫣蛹P09_撌亙�瘜訫�_�箸�雿�30%嚗�"),
]
total_parts = len(parts_to_build)
for idx, (name, cn, fn, color, note) in enumerate(parts_to_build, 1):
print(f" [{idx}/{total_parts}] 甇�銁��遣 {name} ({cn})...", end="", flush=True)
t0 = time.time()
sh = fn()
dt = time.time() - t0
vol = AB.vol_of(sh) / 1000.0
n_solids = len(solids_of(sh))
print(f" 摰峕� �� ({dt:.2f}s | 雿梶妖: {vol:.1f} cm糧 | 摰硺���: {n_solids})", flush=True)
add(name, cn, sh, color, note=note)
print(" [鋆��] 甇�銁撠� M1~M6 �菜㦤摰帋��喳��唾��鞉�雿滚尿...", end="", flush=True)
t0 = time.time()
for k, (tag, cn, rear, d, xd, holder, driven_name) in enumerate(HL.JOINTS):
j = JS[tag]
add("M%d_%s" % (k + 1, tag), "%s �菜㦤璅∠�" % tag, place(motor, j.t), 0x9ca3af,
printed=False, note="憭滨鍂 �菜㦤.STEP")
print(f" 摰峕� �� ({time.time()-t0:.2f}s)", flush=True)
print(f"-> ��辣璅∪��券����摰峕�嚗峕�餉�埈𧒄: {time.time()-t_stage1:.2f}s\n", flush=True)
return JS
CHAIN = ["root", "J1", "J2", "J3", "J4", "J5", "J6"]
SEP = 74.0
def explode_chain(p, JS, cents, gmean):
"""����曉�蝘鳴�蝡𧢲���凒�嗆0�匧�嚗��摨批��𡡞俈���撘�嚗𣬚㩞�箸窒頧湔��綽��箸1��㟲雿㯄�銝𦠜挾��氖"""
nm = p["name"]
if nm == "P01_A_蝡𧢲�銝𧢲挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�":
return [0.0, 0.0, 0.0]
if nm == "P01_B_蝡𧢲�銝剜挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�":
return [0.0, 0.0, 60.0]
if nm == "P01_C_蝡𧢲�銝𦠜挾_銝㕑�敶�30%_憓�4摨�5_蝡𡝗�":
return [0.0, 0.0, 120.0]
if nm == "P02_Center_摨訫漣銝剜瓲敹��箸�雿�30%_憓�5摨�6_撟單�":
return [0.0, 0.0, 0.0]
if nm == "P02_Front_�滚��脩蕃�𥡝�_�箸�雿�30%_憓�4摨�5_撟單�":
return [65.0, 0.0, 0.0]
if nm == "P02_Rear_�𤾸��脩蕃�𥡝�_�箸�雿�30%_憓�4摨�5_撟單�":
return [-65.0, 0.0, 0.0]
if nm == "P03_�拙����箸�雿�35%_憓�5摨�5_蝡𡝗�":
return [0.0, 0.0, 120.0]
grp = AB.GRP.get(p["name"], "root")
if grp == "root":
return [0.0, 0.0, 0.0]
k = CHAIN.index(grp)
off = [0.0, 0.0, 120.0 - SEP * k]
j = JS.get(grp)
if j:
w = 0.0
if "�𡃏�頧游膥" in nm or "�梁�" in nm:
w = 34.0 * (1.0 if ("A" in nm[-1:]) else -1.0)
elif nm.startswith("M"):
w = 62.0
for q in range(3):
off[q] += j.d[q] * w
return off
if __name__ == "__main__":
JS = build()
print("=" * 80, flush=True)
print("�𣂼�摰硺��𤘪�摰峕㟲�扳嵗撉䎚�煾�霂���㗇��唳�隞嗆�敶W�雿梶𠶖��...", flush=True)
print("=" * 80, flush=True)
bad = 0
printed_list = [p for p in PARTS if p["printed"]]
total_pr = len(printed_list)
for idx, p in enumerate(printed_list, 1):
n = len(solids_of(p["shape"]))
if n != 1:
bad += 1
status = "�訫�雿� ��" if n == 1 else f"撘�虜 ({n} 銝芸�雿�) ��"
print(f" [{idx}/{total_pr}] {p['name']:<14} : 雿梶妖 {p['vol']/1000.0:6.1f} cm糧 | {status}", flush=True)
if bad == 0:
print(f"-> �訫�雿𤘪��亙��券�朞�嚗�total_pr}/{total_pr} ��辣��蛹摰𣬚��蓥�瘚�耦�𤘪� �脪n", flush=True)
else:
print(f"-> �𤑳緵 {bad} 銝芷��訫�雿𤘪�隞塚�\n", flush=True)
AB.explode_vec = explode_chain
bom = AB.export(JS)
# 蝝批𤐄隞塚��粹�嚗匧�靘𧢲釣�伐��� docs/screws.json �� 72 憸𡑒卽�㗇��笔�摮𥪯�餈睃��𣂷�蝏游�靘页�
# 餈賢�餈� web/mesh_arm.json �� parts嚗�䰻�见膥�舐� BOM �箔�銵屸�鈭桀�雿㵪�蝥舀㺭�殷�銝滚𢆡 CAD嚗�
try:
import screw_mesh
screw_mesh.main()
except Exception as e:
print("�粹�摰硺�瘜典�憭梯揖嚗��敶勗�銝餅�蝔页��舀��刻� src/screw_mesh.py嚗�:", e, flush=True)
cl = AB.collide()
try:
from build_viewer import rebuild_viewer
rebuild_viewer()
except Exception as e:
print("rebuild_viewer error:", e, flush=True)
# �航噢����芸𢆡瘜典�嚗鋫B.export �𡁻��躰� mesh_arm.json嚗��蝏靝辣隡朞◤�脫�嚗㚁�
# 餈䠷��滩� FK ��甅 + ���蝵烐聢瘜典�嚗���齿����甈⊥䰻�见膥嚗�漲 3~4s嚗𣬚滲�唳旿�� CAD 霈∠�嚗�
try:
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
"..", "scratch"))
import ws_sweep
import gen_env_mesh
t_env = time.time()
ws_sweep.main()
gen_env_mesh.main()
from build_viewer import rebuild_viewer as _rbv
_rbv()
print(f"-> �航噢���撌脰䌊�冽釣�交䰻�见膥嚗�+{time.time()-t_env:.1f}s嚗争�\n", flush=True)
except Exception as e:
print("�航噢����芸𢆡瘜典�憭梯揖嚗��敶勗�銝餅�蝔页�靽桀��擧��刻� scratch/gen_env_mesh.py + src/build_viewer.py嚗�:",
e, flush=True)
print("=" * 80, flush=True)
print("�� �箏膥鈭箸����霂㻫��紡�箔��亦��典�撣��瘚��摰峕�嚗�", flush=True)
print("=" * 80, flush=True)
sys.stdout.flush()
os._exit(0)