from openscad4 import *

c1=circle(30)
l1=cr2dt([[0,0],[100,0,0]@rt(10),[130,0,0]@rt(-10)])
a=path_offset(l1,15)
b=path_offset(l1,-15)
c=path_offset(l1,-5)
b=b[:-1]+[c[-1]]
sec=a+flip(b)
sec=corner_n_radius_list(sec,[0,50,9.9,9.9,50,0])
a1=fillet_line_circle(sec[44:],c1,50,4)
a2=fillet_line_circle(sec[:2],c1,50,2)
sec1=concave_hull(homogenise([c1,sec,a1,a2],2,0))

sec2=min_d_points(equidistant_pathc(sec1,pitch=2),1)[:-1]
c2=circle(15)
l1=mPointOnLine(mid_line(a,b),2,-10)[:-1]
c=path_offset(l1,6)
d=path_offset(l1,-6)
sec3=corner_n_radius_list(c+flip(d),[0,40,5.9,5.9,40,0])
a3=fillet_line_circle(sec3[44:],c2,40,4)
a4=fillet_line_circle(sec3[:2],c2,40,2)
sec4=equidistant_path(concave_hull(homogenise([c2,sec3,a3,a4],1,0)),500)
sec4=[npol(sec4,p,30) for p in sec2]

sec5=offset(sec4,-1)

l1=c23(sec2)
l2,l3=translate([0,0,10],[sec4,sec5])
surf1=[l1,l2,l3]
moveLineOnSurf(surf1,1,-1)
surf2=cpo([bspline_open(p,3,20) for p in cpo(surf1)])
surf3=surface_offset(surf2,1)
l4=two_surface_intersection(plane([0,0,1],[1000,1000],[100,0,0]),surf3)
l5=contiguous_chains(l4)[0]
l6=[npol(l5,p,2) for p in surf3[0]]
surf4=[l6]+surf3[1:]

sol1=surf2+flip(surf4)+[surf2[0]]

c3=translate([0,0,-1],circle(26))
c4=plos_tri(triangulate_solid_openx(surf1,0,1),c3,[0,0,1],1)
c5=translate([0,0,10],circle(15))
c6=translate([0,0,10],circle(13))
c7=translate([0,0,3],circle(12))
c8=translate([0,0,3],circle(3))
c9=translate([0,0,1],circle(3))
c10=translate([0,0,1],circle(14))
c11=translate([0,0,8],circle(15))
c12=translate([0,0,2.64],circle(24))
c13=translate([0,0,-1],circle(24))
sol2=[c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13]
moveLineOnSurf(sol2,1,1)
moveLineOnSurf(sol2,3,-1)
moveLineOnSurf(sol2,5,1)
moveLineOnSurf(sol2,7,-1)
moveLineOnSurf(sol2,8,1)
moveLineOnSurf(sol2,10,-1)
moveLineOnSurf(sol2,12,1)
moveLineOnSurf(sol2,14,-1)
moveLineOnSurf(sol2,15,1)
moveLineOnSurf(sol2,17,-1)
moveLineOnSurf(sol2,18,1)
moveLineOnSurf(sol2,20,-1)
moveLineOnSurf(sol2,21,1)
sol3=cpo([ bspline_open(p,3,100) for p in cpo(sol2)])
sol3=sol3+[sol3[0]]

l1=axis_rot_1(cr3dt([[-40,0,1.5],[70,0,0,5],[3,0,-1.7,5],[20,0,0]]),[0,0,1],[0,0,0],10)
l2=[[-40,0],[40,0]]
s1=sweep_sec2path(l2,l1)
s2=translate([0,0,-3],s1)
sol4=solid_from_2surfaces(s1,s2)

solx=sol3[4:22]
soly=psos_tri(triangulate_solid_openx(surf2,0,1),solx,[0,0,1],1e7,1,)
solz=sol3[:4]+soly+sol3[22:]

surf5=[p[23:222] for p in surf2]

l1=point_vector([0,0],rot2d(10,[50,0]))
l2=path_offset(l1,-6)
l3=path_offset(l1,6)
p0=two_polylines_intersection(sol3[63],c23(l3)+c23(flip(l2)),3)
p1=a_(p0)[:,0].tolist()
pa,pb=p1[7],p1[1]
l4=equidistant_path(trim_sec_ip(sol3[63],pa,pb),20)
l5=equidistant_path(trim_sec_ip(sol3[63],p1[5],p1[4]),20)
s1=slice_surface(surface_line_vector(l4,[50,0,0]@rt(10)),5)
s2=slice_surface(surface_line_vector(l5,[50,0,0]@rt(10)),5)
s2=psos_tri(triangulate_solid_openx(surf4,0,1),s2,[0,0,1],1e7,1)
sol5=solid_from_2surfaces(s1,s2)

l1=c32(axis_rot_1([[-40,0,0],[70,0,0]],[0,0,1],[0,0,0],10))
l2=path_offset(l1,6)
l3=path_offset(l1,-6)
p0=two_polylines_intersection(sol3[63],c23(l2+flip(l3)),3)
p1=a_(p0)[:,0].tolist()
s1=trim_sec_ip(sol3[63],p1[7],p1[11])
p2=equidistant_path(rot('z10',cr3dt([[-13,0,1],[-5,0,0,.8],[0,0,2,.8],[-4.5,0,0]])),20)
s2=xzc(c23(translate_2d([0,-13,0],rot2d(260,c32(s1)))))
s3=[flip(s1)]+sweep_sec2path(c32(s2),p2,0,1)[1:]
s4=psos(surf4,s3,[0,0,1],1e7,1,0)
sol6=solid_from_2surfaces(s3,s4)

s1=sol3[21:40]
s2=translate([0,0,10],s1[0])
s3=flip([s2]+s1)
l1=translate([0,0,11.5],cr2dt([[0,0],[110,0,50]@rt(10),[150,0,0]@rt(-13)]))
sol7=sweep_sec2path(circle(8),l1)
l2=contiguous_chains(two_solids_intersection(s3,sol7))[0]
l2=i_p_p(sol7,l2,0)
l3=o_3dc(l2,s3,-1,1,0)
l4=i_p_p(sol7,l2,2)
f1=cpo(convert_3lines2fillet(l3,l4,l2))[:-1]
sol8=f1+sol7[1:]

fo(f'''
difference(){{
union(){{
{swp_c(sol3)}
difference(){{
{swp_c(sol1)}
{swp(sol4)}
}}
{swp(surf5)}
{swp(sol5)}
{swp(sol6)}
}}
{swp(sol8)}
}}

''')