okay, the thing that went wrong here, is that you tried to save values in a panel, which doesnt like to remember things. so instead we save values in the current scene
i changed you script to the following:
class OBJECT_PT_follow(bpy.types.Panel):
bl_label = "Follow Script"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
# initiate the variables once
bpy.context.scene["curv"] = ""
bpy.context.scene["ob"] = ""
def draw(self, context):
layout = self.layout
# get current scene
sce = bpy.context.scene
# there can be more than one object selected, take the active one
obj = context.active_object
row = layout.row()
row.label(text="Script Follow Curve", icon='WORLD_DATA')
row = layout.row()
row.label(text="Active object is: " + obj.name)
row = layout.row()
#*************************************************************************************************
if obj.type=='CURVE':
row.prop(obj, "name", "Curve Name", "CURVE_DATA")
# save the objects name in the curve variable
sce["curv"] = obj.name
else:
row.prop(obj, "name", "Object Name", "OBJECT_DATA")
# save the objects name in the obj variable
sce["ob"] = obj.name
#*************************************************************************************************
if sce["curv"]: # if the curve variable is not empty
row = layout.row()
row.label(text="Selected Curve: " + sce["curv"], icon='CURVE_DATA')
#************************************************************************************************
if sce["ob"]: # if the obj variable is not empty
row = layout.row()
row.label(text="Selected Object: " + sce["ob"], icon='OBJECT_DATA')
row = layout.row()
row.operator("efollow", text="go!")
class OBJECT_OT_execute_follow(bpy.types.Operator):
bl_label = "efollow"
bl_idname = "efollow"
bl_description = "Move to curve"
def invoke(self, context, event):
sce = bpy.context.scene
if sce["ob"]:
# get object with name stored in the ob variable
obj = bpy.data.objects[sce["ob"]]
# print it for confirmation
print(obj.name)
else:
# none was selected so far, cancel operator
print("no object selected")
return {'CANCELLED'}
if sce["curv"]:
curve = bpy.data.objects[sce["curv"]]
print(curve.name)
else:
print("no curve selected")
return {'CANCELLED'}
# and now you have two variables (obj and curve) that are the object and curve
# and you can do what you want :P
#bpy.ops.object.select_name(name=bpy.types.OBJECT_PT_follow.ob.name)
#bpy.ops.object.duplicate_move()
#bpy.ops.object.constraint_add(type='FOLLOW_PATH')
#bpy.types.Object(ob).constraints["Follow Path"].use_curve_follow=1
#bpy.types.Object(ob).constraints["Follow Path"].target=curv
return {'FINISHED'}
bpy.types.register(OBJECT_OT_execute_follow)
bpy.types.register(OBJECT_PT_follow)
dreampainter Your script works is exactly the same, but… thx.
Atom
Array modifier copies mesh data (and deform her), not object. Me need to copy objects without deformations, and with its own local coordinates for each copies.
Me need to known how copy selected object (not active). Very need.
in blender active object is the last selected object!
try this
class OBJECT_OT_execute_follow(bpy.types.Operator):
bl_label = "efollow"
bl_idname = "efollow"
bl_description = "Move to curve"
def invoke(self, context, event):
#first deselect all
bpy.ops.object.select_all(action='DESELECT')
#after select desired object
bpy.data.objects[bpy.types.OBJECT_PT_follow.ob.name].selected = True
active = context.active_object
#add constraint to base object
const_col = active.constraints
const = const_col.new(type='FOLLOW_PATH')
const.name="followCurve"
const.use_curve_follow=1
#can also be negative!!! depend on direction of curve
const.offset = 3
#depend on direction of curve
const.forward = 'FORWARD_Y'
const.target=bpy.types.OBJECT_PT_follow.curv
#dupli with shared mesh the object base (the active)
obj_new = bpy.ops.object.duplicate(linked=True)
return {'FINISHED'}
bpy.types.register(OBJECT_OT_execute_follow)
bpy.types.register(OBJECT_PT_follow)
I have see a little problem in my script
“const” is a reserved word of python so it’s better and much clear to use “constraint”
“constraint” is the object where you set all your parameters
contraint.offset = 16
To control the number use a for statement
PROBLEMS:
bpy.ops.object.duplicate(linked=True) function is not made to return an object
So how to select the new duplicated object and acess the constraint parameter?
One possibility is that, I think…
class OBJECT_OT_execute_follow(bpy.types.Operator):
bl_label = "efollow"
bl_idname = "efollow"
bl_description = "Move to curve"
def invoke(self, context, event):
#first deselect all
bpy.ops.object.select_all(action='DESELECT')
#after select desired object
bpy.data.objects[bpy.types.OBJECT_PT_follow.ob.name].selected = True
active=context.scene.objects[bpy.types.OBJECT_PT_follow.ob.name]
#add constraint to base object.
const_col = active.constraints
#Set here all the parameters for constraint
constraint = const_col.new(type='FOLLOW_PATH')
constraint.name="followCurve"
constraint.use_curve_follow=1
#can also be negative!!! depend on direction of curve
constraint.offset = 0
#depend on direction of curve
constraint.forward = 'FORWARD_Y'
constraint.target=bpy.types.OBJECT_PT_follow.curv
#Here you can use a for statement
for obj in range(10):
bpy.ops.object.duplicate(linked=True)
active = bpy.context.selected_editable_objects
#constraint object! Here you set parameter for the duplicate
constraint = active[0].constraints[0]
constraint.offset = -16 *(obj+2)
#NOT HERE! Above on the "constraint" variable lines(21...28) for object base or lines(77...78) for duplicates
#bpy.types.Object(active.name).constraints["Follow Path"].offset=16;
return {'FINISHED'}