示例#1
0
 def from_blender_bezier_curve(self, bez_points, count=10):
     # Get a list of points distributed along the curve.
     points_on_curve = interpolate_bezier(bez_points[0].co,
                                          bez_points[0].handle_right,
                                          bez_points[1].handle_left,
                                          bez_points[1].co, count)
     return points_on_curve
示例#2
0
 def divide(self, number_of_segments):
     m, l, r = self.control_point_coordinates()
     points = [
         list(i) for i in interpolate_bezier(m[0], r[0], l[1], m[1],
                                             number_of_segments + 1)
     ]
     return [add_vectors(self.location, point) for point in points]
示例#3
0
def get_points(spline, clean=True, res=False):
    cyclic = True
    knots = spline.bezier_points

    if len(knots) < 2: 
        return

    r = (res if res else spline.resolution_u) + 1
    segments = len(knots)
    
    if not spline.use_cyclic_u:
        cyclic = False
        segments -= 1
 
    master_point_list = []
    for i in range(segments):
        inext = (i + 1) % len(knots)
 
        knot1 = knots[i].co
        handle1 = knots[i].handle_right
        handle2 = knots[inext].handle_left
        knot2 = knots[inext].co
        
        bezier = knot1, handle1, handle2, knot2, r
        points = interpolate_bezier(*bezier)
        master_point_list.extend(points)
 
    # some clean up to remove consecutive doubles, this could be smarter...
    if clean:
        old = master_point_list
        good = [v for i, v in enumerate(old[:-1]) if not old[i] == old[i+1]]
        good.append(old[-1])
        return good, cyclic
            
    return master_point_list, cyclic
示例#4
0
def get_points(spline, matrix_world):

    bezier_points = spline.bezier_points

    if len(bezier_points) < 2:
        return []

    r = spline.resolution_u + 1
    if r < 2:
        return []
    segments = len(bezier_points)

    if not spline.use_cyclic_u:
        segments -= 1

    point_list = []
    for i in range(segments):
        inext = (i + 1) % len(bezier_points)

        bezier_points1 = matrix_world @ bezier_points[i].co
        handle1 = matrix_world @ bezier_points[i].handle_right
        handle2 = matrix_world @ bezier_points[inext].handle_left
        bezier_points2 = matrix_world @ bezier_points[inext].co

        bezier = bezier_points1, handle1, handle2, bezier_points2, r
        points = interpolate_bezier(*bezier)
        point_list.extend(points)

    return point_list
示例#5
0
def get_points(spline, clean=True, res=False):
    cyclic = True
    knots = spline.bezier_points

    if len(knots) < 2: 
        return

    r = (res if res else spline.resolution_u) + 1
    segments = len(knots)
    
    if not spline.use_cyclic_u:
        cyclic = False
        segments -= 1
 
    master_point_list = []
    for i in range(segments):
        inext = (i + 1) % len(knots)
 
        knot1 = knots[i].co
        handle1 = knots[i].handle_right
        handle2 = knots[inext].handle_left
        knot2 = knots[inext].co
        
        bezier = knot1, handle1, handle2, knot2, r
        points = interpolate_bezier(*bezier)
        master_point_list.extend(points)
 
    # some clean up to remove consecutive doubles, this could be smarter...
    if clean:
        old = master_point_list
        good = [v for i, v in enumerate(old[:-1]) if not old[i] == old[i+1]]
        good.append(old[-1])
        return good, cyclic
            
    return master_point_list, cyclic
示例#6
0
文件: curve.py 项目: tclim/compas
 def divide(self, number_of_segments):
     middle, left, right = self.handles()
     n = number_of_segments + 1
     points = [
         list(i) for i in interpolate_bezier(middle[0], right[0], left[1],
                                             middle[1], n)
     ]
     return [add_vectors(self.xyz, point) for point in points]
    def getSplinePoints(self,spline,scale):
        
        knots = spline.bezier_points
        
        if len(knots) < 2:
            return
     
        # verts per segment
        r = spline.resolution_u + 1
        
        # segments in spline
        segments = len(knots)
        
        if not spline.use_cyclic_u:
            segments -= 1
        
        master_point_list = []
        for i in range(segments):
            inext = (i + 1) % len(knots)
     
            knot1 = knots[i].co
            handle1 = knots[i].handle_right
            handle2 = knots[inext].handle_left
            knot2 = knots[inext].co
            
            bezier = knot1, handle1, handle2, knot2, r
            points = interpolate_bezier(*bezier)
            master_point_list.extend(points)
     
        #scaling
        for i in range(len(master_point_list)):
            p = master_point_list[i]
            p.x *= scale
            p.y *= scale
            p.z *= scale
            master_point_list[i]=p
        
        # some clean up to remove consecutive doubles, this could be smarter...
        old = master_point_list
        good = [v for i, v in enumerate(old[:-1]) if not old[i] == old[i+1]]
        good.append(old[-1])

        #remove points too close to each other (distance<treshold)
        i = 0
        while i < len(good):
            if i==len(good)-1:
                j = 0
            else:
                j = i+1
            if (good[j]-good[i]).length<0.1:
                del good[j]
            else:
                i += 1
        
        #remove last index if equal to first one
        if good[0]==good[len(good)-1]:
            good = good[:len(good)-1]
        return good
示例#8
0
def test_bezier_blender():
    degree = 3
    ctrl_points = [
        Vector(tuple(sample(range(100), 3))) for _ in range(degree + 1)
    ]
    value = interpolate_bezier(ctrl_points[0], ctrl_points[1], ctrl_points[2],
                               ctrl_points[3], 10001)[5000]
    for i in range(3):
        assert fit_curve.bezier_ii(degree, ctrl_points,
                                   .5)[i] == pytest.approx(value[i], 0.001)
示例#9
0
    def calc_curve_geo(self):
        self.curve_geo.clear()
        for p, po in enumerate(self.points):
            if p > 0:
                prev_po = self.points[p-1]
                seg_pos = interpolate_bezier(
                    prev_po.co, prev_po.handle_right, po.handle_left, po.co, self.resolution)
                self.curve_geo += seg_pos

        return
示例#10
0
    def interpolate_curve_segment(self, i, resolution):
        n_points = len(self.curve_points)
        p0h = self.curve_points[(i - 1) % n_points]
        p0 = self.curve_points[i]
        p1 = self.curve_points[(i + 1) % n_points]
        p1h = self.curve_points[(i + 2) % n_points]

        weight1 = p0["weight"]
        weight2 = p1["weight"]
        knot1 = p0["2d"]
        knot2 = p1["2d"]

        if max(weight1, weight2) <= 1e-6:
            return [knot1, knot2]

        if self.round_corners:
            handle1 = p0h["2d"]
            handle2 = p1h["2d"]

            #r1 = min(weight1, self.max_radius(handle1, knot1, knot2))
            #r2 = min(weight2, self.max_radius(knot1, knot2, handle2))
            r1 = p0["r"]
            r2 = p1["r"]

            vertices = []

            n = resolution // 2

            if r1 <= 1e-6:
                vertices.append(p0["2d"])
            else:
                vertices.extend(
                    self.interpolate_arc(handle1, knot1, knot2, r1, n))
                if n == 0: vertices = vertices[1:]

            if r2 <= 1e-6:
                vertices.append(p1["2d"])
            else:
                vertices.extend(
                    self.interpolate_arc(handle2,
                                         knot2,
                                         knot1,
                                         r2,
                                         n,
                                         reverse=True))

            return vertices
        else:
            handle1 = knot1 + (knot2 - p0h["2d"]) * (weight1 * 0.5)
            handle2 = knot2 + (knot1 - p1h["2d"]) * (weight2 * 0.5)
            return interpolate_bezier(knot1, handle1, handle2, knot2,
                                      max(resolution, 2))
示例#11
0
def bezier_curve_interpolate(curve, number=3):
    """Interpolate points along a Bezier curve object.

    Parameters:
        curve (obj): Bezier curve object.
        number (int): Number of interpolation points.

    Returns:
        list: Interpolated points [x, y, z.]
    """
    co, left, right = bezier_curve_points(curve)
    vectors = interpolate_bezier(co[0], right[0], left[1], co[1], number)
    points = [list(point) for point in vectors]
    return points
def make_curve_splines(data, ob):
    context = bpy.context
    mat = ob.matrix_world
    if data.coordinate == 'active':
        '''
        v * mat * actob.matrix_world.inverted() == \
        v * (actob.matrix_world.inverted() * mat)
        '''
        actob = data.actob
        if actob:
            quat = actob.matrix_world.to_3x3().to_quaternion()
            m4 = quat.to_matrix().to_4x4()
            mat = m4.inverted() * mat
    pysplines = data.pysplines_dict[ob.name] = []
    curve = ob.data
    for spline in curve.splines:
        if spline.hide or spline.type not in ('POLY', 'BEZIER'):
            # hide:objectModeでも隠れたまま
            continue
        if not spline.points and not spline.bezier_points:
            continue

        cyclic = spline.use_cyclic_u
        if spline.type == 'POLY':
            pysp = PySpline('POLY', cyclic)
            for p in spline.points:
                pysp.points.append(p.co * mat)
            pysplines.append(pysp)
        elif spline.type == 'BEZIER':
            pysp = PySpline('BEZIER', cyclic)
            bezier_points = spline.bezier_points
            for bp in bezier_points:
                pysp.bpoints.append([bp.handle_left * mat, bp.co * mat,
                                     bp.handle_right * mat])
                pysp.handletypes.append([bp.handle_left_type,
                                         bp.handle_right_type])
            # cacl point (for calc_document_size())
            if len(bezier_points) == 1:
                pysp.points.append(bezier_points[0].co * mat)
            elif len(bezier_points) >= 2:
                bps = bezier_points[:]
                if cyclic:
                    bps.append(bps[0])
                for bp1, bp2 in zip(bps, bps[1:]):
                    ps = interpolate_bezier(bp1.co * mat, bp1.handle_right * mat,
                                      bp2.co * mat, bp2.handle_left * mat,
                                      BEZIER_SUBDIVIDE)
                    pysp.points.extend(ps)
            pysplines.append(pysp)
示例#13
0
def interpolate_spline(spline_ob):
    '''
    > spline_ob:     bezier spline object
    < returns segments as lists of vectors
    '''
    point_range = len(spline_ob.bezier_points)
    segments = []

    for i in range (0, point_range-1+spline_ob.use_cyclic_u):
        segments.append(interpolate_bezier(spline_ob.bezier_points[i%point_range].co,
                                           spline_ob.bezier_points[i%point_range].handle_right,
                                           spline_ob.bezier_points[(i+1)%point_range].handle_left,
                                           spline_ob.bezier_points[(i+1)%point_range].co,
                                           spline_ob.resolution_u+1))
    return segments
示例#14
0
def interpolate_spline(spline_ob):
    '''
    > spline_ob:     bezier spline object
    < returns segments as lists of vectors
    '''
    point_range = len(spline_ob.bezier_points)
    segments = []

    for i in range (0, point_range-1+spline_ob.use_cyclic_u):
        segments.append(interpolate_bezier(spline_ob.bezier_points[i%point_range].co,
                                           spline_ob.bezier_points[i%point_range].handle_right,
                                           spline_ob.bezier_points[(i+1)%point_range].handle_left,
                                           spline_ob.bezier_points[(i+1)%point_range].co,
                                           spline_ob.resolution_u+1))
    return segments
示例#15
0
            def doConstant():
                res = max(resolution - 1, 1)
                for i in range(len(points) - 1):
                    p1 = points[i]
                    p2 = points[i + 1]

                    cords = interpolate_bezier(p1.co, p1.handle_right,
                                               p2.handle_left, p2.co,
                                               resolution + 1)

                    for j in range(resolution):
                        c1 = cords[j]
                        c2 = cords[j + 1]

                        yield c1, c2, i, j / res
示例#16
0
def interp_bezier(p0, p1, segs, resolution):
    """
     Bezier curve approximation
    """
    if (resolution == 0 or
            (p0.handle_right_type == 'VECTOR' and
             p1.handle_left_type == 'VECTOR')):
        segs.append(p0.co[0:3])

    else:
        seg = interpolate_bezier(p0.co,
                                 p0.handle_right,
                                 p1.handle_left,
                                 p1.co,
                                 resolution + 1)
        segs.extend([p[0:3] for p in seg[:-2]])
示例#17
0
def get_points(spline, clean=True):
    '''
    usage:
    spline = bpy.data.curves[0].splines[0]
    points = get_points(spline)
    '''

    knots = spline.bezier_points
    if len(knots) < 2:
        return

    # verts per segment
    r = spline.resolution_u + 1

    # segments in spline
    segments = len(knots)

    if not spline.use_cyclic_u:
        segments -= 1

    master_point_list = []
    for i in range(segments):
        inext = (i + 1) % len(knots)

        knot1 = knots[i].co
        handle1 = knots[i].handle_right
        handle2 = knots[inext].handle_left
        knot2 = knots[inext].co

        bezier = knot1, handle1, handle2, knot2, r
        points = interpolate_bezier(*bezier)
        master_point_list.extend(points)

    # some clean up to remove consecutive doubles, this could be smarter...
    if clean:
        old = master_point_list
        good = [v for i, v in enumerate(old[:-1]) if not old[i] == old[i + 1]]
        good.append(old[-1])
        return good

    # makes edge keys, ensure cyclic
    Edges = [[i, i + 1] for i in range(n_verts - 1)]
    if spline.use_cyclic_u:
        Edges.append([i, 0])

    return master_point_list, Edges
def get_points(spline, clean=True):
    '''
    usage:
    spline = bpy.data.curves[0].splines[0]
    points = get_points(spline)
    '''

    knots = spline.bezier_points
    if len(knots) < 2:
        return

    # verts per segment
    r = spline.resolution_u + 1

    # segments in spline
    segments = len(knots)

    if not spline.use_cyclic_u:
        segments -= 1

    master_point_list = []
    for i in range(segments):
        inext = (i + 1) % len(knots)

        knot1 = knots[i].co
        handle1 = knots[i].handle_right
        handle2 = knots[inext].handle_left
        knot2 = knots[inext].co

        bezier = knot1, handle1, handle2, knot2, r
        points = interpolate_bezier(*bezier)
        master_point_list.extend(points)

    # some clean up to remove consecutive doubles, this could be smarter...
    if clean:
        old = master_point_list
        good = [v for i, v in enumerate(old[:-1]) if not old[i] == old[i + 1]]
        good.append(old[-1])
        return good

    # makes edge keys, ensure cyclic
    Edges = [[i, i + 1] for i in range(n_verts - 1)]
    if spline.use_cyclic_u:
        Edges.append([i, 0])

    return master_point_list, Edges
示例#19
0
        def bezier_error(self, error_max=-1.0, test_count=8):
            from mathutils.geometry import interpolate_bezier

            test_points = interpolate_bezier(
                self.points[0].co,
                self.handle_left,
                self.handle_right,
                self.points[-1].co,
                test_count,
            )

            from mathutils.geometry import intersect_point_line

            error = 0.0

            # this is a rough method measuring the error but should be ok
            # TODO. dont test against every single point.
            for co in test_points:
                # initial values
                co_best = self.points[0].co

                length_best = (co - co_best).length
                for p in self.points[1:]:
                    # dist to point
                    length = (co - p.co).length
                    if length < length_best:
                        length_best = length
                        co_best = p.co

                    p_ix, fac = intersect_point_line(co, p.co, p.prev.co)
                    p_ix = p_ix
                    if fac >= 0.0 and fac <= 1.0:
                        length = (co - p_ix).length
                        if length < length_best:
                            length_best = length
                            co_best = p_ix

                error += length_best / test_count

                if error_max != -1.0 and error > error_max:
                    return True

            if error_max != -1.0:
                return False
            else:
                return error
示例#20
0
        def bezier_error(self, error_max=-1.0, test_count=8):
            from mathutils.geometry import interpolate_bezier

            test_points = interpolate_bezier(self.points[0].co,
                                             self.handle_left,
                                             self.handle_right,
                                             self.points[-1].co,
                                             test_count,
                                             )

            from mathutils.geometry import intersect_point_line

            error = 0.0

            # this is a rough method measuring the error but should be ok
            # TODO. dont test against every single point.
            for co in test_points:
                # initial values
                co_best = self.points[0].co

                length_best = (co - co_best).length
                for p in self.points[1:]:
                    # dist to point
                    length = (co - p.co).length
                    if length < length_best:
                        length_best = length
                        co_best = p.co

                    p_ix, fac = intersect_point_line(co, p.co, p.prev.co)
                    p_ix = p_ix
                    if fac >= 0.0 and fac <= 1.0:
                        length = (co - p_ix).length
                        if length < length_best:
                            length_best = length
                            co_best = p_ix

                error += length_best / test_count

                if error_max != -1.0 and error > error_max:
                    return True

            if error_max != -1.0:
                return False
            else:
                return error
示例#21
0
def ratio_to_segment(x, p1, p2, p3, p4, res):
    '''
    > x:            intersection point
    > p1,p2,p3,p4:  cubic bezier control points
    < ratio of x to length of the segment
    '''
    seg = interpolate_bezier(p1, p2, p3, p4, res + 1)
    seg_length = length = ratio = 0

    for i in range(len(seg) - 1):
        seg_length += (seg[i + 1] - seg[i]).length

    for i in range(len(seg) - 1):
        if is_between(x, seg[i], seg[i + 1]):
            length += (x - seg[i].to_2d()).length
            return length / seg_length
        else:
            length += (seg[i + 1] - seg[i]).length
示例#22
0
def interpolate_all_segments(spline_ob):
    '''
    > spline_ob:     bezier spline object
    < returns interpolated splinepoints
    '''
    point_range = len(spline_ob.bezier_points)
    pl = []

    for i in range (0, point_range-1+spline_ob.use_cyclic_u):
        if len(pl) > 0:
            pl.pop()
        seg = (interpolate_bezier(spline_ob.bezier_points[i%point_range].co,
                                  spline_ob.bezier_points[i%point_range].handle_right,
                                  spline_ob.bezier_points[(i+1)%point_range].handle_left,
                                  spline_ob.bezier_points[(i+1)%point_range].co,
                                  spline_ob.resolution_u+1))
        pl += seg
    return pl
示例#23
0
 def interpolate_bezier(self, pts, wM, p0, p1, resolution):
     # straight segment, worth testing here
     # since this can lower points count by a resolution factor
     # use normalized to handle non linear t
     if resolution == 0:
         pts.append(wM @ p0.co.to_3d())
     else:
         v = (p1.co - p0.co).normalized()
         d1 = (p0.handle_right - p0.co).normalized()
         d2 = (p1.co - p1.handle_left).normalized()
         if d1 == v and d2 == v:
             pts.append(wM @ p0.co.to_3d())
         else:
             seg = interpolate_bezier(wM @ p0.co, wM @ p0.handle_right,
                                      wM @ p1.handle_left, wM @ p1.co,
                                      resolution + 1)
             for i in range(resolution):
                 pts.append(seg[i].to_3d())
示例#24
0
def ratio_to_segment(x, p1, p2, p3, p4, res):
    '''
    > x:            intersection point
    > p1,p2,p3,p4:  cubic bezier control points
    < ratio of x to length of the segment
    '''
    seg = interpolate_bezier(p1, p2, p3, p4, res+1)
    seg_length = length = ratio = 0

    for i in range (len(seg)-1):
        seg_length += (seg[i+1] - seg[i]).length

    for i in range (len(seg)-1):
        if is_between(x, seg[i], seg[i+1]):
            length += (x - seg[i].to_2d()).length
            return length/seg_length
        else:
            length += (seg[i+1] - seg[i]).length
示例#25
0
 def interpolate_bezier(self, pts, wM, p0, p1, resolution):
     """
      Bezier curve approximation
     """
     if (resolution == 0 or (p0.handle_right_type == 'VECTOR'
                             and p1.handle_left_type == 'VECTOR')):
         pts.append(wM * p0.co.to_3d())
     else:
         v = (p1.co - p0.co).normalized()
         d1 = (p0.handle_right - p0.co).normalized()
         d2 = (p1.co - p1.handle_left).normalized()
         if d1 == v and d2 == v:
             pts.append(wM * p0.co.to_3d())
         else:
             seg = interpolate_bezier(wM * p0.co, wM * p0.handle_right,
                                      wM * p1.handle_left, wM * p1.co,
                                      resolution + 1)
             for i in range(resolution):
                 pts.append(seg[i].to_3d())
示例#26
0
 def interpolate_bezier(self, pts, wM, p0, p1, resolution):
     # straight segment, worth testing here
     # since this can lower points count by a resolution factor
     # use normalized to handle non linear t
     if resolution == 0:
         pts.append(wM @ p0.co.to_3d())
     else:
         v = (p1.co - p0.co).normalized()
         d1 = (p0.handle_right - p0.co).normalized()
         d2 = (p1.co - p1.handle_left).normalized()
         if d1 == v and d2 == v:
             pts.append(wM @ p0.co.to_3d())
         else:
             seg = interpolate_bezier(wM @ p0.co,
                 wM @ p0.handle_right,
                 wM @ p1.handle_left,
                 wM @ p1.co,
                 resolution + 1)
             for i in range(resolution):
                 pts.append(seg[i].to_3d())
示例#27
0
def interpolate_bezier(curve):
    spline = curve.splines[0]

    if len(spline.bezier_points) >= 2:
        r = spline.resolution_u + 1
        segments = len(spline.bezier_points)
        if not spline.use_cyclic_u:
            segments -= 1

        points = []
        for i in range(segments):
            inext = (i + 1) % len(spline.bezier_points)

            knot1 = spline.bezier_points[i].co
            handle1 = spline.bezier_points[i].handle_right
            handle2 = spline.bezier_points[inext].handle_left
            knot2 = spline.bezier_points[inext].co

            _points = interpolate_bezier(knot1, handle1, handle2, knot2, r)
            points.extend(_points)
        return points
    return None
示例#28
0
    def perform_CurveTo(self):
        '''
        expects 5 params:
            C x1,y1 x2,y2 x3,y3 num bool [z]
        example:
            C control1 control2 knot2 10 0 [z]
            C control1 control2 knot2 20 1 [z]
        '''

        tempstr = self.stripped_line.split(' ')
        if not len(tempstr) == 5:
            print('error on line CurveTo: ', self.stripped_line)
            return

        ''' fully defined '''
        vec = lambda v: Vector((v[0], v[1], 0))

        knot1 = [self.posxy[0], self.posxy[1]]
        if self.section_type == 'bezier_curve_to_absolute':
            handle1 = self.get_2vec(tempstr[0])
            handle2 = self.get_2vec(tempstr[1])
            knot2 = self.get_2vec(tempstr[2])
        else:
            points = []
            for j in range(3):
                point_pre = self.get_2vec(tempstr[j])
                point = self.relative(self.posxy, point_pre)
                points.append(point)
                self.posxy = tuple(point)
            handle1, handle2, knot2 = points

        r = self.get_typed(tempstr[3], int)
        s = self.get_typed(tempstr[4], int)  # not used yet
        bezier = vec(knot1), vec(handle1), vec(handle2), vec(knot2), r
        points = interpolate_bezier(*bezier)

        # parse down to 2d
        points = [[v[0], v[1]] for v in points]
        return self.find_right_index_and_make_edges(points)
示例#29
0
def get_points_bezier(spline, clean=True, calc_radii=False):

    knots = spline.bezier_points
    cyclic = spline.use_cyclic_u

    if len(knots) < 2:
        return

    radii = []

    # verts per segment
    r = spline.resolution_u + 1

    # segments in spline
    segments = len(knots)
    if not cyclic:
        segments -= 1

    print("segments:", segments)
    master_point_list = []
    for i in range(segments):
        inext = (i + 1) % len(knots)

        knot1, knot2 = knots[i].co, knots[inext].co
        handle1, handle2 = knots[i].handle_right, knots[inext].handle_left

        bezier = knot1, handle1, handle2, knot2, r
        points = interpolate_bezier(*bezier)

        if segments == 1 and not cyclic:
            pass
        elif cyclic or (i < segments-1):
            points.pop()

        master_point_list.extend([v[:] for v in points])

    edges = generate_edges(n_verts=len(master_point_list), cyclic=cyclic)

    return master_point_list, edges, radii
示例#30
0
    def perform_CurveTo(self):
        '''
        expects 5 params:
            C x1,y1 x2,y2 x3,y3 num bool [z]
        example:
            C control1 control2 knot2 10 0 [z]
            C control1 control2 knot2 20 1 [z]
        '''

        tempstr = self.stripped_line.split(' ')
        if not len(tempstr) == 5:
            print('error on line CurveTo: ', self.stripped_line)
            return

        ''' fully defined '''
        vec = lambda v: Vector((v[0], v[1], 0))

        knot1 = [self.posxy[0], self.posxy[1]]
        if self.section_type == 'bezier_curve_to_absolute':
            handle1 = self.get_2vec(tempstr[0])
            handle2 = self.get_2vec(tempstr[1])
            knot2 = self.get_2vec(tempstr[2])
        else:
            points = []
            for j in range(3):
                point_pre = self.get_2vec(tempstr[j])
                point = self.relative(self.posxy, point_pre)
                points.append(point)
                self.posxy = tuple(point)
            handle1, handle2, knot2 = points

        r = self.get_typed(tempstr[3], int)
        s = self.get_typed(tempstr[4], int)  # not used yet
        bezier = vec(knot1), vec(handle1), vec(handle2), vec(knot2), r
        points = interpolate_bezier(*bezier)

        # parse down to 2d
        points = [[v[0], v[1]] for v in points]
        return self.find_right_index_and_make_edges(points)
示例#31
0
	def backdrop(self, context):
		# calculate the view frame in world coordinates
		# (i.e. the far plane of the view frustum)
		scene = context.scene
		cam_ob = scene.camera
		cam = bpy.data.cameras[cam_ob.name] # camera in scene is object type, not a camera type
		cam_mat = cam_ob.matrix_world
		view_frame = cam.view_frame(scene)	# without a scene the aspect ratio of the camera is not taken into account
		view_frame = [cam_mat * v for v in view_frame]
		cam_pos = cam_mat * Vector((0,0,0))
		view_center = sum(view_frame, Vector((0,0,0)))/len(view_frame)
		view_normal = (view_center - cam_pos).normalized()

		# enlarge the view frame beyond the actual cam boundaries if requested
		if self.margin != 0.0:
			view_frame = [((v - view_center)*(1+self.margin))+view_center for v in view_frame]

		# calculate the intersection with a horizontal plane below the camera
		# the top edge is intersected with an artificially offset ground plane
		# so it will intersected with the lifted far end of our backdrop
		overts = []
		refz = cam_pos.z if self.zero else self.distance
		for n,vf in enumerate(view_frame):
			v = (vf - cam_pos).normalized()
			d = 0.0 if n in (1,2) else self.lift
			zf =  (d - refz) / v.z
			if zf <= 0.0 :
				break
			overts.append(zf * v)

		# create two edge loops (the right and left side of the intersection
		# of the view frustum with the backdrop). We curve it downward we a
		# bezier interpolation. This curvature can be controlled somewhat
		# with a rotation angle but this is far from ideal yet
		verts = []
		edges = []

		vs = Vector(overts[2])
		ve = Vector(overts[3])
		rotaxis = (vs - ve).cross(Vector((0,0,-1))).normalized()
		rot = Quaternion(rotaxis, self.angle)
		handle2 = ve + rot * Vector((0,0,-self.lift))
		handle1 = vs + (vs - ve).normalized()
		points = interpolate_bezier(vs, handle1, handle2, ve, self.subdivisions+1)

		verts.extend(points)
		edges.extend((i,i+1) for i in range(len(points)-1))

		vs = Vector(overts[0])
		ve = Vector(overts[1])
		rotaxis = (ve - vs).cross(Vector((0,0,-1))).normalized()
		rot = Quaternion(rotaxis, self.angle)
		handle2 = ve + (ve - vs).normalized()
		handle1 = vs + rot * Vector((0,0,-self.lift))
		points = interpolate_bezier(ve, handle2, handle1, vs, self.subdivisions+1)
		points.reverse()

		offset = len(verts)
		verts.extend(points)
		edges.extend((offset+i,offset+i+1) for i in range(len(points)-1))

		return verts, edges
示例#32
0
def def_track_1():
    pts=[] 
    #pts.append([   0.0,   0.0  , 0.0 , 30.0 , 20.0])  # x,y,z,turn0,turn1
    #pts.append([   0.0,  160.0 , 0.0 , 20.0 , 20.0])
    #pts.append([ 100.0,  200.0 , 0.0 , 20.0 , 20.0])
    #pts.append([ 180.0,   0.0  , 5.0 , 20.0 , 10.0])
    #pts.append([-180.0, -50.0  , 5.0 , 10.0 , 10.0])
    #pts.append([-180.0, -160.0 , 0.0 , 10.0 , 20.0])
    #pts.append([   0.0, -200.0 , 0.0 , 10.0 , 30.0])
#Circuit ellipse
#first cadran
    pts.append([ 270.0,   0.0  , 0.0 , 20.0 , 20.0])
    pts.append([ 250.0,  50.0  , 0.0 , 20.0 , 20.0])
    pts.append([ 150.0,  90.0  , 0.0 , 20.0 , 20.0])
    pts.append([   0.0, 100.0  , 0.0 , 20.0 , 20.0])
#second one
    pts.append([ -150.0,  90.0  , 0.0 , 20.0 , 20.0])
    pts.append([ -250.0,  50.0  , 0.0 , 20.0 , 20.0])
    pts.append([ -270.0,   0.0  , 0.0 , 20.0 , 20.0])
#third
    pts.append([ -250.0,  -50.0  , 0.0 , 20.0 , 20.0])
    pts.append([ -150.0,  -90.0  , 0.0 , 20.0 , 20.0])
    pts.append([    0.0, -100.0  , 0.0 , 20.0 , 20.0])
#fourth
    pts.append([ 150.0,  -90.0  , 0.0 , 20.0 , 20.0])
    pts.append([ 250.0,  -50.0  , 0.0 , 20.0 , 20.0])       
 
    # define the number of basis points fro the circular bezier curve
    # ncut is the number of subdivision
    n0=len(pts)
    ncut = 1
    over_sample = 4 # define over sampling factor to have a smoother curve
    while True:
        npt_bez = 4*(ncut+1)  # compute the number of beziers points
        if npt_bez > over_sample*n0:
            break  # exit if subdivision is enough
        ncut += 1
    npt = npt_bez

    # each side of the polygon is reduce at its beginning and at its end to let space for the curves
    # a vertex of the polygon is defined by 5 values : xv,yv,zv,turn0,turn1
    #  (xv,yv,zv) are the coordinates of the vertex, 
    #  turn0 is the place left for the curve before reaching the vertex
    #  turn1 is the place left for the curve after passing the vertex
    # we compute points (x,y,z) at the begining and at the end of each curve
    # also compute the left (xhl,yhl,zhl) and right (xhr,yhr,zhr) handlers to define the tangent to the bezier curve 
    x,y,z,xhl,yhl,zhl,xhr,yhr,zhr = def_track_curves(pts)

    # define how many points are on each segment of the track
    t_cnt = def_points_in_segments(npt,x,y)

    # compute all points that will  define the bezier curve of the track
    lpts = []
    n = len(x)
    for i0 in range(n):
        i1 = (i0+1) % n
        new_pts = geometry.interpolate_bezier(
            (x[i0],y[i0],z[i0]),
            (xhr[i0],yhr[i0],zhr[i0]),
            (xhl[i1],yhl[i1],zhl[i1]),
            (x[i1],y[i1],z[i1]),
            t_cnt[i0]+1) # trick : compute one more points to avoid duplicate of the first
        for ipt in range(len(new_pts)-1):
            pt =new_pts[ipt+1]
            lpts.append([pt.x,pt.y,pt.z])
            
    nptl = len(lpts)
    return ncut,nptl,lpts
示例#33
0
    def execute(self, context):
        bpy.ops.object.editmode_toggle()
        bm = bmesh.new()
        bm.from_mesh(bpy.context.active_object.data)

        bEdges = bm.edges
        bVerts = bm.verts
        
        seg = self.segments
        edges = []
        verts = []

        for e in bEdges:
            if e.select:
                edges.append(e)

        for v in range(4):
            verts.append(edges[v // 2].verts[v % 2])

        if self.flip1:
            v1 = verts[1]
            p1_co = verts[1].co
            p1_dir = verts[1].co - verts[0].co
        else:
            v1 = verts[0]
            p1_co = verts[0].co
            p1_dir = verts[0].co - verts[1].co
        p1_dir.length = self.ten1

        if self.flip2:
            v2 = verts[3]
            p2_co = verts[3].co
            p2_dir = verts[2].co - verts[3].co
        else:
            v2 = verts[2]
            p2_co = verts[2].co
            p2_dir = verts[3].co - verts[2].co
        p2_dir.length = self.ten2

        # Get the interploted coordinates:
        if self.alg == 'Blender':
            pieces = interpolate_bezier(p1_co, p1_dir, p2_dir, p2_co, self.segments)
        elif self.alg == 'Hermite':
            pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'HERMITE')
        elif self.alg == 'Bezier':
            pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'BEZIER')
        elif self.alg == 'B-Spline':
            pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'BSPLINE')

        verts = []
        verts.append(v1)
        # Add vertices and set the points:
        for i in range(seg - 1):
            v = bVerts.new()
            v.co = pieces[i]
            verts.append(v)
        verts.append(v2)
        # Connect vertices:
        for i in range(seg):
            e = bEdges.new((verts[i], verts[i + 1]))

        bm.to_mesh(bpy.context.active_object.data)
        bpy.ops.object.editmode_toggle()
        return {'FINISHED'}
def get_mats_for_segment(self, context, segment, splinetype):
    '''
    Creates the Matrizies for a spline segment.
    '''
    #printd('Creating transforms for segment', splinetype)
    mats = []

    p1 = segment[0]
    p2 = segment[1]


    count = self.leafs_per_segment
    if self.bvh:
        count *= 2

    ### TRANSLATION #################
    if splinetype == 'BEZIER':
        coordsb = interpolate_bezier(p1.co, p1.handle_right, p2.handle_left, p2.co, count+1)
        coords = [coordsb[i].lerp(coordsb[i+1], random()*self.loc_random)
                  for i in range(len(coordsb)-1)]

    elif splinetype == 'POLY':
        if count > 1:
            positions = [i / count for i in range(count)]
        else:
            positions = [0.5]
        #printd('POLY-segment: Lerp-positions', positions)
        coords = [p1.co.lerp(p2.co, positions[i]+(random() * self.loc_random)).to_3d()
                  for i in range(count)]

    mat_locs = [Matrix.Translation(co) for co in coords]


    ### SCALE #################
    mat_scales = [Matrix.Scale(self.scale+(random()*self.scale_random), 4)
                  for i in range(len(mat_locs))]

    ### ROTATION #################
    if splinetype == 'BEZIER':
        directions = [(coordsb[i+1] - coordsb[i]).normalized()
                      for i in range(len(coordsb)-1)]
    elif splinetype == 'POLY':
        directions = [(p2.co - p1.co).to_3d().normalized()]*len(coords)

    #COLLISION -> align leaves to surface
    if self.bvh:
        #printd('COLLISION')
        mat_rots = get_collider_aligned_rots(self, context, coords[:int(count/2)], directions)

    #NO COLLISION
    else:
        vecs_target = directions.copy()

        #direction + random for y alignment
        vecs_target = [vt.lerp(vt+noise.random_unit_vector(), self.rot_random).normalized()
                       for vt in vecs_target]

        #up versus random for z alignment
        vecs_alignz = [Vector((0,0,1)).lerp(noise.random_unit_vector(), self.rot_align_normal_random).normalized()
                       for i in range(len(directions))]

        #return alignz towards the direction vector
        vecs_alignz = [va.lerp(d, self.rot_align_normal).normalized()
                       for va, d in zip(vecs_alignz, directions)]

        mat_rots = [align(vt, va) for vt, va in zip(vecs_target, vecs_alignz)]
        #printd('FREE ROTATION Mats:', len(mat_rots))

    #COMBINED
    mats = [l*s*r for l,s,r in zip(mat_locs, mat_scales, mat_rots)]
    mats = [m for m in mats if not random() > self.leafs_per_segment_random]
    #printd('MATS: ', len(mats), len(mat_locs), len(mat_scales), len(mat_rots))
    return mats
示例#35
0
    def execute(self, context):
        bpy.ops.object.editmode_toggle()
        bm = bmesh.new()
        bm.from_mesh(bpy.context.active_object.data)

        bEdges = bm.edges
        bVerts = bm.verts
        
        seg = self.segments
        edges = []
        verts = []

        for e in bEdges:
            if e.select:
                edges.append(e)

        for v in range(4):
            verts.append(edges[v // 2].verts[v % 2])

        if self.flip1:
            v1 = verts[1]
            p1_co = verts[1].co
            p1_dir = verts[1].co - verts[0].co
        else:
            v1 = verts[0]
            p1_co = verts[0].co
            p1_dir = verts[0].co - verts[1].co
        p1_dir.length = self.ten1

        if self.flip2:
            v2 = verts[3]
            p2_co = verts[3].co
            p2_dir = verts[2].co - verts[3].co
        else:
            v2 = verts[2]
            p2_co = verts[2].co
            p2_dir = verts[3].co - verts[2].co
        p2_dir.length = self.ten2

        # Get the interploted coordinates:
        if self.alg == 'Blender':
            pieces = interpolate_bezier(p1_co, p1_dir, p2_dir, p2_co, self.segments)
        elif self.alg == 'Hermite':
            pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'HERMITE')
        elif self.alg == 'Bezier':
            pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'BEZIER')
        elif self.alg == 'B-Spline':
            pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'BSPLINE')

        verts = []
        verts.append(v1)
        # Add vertices and set the points:
        for i in range(seg - 1):
            v = bVerts.new()
            v.co = pieces[i]
            verts.append(v)
        verts.append(v2)
        # Connect vertices:
        for i in range(seg):
            e = bEdges.new((verts[i], verts[i + 1]))

        bm.to_mesh(bpy.context.active_object.data)
        bpy.ops.object.editmode_toggle()
        return {'FINISHED'}
示例#36
0
    def backdrop(self, context):
        # calculate the view frame in world coordinates
        # (i.e. the far plane of the view frustum)
        scene = context.scene
        cam_ob = scene.camera
        cam = bpy.data.cameras[
            cam_ob.name]  # camera in scene is object type, not a camera type
        cam_mat = cam_ob.matrix_world
        view_frame = cam.view_frame(
            scene
        )  # without a scene the aspect ratio of the camera is not taken into account
        view_frame = [cam_mat * v for v in view_frame]
        cam_pos = cam_mat * Vector((0, 0, 0))
        view_center = sum(view_frame, Vector((0, 0, 0))) / len(view_frame)
        view_normal = (view_center - cam_pos).normalized()

        # enlarge the view frame beyond the actual cam boundaries if requested
        if self.margin != 0.0:
            view_frame = [((v - view_center) * (1 + self.margin)) + view_center
                          for v in view_frame]

        # calculate the intersection with a horizontal plane below the camera
        # the top edge is intersected with an artificially offset ground plane
        # so it will intersected with the lifted far end of our backdrop
        overts = []
        refz = cam_pos.z if self.zero else self.distance
        for n, vf in enumerate(view_frame):
            v = (vf - cam_pos).normalized()
            d = 0.0 if n in (1, 2) else self.lift
            zf = (d - refz) / v.z
            if zf <= 0.0:
                break
            overts.append(zf * v)

        # create two edge loops (the right and left side of the intersection
        # of the view frustum with the backdrop). We curve it downward we a
        # bezier interpolation. This curvature can be controlled somewhat
        # with a rotation angle but this is far from ideal yet
        verts = []
        edges = []

        vs = Vector(overts[2])
        ve = Vector(overts[3])
        rotaxis = (vs - ve).cross(Vector((0, 0, -1))).normalized()
        rot = Quaternion(rotaxis, self.angle)
        handle2 = ve + rot * Vector((0, 0, -self.lift))
        handle1 = vs + (vs - ve).normalized()
        points = interpolate_bezier(vs, handle1, handle2, ve,
                                    self.subdivisions + 1)

        verts.extend(points)
        edges.extend((i, i + 1) for i in range(len(points) - 1))

        vs = Vector(overts[0])
        ve = Vector(overts[1])
        rotaxis = (ve - vs).cross(Vector((0, 0, -1))).normalized()
        rot = Quaternion(rotaxis, self.angle)
        handle2 = ve + (ve - vs).normalized()
        handle1 = vs + rot * Vector((0, 0, -self.lift))
        points = interpolate_bezier(ve, handle2, handle1, vs,
                                    self.subdivisions + 1)
        points.reverse()

        offset = len(verts)
        verts.extend(points)
        edges.extend(
            (offset + i, offset + i + 1) for i in range(len(points) - 1))

        return verts, edges
def get_mats_for_segment(self, context, segment, splinetype):
    '''
    Creates the Matrizies for a spline segment.
    '''
    #printd('Creating transforms for segment', splinetype)
    mats = []

    p1 = segment[0]
    p2 = segment[1]

    count = self.leafs_per_segment
    if self.bvh:
        count *= 2

    ### TRANSLATION #################
    if splinetype == 'BEZIER':
        coordsb = interpolate_bezier(p1.co, p1.handle_right, p2.handle_left,
                                     p2.co, count + 1)
        coords = [
            coordsb[i].lerp(coordsb[i + 1],
                            random() * self.loc_random)
            for i in range(len(coordsb) - 1)
        ]

    elif splinetype == 'POLY':
        if count > 1:
            positions = [i / count for i in range(count)]
        else:
            positions = [0.5]
        #printd('POLY-segment: Lerp-positions', positions)
        coords = [
            p1.co.lerp(p2.co,
                       positions[i] + (random() * self.loc_random)).to_3d()
            for i in range(count)
        ]

    mat_locs = [Matrix.Translation(co) for co in coords]

    ### SCALE #################
    mat_scales = [
        Matrix.Scale(self.scale + (random() * self.scale_random), 4)
        for i in range(len(mat_locs))
    ]

    ### ROTATION #################
    if splinetype == 'BEZIER':
        directions = [(coordsb[i + 1] - coordsb[i]).normalized()
                      for i in range(len(coordsb) - 1)]
    elif splinetype == 'POLY':
        directions = [(p2.co - p1.co).to_3d().normalized()] * len(coords)

    #COLLISION -> align leaves to surface
    if self.bvh:
        #printd('COLLISION')
        mat_rots = get_collider_aligned_rots(self, context,
                                             coords[:int(count / 2)],
                                             directions)

    #NO COLLISION
    else:
        vecs_target = directions.copy()

        #direction + random for y alignment
        vecs_target = [
            vt.lerp(vt + noise.random_unit_vector(),
                    self.rot_random).normalized() for vt in vecs_target
        ]

        #up versus random for z alignment
        vecs_alignz = [
            Vector((0, 0, 1)).lerp(noise.random_unit_vector(),
                                   self.rot_align_normal_random).normalized()
            for i in range(len(directions))
        ]

        #return alignz towards the direction vector
        vecs_alignz = [
            va.lerp(d, self.rot_align_normal).normalized()
            for va, d in zip(vecs_alignz, directions)
        ]

        mat_rots = [align(vt, va) for vt, va in zip(vecs_target, vecs_alignz)]
        #printd('FREE ROTATION Mats:', len(mat_rots))

    #COMBINED
    mats = [l * s * r for l, s, r in zip(mat_locs, mat_scales, mat_rots)]
    mats = [m for m in mats if not random() > self.leafs_per_segment_random]
    #printd('MATS: ', len(mats), len(mat_locs), len(mat_scales), len(mat_rots))
    return mats
    def interpret(self, interpreter, variables):
        vec = lambda v: Vector((v[0], v[1], 0))

        interpreter.assert_not_closed()
        interpreter.start_new_segment()

        v0 = interpreter.position
        if interpreter.has_last_vertex:
            v0_index = interpreter.get_last_vertex()
        else:
            v0_index = interpreter.new_vertex(*v0)

        knot1 = None
        for i, segment in enumerate(self.segments):
            # For first segment, knot1 is initial pen position;
            # for the following, knot1 is knot2 of previous segment.
            if knot1 is None:
                knot1 = interpreter.position
            else:
                knot1 = knot2

            handle1 = interpreter.calc_vertex(self.is_abs, segment.control1[0],
                                              segment.control1[1], variables)

            # In Profile mk2, for "c" handle2 was calculated relative to handle1,
            # and knot2 was calculated relative to handle2.
            # But in SVG specification,
            # >> ...  *At the end of the command*, the new current point becomes
            # >> the final (x,y) coordinate pair used in the polybézier.
            # This is also behaivour of browsers.

            #interpreter.position = handle1
            handle2 = interpreter.calc_vertex(self.is_abs, segment.control2[0],
                                              segment.control2[1], variables)
            #interpreter.position = handle2
            knot2 = interpreter.calc_vertex(self.is_abs, segment.knot2[0],
                                            segment.knot2[1], variables)
            # Judging by the behaivour of Inkscape and Firefox, by "end of command"
            # SVG spec means "end of segment".
            interpreter.position = knot2

            if self.num_segments is not None:
                r = interpreter.eval_(self.num_segments, variables)
            else:
                r = interpreter.dflt_num_verts

            points = interpolate_bezier(vec(knot1), vec(handle1), vec(handle2),
                                        vec(knot2), r)

            interpreter.new_knot("C#.{}.h1".format(i), *handle1)
            interpreter.new_knot("C#.{}.h2".format(i), *handle2)
            interpreter.new_knot("C#.{}.k".format(i), *knot2)

            interpreter.prev_bezier_knot = handle2

            for point in points[1:]:
                v1_index = interpreter.new_vertex(point.x, point.y)
                interpreter.new_edge(v0_index, v1_index)
                v0_index = v1_index

        if self.close:
            interpreter.new_edge(v1_index, interpreter.segment_start_index)

        interpreter.has_last_vertex = True
    def interpret(self, interpreter, variables):
        vec = lambda v: Vector((v[0], v[1], 0))

        interpreter.assert_not_closed()
        interpreter.start_new_segment()

        v0 = interpreter.position
        if interpreter.has_last_vertex:
            v0_index = interpreter.get_last_vertex()
        else:
            v0_index = interpreter.new_vertex(*v0)

        knot1 = None
        for i, segment in enumerate(self.segments):
            # For first segment, knot1 is initial pen position;
            # for the following, knot1 is knot2 of previous segment.
            if knot1 is None:
                knot1 = interpreter.position
            else:
                knot1 = knot2

            if interpreter.prev_bezier_knot is None:
                # If there is no previous command or if the previous command was
                # not an C, c, S or s, assume the first control point is coincident
                # with the current point.
                handle1 = knot1
            else:
                # The first control point is assumed to be the reflection of the
                # second control point on the previous command relative to the
                # current point.
                prev_knot_x, prev_knot_y = interpreter.prev_bezier_knot
                x0, y0 = knot1
                dx, dy = x0 - prev_knot_x, y0 - prev_knot_y
                handle1 = x0 + dx, y0 + dy

            # I assume that handle2 should be relative to knot1, not to handle1.
            # interpreter.position = handle1
            handle2 = interpreter.calc_vertex(self.is_abs, segment.control2[0],
                                              segment.control2[1], variables)
            # interpreter.position = handle2
            knot2 = interpreter.calc_vertex(self.is_abs, segment.knot2[0],
                                            segment.knot2[1], variables)
            interpreter.position = knot2

            if self.num_segments is not None:
                r = interpreter.eval_(self.num_segments, variables)
            else:
                r = interpreter.dflt_num_verts

            points = interpolate_bezier(vec(knot1), vec(handle1), vec(handle2),
                                        vec(knot2), r)

            interpreter.new_knot("S#.{}.h1".format(i), *handle1)
            interpreter.new_knot("S#.{}.h2".format(i), *handle2)
            interpreter.new_knot("S#.{}.k".format(i), *knot2)

            interpreter.prev_bezier_knot = handle2

            for point in points[1:]:
                v1_index = interpreter.new_vertex(point.x, point.y)
                interpreter.new_edge(v0_index, v1_index)
                v0_index = v1_index

        if self.close:
            interpreter.new_edge(v1_index, interpreter.segment_start_index)

        interpreter.has_last_vertex = True
示例#40
0
from bpy import context, data, ops
from mathutils import geometry

ops_mesh = ops.mesh

count = 16

ops.curve.primitive_bezier_curve_add(enter_editmode=True)
ops.transform.vertex_random(offset=1.0, uniform=0.1, normal=0.01, seed=0)
ops.object.mode_set(mode='OBJECT')

bez_curve = context.active_object
bez_points = bez_curve.data.splines[0].bezier_points

points_on_curve = geometry.interpolate_bezier(
    bez_points[0].co,
    bez_points[0].handle_right,
    bez_points[1].handle_left,
    bez_points[1].co,
    count,
)

ops.object.empty_add(type='PLAIN_AXES', location=bez_curve.location)
group = context.active_object

cube_rad = 0.5 / count
for point in points_on_curve:
    ops_mesh.primitive_cube_add(size=cube_rad, location=point)
    cube = context.active_object
    cube.parent = group