# Inset specific faces and extrude them afterwards - Python

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)

#create Curve
def create_Curve():
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():
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!

I've written a library called Blogo (https://github.com/mlewis109/blogo) which (I think) will help you a lot with what you want to do. It allows Blender python to be written in a similar way to the Logo programming language. You define a cross section - such as a circle for a wire - and then this is swept through space using commands like "forward", "left", "right", "up", etc. You can easily change the cross section to put the cap on the end how you want.

For example:

# Draw a wire with a random squiggle in it in the xy plane
wire = Blogo()
# store starting position
pos = wire.get_pos()
# turn around to draw the connector
wire.right(180)
# turn back and go back to start
wire.right(180)
wire.pen_up()
wire.set_pos(pos)
wire.pen_down()

wire.set_texture(wire_colour)
direction = 0
step_length = 0.01
# make lots of turns, each similar to the last but randomly different
for turns in range(int(wire_length/step_length)):
min = -1
max = 1
# bias the turns back towards straight
if (direction > 2):
max = 2/direction
elif (direction < -2):
min = 2/direction
direction += random.uniform(min, max)
# turn by a small amount then go forward by a small amount
wire.right(direction)
wire.forward(step_length)
return wire

# Draws either end of the wire, with a plastic protector and metal connector
wire.set_texture(cap_colour)
# make cap slightly bigger than the wire
# make the end of the cap narrower
# cap is 1cm long
wire.forward(0.01)
# remove the narrowing end

wire.set_texture("grey")
# Cross section shape of the metal connector, these coordinates represent a trapezium,