1
$\begingroup$

Is there an accurate way to subdivide a Curve without using a lot of math? I would like to subdivide the spline and then make it noisy.

import bpy
from mathutils import Euler, Matrix, Quaternion, Vector
import random

 # Make collection
if 'NOISE_CURVE' not in bpy.context.collection.children:
    
    print('hät ä keini, odr.')
    col = bpy.data.collections.new('NOISE_CURVE')
    bpy.context.collection.children.link(col)

def CoordPoints_random(First_Point, coords):
    
    # Last Point
    X_last_point = random.uniform(-8.000, 8.000)
    Y_last_point = random.uniform(-8.000, 8.000)
    Z_last_point = random.uniform(-8.000, -20.0)
    
    # Start-Point 
    coords.append(First_Point)
    
    # random points for subdivision
    Vector_count = random.randint(5, 30)
    
    # Try to subdivide the start and end-point Coordinates  <----------The Question is here
    X_subdiv = (First_Point[0] + X_last_point) / Vector_count
    Y_subdiv = (First_Point[1] + Y_last_point) / Vector_count
    Z_subdiv = (First_Point[2] + Z_last_point) / Vector_count
    
    # X,Y,Z erschaffen
    X = X_subdiv
    Y = Y_subdiv
    Z = Z_subdiv
    
    # Random Points between Start- and End-Point
    for VecPoint in range(Vector_count):
        random.seed()
        
        # Make noise
        X += X_subdiv + random.uniform(0.500, -0.500)
        Y += Y_subdiv + random.uniform(0.500, -0.500)
        Z += Z_subdiv + random.uniform(0.500, -0.500)
        
        coords.append((X,Y,Z))
    coords.append((X_last_point, Y_last_point,Z_last_point))
    
    ### Test
    print("First_Point ", First_Point)
    print("Last_Point ", X_last_point, Y_last_point, Z_last_point)
    for i in coords:
        print(i)
    return coords
    
def create_lightning_Curve():
    
    ### Create a curve-container
    lightning_curve = bpy.data.curves.new('lightning','CURVE')
    # make some settings to the container
    lightning_curve.dimensions = '3D'                                       
    lightning_curve.resolution_u = 1
    lightning_curve.use_fill_caps = True
    lightning_curve.fill_mode = 'FULL'
    lightning_curve.bevel_depth = 0.1
    lightning_curve.bevel_resolution = 0
    
    ### create splines (or multiple curves (= splines) in the curve-container)
    coords = [] ##### Point coordinates
    First_Point = bpy.context.scene.cursor.location #3D-Cursor als Start-Punkt
    CoordPoints_random(First_Point, coords) # Make Coordinates
    
    
    Bezline = lightning_curve.splines.new('BEZIER') #Create a spline (with one Point already)
    Bezline.bezier_points.add(len(coords)-1) # add Points without Coordinates (-1 to not close the curve) 
    for number, coord in enumerate(coords): # give the Points the Coordinates
        x,y,z = coord
        Bezline.bezier_points[number].co = (x, y, z) 


    #Create object
    obj = bpy.data.objects.new('NoiseCurve', lightning_curve)
    # Link object 
    bpy.context.collection.children['NOISE_CURVE'].objects.link(obj)
    return obj

create_lightning_Curve()
$\endgroup$
2
  • $\begingroup$ May find this of use blender.stackexchange.com/questions/180148/… $\endgroup$ – batFINGER Jan 22 at 12:16
  • $\begingroup$ This would probably work, but there is so much math going on... I'm looking for a simpler solution. Something like the subdivide-function from the curve-edit-mode, but with access to it from the blender API to avoid context-problems. $\endgroup$ – Andi Jan 22 at 14:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.