Merge branch 'master' into blender2.8

This commit is contained in:
Campbell Barton 2018-06-26 22:56:39 +02:00
commit a61480c271
68 changed files with 1554 additions and 1454 deletions

View File

@ -15,6 +15,7 @@ font_info = {
"handler": None,
}
def init():
"""init function - runs once"""
import os

View File

@ -10,22 +10,22 @@ bm = bmesh.new()
# Add a circle XXX, should return all geometry created, not just verts.
bmesh.ops.create_circle(
bm,
cap_ends=False,
radius=0.2,
segments=8)
bm,
cap_ends=False,
radius=0.2,
segments=8)
# Spin and deal with geometry on side 'a'
edges_start_a = bm.edges[:]
geom_start_a = bm.verts[:] + edges_start_a
ret = bmesh.ops.spin(
bm,
geom=geom_start_a,
angle=math.radians(180.0),
steps=8,
axis=(1.0, 0.0, 0.0),
cent=(0.0, 1.0, 0.0))
bm,
geom=geom_start_a,
angle=math.radians(180.0),
steps=8,
axis=(1.0, 0.0, 0.0),
cent=(0.0, 1.0, 0.0))
edges_end_a = [ele for ele in ret["geom_last"]
if isinstance(ele, bmesh.types.BMEdge)]
del ret
@ -33,8 +33,8 @@ del ret
# Extrude and create geometry on side 'b'
ret = bmesh.ops.extrude_edge_only(
bm,
edges=edges_start_a)
bm,
edges=edges_start_a)
geom_extrude_mid = ret["geom"]
del ret
@ -45,19 +45,19 @@ verts_extrude_b = [ele for ele in geom_extrude_mid
edges_extrude_b = [ele for ele in geom_extrude_mid
if isinstance(ele, bmesh.types.BMEdge) and ele.is_boundary]
bmesh.ops.translate(
bm,
verts=verts_extrude_b,
vec=(0.0, 0.0, 1.0))
bm,
verts=verts_extrude_b,
vec=(0.0, 0.0, 1.0))
# Create the circle on side 'b'
ret = bmesh.ops.spin(
bm,
geom=verts_extrude_b + edges_extrude_b,
angle=-math.radians(180.0),
steps=8,
axis=(1.0, 0.0, 0.0),
cent=(0.0, 1.0, 1.0))
bm,
geom=verts_extrude_b + edges_extrude_b,
angle=-math.radians(180.0),
steps=8,
axis=(1.0, 0.0, 0.0),
cent=(0.0, 1.0, 1.0))
edges_end_b = [ele for ele in ret["geom_last"]
if isinstance(ele, bmesh.types.BMEdge)]
del ret
@ -65,30 +65,30 @@ del ret
# Bridge the resulting edge loops of both spins 'a & b'
bmesh.ops.bridge_loops(
bm,
edges=edges_end_a + edges_end_b)
bm,
edges=edges_end_a + edges_end_b)
# Now we have made a links of the chain, make a copy and rotate it
# (so this looks something like a chain)
ret = bmesh.ops.duplicate(
bm,
geom=bm.verts[:] + bm.edges[:] + bm.faces[:])
bm,
geom=bm.verts[:] + bm.edges[:] + bm.faces[:])
geom_dupe = ret["geom"]
verts_dupe = [ele for ele in geom_dupe if isinstance(ele, bmesh.types.BMVert)]
del ret
# position the new link
bmesh.ops.translate(
bm,
verts=verts_dupe,
vec=(0.0, 0.0, 2.0))
bm,
verts=verts_dupe,
vec=(0.0, 0.0, 2.0))
bmesh.ops.rotate(
bm,
verts=verts_dupe,
cent=(0.0, 1.0, 0.0),
matrix=mathutils.Matrix.Rotation(math.radians(90.0), 3, 'Z'))
bm,
verts=verts_dupe,
cent=(0.0, 1.0, 0.0),
matrix=mathutils.Matrix.Rotation(math.radians(90.0), 3, 'Z'))
# Done with creating the mesh, simply link it into the scene so we can see it

View File

@ -17,4 +17,5 @@ from bpy.app.handlers import persistent
def load_handler(dummy):
print("Load Handler:", bpy.data.filepath)
bpy.app.handlers.load_post.append(load_handler)

View File

@ -11,4 +11,5 @@ import bpy
def my_handler(scene):
print("Frame Change", scene.frame_current)
bpy.app.handlers.frame_change_pre.append(my_handler)

View File

@ -54,19 +54,19 @@ translations_tuple = (
"Copyright (C) 2013 The Blender Foundation.",
"This file is distributed under the same license as the Blender package.",
"FIRST AUTHOR <EMAIL@ADDRESS>, YEAR."))),
),
),
(("Operator", "Render: Copy Settings"),
(("bpy.types.SCENE_OT_render_copy_settings",),
()),
("fr_FR", "Rendu : copier réglages",
(False, ())),
),
),
(("*", "Copy render settings from current scene to others"),
(("bpy.types.SCENE_OT_render_copy_settings",),
()),
("fr_FR", "Copier les réglages de rendu depuis la scène courante vers dautres",
(False, ())),
),
),
# ... etc, all messages from your addon.
)
@ -81,6 +81,7 @@ for msg in translations_tuple:
# Define remaining addon (operators, UI...) here.
def register():
# Usual operator/UI/etc. registration...

View File

@ -14,6 +14,7 @@ class MaterialSettings(bpy.types.PropertyGroup):
my_float = bpy.props.FloatProperty()
my_string = bpy.props.StringProperty()
bpy.utils.register_class(MaterialSettings)
bpy.types.Material.my_settings = \

View File

@ -14,6 +14,7 @@ class SceneSettingItem(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(name="Test Prop", default="Unknown")
value = bpy.props.IntProperty(name="Test Prop", default=22)
bpy.utils.register_class(SceneSettingItem)
bpy.types.Scene.my_settings = \

View File

@ -14,6 +14,7 @@ import bpy
def update_func(self, context):
print("my test function", self)
bpy.types.Scene.testprop = bpy.props.FloatProperty(update=update_func)
bpy.context.scene.testprop = 11.0

View File

@ -19,6 +19,7 @@ def get_float(self):
def set_float(self, value):
self["testprop"] = value
bpy.types.Scene.test_float = bpy.props.FloatProperty(get=get_float, set=set_float)
@ -27,6 +28,7 @@ def get_date(self):
import datetime
return str(datetime.datetime.now())
bpy.types.Scene.test_date = bpy.props.StringProperty(get=get_date)
@ -40,6 +42,7 @@ def get_array(self):
def set_array(self, values):
self["somebool"] = values[0] and values[1]
bpy.types.Scene.test_array = bpy.props.BoolVectorProperty(size=2, get=get_array, set=set_array)
@ -50,7 +53,7 @@ test_items = [
("GREEN", "Green", "", 2),
("BLUE", "Blue", "", 3),
("YELLOW", "Yellow", "", 4),
]
]
def get_enum(self):
@ -61,6 +64,7 @@ def get_enum(self):
def set_enum(self, value):
print("setting value", value)
bpy.types.Scene.test_enum = bpy.props.EnumProperty(items=test_items, get=get_enum, set=set_enum)

View File

@ -9,7 +9,7 @@ bl_info = {
"wiki_url": "",
"tracker_url": "",
"category": "Object",
}
}
import bpy
@ -23,17 +23,17 @@ class ExampleAddonPreferences(AddonPreferences):
bl_idname = __name__
filepath = StringProperty(
name="Example File Path",
subtype='FILE_PATH',
)
name="Example File Path",
subtype='FILE_PATH',
)
number = IntProperty(
name="Example Number",
default=4,
)
name="Example Number",
default=4,
)
boolean = BoolProperty(
name="Example Boolean",
default=False,
)
name="Example Boolean",
default=False,
)
def draw(self, context):
layout = self.layout

View File

@ -14,4 +14,5 @@ import bpy
def menu_draw(self, context):
self.layout.operator("wm.save_homefile")
bpy.types.INFO_MT_file.append(menu_draw)

View File

@ -32,7 +32,7 @@ class AddPresetObjectDraw(AddPresetBase, Operator):
# variable used for all preset values
preset_defines = [
"obj = bpy.context.object"
]
]
# properties to store in the preset
preset_values = [
@ -42,7 +42,7 @@ class AddPresetObjectDraw(AddPresetBase, Operator):
"obj.show_name",
"obj.show_axis",
"obj.show_wire",
]
]
# where to store the preset
preset_subdir = "object/draw"
@ -61,7 +61,7 @@ def panel_func(self, context):
classes = (
OBJECT_MT_draw_presets,
AddPresetObjectDraw,
)
)
def register():

View File

@ -60,6 +60,7 @@ def menu_func(self, context):
layout.separator()
layout.operator(WM_OT_button_context_test.bl_idname)
classes = (
WM_OT_button_context_test,
WM_MT_button_context,
@ -77,5 +78,6 @@ def unregister():
bpy.utils.unregister_class(cls)
bpy.types.WM_MT_button_context.remove(menu_func)
if __name__ == "__main__":
register()

View File

@ -21,4 +21,5 @@ class CyclesNodeTree(bpy.types.NodeTree):
def poll(cls, context):
return context.scene.render.engine == 'CYCLES'
bpy.utils.register_class(CyclesNodeTree)

View File

@ -42,6 +42,7 @@ class SimpleMouseOperator(bpy.types.Operator):
self.y = event.mouse_y
return self.execute(context)
bpy.utils.register_class(SimpleMouseOperator)
# Test call to the newly defined operator.

View File

@ -42,6 +42,7 @@ def menu_func(self, context):
self.layout.operator_context = 'INVOKE_DEFAULT'
self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")
# Register and add to the file selector
bpy.utils.register_class(ExportSomeData)
bpy.types.INFO_MT_file_export.append(menu_func)

View File

@ -41,6 +41,7 @@ class CustomDrawOperator(bpy.types.Operator):
col.prop(self, "my_string")
bpy.utils.register_class(CustomDrawOperator)
# test call

View File

@ -22,6 +22,7 @@ class HelloWorldOperator(bpy.types.Operator):
print("Hello World")
return {'FINISHED'}
bpy.utils.register_class(HelloWorldOperator)
# test call to the newly defined operator

View File

@ -31,6 +31,7 @@ class MyPropertyGroup(bpy.types.PropertyGroup):
custom_1 = bpy.props.FloatProperty(name="My Float")
custom_2 = bpy.props.IntProperty(name="My Int")
bpy.utils.register_class(MyPropertyGroup)
bpy.types.Object.my_prop_grp = bpy.props.PointerProperty(type=MyPropertyGroup)

View File

@ -10,4 +10,5 @@ import bpy
def draw(self, context):
self.layout.label("Hello World")
bpy.context.window_manager.popup_menu(draw, title="Greeting", icon='INFO')

View File

@ -12,6 +12,7 @@ from bpy.props import PointerProperty
class MyPropGroup(bpy.types.PropertyGroup):
nested = bpy.props.FloatProperty(name="Nested", default=0.0)
# register it so its available for all bones
bpy.utils.register_class(MyPropGroup)
bpy.types.Bone.my_prop = PointerProperty(type=MyPropGroup,

View File

@ -23,9 +23,9 @@ class OffScreenDraw(bpy.types.Operator):
@staticmethod
def handle_add(self, context):
OffScreenDraw._handle_draw = bpy.types.SpaceView3D.draw_handler_add(
self.draw_callback_px, (self, context),
'WINDOW', 'POST_PIXEL',
)
self.draw_callback_px, (self, context),
'WINDOW', 'POST_PIXEL',
)
@staticmethod
def handle_remove():
@ -58,20 +58,20 @@ class OffScreenDraw(bpy.types.Operator):
modelview_matrix = camera.matrix_world.inverted()
projection_matrix = camera.calc_matrix_camera(
render.resolution_x,
render.resolution_y,
render.pixel_aspect_x,
render.pixel_aspect_y,
)
render.resolution_x,
render.resolution_y,
render.pixel_aspect_x,
render.pixel_aspect_y,
)
offscreen.draw_view3d(
scene,
render_layer,
context.space_data,
context.region,
projection_matrix,
modelview_matrix,
)
scene,
render_layer,
context.space_data,
context.region,
projection_matrix,
modelview_matrix,
)
@staticmethod
def _opengl_draw(context, texture, aspect_ratio, scale):

View File

@ -48,7 +48,7 @@ _modules = [
"vertexpaint_dirt",
"view3d",
"wm",
]
]
import bpy

View File

@ -135,63 +135,63 @@ class AddTorus(Operator, object_utils.AddObjectHelper):
self.abso_minor_rad = self.major_radius - self.minor_radius
major_segments = IntProperty(
name="Major Segments",
description="Number of segments for the main ring of the torus",
min=3, max=256,
default=48,
)
name="Major Segments",
description="Number of segments for the main ring of the torus",
min=3, max=256,
default=48,
)
minor_segments = IntProperty(
name="Minor Segments",
description="Number of segments for the minor ring of the torus",
min=3, max=256,
default=12,
)
name="Minor Segments",
description="Number of segments for the minor ring of the torus",
min=3, max=256,
default=12,
)
mode = bpy.props.EnumProperty(
name="Torus Dimensions",
items=(("MAJOR_MINOR", "Major/Minor",
"Use the major/minor radii for torus dimensions"),
("EXT_INT", "Exterior/Interior",
"Use the exterior/interior radii for torus dimensions")),
update=mode_update_callback,
)
name="Torus Dimensions",
items=(("MAJOR_MINOR", "Major/Minor",
"Use the major/minor radii for torus dimensions"),
("EXT_INT", "Exterior/Interior",
"Use the exterior/interior radii for torus dimensions")),
update=mode_update_callback,
)
major_radius = FloatProperty(
name="Major Radius",
description=("Radius from the origin to the "
"center of the cross sections"),
min=0.01, max=100.0,
default=1.0,
subtype='DISTANCE',
unit='LENGTH',
)
name="Major Radius",
description=("Radius from the origin to the "
"center of the cross sections"),
min=0.01, max=100.0,
default=1.0,
subtype='DISTANCE',
unit='LENGTH',
)
minor_radius = FloatProperty(
name="Minor Radius",
description="Radius of the torus' cross section",
min=0.01, max=100.0,
default=0.25,
subtype='DISTANCE',
unit='LENGTH',
)
name="Minor Radius",
description="Radius of the torus' cross section",
min=0.01, max=100.0,
default=0.25,
subtype='DISTANCE',
unit='LENGTH',
)
abso_major_rad = FloatProperty(
name="Exterior Radius",
description="Total Exterior Radius of the torus",
min=0.01, max=100.0,
default=1.25,
subtype='DISTANCE',
unit='LENGTH',
)
name="Exterior Radius",
description="Total Exterior Radius of the torus",
min=0.01, max=100.0,
default=1.25,
subtype='DISTANCE',
unit='LENGTH',
)
abso_minor_rad = FloatProperty(
name="Interior Radius",
description="Total Interior Radius of the torus",
min=0.01, max=100.0,
default=0.75,
subtype='DISTANCE',
unit='LENGTH',
)
name="Interior Radius",
description="Total Interior Radius of the torus",
min=0.01, max=100.0,
default=0.75,
subtype='DISTANCE',
unit='LENGTH',
)
generate_uvs = BoolProperty(
name="Generate UVs",
description="Generate a default UV map",
default=False,
)
name="Generate UVs",
description="Generate a default UV map",
default=False,
)
def draw(self, context):
layout = self.layout

View File

@ -41,23 +41,23 @@ class ANIM_OT_keying_set_export(Operator):
bl_label = "Export Keying Set..."
filepath = StringProperty(
subtype='FILE_PATH',
)
subtype='FILE_PATH',
)
filter_folder = BoolProperty(
name="Filter folders",
default=True,
options={'HIDDEN'},
)
name="Filter folders",
default=True,
options={'HIDDEN'},
)
filter_text = BoolProperty(
name="Filter text",
default=True,
options={'HIDDEN'},
)
name="Filter text",
default=True,
options={'HIDDEN'},
)
filter_python = BoolProperty(
name="Filter python",
default=True,
options={'HIDDEN'},
)
name="Filter python",
default=True,
options={'HIDDEN'},
)
def execute(self, context):
if not self.filepath:
@ -204,58 +204,59 @@ class BakeAction(Operator):
bl_options = {'REGISTER', 'UNDO'}
frame_start = IntProperty(
name="Start Frame",
description="Start frame for baking",
min=0, max=300000,
default=1,
)
name="Start Frame",
description="Start frame for baking",
min=0, max=300000,
default=1,
)
frame_end = IntProperty(
name="End Frame",
description="End frame for baking",
min=1, max=300000,
default=250,
)
name="End Frame",
description="End frame for baking",
min=1, max=300000,
default=250,
)
step = IntProperty(
name="Frame Step",
description="Frame Step",
min=1, max=120,
default=1,
)
name="Frame Step",
description="Frame Step",
min=1, max=120,
default=1,
)
only_selected = BoolProperty(
name="Only Selected Bones",
description="Only key selected bones (Pose baking only)",
default=True,
)
name="Only Selected Bones",
description="Only key selected bones (Pose baking only)",
default=True,
)
visual_keying = BoolProperty(
name="Visual Keying",
description="Keyframe from the final transformations (with constraints applied)",
default=False,
)
name="Visual Keying",
description="Keyframe from the final transformations (with constraints applied)",
default=False,
)
clear_constraints = BoolProperty(
name="Clear Constraints",
description="Remove all constraints from keyed object/bones, and do 'visual' keying",
default=False,
)
name="Clear Constraints",
description="Remove all constraints from keyed object/bones, and do 'visual' keying",
default=False,
)
clear_parents = BoolProperty(
name="Clear Parents",
description="Bake animation onto the object then clear parents (objects only)",
default=False,
)
name="Clear Parents",
description="Bake animation onto the object then clear parents (objects only)",
default=False,
)
use_current_action = BoolProperty(
name="Overwrite Current Action",
description="Bake animation into current action, instead of creating a new one "
"(useful for baking only part of bones in an armature)",
default=False,
)
name="Overwrite Current Action",
description="Bake animation into current action, instead of creating a new one "
"(useful for baking only part of bones in an armature)",
default=False,
)
bake_types = EnumProperty(
name="Bake Data",
description="Which data's transformations to bake",
options={'ENUM_FLAG'},
items=(('POSE', "Pose", "Bake bones transformations"),
('OBJECT', "Object", "Bake object transformations"),
),
default={'POSE'},
)
name="Bake Data",
description="Which data's transformations to bake",
options={'ENUM_FLAG'},
items=(
('POSE', "Pose", "Bake bones transformations"),
('OBJECT', "Object", "Bake object transformations"),
),
default={'POSE'},
)
def execute(self, context):
from bpy_extras import anim_utils
@ -296,16 +297,16 @@ class BakeAction(Operator):
class ClearUselessActions(Operator):
"""Mark actions with no F-Curves for deletion after save & reload of """ \
"""file preserving \"action libraries\""""
"""file preserving \"action libraries\""""
bl_idname = "anim.clear_useless_actions"
bl_label = "Clear Useless Actions"
bl_options = {'REGISTER', 'UNDO'}
only_unused = BoolProperty(
name="Only Unused",
description="Only unused (Fake User only) actions get considered",
default=True,
)
name="Only Unused",
description="Only unused (Fake User only) actions get considered",
default=True,
)
@classmethod
def poll(cls, context):
@ -316,8 +317,10 @@ class ClearUselessActions(Operator):
for action in bpy.data.actions:
# if only user is "fake" user...
if ((self.only_unused is False) or
(action.use_fake_user and action.users == 1)):
if (
(self.only_unused is False) or
(action.use_fake_user and action.users == 1)
):
# if it has F-Curves, then it's a "action library"
# (i.e. walk, wave, jump, etc.)
@ -339,10 +342,10 @@ class UpdateAnimatedTransformConstraint(Operator):
bl_options = {'REGISTER', 'UNDO'}
use_convert_to_radians = BoolProperty(
name="Convert To Radians",
description="Convert fcurves/drivers affecting rotations to radians (Warning: use this only once!)",
default=True,
)
name="Convert To Radians",
description="Convert fcurves/drivers affecting rotations to radians (Warning: use this only once!)",
default=True,
)
def execute(self, context):
import animsys_refactor

View File

@ -134,10 +134,10 @@ class CLIP_OT_filter_tracks(bpy.types.Operator):
bl_options = {'UNDO', 'REGISTER'}
track_threshold = FloatProperty(
name="Track Threshold",
description="Filter Threshold to select problematic tracks",
default=5.0,
)
name="Track Threshold",
description="Filter Threshold to select problematic tracks",
default=5.0,
)
@staticmethod
def _filter_values(context, threshold):
@ -165,9 +165,10 @@ class CLIP_OT_filter_tracks(bpy.types.Operator):
# Find tracks with markers in both this frame and the previous one.
relevant_tracks = [
track for track in clip.tracking.tracks
if (track.markers.find_frame(frame) and
track.markers.find_frame(frame - 1))]
track for track in clip.tracking.tracks
if (track.markers.find_frame(frame) and
track.markers.find_frame(frame - 1))
]
if not relevant_tracks:
continue
@ -399,7 +400,7 @@ class CLIP_OT_delete_proxy(Operator):
class CLIP_OT_set_viewport_background(Operator):
"""Set current movie clip as a camera background in 3D view-port """ \
"""(works only when a 3D view-port is visible)"""
"""(works only when a 3D view-port is visible)"""
bl_idname = "clip.set_viewport_background"
bl_label = "Set as Background"
@ -1047,13 +1048,13 @@ class CLIP_OT_track_settings_to_track(bpy.types.Operator):
"use_green_channel",
"use_blue_channel",
"weight"
)
)
_attrs_marker = (
"pattern_corners",
"search_min",
"search_max",
)
)
@classmethod
def poll(cls, context):

View File

@ -38,8 +38,8 @@ class ConsoleExec(Operator):
bl_label = "Console Execute"
interactive = BoolProperty(
options={'SKIP_SAVE'},
)
options={'SKIP_SAVE'},
)
@classmethod
def poll(cls, context):
@ -61,7 +61,7 @@ class ConsoleExec(Operator):
class ConsoleAutocomplete(Operator):
"""Evaluate the namespace up until the cursor and give a list of """ \
"""options or complete the name if there is only one"""
"""options or complete the name if there is only one"""
bl_idname = "console.autocomplete"
bl_label = "Console Autocomplete"
@ -138,9 +138,9 @@ class ConsoleLanguage(Operator):
bl_label = "Console Language"
language = StringProperty(
name="Language",
maxlen=32,
)
name="Language",
maxlen=32,
)
@classmethod
def poll(cls, context):

View File

@ -38,59 +38,59 @@ class WM_OT_previews_batch_generate(Operator):
# -----------
# File props.
files = CollectionProperty(
type=bpy.types.OperatorFileListElement,
options={'HIDDEN', 'SKIP_SAVE'},
)
type=bpy.types.OperatorFileListElement,
options={'HIDDEN', 'SKIP_SAVE'},
)
directory = StringProperty(
maxlen=1024,
subtype='FILE_PATH',
options={'HIDDEN', 'SKIP_SAVE'},
)
maxlen=1024,
subtype='FILE_PATH',
options={'HIDDEN', 'SKIP_SAVE'},
)
# Show only images/videos, and directories!
filter_blender = BoolProperty(
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
filter_folder = BoolProperty(
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
# -----------
# Own props.
use_scenes = BoolProperty(
default=True,
name="Scenes",
description="Generate scenes' previews",
)
default=True,
name="Scenes",
description="Generate scenes' previews",
)
use_collections = BoolProperty(
default=True,
name="Collections",
description="Generate collections' previews",
)
default=True,
name="Collections",
description="Generate collections' previews",
)
use_objects = BoolProperty(
default=True,
name="Objects",
description="Generate objects' previews",
)
default=True,
name="Objects",
description="Generate objects' previews",
)
use_intern_data = BoolProperty(
default=True,
name="Mat/Tex/...",
description="Generate 'internal' previews (materials, textures, images, etc.)",
)
default=True,
name="Mat/Tex/...",
description="Generate 'internal' previews (materials, textures, images, etc.)",
)
use_trusted = BoolProperty(
default=False,
name="Trusted Blend Files",
description="Enable python evaluation for selected files",
)
default=False,
name="Trusted Blend Files",
description="Enable python evaluation for selected files",
)
use_backups = BoolProperty(
default=True,
name="Save Backups",
description="Keep a backup (.blend1) version of the files when saving with generated previews",
)
default=True,
name="Save Backups",
description="Keep a backup (.blend1) version of the files when saving with generated previews",
)
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
@ -148,58 +148,59 @@ class WM_OT_previews_batch_clear(Operator):
# -----------
# File props.
files = CollectionProperty(
type=bpy.types.OperatorFileListElement,
options={'HIDDEN', 'SKIP_SAVE'},
)
type=bpy.types.OperatorFileListElement,
options={'HIDDEN', 'SKIP_SAVE'},
)
directory = StringProperty(
maxlen=1024,
subtype='FILE_PATH',
options={'HIDDEN', 'SKIP_SAVE'},
)
maxlen=1024,
subtype='FILE_PATH',
options={'HIDDEN', 'SKIP_SAVE'},
)
# Show only images/videos, and directories!
filter_blender = BoolProperty(
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
filter_folder = BoolProperty(
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
default=True,
options={'HIDDEN', 'SKIP_SAVE'},
)
# -----------
# Own props.
use_scenes = BoolProperty(
default=True,
name="Scenes",
description="Clear scenes' previews",
)
use_collections = BoolProperty(default=True,
name="Collections",
description="Clear collections' previews",
)
default=True,
name="Scenes",
description="Clear scenes' previews",
)
use_collections = BoolProperty(
default=True,
name="Collections",
description="Clear collections' previews",
)
use_objects = BoolProperty(
default=True,
name="Objects",
description="Clear objects' previews",
)
default=True,
name="Objects",
description="Clear objects' previews",
)
use_intern_data = BoolProperty(
default=True,
name="Mat/Tex/...",
description="Clear 'internal' previews (materials, textures, images, etc.)",
)
default=True,
name="Mat/Tex/...",
description="Clear 'internal' previews (materials, textures, images, etc.)",
)
use_trusted = BoolProperty(
default=False,
name="Trusted Blend Files",
description="Enable python evaluation for selected files",
)
default=False,
name="Trusted Blend Files",
description="Enable python evaluation for selected files",
)
use_backups = BoolProperty(
default=True,
name="Save Backups",
description="Keep a backup (.blend1) version of the files when saving with cleared previews",
)
default=True,
name="Save Backups",
description="Keep a backup (.blend1) version of the files when saving with cleared previews",
)
def invoke(self, context, event):
context.window_manager.fileselect_add(self)

View File

@ -35,15 +35,15 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
bl_options = {'INTERNAL'}
type = EnumProperty(
name="Type", description="Type of the modifier to work on",
items=(("COLOR", "Color", "Color modifier type"),
("ALPHA", "Alpha", "Alpha modifier type"),
("THICKNESS", "Thickness", "Thickness modifier type")),
)
name="Type", description="Type of the modifier to work on",
items=(("COLOR", "Color", "Color modifier type"),
("ALPHA", "Alpha", "Alpha modifier type"),
("THICKNESS", "Thickness", "Thickness modifier type")),
)
name = StringProperty(
name="Name",
description="Name of the modifier to work on",
)
name="Name",
description="Name of the modifier to work on",
)
@classmethod
def poll(cls, context):

View File

@ -30,8 +30,8 @@ class EditExternally(Operator):
bl_options = {'REGISTER'}
filepath = StringProperty(
subtype='FILE_PATH',
)
subtype='FILE_PATH',
)
@staticmethod
def _editor_guess(context):

View File

@ -34,18 +34,20 @@ class MeshMirrorUV(Operator):
bl_options = {'REGISTER', 'UNDO'}
direction = EnumProperty(
name="Axis Direction",
items=(('POSITIVE', "Positive", ""),
('NEGATIVE', "Negative", "")),
)
name="Axis Direction",
items=(
('POSITIVE', "Positive", ""),
('NEGATIVE', "Negative", ""),
),
)
precision = IntProperty(
name="Precision",
description=("Tolerance for finding vertex duplicates"),
min=1, max=16,
soft_min=1, soft_max=16,
default=3,
)
name="Precision",
description=("Tolerance for finding vertex duplicates"),
min=1, max=16,
soft_min=1, soft_max=16,
default=3,
)
@classmethod
def poll(cls, context):

View File

@ -35,31 +35,31 @@ from bpy.props import (
class NodeSetting(PropertyGroup):
value = StringProperty(
name="Value",
description="Python expression to be evaluated "
"as the initial node setting",
default="",
)
name="Value",
description="Python expression to be evaluated "
"as the initial node setting",
default="",
)
# Base class for node 'Add' operators
class NodeAddOperator:
type = StringProperty(
name="Node Type",
description="Node type",
)
name="Node Type",
description="Node type",
)
use_transform = BoolProperty(
name="Use Transform",
description="Start transform operator after inserting the node",
default=False,
)
name="Use Transform",
description="Start transform operator after inserting the node",
default=False,
)
settings = CollectionProperty(
name="Settings",
description="Settings to be applied on the newly created node",
type=NodeSetting,
options={'SKIP_SAVE'},
)
name="Settings",
description="Settings to be applied on the newly created node",
type=NodeSetting,
options={'SKIP_SAVE'},
)
@staticmethod
def store_mouse_cursor(context, event):
@ -70,7 +70,7 @@ class NodeAddOperator:
if context.region.type == 'WINDOW':
# convert mouse position to the View2D for later node placement
space.cursor_location_from_region(
event.mouse_region_x, event.mouse_region_y)
event.mouse_region_x, event.mouse_region_y)
else:
space.cursor_location = tree.view_center
@ -99,8 +99,8 @@ class NodeAddOperator:
setattr(node, setting.name, value)
except AttributeError as e:
self.report(
{'ERROR_INVALID_INPUT'},
"Node has no attribute " + setting.name)
{'ERROR_INVALID_INPUT'},
"Node has no attribute " + setting.name)
print(str(e))
# Continue despite invalid attribute
@ -153,9 +153,9 @@ class NODE_OT_add_and_link_node(NodeAddOperator, Operator):
bl_options = {'REGISTER', 'UNDO'}
link_socket_index = IntProperty(
name="Link Socket Index",
description="Index of the socket to link",
)
name="Link Socket Index",
description="Index of the socket to link",
)
def execute(self, context):
space = context.space_data
@ -195,11 +195,11 @@ class NODE_OT_add_search(NodeAddOperator, Operator):
nodetype = getattr(bpy.types, item.nodetype, None)
if nodetype:
enum_items.append(
(str(index),
item.label,
nodetype.bl_rna.description,
index,
))
(str(index),
item.label,
nodetype.bl_rna.description,
index,
))
return enum_items
# Look up the item based on index
@ -211,10 +211,10 @@ class NODE_OT_add_search(NodeAddOperator, Operator):
return None
node_item = EnumProperty(
name="Node Type",
description="Node type",
items=node_enum_items,
)
name="Node Type",
description="Node type",
items=node_enum_items,
)
def execute(self, context):
item = self.find_node_item(context)
@ -233,7 +233,7 @@ class NODE_OT_add_search(NodeAddOperator, Operator):
if self.use_transform:
bpy.ops.node.translate_attach_remove_on_cancel(
'INVOKE_DEFAULT')
'INVOKE_DEFAULT')
return {'FINISHED'}
else:

View File

@ -36,22 +36,22 @@ class SelectPattern(Operator):
bl_options = {'REGISTER', 'UNDO'}
pattern = StringProperty(
name="Pattern",
description="Name filter using '*', '?' and "
"'[abc]' unix style wildcards",
maxlen=64,
default="*",
)
name="Pattern",
description="Name filter using '*', '?' and "
"'[abc]' unix style wildcards",
maxlen=64,
default="*",
)
case_sensitive = BoolProperty(
name="Case Sensitive",
description="Do a case sensitive compare",
default=False,
)
name="Case Sensitive",
description="Do a case sensitive compare",
default=False,
)
extend = BoolProperty(
name="Extend",
description="Extend the existing selection",
default=True,
)
name="Extend",
description="Extend the existing selection",
default=True,
)
def execute(self, context):
@ -116,10 +116,10 @@ class SelectCamera(Operator):
bl_options = {'REGISTER', 'UNDO'}
extend = BoolProperty(
name="Extend",
description="Extend the selection",
default=False
)
name="Extend",
description="Extend the selection",
default=False
)
def execute(self, context):
scene = context.scene
@ -147,24 +147,24 @@ class SelectCamera(Operator):
class SelectHierarchy(Operator):
"""Select object relative to the active object's position """ \
"""in the hierarchy"""
"""in the hierarchy"""
bl_idname = "object.select_hierarchy"
bl_label = "Select Hierarchy"
bl_options = {'REGISTER', 'UNDO'}
direction = EnumProperty(
items=(('PARENT', "Parent", ""),
('CHILD', "Child", ""),
),
name="Direction",
description="Direction to select in the hierarchy",
default='PARENT')
items=(('PARENT', "Parent", ""),
('CHILD', "Child", ""),
),
name="Direction",
description="Direction to select in the hierarchy",
default='PARENT')
extend = BoolProperty(
name="Extend",
description="Extend the existing selection",
default=False,
)
name="Extend",
description="Extend the existing selection",
default=False,
)
@classmethod
def poll(cls, context):
@ -222,18 +222,18 @@ class SubdivisionSet(Operator):
bl_options = {'REGISTER', 'UNDO'}
level = IntProperty(
name="Level",
min=-100, max=100,
soft_min=-6, soft_max=6,
default=1,
)
name="Level",
min=-100, max=100,
soft_min=-6, soft_max=6,
default=1,
)
relative = BoolProperty(
name="Relative",
description=("Apply the subsurf level as an offset "
"relative to the current level"),
default=False,
)
name="Relative",
description=("Apply the subsurf level as an offset "
"relative to the current level"),
default=False,
)
@classmethod
def poll(cls, context):
@ -306,36 +306,36 @@ class SubdivisionSet(Operator):
class ShapeTransfer(Operator):
"""Copy another selected objects active shape to this one by """ \
"""applying the relative offsets"""
"""applying the relative offsets"""
bl_idname = "object.shape_key_transfer"
bl_label = "Transfer Shape Key"
bl_options = {'REGISTER', 'UNDO'}
mode = EnumProperty(
items=(('OFFSET',
"Offset",
"Apply the relative positional offset",
),
('RELATIVE_FACE',
"Relative Face",
"Calculate relative position (using faces)",
),
('RELATIVE_EDGE',
"Relative Edge",
"Calculate relative position (using edges)",
),
),
name="Transformation Mode",
description="Relative shape positions to the new shape method",
default='OFFSET',
)
items=(('OFFSET',
"Offset",
"Apply the relative positional offset",
),
('RELATIVE_FACE',
"Relative Face",
"Calculate relative position (using faces)",
),
('RELATIVE_EDGE',
"Relative Edge",
"Calculate relative position (using edges)",
),
),
name="Transformation Mode",
description="Relative shape positions to the new shape method",
default='OFFSET',
)
use_clamp = BoolProperty(
name="Clamp Offset",
description=("Clamp the transformation to the distance each "
"vertex moves in the original shape"),
default=False,
)
name="Clamp Offset",
description=("Clamp the transformation to the distance each "
"vertex moves in the original shape"),
default=False,
)
def _main(self, ob_act, objects, mode='OFFSET', use_clamp=False):
@ -368,7 +368,7 @@ class ShapeTransfer(Operator):
orig_normals = me_nos(me.vertices)
# actual mesh vertex location isn't as reliable as the base shape :S
#~ orig_coords = me_cos(me.vertices)
# orig_coords = me_cos(me.vertices)
orig_coords = me_cos(me.shape_keys.key_blocks[0].data)
for ob_other in objects:
@ -498,7 +498,7 @@ class ShapeTransfer(Operator):
class JoinUVs(Operator):
"""Transfer UV Maps from active to selected objects """ \
"""(needs matching geometry)"""
"""(needs matching geometry)"""
bl_idname = "object.join_uvs"
bl_label = "Transfer UV Maps"
bl_options = {'REGISTER', 'UNDO'}
@ -658,7 +658,7 @@ class MakeDupliFace(Operator):
class IsolateTypeRender(Operator):
"""Hide unselected render objects of same type as active """ \
"""by setting the hide render flag"""
"""by setting the hide render flag"""
bl_idname = "object.isolate_type_render"
bl_label = "Restrict Render Unselected"
bl_options = {'REGISTER', 'UNDO'}
@ -691,38 +691,27 @@ class ClearAllRestrictRender(Operator):
class TransformsToDeltas(Operator):
"""Convert normal object transforms to delta transforms, """ \
"""any existing delta transforms will be included as well"""
"""any existing delta transforms will be included as well"""
bl_idname = "object.transforms_to_deltas"
bl_label = "Transforms to Deltas"
bl_options = {'REGISTER', 'UNDO'}
mode = EnumProperty(
items=(('ALL',
"All Transforms",
"Transfer location, rotation, and scale transforms",
),
('LOC',
"Location",
"Transfer location transforms only",
),
('ROT',
"Rotation",
"Transfer rotation transforms only",
),
('SCALE',
"Scale",
"Transfer scale transforms only",
),
),
name="Mode",
description="Which transforms to transfer",
default='ALL',
)
items=(
('ALL', "All Transforms", "Transfer location, rotation, and scale transforms"),
('LOC', "Location", "Transfer location transforms only"),
('ROT', "Rotation", "Transfer rotation transforms only"),
('SCALE', "Scale", "Transfer scale transforms only"),
),
name="Mode",
description="Which transforms to transfer",
default='ALL',
)
reset_values = BoolProperty(
name="Reset Values",
description=("Clear transform values after transferring to deltas"),
default=True,
)
name="Reset Values",
description=("Clear transform values after transferring to deltas"),
default=True,
)
@classmethod
def poll(cls, context):
@ -788,11 +777,11 @@ class TransformsToDeltasAnim(Operator):
def execute(self, context):
# map from standard transform paths to "new" transform paths
STANDARD_TO_DELTA_PATHS = {
"location" : "delta_location",
"rotation_euler" : "delta_rotation_euler",
"rotation_quaternion" : "delta_rotation_quaternion",
#"rotation_axis_angle" : "delta_rotation_axis_angle",
"scale" : "delta_scale"
"location": "delta_location",
"rotation_euler": "delta_rotation_euler",
"rotation_quaternion": "delta_rotation_quaternion",
# "rotation_axis_angle" : "delta_rotation_axis_angle",
"scale": "delta_scale"
}
DELTA_PATHS = STANDARD_TO_DELTA_PATHS.values()
@ -852,8 +841,8 @@ class TransformsToDeltasAnim(Operator):
fcu.data_path = "delta_rotation_quaternion"
obj.rotation_quaternion.identity()
# XXX: currently not implemented
#~ elif fcu.data_path == "rotation_axis_angle":
#~ fcu.data_path = "delta_rotation_axis_angle"
# ~ elif fcu.data_path == "rotation_axis_angle":
# ~ fcu.data_path = "delta_rotation_axis_angle"
elif fcu.data_path == "scale":
fcu.data_path = "delta_scale"
obj.scale = 1.0, 1.0, 1.0

View File

@ -364,40 +364,45 @@ class AlignObjects(Operator):
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=True,
)
name="High Quality",
description=(
"Enables high quality calculation of the "
"bounding box for perfect results on complex "
"shape meshes with rotation/scale (Slow)"
),
default=True,
)
align_mode = EnumProperty(
name="Align Mode:",
description="Side of object to use for alignment",
items=(('OPT_1', "Negative Sides", ""),
('OPT_2', "Centers", ""),
('OPT_3', "Positive Sides", ""),
),
default='OPT_2',
)
name="Align Mode:",
description="Side of object to use for alignment",
items=(
('OPT_1', "Negative Sides", ""),
('OPT_2', "Centers", ""),
('OPT_3', "Positive Sides", ""),
),
default='OPT_2',
)
relative_to = EnumProperty(
name="Relative To:",
description="Reference location to align to",
items=(('OPT_1', "Scene Origin", "Use the Scene Origin as the position for the selected objects to align to"),
('OPT_2', "3D Cursor", "Use the 3D cursor as the position for the selected objects to align to"),
('OPT_3', "Selection", "Use the selected objects as the position for the selected objects to align to"),
('OPT_4', "Active", "Use the active object as the position for the selected objects to align to"),
),
default='OPT_4',
)
name="Relative To:",
description="Reference location to align to",
items=(
('OPT_1', "Scene Origin", "Use the Scene Origin as the position for the selected objects to align to"),
('OPT_2', "3D Cursor", "Use the 3D cursor as the position for the selected objects to align to"),
('OPT_3', "Selection", "Use the selected objects as the position for the selected objects to align to"),
('OPT_4', "Active", "Use the active object as the position for the selected objects to align to"),
),
default='OPT_4',
)
align_axis = EnumProperty(
name="Align",
description="Align to axis",
items=(('X', "X", ""),
('Y', "Y", ""),
('Z', "Z", ""),
),
options={'ENUM_FLAG'},
)
name="Align",
description="Align to axis",
items=(
('X', "X", ""),
('Y', "Y", ""),
('Z', "Z", ""),
),
options={'ENUM_FLAG'},
)
@classmethod
def poll(cls, context):

View File

@ -53,24 +53,26 @@ class QuickFur(Operator):
bl_options = {'REGISTER', 'UNDO'}
density = EnumProperty(
name="Fur Density",
items=(('LIGHT', "Light", ""),
('MEDIUM', "Medium", ""),
('HEAVY', "Heavy", "")),
default='MEDIUM',
)
name="Fur Density",
items=(
('LIGHT', "Light", ""),
('MEDIUM', "Medium", ""),
('HEAVY', "Heavy", "")
),
default='MEDIUM',
)
view_percentage = IntProperty(
name="View %",
min=1, max=100,
soft_min=1, soft_max=100,
default=10,
)
name="View %",
min=1, max=100,
soft_min=1, soft_max=100,
default=10,
)
length = FloatProperty(
name="Length",
min=0.001, max=100,
soft_min=0.01, soft_max=10,
default=0.1,
)
name="Length",
min=0.001, max=100,
soft_min=0.01, soft_max=10,
default=0.1,
)
def execute(self, context):
fake_context = context.copy()
@ -117,49 +119,51 @@ class QuickExplode(Operator):
bl_options = {'REGISTER', 'UNDO'}
style = EnumProperty(
name="Explode Style",
items=(('EXPLODE', "Explode", ""),
('BLEND', "Blend", "")),
default='EXPLODE',
)
name="Explode Style",
items=(
('EXPLODE', "Explode", ""),
('BLEND', "Blend", ""),
),
default='EXPLODE',
)
amount = IntProperty(
name="Amount of pieces",
min=2, max=10000,
soft_min=2, soft_max=10000,
default=100,
)
name="Amount of pieces",
min=2, max=10000,
soft_min=2, soft_max=10000,
default=100,
)
frame_duration = IntProperty(
name="Duration",
min=1, max=300000,
soft_min=1, soft_max=10000,
default=50,
)
name="Duration",
min=1, max=300000,
soft_min=1, soft_max=10000,
default=50,
)
frame_start = IntProperty(
name="Start Frame",
min=1, max=300000,
soft_min=1, soft_max=10000,
default=1,
)
name="Start Frame",
min=1, max=300000,
soft_min=1, soft_max=10000,
default=1,
)
frame_end = IntProperty(
name="End Frame",
min=1, max=300000,
soft_min=1, soft_max=10000,
default=10,
)
name="End Frame",
min=1, max=300000,
soft_min=1, soft_max=10000,
default=10,
)
velocity = FloatProperty(
name="Outwards Velocity",
min=0, max=300000,
soft_min=0, soft_max=10,
default=1,
)
name="Outwards Velocity",
min=0, max=300000,
soft_min=0, soft_max=10,
default=1,
)
fade = BoolProperty(
name="Fade",
description="Fade the pieces over time",
default=True,
)
name="Fade",
description="Fade the pieces over time",
default=True,
)
def execute(self, context):
fake_context = context.copy()
@ -303,19 +307,20 @@ class QuickSmoke(Operator):
bl_options = {'REGISTER', 'UNDO'}
style = EnumProperty(
name="Smoke Style",
items=(('SMOKE', "Smoke", ""),
('FIRE', "Fire", ""),
('BOTH', "Smoke + Fire", ""),
),
default='SMOKE',
)
name="Smoke Style",
items=(
('SMOKE', "Smoke", ""),
('FIRE', "Fire", ""),
('BOTH', "Smoke + Fire", ""),
),
default='SMOKE',
)
show_flows = BoolProperty(
name="Render Smoke Objects",
description="Keep the smoke objects visible during rendering",
default=False,
)
name="Render Smoke Objects",
description="Keep the smoke objects visible during rendering",
default=False,
)
def execute(self, context):
if not bpy.app.build_options.mod_smoke:
@ -390,7 +395,7 @@ class QuickSmoke(Operator):
node_principled = nodes.new(type='ShaderNodeVolumePrincipled')
node_principled.location = grid_location(4, 1)
links.new(node_principled.outputs["Volume"],
node_out.inputs["Volume"])
node_out.inputs["Volume"])
node_principled.inputs["Density"].default_value = 5.0
@ -406,29 +411,31 @@ class QuickFluid(Operator):
bl_options = {'REGISTER', 'UNDO'}
style = EnumProperty(
name="Fluid Style",
items=(('INFLOW', "Inflow", ""),
('BASIC', "Basic", "")),
default='BASIC',
)
name="Fluid Style",
items=(
('INFLOW', "Inflow", ""),
('BASIC', "Basic", ""),
),
default='BASIC',
)
initial_velocity = FloatVectorProperty(
name="Initial Velocity",
description="Initial velocity of the fluid",
min=-100.0, max=100.0,
default=(0.0, 0.0, 0.0),
subtype='VELOCITY',
)
name="Initial Velocity",
description="Initial velocity of the fluid",
min=-100.0, max=100.0,
default=(0.0, 0.0, 0.0),
subtype='VELOCITY',
)
show_flows = BoolProperty(
name="Render Fluid Objects",
description="Keep the fluid objects visible during rendering",
default=False,
)
name="Render Fluid Objects",
description="Keep the fluid objects visible during rendering",
default=False,
)
start_baking = BoolProperty(
name="Start Fluid Bake",
description=("Start baking the fluid immediately "
"after creating the domain object"),
default=False,
)
name="Start Fluid Bake",
description=("Start baking the fluid immediately "
"after creating the domain object"),
default=False,
)
def execute(self, context):
if not bpy.app.build_options.mod_fluid:

View File

@ -104,55 +104,55 @@ class RandomizeLocRotSize(Operator):
bl_options = {'REGISTER', 'UNDO'}
random_seed = IntProperty(
name="Random Seed",
description="Seed value for the random generator",
min=0,
max=10000,
default=0,
)
name="Random Seed",
description="Seed value for the random generator",
min=0,
max=10000,
default=0,
)
use_delta = BoolProperty(
name="Transform Delta",
description=("Randomize delta transform values "
"instead of regular transform"),
default=False,
)
name="Transform Delta",
description=("Randomize delta transform values "
"instead of regular transform"),
default=False,
)
use_loc = BoolProperty(
name="Randomize Location",
description="Randomize the location values",
default=True,
)
name="Randomize Location",
description="Randomize the location values",
default=True,
)
loc = FloatVectorProperty(
name="Location",
description=("Maximum distance the objects "
"can spread over each axis"),
min=-100.0,
max=100.0,
default=(0.0, 0.0, 0.0),
subtype='TRANSLATION',
)
name="Location",
description=("Maximum distance the objects "
"can spread over each axis"),
min=-100.0,
max=100.0,
default=(0.0, 0.0, 0.0),
subtype='TRANSLATION',
)
use_rot = BoolProperty(
name="Randomize Rotation",
description="Randomize the rotation values",
default=True,
)
name="Randomize Rotation",
description="Randomize the rotation values",
default=True,
)
rot = FloatVectorProperty(
name="Rotation",
description="Maximum rotation over each axis",
min=-3.141592, # math.pi
max=+3.141592,
default=(0.0, 0.0, 0.0),
subtype='EULER',
)
name="Rotation",
description="Maximum rotation over each axis",
min=-3.141592, # math.pi
max=+3.141592,
default=(0.0, 0.0, 0.0),
subtype='EULER',
)
use_scale = BoolProperty(
name="Randomize Scale",
description="Randomize the scale values",
default=True,
)
name="Randomize Scale",
description="Randomize the scale values",
default=True,
)
scale_even = BoolProperty(
name="Scale Even",
description="Use the same scale value for all axis",
default=False,
)
name="Scale Even",
description="Use the same scale value for all axis",
default=False,
)
'''scale_min = FloatProperty(
name="Minimun Scale Factor",
@ -162,13 +162,13 @@ class RandomizeLocRotSize(Operator):
)'''
scale = FloatVectorProperty(
name="Scale",
description="Maximum scale randomization over each axis",
min=-100.0,
max=100.0,
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
)
name="Scale",
description="Maximum scale randomization over each axis",
min=-100.0,
max=100.0,
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
)
def execute(self, context):
seed = self.random_seed

View File

@ -29,6 +29,7 @@ WindowManager.preset_name = StringProperty(
default="New Preset"
)
class AddPresetBase:
"""Base preset class, only for subclassing
subclasses must define
@ -41,26 +42,26 @@ class AddPresetBase:
bl_options = {'REGISTER', 'INTERNAL'}
name = StringProperty(
name="Name",
description="Name of the preset, used to make the path name",
maxlen=64,
options={'SKIP_SAVE'},
)
name="Name",
description="Name of the preset, used to make the path name",
maxlen=64,
options={'SKIP_SAVE'},
)
remove_name = BoolProperty(
default=False,
options={'HIDDEN', 'SKIP_SAVE'},
)
default=False,
options={'HIDDEN', 'SKIP_SAVE'},
)
remove_active = BoolProperty(
default=False,
options={'HIDDEN', 'SKIP_SAVE'},
)
default=False,
options={'HIDDEN', 'SKIP_SAVE'},
)
# needed for mix-ins
order = [
"name",
"remove_name",
"remove_active",
]
]
@staticmethod
def as_filename(name): # could reuse for other presets
@ -225,14 +226,14 @@ class ExecutePreset(Operator):
bl_label = "Execute a Python Preset"
filepath = StringProperty(
subtype='FILE_PATH',
options={'SKIP_SAVE'},
)
subtype='FILE_PATH',
options={'SKIP_SAVE'},
)
menu_idname = StringProperty(
name="Menu ID Name",
description="ID name of the menu this was called from",
options={'SKIP_SAVE'},
)
name="Menu ID Name",
description="ID name of the menu this was called from",
options={'SKIP_SAVE'},
)
def execute(self, context):
from os.path import basename, splitext
@ -268,22 +269,26 @@ class PresetMenu(Panel):
@classmethod
def draw_panel_header(cls, layout):
layout.emboss = 'NONE'
layout.popover(cls.bl_space_type,
cls.bl_region_type,
cls.__name__,
icon='PRESET',
text='')
layout.popover(
cls.bl_space_type,
cls.bl_region_type,
cls.__name__,
icon='PRESET',
text="",
)
@classmethod
def draw_menu(cls, layout, text=None):
if text == None:
if text is None:
text = cls.bl_label
layout.popover(cls.bl_space_type,
cls.bl_region_type,
cls.__name__,
icon='PRESET',
text=text)
layout.popover(
cls.bl_space_type,
cls.bl_region_type,
cls.__name__,
icon='PRESET',
text=text,
)
def draw(self, context):
layout = self.layout
@ -329,10 +334,10 @@ class AddPresetCamera(AddPresetBase, Operator):
preset_subdir = "camera"
use_focal_length = BoolProperty(
name="Include Focal Length",
description="Include focal length into the preset",
options={'SKIP_SAVE'},
)
name="Include Focal Length",
description="Include focal length into the preset",
options={'SKIP_SAVE'},
)
@property
def preset_values(self):
@ -397,12 +402,12 @@ class AddPresetFluid(AddPresetBase, Operator):
preset_defines = [
"fluid = bpy.context.fluid"
]
]
preset_values = [
"fluid.settings.viscosity_base",
"fluid.settings.viscosity_exponent",
]
]
preset_subdir = "fluid"
@ -434,7 +439,7 @@ class AddPresetHairDynamics(AddPresetBase, Operator):
"settings.density_strength",
"settings.voxel_cell_size",
"settings.pin_stiffness",
]
]
class AddPresetInteraction(AddPresetBase, Operator):
@ -476,11 +481,11 @@ class AddPresetTrackingCamera(AddPresetBase, Operator):
preset_subdir = "tracking_camera"
use_focal_length = BoolProperty(
name="Include Focal Length",
description="Include focal length into the preset",
options={'SKIP_SAVE'},
default=True
)
name="Include Focal Length",
description="Include focal length into the preset",
options={'SKIP_SAVE'},
default=True
)
@property
def preset_values(self):
@ -601,10 +606,10 @@ class AddPresetOperator(AddPresetBase, Operator):
preset_menu = "WM_MT_operator_presets"
operator = StringProperty(
name="Operator",
maxlen=64,
options={'HIDDEN', 'SKIP_SAVE'},
)
name="Operator",
maxlen=64,
options={'HIDDEN', 'SKIP_SAVE'},
)
preset_defines = [
"op = bpy.context.active_operator",

View File

@ -51,7 +51,7 @@ class CopyRigidbodySettings(Operator):
"mesh_source",
"use_deform",
"enabled",
)
)
@classmethod
def poll(cls, context):
@ -93,23 +93,23 @@ class BakeToKeyframes(Operator):
bl_options = {'REGISTER', 'UNDO'}
frame_start = IntProperty(
name="Start Frame",
description="Start frame for baking",
min=0, max=300000,
default=1,
)
name="Start Frame",
description="Start frame for baking",
min=0, max=300000,
default=1,
)
frame_end = IntProperty(
name="End Frame",
description="End frame for baking",
min=1, max=300000,
default=250,
)
name="End Frame",
description="End frame for baking",
min=1, max=300000,
default=250,
)
step = IntProperty(
name="Frame Step",
description="Frame Step",
min=1, max=120,
default=1,
)
name="Frame Step",
description="Frame Step",
min=1, max=120,
default=1,
)
@classmethod
def poll(cls, context):
@ -217,28 +217,34 @@ class ConnectRigidBodies(Operator):
bl_options = {'REGISTER', 'UNDO'}
con_type = EnumProperty(
name="Type",
description="Type of generated constraint",
# XXX Would be nice to get icons too, but currently not possible ;)
items=tuple((e.identifier, e.name, e.description, e. value)
for e in bpy.types.RigidBodyConstraint.bl_rna.properties["type"].enum_items),
default='FIXED',
)
name="Type",
description="Type of generated constraint",
# XXX Would be nice to get icons too, but currently not possible ;)
items=tuple(
(e.identifier, e.name, e.description, e. value)
for e in bpy.types.RigidBodyConstraint.bl_rna.properties["type"].enum_items
),
default='FIXED',
)
pivot_type = EnumProperty(
name="Location",
description="Constraint pivot location",
items=(('CENTER', "Center", "Pivot location is between the constrained rigid bodies"),
('ACTIVE', "Active", "Pivot location is at the active object position"),
('SELECTED', "Selected", "Pivot location is at the selected object position")),
default='CENTER',
)
name="Location",
description="Constraint pivot location",
items=(
('CENTER', "Center", "Pivot location is between the constrained rigid bodies"),
('ACTIVE', "Active", "Pivot location is at the active object position"),
('SELECTED', "Selected", "Pivot location is at the selected object position"),
),
default='CENTER',
)
connection_pattern = EnumProperty(
name="Connection Pattern",
description="Pattern used to connect objects",
items=(('SELECTED_TO_ACTIVE', "Selected to Active", "Connect selected objects to the active object"),
('CHAIN_DISTANCE', "Chain by Distance", "Connect objects as a chain based on distance, starting at the active object")),
default='SELECTED_TO_ACTIVE',
)
name="Connection Pattern",
description="Pattern used to connect objects",
items=(
('SELECTED_TO_ACTIVE', "Selected to Active", "Connect selected objects to the active object"),
('CHAIN_DISTANCE', "Chain by Distance", "Connect objects as a chain based on distance, starting at the active object"),
),
default='SELECTED_TO_ACTIVE',
)
@classmethod
def poll(cls, context):

View File

@ -103,7 +103,7 @@ class PlayRenderedAnim(Operator):
file_b = rd.frame_path(frame=int(frame_tmp / 10))
file = ("".join((c if file_b[i] == c else "#")
for i, c in enumerate(file_a)))
for i, c in enumerate(file_a)))
del file_a, file_b, frame_tmp
file = bpy.path.abspath(file) # expand '//'
else:
@ -115,7 +115,7 @@ class PlayRenderedAnim(Operator):
self.report({'WARNING'}, "File %r not found" % file)
path_valid = False
#one last try for full range if we used preview range
# one last try for full range if we used preview range
if scene.use_preview_range and not path_valid:
file = rd.frame_path(frame=scene.frame_start, preview=False)
file = bpy.path.abspath(file) # expand '//'

View File

@ -83,11 +83,11 @@ class SequencerCutMulticam(Operator):
bl_options = {'REGISTER', 'UNDO'}
camera = IntProperty(
name="Camera",
min=1, max=32,
soft_min=1, soft_max=32,
default=1,
)
name="Camera",
min=1, max=32,
soft_min=1, soft_max=32,
default=1,
)
@classmethod
def poll(cls, context):

View File

@ -18,7 +18,7 @@
# <pep8 compliant>
#for full docs see...
# for full docs see...
# http://mediawiki.blender.org/index.php/Scripts/Manual/UV_Calculate/Follow_active_quads
import bpy
@ -227,14 +227,14 @@ class FollowActiveQuads(Operator):
bl_options = {'REGISTER', 'UNDO'}
mode = bpy.props.EnumProperty(
name="Edge Length Mode",
description="Method to space UV edge loops",
items=(('EVEN', "Even", "Space all UVs evenly"),
('LENGTH', "Length", "Average space UVs edge length of each loop"),
('LENGTH_AVERAGE', "Length Average", "Average space UVs edge length of each loop"),
),
default='LENGTH_AVERAGE',
)
name="Edge Length Mode",
description="Method to space UV edge loops",
items=(('EVEN', "Even", "Space all UVs evenly"),
('LENGTH', "Length", "Average space UVs edge length of each loop"),
('LENGTH_AVERAGE', "Length Average", "Average space UVs edge length of each loop"),
),
default='LENGTH_AVERAGE',
)
@classmethod
def poll(cls, context):

View File

@ -33,7 +33,7 @@ class prettyface:
"yoff",
"has_parent",
"rot",
)
)
def __init__(self, data):
self.has_parent = False
@ -63,9 +63,9 @@ class prettyface:
self.width = self.height = d * 2
#else:
# print(len(data), data)
# raise "Error"
# else:
# print(len(data), data)
# raise "Error"
for pf in data:
pf.has_parent = True
@ -460,7 +460,7 @@ def lightmap_uvpack(meshes,
# Tall boxes in groups of 2
for d, boxes in list(odd_dict.items()):
if d[1] < max_int_dimension:
#\boxes.sort(key = lambda a: len(a.children))
# boxes.sort(key=lambda a: len(a.children))
while len(boxes) >= 2:
# print("foo", len(boxes))
ok = True
@ -597,6 +597,7 @@ def unwrap(operator, context, **kwargs):
return {'FINISHED'}
from bpy.props import BoolProperty, FloatProperty, IntProperty
@ -616,50 +617,55 @@ class LightMapPack(Operator):
bl_options = {'UNDO'}
PREF_CONTEXT = bpy.props.EnumProperty(
name="Selection",
items=(('SEL_FACES', "Selected Faces", "Space all UVs evenly"),
('ALL_FACES', "All Faces", "Average space UVs edge length of each loop"),
('ALL_OBJECTS', "Selected Mesh Object", "Average space UVs edge length of each loop")
),
)
name="Selection",
items=(
('SEL_FACES', "Selected Faces", "Space all UVs evenly"),
('ALL_FACES', "All Faces", "Average space UVs edge length of each loop"),
('ALL_OBJECTS', "Selected Mesh Object", "Average space UVs edge length of each loop")
),
)
# Image & UVs...
PREF_PACK_IN_ONE = BoolProperty(
name="Share Tex Space",
description=("Objects Share texture space, map all objects "
"into 1 uvmap"),
default=True,
)
name="Share Tex Space",
description=(
"Objects Share texture space, map all objects "
"into 1 uvmap"
),
default=True,
)
PREF_NEW_UVLAYER = BoolProperty(
name="New UV Map",
description="Create a new UV map for every mesh packed",
default=False,
)
name="New UV Map",
description="Create a new UV map for every mesh packed",
default=False,
)
PREF_APPLY_IMAGE = BoolProperty(
name="New Image",
description=("Assign new images for every mesh (only one if "
"shared tex space enabled)"),
default=False,
)
name="New Image",
description=(
"Assign new images for every mesh (only one if "
"shared tex space enabled)"
),
default=False,
)
PREF_IMG_PX_SIZE = IntProperty(
name="Image Size",
description="Width and Height for the new image",
min=64, max=5000,
default=512,
)
name="Image Size",
description="Width and Height for the new image",
min=64, max=5000,
default=512,
)
# UV Packing...
PREF_BOX_DIV = IntProperty(
name="Pack Quality",
description="Pre Packing before the complex boxpack",
min=1, max=48,
default=12,
)
name="Pack Quality",
description="Pre Packing before the complex boxpack",
min=1, max=48,
default=12,
)
PREF_MARGIN_DIV = FloatProperty(
name="Margin",
description="Size of the margin as a division of the UV",
min=0.001, max=1.0,
default=0.1,
)
name="Margin",
description="Size of the margin as a division of the UV",
min=0.001, max=1.0,
default=0.1,
)
def execute(self, context):
kwargs = self.as_keywords()

View File

@ -26,7 +26,7 @@ from mathutils import (
import bpy
from bpy.types import Operator
DEG_TO_RAD = 0.017453292519943295 # pi/180.0
DEG_TO_RAD = 0.017453292519943295 # pi/180.0
# see bugs:
# - T31598 (when too small).
# - T48086 (when too big).
@ -38,6 +38,7 @@ global USER_FILL_HOLES_QUALITY
USER_FILL_HOLES = None
USER_FILL_HOLES_QUALITY = None
def pointInTri2D(v, v1, v2, v3):
key = v1.x, v1.y, v2.x, v2.y, v3.x, v3.y
@ -93,20 +94,25 @@ def pointInTri2D(v, v1, v2, v3):
def boundsIsland(faces):
minx = maxx = faces[0].uv[0][0] # Set initial bounds.
minx = maxx = faces[0].uv[0][0] # Set initial bounds.
miny = maxy = faces[0].uv[0][1]
# print len(faces), minx, maxx, miny , maxy
for f in faces:
for uv in f.uv:
x= uv.x
y= uv.y
if x<minx: minx= x
if y<miny: miny= y
if x>maxx: maxx= x
if y>maxy: maxy= y
x = uv.x
y = uv.y
if x < minx:
minx = x
if y < miny:
miny = y
if x > maxx:
maxx = x
if y > maxy:
maxy = y
return minx, miny, maxx, maxy
"""
def boundsEdgeLoop(edges):
minx = maxx = edges[0][0] # Set initial bounds.
@ -128,45 +134,51 @@ def boundsEdgeLoop(edges):
# Only for UV's
# only returns outline edges for intersection tests. and unique points.
def island2Edge(island):
# Vert index edges
edges = {}
unique_points= {}
unique_points = {}
for f in island:
f_uvkey= map(tuple, f.uv)
f_uvkey = map(tuple, f.uv)
for vIdx, edkey in enumerate(f.edge_keys):
unique_points[f_uvkey[vIdx]] = f.uv[vIdx]
if f.v[vIdx].index > f.v[vIdx-1].index:
i1= vIdx-1; i2= vIdx
if f.v[vIdx].index > f.v[vIdx - 1].index:
i1 = vIdx - 1
i2 = vIdx
else:
i1= vIdx; i2= vIdx-1
i1 = vIdx
i2 = vIdx - 1
try: edges[ f_uvkey[i1], f_uvkey[i2] ] *= 0 # sets any edge with more than 1 user to 0 are not returned.
except: edges[ f_uvkey[i1], f_uvkey[i2] ] = (f.uv[i1] - f.uv[i2]).length,
try:
edges[f_uvkey[i1], f_uvkey[i2]] *= 0 # sets any edge with more than 1 user to 0 are not returned.
except:
edges[f_uvkey[i1], f_uvkey[i2]] = (f.uv[i1] - f.uv[i2]).length,
# If 2 are the same then they will be together, but full [a,b] order is not correct.
# Sort by length
length_sorted_edges = [(Vector(key[0]), Vector(key[1]), value) for key, value in edges.items() if value != 0]
try: length_sorted_edges.sort(key = lambda A: -A[2]) # largest first
except: length_sorted_edges.sort(lambda A, B: cmp(B[2], A[2]))
try:
length_sorted_edges.sort(key=lambda A: -A[2]) # largest first
except:
length_sorted_edges.sort(lambda A, B: cmp(B[2], A[2]))
# Its okay to leave the length in there.
#for e in length_sorted_edges:
# for e in length_sorted_edges:
# e.pop(2)
# return edges and unique points
return length_sorted_edges, [v.to_3d() for v in unique_points.values()]
# ========================= NOT WORKING????
# Find if a points inside an edge loop, unordered.
# pt is and x/y
@ -190,6 +202,7 @@ def pointInEdges(pt, edges):
return intersectCount % 2
"""
def pointInIsland(pt, island):
vec1, vec2, vec3 = Vector(), Vector(), Vector()
for f in island:
@ -212,7 +225,7 @@ def pointInIsland(pt, island):
# box is (left,bottom, right, top)
def islandIntersectUvIsland(source, target, SourceOffset):
# Is 1 point in the box, inside the vertLoops
edgeLoopsSource = source[6] # Pretend this is offset
edgeLoopsSource = source[6] # Pretend this is offset
edgeLoopsTarget = target[6]
# Edge intersect test
@ -220,24 +233,24 @@ def islandIntersectUvIsland(source, target, SourceOffset):
for seg in edgeLoopsTarget:
i = geometry.intersect_line_line_2d(seg[0],
seg[1],
SourceOffset+ed[0],
SourceOffset+ed[1],
SourceOffset + ed[0],
SourceOffset + ed[1],
)
if i:
return 1 # LINE INTERSECTION
return 1 # LINE INTERSECTION
# 1 test for source being totally inside target
SourceOffset.resize_3d()
for pv in source[7]:
if pointInIsland(pv+SourceOffset, target[0]):
return 2 # SOURCE INSIDE TARGET
if pointInIsland(pv + SourceOffset, target[0]):
return 2 # SOURCE INSIDE TARGET
# 2 test for a part of the target being totally inside the source.
for pv in target[7]:
if pointInIsland(pv-SourceOffset, source[0]):
return 3 # PART OF TARGET INSIDE SOURCE.
if pointInIsland(pv - SourceOffset, source[0]):
return 3 # PART OF TARGET INSIDE SOURCE.
return 0 # NO INTERSECTION
return 0 # NO INTERSECTION
def rotate_uvs(uv_points, angle):
@ -249,7 +262,7 @@ def rotate_uvs(uv_points, angle):
def optiRotateUvIsland(faces):
uv_points = [uv for f in faces for uv in f.uv]
uv_points = [uv for f in faces for uv in f.uv]
angle = geometry.box_fit_2d(uv_points)
if angle != 0.0:
@ -270,81 +283,78 @@ def mergeUvIslands(islandList):
global USER_FILL_HOLES
global USER_FILL_HOLES_QUALITY
# Pack islands to bottom LHS
# Sync with island
#islandTotFaceArea = [] # A list of floats, each island area
#islandArea = [] # a list of tuples ( area, w,h)
# islandTotFaceArea = [] # A list of floats, each island area
# islandArea = [] # a list of tuples ( area, w,h)
decoratedIslandList = []
islandIdx = len(islandList)
while islandIdx:
islandIdx-=1
islandIdx -= 1
minx, miny, maxx, maxy = boundsIsland(islandList[islandIdx])
w, h = maxx-minx, maxy-miny
w, h = maxx - minx, maxy - miny
totFaceArea = 0
offset= Vector((minx, miny))
offset = Vector((minx, miny))
for f in islandList[islandIdx]:
for uv in f.uv:
uv -= offset
totFaceArea += f.area
islandBoundsArea = w*h
islandBoundsArea = w * h
efficiency = abs(islandBoundsArea - totFaceArea)
# UV Edge list used for intersections as well as unique points.
edges, uniqueEdgePoints = island2Edge(islandList[islandIdx])
decoratedIslandList.append([islandList[islandIdx], totFaceArea, efficiency, islandBoundsArea, w,h, edges, uniqueEdgePoints])
decoratedIslandList.append([islandList[islandIdx], totFaceArea, efficiency, islandBoundsArea, w, h, edges, uniqueEdgePoints])
# Sort by island bounding box area, smallest face area first.
# no.. chance that to most simple edge loop first.
decoratedIslandListAreaSort =decoratedIslandList[:]
decoratedIslandListAreaSort = decoratedIslandList[:]
decoratedIslandListAreaSort.sort(key = lambda A: A[3])
decoratedIslandListAreaSort.sort(key=lambda A: A[3])
# sort by efficiency, Least Efficient first.
decoratedIslandListEfficSort = decoratedIslandList[:]
# decoratedIslandListEfficSort.sort(lambda A, B: cmp(B[2], A[2]))
decoratedIslandListEfficSort.sort(key = lambda A: -A[2])
decoratedIslandListEfficSort.sort(key=lambda A: -A[2])
# ================================================== THESE CAN BE TWEAKED.
# This is a quality value for the number of tests.
# from 1 to 4, generic quality value is from 1 to 100
USER_STEP_QUALITY = ((USER_FILL_HOLES_QUALITY - 1) / 25.0) + 1
USER_STEP_QUALITY = ((USER_FILL_HOLES_QUALITY - 1) / 25.0) + 1
# If 100 will test as long as there is enough free space.
# this is rarely enough, and testing takes a while, so lower quality speeds this up.
# 1 means they have the same quality
USER_FREE_SPACE_TO_TEST_QUALITY = 1 + (((100 - USER_FILL_HOLES_QUALITY)/100.0) *5)
USER_FREE_SPACE_TO_TEST_QUALITY = 1 + (((100 - USER_FILL_HOLES_QUALITY) / 100.0) * 5)
#print 'USER_STEP_QUALITY', USER_STEP_QUALITY
#print 'USER_FREE_SPACE_TO_TEST_QUALITY', USER_FREE_SPACE_TO_TEST_QUALITY
# print 'USER_STEP_QUALITY', USER_STEP_QUALITY
# print 'USER_FREE_SPACE_TO_TEST_QUALITY', USER_FREE_SPACE_TO_TEST_QUALITY
removedCount = 0
areaIslandIdx = 0
ctrl = Window.Qual.CTRL
BREAK= False
BREAK = False
while areaIslandIdx < len(decoratedIslandListAreaSort) and not BREAK:
sourceIsland = decoratedIslandListAreaSort[areaIslandIdx]
# Already packed?
if not sourceIsland[0]:
areaIslandIdx+=1
areaIslandIdx += 1
else:
efficIslandIdx = 0
while efficIslandIdx < len(decoratedIslandListEfficSort) and not BREAK:
if Window.GetKeyQualifiers() & ctrl:
BREAK= True
BREAK = True
break
# Now we have 2 islands, if the efficiency of the islands lowers theres an
@ -355,64 +365,60 @@ def mergeUvIslands(islandList):
targetIsland = decoratedIslandListEfficSort[efficIslandIdx]
if sourceIsland[0] == targetIsland[0] or\
not targetIsland[0] or\
not sourceIsland[0]:
not targetIsland[0] or\
not sourceIsland[0]:
pass
else:
#~ ([island, totFaceArea, efficiency, islandArea, w,h])
# Wasted space on target is greater then UV bounding island area.
#~ if targetIsland[3] > (sourceIsland[2]) and\ #
#~ print USER_FREE_SPACE_TO_TEST_QUALITY
# ~ print USER_FREE_SPACE_TO_TEST_QUALITY
if targetIsland[2] > (sourceIsland[1] * USER_FREE_SPACE_TO_TEST_QUALITY) and\
targetIsland[4] > sourceIsland[4] and\
targetIsland[5] > sourceIsland[5]:
targetIsland[4] > sourceIsland[4] and\
targetIsland[5] > sourceIsland[5]:
# DEBUG # print '%.10f %.10f' % (targetIsland[3], sourceIsland[1])
# These enough spare space lets move the box until it fits
# How many times does the source fit into the target x/y
blockTestXUnit = targetIsland[4]/sourceIsland[4]
blockTestYUnit = targetIsland[5]/sourceIsland[5]
blockTestXUnit = targetIsland[4] / sourceIsland[4]
blockTestYUnit = targetIsland[5] / sourceIsland[5]
boxLeft = 0
# Distance we can move between whilst staying inside the targets bounds.
testWidth = targetIsland[4] - sourceIsland[4]
testHeight = targetIsland[5] - sourceIsland[5]
# Increment we move each test. x/y
xIncrement = (testWidth / (blockTestXUnit * ((USER_STEP_QUALITY/50)+0.1)))
yIncrement = (testHeight / (blockTestYUnit * ((USER_STEP_QUALITY/50)+0.1)))
xIncrement = (testWidth / (blockTestXUnit * ((USER_STEP_QUALITY / 50) + 0.1)))
yIncrement = (testHeight / (blockTestYUnit * ((USER_STEP_QUALITY / 50) + 0.1)))
# Make sure were not moving less then a 3rg of our width/height
if xIncrement<sourceIsland[4]/3:
xIncrement= sourceIsland[4]
if yIncrement<sourceIsland[5]/3:
yIncrement= sourceIsland[5]
if xIncrement < sourceIsland[4] / 3:
xIncrement = sourceIsland[4]
if yIncrement < sourceIsland[5] / 3:
yIncrement = sourceIsland[5]
boxLeft = 0 # Start 1 back so we can jump into the loop.
boxBottom = 0 # -yIncrement
boxLeft = 0 # Start 1 back so we can jump into the loop.
boxBottom= 0 #-yIncrement
#~ testcount= 0
# ~ testcount= 0
while boxBottom <= testHeight:
# Should we use this? - not needed for now.
#~ if Window.GetKeyQualifiers() & ctrl:
#~ BREAK= True
#~ break
# ~ if Window.GetKeyQualifiers() & ctrl:
# ~ BREAK= True
# ~ break
##testcount+=1
#print 'Testing intersect'
# testcount+=1
# print 'Testing intersect'
Intersect = islandIntersectUvIsland(sourceIsland, targetIsland, Vector((boxLeft, boxBottom)))
#print 'Done', Intersect
# print 'Done', Intersect
if Intersect == 1: # Line intersect, don't bother with this any more
pass
@ -429,93 +435,92 @@ def mergeUvIslands(islandList):
# Move the test along its width + SMALL_NUM
#boxLeft += sourceIsland[4] + SMALL_NUM
boxLeft += sourceIsland[4]
elif Intersect == 0: # No intersection?? Place it.
elif Intersect == 0: # No intersection?? Place it.
# Progress
removedCount +=1
#XXX Window.DrawProgressBar(0.0, 'Merged: %i islands, Ctrl to finish early.' % removedCount)
removedCount += 1
# XXX Window.DrawProgressBar(0.0, 'Merged: %i islands, Ctrl to finish early.' % removedCount)
# Move faces into new island and offset
targetIsland[0].extend(sourceIsland[0])
offset= Vector((boxLeft, boxBottom))
offset = Vector((boxLeft, boxBottom))
for f in sourceIsland[0]:
for uv in f.uv:
uv+= offset
uv += offset
del sourceIsland[0][:] # Empty
# Move edge loop into new and offset.
# targetIsland[6].extend(sourceIsland[6])
#while sourceIsland[6]:
targetIsland[6].extend( [ (\
(e[0]+offset, e[1]+offset, e[2])\
) for e in sourceIsland[6] ] )
# while sourceIsland[6]:
targetIsland[6].extend([(
(e[0] + offset, e[1] + offset, e[2])
) for e in sourceIsland[6]])
del sourceIsland[6][:] # Empty
# Sort by edge length, reverse so biggest are first.
try: targetIsland[6].sort(key = lambda A: A[2])
except: targetIsland[6].sort(lambda B,A: cmp(A[2], B[2] ))
try:
targetIsland[6].sort(key=lambda A: A[2])
except:
targetIsland[6].sort(lambda B, A: cmp(A[2], B[2]))
targetIsland[7].extend(sourceIsland[7])
offset= Vector((boxLeft, boxBottom, 0.0))
offset = Vector((boxLeft, boxBottom, 0.0))
for p in sourceIsland[7]:
p+= offset
p += offset
del sourceIsland[7][:]
# Decrement the efficiency
targetIsland[1]+=sourceIsland[1] # Increment totFaceArea
targetIsland[2]-=sourceIsland[1] # Decrement efficiency
targetIsland[1] += sourceIsland[1] # Increment totFaceArea
targetIsland[2] -= sourceIsland[1] # Decrement efficiency
# IF we ever used these again, should set to 0, eg
sourceIsland[2] = 0 # No area if anyone wants to know
sourceIsland[2] = 0 # No area if anyone wants to know
break
# INCREMENT NEXT LOCATION
if boxLeft > testWidth:
boxBottom += yIncrement
boxLeft = 0.0
else:
boxLeft += xIncrement
##print testcount
# print testcount
efficIslandIdx+=1
areaIslandIdx+=1
efficIslandIdx += 1
areaIslandIdx += 1
# Remove empty islands
i = len(islandList)
while i:
i-=1
i -= 1
if not islandList[i]:
del islandList[i] # Can increment islands removed here.
del islandList[i] # Can increment islands removed here.
# Takes groups of faces. assumes face groups are UV groups.
def getUvIslands(faceGroups, me):
# Get seams so we don't cross over seams
edge_seams = {} # should be a set
edge_seams = {} # should be a set
for ed in me.edges:
if ed.use_seam:
edge_seams[ed.key] = None # dummy var- use sets!
edge_seams[ed.key] = None # dummy var- use sets!
# Done finding seams
islandList = []
#XXX Window.DrawProgressBar(0.0, 'Splitting %d projection groups into UV islands:' % len(faceGroups))
#print '\tSplitting %d projection groups into UV islands:' % len(faceGroups),
# XXX Window.DrawProgressBar(0.0, 'Splitting %d projection groups into UV islands:' % len(faceGroups))
# print '\tSplitting %d projection groups into UV islands:' % len(faceGroups),
# Find grouped faces
faceGroupIdx = len(faceGroups)
while faceGroupIdx:
faceGroupIdx-=1
faceGroupIdx -= 1
faces = faceGroups[faceGroupIdx]
if not faces:
@ -526,37 +531,38 @@ def getUvIslands(faceGroups, me):
for i, f in enumerate(faces):
for ed_key in f.edge_keys:
if ed_key in edge_seams: # DELIMIT SEAMS! ;)
edge_users[ed_key] = [] # so as not to raise an error
if ed_key in edge_seams: # DELIMIT SEAMS! ;)
edge_users[ed_key] = [] # so as not to raise an error
else:
try: edge_users[ed_key].append(i)
except: edge_users[ed_key] = [i]
try:
edge_users[ed_key].append(i)
except:
edge_users[ed_key] = [i]
# Modes
# 0 - face not yet touched.
# 1 - added to island list, and need to search
# 2 - touched and searched - don't touch again.
face_modes = [0] * len(faces) # initialize zero - untested.
face_modes = [0] * len(faces) # initialize zero - untested.
face_modes[0] = 1 # start the search with face 1
face_modes[0] = 1 # start the search with face 1
newIsland = []
newIsland.append(faces[0])
ok = True
while ok:
ok = True
while ok:
ok= False
ok = False
for i in range(len(faces)):
if face_modes[i] == 1: # search
if face_modes[i] == 1: # search
for ed_key in faces[i].edge_keys:
for ii in edge_users[ed_key]:
if i != ii and face_modes[ii] == 0:
face_modes[ii] = ok = 1 # mark as searched
face_modes[ii] = ok = 1 # mark as searched
newIsland.append(faces[ii])
# mark as searched, don't look again.
@ -574,7 +580,7 @@ def getUvIslands(faceGroups, me):
break
# if not ok will stop looping
#XXX Window.DrawProgressBar(0.1, 'Optimizing Rotation for %i UV Islands' % len(islandList))
# XXX Window.DrawProgressBar(0.1, 'Optimizing Rotation for %i UV Islands' % len(islandList))
for island in islandList:
optiRotateUvIsland(island)
@ -584,9 +590,8 @@ def getUvIslands(faceGroups, me):
def packIslands(islandList):
if USER_FILL_HOLES:
#XXX Window.DrawProgressBar(0.1, 'Merging Islands (Ctrl: skip merge)...')
mergeUvIslands(islandList) # Modify in place
# XXX Window.DrawProgressBar(0.1, 'Merging Islands (Ctrl: skip merge)...')
mergeUvIslands(islandList) # Modify in place
# Now we have UV islands, we need to pack them.
@ -603,16 +608,16 @@ def packIslands(islandList):
while islandIdx < len(islandList):
minx, miny, maxx, maxy = boundsIsland(islandList[islandIdx])
w, h = maxx-minx, maxy-miny
w, h = maxx - minx, maxy - miny
if USER_ISLAND_MARGIN:
minx -= USER_ISLAND_MARGIN# *w
miny -= USER_ISLAND_MARGIN# *h
maxx += USER_ISLAND_MARGIN# *w
maxy += USER_ISLAND_MARGIN# *h
minx -= USER_ISLAND_MARGIN # *w
miny -= USER_ISLAND_MARGIN # *h
maxx += USER_ISLAND_MARGIN # *w
maxy += USER_ISLAND_MARGIN # *h
# recalc width and height
w, h = maxx-minx, maxy-miny
w, h = maxx - minx, maxy - miny
if w < SMALL_NUM:
w = SMALL_NUM
@ -628,24 +633,24 @@ def packIslands(islandList):
# Add to boxList. use the island idx for the BOX id.
packBoxes.append([0, 0, w, h])
islandIdx+=1
islandIdx += 1
# Now we have a list of boxes to pack that syncs
# with the islands.
#print '\tPacking UV Islands...'
#XXX Window.DrawProgressBar(0.7, "Packing %i UV Islands..." % len(packBoxes) )
# print '\tPacking UV Islands...'
# XXX Window.DrawProgressBar(0.7, "Packing %i UV Islands..." % len(packBoxes) )
# time1 = time.time()
packWidth, packHeight = geometry.box_pack_2d(packBoxes)
# print 'Box Packing Time:', time.time() - time1
#if len(pa ckedLs) != len(islandList):
# if len(pa ckedLs) != len(islandList):
# raise ValueError("Packed boxes differs from original length")
#print '\tWriting Packed Data to faces'
#XXX Window.DrawProgressBar(0.8, "Writing Packed Data to faces")
# print '\tWriting Packed Data to faces'
# XXX Window.DrawProgressBar(0.8, "Writing Packed Data to faces")
# Sort by ID, so there in sync again
islandIdx = len(islandList)
@ -661,16 +666,16 @@ def packIslands(islandList):
xfactor = yfactor = 1.0 / max(packWidth, packHeight)
while islandIdx:
islandIdx -=1
islandIdx -= 1
# Write the packed values to the UV's
xoffset = packBoxes[islandIdx][0] - islandOffsetList[islandIdx][0]
yoffset = packBoxes[islandIdx][1] - islandOffsetList[islandIdx][1]
for f in islandList[islandIdx]: # Offsetting the UV's so they fit in there packed box
for f in islandList[islandIdx]: # Offsetting the UV's so they fit in there packed box
for uv in f.uv:
uv.x= (uv.x+xoffset) * xfactor
uv.y= (uv.y+yoffset) * yfactor
uv.x = (uv.x + xoffset) * xfactor
uv.y = (uv.y + yoffset) * yfactor
def VectoQuat(vec):
@ -679,7 +684,8 @@ def VectoQuat(vec):
class thickface:
__slost__= "v", "uv", "no", "area", "edge_keys"
__slost__ = "v", "uv", "no", "area", "edge_keys"
def __init__(self, face, uv_layer, mesh_verts):
self.v = [mesh_verts[i] for i in face.vertices]
self.uv = [uv_layer[i].uv for i in face.loop_indices]
@ -700,18 +706,20 @@ def main_consts():
ROTMAT_2D_POS_45D = Matrix.Rotation(radians(45.0), 2)
RotMatStepRotation = []
rot_angle = 22.5 #45.0/2
rot_angle = 22.5 # 45.0/2
while rot_angle > 0.1:
RotMatStepRotation.append([
Matrix.Rotation(radians(+rot_angle), 2),
Matrix.Rotation(radians(-rot_angle), 2),
])
])
rot_angle = rot_angle/2.0
rot_angle = rot_angle / 2.0
global ob
ob = None
def main(context,
island_margin,
projection_limit,
@ -741,18 +749,18 @@ def main(context,
# Create the variables.
USER_PROJECTION_LIMIT = projection_limit
USER_ONLY_SELECTED_FACES = True
USER_SHARE_SPACE = 1 # Only for hole filling.
USER_SHARE_SPACE = 1 # Only for hole filling.
USER_STRETCH_ASPECT = stretch_to_bounds
USER_ISLAND_MARGIN = island_margin # Only for hole filling.
USER_ISLAND_MARGIN = island_margin # Only for hole filling.
USER_FILL_HOLES = 0
USER_FILL_HOLES_QUALITY = 50 # Only for hole filling.
USER_VIEW_INIT = 0 # Only for hole filling.
USER_FILL_HOLES_QUALITY = 50 # Only for hole filling.
USER_VIEW_INIT = 0 # Only for hole filling.
is_editmode = (context.active_object.mode == 'EDIT')
if is_editmode:
obList = [ob for ob in [context.active_object] if ob and ob.type == 'MESH']
obList = [ob for ob in [context.active_object] if ob and ob.type == 'MESH']
else:
obList = [ob for ob in context.selected_editable_objects if ob and ob.type == 'MESH']
obList = [ob for ob in context.selected_editable_objects if ob and ob.type == 'MESH']
USER_ONLY_SELECTED_FACES = False
if not obList:
@ -770,15 +778,14 @@ def main(context,
time.sleep(10)
'''
#~ XXX if not Draw.PupBlock(ob % len(obList), pup_block):
#~ XXX return
#~ XXX del ob
# ~ XXX if not Draw.PupBlock(ob % len(obList), pup_block):
# ~ XXX return
# ~ XXX del ob
# Convert from being button types
USER_PROJECTION_LIMIT_CONVERTED = cos(USER_PROJECTION_LIMIT * DEG_TO_RAD)
USER_PROJECTION_LIMIT_HALF_CONVERTED = cos((USER_PROJECTION_LIMIT/2) * DEG_TO_RAD)
USER_PROJECTION_LIMIT_HALF_CONVERTED = cos((USER_PROJECTION_LIMIT / 2) * DEG_TO_RAD)
# Toggle Edit mode
is_editmode = (context.active_object.mode == 'EDIT')
@ -788,19 +795,18 @@ def main(context,
if USER_SHARE_SPACE:
# Sort by data name so we get consistent results
obList.sort(key = lambda ob: ob.data.name)
collected_islandList= []
obList.sort(key=lambda ob: ob.data.name)
collected_islandList = []
#XXX Window.WaitCursor(1)
# XXX Window.WaitCursor(1)
time1 = time.time()
# Tag as False so we don't operate on the same mesh twice.
#XXX bpy.data.meshes.tag = False
# XXX bpy.data.meshes.tag = False
for me in bpy.data.meshes:
me.tag = False
for ob in obList:
me = ob.data
@ -810,7 +816,7 @@ def main(context,
# Tag as used
me.tag = True
if not me.uv_layers: # Mesh has no UV Coords, don't bother.
if not me.uv_layers: # Mesh has no UV Coords, don't bother.
me.uv_layers.new()
uv_layer = me.uv_layers.active.data
@ -821,7 +827,7 @@ def main(context,
else:
meshFaces = [thickface(f, uv_layer, me_verts) for i, f in enumerate(me.polygons)]
#XXX Window.DrawProgressBar(0.1, 'SmartProj UV Unwrapper, mapping "%s", %i faces.' % (me.name, len(meshFaces)))
# XXX Window.DrawProgressBar(0.1, 'SmartProj UV Unwrapper, mapping "%s", %i faces.' % (me.name, len(meshFaces)))
# =======
# Generate a projection list from face normals, this is meant to be smart :)
@ -849,17 +855,15 @@ def main(context,
# 0d is 1.0
# 180 IS -0.59846
# Initialize projectVecs
if USER_VIEW_INIT:
# Generate Projection
projectVecs = [Vector(Window.GetViewVector()) * ob.matrix_world.inverted().to_3x3()] # We add to this along the way
projectVecs = [Vector(Window.GetViewVector()) * ob.matrix_world.inverted().to_3x3()] # We add to this along the way
else:
projectVecs = []
newProjectVec = meshFaces[0].no
newProjectMeshFaces = [] # Popping stuffs it up.
newProjectMeshFaces = [] # Popping stuffs it up.
# Pretend that the most unique angle is ages away to start the loop off
mostUniqueAngle = -1.0
@ -867,14 +871,12 @@ def main(context,
# This is popped
tempMeshFaces = meshFaces[:]
# This while only gathers projection vecs, faces are assigned later on.
while 1:
# If theres none there then start with the largest face
# add all the faces that are close.
for fIdx in range(len(tempMeshFaces)-1, -1, -1):
for fIdx in range(len(tempMeshFaces) - 1, -1, -1):
# Use half the angle limit so we don't overweight faces towards this
# normal and hog all the faces.
if newProjectVec.dot(tempMeshFaces[fIdx].no) > USER_PROJECTION_LIMIT_HALF_CONVERTED:
@ -892,24 +894,23 @@ def main(context,
for fprop in newProjectMeshFaces:
averageVec += fprop.no * ((fprop.area * user_area_weight) + (1.0 - user_area_weight))
if averageVec.x != 0 or averageVec.y != 0 or averageVec.z != 0: # Avoid NAN
if averageVec.x != 0 or averageVec.y != 0 or averageVec.z != 0: # Avoid NAN
projectVecs.append(averageVec.normalized())
# Get the next vec!
# Pick the face thats most different to all existing angles :)
mostUniqueAngle = 1.0 # 1.0 is 0d. no difference.
mostUniqueIndex = 0 # dummy
mostUniqueAngle = 1.0 # 1.0 is 0d. no difference.
mostUniqueIndex = 0 # dummy
for fIdx in range(len(tempMeshFaces)-1, -1, -1):
angleDifference = -1.0 # 180d difference.
for fIdx in range(len(tempMeshFaces) - 1, -1, -1):
angleDifference = -1.0 # 180d difference.
# Get the closest vec angle we are to.
for p in projectVecs:
temp_angle_diff= p.dot(tempMeshFaces[fIdx].no)
temp_angle_diff = p.dot(tempMeshFaces[fIdx].no)
if angleDifference < temp_angle_diff:
angleDifference= temp_angle_diff
angleDifference = temp_angle_diff
if angleDifference < mostUniqueAngle:
# We have a new most different angle
@ -917,30 +918,28 @@ def main(context,
mostUniqueAngle = angleDifference
if mostUniqueAngle < USER_PROJECTION_LIMIT_CONVERTED:
#print 'adding', mostUniqueAngle, USER_PROJECTION_LIMIT, len(newProjectMeshFaces)
# print 'adding', mostUniqueAngle, USER_PROJECTION_LIMIT, len(newProjectMeshFaces)
# Now weight the vector to all its faces, will give a more direct projection
# if the face its self was not representative of the normal from surrounding faces.
newProjectVec = tempMeshFaces[mostUniqueIndex].no
newProjectMeshFaces = [tempMeshFaces.pop(mostUniqueIndex)]
else:
if len(projectVecs) >= 1: # Must have at least 2 projections
if len(projectVecs) >= 1: # Must have at least 2 projections
break
# If there are only zero area faces then its possible
# there are no projectionVecs
if not len(projectVecs):
Draw.PupMenu('error, no projection vecs where generated, 0 area faces can cause this.')
return
faceProjectionGroupList =[[] for i in range(len(projectVecs)) ]
faceProjectionGroupList = [[] for i in range(len(projectVecs))]
# MAP and Arrange # We know there are 3 or 4 faces here
for fIdx in range(len(meshFaces)-1, -1, -1):
for fIdx in range(len(meshFaces) - 1, -1, -1):
fvec = meshFaces[fIdx].no
i = len(projectVecs)
@ -949,11 +948,11 @@ def main(context,
bestAngIdx = 0
# Cycle through the remaining, first already done
while i-1:
i-=1
while i - 1:
i -= 1
newAng = fvec.dot(projectVecs[i])
if newAng > bestAng: # Reverse logic for dotvecs
if newAng > bestAng: # Reverse logic for dotvecs
bestAng = newAng
bestAngIdx = i
@ -962,7 +961,6 @@ def main(context,
# Cull faceProjectionGroupList,
# Now faceProjectionGroupList is full of faces that face match the project Vecs list
for i in range(len(projectVecs)):
# Account for projectVecs having no faces.
@ -979,7 +977,6 @@ def main(context,
# XXX - note, between mathutils in 2.4 and 2.5 the order changed.
f_uv[j][:] = (MatQuat * v.co).xy
if USER_SHARE_SPACE:
# Should we collect and pack later?
islandList = getUvIslands(faceProjectionGroupList, me)
@ -990,12 +987,11 @@ def main(context,
islandList = getUvIslands(faceProjectionGroupList, me)
packIslands(islandList)
# update the mesh here if we need to.
# We want to pack all in 1 go, so pack now
if USER_SHARE_SPACE:
#XXX Window.DrawProgressBar(0.9, "Box Packing for all objects...")
# XXX Window.DrawProgressBar(0.9, "Box Packing for all objects...")
packIslands(collected_islandList)
print("Smart Projection time: %.2f" % (time.time() - time1))
@ -1006,31 +1002,32 @@ def main(context,
bpy.ops.object.mode_set(mode='EDIT')
if use_aspect:
import bmesh
aspect = context.scene.uvedit_aspect(context.active_object)
if aspect[0] > aspect[1]:
aspect[0] = aspect[1]/aspect[0];
aspect[1] = 1.0
else:
aspect[1] = aspect[0]/aspect[1];
aspect[0] = 1.0
import bmesh
aspect = context.scene.uvedit_aspect(context.active_object)
if aspect[0] > aspect[1]:
aspect[0] = aspect[1] / aspect[0]
aspect[1] = 1.0
else:
aspect[1] = aspect[0] / aspect[1]
aspect[0] = 1.0
bm = bmesh.from_edit_mesh(me)
bm = bmesh.from_edit_mesh(me)
uv_act = bm.loops.layers.uv.active
uv_act = bm.loops.layers.uv.active
faces = [f for f in bm.faces if f.select]
faces = [f for f in bm.faces if f.select]
for f in faces:
for l in f.loops:
l[uv_act].uv[0] *= aspect[0]
l[uv_act].uv[1] *= aspect[1]
for f in faces:
for l in f.loops:
l[uv_act].uv[0] *= aspect[0]
l[uv_act].uv[1] *= aspect[1]
dict_matrix.clear()
#XXX Window.DrawProgressBar(1.0, "")
#XXX Window.WaitCursor(0)
#XXX Window.RedrawAll()
# XXX Window.DrawProgressBar(1.0, "")
# XXX Window.WaitCursor(0)
# XXX Window.RedrawAll()
"""
pup_block = [\
@ -1052,41 +1049,41 @@ from bpy.props import FloatProperty, BoolProperty
class SmartProject(Operator):
"""This script projection unwraps the selected faces of a mesh """ \
"""(it operates on all selected mesh objects, and can be used """ \
"""to unwrap selected faces, or all faces)"""
"""(it operates on all selected mesh objects, and can be used """ \
"""to unwrap selected faces, or all faces)"""
bl_idname = "uv.smart_project"
bl_label = "Smart UV Project"
bl_options = {'REGISTER', 'UNDO'}
angle_limit = FloatProperty(
name="Angle Limit",
description="Lower for more projection groups, higher for less distortion",
min=1.0, max=89.0,
default=66.0,
)
name="Angle Limit",
description="Lower for more projection groups, higher for less distortion",
min=1.0, max=89.0,
default=66.0,
)
island_margin = FloatProperty(
name="Island Margin",
description="Margin to reduce bleed from adjacent islands",
unit='LENGTH', subtype='DISTANCE',
min=0.0, max=1.0,
default=0.0,
)
name="Island Margin",
description="Margin to reduce bleed from adjacent islands",
unit='LENGTH', subtype='DISTANCE',
min=0.0, max=1.0,
default=0.0,
)
user_area_weight = FloatProperty(
name="Area Weight",
description="Weight projections vector by faces with larger areas",
min=0.0, max=1.0,
default=0.0,
)
name="Area Weight",
description="Weight projections vector by faces with larger areas",
min=0.0, max=1.0,
default=0.0,
)
use_aspect = BoolProperty(
name="Correct Aspect",
description="Map UVs taking image aspect ratio into account",
default=True
)
name="Correct Aspect",
description="Map UVs taking image aspect ratio into account",
default=True
)
stretch_to_bounds = BoolProperty(
name="Stretch to UV Bounds",
description="Stretch the final output to texture bounds",
default=True,
)
name="Stretch to UV Bounds",
description="Stretch the final output to texture bounds",
default=True,
)
@classmethod
def poll(cls, context):

View File

@ -139,36 +139,36 @@ class VertexPaintDirt(Operator):
bl_options = {'REGISTER', 'UNDO'}
blur_strength = FloatProperty(
name="Blur Strength",
description="Blur strength per iteration",
min=0.01, max=1.0,
default=1.0,
)
name="Blur Strength",
description="Blur strength per iteration",
min=0.01, max=1.0,
default=1.0,
)
blur_iterations = IntProperty(
name="Blur Iterations",
description="Number of times to blur the colors (higher blurs more)",
min=0, max=40,
default=1,
)
name="Blur Iterations",
description="Number of times to blur the colors (higher blurs more)",
min=0, max=40,
default=1,
)
clean_angle = FloatProperty(
name="Highlight Angle",
description="Less than 90 limits the angle used in the tonal range",
min=0.0, max=pi,
default=pi,
unit="ROTATION",
)
name="Highlight Angle",
description="Less than 90 limits the angle used in the tonal range",
min=0.0, max=pi,
default=pi,
unit="ROTATION",
)
dirt_angle = FloatProperty(
name="Dirt Angle",
description="Less than 90 limits the angle used in the tonal range",
min=0.0, max=pi,
default=0.0,
unit="ROTATION",
)
name="Dirt Angle",
description="Less than 90 limits the angle used in the tonal range",
min=0.0, max=pi,
default=0.0,
unit="ROTATION",
)
dirt_only = BoolProperty(
name="Dirt Only",
description="Don't calculate cleans for convex areas",
default=False,
)
name="Dirt Only",
description="Don't calculate cleans for convex areas",
default=False,
)
@classmethod
def poll(cls, context):

View File

@ -39,13 +39,16 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
totface = mesh.total_face_sel
totedge = mesh.total_edge_sel
#~ totvert = mesh.total_vert_sel
# totvert = mesh.total_vert_sel
if select_mode[2] and totface == 1:
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN',
TRANSFORM_OT_translate={
"constraint_orientation": 'NORMAL',
"constraint_axis": (False, False, True)})
bpy.ops.mesh.extrude_region_move(
'INVOKE_REGION_WIN',
TRANSFORM_OT_translate={
"constraint_orientation": 'NORMAL',
"constraint_axis": (False, False, True),
}
)
elif select_mode[2] and totface > 1:
bpy.ops.mesh.extrude_faces_move('INVOKE_REGION_WIN')
elif select_mode[1] and totedge >= 1:
@ -77,25 +80,32 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
totface = mesh.total_face_sel
totedge = mesh.total_edge_sel
#~ totvert = mesh.total_vert_sel
# totvert = mesh.total_vert_sel
if totface >= 1:
if use_vert_normals:
bpy.ops.mesh.extrude_region_shrink_fatten('INVOKE_REGION_WIN',
TRANSFORM_OT_shrink_fatten={})
bpy.ops.mesh.extrude_region_shrink_fatten(
'INVOKE_REGION_WIN',
TRANSFORM_OT_shrink_fatten={},
)
else:
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN',
TRANSFORM_OT_translate={
"constraint_orientation": 'NORMAL',
"constraint_axis": (False, False, True)})
elif totedge == 1:
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN',
bpy.ops.mesh.extrude_region_move(
'INVOKE_REGION_WIN',
TRANSFORM_OT_translate={
"constraint_orientation": 'NORMAL',
# not a popular choice, too restrictive for retopo.
#~ "constraint_axis": (True, True, False)})
"constraint_axis": (False, False, False)})
"constraint_axis": (False, False, True),
},
)
elif totedge == 1:
bpy.ops.mesh.extrude_region_move(
'INVOKE_REGION_WIN',
TRANSFORM_OT_translate={
"constraint_orientation": 'NORMAL',
# not a popular choice, too restrictive for retopo.
# "constraint_axis": (True, True, False)})
"constraint_axis": (False, False, False),
})
else:
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
@ -134,40 +144,40 @@ class VIEW3D_OT_select_or_deselect_all(Operator):
bl_options = {'UNDO'}
extend = BoolProperty(
name="Extend",
description="Extend selection instead of deselecting everything first",
default=False,
)
name="Extend",
description="Extend selection instead of deselecting everything first",
default=False,
)
toggle = BoolProperty(
name="Toggle",
description="Toggle the selection",
default=False,
)
name="Toggle",
description="Toggle the selection",
default=False,
)
deselect = BoolProperty(
name="Deselect",
description="Remove from selection",
default=False,
)
name="Deselect",
description="Remove from selection",
default=False,
)
center = BoolProperty(
name="Center",
description="Use the object center when selecting, in editmode used to extend object selection",
default=False,
)
name="Center",
description="Use the object center when selecting, in editmode used to extend object selection",
default=False,
)
enumerate = BoolProperty(
name="Enumerate",
description="List objects under the mouse (object mode only)",
default=False,
)
name="Enumerate",
description="List objects under the mouse (object mode only)",
default=False,
)
object = BoolProperty(
name="Object",
description="Use object selection (editmode only)",
default=False,
)
name="Object",
description="Use object selection (editmode only)",
default=False,
)
@classmethod
def poll(cls, context):

View File

@ -36,37 +36,37 @@ from bpy.app.translations import pgettext_tip as tip_
rna_path_prop = StringProperty(
name="Context Attributes",
description="RNA context string",
maxlen=1024,
)
name="Context Attributes",
description="RNA context string",
maxlen=1024,
)
rna_reverse_prop = BoolProperty(
name="Reverse",
description="Cycle backwards",
default=False,
)
name="Reverse",
description="Cycle backwards",
default=False,
)
rna_wrap_prop = BoolProperty(
name="Wrap",
description="Wrap back to the first/last values",
default=False,
)
name="Wrap",
description="Wrap back to the first/last values",
default=False,
)
rna_relative_prop = BoolProperty(
name="Relative",
description="Apply relative to the current value (delta)",
default=False,
)
name="Relative",
description="Apply relative to the current value (delta)",
default=False,
)
rna_space_type_prop = EnumProperty(
name="Type",
items=tuple(
(e.identifier, e.name, "", e. value)
for e in bpy.types.Space.bl_rna.properties["type"].enum_items
),
default='EMPTY',
)
name="Type",
items=tuple(
(e.identifier, e.name, "", e. value)
for e in bpy.types.Space.bl_rna.properties["type"].enum_items
),
default='EMPTY',
)
def context_path_validate(context, data_path):
@ -163,14 +163,14 @@ class BRUSH_OT_active_index_set(Operator):
bl_label = "Set Brush Number"
mode = StringProperty(
name="Mode",
description="Paint mode to set brush for",
maxlen=1024,
)
name="Mode",
description="Paint mode to set brush for",
maxlen=1024,
)
index = IntProperty(
name="Number",
description="Brush number",
)
name="Number",
description="Brush number",
)
_attr_dict = {
"sculpt": "use_paint_sculpt",
@ -201,10 +201,10 @@ class WM_OT_context_set_boolean(Operator):
data_path = rna_path_prop
value = BoolProperty(
name="Value",
description="Assignment value",
default=True,
)
name="Value",
description="Assignment value",
default=True,
)
execute = execute_context_assign
@ -217,10 +217,10 @@ class WM_OT_context_set_int(Operator): # same as enum
data_path = rna_path_prop
value = IntProperty(
name="Value",
description="Assign value",
default=0,
)
name="Value",
description="Assign value",
default=0,
)
relative = rna_relative_prop
execute = execute_context_assign
@ -234,10 +234,10 @@ class WM_OT_context_scale_float(Operator):
data_path = rna_path_prop
value = FloatProperty(
name="Value",
description="Assign value",
default=1.0,
)
name="Value",
description="Assign value",
default=1.0,
)
def execute(self, context):
data_path = self.data_path
@ -262,15 +262,15 @@ class WM_OT_context_scale_int(Operator):
data_path = rna_path_prop
value = FloatProperty(
name="Value",
description="Assign value",
default=1.0,
)
name="Value",
description="Assign value",
default=1.0,
)
always_step = BoolProperty(
name="Always Step",
description="Always adjust the value by a minimum of 1 when 'value' is not 1.0",
default=True,
)
name="Always Step",
description="Always adjust the value by a minimum of 1 when 'value' is not 1.0",
default=True,
)
def execute(self, context):
data_path = self.data_path
@ -305,10 +305,10 @@ class WM_OT_context_set_float(Operator): # same as enum
data_path = rna_path_prop
value = FloatProperty(
name="Value",
description="Assignment value",
default=0.0,
)
name="Value",
description="Assignment value",
default=0.0,
)
relative = rna_relative_prop
execute = execute_context_assign
@ -322,10 +322,10 @@ class WM_OT_context_set_string(Operator): # same as enum
data_path = rna_path_prop
value = StringProperty(
name="Value",
description="Assign value",
maxlen=1024,
)
name="Value",
description="Assign value",
maxlen=1024,
)
execute = execute_context_assign
@ -338,10 +338,10 @@ class WM_OT_context_set_enum(Operator):
data_path = rna_path_prop
value = StringProperty(
name="Value",
description="Assignment value (as a string)",
maxlen=1024,
)
name="Value",
description="Assignment value (as a string)",
maxlen=1024,
)
execute = execute_context_assign
@ -354,10 +354,10 @@ class WM_OT_context_set_value(Operator):
data_path = rna_path_prop
value = StringProperty(
name="Value",
description="Assignment value (as a string)",
maxlen=1024,
)
name="Value",
description="Assignment value (as a string)",
maxlen=1024,
)
def execute(self, context):
data_path = self.data_path
@ -394,15 +394,15 @@ class WM_OT_context_toggle_enum(Operator):
data_path = rna_path_prop
value_1 = StringProperty(
name="Value",
description="Toggle enum",
maxlen=1024,
)
name="Value",
description="Toggle enum",
maxlen=1024,
)
value_2 = StringProperty(
name="Value",
description="Toggle enum",
maxlen=1024,
)
name="Value",
description="Toggle enum",
maxlen=1024,
)
def execute(self, context):
data_path = self.data_path
@ -426,7 +426,7 @@ class WM_OT_context_toggle_enum(Operator):
class WM_OT_context_cycle_int(Operator):
"""Set a context value (useful for cycling active material, """ \
"""vertex keys, groups, etc.)"""
"""vertex keys, groups, etc.)"""
bl_idname = "wm.context_cycle_int"
bl_label = "Context Int Cycle"
bl_options = {'UNDO', 'INTERNAL'}
@ -519,7 +519,7 @@ class WM_OT_context_cycle_enum(Operator):
class WM_OT_context_cycle_array(Operator):
"""Set a context array value """ \
"""(useful for cycling the active mesh edit mode)"""
"""(useful for cycling the active mesh edit mode)"""
bl_idname = "wm.context_cycle_array"
bl_label = "Context Array Cycle"
bl_options = {'UNDO', 'INTERNAL'}
@ -603,15 +603,15 @@ class WM_OT_operator_pie_enum(Operator):
bl_label = "Operator Enum Pie"
bl_options = {'UNDO', 'INTERNAL'}
data_path = StringProperty(
name="Operator",
description="Operator name (in python as string)",
maxlen=1024,
)
name="Operator",
description="Operator name (in python as string)",
maxlen=1024,
)
prop_string = StringProperty(
name="Property",
description="Property name (as a string)",
maxlen=1024,
)
name="Property",
description="Property name (as a string)",
maxlen=1024,
)
def invoke(self, context, event):
wm = context.window_manager
@ -648,10 +648,10 @@ class WM_OT_context_set_id(Operator):
data_path = rna_path_prop
value = StringProperty(
name="Value",
description="Assign value",
maxlen=1024,
)
name="Value",
description="Assign value",
maxlen=1024,
)
def execute(self, context):
value = self.value
@ -679,16 +679,16 @@ class WM_OT_context_set_id(Operator):
doc_id = StringProperty(
name="Doc ID",
maxlen=1024,
options={'HIDDEN'},
)
name="Doc ID",
maxlen=1024,
options={'HIDDEN'},
)
data_path_iter = StringProperty(
description="The data path relative to the context, must point to an iterable")
description="The data path relative to the context, must point to an iterable")
data_path_item = StringProperty(
description="The data path from each iterable to the value (int or float)")
description="The data path from each iterable to the value (int or float)")
class WM_OT_context_collection_boolean_set(Operator):
@ -701,12 +701,12 @@ class WM_OT_context_collection_boolean_set(Operator):
data_path_item = data_path_item
type = EnumProperty(
name="Type",
items=(('TOGGLE', "Toggle", ""),
('ENABLE', "Enable", ""),
('DISABLE', "Disable", ""),
),
)
name="Type",
items=(('TOGGLE', "Toggle", ""),
('ENABLE', "Enable", ""),
('DISABLE', "Disable", ""),
),
)
def execute(self, context):
data_path_iter = self.data_path_iter
@ -759,18 +759,18 @@ class WM_OT_context_modal_mouse(Operator):
data_path_iter = data_path_iter
data_path_item = data_path_item
header_text = StringProperty(
name="Header Text",
description="Text to display in header during scale",
)
name="Header Text",
description="Text to display in header during scale",
)
input_scale = FloatProperty(
description="Scale the mouse movement by this value before applying the delta",
default=0.01,
)
description="Scale the mouse movement by this value before applying the delta",
default=0.01,
)
invert = BoolProperty(
description="Invert the mouse input",
default=False,
)
description="Invert the mouse input",
default=False,
)
initial_x = IntProperty(options={'HIDDEN'})
def _values_store(self, context):
@ -865,9 +865,9 @@ class WM_OT_url_open(Operator):
bl_options = {'INTERNAL'}
url = StringProperty(
name="URL",
description="URL to open",
)
name="URL",
description="URL to open",
)
def execute(self, context):
import webbrowser
@ -882,9 +882,9 @@ class WM_OT_path_open(Operator):
bl_options = {'INTERNAL'}
filepath = StringProperty(
subtype='FILE_PATH',
options={'SKIP_SAVE'},
)
subtype='FILE_PATH',
options={'SKIP_SAVE'},
)
def execute(self, context):
import sys
@ -1068,44 +1068,44 @@ class WM_OT_doc_view(Operator):
rna_path = StringProperty(
name="Property Edit",
description="Property data_path edit",
maxlen=1024,
options={'HIDDEN'},
)
name="Property Edit",
description="Property data_path edit",
maxlen=1024,
options={'HIDDEN'},
)
rna_value = StringProperty(
name="Property Value",
description="Property value edit",
maxlen=1024,
)
name="Property Value",
description="Property value edit",
maxlen=1024,
)
rna_property = StringProperty(
name="Property Name",
description="Property name edit",
maxlen=1024,
)
name="Property Name",
description="Property name edit",
maxlen=1024,
)
rna_min = FloatProperty(
name="Min",
default=-10000.0,
precision=3,
)
name="Min",
default=-10000.0,
precision=3,
)
rna_max = FloatProperty(
name="Max",
default=10000.0,
precision=3,
)
name="Max",
default=10000.0,
precision=3,
)
rna_use_soft_limits = BoolProperty(
name="Use Soft Limits",
)
name="Use Soft Limits",
)
rna_is_overridable_static = BoolProperty(
name="Is Statically Overridable",
default=False,
)
name="Is Statically Overridable",
default=False,
)
class WM_OT_properties_edit(Operator):
@ -1124,8 +1124,8 @@ class WM_OT_properties_edit(Operator):
soft_min = rna_min
soft_max = rna_max
description = StringProperty(
name="Tooltip",
)
name="Tooltip",
)
def _cmp_props_get(self):
# Changing these properties will refresh the UI
@ -1363,9 +1363,9 @@ class WM_OT_properties_context_change(Operator):
bl_options = {'INTERNAL'}
context = StringProperty(
name="Context",
maxlen=64,
)
name="Context",
maxlen=64,
)
def execute(self, context):
context.space_data.context = self.context
@ -1401,8 +1401,8 @@ class WM_OT_keyconfig_activate(Operator):
bl_label = "Activate Keyconfig"
filepath = StringProperty(
subtype='FILE_PATH',
)
subtype='FILE_PATH',
)
def execute(self, context):
if bpy.utils.keyconfig_set(self.filepath, report=self.report):
@ -1436,8 +1436,8 @@ class WM_OT_appconfig_activate(Operator):
bl_label = "Activate Application Configuration"
filepath = StringProperty(
subtype='FILE_PATH',
)
subtype='FILE_PATH',
)
def execute(self, context):
import os
@ -1461,9 +1461,9 @@ class WM_OT_sysinfo(Operator):
bl_label = "Save System Info"
filepath = StringProperty(
subtype='FILE_PATH',
options={'SKIP_SAVE'},
)
subtype='FILE_PATH',
options={'SKIP_SAVE'},
)
def execute(self, context):
import sys_info
@ -1475,7 +1475,7 @@ class WM_OT_sysinfo(Operator):
if not self.filepath:
self.filepath = os.path.join(
os.path.expanduser("~"), "system-info.txt")
os.path.expanduser("~"), "system-info.txt")
wm = context.window_manager
wm.fileselect_add(self)
@ -1539,29 +1539,29 @@ class WM_OT_keyconfig_import(Operator):
bl_label = "Import Key Configuration..."
filepath = StringProperty(
subtype='FILE_PATH',
default="keymap.py",
)
subtype='FILE_PATH',
default="keymap.py",
)
filter_folder = BoolProperty(
name="Filter folders",
default=True,
options={'HIDDEN'},
)
name="Filter folders",
default=True,
options={'HIDDEN'},
)
filter_text = BoolProperty(
name="Filter text",
default=True,
options={'HIDDEN'},
)
name="Filter text",
default=True,
options={'HIDDEN'},
)
filter_python = BoolProperty(
name="Filter python",
default=True,
options={'HIDDEN'},
)
name="Filter python",
default=True,
options={'HIDDEN'},
)
keep_original = BoolProperty(
name="Keep original",
description="Keep original file after copying to configuration folder",
default=True,
)
name="Keep original",
description="Keep original file after copying to configuration folder",
default=True,
)
def execute(self, context):
import os
@ -1606,24 +1606,24 @@ class WM_OT_keyconfig_export(Operator):
bl_label = "Export Key Configuration..."
filepath = StringProperty(
subtype='FILE_PATH',
default="keymap.py",
)
subtype='FILE_PATH',
default="keymap.py",
)
filter_folder = BoolProperty(
name="Filter folders",
default=True,
options={'HIDDEN'},
)
name="Filter folders",
default=True,
options={'HIDDEN'},
)
filter_text = BoolProperty(
name="Filter text",
default=True,
options={'HIDDEN'},
)
name="Filter text",
default=True,
options={'HIDDEN'},
)
filter_python = BoolProperty(
name="Filter python",
default=True,
options={'HIDDEN'},
)
name="Filter python",
default=True,
options={'HIDDEN'},
)
def execute(self, context):
from bpy_extras import keyconfig_utils
@ -1656,9 +1656,9 @@ class WM_OT_keymap_restore(Operator):
bl_label = "Restore Key Map(s)"
all = BoolProperty(
name="All Keymaps",
description="Restore all keymaps to default",
)
name="All Keymaps",
description="Restore all keymaps to default",
)
def execute(self, context):
wm = context.window_manager
@ -1679,9 +1679,9 @@ class WM_OT_keyitem_restore(Operator):
bl_label = "Restore Key Map Item"
item_id = IntProperty(
name="Item Identifier",
description="Identifier of the item to remove",
)
name="Item Identifier",
description="Identifier of the item to remove",
)
@classmethod
def poll(cls, context):
@ -1726,9 +1726,9 @@ class WM_OT_keyitem_remove(Operator):
bl_label = "Remove Key Map Item"
item_id = IntProperty(
name="Item Identifier",
description="Identifier of the item to remove",
)
name="Item Identifier",
description="Identifier of the item to remove",
)
@classmethod
def poll(cls, context):
@ -1794,9 +1794,9 @@ class WM_OT_addon_enable(Operator):
bl_label = "Enable Add-on"
module = StringProperty(
name="Module",
description="Module name of the add-on to enable",
)
name="Module",
description="Module name of the add-on to enable",
)
def execute(self, context):
import addon_utils
@ -1840,9 +1840,9 @@ class WM_OT_addon_disable(Operator):
bl_label = "Disable Add-on"
module = StringProperty(
name="Module",
description="Module name of the add-on to disable",
)
name="Module",
description="Module name of the add-on to disable",
)
def execute(self, context):
import addon_utils
@ -1869,8 +1869,8 @@ class WM_OT_owner_enable(Operator):
bl_label = "Enable Add-on"
owner_id = StringProperty(
name="UI Tag",
)
name="UI Tag",
)
def execute(self, context):
workspace = context.workspace
@ -1884,8 +1884,8 @@ class WM_OT_owner_disable(Operator):
bl_label = "Disable UI Tag"
owner_id = StringProperty(
name="UI Tag",
)
name="UI Tag",
)
def execute(self, context):
workspace = context.workspace
@ -1900,22 +1900,22 @@ class WM_OT_theme_install(Operator):
bl_label = "Install Theme..."
overwrite = BoolProperty(
name="Overwrite",
description="Remove existing theme file if exists",
default=True,
)
name="Overwrite",
description="Remove existing theme file if exists",
default=True,
)
filepath = StringProperty(
subtype='FILE_PATH',
)
subtype='FILE_PATH',
)
filter_folder = BoolProperty(
name="Filter folders",
default=True,
options={'HIDDEN'},
)
name="Filter folders",
default=True,
options={'HIDDEN'},
)
filter_glob = StringProperty(
default="*.xml",
options={'HIDDEN'},
)
default="*.xml",
options={'HIDDEN'},
)
def execute(self, context):
import os
@ -1977,33 +1977,33 @@ class WM_OT_addon_install(Operator):
bl_label = "Install Add-on from File..."
overwrite = BoolProperty(
name="Overwrite",
description="Remove existing add-ons with the same ID",
default=True,
)
name="Overwrite",
description="Remove existing add-ons with the same ID",
default=True,
)
target = EnumProperty(
name="Target Path",
items=(('DEFAULT', "Default", ""),
('PREFS', "User Prefs", "")),
)
name="Target Path",
items=(('DEFAULT', "Default", ""),
('PREFS', "User Prefs", "")),
)
filepath = StringProperty(
subtype='FILE_PATH',
)
subtype='FILE_PATH',
)
filter_folder = BoolProperty(
name="Filter folders",
default=True,
options={'HIDDEN'},
)
name="Filter folders",
default=True,
options={'HIDDEN'},
)
filter_python = BoolProperty(
name="Filter python",
default=True,
options={'HIDDEN'},
)
name="Filter python",
default=True,
options={'HIDDEN'},
)
filter_glob = StringProperty(
default="*.py;*.zip",
options={'HIDDEN'},
)
default="*.py;*.zip",
options={'HIDDEN'},
)
def execute(self, context):
import addon_utils
@ -2131,9 +2131,9 @@ class WM_OT_addon_remove(Operator):
bl_label = "Remove Add-on"
module = StringProperty(
name="Module",
description="Module name of the add-on to remove",
)
name="Module",
description="Module name of the add-on to remove",
)
@staticmethod
def path_from_addon(module):
@ -2191,9 +2191,9 @@ class WM_OT_addon_expand(Operator):
bl_options = {'INTERNAL'}
module = StringProperty(
name="Module",
description="Module name of the add-on to expand",
)
name="Module",
description="Module name of the add-on to expand",
)
def execute(self, context):
import addon_utils
@ -2215,9 +2215,9 @@ class WM_OT_addon_userpref_show(Operator):
bl_options = {'INTERNAL'}
module = StringProperty(
name="Module",
description="Module name of the add-on to expand",
)
name="Module",
description="Module name of the add-on to expand",
)
def execute(self, context):
import addon_utils
@ -2246,23 +2246,23 @@ class WM_OT_app_template_install(Operator):
bl_label = "Install Template from File..."
overwrite = BoolProperty(
name="Overwrite",
description="Remove existing template with the same ID",
default=True,
)
name="Overwrite",
description="Remove existing template with the same ID",
default=True,
)
filepath = StringProperty(
subtype='FILE_PATH',
)
subtype='FILE_PATH',
)
filter_folder = BoolProperty(
name="Filter folders",
default=True,
options={'HIDDEN'},
)
name="Filter folders",
default=True,
options={'HIDDEN'},
)
filter_glob = StringProperty(
default="*.zip",
options={'HIDDEN'},
)
default="*.zip",
options={'HIDDEN'},
)
def execute(self, context):
import traceback
@ -2345,16 +2345,16 @@ class WM_OT_tool_set_by_name(Operator):
bl_label = "Set Tool By Name"
name = StringProperty(
name="Text",
description="Display name of the tool",
)
name="Text",
description="Display name of the tool",
)
cycle = BoolProperty(
name="Cycle",
description="Cycle through tools in this group",
default=False,
options={'SKIP_SAVE'},
)
name="Cycle",
description="Cycle through tools in this group",
default=False,
options={'SKIP_SAVE'},
)
space_type = rna_space_type_prop
@ -2411,21 +2411,21 @@ class WM_OT_studiolight_install(Operator):
bl_label = "Install Custom Studio Light"
files = CollectionProperty(
name="File Path",
type=OperatorFileListElement,
)
name="File Path",
type=OperatorFileListElement,
)
directory = StringProperty(
subtype='DIR_PATH',
)
subtype='DIR_PATH',
)
filter_folder = BoolProperty(
name="Filter folders",
default=True,
options={'HIDDEN'},
)
name="Filter folders",
default=True,
options={'HIDDEN'},
)
filter_glob = StringProperty(
default="*.png;*.jpg;*.hdr;*.exr",
options={'HIDDEN'},
)
default="*.png;*.jpg;*.hdr;*.exr",
options={'HIDDEN'},
)
orientation = EnumProperty(
items=(
("MATCAP", "MatCap", ""),

View File

@ -59,6 +59,8 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
# Generic Layout - Used as base for filtering popovers used in all animation editors
# Used for DopeSheet, NLA, and Graph Editors
class DopesheetFilterPopoverBase:
bl_region_type = 'HEADER'
bl_label = "Filters"
@ -211,11 +213,13 @@ class DOPESHEET_HT_header(Header):
TIME_HT_editor_buttons.draw_header(context, layout)
else:
layout.prop(st, "ui_mode", text="")
layout.popover(space_type='DOPESHEET_EDITOR',
region_type='HEADER',
panel_type="DOPESHEET_PT_filters",
text="",
icon='FILTER')
layout.popover(
space_type='DOPESHEET_EDITOR',
region_type='HEADER',
panel_type="DOPESHEET_PT_filters",
text="",
icon='FILTER',
)
DOPESHEET_MT_editor_menus.draw_collapsible(context, layout)
DOPESHEET_HT_editor_buttons.draw_header(context, layout)

View File

@ -23,7 +23,7 @@ from bpy.types import Header, Menu, Panel
from .space_dopesheet import (
DopesheetFilterPopoverBase,
dopesheet_filter,
)
)
class GRAPH_HT_header(Header):
@ -41,11 +41,13 @@ class GRAPH_HT_header(Header):
# Now a exposed as a sub-space type
# layout.prop(st, "mode", text="")
layout.popover(space_type='GRAPH_EDITOR',
region_type='HEADER',
panel_type="GRAPH_PT_filters",
text="",
icon='FILTER')
layout.popover(
space_type='GRAPH_EDITOR',
region_type='HEADER',
panel_type="GRAPH_PT_filters",
text="",
icon='FILTER',
)
GRAPH_MT_editor_menus.draw_collapsible(context, layout)

View File

@ -23,7 +23,7 @@ from bpy.types import Header, Menu, Panel
from .space_dopesheet import (
DopesheetFilterPopoverBase,
dopesheet_filter,
)
)
class NLA_HT_header(Header):
@ -37,11 +37,13 @@ class NLA_HT_header(Header):
row = layout.row(align=True)
row.template_header()
layout.popover(space_type='NLA_EDITOR',
region_type='HEADER',
panel_type="NLA_PT_filters",
text="",
icon='FILTER')
layout.popover(
space_type='NLA_EDITOR',
region_type='HEADER',
panel_type="NLA_PT_filters",
text="",
icon='FILTER',
)
NLA_MT_editor_menus.draw_collapsible(context, layout)

View File

@ -91,14 +91,18 @@ class TIME_MT_editor_menus(Menu):
@staticmethod
def draw_menus(layout, context):
layout.popover(space_type='DOPESHEET_EDITOR',
region_type='HEADER',
panel_type="TIME_PT_playback",
text="Playback")
layout.popover(space_type='DOPESHEET_EDITOR',
region_type='HEADER',
panel_type="TIME_PT_keyframing_settings",
text="Keying")
layout.popover(
space_type='DOPESHEET_EDITOR',
region_type='HEADER',
panel_type="TIME_PT_playback",
text="Playback",
)
layout.popover(
space_type='DOPESHEET_EDITOR',
region_type='HEADER',
panel_type="TIME_PT_keyframing_settings",
text="Keying",
)
layout.menu("TIME_MT_view")
layout.menu("TIME_MT_marker")

View File

@ -8,7 +8,7 @@ bl_info = {
"warning": "",
"wiki_url": "",
"category": "Add Mesh",
}
}
import bpy
@ -22,11 +22,12 @@ def add_object(self, context):
scale_x = self.scale.x
scale_y = self.scale.y
verts = [Vector((-1 * scale_x, 1 * scale_y, 0)),
Vector((1 * scale_x, 1 * scale_y, 0)),
Vector((1 * scale_x, -1 * scale_y, 0)),
Vector((-1 * scale_x, -1 * scale_y, 0)),
]
verts = [
Vector((-1 * scale_x, 1 * scale_y, 0)),
Vector((1 * scale_x, 1 * scale_y, 0)),
Vector((1 * scale_x, -1 * scale_y, 0)),
Vector((-1 * scale_x, -1 * scale_y, 0)),
]
edges = []
faces = [[0, 1, 2, 3]]
@ -45,11 +46,11 @@ class OBJECT_OT_add_object(Operator, AddObjectHelper):
bl_options = {'REGISTER', 'UNDO'}
scale = FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
@ -72,7 +73,7 @@ def add_object_manual_map():
url_manual_prefix = "https://docs.blender.org/manual/en/dev/"
url_manual_mapping = (
("bpy.ops.mesh.add_object", "editors/3dview/object"),
)
)
return url_manual_prefix, url_manual_mapping

View File

@ -73,21 +73,27 @@ def main():
# When --help or no args are given, print this help
usage_text = (
"Run blender in background mode with this script:"
" blender --background --python " + __file__ + " -- [options]"
)
"Run blender in background mode with this script:"
" blender --background --python " + __file__ + " -- [options]"
)
parser = argparse.ArgumentParser(description=usage_text)
# Example utility, add some text and renders or saves it (with options)
# Possible types are: string, int, long, choice, float and complex.
parser.add_argument("-t", "--text", dest="text", type=str, required=True,
help="This text will be used to render an image")
parser.add_argument(
"-t", "--text", dest="text", type=str, required=True,
help="This text will be used to render an image",
)
parser.add_argument("-s", "--save", dest="save_path", metavar='FILE',
help="Save the generated file to the specified path")
parser.add_argument("-r", "--render", dest="render_path", metavar='FILE',
help="Render an image to the specified path")
parser.add_argument(
"-s", "--save", dest="save_path", metavar='FILE',
help="Save the generated file to the specified path",
)
parser.add_argument(
"-r", "--render", dest="render_path", metavar='FILE',
help="Render an image to the specified path",
)
args = parser.parse_args(argv) # In this example we wont use the args

View File

@ -28,7 +28,7 @@ for obj in selection:
bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True)
## Can be used for multiple formats
# Can be used for multiple formats
# bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
obj.select_set(action='DESELECT')

View File

@ -124,6 +124,8 @@ from nodeitems_utils import NodeCategory, NodeItem
# our own base class with an appropriate poll function,
# so the categories only show up in our own tree type
class MyNodeCategory(NodeCategory):
@classmethod
def poll(cls, context):
@ -159,6 +161,7 @@ classes = (
MyCustomNode,
)
def register():
from bpy.utils import register_class
for cls in classes:

View File

@ -16,6 +16,7 @@ from bpy.props import (
FloatVectorProperty,
)
def main(context, plane_co, plane_no):
obj = context.active_object
matrix = obj.matrix_world.copy()
@ -218,6 +219,7 @@ classes = (
SelectSideOfPlaneManipulatorGroup,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
@ -227,5 +229,6 @@ def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
if __name__ == "__main__":
register()

View File

@ -8,6 +8,7 @@ from bpy.types import (
ManipulatorGroup,
)
class MyCameraWidgetGroup(ManipulatorGroup):
bl_idname = "OBJECT_WGT_test_camera"
bl_label = "Object Camera Test Widget"
@ -45,4 +46,5 @@ class MyCameraWidgetGroup(ManipulatorGroup):
mpr = self.roll_widget
mpr.matrix_basis = ob.matrix_world.normalized()
bpy.utils.register_class(MyCameraWidgetGroup)

View File

@ -9,6 +9,7 @@ from bpy.types import (
ManipulatorGroup,
)
class MyLampWidgetGroup(ManipulatorGroup):
bl_idname = "OBJECT_WGT_lamp_test"
bl_label = "Test Lamp Widget"
@ -42,4 +43,5 @@ class MyLampWidgetGroup(ManipulatorGroup):
mpr = self.energy_widget
mpr.matrix_basis = ob.matrix_world.normalized()
bpy.utils.register_class(MyLampWidgetGroup)

View File

@ -26,26 +26,28 @@ class ExportSomeData(Operator, ExportHelper):
filename_ext = ".txt"
filter_glob = StringProperty(
default="*.txt",
options={'HIDDEN'},
maxlen=255, # Max internal buffer length, longer would be clamped.
)
default="*.txt",
options={'HIDDEN'},
maxlen=255, # Max internal buffer length, longer would be clamped.
)
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
use_setting = BoolProperty(
name="Example Boolean",
description="Example Tooltip",
default=True,
)
name="Example Boolean",
description="Example Tooltip",
default=True,
)
type = EnumProperty(
name="Example Enum",
description="Choose between two items",
items=(('OPT_A', "First Option", "Description one"),
('OPT_B', "Second Option", "Description two")),
default='OPT_A',
)
name="Example Enum",
description="Choose between two items",
items=(
('OPT_A', "First Option", "Description one"),
('OPT_B', "Second Option", "Description two"),
),
default='OPT_A',
)
def execute(self, context):
return write_some_data(context, self.filepath, self.use_setting)

View File

@ -29,26 +29,28 @@ class ImportSomeData(Operator, ImportHelper):
filename_ext = ".txt"
filter_glob = StringProperty(
default="*.txt",
options={'HIDDEN'},
maxlen=255, # Max internal buffer length, longer would be clamped.
)
default="*.txt",
options={'HIDDEN'},
maxlen=255, # Max internal buffer length, longer would be clamped.
)
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
use_setting = BoolProperty(
name="Example Boolean",
description="Example Tooltip",
default=True,
)
name="Example Boolean",
description="Example Tooltip",
default=True,
)
type = EnumProperty(
name="Example Enum",
description="Choose between two items",
items=(('OPT_A', "First Option", "Description one"),
('OPT_B', "Second Option", "Description two")),
default='OPT_A',
)
name="Example Enum",
description="Choose between two items",
items=(
('OPT_A', "First Option", "Description one"),
('OPT_B', "Second Option", "Description two"),
),
default='OPT_A',
)
def execute(self, context):
return read_some_data(context, self.filepath, self.use_setting)

View File

@ -8,23 +8,25 @@ def add_box(width, height, depth):
no actual mesh data creation is done here.
"""
verts = [(+1.0, +1.0, -1.0),
(+1.0, -1.0, -1.0),
(-1.0, -1.0, -1.0),
(-1.0, +1.0, -1.0),
(+1.0, +1.0, +1.0),
(+1.0, -1.0, +1.0),
(-1.0, -1.0, +1.0),
(-1.0, +1.0, +1.0),
]
verts = [
(+1.0, +1.0, -1.0),
(+1.0, -1.0, -1.0),
(-1.0, -1.0, -1.0),
(-1.0, +1.0, -1.0),
(+1.0, +1.0, +1.0),
(+1.0, -1.0, +1.0),
(-1.0, -1.0, +1.0),
(-1.0, +1.0, +1.0),
]
faces = [(0, 1, 2, 3),
(4, 7, 6, 5),
(0, 4, 5, 1),
(1, 5, 6, 2),
(2, 6, 7, 3),
(4, 0, 3, 7),
]
faces = [
(0, 1, 2, 3),
(4, 7, 6, 5),
(0, 4, 5, 1),
(1, 5, 6, 2),
(2, 6, 7, 3),
(4, 0, 3, 7),
]
# apply size
for i, v in enumerate(verts):
@ -48,50 +50,51 @@ class AddBox(bpy.types.Operator):
bl_options = {'REGISTER', 'UNDO'}
width = FloatProperty(
name="Width",
description="Box Width",
min=0.01, max=100.0,
default=1.0,
)
name="Width",
description="Box Width",
min=0.01, max=100.0,
default=1.0,
)
height = FloatProperty(
name="Height",
description="Box Height",
min=0.01, max=100.0,
default=1.0,
)
name="Height",
description="Box Height",
min=0.01, max=100.0,
default=1.0,
)
depth = FloatProperty(
name="Depth",
description="Box Depth",
min=0.01, max=100.0,
default=1.0,
)
name="Depth",
description="Box Depth",
min=0.01, max=100.0,
default=1.0,
)
layers = BoolVectorProperty(
name="Layers",
description="Object Layers",
size=20,
options={'HIDDEN', 'SKIP_SAVE'},
)
name="Layers",
description="Object Layers",
size=20,
options={'HIDDEN', 'SKIP_SAVE'},
)
# generic transform props
view_align = BoolProperty(
name="Align to View",
default=False,
)
name="Align to View",
default=False,
)
location = FloatVectorProperty(
name="Location",
subtype='TRANSLATION',
)
name="Location",
subtype='TRANSLATION',
)
rotation = FloatVectorProperty(
name="Rotation",
subtype='EULER',
)
name="Rotation",
subtype='EULER',
)
def execute(self, context):
verts_loc, faces = add_box(self.width,
self.height,
self.depth,
)
verts_loc, faces = add_box(
self.width,
self.height,
self.depth,
)
mesh = bpy.data.meshes.new("Box")
@ -127,6 +130,7 @@ def unregister():
bpy.utils.unregister_class(AddBox)
bpy.types.INFO_MT_mesh_add.remove(menu_func)
if __name__ == "__main__":
register()

View File

@ -75,5 +75,6 @@ def register():
def unregister():
bpy.utils.unregister_class(ModalDrawOperator)
if __name__ == "__main__":
register()

View File

@ -9,9 +9,9 @@ class ViewOperator(bpy.types.Operator):
bl_label = "Simple View Operator"
offset = FloatVectorProperty(
name="Offset",
size=3,
)
name="Offset",
size=3,
)
def execute(self, context):
v3d = context.space_data

View File

@ -42,6 +42,7 @@ def unregister():
bpy.types.INFO_HT_header.remove(draw_item)
if __name__ == "__main__":
register()

View File

@ -19,6 +19,7 @@ def register():
def unregister():
bpy.utils.unregister_class(SimpleCustomMenu)
if __name__ == "__main__":
register()

View File

@ -89,19 +89,19 @@ preview_collections = {}
def register():
from bpy.types import WindowManager
from bpy.props import (
StringProperty,
EnumProperty,
)
StringProperty,
EnumProperty,
)
WindowManager.my_previews_dir = StringProperty(
name="Folder Path",
subtype='DIR_PATH',
default=""
)
name="Folder Path",
subtype='DIR_PATH',
default=""
)
WindowManager.my_previews = EnumProperty(
items=enum_previews_from_directory_items,
)
items=enum_previews_from_directory_items,
)
# Note that preview collections returned by bpy.utils.previews
# are regular Python objects - you can use them to store custom data.

View File

@ -368,7 +368,8 @@ void MESH_OT_bisect(struct wmOperatorType *ot)
RNA_def_boolean(ot->srna, "clear_inner", false, "Clear Inner", "Remove geometry behind the plane");
RNA_def_boolean(ot->srna, "clear_outer", false, "Clear Outer", "Remove geometry in front of the plane");
RNA_def_float(ot->srna, "threshold", 0.0001, 0.0, 10.0, "Axis Threshold", "", 0.00001, 0.1);
RNA_def_float(ot->srna, "threshold", 0.0001, 0.0, 10.0, "Axis Threshold",
"Preserves the existing geometry along the cut plane", 0.00001, 0.1);
WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT);

View File

@ -4354,11 +4354,13 @@ void MESH_OT_fill_grid(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
prop = RNA_def_int(ot->srna, "span", 1, 1, 1000, "Span", "Number of sides (zero disables)", 1, 100);
prop = RNA_def_int(ot->srna, "span", 1, 1, 1000, "Span", "Number of grid columns", 1, 100);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_int(ot->srna, "offset", 0, -1000, 1000, "Offset", "Number of sides (zero disables)", -100, 100);
prop = RNA_def_int(ot->srna, "offset", 0, -1000, 1000, "Offset",
"Vertex that is the corner of the grid", -100, 100);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
RNA_def_boolean(ot->srna, "use_interp_simple", false, "Simple Blending", "");
RNA_def_boolean(ot->srna, "use_interp_simple", false, "Simple Blending",
"Use simple interpolation of grid vertices");
}
/** \} */
@ -6610,7 +6612,8 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot)
ot->srna, "direction", rna_enum_symmetrize_direction_items,
BMO_SYMMETRIZE_NEGATIVE_X,
"Direction", "Which sides to copy from and to");
RNA_def_float(ot->srna, "threshold", 1e-4f, 0.0f, 10.0f, "Threshold", "", 1e-5f, 0.1f);
RNA_def_float(ot->srna, "threshold", 1e-4f, 0.0f, 10.0f, "Threshold",
"Limit for snap middle vertices to the axis center", 1e-5f, 0.1f);
}
/** \} */
@ -6741,9 +6744,11 @@ void MESH_OT_symmetry_snap(struct wmOperatorType *ot)
ot->srna, "direction", rna_enum_symmetrize_direction_items,
BMO_SYMMETRIZE_NEGATIVE_X,
"Direction", "Which sides to copy from and to");
RNA_def_float_distance(ot->srna, "threshold", 0.05f, 0.0f, 10.0f, "Threshold", "", 1e-4f, 1.0f);
RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 1.0f, "Factor", "", 0.0f, 1.0f);
RNA_def_boolean(ot->srna, "use_center", true, "Center", "Snap mid verts to the axis center");
RNA_def_float_distance(ot->srna, "threshold", 0.05f, 0.0f, 10.0f, "Threshold",
"Distance within which matching vertices are searched", 1e-4f, 1.0f);
RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 1.0f, "Factor",
"Mix factor of the locations of the vertices", 0.0f, 1.0f);
RNA_def_boolean(ot->srna, "use_center", true, "Center", "Snap middle vertices to the axis center");
}
/** \} */

View File

@ -358,9 +358,9 @@ void WM_operator_properties_checker_interval(wmOperatorType *ot, bool nth_can_di
{
const int nth_default = nth_can_disable ? 1 : 2;
const int nth_min = min_ii(nth_default, 2);
RNA_def_int(ot->srna, "nth", nth_default, nth_min, INT_MAX, "Nth Selection", "", nth_min, 100);
RNA_def_int(ot->srna, "skip", 1, 1, INT_MAX, "Skip", "", 1, 100);
RNA_def_int(ot->srna, "offset", 0, INT_MIN, INT_MAX, "Offset", "", -100, 100);
RNA_def_int(ot->srna, "nth", nth_default, nth_min, INT_MAX, "Nth Element", "Skip every Nth element", nth_min, 100);
RNA_def_int(ot->srna, "skip", 1, 1, INT_MAX, "Skip", "Number of elements to skip at once", 1, 100);
RNA_def_int(ot->srna, "offset", 0, INT_MIN, INT_MAX, "Offset", "Offset from the starting point", -100, 100);
}
void WM_operator_properties_checker_interval_from_op(