Merged changes in the trunk up to revision 45133.
Conflicts resolved: source/blender/blenloader/intern/readfile.c source/blender/blenloader/intern/writefile.c source/blender/bmesh/intern/bmesh_construct.c source/blender/bmesh/intern/bmesh_mesh_conv.c source/blender/bmesh/intern/bmesh_mesh_conv.h source/blender/editors/interface/interface_templates.c source/blender/editors/interface/resources.c source/blender/editors/mesh/bmesh_select.c source/blender/editors/mesh/bmesh_tools.c source/blender/editors/space_view3d/drawobject.c source/blender/render/intern/source/shadeoutput.c
This commit is contained in:
@@ -118,6 +118,14 @@ def clean_name(name, replace="_"):
|
||||
return name
|
||||
|
||||
|
||||
def _clean_utf8(name):
|
||||
name = _os.path.splitext(basename(name))[0]
|
||||
if type(name) == bytes:
|
||||
return name.decode("utf8", "replace")
|
||||
else:
|
||||
return name.encode("utf8", "replace").decode("utf8")
|
||||
|
||||
|
||||
def display_name(name):
|
||||
"""
|
||||
Creates a display string from name to be used menus and the user interface.
|
||||
@@ -126,17 +134,18 @@ def display_name(name):
|
||||
filenames and module names.
|
||||
"""
|
||||
|
||||
name_base = _os.path.splitext(name)[0]
|
||||
name = _os.path.splitext(name)[0]
|
||||
|
||||
# string replacements
|
||||
name_base = name_base.replace("_colon_", ":")
|
||||
name = name.replace("_colon_", ":")
|
||||
|
||||
name_base = name_base.replace("_", " ")
|
||||
name = name.replace("_", " ")
|
||||
|
||||
if name_base.islower():
|
||||
return name_base.lower().title()
|
||||
else:
|
||||
return name_base
|
||||
if name.islower():
|
||||
name = name.lower().title()
|
||||
|
||||
name = _clean_utf8(name)
|
||||
return name
|
||||
|
||||
|
||||
def display_name_from_filepath(name):
|
||||
@@ -144,8 +153,10 @@ def display_name_from_filepath(name):
|
||||
Returns the path stripped of directory and extension,
|
||||
ensured to be utf8 compatible.
|
||||
"""
|
||||
|
||||
name = _os.path.splitext(basename(name))[0]
|
||||
return name.encode("utf8", "replace").decode("utf8")
|
||||
name = _clean_utf8(name)
|
||||
return name
|
||||
|
||||
|
||||
def resolve_ncase(path):
|
||||
|
||||
@@ -19,17 +19,17 @@
|
||||
# <pep8-80 compliant>
|
||||
|
||||
__all__ = (
|
||||
"mesh_linked_faces",
|
||||
"mesh_linked_tessfaces",
|
||||
"edge_face_count_dict",
|
||||
"edge_face_count",
|
||||
"edge_loops_from_faces",
|
||||
"edge_loops_from_tessfaces",
|
||||
"edge_loops_from_edges",
|
||||
"ngon_tesselate",
|
||||
"ngon_tessellate",
|
||||
"face_random_points",
|
||||
)
|
||||
|
||||
|
||||
def mesh_linked_faces(mesh):
|
||||
def mesh_linked_tessfaces(mesh):
|
||||
"""
|
||||
Splits the mesh into connected faces, use this for seperating cubes from
|
||||
other mesh elements within 1 mesh datablock.
|
||||
@@ -42,20 +42,20 @@ def mesh_linked_faces(mesh):
|
||||
|
||||
# Build vert face connectivity
|
||||
vert_faces = [[] for i in range(len(mesh.vertices))]
|
||||
for f in mesh.faces:
|
||||
for f in mesh.tessfaces:
|
||||
for v in f.vertices:
|
||||
vert_faces[v].append(f)
|
||||
|
||||
# sort faces into connectivity groups
|
||||
face_groups = [[f] for f in mesh.faces]
|
||||
face_mapping = list(range(len(mesh.faces))) # map old, new face location
|
||||
face_groups = [[f] for f in mesh.tessfaces]
|
||||
face_mapping = list(range(len(mesh.tessfaces))) # map old, new face location
|
||||
|
||||
# Now clump faces iteratively
|
||||
ok = True
|
||||
while ok:
|
||||
ok = False
|
||||
|
||||
for i, f in enumerate(mesh.faces):
|
||||
for i, f in enumerate(mesh.tessfaces):
|
||||
mapped_index = face_mapping[f.index]
|
||||
mapped_group = face_groups[mapped_index]
|
||||
|
||||
@@ -90,7 +90,7 @@ def edge_face_count_dict(mesh):
|
||||
faces using each edge.
|
||||
:rtype: dict
|
||||
"""
|
||||
face_edge_keys = [face.edge_keys for face in mesh.faces]
|
||||
face_edge_keys = [face.edge_keys for face in mesh.tessfaces]
|
||||
face_edge_count = {}
|
||||
for face_keys in face_edge_keys:
|
||||
for key in face_keys:
|
||||
@@ -112,11 +112,11 @@ def edge_face_count(mesh):
|
||||
return [get(edge_face_count, ed.key, 0) for ed in mesh.edges]
|
||||
|
||||
|
||||
def edge_loops_from_faces(mesh, faces=None, seams=()):
|
||||
def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()):
|
||||
"""
|
||||
Edge loops defined by faces
|
||||
|
||||
Takes me.faces or a list of faces and returns the edge loops
|
||||
Takes me.tessfaces or a list of faces and returns the edge loops
|
||||
These edge loops are the edges that sit between quads, so they dont touch
|
||||
1 quad, note: not connected will make 2 edge loops,
|
||||
both only containing 2 edges.
|
||||
@@ -126,20 +126,20 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
|
||||
|
||||
:arg mesh: the mesh used to get edge loops from.
|
||||
:type mesh: :class:`bpy.types.Mesh`
|
||||
:arg faces: optional face list to only use some of the meshes faces.
|
||||
:type faces: :class:`bpy.types.MeshFaces`, sequence or or NoneType
|
||||
:arg tessfaces: optional face list to only use some of the meshes faces.
|
||||
:type tessfaces: :class:`bpy.types.MeshTessFace`, sequence or or NoneType
|
||||
:return: return a list of edge vertex index lists.
|
||||
:rtype: list
|
||||
"""
|
||||
|
||||
OTHER_INDEX = 2, 3, 0, 1 # opposite face index
|
||||
|
||||
if faces is None:
|
||||
faces = mesh.faces
|
||||
if tessfaces is None:
|
||||
tessfaces = mesh.tessfaces
|
||||
|
||||
edges = {}
|
||||
|
||||
for f in faces:
|
||||
for f in tessfaces:
|
||||
if len(f.vertices) == 4:
|
||||
edge_keys = f.edge_keys
|
||||
for i, edkey in enumerate(f.edge_keys):
|
||||
@@ -256,7 +256,7 @@ def edge_loops_from_edges(mesh, edges=None):
|
||||
return line_polys
|
||||
|
||||
|
||||
def ngon_tesselate(from_data, indices, fix_loops=True):
|
||||
def ngon_tessellate(from_data, indices, fix_loops=True):
|
||||
'''
|
||||
Takes a polyline of indices (fgon) and returns a list of face
|
||||
indicie lists. Designed to be used for importers that need indices for an
|
||||
@@ -269,7 +269,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
|
||||
polylines are delt with correctly.
|
||||
'''
|
||||
|
||||
from mathutils.geometry import tesselate_polygon
|
||||
from mathutils.geometry import tessellate_polygon
|
||||
from mathutils import Vector
|
||||
vector_to_tuple = Vector.to_tuple
|
||||
|
||||
@@ -303,7 +303,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
|
||||
if verts[i][1] == verts[i - 1][0]:
|
||||
verts.pop(i - 1)
|
||||
|
||||
fill = tesselate_polygon([verts])
|
||||
fill = tessellate_polygon([verts])
|
||||
|
||||
else:
|
||||
'''
|
||||
@@ -411,7 +411,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
|
||||
vert_map[i + ii] = vert[2]
|
||||
ii += len(verts)
|
||||
|
||||
fill = tesselate_polygon([[v[0] for v in loop] for loop in loop_list])
|
||||
fill = tessellate_polygon([[v[0] for v in loop] for loop in loop_list])
|
||||
#draw_loops(loop_list)
|
||||
#raise 'done loop'
|
||||
# map to original indices
|
||||
@@ -442,14 +442,14 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
|
||||
return fill
|
||||
|
||||
|
||||
def face_random_points(num_points, faces):
|
||||
def face_random_points(num_points, tessfaces):
|
||||
"""
|
||||
Generates a list of random points over mesh faces.
|
||||
Generates a list of random points over mesh tessfaces.
|
||||
|
||||
:arg num_points: the number of random points to generate on each face.
|
||||
:type int:
|
||||
:arg faces: list of the faces to generate points on.
|
||||
:type faces: :class:`bpy.types.MeshFaces`, sequence
|
||||
:arg tessfaces: list of the faces to generate points on.
|
||||
:type tessfaces: :class:`bpy.types.MeshTessFace`, sequence
|
||||
:return: list of random points over all faces.
|
||||
:rtype: list
|
||||
"""
|
||||
@@ -459,7 +459,7 @@ def face_random_points(num_points, faces):
|
||||
|
||||
# Split all quads into 2 tris, tris remain unchanged
|
||||
tri_faces = []
|
||||
for f in faces:
|
||||
for f in tessfaces:
|
||||
tris = []
|
||||
verts = f.id_data.vertices
|
||||
fv = f.vertices[:]
|
||||
@@ -475,7 +475,7 @@ def face_random_points(num_points, faces):
|
||||
tri_faces.append(tris)
|
||||
|
||||
# For each face, generate the required number of random points
|
||||
sampled_points = [None] * (num_points * len(faces))
|
||||
sampled_points = [None] * (num_points * len(tessfaces))
|
||||
for i, tf in enumerate(tri_faces):
|
||||
for k in range(num_points):
|
||||
# If this is a quad, we need to weight its 2 tris by their area
|
||||
|
||||
@@ -21,12 +21,15 @@
|
||||
__all__ = (
|
||||
"add_object_align_init",
|
||||
"object_data_add",
|
||||
"AddObjectHelper",
|
||||
)
|
||||
|
||||
|
||||
import bpy
|
||||
import mathutils
|
||||
|
||||
from bpy.props import BoolProperty, FloatVectorProperty
|
||||
|
||||
|
||||
def add_object_align_init(context, operator):
|
||||
"""
|
||||
@@ -116,11 +119,12 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True):
|
||||
v3d = context.space_data
|
||||
|
||||
if use_active_layer:
|
||||
if v3d.local_view:
|
||||
if v3d and v3d.local_view:
|
||||
base.layers_from_view(context.space_data)
|
||||
base.layers[scene.active_layer] = True
|
||||
else:
|
||||
base.layers = [True if i == scene.active_layer else False for i in range(len(scene.layers))]
|
||||
base.layers = [True if i == scene.active_layer
|
||||
else False for i in range(len(scene.layers))]
|
||||
if v3d:
|
||||
base.layers_from_view(context.space_data)
|
||||
|
||||
@@ -163,3 +167,23 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True):
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
||||
return base
|
||||
|
||||
|
||||
class AddObjectHelper:
|
||||
def view_align_update_callback(self, context):
|
||||
if not self.view_align:
|
||||
self.rotation.zero()
|
||||
|
||||
view_align = BoolProperty(
|
||||
name="Align to View",
|
||||
default=False,
|
||||
update=view_align_update_callback,
|
||||
)
|
||||
location = FloatVectorProperty(
|
||||
name="Location",
|
||||
subtype='TRANSLATION',
|
||||
)
|
||||
rotation = FloatVectorProperty(
|
||||
name="Rotation",
|
||||
subtype='EULER',
|
||||
)
|
||||
|
||||
@@ -411,7 +411,7 @@ class MeshEdge(StructRNA):
|
||||
return ord_ind(*tuple(self.vertices))
|
||||
|
||||
|
||||
class MeshFace(StructRNA):
|
||||
class MeshTessFace(StructRNA):
|
||||
__slots__ = ()
|
||||
|
||||
@property
|
||||
|
||||
@@ -412,6 +412,7 @@
|
||||
keyframe="#ff8500"
|
||||
meta_strip="#6d9183"
|
||||
movie_strip="#516987"
|
||||
movieclip_strip="#20208f"
|
||||
plugin_strip="#7e7e50"
|
||||
scene_strip="#4e983e"
|
||||
transition_strip="#a25f6f"
|
||||
|
||||
@@ -412,6 +412,7 @@
|
||||
keyframe="#ff8500"
|
||||
meta_strip="#6d9183"
|
||||
movie_strip="#516987"
|
||||
movieclip_strip="#20208f"
|
||||
plugin_strip="#7e7e50"
|
||||
scene_strip="#4e983e"
|
||||
transition_strip="#a25f6f"
|
||||
|
||||
@@ -412,6 +412,7 @@
|
||||
keyframe="#ff8500"
|
||||
meta_strip="#6d9183"
|
||||
movie_strip="#516987"
|
||||
movieclip_strip="#20208f"
|
||||
plugin_strip="#7e7e50"
|
||||
scene_strip="#4e983e"
|
||||
transition_strip="#a25f6f"
|
||||
|
||||
@@ -412,6 +412,7 @@
|
||||
keyframe="#ff8500"
|
||||
meta_strip="#6d9183"
|
||||
movie_strip="#516987"
|
||||
movieclip_strip="#20208f"
|
||||
plugin_strip="#7e7e50"
|
||||
scene_strip="#4e983e"
|
||||
transition_strip="#a25f6f"
|
||||
|
||||
@@ -412,6 +412,7 @@
|
||||
keyframe="#f47421"
|
||||
meta_strip="#6d9183"
|
||||
movie_strip="#516987"
|
||||
movieclip_strip="#20208f"
|
||||
plugin_strip="#7e7e50"
|
||||
scene_strip="#4e983e"
|
||||
transition_strip="#a25f6f"
|
||||
|
||||
@@ -21,6 +21,14 @@ import bpy
|
||||
from bpy.types import Operator
|
||||
import mathutils
|
||||
|
||||
from bpy.props import (FloatProperty,
|
||||
IntProperty,
|
||||
BoolProperty,
|
||||
FloatVectorProperty,
|
||||
)
|
||||
|
||||
from bpy_extras import object_utils
|
||||
|
||||
|
||||
def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
||||
from math import cos, sin, pi
|
||||
@@ -75,14 +83,8 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
||||
|
||||
return verts, faces
|
||||
|
||||
from bpy.props import (FloatProperty,
|
||||
IntProperty,
|
||||
BoolProperty,
|
||||
FloatVectorProperty,
|
||||
)
|
||||
|
||||
|
||||
class AddTorus(Operator):
|
||||
class AddTorus(Operator, object_utils.AddObjectHelper):
|
||||
'''Add a torus mesh'''
|
||||
bl_idname = "mesh.primitive_torus_add"
|
||||
bl_label = "Add Torus"
|
||||
@@ -131,22 +133,7 @@ class AddTorus(Operator):
|
||||
default=0.5,
|
||||
)
|
||||
|
||||
# generic transform props
|
||||
view_align = BoolProperty(
|
||||
name="Align to View",
|
||||
default=False,
|
||||
)
|
||||
location = FloatVectorProperty(
|
||||
name="Location",
|
||||
subtype='TRANSLATION',
|
||||
)
|
||||
rotation = FloatVectorProperty(
|
||||
name="Rotation",
|
||||
subtype='EULER',
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
if self.use_abso == True:
|
||||
extra_helper = (self.abso_major_rad - self.abso_minor_rad) * 0.5
|
||||
self.major_radius = self.abso_minor_rad + extra_helper
|
||||
@@ -160,13 +147,14 @@ class AddTorus(Operator):
|
||||
mesh = bpy.data.meshes.new("Torus")
|
||||
|
||||
mesh.vertices.add(len(verts_loc) // 3)
|
||||
|
||||
# BMESH_TODO, use polygons
|
||||
mesh.faces.add(len(faces) // 4)
|
||||
|
||||
mesh.vertices.foreach_set("co", verts_loc)
|
||||
mesh.faces.foreach_set("vertices_raw", faces)
|
||||
mesh.update()
|
||||
|
||||
from bpy_extras import object_utils
|
||||
object_utils.object_data_add(context, mesh, operator=self)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -716,6 +716,7 @@ class CLIP_OT_setup_tracking_scene(Operator):
|
||||
mesh.vertices.add(len(vertices))
|
||||
mesh.vertices.foreach_set("co", unpack_list(vertices))
|
||||
|
||||
# BMESH_TODO - use polygons
|
||||
mesh.faces.add(len(faces))
|
||||
mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces))
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ class MeshMirrorUV(Operator):
|
||||
for uv in fuvs]
|
||||
|
||||
# as a list
|
||||
# BMESH_TODO - use polygons
|
||||
faces = mesh.faces[:]
|
||||
|
||||
fuvsel = [(False not in uv.select_uv) for uv in active_uv_layer]
|
||||
|
||||
@@ -367,6 +367,7 @@ class ShapeTransfer(Operator):
|
||||
(orig_shape_coords[i] - orig_coords[i]))
|
||||
|
||||
elif mode == 'RELATIVE_FACE':
|
||||
# BMESH TODO - use .polygons
|
||||
for face in me.faces:
|
||||
i1, i2, i3, i4 = face.vertices_raw
|
||||
if i4 != 0:
|
||||
@@ -539,6 +540,7 @@ class JoinUVs(Operator):
|
||||
"Object: %s, Mesh: '%s' has no UVs"
|
||||
% (obj.name, mesh.name))
|
||||
else:
|
||||
# BMESH_TODO - use polygons
|
||||
len_faces = len(mesh.faces)
|
||||
|
||||
# seems to be the fastest way to create an array
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
import bpy
|
||||
from bpy.types import Menu, Operator
|
||||
from bpy.props import StringProperty, BoolProperty
|
||||
|
||||
|
||||
class AddPresetBase():
|
||||
@@ -31,13 +32,13 @@ class AddPresetBase():
|
||||
# bl_label = "Add a Python Preset"
|
||||
bl_options = {'REGISTER'} # only because invoke_props_popup requires.
|
||||
|
||||
name = bpy.props.StringProperty(
|
||||
name = StringProperty(
|
||||
name="Name",
|
||||
description="Name of the preset, used to make the path name",
|
||||
maxlen=64,
|
||||
options={'SKIP_SAVE'},
|
||||
)
|
||||
remove_active = bpy.props.BoolProperty(
|
||||
remove_active = BoolProperty(
|
||||
default=False,
|
||||
options={'HIDDEN', 'SKIP_SAVE'},
|
||||
)
|
||||
@@ -166,12 +167,10 @@ class ExecutePreset(Operator):
|
||||
bl_idname = "script.execute_preset"
|
||||
bl_label = "Execute a Python Preset"
|
||||
|
||||
filepath = bpy.props.StringProperty(
|
||||
name="Path",
|
||||
description="Path of the Python file to execute",
|
||||
maxlen=512,
|
||||
filepath = StringProperty(
|
||||
subtype='FILE_PATH',
|
||||
)
|
||||
menu_idname = bpy.props.StringProperty(
|
||||
menu_idname = StringProperty(
|
||||
name="Menu ID Name",
|
||||
description="ID name of the menu this was called from",
|
||||
)
|
||||
@@ -456,7 +455,7 @@ class AddPresetOperator(AddPresetBase, Operator):
|
||||
bl_label = "Operator Preset"
|
||||
preset_menu = "WM_MT_operator_presets"
|
||||
|
||||
operator = bpy.props.StringProperty(
|
||||
operator = StringProperty(
|
||||
name="Operator",
|
||||
maxlen=64,
|
||||
options={'HIDDEN'},
|
||||
|
||||
@@ -168,7 +168,7 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
edge_faces[edkey] = [i]
|
||||
|
||||
if EXTEND_MODE == 'LENGTH':
|
||||
edge_loops = mesh_utils.edge_loops_from_faces(me, face_sel, [ed.key for ed in me.edges if ed.use_seam])
|
||||
edge_loops = mesh_utils.edge_loops_from_tessfaces(me, face_sel, [ed.key for ed in me.edges if ed.use_seam])
|
||||
me_verts = me.vertices
|
||||
for loop in edge_loops:
|
||||
looplen = [0.0]
|
||||
|
||||
@@ -156,19 +156,19 @@ class VertexPaintDirt(Operator):
|
||||
)
|
||||
clean_angle = FloatProperty(
|
||||
name="Highlight Angle",
|
||||
description="Less then 90 limits the angle used in the tonal range",
|
||||
description="Less than 90 limits the angle used in the tonal range",
|
||||
min=0.0, max=180.0,
|
||||
default=180.0,
|
||||
)
|
||||
dirt_angle = FloatProperty(
|
||||
name="Dirt Angle",
|
||||
description="Less then 90 limits the angle used in the tonal range",
|
||||
description="Less than 90 limits the angle used in the tonal range",
|
||||
min=0.0, max=180.0,
|
||||
default=0.0,
|
||||
)
|
||||
dirt_only = BoolProperty(
|
||||
name="Dirt Only",
|
||||
description="Dont calculate cleans for convex areas",
|
||||
description="Don't calculate cleans for convex areas",
|
||||
default=False,
|
||||
)
|
||||
|
||||
|
||||
@@ -206,8 +206,10 @@ class BONE_PT_display(BoneButtonsPanel, Panel):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(bone, "show_wire", text="Wireframe")
|
||||
col.prop(bone, "hide", text="Hide")
|
||||
sub = col.column()
|
||||
sub.active = bool(pchan.custom_shape)
|
||||
sub.prop(bone, "show_wire", text="Wireframe")
|
||||
|
||||
if pchan:
|
||||
col = split.column()
|
||||
|
||||
@@ -162,7 +162,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
|
||||
row = layout.row()
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.operator("object.vertex_group_assign", text="Assign")
|
||||
sub.operator("object.vertex_group_assign", text="Assign").new = False
|
||||
sub.operator("object.vertex_group_remove_from", text="Remove")
|
||||
|
||||
sub = row.row(align=True)
|
||||
|
||||
@@ -124,9 +124,11 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
split.prop(md, "use_only_vertices")
|
||||
|
||||
# -- new modifier only, this may be reverted in favor of 2.62 mod.
|
||||
'''
|
||||
split = layout.split()
|
||||
split.prop(md, "use_even_offset")
|
||||
split.prop(md, "use_distance_offset")
|
||||
'''
|
||||
# -- end
|
||||
|
||||
layout.label(text="Limit Method:")
|
||||
|
||||
@@ -90,7 +90,7 @@ class OBJECT_PT_delta_transform(ObjectButtonsPanel, Panel):
|
||||
#row.column().prop(ob, "delta_rotation_axis_angle", text="Rotation")
|
||||
row.column().label(text="Not for Axis-Angle")
|
||||
else:
|
||||
row.column().prop(ob, "delta_rotation_euler", text="Rotation")
|
||||
row.column().prop(ob, "delta_rotation_euler", text="Delta Rotation")
|
||||
|
||||
row.column().prop(ob, "delta_scale")
|
||||
|
||||
@@ -211,8 +211,11 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel):
|
||||
col = split.column()
|
||||
col.prop(ob, "show_name", text="Name")
|
||||
col.prop(ob, "show_axis", text="Axis")
|
||||
col.prop(ob, "show_wire", text="Wire")
|
||||
col.prop(ob, "color", text="Object Color")
|
||||
if ob.type in {"MESH", "CURVE", "SURFACE", "META", "FONT"}:
|
||||
# Makes no sense for cameras, armtures, etc.!
|
||||
col.prop(ob, "show_wire", text="Wire")
|
||||
# Only useful with object having faces/materials...
|
||||
col.prop(ob, "color", text="Object Color")
|
||||
|
||||
col = split.column()
|
||||
col.prop(ob, "show_texture_space", text="Texture Space")
|
||||
|
||||
@@ -380,6 +380,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel):
|
||||
|
||||
class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Rotation"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
|
||||
@classmethod
|
||||
@@ -394,6 +395,15 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
|
||||
else:
|
||||
return False
|
||||
|
||||
def draw_header(self, context):
|
||||
psys = context.particle_system
|
||||
if psys:
|
||||
part = psys.settings
|
||||
else:
|
||||
part = context.space_data.pin_id
|
||||
|
||||
self.layout.prop(part, "use_rotations", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
@@ -403,14 +413,9 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
|
||||
else:
|
||||
part = context.space_data.pin_id
|
||||
|
||||
layout.enabled = particle_panel_enabled(context, psys)
|
||||
layout.enabled = particle_panel_enabled(context, psys) and part.use_rotations
|
||||
|
||||
layout.prop(part, "use_dynamic_rotation")
|
||||
|
||||
if part.use_dynamic_rotation:
|
||||
layout.label(text="Initial Rotation Axis:")
|
||||
else:
|
||||
layout.label(text="Rotation Axis:")
|
||||
layout.label(text="Initial Orientation:")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
@@ -423,16 +428,17 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
|
||||
col.prop(part, "phase_factor_random", text="Random", slider=True)
|
||||
|
||||
if part.type != 'HAIR':
|
||||
col = layout.column()
|
||||
if part.use_dynamic_rotation:
|
||||
col.label(text="Initial Angular Velocity:")
|
||||
else:
|
||||
col.label(text="Angular Velocity:")
|
||||
sub = col.row(align=True)
|
||||
sub.prop(part, "angular_velocity_mode", text="")
|
||||
subsub = sub.column()
|
||||
subsub.active = part.angular_velocity_mode != 'NONE'
|
||||
subsub.prop(part, "angular_velocity_factor", text="")
|
||||
layout.label(text="Angular Velocity:")
|
||||
|
||||
split = layout.split()
|
||||
col = split.column(align=True)
|
||||
col.prop(part, "angular_velocity_mode", text="")
|
||||
sub = col.column()
|
||||
sub.active = part.angular_velocity_mode != 'NONE'
|
||||
sub.prop(part, "angular_velocity_factor", text="")
|
||||
|
||||
col = split.column()
|
||||
col.prop(part, "use_dynamic_rotation")
|
||||
|
||||
|
||||
class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
|
||||
|
||||
@@ -985,8 +985,7 @@ class CLIP_MT_select(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
props = layout.operator("clip.select_all", text="Select/Deselect all")
|
||||
props.action = 'TOGGLE'
|
||||
layout.operator("clip.select_all").action = 'TOGGLE'
|
||||
layout.operator("clip.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
layout.menu("CLIP_MT_select_grouped")
|
||||
|
||||
@@ -97,7 +97,7 @@ class IMAGE_MT_select(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("uv.select_all")
|
||||
layout.operator("uv.select_all").action = 'TOGGLE'
|
||||
layout.operator("uv.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("uv.unlink_selected")
|
||||
|
||||
|
||||
@@ -109,43 +109,43 @@ class INFO_MT_file(Menu):
|
||||
layout.operator("wm.read_homefile", text="New", icon='NEW')
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
|
||||
layout.menu("INFO_MT_file_open_recent")
|
||||
layout.menu("INFO_MT_file_open_recent", icon='OPEN_RECENT')
|
||||
layout.operator("wm.recover_last_session", icon='RECOVER_LAST')
|
||||
layout.operator("wm.recover_auto_save", text="Recover Auto Save...")
|
||||
layout.operator("wm.recover_auto_save", text="Recover Auto Save...", icon='RECOVER_AUTO')
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK').check_existing = False
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.operator("wm.save_as_mainfile", text="Save As...")
|
||||
layout.operator("wm.save_as_mainfile", text="Save As...", icon='SAVE_AS')
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.operator("wm.save_as_mainfile", text="Save Copy...").copy = True
|
||||
layout.operator("wm.save_as_mainfile", text="Save Copy...", icon='SAVE_COPY').copy = True
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES')
|
||||
|
||||
layout.operator_context = 'EXEC_AREA'
|
||||
layout.operator("wm.save_homefile")
|
||||
layout.operator("wm.read_factory_settings")
|
||||
layout.operator("wm.save_homefile", icon='SAVE_PREFS')
|
||||
layout.operator("wm.read_factory_settings", icon='LOAD_FACTORY')
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.operator("wm.link_append", text="Link")
|
||||
props = layout.operator("wm.link_append", text="Append")
|
||||
layout.operator("wm.link_append", text="Link", icon='LINK_BLEND')
|
||||
props = layout.operator("wm.link_append", text="Append", icon='APPEND_BLEND')
|
||||
props.link = False
|
||||
props.instance_groups = False
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu("INFO_MT_file_import")
|
||||
layout.menu("INFO_MT_file_export")
|
||||
layout.menu("INFO_MT_file_import", icon='IMPORT')
|
||||
layout.menu("INFO_MT_file_export", icon='EXPORT')
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu("INFO_MT_file_external_data")
|
||||
layout.menu("INFO_MT_file_external_data", icon='EXTERNAL_DATA')
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
||||
@@ -185,6 +185,12 @@ class SEQUENCER_MT_add(Menu):
|
||||
else:
|
||||
layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene...")
|
||||
|
||||
if len(bpy.data.movieclips) > 10:
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator("sequencer.movieclip_strip_add", text="Clips...")
|
||||
else:
|
||||
layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip...")
|
||||
|
||||
layout.operator("sequencer.movie_strip_add", text="Movie")
|
||||
layout.operator("sequencer.image_strip_add", text="Image")
|
||||
layout.operator("sequencer.sound_strip_add", text="Sound")
|
||||
@@ -236,6 +242,7 @@ class SEQUENCER_MT_strip(Menu):
|
||||
layout.operator("sequencer.offset_clear")
|
||||
layout.operator("sequencer.deinterlace_selected_movies")
|
||||
layout.operator("sequencer.rebuild_proxy")
|
||||
layout.operator("sequencer.update_strip_length")
|
||||
layout.separator()
|
||||
|
||||
layout.operator("sequencer.duplicate")
|
||||
@@ -534,7 +541,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
|
||||
if not strip:
|
||||
return False
|
||||
|
||||
return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META',
|
||||
return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'META',
|
||||
'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
|
||||
'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
|
||||
'PLUGIN',
|
||||
@@ -697,7 +704,7 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
|
||||
if not strip:
|
||||
return False
|
||||
|
||||
return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META',
|
||||
return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'META',
|
||||
'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
|
||||
'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
|
||||
'PLUGIN',
|
||||
@@ -713,6 +720,15 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
|
||||
col.label(text="Video:")
|
||||
col.prop(strip, "strobe")
|
||||
|
||||
if strip.type == 'MOVIECLIP':
|
||||
col = layout.column()
|
||||
col.label(text="Tracker:")
|
||||
col.prop(strip, "stabilize2d")
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Distortion:")
|
||||
col.prop(strip, "undistort")
|
||||
|
||||
row = layout.row()
|
||||
row.label(text="Flip:")
|
||||
row.prop(strip, "use_flip_x", text="X")
|
||||
|
||||
@@ -244,6 +244,9 @@ class USERPREF_PT_interface(Panel):
|
||||
|
||||
col.prop(view, "show_splash")
|
||||
|
||||
if os.name == 'nt':
|
||||
col.prop(view, "quit_dialog")
|
||||
|
||||
|
||||
class USERPREF_PT_edit(Panel):
|
||||
bl_space_type = 'USER_PREFERENCES'
|
||||
@@ -301,6 +304,11 @@ class USERPREF_PT_edit(Panel):
|
||||
col.separator()
|
||||
col.label(text="Playback:")
|
||||
col.prop(edit, "use_negative_frames")
|
||||
col.separator()
|
||||
col.separator()
|
||||
col.separator()
|
||||
col.label(text="Animation Editors:")
|
||||
col.prop(edit, "fcurve_unselected_alpha", text="F-Curve Visibility")
|
||||
|
||||
row.separator()
|
||||
row.separator()
|
||||
@@ -625,6 +633,14 @@ class USERPREF_PT_theme(Panel):
|
||||
col.label(text="Menu Back:")
|
||||
ui_items_general(col, ui)
|
||||
|
||||
ui = theme.user_interface.wcol_tooltip
|
||||
col.label(text="Tooltip:")
|
||||
ui_items_general(col, ui)
|
||||
|
||||
ui = theme.user_interface.wcol_tooltip
|
||||
col.label(text="Tooltip:")
|
||||
ui_items_general(col, ui)
|
||||
|
||||
ui = theme.user_interface.wcol_menu_item
|
||||
col.label(text="Menu Item:")
|
||||
ui_items_general(col, ui)
|
||||
|
||||
@@ -54,6 +54,8 @@ class VIEW3D_HT_header(Header):
|
||||
sub.menu("VIEW3D_MT_%s" % mode_string.lower())
|
||||
if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE'}:
|
||||
sub.menu("VIEW3D_MT_brush")
|
||||
if mode_string == 'SCULPT':
|
||||
sub.menu("VIEW3D_MT_hide")
|
||||
else:
|
||||
sub.menu("VIEW3D_MT_object")
|
||||
|
||||
@@ -88,10 +90,10 @@ class VIEW3D_HT_header(Header):
|
||||
row = layout.row(align=True)
|
||||
row.prop(toolsettings, "use_snap", text="")
|
||||
row.prop(toolsettings, "snap_element", text="", icon_only=True)
|
||||
if snap_element not in {'INCREMENT', 'VOLUME'}:
|
||||
if snap_element != 'INCREMENT':
|
||||
row.prop(toolsettings, "snap_target", text="")
|
||||
if obj:
|
||||
if obj.mode == 'OBJECT':
|
||||
if obj.mode == 'OBJECT' and snap_element != 'VOLUME':
|
||||
row.prop(toolsettings, "use_snap_align_rotation", text="")
|
||||
elif obj.mode == 'EDIT':
|
||||
row.prop(toolsettings, "use_snap_self", text="")
|
||||
@@ -425,7 +427,7 @@ class VIEW3D_MT_select_object(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("object.select_all").action = 'TOGGLE'
|
||||
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("object.select_random", text="Random")
|
||||
layout.operator("object.select_mirror", text="Mirror")
|
||||
@@ -450,7 +452,7 @@ class VIEW3D_MT_select_pose(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("pose.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("pose.select_all").action = 'TOGGLE'
|
||||
layout.operator("pose.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("pose.select_flip_active", text="Flip Active")
|
||||
layout.operator("pose.select_constraint_target", text="Constraint Target")
|
||||
@@ -487,9 +489,9 @@ class VIEW3D_MT_select_particle(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("particle.select_all").action = 'TOGGLE'
|
||||
layout.operator("particle.select_linked")
|
||||
layout.operator("particle.select_all").action = 'INVERT'
|
||||
layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -513,7 +515,7 @@ class VIEW3D_MT_select_edit_mesh(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("mesh.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("mesh.select_all").action = 'TOGGLE'
|
||||
layout.operator("mesh.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
layout.separator()
|
||||
@@ -564,7 +566,7 @@ class VIEW3D_MT_select_edit_curve(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("curve.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("curve.select_all").action = 'TOGGLE'
|
||||
layout.operator("curve.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("curve.select_random")
|
||||
layout.operator("curve.select_nth", text="Every Nth Number of Points")
|
||||
@@ -593,7 +595,7 @@ class VIEW3D_MT_select_edit_surface(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("curve.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("curve.select_all").action = 'TOGGLE'
|
||||
layout.operator("curve.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("curve.select_random")
|
||||
layout.operator("curve.select_nth", text="Every Nth Number of Points")
|
||||
@@ -619,7 +621,7 @@ class VIEW3D_MT_select_edit_metaball(Menu):
|
||||
layout.separator()
|
||||
|
||||
layout.operator("mball.select_all").action = 'TOGGLE'
|
||||
layout.operator("mball.select_all").action = 'INVERT'
|
||||
layout.operator("mball.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -636,7 +638,8 @@ class VIEW3D_MT_select_edit_lattice(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("lattice.select_all", text="Select/Deselect All")
|
||||
layout.operator("lattice.select_all").action = 'TOGGLE'
|
||||
layout.operator("lattice.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
|
||||
class VIEW3D_MT_select_edit_armature(Menu):
|
||||
@@ -649,7 +652,7 @@ class VIEW3D_MT_select_edit_armature(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("armature.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("armature.select_all").action = 'TOGGLE'
|
||||
layout.operator("armature.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
layout.separator()
|
||||
@@ -1046,6 +1049,19 @@ class VIEW3D_MT_brush(Menu):
|
||||
ups = context.tool_settings.unified_paint_settings
|
||||
layout.prop(ups, "use_unified_size", text="Unified Size")
|
||||
layout.prop(ups, "use_unified_strength", text="Unified Strength")
|
||||
layout.separator()
|
||||
|
||||
# brush paint modes
|
||||
layout.menu("VIEW3D_MT_brush_paint_modes")
|
||||
|
||||
# brush tool
|
||||
if context.sculpt_object:
|
||||
layout.operator("brush.reset")
|
||||
layout.prop_menu_enum(brush, "sculpt_tool")
|
||||
elif context.image_paint_object:
|
||||
layout.prop_menu_enum(brush, "image_tool")
|
||||
elif context.vertex_paint_object or context.weight_paint_object:
|
||||
layout.prop_menu_enum(brush, "vertex_tool")
|
||||
|
||||
# skip if no active brush
|
||||
if not brush:
|
||||
@@ -1072,6 +1088,21 @@ class VIEW3D_MT_brush(Menu):
|
||||
layout.prop(brush, "use_persistent")
|
||||
layout.operator("sculpt.set_persistent_base")
|
||||
|
||||
|
||||
class VIEW3D_MT_brush_paint_modes(Menu):
|
||||
bl_label = "Enabled Modes"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
settings = UnifiedPaintPanel.paint_settings(context)
|
||||
brush = settings.brush
|
||||
|
||||
layout.prop(brush, "use_paint_sculpt", text="Sculpt")
|
||||
layout.prop(brush, "use_paint_vertex", text="Vertex Paint")
|
||||
layout.prop(brush, "use_paint_weight", text="Weight Paint")
|
||||
layout.prop(brush, "use_paint_image", text="Texture Paint")
|
||||
|
||||
# ********** Vertex paint menu **********
|
||||
|
||||
|
||||
@@ -1195,6 +1226,25 @@ class VIEW3D_MT_sculpt(Menu):
|
||||
layout.prop(sculpt, "use_deform_only")
|
||||
|
||||
|
||||
class VIEW3D_MT_hide(Menu):
|
||||
bl_label = "Hide"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
op = layout.operator("paint.hide_show", text="Show All")
|
||||
op.action = 'SHOW'
|
||||
op.area = 'ALL'
|
||||
|
||||
op = layout.operator("paint.hide_show", text="Hide Bounding Box")
|
||||
op.action = 'HIDE'
|
||||
op.area = 'INSIDE'
|
||||
|
||||
op = layout.operator("paint.hide_show", text="Show Bounding Box")
|
||||
op.action = 'SHOW'
|
||||
op.area = 'INSIDE'
|
||||
|
||||
|
||||
# ********** Particle menu **********
|
||||
|
||||
|
||||
@@ -1519,7 +1569,8 @@ class VIEW3D_MT_edit_mesh(Menu):
|
||||
layout.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual")
|
||||
layout.operator("mesh.dissolve_limited")
|
||||
layout.operator("mesh.duplicate_move")
|
||||
layout.operator("mesh.delete", text="Delete...")
|
||||
layout.menu("VIEW3D_MT_edit_mesh_delete")
|
||||
layout.menu("VIEW3D_MT_edit_mesh_dissolve")
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -1556,7 +1607,7 @@ class VIEW3D_MT_edit_mesh_specials(Menu):
|
||||
layout.operator("mesh.dissolve_limited")
|
||||
layout.operator("mesh.hide", text="Hide")
|
||||
layout.operator("mesh.reveal", text="Reveal")
|
||||
layout.operator("mesh.select_all").action = 'INVERT'
|
||||
layout.operator("mesh.select_all", text="Select Inverse").action = 'INVERT'
|
||||
layout.operator("mesh.flip_normals")
|
||||
layout.operator("mesh.vertices_smooth", text="Smooth")
|
||||
layout.operator("mesh.bevel", text="Bevel")
|
||||
@@ -1687,7 +1738,8 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("mesh.bridge_edge_loops", text="Bridge Two Edge Loops")
|
||||
layout.operator("mesh.edge_split")
|
||||
layout.operator("mesh.bridge_edge_loops")
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -1713,11 +1765,11 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
||||
layout.operator("mesh.flip_normals")
|
||||
# layout.operator("mesh.bevel")
|
||||
# layout.operator("mesh.bevel")
|
||||
layout.operator("mesh.edge_face_add")
|
||||
layout.operator("mesh.fill")
|
||||
layout.operator("mesh.beautify_fill")
|
||||
layout.operator("mesh.inset")
|
||||
layout.operator("mesh.bevel")
|
||||
layout.operator("mesh.solidify")
|
||||
layout.operator("mesh.sort_faces")
|
||||
|
||||
@@ -1765,6 +1817,44 @@ class VIEW3D_MT_edit_mesh_normals(Menu):
|
||||
layout.operator("mesh.flip_normals")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_delete(Menu):
|
||||
bl_label = "Delete"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator_enum("mesh.delete", "type")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("mesh.edge_collapse")
|
||||
|
||||
layout.operator("mesh.delete_edgeloop")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_dissolve(Menu):
|
||||
bl_label = "Dissolve"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("mesh.dissolve")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator_enum("mesh.dissolve", "type")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("mesh.dissolve_limited")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu):
|
||||
_operator_name = "mesh"
|
||||
|
||||
|
||||
@@ -500,7 +500,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
# Sculpt Mode #
|
||||
|
||||
elif context.sculpt_object and brush:
|
||||
tool = brush.sculpt_tool
|
||||
capabilities = brush.sculpt_capabilities
|
||||
|
||||
col = layout.column()
|
||||
|
||||
@@ -519,47 +519,43 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
|
||||
self.prop_unified_size(row, context, brush, "use_pressure_size")
|
||||
|
||||
if tool not in {'SNAKE_HOOK', 'GRAB', 'ROTATE'}:
|
||||
# strength, use_strength_pressure, and use_strength_attenuation
|
||||
if capabilities.has_strength:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
|
||||
if brush.use_space and tool != 'SMOOTH':
|
||||
if brush.use_space_atten:
|
||||
row.prop(brush, "use_space_atten", toggle=True, text="", icon='LOCKED')
|
||||
if capabilities.has_space_attenuation:
|
||||
if brush.use_space_attenuation:
|
||||
row.prop(brush, "use_space_attenuation", toggle=True, text="", icon='LOCKED')
|
||||
else:
|
||||
row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED')
|
||||
row.prop(brush, "use_space_attenuation", toggle=True, text="", icon='UNLOCKED')
|
||||
|
||||
self.prop_unified_strength(row, context, brush, "strength", text="Strength")
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
if tool == 'ROTATE':
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_strength(row, context, brush, "strength", text="Strength")
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
if tool != 'SMOOTH':
|
||||
# auto_smooth_factor and use_inverse_smooth_pressure
|
||||
if capabilities.has_auto_smooth:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "auto_smooth_factor", slider=True)
|
||||
row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="")
|
||||
|
||||
if tool in {'GRAB', 'SNAKE_HOOK'}:
|
||||
# normal_weight
|
||||
if capabilities.has_normal_weight:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "normal_weight", slider=True)
|
||||
|
||||
if tool in {'CREASE', 'BLOB'}:
|
||||
# crease_pinch_factor
|
||||
if capabilities.has_pinch_factor:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
|
||||
|
||||
if tool not in {'PINCH', 'INFLATE', 'SMOOTH'}:
|
||||
# use_original_normal and sculpt_plane
|
||||
if capabilities.has_sculpt_plane:
|
||||
row = col.row(align=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
if brush.use_original_normal:
|
||||
@@ -569,8 +565,8 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
|
||||
row.prop(brush, "sculpt_plane", text="")
|
||||
|
||||
#if tool in {'CLAY', 'CLAY_TUBES', 'FLATTEN', 'FILL', 'SCRAPE'}:
|
||||
if tool in {'CLAY', 'FLATTEN', 'FILL', 'SCRAPE'}:
|
||||
# plane_offset, use_offset_pressure, use_plane_trim, plane_trim
|
||||
if capabilities.has_plane_offset:
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "plane_offset", slider=True)
|
||||
row.prop(brush, "use_offset_pressure", text="")
|
||||
@@ -583,24 +579,28 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
row.active = brush.use_plane_trim
|
||||
row.prop(brush, "plane_trim", slider=True, text="Distance")
|
||||
|
||||
if tool == 'LAYER':
|
||||
# height
|
||||
if capabilities.has_height:
|
||||
row = col.row()
|
||||
row.prop(brush, "height", slider=True, text="Height")
|
||||
|
||||
# use_frontface
|
||||
col.separator()
|
||||
|
||||
row = col.row()
|
||||
row.prop(brush, "use_frontface", text="Front Faces Only")
|
||||
|
||||
# direction
|
||||
col.separator()
|
||||
col.row().prop(brush, "direction", expand=True)
|
||||
|
||||
if tool in {'DRAW', 'CREASE', 'BLOB', 'INFLATE', 'LAYER', 'CLAY'}:
|
||||
# use_accumulate
|
||||
if capabilities.has_accumulate:
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_accumulate")
|
||||
|
||||
if tool == 'LAYER':
|
||||
# use_persistent, set_persistent_base
|
||||
if capabilities.has_persistence:
|
||||
col.separator()
|
||||
|
||||
ob = context.sculpt_object
|
||||
@@ -714,7 +714,7 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
|
||||
col = layout.column()
|
||||
col.active = tex_slot.map_mode in {'FIXED'}
|
||||
col.label(text="Angle:")
|
||||
if not brush.use_anchor and brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'} and tex_slot.map_mode in {'FIXED'}:
|
||||
if brush.sculpt_capabilities.has_random_texture_angle:
|
||||
col.prop(brush, "texture_angle_source_random", text="")
|
||||
else:
|
||||
col.prop(brush, "texture_angle_source_no_random", text="")
|
||||
@@ -733,10 +733,6 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
|
||||
col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
|
||||
col.prop(tex_slot, "angle", text="")
|
||||
|
||||
#col = layout.column()
|
||||
#col.prop(brush, "use_random_rotation")
|
||||
#col.active = (not brush.use_rake) and (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'}) and tex_slot.map_mode in {'FIXED'}
|
||||
|
||||
split = layout.split()
|
||||
split.prop(tex_slot, "offset")
|
||||
split.prop(tex_slot, "scale")
|
||||
@@ -759,40 +755,6 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
|
||||
sub.prop(brush, "texture_overlay_alpha", text="Alpha")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_tool(Panel, View3DPaintPanel):
|
||||
bl_label = "Tool"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
settings = cls.paint_settings(context)
|
||||
return (settings and settings.brush and
|
||||
(context.sculpt_object or context.image_paint_object or
|
||||
context.vertex_paint_object or context.weight_paint_object))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
settings = self.paint_settings(context)
|
||||
brush = settings.brush
|
||||
|
||||
col = layout.column(align=True)
|
||||
|
||||
if context.sculpt_object:
|
||||
col.prop(brush, "sculpt_tool", expand=False, text="")
|
||||
col.operator("brush.reset")
|
||||
elif context.image_paint_object:
|
||||
col.prop(brush, "image_tool", expand=False, text="")
|
||||
elif context.vertex_paint_object or context.weight_paint_object:
|
||||
col.prop(brush, "vertex_tool", expand=False, text="")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(brush, "use_paint_sculpt", text="", icon='SCULPTMODE_HLT')
|
||||
row.prop(brush, "use_paint_vertex", text="", icon='VPAINT_HLT')
|
||||
row.prop(brush, "use_paint_weight", text="", icon='WPAINT_HLT')
|
||||
row.prop(brush, "use_paint_image", text="", icon='TPAINT_HLT')
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
bl_label = "Stroke"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -832,7 +794,7 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
|
||||
if (brush.sculpt_tool not in {'GRAB', 'THUMB', 'SNAKE_HOOK', 'ROTATE'}) and (not brush.use_anchor) and (not brush.use_restore_mesh):
|
||||
if brush.sculpt_capabilities.has_smooth_stroke:
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
@@ -843,6 +805,7 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
if brush.sculpt_capabilities.has_jitter:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
@@ -869,21 +832,13 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.active = (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'THUMB', 'ROTATE', 'SNAKE_HOOK'})
|
||||
col.active = brush.sculpt_capabilities.has_spacing
|
||||
col.prop(brush, "use_space")
|
||||
|
||||
row = col.row()
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
|
||||
#col.prop(brush, "use_space_atten", text="Adaptive Strength")
|
||||
#col.prop(brush, "use_adaptive_space", text="Adaptive Spacing")
|
||||
|
||||
#col.separator()
|
||||
|
||||
#if image_paint:
|
||||
# row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
|
||||
bl_label = "Curve"
|
||||
@@ -989,8 +944,7 @@ class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
|
||||
col = layout.column()
|
||||
|
||||
if context.sculpt_object and context.tool_settings.sculpt:
|
||||
#if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE', 'CLAY_TUBES'}:
|
||||
if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE'}:
|
||||
if brush.sculpt_capabilities.has_secondary_color:
|
||||
col.prop(brush, "cursor_color_add", text="Add Color")
|
||||
col.prop(brush, "cursor_color_subtract", text="Subtract Color")
|
||||
else:
|
||||
|
||||
21
release/scripts/templates/bmesh_simple.py
Normal file
21
release/scripts/templates/bmesh_simple.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# This example assumes we have a mesh object selected
|
||||
|
||||
import bpy
|
||||
import bmesh
|
||||
|
||||
# Get the active mesh
|
||||
me = bpy.context.object.data
|
||||
|
||||
|
||||
# Get a BMesh representation
|
||||
bm = bmesh.new() # create an empty BMesh
|
||||
bm.from_mesh(me) # fill it in from a Mesh
|
||||
|
||||
|
||||
# Modify the BMesh, can do anything here...
|
||||
for v in bm.verts:
|
||||
v.co.x += 1.0
|
||||
|
||||
|
||||
# Finish up, write the bmesh back to the mesh
|
||||
bm.to_mesh(me)
|
||||
@@ -2,6 +2,7 @@ import bpy
|
||||
|
||||
|
||||
class HelloWorldPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the Object properties window"""
|
||||
bl_label = "Hello World Panel"
|
||||
bl_idname = "OBJECT_PT_hello"
|
||||
bl_space_type = "PROPERTIES"
|
||||
|
||||
Reference in New Issue
Block a user