svn merge ^/trunk/blender -r43564:43609

This commit is contained in:
Campbell Barton 2012-01-22 18:04:35 +00:00
commit 4966982a5a
142 changed files with 2474 additions and 830 deletions

@ -37,7 +37,8 @@ CHECKER_BIN = "cppcheck"
CHECKER_ARGS = [ CHECKER_ARGS = [
# not sure why this is needed, but it is. # not sure why this is needed, but it is.
"-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"), "-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"),
"--suppress=*:%s/extern/glew/include/GL/glew.h:241" % project_source_info.SOURCE_DIR,
# "--max-configs=1", # speeds up execution
# "--check-config", # when includes are missing # "--check-config", # when includes are missing
"--enable=all", # if you want sixty hundred pedantic suggestions "--enable=all", # if you want sixty hundred pedantic suggestions
] ]

@ -66,6 +66,12 @@ Game Types (bge.types)
:type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...} :type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
.. attribute:: active_events
A dictionary containing the status of only the active keyboard events or keys. (read-only).
:type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
.. class:: SCA_PythonMouse(PyObjectPlus) .. class:: SCA_PythonMouse(PyObjectPlus)
The current mouse. The current mouse.
@ -76,6 +82,12 @@ Game Types (bge.types)
:type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...} :type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...}
.. attribute:: active_events
a dictionary containing the status of only the active mouse events. (read-only).
:type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...}
.. attribute:: position .. attribute:: position
The normalized x and y position of the mouse cursor. The normalized x and y position of the mouse cursor.
@ -980,7 +992,7 @@ Game Types (bge.types)
.. attribute:: worldScale .. attribute:: worldScale
The object's world scaling factor. Read-only. [sx, sy, sz] The object's world scaling factor. [sx, sy, sz]
:type: :class:`mathutils.Vector` :type: :class:`mathutils.Vector`
@ -996,6 +1008,18 @@ Game Types (bge.types)
:type: :class:`mathutils.Vector` :type: :class:`mathutils.Vector`
.. attribute:: localTransform
The object's local space transform matrix. 4x4 Matrix.
:type: :class:`mathutils.Matrix`
.. attribute:: worldTransform
The object's world space transform matrix. 4x4 Matrix.
:type: :class:`mathutils.Matrix`
.. attribute:: localLinearVelocity .. attribute:: localLinearVelocity
The object's local linear velocity. [x, y, z] The object's local linear velocity. [x, y, z]

@ -33,78 +33,189 @@ from . import enums
class CyclesRenderSettings(bpy.types.PropertyGroup): class CyclesRenderSettings(bpy.types.PropertyGroup):
@classmethod @classmethod
def register(cls): def register(cls):
bpy.types.Scene.cycles = PointerProperty(type=cls, name="Cycles Render Settings", description="Cycles render settings") bpy.types.Scene.cycles = PointerProperty(
name="Cycles Render Settings",
description="Cycles render settings",
type=cls,
)
cls.device = EnumProperty(
name="Device",
description="Device to use for rendering",
items=enums.devices,
default='CPU',
)
cls.feature_set = EnumProperty(
name="Feature Set",
description="Feature set to use for rendering",
items=enums.feature_set,
default='SUPPORTED',
)
cls.shading_system = EnumProperty(
name="Shading System",
description="Shading system to use for rendering",
items=enums.shading_systems,
default='GPU_COMPATIBLE',
)
cls.device = EnumProperty(name="Device", description="Device to use for rendering", cls.samples = IntProperty(
items=enums.devices, default="CPU") name="Samples",
description="Number of samples to render for each pixel",
min=1, max=2147483647,
default=10,
)
cls.preview_samples = IntProperty(
name="Preview Samples",
description="Number of samples to render in the viewport, unlimited if 0",
min=0, max=2147483647,
default=10,
)
cls.preview_pause = BoolProperty(
name="Pause Preview",
description="Pause all viewport preview renders",
default=False,
)
cls.feature_set = EnumProperty(name="Feature Set", description="Feature set to use for rendering", cls.no_caustics = BoolProperty(
items=enums.feature_set, default="SUPPORTED") name="No Caustics",
description="Leave out caustics, resulting in a darker image with less noise",
default=False,
)
cls.blur_caustics = FloatProperty(
name="Blur Caustics",
description="Blur caustics to reduce noise",
min=0.0, max=1.0,
default=0.0,
)
cls.shading_system = EnumProperty(name="Shading System", description="Shading system to use for rendering", cls.min_bounces = IntProperty(
items=enums.shading_systems, default="GPU_COMPATIBLE") name="Min Bounces",
description="Minimum number of bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)",
min=0, max=1024,
default=3,
)
cls.max_bounces = IntProperty(
name="Max Bounces",
description="Total maximum number of bounces",
min=0, max=1024,
default=8,
)
cls.samples = IntProperty(name="Samples", description="Number of samples to render for each pixel", cls.diffuse_bounces = IntProperty(
default=10, min=1, max=2147483647) name="Diffuse Bounces",
cls.preview_samples = IntProperty(name="Preview Samples", description="Number of samples to render in the viewport, unlimited if 0", description="Maximum number of diffuse reflection bounces, bounded by total maximum",
default=10, min=0, max=2147483647) min=0, max=1024,
cls.preview_pause = BoolProperty(name="Pause Preview", description="Pause all viewport preview renders", default=128,
default=False) )
cls.glossy_bounces = IntProperty(
name="Glossy Bounces",
description="Maximum number of glossy reflection bounces, bounded by total maximum",
min=0, max=1024,
default=128,
)
cls.transmission_bounces = IntProperty(
name="Transmission Bounces",
description="Maximum number of transmission bounces, bounded by total maximum",
min=0, max=1024,
default=128,
)
cls.no_caustics = BoolProperty(name="No Caustics", description="Leave out caustics, resulting in a darker image with less noise", cls.transparent_min_bounces = IntProperty(
default=False) name="Transparent Min Bounces",
cls.blur_caustics = FloatProperty(name="Blur Caustics", description="Blur caustics to reduce noise", description="Minimum number of transparent bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)",
default=0.0, min=0.0, max=1.0) min=0, max=1024,
default=8,
)
cls.transparent_max_bounces = IntProperty(
name="Transparent Max Bounces",
description="Maximum number of transparent bounces",
min=0, max=1024,
default=8,
)
cls.use_transparent_shadows = BoolProperty(
name="Transparent Shadows",
description="Use transparency of surfaces for rendering shadows",
default=True,
)
cls.min_bounces = IntProperty(name="Min Bounces", description="Minimum number of bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)", cls.film_exposure = FloatProperty(
default=3, min=0, max=1024) name="Exposure",
cls.max_bounces = IntProperty(name="Max Bounces", description="Total maximum number of bounces", description="Image brightness scale",
default=8, min=0, max=1024) min=0.0, max=10.0,
default=1.0,
)
cls.film_transparent = BoolProperty(
name="Transparent",
description="World background is transparent",
default=False,
)
cls.diffuse_bounces = IntProperty(name="Diffuse Bounces", description="Maximum number of diffuse reflection bounces, bounded by total maximum", cls.filter_type = EnumProperty(
default=128, min=0, max=1024) name="Filter Type",
cls.glossy_bounces = IntProperty(name="Glossy Bounces", description="Maximum number of glossy reflection bounces, bounded by total maximum", description="Pixel filter type",
default=128, min=0, max=1024) items=enums.filter_types,
cls.transmission_bounces = IntProperty(name="Transmission Bounces", description="Maximum number of transmission bounces, bounded by total maximum", default='GAUSSIAN',
default=128, min=0, max=1024) )
cls.filter_width = FloatProperty(
name="Filter Width",
description="Pixel filter width",
min=0.01, max=10.0,
default=1.5,
)
cls.transparent_min_bounces = IntProperty(name="Transparent Min Bounces", description="Minimum number of transparent bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)", cls.seed = IntProperty(
default=8, min=0, max=1024) name="Seed",
cls.transparent_max_bounces = IntProperty(name="Transparent Max Bounces", description="Maximum number of transparent bounces", description="Seed value for integrator to get different noise patterns",
default=8, min=0, max=1024) min=0, max=2147483647,
cls.use_transparent_shadows = BoolProperty(name="Transparent Shadows", description="Use transparency of surfaces for rendering shadows", default=0,
default=True) )
cls.film_exposure = FloatProperty(name="Exposure", description="Image brightness scale", cls.debug_tile_size = IntProperty(
default=1.0, min=0.0, max=10.0) name="Tile Size",
cls.film_transparent = BoolProperty(name="Transparent", description="World background is transparent", description="",
default=False) min=1, max=4096,
default=1024,
)
cls.debug_min_size = IntProperty(
name="Min Size",
description="",
min=1, max=4096,
default=64,
)
cls.debug_reset_timeout = FloatProperty(
name="Reset timeout",
description="",
min=0.01, max=10.0,
default=0.1,
)
cls.debug_cancel_timeout = FloatProperty(
name="Cancel timeout",
description="",
min=0.01, max=10.0,
default=0.1,
)
cls.debug_text_timeout = FloatProperty(
name="Text timeout",
description="",
min=0.01, max=10.0,
default=1.0,
)
cls.filter_type = EnumProperty(name="Filter Type", description="Pixel filter type", cls.debug_bvh_type = EnumProperty(
items=enums.filter_types, default="GAUSSIAN") name="Viewport BVH Type",
cls.filter_width = FloatProperty(name="Filter Width", description="Pixel filter width", description="Choose between faster updates, or faster render",
default=1.5, min=0.01, max=10.0) items=enums.bvh_types,
default='DYNAMIC_BVH',
cls.seed = IntProperty(name="Seed", description="Seed value for integrator to get different noise patterns", )
default=0, min=0, max=2147483647) cls.debug_use_spatial_splits = BoolProperty(
name="Use Spatial Splits",
cls.debug_tile_size = IntProperty(name="Tile Size", description="", description="Use BVH spatial splits: longer builder time, faster render",
default=1024, min=1, max=4096) default=False,
cls.debug_min_size = IntProperty(name="Min Size", description="", )
default=64, min=1, max=4096) cls.use_cache = BoolProperty(
cls.debug_reset_timeout = FloatProperty(name="Reset timeout", description="", name="Cache BVH",
default=0.1, min=0.01, max=10.0) description="Cache last built BVH to disk for faster re-render if no geometry changed",
cls.debug_cancel_timeout = FloatProperty(name="Cancel timeout", description="", default=False,
default=0.1, min=0.01, max=10.0) )
cls.debug_text_timeout = FloatProperty(name="Text timeout", description="",
default=1.0, min=0.01, max=10.0)
cls.debug_bvh_type = EnumProperty(name="Viewport BVH Type", description="Choose between faster updates, or faster render",
items=enums.bvh_types, default="DYNAMIC_BVH")
cls.debug_use_spatial_splits = BoolProperty(name="Use Spatial Splits", description="Use BVH spatial splits: longer builder time, faster render",
default=False)
cls.use_cache = BoolProperty(name="Cache BVH", description="Cache last built BVH to disk for faster re-render if no geometry changed",
default=False)
@classmethod @classmethod
def unregister(cls): def unregister(cls):
@ -114,14 +225,31 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
class CyclesCameraSettings(bpy.types.PropertyGroup): class CyclesCameraSettings(bpy.types.PropertyGroup):
@classmethod @classmethod
def register(cls): def register(cls):
bpy.types.Camera.cycles = PointerProperty(type=cls, name="Cycles Camera Settings", description="Cycles camera settings") bpy.types.Camera.cycles = PointerProperty(
name="Cycles Camera Settings",
description="Cycles camera settings",
type=cls,
)
cls.aperture_size = FloatProperty(name="Aperture Size", description="Radius of the aperture for depth of field", cls.aperture_size = FloatProperty(
default=0.0, min=0.0, max=10.0) name="Aperture Size",
cls.aperture_blades = IntProperty(name="Aperture Blades", description="Number of blades in aperture for polygonal bokeh (at least 3)", description="Radius of the aperture for depth of field",
default=0, min=0, max=100) min=0.0, max=10.0,
cls.aperture_rotation = FloatProperty(name="Aperture Rotation", description="Rotation of blades in aperture", default=0.0,
default=0, soft_min=-math.pi, soft_max=math.pi, subtype='ANGLE') )
cls.aperture_blades = IntProperty(
name="Aperture Blades",
description="Number of blades in aperture for polygonal bokeh (at least 3)",
min=0, max=100,
default=0,
)
cls.aperture_rotation = FloatProperty(
name="Aperture Rotation",
description="Rotation of blades in aperture",
soft_min=-math.pi, soft_max=math.pi,
subtype='ANGLE',
default=0,
)
@classmethod @classmethod
def unregister(cls): def unregister(cls):
@ -131,9 +259,21 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
class CyclesMaterialSettings(bpy.types.PropertyGroup): class CyclesMaterialSettings(bpy.types.PropertyGroup):
@classmethod @classmethod
def register(cls): def register(cls):
bpy.types.Material.cycles = PointerProperty(type=cls, name="Cycles Material Settings", description="Cycles material settings") bpy.types.Material.cycles = PointerProperty(
cls.sample_as_light = BoolProperty(name="Sample as Lamp", description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources", default=True) name="Cycles Material Settings",
cls.homogeneous_volume = BoolProperty(name="Homogeneous Volume", description="When using volume rendering, assume volume has the same density everywhere, for faster rendering", default=False) description="Cycles material settings",
type=cls,
)
cls.sample_as_light = BoolProperty(
name="Sample as Lamp",
description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources",
default=True,
)
cls.homogeneous_volume = BoolProperty(
name="Homogeneous Volume",
description="When using volume rendering, assume volume has the same density everywhere, for faster rendering",
default=False,
)
@classmethod @classmethod
def unregister(cls): def unregister(cls):
@ -143,8 +283,16 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
class CyclesLampSettings(bpy.types.PropertyGroup): class CyclesLampSettings(bpy.types.PropertyGroup):
@classmethod @classmethod
def register(cls): def register(cls):
bpy.types.Lamp.cycles = PointerProperty(type=cls, name="Cycles Lamp Settings", description="Cycles lamp settings") bpy.types.Lamp.cycles = PointerProperty(
cls.cast_shadow = BoolProperty(name="Cast Shadow", description="Lamp casts shadows", default=True) name="Cycles Lamp Settings",
description="Cycles lamp settings",
type=cls,
)
cls.cast_shadow = BoolProperty(
name="Cast Shadow",
description="Lamp casts shadows",
default=True,
)
@classmethod @classmethod
def unregister(cls): def unregister(cls):
@ -154,7 +302,22 @@ class CyclesLampSettings(bpy.types.PropertyGroup):
class CyclesWorldSettings(bpy.types.PropertyGroup): class CyclesWorldSettings(bpy.types.PropertyGroup):
@classmethod @classmethod
def register(cls): def register(cls):
bpy.types.World.cycles = PointerProperty(type=cls, name="Cycles World Settings", description="Cycles world settings") bpy.types.World.cycles = PointerProperty(
name="Cycles World Settings",
description="Cycles world settings",
type=cls,
)
cls.sample_as_light = BoolProperty(
name="Sample as Lamp",
description="Use direct light sampling for the environment, enabling for non-solid colors is recommended",
default=False,
)
cls.sample_map_resolution = IntProperty(
name="Map Resolution",
description="Importance map size is resolution x resolution; higher values potentially produce less noise, at the cost of memory and speed",
min=4, max=8096,
default=256,
)
@classmethod @classmethod
def unregister(cls): def unregister(cls):
@ -164,13 +327,37 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
class CyclesVisibilitySettings(bpy.types.PropertyGroup): class CyclesVisibilitySettings(bpy.types.PropertyGroup):
@classmethod @classmethod
def register(cls): def register(cls):
bpy.types.Object.cycles_visibility = PointerProperty(type=cls, name="Cycles Visibility Settings", description="Cycles visibility settings") bpy.types.Object.cycles_visibility = PointerProperty(
name="Cycles Visibility Settings",
description="Cycles visibility settings",
type=cls,
)
cls.camera = BoolProperty(name="Camera", description="Object visibility for camera rays", default=True) cls.camera = BoolProperty(
cls.diffuse = BoolProperty(name="Diffuse", description="Object visibility for diffuse reflection rays", default=True) name="Camera",
cls.glossy = BoolProperty(name="Glossy", description="Object visibility for glossy reflection rays", default=True) description="Object visibility for camera rays",
cls.transmission = BoolProperty(name="Transmission", description="Object visibility for transmission rays", default=True) default=True,
cls.shadow = BoolProperty(name="Shadow", description="Object visibility for shadow rays", default=True) )
cls.diffuse = BoolProperty(
name="Diffuse",
description="Object visibility for diffuse reflection rays",
default=True,
)
cls.glossy = BoolProperty(
name="Glossy",
description="Object visibility for glossy reflection rays",
default=True,
)
cls.transmission = BoolProperty(
name="Transmission",
description="Object visibility for transmission rays",
default=True,
)
cls.shadow = BoolProperty(
name="Shadow",
description="Object visibility for shadow rays",
default=True,
)
@classmethod @classmethod
def unregister(cls): def unregister(cls):
@ -180,15 +367,39 @@ class CyclesVisibilitySettings(bpy.types.PropertyGroup):
class CyclesMeshSettings(bpy.types.PropertyGroup): class CyclesMeshSettings(bpy.types.PropertyGroup):
@classmethod @classmethod
def register(cls): def register(cls):
bpy.types.Mesh.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings") bpy.types.Mesh.cycles = PointerProperty(
bpy.types.Curve.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings") name="Cycles Mesh Settings",
bpy.types.MetaBall.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings") description="Cycles mesh settings",
type=cls,
)
bpy.types.Curve.cycles = PointerProperty(
name="Cycles Mesh Settings",
description="Cycles mesh settings",
type=cls,
)
bpy.types.MetaBall.cycles = PointerProperty(
name="Cycles Mesh Settings",
description="Cycles mesh settings",
type=cls,
)
cls.displacement_method = EnumProperty(name="Displacement Method", description="Method to use for the displacement", cls.displacement_method = EnumProperty(
items=enums.displacement_methods, default="BUMP") name="Displacement Method",
cls.use_subdivision = BoolProperty(name="Use Subdivision", description="Subdivide mesh for rendering", description="Method to use for the displacement",
default=False) items=enums.displacement_methods,
cls.dicing_rate = FloatProperty(name="Dicing Rate", description="", default=1.0, min=0.001, max=1000.0) default='BUMP',
)
cls.use_subdivision = BoolProperty(
name="Use Subdivision",
description="Subdivide mesh for rendering",
default=False,
)
cls.dicing_rate = FloatProperty(
name="Dicing Rate",
description="",
min=0.001, max=1000.0,
default=1.0,
)
@classmethod @classmethod
def unregister(cls): def unregister(cls):

@ -453,10 +453,38 @@ class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
layout = self.layout layout = self.layout
world = context.world world = context.world
if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'): if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
layout.prop(world, "horizon_color", text="Color") layout.prop(world, "horizon_color", text="Color")
class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
bl_label = "Settings"
bl_context = "world"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return context.world and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
world = context.world
cworld = world.cycles
split = layout.split()
col = split.column()
col.prop(cworld, "sample_as_light")
row = col.row()
row.active = cworld.sample_as_light
row.prop(cworld, "sample_map_resolution")
col = split.column()
col.label()
class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel): class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel):
bl_label = "Volume" bl_label = "Volume"
bl_context = "world" bl_context = "world"

@ -16,10 +16,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "graph.h"
#include "light.h" #include "light.h"
#include "mesh.h" #include "mesh.h"
#include "object.h" #include "object.h"
#include "scene.h" #include "scene.h"
#include "nodes.h"
#include "shader.h"
#include "blender_sync.h" #include "blender_sync.h"
#include "blender_util.h" #include "blender_util.h"
@ -152,6 +155,37 @@ void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob,
light->tag_update(scene); light->tag_update(scene);
} }
void BlenderSync::sync_background_light()
{
BL::World b_world = b_scene.world();
if(b_world) {
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
bool sample_as_light = get_boolean(cworld, "sample_as_light");
if(sample_as_light) {
/* test if we need to sync */
Light *light;
ObjectKey key(b_world, 0, b_world);
if(light_map.sync(&light, b_world, b_world, key) ||
world_recalc ||
b_world.ptr.data != world_map)
{
light->type = LIGHT_BACKGROUND;
light->map_resolution = get_int(cworld, "sample_map_resolution");
light->shader = scene->default_background;
light->tag_update(scene);
light_map.set_recalc(b_world);
}
}
}
world_map = b_world.ptr.data;
world_recalc = false;
}
/* Object */ /* Object */
void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag) void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag)
@ -263,6 +297,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
} }
} }
sync_background_light();
/* handle removed data and modified pointers */ /* handle removed data and modified pointers */
if(light_map.post_sync()) if(light_map.post_sync())
scene->light_manager->tag_update(scene); scene->light_manager->tag_update(scene);

@ -700,9 +700,6 @@ void BlenderSync::sync_world()
if(background->modified(prevbackground)) if(background->modified(prevbackground))
background->tag_update(scene); background->tag_update(scene);
world_map = b_world.ptr.data;
world_recalc = false;
} }
/* Sync Lamps */ /* Sync Lamps */

@ -80,6 +80,7 @@ private:
Mesh *sync_mesh(BL::Object b_ob, bool object_updated); Mesh *sync_mesh(BL::Object b_ob, bool object_updated);
void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag); void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag);
void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm); void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm);
void sync_background_light();
/* util */ /* util */
void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader); void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader);

@ -217,7 +217,7 @@ public:
#ifdef WITH_OPTIMIZED_KERNEL #ifdef WITH_OPTIMIZED_KERNEL
if(system_cpu_support_optimized()) { if(system_cpu_support_optimized()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_optimized_shader(kg, (uint4*)task.shader_input, (float3*)task.shader_output, task.shader_eval_type, x); kernel_cpu_optimized_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
if(tasks.worker_cancel()) if(tasks.worker_cancel())
break; break;
@ -227,7 +227,7 @@ public:
#endif #endif
{ {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_shader(kg, (uint4*)task.shader_input, (float3*)task.shader_output, task.shader_eval_type, x); kernel_cpu_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
if(tasks.worker_cancel()) if(tasks.worker_cancel())
break; break;

@ -80,7 +80,7 @@ __kernel void kernel_ocl_tonemap(
kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride); kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
} }
/*__kernel void kernel_ocl_shader(__global uint4 *input, __global float3 *output, int type, int sx) /*__kernel void kernel_ocl_shader(__global uint4 *input, __global float *output, int type, int sx)
{ {
int x = sx + get_global_id(0); int x = sx + get_global_id(0);

@ -218,7 +218,7 @@ void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sam
/* Shader Evaluation */ /* Shader Evaluation */
void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float3 *output, int type, int i) void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i)
{ {
kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i); kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i);
} }

@ -44,7 +44,7 @@ extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int
kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y, offset, stride); kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y, offset, stride);
} }
extern "C" __global__ void kernel_cuda_shader(uint4 *input, float3 *output, int type, int sx) extern "C" __global__ void kernel_cuda_shader(uint4 *input, float4 *output, int type, int sx)
{ {
int x = sx + blockDim.x*blockIdx.x + threadIdx.x; int x = sx + blockDim.x*blockIdx.x + threadIdx.x;

@ -40,7 +40,7 @@ void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_
int sample, int x, int y, int offset, int stride); int sample, int x, int y, int offset, int stride);
void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer,
int sample, int resolution, int x, int y, int offset, int stride); int sample, int resolution, int x, int y, int offset, int stride);
void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float3 *output, void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float4 *output,
int type, int i); int type, int i);
#ifdef WITH_OPTIMIZED_KERNEL #ifdef WITH_OPTIMIZED_KERNEL
@ -48,7 +48,7 @@ void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned
int sample, int x, int y, int offset, int stride); int sample, int x, int y, int offset, int stride);
void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer,
int sample, int resolution, int x, int y, int offset, int stride); int sample, int resolution, int x, int y, int offset, int stride);
void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float3 *output, void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float4 *output,
int type, int i); int type, int i);
#endif #endif

@ -141,6 +141,7 @@ template<typename T> struct texture_image {
}; };
typedef texture<float4> texture_float4; typedef texture<float4> texture_float4;
typedef texture<float2> texture_float2;
typedef texture<float> texture_float; typedef texture<float> texture_float;
typedef texture<uint> texture_uint; typedef texture<uint> texture_uint;
typedef texture<int> texture_int; typedef texture<int> texture_int;

@ -45,6 +45,7 @@
/* Textures */ /* Textures */
typedef texture<float4, 1> texture_float4; typedef texture<float4, 1> texture_float4;
typedef texture<float2, 1> texture_float2;
typedef texture<float, 1> texture_float; typedef texture<float, 1> texture_float;
typedef texture<uint, 1> texture_uint; typedef texture<uint, 1> texture_uint;
typedef texture<int, 1> texture_int; typedef texture<int, 1> texture_int;

@ -18,7 +18,7 @@
CCL_NAMESPACE_BEGIN CCL_NAMESPACE_BEGIN
__device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float3 *output, ShaderEvalType type, int i) __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *output, ShaderEvalType type, int i)
{ {
ShaderData sd; ShaderData sd;
uint4 in = input[i]; uint4 in = input[i];
@ -62,7 +62,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float3 *ou
} }
/* write output */ /* write output */
output[i] = out; output[i] = make_float4(out.x, out.y, out.z, 0.0f);
} }
CCL_NAMESPACE_END CCL_NAMESPACE_END

@ -25,7 +25,18 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
{ {
/* setup shading at emitter */ /* setup shading at emitter */
ShaderData sd; ShaderData sd;
float3 eval;
if(ls->type == LIGHT_BACKGROUND) {
Ray ray;
ray.D = ls->D;
ray.P = ls->P;
ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f);
ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f);
shader_setup_from_background(kg, &sd, &ray);
eval = shader_eval_background(kg, &sd, 0);
}
else {
shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v); shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v);
ls->Ng = sd.Ng; ls->Ng = sd.Ng;
@ -33,13 +44,12 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
we'd have to do multiple evaluations otherwise */ we'd have to do multiple evaluations otherwise */
shader_eval_surface(kg, &sd, rando, 0); shader_eval_surface(kg, &sd, rando, 0);
float3 eval;
/* evaluate emissive closure */ /* evaluate emissive closure */
if(sd.flag & SD_EMISSION) if(sd.flag & SD_EMISSION)
eval = shader_emissive_eval(kg, &sd); eval = shader_emissive_eval(kg, &sd);
else else
eval = make_float3(0.0f, 0.0f, 0.0f); eval = make_float3(0.0f, 0.0f, 0.0f);
}
shader_release(kg, &sd); shader_release(kg, &sd);
@ -51,25 +61,31 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
{ {
LightSample ls; LightSample ls;
float pdf = -1.0f;
#ifdef __MULTI_LIGHT__ #ifdef __MULTI_LIGHT__
if(lindex != -1) { if(lindex != -1) {
/* sample position on a specified light */ /* sample position on a specified light */
light_select(kg, lindex, randu, randv, sd->P, &ls); light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf);
} }
else else
#endif #endif
{ {
/* sample a light and position on int */ /* sample a light and position on int */
light_sample(kg, randt, randu, randv, sd->P, &ls); light_sample(kg, randt, randu, randv, sd->P, &ls, &pdf);
} }
/* compute pdf */ /* compute pdf */
float pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t); if(pdf < 0.0f)
pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t);
if(pdf == 0.0f)
return false;
/* evaluate closure */ /* evaluate closure */
*eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D); *eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D);
if(is_zero(*eval) || pdf == 0.0f) if(is_zero(*eval))
return false; return false;
/* todo: use visbility flag to skip lights */ /* todo: use visbility flag to skip lights */
@ -83,7 +99,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
if(is_zero(*eval)) if(is_zero(*eval))
return false; return false;
if(ls.prim != ~0) { if(ls.prim != ~0 || ls.type == LIGHT_BACKGROUND) {
/* multiple importance sampling */ /* multiple importance sampling */
float mis_weight = power_heuristic(pdf, bsdf_pdf); float mis_weight = power_heuristic(pdf, bsdf_pdf);
*eval *= mis_weight; *eval *= mis_weight;
@ -125,7 +141,8 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
float3 L = shader_emissive_eval(kg, sd); float3 L = shader_emissive_eval(kg, sd);
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) { if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
/* multiple importance sampling */ /* multiple importance sampling, get triangle light pdf,
and compute weight with respect to BSDF pdf */
float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t); float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t);
float mis_weight = power_heuristic(bsdf_pdf, pdf); float mis_weight = power_heuristic(bsdf_pdf, pdf);
@ -135,5 +152,34 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
return L; return L;
} }
/* Indirect Background */
__device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf)
{
#ifdef __BACKGROUND__
/* evaluate background closure */
ShaderData sd;
shader_setup_from_background(kg, &sd, ray);
float3 L = shader_eval_background(kg, &sd, path_flag);
shader_release(kg, &sd);
/* check if background light exists or if we should skip pdf */
int res = kernel_data.integrator.pdf_background_res;
if(!(path_flag & PATH_RAY_MIS_SKIP) && res) {
/* multiple importance sampling, get background light pdf for ray
direction, and compute weight with respect to BSDF pdf */
float pdf = background_light_pdf(kg, ray->D);
float mis_weight = power_heuristic(bsdf_pdf, pdf);
return L*mis_weight;
}
return L;
#else
return make_float3(0.8f, 0.8f, 0.8f);
#endif
}
CCL_NAMESPACE_END CCL_NAMESPACE_END

@ -26,6 +26,7 @@ typedef struct LightSample {
int object; int object;
int prim; int prim;
int shader; int shader;
LightType type;
} LightSample; } LightSample;
/* Regular Light */ /* Regular Light */
@ -58,13 +59,125 @@ __device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float
return axisu*randu + axisv*randv; return axisu*randu + axisv*randv;
} }
__device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
{
/* for the following, the CDF values are actually a pair of floats, with the
function value as X and the actual CDF as Y. The last entry's function
value is the CDF total. */
int res = kernel_data.integrator.pdf_background_res;
int cdf_count = res + 1;
/* this is basically std::lower_bound as used by pbrt */
int first = 0;
int count = res;
while(count > 0) {
int step = count >> 1;
int middle = first + step;
if(kernel_tex_fetch(__light_background_marginal_cdf, middle).y < randv) {
first = middle + 1;
count -= step + 1;
}
else
count = step;
}
int index_v = max(0, first - 1);
kernel_assert(index_v >= 0 && index_v < res);
float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1);
float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res);
/* importance-sampled V direction */
float dv = (randv - cdf_v.y) / (cdf_next_v.y - cdf_v.y);
float v = (index_v + dv) / res;
/* this is basically std::lower_bound as used by pbrt */
first = 0;
count = res;
while(count > 0) {
int step = count >> 1;
int middle = first + step;
if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + middle).y < randu) {
first = middle + 1;
count -= step + 1;
}
else
count = step;
}
int index_u = max(0, first - 1);
kernel_assert(index_u >= 0 && index_u < res);
float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u);
float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u + 1);
float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + res);
/* importance-sampled U direction */
float du = (randu - cdf_u.y) / (cdf_next_u.y - cdf_u.y);
float u = (index_u + du) / res;
/* spherical coordinates */
float theta = v * M_PI_F;
float phi = u * M_PI_F * 2.0f;
/* compute pdf */
float denom = cdf_last_u.x * cdf_last_v.x;
float sin_theta = sinf(theta);
if(sin_theta == 0.0f || denom == 0.0f)
*pdf = 0.0f;
else
*pdf = (cdf_u.x * cdf_v.x)/(2.0f * M_PI_F * M_PI_F * sin_theta * denom);
*pdf *= kernel_data.integrator.pdf_lights;
/* compute direction */
return spherical_to_direction(theta, phi);
}
__device float background_light_pdf(KernelGlobals *kg, float3 direction)
{
float2 uv = direction_to_equirectangular(direction);
int res = kernel_data.integrator.pdf_background_res;
float sin_theta = sinf(uv.y * M_PI_F);
if(sin_theta == 0.0f)
return 0.0f;
int index_u = clamp((int)(uv.x * res), 0, res - 1);
int index_v = clamp((int)(uv.y * res), 0, res - 1);
/* pdfs in V direction */
float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + res);
float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res);
float denom = cdf_last_u.x * cdf_last_v.x;
if(denom == 0.0f)
return 0.0f;
/* pdfs in U direction */
float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + index_u);
float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
float pdf = (cdf_u.x * cdf_v.x)/(2.0f * M_PI_F * M_PI_F * sin_theta * denom);
return pdf * kernel_data.integrator.pdf_lights;
}
__device void regular_light_sample(KernelGlobals *kg, int point, __device void regular_light_sample(KernelGlobals *kg, int point,
float randu, float randv, float3 P, LightSample *ls) float randu, float randv, float3 P, LightSample *ls, float *pdf)
{ {
float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0); float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0);
float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1); float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1);
LightType type = (LightType)__float_as_int(data0.x); LightType type = (LightType)__float_as_int(data0.x);
ls->type = type;
if(type == LIGHT_DISTANT) { if(type == LIGHT_DISTANT) {
/* distant light */ /* distant light */
@ -79,6 +192,15 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
ls->D = -D; ls->D = -D;
ls->t = FLT_MAX; ls->t = FLT_MAX;
} }
else if(type == LIGHT_BACKGROUND) {
/* infinite area light (e.g. light dome or env light) */
float3 D = background_light_sample(kg, randu, randv, pdf);
ls->P = D;
ls->Ng = D;
ls->D = -D;
ls->t = FLT_MAX;
}
else { else {
ls->P = make_float3(data0.y, data0.z, data0.w); ls->P = make_float3(data0.y, data0.z, data0.w);
@ -139,6 +261,7 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
ls->object = object; ls->object = object;
ls->prim = prim; ls->prim = prim;
ls->t = 0.0f; ls->t = 0.0f;
ls->type = LIGHT_AREA;
#ifdef __INSTANCING__ #ifdef __INSTANCING__
/* instance transform */ /* instance transform */
@ -192,7 +315,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
/* Generic Light */ /* Generic Light */
__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls) __device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls, float *pdf)
{ {
/* sample index */ /* sample index */
int index = light_distribution_sample(kg, randt); int index = light_distribution_sample(kg, randt);
@ -207,7 +330,7 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
} }
else { else {
int point = -prim-1; int point = -prim-1;
regular_light_sample(kg, point, randu, randv, P, ls); regular_light_sample(kg, point, randu, randv, P, ls, pdf);
} }
/* compute incoming direction and distance */ /* compute incoming direction and distance */
@ -227,9 +350,9 @@ __device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, fl
return pdf; return pdf;
} }
__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls) __device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf)
{ {
regular_light_sample(kg, index, randu, randv, P, ls); regular_light_sample(kg, index, randu, randv, P, ls, pdf);
} }
__device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t) __device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)

@ -203,6 +203,28 @@ __device float3 spherical_to_direction(float theta, float phi)
cosf(theta)); cosf(theta));
} }
/* Equirectangular */
__device float2 direction_to_equirectangular(float3 dir)
{
float u = (atan2f(dir.y, dir.x) + M_PI_F)/(2.0f*M_PI_F);
float v = atan2f(dir.z, hypotf(dir.x, dir.y))/M_PI_F + 0.5f;
return make_float2(u, v);
}
__device float3 equirectangular_to_direction(float u, float v)
{
/* XXX check correctness? */
float theta = M_PI_F*v;
float phi = 2.0f*M_PI_F*u;
return make_float3(
sin(theta)*cos(phi),
sin(theta)*sin(phi),
cos(theta));
}
CCL_NAMESPACE_END CCL_NAMESPACE_END
#endif /* __KERNEL_MONTECARLO_CL__ */ #endif /* __KERNEL_MONTECARLO_CL__ */

@ -49,7 +49,7 @@ void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffe
/* Shader Evaluate */ /* Shader Evaluate */
void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float3 *output, int type, int i) void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i)
{ {
kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i); kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i);
} }

@ -260,14 +260,9 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
Ltransparent += average(throughput); Ltransparent += average(throughput);
} }
else { else {
#ifdef __BACKGROUND__ /* sample background shader */
ShaderData sd; float3 background_L = indirect_background(kg, &ray, state.flag, ray_pdf);
shader_setup_from_background(kg, &sd, &ray); L += throughput*background_L;
L += throughput*shader_eval_background(kg, &sd, state.flag);
shader_release(kg, &sd);
#else
L += throughput*make_float3(0.8f, 0.8f, 0.8f);
#endif
} }
break; break;
@ -362,7 +357,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
throughput *= bsdf_eval/bsdf_pdf; throughput *= bsdf_eval/bsdf_pdf;
/* set labels */ /* set labels */
#ifdef __EMISSION__ #if defined(__EMISSION__) || defined(__BACKGROUND__)
ray_pdf = bsdf_pdf; ray_pdf = bsdf_pdf;
#endif #endif

@ -33,6 +33,8 @@ KERNEL_TEX(float4, texture_float4, __attributes_float3)
/* lights */ /* lights */
KERNEL_TEX(float4, texture_float4, __light_distribution) KERNEL_TEX(float4, texture_float4, __light_distribution)
KERNEL_TEX(float4, texture_float4, __light_data) KERNEL_TEX(float4, texture_float4, __light_data)
KERNEL_TEX(float2, texture_float2, __light_background_marginal_cdf)
KERNEL_TEX(float2, texture_float2, __light_background_conditional_cdf)
/* shaders */ /* shaders */
KERNEL_TEX(uint4, texture_uint4, __svm_nodes) KERNEL_TEX(uint4, texture_uint4, __svm_nodes)

@ -165,6 +165,7 @@ typedef enum ShaderFlag {
typedef enum LightType { typedef enum LightType {
LIGHT_POINT, LIGHT_POINT,
LIGHT_DISTANT, LIGHT_DISTANT,
LIGHT_BACKGROUND,
LIGHT_AREA LIGHT_AREA
} LightType; } LightType;
@ -379,6 +380,7 @@ typedef struct KernelIntegrator {
int num_all_lights; int num_all_lights;
float pdf_triangles; float pdf_triangles;
float pdf_lights; float pdf_lights;
int pdf_background_res;
/* bounces */ /* bounces */
int min_bounce; int min_bounce;

@ -175,9 +175,8 @@ __device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float
decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
float3 co = stack_load_float3(stack, co_offset); float3 co = stack_load_float3(stack, co_offset);
float u = (atan2f(co.y, co.x) + M_PI_F)/(2*M_PI_F); float2 uv = direction_to_equirectangular(co);
float v = atan2f(co.z, hypotf(co.x, co.y))/M_PI_F + 0.5f; float4 f = svm_image_texture(kg, id, uv.x, uv.y);
float4 f = svm_image_texture(kg, id, u, v);
float3 r = make_float3(f.x, f.y, f.z); float3 r = make_float3(f.x, f.y, f.z);
if(srgb) { if(srgb) {

@ -26,8 +26,74 @@
#include "util_foreach.h" #include "util_foreach.h"
#include "util_progress.h" #include "util_progress.h"
#include "kernel_montecarlo.h"
CCL_NAMESPACE_BEGIN CCL_NAMESPACE_BEGIN
static void dump_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels)
{
/* create input */
int width = res;
int height = res;
device_vector<uint4> d_input;
device_vector<float4> d_output;
uint4 *d_input_data = d_input.resize(width*height);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
float u = x/(float)width;
float v = y/(float)height;
float3 D = -equirectangular_to_direction(u, v);
uint4 in = make_uint4(__float_as_int(D.x), __float_as_int(D.y), __float_as_int(D.z), 0);
d_input_data[x + y*width] = in;
}
}
/* compute on device */
float4 *d_output_data = d_output.resize(width*height);
memset((void*)d_output.data_pointer, 0, d_output.memory_size());
device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
device->mem_alloc(d_input, MEM_READ_ONLY);
device->mem_copy_to(d_input);
device->mem_alloc(d_output, MEM_WRITE_ONLY);
DeviceTask main_task(DeviceTask::SHADER);
main_task.shader_input = d_input.device_pointer;
main_task.shader_output = d_output.device_pointer;
main_task.shader_eval_type = SHADER_EVAL_BACKGROUND;
main_task.shader_x = 0;
main_task.shader_w = width*height;
list<DeviceTask> split_tasks;
main_task.split_max_size(split_tasks, 128*128);
foreach(DeviceTask& task, split_tasks) {
device->task_add(task);
device->task_wait();
}
device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
device->mem_free(d_input);
device->mem_free(d_output);
d_output_data = reinterpret_cast<float4*>(d_output.data_pointer);
pixels.resize(width*height);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
pixels[y*width + x].x = d_output_data[y*width + x].x;
pixels[y*width + x].y = d_output_data[y*width + x].y;
pixels[y*width + x].z = d_output_data[y*width + x].z;
}
}
}
/* Light */ /* Light */
Light::Light() Light::Light()
@ -44,6 +110,8 @@ Light::Light()
axisv = make_float3(0.0f, 0.0f, 0.0f); axisv = make_float3(0.0f, 0.0f, 0.0f);
sizev = 1.0f; sizev = 1.0f;
map_resolution = 512;
cast_shadow = true; cast_shadow = true;
shader = 0; shader = 0;
} }
@ -66,6 +134,8 @@ LightManager::~LightManager()
void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{ {
progress.set_status("Updating Lights", "Computing distribution");
/* option to always sample all point lights */ /* option to always sample all point lights */
bool multi_light = false; bool multi_light = false;
@ -232,6 +302,99 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
dscene->light_distribution.clear(); dscene->light_distribution.clear();
} }
void LightManager::device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
KernelIntegrator *kintegrator = &dscene->data.integrator;
Light *background_light = NULL;
/* find background light */
foreach(Light *light, scene->lights) {
if(light->type == LIGHT_BACKGROUND) {
background_light = light;
break;
}
}
/* no background light found, signal renderer to skip sampling */
if(!background_light) {
kintegrator->pdf_background_res = 0;
return;
}
progress.set_status("Updating Lights", "Importance map");
assert(kintegrator->use_direct_light);
/* get the resolution from the light's size (we stuff it in there) */
int res = background_light->map_resolution;
kintegrator->pdf_background_res = res;
assert(res > 0);
vector<float3> pixels;
dump_background_pixels(device, dscene, res, pixels);
if(progress.get_cancel())
return;
/* build row distributions and column distribution for the infinite area environment light */
int cdf_count = res + 1;
float2 *marg_cdf = dscene->light_background_marginal_cdf.resize(cdf_count);
float2 *cond_cdf = dscene->light_background_conditional_cdf.resize(cdf_count * cdf_count);
/* conditional CDFs (rows, U direction) */
for(int i = 0; i < res; i++) {
float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
float3 env_color = pixels[i * res];
float ave_luminamce = average(env_color);
cond_cdf[i * cdf_count].x = ave_luminamce * sin_theta;
cond_cdf[i * cdf_count].y = 0.0f;
for(int j = 1; j < res; j++) {
env_color = pixels[i * res + j];
ave_luminamce = average(env_color);
cond_cdf[i * cdf_count + j].x = ave_luminamce * sin_theta;
cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
}
float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res;
/* stuff the total into the brightness value for the last entry, because
we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
cond_cdf[i * cdf_count + res].x = cdf_total;
if(cdf_total > 0.0f)
for(int j = 1; j < res; j++)
cond_cdf[i * cdf_count + j].y /= cdf_total;
cond_cdf[i * cdf_count + res].y = 1.0f;
}
/* marginal CDFs (column, V direction, sum of rows) */
marg_cdf[0].x = cond_cdf[res].x;
marg_cdf[0].y = 0.0f;
for(int i = 1; i < res; i++) {
marg_cdf[i].x = cond_cdf[i * cdf_count + res].x;
marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res;
}
float cdf_total = marg_cdf[res - 1].y + marg_cdf[res - 1].x / res;
marg_cdf[res].x = cdf_total;
if(cdf_total > 0.0f)
for(int i = 1; i < res; i++)
marg_cdf[i].y /= cdf_total;
marg_cdf[res].y = 1.0f;
/* update device */
device->tex_alloc("__light_background_marginal_cdf", dscene->light_background_marginal_cdf);
device->tex_alloc("__light_background_conditional_cdf", dscene->light_background_conditional_cdf);
}
void LightManager::device_update_points(Device *device, DeviceScene *dscene, Scene *scene) void LightManager::device_update_points(Device *device, DeviceScene *dscene, Scene *scene)
{ {
if(scene->lights.size() == 0) if(scene->lights.size() == 0)
@ -264,6 +427,14 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
} }
else if(light->type == LIGHT_BACKGROUND) {
shader_id &= ~SHADER_AREA_LIGHT;
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_AREA) { else if(light->type == LIGHT_AREA) {
float3 axisu = light->axisu*(light->sizeu*light->size); float3 axisu = light->axisu*(light->sizeu*light->size);
float3 axisv = light->axisv*(light->sizev*light->size); float3 axisv = light->axisv*(light->sizev*light->size);
@ -291,6 +462,9 @@ void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *sce
device_update_distribution(device, dscene, scene, progress); device_update_distribution(device, dscene, scene, progress);
if(progress.get_cancel()) return; if(progress.get_cancel()) return;
device_update_background(device, dscene, scene, progress);
if(progress.get_cancel()) return;
need_update = false; need_update = false;
} }
@ -298,9 +472,13 @@ void LightManager::device_free(Device *device, DeviceScene *dscene)
{ {
device->tex_free(dscene->light_distribution); device->tex_free(dscene->light_distribution);
device->tex_free(dscene->light_data); device->tex_free(dscene->light_data);
device->tex_free(dscene->light_background_marginal_cdf);
device->tex_free(dscene->light_background_conditional_cdf);
dscene->light_distribution.clear(); dscene->light_distribution.clear();
dscene->light_data.clear(); dscene->light_data.clear();
dscene->light_background_marginal_cdf.clear();
dscene->light_background_conditional_cdf.clear();
} }
void LightManager::tag_update(Scene *scene) void LightManager::tag_update(Scene *scene)

@ -46,6 +46,8 @@ public:
float3 axisv; float3 axisv;
float sizev; float sizev;
int map_resolution;
bool cast_shadow; bool cast_shadow;
int shader; int shader;
@ -68,6 +70,7 @@ public:
protected: protected:
void device_update_points(Device *device, DeviceScene *dscene, Scene *scene); void device_update_points(Device *device, DeviceScene *dscene, Scene *scene);
void device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
}; };
CCL_NAMESPACE_END CCL_NAMESPACE_END

@ -89,7 +89,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
return false; return false;
/* run device task */ /* run device task */
device_vector<float3> d_output; device_vector<float4> d_output;
d_output.resize(d_input.size()); d_output.resize(d_input.size());
device->mem_alloc(d_input, MEM_READ_ONLY); device->mem_alloc(d_input, MEM_READ_ONLY);
@ -106,7 +106,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
device->task_add(task); device->task_add(task);
device->task_wait(); device->task_wait();
device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float3)); device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
device->mem_free(d_input); device->mem_free(d_input);
device->mem_free(d_output); device->mem_free(d_output);
@ -118,7 +118,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
done.resize(mesh->verts.size(), false); done.resize(mesh->verts.size(), false);
int k = 0; int k = 0;
float3 *offset = (float3*)d_output.data_pointer; float4 *offset = (float4*)d_output.data_pointer;
for(size_t i = 0; i < mesh->triangles.size(); i++) { for(size_t i = 0; i < mesh->triangles.size(); i++) {
Mesh::Triangle t = mesh->triangles[i]; Mesh::Triangle t = mesh->triangles[i];
@ -130,7 +130,8 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
for(int j = 0; j < 3; j++) { for(int j = 0; j < 3; j++) {
if(!done[t.v[j]]) { if(!done[t.v[j]]) {
done[t.v[j]] = true; done[t.v[j]] = true;
mesh->verts[t.v[j]] += offset[k++]; float3 off = float4_to_float3(offset[k++]);
mesh->verts[t.v[j]] += off;
} }
} }
} }

@ -78,6 +78,8 @@ public:
/* lights */ /* lights */
device_vector<float4> light_distribution; device_vector<float4> light_distribution;
device_vector<float4> light_data; device_vector<float4> light_data;
device_vector<float2> light_background_marginal_cdf;
device_vector<float2> light_background_conditional_cdf;
/* shaders */ /* shaders */
device_vector<uint4> svm_nodes; device_vector<uint4> svm_nodes;

@ -79,6 +79,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
sub = col.column(align=True) sub = col.column(align=True)
sub.prop(fluid, "start_time", text="Start") sub.prop(fluid, "start_time", text="Start")
sub.prop(fluid, "end_time", text="End") sub.prop(fluid, "end_time", text="End")
col.prop(fluid, "simulation_rate", text="Speed")
col = split.column() col = split.column()
col.label() col.label()
@ -230,6 +231,10 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel):
if fluid.viscosity_preset == 'MANUAL': if fluid.viscosity_preset == 'MANUAL':
sub.prop(fluid, "viscosity_base", text="Base") sub.prop(fluid, "viscosity_base", text="Base")
sub.prop(fluid, "viscosity_exponent", text="Exponent", slider=True) sub.prop(fluid, "viscosity_exponent", text="Exponent", slider=True)
else:
# just for padding to prevent jumping around
sub.separator()
sub.separator()
col.label(text="Optimization:") col.label(text="Optimization:")
col.prop(fluid, "grid_levels", slider=True) col.prop(fluid, "grid_levels", slider=True)

@ -526,9 +526,9 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
if brush.use_space and tool != 'SMOOTH': if brush.use_space and tool != 'SMOOTH':
if brush.use_space_atten: if brush.use_space_atten:
row.prop(brush, "use_space_atten", toggle=True, icon='LOCKED') row.prop(brush, "use_space_atten", toggle=True, text="", icon='LOCKED')
else: else:
row.prop(brush, "use_space_atten", toggle=True, icon='UNLOCKED') row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED')
self.prop_unified_strength(row, context, brush, "strength", text="Strength") self.prop_unified_strength(row, context, brush, "strength", text="Strength")
self.prop_unified_strength(row, context, brush, "use_pressure_strength") self.prop_unified_strength(row, context, brush, "use_pressure_strength")

@ -86,7 +86,7 @@ int bone_autoside_name (char name[64], int strip_number, short axis, float head,
struct Bone *get_named_bone (struct bArmature *arm, const char *name); struct Bone *get_named_bone (struct bArmature *arm, const char *name);
float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist); float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float rad1, float rad2, float rdist);
void where_is_armature (struct bArmature *arm); void where_is_armature (struct bArmature *arm);
void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone); void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone);

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

@ -53,7 +53,7 @@ typedef struct Global {
struct Main *main; struct Main *main;
/* strings: lastsaved */ /* strings: lastsaved */
char ima[256], lib[256]; char ima[1024], lib[1024]; /* 1024 = FILE_MAX */
/* flag: if != 0 G.main->name contains valid relative base path */ /* flag: if != 0 G.main->name contains valid relative base path */
int relbase_valid; int relbase_valid;

@ -50,7 +50,7 @@ struct Library;
typedef struct Main { typedef struct Main {
struct Main *next, *prev; struct Main *next, *prev;
char name[240]; /* 240 = FILE_MAX */ char name[1024]; /* 1024 = FILE_MAX */
short versionfile, subversionfile; short versionfile, subversionfile;
short minversionfile, minsubversionfile; short minversionfile, minsubversionfile;
int revision; /* svn revision of binary that saved file */ int revision; /* svn revision of binary that saved file */

@ -43,9 +43,9 @@ extern "C" {
/* these values need to be hardcoded in structs, dna does not recognize defines */ /* these values need to be hardcoded in structs, dna does not recognize defines */
/* also defined in DNA_space_types.h */ /* also defined in DNA_space_types.h */
#ifndef FILE_MAXDIR #ifndef FILE_MAXDIR
#define FILE_MAXDIR 160 #define FILE_MAXDIR 768
#define FILE_MAXFILE 80 #define FILE_MAXFILE 256
#define FILE_MAX 240 #define FILE_MAX 1024
#endif #endif
/* this weirdo pops up in two places ... */ /* this weirdo pops up in two places ... */

@ -665,7 +665,7 @@ static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float *co, Dua
} }
/* using vec with dist to bone b1 - b2 */ /* using vec with dist to bone b1 - b2 */
float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist) float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float rad1, float rad2, float rdist)
{ {
float dist=0.0f; float dist=0.0f;
float bdelta[3]; float bdelta[3];
@ -677,17 +677,17 @@ float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, fl
sub_v3_v3v3(pdelta, vec, b1); sub_v3_v3v3(pdelta, vec, b1);
a = bdelta[0]*pdelta[0] + bdelta[1]*pdelta[1] + bdelta[2]*pdelta[2]; a = dot_v3v3(bdelta, pdelta);
hsqr = ((pdelta[0]*pdelta[0]) + (pdelta[1]*pdelta[1]) + (pdelta[2]*pdelta[2])); hsqr = dot_v3v3(pdelta, pdelta);
if (a < 0.0F){ if (a < 0.0f) {
/* If we're past the end of the bone, do a spherical field attenuation thing */ /* If we're past the end of the bone, do a spherical field attenuation thing */
dist= ((b1[0]-vec[0])*(b1[0]-vec[0]) +(b1[1]-vec[1])*(b1[1]-vec[1]) +(b1[2]-vec[2])*(b1[2]-vec[2])) ; dist = len_squared_v3v3(b1, vec);
rad= rad1; rad= rad1;
} }
else if (a > l) { else if (a > l) {
/* If we're past the end of the bone, do a spherical field attenuation thing */ /* If we're past the end of the bone, do a spherical field attenuation thing */
dist= ((b2[0]-vec[0])*(b2[0]-vec[0]) +(b2[1]-vec[1])*(b2[1]-vec[1]) +(b2[2]-vec[2])*(b2[2]-vec[2])) ; dist = len_squared_v3v3(b2, vec);
rad = rad2; rad = rad2;
} }
else { else {
@ -709,7 +709,7 @@ float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, fl
if(rdist==0.0f || dist >= l) if(rdist==0.0f || dist >= l)
return 0.0f; return 0.0f;
else { else {
a= (float)sqrt(dist)-rad; a = sqrtf(dist)-rad;
return 1.0f-( a*a )/( rdist*rdist ); return 1.0f-( a*a )/( rdist*rdist );
} }
} }

@ -2777,13 +2777,14 @@ static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
/* store Z orientation before destroying obmat */ /* store Z orientation before destroying obmat */
normalize_v3_v3(zz, cob->matrix[2]); normalize_v3_v3(zz, cob->matrix[2]);
sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]); dist = len_v3v3(cob->matrix[3], ct->matrix[3]);
vec[0] /= size[0]; /* XXX What was all that for??? Makes the constraint buggy with scaled objects, see #29940. */
vec[1] /= size[1]; /* sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);*/
vec[2] /= size[2]; /* vec[0] /= size[0];*/
/* vec[1] /= size[1];*/
/* vec[2] /= size[2];*/
dist = normalize_v3(vec); /* dist = normalize_v3(vec);*/
//dist = len_v3v3( ob->obmat[3], targetmat[3]);
/* data->orglength==0 occurs on first run, and after 'R' button is clicked */ /* data->orglength==0 occurs on first run, and after 'R' button is clicked */
if (data->orglength == 0) if (data->orglength == 0)

@ -368,8 +368,7 @@ void tex_space_curve(Curve *cu)
dl= cu->disp.first; dl= cu->disp.first;
while(dl) { while(dl) {
if(dl->type==DL_INDEX3 || dl->type==DL_INDEX3) tot= dl->nr; tot = ELEM(dl->type, DL_INDEX3, DL_INDEX4) ? dl->nr : dl->nr * dl->parts;
else tot= dl->nr*dl->parts;
if(tot) doit= 1; if(tot) doit= 1;
fp= dl->verts; fp= dl->verts;

@ -188,11 +188,12 @@ typedef struct ImgSeqFormatData {
Vec3f *barycentricWeights; /* b-weights for all pixel samples */ Vec3f *barycentricWeights; /* b-weights for all pixel samples */
} ImgSeqFormatData; } ImgSeqFormatData;
#if 0 /* UNUSED */
typedef struct EffVelPoint { typedef struct EffVelPoint {
float previous_pos[3]; float previous_pos[3];
float previous_vel[3]; float previous_vel[3];
} EffVelPoint; } EffVelPoint;
#endif
/* adjacency data flags */ /* adjacency data flags */
#define ADJ_ON_MESH_EDGE (1<<0) #define ADJ_ON_MESH_EDGE (1<<0)

@ -1111,9 +1111,9 @@ int BKE_add_image_extension(char *string, const char imtype)
if(BLI_testextensie_array(string, imb_ext_image) if(BLI_testextensie_array(string, imb_ext_image)
|| (G.have_quicktime && BLI_testextensie_array(string, imb_ext_image_qt))) { || (G.have_quicktime && BLI_testextensie_array(string, imb_ext_image_qt))) {
return BLI_replace_extension(string, FILE_MAX, extension); return BLI_replace_extension(string, FILE_MAX, extension);
} else { }
else {
return BLI_ensure_extension(string, FILE_MAX, extension); return BLI_ensure_extension(string, FILE_MAX, extension);
return TRUE;
} }
} }

@ -981,7 +981,7 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
{ {
char name[FILE_MAX]; char name[FILE_MAX];
int quality, rectx, recty; int quality, rectx, recty;
int size= size= rendersize_to_number(proxy_render_size); int size= rendersize_to_number(proxy_render_size);
ImBuf *scaleibuf; ImBuf *scaleibuf;
get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name); get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name);

@ -1448,9 +1448,17 @@ void BKE_nla_validate_state (AnimData *adt)
*/ */
// TODO: 1 solution is to tie this in with auto-blending... // TODO: 1 solution is to tie this in with auto-blending...
if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) { if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
/* 1) First strip must be set to extend hold, otherwise, stuff before acts dodgy
* 2) Only overwrite extend mode if *not* changing it will most probably result in
* occlusion problems, which will occur iff
* - blendmode = REPLACE
* - all channels the same (this is fiddly to test, so is currently assumed)
*
* Should fix problems such as [#29869]
*/
if (strip == fstrip) if (strip == fstrip)
strip->extendmode= NLASTRIP_EXTEND_HOLD; strip->extendmode= NLASTRIP_EXTEND_HOLD;
else else if (strip->blendmode == NLASTRIP_MODE_REPLACE)
strip->extendmode= NLASTRIP_EXTEND_HOLD_FORWARD; strip->extendmode= NLASTRIP_EXTEND_HOLD_FORWARD;
} }
} }
@ -1542,6 +1550,34 @@ short BKE_nla_tweakmode_enter (AnimData *adt)
break; break;
} }
} }
/* There are situations where we may have multiple strips selected and we want to enter tweakmode on all
* of those at once. Usually in those cases, it will usually just be a single strip per AnimData.
* In such cases, compromise and take the last selected track and/or last selected strip [#28468]
*/
if (activeTrack == NULL) {
/* try last selected track for active strip */
for (nlt = adt->nla_tracks.last; nlt; nlt = nlt->prev) {
if (nlt->flag & NLATRACK_SELECTED) {
/* assume this is the active track */
activeTrack= nlt;
/* try to find active strip */
activeStrip= BKE_nlastrip_find_active(nlt);
break;
}
}
}
if ((activeTrack) && (activeStrip == NULL)) {
/* no active strip in active or last selected track; compromise for first selected (assuming only single)... */
for (strip = activeTrack->strips.first; strip; strip= strip->next) {
if (strip->flag & (NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_ACTIVE)) {
activeStrip = strip;
break;
}
}
}
if ELEM3(NULL, activeTrack, activeStrip, activeStrip->act) { if ELEM3(NULL, activeTrack, activeStrip, activeStrip->act) {
if (G.f & G_DEBUG) { if (G.f & G_DEBUG) {
printf("NLA tweakmode enter - neither active requirement found \n"); printf("NLA tweakmode enter - neither active requirement found \n");

@ -100,6 +100,7 @@ static void arena_release(CCGAllocatorHDL a) {
typedef enum { typedef enum {
CCG_USE_AGING = 1, CCG_USE_AGING = 1,
CCG_USE_ARENA = 2, CCG_USE_ARENA = 2,
CCG_CALC_NORMALS = 4,
} CCGFlags; } CCGFlags;
static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags flags) { static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags flags) {
@ -130,7 +131,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags fl
} else { } else {
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8; ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
} }
ifc.vertDataSize = sizeof(DMGridData); ifc.vertDataSize = sizeof(float) * (flags & CCG_CALC_NORMALS ? 6 : 3);
if (useArena) { if (useArena) {
CCGAllocatorIFC allocatorIFC; CCGAllocatorIFC allocatorIFC;
@ -150,7 +151,10 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags fl
ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8); ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
} }
if (flags & CCG_CALC_NORMALS)
ccgSubSurf_setCalcVertexNormals(ccgSS, 1, offsetof(DMGridData, no)); ccgSubSurf_setCalcVertexNormals(ccgSS, 1, offsetof(DMGridData, no));
else
ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0);
return ccgSS; return ccgSS;
} }
@ -380,14 +384,14 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
int numVerts = ccgSubSurf_getFaceNumVerts(f); int numVerts = ccgSubSurf_getFaceNumVerts(f);
for (S=0; S<numVerts; S++) { for (S=0; S<numVerts; S++) {
DMGridData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S); float (*faceGridData)[3]= ccgSubSurf_getFaceGridDataArray(uvss, f, S);
for(y = 0; y < gridFaces; y++) { for(y = 0; y < gridFaces; y++) {
for(x = 0; x < gridFaces; x++) { for(x = 0; x < gridFaces; x++) {
float *a = faceGridData[(y + 0)*gridSize + x + 0].co; float *a = faceGridData[(y + 0)*gridSize + x + 0];
float *b = faceGridData[(y + 0)*gridSize + x + 1].co; float *b = faceGridData[(y + 0)*gridSize + x + 1];
float *c = faceGridData[(y + 1)*gridSize + x + 1].co; float *c = faceGridData[(y + 1)*gridSize + x + 1];
float *d = faceGridData[(y + 1)*gridSize + x + 0].co; float *d = faceGridData[(y + 1)*gridSize + x + 0];
if (tface) { if (tface) {
tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1]; tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1];
@ -3259,7 +3263,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
if(forEditMode) { if(forEditMode) {
int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels; int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
smd->emCache = _getSubSurf(smd->emCache, levels, useAging); smd->emCache = _getSubSurf(smd->emCache, levels, useAging|CCG_CALC_NORMALS);
ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple); ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
result = getCCGDerivedMesh(smd->emCache, result = getCCGDerivedMesh(smd->emCache,
@ -3273,7 +3277,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
if(levels == 0) if(levels == 0)
return dm; return dm;
ss = _getSubSurf(NULL, levels, CCG_USE_ARENA); ss = _getSubSurf(NULL, levels, CCG_USE_ARENA|CCG_CALC_NORMALS);
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
@ -3303,7 +3307,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
} }
if(useIncremental && isFinalCalc) { if(useIncremental && isFinalCalc) {
smd->mCache = ss = _getSubSurf(smd->mCache, levels, useAging); smd->mCache = ss = _getSubSurf(smd->mCache, levels, useAging|CCG_CALC_NORMALS);
if (!ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple)) { if (!ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple)) {
//ccgSubSurf_free(smd->mCache); //ccgSubSurf_free(smd->mCache);
@ -3322,7 +3326,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
smd->mCache = NULL; smd->mCache = NULL;
} }
ss = _getSubSurf(NULL, levels, CCG_USE_ARENA); ss = _getSubSurf(NULL, levels, CCG_USE_ARENA|CCG_CALC_NORMALS);
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm); result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);

@ -808,13 +808,14 @@ static int txt_utf8_len(const char *src)
void txt_move_up(Text *text, short sel) void txt_move_up(Text *text, short sel)
{ {
TextLine **linep; TextLine **linep;
int *charp, old; int *charp;
/* int old; */ /* UNUSED */
if (!text) return; if (!text) return;
if(sel) txt_curs_sel(text, &linep, &charp); if(sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return; if (!*linep) return;
old= *charp; /* old= *charp; */ /* UNUSED */
if((*linep)->prev) { if((*linep)->prev) {
int index = txt_utf8_offset_to_index((*linep)->line, *charp); int index = txt_utf8_offset_to_index((*linep)->line, *charp);
@ -834,13 +835,14 @@ void txt_move_up(Text *text, short sel)
void txt_move_down(Text *text, short sel) void txt_move_down(Text *text, short sel)
{ {
TextLine **linep; TextLine **linep;
int *charp, old; int *charp;
/* int old; */ /* UNUSED */
if (!text) return; if (!text) return;
if(sel) txt_curs_sel(text, &linep, &charp); if(sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return; if (!*linep) return;
old= *charp; /* old= *charp; */ /* UNUSED */
if((*linep)->next) { if((*linep)->next) {
int index = txt_utf8_offset_to_index((*linep)->line, *charp); int index = txt_utf8_offset_to_index((*linep)->line, *charp);
@ -1897,6 +1899,10 @@ static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, s
break; break;
case 4: /* 32-bit unicode symbol */ case 4: /* 32-bit unicode symbol */
unicode= txt_undo_read_uint32(undo_buf, undo_pos); unicode= txt_undo_read_uint32(undo_buf, undo_pos);
default:
/* should never happen */
BLI_assert(0);
unicode= 0;
} }
return unicode; return unicode;
@ -2751,16 +2757,20 @@ void txt_indent(Text *text)
/* hardcoded: TXT_TABSIZE = 4 spaces: */ /* hardcoded: TXT_TABSIZE = 4 spaces: */
int spaceslen = TXT_TABSIZE; int spaceslen = TXT_TABSIZE;
/* insert spaces rather than tabs */ if (ELEM3(NULL, text, text->curl, text->sell)) {
if (text->flags & TXT_TABSTOSPACES){ return;
add = tab_to_spaces;
indentlen = spaceslen;
} }
if (!text) return; if (!text) return;
if (!text->curl) return; if (!text->curl) return;
if (!text->sell) return; if (!text->sell) return;
/* insert spaces rather than tabs */
if (text->flags & TXT_TABSTOSPACES){
add = tab_to_spaces;
indentlen = spaceslen;
}
num = 0; num = 0;
while (TRUE) while (TRUE)
{ {
@ -2812,16 +2822,16 @@ void txt_unindent(Text *text)
/* hardcoded: TXT_TABSIZE = 4 spaces: */ /* hardcoded: TXT_TABSIZE = 4 spaces: */
int spaceslen = TXT_TABSIZE; int spaceslen = TXT_TABSIZE;
if (!text) return;
if (!text->curl) return;
if (!text->sell) return;
/* insert spaces rather than tabs */ /* insert spaces rather than tabs */
if (text->flags & TXT_TABSTOSPACES){ if (text->flags & TXT_TABSTOSPACES){
remove = tab_to_spaces; remove = tab_to_spaces;
indent = spaceslen; indent = spaceslen;
} }
if (!text) return;
if (!text->curl) return;
if (!text->sell) return;
while(TRUE) while(TRUE)
{ {
int i = 0; int i = 0;

@ -132,19 +132,18 @@ void BLI_kdtree_balance(KDTree *tree)
tree->root= kdtree_balance(tree->nodes, tree->totnode, 0); tree->root= kdtree_balance(tree->nodes, tree->totnode, 0);
} }
static float squared_distance(float *v2, float *v1, float *n1, float *n2) static float squared_distance(float *v2, float *v1, float *UNUSED(n1), float *n2)
{ {
float d[3], dist; float d[3], dist;
(void)n1; /* unused */
d[0]= v2[0]-v1[0]; d[0]= v2[0]-v1[0];
d[1]= v2[1]-v1[1]; d[1]= v2[1]-v1[1];
d[2]= v2[2]-v1[2]; d[2]= v2[2]-v1[2];
dist= d[0]*d[0] + d[1]*d[1] + d[2]*d[2]; dist = dot_v3v3(d, d);
//if(n1 && n2 && n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2] < 0.0f) //if(n1 && n2 && (dot_v3v3(n1, n2) < 0.0f))
if(n2 && d[0]*n2[0] + d[1]*n2[1] + d[2]*n2[2] < 0.0f) if(n2 && (dot_v3v3(d, n2) < 0.0f))
dist *= 10.0f; dist *= 10.0f;
return dist; return dist;

@ -390,7 +390,7 @@ void boxPack2D(boxPack *boxarray, const int len, float *tot_width, float *tot_he
} else if ( vert->trb && vert->brb && } else if ( vert->trb && vert->brb &&
(box == vert->trb || box == vert->brb) ) { (box == vert->trb || box == vert->brb) ) {
if (vert->trb->w > vert->brb->w) { if (vert->trb->w > vert->brb->w) {
vert->brb->v[TR]->free &= ~(TRF|TRF); vert->brb->v[TR]->free &= ~(TLF|TRF);
} else if (vert->trb->w < vert->brb->w) { } else if (vert->trb->w < vert->brb->w) {
vert->trb->v[BR]->free &= ~(BLF|BRF); vert->trb->v[BR]->free &= ~(BLF|BRF);
} else { /*same*/ } else { /*same*/

@ -2485,9 +2485,10 @@ void tangent_from_uv(float uv1[2], float uv2[2], float uv3[3], float co1[3], flo
cross_v3_v3v3(ct, tang, tangv); cross_v3_v3v3(ct, tang, tangv);
/* check flip */ /* check flip */
if ((ct[0]*n[0] + ct[1]*n[1] + ct[2]*n[2]) < 0.0f) if (dot_v3v3(ct, n) < 0.0f) {
negate_v3(tang); negate_v3(tang);
} }
}
else { else {
tang[0]= tang[1]= tang[2]= 0.0; tang[0]= tang[1]= tang[2]= 0.0;
} }

@ -811,7 +811,7 @@ void single_axis_angle_to_mat3(float mat[3][3], const char axis, const float ang
mat[2][2] = 1.0f; mat[2][2] = 1.0f;
break; break;
default: default:
assert("invalid axis"); assert(0);
} }
} }

@ -919,10 +919,6 @@ static float g[512+2][3]= {
{-0.944031, -0.326599, -0.045624}, {-0.944031, -0.326599, -0.045624},
}; };
#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
#define setup(i,b0,b1,r0,r1) \ #define setup(i,b0,b1,r0,r1) \
t = vec[i] + 10000.0f; \ t = vec[i] + 10000.0f; \
b0 = ((int)t) & 255; \ b0 = ((int)t) & 255; \

@ -65,7 +65,7 @@ typedef struct BlendFileData {
int fileflags; int fileflags;
int displaymode; int displaymode;
int globalf; int globalf;
char filename[240]; /* 240 = FILE_MAX */ char filename[1024]; /* 1024 = FILE_MAX */
struct bScreen* curscreen; struct bScreen* curscreen;
struct Scene* curscene; struct Scene* curscene;

@ -13099,6 +13099,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
} }
} }
if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 4))
{
{
/* set fluidsim rate */
Object *ob;
for (ob = main->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Fluidsim) {
FluidsimSettings *fss = (FluidsimSettings *)md;
fss->animRate = 1.0f;
}
}
}
}
}
/* put compatibility code here until next subversion bump */ /* put compatibility code here until next subversion bump */
{ {
} }

@ -89,6 +89,9 @@ Any case: direct data is ALWAYS after the lib block
#include "BLI_winstuff.h" #include "BLI_winstuff.h"
#endif #endif
/* allow writefile to use deprecated functionality (for forward compatibility code) */
#define DNA_DEPRECATED_ALLOW
#include "DNA_anim_types.h" #include "DNA_anim_types.h"
#include "DNA_armature_types.h" #include "DNA_armature_types.h"
#include "DNA_actuator_types.h" #include "DNA_actuator_types.h"

@ -63,7 +63,7 @@ typedef struct ImBuf {
int channels; /**< amount of channels in rect_float (0 = 4 channel default) */ int channels; /**< amount of channels in rect_float (0 = 4 channel default) */
float dither; /**< random dither value, for conversion from float -> byte rect */ float dither; /**< random dither value, for conversion from float -> byte rect */
short profile; /** color space/profile preset that the byte rect buffer represents */ short profile; /** color space/profile preset that the byte rect buffer represents */
char profile_filename[256]; /** to be implemented properly, specific filename for custom profiles */ char profile_filename[1024]; /** to be implemented properly, specific filename for custom profiles */
/* mipmapping */ /* mipmapping */
struct ImBuf *mipmap[IB_MIPMAP_LEVELS]; /**< MipMap levels, a series of halved images */ struct ImBuf *mipmap[IB_MIPMAP_LEVELS]; /**< MipMap levels, a series of halved images */

@ -5385,17 +5385,15 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
} }
} }
} }
/* Fix animation data attached to this object */
// TODO: should we be using the database wide version instead (since drivers may break)
if (ob->adt) {
/* posechannels only... */
BKE_animdata_fix_paths_rename(&ob->id, ob->adt, "pose.bones", oldname, newname, 0, 0, 1);
}
} }
{ /* Fix all animdata that may refer to this bone - we can't just do the ones attached to objects, since
* other ID-blocks may have drivers referring to this bone [#29822]
*/
BKE_all_animdata_fix_paths_rename("pose.bones", oldname, newname);
/* correct view locking */ /* correct view locking */
{
bScreen *screen; bScreen *screen;
for(screen= G.main->screen.first; screen; screen= screen->id.next) { for(screen= G.main->screen.first; screen; screen= screen->id.next) {
ScrArea *sa; ScrArea *sa;

@ -450,7 +450,7 @@ static void renameTemplateBone(char *name, char *template_name, ListBase *editbo
{ {
int i, j; int i, j;
for (i = 0, j = 0; template_name[i] != '\0' && i < (MAXBONENAME-1) && j < (MAXBONENAME-1); i++) for (i = 0, j = 0; i < (MAXBONENAME-1) && j < (MAXBONENAME-1) && template_name[i] != '\0'; i++)
{ {
if (template_name[i] == '&') if (template_name[i] == '&')
{ {

@ -376,6 +376,10 @@ static void poselib_add_menu_invoke__replacemenu (bContext *C, uiLayout *layout,
bAction *act= ob->poselib; /* never NULL */ bAction *act= ob->poselib; /* never NULL */
TimeMarker *marker; TimeMarker *marker;
wmOperatorType *ot = WM_operatortype_find("POSELIB_OT_pose_add", 1);
BLI_assert(ot != NULL);
/* set the operator execution context correctly */ /* set the operator execution context correctly */
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
@ -383,7 +387,7 @@ static void poselib_add_menu_invoke__replacemenu (bContext *C, uiLayout *layout,
for (marker= act->markers.first; marker; marker= marker->next) { for (marker= act->markers.first; marker; marker= marker->next) {
PointerRNA props_ptr; PointerRNA props_ptr;
props_ptr = uiItemFullO(layout, "POSELIB_OT_pose_add", props_ptr = uiItemFullO_ptr(layout, ot,
marker->name, ICON_ARMATURE_DATA, NULL, marker->name, ICON_ARMATURE_DATA, NULL,
WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);

@ -5876,8 +5876,8 @@ static int delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
if(obedit->type==OB_SURF) { if(obedit->type==OB_SURF) {
pup= uiPupMenuBegin(C, "Delete", ICON_NONE); pup= uiPupMenuBegin(C, "Delete", ICON_NONE);
layout= uiPupMenuLayout(pup); layout= uiPupMenuLayout(pup);
uiItemEnumO(layout, op->type->idname, NULL, 0, "type", 0); uiItemEnumO_ptr(layout, op->type, NULL, 0, "type", 0);
uiItemEnumO(layout, op->type->idname, NULL, 0, "type", 2); uiItemEnumO_ptr(layout, op->type, NULL, 0, "type", 2);
uiPupMenuEnd(C, pup); uiPupMenuEnd(C, pup);
} }
else { else {

@ -40,6 +40,7 @@ struct bConstraint;
struct bContext; struct bContext;
struct bPoseChannel; struct bPoseChannel;
struct Curve; struct Curve;
struct EnumPropertyItem;
struct KeyBlock; struct KeyBlock;
struct Lattice; struct Lattice;
struct Main; struct Main;
@ -64,6 +65,29 @@ void ED_operatortypes_object(void);
void ED_operatormacros_object(void); void ED_operatormacros_object(void);
void ED_keymap_object(struct wmKeyConfig *keyconf); void ED_keymap_object(struct wmKeyConfig *keyconf);
/* object_relations.c */
typedef enum eParentType {
PAR_OBJECT,
PAR_ARMATURE,
PAR_ARMATURE_NAME,
PAR_ARMATURE_ENVELOPE,
PAR_ARMATURE_AUTO,
PAR_BONE,
PAR_CURVE,
PAR_FOLLOW,
PAR_PATH_CONST,
PAR_LATTICE,
PAR_VERTEX,
PAR_TRIA
} eParentType;
extern struct EnumPropertyItem prop_clear_parent_types[];
extern struct EnumPropertyItem prop_make_parent_types[];
int ED_object_parent_set(struct bContext *C, struct wmOperator *op, struct Object *par, int partype);
void ED_object_parent_clear(struct bContext *C, int type);
/* generic editmode keys like pet /* generic editmode keys like pet
* do_pet * do_pet
* 0: No * 0: No

@ -62,6 +62,7 @@ struct ColorBand;
struct CurveMapping; struct CurveMapping;
struct Image; struct Image;
struct ImageUser; struct ImageUser;
struct wmOperatorType;
struct uiWidgetColors; struct uiWidgetColors;
struct Tex; struct Tex;
struct MTex; struct MTex;
@ -446,6 +447,7 @@ uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *s
uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip);
uiBut *uiDefButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip);
uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconBut(uiBlock *block, uiBut *uiDefIconBut(uiBlock *block,
@ -466,6 +468,7 @@ uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon,
uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip);
uiBut *uiDefIconButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip);
uiBut *uiDefIconTextBut(uiBlock *block, uiBut *uiDefIconTextBut(uiBlock *block,
int type, int retval, int icon, const char *str, int type, int retval, int icon, const char *str,
@ -485,6 +488,7 @@ uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int i
uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip);
uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip);
/* for passing inputs to ButO buttons */ /* for passing inputs to ButO buttons */
struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but); struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but);
@ -773,6 +777,7 @@ void uiTemplateMarker(struct uiLayout *layout, struct PointerRNA *ptr, const cha
/* items */ /* items */
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname); void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname);
void uiItemEnumO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, const char *propname, int value);
void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value); void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value);
void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value); void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value);
void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value); void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value);
@ -781,6 +786,8 @@ void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *op
void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value); void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value);
void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value); void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value);
void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value); void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value);
PointerRNA uiItemFullO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, IDProperty *properties, int context, int flag);
PointerRNA uiItemFullO(uiLayout *layout, const char *idname, const char *name, int icon, struct IDProperty *properties, int context, int flag); PointerRNA uiItemFullO(uiLayout *layout, const char *idname, const char *name, int icon, struct IDProperty *properties, int context, int flag);
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon); void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon);

@ -41,7 +41,7 @@ struct Material;
typedef struct IconFile { typedef struct IconFile {
struct IconFile *next, *prev; struct IconFile *next, *prev;
char filename[80]; // FILE_MAXFILE size char filename[256]; // FILE_MAXFILE size
int index; int index;
} IconFile; } IconFile;

@ -193,8 +193,10 @@ enum {
TH_STITCH_PREVIEW_VERT, TH_STITCH_PREVIEW_VERT,
TH_STITCH_PREVIEW_STITCHABLE, TH_STITCH_PREVIEW_STITCHABLE,
TH_STITCH_PREVIEW_UNSTITCHABLE, TH_STITCH_PREVIEW_UNSTITCHABLE,
TH_STITCH_PREVIEW_ACTIVE TH_STITCH_PREVIEW_ACTIVE,
TH_MATCH, /* highlight color for search matches */
TH_SELECT_HIGHLIGHT /* highlight color for selected outliner item */
}; };
/* XXX WARNING: previous is saved in file, so do not change order! */ /* XXX WARNING: previous is saved in file, so do not change order! */

@ -800,11 +800,43 @@ static void ui_menu_block_set_keyaccels(uiBlock *block)
} }
} }
/* XXX, this code will shorten any allocated string to 'UI_MAX_NAME_STR'
* since this is really long its unlikely to be an issue,
* but this could be supported */
void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const short do_strip)
{
if (do_strip) {
char *cpoin= strchr(but->str, '|');
if(cpoin) {
*cpoin= '\0';
}
}
/* without this, just allow stripping of the shortcut */
if (shortcut_str) {
char *butstr_orig;
if (but->str != but->strdata) {
butstr_orig = but->str; /* free after using as source buffer */
}
else {
butstr_orig = BLI_strdup(but->str);
}
BLI_snprintf(but->strdata,
sizeof(but->strdata),
"%s|%s",
butstr_orig, shortcut_str);
MEM_freeN(butstr_orig);
but->str = but->strdata;
ui_check_but(but);
}
}
static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
{ {
uiBut *but; uiBut *but;
char buf[512]; char buf[128];
/* for menu's */ /* for menu's */
MenuType *mt; MenuType *mt;
@ -815,18 +847,6 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
if(block->minx != block->maxx) if(block->minx != block->maxx)
return; return;
#define UI_MENU_KEY_STR_CAT \
char *butstr_orig= BLI_strdup(but->str); \
BLI_snprintf(but->strdata, \
sizeof(but->strdata), \
"%s|%s", \
butstr_orig, buf); \
MEM_freeN(butstr_orig); \
but->str= but->strdata; \
ui_check_but(but); \
for(but=block->buttons.first; but; but=but->next) { for(but=block->buttons.first; but; but=but->next) {
if(but->optype) { if(but->optype) {
IDProperty *prop= (but->opptr)? but->opptr->data: NULL; IDProperty *prop= (but->opptr)? but->opptr->data: NULL;
@ -834,7 +854,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE,
buf, sizeof(buf))) buf, sizeof(buf)))
{ {
UI_MENU_KEY_STR_CAT ui_but_add_shortcut(but, buf, FALSE);
} }
} }
else if ((mt= uiButGetMenuType(but))) { else if ((mt= uiButGetMenuType(but))) {
@ -851,7 +871,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
if(WM_key_event_operator_string(C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu, FALSE, if(WM_key_event_operator_string(C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu, FALSE,
buf, sizeof(buf))) buf, sizeof(buf)))
{ {
UI_MENU_KEY_STR_CAT ui_but_add_shortcut(but, buf, FALSE);
} }
} }
} }
@ -1693,10 +1713,15 @@ static int ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *
return (BPY_button_exec(C, str_unit_convert, value, TRUE) != -1); return (BPY_button_exec(C, str_unit_convert, value, TRUE) != -1);
} }
static int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double *value) #endif /* WITH_PYTHON */
int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double *value)
{ {
int ok= FALSE; int ok= FALSE;
#ifdef WITH_PYTHON
if(str[0] != '\0') { if(str[0] != '\0') {
int is_unit_but= ui_is_but_unit(but); int is_unit_but= ui_is_but_unit(but);
/* only enable verbose if we won't run again with units */ /* only enable verbose if we won't run again with units */
@ -1718,10 +1743,16 @@ static int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str,
} }
} }
#else /* WITH_PYTHON */
value= atof(str);
ok = TRUE;
#endif /* WITH_PYTHON */
return ok; return ok;
} }
#endif // WITH_PYTHON
int ui_set_but_string(bContext *C, uiBut *but, const char *str) int ui_set_but_string(bContext *C, uiBut *but, const char *str)
{ {
@ -1788,13 +1819,9 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
/* number editing */ /* number editing */
double value; double value;
#ifdef WITH_PYTHON
if(ui_set_but_string_eval_num(C, but, str, &value) == FALSE) { if(ui_set_but_string_eval_num(C, but, str, &value) == FALSE) {
return 0; return 0;
} }
#else
value= atof(str);
#endif // WITH_PYTHON
if(!ui_is_but_float(but)) value= (int)floor(value + 0.5); if(!ui_is_but_float(but)) value= (int)floor(value + 0.5);
if(but->type==NUMABS) value= fabs(value); if(but->type==NUMABS) value= fabs(value);
@ -1939,21 +1966,32 @@ static void ui_free_but(const bContext *C, uiBut *but)
WM_operator_properties_free(but->opptr); WM_operator_properties_free(but->opptr);
MEM_freeN(but->opptr); MEM_freeN(but->opptr);
} }
if(but->func_argN) MEM_freeN(but->func_argN);
if(but->func_argN) {
MEM_freeN(but->func_argN);
}
if(but->active) { if(but->active) {
/* XXX solve later, buttons should be free-able without context ideally, /* XXX solve later, buttons should be free-able without context ideally,
* however they may have open tooltips or popup windows, which need to * however they may have open tooltips or popup windows, which need to
* be closed using a context pointer */ * be closed using a context pointer */
if(C) if (C) {
ui_button_active_free(C, but); ui_button_active_free(C, but);
else }
if(but->active) else {
if(but->active) {
MEM_freeN(but->active); MEM_freeN(but->active);
} }
if(but->str && but->str != but->strdata) MEM_freeN(but->str); }
}
if (but->str && but->str != but->strdata) {
MEM_freeN(but->str);
}
ui_free_link(but->link); ui_free_link(but->link);
if((but->type == BUT_IMAGE) && but->poin) IMB_freeImBuf((struct ImBuf *)but->poin); if ((but->type == BUT_IMAGE) && but->poin) {
IMB_freeImBuf((struct ImBuf *)but->poin);
}
MEM_freeN(but); MEM_freeN(but);
} }
@ -1968,11 +2006,13 @@ void uiFreeBlock(const bContext *C, uiBlock *block)
ui_free_but(C, but); ui_free_but(C, but);
} }
if(block->unit) if (block->unit) {
MEM_freeN(block->unit); MEM_freeN(block->unit);
}
if(block->func_argN) if (block->func_argN) {
MEM_freeN(block->func_argN); MEM_freeN(block->func_argN);
}
CTX_store_free_list(&block->contexts); CTX_store_free_list(&block->contexts);
@ -2639,8 +2679,9 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
str= BLI_dynstr_get_cstring(dynstr); str= BLI_dynstr_get_cstring(dynstr);
BLI_dynstr_free(dynstr); BLI_dynstr_free(dynstr);
if(free) if (free) {
MEM_freeN(item); MEM_freeN(item);
}
freestr= 1; freestr= 1;
} }
@ -2656,11 +2697,13 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
} }
} }
if(!str) if (!str) {
str = RNA_property_ui_name(prop); str = RNA_property_ui_name(prop);
if(free) }
if (free) {
MEM_freeN(item); MEM_freeN(item);
} }
}
else { else {
str= RNA_property_ui_name(prop); str= RNA_property_ui_name(prop);
icon= RNA_property_ui_icon(prop); icon= RNA_property_ui_icon(prop);
@ -2739,8 +2782,9 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
but->a1= ui_get_but_step_unit(but, but->a1); but->a1= ui_get_but_step_unit(but, but->a1);
} }
if(freestr) if (freestr) {
MEM_freeN((void *)str); MEM_freeN((void *)str);
}
return but; return but;
} }
@ -2762,16 +2806,12 @@ static uiBut *ui_def_but_rna_propname(uiBlock *block, int type, int retval, cons
return but; return but;
} }
static uiBut *ui_def_but_operator(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) static uiBut *ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{ {
uiBut *but; uiBut *but;
wmOperatorType *ot;
ot= WM_operatortype_find(opname, 0);
if(!str) { if(!str) {
if(ot) str = ot->name; if(ot) str = ot->name;
else str= opname;
} }
if ((!tip || tip[0]=='\0') && ot && ot->description) { if ((!tip || tip[0]=='\0') && ot && ot->description) {
@ -2793,6 +2833,12 @@ static uiBut *ui_def_but_operator(uiBlock *block, int type, const char *opname,
return but; return but;
} }
static uiBut *UNUSED_FUNCTION(ui_def_but_operator)(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0);
if (str == NULL && ot == NULL) str = opname;
return ui_def_but_operator_ptr(block, type, ot, opcontext, str, x1, y1, x2, y2, tip);
}
static uiBut *ui_def_but_operator_text(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) static uiBut *ui_def_but_operator_text(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
{ {
@ -2999,13 +3045,20 @@ uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int
ui_check_but(but); ui_check_but(but);
return but; return but;
} }
uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip)
uiBut *uiDefButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{ {
uiBut *but; uiBut *but;
but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip); but= ui_def_but_operator_ptr(block, type, ot, opcontext, str, x1, y1, x2, y2, tip);
ui_check_but(but); ui_check_but(but);
return but; return but;
} }
uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0);
if (str == NULL && ot == NULL) str = opname;
return uiDefButO_ptr(block, type, ot, opcontext, str, x1, y1, x2, y2, tip);
}
uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
{ {
@ -3077,13 +3130,19 @@ uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1
ui_check_but_and_iconize(but, icon); ui_check_but_and_iconize(but, icon);
return but; return but;
} }
uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip)
uiBut *uiDefIconButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip)
{ {
uiBut *but; uiBut *but;
but= ui_def_but_operator(block, type, opname, opcontext, "", x1, y1, x2, y2, tip); but= ui_def_but_operator_ptr(block, type, ot, opcontext, "", x1, y1, x2, y2, tip);
ui_check_but_and_iconize(but, icon); ui_check_but_and_iconize(but, icon);
return but; return but;
} }
uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0);
return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x1, y1, x2, y2, tip);
}
/* Button containing both string label and icon */ /* Button containing both string label and icon */
uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
@ -3151,14 +3210,19 @@ uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, co
but->flag|= UI_ICON_LEFT; but->flag|= UI_ICON_LEFT;
return but; return but;
} }
uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip) uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{ {
uiBut *but; uiBut *but;
but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip); but= ui_def_but_operator_ptr(block, type, ot, opcontext, str, x1, y1, x2, y2, tip);
ui_check_but_and_iconize(but, icon); ui_check_but_and_iconize(but, icon);
but->flag|= UI_ICON_LEFT; but->flag|= UI_ICON_LEFT;
return but; return but;
} }
uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0);
return uiDefIconTextButO_ptr(block, type, ot, opcontext, icon, str, x1, y1, x2, y2, tip);
}
/* END Button containing both string label and icon */ /* END Button containing both string label and icon */
@ -3353,8 +3417,9 @@ void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2
void uiBlockSetNFunc(uiBlock *block, uiButHandleFunc func, void *argN, void *arg2) void uiBlockSetNFunc(uiBlock *block, uiButHandleFunc func, void *argN, void *arg2)
{ {
if(block->func_argN) if (block->func_argN) {
MEM_freeN(block->func_argN); MEM_freeN(block->func_argN);
}
block->funcN= func; block->funcN= func;
block->func_argN= argN; block->func_argN= argN;
@ -3383,8 +3448,9 @@ void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2) void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
{ {
if(but->func_argN) if (but->func_argN) {
MEM_freeN(but->func_argN); MEM_freeN(but->func_argN);
}
but->funcN= funcN; but->funcN= funcN;
but->func_argN= argN; but->func_argN= argN;
@ -3422,8 +3488,9 @@ uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, const
{ {
uiBut *but= ui_def_but(block, BLOCK, 0, str, x1, y1, x2, y2, NULL, 0.0, 0.0, 0.0, 0.0, tip); uiBut *but= ui_def_but(block, BLOCK, 0, str, x1, y1, x2, y2, NULL, 0.0, 0.0, 0.0, 0.0, tip);
but->block_create_func= func; but->block_create_func= func;
if(but->func_argN) if (but->func_argN) {
MEM_freeN(but->func_argN); MEM_freeN(but->func_argN);
}
but->func_argN= argN; but->func_argN= argN;
ui_check_but(but); ui_check_but(but);
return but; return but;

@ -1115,7 +1115,6 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
{ {
static ColorBand but_copypaste_coba = {0}; static ColorBand but_copypaste_coba = {0};
char buf[UI_MAX_DRAW_STR+1]= {0}; char buf[UI_MAX_DRAW_STR+1]= {0};
double val;
if(mode=='v' && but->lock) if(mode=='v' && but->lock)
return; return;
@ -1140,17 +1139,16 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
if(but->poin==NULL && but->rnapoin.data==NULL); if(but->poin==NULL && but->rnapoin.data==NULL);
else if(mode=='c') { else if(mode=='c') {
if(ui_is_but_float(but)) ui_get_but_string(but, buf, sizeof(buf));
BLI_snprintf(buf, sizeof(buf), "%f", ui_get_but_val(but));
else
BLI_snprintf(buf, sizeof(buf), "%d", (int)ui_get_but_val(but));
WM_clipboard_text_set(buf, 0); WM_clipboard_text_set(buf, 0);
} }
else { else {
if (sscanf(buf, " %lf ", &val) == 1) { double val;
if (ui_set_but_string_eval_num(C, but, buf, &val)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
data->value= val; data->value= val;
ui_set_but_string(C, but, buf);
button_activate_state(C, but, BUTTON_STATE_EXIT); button_activate_state(C, but, BUTTON_STATE_EXIT);
} }
} }
@ -1703,9 +1701,10 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
changed= 1; changed= 1;
} }
if(pbuf) if (pbuf) {
MEM_freeN(pbuf); MEM_freeN(pbuf);
} }
}
/* cut & copy */ /* cut & copy */
else if (copy || cut) { else if (copy || cut) {
/* copy the contents to the copypaste buffer */ /* copy the contents to the copypaste buffer */
@ -4383,31 +4382,19 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
uiBut *but = (uiBut *)arg1; uiBut *but = (uiBut *)arg1;
if (but->optype) { if (but->optype) {
char buf[512], *cpoin; char shortcut_str[128];
IDProperty *prop= (but->opptr)? but->opptr->data: NULL; IDProperty *prop= (but->opptr)? but->opptr->data: NULL;
/* complex code to change name of button */ /* complex code to change name of button */
if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE,
buf, sizeof(buf))) shortcut_str, sizeof(shortcut_str)))
{ {
char *butstr_orig; ui_but_add_shortcut(but, shortcut_str, TRUE);
// XXX but->str changed... should not, remove the hotkey from it
cpoin= strchr(but->str, '|');
if(cpoin) *cpoin= 0;
butstr_orig= BLI_strdup(but->str);
BLI_snprintf(but->strdata, sizeof(but->strdata), "%s|%s", butstr_orig, buf);
MEM_freeN(butstr_orig);
but->str= but->strdata;
ui_check_but(but);
} }
else { else {
/* shortcut was removed */ /* simply strip the shortcut */
cpoin= strchr(but->str, '|'); ui_but_add_shortcut(but, NULL, TRUE);
if(cpoin) *cpoin= 0;
} }
} }
} }

@ -665,7 +665,9 @@ static void init_iconfile_list(struct ListBase *list)
for(; i>=0; i--){ for(; i>=0; i--){
MEM_freeN(dir[i].relname); MEM_freeN(dir[i].relname);
MEM_freeN(dir[i].path); MEM_freeN(dir[i].path);
if (dir[i].string) MEM_freeN(dir[i].string); if (dir[i].string) {
MEM_freeN(dir[i].string);
}
} }
free(dir); free(dir);
dir= NULL; dir= NULL;

@ -356,6 +356,7 @@ extern void ui_get_but_string(uiBut *but, char *str, size_t maxlen);
extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen); extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen);
extern int ui_set_but_string(struct bContext *C, uiBut *but, const char *str); extern int ui_set_but_string(struct bContext *C, uiBut *but, const char *str);
extern int ui_get_but_string_max_length(uiBut *but); extern int ui_get_but_string_max_length(uiBut *but);
extern int ui_set_but_string_eval_num(struct bContext *C, uiBut *but, const char *str, double *value);
extern void ui_set_but_default(struct bContext *C, short all); extern void ui_set_but_default(struct bContext *C, short all);
@ -497,6 +498,7 @@ void ui_resources_free(void);
void ui_layout_add_but(uiLayout *layout, uiBut *but); void ui_layout_add_but(uiLayout *layout, uiBut *but);
int ui_but_can_align(uiBut *but); int ui_but_can_align(uiBut *but);
void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop); void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop);
void ui_but_add_shortcut(uiBut *but, const char *key_str, const short do_strip);
/* interface_anim.c */ /* interface_anim.c */
void ui_but_anim_flag(uiBut *but, float cfra); void ui_but_anim_flag(uiBut *but, float cfra);

@ -499,9 +499,10 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
} }
uiBlockSetCurLayout(block, layout); uiBlockSetCurLayout(block, layout);
if(free) if (free) {
MEM_freeN(item); MEM_freeN(item);
} }
}
/* callback for keymap item change button */ /* callback for keymap item change button */
static void ui_keymap_but_cb(bContext *UNUSED(C), void *but_v, void *UNUSED(key_v)) static void ui_keymap_but_cb(bContext *UNUSED(C), void *but_v, void *UNUSED(key_v))
@ -621,19 +622,12 @@ static void ui_item_disabled(uiLayout *layout, const char *name)
} }
/* operator items */ /* operator items */
PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, IDProperty *properties, int context, int flag) PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, IDProperty *properties, int context, int flag)
{ {
uiBlock *block= layout->root->block; uiBlock *block= layout->root->block;
wmOperatorType *ot= WM_operatortype_find(opname, 1);
uiBut *but; uiBut *but;
int w; int w;
if(!ot) {
ui_item_disabled(layout, opname);
RNA_warning("unknown operator '%s'", opname);
return PointerRNA_NULL;
}
if(!name) { if(!name) {
name= IFACE_(ot->name); name= IFACE_(ot->name);
} }
@ -649,12 +643,18 @@ PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, i
if (flag & UI_ITEM_R_NO_BG) if (flag & UI_ITEM_R_NO_BG)
uiBlockSetEmboss(block, UI_EMBOSSN); uiBlockSetEmboss(block, UI_EMBOSSN);
if(icon && name[0]) /* create the button */
but= uiDefIconTextButO(block, BUT, ot->idname, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL); if(icon) {
else if(icon) if (name[0]) {
but= uiDefIconButO(block, BUT, ot->idname, context, icon, 0, 0, w, UI_UNIT_Y, NULL); but = uiDefIconTextButO_ptr(block, BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL);
else }
but= uiDefButO(block, BUT, ot->idname, context, name, 0, 0, w, UI_UNIT_Y, NULL); else {
but = uiDefIconButO_ptr(block, BUT, ot, context, icon, 0, 0, w, UI_UNIT_Y, NULL);
}
}
else {
but= uiDefButO_ptr(block, BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL);
}
assert(but->optype != NULL); assert(but->optype != NULL);
@ -686,52 +686,90 @@ PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, i
return PointerRNA_NULL; return PointerRNA_NULL;
} }
static const char *ui_menu_enumpropname(uiLayout *layout, const char *opname, const char *propname, int retval) PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, IDProperty *properties, int context, int flag)
{ {
wmOperatorType *ot= WM_operatortype_find(opname, 0); wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr;
PropertyRNA *prop;
if(!ot || !ot->srna) if(ot) {
return ""; return uiItemFullO_ptr(layout, ot, name, icon, properties, context, flag);
}
else {
ui_item_disabled(layout, opname);
RNA_warning("unknown operator '%s'", opname);
return PointerRNA_NULL;
}
}
RNA_pointer_create(NULL, ot->srna, NULL, &ptr); static const char *ui_menu_enumpropname(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int retval)
prop= RNA_struct_find_property(&ptr, propname); {
if(prop) {
EnumPropertyItem *item; EnumPropertyItem *item;
int totitem, free; int totitem, free;
const char *name; const char *name;
RNA_property_enum_items_gettexted(layout->root->block->evil_C, &ptr, prop, &item, &totitem, &free); RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free);
if(RNA_enum_name(item, retval, &name)) { if (RNA_enum_name(item, retval, &name) == 0) {
if(free) MEM_freeN(item); name = "";
return name;
} }
if(free) if (free) {
MEM_freeN(item); MEM_freeN(item);
} }
return ""; return name;
} }
void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value) /* same as below but 'prop' is already known */
static void uiItemEnumO_ptr__internal(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, PropertyRNA *prop, int value)
{ {
PointerRNA ptr; PointerRNA ptr;
WM_operator_properties_create_ptr(&ptr, ot);
WM_operator_properties_create(&ptr, opname); RNA_property_enum_set(&ptr, prop, value);
RNA_enum_set(&ptr, propname, value);
if(!name) if(!name)
name= ui_menu_enumpropname(layout, opname, propname, value); name = ui_menu_enumpropname(layout, &ptr, prop, value);
uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0);
}
void uiItemEnumO_ptr(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, const char *propname, int value)
{
PointerRNA ptr;
PropertyRNA *prop;
WM_operator_properties_create_ptr(&ptr, ot);
if ((prop = RNA_struct_find_property(&ptr, propname))) {
/* pass */
}
else {
RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
return;
}
RNA_property_enum_set(&ptr, prop, value);
if(!name)
name = ui_menu_enumpropname(layout, &ptr, prop, value);
uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0);
}
void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
if(ot) {
uiItemEnumO_ptr(layout, ot, name, icon, propname, value);
}
else {
ui_item_disabled(layout, opname);
RNA_warning("unknown operator '%s'", opname);
}
uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0);
} }
void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname, IDProperty *properties, int context, int flag) void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname, IDProperty *properties, int context, int flag)
{ {
wmOperatorType *ot= WM_operatortype_find(opname, 1); wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr; PointerRNA ptr;
PropertyRNA *prop; PropertyRNA *prop;
uiBut *bt; uiBut *bt;
@ -768,12 +806,13 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
MEM_freeN(tptr.data); MEM_freeN(tptr.data);
} }
tptr.data= IDP_CopyProperty(properties); tptr.data= IDP_CopyProperty(properties);
RNA_enum_set(&tptr, propname, item[i].value); RNA_property_enum_set(&tptr, prop, item[i].value);
uiItemFullO(column, opname, item[i].name, item[i].icon, tptr.data, context, flag); uiItemFullO_ptr(column, ot, item[i].name, item[i].icon, tptr.data, context, flag);
}
else {
uiItemEnumO_ptr__internal(column, ot, item[i].name, item[i].icon, prop, item[i].value);
} }
else
uiItemEnumO(column, opname, item[i].name, item[i].icon, propname, item[i].value);
} }
else { else {
if(item[i].name) { if(item[i].name) {
@ -792,25 +831,34 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
} }
} }
if(free) if (free) {
MEM_freeN(item); MEM_freeN(item);
} }
} }
}
void uiItemsEnumO(uiLayout *layout, const char *opname, const char *propname) void uiItemsEnumO(uiLayout *layout, const char *opname, const char *propname)
{ {
uiItemsFullEnumO(layout, opname, propname, NULL, layout->root->opcontext, 0); uiItemsFullEnumO(layout, opname, propname, NULL, layout->root->opcontext, 0);
} }
#define UI_OPERATOR_ERROR_RET(_ot, _opname) \
if (ot == NULL) { \
ui_item_disabled(layout, _opname); \
RNA_warning("'%s' unknown operator", _opname); \
return; \
} (void)0
/* for use in cases where we have */ /* for use in cases where we have */
void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
{ {
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr; PointerRNA ptr;
/* for getting the enum */
PropertyRNA *prop; PropertyRNA *prop;
WM_operator_properties_create(&ptr, opname); UI_OPERATOR_ERROR_RET(ot, opname);
WM_operator_properties_create_ptr(&ptr, ot);
/* enum lookup */ /* enum lookup */
if ((prop = RNA_struct_find_property(&ptr, propname))) { if ((prop = RNA_struct_find_property(&ptr, propname))) {
@ -825,34 +873,39 @@ void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char
/* same as uiItemEnumO */ /* same as uiItemEnumO */
if(!name) if(!name)
name= ui_menu_enumpropname(layout, opname, propname, value); name = ui_menu_enumpropname(layout, &ptr, prop, value);
uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0);
} }
void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value_str) void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value_str)
{ {
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr; PointerRNA ptr;
/* for getting the enum */
PropertyRNA *prop; PropertyRNA *prop;
EnumPropertyItem *item; EnumPropertyItem *item;
int value, free; int value, free;
WM_operator_properties_create(&ptr, opname); UI_OPERATOR_ERROR_RET(ot, opname);
WM_operator_properties_create_ptr(&ptr, ot);
/* enum lookup */ /* enum lookup */
if((prop= RNA_struct_find_property(&ptr, propname))) { if((prop= RNA_struct_find_property(&ptr, propname))) {
RNA_property_enum_items_gettexted(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free); RNA_property_enum_items_gettexted(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
if(item==NULL || RNA_enum_value_from_id(item, value_str, &value)==0) { if(item==NULL || RNA_enum_value_from_id(item, value_str, &value)==0) {
if(free) MEM_freeN(item); if(free) {
MEM_freeN(item);
}
RNA_warning("%s.%s, enum %s not found", RNA_struct_identifier(ptr.type), propname, value_str); RNA_warning("%s.%s, enum %s not found", RNA_struct_identifier(ptr.type), propname, value_str);
return; return;
} }
if(free) if (free) {
MEM_freeN(item); MEM_freeN(item);
} }
}
else { else {
RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname); RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
return; return;
@ -862,49 +915,61 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char
/* same as uiItemEnumO */ /* same as uiItemEnumO */
if(!name) if(!name)
name= ui_menu_enumpropname(layout, opname, propname, value); name = ui_menu_enumpropname(layout, &ptr, prop, value);
uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0);
} }
void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
{ {
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr; PointerRNA ptr;
WM_operator_properties_create(&ptr, opname); UI_OPERATOR_ERROR_RET(ot, opname);
WM_operator_properties_create_ptr(&ptr, ot);
RNA_boolean_set(&ptr, propname, value); RNA_boolean_set(&ptr, propname, value);
uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0);
} }
void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
{ {
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr; PointerRNA ptr;
WM_operator_properties_create(&ptr, opname); UI_OPERATOR_ERROR_RET(ot, opname);
WM_operator_properties_create_ptr(&ptr, ot);
RNA_int_set(&ptr, propname, value); RNA_int_set(&ptr, propname, value);
uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0);
} }
void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value) void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value)
{ {
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr; PointerRNA ptr;
WM_operator_properties_create(&ptr, opname); UI_OPERATOR_ERROR_RET(ot, opname);
WM_operator_properties_create_ptr(&ptr, ot);
RNA_float_set(&ptr, propname, value); RNA_float_set(&ptr, propname, value);
uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0);
} }
void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value) void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value)
{ {
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr; PointerRNA ptr;
WM_operator_properties_create(&ptr, opname); UI_OPERATOR_ERROR_RET(ot, opname);
WM_operator_properties_create_ptr(&ptr, ot);
RNA_string_set(&ptr, propname, value); RNA_string_set(&ptr, propname, value);
uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0);
} }
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname) void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
@ -1096,7 +1161,9 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr
RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, NULL, &free); RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
if(!RNA_enum_value_from_id(item, value, &ivalue)) { if(!RNA_enum_value_from_id(item, value, &ivalue)) {
if(free) MEM_freeN(item); if (free) {
MEM_freeN(item);
}
ui_item_disabled(layout, propname); ui_item_disabled(layout, propname);
RNA_warning("enum property value not found: %s", value); RNA_warning("enum property value not found: %s", value);
return; return;
@ -1109,9 +1176,10 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr
} }
} }
if(free) if (free) {
MEM_freeN(item); MEM_freeN(item);
} }
}
void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname) void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname)
{ {
@ -1160,10 +1228,11 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname
} }
} }
if(free) if (free) {
MEM_freeN(item); MEM_freeN(item);
} }
} }
}
/* Pointer RNA button with search */ /* Pointer RNA button with search */
@ -1536,14 +1605,11 @@ static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, vo
void uiItemMenuEnumO(uiLayout *layout, const char *opname, const char *propname, const char *name, int icon) void uiItemMenuEnumO(uiLayout *layout, const char *opname, const char *propname, const char *name, int icon)
{ {
wmOperatorType *ot= WM_operatortype_find(opname, 1); wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
MenuItemLevel *lvl; MenuItemLevel *lvl;
if(!ot) { UI_OPERATOR_ERROR_RET(ot, opname);
ui_item_disabled(layout, opname);
RNA_warning("unknown operator '%s'", opname);
return;
}
if(!ot->srna) { if(!ot->srna) {
ui_item_disabled(layout, opname); ui_item_disabled(layout, opname);
RNA_warning("operator missing srna '%s'", opname); RNA_warning("operator missing srna '%s'", opname);
@ -2731,8 +2797,9 @@ const char *uiLayoutIntrospect(uiLayout *layout)
{ {
DynStr *ds= BLI_dynstr_new(); DynStr *ds= BLI_dynstr_new();
if(str) if (str) {
MEM_freeN(str); MEM_freeN(str);
}
ui_intro_uiLayout(ds, layout); ui_intro_uiLayout(ds, layout);

@ -772,8 +772,9 @@ static int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac, int drag)
ui_panel_copy_offset(pa, pa->paneltab); ui_panel_copy_offset(pa, pa->paneltab);
/* free panelsort array */ /* free panelsort array */
for(ps= panelsort, a=0; a<tot; a++, ps++) for (ps = panelsort, a = 0; a < tot; a++, ps++) {
MEM_freeN(ps->pa); MEM_freeN(ps->pa);
}
MEM_freeN(panelsort); MEM_freeN(panelsort);
return done; return done;

@ -138,8 +138,9 @@ static void menudata_add_item(MenuData *md, const char *str, int retval, int ico
static void menudata_free(MenuData *md) static void menudata_free(MenuData *md)
{ {
MEM_freeN((void *)md->instr); MEM_freeN((void *)md->instr);
if (md->items) if (md->items) {
MEM_freeN(md->items); MEM_freeN(md->items);
}
MEM_freeN(md); MEM_freeN(md);
} }
@ -394,10 +395,11 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
} }
} }
if(free) if (free) {
MEM_freeN(item); MEM_freeN(item);
} }
} }
}
if(but->tip && but->tip[0] != '\0') { if(but->tip && but->tip[0] != '\0') {
BLI_strncpy(data->lines[data->totline], but->tip, sizeof(data->lines[0])); BLI_strncpy(data->lines[data->totline], but->tip, sizeof(data->lines[0]));
@ -982,8 +984,9 @@ static void ui_searchbox_region_free_cb(ARegion *ar)
int a; int a;
/* free search data */ /* free search data */
for(a=0; a<data->items.maxitem; a++) for (a = 0; a < data->items.maxitem; a++) {
MEM_freeN(data->items.names[a]); MEM_freeN(data->items.names[a]);
}
MEM_freeN(data->items.names); MEM_freeN(data->items.names);
MEM_freeN(data->items.pointers); MEM_freeN(data->items.pointers);
MEM_freeN(data->items.icons); MEM_freeN(data->items.icons);
@ -1182,8 +1185,9 @@ void ui_but_search_test(uiBut *but)
uiButSetFlag(but, UI_BUT_REDALERT); uiButSetFlag(but, UI_BUT_REDALERT);
} }
for(x1=0; x1<items->maxitem; x1++) for (x1 = 0; x1 < items->maxitem; x1++) {
MEM_freeN(items->names[x1]); MEM_freeN(items->names[x1]);
}
MEM_freeN(items->names); MEM_freeN(items->names);
MEM_freeN(items); MEM_freeN(items);
} }
@ -2474,7 +2478,7 @@ static void confirm_operator(bContext *C, wmOperator *op, const char *title, con
char *s, buf[512]; char *s, buf[512];
s= buf; s= buf;
if (title) s+= sprintf(s, "%s%%t|%s", title, item); if (title) s+= BLI_snprintf(s, sizeof(buf), "%s%%t|%s", title, item);
(void)s; (void)s;
handle= ui_popup_menu_create(C, NULL, NULL, NULL, NULL, buf); handle= ui_popup_menu_create(C, NULL, NULL, NULL, NULL, buf);

@ -2267,9 +2267,10 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
uiItemL(sub, name, icon); /* fails, backdrop LISTROW... */ uiItemL(sub, name, icon); /* fails, backdrop LISTROW... */
/* free name */ /* free name */
if(namebuf) if (namebuf) {
MEM_freeN(namebuf); MEM_freeN(namebuf);
} }
}
void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *activeptr, const char *activepropname, const char *prop_list, int rows, int maxrows, int listtype) void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *activeptr, const char *activepropname, const char *prop_list, int rows, int maxrows, int listtype)
{ {
@ -2372,9 +2373,10 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
icon= list_item_icon_get(C, &itemptr, rnaicon, 0); icon= list_item_icon_get(C, &itemptr, rnaicon, 0);
uiItemL(row, (name)? name: "", icon); uiItemL(row, (name)? name: "", icon);
if(name) if (name) {
MEM_freeN((void *)name); MEM_freeN((void *)name);
} }
}
i++; i++;
} }

@ -452,6 +452,14 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp= ts->camera_path; break; cp= ts->camera_path; break;
case TH_LOCK_MARKER: case TH_LOCK_MARKER:
cp= ts->lock_marker; break; cp= ts->lock_marker; break;
case TH_MATCH:
cp= ts->match;
break;
case TH_SELECT_HIGHLIGHT:
cp= ts->selected_highlight;
break;
} }
} }
} }
@ -792,6 +800,9 @@ void ui_theme_init_default(void)
btheme->toops= btheme->tv3d; btheme->toops= btheme->tv3d;
SETCOLF(btheme->toops.back, 0.45, 0.45, 0.45, 1.0); SETCOLF(btheme->toops.back, 0.45, 0.45, 0.45, 1.0);
SETCOLF(btheme->toops.match, 0.2, 0.5, 0.2, 0.3); /* highlighting search match - soft green*/
SETCOLF(btheme->toops.selected_highlight, 0.51, 0.53, 0.55, 0.3);
/* space info */ /* space info */
btheme->tinfo= btheme->tv3d; btheme->tinfo= btheme->tv3d;
SETCOLF(btheme->tinfo.back, 0.45, 0.45, 0.45, 1.0); SETCOLF(btheme->tinfo.back, 0.45, 0.45, 0.45, 1.0);
@ -1706,7 +1717,7 @@ void init_userdef_do_versions(void)
} }
} }
if (bmain->versionfile < 262){ if (bmain->versionfile < 261 || (bmain->versionfile == 261 && bmain->subversionfile < 4)) {
bTheme *btheme; bTheme *btheme;
for(btheme= U.themes.first; btheme; btheme= btheme->next) { for(btheme= U.themes.first; btheme; btheme= btheme->next) {
SETCOLF(btheme->tima.preview_stitch_face, 0.071, 0.259, 0.694, 0.150); SETCOLF(btheme->tima.preview_stitch_face, 0.071, 0.259, 0.694, 0.150);
@ -1715,7 +1726,11 @@ void init_userdef_do_versions(void)
SETCOLF(btheme->tima.preview_stitch_stitchable, 0.0, 1.0, 0.0, 1.0); SETCOLF(btheme->tima.preview_stitch_stitchable, 0.0, 1.0, 0.0, 1.0);
SETCOLF(btheme->tima.preview_stitch_unstitchable, 1.0, 0.0, 0.0, 1.0); SETCOLF(btheme->tima.preview_stitch_unstitchable, 1.0, 0.0, 0.0, 1.0);
SETCOLF(btheme->tima.preview_stitch_active, 0.886, 0.824, 0.765, 0.140); SETCOLF(btheme->tima.preview_stitch_active, 0.886, 0.824, 0.765, 0.140);
SETCOLF(btheme->toops.match, 0.2, 0.5, 0.2, 0.3);
SETCOLF(btheme->toops.selected_highlight, 0.51, 0.53, 0.55, 0.3);
} }
U.use_16bit_textures = 0; U.use_16bit_textures = 0;
} }

@ -1339,9 +1339,10 @@ void UI_view2d_grid_size(View2DGrid *grid, float *r_dx, float *r_dy)
void UI_view2d_grid_free(View2DGrid *grid) void UI_view2d_grid_free(View2DGrid *grid)
{ {
/* only free if there's a grid */ /* only free if there's a grid */
if (grid) if (grid) {
MEM_freeN(grid); MEM_freeN(grid);
} }
}
/* *********************************************************************** */ /* *********************************************************************** */
/* Scrollers */ /* Scrollers */
@ -1754,7 +1755,9 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
void UI_view2d_scrollers_free(View2DScrollers *scrollers) void UI_view2d_scrollers_free(View2DScrollers *scrollers)
{ {
/* need to free grid as well... */ /* need to free grid as well... */
if (scrollers->grid) MEM_freeN(scrollers->grid); if (scrollers->grid) {
MEM_freeN(scrollers->grid);
}
MEM_freeN(scrollers); MEM_freeN(scrollers);
} }

@ -46,6 +46,7 @@
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "DNA_speaker_types.h" #include "DNA_speaker_types.h"
#include "DNA_vfont_types.h" #include "DNA_vfont_types.h"
#include "DNA_actuator_types.h"
#include "BLI_ghash.h" #include "BLI_ghash.h"
#include "BLI_listbase.h" #include "BLI_listbase.h"
@ -1795,8 +1796,22 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
Key *key = ob_get_key(obn); Key *key = ob_get_key(obn);
if(dupflag & USER_DUP_ACT) { if(dupflag & USER_DUP_ACT) {
bActuator *act;
BKE_copy_animdata_id_action((ID *)obn->data); BKE_copy_animdata_id_action((ID *)obn->data);
if(key) BKE_copy_animdata_id_action((ID*)key); if(key) {
BKE_copy_animdata_id_action((ID*)key);
}
/* Update the duplicated action in the action actuators */
for (act = obn->actuators.first; act; act = act->next) {
if(act->type == ACT_ACTION) {
bActionActuator* actact = (bActionActuator*) act->data;
if(actact->act == ob->adt->action) {
actact->act = obn->adt->action;
}
}
}
} }
if(dupflag & USER_DUP_MAT) { if(dupflag & USER_DUP_MAT) {

@ -298,7 +298,7 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt)
uiLayout *layout= uiPupMenuLayout(pup); uiLayout *layout= uiPupMenuLayout(pup);
/* create operator menu item with relevant properties filled in */ /* create operator menu item with relevant properties filled in */
uiItemFullO(layout, op->idname, op->type->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); uiItemFullO_ptr(layout, op->type, op->type->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
/* present the menu and be done... */ /* present the menu and be done... */
uiPupMenuEnd(C, pup); uiPupMenuEnd(C, pup);
@ -419,22 +419,20 @@ void OBJECT_OT_proxy_make (wmOperatorType *ot)
/********************** Clear Parent Operator ******************* */ /********************** Clear Parent Operator ******************* */
static EnumPropertyItem prop_clear_parent_types[] = { EnumPropertyItem prop_clear_parent_types[] = {
{0, "CLEAR", 0, "Clear Parent", ""}, {0, "CLEAR", 0, "Clear Parent", ""},
{1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""},
{2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""},
{0, NULL, 0, NULL, NULL} {0, NULL, 0, NULL, NULL}
}; };
/* note, poll should check for editable scene */ void ED_object_parent_clear(bContext *C, int type)
static int parent_clear_exec(bContext *C, wmOperator *op)
{ {
Main *bmain= CTX_data_main(C); Main *bmain= CTX_data_main(C);
Scene *scene= CTX_data_scene(C); Scene *scene= CTX_data_scene(C);
int type= RNA_enum_get(op->ptr, "type");
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects)
{
if(ob->parent == NULL) if(ob->parent == NULL)
continue; continue;
@ -456,6 +454,12 @@ static int parent_clear_exec(bContext *C, wmOperator *op)
DAG_ids_flush_update(bmain, 0); DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, NULL); WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, NULL);
}
/* note, poll should check for editable scene */
static int parent_clear_exec(bContext *C, wmOperator *op)
{
ED_object_parent_clear(C, RNA_enum_get(op->ptr, "type"));
return OPERATOR_FINISHED; return OPERATOR_FINISHED;
} }
@ -481,35 +485,6 @@ void OBJECT_OT_parent_clear(wmOperatorType *ot)
/* ******************** Make Parent Operator *********************** */ /* ******************** Make Parent Operator *********************** */
#define PAR_OBJECT 0
#define PAR_ARMATURE 1
#define PAR_ARMATURE_NAME 2
#define PAR_ARMATURE_ENVELOPE 3
#define PAR_ARMATURE_AUTO 4
#define PAR_BONE 5
#define PAR_CURVE 6
#define PAR_FOLLOW 7
#define PAR_PATH_CONST 8
#define PAR_LATTICE 9
#define PAR_VERTEX 10
#define PAR_TRIA 11
static EnumPropertyItem prop_make_parent_types[] = {
{PAR_OBJECT, "OBJECT", 0, "Object", ""},
{PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""},
{PAR_ARMATURE_NAME, "ARMATURE_NAME", 0, " With Empty Groups", ""},
{PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, " With Automatic Weights", ""},
{PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, " With Envelope Weights", ""},
{PAR_BONE, "BONE", 0, "Bone", ""},
{PAR_CURVE, "CURVE", 0, "Curve Deform", ""},
{PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""},
{PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""},
{PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""},
{PAR_VERTEX, "VERTEX", 0, "Vertex", ""},
{PAR_TRIA, "TRIA", 0, "Triangle", ""},
{0, NULL, 0, NULL, NULL}
};
void ED_object_parent(Object *ob, Object *par, int type, const char *substr) void ED_object_parent(Object *ob, Object *par, int type, const char *substr)
{ {
if (!par || BKE_object_parent_loop_check(par, ob)) { if (!par || BKE_object_parent_loop_check(par, ob)) {
@ -527,13 +502,28 @@ void ED_object_parent(Object *ob, Object *par, int type, const char *substr)
BLI_strncpy(ob->parsubstr, substr, sizeof(ob->parsubstr)); BLI_strncpy(ob->parsubstr, substr, sizeof(ob->parsubstr));
} }
static int parent_set_exec(bContext *C, wmOperator *op) /* Operator Property */
EnumPropertyItem prop_make_parent_types[] = {
{PAR_OBJECT, "OBJECT", 0, "Object", ""},
{PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""},
{PAR_ARMATURE_NAME, "ARMATURE_NAME", 0, " With Empty Groups", ""},
{PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, " With Automatic Weights", ""},
{PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, " With Envelope Weights", ""},
{PAR_BONE, "BONE", 0, "Bone", ""},
{PAR_CURVE, "CURVE", 0, "Curve Deform", ""},
{PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""},
{PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""},
{PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""},
{PAR_VERTEX, "VERTEX", 0, "Vertex", ""},
{PAR_TRIA, "TRIA", 0, "Triangle", ""},
{0, NULL, 0, NULL, NULL}
};
int ED_object_parent_set(bContext *C, wmOperator *op, Object *par, int partype)
{ {
Main *bmain= CTX_data_main(C); Main *bmain= CTX_data_main(C);
Scene *scene= CTX_data_scene(C); Scene *scene= CTX_data_scene(C);
Object *par= ED_object_active_context(C);
bPoseChannel *pchan= NULL; bPoseChannel *pchan= NULL;
int partype= RNA_enum_get(op->ptr, "type");
int pararm= ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); int pararm= ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO);
par->recalc |= OB_RECALC_OB; par->recalc |= OB_RECALC_OB;
@ -541,7 +531,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
/* preconditions */ /* preconditions */
if(partype==PAR_FOLLOW || partype==PAR_PATH_CONST) { if(partype==PAR_FOLLOW || partype==PAR_PATH_CONST) {
if(par->type!=OB_CURVE) if(par->type!=OB_CURVE)
return OPERATOR_CANCELLED; return 0;
else { else {
Curve *cu= par->data; Curve *cu= par->data;
@ -572,15 +562,14 @@ static int parent_set_exec(bContext *C, wmOperator *op)
if(pchan==NULL) { if(pchan==NULL) {
BKE_report(op->reports, RPT_ERROR, "No active Bone"); BKE_report(op->reports, RPT_ERROR, "No active Bone");
return OPERATOR_CANCELLED; return 0;
} }
} }
/* context iterator */ /* context iterator */
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects)
{
if (ob!=par) { if (ob!=par) {
if (BKE_object_parent_loop_check(par, ob)) { if (BKE_object_parent_loop_check(par, ob)) {
BKE_report(op->reports, RPT_ERROR, "Loop in parents"); BKE_report(op->reports, RPT_ERROR, "Loop in parents");
} }
@ -591,8 +580,9 @@ static int parent_set_exec(bContext *C, wmOperator *op)
/* object_apply_mat4(ob, ob->obmat); */ /* removed because of bug [#23577] */ /* object_apply_mat4(ob, ob->obmat); */ /* removed because of bug [#23577] */
/* set the parent (except for follow-path constraint option) */ /* set the parent (except for follow-path constraint option) */
if(partype != PAR_PATH_CONST) if (partype != PAR_PATH_CONST) {
ob->parent= par; ob->parent= par;
}
/* handle types */ /* handle types */
if (pchan) if (pchan)
@ -600,9 +590,10 @@ static int parent_set_exec(bContext *C, wmOperator *op)
else else
ob->parsubstr[0]= 0; ob->parsubstr[0]= 0;
if(partype == PAR_PATH_CONST) if (partype == PAR_PATH_CONST) {
; /* don't do anything here, since this is not technically "parenting" */ /* don't do anything here, since this is not technically "parenting" */
else if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm ) }
else if (ELEM(partype, PAR_CURVE, PAR_LATTICE) || (pararm))
{ {
/* partype is now set to PAROBJECT so that invisible 'virtual' modifiers don't need to be created /* partype is now set to PAROBJECT so that invisible 'virtual' modifiers don't need to be created
* NOTE: the old (2.4x) method was to set ob->partype = PARSKEL, creating the virtual modifiers * NOTE: the old (2.4x) method was to set ob->partype = PARSKEL, creating the virtual modifiers
@ -688,9 +679,21 @@ static int parent_set_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, NULL); WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, NULL);
return OPERATOR_FINISHED; return 1;
} }
static int parent_set_exec(bContext *C, wmOperator *op)
{
Object *par= ED_object_active_context(C);
int partype= RNA_enum_get(op->ptr, "type");
if(ED_object_parent_set(C, op, par, partype))
return OPERATOR_FINISHED;
else
return OPERATOR_CANCELLED;
}
static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
{ {
Object *ob= ED_object_active_context(C); Object *ob= ED_object_active_context(C);

@ -873,7 +873,7 @@ static void getVerticalAndHorizontalChange(const float norm[3], float d, const f
closest_to_plane_v3(projB, coord, norm, end); closest_to_plane_v3(projB, coord, norm, end);
// (vertical and horizontal refer to the plane's y and xz respectively) // (vertical and horizontal refer to the plane's y and xz respectively)
// vertical distance // vertical distance
dists[index] = norm[0]*end[0] + norm[1]*end[1] + norm[2]*end[2] + d; dists[index] = dot_v3v3(norm, end) + d;
// vertical change // vertical change
changes[index][0] = dists[index] - distToStart; changes[index][0] = dists[index] - distToStart;
//printf("vc %f %f\n", distance(end, projB, 3)-distance(start, projA, 3), changes[index][0]); //printf("vc %f %f\n", distance(end, projB, 3)-distance(start, projA, 3), changes[index][0]);
@ -1114,7 +1114,7 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength,
mag= normalize_v3(norm); mag= normalize_v3(norm);
if(mag) { /* zeros fix */ if(mag) { /* zeros fix */
d = -dot_v3v3(norm, coord); d = -dot_v3v3(norm, coord);
/* dist = (norm[0]*m.co[0] + norm[1]*m.co[1] + norm[2]*m.co[2] + d); */ /* UNUSED */ /* dist = (dot_v3v3(norm, m.co) + d); */ /* UNUSED */
moveCloserToDistanceFromPlane(scene, ob, me, i, norm, coord, d, distToBe, strength, cp); moveCloserToDistanceFromPlane(scene, ob, me, i, norm, coord, d, distToBe, strength, cp);
} }
} }

@ -113,6 +113,18 @@ static float get_fluid_viscosity(FluidsimSettings *settings)
} }
} }
static float get_fluid_rate(FluidsimSettings *settings)
{
float rate = 1.0f; /* default rate if not animated... */
rate = settings->animRate;
if (rate < 0.0f)
rate = 0.0f;
return rate;
}
static void get_fluid_gravity(float *gravity, Scene *scene, FluidsimSettings *fss) static void get_fluid_gravity(float *gravity, Scene *scene, FluidsimSettings *fss)
{ {
if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
@ -305,6 +317,8 @@ static void free_domain_channels(FluidAnimChannels *channels)
channels->DomainGravity = NULL; channels->DomainGravity = NULL;
MEM_freeN(channels->DomainViscosity); MEM_freeN(channels->DomainViscosity);
channels->DomainViscosity = NULL; channels->DomainViscosity = NULL;
MEM_freeN(channels->DomainTime);
channels->DomainTime = NULL;
} }
static void free_all_fluidobject_channels(ListBase *fobjects) static void free_all_fluidobject_channels(ListBase *fobjects)
@ -351,14 +365,13 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
int length = channels->length; int length = channels->length;
float eval_time; float eval_time;
/* XXX: first init time channel - temporary for now */ /* init time values (assuming that time moves at a constant speed; may be overridden later) */
/* init time values (should be done after evaluating animated time curve) */
init_time(domainSettings, channels); init_time(domainSettings, channels);
/* allocate domain animation channels */ /* allocate domain animation channels */
channels->DomainGravity = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "channel DomainGravity"); channels->DomainGravity = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "channel DomainGravity");
channels->DomainViscosity = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainViscosity"); channels->DomainViscosity = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainViscosity");
//channels->DomainTime = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime"); channels->DomainTime = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime");
/* allocate fluid objects */ /* allocate fluid objects */
for (base=scene->base.first; base; base= base->next) { for (base=scene->base.first; base; base= base->next) {
@ -406,10 +419,9 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
for (i=0; i<channels->length; i++) { for (i=0; i<channels->length; i++) {
FluidObject *fobj; FluidObject *fobj;
float viscosity, gravity[3]; float viscosity, gravity[3];
float timeAtFrame; float timeAtFrame, time;
eval_time = domainSettings->bakeStart + i; eval_time = domainSettings->bakeStart + i;
timeAtFrame = channels->timeAtFrame[i+1];
/* XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation, /* XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation,
* leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ ) * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
@ -425,12 +437,24 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
/* now scene data should be current according to animation system, so we fill the channels */ /* now scene data should be current according to animation system, so we fill the channels */
/* Domain properties - gravity/viscosity/time */ /* Domain time */
// TODO: have option for not running sim, time mangling, in which case second case comes in handy
if (channels->DomainTime) {
time = get_fluid_rate(domainSettings) * channels->aniFrameTime;
timeAtFrame = channels->timeAtFrame[i] + time;
channels->timeAtFrame[i+1] = timeAtFrame;
set_channel(channels->DomainTime, i, &time, i, CHANNEL_FLOAT);
}
else {
timeAtFrame = channels->timeAtFrame[i+1];
}
/* Domain properties - gravity/viscosity */
get_fluid_gravity(gravity, scene, domainSettings); get_fluid_gravity(gravity, scene, domainSettings);
set_channel(channels->DomainGravity, timeAtFrame, gravity, i, CHANNEL_VEC); set_channel(channels->DomainGravity, timeAtFrame, gravity, i, CHANNEL_VEC);
viscosity = get_fluid_viscosity(domainSettings); viscosity = get_fluid_viscosity(domainSettings);
set_channel(channels->DomainViscosity, timeAtFrame, &viscosity, i, CHANNEL_FLOAT); set_channel(channels->DomainViscosity, timeAtFrame, &viscosity, i, CHANNEL_FLOAT);
// XXX : set_channel(channels->DomainTime, timeAtFrame, &time, i, CHANNEL_VEC);
/* object movement */ /* object movement */
for (fobj=fobjects->first; fobj; fobj=fobj->next) { for (fobj=fobjects->first; fobj; fobj=fobj->next) {
@ -958,38 +982,6 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
scene->r.cfra = origFrame; scene->r.cfra = origFrame;
ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1); ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1);
/* ---- XXX: No Time animation curve for now, leaving this code here for reference
{ int timeIcu[1] = { FLUIDSIM_TIME };
float timeDef[1] = { 1. };
// time channel is a bit special, init by hand...
timeAtIndex = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatindex");
for(i=0; i<=scene->r.efra; i++) {
timeAtIndex[i] = (float)(i-startFrame);
}
fluidsimInitChannel(scene, &channelDomainTime, allchannelSize, timeAtIndex, timeIcu,timeDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB
// time channel is a multiplicator for
if(channelDomainTime) {
for(i=0; i<allchannelSize; i++) {
channelDomainTime[i*2+0] = aniFrameTime * channelDomainTime[i*2+0];
if(channelDomainTime[i*2+0]<0.) channelDomainTime[i*2+0] = 0.;
}
}
timeAtFrame = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatframe");
timeAtFrame[0] = timeAtFrame[1] = domainSettings->animStart; // start at index 1
if(channelDomainTime) {
for(i=2; i<=allchannelSize; i++) {
timeAtFrame[i] = timeAtFrame[i-1]+channelDomainTime[(i-1)*2+0];
}
fsset->} else {
for(i=2; i<=allchannelSize; i++) { timeAtFrame[i] = timeAtFrame[i-1]+aniFrameTime; }
}
} // domain channel init
*/
/* ******** init domain object's matrix ******** */ /* ******** init domain object's matrix ******** */
copy_m4_m4(domainMat, fsDomain->obmat); copy_m4_m4(domainMat, fsDomain->obmat);
if(!invert_m4_m4(invDomMat, domainMat)) { if(!invert_m4_m4(invDomMat, domainMat)) {

@ -663,9 +663,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt"); RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt");
WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, 0, 0); RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "mode", BRUSH_STROKE_NORMAL);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1); RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "mode", BRUSH_STROKE_INVERT);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "temp_relax", 1); RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", BRUSH_STROKE_SMOOTH);
ed_keymap_paint_brush_size(keymap, "tool_settings.uv_sculpt.brush.size"); ed_keymap_paint_brush_size(keymap, "tool_settings.uv_sculpt.brush.size");
ed_keymap_paint_brush_radial_control(keymap, "uv_sculpt", 0); ed_keymap_paint_brush_radial_control(keymap, "uv_sculpt", 0);

@ -580,8 +580,7 @@ void vpaint_dogamma(Scene *scene)
} }
*/ */
BM_INLINE unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
{ {
char *cp1, *cp2, *cp; char *cp1, *cp2, *cp;
int mfac; int mfac;
@ -604,7 +603,7 @@ static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
return col; return col;
} }
static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac) BM_INLINE unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
{ {
char *cp1, *cp2, *cp; char *cp1, *cp2, *cp;
int temp; int temp;
@ -627,7 +626,7 @@ static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
return col; return col;
} }
static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) BM_INLINE unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
{ {
char *cp1, *cp2, *cp; char *cp1, *cp2, *cp;
int temp; int temp;
@ -650,7 +649,7 @@ static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
return col; return col;
} }
static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac) BM_INLINE unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
{ {
char *cp1, *cp2, *cp; char *cp1, *cp2, *cp;
int mfac; int mfac;
@ -674,7 +673,7 @@ static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
return col; return col;
} }
static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac) BM_INLINE unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac)
{ {
char *cp1, *cp2, *cp; char *cp1, *cp2, *cp;
int mfac; int mfac;
@ -702,7 +701,7 @@ static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac)
return col; return col;
} }
static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac) BM_INLINE unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac)
{ {
char *cp1, *cp2, *cp; char *cp1, *cp2, *cp;
int mfac; int mfac;
@ -735,18 +734,12 @@ static unsigned int vpaint_blend_tool(const int tool, const unsigned int col,
{ {
switch (tool) { switch (tool) {
case PAINT_BLEND_MIX: case PAINT_BLEND_MIX:
case PAINT_BLEND_BLUR: case PAINT_BLEND_BLUR: return mcol_blend(col, paintcol, alpha_i);
return mcol_blend(col, paintcol, alpha_i); case PAINT_BLEND_ADD: return mcol_add(col, paintcol, alpha_i);
case PAINT_BLEND_ADD: case PAINT_BLEND_SUB: return mcol_sub(col, paintcol, alpha_i);
return mcol_add(col, paintcol, alpha_i); case PAINT_BLEND_MUL: return mcol_mul(col, paintcol, alpha_i);
case PAINT_BLEND_SUB: case PAINT_BLEND_LIGHTEN: return mcol_lighten(col, paintcol, alpha_i);
return mcol_sub(col, paintcol, alpha_i); case PAINT_BLEND_DARKEN: return mcol_darken(col, paintcol, alpha_i);
case PAINT_BLEND_MUL:
return mcol_mul(col, paintcol, alpha_i);
case PAINT_BLEND_LIGHTEN:
return mcol_lighten(col, paintcol, alpha_i);
case PAINT_BLEND_DARKEN:
return mcol_darken(col, paintcol, alpha_i);
default: default:
BLI_assert(0); BLI_assert(0);
return 0; return 0;
@ -881,6 +874,33 @@ static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
return 0.0f; return 0.0f;
} }
BM_INLINE float wval_blend(const float weight, const float paintval, const float alpha)
{
return (paintval * alpha) + (weight * (1.0f - alpha));
}
BM_INLINE float wval_add(const float weight, const float paintval, const float alpha)
{
return weight + (paintval * alpha);
}
BM_INLINE float wval_sub(const float weight, const float paintval, const float alpha)
{
return weight - (paintval * alpha);
}
BM_INLINE float wval_mul(const float weight, const float paintval, const float alpha)
{ /* first mul, then blend the fac */
return ((1.0f - alpha) + (alpha * paintval)) * weight;
}
BM_INLINE float wval_lighten(const float weight, const float paintval, const float alpha)
{
return (weight < paintval) ? wval_blend(weight, paintval, alpha) : weight;
}
BM_INLINE float wval_darken(const float weight, const float paintval, const float alpha)
{
return (weight > paintval) ? wval_blend(weight, paintval, alpha) : weight;
}
/* vpaint has 'vpaint_blend_tool' */ /* vpaint has 'vpaint_blend_tool' */
/* result is not clamped from [0-1] */ /* result is not clamped from [0-1] */
static float wpaint_blend_tool(const int tool, static float wpaint_blend_tool(const int tool,
@ -890,19 +910,12 @@ static float wpaint_blend_tool(const int tool,
{ {
switch (tool) { switch (tool) {
case PAINT_BLEND_MIX: case PAINT_BLEND_MIX:
case PAINT_BLEND_BLUR: case PAINT_BLEND_BLUR: return wval_blend(weight, paintval, alpha);
return (paintval * alpha) + (weight * (1.0f - alpha)); case PAINT_BLEND_ADD: return wval_add(weight, paintval, alpha);
case PAINT_BLEND_ADD: case PAINT_BLEND_SUB: return wval_sub(weight, paintval, alpha);
return (paintval * alpha) + weight; case PAINT_BLEND_MUL: return wval_mul(weight, paintval, alpha);
case PAINT_BLEND_SUB: case PAINT_BLEND_LIGHTEN: return wval_lighten(weight, paintval, alpha);
return (paintval * alpha) - weight; case PAINT_BLEND_DARKEN: return wval_darken(weight, paintval, alpha);
case PAINT_BLEND_MUL:
/* first mul, then blend the fac */
return ((1.0f - alpha) + alpha * paintval) * weight;
case PAINT_BLEND_LIGHTEN:
return (weight < paintval) ? (paintval * alpha) + (weight * (1.0f - alpha)) : weight;
case PAINT_BLEND_DARKEN:
return (weight > paintval) ? (paintval * alpha) + (weight * (1.0f - alpha)) : weight;
default: default:
BLI_assert(0); BLI_assert(0);
return 0.0f; return 0.0f;

@ -122,24 +122,30 @@ typedef struct UvSculptData{
/* Edges used for adjacency info, used with laplacian smoothing */ /* Edges used for adjacency info, used with laplacian smoothing */
UvEdge *uvedges; UvEdge *uvedges;
/* Need I say more? */ /* need I say more? */
int totalUvEdges; int totalUvEdges;
/* data for initial stroke, used by tools like grab */ /* data for initial stroke, used by tools like grab */
UVInitialStroke *initial_stroke; UVInitialStroke *initial_stroke;
/* Timer to be used for airbrush-type brush */ /* timer to be used for airbrush-type brush */
wmTimer *timer; wmTimer *timer;
/* To determine quickly adjacent uvs */ /* to determine quickly adjacent uvs */
UvElementMap *elementMap; UvElementMap *elementMap;
/* uvsmooth Paint for fast reference */ /* uvsmooth Paint for fast reference */
Paint *uvsculpt; Paint *uvsculpt;
/* tool to use. duplicating here to change if modifier keys are pressed */
char tool;
/* store invert flag here */
char invert;
}UvSculptData; }UvSculptData;
/*********** Improved Laplacian Relaxation Operator ************************/ /*********** Improved Laplacian Relaxation Operator ************************/
/* Original code by Raul Fernandez Hernandez "farsthary" * /* original code by Raul Fernandez Hernandez "farsthary" *
* adapted to uv smoothing by Antony Riakiatakis * * adapted to uv smoothing by Antony Riakiatakis *
***************************************************************************/ ***************************************************************************/
@ -301,9 +307,8 @@ static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, wmEvent *event,
float alpha, zoomx, zoomy; float alpha, zoomx, zoomy;
Brush *brush = paint_brush(sculptdata->uvsculpt); Brush *brush = paint_brush(sculptdata->uvsculpt);
ToolSettings *toolsettings = CTX_data_tool_settings(C); ToolSettings *toolsettings = CTX_data_tool_settings(C);
tool = RNA_boolean_get(op->ptr, "temp_relax")? UV_SCULPT_TOOL_RELAX : toolsettings->uv_sculpt_tool; tool = sculptdata->tool;
invert = sculptdata->invert? -1 : 1;
invert = RNA_boolean_get(op->ptr, "invert")? -1 : 1;
alpha = brush_alpha(scene, brush); alpha = brush_alpha(scene, brush);
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
@ -475,6 +480,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
int island_index = 0; int island_index = 0;
/* Holds, for each UvElement in elementMap, a pointer to its unique uv.*/ /* Holds, for each UvElement in elementMap, a pointer to its unique uv.*/
int *uniqueUv; int *uniqueUv;
data->tool = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_SMOOTH)? UV_SCULPT_TOOL_RELAX : ts->uv_sculpt_tool;
data->invert = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT)? 1 : 0;
data->uvsculpt = &ts->uvsculpt->paint; data->uvsculpt = &ts->uvsculpt->paint;
@ -652,7 +659,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
} }
/* Allocate initial selection for grab tool */ /* Allocate initial selection for grab tool */
if(ts->uv_sculpt_tool == UV_SCULPT_TOOL_GRAB){ if(data->tool){
float radius, radius_root; float radius, radius_root;
UvSculptData *sculptdata = (UvSculptData *)op->customdata; UvSculptData *sculptdata = (UvSculptData *)op->customdata;
SpaceImage *sima; SpaceImage *sima;
@ -768,6 +775,13 @@ static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot) void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot)
{ {
static EnumPropertyItem stroke_mode_items[] = {
{BRUSH_STROKE_NORMAL, "NORMAL", 0, "Normal", "Apply brush normally"},
{BRUSH_STROKE_INVERT, "INVERT", 0, "Invert", "Invert action of brush for duration of stroke"},
{BRUSH_STROKE_SMOOTH, "RELAX", 0, "Relax", "Switch brush to relax mode for duration of stroke"},
{0}
};
/* identifiers */ /* identifiers */
ot->name = "Sculpt UVs"; ot->name = "Sculpt UVs";
ot->description = "Sculpt UVs using a brush"; ot->description = "Sculpt UVs using a brush";
@ -782,6 +796,5 @@ void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
/* props */ /* props */
RNA_def_boolean(ot->srna, "invert", 0, "Invert", "Inverts the operator"); RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL, "Mode", "Stroke Mode");
RNA_def_boolean(ot->srna, "temp_relax", 0, "Relax", "Relax Tool");
} }

@ -1061,7 +1061,6 @@ ID *buttons_context_id_path(const bContext *C)
if(ptr->id.data) { if(ptr->id.data) {
return ptr->id.data; return ptr->id.data;
break;
} }
} }
} }

@ -586,7 +586,7 @@ const char * filelist_dir(struct FileList* filelist)
void filelist_setdir(struct FileList* filelist, const char *dir) void filelist_setdir(struct FileList* filelist, const char *dir)
{ {
BLI_strncpy(filelist->dir, dir, FILE_MAX); BLI_strncpy(filelist->dir, dir, sizeof(filelist->dir));
} }
void filelist_imgsize(struct FileList* filelist, short w, short h) void filelist_imgsize(struct FileList* filelist, short w, short h)
@ -854,8 +854,7 @@ static void filelist_read_library(struct FileList* filelist)
if(BLO_has_bfile_extension(file->relname)) { if(BLO_has_bfile_extension(file->relname)) {
char name[FILE_MAX]; char name[FILE_MAX];
BLI_strncpy(name, filelist->dir, sizeof(name)); BLI_join_dirfile(name, sizeof(name), filelist->dir, file->relname);
strcat(name, file->relname);
/* prevent current file being used as acceptable dir */ /* prevent current file being used as acceptable dir */
if (BLI_path_cmp(G.main->name, name) != 0) { if (BLI_path_cmp(G.main->name, name) != 0) {

@ -2069,6 +2069,7 @@ void GRAPH_OT_smooth (wmOperatorType *ot)
/* present a special customised popup menu for this, with some filtering */ /* present a special customised popup menu for this, with some filtering */
static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *UNUSED(event)) static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{ {
wmOperatorType *ot = WM_operatortype_find("GRAPH_OT_fmodifier_add", 1);
uiPopupMenu *pup; uiPopupMenu *pup;
uiLayout *layout; uiLayout *layout;
int i; int i;
@ -2086,7 +2087,7 @@ static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *UNU
continue; continue;
/* create operator menu item with relevant properties filled in */ /* create operator menu item with relevant properties filled in */
props_ptr= uiItemFullO(layout, "GRAPH_OT_fmodifier_add", fmi->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, fmi->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
/* the only thing that gets set from the menu is the type of F-Modifier to add */ /* the only thing that gets set from the menu is the type of F-Modifier to add */
RNA_enum_set(&props_ptr, "type", i); RNA_enum_set(&props_ptr, "type", i);
/* the following properties are just repeats of existing ones... */ /* the following properties are just repeats of existing ones... */

@ -1233,6 +1233,9 @@ static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, Point
PropertyRNA *prop; PropertyRNA *prop;
const char *layer_name; const char *layer_name;
char scene_name[MAX_ID_NAME-2]; char scene_name[MAX_ID_NAME-2];
wmOperatorType *ot = WM_operatortype_find("RENDER_OT_render", 1);
BLI_assert(ot != 0);
uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL); uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL);
@ -1249,10 +1252,10 @@ static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, Point
scn_ptr = RNA_pointer_get(ptr, "scene"); scn_ptr = RNA_pointer_get(ptr, "scene");
RNA_string_get(&scn_ptr, "name", scene_name); RNA_string_get(&scn_ptr, "name", scene_name);
WM_operator_properties_create(&op_ptr, "RENDER_OT_render"); WM_operator_properties_create_ptr(&op_ptr, ot);
RNA_string_set(&op_ptr, "layer", layer_name); RNA_string_set(&op_ptr, "layer", layer_name);
RNA_string_set(&op_ptr, "scene", scene_name); RNA_string_set(&op_ptr, "scene", scene_name);
uiItemFullO(row, "RENDER_OT_render", "", ICON_RENDER_STILL, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); uiItemFullO_ptr(row, ot, "", ICON_RENDER_STILL, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
} }

@ -1258,8 +1258,10 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if ( (SEARCHING_OUTLINER(soops) || (soops->outlinevis==SO_DATABLOCKS && soops->search_string[0]!=0)) && if ( (SEARCHING_OUTLINER(soops) || (soops->outlinevis==SO_DATABLOCKS && soops->search_string[0]!=0)) &&
(tselem->flag & TSE_SEARCHMATCH)) (tselem->flag & TSE_SEARCHMATCH))
{ {
/* TODO - add search highlight color to theme? */ char col[4];
glColor4f(0.2f, 0.5f, 0.2f, 0.3f); UI_GetThemeColorType4ubv(TH_MATCH, SPACE_OUTLINER, col);
col[3]=100;
glColor4ubv((GLubyte *)col);
glRecti(startx, *starty+1, ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1); glRecti(startx, *starty+1, ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1);
} }
@ -1513,8 +1515,8 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio
} }
/* always draw selection fill before hierarchy */ /* always draw selection fill before hierarchy */
UI_GetThemeColor3fv(TH_BACK, col); UI_GetThemeColor3fv(TH_SELECT_HIGHLIGHT, col);
glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f); glColor3fv(col);
starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET;
outliner_draw_selection(ar, soops, &soops->tree, &starty); outliner_draw_selection(ar, soops, &soops->tree, &starty);

@ -1429,3 +1429,278 @@ void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot)
/* flags */ /* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
} }
/* ******************** Parent Drop Operator *********************** */
static int parent_drop_exec(bContext *C, wmOperator *op)
{
Object *par = NULL;
int partype = -1;
char parname[32];
partype= RNA_enum_get(op->ptr, "type");
RNA_string_get(op->ptr, "parent", parname);
par= (Object *)find_id("OB", parname);
ED_object_parent_set(C, op, par, partype);
return OPERATOR_FINISHED;
}
/* Used for drag and drop parenting */
TreeElement *outliner_dropzone_parent(bContext *C, wmEvent *event, TreeElement *te, float *fmval)
{
SpaceOops *soops= CTX_wm_space_outliner(C);
TreeStoreElem *tselem= TREESTORE(te);
if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) {
/* name and first icon */
if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) {
/* always makes active object */
if (te->idcode == ID_OB) {
return te;
}
else {
return NULL;
}
}
}
/* Not it. Let's look at its children. */
if ((tselem->flag & TSE_CLOSED)==0 && (te->subtree.first)) {
for (te = te->subtree.first; te; te = te->next) {
TreeElement *te_valid;
te_valid= outliner_dropzone_parent(C, event, te, fmval);
if (te_valid) return te_valid;
}
}
return NULL;
}
static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Object *par= NULL;
Object *ob= NULL;
SpaceOops *soops= CTX_wm_space_outliner(C);
ARegion *ar= CTX_wm_region(C);
Scene *scene= CTX_data_scene(C);
TreeElement *te= NULL;
TreeElement *te_found= NULL;
char childname[MAX_ID_NAME];
char parname[MAX_ID_NAME];
int partype= 0;
float fmval[2];
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
/* Find object hovered over */
for (te= soops->tree.first; te; te= te->next) {
te_found= outliner_dropzone_parent(C, event, te, fmval);
if (te_found) break;
}
if(te_found) {
RNA_string_set(op->ptr, "parent", te_found->name);
/* Identify parent and child */
RNA_string_get(op->ptr, "child", childname);
ob= (Object *)find_id("OB", childname);
RNA_string_get(op->ptr, "parent", parname);
par= (Object *)find_id("OB", parname);
if (ELEM(NULL, ob, par)) {
if (par == NULL) printf("par==NULL\n");
return OPERATOR_CANCELLED;
}
if (ob == par) {
return OPERATOR_CANCELLED;
}
/* check dragged object (child) is active */
if (ob != CTX_data_active_object(C))
ED_base_object_select(object_in_scene(ob, scene), BA_SELECT);
if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) {
ED_object_parent_set(C, op, par, partype);
}
else {
/* Menu creation */
uiPopupMenu *pup= uiPupMenuBegin(C, "Set Parent To", ICON_NONE);
uiLayout *layout= uiPupMenuLayout(pup);
PointerRNA ptr;
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_OBJECT);
/* Cannot use uiItemEnumO()... have multiple properties to set. */
uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Object", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
/* par becomes parent, make the associated menus */
if (par->type==OB_ARMATURE) {
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_ARMATURE);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Armature Deform", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", " With Empty Groups", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", " With Envelope Weights", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", " With Automatic Weights", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_BONE);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Bone", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
}
else if (par->type==OB_CURVE) {
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_CURVE);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Curve Deform", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_FOLLOW);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Follow Path", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_PATH_CONST);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Path Constraint", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
}
else if (par->type == OB_LATTICE) {
WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop");
RNA_string_set(&ptr, "parent", parname);
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_LATTICE);
uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Lattice Deform", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
}
uiPupMenuEnd(C, pup);
return OPERATOR_CANCELLED;
}
}
else {
return OPERATOR_CANCELLED;
}
return OPERATOR_FINISHED;
}
void OUTLINER_OT_parent_drop(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Drop to Set Parent";
ot->description = "Drag to parent in Outliner";
ot->idname= "OUTLINER_OT_parent_drop";
/* api callbacks */
ot->invoke= parent_drop_invoke;
ot->exec= parent_drop_exec;
ot->poll= ED_operator_outliner_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object");
RNA_def_string(ot->srna, "parent", "Object", MAX_ID_NAME, "Parent", "Parent Object");
RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
}
int outliner_dropzone_parent_clear(bContext *C, wmEvent *event, TreeElement *te, float *fmval)
{
SpaceOops *soops= CTX_wm_space_outliner(C);
TreeStoreElem *tselem= TREESTORE(te);
/* Check for row */
if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) {
/* Ignore drop on scene tree elements */
if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) {
if ((te->idcode == ID_SCE) &&
!ELEM3(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS))
{
return 0;
}
// Other codes to ignore?
}
/* Left or right of: (+), first icon, and name */
if ((fmval[0] < (te->xs + UI_UNIT_X)) || (fmval[0] > te->xend)) {
return 1;
}
else if (te->idcode != ID_OB) {
return 1;
}
return 0; // ID_OB, but mouse in undefined dropzone.
}
/* Not this row. Let's look at its children. */
if ((tselem->flag & TSE_CLOSED)==0 && (te->subtree.first)) {
for (te = te->subtree.first; te; te = te->next) {
if (outliner_dropzone_parent_clear(C, event, te, fmval))
return 1;
}
}
return 0;
}
static int parent_clear_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
Scene *scene= CTX_data_scene(C);
Object *ob= NULL;
char obname[MAX_ID_NAME];
RNA_string_get(op->ptr, "dragged_obj", obname);
ob= (Object *)find_id("OB", obname);
/* check dragged object (child) is active */
if (ob != CTX_data_active_object(C))
ED_base_object_select(object_in_scene(ob, scene), BA_SELECT);
ED_object_parent_clear(C, RNA_enum_get(op->ptr, "type"));
return OPERATOR_FINISHED;
}
void OUTLINER_OT_parent_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Drop to Clear Parent";
ot->description = "Drag to clear parent in outliner";
ot->idname= "OUTLINER_OT_parent_clear";
/* api callbacks */
ot->invoke= parent_clear_invoke;
ot->poll= ED_operator_outliner_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object");
RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", "");
}

@ -188,6 +188,9 @@ void group_toggle_renderability_cb(struct bContext *C, struct Scene *scene, Tree
void item_rename_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem); void item_rename_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
TreeElement *outliner_dropzone_parent(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
int outliner_dropzone_parent_clear(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
/* ...................................................... */ /* ...................................................... */
void OUTLINER_OT_item_activate(struct wmOperatorType *ot); void OUTLINER_OT_item_activate(struct wmOperatorType *ot);
@ -215,6 +218,9 @@ void OUTLINER_OT_keyingset_remove_selected(struct wmOperatorType *ot);
void OUTLINER_OT_drivers_add_selected(struct wmOperatorType *ot); void OUTLINER_OT_drivers_add_selected(struct wmOperatorType *ot);
void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot); void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot);
void OUTLINER_OT_parent_drop(struct wmOperatorType *ot);
void OUTLINER_OT_parent_clear(struct wmOperatorType *ot);
/* outliner_tools.c ---------------------------------------------- */ /* outliner_tools.c ---------------------------------------------- */
void OUTLINER_OT_operation(struct wmOperatorType *ot); void OUTLINER_OT_operation(struct wmOperatorType *ot);

@ -77,6 +77,9 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_drivers_add_selected); WM_operatortype_append(OUTLINER_OT_drivers_add_selected);
WM_operatortype_append(OUTLINER_OT_drivers_delete_selected); WM_operatortype_append(OUTLINER_OT_drivers_delete_selected);
WM_operatortype_append(OUTLINER_OT_parent_drop);
WM_operatortype_append(OUTLINER_OT_parent_clear);
} }
void outliner_keymap(wmKeyConfig *keyconf) void outliner_keymap(wmKeyConfig *keyconf)

@ -50,6 +50,8 @@
#include "BIF_gl.h" #include "BIF_gl.h"
#include "RNA_access.h"
#include "UI_resources.h" #include "UI_resources.h"
#include "UI_view2d.h" #include "UI_view2d.h"
@ -58,6 +60,7 @@
static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar) static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
{ {
ListBase *lb;
wmKeyMap *keymap; wmKeyMap *keymap;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
@ -66,6 +69,88 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
keymap= WM_keymap_find(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0); keymap= WM_keymap_find(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0);
/* don't pass on view2d mask, it's always set with scrollbar space, hide fails */ /* don't pass on view2d mask, it's always set with scrollbar space, hide fails */
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, &ar->winrct); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, &ar->winrct);
/* Add dropboxes */
lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
WM_event_add_dropbox_handler(&ar->handlers, lb);
}
static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
{
ARegion *ar= CTX_wm_region(C);
SpaceOops *soops= CTX_wm_space_outliner(C);
TreeElement *te= NULL;
float fmval[2];
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
if(drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
if( GS(id->name) == ID_OB ) {
/* Ensure item under cursor is valid drop target */
/* Find object hovered over */
for(te= soops->tree.first; te; te= te->next) {
TreeElement *te_valid;
te_valid= outliner_dropzone_parent(C, event, te, fmval);
if(te_valid) return 1;
}
}
}
return 0;
}
static void outliner_parent_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = (ID *)drag->poin;
RNA_string_set(drop->ptr, "child", id->name+2);
}
static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, wmEvent *event)
{
ARegion *ar= CTX_wm_region(C);
SpaceOops *soops= CTX_wm_space_outliner(C);
TreeElement *te= NULL;
float fmval[2];
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
if(drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
if( GS(id->name) == ID_OB ) {
//TODO: Check if no parent?
/* Ensure location under cursor is valid dropzone */
for(te= soops->tree.first; te; te= te->next) {
if(outliner_dropzone_parent_clear(C, event, te, fmval)) return 1;
}
/* Check if mouse cursor is below the tree */
te= soops->tree.last;
while(((te->flag & TE_LAZY_CLOSED)==0) && (te->subtree.last)) {
te= te->subtree.last;
}
if(fmval[1] < te->ys) return 1;
}
}
return 0;
}
static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = (ID *)drag->poin;
RNA_string_set(drop->ptr, "dragged_obj", id->name+2);
/* Set to simple parent clear type. Avoid menus for drag and drop if possible.
If desired, user can toggle the different "Clear Parent" types in the operator
menu on tool shelf. */
RNA_string_set(drop->ptr, "type", 0);
}
/* region dropbox definition */
static void outliner_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", outliner_parent_drop_poll, outliner_parent_drop_copy);
WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", outliner_parent_clear_poll, outliner_parent_clear_copy);
} }
static void outliner_main_area_draw(const bContext *C, ARegion *ar) static void outliner_main_area_draw(const bContext *C, ARegion *ar)
@ -302,6 +387,7 @@ void ED_spacetype_outliner(void)
st->duplicate= outliner_duplicate; st->duplicate= outliner_duplicate;
st->operatortypes= outliner_operatortypes; st->operatortypes= outliner_operatortypes;
st->keymap= outliner_keymap; st->keymap= outliner_keymap;
st->dropboxes= outliner_dropboxes;
/* regions: main window */ /* regions: main window */
art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); art= MEM_callocN(sizeof(ARegionType), "spacetype time region");

@ -96,8 +96,8 @@ static int script_reload_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED; return OPERATOR_FINISHED;
#else #else
(void)C; /* unused */ (void)C; /* unused */
#endif
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
#endif
} }
void SCRIPT_OT_reload(wmOperatorType *ot) void SCRIPT_OT_reload(wmOperatorType *ot)

@ -3187,25 +3187,25 @@ static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *UN
/* modified locally and externally, ahhh. offer more possibilites. */ /* modified locally and externally, ahhh. offer more possibilites. */
pup= uiPupMenuBegin(C, "File Modified Outside and Inside Blender", ICON_NONE); pup= uiPupMenuBegin(C, "File Modified Outside and Inside Blender", ICON_NONE);
layout= uiPupMenuLayout(pup); layout= uiPupMenuLayout(pup);
uiItemEnumO(layout, op->type->idname, "Reload from disk (ignore local changes)", 0, "resolution", RESOLVE_RELOAD); uiItemEnumO_ptr(layout, op->type, "Reload from disk (ignore local changes)", 0, "resolution", RESOLVE_RELOAD);
uiItemEnumO(layout, op->type->idname, "Save to disk (ignore outside changes)", 0, "resolution", RESOLVE_SAVE); uiItemEnumO_ptr(layout, op->type, "Save to disk (ignore outside changes)", 0, "resolution", RESOLVE_SAVE);
uiItemEnumO(layout, op->type->idname, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL); uiItemEnumO_ptr(layout, op->type, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL);
uiPupMenuEnd(C, pup); uiPupMenuEnd(C, pup);
} }
else { else {
pup= uiPupMenuBegin(C, "File Modified Outside Blender", ICON_NONE); pup= uiPupMenuBegin(C, "File Modified Outside Blender", ICON_NONE);
layout= uiPupMenuLayout(pup); layout= uiPupMenuLayout(pup);
uiItemEnumO(layout, op->type->idname, "Reload from disk", 0, "resolution", RESOLVE_RELOAD); uiItemEnumO_ptr(layout, op->type, "Reload from disk", 0, "resolution", RESOLVE_RELOAD);
uiItemEnumO(layout, op->type->idname, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL); uiItemEnumO_ptr(layout, op->type, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL);
uiItemEnumO(layout, op->type->idname, "Ignore", 0, "resolution", RESOLVE_IGNORE); uiItemEnumO_ptr(layout, op->type, "Ignore", 0, "resolution", RESOLVE_IGNORE);
uiPupMenuEnd(C, pup); uiPupMenuEnd(C, pup);
} }
break; break;
case 2: case 2:
pup= uiPupMenuBegin(C, "File Deleted Outside Blender", ICON_NONE); pup= uiPupMenuBegin(C, "File Deleted Outside Blender", ICON_NONE);
layout= uiPupMenuLayout(pup); layout= uiPupMenuLayout(pup);
uiItemEnumO(layout, op->type->idname, "Make text internal", 0, "resolution", RESOLVE_MAKE_INTERNAL); uiItemEnumO_ptr(layout, op->type, "Make text internal", 0, "resolution", RESOLVE_MAKE_INTERNAL);
uiItemEnumO(layout, op->type->idname, "Recreate file", 0, "resolution", RESOLVE_SAVE); uiItemEnumO_ptr(layout, op->type, "Recreate file", 0, "resolution", RESOLVE_SAVE);
uiPupMenuEnd(C, pup); uiPupMenuEnd(C, pup);
break; break;
} }

@ -518,49 +518,51 @@ static void viewops_data_free(bContext *C, wmOperator *op)
static const float thres = 0.93f; //cos(20 deg); static const float thres = 0.93f; //cos(20 deg);
#define COS45 0.70710678118654746 #define COS45 0.7071068
#define SIN45 COS45 #define SIN45 COS45
static float snapquats[39][5] = { #define NUM_SNAP_QUATS 39
static const float snapquats[NUM_SNAP_QUATS][5] = {
/*{q0, q1, q3, q4, view}*/ /*{q0, q1, q3, q4, view}*/
{COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT}, //front {COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT},
{0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK}, //back {0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK},
{1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP}, //top {1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP},
{0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM}, //bottom {0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM},
{0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT}, //left {0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT},
{0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT}, //right {0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT},
/* some more 45 deg snaps */ /* some more 45 deg snaps */
{0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0}, { 0.6532815, -0.6532815, 0.2705981, 0.2705981, 0},
{0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0}, { 0.9238795, 0.0, 0.0, 0.3826834, 0},
{0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0}, { 0.0, -0.9238795, 0.3826834, 0.0, 0},
{0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0}, { 0.3535534, -0.8535534, 0.3535534, 0.1464466, 0},
{0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0}, { 0.8535534, -0.3535534, 0.1464466, 0.3535534, 0},
{0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0}, { 0.4999999, -0.4999999, 0.5, 0.5, 0},
{0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0}, { 0.2705980, -0.6532815, 0.6532815, 0.2705980, 0},
{0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0}, { 0.6532815, -0.2705980, 0.2705980, 0.6532815, 0},
{0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0}, { 0.2705978, -0.2705980, 0.6532814, 0.6532814, 0},
{0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0}, { 0.3826834, 0.0, 0.0, 0.9238794, 0},
{0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0}, { 0.0, -0.3826834, 0.9238794, 0.0, 0},
{0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0}, { 0.1464466, -0.3535534, 0.8535534, 0.3535534, 0},
{0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0}, { 0.3535534, -0.1464466, 0.3535534, 0.8535534, 0},
{0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0}, { 0.0, 0.0, 0.9238794, 0.3826834, 0},
{-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0}, {-0.0, 0.0, 0.3826834, 0.9238794, 0},
{-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0}, {-0.2705980, 0.2705980, 0.6532813, 0.6532813, 0},
{-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0}, {-0.3826834, 0.0, 0.0, 0.9238794, 0},
{0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0}, { 0.0, 0.3826834, 0.9238794, 0.0, 0},
{-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0}, {-0.1464466, 0.3535534, 0.8535533, 0.3535533, 0},
{-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0}, {-0.3535534, 0.1464466, 0.3535533, 0.8535533, 0},
{-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0}, {-0.4999999, 0.4999999, 0.4999999, 0.4999999, 0},
{-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0}, {-0.2705980, 0.6532815, 0.6532814, 0.2705980, 0},
{-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0}, {-0.6532815, 0.2705980, 0.2705980, 0.6532814, 0},
{-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0}, {-0.6532813, 0.6532813, 0.2705979, 0.2705979, 0},
{-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0}, {-0.9238793, 0.0, 0.0, 0.3826833, 0},
{0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0}, { 0.0, 0.9238793, 0.3826833, 0.0, 0},
{-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0}, {-0.3535533, 0.8535533, 0.3535533, 0.1464466, 0},
{-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0}, {-0.8535533, 0.3535533, 0.1464466, 0.3535533, 0},
{-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0}, {-0.3826833, 0.9238794, 0.0, 0.0, 0},
{-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0}, {-0.9238794, 0.3826833, 0.0, 0.0, 0},
{-COS45, 0.0, 0.0, SIN45, 0}, {-COS45, 0.0, 0.0, SIN45, 0},
{ COS45, 0.0, 0.0, SIN45, 0}, { COS45, 0.0, 0.0, SIN45, 0},
{ 0.0, 0.0, 0.0, 1.0, 0} { 0.0, 0.0, 0.0, 1.0, 0}
@ -632,7 +634,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
sub_v3_v3v3(dvec, newvec, vod->trackvec); sub_v3_v3v3(dvec, newvec, vod->trackvec);
si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]); si = len_v3(dvec);
si /= (float)(2.0 * TRACKBALLSIZE); si /= (float)(2.0 * TRACKBALLSIZE);
cross_v3_v3v3(q1+1, vod->trackvec, newvec); cross_v3_v3v3(q1+1, vod->trackvec, newvec);
@ -724,7 +726,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
mul_qt_v3(viewquat_inv, zaxis); mul_qt_v3(viewquat_inv, zaxis);
for (i = 0 ; i < 39; i++){ for (i = 0 ; i < NUM_SNAP_QUATS; i++){
float view = (int)snapquats[i][4]; float view = (int)snapquats[i][4];
float viewquat_inv_test[4]; float viewquat_inv_test[4];
@ -961,8 +963,9 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
} }
// NDOF utility functions /* NDOF utility functions
// (should these functions live in this file?) * (should these functions live in this file?)
*/
float ndof_to_axis_angle(struct wmNDOFMotionData* ndof, float axis[3]) float ndof_to_axis_angle(struct wmNDOFMotionData* ndof, float axis[3])
{ {
return ndof->dt * normalize_v3_v3(axis, ndof->rvec); return ndof->dt * normalize_v3_v3(axis, ndof->rvec);
@ -983,9 +986,8 @@ void ndof_to_quat(struct wmNDOFMotionData* ndof, float q[4])
*/ */
static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
{ {
if (event->type != NDOF_MOTION) { if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
}
else { else {
View3D *v3d = CTX_wm_view3d(C); View3D *v3d = CTX_wm_view3d(C);
RegionView3D* rv3d = CTX_wm_region_view3d(C); RegionView3D* rv3d = CTX_wm_region_view3d(C);
@ -993,35 +995,34 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
ED_view3d_camera_lock_init(v3d, rv3d); ED_view3d_camera_lock_init(v3d, rv3d);
rv3d->rot_angle = 0.f; // off by default, until changed later this function rv3d->rot_angle = 0.f; /* off by default, until changed later this function */
if (ndof->progress != P_FINISHING) { if (ndof->progress != P_FINISHING) {
const float dt = ndof->dt; const float dt = ndof->dt;
// tune these until everything feels right /* tune these until everything feels right */
const float rot_sensitivity = 1.f; const float rot_sensitivity = 1.f;
const float zoom_sensitivity = 1.f; const float zoom_sensitivity = 1.f;
const float pan_sensitivity = 1.f; const float pan_sensitivity = 1.f;
// rather have bool, but... const int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec);
int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec);
float view_inv[4]; float view_inv[4];
invert_qt_qt(view_inv, rv3d->viewquat); invert_qt_qt(view_inv, rv3d->viewquat);
//#define DEBUG_NDOF_MOTION /* #define DEBUG_NDOF_MOTION */
#ifdef DEBUG_NDOF_MOTION #ifdef DEBUG_NDOF_MOTION
printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n", printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt); ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
#endif #endif
if (ndof->tvec[2]) { if (ndof->tz) {
// Zoom! /* Zoom!
// velocity should be proportional to the linear velocity attained by rotational motion of same strength * velocity should be proportional to the linear velocity attained by rotational motion of same strength
// [got that?] * [got that?]
// proportional to arclength = radius * angle * proportional to arclength = radius * angle
*/
float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2]; float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
if (U.ndof_flag & NDOF_ZOOM_INVERT) if (U.ndof_flag & NDOF_ZOOM_INVERT)
zoom_distance = -zoom_distance; zoom_distance = -zoom_distance;
@ -1031,7 +1032,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
if (rv3d->viewlock == RV3D_LOCKED) { if (rv3d->viewlock == RV3D_LOCKED) {
/* rotation not allowed -- explore panning options instead */ /* rotation not allowed -- explore panning options instead */
float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f}; float pan_vec[3] = {ndof->tx, ndof->ty, 0.0f};
mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
/* transform motion from view to world coordinates */ /* transform motion from view to world coordinates */
@ -1060,18 +1061,20 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS)
axis[1] = -axis[1]; axis[1] = -axis[1];
// transform rotation axis from view to world coordinates /* transform rotation axis from view to world coordinates */
mul_qt_v3(view_inv, axis); mul_qt_v3(view_inv, axis);
// update the onscreen doo-dad /* update the onscreen doo-dad */
rv3d->rot_angle = angle; rv3d->rot_angle = angle;
copy_v3_v3(rv3d->rot_axis, axis); copy_v3_v3(rv3d->rot_axis, axis);
axis_angle_to_quat(rot, axis, angle); axis_angle_to_quat(rot, axis, angle);
// apply rotation /* apply rotation */
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
} else { } else {
/* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
float angle, rot[4]; float angle, rot[4];
float xvec[3] = {1,0,0}; float xvec[3] = {1,0,0};
@ -1080,7 +1083,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
mul_qt_v3(view_inv, xvec); mul_qt_v3(view_inv, xvec);
/* Perform the up/down rotation */ /* Perform the up/down rotation */
angle = rot_sensitivity * dt * ndof->rvec[0]; angle = rot_sensitivity * dt * ndof->rx;
if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) if (U.ndof_flag & NDOF_TILT_INVERT_AXIS)
angle = -angle; angle = -angle;
rot[0] = cos(angle); rot[0] = cos(angle);
@ -1088,11 +1091,11 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
/* Perform the orbital rotation */ /* Perform the orbital rotation */
angle = rot_sensitivity * dt * ndof->rvec[1]; angle = rot_sensitivity * dt * ndof->ry;
if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS)
angle = -angle; angle = -angle;
// update the onscreen doo-dad /* update the onscreen doo-dad */
rv3d->rot_angle = angle; rv3d->rot_angle = angle;
rv3d->rot_axis[0] = 0; rv3d->rot_axis[0] = 0;
rv3d->rot_axis[1] = 0; rv3d->rot_axis[1] = 0;
@ -1134,9 +1137,8 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
*/ */
static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
{ {
if (event->type != NDOF_MOTION) { if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
}
else { else {
View3D *v3d= CTX_wm_view3d(C); View3D *v3d= CTX_wm_view3d(C);
RegionView3D* rv3d = CTX_wm_region_view3d(C); RegionView3D* rv3d = CTX_wm_region_view3d(C);
@ -1144,13 +1146,13 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
ED_view3d_camera_lock_init(v3d, rv3d); ED_view3d_camera_lock_init(v3d, rv3d);
rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators rv3d->rot_angle = 0.f; /* we're panning here! so erase any leftover rotation from other operators */
if (ndof->progress != P_FINISHING) { if (ndof->progress != P_FINISHING) {
const float dt = ndof->dt; const float dt = ndof->dt;
float view_inv[4]; float view_inv[4];
#if 0 // ------------------------------------------- zoom with Z #if 0 /* ------------------------------------------- zoom with Z */
// tune these until everything feels right /* tune these until everything feels right */
const float zoom_sensitivity = 1.f; const float zoom_sensitivity = 1.f;
const float pan_sensitivity = 1.f; const float pan_sensitivity = 1.f;
@ -1158,18 +1160,18 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
ndof->tx, ndof->ty, 0 ndof->tx, ndof->ty, 0
}; };
// "zoom in" or "translate"? depends on zoom mode in user settings? /* "zoom in" or "translate"? depends on zoom mode in user settings? */
if (ndof->tz) { if (ndof->tz) {
float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
rv3d->dist += zoom_distance; rv3d->dist += zoom_distance;
} }
mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
#else // ------------------------------------------------------- dolly with Z #else /* ------------------------------------------------------- dolly with Z */
float speed = 10.f; // blender units per second float speed = 10.f; /* blender units per second */
// ^^ this is ok for default cube scene, but should scale with.. something /* ^^ this is ok for default cube scene, but should scale with.. something */
// tune these until everything feels right /* tune these until everything feels right */
const float forward_sensitivity = 1.f; const float forward_sensitivity = 1.f;
const float vertical_sensitivity = 0.4f; const float vertical_sensitivity = 0.4f;
const float lateral_sensitivity = 0.6f; const float lateral_sensitivity = 0.6f;

@ -58,6 +58,7 @@
#include "UI_resources.h" #include "UI_resources.h"
#include "WM_types.h" #include "WM_types.h"
#include "WM_api.h"
#include "RNA_access.h" #include "RNA_access.h"
@ -165,12 +166,13 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
uiPopupMenu *pup; uiPopupMenu *pup;
uiLayout *layout; uiLayout *layout;
char line[FILE_MAX + 100]; char line[FILE_MAX + 100];
wmOperatorType *ot = WM_operatortype_find(opname, 1);
pup= uiPupMenuBegin(C, "Unpack file", ICON_NONE); pup= uiPupMenuBegin(C, "Unpack file", ICON_NONE);
layout= uiPupMenuLayout(pup); layout= uiPupMenuLayout(pup);
strcpy(line, "Remove Pack"); strcpy(line, "Remove Pack");
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_REMOVE); RNA_enum_set(&props_ptr, "method", PF_REMOVE);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
@ -184,29 +186,29 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
switch(checkPackedFile(local_name, pf)) { switch(checkPackedFile(local_name, pf)) {
case PF_NOFILE: case PF_NOFILE:
BLI_snprintf(line, sizeof(line), "Create %s", local_name); BLI_snprintf(line, sizeof(line), "Create %s", local_name);
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
break; break;
case PF_EQUAL: case PF_EQUAL:
BLI_snprintf(line, sizeof(line), "Use %s (identical)", local_name); BLI_snprintf(line, sizeof(line), "Use %s (identical)", local_name);
//uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL);
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
break; break;
case PF_DIFFERS: case PF_DIFFERS:
BLI_snprintf(line, sizeof(line), "Use %s (differs)", local_name); BLI_snprintf(line, sizeof(line), "Use %s (differs)", local_name);
//uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL);
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
BLI_snprintf(line, sizeof(line), "Overwrite %s", local_name); BLI_snprintf(line, sizeof(line), "Overwrite %s", local_name);
//uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_LOCAL); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_LOCAL);
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
break; break;
@ -217,28 +219,28 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
switch(checkPackedFile(abs_name, pf)) { switch(checkPackedFile(abs_name, pf)) {
case PF_NOFILE: case PF_NOFILE:
BLI_snprintf(line, sizeof(line), "Create %s", abs_name); BLI_snprintf(line, sizeof(line), "Create %s", abs_name);
//uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
break; break;
case PF_EQUAL: case PF_EQUAL:
BLI_snprintf(line, sizeof(line), "Use %s (identical)", abs_name); BLI_snprintf(line, sizeof(line), "Use %s (identical)", abs_name);
//uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL);
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
break; break;
case PF_DIFFERS: case PF_DIFFERS:
BLI_snprintf(line, sizeof(line), "Use %s (differs)", abs_name); BLI_snprintf(line, sizeof(line), "Use %s (differs)", abs_name);
//uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL);
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
BLI_snprintf(line, sizeof(line), "Overwrite %s", abs_name); BLI_snprintf(line, sizeof(line), "Overwrite %s", abs_name);
//uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
RNA_string_set(&props_ptr, "id", id_name); RNA_string_set(&props_ptr, "id", id_name);
break; break;

@ -916,12 +916,13 @@ static void stitch_select_uv(UvElement *element, StitchState *stitch_state, int
} }
} }
static void stitch_calculate_edge_normal(EditMesh *em, UvEdge *edge, float *normal){ static void stitch_calculate_edge_normal(EditMesh *em, UvEdge *edge, float *normal)
{
UvElement *element = edge->element; UvElement *element = edge->element;
EditFace *efa = element->face; EditFace *efa = element->face;
MTFace *mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); MTFace *mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
int nverts = efa->v4?4 : 3; int nverts = efa->v4?4 : 3;
int index = index = (element->tfindex + 2)%nverts; int index = (element->tfindex + 2)%nverts;
float tangent[2], internal[2]; float tangent[2], internal[2];
sub_v2_v2v2(tangent, mt->uv[(element->tfindex + 1)%nverts], mt->uv[element->tfindex]); sub_v2_v2v2(tangent, mt->uv[(element->tfindex + 1)%nverts], mt->uv[element->tfindex]);

@ -50,7 +50,7 @@
struct ImMetaData; struct ImMetaData;
#define IB_MIPMAP_LEVELS 20 #define IB_MIPMAP_LEVELS 20
#define IB_FILENAME_SIZE 1023 #define IB_FILENAME_SIZE 1024
/** /**
* \ingroup imbuf * \ingroup imbuf

@ -136,9 +136,9 @@ struct anim {
int x, y; int x, y;
/* voor op nummer */ /* voor op nummer */
char name[256]; char name[1024];
/* voor sequence */ /* voor sequence */
char first[256]; char first[1024];
/* movie */ /* movie */
void *movie; void *movie;
@ -189,7 +189,7 @@ struct anim {
struct redcode_handle * redcodeCtx; struct redcode_handle * redcodeCtx;
#endif #endif
char index_dir[256]; char index_dir[768];
int proxies_tried; int proxies_tried;
int indices_tried; int indices_tried;

@ -62,7 +62,7 @@ typedef struct anim_index_entry {
} anim_index_entry; } anim_index_entry;
struct anim_index { struct anim_index {
char name[256]; char name[1024];
int num_entries; int num_entries;
struct anim_index_entry * entries; struct anim_index_entry * entries;

@ -128,8 +128,8 @@ typedef struct Library {
ID id; ID id;
ID *idblock; ID *idblock;
struct FileData *filedata; struct FileData *filedata;
char name[240]; /* path name used for reading, can be relative and edited in the outliner */ char name[1024]; /* path name used for reading, can be relative and edited in the outliner */
char filepath[240]; /* absolute filepath, this is only for convenience, char filepath[1024]; /* absolute filepath, this is only for convenience,
* 'name' is the real path used on file read but in * 'name' is the real path used on file read but in
* some cases its useful to access the absolute one, * some cases its useful to access the absolute one,
* This is set on file read. * This is set on file read.

@ -59,7 +59,7 @@ typedef struct Brush {
struct ImBuf *icon_imbuf; struct ImBuf *icon_imbuf;
PreviewImage *preview; PreviewImage *preview;
char icon_filepath[240]; /* 240 = FILE_MAX */ char icon_filepath[1024]; /* 1024 = FILE_MAX */
float normal_weight; float normal_weight;

@ -55,7 +55,7 @@ typedef struct CustomDataLayer {
#define MAX_CUSTOMDATA_LAYER_NAME 64 #define MAX_CUSTOMDATA_LAYER_NAME 64
typedef struct CustomDataExternal { typedef struct CustomDataExternal {
char filename[240]; /* FILE_MAX */ char filename[1024]; /* FILE_MAX */
} CustomDataExternal; } CustomDataExternal;
/** structure which stores custom element data associated with mesh elements /** structure which stores custom element data associated with mesh elements

@ -128,7 +128,7 @@ typedef struct DynamicPaintSurface {
float wave_damping, wave_speed, wave_timescale, wave_spring; float wave_damping, wave_speed, wave_timescale, wave_spring;
char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
char image_output_path[240]; /* 240 = FILE_MAX */ char image_output_path[1024]; /* 1024 = FILE_MAX */
char output_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ char output_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
char output_name2[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ /* some surfaces have 2 outputs */ char output_name2[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ /* some surfaces have 2 outputs */

@ -51,7 +51,7 @@ typedef struct FileGlobal {
int revision; /* svn revision from buildinfo */ int revision; /* svn revision from buildinfo */
int pad; int pad;
/* file path where this was saved, for recover */ /* file path where this was saved, for recover */
char filename[240]; /* 240 = FILE_MAX */ char filename[1024]; /* 1024 = FILE_MAX */
} FileGlobal; } FileGlobal;

@ -69,7 +69,7 @@ typedef struct ImageUser {
typedef struct Image { typedef struct Image {
ID id; ID id;
char name[240]; /* file path, 240 = FILE_MAX */ char name[1024]; /* file path, 1024 = FILE_MAX */
ListBase ibufs; /* not written in file */ ListBase ibufs; /* not written in file */
struct GPUTexture *gputexture; /* not written in file */ struct GPUTexture *gputexture; /* not written in file */

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