Skip to content

Instantly share code, notes, and snippets.

@tartavull
Created July 2, 2019 13:44
Show Gist options
  • Save tartavull/b8f193a7529c9af63ea21f245757aaef to your computer and use it in GitHub Desktop.
Save tartavull/b8f193a7529c9af63ea21f245757aaef to your computer and use it in GitHub Desktop.
from __future__ import division
import rhinoscriptsyntax as rs
__commandname__ = "tbr_seam"
def get_plane(c_0, c_1):
"""
Given two curves it gives you a normal vector to them
"""
pass
def point_to_coordinates(p):
return p.X, p.Y, p.Z
def coordinates_to_point(xyz):
return rs.coerce3dpoint(xyz)
def normalize(p):
l = (p.X**2 + p.Y**2 + p.Z **2) ** 0.5
return p / l
def get_direction(c):
"""
Given a curve it gives your a length one vector
describing it orientation
"""
p0, p1 = rs.CurvePoints(c)
v = (p1 - p0) / rs.Distance(p0, p1)
return v
def cross_product(u, v):
u = point_to_coordinates(u)
v = point_to_coordinates(v)
dim = len(u)
s = []
s.append(u[1]*v[2] - u[2]*v[1])
s.append(u[2]*v[0] - u[2]*v[0])
s.append(u[0]*v[1] - u[1]*v[0])
return coordinates_to_point(s)
def get_edge(message):
edges = rs.GetEdgeCurves(message, min_count=1, max_count=1)
curve_id, parent_id, selection_point = edges[0]
return parent_id, curve_id
def fillet_corner(c0, c1, radius=7.):
p0, p1, _, _, _, _ = rs.CurveFilletPoints(c0, c1 , radius, return_points=False)
c0k, c0d = rs.SplitCurve(c0, rs.CurveClosestPoint(c0,p0), delete_input=True)
c1d, c1k = rs.SplitCurve(c1, rs.CurveClosestPoint(c1,p1), delete_input=True)
rs.DeleteObject(c0d)
rs.DeleteObject(c1d)
fillet = rs.AddFilletCurve(c0k, c1k, radius=radius, base_point0=p0, base_point1=p1)
return rs.JoinCurves([c0k, fillet, c1k], delete_input=True)
def get_type(obj):
return {
0: "Unknown object",
1: "Point",
2: "Point cloud",
4: "Curve",
8: "Surface",
16: "Polysurface",
32: "Mesh",
256: "Light",
512: "Annotation",
4096: "Instance or block reference",
8192: "Text dot object",
16384: "Grip object",
32768: "Detail",
65536: "Hatch",
131072: "Morph control",
134217728: "Cage",
268435456: "Phantom",
536870912: "Clipping plane",
1073741824: "Extrusion"}[rs.ObjectType(obj)]
def extrude_both_sides(curve, p, direction, length=100):
e0 = rs.ExtrudeCurveStraight(curve, p, p+direction * length)
rs.CapPlanarHoles(e0)
e1 = rs.ExtrudeCurveStraight(curve, p, p-direction * length)
rs.CapPlanarHoles(e1)
rs.DeleteObject(curve)
return rs.BooleanUnion([e0,e1], delete_input=True)
def draw_rounded_trapesoid(p,v,u,trap):
top = rs.AddCurve([p,p+v-trap], degree=3)
right = rs.AddCurve([p+v-trap,p+v+u+trap], degree=3)
bottom = rs.AddCurve([p+v+u+trap,p+u], degree=3)
left = rs.AddCurve([p+u,p], degree=3)
top_right = fillet_corner(top,right)
top_right_bottom = fillet_corner(top_right, bottom)
return rs.JoinCurves([top_right_bottom, left], delete_input=True)
def RunCommand(is_interactive):
obj_0, seam_edge = get_edge("Get seam edge")
obj_1, other_seam_edge = get_edge("Opposite seam eedge")
_, width_edge = get_edge("Tooth edge")
#widht = rs.GetInteger("width")
n_teeth = 5
assert obj_0 != obj_1
assert get_type(obj_0) == "Polysurface"
assert get_type(obj_1) == "Polysurface"
assert seam_edge != other_seam_edge
#TODO check it has the same start and end points
assert get_type(seam_edge) == "Curve"
assert get_type(other_seam_edge) == "Curve"
print("assertion passed")
p0, p1 = rs.CurvePoints(seam_edge)
u = get_direction(seam_edge) * rs.Distance(p0, p1) / n_teeth
v = get_direction(width_edge) * 15
w = normalize(cross_product(u,v))
p = p0
rs.DeleteObjects([seam_edge, other_seam_edge, width_edge])
trap = 0.2 * u
print("computed u,v and w")
for i in range(n_teeth):
if i % 2 == 0:
tooth_curve = draw_rounded_trapesoid(p,v,u,trap)
long_tooth = extrude_both_sides(tooth_curve, p0, w)
tooth_0 = rs.BooleanIntersection(obj_0, long_tooth, delete_input=False)
tooth_1 = rs.CopyObject(tooth_0)
rs.DeleteObject(long_tooth)
obj_0 = rs.BooleanDifference(obj_0, tooth_0, delete_input=True)
obj_1 = rs.BooleanUnion([obj_1, tooth_1], delete_input=True)
else:
tooth_curve = draw_rounded_trapesoid(p,-v,u,trap)
long_tooth = extrude_both_sides(tooth_curve, p0, w)
tooth_0 = rs.BooleanIntersection(obj_1, long_tooth, delete_input=False)
tooth_1 = rs.CopyObject(tooth_0)
rs.DeleteObject(long_tooth)
obj_1 = rs.BooleanDifference(obj_1, tooth_0, delete_input=True)
obj_0 = rs.BooleanUnion([obj_0, tooth_1], delete_input=True)
p = p + u
print("Created seam")
if __name__ == "__main__":
RunCommand(True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment