bugfix [#25290] Align on text gives a traceback
[#25284] Traceback error on "System Info" script - Align was only working on mesh objects, now operate on all objects, missing boundbox's are treated as single points. - obj.bound_box was returning all nan's for object types with no boundbox. - ENUM_FLAG type enums were showing no text when displayed in operator redo panel.
This commit is contained in:
@@ -560,7 +560,7 @@ def keyconfig_set(filepath):
|
||||
keyconfigs.active = kc_new
|
||||
|
||||
|
||||
def user_resource(type, path, create=False):
|
||||
def user_resource(type, path="", create=False):
|
||||
"""
|
||||
Return a user resource path (normally from the users home directory).
|
||||
|
||||
@@ -588,7 +588,7 @@ def user_resource(type, path, create=False):
|
||||
traceback.print_exc()
|
||||
target_path = ""
|
||||
elif not _os.path.isdir(target_path):
|
||||
print("Path %r found but isn't a directory!" % path)
|
||||
print("Path %r found but isn't a directory!" % target_path)
|
||||
target_path = ""
|
||||
|
||||
return target_path
|
||||
|
||||
@@ -26,206 +26,213 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
|
||||
|
||||
cursor = bpy.context.scene.cursor_location
|
||||
|
||||
Left_Up_Front_SEL = [[], [], []]
|
||||
Right_Down_Back_SEL = [[], [], []]
|
||||
Left_Up_Front_SEL = [0.0, 0.0, 0.0]
|
||||
Right_Down_Back_SEL = [0.0, 0.0, 0.0]
|
||||
|
||||
flag_first = True
|
||||
|
||||
objs = []
|
||||
|
||||
for obj in bpy.context.selected_objects:
|
||||
if obj.type == 'MESH':
|
||||
matrix_world = obj.matrix_world
|
||||
bb_world = [Vector(v[:]) * matrix_world for v in obj.bound_box]
|
||||
objs.append((obj, bb_world))
|
||||
|
||||
bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box]
|
||||
if not objs:
|
||||
return False
|
||||
|
||||
Left_Up_Front = bb_world[1]
|
||||
Right_Down_Back = bb_world[7]
|
||||
for obj, bb_world in objs:
|
||||
Left_Up_Front = bb_world[1]
|
||||
Right_Down_Back = bb_world[7]
|
||||
|
||||
# Active Center
|
||||
# Active Center
|
||||
|
||||
if obj == bpy.context.active_object:
|
||||
if obj == bpy.context.active_object:
|
||||
|
||||
center_active_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2
|
||||
center_active_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2
|
||||
center_active_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2
|
||||
center_active_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2.0
|
||||
center_active_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2.0
|
||||
center_active_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2.0
|
||||
|
||||
size_active_x = (Right_Down_Back[0] - Left_Up_Front[0]) / 2
|
||||
size_active_y = (Right_Down_Back[1] - Left_Up_Front[1]) / 2
|
||||
size_active_z = (Left_Up_Front[2] - Right_Down_Back[2]) / 2
|
||||
size_active_x = (Right_Down_Back[0] - Left_Up_Front[0]) / 2.0
|
||||
size_active_y = (Right_Down_Back[1] - Left_Up_Front[1]) / 2.0
|
||||
size_active_z = (Left_Up_Front[2] - Right_Down_Back[2]) / 2.0
|
||||
|
||||
# Selection Center
|
||||
# Selection Center
|
||||
|
||||
if flag_first:
|
||||
flag_first = False
|
||||
if flag_first:
|
||||
flag_first = False
|
||||
|
||||
Left_Up_Front_SEL[0] = Left_Up_Front[0]
|
||||
Left_Up_Front_SEL[1] = Left_Up_Front[1]
|
||||
Left_Up_Front_SEL[2] = Left_Up_Front[2]
|
||||
|
||||
Right_Down_Back_SEL[0] = Right_Down_Back[0]
|
||||
Right_Down_Back_SEL[1] = Right_Down_Back[1]
|
||||
Right_Down_Back_SEL[2] = Right_Down_Back[2]
|
||||
|
||||
else:
|
||||
# X axis
|
||||
if Left_Up_Front[0] < Left_Up_Front_SEL[0]:
|
||||
Left_Up_Front_SEL[0] = Left_Up_Front[0]
|
||||
# Y axis
|
||||
if Left_Up_Front[1] < Left_Up_Front_SEL[1]:
|
||||
Left_Up_Front_SEL[1] = Left_Up_Front[1]
|
||||
# Z axis
|
||||
if Left_Up_Front[2] > Left_Up_Front_SEL[2]:
|
||||
Left_Up_Front_SEL[2] = Left_Up_Front[2]
|
||||
|
||||
# X axis
|
||||
if Right_Down_Back[0] > Right_Down_Back_SEL[0]:
|
||||
Right_Down_Back_SEL[0] = Right_Down_Back[0]
|
||||
# Y axis
|
||||
if Right_Down_Back[1] > Right_Down_Back_SEL[1]:
|
||||
Right_Down_Back_SEL[1] = Right_Down_Back[1]
|
||||
# Z axis
|
||||
if Right_Down_Back[2] < Right_Down_Back_SEL[2]:
|
||||
Right_Down_Back_SEL[2] = Right_Down_Back[2]
|
||||
|
||||
else:
|
||||
# X axis
|
||||
if Left_Up_Front[0] < Left_Up_Front_SEL[0]:
|
||||
Left_Up_Front_SEL[0] = Left_Up_Front[0]
|
||||
# Y axis
|
||||
if Left_Up_Front[1] < Left_Up_Front_SEL[1]:
|
||||
Left_Up_Front_SEL[1] = Left_Up_Front[1]
|
||||
# Z axis
|
||||
if Left_Up_Front[2] > Left_Up_Front_SEL[2]:
|
||||
Left_Up_Front_SEL[2] = Left_Up_Front[2]
|
||||
|
||||
# X axis
|
||||
if Right_Down_Back[0] > Right_Down_Back_SEL[0]:
|
||||
Right_Down_Back_SEL[0] = Right_Down_Back[0]
|
||||
# Y axis
|
||||
if Right_Down_Back[1] > Right_Down_Back_SEL[1]:
|
||||
Right_Down_Back_SEL[1] = Right_Down_Back[1]
|
||||
# Z axis
|
||||
if Right_Down_Back[2] < Right_Down_Back_SEL[2]:
|
||||
Right_Down_Back_SEL[2] = Right_Down_Back[2]
|
||||
|
||||
center_sel_x = (Left_Up_Front_SEL[0] + Right_Down_Back_SEL[0]) / 2
|
||||
center_sel_y = (Left_Up_Front_SEL[1] + Right_Down_Back_SEL[1]) / 2
|
||||
center_sel_z = (Left_Up_Front_SEL[2] + Right_Down_Back_SEL[2]) / 2
|
||||
center_sel_x = (Left_Up_Front_SEL[0] + Right_Down_Back_SEL[0]) / 2.0
|
||||
center_sel_y = (Left_Up_Front_SEL[1] + Right_Down_Back_SEL[1]) / 2.0
|
||||
center_sel_z = (Left_Up_Front_SEL[2] + Right_Down_Back_SEL[2]) / 2.0
|
||||
|
||||
# Main Loop
|
||||
|
||||
for obj in bpy.context.selected_objects:
|
||||
if obj.type == 'MESH':
|
||||
for obj, bb_world in objs:
|
||||
|
||||
loc_world = obj.location
|
||||
bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box]
|
||||
loc_world = obj.location
|
||||
bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box]
|
||||
|
||||
Left_Up_Front = bb_world[1]
|
||||
Right_Down_Back = bb_world[7]
|
||||
Left_Up_Front = bb_world[1]
|
||||
Right_Down_Back = bb_world[7]
|
||||
|
||||
center_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2
|
||||
center_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2
|
||||
center_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2
|
||||
center_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2.0
|
||||
center_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2.0
|
||||
center_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2.0
|
||||
|
||||
positive_x = Right_Down_Back[0]
|
||||
positive_y = Right_Down_Back[1]
|
||||
positive_z = Left_Up_Front[2]
|
||||
positive_x = Right_Down_Back[0]
|
||||
positive_y = Right_Down_Back[1]
|
||||
positive_z = Left_Up_Front[2]
|
||||
|
||||
negative_x = Left_Up_Front[0]
|
||||
negative_y = Left_Up_Front[1]
|
||||
negative_z = Right_Down_Back[2]
|
||||
negative_x = Left_Up_Front[0]
|
||||
negative_y = Left_Up_Front[1]
|
||||
negative_z = Right_Down_Back[2]
|
||||
|
||||
obj_loc = obj.location
|
||||
obj_loc = obj.location
|
||||
|
||||
if align_x:
|
||||
if align_x:
|
||||
|
||||
# Align Mode
|
||||
# Align Mode
|
||||
|
||||
if relative_to == 'OPT_4': # Active relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_x = obj_loc[0] - negative_x - size_active_x
|
||||
if relative_to == 'OPT_4': # Active relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_x = obj_loc[0] - negative_x - size_active_x
|
||||
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_x = obj_loc[0] - positive_x + size_active_x
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_x = obj_loc[0] - positive_x + size_active_x
|
||||
|
||||
else: # Everything else relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_x = obj_loc[0] - negative_x
|
||||
else: # Everything else relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_x = obj_loc[0] - negative_x
|
||||
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_x = obj_loc[0] - positive_x
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_x = obj_loc[0] - positive_x
|
||||
|
||||
if align_mode == 'OPT_2': # All relative
|
||||
obj_x = obj_loc[0] - center_x
|
||||
if align_mode == 'OPT_2': # All relative
|
||||
obj_x = obj_loc[0] - center_x
|
||||
|
||||
# Relative To
|
||||
# Relative To
|
||||
|
||||
if relative_to == 'OPT_1':
|
||||
loc_x = obj_x
|
||||
if relative_to == 'OPT_1':
|
||||
loc_x = obj_x
|
||||
|
||||
elif relative_to == 'OPT_2':
|
||||
loc_x = obj_x + cursor[0]
|
||||
elif relative_to == 'OPT_2':
|
||||
loc_x = obj_x + cursor[0]
|
||||
|
||||
elif relative_to == 'OPT_3':
|
||||
loc_x = obj_x + center_sel_x
|
||||
elif relative_to == 'OPT_3':
|
||||
loc_x = obj_x + center_sel_x
|
||||
|
||||
elif relative_to == 'OPT_4':
|
||||
loc_x = obj_x + center_active_x
|
||||
elif relative_to == 'OPT_4':
|
||||
loc_x = obj_x + center_active_x
|
||||
|
||||
obj.location[0] = loc_x
|
||||
obj.location[0] = loc_x
|
||||
|
||||
|
||||
if align_y:
|
||||
if align_y:
|
||||
|
||||
# Align Mode
|
||||
# Align Mode
|
||||
|
||||
if relative_to == 'OPT_4': # Active relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_y = obj_loc[1] - negative_y - size_active_y
|
||||
if relative_to == 'OPT_4': # Active relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_y = obj_loc[1] - negative_y - size_active_y
|
||||
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_y = obj_loc[1] - positive_y + size_active_y
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_y = obj_loc[1] - positive_y + size_active_y
|
||||
|
||||
else: # Everything else relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_y = obj_loc[1] - negative_y
|
||||
else: # Everything else relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_y = obj_loc[1] - negative_y
|
||||
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_y = obj_loc[1] - positive_y
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_y = obj_loc[1] - positive_y
|
||||
|
||||
if align_mode == 'OPT_2': # All relative
|
||||
obj_y = obj_loc[1] - center_y
|
||||
if align_mode == 'OPT_2': # All relative
|
||||
obj_y = obj_loc[1] - center_y
|
||||
|
||||
# Relative To
|
||||
# Relative To
|
||||
|
||||
if relative_to == 'OPT_1':
|
||||
loc_y = obj_y
|
||||
if relative_to == 'OPT_1':
|
||||
loc_y = obj_y
|
||||
|
||||
elif relative_to == 'OPT_2':
|
||||
loc_y = obj_y + cursor[1]
|
||||
elif relative_to == 'OPT_2':
|
||||
loc_y = obj_y + cursor[1]
|
||||
|
||||
elif relative_to == 'OPT_3':
|
||||
loc_y = obj_y + center_sel_y
|
||||
elif relative_to == 'OPT_3':
|
||||
loc_y = obj_y + center_sel_y
|
||||
|
||||
elif relative_to == 'OPT_4':
|
||||
loc_y = obj_y + center_active_y
|
||||
elif relative_to == 'OPT_4':
|
||||
loc_y = obj_y + center_active_y
|
||||
|
||||
obj.location[1] = loc_y
|
||||
obj.location[1] = loc_y
|
||||
|
||||
|
||||
if align_z:
|
||||
if align_z:
|
||||
|
||||
# Align Mode
|
||||
# Align Mode
|
||||
|
||||
if relative_to == 'OPT_4': # Active relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_z = obj_loc[2] - negative_z - size_active_z
|
||||
if relative_to == 'OPT_4': # Active relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_z = obj_loc[2] - negative_z - size_active_z
|
||||
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_z = obj_loc[2] - positive_z + size_active_z
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_z = obj_loc[2] - positive_z + size_active_z
|
||||
|
||||
else: # Everything else relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_z = obj_loc[2] - negative_z
|
||||
else: # Everything else relative
|
||||
if align_mode == 'OPT_1':
|
||||
obj_z = obj_loc[2] - negative_z
|
||||
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_z = obj_loc[2] - positive_z
|
||||
elif align_mode == 'OPT_3':
|
||||
obj_z = obj_loc[2] - positive_z
|
||||
|
||||
if align_mode == 'OPT_2': # All relative
|
||||
obj_z = obj_loc[2] - center_z
|
||||
if align_mode == 'OPT_2': # All relative
|
||||
obj_z = obj_loc[2] - center_z
|
||||
|
||||
# Relative To
|
||||
# Relative To
|
||||
|
||||
if relative_to == 'OPT_1':
|
||||
loc_z = obj_z
|
||||
if relative_to == 'OPT_1':
|
||||
loc_z = obj_z
|
||||
|
||||
elif relative_to == 'OPT_2':
|
||||
loc_z = obj_z + cursor[2]
|
||||
elif relative_to == 'OPT_2':
|
||||
loc_z = obj_z + cursor[2]
|
||||
|
||||
elif relative_to == 'OPT_3':
|
||||
loc_z = obj_z + center_sel_z
|
||||
elif relative_to == 'OPT_3':
|
||||
loc_z = obj_z + center_sel_z
|
||||
|
||||
elif relative_to == 'OPT_4':
|
||||
loc_z = obj_z + center_active_z
|
||||
elif relative_to == 'OPT_4':
|
||||
loc_z = obj_z + center_active_z
|
||||
|
||||
obj.location[2] = loc_z
|
||||
obj.location[2] = loc_z
|
||||
|
||||
return True
|
||||
|
||||
|
||||
from bpy.props import *
|
||||
@@ -254,23 +261,28 @@ class AlignObjects(bpy.types.Operator):
|
||||
description="",
|
||||
default='OPT_4')
|
||||
|
||||
align_x = BoolProperty(name="Align X",
|
||||
description="Align in the X axis", default=False)
|
||||
|
||||
align_y = BoolProperty(name="Align Y",
|
||||
description="Align in the Y axis", default=False)
|
||||
|
||||
align_z = BoolProperty(name="Align Z",
|
||||
description="Align in the Z axis", default=False)
|
||||
align_axis = EnumProperty(items=(
|
||||
('X', "X", ""),
|
||||
('Y', "Y", ""),
|
||||
('Z', "Z", ""),
|
||||
),
|
||||
name="Align",
|
||||
description="Align to axis",
|
||||
options={'ENUM_FLAG'})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.mode == 'OBJECT'
|
||||
|
||||
def execute(self, context):
|
||||
align_objects(self.align_x, self.align_y, self.align_z, self.align_mode, self.relative_to)
|
||||
align_axis = self.align_axis
|
||||
ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to)
|
||||
|
||||
return {'FINISHED'}
|
||||
if not ret:
|
||||
self.report({'WARNING'}, "No objects with bound-box selected")
|
||||
return {'CANCELLED'}
|
||||
else:
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
|
||||
@@ -176,6 +176,7 @@ void mul_vn_fl(float *array, const int size, const float f);
|
||||
void mul_vn_vn_fl(float *array_tar, const float *array_src, const int size, const float f);
|
||||
void add_vn_vn(float *array_tar, const float *array_src, const int size);
|
||||
void fill_vni(int *array_tar, const int size, const int val);
|
||||
void fill_vn(float *array_tar, const int size, const float val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -404,3 +404,10 @@ void fill_vni(int *array_tar, const int size, const int val)
|
||||
int i= size;
|
||||
while(i--) { *(tar--) = val; }
|
||||
}
|
||||
|
||||
void fill_vn(float *array_tar, const int size, const float val)
|
||||
{
|
||||
float *tar= array_tar + (size-1);
|
||||
int i= size;
|
||||
while(i--) { *(tar--) = val; }
|
||||
}
|
||||
|
||||
@@ -163,7 +163,14 @@ int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(Proper
|
||||
col= NULL;
|
||||
}
|
||||
|
||||
name= ""; /* name is shown above, empty name for button below */
|
||||
/* may meed to add more cases here.
|
||||
* don't override enum flag names */
|
||||
if(flag & PROP_ENUM_FLAG) {
|
||||
name= NULL;
|
||||
}
|
||||
else {
|
||||
name= ""; /* name is shown above, empty name for button below */
|
||||
}
|
||||
}
|
||||
else {
|
||||
col= layout;
|
||||
|
||||
@@ -1091,7 +1091,7 @@ static void rna_Object_boundbox_get(PointerRNA *ptr, float *values)
|
||||
memcpy(values, bb->vec, sizeof(bb->vec));
|
||||
}
|
||||
else {
|
||||
memset(values, -1.0f, sizeof(bb->vec));
|
||||
fill_vn(values, sizeof(bb->vec)/sizeof(float), 0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1696,7 +1696,7 @@ static void rna_def_object(BlenderRNA *brna)
|
||||
RNA_def_property_multi_array(prop, 2, boundbox_dimsize);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_float_funcs(prop, "rna_Object_boundbox_get", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Bound Box", "Objects bound box in object-space coordinates");
|
||||
RNA_def_property_ui_text(prop, "Bound Box", "Objects bound box in object-space coordinates, all values are -1.0 when not available.");
|
||||
|
||||
/* parent */
|
||||
prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
|
||||
|
||||
Reference in New Issue
Block a user