codeCAD/pretiosius.py
2026-02-27 01:43:44 +01:00

258 lines
8.9 KiB
Python

#%%
from build123d import *
from ocp_vscode import *
from math import sin, cos, pi
import copy
set_defaults(reset_camera=Camera.KEEP, render_joints=True, helper_scale=8)
# %%
y = 120
height = 6
pad = 2
s = 0.8
s1 = 0.7
#%%
with BuildPart() as ring:
with BuildSketch(Plane.XY) as sk:
with BuildLine() as outline:
c1 = Bezier((-pad,y,0),(-pad,y+3,0),(height+pad,y+3,0),(height+pad, y, 0))
c2 = Bezier((-pad,y,0),(-pad,y-2,0),(height+pad,y-2,0),(height+pad, y, 0))
#c1 = Spline([(-pad,y,0),(height+pad,y,0)], tangents=[(0,1),( 0,-1)], tangent_scalars=[s,s])
#c2 = Spline([(-pad,y,0),(height+pad,y,0)], tangents=[(0,-1),(0,1)], tangent_scalars=[s1,s1])
make_face()
revolve(axis=Axis.X)
show(ring,outline)
# %%
outer_ring_surface = Face.revolve(c1, 360, Axis.X)
# cut ring in half and use the outer edge that got created by the cut
#outer_ring_path = (copy.copy(ring.part)-(Pos(X=10+height/2)*Box(20,50,50))).edges().sort_by(Axis.X)[-1]
outer_ring_path = ring.part.edges().sort_by(Axis.X)[0]
show(ring,outer_ring_surface,outer_ring_path)
# %%
def sinus_signal(periods, width, height,n):
dw = (width) / (n-1)
dphi = periods * 2 * pi / (n-1)
t = 0.5 # thickness
pts = [( t+0.1+dw*i, t+0.1+(height/2)*(1+sin(dphi*i))) for i in range(n)]
with BuildSketch() as sk:
with BuildLine() as signal:
Polyline(pts)
offset(amount=t)
make_face()
return sk
sig = sinus_signal(1,outer_ring_path.length/3, 5, 60)
show(sig)
#%%
wrapped_sig = outer_ring_surface.wrap_faces(sig.faces(), outer_ring_path)
show(ring, wrapped_sig)
# %%
width = 3
ri = 10
rm = ri+2
ro = ri+4
p = Pos(ri,0,0)
def string_to_binary_string(s:str):
return ''.join(["{0:08b}".format(ord(c)) for c in s])
def build_signal2D(binstring, width):
hheight = height - 1
print(f"{width=} {hheight=}")
n = len(binstring)
dw = width/n
h = 0.5 if binstring[0] == "0" else hheight
pts = [(h,+ 0.5)]
for i, b in enumerate(binstring):
pos_flank = (b == "0" and binstring[(i+1)%n] == "1")
neg_flank = (b == "1" and binstring[(i+1)%n] == "0")
#print(f"{pos_flank*1}{neg_flank*1}")
if pos_flank or neg_flank:
x = dw*(1+i) if i < len(binstring)-1 else dw*(1+i) -0.5
pts.append((h,x))
#print(f"- {i} {b}")
if pos_flank:
h = hheight
#print(f"^ {i} {b}")
pts.append((h,x))
if neg_flank:
#print(f"v {i} {b}")
h = 0.5
pts.append((h,x))
#print(f"{pts = }")
with BuildSketch() as sk:
with BuildLine() as signal:
Polyline(pts)
offset(amount=0.4)
make_face()
#rrr = Rectangle(width, height,mode=Mode.PRIVATE)
return sk
# %%
sig = build_signal2D("100010",outer_ring_path.length-0.0)
show(sig.face())
# %%
wrapped_sig = outer_ring_surface.wrap_faces(sig.faces(), outer_ring_path)
show(ring, wrapped_sig)
#show(sig)
# %%
def build_signal_A(binstring, ri):
n = len(binstring)
ro = ri+1
dphi =2*pi/(n+0)
dp = dphi/10
dh = min(dp*ro, 18*pi/180)
a = 1
tngu = lambda phi, d: (a*cos(phi), a*sin(phi), d)
tngd = lambda phi, d: (-a*cos(phi), -a*sin(phi), d)
with BuildPart() as signal:
with BuildLine(Plane.XY) as path_builder:
segments = []
h = 0 if binstring[0] == "0" else height
same_bits_streak = 0
for i, b in enumerate(binstring):
pos_flank = (b == "0" and binstring[(i+1)%n] == "1")
neg_flank = (b == "1" and binstring[(i+1)%n] == "0")
same_bits_streak += 1
if neg_flank or pos_flank or (i == n-1):
phi0 = dphi*(i-same_bits_streak+1)
phi1 = dphi*(i-same_bits_streak+1+0.5*same_bits_streak)
phi2 = dphi*(i+1)
phi0_pad = phi0 + dp
phi2_pad = phi2 - dp
#if segments:
# segments.append(Spline(segments[-1]@1,p1, tangents=[segments[-1]%1, tngu(phi2, -1)]))
segments.append(ThreePointArc(
(ri * cos(phi0_pad), ri * sin(phi0_pad),h),
(ri * cos(phi1), ri * sin(phi1),h),
(ri * cos(phi2_pad), ri * sin(phi2_pad),h),
))
same_bits_streak = 0
p1 = (ri * cos(phi2), ri * sin(phi2),height-dh)
p2 = (ri * cos(phi2), ri * sin(phi2),dh)
#l = segments[i]
if neg_flank:
h = 0
segments.append(Spline(segments[-1]@1,p1, tangents=[segments[-1]%1, tngu(phi2, -1)]))
segments.append(Spline(p1,p2,
tangents=[tngu(phi2, -1), tngd(phi2, -1)]))
if pos_flank:
h = height
segments.append(Spline(p2,p1,
tangents=[tngu(phi2, 1), tngd(phi2, 1)]))
# l1 = segments[0]
with BuildSketch(Plane( segments[0] @ 0, z_dir=segments[0] % 0)) as x_section:
Circle(0.5)
#return path_builder
sweep(transition=Transition.ROUND)
return signal
def build_signal_B(binstring, ri):
n = len(binstring)
ro = ri+1
dphi =2*pi/(n+0) # how much angle per bit
dp = 0.81/ri/pi#dphi/10 # how much of that used for curvature
dh = min(dp*ro, 10*pi/180)
a = 1
tngu = lambda phi, d: (a*cos(phi), a*sin(phi), d)
tngd = lambda phi, d: (-a*cos(phi), -a*sin(phi), d)
def build_segments(pre_segments=[]):
segments = []
h = 0 if binstring[0] == "0" else height
same_bits_streak = 0
i_hoz = 0
ns = len(pre_segments)
for i, b in enumerate(binstring):
pos_flank = b == "0" and binstring[(i+1)%n] == "1"
neg_flank = b == "1" and binstring[(i+1)%n] == "0"
same_bits_streak += 1
if neg_flank or pos_flank or (i == n-1):
phi0 = dphi*(i-same_bits_streak+1)
phi1 = dphi*(i-same_bits_streak+1+0.5*same_bits_streak)
phi2 = dphi*(i+1)
phi0_pad = phi0 + dp
phi2_pad = phi2 - dp
#if segments:
# segments.append(Spline(segments[-1]@1,p1, tangents=[segments[-1]%1, tngu(phi2, -1)]))
segments.append(ThreePointArc(
(ri * cos(phi0_pad), ri * sin(phi0_pad),h),
(ri * cos(phi1), ri * sin(phi1),h),
(ri * cos(phi2_pad), ri * sin(phi2_pad),h),
))
i_hoz += 1
same_bits_streak = 0
p1 = (ri * cos(phi2), ri * sin(phi2),height-dh)
p2 = (ri * cos(phi2), ri * sin(phi2),dh)
#l = segments[i]
if neg_flank:
h = 0
if pre_segments:
segments.append(Spline(pre_segments[i_hoz-1]@1,p1, tangents=[pre_segments[i_hoz-1]%1, tngu(phi2, -1)]))
segments.append(Spline(p1,p2,
tangents=[tngu(phi2, -1), tngd(phi2, -1)]))
segments.append(Spline(p2, pre_segments[i_hoz%ns]@0, tangents=[tngd(phi2, -1), pre_segments[i_hoz%ns]%0]))
if pos_flank:
h = height
if pre_segments:
segments.append(Spline(pre_segments[i_hoz-1]@1,p2, tangents=[pre_segments[i_hoz-1]%1, tngu(phi2, 1)]))
segments.append(Spline(p2,p1,
tangents=[tngu(phi2, 1), tngd(phi2, 1)]))
segments.append(Spline(p1, pre_segments[i_hoz%ns]@0, tangents=[tngd(phi2, 1), pre_segments[i_hoz%ns]%0]))
return segments
pre_segments = build_segments()#???
with BuildPart() as signal:
with BuildLine(Plane.XY) as path_builder:
#path_builder.mode=Mode.PRIVATE
segments = build_segments(pre_segments)
#segments = build_segments()
# l1 = segments[0]
with BuildSketch(Plane(segments[0] @ 0, z_dir=segments[0] % 0)) as x_section:
Circle(0.4)
#Rectangle(0.8,0.8)
#return path_builder
sweep()
#sweep(transition=Transition.ROUND)
signal.label="decor"
#return pre_segments
return path_builder
#return signal
# %%
#binstr = '0101100'#
#binstr = '110101000'#
binstr = string_to_binary_string("munsel")
#binstr = string_to_binary_string("nonpostrans")
signal = build_signal_B(binstr, ri+width+0.3)
#show(signal,ring, transparent=True)
show(signal, transparent=True)
#%%
product = Compound(label="ring", children=[ring.part, signal.part])
show(product)