Merged changes in the trunk up to revision 38893.

This commit is contained in:
Tamito Kajiyama 2011-08-01 20:18:02 +00:00
commit 9a0b816416
128 changed files with 2166 additions and 959 deletions

@ -1054,20 +1054,34 @@ if(APPLE OR WIN32)
endif() endif()
endif() endif()
# See TEST_SSE_SUPPORT() for how this is defined.
if(WITH_RAYOPTIMIZATION) if(WITH_RAYOPTIMIZATION)
if(CMAKE_COMPILER_IS_GNUCC) if(CMAKE_COMPILER_IS_GNUCC)
if(SUPPORT_SSE_BUILD) set(_sse "-msse")
set(PLATFORM_CFLAGS " -msse ${PLATFORM_CFLAGS}") set(_sse2 "-msse2")
add_definitions(-D__SSE__ -D__MMX__) elseif(MSVC)
endif() set(_sse "/arch:SSE")
if(SUPPORT_SSE2_BUILD) set(_sse2 "/arch:SSE2")
set(PLATFORM_CFLAGS " -msse2 ${PLATFORM_CFLAGS}") else()
add_definitions(-D__SSE2__) message(WARNING "SSE flags for this compiler not known")
if(NOT SUPPORT_SSE_BUILD) # dont double up set(_sse)
add_definitions(-D__MMX__) set(_sse2)
endif() endif()
if(SUPPORT_SSE_BUILD)
set(PLATFORM_CFLAGS " ${_sse} ${PLATFORM_CFLAGS}")
add_definitions(-D__SSE__ -D__MMX__)
endif()
if(SUPPORT_SSE2_BUILD)
set(PLATFORM_CFLAGS " ${_sse2} ${PLATFORM_CFLAGS}")
add_definitions(-D__SSE2__)
if(NOT SUPPORT_SSE_BUILD) # dont double up
add_definitions(-D__MMX__)
endif() endif()
endif() endif()
unset(_sse)
unset(_sse2)
endif() endif()
if(WITH_IMAGE_OPENJPEG) if(WITH_IMAGE_OPENJPEG)

@ -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

@ -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)

@ -8,6 +8,7 @@ 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
@ -29,6 +30,7 @@ def createTexture(cont):
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:

@ -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,16 +12,18 @@ 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"""
@ -36,6 +39,6 @@ def write():
# 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]

@ -1,28 +1,47 @@
Game Engine bge.constraints Module Physics Constraints (bge.constraints)
================================== =====================================
.. note:: .. function:: createConstraint(physicsid, physicsid2, constrainttype, [pivotX, pivotY, pivotZ, [axisX, axisY, axisZ, [flag]]]])
This documentation is still very weak, and needs some help!
.. function:: createConstraint([obj1, [obj2, [restLength, [restitution, [damping]]]]])
Creates a constraint. Creates a constraint.
:arg obj1: first object on Constraint :arg physicsid: the physics id of the first object in constraint
:type obj1: :class:'bge.types.KX_GameObject' #I think, there is no error when I use one :type physicsid: int
:arg obj2: second object on Constraint :arg physicsid2: the physics id of the second object in constraint
:type obj2: :class:'bge.types.KX_GameObject' #too :type physicsid2: int
:arg restLength: #to be filled :arg constrainttype: the type of the constraint. The constraint types are:
:type restLength: float
:arg restitution: #to be filled - :class:`POINTTOPOINT_CONSTRAINT`
:type restitution: float - :class:`LINEHINGE_CONSTRAINT`
- :class:`ANGULAR_CONSTRAINT`
- :class:`CONETWIST_CONSTRAINT`
- :class:`VEHICLE_CONSTRAINT`
:arg damping: #to be filled :type constrainttype: int
:type damping: float
:arg pivotX: pivot X position
:type pivotX: float
:arg pivotY: pivot Y position
:type pivotY: float
:arg pivotZ: pivot Z position
:type pivotZ: float
:arg axisX: X axis
:type axisX: float
:arg axisY: Y axis
:type axisY: float
:arg axisZ: Z axis
:type axisZ: float
:arg flag: .. to do
:type flag: int
.. attribute:: error .. attribute:: error
@ -49,7 +68,7 @@ Game Engine bge.constraints Module
:type constraintId: int :type constraintId: int
:return: a vehicle constraint object. :return: a vehicle constraint object.
:rtype: :class:'KX_VehicleWrapper' :rtype: :class:`bge.types.KX_VehicleWrapper`
.. function:: removeConstraint(constraintId) .. function:: removeConstraint(constraintId)
@ -60,10 +79,10 @@ Game Engine bge.constraints Module
.. function:: setCcdMode(ccdMode) .. function:: setCcdMode(ccdMode)
..note:: .. note::
Very experimental, not recommended Very experimental, not recommended
Sets the CCD mode in the Physics Environment. Sets the CCD (Continous Colision Detection) mode in the Physics Environment.
:arg ccdMode: The new CCD mode. :arg ccdMode: The new CCD mode.
:type ccdMode: int :type ccdMode: int
@ -73,21 +92,21 @@ Game Engine bge.constraints Module
.. note:: .. note::
Reasonable default is 0.02 (if units are meters) Reasonable default is 0.02 (if units are meters)
Sets the contact breaking treshold in the Physics Environment. Sets tresholds to do with contact point management.
:arg breakingTreshold: The new contact breaking treshold. :arg breakingTreshold: The new contact breaking treshold.
:type breakingTreshold: float :type breakingTreshold: float
.. function:: setDeactivationAngularTreshold(angularTreshold) .. function:: setDeactivationAngularTreshold(angularTreshold)
Sets the deactivation angular treshold. Sets the angular velocity treshold.
:arg angularTreshold: New deactivation angular treshold. :arg angularTreshold: New deactivation angular treshold.
:type angularTreshold: float :type angularTreshold: float
.. function:: setDeactivationLinearTreshold(linearTreshold) .. function:: setDeactivationLinearTreshold(linearTreshold)
Sets the deactivation linear treshold. Sets the linear velocity treshold.
:arg linearTreshold: New deactivation linear treshold. :arg linearTreshold: New deactivation linear treshold.
:type linearTreshold: float :type linearTreshold: float
@ -104,21 +123,20 @@ Game Engine bge.constraints Module
Sets the debug mode. Sets the debug mode.
Debug modes: Debug modes:
- No debug: 0 - :class:`DBG_NODEBUG`
- Draw wireframe: 1 - :class:`DBG_DRAWWIREFRAME`
- Draw Aabb: 2 #What's Aabb? - :class:`DBG_DRAWAABB`
- Draw freatures text: 4 - :class:`DBG_DRAWFREATURESTEXT`
- Draw contact points: 8 - :class:`DBG_DRAWCONTACTPOINTS`
- No deactivation: 16 - :class:`DBG_NOHELPTEXT`
- No help text: 32 - :class:`DBG_DRAWTEXT`
- Draw text: 64 - :class:`DBG_PROFILETIMINGS`
- Profile timings: 128 - :class:`DBG_ENABLESATCOMPARISION`
- Enable sat comparision: 256 - :class:`DBG_DISABLEBULLETLCP`
- Disable Bullet LCP: 512 - :class:`DBG_ENABLECCD`
- Enable CCD: 1024 - :class:`DBG_DRAWCONSTRAINTS`
- Draw Constraints: #(1 << 11) = ? - :class:`DBG_DRAWCONSTRAINTLIMITS`
- Draw Constraint Limits: #(1 << 12) = ? - :class:`DBG_FASTWIREFRAME`
- Fast Wireframe: #(1 << 13) = ?
:arg mode: The new debug mode. :arg mode: The new debug mode.
:type mode: int :type mode: int
@ -138,7 +156,10 @@ Game Engine bge.constraints Module
.. function:: setLinearAirDamping(damping) .. function:: setLinearAirDamping(damping)
Not implemented. .. note::
Not implemented.
Sets the linear air damping for rigidbodies.
.. function:: setNumIterations(numiter) .. function:: setNumIterations(numiter)
@ -156,10 +177,10 @@ Game Engine bge.constraints Module
.. function:: setSolverDamping(damping) .. function:: setSolverDamping(damping)
..note:: .. note::
Very experimental, not recommended Very experimental, not recommended
Sets the solver damping. Sets the damper constant of a penalty based solver.
:arg damping: New damping for the solver. :arg damping: New damping for the solver.
:type damping: float :type damping: float
@ -169,7 +190,7 @@ Game Engine bge.constraints Module
.. note:: .. note::
Very experimental, not recommended Very experimental, not recommended
Sets the solver tau. Sets the spring constant of a penalty based solver.
:arg tau: New tau for the solver. :arg tau: New tau for the solver.
:type tau: float :type tau: float
@ -189,7 +210,7 @@ Game Engine bge.constraints Module
.. note:: .. note::
Very experimental, not recommended Very experimental, not recommended
Sets the sor constant. Sets the successive overrelaxation constant.
:arg sor: New sor value. :arg sor: New sor value.
:type sor: float :type sor: float
@ -197,3 +218,136 @@ Game Engine bge.constraints Module
.. function:: setUseEpa(epa) .. function:: setUseEpa(epa)
Not implemented. Not implemented.
.. data:: DBG_NODEBUG
.. note::
Debug mode to be used with function :class:`setDebugMode`
No debug.
.. data:: DBG_DRAWWIREFRAME
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw wireframe in debug.
.. data:: DBG_DRAWAABB
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw Axis Aligned Bounding Box in debug.
.. data:: DBG_DRAWFREATURESTEXT
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw freatures text in debug.
.. data:: DBG_DRAWCONTACTPOINTS
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw contact points in debug.
.. data:: DBG_NOHELPTEXT
.. note::
Debug mode to be used with function :class:`setDebugMode`
Debug without help text.
.. data:: DBG_DRAWTEXT
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw text in debug.
.. data:: DBG_PROFILETIMINGS
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw profile timings in debug.
.. data:: DBG_ENABLESATCOMPARISION
.. note::
Debug mode to be used with function :class:`setDebugMode`
Enable sat comparision in debug.
.. data:: DBG_DISABLEBULLETLCP
.. note::
Debug mode to be used with function :class:`setDebugMode`
Disable Bullet LCP.
.. data:: DBG_ENABLECCD
.. note::
Debug mode to be used with function :class:`setDebugMode`
Enable Continous Colision Detection in debug.
.. data:: DBG_DRAWCONSTRAINTS
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw constraints in debug.
.. data:: DBG_DRAWCONSTRAINTLIMITS
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw constraint limits in debug.
.. data:: DBG_FASTWIREFRAME
.. note::
Debug mode to be used with function :class:`setDebugMode`
Draw a fast wireframe in debug.
.. data:: POINTTOPOINT_CONSTRAINT
.. note::
Constraint type to be used with function :class:`createConstraint`
.. to do
.. data:: LINEHINGE_CONSTRAINT
.. note::
Constraint type to be used with function :class:`createConstraint`
.. to do
.. data:: ANGULAR_CONSTRAINT
.. note::
Constraint type to be used with function :class:`createConstraint`
.. to do
.. data:: CONETWIST_CONSTRAINT
.. note::
Constraint type to be used with function :class:`createConstraint`
.. to do
.. data:: VEHICLE_CONSTRAINT
.. note::
Constraint type to be used with function :class:`createConstraint`
.. to do

@ -1,6 +1,6 @@
Game Engine bge.events Module Game Keys (bge.events)
============================= ======================
***** *****
Intro Intro

@ -1,6 +1,7 @@
Game Engine bge.logic Module Game Logic (bge.logic)
============================ ======================
***** *****
Intro Intro
***** *****

@ -1,6 +1,6 @@
Game Engine bge.render Module Rasterizer (bge.render)
============================= =======================
***** *****
Intro Intro
@ -16,8 +16,8 @@ Intro
import bge.render import bge.render
import bge.logic import bge.logic
# SCALE sets the speed of motion # scale sets the speed of motion
SCALE=[1, 0.5] scale = 1.0, 0.5
co = bge.logic.getCurrentController() co = bge.logic.getCurrentController()
obj = co.getOwner() obj = co.getOwner()
@ -27,8 +27,8 @@ Intro
# Transform the mouse coordinates to see how far the mouse has moved. # Transform the mouse coordinates to see how far the mouse has moved.
def mousePos(): def mousePos():
x = (bge.render.getWindowWidth()/2 - mouse.getXPosition())*SCALE[0] x = (bge.render.getWindowWidth() / 2 - mouse.getXPosition()) * scale[0]
y = (bge.render.getWindowHeight()/2 - mouse.getYPosition())*SCALE[1] y = (bge.render.getWindowHeight() / 2 - mouse.getYPosition()) * scale[1]
return (x, y) return (x, y)
pos = mousePos() pos = mousePos()
@ -43,7 +43,7 @@ Intro
bge.logic.addActiveActuator(wmotion, True) bge.logic.addActiveActuator(wmotion, True)
# Centre the mouse # Centre the mouse
bge.render.setMousePosition(bge.render.getWindowWidth()/2, bge.render.getWindowHeight()/2) bge.render.setMousePosition(bge.render.getWindowWidth() / 2, bge.render.getWindowHeight() / 2)
********* *********
Constants Constants

@ -1,10 +1,6 @@
Game Engine bge.texture Module Video Texture (bge.texture)
============================== ===========================
.. note::
This documentation is still very weak, and needs some help! Right now they are mostly a collection
of the docstrings found in the bge.texture source code + some random places filled with text.
***** *****
Intro Intro

@ -1,6 +1,6 @@
Game Engine bge.types Module Game Types (bge.types)
============================= ======================
.. module:: bge.types .. module:: bge.types

@ -1,6 +1,6 @@
bgl module (OpenGL wrapper) OpenGL Wrapper (bgl)
=========================== ====================
.. module:: bgl .. module:: bgl
@ -71,8 +71,8 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
.. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/begin.html>`_ .. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/begin.html>`_
:type mode: Enumerated constant :type mode: Enumerated constant
:arg mode: Specifies the primitive that will be create from vertices between glBegin and :arg mode: Specifies the primitive that will be create from vertices between
glEnd. glBegin and glEnd.
.. function:: glBindTexture(target, texture): .. function:: glBindTexture(target, texture):
@ -1886,4 +1886,3 @@ class Buffer:
the Buffer. If a template is not passed in all fields will be initialized to 0. the Buffer. If a template is not passed in all fields will be initialized to 0.
:rtype: Buffer object :rtype: Buffer object
:return: The newly created buffer as a PyObject. :return: The newly created buffer as a PyObject.

@ -418,6 +418,7 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
del key, descr del key, descr
classes = [] classes = []
submodules = []
for attribute in module_dir: for attribute in module_dir:
if not attribute.startswith("_"): if not attribute.startswith("_"):
@ -439,6 +440,8 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
py_c_func2sphinx("", fw, module_name, None, attribute, value, is_class=False) py_c_func2sphinx("", fw, module_name, None, attribute, value, is_class=False)
elif value_type == type: elif value_type == type:
classes.append((attribute, value)) classes.append((attribute, value))
elif issubclass(value_type, types.ModuleType):
submodules.append((attribute, value))
elif value_type in (bool, int, float, str, tuple): elif value_type in (bool, int, float, str, tuple):
# constant, not much fun we can do here except to list it. # constant, not much fun we can do here except to list it.
# TODO, figure out some way to document these! # TODO, figure out some way to document these!
@ -446,12 +449,26 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
write_indented_lines(" ", fw, "constant value %s" % repr(value), False) write_indented_lines(" ", fw, "constant value %s" % repr(value), False)
fw("\n") fw("\n")
else: else:
print("\tnot documenting %s.%s" % (module_name, attribute)) print("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__))
continue continue
attribute_set.add(attribute) attribute_set.add(attribute)
# TODO, more types... # TODO, more types...
# TODO, bpy_extras does this already, mathutils not.
"""
if submodules:
fw("\n"
"**********\n"
"Submodules\n"
"**********\n"
"\n"
)
for attribute, submod in submodules:
fw("* :mod:`%s.%s`\n" % (module_name, attribute))
fw("\n")
"""
# write collected classes now # write collected classes now
for (type_name, value) in classes: for (type_name, value) in classes:
# May need to be its own function # May need to be its own function

@ -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

@ -1560,6 +1560,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
GHOST_TInt32 delta; GHOST_TInt32 delta;
double deltaF = [event deltaY]; double deltaF = [event deltaY];
if (deltaF == 0.0) deltaF = [event deltaX]; // make blender decide if it's horizontal scroll
if (deltaF == 0.0) break; //discard trackpad delta=0 events if (deltaF == 0.0) break; //discard trackpad delta=0 events
delta = deltaF > 0.0 ? 1 : -1; delta = deltaF > 0.0 ? 1 : -1;

@ -55,6 +55,7 @@
#define _WIN32_IE 0x0501 #define _WIN32_IE 0x0501
#include <windows.h> #include <windows.h>
#include <shlobj.h> #include <shlobj.h>
#include <tlhelp32.h>
// win64 doesn't define GWL_USERDATA // win64 doesn't define GWL_USERDATA
#ifdef WIN32 #ifdef WIN32
@ -989,11 +990,16 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* procedure of the top-level window being activated. If the windows use different input queues, * procedure of the top-level window being activated. If the windows use different input queues,
* the message is sent asynchronously, so the window is activated immediately. * the message is sent asynchronously, so the window is activated immediately.
*/ */
{
GHOST_ModifierKeys modifiers;
modifiers.clear();
system->storeModifierKeys(modifiers);
event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window); event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL /* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
will not be dispatched to OUR active window if we minimize one of OUR windows. */ will not be dispatched to OUR active window if we minimize one of OUR windows. */
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
break; break;
}
case WM_PAINT: case WM_PAINT:
/* An application sends the WM_PAINT message when the system or another application /* An application sends the WM_PAINT message when the system or another application
* makes a request to paint a portion of an application's window. The message is sent * makes a request to paint a portion of an application's window. The message is sent
@ -1237,8 +1243,32 @@ int GHOST_SystemWin32::toggleConsole(int action)
{ {
case 3: //hide if no console case 3: //hide if no console
{ {
CONSOLE_SCREEN_BUFFER_INFO csbi = {{0}}; DWORD sp = GetCurrentProcessId();
if(!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) || csbi.dwCursorPosition.X || csbi.dwCursorPosition.Y>1) HANDLE ptree = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 e = {0}; e.dwSize = sizeof(PROCESSENTRY32);
if( Process32First(ptree, &e)) {
do { //Searches for Blender's PROCESSENTRY32
if (e.th32ProcessID == sp) {
sp = e.th32ParentProcessID;
Process32First(ptree, &e);
do { //Got parent id, searches for its PROCESSENTRY32
if (e.th32ProcessID == sp) {
if(strcmp("explorer.exe",e.szExeFile)==0)
{ //If explorer, hide cmd
ShowWindow(GetConsoleWindow(),SW_HIDE);
m_consoleStatus = 0;
}
break;
}
} while( Process32Next(ptree, &e));
break;
}
} while( Process32Next(ptree, &e));
}
CloseHandle(ptree);
break; break;
} }
case 0: //hide case 0: //hide

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
__all__ = ( __all__ = (
"paths", "paths",
@ -26,13 +26,14 @@ __all__ = (
"disable", "disable",
"reset_all", "reset_all",
"module_bl_info", "module_bl_info",
) )
import bpy as _bpy 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")
@ -128,7 +129,12 @@ def modules(module_cache):
error_duplicates = True error_duplicates = True
elif mod.__time__ != os.path.getmtime(mod_path): elif mod.__time__ != os.path.getmtime(mod_path):
print("reloading addon:", mod_name, mod.__time__, os.path.getmtime(mod_path), mod_path) print("reloading addon:",
mod_name,
mod.__time__,
os.path.getmtime(mod_path),
mod_path,
)
del module_cache[mod_name] del module_cache[mod_name]
mod = None mod = None
@ -143,7 +149,9 @@ def modules(module_cache):
del modules_stale del modules_stale
mod_list = list(module_cache.values()) mod_list = list(module_cache.values())
mod_list.sort(key=lambda mod: (mod.bl_info['category'], mod.bl_info['name'])) mod_list.sort(key=lambda mod: (mod.bl_info['category'],
mod.bl_info['name'],
))
return mod_list return mod_list
@ -163,8 +171,9 @@ def check(module_name):
loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis) loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
if loaded_state is Ellipsis: if loaded_state is Ellipsis:
print("Warning: addon-module %r found module but without" print("Warning: addon-module %r found module "
" __addon_enabled__ field, possible name collision from file: %r" % "but without __addon_enabled__ field, "
"possible name collision from file: %r" %
(module_name, getattr(mod, "__file__", "<unknown>"))) (module_name, getattr(mod, "__file__", "<unknown>")))
loaded_state = False loaded_state = False
@ -207,7 +216,8 @@ def enable(module_name, default_set=True):
return None return None
mod.__addon_enabled__ = False mod.__addon_enabled__ = False
# Split registering up into 3 steps so we can undo if it fails par way through # Split registering up into 3 steps so we can undo
# if it fails par way through.
# 1) try import # 1) try import
try: try:
mod = __import__(module_name) mod = __import__(module_name)
@ -254,8 +264,9 @@ def disable(module_name, default_set=True):
import sys import sys
mod = sys.modules.get(module_name) mod = sys.modules.get(module_name)
# possible this addon is from a previous session and didnt load a module this time. # possible this addon is from a previous session and didnt load a
# so even if the module is not found, still disable the addon in the user prefs. # module this time. So even if the module is not found, still disable
# the addon in the user prefs.
if mod: if mod:
mod.__addon_enabled__ = False mod.__addon_enabled__ = False
@ -310,7 +321,22 @@ def reset_all(reload_scripts=False):
disable(mod_name) disable(mod_name)
def module_bl_info(mod, info_basis={"name": "", "author": "", "version": (), "blender": (), "api": 0, "location": "", "description": "", "wiki_url": "", "tracker_url": "", "support": 'COMMUNITY', "category": "", "warning": "", "show_expanded": False}): def module_bl_info(mod, info_basis={"name": "",
"author": "",
"version": (),
"blender": (),
"api": 0,
"location": "",
"description": "",
"wiki_url": "",
"tracker_url": "",
"support": 'COMMUNITY',
"category": "",
"warning": "",
"show_expanded": False,
}
):
addon_info = getattr(mod, "bl_info", {}) addon_info = getattr(mod, "bl_info", {})
# avoid re-initializing # avoid re-initializing

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
""" """
Give access to blender data and utility functions. Give access to blender data and utility functions.
@ -31,7 +31,7 @@ __all__ = (
"props", "props",
"types", "types",
"utils", "utils",
) )
# internal blender C module # internal blender C module
@ -43,12 +43,14 @@ 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
# Possibly temp. addons path # Possibly temp. addons path
from os.path import join, dirname, normpath from os.path import join, dirname, normpath
_sys.path.append(normpath(join(dirname(__file__), "..", "..", "addons", "modules"))) _sys.path.append(normpath(join(dirname(__file__),
"..", "..", "addons", "modules")))
# if "-d" in sys.argv: # Enable this to measure startup speed # if "-d" in sys.argv: # Enable this to measure startup speed
if 0: if 0:

@ -16,26 +16,44 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
""" """
This module has a similar scope to os.path, containing utility This module has a similar scope to os.path, containing utility
functions for dealing with paths in Blender. functions for dealing with paths in Blender.
""" """
__all__ = (
"abspath",
"basename",
"clean_name",
"display_name",
"display_name_from_filepath",
"ensure_ext",
"is_subdir",
"module_names",
"relpath",
"resolve_ncase",
)
import bpy as _bpy import bpy as _bpy
import os as _os import os as _os
def abspath(path, start=None): def abspath(path, start=None):
""" """
Returns the absolute path relative to the current blend file using the "//" prefix. Returns the absolute path relative to the current blend file
using the "//" prefix.
:arg start: Relative to this path, when not set the current filename is used. :arg start: Relative to this path,
when not set the current filename is used.
:type start: string :type start: string
""" """
if path.startswith("//"): if path.startswith("//"):
return _os.path.join(_os.path.dirname(_bpy.data.filepath) if start is None else start, path[2:]) return _os.path.join(_os.path.dirname(_bpy.data.filepath)
if start is None else start,
path[2:],
)
return path return path
@ -44,7 +62,8 @@ def relpath(path, start=None):
""" """
Returns the path relative to the current blend file using the "//" prefix. Returns the path relative to the current blend file using the "//" prefix.
:arg start: Relative to this path, when not set the current filename is used. :arg start: Relative to this path,
when not set the current filename is used.
:type start: string :type start: string
""" """
if not path.startswith("//"): if not path.startswith("//"):
@ -68,27 +87,28 @@ def is_subdir(path, directory):
def clean_name(name, replace="_"): def clean_name(name, replace="_"):
""" """
Returns a name with characters replaced that may cause problems under various circumstances, such as writing to a file. Returns a name with characters replaced that
may cause problems under various circumstances,
such as writing to a file.
All characters besides A-Z/a-z, 0-9 are replaced with "_" All characters besides A-Z/a-z, 0-9 are replaced with "_"
or the replace argument if defined. or the replace argument if defined.
""" """
unclean_chars = \ bad_chars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\ "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"
\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\ "\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c"
\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\ "\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x60\x7b"
\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x60\x7b\ "\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"
\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\ "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99"
\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\ "\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\ "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"
\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\ "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5"
\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\ "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"
\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\ "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3"
\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\ "\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe")
\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe"
for ch in unclean_chars: for ch in bad_chars:
name = name.replace(ch, replace) name = name.replace(ch, replace)
return name return name
@ -96,8 +116,9 @@ def clean_name(name, replace="_"):
def display_name(name): def display_name(name):
""" """
Creates a display string from name to be used menus and the user interface. Creates a display string from name to be used menus and the user interface.
Capitalize the first letter in all lowercase names, mixed case names are kept as is. Capitalize the first letter in all lowercase names,
Intended for use with filenames and module names. mixed case names are kept as is. Intended for use with
filenames and module names.
""" """
name_base = _os.path.splitext(name)[0] name_base = _os.path.splitext(name)[0]
@ -115,9 +136,11 @@ def display_name(name):
def display_name_from_filepath(name): def display_name_from_filepath(name):
""" """
Returns the path stripped of directort and extension, ensured to be utf8 compatible. Returns the path stripped of directort and extension,
ensured to be utf8 compatible.
""" """
return _os.path.splitext(basename(name))[0].encode("utf8", "replace").decode("utf8") name = _os.path.splitext(basename(name))[0]
return name.encode("utf8", "replace").decode("utf8")
def resolve_ncase(path): def resolve_ncase(path):
@ -132,7 +155,8 @@ def resolve_ncase(path):
if not path or os.path.exists(path): if not path or os.path.exists(path):
return path, True return path, True
filename = os.path.basename(path) # filename may be a directory or a file # filename may be a directory or a file
filename = os.path.basename(path)
dirpath = os.path.dirname(path) dirpath = os.path.dirname(path)
suffix = path[:0] # "" but ensure byte/str match suffix = path[:0] # "" but ensure byte/str match
@ -190,7 +214,9 @@ def ensure_ext(filepath, ext, case_sensitive=False):
import os import os
fn_base, fn_ext = os.path.splitext(filepath) fn_base, fn_ext = os.path.splitext(filepath)
if fn_base and fn_ext: if fn_base and fn_ext:
if (case_sensitive and ext == fn_ext) or (ext.lower() == fn_ext.lower()): if ((case_sensitive and ext == fn_ext) or
(ext.lower() == fn_ext.lower())):
return filepath return filepath
else: else:
return fn_base + ext return fn_base + ext
@ -228,7 +254,9 @@ def module_names(path, recursive=False):
modules.append((filename, fullpath)) modules.append((filename, fullpath))
if recursive: if recursive:
for mod_name, mod_path in module_names(directory, True): for mod_name, mod_path in module_names(directory, True):
modules.append(("%s.%s" % (filename, mod_name), mod_path)) modules.append(("%s.%s" % (filename, mod_name),
mod_path,
))
return modules return modules
@ -239,4 +267,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)

@ -16,13 +16,33 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
""" """
This module contains utility functions specific to blender but This module contains utility functions specific to blender but
not assosiated with blenders internal data. not assosiated with blenders internal data.
""" """
__all__ = (
"blend_paths",
"keyconfig_set",
"load_scripts",
"modules_from_path",
"preset_find",
"preset_paths",
"refresh_script_paths",
"register_class",
"register_module",
"resource_path",
"script_paths",
"smpte_from_frame",
"smpte_from_seconds",
"unregister_class",
"unregister_module",
"user_resource",
"user_script_path",
)
from _bpy import register_class, unregister_class, blend_paths, resource_path from _bpy import register_class, unregister_class, blend_paths, resource_path
from _bpy import script_paths as _bpy_script_paths from _bpy import script_paths as _bpy_script_paths
from _bpy import user_resource as _user_resource from _bpy import user_resource as _user_resource
@ -42,7 +62,8 @@ def _test_import(module_name, loaded_modules):
if module_name in loaded_modules: if module_name in loaded_modules:
return None return None
if "." in module_name: if "." in module_name:
print("Ignoring '%s', can't import files containing multiple periods." % module_name) print("Ignoring '%s', can't import files containing "
"multiple periods." % module_name)
return None return None
if use_time: if use_time:
@ -74,7 +95,8 @@ def modules_from_path(path, loaded_modules):
:arg path: this path is scanned for scripts and packages. :arg path: this path is scanned for scripts and packages.
:type path: string :type path: string
:arg loaded_modules: already loaded module names, files matching these names will be ignored. :arg loaded_modules: already loaded module names, files matching these
names will be ignored.
:type loaded_modules: set :type loaded_modules: set
:return: all loaded modules. :return: all loaded modules.
:rtype: list :rtype: list
@ -97,13 +119,17 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
""" """
Load scripts and run each modules register function. Load scripts and run each modules register function.
:arg reload_scripts: Causes all scripts to have their unregister method called before loading. :arg reload_scripts: Causes all scripts to have their unregister method
called before loading.
:type reload_scripts: bool :type reload_scripts: bool
:arg refresh_scripts: only load scripts which are not already loaded as modules. :arg refresh_scripts: only load scripts which are not already loaded
as modules.
:type refresh_scripts: bool :type refresh_scripts: bool
""" """
use_time = _bpy.app.debug use_time = _bpy.app.debug
prefs = _bpy.context.user_preferences
if use_time: if use_time:
import time import time
t_main = time.time() t_main = time.time()
@ -116,10 +142,11 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
if reload_scripts: if reload_scripts:
_bpy_types.TypeMap.clear() _bpy_types.TypeMap.clear()
# just unload, dont change user defaults, this means we can sync to reload. # just unload, dont change user defaults, this means we can sync
# note that they will only actually reload of the modification time changes. # to reload. note that they will only actually reload of the
# this `wont` work for packages so... its not perfect. # modification time changes. This `wont` work for packages so...
for module_name in [ext.module for ext in _bpy.context.user_preferences.addons]: # its not perfect.
for module_name in [ext.module for ext in prefs.addons]:
_addon_utils.disable(module_name, default_set=False) _addon_utils.disable(module_name, default_set=False)
def register_module_call(mod): def register_module_call(mod):
@ -131,7 +158,9 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
import traceback import traceback
traceback.print_exc() traceback.print_exc()
else: else:
print("\nWarning! '%s' has no register function, this is now a requirement for registerable scripts." % mod.__file__) print("\nWarning! '%s' has no register function, "
"this is now a requirement for registerable scripts." %
mod.__file__)
def unregister_module_call(mod): def unregister_module_call(mod):
unregister = getattr(mod, "unregister", None) unregister = getattr(mod, "unregister", None)
@ -172,7 +201,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
if reload_scripts: if reload_scripts:
# module names -> modules # module names -> modules
_global_loaded_modules[:] = [_sys.modules[mod_name] for mod_name in _global_loaded_modules] _global_loaded_modules[:] = [_sys.modules[mod_name]
for mod_name in _global_loaded_modules]
# loop over and unload all scripts # loop over and unload all scripts
_global_loaded_modules.reverse() _global_loaded_modules.reverse()
@ -201,7 +231,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
_addon_utils.reset_all(reload_scripts) _addon_utils.reset_all(reload_scripts)
# run the active integration preset # run the active integration preset
filepath = preset_find(_bpy.context.user_preferences.inputs.active_keyconfig, "keyconfig") filepath = preset_find(prefs.inputs.active_keyconfig, "keyconfig")
if filepath: if filepath:
keyconfig_set(filepath) keyconfig_set(filepath)
@ -214,12 +245,16 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
# base scripts # base scripts
_scripts = _os.path.join(_os.path.dirname(__file__), _os.path.pardir, _os.path.pardir) _scripts = _os.path.join(_os.path.dirname(__file__),
_os.path.pardir,
_os.path.pardir,
)
_scripts = (_os.path.normpath(_scripts), ) _scripts = (_os.path.normpath(_scripts), )
def user_script_path(): def user_script_path():
path = _bpy.context.user_preferences.filepaths.script_directory prefs = _bpy.context.user_preferences
path = prefs.filepaths.script_directory
if path: if path:
path = _os.path.normpath(path) path = _os.path.normpath(path)
@ -236,22 +271,25 @@ def script_paths(subdir=None, user_pref=True, all=False):
:type subdir: string :type subdir: string
:arg user_pref: Include the user preference script path. :arg user_pref: Include the user preference script path.
:type user_pref: bool :type user_pref: bool
:arg all: Include local, user and system paths rather just the paths blender uses. :arg all: Include local, user and system paths rather just the paths
blender uses.
:type all: bool :type all: bool
:return: script paths. :return: script paths.
:rtype: list :rtype: list
""" """
scripts = list(_scripts) scripts = list(_scripts)
prefs = _bpy.context.user_preferences
# add user scripts dir # add user scripts dir
if user_pref: if user_pref:
user_script_path = _bpy.context.user_preferences.filepaths.script_directory user_script_path = prefs.filepaths.script_directory
else: else:
user_script_path = None user_script_path = None
if all: if all:
# all possible paths # all possible paths
base_paths = tuple(_os.path.join(resource_path(res), "scripts") for res in ('LOCAL', 'USER', 'SYSTEM')) base_paths = tuple(_os.path.join(resource_path(res), "scripts")
for res in ('LOCAL', 'USER', 'SYSTEM'))
else: else:
# only paths blender uses # only paths blender uses
base_paths = _bpy_script_paths() base_paths = _bpy_script_paths()
@ -426,7 +464,8 @@ def user_resource(type, path="", create=False):
:type type: string :type type: string
:arg subdir: Optional subdirectory. :arg subdir: Optional subdirectory.
:type subdir: string :type subdir: string
:arg create: Treat the path as a directory and create it if its not existing. :arg create: Treat the path as a directory and create
it if its not existing.
:type create: boolean :type create: boolean
:return: a path. :return: a path.
:rtype: string :rtype: string
@ -477,7 +516,8 @@ def register_module(module, verbose=False):
try: try:
register_class(cls) register_class(cls)
except: except:
print("bpy.utils.register_module(): failed to registering class %r" % cls) print("bpy.utils.register_module(): "
"failed to registering class %r" % cls)
import traceback import traceback
traceback.print_exc() traceback.print_exc()
if verbose: if verbose:
@ -495,7 +535,8 @@ def unregister_module(module, verbose=False):
try: try:
unregister_class(cls) unregister_class(cls)
except: except:
print("bpy.utils.unregister_module(): failed to unregistering class %r" % cls) print("bpy.utils.unregister_module(): "
"failed to unregistering class %r" % cls)
import traceback import traceback
traceback.print_exc() traceback.print_exc()
if verbose: if verbose:

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
""" """
Utility modules assosiated with the bpy module. Utility modules assosiated with the bpy module.
@ -28,4 +28,4 @@ __all__ = (
"image_utils", "image_utils",
"mesh_utils", "mesh_utils",
"view3d_utils", "view3d_utils",
) )

@ -16,11 +16,11 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
__all__ = ( __all__ = (
"load_image", "load_image",
) )
# limited replacement for BPyImage.comprehensiveImageLoad # limited replacement for BPyImage.comprehensiveImageLoad
@ -33,8 +33,8 @@ def load_image(imagepath,
verbose=False, verbose=False,
): ):
""" """
Return an image from the file path with options to search multiple paths and Return an image from the file path with options to search multiple paths
return a placeholder if its not found. and return a placeholder if its not found.
:arg filepath: The image filename :arg filepath: The image filename
If a path precedes it, this will be searched as well. If a path precedes it, this will be searched as well.
@ -51,9 +51,10 @@ def load_image(imagepath,
:type recursive: bool :type recursive: bool
:arg ncase_cmp: on non windows systems, find the correct case for the file. :arg ncase_cmp: on non windows systems, find the correct case for the file.
:type ncase_cmp: bool :type ncase_cmp: bool
:arg convert_callback: a function that takes an existing path and returns a new one. :arg convert_callback: a function that takes an existing path and returns
Use this when loading image formats blender may not support, the CONVERT_CALLBACK a new one. Use this when loading image formats blender may not support,
can take the path for a GIF (for example), convert it to a PNG and return the PNG's path. the CONVERT_CALLBACK can take the path for a GIF (for example),
convert it to a PNG and return the PNG's path.
For formats blender can read, simply return the path that is given. For formats blender can read, simply return the path that is given.
:type convert_callback: function :type convert_callback: function
:return: an image or None :return: an image or None
@ -92,7 +93,9 @@ def load_image(imagepath,
for filepath_test in variants: for filepath_test in variants:
if ncase_cmp: if ncase_cmp:
ncase_variants = filepath_test, bpy.path.resolve_ncase(filepath_test) ncase_variants = (filepath_test,
bpy.path.resolve_ncase(filepath_test),
)
else: else:
ncase_variants = (filepath_test, ) ncase_variants = (filepath_test, )

@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
__all__ = ( __all__ = (
"ExportHelper", "ExportHelper",
@ -31,15 +31,25 @@ __all__ = (
"path_reference_copy", "path_reference_copy",
"path_reference_mode", "path_reference_mode",
"unique_name" "unique_name"
) )
import bpy import bpy
from bpy.props import StringProperty, BoolProperty, EnumProperty from bpy.props import StringProperty, BoolProperty, EnumProperty
class ExportHelper: class ExportHelper:
filepath = StringProperty(name="File Path", description="Filepath used for exporting the file", maxlen=1024, default="", subtype='FILE_PATH') filepath = StringProperty(
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'}) name="File Path",
description="Filepath used for exporting the file",
maxlen=1024,
subtype='FILE_PATH',
)
check_existing = BoolProperty(
name="Check Existing",
description="Check and warn on overwriting existing files",
default=True,
options={'HIDDEN'},
)
# subclasses can override with decorator # subclasses can override with decorator
# True == use ext, False == no ext, None == do nothing. # True == use ext, False == no ext, None == do nothing.
@ -65,7 +75,10 @@ class ExportHelper:
if check_extension is None: if check_extension is None:
return False return False
filepath = bpy.path.ensure_ext(self.filepath, self.filename_ext if check_extension else "") filepath = bpy.path.ensure_ext(self.filepath,
self.filename_ext
if check_extension
else "")
if filepath != self.filepath: if filepath != self.filepath:
self.filepath = filepath self.filepath = filepath
@ -75,7 +88,12 @@ class ExportHelper:
class ImportHelper: class ImportHelper:
filepath = StringProperty(name="File Path", description="Filepath used for importing the file", maxlen=1024, default="", subtype='FILE_PATH') filepath = StringProperty(
name="File Path",
description="Filepath used for importing the file",
maxlen=1024,
subtype='FILE_PATH',
)
def invoke(self, context, event): def invoke(self, context, event):
context.window_manager.fileselect_add(self) context.window_manager.fileselect_add(self)
@ -116,29 +134,75 @@ _axis_convert_matrix = (
# where all 4 values are or'd into a single value... # where all 4 values are or'd into a single value...
# (i1<<0 | i1<<3 | i1<<6 | i1<<9) # (i1<<0 | i1<<3 | i1<<6 | i1<<9)
_axis_convert_lut = ( _axis_convert_lut = (
{0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A, 0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C, 0x745, 0x94D, 0x15D, 0x365}, {0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A,
{0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A, 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC, 0x645, 0xA4D, 0x05D, 0x465}, 0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C,
{0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A, 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C, 0x705, 0x50D, 0x11D, 0xB25}, 0x745, 0x94D, 0x15D, 0x365},
{0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A, 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C, 0x685, 0x28D, 0x09D, 0x8A5}, {0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A,
{0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A, 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C, 0x885, 0x68D, 0x29D, 0x0A5}, 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC,
{0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A, 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC, 0x8C5, 0xACD, 0x2DD, 0x4E5}, 0x645, 0xA4D, 0x05D, 0x465},
{0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA, 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C, 0x805, 0x40D, 0x21D, 0xA25}, {0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A,
{0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A, 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC, 0x945, 0x14D, 0x35D, 0x765}, 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C,
{0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A, 0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C, 0xB05, 0x70D, 0x51D, 0x125}, 0x705, 0x50D, 0x11D, 0xB25},
{0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA, 0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C, 0xA05, 0x80D, 0x41D, 0x225}, {0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A,
{0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A, 0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C, 0xAC5, 0x2CD, 0x4DD, 0x8E5}, 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C,
{0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A, 0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC, 0xA45, 0x04D, 0x45D, 0x665}, 0x685, 0x28D, 0x09D, 0x8A5},
{0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A, 0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C, 0x445, 0x64D, 0xA5D, 0x065}, {0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A,
{0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A, 0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C, 0x4C5, 0x8CD, 0xADD, 0x2E5}, 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C,
{0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA, 0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C, 0x405, 0x20D, 0xA1D, 0x825}, 0x885, 0x68D, 0x29D, 0x0A5},
{0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A, 0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC, 0x505, 0x10D, 0xB1D, 0x725}, {0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A,
{0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A, 0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C, 0x345, 0x74D, 0x95D, 0x165}, 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC,
{0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA, 0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC, 0x205, 0xA0D, 0x81D, 0x425}, 0x8C5, 0xACD, 0x2DD, 0x4E5},
{0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A, 0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C, 0x2C5, 0x4CD, 0x8DD, 0xAE5}, {0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA,
{0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A, 0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC, 0x285, 0x08D, 0x89D, 0x6A5}, 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C,
{0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A, 0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C, 0x085, 0x88D, 0x69D, 0x2A5}, 0x805, 0x40D, 0x21D, 0xA25},
{0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A, 0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC, 0x105, 0xB0D, 0x71D, 0x525}, {0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A,
{0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A, 0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C, 0x045, 0x44D, 0x65D, 0xA65}, 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC,
0x945, 0x14D, 0x35D, 0x765},
{0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A,
0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C,
0xB05, 0x70D, 0x51D, 0x125},
{0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA,
0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C,
0xA05, 0x80D, 0x41D, 0x225},
{0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A,
0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C,
0xAC5, 0x2CD, 0x4DD, 0x8E5},
{0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A,
0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC,
0xA45, 0x04D, 0x45D, 0x665},
{0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A,
0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C,
0x445, 0x64D, 0xA5D, 0x065},
{0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A,
0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C,
0x4C5, 0x8CD, 0xADD, 0x2E5},
{0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA,
0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C,
0x405, 0x20D, 0xA1D, 0x825},
{0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A,
0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC,
0x505, 0x10D, 0xB1D, 0x725},
{0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A,
0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C,
0x345, 0x74D, 0x95D, 0x165},
{0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA,
0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC,
0x205, 0xA0D, 0x81D, 0x425},
{0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A,
0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C,
0x2C5, 0x4CD, 0x8DD, 0xAE5},
{0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A,
0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC,
0x285, 0x08D, 0x89D, 0x6A5},
{0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A,
0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C,
0x085, 0x88D, 0x69D, 0x2A5},
{0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A,
0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC,
0x105, 0xB0D, 0x71D, 0x525},
{0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A,
0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C,
0x045, 0x44D, 0x65D, 0xA65},
) )
_axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5} _axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
@ -159,7 +223,12 @@ 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:
@ -174,9 +243,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
@ -201,9 +270,10 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
return False return False
# 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':
@ -249,31 +319,45 @@ path_reference_mode = EnumProperty(
description="Method used to reference paths", description="Method used to reference paths",
items=(('AUTO', "Auto", "Use Relative paths with subdirectories only"), items=(('AUTO', "Auto", "Use Relative paths with subdirectories only"),
('ABSOLUTE', "Absolute", "Always write absolute paths"), ('ABSOLUTE', "Absolute", "Always write absolute paths"),
('RELATIVE', "Relative", "Always write relative patsh (where possible)"), ('RELATIVE', "Relative", "Always write relative patsh "
('MATCH', "Match", "Match Absolute/Relative setting with input path"), "(where possible)"),
('MATCH', "Match", "Match Absolute/Relative "
"setting with input path"),
('STRIP', "Strip Path", "Filename only"), ('STRIP', "Strip Path", "Filename only"),
('COPY', "Copy", "copy the file to the destination path (or subdirectory)"), ('COPY', "Copy", "copy the file to the destination path "
"(or subdirectory)"),
), ),
default='AUTO' default='AUTO'
) )
def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", copy_set=None): def path_reference(filepath,
base_src,
base_dst,
mode='AUTO',
copy_subdir="",
copy_set=None,
):
""" """
Return a filepath relative to a destination directory, for use with Return a filepath relative to a destination directory, for use with
exporters. exporters.
:arg filepath: the file path to return, supporting blenders relative '//' prefix. :arg filepath: the file path to return,
supporting blenders relative '//' prefix.
:type filepath: string :type filepath: string
:arg base_src: the directory the *filepath* is relative too (normally the blend file). :arg base_src: the directory the *filepath* is relative too
(normally the blend file).
:type base_src: string :type base_src: string
:arg base_dst: the directory the *filepath* will be referenced from (normally the export path). :arg base_dst: the directory the *filepath* will be referenced from
(normally the export path).
:type base_dst: string :type base_dst: string
:arg mode: the method used get the path in ['AUTO', 'ABSOLUTE', 'RELATIVE', 'MATCH', 'STRIP', 'COPY'] :arg mode: the method used get the path in
['AUTO', 'ABSOLUTE', 'RELATIVE', 'MATCH', 'STRIP', 'COPY']
:type mode: string :type mode: string
:arg copy_subdir: the subdirectory of *base_dst* to use when mode='COPY'. :arg copy_subdir: the subdirectory of *base_dst* to use when mode='COPY'.
:type copy_subdir: string :type copy_subdir: string
:arg copy_set: collect from/to pairs when mode='COPY', pass to *path_reference_copy* when exportign is done. :arg copy_set: collect from/to pairs when mode='COPY',
pass to *path_reference_copy* when exportign is done.
:type copy_set: set :type copy_set: set
:return: the new filepath. :return: the new filepath.
:rtype: string :rtype: string
@ -287,7 +371,9 @@ def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", co
elif mode == 'MATCH': elif mode == 'MATCH':
mode = 'RELATIVE' if is_relative else 'ABSOLUTE' mode = 'RELATIVE' if is_relative else 'ABSOLUTE'
elif mode == 'AUTO': elif mode == 'AUTO':
mode = 'RELATIVE' if bpy.path.is_subdir(filepath, base_dst) else 'ABSOLUTE' mode = ('RELATIVE'
if bpy.path.is_subdir(filepath, base_dst)
else 'ABSOLUTE')
elif mode == 'COPY': elif mode == 'COPY':
if copy_subdir: if copy_subdir:
subdir_abs = os.path.join(os.path.normpath(base_dst), copy_subdir) subdir_abs = os.path.join(os.path.normpath(base_dst), copy_subdir)
@ -362,7 +448,8 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None):
if name_new is None: if name_new is None:
count = 1 count = 1
name_dict_values = name_dict.values() name_dict_values = name_dict.values()
name_new = name_new_orig = name if clean_func is None else clean_func(name) name_new = name_new_orig = (name if clean_func is None
else clean_func(name))
if name_max == -1: if name_max == -1:
while name_new in name_dict_values: while name_new in name_dict_values:
@ -372,7 +459,10 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None):
name_new = name_new[:name_max] name_new = name_new[:name_max]
while name_new in name_dict_values: while name_new in name_dict_values:
count_str = "%03d" % count count_str = "%03d" % count
name_new = "%.*s.%s" % (name_max - (len(count_str) + 1), name_new_orig, count_str) name_new = "%.*s.%s" % (name_max - (len(count_str) + 1),
name_new_orig,
count_str,
)
count += 1 count += 1
name_dict[key] = name_new name_dict[key] = name_new

@ -26,7 +26,7 @@ __all__ = (
"edge_loops_from_edges", "edge_loops_from_edges",
"ngon_tesselate", "ngon_tesselate",
"face_random_points", "face_random_points",
) )
def mesh_linked_faces(mesh): def mesh_linked_faces(mesh):
@ -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:

@ -16,12 +16,12 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
__all__ = ( __all__ = (
"add_object_align_init", "add_object_align_init",
"object_data_add", "object_data_add",
) )
import bpy import bpy
@ -39,42 +39,49 @@ def add_object_align_init(context, operator):
:return: the matrix from the context and settings. :return: the matrix from the context and settings.
:rtype: :class:`Matrix` :rtype: :class:`Matrix`
""" """
from mathutils import Matrix, Vector, Euler
properties = operator.properties if operator is not None else None
space_data = context.space_data space_data = context.space_data
if space_data.type != 'VIEW_3D': if space_data.type != 'VIEW_3D':
space_data = None space_data = None
# location # location
if operator and operator.properties.is_property_set("location"): if operator and properties.is_property_set("location"):
location = mathutils.Matrix.Translation(mathutils.Vector(operator.properties.location)) location = Matrix.Translation(Vector(properties.location))
else: else:
if space_data: # local view cursor is detected below if space_data: # local view cursor is detected below
location = mathutils.Matrix.Translation(space_data.cursor_location) location = Matrix.Translation(space_data.cursor_location)
else: else:
location = mathutils.Matrix.Translation(context.scene.cursor_location) location = Matrix.Translation(context.scene.cursor_location)
if operator: if operator:
operator.properties.location = location.to_translation() properties.location = location.to_translation()
# rotation # rotation
view_align = (context.user_preferences.edit.object_align == 'VIEW') view_align = (context.user_preferences.edit.object_align == 'VIEW')
view_align_force = False view_align_force = False
if operator: if operator:
if operator.properties.is_property_set("view_align"): if properties.is_property_set("view_align"):
view_align = view_align_force = operator.view_align view_align = view_align_force = operator.view_align
else: else:
operator.properties.view_align = view_align properties.view_align = view_align
if operator and operator.properties.is_property_set("rotation") and not view_align_force: if operator and (properties.is_property_set("rotation") and
rotation = mathutils.Euler(operator.properties.rotation).to_matrix().to_4x4() not view_align_force):
rotation = Euler(properties.rotation).to_matrix().to_4x4()
else: else:
if view_align and space_data: if view_align and space_data:
rotation = space_data.region_3d.view_matrix.to_3x3().inverted().to_4x4() rotation = space_data.region_3d.view_matrix.to_3x3().inverted()
rotation.resize_4x4()
else: else:
rotation = mathutils.Matrix() rotation = mathutils.Matrix()
# set the operator properties # set the operator properties
if operator: if operator:
operator.properties.rotation = rotation.to_euler() properties.rotation = rotation.to_euler()
return location * rotation return location * rotation
@ -114,14 +121,18 @@ def object_data_add(context, obdata, operator=None):
# XXX # XXX
# caused because entering editmodedoes not add a empty undo slot! # caused because entering editmodedoes not add a empty undo slot!
if context.user_preferences.edit.use_enter_edit_mode: if context.user_preferences.edit.use_enter_edit_mode:
if not (obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type): if not (obj_act and
obj_act.mode == 'EDIT' and
obj_act.type == obj_new.type):
_obdata = bpy.data.meshes.new(obdata.name) _obdata = bpy.data.meshes.new(obdata.name)
obj_act = bpy.data.objects.new(_obdata.name, _obdata) obj_act = bpy.data.objects.new(_obdata.name, _obdata)
obj_act.matrix_world = obj_new.matrix_world obj_act.matrix_world = obj_new.matrix_world
scene.objects.link(obj_act) scene.objects.link(obj_act)
scene.objects.active = obj_act scene.objects.active = obj_act
bpy.ops.object.mode_set(mode='EDIT') bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.ed.undo_push(message="Enter Editmode") # need empty undo step # need empty undo step
bpy.ops.ed.undo_push(message="Enter Editmode")
# XXX # XXX
if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type: if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type:

@ -16,13 +16,13 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
__all__ = ( __all__ = (
"region_2d_to_vector_3d", "region_2d_to_vector_3d",
"region_2d_to_location_3d", "region_2d_to_location_3d",
"location_3d_to_region_2d", "location_3d_to_region_2d",
) )
def region_2d_to_vector_3d(region, rv3d, coord): def region_2d_to_vector_3d(region, rv3d, coord):
@ -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()
@ -90,15 +90,23 @@ def region_2d_to_location_3d(region, rv3d, coord, depth_location):
origin_start = rv3d.view_matrix.inverted()[3].to_3d() origin_start = rv3d.view_matrix.inverted()[3].to_3d()
origin_end = origin_start + coord_vec origin_end = origin_start + coord_vec
view_vec = rv3d.view_matrix.inverted()[2] view_vec = rv3d.view_matrix.inverted()[2]
return intersect_line_plane(origin_start, origin_end, depth_location, view_vec, 1) return intersect_line_plane(origin_start,
origin_end,
depth_location,
view_vec, 1,
)
else: else:
dx = (2.0 * coord[0] / region.width) - 1.0 dx = (2.0 * coord[0] / region.width) - 1.0
dy = (2.0 * coord[1] / region.height) - 1.0 dy = (2.0 * coord[1] / region.height) - 1.0
persinv = persmat.inverted() persinv = persmat.inverted()
viewinv = rv3d.view_matrix.inverted() viewinv = rv3d.view_matrix.inverted()
origin_start = (persinv[0].xyz * dx) + (persinv[1].xyz * dy) + viewinv[3].xyz origin_start = ((persinv[0].xyz * dx) +
(persinv[1].xyz * dy) + viewinv[3].xyz)
origin_end = origin_start + coord_vec origin_end = origin_start + coord_vec
return intersect_point_line(depth_location, origin_start, origin_end)[0] return intersect_point_line(depth_location,
origin_start,
origin_end,
)[0]
def location_3d_to_region_2d(region, rv3d, coord): def location_3d_to_region_2d(region, rv3d, coord):
@ -116,7 +124,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,14 +16,14 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
# This file defines a set of methods that are useful for various # This file defines a set of methods that are useful for various
# Relative Keying Set (RKS) related operations, such as: callbacks # Relative Keying Set (RKS) related operations, such as: callbacks
# for polling, iterator callbacks, and also generate callbacks. # for polling, iterator callbacks, and also generate callbacks.
# All of these can be used in conjunction with the others. # All of these can be used in conjunction with the others.
__all__ = [ __all__ = (
"path_add_property", "path_add_property",
"RKS_POLL_selected_objects", "RKS_POLL_selected_objects",
"RKS_POLL_selected_bones", "RKS_POLL_selected_bones",
@ -33,7 +33,7 @@ __all__ = [
"RKS_GEN_location", "RKS_GEN_location",
"RKS_GEN_rotation", "RKS_GEN_rotation",
"RKS_GEN_scaling", "RKS_GEN_scaling",
] )
import bpy import bpy
@ -75,7 +75,8 @@ def RKS_POLL_selected_bones(ksi, context):
# selected bones or objects # selected bones or objects
def RKS_POLL_selected_items(ksi, context): def RKS_POLL_selected_items(ksi, context):
return RKS_POLL_selected_bones(ksi, context) or RKS_POLL_selected_objects(ksi, context) return (RKS_POLL_selected_bones(ksi, context) or
RKS_POLL_selected_objects(ksi, context))
########################### ###########################
# Iterator Callbacks # Iterator Callbacks

@ -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,24 +16,25 @@
# #
# ##### 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]
@ -61,6 +62,7 @@ def GlobalBB_LQ(bb_world):
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()
@ -69,20 +71,20 @@ def GlobalBB_HQ(obj):
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]
@ -108,10 +110,15 @@ def GlobalBB_HQ(obj):
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,8 +130,8 @@ 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:
@ -193,7 +200,8 @@ 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)
@ -339,7 +347,9 @@ 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 "
"bounding box for perfect results on complex "
"shape meshes with rotation/scale (Slow)"),
default=True) default=True)
align_mode = EnumProperty(items=( align_mode = EnumProperty(items=(
@ -374,7 +384,12 @@ 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")

@ -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
@ -85,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)
@ -98,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)
@ -112,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)]
@ -128,20 +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)
if (player_path == "") or (os.path.exists(player_path)==False): # launch it
self.report({'ERROR'}, "Couldn't find an external animation player") print("Executing command:\n %r" % " ".join(cmd))
else:
# launch it try:
try: process = subprocess.Popen(cmd)
process = subprocess.Popen(cmd) except Exception as e:
except: import traceback
pass 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()

@ -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}

@ -79,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):

@ -35,7 +35,7 @@ def add_object(self, context):
mesh.from_pydata(verts, edges, faces) mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid. # useful for development when the mesh may be invalid.
# mesh.validate(verbose=True) # mesh.validate(verbose=True)
add_object_data(context, mesh_data, operator=self) add_object_data(context, mesh, operator=self)
class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper): class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper):

@ -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;

@ -115,5 +115,6 @@ int minmax_curve(struct Curve *cu, float min[3], float max[3]);
int curve_center_median(struct Curve *cu, float cent[3]); int curve_center_median(struct Curve *cu, float cent[3]);
int curve_center_bounds(struct Curve *cu, float cent[3]); int curve_center_bounds(struct Curve *cu, float cent[3]);
void curve_translate(struct Curve *cu, float offset[3], int do_keys); void curve_translate(struct Curve *cu, float offset[3], int do_keys);
void curve_delete_material_index(struct Curve *cu, int index);
#endif #endif

@ -78,7 +78,7 @@ int object_remove_material_slot(struct Object *ob);
/* rna api */ /* rna api */
void material_append_id(struct ID *id, struct Material *ma); void material_append_id(struct ID *id, struct Material *ma);
struct Material *material_pop_id(struct ID *id, int index); struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot);
/* rendering */ /* rendering */

@ -1883,7 +1883,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
/* set the DerivedMesh to only copy needed data */ /* set the DerivedMesh to only copy needed data */
mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
DM_set_only_copy(dm, mask); /* needMapping check here fixes bug [#28112], otherwise its
* possible that it wont be copied */
DM_set_only_copy(dm, mask | (needMapping ? CD_MASK_ORIGINDEX : 0));
/* add cloth rest shape key if need */ /* add cloth rest shape key if need */
if(mask & CD_MASK_CLOTH_ORCO) if(mask & CD_MASK_CLOTH_ORCO)

@ -1287,6 +1287,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) {
@ -1327,6 +1328,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++;

@ -580,46 +580,47 @@ void addNurbPointsBezier(Nurb *nu, int number)
/* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */ /* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */
static void calcknots(float *knots, short aantal, short order, short type) static void calcknots(float *knots, const short pnts, const short order, const short flag)
/* knots: number of pnts NOT corrected for cyclic */
/* type; 0: uniform, 1: endpoints, 2: bezier */
{ {
/* knots: number of pnts NOT corrected for cyclic */
const int pnts_order= pnts + order;
float k; float k;
int a, t; int a;
t = aantal+order; switch(flag & (CU_NURB_ENDPOINT|CU_NURB_BEZIER)) {
if(type==0) { case CU_NURB_ENDPOINT:
for(a=0;a<t;a++) {
knots[a]= (float)a;
}
}
else if(type==1) {
k= 0.0; k= 0.0;
for(a=1;a<=t;a++) { for(a=1; a <= pnts_order; a++) {
knots[a-1]= k; knots[a-1]= k;
if(a>=order && a<=aantal) k+= 1.0f; if(a >= order && a <= pnts) k+= 1.0f;
} }
} break;
else if(type==2) { case CU_NURB_BEZIER:
/* Warning, the order MUST be 2 or 4, if this is not enforced, the displist will be corrupt */ /* Warning, the order MUST be 2 or 4,
* if this is not enforced, the displist will be corrupt */
if(order==4) { if(order==4) {
k= 0.34; k= 0.34;
for(a=0;a<t;a++) { for(a=0; a < pnts_order; a++) {
knots[a]= floorf(k); knots[a]= floorf(k);
k+= (1.0f/3.0f); k+= (1.0f/3.0f);
} }
} }
else if(order==3) { else if(order==3) {
k= 0.6f; k= 0.6f;
for(a=0;a<t;a++) { for(a=0; a < pnts_order; a++) {
if(a>=order && a<=aantal) k+= 0.5f; if(a >= order && a <= pnts) k+= 0.5f;
knots[a]= floorf(k); knots[a]= floorf(k);
} }
} }
else { else {
printf("bez nurb curve order is not 3 or 4, should never happen\n"); printf("bez nurb curve order is not 3 or 4, should never happen\n");
} }
break;
default:
for(a=0; a < pnts_order; a++) {
knots[a]= (float)a;
}
break;
} }
} }
@ -662,7 +663,7 @@ static void makeknots(Nurb *nu, short uv)
calcknots(nu->knotsu, nu->pntsu, nu->orderu, 0); /* cyclic should be uniform */ calcknots(nu->knotsu, nu->pntsu, nu->orderu, 0); /* cyclic should be uniform */
makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu); makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu);
} else { } else {
calcknots(nu->knotsu, nu->pntsu, nu->orderu, nu->flagu>>1); calcknots(nu->knotsu, nu->pntsu, nu->orderu, nu->flagu);
} }
} }
else nu->knotsu= NULL; else nu->knotsu= NULL;
@ -675,7 +676,7 @@ static void makeknots(Nurb *nu, short uv)
calcknots(nu->knotsv, nu->pntsv, nu->orderv, 0); /* cyclic should be uniform */ calcknots(nu->knotsv, nu->pntsv, nu->orderv, 0); /* cyclic should be uniform */
makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv); makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv);
} else { } else {
calcknots(nu->knotsv, nu->pntsv, nu->orderv, nu->flagv>>1); calcknots(nu->knotsv, nu->pntsv, nu->orderv, nu->flagv);
} }
} }
else nu->knotsv= NULL; else nu->knotsv= NULL;
@ -3259,3 +3260,28 @@ void curve_translate(Curve *cu, float offset[3], int do_keys)
} }
} }
} }
void curve_delete_material_index(Curve *cu, int index)
{
const int curvetype= curve_type(cu);
if(curvetype == OB_FONT) {
struct CharInfo *info= cu->strinfo;
int i;
for(i= cu->len-1; i >= 0; i--, info++) {
if (info->mat_nr && info->mat_nr>=index) {
info->mat_nr--;
}
}
}
else {
Nurb *nu;
for (nu= cu->nurb.first; nu; nu= nu->next) {
if(nu->mat_nr && nu->mat_nr>=index) {
nu->mat_nr--;
if (curvetype == OB_CURVE) nu->charidx--;
}
}
}
}

@ -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++)

@ -518,7 +518,7 @@ static const char *material_adrcodes_to_paths (int adrcode, int *array_index)
return "alpha"; return "alpha";
case MA_REF: case MA_REF:
return "diffuse_reflection"; return "diffuse_intensity";
case MA_EMIT: case MA_EMIT:
return "emit"; return "emit";
@ -527,7 +527,7 @@ static const char *material_adrcodes_to_paths (int adrcode, int *array_index)
return "ambient"; return "ambient";
case MA_SPEC: case MA_SPEC:
return "specular_reflection"; return "specular_intensity";
case MA_HARD: case MA_HARD:
return "specular_hardness"; return "specular_hardness";
@ -551,13 +551,13 @@ static const char *material_adrcodes_to_paths (int adrcode, int *array_index)
return "raytrace_mirror.fresnel"; return "raytrace_mirror.fresnel";
case MA_FRESMIRI: case MA_FRESMIRI:
return "raytrace_mirror.fresnel_fac"; return "raytrace_mirror.fresnel_factor";
case MA_FRESTRA: case MA_FRESTRA:
return "raytrace_transparency.fresnel"; return "raytrace_transparency.fresnel";
case MA_FRESTRAI: case MA_FRESTRAI:
return "raytrace_transparency.fresnel_fac"; return "raytrace_transparency.fresnel_factor";
case MA_ADD: case MA_ADD:
return "halo.add"; return "halo.add";

@ -474,20 +474,20 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl)
} }
static void flerp(int aantal, float *in, float *f0, float *f1, float *f2, float *f3, float *t) static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3, float *t)
{ {
int a; int a;
for(a=0; a<aantal; a++) { for(a=0; a<tot; a++) {
in[a]= t[0]*f0[a]+t[1]*f1[a]+t[2]*f2[a]+t[3]*f3[a]; in[a]= t[0]*f0[a]+t[1]*f1[a]+t[2]*f2[a]+t[3]*f3[a];
} }
} }
static void rel_flerp(int aantal, float *in, float *ref, float *out, float fac) static void rel_flerp(int tot, float *in, float *ref, float *out, float fac)
{ {
int a; int a;
for(a=0; a<aantal; a++) { for(a=0; a<tot; a++) {
in[a]-= fac*(ref[a]-out[a]); in[a]-= fac*(ref[a]-out[a]);
} }
} }

@ -61,7 +61,7 @@
#include "BKE_material.h" #include "BKE_material.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_node.h" #include "BKE_node.h"
#include "BKE_curve.h"
#include "GPU_material.h" #include "GPU_material.h"
@ -516,6 +516,21 @@ short *give_totcolp_id(ID *id)
return NULL; return NULL;
} }
void data_delete_material_index_id(ID *id, int index)
{
switch(GS(id->name)) {
case ID_ME:
mesh_delete_material_index((Mesh *)id, index);
break;
case ID_CU:
curve_delete_material_index((Curve *)id, index);
break;
case ID_MB:
/* meta-elems dont have materials atm */
break;
}
}
void material_append_id(ID *id, Material *ma) void material_append_id(ID *id, Material *ma)
{ {
Material ***matar; Material ***matar;
@ -533,7 +548,7 @@ void material_append_id(ID *id, Material *ma)
} }
} }
Material *material_pop_id(ID *id, int index) Material *material_pop_id(ID *id, int index, int remove_material_slot)
{ {
Material *ret= NULL; Material *ret= NULL;
Material ***matar; Material ***matar;
@ -542,26 +557,35 @@ Material *material_pop_id(ID *id, int index)
if(index >= 0 && index < (*totcol)) { if(index >= 0 && index < (*totcol)) {
ret= (*matar)[index]; ret= (*matar)[index];
id_us_min((ID *)ret); id_us_min((ID *)ret);
if(*totcol <= 1) {
*totcol= 0; if (remove_material_slot) {
MEM_freeN(*matar); if(*totcol <= 1) {
*matar= NULL; *totcol= 0;
MEM_freeN(*matar);
*matar= NULL;
}
else {
Material **mat;
if(index + 1 != (*totcol))
memmove((*matar)+index, (*matar)+(index+1), sizeof(void *) * ((*totcol) - (index + 1)));
(*totcol)--;
mat= MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
memcpy(mat, *matar, sizeof(void *) * (*totcol));
MEM_freeN(*matar);
*matar= mat;
test_object_materials(id);
}
/* decrease mat_nr index */
data_delete_material_index_id(id, index);
} }
else {
Material **mat;
if(index + 1 != (*totcol)) /* don't remove material slot, only clear it*/
memmove((*matar), (*matar) + 1, sizeof(void *) * ((*totcol) - (index + 1))); else
(*matar)[index]= NULL;
(*totcol)--;
mat= MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
memcpy(mat, *matar, sizeof(void *) * (*totcol));
MEM_freeN(*matar);
*matar= mat;
test_object_materials(id);
}
} }
} }
@ -1026,8 +1050,6 @@ int object_remove_material_slot(Object *ob)
{ {
Material *mao, ***matarar; Material *mao, ***matarar;
Object *obt; Object *obt;
Curve *cu;
Nurb *nu;
short *totcolp; short *totcolp;
int a, actcol; int a, actcol;
@ -1087,23 +1109,8 @@ int object_remove_material_slot(Object *ob)
} }
/* check indices from mesh */ /* check indices from mesh */
if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
if(ob->type==OB_MESH) { data_delete_material_index_id((ID *)ob->data, actcol-1);
Mesh *me= get_mesh(ob);
mesh_delete_material_index(me, actcol-1);
freedisplist(&ob->disp);
}
else if ELEM(ob->type, OB_CURVE, OB_SURF) {
cu= ob->data;
nu= cu->nurb.first;
while(nu) {
if(nu->mat_nr && nu->mat_nr>=actcol-1) {
nu->mat_nr--;
if (ob->type == OB_CURVE) nu->charidx--;
}
nu= nu->next;
}
freedisplist(&ob->disp); freedisplist(&ob->disp);
} }

@ -1254,10 +1254,10 @@ void mesh_to_curve(Scene *scene, Object *ob)
void mesh_delete_material_index(Mesh *me, int index) void mesh_delete_material_index(Mesh *me, int index)
{ {
MFace *mf;
int i; int i;
for (i=0; i<me->totface; i++) { for (i=0, mf=me->mface; i<me->totface; i++, mf++) {
MFace *mf = &((MFace*) me->mface)[i];
if (mf->mat_nr && mf->mat_nr>=index) if (mf->mat_nr && mf->mat_nr>=index)
mf->mat_nr--; mf->mat_nr--;
} }

@ -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;
} }
/******************/ /******************/

@ -290,8 +290,10 @@ void BLI_argsParse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *
} }
i += retval; i += retval;
} else if (retval == -1){ } else if (retval == -1){
if (a->key->pass != -1) if (a) {
ba->passes[i] = pass; if (a->key->pass != -1)
ba->passes[i] = pass;
}
break; break;
} }
} }

@ -26,7 +26,6 @@
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
@ -85,25 +84,61 @@ struct PBVHNode {
/* Opaque handle for drawing code */ /* Opaque handle for drawing code */
void *draw_buffers; void *draw_buffers;
int *vert_indices;
/* Voxel bounds */ /* Voxel bounds */
BB vb; BB vb;
BB orig_vb; BB orig_vb;
/* For internal nodes */ /* For internal nodes, the offset of the children in the PBVH
'nodes' array. */
int children_offset; int children_offset;
/* Pointer into bvh prim_indices */ /* Pointer into the PBVH prim_indices array and the number of
int *prim_indices; primitives used by this leaf node.
int *face_vert_indices;
Used for leaf nodes in both mesh- and multires-based PBVHs.
*/
int *prim_indices;
unsigned int totprim; unsigned int totprim;
/* Array of indices into the mesh's MVert array. Contains the
indices of all vertices used by faces that are within this
node's bounding box.
Note that a vertex might be used by a multiple faces, and
these faces might be in different leaf nodes. Such a vertex
will appear in the vert_indices array of each of those leaf
nodes.
In order to support cases where you want access to multiple
nodes' vertices without duplication, the vert_indices array
is ordered such that the first part of the array, up to
index 'uniq_verts', contains "unique" vertex indices. These
vertices might not be truly unique to this node, but if
they appear in another node's vert_indices array, they will
be above that node's 'uniq_verts' value.
Used for leaf nodes in a mesh-based PBVH (not multires.)
*/
int *vert_indices;
unsigned int uniq_verts, face_verts; unsigned int uniq_verts, face_verts;
char flag; /* An array mapping face corners into the vert_indices
array. The array is sized to match 'totprim', and each of
the face's corners gets an index into the vert_indices
array, in the same order as the corners in the original
MFace. The fourth value should not be used if the original
face is a triangle.
float tmin; // used for raycasting, is how close bb is to the ray point Used for leaf nodes in a mesh-based PBVH (not multires.)
*/
int (*face_vert_indices)[4];
/* Indicates whether this node is a leaf or not; also used for
marking various updates that need to be applied. */
PBVHNodeFlags flag : 8;
/* Used for raycasting: how close bb is to the ray point. */
float tmin;
int proxy_count; int proxy_count;
PBVHProxyNode* proxies; PBVHProxyNode* proxies;
@ -339,15 +374,15 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
node->uniq_verts = node->face_verts = 0; node->uniq_verts = node->face_verts = 0;
totface= node->totprim; totface= node->totprim;
node->face_vert_indices = MEM_callocN(sizeof(int) * node->face_vert_indices = MEM_callocN(sizeof(int) * 4*totface,
4*totface, "bvh node face vert indices"); "bvh node face vert indices");
for(i = 0; i < totface; ++i) { for(i = 0; i < totface; ++i) {
MFace *f = bvh->faces + node->prim_indices[i]; MFace *f = bvh->faces + node->prim_indices[i];
int sides = f->v4 ? 4 : 3; int sides = f->v4 ? 4 : 3;
for(j = 0; j < sides; ++j) { for(j = 0; j < sides; ++j) {
node->face_vert_indices[i*4 + j]= node->face_vert_indices[i][j]=
map_insert_vert(bvh, map, &node->face_verts, map_insert_vert(bvh, map, &node->face_verts,
&node->uniq_verts, (&f->v1)[j]); &node->uniq_verts, (&f->v1)[j]);
} }
@ -373,9 +408,17 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
BLI_ghashIterator_free(iter); BLI_ghashIterator_free(iter);
for(i = 0; i < totface*4; ++i) for(i = 0; i < totface; ++i) {
if(node->face_vert_indices[i] < 0) MFace *f = bvh->faces + node->prim_indices[i];
node->face_vert_indices[i]= -node->face_vert_indices[i] + node->uniq_verts - 1; int sides = f->v4 ? 4 : 3;
for(j = 0; j < sides; ++j) {
if(node->face_vert_indices[i][j] < 0)
node->face_vert_indices[i][j]=
-node->face_vert_indices[i][j] +
node->uniq_verts - 1;
}
}
if(!G.background) { if(!G.background) {
node->draw_buffers = node->draw_buffers =
@ -1340,20 +1383,20 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
if(bvh->faces) { if(bvh->faces) {
MVert *vert = bvh->verts; MVert *vert = bvh->verts;
int *faces= node->prim_indices; int *faces= node->prim_indices;
int *face_verts= node->face_vert_indices;
int totface= node->totprim; int totface= node->totprim;
int i; int i;
for(i = 0; i < totface; ++i) { for(i = 0; i < totface; ++i) {
MFace *f = bvh->faces + faces[i]; MFace *f = bvh->faces + faces[i];
int *face_verts = node->face_vert_indices[i];
if(origco) { if(origco) {
/* intersect with backuped original coordinates */ /* intersect with backuped original coordinates */
hit |= ray_face_intersection(ray_start, ray_normal, hit |= ray_face_intersection(ray_start, ray_normal,
origco[face_verts[i*4+0]], origco[face_verts[0]],
origco[face_verts[i*4+1]], origco[face_verts[1]],
origco[face_verts[i*4+2]], origco[face_verts[2]],
f->v4? origco[face_verts[i*4+3]]: NULL, f->v4? origco[face_verts[3]]: NULL,
dist); dist);
} }
else { else {

@ -3163,7 +3163,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
if(part->effector_weights) if(part->effector_weights)
part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group); part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
if(part->dupliweights.first) { if(part->dupliweights.first && part->dup_group) {
int index_ok = 0; int index_ok = 0;
/* check for old files without indices (all indexes 0) */ /* check for old files without indices (all indexes 0) */
dw = part->dupliweights.first; dw = part->dupliweights.first;
@ -3194,6 +3194,9 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
dw->ob = newlibadr(fd, part->id.lib, dw->ob); dw->ob = newlibadr(fd, part->id.lib, dw->ob);
} }
} }
else {
part->dupliweights.first = part->dupliweights.last = NULL;
}
if(part->boids) { if(part->boids) {
BoidState *state = part->boids->states.first; BoidState *state = part->boids->states.first;

@ -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);

@ -3432,7 +3432,6 @@ static int convertspline(short type, Nurb *nu)
nu->type = CU_NURBS; nu->type = CU_NURBS;
nu->orderu= 4; nu->orderu= 4;
nu->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */ nu->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */
nu->flagu |= CU_NURB_BEZIER;
nurbs_knot_calc_u(nu); nurbs_knot_calc_u(nu);
a= nu->pntsu*nu->pntsv; a= nu->pntsu*nu->pntsv;
bp= nu->bp; bp= nu->bp;
@ -6545,10 +6544,13 @@ Nurb *add_nurbs_primitive(bContext *C, float mat[4][4], int type, int newob)
return NULL; return NULL;
} }
/* always do: */ BLI_assert(nu != NULL);
nu->flag |= CU_SMOOTH;
test2DNurb(nu); if(nu) { /* should always be set */
nu->flag |= CU_SMOOTH;
test2DNurb(nu);
}
return nu; return nu;
} }

@ -1,3 +1,27 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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 distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s):
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/editors/interface/interface_anim.c /** \file blender/editors/interface/interface_anim.c
* \ingroup edinterface * \ingroup edinterface
*/ */

@ -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;

@ -576,7 +576,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
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);

@ -2197,7 +2197,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);
@ -2212,7 +2212,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);

@ -1,6 +1,3 @@
/** \file blender/editors/interface/resources.c
* \ingroup edinterface
*/
/* /*
* $Id$ * $Id$
* *
@ -33,6 +30,10 @@
* ***** END GPL/BL DUAL LICENSE BLOCK ***** * ***** END GPL/BL DUAL LICENSE BLOCK *****
*/ */
/** \file blender/editors/interface/resources.c
* \ingroup edinterface
*/
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -1116,8 +1117,9 @@ 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);

@ -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;

@ -1096,7 +1096,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C); Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C); View3D *v3d= CTX_wm_view3d(C);
unsigned int lay, local; unsigned int lay, local;
int islamp= 0; /* int islamp= 0; */ /* UNUSED */
lay= move_to_layer_init(C, op); lay= move_to_layer_init(C, op);
lay &= 0xFFFFFF; lay &= 0xFFFFFF;
@ -1112,7 +1112,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
base->object->lay= lay; base->object->lay= lay;
base->object->flag &= ~SELECT; base->object->flag &= ~SELECT;
base->flag &= ~SELECT; base->flag &= ~SELECT;
if(base->object->type==OB_LAMP) islamp= 1; /* if(base->object->type==OB_LAMP) islamp= 1; */
} }
CTX_DATA_END; CTX_DATA_END;
} }
@ -1124,7 +1124,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
local= base->lay & 0xFF000000; local= base->lay & 0xFF000000;
base->lay= lay + local; base->lay= lay + local;
base->object->lay= lay; base->object->lay= lay;
if(base->object->type==OB_LAMP) islamp= 1; /* if(base->object->type==OB_LAMP) islamp= 1; */
} }
CTX_DATA_END; CTX_DATA_END;
} }

@ -301,7 +301,7 @@ int ED_operator_object_active_editable(bContext *C)
int ED_operator_object_active_editable_mesh(bContext *C) int ED_operator_object_active_editable_mesh(bContext *C)
{ {
Object *ob = ED_object_active_context(C); Object *ob = ED_object_active_context(C);
return ((ob != NULL) && !(ob->id.lib) && !(ob->restrictflag & OB_RESTRICT_VIEW) && ob->type == OB_MESH); return ((ob != NULL) && !(ob->id.lib) && !(ob->restrictflag & OB_RESTRICT_VIEW) && ob->type == OB_MESH && !(((ID *)ob->data)->lib));
} }
int ED_operator_object_active_editable_font(bContext *C) int ED_operator_object_active_editable_font(bContext *C)

@ -2187,7 +2187,7 @@ static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
/* One of the most important function for projectiopn painting, since it selects the pixels to be added into each bucket. /* One of the most important function for projectiopn painting, since it selects the pixels to be added into each bucket.
* initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */ * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf) static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf, const short clamp_u, const short clamp_v)
{ {
/* Projection vars, to get the 3D locations into screen space */ /* Projection vars, to get the 3D locations into screen space */
MemArena *arena = ps->arena_mt[thread_index]; MemArena *arena = ps->arena_mt[thread_index];
@ -2305,6 +2305,16 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) { if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
if(clamp_u) {
CLAMP(bounds_px.xmin, 0, ibuf->x);
CLAMP(bounds_px.xmax, 0, ibuf->x);
}
if(clamp_v) {
CLAMP(bounds_px.ymin, 0, ibuf->y);
CLAMP(bounds_px.ymax, 0, ibuf->y);
}
/* clip face and */ /* clip face and */
has_isect = 0; has_isect = 0;
@ -2630,6 +2640,7 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
LinkNode *node; LinkNode *node;
int face_index, image_index=0; int face_index, image_index=0;
ImBuf *ibuf = NULL; ImBuf *ibuf = NULL;
Image *ima = NULL;
MTFace *tf; MTFace *tf;
Image *tpage_last = NULL; Image *tpage_last = NULL;
@ -2638,9 +2649,10 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
if (ps->image_tot==1) { if (ps->image_tot==1) {
/* Simple loop, no context switching */ /* Simple loop, no context switching */
ibuf = ps->projImages[0].ibuf; ibuf = ps->projImages[0].ibuf;
ima = ps->projImages[0].ima;
for (node = ps->bucketFaces[bucket_index]; node; node= node->next) { for (node = ps->bucketFaces[bucket_index]; node; node= node->next) {
project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf); project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
} }
} }
else { else {
@ -2659,14 +2671,14 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
for (image_index=0; image_index < ps->image_tot; image_index++) { for (image_index=0; image_index < ps->image_tot; image_index++) {
if (ps->projImages[image_index].ima == tpage_last) { if (ps->projImages[image_index].ima == tpage_last) {
ibuf = ps->projImages[image_index].ibuf; ibuf = ps->projImages[image_index].ibuf;
ima = ps->projImages[image_index].ima;
break; break;
} }
} }
} }
/* context switching done */ /* context switching done */
project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf); project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
} }
} }

@ -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 */

@ -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", "");
} }
@ -251,6 +253,10 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
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) {
@ -507,6 +522,10 @@ 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);
} }

@ -280,7 +280,8 @@ static char *view3d_modeselect_pup(Scene *scene)
str += sprintf(str, formatstr, "Object Mode", OB_MODE_OBJECT, ICON_OBJECT_DATA); str += sprintf(str, formatstr, "Object Mode", OB_MODE_OBJECT, ICON_OBJECT_DATA);
if(ob==NULL) return string; if(ob==NULL || ob->data==NULL) return string;
if(ob->id.lib || ((ID *)ob->data)->lib) return string;
/* if active object is editable */ /* if active object is editable */
if ( ((ob->type == OB_MESH) if ( ((ob->type == OB_MESH)

@ -889,14 +889,14 @@ static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo)
{ {
Base *base; Base *base;
unsigned int *bufmin,*bufmax; unsigned int *bufmin,*bufmax;
int a,b,rc,tel,aantal,dirvec[4][2],maxob; int a,b,rc,tel,len,dirvec[4][2],maxob;
unsigned int retval=0; unsigned int retval=0;
base= LASTBASE; base= LASTBASE;
if(base==0) return 0; if(base==0) return 0;
maxob= base->selcol; maxob= base->selcol;
aantal= (size-1)/2; len= (size-1)/2;
rc= 0; rc= 0;
dirvec[0][0]= 1; dirvec[0][0]= 1;
@ -910,7 +910,7 @@ static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo)
bufmin= buf; bufmin= buf;
bufmax= buf+ size*size; bufmax= buf+ size*size;
buf+= aantal*size+ aantal; buf+= len*size+ len;
for(tel=1;tel<=size;tel++) { for(tel=1;tel<=size;tel++) {

@ -4659,7 +4659,7 @@ static int createSlideVerts(TransInfo *t)
#define EDGE_SLIDE_MIN 30 #define EDGE_SLIDE_MIN 30
if (len_squared_v2v2(start, end) < (EDGE_SLIDE_MIN * EDGE_SLIDE_MIN)) { if (len_squared_v2v2(start, end) < (EDGE_SLIDE_MIN * EDGE_SLIDE_MIN)) {
if(ABS(start[0]-end[0]) + ABS(start[1]-end[1]) < 4.0f) { if(ABS(start[0]-end[0]) + ABS(start[1]-end[1]) < 4.0f) {
/* even more exceptional case, points are ontop of eachother */ /* even more exceptional case, points are ontop of each other */
end[0]= start[0]; end[0]= start[0];
end[1]= start[1] + EDGE_SLIDE_MIN; end[1]= start[1] + EDGE_SLIDE_MIN;
} }

@ -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 */

@ -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))
{ {

@ -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);

@ -1060,8 +1060,8 @@ static void weld_align_uv(bContext *C, int tool)
if(tool == 's' || tool == 't' || tool == 'u') { if(tool == 's' || tool == 't' || tool == 'u') {
/* pass 1&2 variables */ /* pass 1&2 variables */
int i, j; int i, j;
int starttmpl= -1, connectedtostarttmpl, startcorner; int starttmpl= -1, connectedtostarttmpl= -1, startcorner;
int endtmpl= -1, connectedtoendtmpl, endcorner; int endtmpl= -1, connectedtoendtmpl= -1, endcorner;
MTFace *startface, *endface; MTFace *startface, *endface;
int itmpl, jtmpl; int itmpl, jtmpl;
EditVert *eve; EditVert *eve;

@ -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;

@ -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 {

@ -1080,7 +1080,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

@ -35,6 +35,7 @@
#include "DNA_ID.h" #include "DNA_ID.h"
#include "DNA_vfont_types.h" #include "DNA_vfont_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "WM_types.h" #include "WM_types.h"
@ -419,8 +420,9 @@ static void rna_def_ID_materials(BlenderRNA *brna)
func= RNA_def_function(srna, "pop", "material_pop_id"); func= RNA_def_function(srna, "pop", "material_pop_id");
RNA_def_function_ui_description(func, "Remove a material from the data block."); RNA_def_function_ui_description(func, "Remove a material from the data block.");
parm= RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of material to remove.", 0, INT_MAX); parm= RNA_def_int(func, "index", 0, 0, MAXMAT, "", "Index of material to remove.", 0, MAXMAT);
RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_boolean(func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned.");
parm= RNA_def_pointer(func, "material", "Material", "", "Material to remove."); parm= RNA_def_pointer(func, "material", "Material", "", "Material to remove.");
RNA_def_function_return(func, parm); RNA_def_function_return(func, parm);
} }

@ -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:

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