Merged 38568-38822

This commit is contained in:
Jason Hays 2011-07-29 17:57:46 +00:00
commit 5b6da0c1d1
114 changed files with 1635 additions and 716 deletions

@ -155,6 +155,7 @@ option(WITH_IMAGE_DDS "Enable DDS Image Support" ON)
option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON) option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON)
option(WITH_IMAGE_HDR "Enable HDR Image Support" ON) option(WITH_IMAGE_HDR "Enable HDR Image Support" ON)
option(WITH_IMAGE_REDCODE "Enable RedCode Image Support" OFF) option(WITH_IMAGE_REDCODE "Enable RedCode Image Support" OFF)
option(WITH_IMAGE_FRAMESERVER "Enable image FrameServer Support for rendering" ON)
# Audio/Video format support # Audio/Video format support
option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF) option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF)

@ -42,9 +42,9 @@ def replace_line(f, i, text, keep_indent=True):
l = data[i] l = data[i]
ws = l[:len(l) - len(l.lstrip())] ws = l[:len(l) - len(l.lstrip())]
data[i] = "%s%s\n" % (ws, text) data[i] = "%s%s\n" % (ws, text)
file_handle = open(f, 'w') file_handle = open(f, 'w')
file_handle.writelines(data) file_handle.writelines(data)
file_handle.close() file_handle.close()
@ -182,13 +182,13 @@ def cmake_get_src(f):
if new_path_rel != l: if new_path_rel != l:
print("overly relative path:\n %s:%d\n %s\n %s" % (f, i, l, new_path_rel)) print("overly relative path:\n %s:%d\n %s\n %s" % (f, i, l, new_path_rel))
## Save time. just replace the line ## Save time. just replace the line
# replace_line(f, i - 1, new_path_rel) # replace_line(f, i - 1, new_path_rel)
else: else:
raise Exception("non existant include %s:%d -> %s" % (f, i, new_file)) raise Exception("non existant include %s:%d -> %s" % (f, i, new_file))
# print(new_file) # print(new_file)
global_h.update(set(sources_h)) global_h.update(set(sources_h))
@ -206,7 +206,7 @@ def cmake_get_src(f):
if ff not in sources_c: if ff not in sources_c:
print(" missing: " + ff) print(" missing: " + ff)
''' '''
# reset # reset
sources_h[:] = [] sources_h[:] = []
sources_c[:] = [] sources_c[:] = []

@ -30,7 +30,18 @@ Example linux usage
Windows not supported so far Windows not supported so far
""" """
from project_info import * from project_info import (SIMPLE_PROJECTFILE,
SOURCE_DIR,
CMAKE_DIR,
PROJECT_DIR,
source_list,
is_project_file,
is_c_header,
is_py,
cmake_advanced_info,
cmake_compiler_defines,
)
import os import os
from os.path import join, dirname, normpath, relpath, exists from os.path import join, dirname, normpath, relpath, exists

@ -31,7 +31,17 @@ example linux usage
python .~/blenderSVN/blender/build_files/cmake/cmake_qtcreator_project.py ~/blenderSVN/cmake python .~/blenderSVN/blender/build_files/cmake/cmake_qtcreator_project.py ~/blenderSVN/cmake
""" """
from project_info import * from project_info import (SIMPLE_PROJECTFILE,
SOURCE_DIR,
CMAKE_DIR,
PROJECT_DIR,
source_list,
is_project_file,
is_c_header,
is_py,
cmake_advanced_info,
cmake_compiler_defines,
)
import os import os
import sys import sys

@ -8,11 +8,11 @@ from bge import constraints
# get object list # get object list
objects = logic.getCurrentScene().objects objects = logic.getCurrentScene().objects
# get object named Object1 and Object 2 # get object named Object1 and Object 2
object_1 = objects["Object1"] object_1 = objects["Object1"]
object_2 = objects["Object2"] object_2 = objects["Object2"]
# want to use Edge constraint type # want to use Edge constraint type
constraint_type = 2 constraint_type = 2
@ -31,7 +31,7 @@ edge_angle_y = 1.0
edge_angle_z = 0.0 edge_angle_z = 0.0
# create an edge constraint # create an edge constraint
constraints.createConstraint( physics_id_1, physics_id_2, constraints.createConstraint(physics_id_1, physics_id_2,
constraint_type, constraint_type,
edge_position_x, edge_position_y, edge_position_z, edge_position_x, edge_position_y, edge_position_z,
edge_angle_x, edge_angle_y, edge_angle_z ) edge_angle_x, edge_angle_y, edge_angle_z)

@ -6,29 +6,31 @@ createTexture() and removeTexture() are to be called from a module Python
Controller. Controller.
""" """
from bge import logic from bge import logic
from bge import texture from bge import texture
def createTexture(cont): def createTexture(cont):
"""Create a new Dynamic Texture""" """Create a new Dynamic Texture"""
object = cont.owner object = cont.owner
# get the reference pointer (ID) of the internal texture # get the reference pointer (ID) of the internal texture
ID = texture.materialID(obj, 'IMoriginal.png') ID = texture.materialID(obj, 'IMoriginal.png')
# create a texture object # create a texture object
object_texture = texture.Texture(object, ID) object_texture = texture.Texture(object, ID)
# create a new source with an external image # create a new source with an external image
url = logic.expandPath("//newtexture.jpg") url = logic.expandPath("//newtexture.jpg")
new_source = texture.ImageFFmpeg(url) new_source = texture.ImageFFmpeg(url)
# the texture has to be stored in a permanent Python object # the texture has to be stored in a permanent Python object
logic.texture = object_texture logic.texture = object_texture
# update/replace the texture # update/replace the texture
logic.texture.source = new_source logic.texture.source = new_source
logic.texture.refresh(False) logic.texture.refresh(False)
def removeTexture(cont): def removeTexture(cont):
"""Delete the Dynamic Texture, reversing back the final to its original state.""" """Delete the Dynamic Texture, reversing back the final to its original state."""
try: try:

@ -9,14 +9,14 @@ from bge import logic
cont = logic.getCurrentController() cont = logic.getCurrentController()
obj = cont.owner obj = cont.owner
# the creation of the texture must be done once: save the # the creation of the texture must be done once: save the
# texture object in an attribute of bge.logic module makes it persistent # texture object in an attribute of bge.logic module makes it persistent
if not hasattr(logic, 'video'): if not hasattr(logic, 'video'):
# identify a static texture by name # identify a static texture by name
matID = texture.materialID(obj, 'IMvideo.png') matID = texture.materialID(obj, 'IMvideo.png')
# create a dynamic texture that will replace the static texture # create a dynamic texture that will replace the static texture
logic.video = texture.Texture(obj, matID) logic.video = texture.Texture(obj, matID)
@ -24,7 +24,7 @@ if not hasattr(logic, 'video'):
movie = logic.expandPath('//trailer_400p.ogg') movie = logic.expandPath('//trailer_400p.ogg')
logic.video.source = texture.VideoFFmpeg(movie) logic.video.source = texture.VideoFFmpeg(movie)
logic.video.source.scale = True logic.video.source.scale = True
# quick off the movie, but it wont play in the background # quick off the movie, but it wont play in the background
logic.video.source.play() logic.video.source.play()

@ -1,6 +1,7 @@
""" """
Hello World Text Example Hello World Text Example
++++++++++++++++++++++++ ++++++++++++++++++++++++
Blender Game Engine example of using the blf module. For this module to work we Blender Game Engine example of using the blf module. For this module to work we
need to use the OpenGL wrapper :class:`~bgl` as well. need to use the OpenGL wrapper :class:`~bgl` as well.
""" """
@ -11,31 +12,33 @@ from bge import logic
import bgl import bgl
import blf import blf
def init(): def init():
"""init function - runs once""" """init function - runs once"""
# create a new font object, use external ttf file # create a new font object, use external ttf file
font_path = logic.expandPath('//Zeyada.ttf') font_path = logic.expandPath('//Zeyada.ttf')
# store the font indice - to use later # store the font indice - to use later
logic.font_id = blf.load(font_path) logic.font_id = blf.load(font_path)
# set the font drawing routine to run every frame # set the font drawing routine to run every frame
scene = logic.getCurrentScene() scene = logic.getCurrentScene()
scene.post_draw=[write] scene.post_draw = [write]
def write(): def write():
"""write on screen""" """write on screen"""
width = render.getWindowWidth() width = render.getWindowWidth()
height = render.getWindowHeight() height = render.getWindowHeight()
# OpenGL setup # OpenGL setup
bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glMatrixMode(bgl.GL_PROJECTION)
bgl.glLoadIdentity() bgl.glLoadIdentity()
bgl.gluOrtho2D(0, width, 0, height) bgl.gluOrtho2D(0, width, 0, height)
bgl.glMatrixMode(bgl.GL_MODELVIEW) bgl.glMatrixMode(bgl.GL_MODELVIEW)
bgl.glLoadIdentity() bgl.glLoadIdentity()
# BLF drawing routine # BLF drawing routine
font_id = logic.font_id font_id = logic.font_id
blf.position(font_id, (width*0.2), (height*0.3), 0) blf.position(font_id, (width * 0.2), (height * 0.3), 0)
blf.size(font_id, 50, 72) blf.size(font_id, 50, 72)
blf.draw(font_id, "Hello World") blf.draw(font_id, "Hello World")

@ -1,15 +1,15 @@
import mathutils import mathutils
# zero length vector # zero length vector
vec = mathutils.Vector((0, 0, 1)) vec = mathutils.Vector((0.0, 0.0, 1.0))
# unit length vector # unit length vector
vec_a = vec.copy().normalize() vec_a = vec.copy().normalize()
vec_b = mathutils.Vector((0, 1, 2)) vec_b = mathutils.Vector((0.0, 1.0, 2.0))
vec2d = mathutils.Vector((1, 2)) vec2d = mathutils.Vector((1.0, 2.0))
vec3d = mathutils.Vector((1, 0, 0)) vec3d = mathutils.Vector((1.0, 0.0, 0.0))
vec4d = vec_a.to_4d() vec4d = vec_a.to_4d()
# other mathutuls types # other mathutuls types
@ -34,9 +34,9 @@ vec_a + vec_b
vec_a - vec_b vec_a - vec_b
vec_a * vec_b vec_a * vec_b
vec_a * 10.0 vec_a * 10.0
vec_a * matrix matrix * vec_a
quat * vec_a
vec_a * vec_b vec_a * vec_b
vec_a * quat
-vec_a -vec_a
@ -44,6 +44,7 @@ vec_a * quat
x = vec_a[0] x = vec_a[0]
len(vec) len(vec)
vec_a[:] = vec_b vec_a[:] = vec_b
vec_a[:] = 1.0, 2.0, 3.0
vec2d[:] = vec3d[:2] vec2d[:] = vec3d[:2]

@ -38,8 +38,11 @@ cp $SPHINXBASE/sphinx-out/contents.html $SPHINXBASE/sphinx-out/index.html
ssh $SSH_USER@emo.blender.org 'rm -rf '$SSH_UPLOAD_FULL'/*' ssh $SSH_USER@emo.blender.org 'rm -rf '$SSH_UPLOAD_FULL'/*'
rsync --progress -avze "ssh -p 22" $SPHINXBASE/sphinx-out/* $SSH_HOST:$SSH_UPLOAD_FULL/ rsync --progress -avze "ssh -p 22" $SPHINXBASE/sphinx-out/* $SSH_HOST:$SSH_UPLOAD_FULL/
# symlink the dir to a static URL ## symlink the dir to a static URL
ssh $SSH_USER@emo.blender.org 'rm '$SSH_UPLOAD'/250PythonDoc && ln -s '$SSH_UPLOAD_FULL' '$SSH_UPLOAD'/250PythonDoc' #ssh $SSH_USER@emo.blender.org 'rm '$SSH_UPLOAD'/250PythonDoc && ln -s '$SSH_UPLOAD_FULL' '$SSH_UPLOAD'/250PythonDoc'
# better redirect
ssh $SSH_USER@emo.blender.org 'echo "<html><head><title>Redirecting...</title><meta http-equiv=\"REFRESH\" content=\"0;url=../blender_python_api_'$BLENDER_VERSION'/\"></head><body>Redirecting...</body></html>" > '$SSH_UPLOAD'/250PythonDoc/index.html'
# pdf # pdf
sphinx-build -b latex $SPHINXBASE/sphinx-in $SPHINXBASE/sphinx-out sphinx-build -b latex $SPHINXBASE/sphinx-in $SPHINXBASE/sphinx-out

@ -105,12 +105,15 @@ void* AUD_openalRunThread(void* device)
return NULL; return NULL;
} }
void AUD_OpenALDevice::start() void AUD_OpenALDevice::start(bool join)
{ {
lock(); lock();
if(!m_playing) if(!m_playing)
{ {
if(join)
pthread_join(m_thread, NULL);
pthread_attr_t attr; pthread_attr_t attr;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
@ -271,8 +274,8 @@ void AUD_OpenALDevice::updateStreams()
// stop thread // stop thread
if(m_playingSounds->empty() || (cerr != ALC_NO_ERROR)) if(m_playingSounds->empty() || (cerr != ALC_NO_ERROR))
{ {
unlock();
m_playing = false; m_playing = false;
unlock();
pthread_exit(NULL); pthread_exit(NULL);
} }
@ -366,6 +369,8 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
pthread_mutex_init(&m_mutex, &attr); pthread_mutex_init(&m_mutex, &attr);
pthread_mutexattr_destroy(&attr); pthread_mutexattr_destroy(&attr);
start(false);
} }
AUD_OpenALDevice::~AUD_OpenALDevice() AUD_OpenALDevice::~AUD_OpenALDevice()
@ -414,13 +419,8 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
alcProcessContext(m_context); alcProcessContext(m_context);
// wait for the thread to stop // wait for the thread to stop
if(m_playing) unlock();
{ pthread_join(m_thread, NULL);
unlock();
pthread_join(m_thread, NULL);
}
else
unlock();
delete m_playingSounds; delete m_playingSounds;
delete m_pausedSounds; delete m_pausedSounds;

@ -106,7 +106,7 @@ private:
/** /**
* Starts the streaming thread. * Starts the streaming thread.
*/ */
void start(); void start(bool join = true);
/** /**
* Checks if a handle is valid. * Checks if a handle is valid.

@ -33,6 +33,7 @@ import bpy as _bpy
error_duplicates = False error_duplicates = False
def paths(): def paths():
# RELEASE SCRIPTS: official scripts distributed in Blender releases # RELEASE SCRIPTS: official scripts distributed in Blender releases
paths = _bpy.utils.script_paths("addons") paths = _bpy.utils.script_paths("addons")

@ -43,6 +43,7 @@ from . import utils, path, ops
# fake operator module # fake operator module
ops = ops.ops_fake_module ops = ops.ops_fake_module
def _main(): def _main():
import sys as _sys import sys as _sys

@ -239,4 +239,4 @@ def basename(path):
Use for Windows compatibility. Use for Windows compatibility.
""" """
return _os.path.basename(path[2:] if path.startswith("//") else path) return _os.path.basename(path[2:] if path[:2] in {"//", b"//"} else path)

@ -159,14 +159,19 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
raise Exception("invalid axis arguments passed, " raise Exception("invalid axis arguments passed, "
"can't use up/forward on the same axis.") "can't use up/forward on the same axis.")
value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3) for i, a in enumerate((from_forward, from_up, to_forward, to_up)))) value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3)
for i, a in enumerate((from_forward,
from_up,
to_forward,
to_up,
))))
for i, axis_lut in enumerate(_axis_convert_lut): for i, axis_lut in enumerate(_axis_convert_lut):
if value in axis_lut: if value in axis_lut:
return Matrix(_axis_convert_matrix[i]) return Matrix(_axis_convert_matrix[i])
assert(0) assert(0)
def axis_conversion_ensure(operator, forward_attr, up_attr): def axis_conversion_ensure(operator, forward_attr, up_attr):
""" """
Function to ensure an operator has valid axis conversion settings, intended Function to ensure an operator has valid axis conversion settings, intended
@ -174,9 +179,9 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
:arg operator: the operator to access axis attributes from. :arg operator: the operator to access axis attributes from.
:type operator: :class:`Operator` :type operator: :class:`Operator`
:arg forward_attr: :arg forward_attr: attribute storing the forward axis
:type forward_attr: string :type forward_attr: string
:arg up_attr: the directory the *filepath* will be referenced from (normally the export path). :arg up_attr: attribute storing the up axis
:type up_attr: string :type up_attr: string
:return: True if the value was modified. :return: True if the value was modified.
:rtype: boolean :rtype: boolean
@ -184,9 +189,9 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
def validate(axis_forward, axis_up): def validate(axis_forward, axis_up):
if axis_forward[-1] == axis_up[-1]: if axis_forward[-1] == axis_up[-1]:
axis_up = axis_up[0:-1] + 'XYZ'[('XYZ'.index(axis_up[-1]) + 1) % 3] axis_up = axis_up[0:-1] + 'XYZ'[('XYZ'.index(axis_up[-1]) + 1) % 3]
return axis_forward, axis_up return axis_forward, axis_up
change = False change = False
axis = getattr(operator, forward_attr), getattr(operator, up_attr) axis = getattr(operator, forward_attr), getattr(operator, up_attr)
@ -203,7 +208,7 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects() # return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
def create_derived_objects(scene, ob): def create_derived_objects(scene, ob):
if ob.parent and ob.parent.dupli_type != 'NONE': if ob.parent and ob.parent.dupli_type in {'VERTS', 'FACES'}:
return False, None return False, None
if ob.dupli_type != 'NONE': if ob.dupli_type != 'NONE':

@ -170,8 +170,8 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
# from knowing the last 2, look for th next. # from knowing the last 2, look for th next.
ed_adj = edges[context_loop[-1]] ed_adj = edges[context_loop[-1]]
if len(ed_adj) != 2: if len(ed_adj) != 2:
# the original edge had 2 other edges
if other_dir and flipped == False: # the original edge had 2 other edges if other_dir and flipped == False:
flipped = True # only flip the list once flipped = True # only flip the list once
context_loop.reverse() context_loop.reverse()
ed_adj[:] = [] ed_adj[:] = []
@ -259,13 +259,15 @@ def edge_loops_from_edges(mesh, edges=None):
def ngon_tesselate(from_data, indices, fix_loops=True): def ngon_tesselate(from_data, indices, fix_loops=True):
''' '''
Takes a polyline of indices (fgon) Takes a polyline of indices (fgon) and returns a list of face
and returns a list of face indicie lists. indicie lists. Designed to be used for importers that need indices for an
Designed to be used for importers that need indices for an fgon to create from existing verts. fgon to create from existing verts.
from_data: either a mesh, or a list/tuple of vectors. from_data: either a mesh, or a list/tuple of vectors.
indices: a list of indices to use this list is the ordered closed polyline to fill, and can be a subset of the data given. indices: a list of indices to use this list is the ordered closed polyline
fix_loops: If this is enabled polylines that use loops to make multiple polylines are delt with correctly. to fill, and can be a subset of the data given.
fix_loops: If this is enabled polylines that use loops to make multiple
polylines are delt with correctly.
''' '''
from mathutils.geometry import tesselate_polygon from mathutils.geometry import tesselate_polygon
@ -276,7 +278,8 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
return [] return []
def mlen(co): def mlen(co):
return abs(co[0]) + abs(co[1]) + abs(co[2]) # manhatten length of a vector, faster then length # manhatten length of a vector, faster then length
return abs(co[0]) + abs(co[1]) + abs(co[2])
def vert_treplet(v, i): def vert_treplet(v, i):
return v, vector_to_tuple(v, 6), i, mlen(v) return v, vector_to_tuple(v, 6), i, mlen(v)
@ -296,7 +299,8 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
else: else:
verts = [from_data.vertices[i].co for ii, i in enumerate(indices)] verts = [from_data.vertices[i].co for ii, i in enumerate(indices)]
for i in range(len(verts) - 1, 0, -1): # same as reversed(xrange(1, len(verts))): # same as reversed(range(1, len(verts))):
for i in range(len(verts) - 1, 0, -1):
if verts[i][1] == verts[i - 1][0]: if verts[i][1] == verts[i - 1][0]:
verts.pop(i - 1) verts.pop(i - 1)
@ -304,14 +308,16 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
else: else:
''' '''
Seperate this loop into multiple loops be finding edges that are used twice Seperate this loop into multiple loops be finding edges that are
This is used by lightwave LWO files a lot used twice. This is used by lightwave LWO files a lot
''' '''
if type(from_data) in (tuple, list): if type(from_data) in (tuple, list):
verts = [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)] verts = [vert_treplet(Vector(from_data[i]), ii)
for ii, i in enumerate(indices)]
else: else:
verts = [vert_treplet(from_data.vertices[i].co, ii) for ii, i in enumerate(indices)] verts = [vert_treplet(from_data.vertices[i].co, ii)
for ii, i in enumerate(indices)]
edges = [(i, i - 1) for i in range(len(verts))] edges = [(i, i - 1) for i in range(len(verts))]
if edges: if edges:

@ -50,11 +50,11 @@ def region_2d_to_vector_3d(region, rv3d, coord):
-0.5 -0.5
)) ))
w = (out[0] * persinv[0][3]) + \ w = ((out[0] * persinv[0][3]) +
(out[1] * persinv[1][3]) + \ (out[1] * persinv[1][3]) +
(out[2] * persinv[2][3]) + persinv[3][3] (out[2] * persinv[2][3]) + persinv[3][3])
return ((out * persinv) / w) - rv3d.view_matrix.inverted()[3].xyz return ((persinv * out) / w) - rv3d.view_matrix.inverted()[3].xyz
else: else:
return rv3d.view_matrix.inverted()[2].xyz.normalized() return rv3d.view_matrix.inverted()[2].xyz.normalized()
@ -116,7 +116,7 @@ def location_3d_to_region_2d(region, rv3d, coord):
""" """
from mathutils import Vector from mathutils import Vector
prj = Vector((coord[0], coord[1], coord[2], 1.0)) * rv3d.perspective_matrix prj = rv3d.perspective_matrix * Vector((coord[0], coord[1], coord[2], 1.0))
if prj.w > 0.0: if prj.w > 0.0:
width_half = region.width / 2.0 width_half = region.width / 2.0
height_half = region.height / 2.0 height_half = region.height / 2.0

@ -144,21 +144,21 @@ class _GenericBone:
""" Vector pointing down the x-axis of the bone. """ Vector pointing down the x-axis of the bone.
""" """
from mathutils import Vector from mathutils import Vector
return Vector((1.0, 0.0, 0.0)) * self.matrix.to_3x3() return self.matrix.to_3x3() * Vector((1.0, 0.0, 0.0))
@property @property
def y_axis(self): def y_axis(self):
""" Vector pointing down the x-axis of the bone. """ Vector pointing down the x-axis of the bone.
""" """
from mathutils import Vector from mathutils import Vector
return Vector((0.0, 1.0, 0.0)) * self.matrix.to_3x3() return self.matrix.to_3x3() * Vector((0.0, 1.0, 0.0))
@property @property
def z_axis(self): def z_axis(self):
""" Vector pointing down the x-axis of the bone. """ Vector pointing down the x-axis of the bone.
""" """
from mathutils import Vector from mathutils import Vector
return Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3() return self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0))
@property @property
def basename(self): def basename(self):
@ -294,9 +294,9 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
:type roll: bool :type roll: bool
""" """
from mathutils import Vector from mathutils import Vector
z_vec = Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3() z_vec = self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0))
self.tail = self.tail * matrix self.tail = matrix * self.tail
self.head = self.head * matrix self.head = matrix * self.head
if scale: if scale:
scalar = matrix.median_scale scalar = matrix.median_scale
@ -304,7 +304,7 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
self.tail_radius *= scalar self.tail_radius *= scalar
if roll: if roll:
self.align_roll(z_vec * matrix) self.align_roll(matrix * z_vec)
def ord_ind(i1, i2): def ord_ind(i1, i2):

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
import bpy import bpy
import mathutils import mathutils
@ -40,8 +40,10 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
for minor_index in range(minor_seg): for minor_index in range(minor_seg):
angle = 2 * pi * minor_index / minor_seg angle = 2 * pi * minor_index / minor_seg
vec = Vector((major_rad + (cos(angle) * minor_rad), 0.0, vec = quat * Vector((major_rad + (cos(angle) * minor_rad),
(sin(angle) * minor_rad))) * quat 0.0,
(sin(angle) * minor_rad),
))
verts.extend(vec[:]) verts.extend(vec[:])
@ -72,7 +74,11 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
return verts, faces return verts, faces
from bpy.props import FloatProperty, IntProperty, BoolProperty, FloatVectorProperty from bpy.props import (FloatProperty,
IntProperty,
BoolProperty,
FloatVectorProperty,
)
class AddTorus(bpy.types.Operator): class AddTorus(bpy.types.Operator):
@ -82,7 +88,8 @@ class AddTorus(bpy.types.Operator):
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
major_radius = FloatProperty(name="Major Radius", major_radius = FloatProperty(name="Major Radius",
description="Radius from the origin to the center of the cross sections", description=("Radius from the origin to the "
"center of the cross sections"),
default=1.0, min=0.01, max=100.0) default=1.0, min=0.01, max=100.0)
minor_radius = FloatProperty(name="Minor Radius", minor_radius = FloatProperty(name="Minor Radius",
description="Radius of the torus' cross section", description="Radius of the torus' cross section",

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
import bpy import bpy
from bpy.props import StringProperty from bpy.props import StringProperty
@ -28,7 +28,11 @@ class EditExternally(bpy.types.Operator):
bl_label = "Image Edit Externally" bl_label = "Image Edit Externally"
bl_options = {'REGISTER'} bl_options = {'REGISTER'}
filepath = StringProperty(name="File Path", description="Path to an image file", maxlen=1024, default="") filepath = StringProperty(
name="File Path",
description="Path to an image file",
maxlen=1024,
)
def _editor_guess(self, context): def _editor_guess(self, context):
import sys import sys
@ -57,10 +61,13 @@ class EditExternally(bpy.types.Operator):
def execute(self, context): def execute(self, context):
import os import os
import subprocess import subprocess
filepath = bpy.path.abspath(self.filepath) filepath = os.path.normpath(bpy.path.abspath(self.filepath))
if not os.path.exists(filepath): if not os.path.exists(filepath):
self.report({'ERROR'}, "Image path %r not found, image may be packed or unsaved." % filepath) self.report({'ERROR'},
"Image path %r not found, image may be packed or "
"unsaved." % filepath)
return {'CANCELLED'} return {'CANCELLED'}
cmd = self._editor_guess(context) + [filepath] cmd = self._editor_guess(context) + [filepath]
@ -70,7 +77,10 @@ class EditExternally(bpy.types.Operator):
except: except:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
self.report({'ERROR'}, "Image editor not found, please specify in User Preferences > File") self.report({'ERROR'},
"Image editor not found, "
"please specify in User Preferences > File")
return {'CANCELLED'} return {'CANCELLED'}
return {'FINISHED'} return {'FINISHED'}
@ -104,7 +114,9 @@ class SaveDirty(bpy.types.Operator):
if "\\" not in filepath and "/" not in filepath: if "\\" not in filepath and "/" not in filepath:
self.report({'WARNING'}, "Invalid path: " + filepath) self.report({'WARNING'}, "Invalid path: " + filepath)
elif filepath in unique_paths: elif filepath in unique_paths:
self.report({'WARNING'}, "Path used by more then one image: " + filepath) self.report({'WARNING'},
"Path used by more then one image: %r" %
filepath)
else: else:
unique_paths.add(filepath) unique_paths.add(filepath)
image.save() image.save()
@ -142,14 +154,14 @@ class ProjectEdit(bpy.types.Operator):
filepath = os.path.basename(bpy.data.filepath) filepath = os.path.basename(bpy.data.filepath)
filepath = os.path.splitext(filepath)[0] filepath = os.path.splitext(filepath)[0]
# filepath = bpy.path.clean_name(filepath) # fixes <memory> rubbish, needs checking # fixes <memory> rubbish, needs checking
# filepath = bpy.path.clean_name(filepath)
if filepath.startswith(".") or filepath == "": if bpy.data.is_saved:
# TODO, have a way to check if the file is saved, assume startup.blend filepath = "//" + filepath
else:
tmpdir = context.user_preferences.filepaths.temporary_directory tmpdir = context.user_preferences.filepaths.temporary_directory
filepath = os.path.join(tmpdir, "project_edit") filepath = os.path.join(tmpdir, "project_edit")
else:
filepath = "//" + filepath
obj = context.object obj = context.object

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
import bpy import bpy
@ -111,7 +111,8 @@ class MeshMirrorUV(bpy.types.Operator):
#for i, v in enumerate(mesh.vertices): #for i, v in enumerate(mesh.vertices):
vmap = {} vmap = {}
for mirror_a, mirror_b in (mirror_gt, mirror_lt), (mirror_lt, mirror_gt): for mirror_a, mirror_b in ((mirror_gt, mirror_lt),
(mirror_lt, mirror_gt)):
for co, i in mirror_a.items(): for co, i in mirror_a.items():
nco = (-co[0], co[1], co[2]) nco = (-co[0], co[1], co[2])
j = mirror_b.get(nco) j = mirror_b.get(nco)
@ -120,7 +121,8 @@ class MeshMirrorUV(bpy.types.Operator):
active_uv_layer = mesh.uv_textures.active.data active_uv_layer = mesh.uv_textures.active.data
fuvs = [(uv.uv1, uv.uv2, uv.uv3, uv.uv4) for uv in active_uv_layer] fuvs = [(uv.uv1, uv.uv2, uv.uv3, uv.uv4) for uv in active_uv_layer]
fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy()) for uv in fuvs] fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy())
for uv in fuvs]
# as a list # as a list
faces = mesh.faces[:] faces = mesh.faces[:]

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
import bpy import bpy
from bpy.props import StringProperty, BoolProperty, EnumProperty, IntProperty from bpy.props import StringProperty, BoolProperty, EnumProperty, IntProperty
@ -28,9 +28,22 @@ class SelectPattern(bpy.types.Operator):
bl_label = "Select Pattern" bl_label = "Select Pattern"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
pattern = StringProperty(name="Pattern", description="Name filter using '*' and '?' wildcard chars", maxlen=32, default="*") pattern = StringProperty(
case_sensitive = BoolProperty(name="Case Sensitive", description="Do a case sensitive compare", default=False) name="Pattern",
extend = BoolProperty(name="Extend", description="Extend the existing selection", default=True) description="Name filter using '*' and '?' wildcard chars",
maxlen=32,
default="*",
)
case_sensitive = BoolProperty(
name="Case Sensitive",
description="Do a case sensitive compare",
default=False,
)
extend = BoolProperty(
name="Extend",
description="Extend the existing selection",
default=True,
)
def execute(self, context): def execute(self, context):
@ -39,22 +52,37 @@ class SelectPattern(bpy.types.Operator):
if self.case_sensitive: if self.case_sensitive:
pattern_match = fnmatch.fnmatchcase pattern_match = fnmatch.fnmatchcase
else: else:
pattern_match = lambda a, b: fnmatch.fnmatchcase(a.upper(), b.upper()) pattern_match = (lambda a, b:
fnmatch.fnmatchcase(a.upper(), b.upper()))
is_ebone = False
obj = context.object obj = context.object
if obj and obj.mode == 'POSE': if obj and obj.mode == 'POSE':
items = obj.data.bones items = obj.data.bones
if not self.extend:
bpy.ops.pose.select_all(action='DESELECT')
elif obj and obj.type == 'ARMATURE' and obj.mode == 'EDIT': elif obj and obj.type == 'ARMATURE' and obj.mode == 'EDIT':
items = obj.data.edit_bones items = obj.data.edit_bones
if not self.extend:
bpy.ops.armature.select_all(action='DESELECT')
is_ebone = True
else: else:
items = context.visible_objects items = context.visible_objects
if not self.extend:
bpy.ops.object.select_all(action='DESELECT')
# Can be pose bones or objects # Can be pose bones or objects
for item in items: for item in items:
if pattern_match(item.name, self.pattern): if pattern_match(item.name, self.pattern):
item.select = True item.select = True
elif not self.extend:
item.select = False # hrmf, perhaps there should be a utility function for this.
if is_ebone:
item.select_head = True
item.select_tail = True
if item.use_connect:
item_parent = item.parent
if item_parent is not None:
item_parent.select_tail = True
return {'FINISHED'} return {'FINISHED'}
@ -93,19 +121,25 @@ class SelectCamera(bpy.types.Operator):
class SelectHierarchy(bpy.types.Operator): class SelectHierarchy(bpy.types.Operator):
'''Select object relative to the active objects position in the hierarchy''' '''Select object relative to the active objects position''' \
'''in the hierarchy'''
bl_idname = "object.select_hierarchy" bl_idname = "object.select_hierarchy"
bl_label = "Select Hierarchy" bl_label = "Select Hierarchy"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
direction = EnumProperty(items=( direction = EnumProperty(
('PARENT', "Parent", ""), items=(('PARENT', "Parent", ""),
('CHILD', "Child", "")), ('CHILD', "Child", ""),
name="Direction", ),
description="Direction to select in the hierarchy", name="Direction",
default='PARENT') description="Direction to select in the hierarchy",
default='PARENT')
extend = BoolProperty(name="Extend", description="Extend the existing selection", default=False) extend = BoolProperty(
name="Extend",
description="Extend the existing selection",
default=False,
)
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -163,7 +197,12 @@ class SubdivisionSet(bpy.types.Operator):
level = IntProperty(name="Level", level = IntProperty(name="Level",
default=1, min=-100, max=100, soft_min=-6, soft_max=6) default=1, min=-100, max=100, soft_min=-6, soft_max=6)
relative = BoolProperty(name="Relative", description="Apply the subsurf level as an offset relative to the current level", default=False) relative = BoolProperty(
name="Relative",
description=("Apply the subsurf level as an offset "
"relative to the current level"),
default=False,
)
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -215,7 +254,8 @@ class SubdivisionSet(bpy.types.Operator):
mod = obj.modifiers.new("Subsurf", 'SUBSURF') mod = obj.modifiers.new("Subsurf", 'SUBSURF')
mod.levels = level mod.levels = level
except: except:
self.report({'WARNING'}, "Modifiers cannot be added to object: " + obj.name) self.report({'WARNING'},
"Modifiers cannot be added to object: " + obj.name)
for obj in context.selected_editable_objects: for obj in context.selected_editable_objects:
set_object_subd(obj) set_object_subd(obj)
@ -224,23 +264,37 @@ class SubdivisionSet(bpy.types.Operator):
class ShapeTransfer(bpy.types.Operator): class ShapeTransfer(bpy.types.Operator):
'''Copy another selected objects active shape to this one by applying the relative offsets''' '''Copy another selected objects active shape to this one by ''' \
'''applying the relative offsets'''
bl_idname = "object.shape_key_transfer" bl_idname = "object.shape_key_transfer"
bl_label = "Transfer Shape Key" bl_label = "Transfer Shape Key"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
mode = EnumProperty(items=( mode = EnumProperty(
('OFFSET', "Offset", "Apply the relative positional offset"), items=(('OFFSET',
('RELATIVE_FACE', "Relative Face", "Calculate the geometricly relative position (using faces)."), "Offset",
('RELATIVE_EDGE', "Relative Edge", "Calculate the geometricly relative position (using edges).")), "Apply the relative positional offset",
name="Transformation Mode", ),
description="Method to apply relative shape positions to the new shape", ('RELATIVE_FACE',
default='OFFSET') "Relative Face",
"Calculate relative position (using faces).",
use_clamp = BoolProperty(name="Clamp Offset", ),
description="Clamp the transformation to the distance each vertex moves in the original shape.", ('RELATIVE_EDGE',
default=False) "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,
)
def _main(self, ob_act, objects, mode='OFFSET', use_clamp=False): def _main(self, ob_act, objects, mode='OFFSET', use_clamp=False):
@ -272,13 +326,16 @@ class ShapeTransfer(bpy.types.Operator):
orig_shape_coords = me_cos(ob_act.active_shape_key.data) orig_shape_coords = me_cos(ob_act.active_shape_key.data)
orig_normals = me_nos(me.vertices) orig_normals = me_nos(me.vertices)
# orig_coords = me_cos(me.vertices) # the actual mverts location isnt as relyable as the base shape :S # the actual mverts location isnt as relyable as the base shape :S
# orig_coords = me_cos(me.vertices)
orig_coords = me_cos(me.shape_keys.key_blocks[0].data) orig_coords = me_cos(me.shape_keys.key_blocks[0].data)
for ob_other in objects: for ob_other in objects:
me_other = ob_other.data me_other = ob_other.data
if len(me_other.vertices) != len(me.vertices): if len(me_other.vertices) != len(me.vertices):
self.report({'WARNING'}, "Skipping '%s', vertex count differs" % ob_other.name) self.report({'WARNING'},
("Skipping '%s', "
"vertex count differs") % ob_other.name)
continue continue
target_normals = me_nos(me_other.vertices) target_normals = me_nos(me_other.vertices)
@ -290,53 +347,90 @@ class ShapeTransfer(bpy.types.Operator):
ob_add_shape(ob_other, orig_key_name) ob_add_shape(ob_other, orig_key_name)
# editing the final coords, only list that stores wrapped coords # editing the final coords, only list that stores wrapped coords
target_shape_coords = [v.co for v in ob_other.active_shape_key.data] target_shape_coords = [v.co for v in
ob_other.active_shape_key.data]
median_coords = [[] for i in range(len(me.vertices))] median_coords = [[] for i in range(len(me.vertices))]
# Method 1, edge # Method 1, edge
if mode == 'OFFSET': if mode == 'OFFSET':
for i, vert_cos in enumerate(median_coords): for i, vert_cos in enumerate(median_coords):
vert_cos.append(target_coords[i] + (orig_shape_coords[i] - orig_coords[i])) vert_cos.append(target_coords[i] +
(orig_shape_coords[i] - orig_coords[i]))
elif mode == 'RELATIVE_FACE': elif mode == 'RELATIVE_FACE':
for face in me.faces: for face in me.faces:
i1, i2, i3, i4 = face.vertices_raw i1, i2, i3, i4 = face.vertices_raw
if i4 != 0: if i4 != 0:
pt = barycentric_transform(orig_shape_coords[i1], pt = barycentric_transform(orig_shape_coords[i1],
orig_coords[i4], orig_coords[i1], orig_coords[i2], orig_coords[i4],
target_coords[i4], target_coords[i1], target_coords[i2]) orig_coords[i1],
orig_coords[i2],
target_coords[i4],
target_coords[i1],
target_coords[i2],
)
median_coords[i1].append(pt) median_coords[i1].append(pt)
pt = barycentric_transform(orig_shape_coords[i2], pt = barycentric_transform(orig_shape_coords[i2],
orig_coords[i1], orig_coords[i2], orig_coords[i3], orig_coords[i1],
target_coords[i1], target_coords[i2], target_coords[i3]) orig_coords[i2],
orig_coords[i3],
target_coords[i1],
target_coords[i2],
target_coords[i3],
)
median_coords[i2].append(pt) median_coords[i2].append(pt)
pt = barycentric_transform(orig_shape_coords[i3], pt = barycentric_transform(orig_shape_coords[i3],
orig_coords[i2], orig_coords[i3], orig_coords[i4], orig_coords[i2],
target_coords[i2], target_coords[i3], target_coords[i4]) orig_coords[i3],
orig_coords[i4],
target_coords[i2],
target_coords[i3],
target_coords[i4],
)
median_coords[i3].append(pt) median_coords[i3].append(pt)
pt = barycentric_transform(orig_shape_coords[i4], pt = barycentric_transform(orig_shape_coords[i4],
orig_coords[i3], orig_coords[i4], orig_coords[i1], orig_coords[i3],
target_coords[i3], target_coords[i4], target_coords[i1]) orig_coords[i4],
orig_coords[i1],
target_coords[i3],
target_coords[i4],
target_coords[i1],
)
median_coords[i4].append(pt) median_coords[i4].append(pt)
else: else:
pt = barycentric_transform(orig_shape_coords[i1], pt = barycentric_transform(orig_shape_coords[i1],
orig_coords[i3], orig_coords[i1], orig_coords[i2], orig_coords[i3],
target_coords[i3], target_coords[i1], target_coords[i2]) orig_coords[i1],
orig_coords[i2],
target_coords[i3],
target_coords[i1],
target_coords[i2],
)
median_coords[i1].append(pt) median_coords[i1].append(pt)
pt = barycentric_transform(orig_shape_coords[i2], pt = barycentric_transform(orig_shape_coords[i2],
orig_coords[i1], orig_coords[i2], orig_coords[i3], orig_coords[i1],
target_coords[i1], target_coords[i2], target_coords[i3]) orig_coords[i2],
orig_coords[i3],
target_coords[i1],
target_coords[i2],
target_coords[i3],
)
median_coords[i2].append(pt) median_coords[i2].append(pt)
pt = barycentric_transform(orig_shape_coords[i3], pt = barycentric_transform(orig_shape_coords[i3],
orig_coords[i2], orig_coords[i3], orig_coords[i1], orig_coords[i2],
target_coords[i2], target_coords[i3], target_coords[i1]) orig_coords[i3],
orig_coords[i1],
target_coords[i2],
target_coords[i3],
target_coords[i1],
)
median_coords[i3].append(pt) median_coords[i3].append(pt)
elif mode == 'RELATIVE_EDGE': elif mode == 'RELATIVE_EDGE':
@ -374,7 +468,8 @@ class ShapeTransfer(bpy.types.Operator):
if use_clamp: if use_clamp:
# clamp to the same movement as the original # clamp to the same movement as the original
# breaks copy between different scaled meshes. # breaks copy between different scaled meshes.
len_from = (orig_shape_coords[i] - orig_coords[i]).length len_from = (orig_shape_coords[i] -
orig_coords[i]).length
ofs = co - target_coords[i] ofs = co - target_coords[i]
ofs.length = len_from ofs.length = len_from
co = target_coords[i] + ofs co = target_coords[i] + ofs
@ -395,7 +490,10 @@ class ShapeTransfer(bpy.types.Operator):
if 1: # swap from/to, means we cant copy to many at once. if 1: # swap from/to, means we cant copy to many at once.
if len(objects) != 1: if len(objects) != 1:
self.report({'ERROR'}, "Expected one other selected mesh object to copy from") self.report({'ERROR'},
("Expected one other selected "
"mesh object to copy from"))
return {'CANCELLED'} return {'CANCELLED'}
ob_act, objects = objects[0], [ob_act] ob_act, objects = objects[0], [ob_act]
@ -429,11 +527,14 @@ class JoinUVs(bpy.types.Operator):
bpy.ops.object.mode_set(mode='OBJECT', toggle=False) bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
if not mesh.uv_textures: if not mesh.uv_textures:
self.report({'WARNING'}, "Object: %s, Mesh: '%s' has no UVs\n" % (obj.name, mesh.name)) self.report({'WARNING'},
"Object: %s, Mesh: '%s' has no UVs"
% (obj.name, mesh.name))
else: else:
len_faces = len(mesh.faces) len_faces = len(mesh.faces)
uv_array = array.array('f', [0.0] * 8) * len_faces # seems to be the fastest way to create an array # seems to be the fastest way to create an array
uv_array = array.array('f', [0.0] * 8) * len_faces
mesh.uv_textures.active.data.foreach_get("uv_raw", uv_array) mesh.uv_textures.active.data.foreach_get("uv_raw", uv_array)
objects = context.selected_editable_objects[:] objects = context.selected_editable_objects[:]
@ -450,11 +551,18 @@ class JoinUVs(bpy.types.Operator):
mesh_other.tag = True mesh_other.tag = True
if len(mesh_other.faces) != len_faces: if len(mesh_other.faces) != len_faces:
self.report({'WARNING'}, "Object: %s, Mesh: '%s' has %d faces, expected %d\n" % (obj_other.name, mesh_other.name, len(mesh_other.faces), len_faces)) self.report({'WARNING'}, "Object: %s, Mesh: "
"'%s' has %d faces, expected %d\n"
% (obj_other.name,
mesh_other.name,
len(mesh_other.faces),
len_faces),
)
else: else:
uv_other = mesh_other.uv_textures.active uv_other = mesh_other.uv_textures.active
if not uv_other: if not uv_other:
uv_other = mesh_other.uv_textures.new() # should return the texture it adds # should return the texture it adds
uv_other = mesh_other.uv_textures.new()
# finally do the copy # finally do the copy
uv_other.data.foreach_set("uv_raw", uv_array) uv_other.data.foreach_set("uv_raw", uv_array)
@ -482,14 +590,18 @@ class MakeDupliFace(bpy.types.Operator):
SCALE_FAC = 0.01 SCALE_FAC = 0.01
offset = 0.5 * SCALE_FAC offset = 0.5 * SCALE_FAC
base_tri = Vector((-offset, -offset, 0.0)), Vector((offset, -offset, 0.0)), Vector((offset, offset, 0.0)), Vector((-offset, offset, 0.0)) base_tri = (Vector((-offset, -offset, 0.0)),
Vector((+offset, -offset, 0.0)),
Vector((+offset, +offset, 0.0)),
Vector((-offset, +offset, 0.0)),
)
def matrix_to_quat(matrix): def matrix_to_quat(matrix):
# scale = matrix.median_scale # scale = matrix.median_scale
trans = matrix.to_translation() trans = matrix.to_translation()
rot = matrix.to_3x3() # also contains scale rot = matrix.to_3x3() # also contains scale
return [(b * rot) + trans for b in base_tri] return [(rot * b) + trans for b in base_tri]
scene = bpy.context.scene scene = bpy.context.scene
linked = {} linked = {}
for obj in bpy.context.selected_objects: for obj in bpy.context.selected_objects:
@ -498,7 +610,10 @@ class MakeDupliFace(bpy.types.Operator):
linked.setdefault(data, []).append(obj) linked.setdefault(data, []).append(obj)
for data, objects in linked.items(): for data, objects in linked.items():
face_verts = [axis for obj in objects for v in matrix_to_quat(obj.matrix_world) for axis in v] face_verts = [axis for obj in objects
for v in matrix_to_quat(obj.matrix_world)
for axis in v]
faces = list(range(len(face_verts) // 3)) faces = list(range(len(face_verts) // 3))
mesh = bpy.data.meshes.new(data.name + "_dupli") mesh = bpy.data.meshes.new(data.name + "_dupli")
@ -535,7 +650,8 @@ class MakeDupliFace(bpy.types.Operator):
class IsolateTypeRender(bpy.types.Operator): class IsolateTypeRender(bpy.types.Operator):
'''Hide unselected render objects of same type as active by setting the hide render flag''' '''Hide unselected render objects of same type as active ''' \
'''by setting the hide render flag'''
bl_idname = "object.isolate_type_render" bl_idname = "object.isolate_type_render"
bl_label = "Restrict Render Unselected" bl_label = "Restrict Render Unselected"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}

@ -16,102 +16,109 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
import bpy import bpy
from mathutils import Vector from mathutils import Vector
def GlobalBB_LQ(bb_world): def GlobalBB_LQ(bb_world):
# Initialize the variables with the 8th vertex # Initialize the variables with the 8th vertex
left, right, front, back, down, up =\ left, right, front, back, down, up = (bb_world[7][0],
bb_world[7][0],\ bb_world[7][0],
bb_world[7][0],\ bb_world[7][1],
bb_world[7][1],\ bb_world[7][1],
bb_world[7][1],\ bb_world[7][2],
bb_world[7][2],\ bb_world[7][2],
bb_world[7][2] )
# Test against the other 7 verts # Test against the other 7 verts
for i in range (7): for i in range(7):
# X Range # X Range
val = bb_world[i][0] val = bb_world[i][0]
if val < left: if val < left:
left = val left = val
if val > right: if val > right:
right = val right = val
# Y Range # Y Range
val = bb_world[i][1] val = bb_world[i][1]
if val < front: if val < front:
front = val front = val
if val > back: if val > back:
back = val back = val
# Z Range # Z Range
val = bb_world[i][2] val = bb_world[i][2]
if val < down: if val < down:
down = val down = val
if val > up: if val > up:
up = val up = val
return (Vector((left, front, up)), Vector((right, back, down))) return (Vector((left, front, up)), Vector((right, back, down)))
def GlobalBB_HQ(obj): def GlobalBB_HQ(obj):
matrix_world = obj.matrix_world.copy() matrix_world = obj.matrix_world.copy()
# Initialize the variables with the last vertex # Initialize the variables with the last vertex
verts = obj.data.vertices verts = obj.data.vertices
val = verts[-1].co * matrix_world val = matrix_world * verts[-1].co
left, right, front, back, down, up =\ left, right, front, back, down, up = (val[0],
val[0],\ val[0],
val[0],\ val[1],
val[1],\ val[1],
val[1],\ val[2],
val[2],\ val[2],
val[2] )
# Test against all other verts # Test against all other verts
for i in range (len(verts)-1): for i in range(len(verts) - 1):
vco = verts[i].co * matrix_world vco = matrix_world * verts[i].co
# X Range # X Range
val = vco[0] val = vco[0]
if val < left: if val < left:
left = val left = val
if val > right: if val > right:
right = val right = val
# Y Range # Y Range
val = vco[1] val = vco[1]
if val < front: if val < front:
front = val front = val
if val > back: if val > back:
back = val back = val
# Z Range # Z Range
val = vco[2] val = vco[2]
if val < down: if val < down:
down = val down = val
if val > up: if val > up:
up = val up = val
return (Vector((left, front, up)), Vector((right, back, down))) return Vector((left, front, up)), Vector((right, back, down))
def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality): def align_objects(align_x,
align_y,
align_z,
align_mode,
relative_to,
bb_quality):
cursor = bpy.context.scene.cursor_location cursor = bpy.context.scene.cursor_location
@ -123,20 +130,20 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality
objs = [] objs = []
for obj in bpy.context.selected_objects: for obj in bpy.context.selected_objects:
matrix_world = obj.matrix_world matrix_world = obj.matrix_world.copy()
bb_world = [Vector(v[:]) * matrix_world for v in obj.bound_box] bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
objs.append((obj, bb_world)) objs.append((obj, bb_world))
if not objs: if not objs:
return False return False
for obj, bb_world in objs: for obj, bb_world in objs:
if bb_quality: if bb_quality:
GBB = GlobalBB_HQ(obj) GBB = GlobalBB_HQ(obj)
else: else:
GBB = GlobalBB_LQ(bb_world) GBB = GlobalBB_LQ(bb_world)
Left_Front_Up = GBB[0] Left_Front_Up = GBB[0]
Right_Back_Down = GBB[1] Right_Back_Down = GBB[1]
@ -193,13 +200,14 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality
# Main Loop # Main Loop
for obj, bb_world in objs: for obj, bb_world in objs:
bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box] matrix_world = obj.matrix_world.copy()
bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
if bb_quality: if bb_quality:
GBB = GlobalBB_HQ(obj) GBB = GlobalBB_HQ(obj)
else: else:
GBB = GlobalBB_LQ(bb_world) GBB = GlobalBB_LQ(bb_world)
Left_Front_Up = GBB[0] Left_Front_Up = GBB[0]
Right_Back_Down = GBB[1] Right_Back_Down = GBB[1]
@ -339,8 +347,10 @@ class AlignObjects(bpy.types.Operator):
bb_quality = BoolProperty( bb_quality = BoolProperty(
name="High Quality", name="High Quality",
description="Enables high quality calculation of the bounding box for perfect results on complex shape meshes with rotation/scale (Slow)", description=("Enables high quality calculation of the "
default=False) "bounding box for perfect results on complex "
"shape meshes with rotation/scale (Slow)"),
default=True)
align_mode = EnumProperty(items=( align_mode = EnumProperty(items=(
('OPT_1', "Negative Sides", ""), ('OPT_1', "Negative Sides", ""),
@ -374,10 +384,15 @@ class AlignObjects(bpy.types.Operator):
def execute(self, context): def execute(self, context):
align_axis = self.align_axis align_axis = self.align_axis
ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to, self.bb_quality) ret = align_objects('X' in align_axis,
'Y' in align_axis,
'Z' in align_axis,
self.align_mode,
self.relative_to,
self.bb_quality)
if not ret: if not ret:
self.report({'WARNING'}, "No objects with bound-box selected") self.report({'WARNING'}, "No objects with bound-box selected")
return {'CANCELLED'} return {'CANCELLED'}
else: else:
return {'FINISHED'} return {'FINISHED'}

@ -16,11 +16,16 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
from mathutils import Vector from mathutils import Vector
import bpy import bpy
from bpy.props import BoolProperty, EnumProperty, IntProperty, FloatProperty, FloatVectorProperty from bpy.props import (BoolProperty,
EnumProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
)
def object_ensure_material(obj, mat_name): def object_ensure_material(obj, mat_name):
@ -61,7 +66,8 @@ class QuickFur(bpy.types.Operator):
def execute(self, context): def execute(self, context):
fake_context = bpy.context.copy() fake_context = bpy.context.copy()
mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH'] mesh_objects = [obj for obj in context.selected_objects
if obj.type == 'MESH']
if not mesh_objects: if not mesh_objects:
self.report({'ERROR'}, "Select at least one mesh object.") self.report({'ERROR'}, "Select at least one mesh object.")
@ -92,7 +98,8 @@ class QuickFur(bpy.types.Operator):
psys.settings.child_type = 'INTERPOLATED' psys.settings.child_type = 'INTERPOLATED'
obj.data.materials.append(mat) obj.data.materials.append(mat)
obj.particle_systems[-1].settings.material = len(obj.data.materials) obj.particle_systems[-1].settings.material = \
len(obj.data.materials)
return {'FINISHED'} return {'FINISHED'}
@ -149,7 +156,10 @@ class QuickExplode(bpy.types.Operator):
for obj in mesh_objects: for obj in mesh_objects:
if obj.particle_systems: if obj.particle_systems:
self.report({'ERROR'}, "Object %r already has a particle system" % obj.name) self.report({'ERROR'},
"Object %r already has a "
"particle system" % obj.name)
return {'CANCELLED'} return {'CANCELLED'}
if self.fade: if self.fade:
@ -184,9 +194,7 @@ class QuickExplode(bpy.types.Operator):
if self.fade: if self.fade:
explode.show_dead = False explode.show_dead = False
bpy.ops.mesh.uv_texture_add(fake_context) uv = obj.data.uv_textures.new("Explode fade")
uv = obj.data.uv_textures[-1]
uv.name = "Explode fade"
explode.particle_uv = uv.name explode.particle_uv = uv.name
mat = object_ensure_material(obj, "Explode Fade") mat = object_ensure_material(obj, "Explode Fade")
@ -247,7 +255,7 @@ class QuickExplode(bpy.types.Operator):
def obj_bb_minmax(obj, min_co, max_co): def obj_bb_minmax(obj, min_co, max_co):
for i in range(0, 8): for i in range(0, 8):
bb_vec = Vector(obj.bound_box[i]) * obj.matrix_world bb_vec = obj.matrix_world * Vector(obj.bound_box[i])
min_co[0] = min(bb_vec[0], min_co[0]) min_co[0] = min(bb_vec[0], min_co[0])
min_co[1] = min(bb_vec[1], min_co[1]) min_co[1] = min(bb_vec[1], min_co[1])
@ -262,21 +270,26 @@ class QuickSmoke(bpy.types.Operator):
bl_label = "Quick Smoke" bl_label = "Quick Smoke"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
style = EnumProperty(items=( style = EnumProperty(
('STREAM', "Stream", ""), items=(('STREAM', "Stream", ""),
('PUFF', "Puff", ""), ('PUFF', "Puff", ""),
('FIRE', "Fire", "")), ('FIRE', "Fire", ""),
name="Smoke Style", ),
description="", name="Smoke Style",
default='STREAM') description="",
default='STREAM',
)
show_flows = BoolProperty(name="Render Smoke Objects", show_flows = BoolProperty(
description="Keep the smoke objects visible during rendering.", name="Render Smoke Objects",
default=False) description="Keep the smoke objects visible during rendering.",
default=False,
)
def execute(self, context): def execute(self, context):
fake_context = bpy.context.copy() fake_context = bpy.context.copy()
mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH'] mesh_objects = [obj for obj in context.selected_objects
if obj.type == 'MESH']
min_co = Vector((100000.0, 100000.0, 100000.0)) min_co = Vector((100000.0, 100000.0, 100000.0))
max_co = -min_co max_co = -min_co
@ -336,21 +349,25 @@ class QuickSmoke(bpy.types.Operator):
mat.volume.density = 0 mat.volume.density = 0
mat.volume.density_scale = 5 mat.volume.density_scale = 5
mat.texture_slots.add() tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA')
mat.texture_slots[0].texture = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA') tex.voxel_data.domain_object = obj
mat.texture_slots[0].texture.voxel_data.domain_object = obj
mat.texture_slots[0].use_map_color_emission = False tex_slot = mat.texture_slots.add()
mat.texture_slots[0].use_map_density = True tex_slot.texture = tex
tex_slot.use_map_color_emission = False
tex_slot.use_map_density = True
# for fire add a second texture for emission and emission color # for fire add a second texture for emission and emission color
if self.style == 'FIRE': if self.style == 'FIRE':
mat.volume.emission = 5 mat.volume.emission = 5
mat.texture_slots.add() tex = bpy.data.textures.new("Smoke Heat", 'VOXEL_DATA')
mat.texture_slots[1].texture = bpy.data.textures.new("Smoke Heat", 'VOXEL_DATA') tex.voxel_data.domain_object = obj
mat.texture_slots[1].texture.voxel_data.domain_object = obj tex.use_color_ramp = True
mat.texture_slots[1].texture.use_color_ramp = True
ramp = mat.texture_slots[1].texture.color_ramp tex_slot = mat.texture_slots.add()
tex_slot.texture = tex
ramp = tex.color_ramp
elem = ramp.elements.new(0.333) elem = ramp.elements.new(0.333)
elem.color[0] = elem.color[3] = 1 elem.color[0] = elem.color[3] = 1
@ -371,28 +388,38 @@ class QuickFluid(bpy.types.Operator):
bl_label = "Quick Fluid" bl_label = "Quick Fluid"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
style = EnumProperty(items=( style = EnumProperty(
('INFLOW', "Inflow", ""), items=(('INFLOW', "Inflow", ""),
('BASIC', "Basic", "")), ('BASIC', "Basic", ""),
),
name="Fluid Style", name="Fluid Style",
description="", description="",
default='BASIC') default='BASIC',
)
initial_velocity = FloatVectorProperty(name="Initial Velocity", initial_velocity = FloatVectorProperty(
description="Initial velocity of the fluid", name="Initial Velocity",
default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='VELOCITY') description="Initial velocity of the fluid",
default=(0.0, 0.0, 0.0),
show_flows = BoolProperty(name="Render Fluid Objects", min=-100.0,
description="Keep the fluid objects visible during rendering.", max=100.0,
default=False) subtype='VELOCITY',
)
start_baking = BoolProperty(name="Start Fluid Bake", show_flows = BoolProperty(
description="Start baking the fluid immediately after creating the domain object.", name="Render Fluid Objects",
default=False) 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,
)
def execute(self, context): def execute(self, context):
fake_context = bpy.context.copy() fake_context = bpy.context.copy()
mesh_objects = [obj for obj in context.selected_objects if (obj.type == 'MESH' and not 0 in obj.dimensions)] mesh_objects = [obj for obj in context.selected_objects
if (obj.type == 'MESH' and not 0.0 in obj.dimensions)]
min_co = Vector((100000, 100000, 100000)) min_co = Vector((100000, 100000, 100000))
max_co = Vector((-100000, -100000, -100000)) max_co = Vector((-100000, -100000, -100000))
@ -405,7 +432,8 @@ class QuickFluid(bpy.types.Operator):
# make each selected object a fluid # make each selected object a fluid
bpy.ops.object.modifier_add(fake_context, type='FLUID_SIMULATION') bpy.ops.object.modifier_add(fake_context, type='FLUID_SIMULATION')
# fluid has to be before constructive modifiers, so it might not be the last modifier # fluid has to be before constructive modifiers,
# so it might not be the last modifier
for mod in obj.modifiers: for mod in obj.modifiers:
if mod.type == 'FLUID_SIMULATION': if mod.type == 'FLUID_SIMULATION':
break break
@ -429,10 +457,14 @@ class QuickFluid(bpy.types.Operator):
obj = context.active_object obj = context.active_object
obj.name = "Fluid Domain" obj.name = "Fluid Domain"
# give the fluid some room below the flows and scale with initial velocity # give the fluid some room below the flows
# and scale with initial velocity
v = 0.5 * self.initial_velocity v = 0.5 * self.initial_velocity
obj.location = 0.5 * (max_co + min_co) + Vector((0.0, 0.0, -1.0)) + v obj.location = 0.5 * (max_co + min_co) + Vector((0.0, 0.0, -1.0)) + v
obj.scale = 0.5 * (max_co - min_co) + Vector((1.0, 1.0, 2.0)) + Vector((abs(v[0]), abs(v[1]), abs(v[2]))) obj.scale = (0.5 * (max_co - min_co) +
Vector((1.0, 1.0, 2.0)) +
Vector((abs(v[0]), abs(v[1]), abs(v[2])))
)
# setup smoke domain # setup smoke domain
bpy.ops.object.modifier_add(type='FLUID_SIMULATION') bpy.ops.object.modifier_add(type='FLUID_SIMULATION')

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
import bpy import bpy
@ -93,40 +93,69 @@ class RandomizeLocRotSize(bpy.types.Operator):
bl_label = "Randomize Transform" bl_label = "Randomize Transform"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
random_seed = IntProperty(name="Random Seed", random_seed = IntProperty(
description="Seed value for the random generator", name="Random Seed",
default=0, min=0, max=1000) description="Seed value for the random generator",
min=0,
use_delta = BoolProperty(name="Transform Delta", max=1000,
description="Randomize delta transform values instead of regular transform", default=False) default=0,
)
use_loc = BoolProperty(name="Randomize Location", use_delta = BoolProperty(
description="Randomize the location values", default=True) name="Transform Delta",
description=("Randomize delta transform values "
loc = FloatVectorProperty(name="Location", "instead of regular transform"),
description="Maximun distance the objects can spread over each axis", default=False,
default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='TRANSLATION') )
use_loc = BoolProperty(
use_rot = BoolProperty(name="Randomize Rotation", name="Randomize Location",
description="Randomize the rotation values", default=True) description="Randomize the location values",
default=True,
rot = FloatVectorProperty(name="Rotation", )
description="Maximun rotation over each axis", loc = FloatVectorProperty(
default=(0.0, 0.0, 0.0), min=-180.0, max=180.0, subtype='TRANSLATION') name="Location",
description=("Maximun distance the objects "
use_scale = BoolProperty(name="Randomize Scale", "can spread over each axis"),
description="Randomize the scale values", default=True) min=-100.0,
max=100.0,
scale_even = BoolProperty(name="Scale Even", default=(0.0, 0.0, 0.0),
description="Use the same scale value for all axis", default=False) subtype='TRANSLATION',
)
use_rot = BoolProperty(
name="Randomize Rotation",
description="Randomize the rotation values",
default=True,
)
rot = FloatVectorProperty(
name="Rotation",
description="Maximun rotation over each axis",
min=-180.0,
max=180.0,
default=(0.0, 0.0, 0.0),
subtype='TRANSLATION',
)
use_scale = BoolProperty(
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,
)
'''scale_min = FloatProperty(name="Minimun Scale Factor", '''scale_min = FloatProperty(name="Minimun Scale Factor",
description="Lowest scale percentage possible", description="Lowest scale percentage possible",
default=0.15, min=-1.0, max=1.0, precision=3)''' default=0.15, min=-1.0, max=1.0, precision=3)'''
scale = FloatVectorProperty(name="Scale", scale = FloatVectorProperty(
description="Maximum scale randomization over each axis", name="Scale",
default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='TRANSLATION') description="Maximum scale randomization over each axis",
min=-100.0,
max=100.0,
default=(0.0, 0.0, 0.0),
subtype='TRANSLATION',
)
def execute(self, context): def execute(self, context):
from math import radians from math import radians

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
import bpy import bpy
@ -30,8 +30,15 @@ class AddPresetBase():
# bl_label = "Add a Python Preset" # bl_label = "Add a Python Preset"
bl_options = {'REGISTER'} # only because invoke_props_popup requires. bl_options = {'REGISTER'} # only because invoke_props_popup requires.
name = bpy.props.StringProperty(name="Name", description="Name of the preset, used to make the path name", maxlen=64, default="") name = bpy.props.StringProperty(
remove_active = bpy.props.BoolProperty(default=False, options={'HIDDEN'}) name="Name",
description="Name of the preset, used to make the path name",
maxlen=64,
)
remove_active = bpy.props.BoolProperty(
default=False,
options={'HIDDEN'},
)
@staticmethod @staticmethod
def as_filename(name): # could reuse for other presets def as_filename(name): # could reuse for other presets
@ -54,7 +61,10 @@ class AddPresetBase():
filename = self.as_filename(name) filename = self.as_filename(name)
target_path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", self.preset_subdir), create=True) target_path = os.path.join("presets", self.preset_subdir)
target_path = bpy.utils.user_resource('SCRIPTS',
target_path,
create=True)
if not target_path: if not target_path:
self.report({'WARNING'}, "Failed to create presets path") self.report({'WARNING'}, "Failed to create presets path")
@ -95,7 +105,9 @@ class AddPresetBase():
filepath = bpy.utils.preset_find(preset_active, self.preset_subdir) filepath = bpy.utils.preset_find(preset_active, self.preset_subdir)
if not filepath: if not filepath:
filepath = bpy.utils.preset_find(preset_active, self.preset_subdir, display_name=True) filepath = bpy.utils.preset_find(preset_active,
self.preset_subdir,
display_name=True)
if not filepath: if not filepath:
return {'CANCELLED'} return {'CANCELLED'}
@ -133,8 +145,15 @@ class ExecutePreset(bpy.types.Operator):
bl_idname = "script.execute_preset" bl_idname = "script.execute_preset"
bl_label = "Execute a Python Preset" bl_label = "Execute a Python Preset"
filepath = bpy.props.StringProperty(name="Path", description="Path of the Python file to execute", maxlen=512, default="") filepath = bpy.props.StringProperty(
menu_idname = bpy.props.StringProperty(name="Menu ID Name", description="ID name of the menu this was called from", default="") name="Path",
description="Path of the Python file to execute",
maxlen=512,
)
menu_idname = bpy.props.StringProperty(
name="Menu ID Name",
description="ID name of the menu this was called from",
)
def execute(self, context): def execute(self, context):
from os.path import basename from os.path import basename
@ -182,7 +201,10 @@ class AddPresetSSS(AddPresetBase, bpy.types.Operator):
preset_menu = "MATERIAL_MT_sss_presets" preset_menu = "MATERIAL_MT_sss_presets"
preset_defines = [ preset_defines = [
"material = (bpy.context.material.active_node_material if bpy.context.material.active_node_material else bpy.context.material)" ("material = "
"bpy.context.material.active_node_material "
"if bpy.context.material.active_node_material "
"else bpy.context.material")
] ]
preset_values = [ preset_values = [
@ -306,7 +328,11 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
bl_label = "Operator Preset" bl_label = "Operator Preset"
preset_menu = "WM_MT_operator_presets" preset_menu = "WM_MT_operator_presets"
operator = bpy.props.StringProperty(name="Operator", maxlen=64, options={'HIDDEN'}) operator = bpy.props.StringProperty(
name="Operator",
maxlen=64,
options={'HIDDEN'},
)
# XXX, not ideal # XXX, not ideal
preset_defines = [ preset_defines = [
@ -322,12 +348,15 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
properties_blacklist = bpy.types.Operator.bl_rna.properties.keys() properties_blacklist = bpy.types.Operator.bl_rna.properties.keys()
prefix, suffix = self.operator.split("_OT_", 1) prefix, suffix = self.operator.split("_OT_", 1)
operator_rna = getattr(getattr(bpy.ops, prefix.lower()), suffix).get_rna().bl_rna op = getattr(getattr(bpy.ops, prefix.lower()), suffix)
operator_rna = op.get_rna().bl_rna
del op
ret = [] ret = []
for prop_id, prop in operator_rna.properties.items(): for prop_id, prop in operator_rna.properties.items():
if (not (prop.is_hidden or prop.is_skip_save)) and prop_id not in properties_blacklist: if not (prop.is_hidden or prop.is_skip_save):
ret.append("op.%s" % prop_id) if prop_id not in properties_blacklist:
ret.append("op.%s" % prop_id)
return ret return ret

@ -1,27 +1,23 @@
# ***** BEGIN GPL LICENSE BLOCK ***** # ##### BEGIN GPL LICENSE BLOCK #####
# #
# Script copyright (C) Campbell J Barton # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# #
# This program is free software; you can redistribute it and/or # This program is distributed in the hope that it will be useful,
# modify it under the terms of the GNU General Public License # but WITHOUT ANY WARRANTY; without even the implied warranty of
# as published by the Free Software Foundation; either version 2 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# of the License, or (at your option) any later version. # GNU General Public License for more details.
# #
# This program is distributed in the hope that it will be useful, # You should have received a copy of the GNU General Public License
# but WITHOUT ANY WARRANTY; without even the implied warranty of # along with this program; if not, write to the Free Software Foundation,
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # ##### END GPL LICENSE BLOCK #####
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
# <pep8 compliant> # <pep8-80 compliant>
# History
#
# Originally written by Matt Ebb # Originally written by Matt Ebb
import bpy import bpy
@ -46,8 +42,10 @@ def guess_player_path(preset):
player_path = "djv_view" player_path = "djv_view"
if sys.platform == "darwin": if sys.platform == "darwin":
# TODO, crummy supporting only 1 version, could find the newest installed version # TODO, crummy supporting only 1 version,
test_path = '/Applications/djv-0.8.2.app/Contents/Resources/bin/djv_view' # could find the newest installed version
test_path = ("/Applications/djv-0.8.2.app"
"/Contents/Resources/bin/djv_view")
if os.path.exists(test_path): if os.path.exists(test_path):
player_path = test_path player_path = test_path
@ -60,6 +58,9 @@ def guess_player_path(preset):
elif preset == 'MPLAYER': elif preset == 'MPLAYER':
player_path = "mplayer" player_path = "mplayer"
else:
player_path = ""
return player_path return player_path
@ -82,10 +83,10 @@ class PlayRenderedAnim(bpy.types.Operator):
is_movie = rd.is_movie_format is_movie = rd.is_movie_format
# try and guess a command line if it doesn't exist # try and guess a command line if it doesn't exist
if player_path == '': if player_path == "":
player_path = guess_player_path(preset) player_path = guess_player_path(preset)
if is_movie == False and preset in ('FRAMECYCLER', 'RV', 'MPLAYER'): if is_movie == False and preset in {'FRAMECYCLER', 'RV', 'MPLAYER'}:
# replace the number with '#' # replace the number with '#'
file_a = rd.frame_path(frame=0) file_a = rd.frame_path(frame=0)
@ -95,11 +96,11 @@ class PlayRenderedAnim(bpy.types.Operator):
while len(file_a) == len(file_b): while len(file_a) == len(file_b):
frame_tmp = (frame_tmp * 10) + 9 frame_tmp = (frame_tmp * 10) + 9
print(frame_tmp)
file_b = rd.frame_path(frame=frame_tmp) file_b = rd.frame_path(frame=frame_tmp)
file_b = rd.frame_path(frame=int(frame_tmp / 10)) 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)) file = ("".join((c if file_b[i] == c else "#")
for i, c in enumerate(file_a)))
else: else:
# works for movies and images # works for movies and images
file = rd.frame_path(frame=scene.frame_start) file = rd.frame_path(frame=scene.frame_start)
@ -109,10 +110,35 @@ class PlayRenderedAnim(bpy.types.Operator):
cmd = [player_path] cmd = [player_path]
# extra options, fps controls etc. # extra options, fps controls etc.
if preset == 'BLENDER24': if preset == 'BLENDER24':
# -----------------------------------------------------------------
# Check blender is not 2.5x until it supports playback again
try:
process = subprocess.Popen([player_path, '--version'],
stdout=subprocess.PIPE,
)
except:
# ignore and allow the main execution to catch the problem.
process = None
if process is not None:
process.wait()
out = process.stdout.read()
process.stdout.close()
out_split = out.strip().split()
if out_split[0] == b'Blender':
if not out_split[1].startswith(b'2.4'):
self.report({'ERROR'},
"Blender %s doesn't support playback: %r" %
(out_split[1].decode(), player_path))
return {'CANCELLED'}
del out, out_split
del process
# -----------------------------------------------------------------
opts = ["-a", "-f", str(rd.fps), str(rd.fps_base), file] opts = ["-a", "-f", str(rd.fps), str(rd.fps_base), file]
cmd.extend(opts) cmd.extend(opts)
elif preset == 'DJV': elif preset == 'DJV':
opts = [file, "-playback_speed", str(rd.fps)] opts = [file, "-playback_speed", "%d" % int(rd.fps / rd.fps_base)]
cmd.extend(opts) cmd.extend(opts)
elif preset == 'FRAMECYCLER': elif preset == 'FRAMECYCLER':
opts = [file, "%d-%d" % (scene.frame_start, scene.frame_end)] opts = [file, "%d-%d" % (scene.frame_start, scene.frame_end)]
@ -125,18 +151,26 @@ class PlayRenderedAnim(bpy.types.Operator):
if is_movie: if is_movie:
opts.append(file) opts.append(file)
else: else:
opts.append("mf://%s" % file.replace("#", "?")) opts += [("mf://%s" % file.replace("#", "?")),
opts += ["-mf", "fps=%.4f" % (rd.fps / rd.fps_base)] "-mf",
"fps=%.4f" % (rd.fps / rd.fps_base),
]
opts += ["-loop", "0", "-really-quiet", "-fs"] opts += ["-loop", "0", "-really-quiet", "-fs"]
cmd.extend(opts) cmd.extend(opts)
else: # 'CUSTOM' else: # 'CUSTOM'
cmd.append(file) cmd.append(file)
# launch it # launch it
print("Executing command:\n %r" % " ".join(cmd))
try: try:
process = subprocess.Popen(cmd) process = subprocess.Popen(cmd)
except: except Exception as e:
pass import traceback
#raise OSError("Couldn't find an external animation player.") self.report({'ERROR'},
"Couldn't run external animation player with command "
"%r\n%s" % (" ".join(cmd), str(e)))
return {'CANCELLED'}
return {'FINISHED'} return {'FINISHED'}

@ -243,7 +243,7 @@ def testNewVecLs2DRotIsBetter(vecs, mat=-1, bestAreaSoFar = -1):
# Do this allong the way # Do this allong the way
if mat != -1: if mat != -1:
v = vecs[i] = v*mat v = vecs[i] = mat * v
x= v.x x= v.x
y= v.y y= v.y
if x<minx: minx= x if x<minx: minx= x
@ -1064,7 +1064,7 @@ def main(context,
f_uv = f.uv f_uv = f.uv
for j, v in enumerate(f.v): for j, v in enumerate(f.v):
# XXX - note, between mathutils in 2.4 and 2.5 the order changed. # XXX - note, between mathutils in 2.4 and 2.5 the order changed.
f_uv[j][:] = (v.co * MatQuat).xy f_uv[j][:] = (MatQuat * v.co).xy
if USER_SHARE_SPACE: if USER_SHARE_SPACE:

@ -41,11 +41,9 @@ class DATA_PT_empty(DataButtonsPanel, bpy.types.Panel):
layout.prop(ob, "empty_draw_type", text="Display") layout.prop(ob, "empty_draw_type", text="Display")
if ob.empty_draw_type == 'IMAGE': if ob.empty_draw_type == 'IMAGE':
# layout.template_image(ob, "data", None)
layout.template_ID(ob, "data", open="image.open", unlink="image.unlink") layout.template_ID(ob, "data", open="image.open", unlink="image.unlink")
row = layout.row(align=True) layout.prop(ob, "color", text="Transparency", index=3, slider=True)
row.prop(ob, "color", text="Transparency", index=3, slider=True)
row = layout.row(align=True) row = layout.row(align=True)
row.prop(ob, "empty_image_offset", text="Offset X", index=0) row.prop(ob, "empty_image_offset", text="Offset X", index=0)
row.prop(ob, "empty_image_offset", text="Offset Y", index=1) row.prop(ob, "empty_image_offset", text="Offset Y", index=1)

@ -394,6 +394,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
col.operator("object.multires_higher_levels_delete", text="Delete Higher") col.operator("object.multires_higher_levels_delete", text="Delete Higher")
col.operator("object.multires_reshape", text="Reshape") col.operator("object.multires_reshape", text="Reshape")
col.operator("object.multires_base_apply", text="Apply Base") col.operator("object.multires_base_apply", text="Apply Base")
col.prop(md, "use_subsurf_uv")
col.prop(md, "show_only_control_edges") col.prop(md, "show_only_control_edges")
layout.separator() layout.separator()

@ -20,8 +20,6 @@
import bpy import bpy
from rna_prop_ui import PropertyPanel from rna_prop_ui import PropertyPanel
# TODO, "color_range" not in the UI
class WorldButtonsPanel(): class WorldButtonsPanel():
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
@ -96,6 +94,10 @@ class WORLD_PT_world(WorldButtonsPanel, bpy.types.Panel):
col.active = world.use_sky_blend col.active = world.use_sky_blend
row.column().prop(world, "ambient_color") row.column().prop(world, "ambient_color")
row = layout.row()
row.prop(world, "exposure")
row.prop(world, "color_range")
class WORLD_PT_ambient_occlusion(WorldButtonsPanel, bpy.types.Panel): class WORLD_PT_ambient_occlusion(WorldButtonsPanel, bpy.types.Panel):
bl_label = "Ambient Occlusion" bl_label = "Ambient Occlusion"

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

@ -61,7 +61,9 @@ class INFO_HT_header(bpy.types.Header):
layout.template_reports_banner() layout.template_reports_banner()
layout.label(text=scene.statistics()) row = layout.row(align=True)
row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
row.label(text=scene.statistics())
# XXX: this should be right-aligned to the RHS of the region # XXX: this should be right-aligned to the RHS of the region
layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER', text="") layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER', text="")

@ -135,7 +135,7 @@ class NODE_MT_node(bpy.types.Menu):
layout.operator("transform.resize") layout.operator("transform.resize")
layout.separator() layout.separator()
layout.operator("node.duplicate_move") layout.operator("node.duplicate_move")
layout.operator("node.delete") layout.operator("node.delete")
layout.operator("node.delete_reconnect") layout.operator("node.delete_reconnect")

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
import bpy import bpy
@ -33,19 +33,21 @@ class TEXT_HT_header(bpy.types.Header):
row.template_header() row.template_header()
if context.area.show_menus: if context.area.show_menus:
sub = row.row(align=True) row.menu("TEXT_MT_view")
sub.menu("TEXT_MT_view") row.menu("TEXT_MT_text")
sub.menu("TEXT_MT_text")
if text: if text:
sub.menu("TEXT_MT_edit") row.menu("TEXT_MT_edit")
sub.menu("TEXT_MT_format") row.menu("TEXT_MT_format")
row.menu("TEXT_MT_templates")
if text and text.is_modified: if text and text.is_modified:
row = layout.row() sub = row.row()
row.alert = True sub.alert = True
row.operator("text.resolve_conflict", text="", icon='HELP') sub.operator("text.resolve_conflict", text="", icon='HELP')
layout.template_ID(st, "text", new="text.new", unlink="text.unlink") row.template_ID(st, "text", new="text.new", unlink="text.unlink")
row = layout.row(align=True) row = layout.row(align=True)
row.prop(st, "show_line_numbers", text="") row.prop(st, "show_line_numbers", text="")
@ -63,11 +65,13 @@ class TEXT_HT_header(bpy.types.Header):
row = layout.row() row = layout.row()
if text.filepath: if text.filepath:
if text.is_dirty: if text.is_dirty:
row.label(text="File: *%s (unsaved)" % text.filepath) row.label(text="File: *%r (unsaved)" % text.filepath)
else: else:
row.label(text="File: %s" % text.filepath) row.label(text="File: %r" % text.filepath)
else: else:
row.label(text="Text: External" if text.library else "Text: Internal") row.label(text="Text: External"
if text.library
else "Text: Internal")
class TEXT_PT_properties(bpy.types.Panel): class TEXT_PT_properties(bpy.types.Panel):
@ -150,8 +154,12 @@ class TEXT_MT_view(bpy.types.Menu):
layout.separator() layout.separator()
layout.operator("text.move", text="Top of File").type = 'FILE_TOP' layout.operator("text.move",
layout.operator("text.move", text="Bottom of File").type = 'FILE_BOTTOM' text="Top of File",
).type = 'FILE_TOP'
layout.operator("text.move",
text="Bottom of File",
).type = 'FILE_BOTTOM'
class TEXT_MT_text(bpy.types.Menu): class TEXT_MT_text(bpy.types.Menu):
@ -185,19 +193,15 @@ class TEXT_MT_text(bpy.types.Menu):
# XXX uiMenuItemO(head, 0, "text.refresh_pyconstraints"); # XXX uiMenuItemO(head, 0, "text.refresh_pyconstraints");
#endif #endif
layout.separator()
layout.menu("TEXT_MT_templates")
class TEXT_MT_templates(bpy.types.Menu): class TEXT_MT_templates(bpy.types.Menu):
''' bl_label = "Templates"
Creates the menu items by scanning scripts/templates
'''
bl_label = "Script Templates"
def draw(self, context): def draw(self, context):
self.path_menu(bpy.utils.script_paths("templates"), "text.open", {"internal": True}) self.path_menu(bpy.utils.script_paths("templates"),
"text.open",
{"internal": True},
)
class TEXT_MT_edit_select(bpy.types.Menu): class TEXT_MT_edit_select(bpy.types.Menu):
@ -246,8 +250,12 @@ class TEXT_MT_edit_to3d(bpy.types.Menu):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.operator("text.to_3d_object", text="One Object").split_lines = False layout.operator("text.to_3d_object",
layout.operator("text.to_3d_object", text="One Object Per Line").split_lines = True text="One Object",
).split_lines = False
layout.operator("text.to_3d_object",
text="One Object Per Line",
).split_lines = True
class TEXT_MT_edit(bpy.types.Menu): class TEXT_MT_edit(bpy.types.Menu):

@ -1020,7 +1020,6 @@ class USERPREF_PT_addons(bpy.types.Panel):
for i in range(4 - tot_row): for i in range(4 - tot_row):
split.separator() split.separator()
# Append missing scripts # Append missing scripts
# First collect scripts that are used but have no script file. # First collect scripts that are used but have no script file.
module_names = {mod.__name__ for mod, info in addons} module_names = {mod.__name__ for mod, info in addons}

@ -54,21 +54,13 @@ class VIEW3D_HT_header(bpy.types.Header):
sub.menu("VIEW3D_MT_object") sub.menu("VIEW3D_MT_object")
row = layout.row() row = layout.row()
# Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode...
row.template_header_3D() row.template_header_3D()
# do in C for now since these buttons cant be both toggle AND exclusive.
'''
if obj and obj.mode == 'EDIT' and obj.type == 'MESH':
row_sub = row.row(align=True)
row_sub.prop(toolsettings, "mesh_select_mode", text="", index=0, icon='VERTEXSEL')
row_sub.prop(toolsettings, "mesh_select_mode", text="", index=1, icon='EDGESEL')
row_sub.prop(toolsettings, "mesh_select_mode", text="", index=2, icon='FACESEL')
'''
if obj: if obj:
# Particle edit # Particle edit
if obj.mode == 'PARTICLE_EDIT': if obj.mode == 'PARTICLE_EDIT':
row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True, toggle=True) row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
# Occlude geometry # Occlude geometry
if view.viewport_shade in {'SOLID', 'SHADED', 'TEXTURED'} and (obj.mode == 'PARTICLE_EDIT' or (obj.mode == 'EDIT' and obj.type == 'MESH')): if view.viewport_shade in {'SOLID', 'SHADED', 'TEXTURED'} and (obj.mode == 'PARTICLE_EDIT' or (obj.mode == 'EDIT' and obj.type == 'MESH')):
@ -87,19 +79,22 @@ class VIEW3D_HT_header(bpy.types.Header):
row.prop(toolsettings, "proportional_edit_falloff", text="", icon_only=True) row.prop(toolsettings, "proportional_edit_falloff", text="", icon_only=True)
# Snap # Snap
snap_element = toolsettings.snap_element
row = layout.row(align=True) row = layout.row(align=True)
row.prop(toolsettings, "use_snap", text="") row.prop(toolsettings, "use_snap", text="")
row.prop(toolsettings, "snap_element", text="", icon_only=True) row.prop(toolsettings, "snap_element", text="", icon_only=True)
if toolsettings.snap_element != 'INCREMENT': if snap_element != 'INCREMENT':
row.prop(toolsettings, "snap_target", text="") row.prop(toolsettings, "snap_target", text="")
if obj and obj.mode == 'OBJECT': if obj:
row.prop(toolsettings, "use_snap_align_rotation", text="") if obj.mode == 'OBJECT':
if toolsettings.snap_element == 'VOLUME': row.prop(toolsettings, "use_snap_align_rotation", text="")
elif obj.mode == 'EDIT':
row.prop(toolsettings, "use_snap_self", text="")
if snap_element == 'VOLUME':
row.prop(toolsettings, "use_snap_peel_object", text="") row.prop(toolsettings, "use_snap_peel_object", text="")
elif toolsettings.snap_element == 'FACE': elif snap_element == 'FACE':
row.prop(toolsettings, "use_snap_project", text="") row.prop(toolsettings, "use_snap_project", text="")
if toolsettings.use_snap_project and obj.mode == 'EDIT':
row.prop(toolsettings, "use_snap_project_self", text="")
# OpenGL render # OpenGL render
row = layout.row(align=True) row = layout.row(align=True)

@ -58,6 +58,7 @@ def draw_gpencil_tools(context, layout):
row = col.row() row = col.row()
row.prop(context.tool_settings, "use_grease_pencil_sessions") row.prop(context.tool_settings, "use_grease_pencil_sessions")
# ********** default tools for objectmode **************** # ********** default tools for objectmode ****************
class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel): class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
@ -116,7 +117,8 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, bpy.types.Panel):
col.operator("transform.translate") col.operator("transform.translate")
col.operator("transform.rotate") col.operator("transform.rotate")
col.operator("transform.resize", text="Scale") col.operator("transform.resize", text="Scale")
col.operator("transform.shrink_fatten", text="Along Normal") col.operator("transform.shrink_fatten", text="Shrink/Fatten")
col.operator("transform.push_pull", text="Push/Pull")
col = layout.column(align=True) col = layout.column(align=True)
col.label(text="Deform:") col.label(text="Deform:")

@ -26,7 +26,7 @@ for obj in selection:
# bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True) # bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
obj.select = False obj.select = False
print("written:", fn) print("written:", fn)
for obj in selection: for obj in selection:

@ -0,0 +1,49 @@
import bpy
class CustomMenu(bpy.types.Menu):
bl_label = "Custom Menu"
bl_idname = "OBJECT_MT_custom_menu"
def draw(self, context):
layout = self.layout
layout.operator("wm.open_mainfile")
layout.operator("wm.save_as_mainfile").copy = True
layout.operator("object.shade_smooth")
layout.label(text="Hello world!", icon='WORLD_DATA')
# use an operator enum property to populate a submenu
layout.operator_menu_enum("object.select_by_type",
property="type",
text="Select All by Type...",
)
# call another menu
layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
def draw_item(self, context):
layout = self.layout
layout.menu(CustomMenu.bl_idname)
def register():
bpy.utils.register_class(CustomMenu)
# lets add ourselves to the main header
bpy.types.INFO_HT_header.append(draw_item)
def unregister():
bpy.utils.unregister_class(CustomMenu)
bpy.types.INFO_HT_header.remove(draw_item)
if __name__ == "__main__":
register()
# The menu can also be called from scripts
bpy.ops.wm.call_menu(name=CustomMenu.bl_idname)

@ -0,0 +1,26 @@
import bpy
class SimpleCustomMenu(bpy.types.Menu):
bl_label = "Simple Custom Menu"
bl_idname = "OBJECT_MT_simple_custom_menu"
def draw(self, context):
layout = self.layout
layout.operator("wm.open_mainfile")
layout.operator("wm.save_as_mainfile")
def register():
bpy.utils.register_class(SimpleCustomMenu)
def unregister():
bpy.utils.unregister_class(SimpleCustomMenu)
if __name__ == "__main__":
register()
# The menu can also be called from scripts
bpy.ops.wm.call_menu(name=SimpleCustomMenu.bl_idname)

@ -1,8 +1,9 @@
import bpy import bpy
class OBJECT_PT_hello(bpy.types.Panel): class HelloWorldPanel(bpy.types.Panel):
bl_label = "Hello World Panel" bl_label = "Hello World Panel"
bl_idname = "OBJECT_PT_hello"
bl_space_type = "PROPERTIES" bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW" bl_region_type = "WINDOW"
bl_context = "object" bl_context = "object"
@ -22,11 +23,11 @@ class OBJECT_PT_hello(bpy.types.Panel):
def register(): def register():
bpy.utils.register_class(OBJECT_PT_hello) bpy.utils.register_class(HelloWorldPanel)
def unregister(): def unregister():
bpy.utils.unregister_class(OBJECT_PT_hello) bpy.utils.unregister_class(HelloWorldPanel)
if __name__ == "__main__": if __name__ == "__main__":

@ -53,7 +53,7 @@ extern "C" {
/* can be left blank, otherwise a,b,c... etc with no quotes */ /* can be left blank, otherwise a,b,c... etc with no quotes */
#define BLENDER_VERSION_CHAR a #define BLENDER_VERSION_CHAR a
/* alpha/beta/rc/release, docs use this */ /* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE release #define BLENDER_VERSION_CYCLE beta
struct ListBase; struct ListBase;
struct MemFile; struct MemFile;

@ -105,6 +105,7 @@ typedef struct EffectorCache {
/* precalculated for guides */ /* precalculated for guides */
struct GuideEffectorData *guide_data; struct GuideEffectorData *guide_data;
float guide_loc[4], guide_dir[3], guide_radius; float guide_loc[4], guide_dir[3], guide_radius;
float velocity[3];
float frame; float frame;
int flag; int flag;

@ -279,6 +279,10 @@ if(WITH_IMAGE_CINEON)
add_definitions(-DWITH_CINEON) add_definitions(-DWITH_CINEON)
endif() endif()
if(WITH_IMAGE_FRAMESERVER)
add_definitions(-DWITH_FRAMESERVER)
endif()
if(WITH_IMAGE_HDR) if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR) add_definitions(-DWITH_HDR)
endif() endif()

@ -22,6 +22,7 @@ incs += ' ' + env['BF_ZLIB_INC']
defs = [ 'GLEW_STATIC' ] defs = [ 'GLEW_STATIC' ]
defs.append('WITH_SMOKE') # TODO, make optional defs.append('WITH_SMOKE') # TODO, make optional
defs.append('WITH_FRAMESERVER') # TODO, make optional
if env['WITH_BF_PYTHON']: if env['WITH_BF_PYTHON']:
incs += ' ../python' incs += ' ../python'

@ -1325,6 +1325,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang); QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
offset += sizeof(float)*4; offset += sizeof(float)*4;
} }
(void)offset;
} }
curface++; curface++;
if(mface->v4) { if(mface->v4) {
@ -1365,6 +1366,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang); QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
offset += sizeof(float)*4; offset += sizeof(float)*4;
} }
(void)offset;
} }
curface++; curface++;
i++; i++;

@ -466,7 +466,6 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
MDisps tris[2]; MDisps tris[2];
int vindex[4] = {0}; int vindex[4] = {0};
S = 0;
for(i = 0; i < 2; i++) for(i = 0; i < 2; i++)
for(y = 0; y < 4; y++) for(y = 0; y < 4; y++)
for(x = 0; x < 4; x++) for(x = 0; x < 4; x++)

@ -241,6 +241,16 @@ static void precalculate_effector(EffectorCache *eff)
} }
else if(eff->psys) else if(eff->psys)
psys_update_particle_tree(eff->psys, eff->scene->r.cfra); psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
/* Store object velocity */
if(eff->ob) {
float old_vel[3];
where_is_object_time(eff->scene, eff->ob, cfra - 1.0f);
copy_v3_v3(old_vel, eff->ob->obmat[3]);
where_is_object_time(eff->scene, eff->ob, cfra);
sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel);
}
} }
static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd) static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
{ {
@ -680,10 +690,6 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
Object *ob = eff->ob; Object *ob = eff->ob;
Object obcopy = *ob; Object obcopy = *ob;
/* XXX this is not thread-safe, but used from multiple threads by
particle system */
where_is_object_time(eff->scene, ob, cfra);
/* use z-axis as normal*/ /* use z-axis as normal*/
normalize_v3_v3(efd->nor, ob->obmat[2]); normalize_v3_v3(efd->nor, ob->obmat[2]);
@ -702,13 +708,8 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
VECCOPY(efd->loc, ob->obmat[3]); VECCOPY(efd->loc, ob->obmat[3]);
} }
if(real_velocity) { if(real_velocity)
VECCOPY(efd->vel, ob->obmat[3]); copy_v3_v3(efd->vel, eff->velocity);
where_is_object_time(eff->scene, ob, cfra - 1.0f);
sub_v3_v3v3(efd->vel, efd->vel, ob->obmat[3]);
}
*eff->ob = obcopy; *eff->ob = obcopy;

@ -550,7 +550,7 @@ Material *material_pop_id(ID *id, int index)
Material **mat; Material **mat;
if(index + 1 != (*totcol)) if(index + 1 != (*totcol))
memmove((*matar), (*matar) + 1, sizeof(void *) * ((*totcol) - (index + 1))); memmove((*matar)+index, (*matar)+(index+1), sizeof(void *) * ((*totcol) - (index + 1)));
(*totcol)--; (*totcol)--;

@ -465,12 +465,13 @@ static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lv
return multires_dm_create_from_derived(&mmd, 1, dm, ob, 0, 0); return multires_dm_create_from_derived(&mmd, 1, dm, ob, 0, 0);
} }
static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal) static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv)
{ {
SubsurfModifierData smd= {{NULL}}; SubsurfModifierData smd= {{NULL}};
smd.levels = smd.renderLevels = lvl; smd.levels = smd.renderLevels = lvl;
smd.flags |= eSubsurfModifierFlag_SubsurfUv; if(!plain_uv)
smd.flags |= eSubsurfModifierFlag_SubsurfUv;
if(simple) if(simple)
smd.subdivType = ME_SIMPLE_SUBSURF; smd.subdivType = ME_SIMPLE_SUBSURF;
if(optimal) if(optimal)
@ -591,7 +592,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
/* subdivide the mesh to highest level without displacements */ /* subdivide the mesh to highest level without displacements */
cddm = CDDM_from_mesh(me, NULL); cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH); DM_set_only_copy(cddm, CD_MASK_BAREMESH);
origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0); origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
cddm->release(cddm); cddm->release(cddm);
/* calc disps */ /* calc disps */
@ -626,7 +627,7 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
/* create subsurf DM from original mesh at high level */ /* create subsurf DM from original mesh at high level */
cddm = CDDM_from_mesh(me, NULL); cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH); DM_set_only_copy(cddm, CD_MASK_BAREMESH);
highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0); highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
/* create multires DM from original mesh at low level */ /* create multires DM from original mesh at low level */
lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple); lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple);
@ -830,7 +831,7 @@ static void multiresModifier_update(DerivedMesh *dm)
else cddm = CDDM_from_mesh(me, NULL); else cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH); DM_set_only_copy(cddm, CD_MASK_BAREMESH);
highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0); highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
/* create multires DM from original mesh and displacements */ /* create multires DM from original mesh and displacements */
lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple); lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple);
@ -884,7 +885,7 @@ static void multiresModifier_update(DerivedMesh *dm)
else cddm = CDDM_from_mesh(me, NULL); else cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH); DM_set_only_copy(cddm, CD_MASK_BAREMESH);
subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0); subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
cddm->release(cddm); cddm->release(cddm);
multiresModifier_disp_run(dm, me, 1, 0, subdm->getGridData(subdm), mmd->totlvl); multiresModifier_disp_run(dm, me, 1, 0, subdm->getGridData(subdm), mmd->totlvl);
@ -927,7 +928,8 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int loca
return dm; return dm;
result = subsurf_dm_create_local(ob, dm, lvl, result = subsurf_dm_create_local(ob, dm, lvl,
mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges); mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges,
mmd->flags & eMultiresModifierFlag_PlainUv);
if(!local_mmd) { if(!local_mmd) {
ccgdm = (CCGDerivedMesh*)result; ccgdm = (CCGDerivedMesh*)result;
@ -1633,7 +1635,7 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
MEM_freeN(vertCos); MEM_freeN(vertCos);
/* scaled ccgDM for tangent space of object with applied scale */ /* scaled ccgDM for tangent space of object with applied scale */
dm= subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0); dm= subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
cddm->release(cddm); cddm->release(cddm);
/*numGrids= dm->getNumGrids(dm);*/ /*UNUSED*/ /*numGrids= dm->getNumGrids(dm);*/ /*UNUSED*/

@ -2373,7 +2373,7 @@ static void RVBlurBitmap2_float ( float* map, int width,int height,
/* Blancmange (bmange@airdmhor.gen.nz) */ /* Blancmange (bmange@airdmhor.gen.nz) */
k = -1.0f/(2.0f*(float)M_PI*blur*blur); k = -1.0f/(2.0f*(float)M_PI*blur*blur);
fval=0;
for (ix = 0;ix< halfWidth;ix++){ for (ix = 0;ix< halfWidth;ix++){
weight = (float)exp(k*(ix*ix)); weight = (float)exp(k*(ix*ix));
filter[halfWidth - ix] = weight; filter[halfWidth - ix] = weight;

@ -400,7 +400,13 @@ Text *add_text(const char *file, const char *relpath)
llen++; llen++;
} }
if (llen!=0 || ta->nlines==0) { /* create new line in cases:
- rest of line (if last line in file hasn't got \n terminator).
in this case content of such line would be used to fill text line buffer
- file is empty. in this case new line is needed to start editing from.
- last characted in buffer is \n. in this case new line is needed to
deal with newline at end of file. (see [#28087]) (sergey) */
if (llen!=0 || ta->nlines==0 || buffer[len-1]=='\n') {
tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline"); tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
tmp->line= (char*) MEM_mallocN(llen+1, "textline_string"); tmp->line= (char*) MEM_mallocN(llen+1, "textline_string");
tmp->format= NULL; tmp->format= NULL;
@ -1417,6 +1423,8 @@ void txt_insert_buf(Text *text, const char *in_buffer)
} }
undoing= u; undoing= u;
(void)count;
} }
/******************/ /******************/

@ -105,13 +105,18 @@ bMovieHandle *BKE_get_movie_handle(int imtype)
mh.get_movie_path = filepath_ffmpeg; mh.get_movie_path = filepath_ffmpeg;
} }
#endif #endif
#ifdef WITH_FRAMESERVER
if (imtype == R_FRAMESERVER) { if (imtype == R_FRAMESERVER) {
mh.start_movie = start_frameserver; mh.start_movie = start_frameserver;
mh.append_movie = append_frameserver; mh.append_movie = append_frameserver;
mh.end_movie = end_frameserver; mh.end_movie = end_frameserver;
mh.get_next_frame = frameserver_loop; mh.get_next_frame = frameserver_loop;
} }
#endif
/* incase all above are disabled */
(void)imtype;
return &mh; return &mh;
} }

@ -22,6 +22,7 @@
* *
*/ */
#ifdef WITH_FRAMESERVER
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -381,3 +382,4 @@ void end_frameserver(void)
shutdown_socket_system(); shutdown_socket_system();
} }
#endif /* WITH_FRAMESERVER */

@ -37,12 +37,36 @@ MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw): COLLADASW::Li
void MaterialsExporter::exportMaterials(Scene *sce, bool export_selected) void MaterialsExporter::exportMaterials(Scene *sce, bool export_selected)
{ {
openLibrary(); if(hasMaterials(sce)) {
openLibrary();
MaterialFunctor mf; MaterialFunctor mf;
mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, export_selected); mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, export_selected);
closeLibrary(); closeLibrary();
}
}
bool MaterialsExporter::hasMaterials(Scene *sce)
{
Base *base = (Base *)sce->base.first;
while(base) {
Object *ob= base->object;
int a;
for(a = 0; a < ob->totcol; a++)
{
Material *ma = give_current_material(ob, a+1);
// no material, but check all of the slots
if (!ma) continue;
return true;
}
base= base->next;
}
return false;
} }
void MaterialsExporter::operator()(Material *ma, Object *ob) void MaterialsExporter::operator()(Material *ma, Object *ob)

@ -51,6 +51,9 @@ public:
MaterialsExporter(COLLADASW::StreamWriter *sw); MaterialsExporter(COLLADASW::StreamWriter *sw);
void exportMaterials(Scene *sce, bool export_selected); void exportMaterials(Scene *sce, bool export_selected);
void operator()(Material *ma, Object *ob); void operator()(Material *ma, Object *ob);
private:
bool hasMaterials(Scene *sce);
}; };
// used in forEachMaterialInScene // used in forEachMaterialInScene

@ -1478,10 +1478,8 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *e
bArmature *arm; bArmature *arm;
EditBone *bone, *curBone, *next; EditBone *bone, *curBone, *next;
int extend= RNA_boolean_get(op->ptr, "extend"); int extend= RNA_boolean_get(op->ptr, "extend");
ARegion *ar;
Object *obedit= CTX_data_edit_object(C); Object *obedit= CTX_data_edit_object(C);
arm= obedit->data; arm= obedit->data;
ar= CTX_wm_region(C);
view3d_operator_needs_opengl(C); view3d_operator_needs_opengl(C);

@ -39,6 +39,7 @@ struct Tex;
struct bContext; struct bContext;
struct bNode; struct bNode;
struct ID; struct ID;
struct ScrArea;
/* drawnode.c */ /* drawnode.c */
void ED_init_node_butfuncs(void); void ED_init_node_butfuncs(void);
@ -51,6 +52,8 @@ void ED_node_generic_update(struct Main *bmain, struct bNodeTree *ntree, struct
void ED_node_shader_default(struct Material *ma); void ED_node_shader_default(struct Material *ma);
void ED_node_composit_default(struct Scene *sce); void ED_node_composit_default(struct Scene *sce);
void ED_node_texture_default(struct Tex *tex); void ED_node_texture_default(struct Tex *tex);
void ED_node_link_intersect_test(struct ScrArea *sa, int test);
void ED_node_link_insert(struct ScrArea *sa);
/* node ops.c */ /* node ops.c */
void ED_operatormacros_node(void); void ED_operatormacros_node(void);

@ -1879,7 +1879,6 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
if(but->autocomplete_func || data->searchbox) { if(but->autocomplete_func || data->searchbox) {
changed= ui_textedit_autocomplete(C, but, data); changed= ui_textedit_autocomplete(C, but, data);
update= 1; /* do live update for tab key */ update= 1; /* do live update for tab key */
retval= WM_UI_HANDLER_BREAK;
} }
/* the hotkey here is not well defined, was G.qual so we check all */ /* the hotkey here is not well defined, was G.qual so we check all */
else if(event->shift || event->ctrl || event->alt || event->oskey) { else if(event->shift || event->ctrl || event->alt || event->oskey) {
@ -2325,8 +2324,8 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa
if(fac != 1.0f) { if(fac != 1.0f) {
/* snap in unit-space */ /* snap in unit-space */
tempf /= fac; tempf /= fac;
softmin /= fac; /* softmin /= fac; */ /* UNUSED */
softmax /= fac; /* softmax /= fac; */ /* UNUSED */
softrange /= fac; softrange /= fac;
} }
@ -3469,13 +3468,13 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
CurveMapping *cumap= (CurveMapping*)but->poin; CurveMapping *cumap= (CurveMapping*)but->poin;
CurveMap *cuma= cumap->cm+cumap->cur; CurveMap *cuma= cumap->cm+cumap->cur;
CurveMapPoint *cmp= cuma->curve; CurveMapPoint *cmp= cuma->curve;
float fx, fy, zoomx, zoomy, offsx, offsy; float fx, fy, zoomx, zoomy /*, offsx, offsy */ /* UNUSED */;
int a, changed= 0; int a, changed= 0;
zoomx= (but->x2-but->x1)/(cumap->curr.xmax-cumap->curr.xmin); zoomx= (but->x2-but->x1)/(cumap->curr.xmax-cumap->curr.xmin);
zoomy= (but->y2-but->y1)/(cumap->curr.ymax-cumap->curr.ymin); zoomy= (but->y2-but->y1)/(cumap->curr.ymax-cumap->curr.ymin);
offsx= cumap->curr.xmin; /* offsx= cumap->curr.xmin; */
offsy= cumap->curr.ymin; /* offsy= cumap->curr.ymin; */
if(snap) { if(snap) {
float d[2]; float d[2];

@ -149,10 +149,10 @@ typedef struct uiLayoutItemBx {
uiBut *roundbox; uiBut *roundbox;
} uiLayoutItemBx; } uiLayoutItemBx;
typedef struct uiLayoutItemSplt { typedef struct uiLayoutItemSplit {
uiLayout litem; uiLayout litem;
float percentage; float percentage;
} uiLayoutItemSplt; } uiLayoutItemSplit;
typedef struct uiLayoutItemRoot { typedef struct uiLayoutItemRoot {
uiLayout litem; uiLayout litem;
@ -1615,7 +1615,7 @@ static void ui_litem_layout_row(uiLayout *litem)
int x, y, w, tot, totw, neww, itemw, minw, itemh, offset; int x, y, w, tot, totw, neww, itemw, minw, itemh, offset;
int fixedw, freew, fixedx, freex, flag= 0, lastw= 0; int fixedw, freew, fixedx, freex, flag= 0, lastw= 0;
x= litem->x; /* x= litem->x; */ /* UNUSED */
y= litem->y; y= litem->y;
w= litem->w; w= litem->w;
totw= 0; totw= 0;
@ -2020,7 +2020,7 @@ static void ui_litem_estimate_split(uiLayout *litem)
static void ui_litem_layout_split(uiLayout *litem) static void ui_litem_layout_split(uiLayout *litem)
{ {
uiLayoutItemSplt *split= (uiLayoutItemSplt*)litem; uiLayoutItemSplit *split= (uiLayoutItemSplit*)litem;
uiItem *item; uiItem *item;
float percentage; float percentage;
const int tot= BLI_countlist(&litem->items); const int tot= BLI_countlist(&litem->items);
@ -2242,9 +2242,9 @@ uiLayout *uiLayoutOverlap(uiLayout *layout)
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align) uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align)
{ {
uiLayoutItemSplt *split; uiLayoutItemSplit *split;
split= MEM_callocN(sizeof(uiLayoutItemSplt), "uiLayoutItemSplt"); split= MEM_callocN(sizeof(uiLayoutItemSplit), "uiLayoutItemSplit");
split->litem.item.type= ITEM_LAYOUT_SPLIT; split->litem.item.type= ITEM_LAYOUT_SPLIT;
split->litem.root= layout->root; split->litem.root= layout->root;
split->litem.align= align; split->litem.align= align;

@ -575,8 +575,8 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
ui_draw_tria_rect(&itemrect, 'h'); ui_draw_tria_rect(&itemrect, 'h');
else else
ui_draw_tria_rect(&itemrect, 'v'); ui_draw_tria_rect(&itemrect, 'v');
(void)ofsx;
} }
/************************** panel alignment *************************/ /************************** panel alignment *************************/

@ -484,6 +484,17 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
} }
} }
} }
else if (ELEM(but->type, MENU, PULLDOWN)) {
if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) {
if(but->menu_create_func && WM_menutype_contains((MenuType *)but->poin)) {
MenuType *mt= (MenuType *)but->poin;
BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Python: %s", mt->idname);
data->color[data->totline]= 0x888888;
data->totline++;
}
}
}
assert(data->totline < MAX_TOOLTIP_LINES); assert(data->totline < MAX_TOOLTIP_LINES);

@ -851,7 +851,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
/* verify we have valid data */ /* verify we have valid data */
if(!RNA_struct_is_a(ptr->type, &RNA_Modifier)) { if(!RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
RNA_warning("uiTemplateModifier: expected modifier on object.\n"); RNA_warning("uiTemplateModifier: Expected modifier on object.\n");
return NULL; return NULL;
} }
@ -859,7 +859,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
md= ptr->data; md= ptr->data;
if(!ob || !(GS(ob->id.name) == ID_OB)) { if(!ob || !(GS(ob->id.name) == ID_OB)) {
RNA_warning("uiTemplateModifier: expected modifier on object.\n"); RNA_warning("uiTemplateModifier: Expected modifier on object.\n");
return NULL; return NULL;
} }
@ -976,9 +976,6 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
block= uiLayoutGetBlock(box); block= uiLayoutGetBlock(box);
/* Draw constraint header */ /* Draw constraint header */
/* rounded header */
// rb_col= (con->flag & CONSTRAINT_ACTIVE)?50:20; // UNUSED
/* open/close */ /* open/close */
uiBlockSetEmboss(block, UI_EMBOSSN); uiBlockSetEmboss(block, UI_EMBOSSN);
@ -1083,7 +1080,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
/* verify we have valid data */ /* verify we have valid data */
if(!RNA_struct_is_a(ptr->type, &RNA_Constraint)) { if(!RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
RNA_warning("uiTemplateConstraint: expected constraint on object.\n"); RNA_warning("uiTemplateConstraint: Expected constraint on object.\n");
return NULL; return NULL;
} }
@ -1091,7 +1088,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
con= ptr->data; con= ptr->data;
if(!ob || !(GS(ob->id.name) == ID_OB)) { if(!ob || !(GS(ob->id.name) == ID_OB)) {
RNA_warning("uiTemplateConstraint: expected constraint on object.\n"); RNA_warning("uiTemplateConstraint: Expected constraint on object.\n");
return NULL; return NULL;
} }
@ -1137,7 +1134,7 @@ void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, M
PointerRNA texture_ptr; PointerRNA texture_ptr;
if(id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) { if(id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) {
RNA_warning("uiTemplatePreview: expected ID of type material, texture, lamp or world.\n"); RNA_warning("uiTemplatePreview: Expected ID of type material, texture, lamp or world.\n");
return; return;
} }
@ -2177,14 +2174,14 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
if(prop) { if(prop) {
type= RNA_property_type(prop); type= RNA_property_type(prop);
if(type != PROP_COLLECTION) { if(type != PROP_COLLECTION) {
RNA_warning("uiTemplateList: expected collection property.\n"); RNA_warning("uiTemplateList: Expected collection property.\n");
return; return;
} }
} }
activetype= RNA_property_type(activeprop); activetype= RNA_property_type(activeprop);
if(activetype != PROP_INT) { if(activetype != PROP_INT) {
RNA_warning("uiTemplateList: expected integer property.\n"); RNA_warning("uiTemplateList: Expected integer property.\n");
return; return;
} }
@ -2206,7 +2203,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
/* create list items */ /* create list items */
RNA_PROP_BEGIN(ptr, itemptr, prop) { RNA_PROP_BEGIN(ptr, itemptr, prop) {
/* create button */ /* create button */
if(i == 9) if(!(i % 9))
row= uiLayoutRow(col, 0); row= uiLayoutRow(col, 0);
icon= list_item_icon_get(C, &itemptr, rnaicon, 1); icon= list_item_icon_get(C, &itemptr, rnaicon, 1);
@ -2221,7 +2218,6 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
} }
else if(listtype == 'c') { else if(listtype == 'c') {
/* compact layout */ /* compact layout */
found= 0;
row= uiLayoutRow(layout, 1); row= uiLayoutRow(layout, 1);

@ -1115,10 +1115,11 @@ void init_userdef_do_versions(void)
} }
if(U.pad_rot_angle==0) if(U.pad_rot_angle==0)
U.pad_rot_angle= 15; U.pad_rot_angle= 15;
if(U.flag & USER_CUSTOM_RANGE) /* signal for derivedmesh to use colorband */
vDM_ColorBand_store(&U.coba_weight); /* signal for derivedmesh to use colorband */ /* run incase this was on and is now off in the user prefs [#28096] */
vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight):NULL);
if (bmain->versionfile <= 191) { if (bmain->versionfile <= 191) {
strcpy(U.plugtexdir, U.textudir); strcpy(U.plugtexdir, U.textudir);
strcpy(U.sounddir, "/"); strcpy(U.sounddir, "/");

@ -806,14 +806,14 @@ static int object_delete_exec(bContext *C, wmOperator *UNUSED(op))
{ {
Main *bmain= CTX_data_main(C); Main *bmain= CTX_data_main(C);
Scene *scene= CTX_data_scene(C); Scene *scene= CTX_data_scene(C);
int islamp= 0; /* int islamp= 0; */ /* UNUSED */
if(CTX_data_edit_object(C)) if(CTX_data_edit_object(C))
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
CTX_DATA_BEGIN(C, Base*, base, selected_bases) { CTX_DATA_BEGIN(C, Base*, base, selected_bases) {
if(base->object->type==OB_LAMP) islamp= 1; /* if(base->object->type==OB_LAMP) islamp= 1; */
/* deselect object -- it could be used in other scenes */ /* deselect object -- it could be used in other scenes */
base->object->flag &= ~SELECT; base->object->flag &= ~SELECT;

@ -2162,16 +2162,20 @@ static int game_property_copy_exec(bContext *C, wmOperator *op)
} CTX_DATA_END; } CTX_DATA_END;
} }
} }
else if (ELEM(type, COPY_PROPERTIES_REPLACE, COPY_PROPERTIES_MERGE)) {
else {
CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) {
if (ob != ob_iter) { if (ob != ob_iter) {
if (ob->data != ob_iter->data){ if (ob->data != ob_iter->data){
if (type == 2) {/* merge */ if (type == COPY_PROPERTIES_REPLACE)
copy_properties( &ob_iter->prop, &ob->prop );
/* merge - the default when calling with no argument */
else {
for(prop = ob->prop.first; prop; prop= prop->next ) { for(prop = ob->prop.first; prop; prop= prop->next ) {
set_ob_property(ob_iter, prop); set_ob_property(ob_iter, prop);
} }
} else /* replace */ }
copy_properties( &ob_iter->prop, &ob->prop );
} }
} }
} }

@ -108,7 +108,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot)
/* identifiers */ /* identifiers */
ot->name= "Add Material Slot"; ot->name= "Add Material Slot";
ot->idname= "OBJECT_OT_material_slot_add"; ot->idname= "OBJECT_OT_material_slot_add";
ot->description="Add a new material slot or duplicate the selected one"; ot->description="Add a new material slot";
/* api callbacks */ /* api callbacks */
ot->exec= material_slot_add_exec; ot->exec= material_slot_add_exec;

@ -1869,10 +1869,17 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
else { else {
/* check cyclic */ /* check cyclic */
if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) { if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
if(link->fromnode->flag & SELECT) /* special indicated link, on drop-node */
th_col1= TH_EDGE_SELECT; if(link->flag & NODE_LINKFLAG_HILITE) {
if(link->tonode->flag & SELECT) th_col1= th_col2= TH_ACTIVE;
th_col2= TH_EDGE_SELECT; }
else {
/* regular link */
if(link->fromnode->flag & SELECT)
th_col1= TH_EDGE_SELECT;
if(link->tonode->flag & SELECT)
th_col2= TH_EDGE_SELECT;
}
do_shaded= 1; do_shaded= 1;
do_triple= 1; do_triple= 1;
} }

@ -781,14 +781,15 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, ""); iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
} }
{ /* always hide/reveal unused sockets */ { /* always hide/reveal unused sockets */
int shade; // XXX re-enable
/* int shade;
if(node_has_hidden_sockets(node))
shade= -40;
else
shade= -90; */
iconofs-=iconbutw; iconofs-=iconbutw;
// XXX re-enable
/*if(node_has_hidden_sockets(node))
shade= -40;
else*/
shade= -90;
uiDefIconBut(node->block, LABEL, B_REDR, ICON_PLUS, iconofs, rct->ymax-NODE_DY, uiDefIconBut(node->block, LABEL, B_REDR, ICON_PLUS, iconofs, rct->ymax-NODE_DY,
iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, ""); iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
} }

@ -1101,7 +1101,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot)
ot->cancel= snode_bg_viewmove_cancel; ot->cancel= snode_bg_viewmove_cancel;
/* flags */ /* flags */
ot->flag= OPTYPE_BLOCKING; ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
} }
static int backimage_zoom(bContext *C, wmOperator *op) static int backimage_zoom(bContext *C, wmOperator *op)
@ -2216,6 +2216,12 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
/* we might need to remove a link */ /* we might need to remove a link */
if(in_out==SOCK_OUT) if(in_out==SOCK_OUT)
node_remove_extra_links(snode, link->tosock, link); node_remove_extra_links(snode, link->tosock, link);
/* when linking to group outputs, update the socket type */
/* XXX this should all be part of a generic update system */
if (!link->tonode) {
link->tosock->type = link->fromsock->type;
}
} }
else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) { else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
/* automatically add new group socket */ /* automatically add new group socket */
@ -2492,6 +2498,151 @@ void NODE_OT_links_cut(wmOperatorType *ot)
RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
} }
/* ********************* automatic node insert on dragging ******************* */
/* assumes sockets in list */
static bNodeSocket *socket_best_match(ListBase *sockets, int type)
{
bNodeSocket *sock;
/* first, match type */
for(sock= sockets->first; sock; sock= sock->next)
if(!(sock->flag & SOCK_HIDDEN))
if(type == sock->type)
return sock;
/* then just use first unhidden socket */
for(sock= sockets->first; sock; sock= sock->next)
if(!(sock->flag & SOCK_HIDDEN))
return sock;
/* OK, let's unhide proper one */
for(sock= sockets->first; sock; sock= sock->next) {
if(type == sock->type) {
sock->flag &= ~SOCK_HIDDEN;
return sock;
}
}
/* just the first */
sock= sockets->first;
sock->flag &= ~SOCK_HIDDEN;
return sockets->first;
}
/* prevent duplicate testing code below */
static SpaceNode *ed_node_link_conditions(ScrArea *sa, bNode **select)
{
SpaceNode *snode= sa?sa->spacedata.first:NULL;
bNode *node;
bNodeLink *link;
/* no unlucky accidents */
if(sa==NULL || sa->spacetype!=SPACE_NODE) return NULL;
*select= NULL;
for(node= snode->edittree->nodes.first; node; node= node->next) {
if(node->flag & SELECT) {
if(*select)
break;
else
*select= node;
}
}
/* only one selected */
if(node || *select==NULL) return NULL;
/* correct node */
if((*select)->inputs.first==NULL || (*select)->outputs.first==NULL) return NULL;
/* test node for links */
for(link= snode->edittree->links.first; link; link=link->next) {
if(link->tonode == *select || link->fromnode == *select)
return NULL;
}
return snode;
}
/* assumes link with NODE_LINKFLAG_HILITE set */
void ED_node_link_insert(ScrArea *sa)
{
bNode *node, *select;
SpaceNode *snode= ed_node_link_conditions(sa, &select);
bNodeLink *link;
bNodeSocket *sockto;
if(snode==NULL) return;
/* get the link */
for(link= snode->edittree->links.first; link; link=link->next)
if(link->flag & NODE_LINKFLAG_HILITE)
break;
if(link) {
node= link->tonode;
sockto= link->tosock;
link->tonode= select;
link->tosock= socket_best_match(&select->inputs, link->fromsock->type);
link->flag &= ~NODE_LINKFLAG_HILITE;
nodeAddLink(snode->edittree, select, socket_best_match(&select->outputs, sockto->type), node, sockto);
ntreeSolveOrder(snode->edittree); /* needed for pointers */
snode_tag_changed(snode, select);
ED_node_changed_update(snode->id, select);
}
}
/* test == 0, clear all intersect flags */
void ED_node_link_intersect_test(ScrArea *sa, int test)
{
bNode *select;
SpaceNode *snode= ed_node_link_conditions(sa, &select);
bNodeLink *link, *selink=NULL;
float mcoords[6][2];
if(snode==NULL) return;
/* clear flags */
for(link= snode->edittree->links.first; link; link=link->next)
link->flag &= ~NODE_LINKFLAG_HILITE;
if(test==0) return;
/* okay, there's 1 node, without links, now intersect */
mcoords[0][0]= select->totr.xmin;
mcoords[0][1]= select->totr.ymin;
mcoords[1][0]= select->totr.xmax;
mcoords[1][1]= select->totr.ymin;
mcoords[2][0]= select->totr.xmax;
mcoords[2][1]= select->totr.ymax;
mcoords[3][0]= select->totr.xmin;
mcoords[3][1]= select->totr.ymax;
mcoords[4][0]= select->totr.xmin;
mcoords[4][1]= select->totr.ymin;
mcoords[5][0]= select->totr.xmax;
mcoords[5][1]= select->totr.ymax;
/* we only tag a single link for intersect now */
/* idea; use header dist when more? */
for(link= snode->edittree->links.first; link; link=link->next) {
if(cut_links_intersect(link, mcoords, 5)) { /* intersect code wants edges */
if(selink)
break;
selink= link;
}
}
if(link==NULL && selink)
selink->flag |= NODE_LINKFLAG_HILITE;
}
/* ******************************** */ /* ******************************** */
// XXX some code needing updating to operators... // XXX some code needing updating to operators...
@ -2914,7 +3065,8 @@ void NODE_OT_delete(wmOperatorType *ot)
/* note: in cmp_util.c is similar code, for node_compo_pass_on() */ /* note: in cmp_util.c is similar code, for node_compo_pass_on() */
/* used for disabling node (similar code in node_draw.c for disable line) */ /* used for disabling node (similar code in node_draw.c for disable line) */
static void node_delete_reconnect(bNodeTree* tree, bNode* node) { static void node_delete_reconnect(bNodeTree* tree, bNode* node)
{
bNodeLink *link, *next; bNodeLink *link, *next;
bNodeSocket *valsocket= NULL, *colsocket= NULL, *vecsocket= NULL; bNodeSocket *valsocket= NULL, *colsocket= NULL, *vecsocket= NULL;
bNodeSocket *deliveringvalsocket= NULL, *deliveringcolsocket= NULL, *deliveringvecsocket= NULL; bNodeSocket *deliveringvalsocket= NULL, *deliveringcolsocket= NULL, *deliveringvecsocket= NULL;
@ -3142,3 +3294,5 @@ void NODE_OT_add_file(wmOperatorType *ot)
RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Datablock name to assign."); RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Datablock name to assign.");
} }

@ -101,6 +101,8 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
RNA_def_boolean(ot->srna, "replace_sel", 1, "Replace Selection", "replace the current selection"); RNA_def_boolean(ot->srna, "replace_sel", 1, "Replace Selection", "replace the current selection");
RNA_def_boolean(ot->srna, "overlap", 0, "Allow Overlap", "Don't correct overlap on new sequence strips");
if(flag & SEQPROP_FILES) if(flag & SEQPROP_FILES)
RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
} }
@ -250,7 +252,11 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
seq_active_set(scene, seq); seq_active_set(scene, seq);
seq->flag |= SELECT; seq->flag |= SELECT;
} }
if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
}
WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
return OPERATOR_FINISHED; return OPERATOR_FINISHED;
@ -305,6 +311,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
SeqLoadInfo seq_load; SeqLoadInfo seq_load;
Sequence *seq; Sequence *seq;
int tot_files; int tot_files;
const short overlap= RNA_boolean_get(op->ptr, "overlap");
seq_load_operator_info(&seq_load, op); seq_load_operator_info(&seq_load, op);
@ -325,12 +332,20 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
BLI_join_dirfile(seq_load.path, sizeof(seq_load.path), dir_only, file_only); BLI_join_dirfile(seq_load.path, sizeof(seq_load.path), dir_only, file_only);
seq= seq_load_func(C, ed->seqbasep, &seq_load); seq= seq_load_func(C, ed->seqbasep, &seq_load);
if(overlap == FALSE) {
if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
}
} }
RNA_END; RNA_END;
} }
else { else {
/* single file */ /* single file */
seq= seq_load_func(C, ed->seqbasep, &seq_load); seq= seq_load_func(C, ed->seqbasep, &seq_load);
if(overlap == FALSE) {
if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
}
} }
if (seq_load.tot_success==0) { if (seq_load.tot_success==0) {
@ -506,7 +521,11 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
/* last active name */ /* last active name */
strncpy(ed->act_imagedir, strip->dir, FILE_MAXDIR-1); strncpy(ed->act_imagedir, strip->dir, FILE_MAXDIR-1);
if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
}
WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
return OPERATOR_FINISHED; return OPERATOR_FINISHED;
@ -656,7 +675,9 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
} }
} }
if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
}
update_changed_seq_and_deps(scene, seq, 1, 1); /* runs calc_sequence */ update_changed_seq_and_deps(scene, seq, 1, 1); /* runs calc_sequence */

@ -36,6 +36,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> /* ispunct */ #include <ctype.h> /* ispunct */
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h>
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
@ -449,15 +450,14 @@ static void txt_write_file(Text *text, ReportList *reports)
FILE *fp; FILE *fp;
TextLine *tmp; TextLine *tmp;
struct stat st; struct stat st;
int res; char filepath[FILE_MAXDIR+FILE_MAXFILE];
char file[FILE_MAXDIR+FILE_MAXFILE];
BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE); BLI_strncpy(filepath, text->name, FILE_MAXDIR+FILE_MAXFILE);
BLI_path_abs(file, G.main->name); BLI_path_abs(filepath, G.main->name);
fp= fopen(file, "w"); fp= fopen(filepath, "w");
if(fp==NULL) { if(fp==NULL) {
BKE_report(reports, RPT_ERROR, "Unable to save file."); BKE_reportf(reports, RPT_ERROR, "Unable to save \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error writing file");
return; return;
} }
@ -471,8 +471,13 @@ static void txt_write_file(Text *text, ReportList *reports)
fclose (fp); fclose (fp);
res= stat(file, &st); if(stat(filepath, &st) == 0) {
text->mtime= st.st_mtime; text->mtime= st.st_mtime;
}
else {
text->mtime= 0;
BKE_reportf(reports, RPT_WARNING, "Unable to stat \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error starrng file");
}
if(text->flags & TXT_ISDIRTY) if(text->flags & TXT_ISDIRTY)
text->flags ^= TXT_ISDIRTY; text->flags ^= TXT_ISDIRTY;

@ -129,7 +129,6 @@ void ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
} }
else { else {
ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist); ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
root_parent= v3d->camera;
DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB); DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, v3d->camera); WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, v3d->camera);
} }

@ -511,17 +511,6 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
/* NDOF */
/* Not implemented yet
if (G.ndofdevice ==0 ) {
uiDefIconTextButC(block, ICONTEXTROW,B_NDOF, ICON_NDOF_TURN, ndof_pup(), 0,0,UI_UNIT_X+10,UI_UNIT_Y, &(v3d->ndofmode), 0, 3.0, 0, 0, "Ndof mode");
uiDefIconButC(block, TOG, B_NDOF, ICON_NDOF_DOM,
0,0,UI_UNIT_X,UI_UNIT_Y,
&v3d->ndoffilter, 0, 1, 0, 0, "dominant axis");
}
*/
/* Transform widget / manipulators */ /* Transform widget / manipulators */
row= uiLayoutRow(layout, 1); row= uiLayoutRow(layout, 1);
uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);

@ -969,7 +969,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
break; break;
case OKEY: case OKEY:
if (t->flag & T_PROP_EDIT && event->shift) { if (t->flag & T_PROP_EDIT && event->shift) {
t->prop_mode = (t->prop_mode + 1) % 6; t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
calculatePropRatio(t); calculatePropRatio(t);
t->redraw |= TREDRAW_HARD; t->redraw |= TREDRAW_HARD;
} }

@ -96,7 +96,7 @@ typedef struct TransSnap {
short modeSelect; short modeSelect;
short align; short align;
char project; char project;
char project_self; char snap_self;
short peel; short peel;
short status; short status;
float snapPoint[3]; /* snapping from this point */ float snapPoint[3]; /* snapping from this point */

@ -87,6 +87,7 @@
#include "ED_object.h" #include "ED_object.h"
#include "ED_markers.h" #include "ED_markers.h"
#include "ED_mesh.h" #include "ED_mesh.h"
#include "ED_node.h"
#include "ED_types.h" #include "ED_types.h"
#include "ED_uvedit.h" #include "ED_uvedit.h"
#include "ED_curve.h" /* for ED_curve_editnurbs */ #include "ED_curve.h" /* for ED_curve_editnurbs */
@ -2182,6 +2183,12 @@ void flushTransNodes(TransInfo *t)
td->loc2d[0]= td->loc[0]; td->loc2d[0]= td->loc[0];
td->loc2d[1]= td->loc[1]; td->loc2d[1]= td->loc[1];
} }
/* handle intersection with noodles */
if(t->total==1) {
ED_node_link_intersect_test(t->sa, 1);
}
} }
/* *** SEQUENCE EDITOR *** */ /* *** SEQUENCE EDITOR *** */
@ -4756,7 +4763,12 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
} }
else if (t->spacetype == SPACE_NODE) { else if (t->spacetype == SPACE_NODE) {
/* pass */ if(cancelled == 0)
ED_node_link_insert(t->sa);
/* clear link line */
ED_node_link_intersect_test(t->sa, 0);
} }
else if (t->spacetype == SPACE_ACTION) { else if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;

@ -1070,7 +1070,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
} }
} }
// Need stuff to take it from edit mesh or whatnot here // Need stuff to take it from edit mesh or whatnot here
else else if (t->spacetype == SPACE_VIEW3D)
{ {
if (t->obedit && t->obedit->type == OB_MESH && (((Mesh *)t->obedit->data)->editflag & ME_EDIT_MIRROR_X)) if (t->obedit && t->obedit->type == OB_MESH && (((Mesh *)t->obedit->data)->editflag & ME_EDIT_MIRROR_X))
{ {

@ -954,6 +954,8 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0); km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);

@ -392,7 +392,7 @@ static void initSnappingMode(TransInfo *t)
} }
else else
{ {
t->tsnap.modeSelect = t->tsnap.project_self ? SNAP_ALL : SNAP_NOT_OBEDIT; t->tsnap.modeSelect = t->tsnap.snap_self ? SNAP_ALL : SNAP_NOT_OBEDIT;
} }
} }
/* Particles edit mode*/ /* Particles edit mode*/
@ -458,23 +458,26 @@ void initSnapping(TransInfo *t, wmOperator *op)
t->tsnap.project = RNA_boolean_get(op->ptr, "use_snap_project"); t->tsnap.project = RNA_boolean_get(op->ptr, "use_snap_project");
} }
if (RNA_struct_find_property(op->ptr, "use_snap_project_self")) if (RNA_struct_find_property(op->ptr, "use_snap_self"))
{ {
t->tsnap.project = RNA_boolean_get(op->ptr, "use_snap_project_self"); t->tsnap.snap_self = RNA_boolean_get(op->ptr, "use_snap_self");
} }
} }
} }
/* use scene defaults only when transform is modal */ /* use scene defaults only when transform is modal */
else if (t->flag & T_MODAL) else if (t->flag & T_MODAL)
{ {
if (ts->snap_flag & SCE_SNAP) { if(ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE))
t->modifiers |= MOD_SNAP; {
} if (ts->snap_flag & SCE_SNAP) {
t->modifiers |= MOD_SNAP;
}
t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE); t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT); t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
t->tsnap.project_self = !((t->settings->snap_flag & SCE_SNAP_PROJECT_NO_SELF) == SCE_SNAP_PROJECT_NO_SELF); t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) == SCE_SNAP_NO_SELF);
t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT); t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
}
} }
t->tsnap.target = snap_target; t->tsnap.target = snap_target;
@ -1944,6 +1947,11 @@ static void applyGrid(TransInfo *t, float *val, int max_index, float fac[3], Gea
int i; int i;
float asp[3] = {1.0f, 1.0f, 1.0f}; // TODO: Remove hard coded limit here (3) float asp[3] = {1.0f, 1.0f, 1.0f}; // TODO: Remove hard coded limit here (3)
if(max_index > 2) {
printf("applyGrid: invalid index %d, clamping\n", max_index);
max_index= 2;
}
// Early bailing out if no need to snap // Early bailing out if no need to snap
if (fac[action] == 0.0f) if (fac[action] == 0.0f)
return; return;

@ -358,19 +358,25 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
ret= 1; ret= 1;
} }
} }
else {
if (G.f & G_DEBUG) {
printf("redo_cb: WM_operator_repeat_check returned false %s\n", op->type->name);
}
}
/* set region back */ /* set region back */
CTX_wm_region_set(C, ar); CTX_wm_region_set(C, ar);
} }
else { else {
if (G.f & G_DEBUG) { if (G.f & G_DEBUG) {
printf("redo_cb: WM_operator_repeat_check returned false %s\n", op->type->name); printf("redo_cb: ED_undo_operator_repeat called with NULL 'op'\n");
} }
} }
return ret; return ret;
} }
void ED_undo_operator_repeat_cb(bContext *C, void *arg_op, void *UNUSED(arg_unused)) void ED_undo_operator_repeat_cb(bContext *C, void *arg_op, void *UNUSED(arg_unused))
{ {
ED_undo_operator_repeat(C, (wmOperator *)arg_op); ED_undo_operator_repeat(C, (wmOperator *)arg_op);

@ -1057,6 +1057,134 @@ static void weld_align_uv(bContext *C, int tool)
} }
} }
if(tool == 's' || tool == 't' || tool == 'u') {
/* pass 1&2 variables */
int i, j;
int starttmpl= -1, connectedtostarttmpl= -1, startcorner;
int endtmpl= -1, connectedtoendtmpl= -1, endcorner;
MTFace *startface, *endface;
int itmpl, jtmpl;
EditVert *eve;
int pass; /* first 2 passes find endpoints, 3rd pass moves middle points, 4th pass is fail-on-face-selected */
EditFace *startefa, *endefa;
/* pass 3 variables */
float startx, starty, firstm, firstb, midx, midy;
float endx, endy, secondm, secondb, midmovedx, midmovedy;
float IsVertical_check= -1;
float IsHorizontal_check= -1;
for(i= 0, eve= em->verts.first; eve; eve= eve->next, i++) /* give each point a unique name */
eve->tmp.l= i;
for(pass= 1; pass <= 3; pass++) { /* do this for each endpoint */
if(pass == 3){ /* calculate */
startx= startface->uv[startcorner][0];
starty= startface->uv[startcorner][1];
endx= endface->uv[endcorner][0];
endy= endface->uv[endcorner][1];
firstm= (endy-starty)/(endx-startx);
firstb= starty-(firstm*startx);
secondm= -1.0f/firstm;
if(startx == endx) IsVertical_check= startx;
if(starty == endy) IsHorizontal_check= starty;
}
for(efa= em->faces.first; efa; efa= efa->next) { /* for each face */
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); /* get face */
if(uvedit_face_visible(scene, ima, efa, tf)) { /* if you can see it */
if(uvedit_face_selected(scene, efa, tf)) { /* if the face is selected, get out now! */
pass= 4;
break;
}
for(i= 0; (i < 3 || (i == 3 && efa->v4)); i++) { /* for each point of the face */
itmpl= (*(&efa->v1 + i))->tmp.l; /* get unique name for points */
if(pass == 3) { /* move */
if(uvedit_uv_selected(scene, efa, tf, i)) {
if(!(itmpl == starttmpl || itmpl == endtmpl)) {
if(IsVertical_check != -1) tf->uv[i][0]= IsVertical_check;
if(IsHorizontal_check != -1) tf->uv[i][1]= IsHorizontal_check;
if((IsVertical_check == -1) && (IsHorizontal_check == -1)) {
midx= tf->uv[i][0];
midy= tf->uv[i][1];
if(tool == 's') {
secondb= midy-(secondm*midx);
midmovedx= (secondb-firstb)/(firstm-secondm);
midmovedy= (secondm*midmovedx)+secondb;
tf->uv[i][0]= midmovedx;
tf->uv[i][1]= midmovedy;
}
else if(tool == 't') {
tf->uv[i][0]= (midy-firstb)/firstm; /* midmovedx */
}
else if(tool == 'u') {
tf->uv[i][1]= (firstm*midx)+firstb; /* midmovedy */
}
}
}
}
}
else {
for(j= 0; (j < 3 || (j == 3 && efa->v4)); j++) { /* also for each point on the face */
jtmpl= (*(&efa->v1 + j))->tmp.l;
if(i != j && (!efa->v4 || ABS(i-j) != 2)) { /* if the points are connected */
/* quad (0,1,2,3) 0,1 0,3 1,0 1,2 2,1 2,3 3,0 3,2
* triangle (0,1,2) 0,1 0,2 1,0 1,2 2,0 2,1 */
if(uvedit_uv_selected(scene, efa, tf, i) && uvedit_uv_selected(scene, efa, tf, j)) {
/* if the edge is selected */
if(pass == 1) { /* if finding first endpoint */
if(starttmpl == -1) { /* if the first endpoint isn't found yet */
starttmpl= itmpl; /* set unique name for endpoint */
connectedtostarttmpl= jtmpl;
/* get point that endpoint is connected to */
startface= tf; /* get face it's on */
startcorner= i; /* what corner of the face? */
startefa= efa;
efa= em->faces.first;
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
i= -1;
break;
}
if(starttmpl == itmpl && jtmpl != connectedtostarttmpl) {
starttmpl= -1; /* not an endpoint */
efa= startefa;
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
i= startcorner;
break;
}
}
else if(pass == 2) { /* if finding second endpoint */
if(endtmpl == -1 && itmpl != starttmpl) {
endtmpl= itmpl;
connectedtoendtmpl= jtmpl;
endface= tf;
endcorner= i;
endefa= efa;
efa= em->faces.first;
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
i= -1;
break;
}
if(endtmpl == itmpl && jtmpl != connectedtoendtmpl) {
endtmpl= -1;
efa= endefa;
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
i= endcorner;
break;
}
}
}
}
}
}
}
}
}
if(pass == 2 && (starttmpl == -1 || endtmpl == -1)) {
/* if endpoints aren't found */
pass=4;
}
}
}
uvedit_live_unwrap_update(sima, scene, obedit); uvedit_live_unwrap_update(sima, scene, obedit);
DAG_id_tag_update(obedit->data, 0); DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
@ -1074,6 +1202,9 @@ static int align_exec(bContext *C, wmOperator *op)
static void UV_OT_align(wmOperatorType *ot) static void UV_OT_align(wmOperatorType *ot)
{ {
static EnumPropertyItem axis_items[] = { static EnumPropertyItem axis_items[] = {
{'s', "ALIGN_S", 0, "Straighten", "Align UVs along the line defined by the endpoints"},
{'t', "ALIGN_T", 0, "Straighten X", "Align UVs along the line defined by the endpoints along the X axis"},
{'u', "ALIGN_U", 0, "Straighten Y", "Align UVs along the line defined by the endpoints along the Y axis"},
{'a', "ALIGN_AUTO", 0, "Align Auto", "Automatically choose the axis on which there is most alignment already"}, {'a', "ALIGN_AUTO", 0, "Align Auto", "Automatically choose the axis on which there is most alignment already"},
{'x', "ALIGN_X", 0, "Align X", "Align UVs on X axis"}, {'x', "ALIGN_X", 0, "Align X", "Align UVs on X axis"},
{'y', "ALIGN_Y", 0, "Align Y", "Align UVs on Y axis"}, {'y', "ALIGN_Y", 0, "Align Y", "Align UVs on Y axis"},

@ -671,7 +671,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
i = is; i = is;
GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i); GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
vn = shi->vn;
/*if(ma->mode & MA_TANGENT_VN) /*if(ma->mode & MA_TANGENT_VN)
GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);*/ GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);*/
@ -1371,9 +1371,6 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
mat->obcolalpha = 1; mat->obcolalpha = 1;
GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined); GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
} }
if(gpu_do_color_management(mat))
GPU_link(mat, "linearrgb_to_srgb", shr->combined, &shr->combined);
} }
static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma) static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
@ -1408,6 +1405,10 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
GPU_material_output_link(mat, outlink); GPU_material_output_link(mat, outlink);
} }
if(gpu_do_color_management(mat))
if(mat->outlink)
GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
/*if(!GPU_material_construct_end(mat)) { /*if(!GPU_material_construct_end(mat)) {
GPU_material_free(mat); GPU_material_free(mat);
mat= NULL; mat= NULL;

@ -252,7 +252,7 @@ void IMB_filter(struct ImBuf *ibuf);
void IMB_filterN(struct ImBuf *out, struct ImBuf *in); void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
void IMB_mask_filter_extend(char *mask, int width, int height); void IMB_mask_filter_extend(char *mask, int width, int height);
void IMB_mask_clear(struct ImBuf *ibuf, char *mask, int val); void IMB_mask_clear(struct ImBuf *ibuf, char *mask, int val);
void IMB_filter_extend(struct ImBuf *ibuf, char *mask); void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter);
void IMB_makemipmap(struct ImBuf *ibuf, int use_filter); void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
void IMB_remakemipmap(struct ImBuf *ibuf, int use_filter); void IMB_remakemipmap(struct ImBuf *ibuf, int use_filter);
struct ImBuf *IMB_getmipmap(struct ImBuf *ibuf, int level); struct ImBuf *IMB_getmipmap(struct ImBuf *ibuf, int level);

@ -21,7 +21,7 @@
* *
* The Original Code is: all of this file. * The Original Code is: all of this file.
* *
* Contributor(s): none yet. * Contributor(s): Morten Mikkelsen.
* *
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
* filter.c * filter.c
@ -326,121 +326,132 @@ void IMB_mask_clear(ImBuf *ibuf, char *mask, int val)
} }
} }
#define EXTEND_PIXEL(color, w) if((color)[3]) {r+= w*(color)[0]; g+= w*(color)[1]; b+= w*(color)[2]; a+= w*(color)[3]; tot+=w;} static int filter_make_index(const int x, const int y, const int w, const int h)
{
if(x<0 || x>=w || y<0 || y>=h) return -1; /* return bad index */
else return y*w+x;
}
static int check_pixel_assigned(const void *buffer, const char *mask, const int index, const int depth, const int is_float)
{
int res = 0;
if(index>=0) {
const int alpha_index = depth*index+(depth-1);
if(mask!=NULL) {
res = mask[index]!=0 ? 1 : 0;
}
else if( (is_float && ((const float *) buffer)[alpha_index]!=0.0f) ||
(!is_float && ((const unsigned char *) buffer)[alpha_index]!=0) ) {
res=1;
}
}
return res;
}
/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0 /* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0
* *
* When a mask is given, only effect pixels with a mask value of 1, defined as BAKE_MASK_MARGIN in rendercore.c * When a mask is given, only effect pixels with a mask value of 1, defined as BAKE_MASK_MARGIN in rendercore.c
* */ * */
void IMB_filter_extend(struct ImBuf *ibuf, char *mask) void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
{ {
register char *row1, *row2, *row3; const int width= ibuf->x;
register char *cp; const int height= ibuf->y;
int rowlen, x, y; const int depth= 4; /* always 4 channels */
const int chsize= ibuf->rect_float ? sizeof(float) : sizeof(unsigned char);
rowlen= ibuf->x; const int bsize= width*height*depth*chsize;
const int is_float= ibuf->rect_float!=NULL;
void *dstbuf= (void *) MEM_dupallocN(ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect);
if (ibuf->rect_float) { char *dstmask= mask==NULL ? NULL : (char *) MEM_dupallocN(mask);
float *temprect; void *srcbuf= ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect;
float *row1f, *row2f, *row3f; char *srcmask= mask;
float *fp; int cannot_early_out= 1, r, n, k, i, j, c;
temprect= MEM_dupallocN(ibuf->rect_float); float weight[25];
for(y=1; y<=ibuf->y; y++) { /* build a weights buffer */
/* setup rows */ n= 2;
row1f= (float *)(temprect + (y-2)*rowlen*4); k= 0;
row2f= row1f + 4*rowlen; for(i = -n; i <= n; i++)
row3f= row2f + 4*rowlen; for(j = -n; j <= n; j++)
if(y==1) weight[k++] = sqrt((float) i * i + j * j);
row1f= row2f;
else if(y==ibuf->y) /* run passes */
row3f= row2f; for(r = 0; cannot_early_out == 1 && r < filter; r++) {
int x, y;
fp= (float *)(ibuf->rect_float + (y-1)*rowlen*4); cannot_early_out = 0;
for(x=0; x<rowlen; x++) { for(y= 0; y<height; y++) {
if((mask==NULL && fp[3]==0.0f) || (mask && mask[((y-1)*rowlen)+x]==1)) { for(x= 0; x<width; x++) {
int tot= 0; const int index= filter_make_index(x, y, width, height);
float r=0.0f, g=0.0f, b=0.0f, a=0.0f;
/* only update unassigned pixels */
EXTEND_PIXEL(row1f, 1); if(!check_pixel_assigned(srcbuf, srcmask, index, depth, is_float)) {
EXTEND_PIXEL(row2f, 2); float tmp[4];
EXTEND_PIXEL(row3f, 1); float wsum=0;
EXTEND_PIXEL(row1f+4, 2); float acc[4]={0,0,0,0};
EXTEND_PIXEL(row3f+4, 2); k = 0;
if(x!=rowlen-1) {
EXTEND_PIXEL(row1f+8, 1); if (check_pixel_assigned(srcbuf, srcmask, filter_make_index(x-1, y, width, height), depth, is_float) ||
EXTEND_PIXEL(row2f+8, 2); check_pixel_assigned(srcbuf, srcmask, filter_make_index(x+1, y, width, height), depth, is_float) ||
EXTEND_PIXEL(row3f+8, 1); check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y-1, width, height), depth, is_float) ||
} check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y+1, width, height), depth, is_float)) {
if(tot) { for(i= -n; i<=n; i++) {
fp[0]= r/tot; for(j=-n; j<=n; j++) {
fp[1]= g/tot; if(i != 0 || j != 0) {
fp[2]= b/tot; const int tmpindex= filter_make_index(x+i, y+j, width, height);
fp[3]= a/tot;
if(check_pixel_assigned(srcbuf, srcmask, tmpindex, depth, is_float)) {
if(is_float) {
for(c=0; c<depth; c++)
tmp[c] = ((const float *) srcbuf)[depth*tmpindex+c];
}
else {
for(c=0; c<depth; c++)
tmp[c] = (float) ((const unsigned char *) srcbuf)[depth*tmpindex+c];
}
wsum+= weight[k];
for(c=0; c<depth; c++)
acc[c]+= weight[k] * tmp[c];
}
}
k++;
}
}
if(wsum!=0) {
for(c=0; c<depth; c++)
acc[c]/= wsum;
if(is_float) {
for(c=0; c<depth; c++)
((float *) dstbuf)[depth*index+c] = acc[c];
}
else {
for(c=0; c<depth; c++) {
((unsigned char *) dstbuf)[depth*index+c]= acc[c] > 255 ? 255 : (acc[c] < 0 ? 0 : ((unsigned char) (acc[c]+0.5f)));
}
}
if(dstmask!=NULL) dstmask[index]=FILTER_MASK_MARGIN; /* assigned */
cannot_early_out = 1;
}
} }
} }
fp+=4;
if(x!=0) {
row1f+=4; row2f+=4; row3f+=4;
}
} }
} }
MEM_freeN(temprect); /* keep the original buffer up to date. */
} memcpy(srcbuf, dstbuf, bsize);
else if(ibuf->rect) { if(dstmask!=NULL) memcpy(srcmask, dstmask, width*height);
int *temprect;
/* make a copy, to prevent flooding */
temprect= MEM_dupallocN(ibuf->rect);
for(y=1; y<=ibuf->y; y++) {
/* setup rows */
row1= (char *)(temprect + (y-2)*rowlen);
row2= row1 + 4*rowlen;
row3= row2 + 4*rowlen;
if(y==1)
row1= row2;
else if(y==ibuf->y)
row3= row2;
cp= (char *)(ibuf->rect + (y-1)*rowlen);
for(x=0; x<rowlen; x++) {
/*if(cp[3]==0) {*/
if((mask==NULL && cp[3]==0) || (mask && mask[((y-1)*rowlen)+x]==1)) {
int tot= 0, r=0, g=0, b=0, a=0;
EXTEND_PIXEL(row1, 1);
EXTEND_PIXEL(row2, 2);
EXTEND_PIXEL(row3, 1);
EXTEND_PIXEL(row1+4, 2);
EXTEND_PIXEL(row3+4, 2);
if(x!=rowlen-1) {
EXTEND_PIXEL(row1+8, 1);
EXTEND_PIXEL(row2+8, 2);
EXTEND_PIXEL(row3+8, 1);
}
if(tot) {
cp[0]= r/tot;
cp[1]= g/tot;
cp[2]= b/tot;
cp[3]= a/tot;
}
}
cp+=4;
if(x!=0) {
row1+=4; row2+=4; row3+=4;
}
}
}
MEM_freeN(temprect);
} }
/* free memory */
MEM_freeN(dstbuf);
if(dstmask!=NULL) MEM_freeN(dstmask);
} }
/* threadsafe version, only recreates existing maps */ /* threadsafe version, only recreates existing maps */

@ -624,6 +624,7 @@ typedef struct MultiresModifierData {
typedef enum { typedef enum {
eMultiresModifierFlag_ControlEdges = (1<<0), eMultiresModifierFlag_ControlEdges = (1<<0),
eMultiresModifierFlag_PlainUv = (1<<1),
} MultiresModifierFlag; } MultiresModifierFlag;
typedef struct FluidsimModifierData { typedef struct FluidsimModifierData {

@ -179,6 +179,10 @@ typedef struct bNodeLink {
} bNodeLink; } bNodeLink;
/* link->flag */
#define NODE_LINKFLAG_HILITE 1
/* the basis for a Node tree, all links and nodes reside internal here */ /* the basis for a Node tree, all links and nodes reside internal here */
/* only re-usable node trees are in the library though, materials and textures allocate own tree struct */ /* only re-usable node trees are in the library though, materials and textures allocate own tree struct */
typedef struct bNodeTree { typedef struct bNodeTree {

@ -1077,7 +1077,7 @@ typedef struct Scene {
#define SCE_SNAP_ROTATE 2 #define SCE_SNAP_ROTATE 2
#define SCE_SNAP_PEEL_OBJECT 4 #define SCE_SNAP_PEEL_OBJECT 4
#define SCE_SNAP_PROJECT 8 #define SCE_SNAP_PROJECT 8
#define SCE_SNAP_PROJECT_NO_SELF 16 #define SCE_SNAP_NO_SELF 16
/* toolsettings->snap_target */ /* toolsettings->snap_target */
#define SCE_SNAP_TARGET_CLOSEST 0 #define SCE_SNAP_TARGET_CLOSEST 0
#define SCE_SNAP_TARGET_CENTER 1 #define SCE_SNAP_TARGET_CENTER 1
@ -1110,7 +1110,8 @@ typedef struct Scene {
#define PROP_SHARP 3 #define PROP_SHARP 3
#define PROP_LIN 4 #define PROP_LIN 4
#define PROP_CONST 5 #define PROP_CONST 5
#define PROP_RANDOM 6 #define PROP_RANDOM 6
#define PROP_MODE_MAX 7
/* toolsettings->proportional */ /* toolsettings->proportional */
#define PROP_EDIT_OFF 0 #define PROP_EDIT_OFF 0

@ -171,6 +171,10 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR) add_definitions(-DWITH_HDR)
endif() endif()
if(WITH_IMAGE_FRAMESERVER)
add_definitions(-DWITH_FRAMESERVER)
endif()
if(WITH_AUDASPACE) if(WITH_AUDASPACE)
add_definitions(-DWITH_AUDASPACE) add_definitions(-DWITH_AUDASPACE)
endif() endif()

@ -54,6 +54,8 @@ if env['WITH_BF_CINEON']:
if env['WITH_BF_HDR']: if env['WITH_BF_HDR']:
defs.append('WITH_HDR') defs.append('WITH_HDR')
defs.append('WITH_FRAMESERVER') # TODO, make optional
if env['WITH_BF_FFMPEG']: if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG') defs.append('WITH_FFMPEG')
incs += ' ' + env['BF_FFMPEG_INC'] incs += ' ' + env['BF_FFMPEG_INC']

@ -1364,13 +1364,13 @@ static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerR
if(prop->noteflag) if(prop->noteflag)
WM_main_add_notifier(prop->noteflag, ptr->id.data); WM_main_add_notifier(prop->noteflag, ptr->id.data);
} }
else {
if(!is_rna || (prop->flag & PROP_IDPROPERTY)) {
/* WARNING! This is so property drivers update the display! /* WARNING! This is so property drivers update the display!
* not especially nice */ * not especially nice */
DAG_id_tag_update(ptr->id.data, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); DAG_id_tag_update(ptr->id.data, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME);
WM_main_add_notifier(NC_WINDOW, NULL); WM_main_add_notifier(NC_WINDOW, NULL);
} }
} }
/* must keep in sync with 'rna_property_update' /* must keep in sync with 'rna_property_update'
@ -4407,15 +4407,15 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *UNUSE
if(!(parm->flag & PROP_REQUIRED) && !(parm->flag & PROP_DYNAMIC)) { if(!(parm->flag & PROP_REQUIRED) && !(parm->flag & PROP_DYNAMIC)) {
switch(parm->type) { switch(parm->type) {
case PROP_BOOLEAN: case PROP_BOOLEAN:
if(parm->arraydimension) memcpy(data, &((BooleanPropertyRNA*)parm)->defaultarray, size); if(parm->arraydimension) memcpy(data, ((BooleanPropertyRNA*)parm)->defaultarray, size);
else memcpy(data, &((BooleanPropertyRNA*)parm)->defaultvalue, size); else memcpy(data, &((BooleanPropertyRNA*)parm)->defaultvalue, size);
break; break;
case PROP_INT: case PROP_INT:
if(parm->arraydimension) memcpy(data, &((IntPropertyRNA*)parm)->defaultarray, size); if(parm->arraydimension) memcpy(data, ((IntPropertyRNA*)parm)->defaultarray, size);
else memcpy(data, &((IntPropertyRNA*)parm)->defaultvalue, size); else memcpy(data, &((IntPropertyRNA*)parm)->defaultvalue, size);
break; break;
case PROP_FLOAT: case PROP_FLOAT:
if(parm->arraydimension) memcpy(data, &((FloatPropertyRNA*)parm)->defaultarray, size); if(parm->arraydimension) memcpy(data, ((FloatPropertyRNA*)parm)->defaultarray, size);
else memcpy(data, &((FloatPropertyRNA*)parm)->defaultvalue, size); else memcpy(data, &((FloatPropertyRNA*)parm)->defaultvalue, size);
break; break;
case PROP_ENUM: case PROP_ENUM:

@ -805,6 +805,11 @@ static void rna_def_modifier_multires(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_ControlEdges); RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_ControlEdges);
RNA_def_property_ui_text(prop, "Optimal Display", "Skip drawing/rendering of interior subdivided edges"); RNA_def_property_ui_text(prop, "Optimal Display", "Skip drawing/rendering of interior subdivided edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop= RNA_def_property(srna, "use_subsurf_uv", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", eMultiresModifierFlag_PlainUv);
RNA_def_property_ui_text(prop, "Subdivide UVs", "Use subsurf to subdivide UVs");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
} }
static void rna_def_modifier_lattice(BlenderRNA *brna) static void rna_def_modifier_lattice(BlenderRNA *brna)

@ -544,7 +544,7 @@ void RNA_api_object(StructRNA *srna)
/* location of point for test and max distance */ /* location of point for test and max distance */
parm= RNA_def_float_vector(func, "point", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4); parm= RNA_def_float_vector(func, "point", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_property_flag(parm, PROP_REQUIRED);
parm= RNA_def_float(func, "max_dist", sqrt(FLT_MAX), 0.0, FLT_MAX, "", "", 0.0, FLT_MAX); RNA_def_float(func, "max_dist", sqrt(FLT_MAX), 0.0, FLT_MAX, "", "", 0.0, FLT_MAX);
/* return location and normal */ /* return location and normal */
parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The location on the object closest to the point", -1e4, 1e4); parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The location on the object closest to the point", -1e4, 1e4);

@ -135,7 +135,9 @@ EnumPropertyItem image_type_items[] = {
#endif #endif
{R_AVIJPEG, "AVI_JPEG", ICON_FILE_MOVIE, "AVI JPEG", "Output video in AVI JPEG format"}, {R_AVIJPEG, "AVI_JPEG", ICON_FILE_MOVIE, "AVI JPEG", "Output video in AVI JPEG format"},
{R_AVIRAW, "AVI_RAW", ICON_FILE_MOVIE, "AVI Raw", "Output video in AVI Raw format"}, {R_AVIRAW, "AVI_RAW", ICON_FILE_MOVIE, "AVI Raw", "Output video in AVI Raw format"},
#ifdef WITH_FRAMESERVER
{R_FRAMESERVER, "FRAMESERVER", ICON_FILE_SCRIPT, "Frame Server", "Output image to a frameserver"}, {R_FRAMESERVER, "FRAMESERVER", ICON_FILE_SCRIPT, "Frame Server", "Output image to a frameserver"},
#endif
#ifdef WITH_FFMPEG #ifdef WITH_FFMPEG
{R_H264, "H264", ICON_FILE_MOVIE, "H.264", "Output video in H.264 format"}, {R_H264, "H264", ICON_FILE_MOVIE, "H.264", "Output video in H.264 format"},
{R_FFMPEG, "FFMPEG", ICON_FILE_MOVIE, "MPEG", "Output video in MPEG format"}, {R_FFMPEG, "FFMPEG", ICON_FILE_MOVIE, "MPEG", "Output video in MPEG format"},
@ -1184,9 +1186,9 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_RETOPO, 0); RNA_def_property_ui_icon(prop, ICON_RETOPO, 0);
RNA_def_property_update(prop, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */ RNA_def_property_update(prop, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */
prop= RNA_def_property(srna, "use_snap_project_self", PROP_BOOLEAN, PROP_NONE); prop= RNA_def_property(srna, "use_snap_self", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_flag", SCE_SNAP_PROJECT_NO_SELF); RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_flag", SCE_SNAP_NO_SELF);
RNA_def_property_ui_text(prop, "Project to Self", "Project into its self (editmode)"); RNA_def_property_ui_text(prop, "Project to Self", "Snap onto its self (editmode)");
RNA_def_property_ui_icon(prop, ICON_ORTHO, 0); RNA_def_property_ui_icon(prop, ICON_ORTHO, 0);
RNA_def_property_update(prop, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */ RNA_def_property_update(prop, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */
@ -2821,7 +2823,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "bake_margin", PROP_INT, PROP_NONE); prop= RNA_def_property(srna, "bake_margin", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "bake_filter"); RNA_def_property_int_sdna(prop, NULL, "bake_filter");
RNA_def_property_range(prop, 0, 32); RNA_def_property_range(prop, 0, 64);
RNA_def_property_ui_text(prop, "Margin", "Amount of pixels to extend the baked result with, as post process filter"); RNA_def_property_ui_text(prop, "Margin", "Amount of pixels to extend the baked result with, as post process filter");
prop= RNA_def_property(srna, "bake_distance", PROP_FLOAT, PROP_NONE); prop= RNA_def_property(srna, "bake_distance", PROP_FLOAT, PROP_NONE);

@ -940,7 +940,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
rna_Operator_unregister(bmain, ot->ext.srna); rna_Operator_unregister(bmain, ot->ext.srna);
} }
/* create a new menu type */ /* create a new operator type */
dummyot.ext.srna= RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator"); dummyot.ext.srna= RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */ RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */
dummyot.ext.data= data; dummyot.ext.data= data;

@ -108,4 +108,6 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix); int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix); int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
#endif /* MATHUTILS_H */ #endif /* MATHUTILS_H */

@ -1612,8 +1612,20 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
} }
} }
else if(mat1) { else if(mat1) {
/*VEC * MATRIX */
if(VectorObject_Check(m2)) {
VectorObject *vec2= (VectorObject *)m2;
float tvec[4];
if(BaseMath_ReadCallback(vec2) == -1)
return NULL;
if(column_vector_multiplication(tvec, vec2, mat1) == -1) {
return NULL;
}
return newVectorObject(tvec, vec2->size, Py_NEW, Py_TYPE(m2));
}
/*FLOAT/INT * MATRIX */ /*FLOAT/INT * MATRIX */
if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) { else if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) {
return matrix_mul_float(mat1, scalar); return matrix_mul_float(mat1, scalar);
} }
} }

@ -753,8 +753,30 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
return quat_mul_float(quat2, scalar); return quat_mul_float(quat2, scalar);
} }
} }
else if (quat1) { /* QUAT*FLOAT */ else if (quat1) {
if((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) { /* QUAT * VEC */
if (VectorObject_Check(q2)) {
VectorObject *vec2 = (VectorObject *)q2;
float tvec[3];
if(vec2->size != 3) {
PyErr_SetString(PyExc_ValueError,
"Vector multiplication: "
"only 3D vector rotations (with quats) "
"currently supported");
return NULL;
}
if(BaseMath_ReadCallback(vec2) == -1) {
return NULL;
}
copy_v3_v3(tvec, vec2->vec);
mul_qt_v3(quat1->quat, tvec);
return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec2));
}
/* QUAT * FLOAT */
else if((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) {
return quat_mul_float(quat1, scalar); return quat_mul_float(quat1, scalar);
} }
} }

Some files were not shown because too many files have changed in this diff Show More