I'm quite new to blender-python so forgive me if there are some things I don't get right...
I try to model some cables with the Blender Python API. I came to the point where I need to inset the ends of the cables and extrude them (represents the copper ends of a wire). I searched online but could not find a good solution for my problem.
This is my code so far:
import bpy
import math
import random
import bmesh
#define number of Cables
numberOfCables = 2
count = 0
#clean scene (delete all objects inside
def clean_scene():
for things in bpy.data.objects:
bpy.data.objects.remove(things)
clean_scene()
#bpy.ops.object.select_all(action='SELECT')
#bpy.ops.object.delete(use_global=False, confirm=False)
#Main Programm
for i in range(numberOfCables):
#define random values for location and size
X = random.uniform(0,5)
Y = random.uniform(0,5)
randomRadius = random.randrange(15,50,5)/10000 #random thickness ranging from 3mm to 8mm
randomLength = random.uniform(0.3,1) #random length ranging from 30cm to 1m
randomSeed = random.uniform(0,10)
#print(randomRadius)
#create Curve
def create_Curve():
bpy.ops.curve.primitive_nurbs_path_add(radius = randomRadius,
enter_editmode = True,
location=(X,Y,1))
return bpy.context.object
obj = create_Curve()
#randomly place vertecies to have different "cables"
bpy.ops.transform.vertex_random(offset=.5,
uniform=5,
normal=5,
seed=randomSeed,
wait_for_input=True)
bpy.ops.object.editmode_toggle()
#defining a volume for the cable
def create_Cable():
bpy.ops.mesh.primitive_cylinder_add(radius=randomRadius,
depth=randomLength,
enter_editmode=True,
location=(X,Y,1))
return bpy.context.object
cable = create_Cable()
#loopcutting the Cylinders for flexibility
def view3d_find( return_area = False ):
# returns first 3d view, normally we get from context
for area in bpy.context.window.screen.areas:
if area.type == 'VIEW_3D':
v3d = area.spaces[0]
rv3d = v3d.region_3d
for region in area.regions:
if region.type == 'WINDOW':
if return_area: return region, rv3d, v3d, area
return region, rv3d, v3d
return None, None
region, rv3d, v3d, area = view3d_find(True)
override = {
'scene' : bpy.context.scene,
'region' : region,
'area' : area,
'space' : v3d
}
bpy.ops.mesh.loopcut_slide(
override,
MESH_OT_loopcut = {
"number_cuts" : 100,
"smoothness" : 0,
"falloff" : 'SMOOTH',
"edge_index" : 2,
"mesh_select_mode_init" : (True, False, False),
"object_index" : 0
},
TRANSFORM_OT_edge_slide = {
"value" : 0,
"mirror" : False,
"snap" : False,
"snap_target" : 'CLOSEST',
"snap_point" : (0, 0, 0),
"snap_align" : False,
"snap_normal" : (0, 0, 0),
"correct_uv" : False,
"release_confirm" : False
}
)
#back into OBJECT Mode
bpy.ops.object.editmode_toggle()
#apply Cylinder to shape of the Curve
cable.modifiers.new(type='CURVE', name='applyShape')
#Select Curve
#Still Problem with NurbsCurve
if count == 0:
cable.modifiers["applyShape"].object = bpy.data.objects["NurbsPath"]
cable.modifiers["applyShape"].deform_axis = 'POS_Z'
else:
a = "NurbsPath."
b = str(count).zfill(3)
cable.modifiers["applyShape"].object = bpy.data.objects[str(a+b)]
cable.modifiers["applyShape"].deform_axis = 'POS_Z'
#Increase Count by 1 to go into else loop in line 115
count += 1
#move Cable along Z axis to align more with Curve
bpy.ops.transform.translate(value=(0, 0, 0.6))
Please be patient I know it is kinda messy...
And everything after the for loop (under #Main Programm) should be indented but something is messed up here so I can't indent it.
Now as I said I need to inset the end caps and extrude them so that it looks like this.
If here is anyone out there helping me I would really appreciate that! Thank you very much!
P.S. I also have a Problem with randomising the vertices only in X and Y direction (I want the cable to be "flat") I only found the bpy.ops.transform.vertex_random function but it also randomises the vertecies along the Z axis. So if there is a solution to this as well I would really appreciate that!