This commit is contained in:
Campbell Barton
2011-07-26 04:17:15 +00:00
41 changed files with 615 additions and 124 deletions

View File

@@ -35,7 +35,7 @@ def abspath(path, start=None):
:type start: string
"""
if path.startswith("//"):
return _os.path.join(_os.path.dirname(_bpy.data.filepath if start is None else start), path[2:])
return _os.path.join(_os.path.dirname(_bpy.data.filepath) if start is None else start, path[2:])
return path
@@ -117,7 +117,7 @@ def display_name_from_filepath(name):
"""
Returns the path stripped of directort and extension, ensured to be utf8 compatible.
"""
return _os.path.splitext(_os.path.basename(name))[0].encode("utf8", "replace").decode("utf8")
return _os.path.splitext(basename(name))[0].encode("utf8", "replace").decode("utf8")
def resolve_ncase(path):
@@ -231,3 +231,12 @@ def module_names(path, recursive=False):
modules.append(("%s.%s" % (filename, mod_name), mod_path))
return modules
def basename(path):
"""
Equivalent to os.path.basename, but skips a "//" suffix.
Use for Windows compatibility.
"""
return _os.path.basename(path[2:] if path.startswith("//") else path)

View File

@@ -298,11 +298,18 @@ _presets = _os.path.join(_scripts[0], "presets") # FIXME - multiple paths
def preset_paths(subdir):
"""
Returns a list of paths for a specific preset.
:arg subdir: preset subdirectory (must not be an absolute path).
:type subdir: string
:return: script paths.
:rtype: list
"""
dirs = []
for path in script_paths("presets", all=True):
directory = _os.path.join(path, subdir)
if _os.path.isdir(directory):
if not directory.startswith(path):
raise Exception("invalid subdir given %r" % subdir)
elif _os.path.isdir(directory):
dirs.append(directory)
return dirs

View File

@@ -86,7 +86,9 @@ def load_image(imagepath,
variants = [imagepath]
if dirname:
variants += [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
variants += [os.path.join(dirname, imagepath),
os.path.join(dirname, bpy.path.basename(imagepath)),
]
for filepath_test in variants:
if ncase_cmp:
@@ -99,7 +101,7 @@ def load_image(imagepath,
return _image_load(nfilepath)
if place_holder:
image = bpy.data.images.new(os.path.basename(imagepath), 128, 128)
image = bpy.data.images.new(bpy.path.basename(imagepath), 128, 128)
# allow the path to be resolved later
image.filepath = imagepath
return image

View File

@@ -163,7 +163,7 @@ class ProjectEdit(bpy.types.Operator):
filepath_final = filepath + ("%.3d.%s" % (i, EXT))
i += 1
image_new.name = os.path.basename(filepath_final)
image_new.name = bpy.path.basename(filepath_final)
ProjectEdit._proj_hack[0] = image_new.name
image_new.filepath_raw = filepath_final # TODO, filepath raw is crummy

View File

@@ -21,13 +21,102 @@
import bpy
from mathutils import Vector
def GlobalBB_LQ(bb_world):
# Initialize the variables with the 8th vertex
left, right, front, back, down, up =\
bb_world[7][0],\
bb_world[7][0],\
bb_world[7][1],\
bb_world[7][1],\
bb_world[7][2],\
bb_world[7][2]
# Test against the other 7 verts
for i in range (7):
# X Range
val = bb_world[i][0]
if val < left:
left = val
if val > right:
right = val
# Y Range
val = bb_world[i][1]
if val < front:
front = val
if val > back:
back = val
# Z Range
val = bb_world[i][2]
if val < down:
down = val
if val > up:
up = val
return (Vector((left, front, up)), Vector((right, back, down)))
def align_objects(align_x, align_y, align_z, align_mode, relative_to):
def GlobalBB_HQ(obj):
matrix_world = obj.matrix_world.copy()
# Initialize the variables with the last vertex
verts = obj.data.vertices
val = verts[-1].co * matrix_world
left, right, front, back, down, up =\
val[0],\
val[0],\
val[1],\
val[1],\
val[2],\
val[2]
# Test against all other verts
for i in range (len(verts)-1):
vco = verts[i].co * matrix_world
# X Range
val = vco[0]
if val < left:
left = val
if val > right:
right = val
# Y Range
val = vco[1]
if val < front:
front = val
if val > back:
back = val
# Z Range
val = vco[2]
if val < down:
down = val
if val > up:
up = val
return (Vector((left, front, up)), Vector((right, back, down)))
def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality):
cursor = bpy.context.scene.cursor_location
Left_Up_Front_SEL = [0.0, 0.0, 0.0]
Right_Down_Back_SEL = [0.0, 0.0, 0.0]
Left_Front_Up_SEL = [0.0, 0.0, 0.0]
Right_Back_Down_SEL = [0.0, 0.0, 0.0]
flag_first = True
@@ -42,78 +131,89 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
return False
for obj, bb_world in objs:
Left_Up_Front = bb_world[1]
Right_Down_Back = bb_world[7]
if bb_quality:
GBB = GlobalBB_HQ(obj)
else:
GBB = GlobalBB_LQ(bb_world)
Left_Front_Up = GBB[0]
Right_Back_Down = GBB[1]
# Active Center
if obj == bpy.context.active_object:
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
center_active_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0
center_active_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0
center_active_z = (Left_Front_Up[2] + Right_Back_Down[2]) / 2.0
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
size_active_x = (Right_Back_Down[0] - Left_Front_Up[0]) / 2.0
size_active_y = (Right_Back_Down[1] - Left_Front_Up[1]) / 2.0
size_active_z = (Left_Front_Up[2] - Right_Back_Down[2]) / 2.0
# Selection Center
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]
Left_Front_Up_SEL[0] = Left_Front_Up[0]
Left_Front_Up_SEL[1] = Left_Front_Up[1]
Left_Front_Up_SEL[2] = Left_Front_Up[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]
Right_Back_Down_SEL[0] = Right_Back_Down[0]
Right_Back_Down_SEL[1] = Right_Back_Down[1]
Right_Back_Down_SEL[2] = Right_Back_Down[2]
else:
# X axis
if Left_Up_Front[0] < Left_Up_Front_SEL[0]:
Left_Up_Front_SEL[0] = Left_Up_Front[0]
if Left_Front_Up[0] < Left_Front_Up_SEL[0]:
Left_Front_Up_SEL[0] = Left_Front_Up[0]
# Y axis
if Left_Up_Front[1] < Left_Up_Front_SEL[1]:
Left_Up_Front_SEL[1] = Left_Up_Front[1]
if Left_Front_Up[1] < Left_Front_Up_SEL[1]:
Left_Front_Up_SEL[1] = Left_Front_Up[1]
# Z axis
if Left_Up_Front[2] > Left_Up_Front_SEL[2]:
Left_Up_Front_SEL[2] = Left_Up_Front[2]
if Left_Front_Up[2] > Left_Front_Up_SEL[2]:
Left_Front_Up_SEL[2] = Left_Front_Up[2]
# X axis
if Right_Down_Back[0] > Right_Down_Back_SEL[0]:
Right_Down_Back_SEL[0] = Right_Down_Back[0]
if Right_Back_Down[0] > Right_Back_Down_SEL[0]:
Right_Back_Down_SEL[0] = Right_Back_Down[0]
# Y axis
if Right_Down_Back[1] > Right_Down_Back_SEL[1]:
Right_Down_Back_SEL[1] = Right_Down_Back[1]
if Right_Back_Down[1] > Right_Back_Down_SEL[1]:
Right_Back_Down_SEL[1] = Right_Back_Down[1]
# Z axis
if Right_Down_Back[2] < Right_Down_Back_SEL[2]:
Right_Down_Back_SEL[2] = Right_Down_Back[2]
if Right_Back_Down[2] < Right_Back_Down_SEL[2]:
Right_Back_Down_SEL[2] = Right_Back_Down[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
center_sel_x = (Left_Front_Up_SEL[0] + Right_Back_Down_SEL[0]) / 2.0
center_sel_y = (Left_Front_Up_SEL[1] + Right_Back_Down_SEL[1]) / 2.0
center_sel_z = (Left_Front_Up_SEL[2] + Right_Back_Down_SEL[2]) / 2.0
# Main Loop
for obj, bb_world in objs:
bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box]
if bb_quality:
GBB = GlobalBB_HQ(obj)
else:
GBB = GlobalBB_LQ(bb_world)
Left_Front_Up = GBB[0]
Right_Back_Down = GBB[1]
Left_Up_Front = bb_world[1]
Right_Down_Back = bb_world[7]
center_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0
center_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0
center_z = (Left_Front_Up[2] + Right_Back_Down[2]) / 2.0
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_Back_Down[0]
positive_y = Right_Back_Down[1]
positive_z = Left_Front_Up[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_Front_Up[0]
negative_y = Left_Front_Up[1]
negative_z = Right_Back_Down[2]
obj_loc = obj.location
@@ -228,7 +328,7 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to):
return True
from bpy.props import EnumProperty
from bpy.props import EnumProperty, BoolProperty
class AlignObjects(bpy.types.Operator):
@@ -237,6 +337,11 @@ class AlignObjects(bpy.types.Operator):
bl_label = "Align Objects"
bl_options = {'REGISTER', 'UNDO'}
bb_quality = BoolProperty(
name="High Quality",
description="Enables high quality calculation of the bounding box for perfect results on complex shape meshes with rotation/scale (Slow)",
default=False)
align_mode = EnumProperty(items=(
('OPT_1', "Negative Sides", ""),
('OPT_2', "Centers", ""),
@@ -269,10 +374,10 @@ class AlignObjects(bpy.types.Operator):
def execute(self, context):
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)
ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to, self.bb_quality)
if not ret:
self.report({'WARNING'}, "No objects with bound-box selected")
return {'CANCELLED'}
else:
return {'FINISHED'}
return {'FINISHED'}

View File

@@ -174,6 +174,7 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, bpy.types.Panel):
row.prop(mat, "use_transparency")
sub = row.column()
sub.prop(mat, "offset_z")
sub.active = mat_type and mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY'
row = layout.row()
@@ -199,6 +200,7 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, bpy.types.Panel):
col.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
col.prop(mat, "use_cast_buffer_shadows")
col.prop(mat, "use_cast_approximate")
col.prop(mat, "pass_index")
class MATERIAL_PT_diffuse(MaterialButtonsPanel, bpy.types.Panel):
@@ -729,7 +731,8 @@ class MATERIAL_PT_options(MaterialButtonsPanel, bpy.types.Panel):
col.prop(mat, "use_vertex_color_paint")
col.prop(mat, "use_vertex_color_light")
col.prop(mat, "use_object_color")
col.prop(mat, "pass_index")
if simple_material(base_mat):
col.prop(mat, "pass_index")
class MATERIAL_PT_shadow(MaterialButtonsPanel, bpy.types.Panel):

View File

@@ -198,6 +198,10 @@ class IMAGE_MT_uvs_transform(bpy.types.Menu):
layout.operator("transform.rotate")
layout.operator("transform.resize")
layout.separator()
layout.operator("transform.shear")
class IMAGE_MT_uvs_snap(bpy.types.Menu):
bl_label = "Snap"