I have a problem with a script I wrote, but I’m not sure it’s a blender bug so I simplified the question and the code to expose it here:
suppose an empty scene with only one selected cube.
I write a script to delete the selected object and create a cone instead:
(don’t care about ‘house’ or ‘homa’ words, it comes from the original script)
import bpy
import math
from mathutils import Vector, Matrix
from bpy.props import *
class OBJECT_PT_ArToKi_HoMa_bug(bpy.types.Panel):
bl_label = "tmaes - bug"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
# Interface Buttons etc...
def draw(self, context):
layout = self.layout
obj = bpy.context.object
scene = bpy.context.scene
row = layout.row()
row.operator("object.homa_modify_house",text="Tranform cube to cone")
class OBJECT_OT_HoMa_modify_house(bpy.types.Operator):
bl_label = "HoMa modify House"
bl_idname = "object.homa_modify_house"
bl_description = "Transforms cube to cone."
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
scene = bpy.context.scene
obj = bpy.context.object
ver = obj.data.vertices
edg = obj.data.edges
num = len(edg)
bpy.ops.object.delete(use_global=False)
bpy.ops.mesh.primitive_cone_add(
True,
)
return {'FINISHED'}
# registering and menu integration
def register():
bpy.utils.register_class(OBJECT_PT_ArToKi_HoMa_bug)
bpy.utils.register_class(OBJECT_OT_HoMa_modify_house)
# unregistering and removing menus
def unregister():
bpy.utils.unregister_class(OBJECT_PT_ArToKi_HoMa_bug)
bpy.utils.unregister_class(OBJECT_OT_HoMa_modify_house)
if __name__ == "__main__":
register()
Result: a button in the Object panel that deletes the cube and creates a cone, with editable settings (thanks to the True param in bpy.ops.mesh.primitive_cone_add).
But Why oooh Why, when I edit those settings, does the initial cube reappear???
What version of Blender are you using? When I try to run it on 2.62 I get error related to the “primitive_cone_add” call. That method does not have any way to simply pass a boolean value to it.
The operator settings on the side panel are for ‘add cone’ and not for your operator so when you edit them it undos the last operation and redoes the add cone operation.
You need to register your operator in the undo stack (and add properties to edit) or something like that.
So thank you Uncle Entity, I don’t think I understood all the register/undo stack thing…
But I found the pieces of code needed to make it work here is the same example, with register and undo, and the radius2 property of the created cone and it works…
And the boolean parameter doesn’t seem to be useful using this method.
Thanks again!
import bpy
import math
from mathutils import Vector, Matrix
from bpy.props import *
class OBJECT_PT_ArToKi_HoMa_bug(bpy.types.Panel):
bl_label = "tmaes - bug"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
# Interface Buttons etc...
def draw(self, context):
layout = self.layout
obj = bpy.context.object
scene = bpy.context.scene
row = layout.row()
row.operator("object.homa_modify_house",text="Tranform cube to cone")
class OBJECT_OT_HoMa_modify_house(bpy.types.Operator):
bl_label = "HoMa modify House"
bl_idname = "object.homa_modify_house"
bl_description = "Transforms cube to cone."
bl_options = {'REGISTER', 'UNDO'}
radius2 = FloatProperty(
name="Radius2",
description="Cone radius2",
min=0.01, max=100.0,
default=1.0,
)
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
scene = bpy.context.scene
obj = bpy.context.object
ver = obj.data.vertices
edg = obj.data.edges
num = len(edg)
bpy.ops.object.delete(use_global=False)
bpy.ops.mesh.primitive_cone_add(
radius2=self.radius2,
)
return {'FINISHED'}
# registering and menu integration
def register():
bpy.utils.register_class(OBJECT_PT_ArToKi_HoMa_bug)
bpy.utils.register_class(OBJECT_OT_HoMa_modify_house)
# unregistering and removing menus
def unregister():
bpy.utils.unregister_class(OBJECT_PT_ArToKi_HoMa_bug)
bpy.utils.unregister_class(OBJECT_OT_HoMa_modify_house)
if __name__ == "__main__":
register()
So hi again…
after testing I have the impression to ‘turn arround myself’…
Your solution of registering etc works but I need to pass parameters I passed before without problems and now its very difficult.
In brief isn’t there a way to avoid the undo part of the behavior you described here: (ie clean the desired stack point)?
so when you edit them it undos the last operation and redoes the add cone operation
edit:
I found a method I don’t know if its clean:
added:
bpy.ops.ed.undo_push(message=“Add an undo step function may be moved”)
after object deletion and the undo part doesn’t happend anymore.
import bpy
import math
from mathutils import Vector, Matrix
from bpy.props import *
class OBJECT_PT_ArToKi_HoMa_bug(bpy.types.Panel):
bl_label = "tmaes - bug"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
# Interface Buttons etc...
def draw(self, context):
layout = self.layout
obj = bpy.context.object
scene = bpy.context.scene
row = layout.row()
row.operator("object.homa_modify_house",text="Tranform cube to cone")
class OBJECT_OT_HoMa_modify_house(bpy.types.Operator):
bl_label = "HoMa modify House"
bl_idname = "object.homa_modify_house"
bl_description = "Transforms cube to cone."
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
scene = bpy.context.scene
obj = bpy.context.object
ver = obj.data.vertices
edg = obj.data.edges
num = len(edg)
bpy.ops.object.delete(use_global=False)
bpy.ops.ed.undo_push(<i>message="Add an undo step *function may be moved*"</i>)
bpy.ops.mesh.primitive_cone_add(
True,
)
return {'FINISHED'}
# registering and menu integration
def register():
bpy.utils.register_class(OBJECT_PT_ArToKi_HoMa_bug)
bpy.utils.register_class(OBJECT_OT_HoMa_modify_house)
# unregistering and removing menus
def unregister():
bpy.utils.unregister_class(OBJECT_PT_ArToKi_HoMa_bug)
bpy.utils.unregister_class(OBJECT_OT_HoMa_modify_house)
if __name__ == "__main__":
register()