svn merge ^/trunk/blender -r46844:HEAD

This commit is contained in:
Ove Murberg Henriksen 2012-05-23 10:56:06 +00:00
commit 736daa9f04
149 changed files with 23467 additions and 19210 deletions

@ -238,8 +238,14 @@ mark_as_advanced(WITH_MINGW64)
option(WITH_CYCLES "Enable cycles Render Engine" ON)
option(WITH_CYCLES_TEST "Build cycles test application" OFF)
option(WITH_CYCLES_CUDA_BINARIES "Build cycles CUDA binaries" OFF)
set(CYCLES_CUDA_BINARIES_ARCH sm_13 sm_20 sm_21 CACHE STRING "CUDA architectures to build binaries for")
if(WIN32 AND NOT CMAKE_CL_64 AND NOT WITH_MINGW64)
set(PLATFORM_DEFAULT sm_20 sm_21)
else()
set(PLATFORM_DEFAULT sm_13 sm_20 sm_21)
endif()
set(CYCLES_CUDA_BINARIES_ARCH ${PLATFORM_DEFAULT} CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
unset(PLATFORM_DEFAULT)
# disable for now, but plan to support on all platforms eventually
option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" OFF)

@ -553,7 +553,7 @@ if env['OURPLATFORM']!='darwin':
source=[os.path.join(dp, f) for f in df if not f.endswith(".pyc")]
# To ensure empty dirs are created too
if len(source)==0:
if len(source)==0 and not os.path.exists(dir):
env.Execute(Mkdir(dir))
scriptinstall.append(env.Install(dir=dir,source=source))
if env['WITH_BF_CYCLES']:

@ -169,6 +169,11 @@ BF_BOOST_LIBPATH = BF_BOOST + '/lib'
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21'] # don't build sm_13 until the compile can fit in 32bit process again :)
##
CC = 'gcc'
CXX = 'g++'

@ -869,12 +869,17 @@ class BlenderEnvironment(SConsEnvironment):
lenv.AddPostAction(prog,Action(AppIt,strfunction=my_appit_print))
elif os.sep == '/' and lenv['OURPLATFORM'] != 'linuxcross': # any unix (except cross-compilation)
if lenv['WITH_BF_PYTHON']:
if not lenv['WITHOUT_BF_INSTALL'] and not lenv['WITHOUT_BF_PYTHON_INSTALL'] and not BlenderEnvironment.PyBundleActionAdded:
if (not lenv['WITHOUT_BF_INSTALL'] and
not lenv['WITHOUT_BF_PYTHON_INSTALL'] and
not lenv['WITHOUT_BF_PYTHON_UNPACK'] and
not BlenderEnvironment.PyBundleActionAdded):
lenv.AddPostAction(prog,Action(UnixPyBundle,strfunction=my_unixpybundle_print))
BlenderEnvironment.PyBundleActionAdded = True
elif lenv['OURPLATFORM'].startswith('win') or lenv['OURPLATFORM'] == 'linuxcross': # windows or cross-compilation
if lenv['WITH_BF_PYTHON']:
if not lenv['WITHOUT_BF_PYTHON_INSTALL'] and not BlenderEnvironment.PyBundleActionAdded:
if (not lenv['WITHOUT_BF_PYTHON_INSTALL'] and
not lenv['WITHOUT_BF_PYTHON_UNPACK'] and
not BlenderEnvironment.PyBundleActionAdded):
lenv.AddPostAction(prog,Action(WinPyBundle,strfunction=my_winpybundle_print))
BlenderEnvironment.PyBundleActionAdded = True
return prog

@ -134,7 +134,7 @@ def validate_arguments(args, bc):
'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC',
'BF_TWEAK_MODE', 'BF_SPLIT_SRC',
'WITHOUT_BF_INSTALL',
'WITHOUT_BF_PYTHON_INSTALL',
'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_PYTHON_UNPACK',
'WITHOUT_BF_OVERWRITE_INSTALL',
'WITH_BF_OPENMP', 'BF_OPENMP', 'BF_OPENMP_LIBPATH',
'WITH_GHOST_COCOA',
@ -519,6 +519,7 @@ def read_opts(env, cfg, args):
(BoolVariable('BF_SPLIT_SRC', 'Split src lib into several chunks if true', False)),
(BoolVariable('WITHOUT_BF_INSTALL', 'dont install if true', False)),
(BoolVariable('WITHOUT_BF_PYTHON_INSTALL', 'dont install Python modules if true', False)),
(BoolVariable('WITHOUT_BF_PYTHON_UNPACK', 'dont remove and unpack Python modules everytime if true', False)),
(BoolVariable('WITHOUT_BF_OVERWRITE_INSTALL', 'dont remove existing files before breating the new install directory (set to False when making packages for others)', False)),
(BoolVariable('BF_FANCY', 'Enable fancy output if true', True)),
(BoolVariable('BF_QUIET', 'Enable silent output if true', True)),

@ -28,7 +28,7 @@ This example script prints the vertices and UV's for each polygon, assumes the a
import bpy
me = bpy.context.object.data
uv_layer = me.uv.layers.active.data
uv_layer = me.uv_layers.active.data
for poly in me.polygons:
print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))

@ -99,9 +99,11 @@ Here are some examples ...
uv_lay = bm.loops.layers.uv.active
for face in bm.faces:
for loop in f.loops:
uv = loop[uv_lay]
print("Loop UV: %f, %f" % (uv.x, uv.y))
for loop in face.loops:
uv = loop[uv_lay].uv
print("Loop UV: %f, %f" % uv[:])
vert = loop.vert
print("Loop Vert: (%f,%f,%f)" % vert.co[:])
.. code-block:: python

@ -285,52 +285,55 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
/* object loop */
BL::Scene::objects_iterator b_ob;
BL::Scene b_sce = b_scene;
for(b_scene.objects.begin(b_ob); b_ob != b_scene.objects.end(); ++b_ob) {
bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render();
uint ob_layer = get_layer(b_ob->layers());
for(; b_sce; b_sce = b_sce.background_set()) {
for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) {
bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render();
uint ob_layer = get_layer(b_ob->layers());
if(!hide && (ob_layer & scene_layer)) {
if(b_ob->is_duplicator()) {
/* dupli objects */
object_create_duplilist(*b_ob, b_scene);
if(!hide && (ob_layer & scene_layer)) {
if(b_ob->is_duplicator()) {
/* dupli objects */
object_create_duplilist(*b_ob, b_scene);
BL::Object::dupli_list_iterator b_dup;
int b_index = 0;
BL::Object::dupli_list_iterator b_dup;
int b_index = 0;
for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) {
Transform tfm = get_transform(b_dup->matrix());
BL::Object b_dup_ob = b_dup->object();
bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) {
Transform tfm = get_transform(b_dup->matrix());
BL::Object b_dup_ob = b_dup->object();
bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
if(!(b_dup->hide() || dup_hide))
sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion);
if(!(b_dup->hide() || dup_hide))
sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion);
b_index++;
}
b_index++;
}
object_free_duplilist(*b_ob);
object_free_duplilist(*b_ob);
hide = true;
}
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
bool render_emitter = false;
for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
if(b_psys->settings().use_render_emitter()) {
hide = false;
render_emitter = true;
}
else if(!render_emitter)
hide = true;
}
}
if(!hide) {
/* object itself */
Transform tfm = get_transform(b_ob->matrix_world());
sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion);
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
bool render_emitter = false;
for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
if(b_psys->settings().use_render_emitter()) {
hide = false;
render_emitter = true;
}
else if(!render_emitter)
hide = true;
}
if(!hide) {
/* object itself */
Transform tfm = get_transform(b_ob->matrix_world());
sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion);
}
}
}
}

@ -29,8 +29,7 @@
* \ingroup MEM
*/
#if defined(WIN32)
#ifdef WIN32
#include <windows.h>
#include <errno.h>
@ -53,21 +52,19 @@
#endif
/* --------------------------------------------------------------------- */
/* local storage definitions */
/* local storage definitions */
/* --------------------------------------------------------------------- */
/* all memory mapped chunks are put in linked lists */
typedef struct mmapLink
{
struct mmapLink *next,*prev;
typedef struct mmapLink {
struct mmapLink *next, *prev;
} mmapLink;
typedef struct mmapListBase
{
typedef struct mmapListBase {
void *first, *last;
} mmapListBase;
typedef struct MemMap {
struct MemMap *next,*prev;
struct MemMap *next, *prev;
void *mmap;
HANDLE fhandle;
HANDLE maphandle;
@ -81,8 +78,8 @@ static void mmap_addtail(volatile mmapListBase *listbase, void *vlink);
static void mmap_remlink(volatile mmapListBase *listbase, void *vlink);
static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr);
static int mmap_get_prot_flags (int flags);
static int mmap_get_access_flags (int flags);
static int mmap_get_prot_flags(int flags);
static int mmap_get_access_flags(int flags);
/* --------------------------------------------------------------------- */
/* vars */
@ -105,52 +102,53 @@ void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t o
MemMap *mm = NULL;
void *ptr = NULL;
if ( flags & MAP_FIXED ) {
if (flags & MAP_FIXED) {
return MAP_FAILED;
}
/*
#if 0
if ( fd == -1 ) {
_set_errno( EBADF );
return MAP_FAILED;
}
*/
#endif
if ( fd != -1 ) {
fhandle = (HANDLE) _get_osfhandle (fd);
if (fd != -1) {
fhandle = (HANDLE) _get_osfhandle(fd);
}
if ( fhandle == INVALID_HANDLE_VALUE ) {
if (fhandle == INVALID_HANDLE_VALUE) {
if (!(flags & MAP_ANONYMOUS)) {
errno = EBADF;
return MAP_FAILED;
}
} else {
if ( !DuplicateHandle( GetCurrentProcess(), fhandle, GetCurrentProcess(),
&fhandle, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
}
else {
if (!DuplicateHandle(GetCurrentProcess(), fhandle, GetCurrentProcess(),
&fhandle, 0, FALSE, DUPLICATE_SAME_ACCESS) ) {
return MAP_FAILED;
}
}
maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL);
if ( maphandle == 0 ) {
if (maphandle == 0) {
errno = EBADF;
return MAP_FAILED;
}
ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
if ( ptr == NULL ) {
if (ptr == NULL) {
DWORD dwLastErr = GetLastError();
if ( dwLastErr == ERROR_MAPPED_ALIGNMENT )
errno=EINVAL;
if (dwLastErr == ERROR_MAPPED_ALIGNMENT)
errno = EINVAL;
else
errno=EACCES;
errno = EACCES;
CloseHandle(maphandle);
return MAP_FAILED;
}
mm= (MemMap *)malloc(sizeof(MemMap));
mm = (MemMap *)malloc(sizeof(MemMap));
if (!mm) {
errno=ENOMEM;
errno = ENOMEM;
}
mm->fhandle = fhandle;
mm->maphandle = maphandle;
@ -165,12 +163,12 @@ intptr_t munmap(void *ptr, intptr_t UNUSED(size))
{
MemMap *mm = mmap_findlink(mmapbase, ptr);
if (!mm) {
errno=EINVAL;
errno = EINVAL;
return -1;
}
UnmapViewOfFile( mm->mmap );
CloseHandle( mm->maphandle );
CloseHandle( mm->fhandle);
UnmapViewOfFile(mm->mmap);
CloseHandle(mm->maphandle);
CloseHandle(mm->fhandle);
mmap_remlink(mmapbase, mm);
free(mm);
return 0;
@ -182,7 +180,7 @@ intptr_t munmap(void *ptr, intptr_t UNUSED(size))
static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
{
struct mmapLink *link= vlink;
struct mmapLink *link = vlink;
if (link == 0) return;
if (listbase == 0) return;
@ -197,7 +195,7 @@ static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
static void mmap_remlink(volatile mmapListBase *listbase, void *vlink)
{
struct mmapLink *link= vlink;
struct mmapLink *link = vlink;
if (link == 0) return;
if (listbase == 0) return;
@ -226,46 +224,46 @@ static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr)
return NULL;
}
static int mmap_get_prot_flags (int flags)
static int mmap_get_prot_flags(int flags)
{
int prot = PAGE_NOACCESS;
if ( ( flags & PROT_READ ) == PROT_READ ) {
if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
if ( (flags & PROT_READ) == PROT_READ) {
if ( (flags & PROT_WRITE) == PROT_WRITE) {
prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
} else {
}
else {
prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
}
} else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
}
else if ( (flags & PROT_WRITE) == PROT_WRITE) {
prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
} else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
}
else if ( (flags & PROT_EXEC) == PROT_EXEC) {
prot = PAGE_EXECUTE_READ;
}
return prot;
}
static int mmap_get_access_flags (int flags)
static int mmap_get_access_flags(int flags)
{
int access = 0;
if ( ( flags & PROT_READ ) == PROT_READ ) {
if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
if ( (flags & PROT_READ) == PROT_READ) {
if ( (flags & PROT_WRITE) == PROT_WRITE) {
access = FILE_MAP_WRITE;
} else {
}
else {
access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
}
} else if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
}
else if ( (flags & PROT_WRITE) == PROT_WRITE) {
access = FILE_MAP_COPY;
} else if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
}
else if ( (flags & PROT_EXEC) == PROT_EXEC) {
access = FILE_MAP_EXECUTE;
}
return access;
}
#endif // WIN32

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 222 KiB

@ -35,7 +35,7 @@ class SelectPattern(Operator):
pattern = StringProperty(
name="Pattern",
description="Name filter using '*' and '?' wildcard chars",
maxlen=32,
maxlen=64,
default="*",
)
case_sensitive = BoolProperty(

@ -452,6 +452,24 @@ class AddPresetTrackingSettings(AddPresetBase, Operator):
preset_subdir = "tracking_settings"
class AddPresetNodeColor(AddPresetBase, Operator):
'''Add a Node Color Preset'''
bl_idname = "node.node_color_preset_add"
bl_label = "Add Node Color Preset"
preset_menu = "NODE_MT_node_color_presets"
preset_defines = [
"node = bpy.context.active_node"
]
preset_values = [
"node.color",
"node.use_custom_color"
]
preset_subdir = "node_color"
class AddPresetInterfaceTheme(AddPresetBase, Operator):
'''Add a theme preset'''
bl_idname = "wm.interface_theme_preset_add"

@ -1077,7 +1077,7 @@ class WM_OT_properties_context_change(Operator):
context = StringProperty(
name="Context",
maxlen=32,
maxlen=64,
)
def execute(self, context):

@ -70,8 +70,12 @@ class MotionPathButtonsPanel():
else:
col.operator("object.paths_update", text="Update Paths", icon='OBJECT_DATA')
else:
col.label(text="Not available yet...", icon='ERROR')
col.label(text="Calculate Paths first", icon='INFO')
sub = col.column(align=True)
sub.label(text="Nothing to show yet...", icon='ERROR')
if bones:
sub.operator("pose.paths_calculate", text="Calculate...", icon='BONE_DATA')
else:
sub.operator("object.paths_calculate", text="Calculate...", icon='OBJECT_DATA')
# Display Settings
split = layout.split()

@ -130,7 +130,7 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
col.active = (ob.proxy is None)
col.operator("pose.group_add", icon='ZOOMIN', text="")
col.operator("pose.group_remove", icon='ZOOMOUT', text="")
col.menu("DATA_PT_bone_group_specials", icon='DOWNARROW_HLT', text="")
col.menu("DATA_PT_bone_group_specials", icon='BLANK1', text="")
if group:
col.separator()
col.operator("pose.group_move", icon='TRIA_UP', text="").direction = 'UP'

@ -149,7 +149,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
col = row.column(align=True)
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="")
col.menu("MESH_MT_vertex_group_specials", icon='DOWNARROW_HLT', text="")
col.menu("MESH_MT_vertex_group_specials", icon='BLANK1', text="")
if group:
col.operator("object.vertex_group_move", icon='TRIA_UP', text="").direction = 'UP'
col.operator("object.vertex_group_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
@ -208,7 +208,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
sub = col.column(align=True)
sub.operator("object.shape_key_add", icon='ZOOMIN', text="").from_mix = False
sub.operator("object.shape_key_remove", icon='ZOOMOUT', text="")
sub.menu("MESH_MT_shape_key_specials", icon='DOWNARROW_HLT', text="")
sub.menu("MESH_MT_shape_key_specials", icon='BLANK1', text="")
if kb:
col.separator()
@ -262,6 +262,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
col.prop_search(kb, "relative_key", key, "key_blocks", text="")
else:
layout.prop(kb, "interpolation")
row = layout.column()
row.active = enable_edit_value
row.prop(key, "eval_time")

@ -959,5 +959,29 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.separator()
self.vertex_weight_mask(layout, ob, md)
def SKIN(self, layout, ob, md):
layout.operator("object.skin_armature_create", text="Create Armature")
layout.separator()
layout.prop(md, "branch_smoothing")
layout.prop(md, "use_smooth_shade")
layout.label(text="Selected Vertices:")
split = layout.split()
col = split.column(align=True)
col.operator("object.skin_loose_mark_clear", text="Mark Loose").action = "MARK"
col.operator("object.skin_loose_mark_clear", text="Clear Loose").action = "CLEAR"
col = split.column()
col.operator("object.skin_root_mark", text="Mark Root")
col.operator("object.skin_radii_equalize", text="Equalize Radii")
layout.label(text="Symmetry Axes:")
col = layout.column()
col.prop(md, "use_x_symmetry")
col.prop(md, "use_y_symmetry")
col.prop(md, "use_z_symmetry")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

@ -110,7 +110,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
col.operator("object.material_slot_add", icon='ZOOMIN', text="")
col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
col.menu("MATERIAL_MT_specials", icon='BLANK1', text="")
if ob.mode == 'EDIT':
row = layout.row(align=True)

@ -130,7 +130,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
col = row.column(align=True)
col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="")
col.menu("TEXTURE_MT_specials", icon='BLANK1', text="")
split = layout.split(percentage=0.65)
col = split.column()
@ -511,7 +511,7 @@ class TEXTURE_PT_envmap(TextureTypePanel, Panel):
row = layout.row()
row.prop(env, "source", expand=True)
row.menu("TEXTURE_MT_envmap_specials", icon='DOWNARROW_HLT', text="")
row.menu("TEXTURE_MT_envmap_specials", icon='BLANK1', text="")
if env.source == 'IMAGE_FILE':
layout.template_ID(tex, "image", open="image.open")

@ -225,5 +225,23 @@ class NODE_PT_quality(bpy.types.Panel):
layout.prop(tree, "chunksize")
layout.prop(tree, "use_opencl")
class NODE_MT_node_color_presets(Menu):
"""Predefined node color"""
bl_label = "Color Presets"
preset_subdir = "node_color"
preset_operator = "script.execute_preset"
draw = Menu.draw_preset
class NODE_MT_node_color_specials(Menu):
bl_label = "Node Color Specials"
def draw(self, context):
layout = self.layout
layout.operator('node.node_copy_color', icon='COPY_ID')
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

@ -873,6 +873,8 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
layout.prop(sculpt, "show_brush")
layout.prop(sculpt, "use_deform_only")
layout.prop(sculpt, "input_samples")
self.unified_paint_settings(layout, context)
@ -985,6 +987,8 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
col.prop(mesh, "use_mirror_x")
col.prop(mesh, "use_mirror_topology")
col.prop(wpaint, "input_samples")
self.unified_paint_settings(col, context)
# Commented out because the Apply button isn't an operator yet, making these settings useless
@ -1015,6 +1019,8 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
col.prop(vpaint, "use_normal")
col.prop(vpaint, "use_spray")
col.prop(vpaint, "input_samples")
self.unified_paint_settings(col, context)
# Commented out because the Apply button isn't an operator yet, making these settings useless

@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 263
#define BLENDER_SUBVERSION 5
#define BLENDER_SUBVERSION 6
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0

@ -55,9 +55,9 @@ struct Key *copy_key_nolib(struct Key *key);
void BKE_key_make_local(struct Key *key);
void sort_keys(struct Key *key);
void key_curve_position_weights(float t, float *data, int type);
void key_curve_tangent_weights(float t, float *data, int type);
void key_curve_normal_weights(float t, float *data, int type);
void key_curve_position_weights(float t, float data[4], int type);
void key_curve_tangent_weights(float t, float data[4], int type);
void key_curve_normal_weights(float t, float data[4], int type);
float *do_ob_key(struct Scene *scene, struct Object *ob);

@ -111,6 +111,10 @@ int poly_find_loop_from_vert(const struct MPoly *poly,
int poly_get_adj_loops_from_vert(unsigned adj_r[3], const struct MPoly *poly,
const struct MLoop *mloop, unsigned vert);
/* Return the index of the edge vert that is not equal to 'v'. If
* neither edge vertex is equal to 'v', returns -1. */
int BKE_mesh_edge_other_vert(const struct MEdge *e, int v);
/* update the hide flag for edges and polys from the corresponding
* flag in verts */
void BKE_mesh_flush_hidden_from_verts(const struct MVert *mvert,

@ -248,6 +248,12 @@ typedef struct bNodeType {
#define NODE_OLD_SHADING 1
#define NODE_NEW_SHADING 2
/* node resize directions */
#define NODE_RESIZE_TOP 1
#define NODE_RESIZE_BOTTOM 2
#define NODE_RESIZE_RIGHT 4
#define NODE_RESIZE_LEFT 8
/* enum values for input/output */
#define SOCK_IN 1
#define SOCK_OUT 2
@ -348,7 +354,8 @@ void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link);
void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node);
void nodeSpaceCoords(struct bNode *node, float *locx, float *locy);
void nodeToView(struct bNode *node, float x, float y, float *rx, float *ry);
void nodeFromView(struct bNode *node, float x, float y, float *rx, float *ry);
void nodeAttachNode(struct bNode *node, struct bNode *parent);
void nodeDetachNode(struct bNode *node);

@ -53,6 +53,7 @@ struct MovieClip;
void BKE_object_workob_clear(struct Object *workob);
void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob);
void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
struct SoftBody *copy_softbody(struct SoftBody *sb);
struct BulletSoftBody *copy_bulletsoftbody(struct BulletSoftBody *sb);
void BKE_object_copy_particlesystems(struct Object *obn, struct Object *ob);

@ -153,6 +153,8 @@ typedef struct ARegionType {
int keymapflag;
/* return without drawing. lock is set by region definition, and copied to do_lock by render. can become flag */
short do_lock, lock;
/* call cursor function on each move event */
short event_cursor;
} ARegionType;
/* panel types */

@ -1329,7 +1329,7 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br)
for (i = 0; i < side; ++i) {
for (j = 0; j < side; ++j) {
float magn = sqrt(pow(i - half, 2) + pow(j - half, 2));
float magn = sqrtf(powf(i - half, 2) + powf(j - half, 2));
im->rect_float[i * side + j] = BKE_brush_curve_strength_clamp(br, magn, half);
}
}

@ -1891,6 +1891,14 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis
med->flag = BM_edge_flag_to_mflag(eed);
/* handle this differently to editmode switching,
* only enable draw for single user edges rather then calculating angle */
if ((med->flag & ME_EDGEDRAW) == 0) {
if (eed->l && eed->l == eed->l->radial_next) {
med->flag |= ME_EDGEDRAW;
}
}
CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
if (add_orig) *index = i;
}

@ -429,10 +429,10 @@ static DerivedMesh *cloth_to_triangles(DerivedMesh *dm)
MFace *mface2 = NULL;
/* calc faces */
for(i = 0; i < numfaces; i++)
{
if(mface[i].v4)
for (i = 0; i < numfaces; i++) {
if (mface[i].v4) {
quads++;
}
}
result = CDDM_from_template(dm, dm->getNumVerts(dm), 0, numfaces + quads, 0, 0);
@ -443,8 +443,7 @@ static DerivedMesh *cloth_to_triangles(DerivedMesh *dm)
DM_ensure_tessface(result);
mface2 = result->getTessFaceArray(result);
for(i = 0, j = numfaces; i < numfaces; i++)
{
for (i = 0, j = numfaces; i < numfaces; i++) {
// DG TODO: is this necessary?
mface2[i].v1 = mface[i].v1;
mface2[i].v2 = mface[i].v2;
@ -453,8 +452,7 @@ static DerivedMesh *cloth_to_triangles(DerivedMesh *dm)
mface2[i].v4 = 0;
//test_index_face(&mface2[i], &result->faceData, i, 3);
if(mface[i].v4)
{
if (mface[i].v4) {
DM_copy_tessface_data(dm, result, i, j, 1);
mface2[j].v1 = mface[i].v1;

@ -345,19 +345,17 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
}
}
if(result)
{
if (result) {
int i = 0;
for(i = 0; i < 3; i++)
{
if(cloth1->verts[collpair->ap1].impulse_count > 0 && ABS(cloth1->verts[collpair->ap1].impulse[i]) < ABS(i1[i]))
for (i = 0; i < 3; i++) {
if (cloth1->verts[collpair->ap1].impulse_count > 0 && ABS(cloth1->verts[collpair->ap1].impulse[i]) < ABS(i1[i]))
cloth1->verts[collpair->ap1].impulse[i] = i1[i];
if(cloth1->verts[collpair->ap2].impulse_count > 0 && ABS(cloth1->verts[collpair->ap2].impulse[i]) < ABS(i2[i]))
if (cloth1->verts[collpair->ap2].impulse_count > 0 && ABS(cloth1->verts[collpair->ap2].impulse[i]) < ABS(i2[i]))
cloth1->verts[collpair->ap2].impulse[i] = i2[i];
if(cloth1->verts[collpair->ap3].impulse_count > 0 && ABS(cloth1->verts[collpair->ap3].impulse[i]) < ABS(i3[i]))
if (cloth1->verts[collpair->ap3].impulse_count > 0 && ABS(cloth1->verts[collpair->ap3].impulse[i]) < ABS(i3[i]))
cloth1->verts[collpair->ap3].impulse[i] = i3[i];
}
}
@ -681,8 +679,9 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
}
}
if(!result)
if (!result) {
break;
}
}
return ret;
}

@ -3155,7 +3155,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
/* find bounding-box range where target is located */
if (ownLoc[clamp_axis] < curveMin[clamp_axis]) {
/* bounding-box range is before */
offset = curveMin[clamp_axis] - ceil((curveMin[clamp_axis] - ownLoc[clamp_axis]) / len) * len;
offset = curveMin[clamp_axis] - ceilf((curveMin[clamp_axis] - ownLoc[clamp_axis]) / len) * len;
/* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */
curvetime = (ownLoc[clamp_axis] - offset) / (len);

@ -992,6 +992,38 @@ static void layerInterp_shapekey(void **sources, float *weights,
}
}
static void layerDefault_mvert_skin(void *data, int count)
{
MVertSkin *vs = data;
int i;
for (i = 0; i < count; i++) {
copy_v3_fl(vs[i].radius, 0.25f);
vs[i].flag = 0;
}
}
static void layerInterp_mvert_skin(void **sources, float *weights,
float *UNUSED(sub_weights),
int count, void *dest)
{
float radius[3], w;
MVertSkin *vs;
int i;
zero_v3(radius);
for (i = 0; i < count; i++) {
w = weights ? weights[i] : 1.0f;
vs = sources[i];
madd_v3_v3fl(radius, vs->radius, w);
}
vs = dest;
copy_v3_v3(vs->radius, radius);
vs->flag &= ~MVERT_SKIN_ROOT;
}
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 0: CD_MVERT */
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
@ -1093,7 +1125,10 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 35: CD_GRID_PAINT_MASK */
{sizeof(GridPaintMask), "GridPaintMask", 1, NULL, layerCopy_grid_paint_mask,
layerFree_grid_paint_mask, NULL, NULL, NULL}
layerFree_grid_paint_mask, NULL, NULL, NULL},
/* 36: CD_SKIN_NODE */
{sizeof(MVertSkin), "MVertSkin", 1, "Skin", NULL, NULL,
layerInterp_mvert_skin, NULL, layerDefault_mvert_skin}
};
/* note, numbers are from trunk and need updating for bmesh */
@ -1108,10 +1143,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* BMESH ONLY */
/* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
/* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask",
/* 35 */ "CDGridPaintMask"
/* END BMESH ONLY */
/* 35-36 */ "CDGridPaintMask", "CDMVertSkin"
};
@ -1123,26 +1155,26 @@ const CustomDataMask CD_MASK_MESH =
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
CD_MASK_GRID_PAINT_MASK;
CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN;
const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
CD_MASK_GRID_PAINT_MASK;
CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_PREVIEW_MLOOPCOL |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORCO | CD_MASK_TANGENT |
CD_MASK_PREVIEW_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST |
CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX;
CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX | CD_MASK_MVERT_SKIN;
const CustomDataMask CD_MASK_BMESH =
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS |
CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
CD_MASK_GRID_PAINT_MASK;
CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN;
const CustomDataMask CD_MASK_FACECORNERS =
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL;

@ -1688,6 +1688,20 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
}
}
if (CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
BMIter iter;
BMVert *eve;
int i;
DM_add_vert_layer(&bmdm->dm, CD_MVERT_SKIN, CD_CALLOC, NULL);
BM_ITER_MESH_INDEX (eve, &iter, bmdm->tc->bm, BM_VERTS_OF_MESH, i) {
DM_set_vert_data(&bmdm->dm, i, CD_MVERT_SKIN,
CustomData_bmesh_get(&bm->vdata, eve->head.data,
CD_MVERT_SKIN));
}
}
if (vertexCos) {
BMFace *efa;
BMVert *eve;

@ -271,7 +271,7 @@ void sort_keys(Key *key)
/**************** do the key ****************/
void key_curve_position_weights(float t, float *data, int type)
void key_curve_position_weights(float t, float data[4], int type)
{
float t2, t3, fc;
@ -303,7 +303,7 @@ void key_curve_position_weights(float t, float *data, int type)
}
/* first derivative */
void key_curve_tangent_weights(float t, float *data, int type)
void key_curve_tangent_weights(float t, float data[4], int type)
{
float t2, fc;
@ -333,7 +333,7 @@ void key_curve_tangent_weights(float t, float *data, int type)
}
/* second derivative */
void key_curve_normal_weights(float t, float *data, int type)
void key_curve_normal_weights(float t, float data[4], int type)
{
float fc;
@ -359,11 +359,11 @@ void key_curve_normal_weights(float t, float *data, int type)
}
}
static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl)
static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
{
/* return 1 means k[2] is the position, return 0 means interpolate */
KeyBlock *k1, *firstkey;
float d, dpos, ofs = 0, lastpos, temp, fval[4];
float d, dpos, ofs = 0, lastpos;
short bsplinetype;
firstkey = lb->first;
@ -467,17 +467,12 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl)
}
/* interpolation */
key_curve_position_weights(d, t, k[1]->type);
if (k[1]->type != k[2]->type) {
key_curve_position_weights(d, fval, k[2]->type);
temp = 1.0f - d;
t[0] = temp * t[0] + d * fval[0];
t[1] = temp * t[1] + d * fval[1];
t[2] = temp * t[2] + d * fval[2];
t[3] = temp * t[3] + d * fval[3];
float t_other[4];
key_curve_position_weights(d, t_other, k[2]->type);
interp_v4_v4v4(t, t, t_other, d);
}
return 0;

@ -662,7 +662,8 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
use_vgroups = (dm->getVertData(dm, 0, CD_MDEFORMVERT) != NULL);
}
else {
use_vgroups = FALSE;
Mesh *me = target->data;
use_vgroups = (me->dvert != NULL);
}
}
else {
@ -807,7 +808,8 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
use_vgroups = (dm->getVertData(dm, 0, CD_MDEFORMVERT) != NULL);
}
else {
use_vgroups = FALSE;
Mesh *me = target->data;
use_vgroups = (me->dvert != NULL);
}
}
else {

@ -2996,6 +2996,18 @@ int poly_get_adj_loops_from_vert(unsigned adj_r[3], const MPoly *poly,
return corner;
}
/* Return the index of the edge vert that is not equal to 'v'. If
* neither edge vertex is equal to 'v', returns -1. */
int BKE_mesh_edge_other_vert(const MEdge *e, int v)
{
if (e->v1 == v)
return e->v2;
else if (e->v2 == v)
return e->v1;
else
return -1;
}
/* update the hide flag for edges and faces from the corresponding
* flag in verts */
void BKE_mesh_flush_hidden_from_verts(const MVert *mvert,

@ -336,6 +336,7 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp)
node->width= ntype->width;
node->miniwidth= 42.0f;
node->height= ntype->height;
node->color[0] = node->color[1] = node->color[2] = 0.608; /* default theme color */
node_add_sockets_from_type(ntree, node, ntype);
@ -591,40 +592,49 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
BLI_freelistN(&intlinks);
}
/* transforms node location to area coords */
void nodeSpaceCoords(bNode *node, float *locx, float *locy)
void nodeToView(bNode *node, float x, float y, float *rx, float *ry)
{
if (node->parent) {
nodeSpaceCoords(node->parent, locx, locy);
*locx += node->locx;
*locy += node->locy;
nodeToView(node->parent, x + node->locx, y + node->locy, rx, ry);
}
else {
*locx = node->locx;
*locy = node->locy;
*rx = x + node->locx;
*ry = y + node->locy;
}
}
void nodeFromView(bNode *node, float x, float y, float *rx, float *ry)
{
if (node->parent) {
nodeFromView(node->parent, x, y, rx, ry);
*rx -= node->locx;
*ry -= node->locy;
}
else {
*rx = x - node->locx;
*ry = y - node->locy;
}
}
void nodeAttachNode(bNode *node, bNode *parent)
{
float parentx, parenty;
float locx, locy;
nodeToView(node, 0.0f, 0.0f, &locx, &locy);
node->parent = parent;
/* transform to parent space */
nodeSpaceCoords(parent, &parentx, &parenty);
node->locx -= parentx;
node->locy -= parenty;
nodeFromView(parent, locx, locy, &node->locx, &node->locy);
}
void nodeDetachNode(struct bNode *node)
{
float parentx, parenty;
float locx, locy;
if (node->parent) {
/* transform to "global" (area) space */
nodeSpaceCoords(node->parent, &parentx, &parenty);
node->locx += parentx;
node->locy += parenty;
/* transform to view space */
nodeToView(node, 0.0f, 0.0f, &locx, &locy);
node->locx = locx;
node->locy = locy;
node->parent = NULL;
}
}

@ -1036,6 +1036,10 @@ static void copy_object_pose(Object *obn, Object *ob)
chan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE);
if (chan->custom) {
id_us_plus(&chan->custom->id);
}
for (con = chan->constraints.first; con; con = con->next) {
bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
@ -1086,7 +1090,7 @@ Object *BKE_object_pose_armature_get(Object *ob)
return NULL;
}
static void copy_object_transform(Object *ob_tar, Object *ob_src)
void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
{
copy_v3_v3(ob_tar->loc, ob_src->loc);
copy_v3_v3(ob_tar->rot, ob_src->rot);
@ -1361,7 +1365,7 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
BKE_object_apply_mat4(ob, ob->obmat, FALSE, TRUE);
}
else {
copy_object_transform(ob, target);
BKE_object_transform_copy(ob, target);
ob->parent = target->parent; /* libdata */
copy_m4_m4(ob->parentinv, target->parentinv);
}
@ -3026,10 +3030,12 @@ int BKE_object_is_animated(Scene *scene, Object *ob)
ModifierData *md;
for (md = modifiers_getVirtualModifierList(ob); md; md = md->next)
if(modifier_dependsOnTime(md) &&
(modifier_isEnabled(scene, md, eModifierMode_Realtime) ||
modifier_isEnabled(scene, md, eModifierMode_Render)))
if (modifier_dependsOnTime(md) &&
(modifier_isEnabled(scene, md, eModifierMode_Realtime) ||
modifier_isEnabled(scene, md, eModifierMode_Render)))
{
return 1;
}
return 0;
}

@ -3292,9 +3292,9 @@ void BKE_ptcache_update_info(PTCacheID *pid)
mb = (bytes > 1024.0f * 1024.0f);
BLI_snprintf(mem_info, sizeof(mem_info), "%i frames in memory (%.1f %s)",
totframes,
bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
mb ? "Mb" : "kb");
totframes,
bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
mb ? "Mb" : "kb");
}
if (cache->flag & PTCACHE_OUTDATED) {

@ -3826,7 +3826,7 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
layer->data = newdataadr(fd, layer->data);
if (layer->type == CD_MDISPS)
direct_link_mdisps(fd, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
else if(layer->type == CD_GRID_PAINT_MASK)
else if (layer->type == CD_GRID_PAINT_MASK)
direct_link_grid_paint_mask(fd, count, layer->data);
i++;
}
@ -4897,8 +4897,10 @@ static void link_recurs_seq(FileData *fd, ListBase *lb)
static void direct_link_paint(FileData *fd, Paint **paint)
{
/* TODO. is this needed */
/* TODO. is this needed */
(*paint) = newdataadr(fd, (*paint));
if (*paint && (*paint)->num_input_samples < 1)
(*paint)->num_input_samples = 1;
}
static void direct_link_scene(FileData *fd, Scene *sce)
@ -6793,6 +6795,29 @@ static void do_versions_nodetree_image_layer_2_64_5(bNodeTree *ntree)
}
}
static void do_versions_nodetree_frame_2_64_6(bNodeTree *ntree)
{
bNode *node;
for (node=ntree->nodes.first; node; node=node->next) {
if (node->type==NODE_FRAME) {
/* initialize frame node storage data */
if (node->storage == NULL) {
NodeFrame *data = (NodeFrame *)MEM_callocN(sizeof(NodeFrame), "frame node storage");
node->storage = data;
/* copy current flags */
data->flag = node->custom1;
data->label_size = 20;
}
}
/* initialize custom node color */
node->color[0] = node->color[1] = node->color[2] = 0.608; /* default theme color */
}
}
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@ -7412,7 +7437,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
for(cu = main->curve.first; cu; cu = cu->id.next) {
for (cu = main->curve.first; cu; cu = cu->id.next) {
if (cu->bevfac2 == 0.0f) {
cu->bevfac1 = 0.0f;
cu->bevfac2 = 1.0f;
@ -7439,6 +7464,40 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 6))
{
/* update use flags for node sockets (was only temporary before) */
Scene *sce;
Material *mat;
Tex *tex;
Lamp *lamp;
World *world;
bNodeTree *ntree;
for (sce=main->scene.first; sce; sce=sce->id.next)
if (sce->nodetree)
do_versions_nodetree_frame_2_64_6(sce->nodetree);
for (mat=main->mat.first; mat; mat=mat->id.next)
if (mat->nodetree)
do_versions_nodetree_frame_2_64_6(mat->nodetree);
for (tex=main->tex.first; tex; tex=tex->id.next)
if (tex->nodetree)
do_versions_nodetree_frame_2_64_6(tex->nodetree);
for (lamp=main->lamp.first; lamp; lamp=lamp->id.next)
if (lamp->nodetree)
do_versions_nodetree_frame_2_64_6(lamp->nodetree);
for (world=main->world.first; world; world=world->id.next)
if (world->nodetree)
do_versions_nodetree_frame_2_64_6(world->nodetree);
for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
do_versions_nodetree_frame_2_64_6(ntree);
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */

@ -1662,17 +1662,17 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external)
static void write_grid_paint_mask(WriteData *wd, int count, GridPaintMask *grid_paint_mask)
{
if(grid_paint_mask) {
if (grid_paint_mask) {
int i;
writestruct(wd, DATA, "GridPaintMask", count, grid_paint_mask);
for(i = 0; i < count; ++i) {
for (i = 0; i < count; ++i) {
GridPaintMask *gpm = &grid_paint_mask[i];
if(gpm->data) {
if (gpm->data) {
const int gridsize = ccg_gridsize(gpm->level);
writedata(wd, DATA,
sizeof(*gpm->data) * gridsize * gridsize,
gpm->data);
sizeof(*gpm->data) * gridsize * gridsize,
gpm->data);
}
}
}

@ -225,9 +225,10 @@ enum {
* when temp tagging is handy.
* always assume dirty & clear before use. */
/* we have 2 spare flags which is awesome but since we're limited to 8
BM_ELEM_DRAW = (1 << 5), /* edge display */
/* we have 1 spare flag which is awesome but since we're limited to 8
* only add new flags with care! - campbell */
/* BM_ELEM_SPARE = (1 << 5), */
/* BM_ELEM_SPARE = (1 << 6), */
BM_ELEM_INTERNAL_TAG = (1 << 7) /* for low level internal API tagging,

@ -973,6 +973,7 @@ char BM_edge_flag_from_mflag(const short meflag)
{
return ( ((meflag & SELECT) ? BM_ELEM_SELECT : 0) |
((meflag & ME_SEAM) ? BM_ELEM_SEAM : 0) |
((meflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) |
((meflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0) | /* invert */
((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0)
);
@ -994,16 +995,18 @@ char BM_vert_flag_to_mflag(BMVert *eve)
((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0)
);
}
short BM_edge_flag_to_mflag(BMEdge *eed)
{
const char hflag = eed->head.hflag;
return ( ((hflag & BM_ELEM_SELECT) ? SELECT : 0) |
((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) |
((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) |
((BM_edge_is_wire(eed)) ? ME_LOOSEEDGE : 0) | /* not typical */
(ME_EDGEDRAW | ME_EDGERENDER)
return ( ((hflag & BM_ELEM_SELECT) ? SELECT : 0) |
((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) |
((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) |
((BM_edge_is_wire(eed)) ? ME_LOOSEEDGE : 0) | /* not typical */
ME_EDGERENDER
);
}
char BM_face_flag_to_mflag(BMFace *efa)

@ -852,24 +852,24 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int ds
BMVert *eve;
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, dst_n);
CustomData_bmesh_set_n(data, eve->head.data, type, src_n, ptr);
void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, src_n);
CustomData_bmesh_set_n(data, eve->head.data, type, dst_n, ptr);
}
}
else if (&bm->edata == data) {
BMEdge *eed;
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, dst_n);
CustomData_bmesh_set_n(data, eed->head.data, type, src_n, ptr);
void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, src_n);
CustomData_bmesh_set_n(data, eed->head.data, type, dst_n, ptr);
}
}
else if (&bm->pdata == data) {
BMFace *efa;
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, dst_n);
CustomData_bmesh_set_n(data, efa->head.data, type, src_n, ptr);
void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, src_n);
CustomData_bmesh_set_n(data, efa->head.data, type, dst_n, ptr);
}
}
else if (&bm->ldata == data) {
@ -879,8 +879,8 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int ds
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, dst_n);
CustomData_bmesh_set_n(data, l->head.data, type, src_n, ptr);
void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, src_n);
CustomData_bmesh_set_n(data, l->head.data, type, dst_n, ptr);
}
}
}

@ -612,8 +612,6 @@ void BM_editselection_normal(BMEditSelection *ese, float r_normal[3])
}
}
/* ref - editmesh_lib.cL:EM_editselection_plane() */
/* Calculate a plane that is rightangles to the edge/vert/faces normal
* also make the plane run along an axis that is related to the geometry,
* because this is used for the manipulators Y axis. */
@ -691,21 +689,9 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3])
}
}
else {
/* BMESH_TODO (not urgent, use longest ngon edge for alignment) */
BMLoop *l_long = BM_face_find_longest_loop(efa);
/* start with v1-2 */
sub_v3_v3v3(r_plane, verts[0]->co, verts[1]->co);
/* test the edge between v2-3, use if longer */
sub_v3_v3v3(vec, verts[1]->co, verts[2]->co);
if (dot_v3v3(r_plane, r_plane) < dot_v3v3(vec, vec))
copy_v3_v3(r_plane, vec);
/* test the edge between v1-3, use if longer */
sub_v3_v3v3(vec, verts[2]->co, verts[0]->co);
if (dot_v3v3(r_plane, r_plane) < dot_v3v3(vec, vec)) {
copy_v3_v3(r_plane, vec);
}
sub_v3_v3v3(r_plane, l_long->v->co, l_long->next->v->co);
}
}

@ -495,6 +495,9 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
{
med->flag &= ~ME_EDGEDRAW;
}
else {
med->flag |= ME_EDGEDRAW;
}
}
void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)

@ -951,6 +951,64 @@ float BM_vert_calc_mean_tagged_edge_length(BMVert *v)
}
/**
* Returns the shortest edge in f.
*/
BMLoop *BM_face_find_shortest_loop(BMFace *f)
{
BMLoop *shortest_loop = NULL;
float shortest_len = FLT_MAX;
BMLoop *l_iter;
BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
const float len = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
if (len <= shortest_len) {
shortest_loop = l_iter;
shortest_len = len;
}
} while ((l_iter = l_iter->next) != l_first);
return shortest_loop;
}
/**
* Returns the longest edge in f.
*/
BMLoop *BM_face_find_longest_loop(BMFace *f)
{
BMLoop *longest_loop = NULL;
float longest_len = 0.0f;
BMLoop *l_iter;
BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
const float len = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
if (len >= longest_len) {
longest_loop = l_iter;
longest_len = len;
}
} while ((l_iter = l_iter->next) != l_first);
return longest_loop;
}
BMEdge *BM_face_find_shortest_edge(BMFace *f)
{
return BM_face_find_shortest_loop(f)->e;
}
BMEdge *BM_face_find_longest_edge(BMFace *f)
{
return BM_face_find_longest_loop(f)->e;
}
/**
* Returns the edge existing between v1 and v2, or NULL if there isn't one.
*

@ -67,6 +67,12 @@ float BM_vert_calc_edge_angle(BMVert *v);
float BM_vert_calc_shell_factor(BMVert *v);
float BM_vert_calc_mean_tagged_edge_length(BMVert *v);
BMEdge *BM_face_find_shortest_edge(BMFace *f);
BMEdge *BM_face_find_longest_edge(BMFace *f);
BMLoop *BM_face_find_shortest_loop(BMFace *f);
BMLoop *BM_face_find_longest_loop(BMFace *f);
BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2);
int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_existface);

@ -26,9 +26,13 @@
#include "MEM_guardedalloc.h"
#include "DNA_meshdata_types.h"
#include "BLI_math.h"
#include "BLI_array.h"
#include "BKE_customdata.h"
#include "bmesh.h"
#include "intern/bmesh_operators_private.h" /* own include */
@ -167,6 +171,16 @@ static void bm_extrude_copy_face_loop_attributes(BMesh *bm, BMFace *f, BMEdge *e
BM_elem_attrs_copy(bm, bm, l_src_1, l_dst_b);
}
/* Disable the skin root flag on the input vert, assumes that the vert
data includes an CD_MVERT_SKIN layer */
static void bm_extrude_disable_skin_root(BMesh *bm, BMVert *v)
{
MVertSkin *vs;
vs = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_MVERT_SKIN);
vs->flag &= ~MVERT_SKIN_ROOT;
}
void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
@ -184,6 +198,13 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
BMO_op_initf(bm, &dupeop, "dupe geom=%fve", EXT_INPUT);
BMO_op_exec(bm, &dupeop);
/* disable root flag on all new skin nodes */
if (CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
BMO_ITER(v1, &siter, bm, &dupeop, "newout", BM_VERT) {
bm_extrude_disable_skin_root(bm, v1);
}
}
for (e = BMO_iter_new(&siter, bm, &dupeop, "boundarymap", 0); e; e = BMO_iter_step(&siter)) {
e2 = BMO_iter_map_value(&siter);
e2 = *(BMEdge **)e2;
@ -224,9 +245,12 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMVert *v, *dupev;
BMEdge *e;
const int has_vskin = CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN);
for (v = BMO_iter_new(&siter, bm, op, "verts", BM_VERT); v; v = BMO_iter_step(&siter)) {
dupev = BM_vert_create(bm, v->co, v);
if (has_vskin)
bm_extrude_disable_skin_root(bm, v);
e = BM_edge_create(bm, v, dupev, NULL, FALSE);
@ -324,6 +348,13 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMO_slot_copy(op, &dupeop, "edgefacein", "geom");
BMO_op_exec(bm, &dupeop);
/* disable root flag on all new skin nodes */
if (CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
BMO_ITER(v, &siter, bm, &dupeop, "newout", BM_VERT) {
bm_extrude_disable_skin_root(bm, v);
}
}
if (bm->act_face && BMO_elem_flag_test(bm, bm->act_face, EXT_INPUT))
bm->act_face = BMO_slot_map_ptr_get(bm, &dupeop, "facemap", bm->act_face);

@ -289,8 +289,10 @@ void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW:
float vec[3] = {x, y, z};
copy_v3_v3(leaf.bone->tail, leaf.bone->head);
add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
}else
}
else {
leaf_bones.push_back(leaf);
}
}
void ArmatureImporter::fix_leaf_bones( )

@ -138,7 +138,6 @@ void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocke
operation->setX(val->value[0]);
operation->setY(val->value[1]);
operation->setZ(val->value[2]);
operation->setW(val->value[3]);
this->addLink(graph, operation->getOutputSocket(), inputsocket);
graph->addOperation(operation);
}

@ -29,6 +29,7 @@
#include "OCL_opencl.h"
#include "stdio.h"
#include "COM_OpenCLKernels.cl.cpp"
#include "BKE_global.h"
#if COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD
#warning COM_CURRENT_THREADING_MODEL COM_TM_NOTHREAD is activated. Use only for debugging.
@ -235,7 +236,7 @@ void WorkScheduler::initialize()
cl_int error;
error = clGetPlatformIDs(0, 0, &numberOfPlatforms);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
printf("%d number of platforms\n", numberOfPlatforms);
if (G.f & G_DEBUG) printf("%d number of platforms\n", numberOfPlatforms);
cl_platform_id *platforms = new cl_platform_id[numberOfPlatforms];
error = clGetPlatformIDs(numberOfPlatforms, platforms, 0);
unsigned int indexPlatform;
@ -280,11 +281,13 @@ void WorkScheduler::initialize()
OpenCLDevice *clDevice = new OpenCLDevice(context, device, program);
clDevice->initialize(),
gpudevices.push_back(clDevice);
char resultString[32];
error = clGetDeviceInfo(device, CL_DEVICE_NAME, 32, resultString, 0);
printf("OPENCL_DEVICE: %s, ", resultString);
error = clGetDeviceInfo(device, CL_DEVICE_VENDOR, 32, resultString, 0);
printf("%s\n", resultString);
if (G.f & G_DEBUG) {
char resultString[32];
error = clGetDeviceInfo(device, CL_DEVICE_NAME, 32, resultString, 0);
printf("OPENCL_DEVICE: %s, ", resultString);
error = clGetDeviceInfo(device, CL_DEVICE_VENDOR, 32, resultString, 0);
printf("%s\n", resultString);
}
}
delete cldevices;
delete platforms;

@ -29,6 +29,7 @@ extern "C" {
#include "COM_compositor.h"
#include "COM_ExecutionSystem.h"
#include "COM_WorkScheduler.h"
#include "OCL_opencl.h"
static ThreadMutex *compositorMutex;
void COM_execute(bNodeTree *editingtree, int rendering)
@ -36,6 +37,7 @@ void COM_execute(bNodeTree *editingtree, int rendering)
if (compositorMutex == NULL) { /// TODO: move to blender startup phase
compositorMutex = new ThreadMutex();
BLI_mutex_init(compositorMutex);
OCL_init();
WorkScheduler::initialize(); ///TODO: call workscheduler.deinitialize somewhere
}
BLI_mutex_lock(compositorMutex);

@ -47,18 +47,21 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont
addLink(graph, operation->getOutputSocket(), antiAlias->getInputSocket(0));
this->getOutputSocket(0)->relinkConnections(antiAlias->getOutputSocket(0));
graph->addOperation(antiAlias);
} else {
}
else {
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
}
graph->addOperation(operation);
} else {
}
else {
if (editorNode->custom2 > 0) {
DilateStepOperation * operation = new DilateStepOperation();
operation->setIterations(editorNode->custom2);
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0));
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
} else {
}
else {
ErodeStepOperation * operation = new ErodeStepOperation();
operation->setIterations(-editorNode->custom2);
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0));

@ -30,6 +30,7 @@ extern "C" {
#include "DNA_movieclip_types.h"
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
#include "IMB_imbuf.h"
}
MovieClipNode::MovieClipNode(bNode *editorNode): Node(editorNode)
@ -118,4 +119,8 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex
angleMovieClip->relinkConnections(operationSetValue->getOutputSocket());
graph->addOperation(operationSetValue);
}
if (ibuf) {
IMB_freeImBuf(ibuf);
}
}

@ -39,6 +39,7 @@ void MovieDistortionNode::convertToOperations(ExecutionSystem *system, Composito
MovieDistortionOperation * operation = new MovieDistortionOperation(bnode->custom1 == 1);
operation->setMovieClip(clip);
operation->setFramenumber(context->getFramenumber());
inputSocket->relinkConnections(operation->getInputSocket(0), true, 0, system);
outputSocket->relinkConnections(operation->getOutputSocket(0));

@ -37,6 +37,7 @@ void TextureNode::convertToOperations(ExecutionSystem *system, CompositorContext
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), true, 0, system);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), true, 1, system);
operation->setTexture(texture);
operation->setScene(context->getScene());
system->addOperation(operation);
addPreviewOperation(system, operation->getOutputSocket(), 9);
@ -46,6 +47,7 @@ void TextureNode::convertToOperations(ExecutionSystem *system, CompositorContext
addLink(system, operation->getInputSocket(0)->getConnection()->getFromSocket(), alphaOperation->getInputSocket(0));
addLink(system, operation->getInputSocket(1)->getConnection()->getFromSocket(), alphaOperation->getInputSocket(1));
alphaOperation->setTexture(texture);
alphaOperation->setScene(context->getScene());
system->addOperation(alphaOperation);
}
}

@ -31,7 +31,7 @@ extern "C" {
#include "RE_shader_ext.h"
#include "RE_render_ext.h"
#include "MEM_guardedalloc.h"
#include "render_types.h"
#include "render_types.h"
}
#include "PIL_time.h"
@ -55,24 +55,31 @@ void CompositorOperation::initExecution()
if (this->getWidth() * this->getHeight() != 0) {
this->outputBuffer=(float*) MEM_callocN(this->getWidth()*this->getHeight()*4*sizeof(float), "CompositorOperation");
}
const Scene * scene = this->scene;
Render *re = RE_GetRender(scene->id.name);
RenderResult *rr = RE_AcquireResultWrite(re);
if (rr) {
if (rr->rectf != NULL) {
MEM_freeN(rr->rectf);
}
rr->rectf = outputBuffer;
}
if (re) {
RE_ReleaseResult(re);
re = NULL;
}
}
void CompositorOperation::deinitExecution()
{
if (tree->test_break && !tree->test_break(tree->tbh)) {
const Scene * scene = this->scene;
Render *re = RE_GetRender(scene->id.name);
RenderResult *rr = RE_AcquireResultWrite(re);
if (rr) {
if (rr->rectf != NULL) {
MEM_freeN(rr->rectf);
}
rr->rectf = outputBuffer;
}
if (re) {
RE_ReleaseResult(re);
re = NULL;
}
BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
} else {
if (this->outputBuffer) {
MEM_freeN(this->outputBuffer);
}
}
this->outputBuffer = NULL;
this->imageInput = NULL;
this->alphaInput = NULL;

@ -60,7 +60,7 @@ public:
void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers);
void setScene(const Scene *scene) {this->scene = scene;}
void setbNodeTree(const bNodeTree *tree) {this->tree = tree;}
bool isOutputOperation(bool rendering) const {return rendering;}
bool isOutputOperation(bool rendering) const {return true;}
void initExecution();
void deinitExecution();
const int getRenderPriority() const {return 7;}

@ -241,7 +241,8 @@ bool DilateStepOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff
{
if (this->cached_buffer) {
return false;
} else {
}
else {
rcti newInput;
newInput.xmax = getWidth();

@ -74,7 +74,8 @@ bool GlareBaseOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe
{
if (this->cachedInstance != NULL) {
return false;
} else {
}
else {
rcti newInput;
newInput.xmax = this->getWidth();
newInput.xmin = 0;

@ -61,21 +61,27 @@ void MovieClipOperation::initExecution()
void MovieClipOperation::deinitExecution()
{
this->movieClipBuffer = NULL;
if (this->movieClipBuffer) {
IMB_freeImBuf(this->movieClipBuffer);
this->movieClipBuffer = NULL;
}
}
void MovieClipOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[])
{
ImBuf *ibuf;
resolution[0] = 0;
resolution[1] = 0;
resolution[0] = 0;
resolution[1] = 0;
if (this->movieClip) {
ibuf = BKE_movieclip_get_ibuf(this->movieClip, this->movieClipUser);
if (ibuf) {
resolution[0] = ibuf->x;
resolution[1] = ibuf->y;
IMB_freeImBuf(ibuf);
}
}
}

@ -24,8 +24,8 @@
extern "C" {
#include "BKE_tracking.h"
#include "BLI_linklist.h"
#include "BKE_movieclip.h"
#include "BLI_linklist.h"
}
@ -46,14 +46,23 @@ void MovieDistortionOperation::initExecution()
{
this->inputOperation = this->getInputSocketReader(0);
if (this->movieClip) {
MovieClipUser clipUser = {0};
int calibration_width, calibration_height;
BKE_movieclip_user_set_frame(&clipUser, this->framenumber);
BKE_movieclip_get_size(this->movieClip, &clipUser, &calibration_width, &calibration_height);
for (int i = 0 ; i < s_cache.size() ; i ++) {
DistortionCache *c = (DistortionCache*)s_cache[i];
if (c->isCacheFor(this->movieClip, this->width, this->height, this->distortion)) {
if (c->isCacheFor(this->movieClip, this->width, this->height,
calibration_width, calibration_height, this->distortion))
{
this->cache = c;
return;
}
}
DistortionCache *newC = new DistortionCache(this->movieClip, this->width, this->height, this->distortion);
DistortionCache *newC = new DistortionCache(this->movieClip, this->width, this->height,
calibration_width, calibration_height, this->distortion);
s_cache.push_back(newC);
this->cache = newC;
}

@ -34,18 +34,28 @@ private:
float k1;
float k2;
float k3;
float principal_x;
float principal_y;
float pixel_aspect;
int width;
int height;
int calibration_width;
int calibration_height;
bool inverted;
float *buffer;
int *bufferCalculated;
public:
DistortionCache(MovieClip *movieclip, int width, int height, bool inverted) {
DistortionCache(MovieClip *movieclip, int width, int height, int calibration_width, int calibration_height, bool inverted) {
this->k1 = movieclip->tracking.camera.k1;
this->k2 = movieclip->tracking.camera.k2;
this->k3 = movieclip->tracking.camera.k3;
this->principal_x = movieclip->tracking.camera.principal[0];
this->principal_y = movieclip->tracking.camera.principal[1];
this->pixel_aspect = movieclip->tracking.camera.pixel_aspect;
this->width = width;
this->height = height;
this->calibration_width = calibration_width;
this->calibration_height = calibration_height;
this->inverted = inverted;
this->bufferCalculated = new int[this->width*this->height];
this->buffer = new float[this->width*this->height*2];
@ -53,13 +63,18 @@ public:
this->bufferCalculated[i] = 0;
}
}
bool isCacheFor(MovieClip *movieclip, int width, int height, bool inverted) {
bool isCacheFor(MovieClip *movieclip, int width, int height, int calibration_width, int claibration_height, bool inverted) {
return this->k1 == movieclip->tracking.camera.k1 &&
this->k2 == movieclip->tracking.camera.k2 &&
this->k3 == movieclip->tracking.camera.k3 &&
this->principal_x == movieclip->tracking.camera.principal[0] &&
this->principal_y == movieclip->tracking.camera.principal[1] &&
this->pixel_aspect == movieclip->tracking.camera.pixel_aspect &&
this->inverted == inverted &&
this->width == width &&
this->height == height;
this->width == width &&
this->height == height &&
this->calibration_width == calibration_width &&
this->calibration_height == calibration_height;
}
void getUV(MovieTracking *trackingData, int x, int y, float *u, float*v) {
@ -67,20 +82,30 @@ public:
*u = x;
*v = y;
} else {
int offset = y * this->width + x;
int offset2 = offset*2;
if (!bufferCalculated[offset]) {
//float overscan = 0.0f;
float w = (float)this->width/* / (1 + overscan) */;
float h = (float)this->height/* / (1 + overscan) */;
float aspx = (float)w / this->calibration_width;
float aspy = (float)h / this->calibration_height;
float in[2];
float out[2];
in[0] = x;
in[1] = y;
in[0] = (x /* - 0.5 * overscan * w */) / aspx;
in[1] = (y /* - 0.5 * overscan * h */) / aspy / this->pixel_aspect;
if (inverted) {
BKE_tracking_invert_intrinsics(trackingData, in, out);
} else {
BKE_tracking_apply_intrinsics(trackingData, in, out);
}
buffer[offset2] = out[0];
buffer[offset2+1] = out[1];
buffer[offset2] = out[0] * aspx /* + 0.5 * overscan * w */;
buffer[offset2+1] = (out[1] * aspy /* + 0.5 * overscan * h */) * this->pixel_aspect;
bufferCalculated[offset] = 1;
}
*u = buffer[offset2];
@ -97,6 +122,7 @@ private:
protected:
bool distortion;
int framenumber;
public:
MovieDistortionOperation(bool distortion);
@ -107,7 +133,7 @@ public:
void deinitExecution();
void setMovieClip(MovieClip *clip) {this->movieClip = clip;}
void setFramenumber(int framenumber) {this->framenumber = framenumber;}
};
#endif

@ -32,6 +32,7 @@ TextureBaseOperation::TextureBaseOperation(): NodeOperation()
this->texture = NULL;
this->inputSize = NULL;
this->inputOffset = NULL;
this->scene = NULL;
}
TextureOperation::TextureOperation() : TextureBaseOperation()
{
@ -56,8 +57,10 @@ void TextureBaseOperation::deinitExecution()
void TextureBaseOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[])
{
if (preferredResolution[0] == 0 || preferredResolution[1] == 0) {
resolution[0] = COM_DEFAULT_RESOLUTION_WIDTH;
resolution[1] = COM_DEFAULT_RESOLUTION_HEIGHT;
int width = this->scene->r.xsch*this->scene->r.size/100;
int height = this->scene->r.ysch*this->scene->r.size/100;
resolution[0] = width;
resolution[1] = height;
}
else {
resolution[0] = preferredResolution[0];

@ -43,6 +43,7 @@ extern "C" {
class TextureBaseOperation : public NodeOperation {
private:
Tex *texture;
const Scene *scene;
SocketReader *inputSize;
SocketReader *inputOffset;
@ -64,6 +65,7 @@ public:
void setTexture(Tex *texture) {this->texture = texture;}
void initExecution();
void deinitExecution();
void setScene(const Scene *scene) {this->scene = scene;}
};
class TextureOperation:public TextureBaseOperation {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -49,6 +49,7 @@ void ED_init_node_butfuncs(void);
void ED_node_tree_update(struct SpaceNode *snode, struct Scene *scene);
void ED_node_changed_update(struct ID *id, struct bNode *node);
void ED_node_generic_update(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node);
void ED_node_sort(struct bNodeTree *ntree);
/* node_edit.c */
void ED_node_shader_default(struct Scene *scene, struct ID *id);
@ -57,7 +58,7 @@ void ED_node_texture_default(struct Tex *tex);
void ED_node_link_intersect_test(struct ScrArea *sa, int test);
void ED_node_link_insert(struct ScrArea *sa);
void ED_node_update_hierarchy(struct bContext *C, struct bNodeTree *ntree);
void ED_node_post_apply_transform(struct bContext *C, struct bNodeTree *ntree);
void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node);
/* node ops.c */

@ -58,6 +58,7 @@ enum {
TFM_TRANSLATION,
TFM_ROTATION,
TFM_RESIZE,
TFM_SKIN_RESIZE,
TFM_TOSPHERE,
TFM_SHEAR,
TFM_WARP,

@ -592,8 +592,8 @@ DEF_ICON(MOD_DYNAMICPAINT)
DEF_ICON(MOD_REMESH)
DEF_ICON(MOD_OCEAN)
DEF_ICON(MOD_WARP)
DEF_ICON(MOD_SKIN)
#ifndef DEF_ICON_BLANK_SKIP
DEF_ICON(BLANK165)
DEF_ICON(BLANK166)
DEF_ICON(BLANK167)
DEF_ICON(BLANK168)

@ -198,7 +198,9 @@ enum {
TH_STITCH_PREVIEW_ACTIVE,
TH_MATCH, /* highlight color for search matches */
TH_SELECT_HIGHLIGHT /* highlight color for selected outliner item */
TH_SELECT_HIGHLIGHT, /* highlight color for selected outliner item */
TH_SKIN_ROOT
};
/* XXX WARNING: previous is saved in file, so do not change order! */
@ -232,9 +234,10 @@ float UI_GetThemeValuef(int colorid);
int UI_GetThemeValue(int colorid);
// get three color values, scaled to 0.0-1.0 range
void UI_GetThemeColor3fv(int colorid, float *col);
void UI_GetThemeColor3fv(int colorid, float col[3]);
// get the color, range 0.0-1.0, complete with shading offset
void UI_GetThemeColorShade3fv(int colorid, int offset, float *col);
void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3]);
void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3]);
// get the 3 or 4 byte values
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3]);

@ -442,7 +442,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
if (ELEM(but->type, ROW, MENU)) {
EnumPropertyItem *item;
int i, totitem, free;
int value = (but->type == ROW) ? but->hardmax : ui_get_but_val(but);
int value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but);
RNA_property_enum_items_gettexted(C, &but->rnapoin, but->rnaprop, &item, &totitem, &free);

@ -2154,11 +2154,11 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
manode = give_node_material(ma);
if (manode) {
char str[MAX_ID_NAME + 12];
BLI_snprintf(str, sizeof(str), "Node %s", manode->id.name + 2);
BLI_snprintf(str, sizeof(str), IFACE_("Node %s"), manode->id.name + 2);
uiItemL(sub, str, ui_id_icon_get(C, &manode->id, 1));
}
else if (ma->use_nodes) {
uiItemL(sub, "Node <none>", ICON_NONE);
uiItemL(sub, IFACE_("Node <none>"), ICON_NONE);
}
}
}
@ -2192,7 +2192,9 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "lock_weight", 0, 0, 0, 0, 0, NULL);
#else
uiBlockSetEmboss(block, UI_EMBOSSN);
uiDefIconButBitC(block, TOG, DG_LOCK_WEIGHT, 0, (dg->flag & DG_LOCK_WEIGHT) ? ICON_LOCKED : ICON_UNLOCKED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &dg->flag, 0, 0, 0, 0, "Maintain relative weights while painting");
uiDefIconButBitC(block, TOG, DG_LOCK_WEIGHT, 0, (dg->flag & DG_LOCK_WEIGHT) ? ICON_LOCKED : ICON_UNLOCKED,
0, 0, UI_UNIT_X, UI_UNIT_Y, &dg->flag, 0, 0, 0, 0,
TIP_("Maintain relative weights while painting"));
uiBlockSetEmboss(block, UI_EMBOSS);
#endif
}

@ -161,10 +161,12 @@ static unsigned int scroll_circle_face[14][3] = {
{6, 13, 12}, {6, 12, 7}, {7, 12, 11}, {7, 11, 8}, {8, 11, 10}, {8, 10, 9}
};
static float menu_tria_vert[6][2] = {
{-0.41, 0.16}, {0.41, 0.16}, {0, 0.82},
{0, -0.82}, {-0.41, -0.16}, {0.41, -0.16}
};
static float menu_tria_vert[6][2]= {
{-0.33, 0.16}, {0.33, 0.16}, {0, 0.82},
{0, -0.82}, {-0.33, -0.16}, {0.33, -0.16}};
static unsigned int menu_tria_face[2][3] = {{2, 0, 1}, {3, 5, 4}};
@ -1163,11 +1165,13 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
if (fstyle->kerning == 1)
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
// ui_rasterpos_safe(x, y, but->aspect);
// if (but->type==IDPOIN) transopts= 0; // no translation, of course!
// else transopts= ui_translate_buttons();
#if 0
ui_rasterpos_safe(x, y, but->aspect);
if (but->type == IDPOIN) transopts = 0; // no translation, of course!
else transopts = ui_translate_buttons();
#endif
/* cut string in 2 parts - only for menu entries */
if ((but->block->flag & UI_BLOCK_LOOP)) {
if (ELEM5(but->type, SLI, NUM, TEX, NUMSLI, NUMABS) == 0) {
@ -3126,10 +3130,18 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
case MENU:
case BLOCK:
case ICONTEXTROW:
/* new node-link button, not active yet XXX */
if (but->flag & UI_BUT_NODE_LINK)
wt = widget_type(UI_WTYPE_MENU_NODE_LINK);
else if (!but->str[0] && but->icon)
wt = widget_type(UI_WTYPE_MENU_ICON_RADIO);
/* no text, with icon */
else if (!but->str[0] && but->icon) {
if (but->flag & UI_ICON_PREVIEW)
wt = widget_type(UI_WTYPE_MENU_ICON_RADIO); /* no arrows */
else
wt = widget_type(UI_WTYPE_MENU_RADIO); /* with arrows */
}
/* with menu arrows */
else
wt = widget_type(UI_WTYPE_MENU_RADIO);
break;

@ -469,6 +469,10 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_SELECT_HIGHLIGHT:
cp = ts->selected_highlight;
break;
case TH_SKIN_ROOT:
cp = ts->skin_root;
break;
}
}
}
@ -702,6 +706,8 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.bundle_solid, 200, 200, 200, 255);
rgba_char_args_set(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255);
rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255);
/* space buttons */
/* to have something initialized */
@ -837,7 +843,7 @@ void ui_theme_init_default(void)
/* space node, re-uses syntax color storage */
btheme->tnode = btheme->tv3d;
rgba_char_args_set(btheme->tnode.edge_select, 255, 255, 255, 255);
rgba_char_args_set(btheme->tnode.edge_select, 255, 255, 255, 255); /* wire selected */
rgba_char_args_set(btheme->tnode.syntaxl, 155, 155, 155, 160); /* TH_NODE, backdrop */
rgba_char_args_set(btheme->tnode.syntaxn, 100, 100, 100, 255); /* in/output */
rgba_char_args_set(btheme->tnode.syntaxb, 108, 105, 111, 255); /* operator */
@ -1028,7 +1034,7 @@ int UI_GetThemeValue(int colorid)
// get the color, range 0.0-1.0
void UI_GetThemeColor3fv(int colorid, float *col)
void UI_GetThemeColor3fv(int colorid, float col[3])
{
const unsigned char *cp;
@ -1039,7 +1045,7 @@ void UI_GetThemeColor3fv(int colorid, float *col)
}
// get the color, range 0.0-1.0, complete with shading offset
void UI_GetThemeColorShade3fv(int colorid, int offset, float *col)
void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3])
{
int r, g, b;
const unsigned char *cp;
@ -1058,6 +1064,25 @@ void UI_GetThemeColorShade3fv(int colorid, int offset, float *col)
col[2] = ((float)b) / 255.0f;
}
void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3])
{
int r, g, b;
const unsigned char *cp;
cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
r = offset + (int) cp[0];
CLAMP(r, 0, 255);
g = offset + (int) cp[1];
CLAMP(g, 0, 255);
b = offset + (int) cp[2];
CLAMP(b, 0, 255);
col[0] = r;
col[1] = g;
col[2] = b;
}
// get the color, in char pointer
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
{
@ -1789,6 +1814,12 @@ void init_userdef_do_versions(void)
}
}
if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 6)) {
bTheme *btheme;
for (btheme = U.themes.first; btheme; btheme = btheme->next)
rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255);
}
/* GL Texture Garbage Collection (variable abused above!) */
if (U.textimeout == 0) {
U.texcollectrate = 60;

@ -4541,7 +4541,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
mdiff[1] = opdata->mcenter[1] - event->mval[1];
factor = len_v2(mdiff) / opdata->initial_length;
factor = MAX2(1.0 - factor, 0.0);
factor = MAX2(1.0f - factor, 0.0f);
RNA_float_set(op->ptr, "percent", factor);
@ -4837,7 +4837,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
else {
amount = opdata->old_thickness - (len_v2(mdiff)
- opdata->initial_length) / opdata->initial_length;
amount = MAX2(amount, 0.0);
amount = MAX2(amount, 0.0f);
RNA_float_set(op->ptr, "thickness", amount);
}

@ -309,44 +309,44 @@ int ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me)
int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_set)
{
BMEditMesh *em;
int layernum;
int layernum_dst;
short is_init = FALSE;
if (me->edit_btmesh) {
em = me->edit_btmesh;
layernum = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
if (layernum >= MAX_MTFACE)
layernum_dst = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
if (layernum_dst >= MAX_MTFACE)
return -1;
/* CD_MTEXPOLY */
BM_data_layer_add_named(em->bm, &em->bm->pdata, CD_MTEXPOLY, name);
/* copy data from active UV */
if (layernum) {
const int layernum_dst = CustomData_get_active_layer(&em->bm->pdata, CD_MTEXPOLY);
BM_data_layer_copy(em->bm, &em->bm->pdata, CD_MTEXPOLY, layernum, layernum_dst);
if (layernum_dst) {
const int layernum_src = CustomData_get_active_layer(&em->bm->pdata, CD_MTEXPOLY);
BM_data_layer_copy(em->bm, &em->bm->pdata, CD_MTEXPOLY, layernum_src, layernum_dst);
}
if (active_set || layernum == 0) {
CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum);
if (active_set || layernum_dst == 0) {
CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum_dst);
}
/* CD_MLOOPUV */
BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPUV, name);
/* copy data from active UV */
if (layernum) {
const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV);
BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst);
if (layernum_dst) {
const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV);
BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum_src, layernum_dst);
is_init = TRUE;
}
if (active_set || layernum == 0) {
CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum);
if (active_set || layernum_dst == 0) {
CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum_dst);
}
}
else {
layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
if (layernum >= MAX_MTFACE)
layernum_dst = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
if (layernum_dst >= MAX_MTFACE)
return -1;
if (me->mtpoly) {
@ -361,11 +361,11 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name);
}
if (active_set || layernum == 0) {
CustomData_set_layer_active(&me->pdata, CD_MTEXPOLY, layernum);
CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum);
if (active_set || layernum_dst == 0) {
CustomData_set_layer_active(&me->pdata, CD_MTEXPOLY, layernum_dst);
CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst);
CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum_dst);
}
mesh_update_customdata_pointers(me, TRUE);
@ -373,13 +373,13 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
/* don't overwrite our copied coords */
if (is_init == FALSE) {
ED_mesh_uv_loop_reset_ex(C, me, layernum);
ED_mesh_uv_loop_reset_ex(C, me, layernum_dst);
}
DAG_id_tag_update(&me->id, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
return layernum;
return layernum_dst;
}
int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)

@ -534,7 +534,7 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *orig
int grid_index = origindex[face_index];
int loc_offs = face_index % (1 << (2 * lvl));
int cell_index = loc_offs % ((side - 1) * (side - 1));
int cell_side = grid_size / (side - 1);
int cell_side = (grid_size - 1) / (side - 1);
int row = cell_index / (side - 1);
int col = cell_index % (side - 1);

@ -160,6 +160,10 @@ void OBJECT_OT_multires_external_pack(struct wmOperatorType *ot);
void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_explode_refresh(struct wmOperatorType *ot);
void OBJECT_OT_ocean_bake(struct wmOperatorType *ot);
void OBJECT_OT_skin_root_mark(struct wmOperatorType *ot);
void OBJECT_OT_skin_loose_mark_clear(struct wmOperatorType *ot);
void OBJECT_OT_skin_radii_equalize(struct wmOperatorType *ot);
void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot);
/* object_constraint.c */
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);

@ -35,6 +35,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
@ -42,6 +43,7 @@
#include "DNA_object_force.h"
#include "DNA_scene_types.h"
#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@ -85,6 +87,8 @@
#include "object_intern.h"
static void modifier_skin_customdata_ensure(struct Object *ob);
/******************************** API ****************************/
ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
@ -157,6 +161,10 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
/* ensure that grid paint mask layer is created */
ED_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
}
else if (type == eModifierType_Skin) {
/* ensure skin-node customdata exists */
modifier_skin_customdata_ensure(ob);
}
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@ -1131,7 +1139,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
CTX_DATA_BEGIN (C, Object *, selob, selected_editable_objects)
CTX_DATA_BEGIN(C, Object *, selob, selected_editable_objects)
{
if (selob->type == OB_MESH && selob != ob) {
secondob = selob;
@ -1327,6 +1335,409 @@ void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
}
/************************** skin modifier ***********************/
static void modifier_skin_customdata_ensure(Object *ob)
{
Mesh *me = ob->data;
BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
MVertSkin *vs;
if (bm && !CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
BMVert *v;
BMIter iter;
BM_data_layer_add(bm, &bm->vdata, CD_MVERT_SKIN);
/* Mark an arbitrary vertex as root */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
vs = CustomData_bmesh_get(&bm->vdata, v->head.data,
CD_MVERT_SKIN);
vs->flag |= MVERT_SKIN_ROOT;
break;
}
}
else if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) {
vs = CustomData_add_layer(&me->vdata,
CD_MVERT_SKIN,
CD_DEFAULT,
NULL,
me->totvert);
/* Mark an arbitrary vertex as root */
vs->flag |= MVERT_SKIN_ROOT;
}
}
static int skin_poll(bContext *C)
{
return (!CTX_data_edit_object(C) &&
edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
}
static int skin_edit_poll(bContext *C)
{
return (CTX_data_edit_object(C) &&
edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
}
static void skin_root_clear(BMesh *bm, BMVert *bm_vert, GHash *visited)
{
BMEdge *bm_edge;
BMIter bm_iter;
BM_ITER_ELEM (bm_edge, &bm_iter, bm_vert, BM_EDGES_OF_VERT) {
BMVert *v2 = BM_edge_other_vert(bm_edge, bm_vert);
if (!BLI_ghash_lookup(visited, v2)) {
MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
v2->head.data,
CD_MVERT_SKIN);
/* clear vertex root flag and add to visited set */
vs->flag &= ~MVERT_SKIN_ROOT;
BLI_ghash_insert(visited, v2, v2);
skin_root_clear(bm, v2, visited);
}
}
}
static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = CTX_data_edit_object(C);
Mesh *me = ob->data;
BMesh *bm = me->edit_btmesh->bm;
BMVert *bm_vert;
BMIter bm_iter;
GHash *visited;
visited = BLI_ghash_ptr_new("skin_root_mark_exec visited");
modifier_skin_customdata_ensure(ob);
BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
if (!BLI_ghash_lookup(visited, bm_vert) &&
bm_vert->head.hflag & BM_ELEM_SELECT)
{
MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
bm_vert->head.data,
CD_MVERT_SKIN);
/* mark vertex as root and add to visited set */
vs->flag |= MVERT_SKIN_ROOT;
BLI_ghash_insert(visited, bm_vert, bm_vert);
/* clear root flag from all connected vertices (recursively) */
skin_root_clear(bm, bm_vert, visited);
}
}
BLI_ghash_free(visited, NULL, NULL);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_skin_root_mark(wmOperatorType *ot)
{
ot->name = "Skin Root Mark";
ot->description = "Mark selected vertices as roots";
ot->idname = "OBJECT_OT_skin_root_mark";
ot->poll = skin_edit_poll;
ot->exec = skin_root_mark_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
typedef enum {
SKIN_LOOSE_MARK,
SKIN_LOOSE_CLEAR
} SkinLooseAction;
static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
Mesh *me = ob->data;
BMesh *bm = me->edit_btmesh->bm;
BMVert *bm_vert;
BMIter bm_iter;
SkinLooseAction action = RNA_enum_get(op->ptr, "action");
BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
if (bm_vert->head.hflag & BM_ELEM_SELECT) {
MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
bm_vert->head.data,
CD_MVERT_SKIN);
switch (action) {
case SKIN_LOOSE_MARK:
vs->flag |= MVERT_SKIN_LOOSE;
break;
case SKIN_LOOSE_CLEAR:
vs->flag &= ~MVERT_SKIN_LOOSE;
break;
}
}
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot)
{
static EnumPropertyItem action_items[] = {
{SKIN_LOOSE_MARK, "MARK", 0, "Mark", "Mark selected vertices as loose"},
{SKIN_LOOSE_CLEAR, "CLEAR", 0, "Clear", "Set selected vertices as not loose"},
{0, NULL, 0, NULL, NULL}
};
ot->name = "Skin Mark/Clear Loose";
ot->description = "Mark/clear selected vertices as loose";
ot->idname = "OBJECT_OT_skin_loose_mark_clear";
ot->poll = skin_edit_poll;
ot->exec = skin_loose_mark_clear_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_enum(ot->srna, "action", action_items, SKIN_LOOSE_MARK, "Action", NULL);
}
static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = CTX_data_edit_object(C);
Mesh *me = ob->data;
BMesh *bm = me->edit_btmesh->bm;
BMVert *bm_vert;
BMIter bm_iter;
BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
if (bm_vert->head.hflag & BM_ELEM_SELECT) {
MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
bm_vert->head.data,
CD_MVERT_SKIN);
float avg = (vs->radius[0] + vs->radius[1]) * 0.5f;
vs->radius[0] = vs->radius[1] = avg;
}
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
{
ot->name = "Skin Radii Equalize";
ot->description = "Make skin radii of selected vertices equal";
ot->idname = "OBJECT_OT_skin_radii_equalize";
ot->poll = skin_edit_poll;
ot->exec = skin_radii_equalize_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static void skin_armature_bone_create(Object *skin_ob,
MVert *mvert, MEdge *medge,
bArmature *arm,
BLI_bitmap edges_visited,
const MeshElemMap *emap,
EditBone *parent_bone,
int parent_v)
{
int i;
for (i = 0; i < emap[parent_v].count; i++) {
int endx = emap[parent_v].indices[i];
const MEdge *e = &medge[endx];
EditBone *bone;
bDeformGroup *dg;
int v;
/* ignore edge if already visited */
if (BLI_BITMAP_GET(edges_visited, endx))
continue;
BLI_BITMAP_SET(edges_visited, endx);
v = (e->v1 == parent_v ? e->v2 : e->v1);
bone = MEM_callocN(sizeof(EditBone),
"skin_armature_bone_create EditBone");
bone->parent = parent_bone;
bone->layer = 1;
bone->flag |= BONE_CONNECTED;
copy_v3_v3(bone->head, mvert[parent_v].co);
copy_v3_v3(bone->tail, mvert[v].co);
bone->rad_head = bone->rad_tail = 0.25;
BLI_snprintf(bone->name, sizeof(bone->name), "Bone.%.2d", endx);
BLI_addtail(arm->edbo, bone);
/* add bDeformGroup */
if ((dg = ED_vgroup_add_name(skin_ob, bone->name))) {
ED_vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE);
ED_vgroup_vert_add(skin_ob, dg, v, 1, WEIGHT_REPLACE);
}
skin_armature_bone_create(skin_ob,
mvert, medge,
arm,
edges_visited,
emap,
bone,
v);
}
}
static Object *modifier_skin_armature_create(struct Scene *scene,
Object *skin_ob)
{
BLI_bitmap edges_visited;
DerivedMesh *deform_dm;
MVert *mvert;
Mesh *me = skin_ob->data;
Object *arm_ob;
bArmature *arm;
MVertSkin *mvert_skin;
MeshElemMap *emap;
int *emap_mem;
int v;
deform_dm = mesh_get_derived_deform(scene, skin_ob, CD_MASK_BAREMESH);
mvert = deform_dm->getVertArray(deform_dm);
/* add vertex weights to original mesh */
CustomData_add_layer(&me->vdata,
CD_MDEFORMVERT,
CD_CALLOC,
NULL,
me->totvert);
arm_ob = BKE_object_add(scene, OB_ARMATURE);
BKE_object_transform_copy(arm_ob, skin_ob);
arm = arm_ob->data;
arm->layer = 1;
arm_ob->dtx |= OB_DRAWXRAY;
arm->drawtype = ARM_LINE;
arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature");
mvert_skin = CustomData_get_layer(&me->vdata, CD_MVERT_SKIN);
create_vert_edge_map(&emap, &emap_mem,
me->medge, me->totvert, me->totedge);
edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited");
/* note: we use EditBones here, easier to set them up and use
* edit-armature functions to convert back to regular bones */
for (v = 0; v < me->totvert; v++) {
if (mvert_skin[v].flag & MVERT_SKIN_ROOT) {
EditBone *bone = NULL;
/* Unless the skin root has just one adjacent edge, create
* a fake root bone (have it going off in the Y direction
* (arbitrary) */
if (emap[v].count > 1) {
bone = MEM_callocN(sizeof(EditBone), "EditBone");
copy_v3_v3(bone->head, me->mvert[v].co);
copy_v3_v3(bone->tail, me->mvert[v].co);
bone->layer = 1;
bone->head[1] = 1.0f;
bone->rad_head = bone->rad_tail = 0.25;
BLI_addtail(arm->edbo, bone);
}
if (emap[v].count >= 1) {
skin_armature_bone_create(skin_ob,
mvert, me->medge,
arm,
edges_visited,
emap,
bone,
v);
}
}
}
MEM_freeN(edges_visited);
MEM_freeN(emap);
MEM_freeN(emap_mem);
ED_armature_from_edit(arm_ob);
ED_armature_edit_free(arm_ob);
return arm_ob;
}
static int skin_armature_create_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C), *arm_ob;
ModifierData *skin_md;
ArmatureModifierData *arm_md;
/* create new armature */
arm_ob = modifier_skin_armature_create(scene, ob);
/* add a modifier to connect the new armature to the mesh */
arm_md = (ArmatureModifierData *)modifier_new(eModifierType_Armature);
if (arm_md) {
skin_md = edit_modifier_property_get(op, ob, eModifierType_Skin);
BLI_insertlinkafter(&ob->modifiers, skin_md, arm_md);
arm_md->object = arm_ob;
arm_md->deformflag = ARM_DEF_VGROUP | ARM_DEF_QUATERNION;
DAG_scene_sort(bmain, scene);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
static int skin_armature_create_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return skin_armature_create_exec(C, op);
else
return OPERATOR_CANCELLED;
}
void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
{
ot->name = "Skin Armature Create";
ot->description = "Create an armature that parallels the skin layout";
ot->idname = "OBJECT_OT_skin_armature_create";
ot->poll = skin_poll;
ot->invoke = skin_armature_create_invoke;
ot->exec = skin_armature_create_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
edit_modifier_properties(ot);
}
/************************ mdef bind operator *********************/
static int meshdeform_poll(bContext *C)
@ -1516,7 +1927,7 @@ static void oceanbake_free(void *customdata)
/* called by oceanbake, only to check job 'stop' value */
static int oceanbake_breakjob(void *UNUSED(customdata))
{
//OceanBakeJob *ob= (OceanBakeJob *)customdata;
//OceanBakeJob *ob = (OceanBakeJob *)customdata;
//return *(ob->stop);
/* this is not nice yet, need to make the jobs list template better

@ -139,6 +139,11 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_multires_base_apply);
WM_operatortype_append(OBJECT_OT_multires_external_save);
WM_operatortype_append(OBJECT_OT_multires_external_pack);
WM_operatortype_append(OBJECT_OT_skin_root_mark);
WM_operatortype_append(OBJECT_OT_skin_loose_mark_clear);
WM_operatortype_append(OBJECT_OT_skin_radii_equalize);
WM_operatortype_append(OBJECT_OT_skin_armature_create);
WM_operatortype_append(OBJECT_OT_meshdeform_bind);
WM_operatortype_append(OBJECT_OT_explode_refresh);
WM_operatortype_append(OBJECT_OT_ocean_bake);

@ -944,7 +944,7 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
}
/* screen sets cursor based on swinid */
static void region_cursor_set(wmWindow *win, int swinid)
static void region_cursor_set(wmWindow *win, int swinid, int swin_changed)
{
ScrArea *sa = win->screen->areabase.first;
@ -952,10 +952,12 @@ static void region_cursor_set(wmWindow *win, int swinid)
ARegion *ar = sa->regionbase.first;
for (; ar; ar = ar->next) {
if (ar->swinid == swinid) {
if (ar->type && ar->type->cursor)
ar->type->cursor(win, sa, ar);
else
WM_cursor_set(win, CURSOR_STD);
if (swin_changed || (ar->type && ar->type->event_cursor)) {
if (ar->type && ar->type->cursor)
ar->type->cursor(win, sa, ar);
else
WM_cursor_set(win, CURSOR_STD);
}
return;
}
}
@ -983,7 +985,7 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note)
break;
case NC_SCENE:
if (note->data == ND_MODE)
region_cursor_set(win, note->swinid);
region_cursor_set(win, note->swinid, TRUE);
break;
}
}
@ -1239,9 +1241,7 @@ static void screen_cursor_set(wmWindow *win, wmEvent *event)
else
WM_cursor_set(win, CURSOR_X_MOVE);
}
else
WM_cursor_set(win, CURSOR_STD);
}
}
}
@ -1294,9 +1294,13 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
if (scr->subwinactive == scr->mainwin) {
screen_cursor_set(win, event);
}
else if (oldswin != scr->subwinactive) {
region_cursor_set(win, scr->subwinactive);
WM_event_add_notifier(C, NC_SCREEN | ND_SUBWINACTIVE, scr);
else {
if (oldswin != scr->subwinactive) {
region_cursor_set(win, scr->subwinactive, TRUE);
WM_event_add_notifier(C, NC_SCREEN | ND_SUBWINACTIVE, scr);
}
else
region_cursor_set(win, scr->subwinactive, FALSE);
}
}
}

@ -52,7 +52,7 @@ struct wmOperatorType;
/* paint_stroke.c */
typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], float mouse[2]);
typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, const float mouse[2]);
typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke, struct PointerRNA *itemptr);
typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke);

@ -64,7 +64,7 @@ static void mask_flood_fill_set_elem(float *elem,
PaintMaskFloodMode mode,
float value)
{
switch(mode) {
switch (mode) {
case PAINT_MASK_FLOOD_VALUE:
(*elem) = value;
break;
@ -96,7 +96,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
sculpt_undo_push_begin("Mask flood fill");
for(i = 0; i < totnode; i++) {
for (i = 0; i < totnode; i++) {
PBVHVertexIter vi;
sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
@ -106,13 +106,13 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
} BLI_pbvh_vertex_iter_end;
BLI_pbvh_node_mark_update(nodes[i]);
if(BLI_pbvh_type(pbvh) == PBVH_GRIDS)
if (BLI_pbvh_type(pbvh) == PBVH_GRIDS)
multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
}
sculpt_undo_push_end();
if(nodes)
if (nodes)
MEM_freeN(nodes);
ED_region_tag_redraw(ar);

@ -60,6 +60,12 @@
#include <float.h>
#include <math.h>
typedef struct PaintSample {
float mouse[2];
/* TODO: other input properties, e.g. tablet pressure */
} PaintSample;
typedef struct PaintStroke {
void *mode_data;
void *smooth_stroke_cursor;
@ -70,6 +76,12 @@ typedef struct PaintStroke {
bglMats mats;
Brush *brush;
/* Paint stroke can use up to PAINT_MAX_INPUT_SAMPLES prior inputs
* to smooth the stroke */
PaintSample samples[PAINT_MAX_INPUT_SAMPLES];
int num_samples;
int cur_sample;
float last_mouse_position[2];
/* Set whether any stroke step has yet occurred
@ -182,10 +194,11 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
}
/* Returns zero if no sculpt changes should be made, non-zero otherwise */
static int paint_smooth_stroke(PaintStroke *stroke, float output[2], wmEvent *event)
static int paint_smooth_stroke(PaintStroke *stroke, float output[2],
const PaintSample *sample)
{
output[0] = event->x;
output[1] = event->y;
output[0] = sample->mouse[0];
output[1] = sample->mouse[1];
if ((stroke->brush->flag & BRUSH_SMOOTH_STROKE) &&
!ELEM4(stroke->brush->sculpt_tool,
@ -197,15 +210,16 @@ static int paint_smooth_stroke(PaintStroke *stroke, float output[2], wmEvent *ev
!(stroke->brush->flag & BRUSH_RESTORE_MESH))
{
float u = stroke->brush->smooth_stroke_factor, v = 1.0f - u;
float dx = stroke->last_mouse_position[0] - event->x, dy = stroke->last_mouse_position[1] - event->y;
float dx = stroke->last_mouse_position[0] - sample->mouse[0];
float dy = stroke->last_mouse_position[1] - sample->mouse[1];
/* If the mouse is moving within the radius of the last move,
* don't update the mouse position. This allows sharp turns. */
if (dx * dx + dy * dy < stroke->brush->smooth_stroke_radius * stroke->brush->smooth_stroke_radius)
return 0;
output[0] = event->x * v + stroke->last_mouse_position[0] * u;
output[1] = event->y * v + stroke->last_mouse_position[1] * u;
output[0] = sample->mouse[0] * v + stroke->last_mouse_position[0] * u;
output[1] = sample->mouse[1] * v + stroke->last_mouse_position[1] * u;
}
return 1;
@ -343,12 +357,52 @@ struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf)
return keymap;
}
static void paint_stroke_add_sample(const Paint *paint,
PaintStroke *stroke,
float x, float y)
{
PaintSample *sample = &stroke->samples[stroke->cur_sample];
int max_samples = MIN2(PAINT_MAX_INPUT_SAMPLES,
MAX2(paint->num_input_samples, 1));
sample->mouse[0] = x;
sample->mouse[1] = y;
stroke->cur_sample++;
if (stroke->cur_sample >= max_samples)
stroke->cur_sample = 0;
if (stroke->num_samples < max_samples)
stroke->num_samples++;
}
static void paint_stroke_sample_average(const PaintStroke *stroke,
PaintSample *average)
{
int i;
memset(average, 0, sizeof(*average));
BLI_assert(stroke->num_samples > 0);
for (i = 0; i < stroke->num_samples; i++)
add_v2_v2(average->mouse, stroke->samples[i].mouse);
mul_v2_fl(average->mouse, 1.0f / stroke->num_samples);
/*printf("avg=(%f, %f), num=%d\n", average->mouse[0], average->mouse[1], stroke->num_samples);*/
}
int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
{
Paint *p = paint_get_active(CTX_data_scene(C));
PaintStroke *stroke = op->customdata;
PaintSample sample_average;
float mouse[2];
int first = 0;
paint_stroke_add_sample(p, stroke, event->x, event->y);
paint_stroke_sample_average(stroke, &sample_average);
// let NDOF motion pass through to the 3D view so we can paint and rotate simultaneously!
// this isn't perfect... even when an extra MOUSEMOVE is spoofed, the stroke discards it
// since the 2D deltas are zero -- code in this file needs to be updated to use the
@ -357,9 +411,8 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_PASS_THROUGH;
if (!stroke->stroke_started) {
stroke->last_mouse_position[0] = event->x;
stroke->last_mouse_position[1] = event->y;
stroke->stroke_started = stroke->test_start(C, op, event);
copy_v2_v2(stroke->last_mouse_position, sample_average.mouse);
stroke->stroke_started = stroke->test_start(C, op, sample_average.mouse);
if (stroke->stroke_started) {
stroke->smooth_stroke_cursor =
@ -390,7 +443,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
(event->type == TIMER && (event->customdata == stroke->timer)) )
{
if (stroke->stroke_started) {
if (paint_smooth_stroke(stroke, mouse, event)) {
if (paint_smooth_stroke(stroke, mouse, &sample_average)) {
if (paint_space_stroke_enabled(stroke->brush)) {
if (!paint_space_stroke(C, op, event, mouse)) {
//ED_region_tag_redraw(ar);

@ -2125,7 +2125,7 @@ static char *wpaint_make_validmap(Object *ob)
return vgroup_validmap;
}
static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNUSED(mouse[2]))
{
Scene *scene = CTX_data_scene(C);
struct PaintStroke *stroke = op->customdata;
@ -2673,7 +2673,7 @@ static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
}
}
static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent *UNUSED(event))
static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const float UNUSED(mouse[2]))
{
ToolSettings *ts = CTX_data_tool_settings(C);
struct PaintStroke *stroke = op->customdata;

@ -3224,7 +3224,7 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
}
/* Initialize the stroke cache invariants from operator properties */
static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, wmEvent *event)
static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mouse[2])
{
StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache");
Brush *brush = paint_brush(&sd->paint);
@ -3247,14 +3247,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
sculpt_init_mirror_clipping(ob, ss);
/* Initial mouse location */
if (event) {
ss->cache->initial_mouse[0] = event->x;
ss->cache->initial_mouse[1] = event->y;
}
else {
ss->cache->initial_mouse[0] = 0;
ss->cache->initial_mouse[1] = 0;
}
copy_v2_v2(ss->cache->initial_mouse, mouse);
mode = RNA_enum_get(op->ptr, "mode");
cache->invert = mode == BRUSH_STROKE_INVERT;
@ -3768,18 +3761,18 @@ static int over_mesh(bContext *C, struct wmOperator *UNUSED(op), float x, float
}
static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op,
wmEvent *event)
const float mouse[2])
{
/* Don't start the stroke until mouse goes over the mesh.
* note: event will only be null when re-executing the saved stroke. */
if (event == NULL || over_mesh(C, op, event->x, event->y)) {
if (over_mesh(C, op, mouse[0], mouse[1])) {
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
ED_view3d_init_mats_rv3d(ob, CTX_wm_region_view3d(C));
sculpt_update_cache_invariants(C, sd, ss, op, event);
sculpt_update_cache_invariants(C, sd, ss, op, mouse);
sculpt_undo_push_begin(sculpt_tool_name(sd));

@ -440,7 +440,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
}
/* Finally get user favorite places */
if(read_bookmarks) {
if (read_bookmarks) {
list = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteItems, NULL);
pathesArray = LSSharedFileListCopySnapshot(list, &seed);
pathesCount = CFArrayGetCount(pathesArray);

@ -53,6 +53,8 @@
#include "BKE_main.h"
#include "BKE_node.h"
#include "BLF_api.h"
#include "NOD_composite.h"
#include "NOD_shader.h"
@ -79,6 +81,9 @@
#include "node_intern.h"
// XXX interface.h
extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select);
/* ****************** SOCKET BUTTON DRAW FUNCTIONS ***************** */
static void node_sync_cb(bContext *UNUSED(C), void *snode_v, void *node_v)
@ -474,15 +479,21 @@ static int node_resize_area_default(bNode *node, int x, int y)
rctf totr= node->totr;
/* right part of node */
totr.xmin = node->totr.xmax-20.0f;
return BLI_in_rctf(&totr, x, y);
if (BLI_in_rctf(&totr, x, y))
return NODE_RESIZE_RIGHT;
else
return 0;
}
else {
/* rect we're interested in is just the bottom right corner */
const float size = 10.0f;
rctf totr= node->totr;
/* bottom right corner */
totr.xmin = totr.xmax-10.0f;
totr.ymax = totr.ymin+10.0f;
return BLI_in_rctf(&totr, x, y);
int dir = 0;
if (x >= totr.xmax-size && x < totr.xmax && y >= totr.ymin && y < totr.ymax)
dir |= NODE_RESIZE_RIGHT;
if (x >= totr.xmin && x < totr.xmin+size && y >= totr.ymin && y < totr.ymax)
dir |= NODE_RESIZE_LEFT;
return dir;
}
}
@ -511,7 +522,7 @@ static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode)
int dy;
/* get "global" coords */
nodeSpaceCoords(gnode, &locx, &locy);
nodeToView(gnode, 0.0f, 0.0f, &locx, &locy);
/* center them, is a bit of abuse of locx and locy though */
node_update_nodetree(C, ngroup, locx, locy);
@ -906,20 +917,166 @@ static void node_common_buts_whileloop(uiLayout *layout, bContext *UNUSED(C), Po
uiItemR(layout, ptr, "max_iterations", 0, NULL, 0);
}
static void node_update_frame(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node)
/* XXX Does a bounding box update by iterating over all children.
* Not ideal to do this in every draw call, but doing as transform callback doesn't work,
* since the child node totr rects are not updated properly at that point.
*/
static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node)
{
float locx, locy;
const float margin = 30.0f;
NodeFrame *data = (NodeFrame *)node->storage;
int bbinit;
bNode *tnode;
rctf rect, noderect;
float xmax, ymax;
/* init rect from current frame size */
nodeToView(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
nodeToView(node, node->offsetx+node->width, node->offsety-node->height, &rect.xmax, &rect.ymin);
/* frame can be resized manually only if shrinking is disabled or no children are attached */
data->flag |= NODE_FRAME_RESIZEABLE;
/* for shrinking bbox, initialize the rect from first child node */
bbinit = (data->flag & NODE_FRAME_SHRINK);
/* fit bounding box to all children */
for (tnode=ntree->nodes.first; tnode; tnode=tnode->next) {
if (tnode->parent!=node)
continue;
/* add margin to node rect */
noderect = tnode->totr;
noderect.xmin -= margin;
noderect.xmax += margin;
noderect.ymin -= margin;
noderect.ymax += margin;
/* first child initializes frame */
if (bbinit) {
bbinit = 0;
rect = noderect;
data->flag &= ~NODE_FRAME_RESIZEABLE;
}
else
BLI_union_rctf(&rect, &noderect);
}
/* now adjust the frame size from view-space bounding box */
nodeFromView(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
nodeFromView(node, rect.xmax, rect.ymin, &xmax, &ymax);
node->width = xmax - node->offsetx;
node->height = -ymax + node->offsety;
node->totr = rect;
}
/* get "global" coords */
nodeSpaceCoords(node, &locx, &locy);
static void node_draw_frame_label(bNode *node)
{
/* XXX font id is crap design */
const int fontid = blf_mono_font;
NodeFrame *data = (NodeFrame *)node->storage;
rctf *rct= &node->totr;
int color_id= node_get_colorid(node);
char label[128];
/* XXX a bit hacky, should use separate align values for x and y */
float width, ascender;
float x, y;
BLI_strncpy(label, nodeLabel(node), sizeof(label));
BLF_size(fontid, data->label_size, U.dpi);
/* title color */
UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.8f, 10);
node->prvr.xmin = locx + NODE_DYS;
node->prvr.xmax = locx + node->width- NODE_DYS;
width = BLF_width(fontid, label);
ascender = BLF_ascender(fontid);
x = 0.5f*(rct->xmin + rct->xmax) - 0.5f*width;
y = rct->ymax - NODE_DYS - ascender;
BLF_position(fontid, x, y, 0);
BLF_draw(fontid, label, BLF_DRAW_STR_DUMMY_MAX);
}
node->totr.xmin = locx;
node->totr.xmax = locx + node->width;
node->totr.ymax = locy;
node->totr.ymin = locy - node->height;
static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *UNUSED(ntree), bNode *node)
{
rctf *rct= &node->totr;
int color_id= node_get_colorid(node);
/* skip if out of view */
if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax ||
node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax) {
uiEndBlock(C, node->block);
node->block= NULL;
return;
}
/* shadow */
node_draw_shadow(snode, node, BASIS_RAD);
/* body */
if (node->flag & NODE_CUSTOM_COLOR)
glColor3fv(node->color);
else
UI_ThemeColor4(TH_NODE);
glEnable(GL_BLEND);
uiSetRoundBox(UI_CNR_ALL);
uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
glDisable(GL_BLEND);
/* outline active and selected emphasis */
if ( node->flag & (NODE_ACTIVE|SELECT) ) {
glEnable(GL_BLEND);
glEnable( GL_LINE_SMOOTH );
if (node->flag & NODE_ACTIVE)
UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
else
UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
uiSetRoundBox(UI_CNR_ALL);
uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
glDisable( GL_LINE_SMOOTH );
glDisable(GL_BLEND);
}
/* label */
node_draw_frame_label(node);
UI_ThemeClearColor(color_id);
uiEndBlock(C, node->block);
uiDrawBlock(C, node->block);
node->block= NULL;
}
static int node_resize_area_frame(bNode *node, int x, int y)
{
const float size = 10.0f;
NodeFrame *data = (NodeFrame *)node->storage;
rctf totr= node->totr;
int dir = 0;
/* shrinking frame size is determined by child nodes */
if (!(data->flag & NODE_FRAME_RESIZEABLE))
return 0;
if (x >= totr.xmax-size && x < totr.xmax && y >= totr.ymin && y < totr.ymax)
dir |= NODE_RESIZE_RIGHT;
if (x >= totr.xmin && x < totr.xmin+size && y >= totr.ymin && y < totr.ymax)
dir |= NODE_RESIZE_LEFT;
if (x >= totr.xmin && x < totr.xmax && y >= totr.ymax-size && y < totr.ymax)
dir |= NODE_RESIZE_TOP;
if (x >= totr.xmin && x < totr.xmax && y >= totr.ymin && y < totr.ymin+size)
dir |= NODE_RESIZE_BOTTOM;
return dir;
}
static void node_buts_frame_details(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "label_size", 0, "Label Size", ICON_NONE);
uiItemR(layout, ptr, "shrink", 0, "Shrink", ICON_NONE);
}
static void node_common_set_butfunc(bNodeType *ntype)
@ -941,7 +1098,10 @@ static void node_common_set_butfunc(bNodeType *ntype)
ntype->drawupdatefunc= node_update_group;
break;
case NODE_FRAME:
ntype->drawfunc= node_draw_frame;
ntype->drawupdatefunc= node_update_frame;
ntype->uifuncbut= node_buts_frame_details;
ntype->resize_area_func= node_resize_area_frame;
break;
}
}
@ -1136,7 +1296,6 @@ static void node_shader_buts_dynamic(uiLayout *layout, bContext *C, PointerRNA *
/* only once called */
static void node_shader_set_butfunc(bNodeType *ntype)
{
ntype->uifuncbut = NULL;
switch (ntype->type) {
/* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */
@ -1215,7 +1374,6 @@ static void node_shader_set_butfunc(bNodeType *ntype)
ntype->uifunc= node_shader_buts_dynamic;
break;
}
if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc;
}
/* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
@ -1984,17 +2142,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE);
row = uiLayoutRow(layout, 0);
uiItemR(row, ptr, "midtones_start", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_end", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
row = uiLayoutRow(layout, 0);
uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "master_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
row = uiLayoutRow(layout, 0);
uiItemL(row, "", 0);
uiItemL(row, "Saturation", 0);
uiItemL(row, "Contrast", 0);
uiItemL(row, "Gamma", 0);
@ -2002,26 +2150,42 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
uiItemL(row, "Lift", 0);
row = uiLayoutRow(layout, 0);
uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "highlights_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemL(row, "Master", 0);
uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "master_gamma", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
row = uiLayoutRow(layout, 0);
uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemL(row, "Highlights", 0);
uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "highlights_gamma", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
row = uiLayoutRow(layout, 0);
uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "shadows_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemL(row, "Midtones", 0);
uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "midtones_gamma", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
row = uiLayoutRow(layout, 0);
uiItemL(row, "Shadows", 0);
uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "shadows_gamma", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
row = uiLayoutRow(layout, 0);
uiItemR(row, ptr, "midtones_start", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_end", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
static void node_composit_buts_colorcorrection_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) {
uiLayout *row;
@ -2075,8 +2239,8 @@ static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), Po
uiLayout *row;
row= uiLayoutRow(layout, 1);
uiItemR(row, ptr, "x", 0, "X", ICON_NONE);
uiItemR(row, ptr, "y", 0, "Y", ICON_NONE);
uiItemR(row, ptr, "x", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "y", 0, NULL, ICON_NONE);
row= uiLayoutRow(layout, 1);
uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@ -2117,22 +2281,22 @@ void node_composit_backdrop_viewer(SpaceNode* snode, ImBuf* backdrop, bNode* nod
void node_composit_backdrop_boxmask(SpaceNode* snode, ImBuf* backdrop, bNode* node, int x, int y)
{
NodeBoxMask * boxmask = node->storage;
NodeBoxMask *boxmask = node->storage;
const float backdropWidth = backdrop->x;
const float backdropHeight = backdrop->y;
const float aspect = backdropWidth/backdropHeight;
const float rad = DEG2RAD(-boxmask->rotation);
const float cosine = cos(rad);
const float sine = sin(rad);
const float halveBoxWidth = backdropWidth*(boxmask->width/2.0f);
const float halveBoxHeight = backdropHeight*(boxmask->height/2.0f)*aspect;
const float rad = DEG2RADF(-boxmask->rotation);
const float cosine = cosf(rad);
const float sine = sinf(rad);
const float halveBoxWidth = backdropWidth * (boxmask->width / 2.0f);
const float halveBoxHeight = backdropHeight * (boxmask->height / 2.0f) * aspect;
float cx, cy, x1, x2, x3, x4;
float y1, y2, y3, y4;
/* keep this, saves us from a version patch */
if(snode->zoom==0.0f) snode->zoom= 1.0f;
if (snode->zoom == 0.0f) snode->zoom = 1.0f;
glColor3f(1.0, 1.0, 1.0);
@ -2161,19 +2325,19 @@ void node_composit_backdrop_ellipsemask(SpaceNode* snode, ImBuf* backdrop, bNode
NodeEllipseMask * ellipsemask = node->storage;
const float backdropWidth = backdrop->x;
const float backdropHeight = backdrop->y;
const float aspect = backdropWidth/backdropHeight;
const float rad = DEG2RAD(-ellipsemask->rotation);
const float cosine = cos(rad);
const float sine = sin(rad);
const float halveBoxWidth = backdropWidth*(ellipsemask->width/2.0f);
const float halveBoxHeight = backdropHeight*(ellipsemask->height/2.0f)*aspect;
const float aspect = backdropWidth / backdropHeight;
const float rad = DEG2RADF(-ellipsemask->rotation);
const float cosine = cosf(rad);
const float sine = sinf(rad);
const float halveBoxWidth = backdropWidth * (ellipsemask->width / 2.0f);
const float halveBoxHeight = backdropHeight * (ellipsemask->height / 2.0f) * aspect;
float cx, cy, x1, x2, x3, x4;
float y1, y2, y3, y4;
/* keep this, saves us from a version patch */
if(snode->zoom==0.0f) snode->zoom= 1.0f;
if (snode->zoom == 0.0f) snode->zoom = 1.0f;
glColor3f(1.0, 1.0, 1.0);
@ -2202,8 +2366,8 @@ static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C)
{
uiLayout *row;
row= uiLayoutRow(layout, 1);
uiItemR(row, ptr, "x", 0, "X", ICON_NONE);
uiItemR(row, ptr, "y", 0, "Y", ICON_NONE);
uiItemR(row, ptr, "x", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "y", 0, NULL, ICON_NONE);
row= uiLayoutRow(layout, 1);
uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@ -2227,7 +2391,6 @@ static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C),
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
ntype->uifuncbut = NULL;
switch (ntype->type) {
/* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */
@ -2418,8 +2581,6 @@ static void node_composit_set_butfunc(bNodeType *ntype)
default:
ntype->uifunc= NULL;
}
if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc;
}
/* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
@ -2530,7 +2691,6 @@ static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), Poin
/* only once called */
static void node_texture_set_butfunc(bNodeType *ntype)
{
ntype->uifuncbut = NULL;
if ( ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX ) {
ntype->uifunc = node_texture_buts_proc;
}
@ -2574,10 +2734,6 @@ static void node_texture_set_butfunc(bNodeType *ntype)
break;
}
}
if (ntype->uifuncbut == NULL) {
ntype->uifuncbut = ntype->uifunc;
}
}
/* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */

@ -89,8 +89,8 @@ static void active_node_panel(const bContext *C, Panel *pa)
SpaceNode *snode= CTX_wm_space_node(C);
bNodeTree *ntree= (snode) ? snode->edittree : NULL;
bNode *node = (ntree) ? nodeGetActive(ntree) : NULL; // xxx... for editing group nodes
uiLayout *layout;
PointerRNA ptr;
uiLayout *layout, *row, *col, *sub;
PointerRNA ptr, opptr;
/* verify pointers, and create RNA pointer for the node */
if (ELEM(NULL, ntree, node))
@ -100,7 +100,6 @@ static void active_node_panel(const bContext *C, Panel *pa)
//else
RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
/* XXX nicer way to make sub-layout? */
layout = uiLayoutColumn(pa->layout, 0);
uiLayoutSetContextPointer(layout, "node", &ptr);
@ -112,12 +111,35 @@ static void active_node_panel(const bContext *C, Panel *pa)
uiItemO(layout, NULL, 0, "NODE_OT_hide_socket_toggle");
uiItemS(layout);
uiItemS(layout);
row = uiLayoutRow(layout, 0);
col = uiLayoutColumn(row, 1);
uiItemM(col, (bContext *)C, "NODE_MT_node_color_presets", NULL, 0);
uiItemR(col, &ptr, "use_custom_color", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE);
sub = uiLayoutRow(col, 0);
if (!(node->flag & NODE_CUSTOM_COLOR))
uiLayoutSetEnabled(sub, 0);
uiItemR(sub, &ptr, "color", 0, "", 0);
col = uiLayoutColumn(row, 1);
uiItemO(col, "", ICON_ZOOMIN, "node.node_color_preset_add");
opptr = uiItemFullO(col, "node.node_color_preset_add", "", ICON_ZOOMOUT, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_boolean_set(&opptr, "remove_active", 1);
uiItemM(col, (bContext *)C, "NODE_MT_node_color_specials", "", ICON_BLANK1);
/* draw this node's settings */
if (node->typeinfo && node->typeinfo->uifuncbut)
if (node->typeinfo && node->typeinfo->uifuncbut) {
uiItemS(layout);
uiItemS(layout);
node->typeinfo->uifuncbut(layout, (bContext *)C, &ptr);
else if (node->typeinfo && node->typeinfo->uifunc)
}
else if (node->typeinfo && node->typeinfo->uifunc) {
uiItemS(layout);
uiItemS(layout);
node->typeinfo->uifunc(layout, (bContext *)C, &ptr);
}
}
static int node_sockets_poll(const bContext *C, PanelType *UNUSED(pt))

@ -167,6 +167,110 @@ void ED_node_generic_update(Main *bmain, bNodeTree *ntree, bNode *node)
ntreeTexCheckCyclics(ntree);
}
static int compare_nodes(bNode *a, bNode *b)
{
bNode *parent;
/* These tell if either the node or any of the parent nodes is selected.
* A selected parent means an unselected node is also in foreground!
*/
int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT);
int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE);
/* if one is an ancestor of the other */
/* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */
for (parent = a->parent; parent; parent=parent->parent) {
/* if b is an ancestor, it is always behind a */
if (parent==b)
return 1;
/* any selected ancestor moves the node forward */
if (parent->flag & NODE_ACTIVE)
a_active = 1;
if (parent->flag & NODE_SELECT)
a_select = 1;
}
for (parent = b->parent; parent; parent=parent->parent) {
/* if a is an ancestor, it is always behind b */
if (parent==a)
return 0;
/* any selected ancestor moves the node forward */
if (parent->flag & NODE_ACTIVE)
b_active = 1;
if (parent->flag & NODE_SELECT)
b_select = 1;
}
/* if one of the nodes is in the background and the other not */
if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND))
return 0;
else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND))
return 1;
/* if one has a higher selection state (active > selected > nothing) */
if (!b_active && a_active)
return 1;
else if (!b_select && (a_active || a_select))
return 1;
return 0;
}
/* Sorts nodes by selection: unselected nodes first, then selected,
* then the active node at the very end. Relative order is kept intact!
*/
void ED_node_sort(bNodeTree *ntree)
{
/* merge sort is the algorithm of choice here */
bNode *first_a, *first_b, *node_a, *node_b, *tmp;
int totnodes= BLI_countlist(&ntree->nodes);
int k, a, b;
k = 1;
while (k < totnodes) {
first_a = first_b = ntree->nodes.first;
do {
/* setup first_b pointer */
for (b=0; b < k && first_b; ++b) {
first_b = first_b->next;
}
/* all batches merged? */
if (first_b==NULL)
break;
/* merge batches */
node_a = first_a;
node_b = first_b;
a = b = 0;
while (a < k && b < k && node_b) {
if (compare_nodes(node_a, node_b)==0) {
node_a = node_a->next;
++a;
}
else {
tmp = node_b;
node_b = node_b->next;
++b;
BLI_remlink(&ntree->nodes, tmp);
BLI_insertlinkbefore(&ntree->nodes, node_a, tmp);
}
}
/* setup first pointers for next batch */
first_b = node_b;
for (; b < k; ++b) {
/* all nodes sorted? */
if (first_b==NULL)
break;
first_b = first_b->next;
}
first_a = first_b;
} while (first_b);
k = k << 1;
}
}
static void do_node_internal_buttons(bContext *C, void *node_v, int event)
{
if (event==B_NODE_EXEC) {
@ -176,24 +280,6 @@ static void do_node_internal_buttons(bContext *C, void *node_v, int event)
}
}
static void node_scaling_widget(int color_id, float aspect, float xmin, float ymin, float xmax, float ymax)
{
float dx;
float dy;
dx= 0.5f*(xmax-xmin);
dy= 0.5f*(ymax-ymin);
UI_ThemeColorShade(color_id, +30);
fdrawline(xmin, ymin, xmax, ymax);
fdrawline(xmin+dx, ymin, xmax, ymax-dy);
UI_ThemeColorShade(color_id, -10);
fdrawline(xmin, ymin+aspect, xmax, ymax+aspect);
fdrawline(xmin+dx, ymin+aspect, xmax, ymax-dy+aspect);
}
static void node_uiblocks_init(const bContext *C, bNodeTree *ntree)
{
bNode *node;
@ -223,7 +309,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
int buty;
/* get "global" coords */
nodeSpaceCoords(node, &locx, &locy);
nodeToView(node, 0.0f, 0.0f, &locx, &locy);
dy= locy;
/* header */
@ -350,7 +436,7 @@ static void node_update_hidden(bNode *node)
int totin=0, totout=0, tot;
/* get "global" coords */
nodeSpaceCoords(node, &locx, &locy);
nodeToView(node, 0.0f, 0.0f, &locx, &locy);
/* calculate minimal radius */
for (nsock= node->inputs.first; nsock; nsock= nsock->next)
@ -410,7 +496,7 @@ void node_update_default(const bContext *C, bNodeTree *ntree, bNode *node)
node_update_basis(C, ntree, node);
}
static int node_get_colorid(bNode *node)
int node_get_colorid(bNode *node)
{
if (node->typeinfo->nclass==NODE_CLASS_INPUT)
return TH_NODE_IN_OUT;
@ -573,6 +659,24 @@ static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_
WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, NULL);
}
void node_draw_shadow(SpaceNode *snode, bNode *node, float radius)
{
rctf *rct = &node->totr;
uiSetRoundBox(UI_CNR_ALL);
if (node->parent==NULL)
ui_dropshadow(rct, radius, snode->aspect, node->flag & SELECT);
else {
const float margin = 3.0f;
glColor4f(0.0f, 0.0f, 0.0f, 0.33f);
glEnable(GL_BLEND);
uiRoundBox(rct->xmin-margin, rct->ymin-margin,
rct->xmax+margin, rct->ymax+margin, radius+margin);
glDisable(GL_BLEND);
}
}
static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node)
{
bNodeSocket *sock;
@ -597,8 +701,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
return;
}
uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_LEFT);
ui_dropshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT);
/* shadow */
node_draw_shadow(snode, node, BASIS_RAD);
/* header */
if (color_id==TH_NODE)
@ -644,7 +748,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* title */
if (node->flag & SELECT)
UI_ThemeColor(TH_TEXT_HI);
UI_ThemeColor(TH_SELECT);
else
UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
@ -680,27 +784,27 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
(int)(iconofs - rct->xmin-18.0f), NODE_DY, NULL, 0, 0, 0, 0, "");
/* body */
UI_ThemeColor4(TH_NODE);
if (node->flag & NODE_CUSTOM_COLOR)
glColor3fv(node->color);
else
UI_ThemeColor4(TH_NODE);
glEnable(GL_BLEND);
uiSetRoundBox(UI_CNR_BOTTOM_LEFT);
uiSetRoundBox(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax-NODE_DY, BASIS_RAD);
glDisable(GL_BLEND);
/* scaling indicator */
node_scaling_widget(TH_NODE, snode->aspect, rct->xmax-BASIS_RAD*snode->aspect, rct->ymin, rct->xmax, rct->ymin+BASIS_RAD*snode->aspect);
/* outline active and selected emphasis */
if ( node->flag & (NODE_ACTIVE|SELECT) ) {
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
/* using different shades of TH_TEXT_HI for the empasis, like triangle */
if ( node->flag & NODE_ACTIVE )
UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40);
else
UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120);
uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_LEFT); // round all corners except lower right
uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
if (node->flag & NODE_ACTIVE)
UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
else
UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
uiSetRoundBox(UI_CNR_ALL);
uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
@ -758,8 +862,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
char showname[128]; /* 128 is used below */
/* shadow */
uiSetRoundBox(UI_CNR_ALL);
ui_dropshadow(rct, hiddenrad, snode->aspect, node->flag & SELECT);
node_draw_shadow(snode, node, hiddenrad);
/* body */
UI_ThemeColor(color_id);
@ -771,19 +874,20 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
if ( node->flag & (NODE_ACTIVE|SELECT) ) {
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
/* using different shades of TH_TEXT_HI for the empasis, like triangle */
if ( node->flag & NODE_ACTIVE )
UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40);
else
UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120);
uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
if (node->flag & NODE_ACTIVE)
UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
else
UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
/* title */
if (node->flag & SELECT)
UI_ThemeColor(TH_TEXT_HI);
UI_ThemeColor(TH_SELECT);
else
UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
@ -807,7 +911,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
node_draw_mute_line(&ar->v2d, snode, node);
if (node->flag & SELECT)
UI_ThemeColor(TH_TEXT_HI);
UI_ThemeColor(TH_SELECT);
else
UI_ThemeColor(TH_TEXT);
@ -848,6 +952,45 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
node->block= NULL;
}
int node_get_resize_cursor(int directions)
{
if (directions==0)
return CURSOR_STD;
else if ((directions & ~(NODE_RESIZE_TOP|NODE_RESIZE_BOTTOM))==0)
return CURSOR_Y_MOVE;
else if ((directions & ~(NODE_RESIZE_RIGHT|NODE_RESIZE_LEFT))==0)
return CURSOR_X_MOVE;
else
return CURSOR_EDIT;
}
void node_set_cursor(wmWindow *win, SpaceNode *snode)
{
bNodeTree *ntree = snode->edittree;
bNode *node;
bNodeSocket *sock;
int cursor = CURSOR_STD;
if (ntree) {
if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN|SOCK_OUT)) {
/* pass */
}
else {
/* check nodes front to back */
for (node=ntree->nodes.last; node; node=node->prev) {
if (BLI_in_rctf(&node->totr, snode->mx, snode->my))
break; /* first hit on node stops */
}
if (node) {
int dir = node->typeinfo->resize_area_func(node, snode->mx, snode->my);
cursor = node_get_resize_cursor(dir);
}
}
}
WM_cursor_set(win, cursor);
}
void node_draw_default(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node)
{
if (node->flag & NODE_HIDDEN)
@ -866,7 +1009,8 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree, float offsetx, fl
{
bNode *node;
for (node= ntree->nodes.first; node; node= node->next) {
/* update nodes front to back, so children sizes get updated before parents */
for (node= ntree->nodes.last; node; node= node->prev) {
/* XXX little hack */
node->locx += offsetx;
node->locy += offsety;
@ -892,6 +1036,14 @@ void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeT
if (ntree==NULL) return; /* groups... */
/* draw background nodes, last nodes in front */
for (a=0, node= ntree->nodes.first; node; node=node->next, a++) {
if (!(node->flag & NODE_BACKGROUND))
continue;
node->nr= a; /* index of node in list, used for exec event code */
node_draw(C, ar, snode, ntree, node);
}
/* node lines */
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
@ -900,8 +1052,10 @@ void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeT
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
/* draw nodes, last nodes in front */
/* draw foreground nodes, last nodes in front */
for (a=0, node= ntree->nodes.first; node; node=node->next, a++) {
if (node->flag & NODE_BACKGROUND)
continue;
node->nr= a; /* index of node in list, used for exec event code */
node_draw(C, ar, snode, ntree, node);
}

@ -711,55 +711,13 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
}
}
static int inside_rctf(rctf *bounds, rctf *rect)
void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree))
{
return (bounds->xmin <= rect->xmin &&
bounds->xmax >= rect->xmax &&
bounds->ymin <= rect->ymin &&
bounds->ymax >= rect->ymax);
}
static void node_frame_attach_nodes(bNodeTree *UNUSED(ntree), bNode *frame)
{
bNode *node;
/* only check nodes on top of the frame for attaching */
for (node=frame->next; node; node=node->next) {
if (node->parent==frame) {
/* detach nodes that went outside the frame */
if (!inside_rctf(&frame->totr, &node->totr))
nodeDetachNode(node);
}
else if (node->flag & NODE_SELECT && node->parent==NULL) {
/* attach selected, still unparented nodes */
if (inside_rctf(&frame->totr, &node->totr))
nodeAttachNode(node, frame);
}
}
}
void ED_node_update_hierarchy(bContext *UNUSED(C), bNodeTree *ntree)
{
bNode *node;
/* XXX This does not work due to layout functions relying on node->block,
* which only exists during actual drawing. Can we rely on valid totr rects?
*/
/* make sure nodes have correct bounding boxes after transform */
// node_update_nodetree(C, ntree, 0.0f, 0.0f);
/* all selected nodes are re-parented */
for (node=ntree->nodes.last; node; node=node->prev) {
if (node->flag & NODE_SELECT && node->parent)
nodeDetachNode(node);
}
/* update higher Z-level nodes first */
for (node=ntree->nodes.last; node; node=node->prev) {
/* XXX callback? */
if (node->type==NODE_FRAME)
node_frame_attach_nodes(ntree, node);
}
/* node_update_nodetree(C, ntree, 0.0f, 0.0f); */
}
/* ***************** generic operator functions for nodes ***************** */
@ -1517,36 +1475,130 @@ void NODE_OT_backimage_sample(wmOperatorType *ot)
typedef struct NodeSizeWidget {
float mxstart, mystart;
float oldlocx, oldlocy;
float oldoffsetx, oldoffsety;
float oldwidth, oldheight;
float oldminiwidth;
int directions;
} NodeSizeWidget;
static void node_resize_init(bContext *C, wmOperator *op, wmEvent *UNUSED(event), bNode *node, int dir)
{
SpaceNode *snode = CTX_wm_space_node(C);
NodeSizeWidget *nsw= MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
op->customdata= nsw;
nsw->mxstart= snode->mx;
nsw->mystart= snode->my;
/* store old */
nsw->oldlocx= node->locx;
nsw->oldlocy= node->locy;
nsw->oldoffsetx= node->offsetx;
nsw->oldoffsety= node->offsety;
nsw->oldwidth= node->width;
nsw->oldheight= node->height;
nsw->oldminiwidth= node->miniwidth;
nsw->directions = dir;
WM_cursor_modal(CTX_wm_window(C), node_get_resize_cursor(dir));
/* add modal handler */
WM_event_add_modal_handler(C, op);
}
static void node_resize_exit(bContext *C, wmOperator *op, int UNUSED(cancel))
{
WM_cursor_restore(CTX_wm_window(C));
MEM_freeN(op->customdata);
op->customdata= NULL;
}
static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
{
SpaceNode *snode= CTX_wm_space_node(C);
ARegion *ar= CTX_wm_region(C);
bNode *node= editnode_get_active(snode->edittree);
NodeSizeWidget *nsw= op->customdata;
float mx, my;
float mx, my, dx, dy;
switch (event->type) {
case MOUSEMOVE:
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&mx, &my);
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my);
dx = mx - nsw->mxstart;
dy = my - nsw->mystart;
if (node) {
if (node->flag & NODE_HIDDEN) {
node->miniwidth= nsw->oldminiwidth + mx - nsw->mxstart;
CLAMP(node->miniwidth, 0.0f, 100.0f);
float widthmin = 0.0f;
float widthmax = 100.0f;
if (nsw->directions & NODE_RESIZE_RIGHT) {
node->miniwidth= nsw->oldminiwidth + dx;
CLAMP(node->miniwidth, widthmin, widthmax);
}
if (nsw->directions & NODE_RESIZE_LEFT) {
float locmax = nsw->oldlocx + nsw->oldminiwidth;
node->locx= nsw->oldlocx + dx;
CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
node->miniwidth= locmax - node->locx;
}
}
else {
node->width= nsw->oldwidth + mx - nsw->mxstart;
CLAMP(node->width, UI_DPI_FAC*node->typeinfo->minwidth, UI_DPI_FAC*node->typeinfo->maxwidth);
float widthmin = UI_DPI_FAC*node->typeinfo->minwidth;
float widthmax = UI_DPI_FAC*node->typeinfo->maxwidth;
if (nsw->directions & NODE_RESIZE_RIGHT) {
node->width= nsw->oldwidth + dx;
CLAMP(node->width, widthmin, widthmax);
}
if (nsw->directions & NODE_RESIZE_LEFT) {
float locmax = nsw->oldlocx + nsw->oldwidth;
node->locx= nsw->oldlocx + dx;
CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
node->width= locmax - node->locx;
}
}
/* height works the other way round ... */
node->height= nsw->oldheight - my + nsw->mystart;
CLAMP(node->height, node->typeinfo->minheight, node->typeinfo->maxheight);
{
float heightmin = UI_DPI_FAC*node->typeinfo->minheight;
float heightmax = UI_DPI_FAC*node->typeinfo->maxheight;
if (nsw->directions & NODE_RESIZE_TOP) {
float locmin = nsw->oldlocy - nsw->oldheight;
node->locy= nsw->oldlocy + dy;
CLAMP(node->locy, locmin + heightmin, locmin + heightmax);
node->height= node->locy - locmin;
}
if (nsw->directions & NODE_RESIZE_BOTTOM) {
node->height= nsw->oldheight - dy;
CLAMP(node->height, heightmin, heightmax);
}
}
/* XXX make callback? */
if (node->type == NODE_FRAME) {
/* keep the offset symmetric around center point */
if (nsw->directions & NODE_RESIZE_LEFT) {
node->locx = nsw->oldlocx + 0.5f*dx;
node->offsetx = nsw->oldoffsetx + 0.5f*dx;
}
if (nsw->directions & NODE_RESIZE_RIGHT) {
node->locx = nsw->oldlocx + 0.5f*dx;
node->offsetx = nsw->oldoffsetx - 0.5f*dx;
}
if (nsw->directions & NODE_RESIZE_TOP) {
node->locy = nsw->oldlocy + 0.5f*dy;
node->offsety = nsw->oldoffsety + 0.5f*dy;
}
if (nsw->directions & NODE_RESIZE_BOTTOM) {
node->locy = nsw->oldlocy + 0.5f*dy;
node->offsety = nsw->oldoffsety - 0.5f*dy;
}
}
}
ED_region_tag_redraw(ar);
@ -1557,10 +1609,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
case MIDDLEMOUSE:
case RIGHTMOUSE:
MEM_freeN(nsw);
op->customdata= NULL;
ED_node_update_hierarchy(C, snode->edittree);
node_resize_exit(C, op, 0);
ED_node_post_apply_transform(C, snode->edittree);
return OPERATOR_FINISHED;
}
@ -1573,37 +1623,24 @@ static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event)
SpaceNode *snode= CTX_wm_space_node(C);
ARegion *ar= CTX_wm_region(C);
bNode *node= editnode_get_active(snode->edittree);
int dir;
if (node) {
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->mx, &snode->my);
if (node->typeinfo->resize_area_func(node, snode->mx, snode->my)) {
NodeSizeWidget *nsw= MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
op->customdata= nsw;
nsw->mxstart= snode->mx;
nsw->mystart= snode->my;
/* store old */
nsw->oldwidth= node->width;
nsw->oldheight= node->height;
nsw->oldminiwidth= node->miniwidth;
/* add modal handler */
WM_event_add_modal_handler(C, op);
&snode->mx, &snode->my);
dir = node->typeinfo->resize_area_func(node, snode->mx, snode->my);
if (dir != 0) {
node_resize_init(C, op, event, node, dir);
return OPERATOR_RUNNING_MODAL;
}
}
return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
}
static int node_resize_cancel(bContext *UNUSED(C), wmOperator *op)
static int node_resize_cancel(bContext *C, wmOperator *op)
{
MEM_freeN(op->customdata);
op->customdata= NULL;
node_resize_exit(C, op, 1);
return OPERATOR_CANCELLED;
}
@ -2180,6 +2217,27 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate
/* ****************** Duplicate *********************** */
static void node_duplicate_reparent_recursive(bNode *node)
{
bNode *parent;
node->flag |= NODE_TEST;
/* find first selected parent */
for (parent=node->parent; parent; parent=parent->parent) {
if (parent->flag & SELECT) {
if (!(parent->flag & NODE_TEST))
node_duplicate_reparent_recursive(parent);
break;
}
}
/* reparent node copy to parent copy */
if (parent) {
nodeDetachNode(node->new_node);
nodeAttachNode(node->new_node, parent->new_node);
}
}
static int node_duplicate_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode= CTX_wm_space_node(C);
@ -2242,6 +2300,19 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
break;
}
/* clear flags for recursive depth-first iteration */
for (node= ntree->nodes.first; node; node= node->next)
node->flag &= ~NODE_TEST;
/* reparent copied nodes */
for (node= ntree->nodes.first; node; node= node->next) {
if ((node->flag & SELECT) && !(node->flag & NODE_TEST))
node_duplicate_reparent_recursive(node);
/* only has to check old nodes */
if (node==lastnode)
break;
}
/* deselect old nodes, select the copies instead */
for (node= ntree->nodes.first; node; node= node->next) {
if (node->flag & SELECT) {
@ -2450,7 +2521,7 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
/* when linking to group outputs, update the socket type */
/* XXX this should all be part of a generic update system */
if (!link->tonode) {
if(link->tosock->type != link->fromsock->type)
if (link->tosock->type != link->fromsock->type)
nodeSocketSetType(link->tosock, link->fromsock->type);
}
}
@ -3782,3 +3853,354 @@ void NODE_OT_output_file_move_active_socket(wmOperatorType *ot)
RNA_def_enum(ot->srna, "direction", direction_items, 2, "Direction", "");
}
/* ****************** Copy Node Color ******************* */
static int node_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNode *node, *tnode;
if (!ntree)
return OPERATOR_CANCELLED;
node = nodeGetActive(ntree);
if (!node)
return OPERATOR_CANCELLED;
for (tnode=ntree->nodes.first; tnode; tnode=tnode->next) {
if (tnode->flag & NODE_SELECT && tnode != node) {
if (node->flag & NODE_CUSTOM_COLOR) {
tnode->flag |= NODE_CUSTOM_COLOR;
copy_v3_v3(tnode->color, node->color);
}
else
tnode->flag &= ~NODE_CUSTOM_COLOR;
}
}
ED_node_sort(ntree);
WM_event_add_notifier(C, NC_NODE|ND_DISPLAY, NULL);
return OPERATOR_FINISHED;
}
void NODE_OT_node_copy_color(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Copy Color";
ot->description = "Copy color to all selected nodes";
ot->idname = "NODE_OT_node_copy_color";
/* api callbacks */
ot->exec = node_copy_color_exec;
ot->poll = ED_operator_node_active;
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
/* ****************** Set Parent ******************* */
static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNode *frame = nodeGetActive(ntree), *node;
if (!frame || frame->type != NODE_FRAME)
return OPERATOR_CANCELLED;
for (node=ntree->nodes.first; node; node=node->next) {
if (node == frame)
continue;
if (node->flag & NODE_SELECT) {
nodeDetachNode(node);
nodeAttachNode(node, frame);
}
}
ED_node_sort(ntree);
WM_event_add_notifier(C, NC_NODE|ND_DISPLAY, NULL);
return OPERATOR_FINISHED;
}
void NODE_OT_parent_set(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Make Parent";
ot->description = "Attach selected nodes";
ot->idname = "NODE_OT_parent_set";
/* api callbacks */
ot->exec = node_parent_set_exec;
ot->poll = ED_operator_node_active;
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
/* ****************** Clear Parent ******************* */
static int node_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNode *node;
for (node=ntree->nodes.first; node; node=node->next) {
if (node->flag & NODE_SELECT) {
nodeDetachNode(node);
}
}
WM_event_add_notifier(C, NC_NODE|ND_DISPLAY, NULL);
return OPERATOR_FINISHED;
}
void NODE_OT_parent_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clear Parent";
ot->description = "Detach selected nodes";
ot->idname = "NODE_OT_parent_clear";
/* api callbacks */
ot->exec = node_parent_clear_exec;
ot->poll = ED_operator_node_active;
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
/* ****************** Join Nodes ******************* */
/* tags for depth-first search */
#define NODE_JOIN_DONE 1
#define NODE_JOIN_IS_DESCENDANT 2
static void node_join_attach_recursive(bNode *node, bNode *frame)
{
node->done |= NODE_JOIN_DONE;
if (node == frame) {
node->done |= NODE_JOIN_IS_DESCENDANT;
}
else if (node->parent) {
/* call recursively */
if (!(node->parent->done & NODE_JOIN_DONE))
node_join_attach_recursive(node->parent, frame);
/* in any case: if the parent is a descendant, so is the child */
if (node->parent->done & NODE_JOIN_IS_DESCENDANT)
node->done |= NODE_JOIN_IS_DESCENDANT;
else if (node->flag & NODE_TEST) {
/* if parent is not an decendant of the frame, reattach the node */
nodeDetachNode(node);
nodeAttachNode(node, frame);
node->done |= NODE_JOIN_IS_DESCENDANT;
}
}
else if (node->flag & NODE_TEST) {
nodeAttachNode(node, frame);
node->done |= NODE_JOIN_IS_DESCENDANT;
}
}
static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
bNodeTree *ntree = snode->edittree;
bNode *node, *frame;
bNodeTemplate ntemp;
/* XXX save selection: node_add_node call below sets the new frame as single active+selected node */
for (node=ntree->nodes.first; node; node=node->next) {
if (node->flag & NODE_SELECT)
node->flag |= NODE_TEST;
else
node->flag &= ~NODE_TEST;
}
ntemp.main = bmain;
ntemp.scene = scene;
ntemp.type = NODE_FRAME;
frame = node_add_node(snode, bmain, scene, &ntemp, 0.0f, 0.0f);
/* reset tags */
for (node=ntree->nodes.first; node; node=node->next)
node->done = 0;
for (node=ntree->nodes.first; node; node=node->next) {
if (!(node->done & NODE_JOIN_DONE))
node_join_attach_recursive(node, frame);
}
/* restore selection */
for (node=ntree->nodes.first; node; node=node->next) {
if (node->flag & NODE_TEST)
node->flag |= NODE_SELECT;
}
ED_node_sort(ntree);
WM_event_add_notifier(C, NC_NODE|ND_DISPLAY, NULL);
return OPERATOR_FINISHED;
}
void NODE_OT_join(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Join Nodes";
ot->description = "Attaches selected nodes to a new common frame";
ot->idname = "NODE_OT_join";
/* api callbacks */
ot->exec = node_join_exec;
ot->poll = ED_operator_node_active;
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
/* ****************** Attach ******************* */
static int node_attach_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNode *frame;
/* check nodes front to back */
for (frame=ntree->nodes.last; frame; frame=frame->prev) {
/* skip selected, those are the nodes we want to attach */
if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT))
continue;
if (BLI_in_rctf(&frame->totr, snode->mx, snode->my))
break;
}
if (frame) {
bNode *node, *parent;
for (node=ntree->nodes.last; node; node=node->prev) {
if (node->flag & NODE_SELECT) {
if (node->parent == NULL) {
/* attach all unparented nodes */
nodeAttachNode(node, frame);
}
else {
/* attach nodes which share parent with the frame */
for (parent=frame->parent; parent; parent=parent->parent)
if (parent == node->parent)
break;
if (parent) {
nodeDetachNode(node);
nodeAttachNode(node, frame);
}
}
}
}
}
ED_node_sort(ntree);
WM_event_add_notifier(C, NC_NODE|ND_DISPLAY, NULL);
return OPERATOR_FINISHED;
}
static int node_attach_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
ARegion *ar= CTX_wm_region(C);
SpaceNode *snode= CTX_wm_space_node(C);
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->mx, &snode->my);
return node_attach_exec(C, op);
}
void NODE_OT_attach(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Attach Nodes";
ot->description = "Attaches active node to a frame";
ot->idname = "NODE_OT_attach";
/* api callbacks */
ot->exec = node_attach_exec;
ot->invoke = node_attach_invoke;
ot->poll = ED_operator_node_active;
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
/* ****************** Detach ******************* */
/* tags for depth-first search */
#define NODE_DETACH_DONE 1
#define NODE_DETACH_IS_DESCENDANT 2
static void node_detach_recursive(bNode *node)
{
node->done |= NODE_DETACH_DONE;
if (node->parent) {
/* call recursively */
if (!(node->parent->done & NODE_DETACH_DONE))
node_detach_recursive(node->parent);
/* in any case: if the parent is a descendant, so is the child */
if (node->parent->done & NODE_DETACH_IS_DESCENDANT)
node->done |= NODE_DETACH_IS_DESCENDANT;
else if (node->flag & NODE_SELECT) {
/* if parent is not a decendant of a selected node, detach */
nodeDetachNode(node);
node->done |= NODE_DETACH_IS_DESCENDANT;
}
}
else if (node->flag & NODE_SELECT) {
node->done |= NODE_DETACH_IS_DESCENDANT;
}
}
/* detach the root nodes in the current selection */
static int node_detach_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNode *node;
/* reset tags */
for (node=ntree->nodes.first; node; node=node->next)
node->done = 0;
/* detach nodes recursively
* relative order is preserved here!
*/
for (node=ntree->nodes.first; node; node=node->next) {
if (!(node->done & NODE_DETACH_DONE))
node_detach_recursive(node);
}
ED_node_sort(ntree);
WM_event_add_notifier(C, NC_NODE|ND_DISPLAY, NULL);
return OPERATOR_FINISHED;
}
void NODE_OT_detach(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Detach Nodes";
ot->description = "Detaches selected nodes from parents";
ot->idname = "NODE_OT_detach";
/* api callbacks */
ot->exec = node_detach_exec;
ot->poll = ED_operator_node_active;
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}

@ -40,7 +40,9 @@ struct ARegion;
struct ARegionType;
struct View2D;
struct bContext;
struct wmWindow;
struct wmWindowManager;
struct wmEvent;
struct bNodeTemplate;
struct bNode;
struct bNodeSocket;
@ -67,13 +69,18 @@ ARegion *node_has_buttons_region(ScrArea *sa);
void node_menus_register(void);
/* node_draw.c */
int node_get_colorid(struct bNode *node);
void node_socket_circle_draw(struct bNodeTree *ntree, struct bNodeSocket *sock, float size);
int node_get_resize_cursor(int directions);
void node_draw_shadow(struct SpaceNode *snode, struct bNode *node, float radius);
void node_draw_default(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode, struct bNodeTree *ntree, struct bNode *node);
void node_update_default(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node);
void node_update_nodetree(const struct bContext *C, struct bNodeTree *ntree, float offsetx, float offsety);
void node_draw_nodetree(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode, struct bNodeTree *ntree);
void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode);
/* node_buttons.c */
void node_buttons_register(struct ARegionType *art);
void NODE_OT_properties(struct wmOperatorType *ot);
@ -151,6 +158,7 @@ void NODE_OT_hide_toggle(struct wmOperatorType *ot);
void NODE_OT_hide_socket_toggle(struct wmOperatorType *ot);
void NODE_OT_preview_toggle(struct wmOperatorType *ot);
void NODE_OT_options_toggle(struct wmOperatorType *ot);
void NODE_OT_node_copy_color(struct wmOperatorType *ot);
void NODE_OT_show_cyclic_dependencies(struct wmOperatorType *ot);
void NODE_OT_link_viewer(struct wmOperatorType *ot);
@ -170,6 +178,12 @@ void NODE_OT_output_file_add_socket(struct wmOperatorType *ot);
void NODE_OT_output_file_remove_active_socket(struct wmOperatorType *ot);
void NODE_OT_output_file_move_active_socket(struct wmOperatorType *ot);
void NODE_OT_parent_set(struct wmOperatorType *ot);
void NODE_OT_parent_clear(struct wmOperatorType *ot);
void NODE_OT_join(struct wmOperatorType *ot);
void NODE_OT_attach(struct wmOperatorType *ot);
void NODE_OT_detach(struct wmOperatorType *ot);
extern const char *node_context_dir[];
// XXXXXX

@ -68,6 +68,7 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_options_toggle);
WM_operatortype_append(NODE_OT_hide_socket_toggle);
WM_operatortype_append(NODE_OT_show_cyclic_dependencies);
WM_operatortype_append(NODE_OT_node_copy_color);
WM_operatortype_append(NODE_OT_duplicate);
WM_operatortype_append(NODE_OT_delete);
@ -104,6 +105,12 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_output_file_add_socket);
WM_operatortype_append(NODE_OT_output_file_remove_active_socket);
WM_operatortype_append(NODE_OT_output_file_move_active_socket);
WM_operatortype_append(NODE_OT_parent_set);
WM_operatortype_append(NODE_OT_parent_clear);
WM_operatortype_append(NODE_OT_join);
WM_operatortype_append(NODE_OT_attach);
WM_operatortype_append(NODE_OT_detach);
}
void ED_operatormacros_node(void)
@ -111,10 +118,32 @@ void ED_operatormacros_node(void)
wmOperatorType *ot;
wmOperatorTypeMacro *mot;
ot = WM_operatortype_append_macro("NODE_OT_duplicate_move", "Duplicate", "Duplicate selected nodes and move them",
ot = WM_operatortype_append_macro("NODE_OT_select_link_viewer", "Link Viewer",
"Select node and link it to a viewer node",
OPTYPE_UNDO);
WM_operatortype_macro_define(ot, "NODE_OT_select");
WM_operatortype_macro_define(ot, "NODE_OT_link_viewer");
ot = WM_operatortype_append_macro("NODE_OT_translate_attach", "Move and Attach",
"Move nodes and attach to frame",
OPTYPE_UNDO|OPTYPE_REGISTER);
mot = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_boolean_set(mot->ptr, "release_confirm", TRUE);
WM_operatortype_macro_define(ot, "NODE_OT_attach");
ot = WM_operatortype_append_macro("NODE_OT_detach_translate_attach", "Detach and Move",
"Detach nodes, move and attach to frame",
OPTYPE_UNDO|OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "NODE_OT_detach");
mot = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_boolean_set(mot->ptr, "release_confirm", TRUE);
WM_operatortype_macro_define(ot, "NODE_OT_attach");
ot = WM_operatortype_append_macro("NODE_OT_duplicate_move", "Duplicate",
"Duplicate selected nodes and move them",
OPTYPE_UNDO|OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
WM_operatortype_macro_define(ot, "NODE_OT_translate_attach");
/* modified operator call for duplicating with input links */
ot = WM_operatortype_append_macro("NODE_OT_duplicate_move_keep_inputs", "Duplicate",
@ -122,12 +151,7 @@ void ED_operatormacros_node(void)
OPTYPE_UNDO|OPTYPE_REGISTER);
mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
RNA_boolean_set(mot->ptr, "keep_inputs", TRUE);
WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
ot = WM_operatortype_append_macro("NODE_OT_select_link_viewer", "Link Viewer",
"Select node and link it to a viewer node", OPTYPE_UNDO);
WM_operatortype_macro_define(ot, "NODE_OT_select");
WM_operatortype_macro_define(ot, "NODE_OT_link_viewer");
WM_operatortype_macro_define(ot, "NODE_OT_translate_attach");
ot = WM_operatortype_append_macro("NODE_OT_move_detach_links", "Detach", "Move a node to detach links",
OPTYPE_UNDO|OPTYPE_REGISTER);
@ -137,8 +161,30 @@ void ED_operatormacros_node(void)
ot = WM_operatortype_append_macro("NODE_OT_move_detach_links_release", "Detach", "Move a node to detach links",
OPTYPE_UNDO|OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "NODE_OT_links_detach");
mot = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_boolean_set(mot->ptr, "release_confirm", TRUE);
mot = WM_operatortype_macro_define(ot, "NODE_OT_translate_attach");
}
/* helper function for repetitive select operator keymap */
static void node_select_keymap(wmKeyMap *keymap, int extend)
{
/* modifier combinations */
const int mod_single[] = { 0, KM_CTRL, KM_ALT, KM_CTRL|KM_ALT,
-1 /* terminator */
};
const int mod_extend[] = { KM_SHIFT, KM_SHIFT|KM_CTRL,
KM_SHIFT|KM_ALT, KM_SHIFT|KM_CTRL|KM_ALT,
-1 /* terminator */
};
const int *mod = (extend ? mod_extend : mod_single);
wmKeyMapItem *kmi;
int i;
for (i=0; mod[i] >= 0; ++i) {
kmi = WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, mod[i], 0);
RNA_boolean_set(kmi->ptr, "extend", extend);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, mod[i], 0);
RNA_boolean_set(kmi->ptr, "extend", extend);
}
}
void node_keymap(struct wmKeyConfig *keyconf)
@ -157,15 +203,12 @@ void node_keymap(struct wmKeyConfig *keyconf)
/* mouse select in nodes used to be both keys, but perhaps this should be reduced?
* NOTE: mouse-clicks on left-mouse will fall through to allow transform-tweak, but also link/resize
* NOTE 2: socket select is part of the node select operator, to handle overlapping cases
* NOTE 3: select op is registered for various combinations of modifier key, so the specialized
* grab operators (unlink, attach, etc.) can work easily on single nodes.
*/
kmi = WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", TRUE);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", TRUE);
node_select_keymap(keymap, FALSE);
node_select_keymap(keymap, TRUE);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_border", EVT_TWEAK_S, KM_ANY, 0, 0);
RNA_boolean_set(kmi->ptr, "tweak", TRUE);
@ -195,6 +238,10 @@ void node_keymap(struct wmKeyConfig *keyconf)
/* modified operator call for duplicating with input links */
WM_keymap_add_item(keymap, "NODE_OT_duplicate_move_keep_inputs", DKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "NODE_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_hide_toggle", HKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_mute_toggle", MKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_preview_toggle", HKEY, KM_PRESS, KM_SHIFT, 0);

@ -70,109 +70,6 @@ static bNode *node_under_mouse(bNodeTree *ntree, int mx, int my)
return NULL;
}
static int compare_nodes(bNode *a, bNode *b)
{
bNode *parent;
/* These tell if either the node or any of the parent nodes is selected.
* A selected parent means an unselected node is also in foreground!
*/
int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT);
int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE);
/* if one is an ancestor of the other */
/* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */
for (parent = a->parent; parent; parent=parent->parent) {
/* if b is an ancestor, it is always behind a */
if (parent==b)
return 1;
/* any selected ancestor moves the node forward */
if (parent->flag & NODE_ACTIVE)
a_active = 1;
if (parent->flag & NODE_SELECT)
a_select = 1;
}
for (parent = b->parent; parent; parent=parent->parent) {
/* if a is an ancestor, it is always behind b */
if (parent==a)
return 0;
/* any selected ancestor moves the node forward */
if (parent->flag & NODE_ACTIVE)
b_active = 1;
if (parent->flag & NODE_SELECT)
b_select = 1;
}
/* if one of the nodes is in the background and the other not */
if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND))
return 0;
else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND))
return 1;
/* if one has a higher selection state (active > selected > nothing) */
if (!b_active && a_active)
return 1;
else if (!b_select && (a_active || a_select))
return 1;
return 0;
}
/* Sorts nodes by selection: unselected nodes first, then selected,
* then the active node at the very end. Relative order is kept intact!
*/
static void node_sort(bNodeTree *ntree)
{
/* merge sort is the algorithm of choice here */
bNode *first_a, *first_b, *node_a, *node_b, *tmp;
int totnodes= BLI_countlist(&ntree->nodes);
int k, a, b;
k = 1;
while (k < totnodes) {
first_a = first_b = ntree->nodes.first;
do {
/* setup first_b pointer */
for (b=0; b < k && first_b; ++b) {
first_b = first_b->next;
}
/* all batches merged? */
if (first_b==NULL)
break;
/* merge batches */
node_a = first_a;
node_b = first_b;
a = b = 0;
while (a < k && b < k && node_b) {
if (compare_nodes(node_a, node_b)==0) {
node_a = node_a->next;
++a;
}
else {
tmp = node_b;
node_b = node_b->next;
++b;
BLI_remlink(&ntree->nodes, tmp);
BLI_insertlinkbefore(&ntree->nodes, node_a, tmp);
}
}
/* setup first pointers for next batch */
first_b = node_b;
for (; b < k; ++b) {
/* all nodes sorted? */
if (first_b==NULL)
break;
first_b = first_b->next;
}
first_a = first_b;
} while (first_b);
k = k << 1;
}
}
void node_select(bNode *node)
{
node->flag |= SELECT;
@ -407,7 +304,7 @@ void node_select_single(bContext *C, bNode *node)
ED_node_set_active(bmain, snode->edittree, node);
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
}
@ -479,7 +376,7 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
/* update node order */
if (selected)
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
return selected;
}
@ -573,7 +470,7 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
}
}
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
@ -645,7 +542,7 @@ static int node_select_all_exec(bContext *C, wmOperator *UNUSED(op))
node_select(node);
}
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@ -687,7 +584,7 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
node_select(node);
}
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@ -729,7 +626,7 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
node_select(node);
}
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@ -758,7 +655,7 @@ static int node_select_same_type_exec(bContext *C, wmOperator *UNUSED(op))
node_select_same_type(snode);
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@ -787,7 +684,7 @@ static int node_select_same_type_next_exec(bContext *C, wmOperator *UNUSED(op))
node_select_same_type_np(snode, 0);
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
@ -815,7 +712,7 @@ static int node_select_same_type_prev_exec(bContext *C, wmOperator *UNUSED(op))
node_select_same_type_np(snode, 1);
node_sort(snode->edittree);
ED_node_sort(snode->edittree);
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
return OPERATOR_FINISHED;

@ -291,7 +291,7 @@ static void ui_node_sock_name(bNodeSocket *sock, char name[UI_MAX_NAME_STR])
if (node->id)
BLI_strncpy(node_name, node->id->name+2, UI_MAX_NAME_STR);
else
BLI_strncpy(node_name, "Group", UI_MAX_NAME_STR);
BLI_strncpy(node_name, N_("Group"), UI_MAX_NAME_STR);
}
else
BLI_strncpy(node_name, node->typeinfo->name, UI_MAX_NAME_STR);
@ -300,16 +300,16 @@ static void ui_node_sock_name(bNodeSocket *sock, char name[UI_MAX_NAME_STR])
node->outputs.first != node->outputs.last &&
!(node->typeinfo->flag & NODE_OPTIONS))
{
BLI_snprintf(name, UI_MAX_NAME_STR, "%s | %s", node_name, sock->link->fromsock->name);
BLI_snprintf(name, UI_MAX_NAME_STR, "%s | %s", IFACE_(node_name), IFACE_(sock->link->fromsock->name));
}
else {
BLI_strncpy(name, node_name, UI_MAX_NAME_STR);
BLI_strncpy(name, IFACE_(node_name), UI_MAX_NAME_STR);
}
}
else if (sock->type == SOCK_SHADER)
BLI_strncpy(name, "None", UI_MAX_NAME_STR);
BLI_strncpy(name, IFACE_("None"), UI_MAX_NAME_STR);
else
BLI_strncpy(name, "Default", UI_MAX_NAME_STR);
BLI_strncpy(name, IFACE_("Default"), UI_MAX_NAME_STR);
}
static int ui_compatible_sockets(int typeA, int typeB)
@ -360,7 +360,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
column= uiLayoutColumn(layout, 0);
uiBlockSetCurLayout(block, column);
uiItemL(column, cname, ICON_NODE);
uiItemL(column, IFACE_(cname), ICON_NODE);
but= block->buttons.last;
but->flag= UI_TEXT_LEFT;
@ -381,7 +381,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
BLI_strncpy(name, ngroup->id.name+2, UI_MAX_NAME_STR);
but = uiDefBut(block, BUT, 0, ngroup->id.name+2, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input");
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input"));
argN = MEM_dupallocN(arg);
argN->type = NODE_GROUP;
@ -417,7 +417,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
column= uiLayoutColumn(layout, 0);
uiBlockSetCurLayout(block, column);
uiItemL(column, cname, ICON_NODE);
uiItemL(column, IFACE_(cname), ICON_NODE);
but= block->buttons.last;
but->flag= UI_TEXT_LEFT;
@ -426,19 +426,19 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
if (num > 1) {
if (j == 0) {
uiItemL(column, ntype->name, ICON_NODE);
uiItemL(column, IFACE_(ntype->name), ICON_NODE);
but= block->buttons.last;
but->flag= UI_TEXT_LEFT;
}
BLI_snprintf(name, UI_MAX_NAME_STR, " %s", stemp->name);
BLI_snprintf(name, UI_MAX_NAME_STR, " %s", IFACE_(stemp->name));
j++;
}
else
BLI_strncpy(name, ntype->name, UI_MAX_NAME_STR);
BLI_strncpy(name, IFACE_(ntype->name), UI_MAX_NAME_STR);
but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input");
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input"));
argN = MEM_dupallocN(arg);
argN->type = ntype->type;
@ -486,16 +486,16 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
but= block->buttons.last;
but->flag= UI_TEXT_LEFT;
but = uiDefBut(block, BUT, 0, "Remove", 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, "Remove nodes connected to the input");
but = uiDefBut(block, BUT, 0, IFACE_("Remove"), 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Remove nodes connected to the input"));
uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE));
but = uiDefBut(block, BUT, 0, "Disconnect", 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, "Disconnect nodes connected to the input");
but = uiDefBut(block, BUT, 0, IFACE_("Disconnect"), 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Disconnect nodes connected to the input"));
uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT));
}
ui_node_menu_column(arg, NODE_CLASS_GROUP, IFACE_("Group"));
ui_node_menu_column(arg, NODE_CLASS_GROUP, N_("Group"));
}
void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSocket *sock)
@ -586,7 +586,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
/* indented label */
memset(label, ' ', indent);
label[indent] = '\0';
BLI_snprintf(label, UI_MAX_NAME_STR, "%s%s:", label, input->name);
BLI_snprintf(label, UI_MAX_NAME_STR, "%s%s:", label, IFACE_(input->name));
/* split in label and value */
split = uiLayoutSplit(layout, 0.35f, 0);
@ -615,7 +615,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
if (dependency_loop) {
row = uiLayoutRow(split, 0);
uiItemL(row, "Dependency Loop", ICON_ERROR);
uiItemL(row, IFACE_("Dependency Loop"), ICON_ERROR);
}
else if (lnode) {
/* input linked to a node */

@ -339,6 +339,17 @@ static void node_buttons_area_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, 1, NULL, -1);
}
static void node_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
{
SpaceNode *snode= sa->spacedata.first;
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin,
&snode->mx, &snode->my);
node_set_cursor(win, snode);
}
/* Initialize main area, setting handlers. */
static void node_main_area_init(wmWindowManager *wm, ARegion *ar)
{
@ -522,6 +533,8 @@ void ED_spacetype_node(void)
art->init= node_main_area_init;
art->draw= node_main_area_draw;
art->listener= node_region_listener;
art->cursor = node_cursor;
art->event_cursor = TRUE;
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_GPENCIL;
BLI_addhead(&st->regiontypes, art);

@ -932,7 +932,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
{
Object *ob = (Object *)tselem->id;
ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr);
switch (md->type) {
switch ((ModifierType)md->type) {
case eModifierType_Subsurf:
UI_icon_draw(x, y, ICON_MOD_SUBSURF); break;
case eModifierType_Armature:
@ -986,6 +986,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
case eModifierType_Explode:
UI_icon_draw(x, y, ICON_MOD_EXPLODE); break;
case eModifierType_Collision:
case eModifierType_Surface:
UI_icon_draw(x, y, ICON_MOD_PHYSICS); break;
case eModifierType_Fluidsim:
UI_icon_draw(x, y, ICON_MOD_FLUIDSIM); break;
@ -1009,7 +1010,13 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
UI_icon_draw(x, y, ICON_MOD_OCEAN); break;
case eModifierType_Warp:
UI_icon_draw(x, y, ICON_MOD_WARP); break;
default:
case eModifierType_Skin:
UI_icon_draw(x, y, ICON_MOD_SKIN); break;
/* Default */
case eModifierType_None:
case eModifierType_ShapeKey:
case NUM_MODIFIER_TYPES:
UI_icon_draw(x, y, ICON_DOT); break;
}
break;

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