class SmartArrayAlongCurve(bpy.types.Operator):
bl_label ='Smart Array Along Curve'
bl_idname = 'object.arrayalongcurve'
bl_description = 'Creates array with predefined smart setup along selected curve'
bl_space_type="VIEW_3D"
bl_region_type="UI"
bl_option= {'REGISTER','UNDO'}
@classmethod
def poll(cls, context):
try :
return context.object.select_get() and context.object.type == 'CURVE'
except AttributeError:
pass
def execute(self, contex):
cScene = bpy.context.scene
# tmplObjName = name of object tamplate in the .blend file
# objName = created object name
tmplObjName = cScene.arrProps.cArrayObject.name
# getting Objects names
if cScene.arrProps.cArrObjName != "":
objName = cScene.arrProps.cArrObjName
else :
objName = cScene.arrProps.cArrayObject.name
# getting Curve names
if cScene.arrProps.cArrCurveName != "":
curveName = cScene.arrProps.cArrCurveName
bpy.context.active_object.name = curveName
else :
curveName = bpy.context.active_object.name
#not a curve Error handler
try:
curveLoc = bpy.context.active_object.location
except:
self.report({'ERROR'}, "You have not selected a curve object")
raise Exception("You have not selected a curve object")
# deselecting curve
bpy.context.active_object.select_set(0)
#selecting and copying object tamplate
bpy.data.objects[tmplObjName].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects[tmplObjName]
if cScene.arrProps.cArrDuplType == 'Duplicate':
bpy.ops.object.duplicate()
else:
bpy.ops.object.duplicate_move_linked(OBJECT_OT_duplicate={"linked":True, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(0, 0, 0), "orient_type":'GLOBAL', "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)), "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, False), "mirror":True, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":0, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "cursor_transform":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})
# bpy.context.active_object.name = objName
#moving sidewalk to the beggining of the curve
bpy.context.active_object.location = curveLoc
#adding and setting up Array modifier
bpy.ops.object.modifier_add(type='ARRAY')
bpy.context.active_object.modifiers["Array"].name=objName+'_Array'
bpy.context.active_object.modifiers[objName+'_Array'].fit_type='FIT_CURVE'
bpy.context.active_object.modifiers[objName+'_Array'].curve=bpy.data.objects[curveName]
bpy.context.active_object.modifiers[objName+'_Array'].use_merge_vertices = True
bpy.context.active_object.modifiers[objName+'_Array'].merge_threshold = 0.05
##
try:
bpy.context.object.modifiers[objName+'_Array'].start_cap = cScene.arrProps.cArrayStartCapObject
except:
pass
try:
bpy.context.object.modifiers[objName+'_Array'].end_cap = cScene.arrProps.cArrayEndCapObject
except:
pass
#bpy.context.object.modifiers["SidewalkArray"].end_cap = cArrayEndCapObject
#adding and setting up Curve modifier
bpy.ops.object.modifier_add(type='CURVE')
bpy.context.active_object.modifiers["Curve"].name=objName+'_Curve'
bpy.context.active_object.modifiers[objName+'_Curve'].object=bpy.data.objects[curveName]
#adding and setting up Decimate modifier
# bpy.ops.object.modifier_add(type='DECIMATE')
# bpy.context.active_object.modifiers["Decimate"].name=objName+'_Decimate'
# bpy.context.object.modifiers[objName+'_Decimate'].decimate_type = 'DISSOLVE'
# bpy.context.object.modifiers[objName+'_Decimate'].angle_limit = cScene.arrProps.trDecimateAngleLimit
# bpy.context.object.modifiers[objName+'_Decimate'].delimit = {'UV'}
#print(trDecimateAngleLimit)
bpy.context.active_object.name = objName
# print(bpy.context.active_object.name)
# print(objName)
#bpy.ops.object.duplicate_move(bpy.data.objects[tmplObjName], curveLoc)
#Moving to target Collections:
#Objects Collection
to_unlink =[]
for y in range(len(bpy.data.objects[objName].users_collection)) :
to_unlink.append(bpy.data.objects[objName].users_collection[y].name)
# #changing objName, if overriden by user
# if cScene.arrProps.cArrObjName is not None:
# objName = cScene.arrProps.cArrObjName
#if Object Target collection isnt null, manage collections
if cScene.arrProps.cArrObjectsColl is not None:
if cScene.arrProps.cArrObjectsColl.name in to_unlink :
to_unlink.remove(cScene.arrProps.cArrObjectsColl.name)
try:
to_unlink.remove("Master Collection")
cScene.collection.objects.unlink(bpy.data.objects[objName])
except ValueError:
pass
if cScene.arrProps.cArrObjectsColl not in bpy.data.objects[tmplObjName].users_collection :
try:
bpy.data.collections[cScene.arrProps.cArrObjectsColl.name].objects.link(bpy.data.objects[objName])
except RuntimeError:
pass
for z in range(len(to_unlink)) :
bpy.data.collections[to_unlink[z]].objects.unlink(bpy.data.objects[objName])
#Curve Collection management:
to_unlink =[]
for y in range(len(bpy.data.objects[curveName].users_collection)) :
to_unlink.append(bpy.data.objects[curveName].users_collection[y].name)
if cScene.arrProps.cArrCurvesColl is not None:
if cScene.arrProps.cArrCurvesColl.name in to_unlink :
to_unlink.remove(cScene.arrProps.cArrCurvesColl.name)
try:
to_unlink.remove("Master Collection")
cScene.collection.objects.unlink(bpy.data.objects[curveName])
except ValueError:
pass
if cScene.arrProps.cArrCurvesColl not in bpy.data.objects[curveName].users_collection :
bpy.data.collections[cScene.arrProps.cArrCurvesColl.name].objects.link(bpy.data.objects[curveName])
for z in range(len(to_unlink)) :
bpy.data.collections[to_unlink[z]].objects.unlink(bpy.data.objects[curveName])
#Decimation
if cScene.arrProps.cArrDec == 1 :
bpy.ops.object.modifier_add(type='DECIMATE')
bpy.context.active_object.modifiers["Decimate"].name='tr_Decimate'
bpy.context.object.modifiers["tr_Decimate"].decimate_type = 'COLLAPSE'
bpy.context.object.modifiers["tr_Decimate"].ratio = 0.1
# bpy.context.object.modifiers["MB_Decimate"].angle_limit = 1.5708
# bpy.context.object.modifiers["MB_Decimate"].delimit = {'UV'}
bpy.context.view_layer.objects.active = bpy.data.objects[curveName]
return {'FINISHED'}