Exemplo n.º 1
0
def extrude_example_xy_scaling() -> OpenSCADObject:
    num_points = SEGMENTS
    path_rad = PATH_RAD
    circle = circle_points(15)
    path = circle_points(rad=path_rad)

    # If scales aren't included, they'll default to
    # no scaling at each step along path.
    no_scale_obj = make_label('No Scale')
    no_scale_obj += extrude_along_path(circle, path)

    # angles: from 0 to 6*Pi
    angles = list((frange(0, 3 * tau, num_steps=len(path))))

    # With a 1-D scale factor, an extrusion grows and shrinks uniformly
    x_scales = [(1 + cos(a) / 2) for a in angles]
    x_obj = make_label('1D Scale')
    x_obj += extrude_along_path(circle, path, scales=x_scales)

    # With a 2D scale factor, a shape's X & Y dimensions can scale
    # independently, leading to more interesting shapes
    # X & Y scales vary between 0.5 & 1.5
    xy_scales = [Point2(1 + cos(a) / 2, 1 + sin(a) / 2) for a in angles]
    xy_obj = make_label('2D Scale')
    xy_obj += extrude_along_path(circle, path, scales=xy_scales)

    obj = no_scale_obj + right(3 * path_rad)(x_obj) + right(
        6 * path_rad)(xy_obj)
    return obj
Exemplo n.º 2
0
    def test_extrude_along_path_rotations(self):
        # confirm we can rotate for each point in path
        path = [[0, 0, 0], [20, 0, 0]]
        rotations = [-45, 45]
        actual = extrude_along_path(tri, path, rotations=rotations)
        expected = 'polyhedron(faces=[[0,3,1],[1,3,4],[1,4,2],[2,4,5],[2,5,0],[0,5,3],[6,0,1],[6,1,2],[6,2,0],[7,3,4],[7,4,5],[7,5,3]],points=[[0.0000000000,0.0000000000,0.0000000000],[0.0000000000,-7.0710678119,-7.0710678119],[0.0000000000,-7.0710678119,7.0710678119],[20.0000000000,0.0000000000,0.0000000000],[20.0000000000,-7.0710678119,7.0710678119],[20.0000000000,7.0710678119,7.0710678119],[0.0000000000,-4.7140452079,0.0000000000],[20.0000000000,-0.0000000000,4.7140452079]]);'
        self.assertEqualOpenScadObject(expected, actual)

        # confirm we can rotate with a single supplied value
        path = [[0, 0, 0], [20, 0, 0]]
        rotations = [45]
        actual = extrude_along_path(tri, path, rotations=rotations)
        expected = 'polyhedron(faces=[[0,3,1],[1,3,4],[1,4,2],[2,4,5],[2,5,0],[0,5,3],[6,0,1],[6,1,2],[6,2,0],[7,3,4],[7,4,5],[7,5,3]],points=[[0.0000000000,0.0000000000,0.0000000000],[0.0000000000,-10.0000000000,0.0000000000],[0.0000000000,0.0000000000,10.0000000000],[20.0000000000,0.0000000000,0.0000000000],[20.0000000000,-7.0710678119,7.0710678119],[20.0000000000,7.0710678119,7.0710678119],[0.0000000000,-3.3333333333,3.3333333333],[20.0000000000,-0.0000000000,4.7140452079]]);'
        self.assertEqualOpenScadObject(expected, actual)
Exemplo n.º 3
0
def extrude_example_rotations() -> OpenSCADObject:
    path_rad = PATH_RAD
    shape = star(num_points=5)
    path = circle_points(path_rad, num_points=240)

    # For a simple example, make one complete revolution by the end of the extrusion
    simple_rot = make_label('Simple Rotation')
    simple_rot += extrude_along_path(shape,
                                     path,
                                     rotations=[360],
                                     connect_ends=True)

    # For a more complex set of rotations, add a rotation degree for each point in path
    complex_rotations = []
    degs = 0
    oscillation_max = 60

    for i in frange(0, 1, num_steps=len(path)):
        # For the first third of the path, do one complete rotation
        if i <= 0.333:
            degs = i / 0.333 * 360
        # For the second third of the path, oscillate between +/- oscillation_max degrees
        elif i <= 0.666:
            angle = lerp(i, 0.333, 0.666, 0, 2 * tau)
            degs = oscillation_max * sin(angle)
        # For the last third of the path, oscillate increasingly fast but with smaller magnitude
        else:
            # angle increases in a nonlinear curve, so
            # oscillations should get quicker and quicker
            x = lerp(i, 0.666, 1.0, 0, 2)
            angle = pow(x, 2.2) * tau
            # decrease the size of the oscillations by a factor of 10
            # over the course of this stretch
            osc = lerp(i, 0.666, 1.0, oscillation_max, oscillation_max / 10)
            degs = osc * sin(angle)
        complex_rotations.append(degs)

    complex_rot = make_label('Complex Rotation')
    complex_rot += extrude_along_path(shape, path, rotations=complex_rotations)

    # Make some red markers to show the boundaries between the three sections of this path
    marker_w = SHAPE_RAD * 1.5
    marker = translate([path_rad, 0, 0])(cube([marker_w, 1, marker_w],
                                              center=True))
    markers = [color('red')(rotate([0, 0, 120 * i])(marker)) for i in range(3)]
    complex_rot += markers

    return simple_rot + right(3 * path_rad)(complex_rot)
Exemplo n.º 4
0
    def test_extrude_along_path_transforms(self):
        path = [[0, 0, 0], [20, 0, 0]]
        # scale points by a factor of 2 & then 1/2
        # Make sure we can take a transform function for each point in path
        transforms = [
            lambda p, path, loop: 2 * p, lambda p, path, loop: 0.5 * p
        ]
        actual = extrude_along_path(tri, path, transforms=transforms)
        expected = 'polyhedron(faces=[[0,3,1],[1,3,4],[1,4,2],[2,4,5],[2,5,0],[0,5,3],[6,0,1],[6,1,2],[6,2,0],[7,3,4],[7,4,5],[7,5,3]],points=[[0.0000000000,0.0000000000,0.0000000000],[0.0000000000,-20.0000000000,0.0000000000],[0.0000000000,0.0000000000,20.0000000000],[20.0000000000,0.0000000000,0.0000000000],[20.0000000000,-5.0000000000,0.0000000000],[20.0000000000,0.0000000000,5.0000000000],[0.0000000000,-6.6666666667,6.6666666667],[20.0000000000,-1.6666666667,1.6666666667]]);'
        self.assertEqualOpenScadObject(expected, actual)

        # Make sure we can take a single transform function for all points
        transforms = [lambda p, path, loop: 2 * p]
        actual = extrude_along_path(tri, path, transforms=transforms)
        expected = 'polyhedron(faces = [[0, 3, 1], [1, 3, 4], [1, 4, 2], [2, 4, 5], [2, 5, 0], [0, 5, 3], [6, 0, 1], [6, 1, 2], [6, 2, 0], [7, 3, 4], [7, 4, 5], [7, 5, 3]], points = [[0.0000000000, 0.0000000000, 0.0000000000], [0.0000000000, -20.0000000000, 0.0000000000], [0.0000000000, 0.0000000000, 20.0000000000], [20.0000000000, 0.0000000000, 0.0000000000], [20.0000000000, -20.0000000000, 0.0000000000], [20.0000000000, 0.0000000000, 20.0000000000], [0.0000000000, -6.6666666667, 6.6666666667], [20.0000000000, -6.6666666667, 6.6666666667]]);'
        self.assertEqualOpenScadObject(expected, actual)
Exemplo n.º 5
0
 def test_extrude_along_path_1d_scale(self):
     # verify that we can apply scalar scaling
     path = [[0, 0, 0], [0, 20, 0]]
     scales_1d = [1.5, 0.5]
     actual = extrude_along_path(tri, path, scales=scales_1d)
     expected = 'polyhedron(faces=[[0,3,1],[1,3,4],[1,4,2],[2,4,5],[2,5,0],[0,5,3],[6,0,1],[6,1,2],[6,2,0],[7,3,4],[7,4,5],[7,5,3]],points=[[0.0000000000,0.0000000000,0.0000000000],[15.0000000000,0.0000000000,0.0000000000],[0.0000000000,0.0000000000,15.0000000000],[0.0000000000,20.0000000000,0.0000000000],[5.0000000000,20.0000000000,0.0000000000],[0.0000000000,20.0000000000,5.0000000000],[5.0000000000,0.0000000000,5.0000000000],[1.6666666667,20.0000000000,1.6666666667]]);'
     self.assertEqualOpenScadObject(expected, actual)
Exemplo n.º 6
0
def extrude_example_transforms() -> OpenSCADObject:
    path_rad = PATH_RAD
    height = 2 * SHAPE_RAD
    num_steps = 120

    shape = circle_points(rad=path_rad, num_points=120)
    path = [Point3(0, 0, i) for i in frange(0, height, num_steps=num_steps)]

    max_rotation = radians(15)
    max_z_displacement = height / 10
    up = Vector3(0, 0, 1)

    # The transforms argument is powerful.
    # Each point in the entire extrusion will call this function with unique arguments:
    #   -- `path_norm` in [0, 1] specifying how far along in the extrusion a point's loop is
    #   -- `loop_norm` in [0, 1] specifying where in its loop a point is.
    def point_trans(point: Point3, path_norm: float,
                    loop_norm: float) -> Point3:
        # scale the point from 1x to 2x in the course of the
        # extrusion,
        scale = 1 + path_norm * path_norm / 2
        p = scale * point

        # Rotate the points sinusoidally up to max_rotation
        p = p.rotate_around(up, max_rotation * sin(tau * path_norm))

        # Oscillate z values sinusoidally, growing from
        # 0 magnitude to max_z_displacement
        max_z = lerp(path_norm, 0, 1, 0, max_z_displacement)
        angle = lerp(loop_norm, 0, 1, 0, 10 * tau)
        p.z += max_z * sin(angle)
        return p

    no_trans = make_label('No Transform')
    no_trans += down(height / 2)(extrude_along_path(shape,
                                                    path,
                                                    cap_ends=False))

    # We can pass transforms a single function that will be called on all points,
    # or pass a list with a transform function for each point along path
    arb_trans = make_label('Arbitrary Transform')
    arb_trans += down(height / 2)(extrude_along_path(shape,
                                                     path,
                                                     transforms=[point_trans],
                                                     cap_ends=False))

    return no_trans + right(3 * path_rad)(arb_trans)
Exemplo n.º 7
0
def basic_extrude_example():
    path_rad = PATH_RAD
    shape = star(num_points=5)
    path = sinusoidal_ring(rad=path_rad, segments=240)

    # At its simplest, just sweep a shape along a path
    extruded = extrude_along_path(shape_pts=shape, path_pts=path)
    extruded += make_label('Basic Extrude')
    return extruded
Exemplo n.º 8
0
def extrude_example_capped_ends() -> OpenSCADObject:
    num_points = SEGMENTS / 2
    path_rad = 50
    circle = star(6)
    path = circle_points(rad=path_rad)[:-4]

    # If `connect_ends` is False or unspecified, ends will be capped.
    # Endcaps will be correct for most convex or mildly concave (e.g. stars) cross sections
    capped_obj = make_label('Capped Ends')
    capped_obj += extrude_along_path(circle,
                                     path,
                                     connect_ends=False,
                                     cap_ends=True)

    # If `connect_ends` is specified, create a continuous manifold object
    connected_obj = make_label('Connected Ends')
    connected_obj += extrude_along_path(circle, path, connect_ends=True)

    return capped_obj + right(3 * path_rad)(connected_obj)
Exemplo n.º 9
0
 def test_extrude_along_path_2d_scale_list_input(self):
     # verify that we can apply differential x & y scaling
     path = [[0, 0, 0], [0, 20, 0], [0, 40, 0]]
     scales_2d = [
         (1, 1),
         (0.5, 1.5),
         (1.5, 0.5),
     ]
     actual = extrude_along_path(tri, path, scales=scales_2d)
     expected = 'polyhedron(faces=[[0,3,1],[1,3,4],[1,4,2],[2,4,5],[2,5,0],[0,5,3],[3,6,4],[4,6,7],[4,7,5],[5,7,8],[5,8,3],[3,8,6],[9,0,1],[9,1,2],[9,2,0],[10,6,7],[10,7,8],[10,8,6]],points=[[0.0000000000,0.0000000000,0.0000000000],[10.0000000000,0.0000000000,0.0000000000],[0.0000000000,0.0000000000,10.0000000000],[0.0000000000,20.0000000000,0.0000000000],[5.0000000000,20.0000000000,0.0000000000],[0.0000000000,20.0000000000,15.0000000000],[0.0000000000,40.0000000000,0.0000000000],[15.0000000000,40.0000000000,0.0000000000],[0.0000000000,40.0000000000,5.0000000000],[3.3333333333,0.0000000000,3.3333333333],[5.0000000000,40.0000000000,1.6666666667]]);'
     self.assertEqualOpenScadObject(expected, actual)
Exemplo n.º 10
0
def extrude_bridge():
    start1 = [0, 0, 0]

    face1 = face(start1, 2, 'xy')
    path1 = linearpath(start1, 10, 'z')
    cube1 = extrude_along_path(shape_pts=face1, path_pts=path1)

    start2 = [0, 0, 10]
    face2 = face(start2, 2, 'xz')
    print(np.array(face2))
    path2 = linearpath(start2, 32, 'y')
    print(np.array(path2))
    cube2 = extrude_along_path(shape_pts=face2, path_pts=path2)

    start3 = [0, 10, 0]
    face3 = face(start3, 2, 'xy')
    path3 = linearpath(start3, 10, 'z')
    cube3 = extrude_along_path(shape_pts=face3, path_pts=path3)

    return cube1 + cube2 + cube3
Exemplo n.º 11
0
    def test_extrude_along_path_numpy(self):
        try: 
            import numpy as np
        except ImportError:
            return

        N = 3
        thetas=np.linspace(0,np.pi,N) 
        path=list(zip(3*np.sin(thetas),3*np.cos(thetas),thetas)) 
        profile=list(zip(np.sin(thetas),np.cos(thetas), [0]*len(thetas))) 
        scalepts=list(np.linspace(1,.1,N))   

        # in earlier code, this would have thrown an exception
        a = extrude_along_path(shape_pts=profile, path_pts=path, scale_factors=scalepts)
Exemplo n.º 12
0
def extrude_example():
    # Note the incorrect triangulation at the two ends of the path.  This
    # is because star isn't convex, and the triangulation algorithm for
    # the two end caps only works for convex shapes.
    shape = star(num_points=5)
    path = sinusoidal_ring(rad=50)

    # If scale_factors aren't included, they'll default to
    # no scaling at each step along path.  Here, let's
    # make the shape twice as big at beginning and end of the path
    scales = [1] * len(path)
    scales[0] = 2
    scales[-1] = 2

    extruded = extrude_along_path(shape_pts=shape,
                                  path_pts=path,
                                  scale_factors=scales)

    return extruded
Exemplo n.º 13
0
 def test_extrude_along_path(self):
     path = [[0, 0, 0], [0, 20, 0]]
     # basic test
     actual = extrude_along_path(tri, path)
     expected = 'polyhedron(faces = [[0, 3, 1], [1, 3, 4], [1, 4, 2], [2, 4, 5], [2, 5, 0], [0, 5, 3], [6, 0, 1], [6, 1, 2], [6, 2, 0], [7, 3, 4], [7, 4, 5], [7, 5, 3]], points = [[0.0000000000, 0.0000000000, 0.0000000000], [10.0000000000, 0.0000000000, 0.0000000000], [0.0000000000, 0.0000000000, 10.0000000000], [0.0000000000, 20.0000000000, 0.0000000000], [10.0000000000, 20.0000000000, 0.0000000000], [0.0000000000, 20.0000000000, 10.0000000000], [3.3333333333, 0.0000000000, 3.3333333333], [3.3333333333, 20.0000000000, 3.3333333333]]);'
     self.assertEqualOpenScadObject(expected, actual)
Exemplo n.º 14
0
def extrude_cube():
    shape = face(2, 2)
    path = linearpath(0, 20, 0)
    scales = [1]
    extruded = extrude_along_path(shape_pts=shape, path_pts=path)
    return extruded
Exemplo n.º 15
0
 def test_extrude_along_path_connect_ends(self):
     path = [[0, 0, 0], [20, 0, 0], [20, 20, 0], [0, 20, 0]]
     actual = extrude_along_path(tri, path, connect_ends=True)
     expected = 'polyhedron(faces=[[0,3,1],[1,3,4],[1,4,2],[2,4,5],[2,5,0],[0,5,3],[3,6,4],[4,6,7],[4,7,5],[5,7,8],[5,8,3],[3,8,6],[6,9,7],[7,9,10],[7,10,8],[8,10,11],[8,11,6],[6,11,9],[0,9,1],[1,9,10],[1,10,2],[2,10,11],[2,11,0],[0,11,9]],points=[[0.0000000000,0.0000000000,0.0000000000],[-7.0710678119,-7.0710678119,0.0000000000],[0.0000000000,0.0000000000,10.0000000000],[20.0000000000,0.0000000000,0.0000000000],[27.0710678119,-7.0710678119,0.0000000000],[20.0000000000,0.0000000000,10.0000000000],[20.0000000000,20.0000000000,0.0000000000],[27.0710678119,27.0710678119,0.0000000000],[20.0000000000,20.0000000000,10.0000000000],[0.0000000000,20.0000000000,0.0000000000],[-7.0710678119,27.0710678119,0.0000000000],[0.0000000000,20.0000000000,10.0000000000]]);'
     self.assertEqualOpenScadObject(expected, actual)
Exemplo n.º 16
0
 def test_extrude_along_path_end_caps(self):
     path = [[0, 0, 0], [0, 20, 0]]
     actual = scad_render(extrude_along_path(tri, path, connect_ends=False))
     expected = 'polyhedron(faces = [[0, 3, 1], [1, 3, 4], [1, 4, 2], [2, 4, 5], [2, 5, 0], [0, 5, 3], [6, 0, 1], [6, 1, 2], [6, 2, 0], [7, 3, 4], [7, 4, 5], [7, 5, 3]], points = [[0.0000000000, 0.0000000000, 0.0000000000], [10.0000000000, 0.0000000000, 0.0000000000], [0.0000000000, 0.0000000000, 10.0000000000], [0.0000000000, 20.0000000000, 0.0000000000], [10.0000000000, 20.0000000000, 0.0000000000], [0.0000000000, 20.0000000000, 10.0000000000], [3.3333333333, 0.0000000000, 3.3333333333], [3.3333333333, 20.0000000000, 3.3333333333]]);'
     self.assertEqualNoWhitespace(expected, actual)
Exemplo n.º 17
0
 def test_extrude_along_path_vertical(self):
     # make sure we still look good extruding along z axis; gimbal lock can mess us up
     vert_path = [[0, 0, 0], [0, 0, 20]]
     actual = extrude_along_path(tri, vert_path)
     expected = 'polyhedron(faces=[[0,3,1],[1,3,4],[1,4,2],[2,4,5],[2,5,0],[0,5,3],[6,0,1],[6,1,2],[6,2,0],[7,3,4],[7,4,5],[7,5,3]],points=[[0.0000000000,0.0000000000,0.0000000000],[-10.0000000000,0.0000000000,0.0000000000],[0.0000000000,10.0000000000,0.0000000000],[0.0000000000,0.0000000000,20.0000000000],[-10.0000000000,0.0000000000,20.0000000000],[0.0000000000,10.0000000000,20.0000000000],[-3.3333333333,3.3333333333,0.0000000000],[-3.3333333333,3.3333333333,20.0000000000]]);'
     self.assertEqualOpenScadObject(expected, actual)