[SCM] blender/upstream: Imported Upstream version 2.76.a+dfsg0
mfv at users.alioth.debian.org
mfv at users.alioth.debian.org
Wed Dec 9 21:43:42 UTC 2015
The following commit has been merged in the upstream branch:
commit 65f721dad143aca88ecdfbafe0a3100d11f81a50
Author: Matteo F. Vescovi <mfv at debian.org>
Date: Fri Nov 13 21:19:18 2015 +0100
Imported Upstream version 2.76.a+dfsg0
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 0a79bfb..065bd1a 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -487,6 +487,11 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings b_render,
BlenderCamera bcam;
float aspectratio, sensor_size;
blender_camera_init(&bcam, b_render);
+
+ /* TODO(sergey): Consider making it a part of blender_camera_init(). */
+ bcam.pixelaspect.x = b_render.pixel_aspect_x();
+ bcam.pixelaspect.y = b_render.pixel_aspect_y();
+
blender_camera_from_object(&bcam, b_engine, b_ob);
blender_camera_viewplane(&bcam,
width, height,
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index ba309a1..9cc31ca 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -51,11 +51,7 @@ typedef struct IsectPrecalc {
#if defined(__KERNEL_CUDA__)
# if (defined(i386) || defined(_M_IX86))
-# if __CUDA_ARCH__ > 500
ccl_device_noinline
-# else /* __CUDA_ARCH__ > 500 */
-ccl_device_inline
-# endif /* __CUDA_ARCH__ > 500 */
# else /* (defined(i386) || defined(_M_IX86)) */
# if defined(__KERNEL_EXPERIMENTAL__) && (__CUDA_ARCH__ >= 500)
ccl_device_noinline
@@ -142,12 +138,8 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
float U = Cx * By - Cy * Bx;
float V = Ax * Cy - Ay * Cx;
float W = Bx * Ay - By * Ax;
- const int sign_mask = (__float_as_int(U) & 0x80000000);
- /* TODO(sergey): Check if multiplication plus sign check is faster
- * or at least same speed (but robust for endian types).
- */
- if(sign_mask != (__float_as_int(V) & 0x80000000) ||
- sign_mask != (__float_as_int(W) & 0x80000000))
+ if((U < 0.0f || V < 0.0f || W < 0.0f) &&
+ (U > 0.0f || V > 0.0f || W > 0.0f))
{
return false;
}
@@ -162,9 +154,10 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
* the hit distance.
*/
const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz;
- const float sign_T = xor_signmask(T, sign_mask);
+ const int sign_det = (__float_as_int(det) & 0x80000000);
+ const float sign_T = xor_signmask(T, sign_det);
if((sign_T < 0.0f) ||
- (sign_T > isect->t * xor_signmask(det, sign_mask)))
+ (sign_T > isect->t * xor_signmask(det, sign_det)))
{
return false;
}
@@ -204,7 +197,13 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
*/
#ifdef __SUBSURFACE__
-ccl_device_inline void triangle_intersect_subsurface(
+
+#if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86))
+ccl_device_noinline
+#else
+ccl_device_inline
+#endif
+void triangle_intersect_subsurface(
KernelGlobals *kg,
const IsectPrecalc *isect_precalc,
Intersection *isect_array,
@@ -245,13 +244,12 @@ ccl_device_inline void triangle_intersect_subsurface(
/* Calculate scaled barycentric coordinates. */
float U = Cx * By - Cy * Bx;
- int sign_mask = (__float_as_int(U) & 0x80000000);
float V = Ax * Cy - Ay * Cx;
- if(sign_mask != (__float_as_int(V) & 0x80000000)) {
- return;
- }
float W = Bx * Ay - By * Ax;
- if(sign_mask != (__float_as_int(W) & 0x80000000)) {
+
+ if((U < 0.0f || V < 0.0f || W < 0.0f) &&
+ (U > 0.0f || V > 0.0f || W > 0.0f))
+ {
return;
}
@@ -264,10 +262,11 @@ ccl_device_inline void triangle_intersect_subsurface(
/* Calculate scaled z−coordinates of vertices and use them to calculate
* the hit distance.
*/
+ const int sign_det = (__float_as_int(det) & 0x80000000);
const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz;
- const float sign_T = xor_signmask(T, sign_mask);
+ const float sign_T = xor_signmask(T, sign_det);
if((sign_T < 0.0f) ||
- (sign_T > tmax * xor_signmask(det, sign_mask)))
+ (sign_T > tmax * xor_signmask(det, sign_det)))
{
return;
}
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 7bceb8a..7a846e1 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -69,6 +69,9 @@ void ImageManager::set_extended_image_limits(const DeviceInfo& info)
else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.extended_images) {
tex_num_images = TEX_EXTENDED_NUM_IMAGES_GPU;
}
+ else if(info.pack_images) {
+ tex_num_images = TEX_PACKED_NUM_IMAGES;
+ }
}
bool ImageManager::set_animation_frame_update(int frame)
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index bcc58ae..c79c152 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -40,6 +40,13 @@ CCL_NAMESPACE_BEGIN
#define TEX_EXTENDED_NUM_IMAGES_CPU 1024
#define TEX_EXTENDED_IMAGE_BYTE_START TEX_EXTENDED_NUM_FLOAT_IMAGES
+/* Limitations for packed images.
+ *
+ * Technically number of textures is unlimited, but it should in
+ * fact be in sync with CPU limitations.
+ */
+#define TEX_PACKED_NUM_IMAGES 1024
+
/* color to use when textures are not found */
#define TEX_IMAGE_MISSING_R 1
#define TEX_IMAGE_MISSING_G 0
diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h
index c951c35..42d3ca6 100644
--- a/intern/cycles/util/util_optimization.h
+++ b/intern/cycles/util/util_optimization.h
@@ -101,7 +101,7 @@
#ifdef _MSC_VER
#include <intrin.h>
-#else
+#elif (defined(__x86_64__) || defined(__i386__))
#include <x86intrin.h>
#endif
diff --git a/release/scripts/addons/modules/rna_manual_reference.py b/release/scripts/addons/modules/rna_manual_reference.py
index d23d436..b0c67d5 100644
--- a/release/scripts/addons/modules/rna_manual_reference.py
+++ b/release/scripts/addons/modules/rna_manual_reference.py
@@ -98,54 +98,54 @@ url_manual_mapping = (
# *** Modifiers ***
# --- Intro ---
- ("bpy.types.Modifier.show_*", "modifiers/the_stack.html"),
- ("bpy.types.Modifier.*", "modifiers"), # catchall for various generic options
+ ("bpy.types.Modifier.show_*", "modeling/modifiers/the_stack.html"),
+ ("bpy.types.Modifier.*", "modeling/modifiers"), # catchall for various generic options
# --- Modify Modifiers ---
- ("bpy.types.MeshCacheModifier.*", "modifiers/modify/mesh_cache.html"),
- ("bpy.types.UVProjectModifier.*", "modifiers/modify/uv_project.html"),
- ("bpy.types.UVWarpModifier.*", "modifiers/modify/uv_warp.html"),
- ("bpy.types.VertexWeightMixModifier.*", "modifiers/modify/vertex_weight.html"),
- ("bpy.types.VertexWeightEditModifier.*", "modifiers/modify/vertex_weight.html"),
- ("bpy.types.VertexWeightProximityModifier.*", "modifiers/modify/vertex_weight.html"),
+ ("bpy.types.MeshCacheModifier.*", "modeling/modifiers/modify/mesh_cache.html"),
+ ("bpy.types.UVProjectModifier.*", "modeling/modifiers/modify/uv_project.html"),
+ ("bpy.types.UVWarpModifier.*", "modeling/modifiers/modify/uv_warp.html"),
+ ("bpy.types.VertexWeightMixModifier.*", "modeling/modifiers/modify/vertex_weight.html"),
+ ("bpy.types.VertexWeightEditModifier.*", "modeling/modifiers/modify/vertex_weight.html"),
+ ("bpy.types.VertexWeightProximityModifier.*", "modeling/modifiers/modify/vertex_weight.html"),
# --- Generate Modifiers ---
- ("bpy.types.ArrayModifier.*", "modifiers/generate/array.html"),
- ("bpy.types.BevelModifier.*", "modifiers/generate/bevel.html"),
- ("bpy.types.BooleanModifier.*", "modifiers/generate/booleans.html"),
- ("bpy.types.BuildModifier.*", "modifiers/generate/build.html"),
- ("bpy.types.DecimateModifier.*", "modifiers/generate/decimate.html"),
- ("bpy.types.EdgeSplitModifier.*", "modifiers/generate/edge_split.html"),
- ("bpy.types.MaskModifier.*", "modifiers/generate/mask.html"),
- ("bpy.types.MirrorModifier.*", "modifiers/generate/mirror.html"),
- ("bpy.types.MultiresModifier.*", "modifiers/generate/multiresolution.html"),
- ("bpy.types.RemeshModifier.*", "modifiers/generate/remesh.html"),
- ("bpy.types.ScrewModifier.*", "modifiers/generate/screw.html"),
- ("bpy.types.SkinModifier.*", "modifiers/generate/skin.html"),
- ("bpy.types.SolidifyModifier.*", "modifiers/generate/solidify.html"),
- ("bpy.types.SubsurfModifier.*", "modifiers/generate/subsurf.html"),
- ("bpy.types.TriangulateModifier.*","modifiers/generate/triangulate.html"),
+ ("bpy.types.ArrayModifier.*", "modeling/modifiers/generate/array.html"),
+ ("bpy.types.BevelModifier.*", "modeling/modifiers/generate/bevel.html"),
+ ("bpy.types.BooleanModifier.*", "modeling/modifiers/generate/booleans.html"),
+ ("bpy.types.BuildModifier.*", "modeling/modifiers/generate/build.html"),
+ ("bpy.types.DecimateModifier.*", "modeling/modifiers/generate/decimate.html"),
+ ("bpy.types.EdgeSplitModifier.*", "modeling/modifiers/generate/edge_split.html"),
+ ("bpy.types.MaskModifier.*", "modeling/modifiers/generate/mask.html"),
+ ("bpy.types.MirrorModifier.*", "modeling/modifiers/generate/mirror.html"),
+ ("bpy.types.MultiresModifier.*", "modeling/modifiers/generate/multiresolution.html"),
+ ("bpy.types.RemeshModifier.*", "modeling/modifiers/generate/remesh.html"),
+ ("bpy.types.ScrewModifier.*", "modeling/modifiers/generate/screw.html"),
+ ("bpy.types.SkinModifier.*", "modeling/modifiers/generate/skin.html"),
+ ("bpy.types.SolidifyModifier.*", "modeling/modifiers/generate/solidify.html"),
+ ("bpy.types.SubsurfModifier.*", "modeling/modifiers/generate/subsurf.html"),
+ ("bpy.types.TriangulateModifier.*","modeling/modifiers/generate/triangulate.html"),
# --- Deform Modifiers ---
- ("bpy.types.ArmatureModifier.*", "modifiers/deform/armature.html"),
- ("bpy.types.CastModifier.*", "modifiers/deform/cast.html"),
- ("bpy.types.CurveModifier.*", "modifiers/deform/curve.html"),
- ("bpy.types.DisplaceModifier.*", "modifiers/deform/displace.html"),
- ("bpy.types.HookModifier.*", "modifiers/deform/hooks.html"),
- ("bpy.types.LaplacianSmoothModifier.*", "modifiers/deform/laplacian_smooth.html"),
- ("bpy.types.LatticeModifier.*", "modifiers/deform/lattice.html"),
- ("bpy.types.MeshDeformModifier.*", "modifiers/deform/mesh_deform.html"),
- ("bpy.types.ShrinkwrapModifier.*", "modifiers/deform/shrinkwrap.html"),
- ("bpy.types.SimpleDeformModifier.*", "modifiers/deform/simple_deform.html"),
- ("bpy.types.SmoothModifier.*", "modifiers/deform/smooth.html"),
+ ("bpy.types.ArmatureModifier.*", "modeling/modifiers/deform/armature.html"),
+ ("bpy.types.CastModifier.*", "modeling/modifiers/deform/cast.html"),
+ ("bpy.types.CurveModifier.*", "modeling/modifiers/deform/curve.html"),
+ ("bpy.types.DisplaceModifier.*", "modeling/modifiers/deform/displace.html"),
+ ("bpy.types.HookModifier.*", "modeling/modifiers/deform/hooks.html"),
+ ("bpy.types.LaplacianSmoothModifier.*", "modeling/modifiers/deform/laplacian_smooth.html"),
+ ("bpy.types.LatticeModifier.*", "modeling/modifiers/deform/lattice.html"),
+ ("bpy.types.MeshDeformModifier.*", "modeling/modifiers/deform/mesh_deform.html"),
+ ("bpy.types.ShrinkwrapModifier.*", "modeling/modifiers/deform/shrinkwrap.html"),
+ ("bpy.types.SimpleDeformModifier.*", "modeling/modifiers/deform/simple_deform.html"),
+ ("bpy.types.SmoothModifier.*", "modeling/modifiers/deform/smooth.html"),
# ("bpy.types.SurfaceModifier.*", "Modifiers/Deform/"), # USERS NEVER SEE THIS
- ("bpy.types.WarpModifier.*", "modifiers/deform/warp.html"),
- ("bpy.types.WaveModifier.*", "modifiers/deform/wave.html"),
+ ("bpy.types.WarpModifier.*", "modeling/modifiers/deform/warp.html"),
+ ("bpy.types.WaveModifier.*", "modeling/modifiers/deform/wave.html"),
# --- Simulate Modifiers ---
("bpy.types.ClothModifier.*", "physics/cloth.html"),
("bpy.types.CollisionModifier.*", "physics/collision.html"),
("bpy.types.DynamicPaintModifier.*", "physics/dynamic_paint"),
- ("bpy.types.ExplodeModifier.*", "modifiers/simulate/explode.html"),
+ ("bpy.types.ExplodeModifier.*", "modeling/modifiers/simulate/explode.html"),
("bpy.types.FluidSimulationModifier.*", "physics/fluid"),
- ("bpy.types.OceanModifier.*", "modifiers/simulate/ocean.html"),
- ("bpy.types.ParticleInstanceModifier.*", "modifiers/simulate/particle_instance.html"),
+ ("bpy.types.OceanModifier.*", "modeling/modifiers/simulate/ocean.html"),
+ ("bpy.types.ParticleInstanceModifier.*", "modeling/modifiers/simulate/particle_instance.html"),
("bpy.types.ParticleSystemModifier.*", "physics/particles"),
("bpy.types.SmokeModifier.*", "physics/smoke"),
("bpy.types.SoftBodyModifier.*", "physics/soft_body"),
@@ -185,20 +185,20 @@ url_manual_mapping = (
("bpy.types.RigidBodyJointConstraint.*", "rigging/constraints/relationship/rigid_body_joint.html"),
("bpy.types.ShrinkwrapConstraint.*", "rigging/constraints/relationship/shrinkwrap.html"),
- ("bpy.types.ImageFormatSettings.*", "render/output.html#file-type"),
- ("bpy.types.RenderSettings.filepath", "render/output.html#file-locations"),
- ("bpy.types.RenderSettings.display_mode", "render/display.html#displaying-renders"),
+ ("bpy.types.ImageFormatSettings.*", "data_system/files/image_formats.html"),
+ ("bpy.types.RenderSettings.filepath", "render/output/output.html#output-panel"),
+ ("bpy.types.RenderSettings.display_mode", "render/output/display.html#displaying-renders"),
("bpy.types.RenderSettings.*", "render"), # catchall, todo - refine
# *** ID Subclasses ***
- ("bpy.types.Action.*", "animation/basics/actions.html"),
+ ("bpy.types.Action.*", "animation/actions.html"),
#("bpy.types.Brush.*", ""), # TODO - manual has no place for this! XXX
("bpy.types.Curve.*", "modeling/curves"),
("bpy.types.GreasePencil.*", "interface/grease_pencil/index.html"),
("bpy.types.Group.*", "modeling/objects/groups_and_parenting.html#grouping-objects"),
("bpy.types.Image.*", "render/blender_render/textures/types/image.html"),
- ("bpy.types.ShapeKey.*", "animation/techs/shape/shape_keys.html"), # not an id but include because of key
- ("bpy.types.Key.*", "animation/techs/shape/shape_keys.html"),
+ ("bpy.types.ShapeKey.*", "animation/shape_keys.html"), # not an id but include because of key
+ ("bpy.types.Key.*", "animation/shape_keys.html"),
#("bpy.types.Lattice.*", ""), # TODO - manual has no place for this! XXX
("bpy.types.Library.*", "data_system/linked_libraries.html"),
#("bpy.types.Mask.*", ""), # TODO - manual has no place for this! XXX
@@ -227,7 +227,7 @@ url_manual_mapping = (
#("bpy.types.NodeTree.*", ""), # dont document
("bpy.types.Object.*", "modeling/objects"), # catchall, todo - refine
("bpy.types.ParticleSettings.*", "physics/particles"),
- ("bpy.types.Scene.*", "interface/scenes.html"),
+ ("bpy.types.Scene.*", "data_system/scenes.html"),
("bpy.types.Screen.*", "interface/screens.html"),
#("bpy.types.Sound.*", ""), # TODO - manual has no place for this! XXX
#("bpy.types.Speaker.*", ""), # TODO - manual has no place for this! XXX
@@ -252,7 +252,7 @@ url_manual_mapping = (
# Currently all manual links on all sockets and values (such as Fac, Roughness, Color...) are NodeSocket* type.
# It'd be much better if the name of the socket could be used for the manual reference
- ("bpy.types.NodeSocket*", "editors/node_editor/node_controls.html"), # no generic socket type page exists, but composite types are the same
+ ("bpy.types.NodeSocket*", "editors/node_editor/node_parts.html"), # no generic socket type page exists, but composite types are the same
# *** Cycles Material Nodes ***
# Outputs
@@ -440,7 +440,7 @@ url_manual_mapping = (
("bpy.types.Lamp.*", "render/blender_render/lighting"), # catchall, todo - refine
# --- Animation ---
- ("bpy.types.Keyframe.*", "animation/basics/actions.html"),
+ ("bpy.types.Keyframe.*", "animation/actions.html"),
("bpy.types.FCurve.*", "editors/graph_editor/fcurves.html"),
# --- Rigging ---
@@ -460,7 +460,7 @@ url_manual_mapping = (
# Catch all only for now!
# *** Window/Screen ***
- ("bpy.ops.action.*", "animation/basics/actions.html"),
+ ("bpy.ops.action.*", "animation/actions.html"),
("bpy.ops.anim.*", "animation"),
("bpy.ops.armature.*", "rigging/armatures.html"),
("bpy.ops.boid.*", "physics/particles/physics/boids.html"),
@@ -492,7 +492,7 @@ url_manual_mapping = (
("bpy.ops.lamp.*", "render/blender_render/lighting"), # --- todo ... all below ---
# ("bpy.ops.lattice.*", ""), # TODO
("bpy.ops.logic.*", "game_engine/logic"),
- ("bpy.ops.marker.*", "animation/basics/markers.html"),
+ ("bpy.ops.marker.*", "animation/markers.html"),
# ("bpy.ops.mask.*", ""), # TODO
("bpy.ops.material.new", "render/blender_render/materials/assigning_a_material.html#creating-a-new-material"),
("bpy.ops.material.*", "render/blender_render"),
@@ -510,8 +510,8 @@ url_manual_mapping = (
("bpy.ops.mesh.*", "modeling/meshes"),
("bpy.ops.nla.*", "editors/nla.html"),
# ("bpy.ops.node.*", ""), # TODO
- ("bpy.ops.object.*shape_key*", "animation/techs/shape/shape_keys.html"),
- ("bpy.ops.object.join_shapes", "animation/techs/shape/shape_keys.html"),
+ ("bpy.ops.object.*shape_key*", "animation/shape_keys.html"),
+ ("bpy.ops.object.join_shapes", "animation/shape_keys.html"),
("bpy.ops.object.*", "modeling/objects"),
("bpy.ops.outliner.*", "editors/outliner.html"),
# ("bpy.ops.paint.*", ""), # TODO
@@ -520,10 +520,10 @@ url_manual_mapping = (
("bpy.ops.poselib.*", "rigging/posing/pose_library.html"),
# ("bpy.ops.ptcache.*", ""), # TODO
- ("bpy.ops.render.play-rendered-anim", "render/display.html#animation-playback"),
+ ("bpy.ops.render.play-rendered-anim", "render/output/display.html#animation-playback"),
("bpy.ops.render.*", "render"), # catchall
- ("bpy.ops.scene.*", "interface/scenes.html"),
+ ("bpy.ops.scene.*", "data_system/scenes.html"),
("bpy.ops.screen.*", "interface/window_system"),
("bpy.ops.script.*", "advanced/scripting"),
("bpy.ops.sculpt.*", "modeling/meshes/editing/sculpt_mode.html"),
diff --git a/release/scripts/freestyle/modules/parameter_editor.py b/release/scripts/freestyle/modules/parameter_editor.py
index fe6c6f6..082ce13 100644
--- a/release/scripts/freestyle/modules/parameter_editor.py
+++ b/release/scripts/freestyle/modules/parameter_editor.py
@@ -1406,10 +1406,11 @@ def process(layer_name, lineset_name):
shaders_list.append(ColorDistanceFromCameraShader(
m.blend, m.influence, m.color_ramp,
m.range_min, m.range_max))
- elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None:
- shaders_list.append(ColorDistanceFromObjectShader(
- m.blend, m.influence, m.color_ramp, m.target,
- m.range_min, m.range_max))
+ elif m.type == 'DISTANCE_FROM_OBJECT':
+ if m.target is not None:
+ shaders_list.append(ColorDistanceFromObjectShader(
+ m.blend, m.influence, m.color_ramp, m.target,
+ m.range_min, m.range_max))
elif m.type == 'MATERIAL':
shaders_list.append(ColorMaterialShader(
m.blend, m.influence, m.color_ramp, m.material_attribute,
@@ -1439,10 +1440,11 @@ def process(layer_name, lineset_name):
shaders_list.append(AlphaDistanceFromCameraShader(
m.blend, m.influence, m.mapping, m.invert, m.curve,
m.range_min, m.range_max))
- elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None:
- shaders_list.append(AlphaDistanceFromObjectShader(
- m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
- m.range_min, m.range_max))
+ elif m.type == 'DISTANCE_FROM_OBJECT':
+ if m.target is not None:
+ shaders_list.append(AlphaDistanceFromObjectShader(
+ m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
+ m.range_min, m.range_max))
elif m.type == 'MATERIAL':
shaders_list.append(AlphaMaterialShader(
m.blend, m.influence, m.mapping, m.invert, m.curve,
@@ -1475,11 +1477,12 @@ def process(layer_name, lineset_name):
thickness_position, linestyle.thickness_ratio,
m.blend, m.influence, m.mapping, m.invert, m.curve,
m.range_min, m.range_max, m.value_min, m.value_max))
- elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None:
- shaders_list.append(ThicknessDistanceFromObjectShader(
- thickness_position, linestyle.thickness_ratio,
- m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
- m.range_min, m.range_max, m.value_min, m.value_max))
+ elif m.type == 'DISTANCE_FROM_OBJECT':
+ if m.target is not None:
+ shaders_list.append(ThicknessDistanceFromObjectShader(
+ thickness_position, linestyle.thickness_ratio,
+ m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
+ m.range_min, m.range_max, m.value_min, m.value_max))
elif m.type == 'MATERIAL':
shaders_list.append(ThicknessMaterialShader(
thickness_position, linestyle.thickness_ratio,
diff --git a/release/scripts/modules/bpy/utils/previews.py b/release/scripts/modules/bpy/utils/previews.py
index 9659711..c67c523 100644
--- a/release/scripts/modules/bpy/utils/previews.py
+++ b/release/scripts/modules/bpy/utils/previews.py
@@ -86,7 +86,7 @@ class ImagePreviewCollection(dict):
def new(self, name):
if name in self:
- raise KeyException("key %r already exists")
+ raise KeyError("key %r already exists" % name)
p = self[name] = _utils_previews.new(
self._gen_key(name))
return p
@@ -94,7 +94,7 @@ class ImagePreviewCollection(dict):
def load(self, name, path, path_type, force_reload=False):
if name in self:
- raise KeyException("key %r already exists")
+ raise KeyError("key %r already exists" % name)
p = self[name] = _utils_previews.load(
self._gen_key(name), path, path_type, force_reload)
return p
diff --git a/release/scripts/modules/progress_report.py b/release/scripts/modules/progress_report.py
index 578eb96..fc77a3e 100644
--- a/release/scripts/modules/progress_report.py
+++ b/release/scripts/modules/progress_report.py
@@ -99,7 +99,7 @@ class ProgressReport:
def enter_substeps(self, nbr, msg=""):
if msg:
self.update(msg)
- self.steps.append(self.steps[-1] / nbr)
+ self.steps.append(self.steps[-1] / max(nbr, 1))
self.curr_step.append(0)
self.start_time.append(time.time())
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index a14e345..33398b3 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -220,7 +220,7 @@ class BONE_PT_display(BoneButtonsPanel, Panel):
col = split.column()
col.prop(bone, "hide", text="Hide")
sub = col.column()
- sub.active = bool(pchan.custom_shape)
+ sub.active = bool(pchan and pchan.custom_shape)
sub.prop(bone, "show_wire", text="Wireframe")
if pchan:
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 6b32d2a..34137c8 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -339,7 +339,7 @@ class DOPESHEET_MT_key(Menu):
layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode")
layout.separator()
- layout.operator("action.clean")
+ layout.operator("action.clean").channels = False
layout.operator("action.clean", text="Clean Channels").channels = True
layout.operator("action.sample")
@@ -422,7 +422,7 @@ class DOPESHEET_MT_delete(Menu):
layout.separator()
- layout.operator("action.clean")
+ layout.operator("action.clean").channels = False
layout.operator("action.clean", text="Clean Channels").channels = True
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index 104fd14..82497f1 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -257,7 +257,7 @@ class GRAPH_MT_key(Menu):
layout.operator_menu_enum("graph.easing_type", "type", text="Easing Type")
layout.separator()
- layout.operator("graph.clean")
+ layout.operator("graph.clean").channels = False
layout.operator("graph.clean", text="Clean Channels").channels = True
layout.operator("graph.smooth")
layout.operator("graph.sample")
@@ -293,7 +293,7 @@ class GRAPH_MT_delete(Menu):
layout.separator()
- layout.operator("graph.clean")
+ layout.operator("graph.clean").channels = False
layout.operator("graph.clean", text="Clean Channels").channels = True
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c
index 6ea94d3..9601d6e 100644
--- a/source/blender/avi/intern/avi.c
+++ b/source/blender/avi/intern/avi.c
@@ -1063,6 +1063,11 @@ AviError AVI_close_compress(AviMovie *movie)
{
int temp, movi_size, i;
+ if (movie->fp == NULL) {
+ /* none of the allocations below were done if the file failed to open */
+ return AVI_ERROR_FOUND;
+ }
+
fseek(movie->fp, 0L, SEEK_END);
movi_size = (int)ftell(movie->fp);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 38ebda1..3c705a1 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -49,7 +49,7 @@ extern "C" {
/* used by packaging tools */
/* can be left blank, otherwise a,b,c... etc with no quotes */
-#define BLENDER_VERSION_CHAR
+#define BLENDER_VERSION_CHAR a
/* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE release
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 3e78475..a7c5c21 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -472,6 +472,8 @@ typedef struct CustomDataTransferLayerMap {
size_t data_offset; /* Offset of actual data we transfer (in element contained in data_src/dst). */
uint64_t data_flag; /* For bitflag transfer, flag(s) to affect in transfered data. */
+ void *interp_data; /* Opaque pointer, to be used by specific interp callback (e.g. transformspace for normals). */
+
cd_datatransfer_interp interp;
} CustomDataTransferLayerMap;
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 94afc8a..ea63161 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -212,6 +212,8 @@ void BKE_image_multiview_index(struct Image *ima, struct ImageUser *iuser);
/* for multilayer images as well as for render-viewer */
bool BKE_image_is_multilayer(struct Image *ima);
+bool BKE_image_is_multiview(struct Image *ima);
+bool BKE_image_is_stereo(struct Image *ima);
struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima);
void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 20dabbd..144f6e3 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -3453,7 +3453,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
if (attribs->mcol[b].array) {
const MLoopCol *cp = &attribs->mcol[b].array[loop];
- copy_v4_v4_char((char *)col, &cp->r);
+ copy_v4_v4_char((char *)col, (char *)&cp->r);
}
else {
col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 7c3287e..c0ebad0 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1072,7 +1072,7 @@ static void cdDM_drawMappedFacesGLSL(
if (matconv[i].attribs.mcol[b].array) {
const MLoopCol *mloopcol = matconv[i].attribs.mcol[b].array;
for (j = 0; j < mpoly->totloop; j++)
- copy_v4_v4_char((char *)&varray[offset + j * max_element_size], &mloopcol[mpoly->loopstart + j].r);
+ copy_v4_v4_char((char *)&varray[offset + j * max_element_size], (char *)&mloopcol[mpoly->loopstart + j].r);
offset += sizeof(unsigned char) * 4;
}
}
@@ -1482,7 +1482,7 @@ static void cdDM_buffer_copy_mcol(
for (i = 0; i < totpoly; i++, mpoly++) {
for (j = 0; j < mpoly->totloop; j++) {
- copy_v3_v3_char((char *)&varray[start], &mloopcol[mpoly->loopstart + j].r);
+ copy_v3_v3_char((char *)&varray[start], (char *)&mloopcol[mpoly->loopstart + j].r);
start += 3;
}
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 2aba4fc..27043b0 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -133,7 +133,20 @@ bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subda
if (ob) {
cob->ob = ob;
cob->type = datatype;
- cob->rotOrder = EULER_ORDER_DEFAULT; // TODO: when objects have rotation order too, use that
+
+ if (cob->ob->rotmode > 0) {
+ /* Should be some kind of Euler order, so use it */
+ /* NOTE: Versions <= 2.76 assumed that "default" order
+ * would always get used, so we may seem some rig
+ * breakage as a result. However, this change here
+ * is needed to fix T46599
+ */
+ cob->rotOrder = ob->rotmode;
+ }
+ else {
+ /* Quats/Axis-Angle, so Eulers should just use default order */
+ cob->rotOrder = EULER_ORDER_DEFAULT;
+ }
copy_m4_m4(cob->matrix, ob->obmat);
}
else
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 815c18b..88ab634 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -61,6 +61,8 @@
#include "BKE_mesh_remap.h"
#include "BKE_multires.h"
+#include "data_transfer_intern.h"
+
#include "bmesh.h"
#include <math.h>
@@ -305,13 +307,16 @@ static void layerInterp_normal(
const void **sources, const float *weights,
const float *UNUSED(sub_weights), int count, void *dest)
{
+ /* Note: This is linear interpolation, which is not optimal for vectors.
+ * Unfortunately, spherical interpolation of more than two values is hairy, so for now it will do... */
float no[3] = {0.0f};
while (count--) {
madd_v3_v3fl(no, (const float *)sources[count], weights[count]);
}
- copy_v3_v3((float *)dest, no);
+ /* Weighted sum of normalized vectors will **not** be normalized, even if weights are. */
+ normalize_v3_v3((float *)dest, no);
}
static void layerCopyValue_normal(const void *source, void *dest, const int mixmode, const float mixfactor)
@@ -926,6 +931,7 @@ static void layerInterp_mloopuv(
}
/* delay writing to the destination incase dest is in sources */
+ ((MLoopUV *)dest)->flag = ((MLoopUV *)sources)->flag;
copy_v2_v2(((MLoopUV *)dest)->uv, uv);
}
@@ -3912,6 +3918,38 @@ static void customdata_data_transfer_interp_generic(
MEM_freeN(tmp_dst);
}
+/* Normals are special, we need to take care of source & destination spaces... */
+void customdata_data_transfer_interp_normal_normals(
+ const CustomDataTransferLayerMap *laymap, void *data_dst,
+ const void **sources, const float *weights, const int count,
+ const float mix_factor)
+{
+ const int data_type = laymap->data_type;
+ const int mix_mode = laymap->mix_mode;
+
+ SpaceTransform *space_transform = laymap->interp_data;
+
+ const LayerTypeInfo *type_info = layerType_getInfo(data_type);
+ cd_interp interp_cd = type_info->interp;
+
+ float tmp_dst[3];
+
+ BLI_assert(data_type == CD_NORMAL);
+
+ if (!sources) {
+ /* Not supported here, abort. */
+ return;
+ }
+
+ interp_cd(sources, weights, NULL, count, tmp_dst);
+ if (space_transform) {
+ /* tmp_dst is in source space so far, bring it back in destination space. */
+ BLI_space_transform_invert_normal(space_transform, tmp_dst);
+ }
+
+ CustomData_data_mix_value(data_type, tmp_dst, data_dst, mix_mode, mix_factor);
+}
+
void CustomData_data_transfer(const MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap)
{
MeshPairRemapItem *mapit = me_remap->items;
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 53b6f4a..0baf7e3 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -428,7 +428,7 @@ void data_transfer_layersmapping_add_item(
ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights,
const void *data_src, void *data_dst, const int data_src_n, const int data_dst_n,
const size_t elem_size, const size_t data_size, const size_t data_offset, const uint64_t data_flag,
- cd_datatransfer_interp interp)
+ cd_datatransfer_interp interp, void *interp_data)
{
CustomDataTransferLayerMap *item = MEM_mallocN(sizeof(*item), __func__);
@@ -450,17 +450,18 @@ void data_transfer_layersmapping_add_item(
item->data_flag = data_flag;
item->interp = interp;
+ item->interp_data = interp_data;
BLI_addtail(r_map, item);
}
static void data_transfer_layersmapping_add_item_cd(
ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights,
- void *data_src, void *data_dst)
+ void *data_src, void *data_dst, cd_datatransfer_interp interp, void *interp_data)
{
data_transfer_layersmapping_add_item(
r_map, cddata_type, mix_mode, mix_factor, mix_weights, data_src, data_dst,
- 0, 0, 0, 0, 0, 0, NULL);
+ 0, 0, 0, 0, 0, 0, interp, interp_data);
}
/* Note: All those layer mapping handlers return false *only* if they were given invalid parameters.
@@ -473,7 +474,8 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(
ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights,
const int num_elem_dst, const bool use_create, const bool use_delete,
CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst,
- const int tolayers, bool *use_layers_src, const int num_layers_src)
+ const int tolayers, bool *use_layers_src, const int num_layers_src,
+ cd_datatransfer_interp interp, void *interp_data)
{
void *data_src, *data_dst = NULL;
int idx_src = num_layers_src;
@@ -527,7 +529,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(
data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_src);
}
data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
- data_src, data_dst);
+ data_src, data_dst, interp, interp_data);
}
}
break;
@@ -571,7 +573,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(
data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
}
data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
- data_src, data_dst);
+ data_src, data_dst, interp, interp_data);
}
}
@@ -599,7 +601,8 @@ static bool data_transfer_layersmapping_cdlayers(
ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights,
const int num_elem_dst, const bool use_create, const bool use_delete,
CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst,
- const int fromlayers, const int tolayers)
+ const int fromlayers, const int tolayers,
+ cd_datatransfer_interp interp, void *interp_data)
{
int idx_src, idx_dst;
void *data_src, *data_dst = NULL;
@@ -626,7 +629,7 @@ static bool data_transfer_layersmapping_cdlayers(
if (r_map) {
data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
- data_src, data_dst);
+ data_src, data_dst, interp, interp_data);
}
}
else if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {
@@ -719,7 +722,7 @@ static bool data_transfer_layersmapping_cdlayers(
if (r_map) {
data_transfer_layersmapping_add_item_cd(
- r_map, cddata_type, mix_mode, mix_factor, mix_weights, data_src, data_dst);
+ r_map, cddata_type, mix_mode, mix_factor, mix_weights, data_src, data_dst, interp, interp_data);
}
}
else if (fromlayers == DT_LAYERS_ALL_SRC) {
@@ -734,7 +737,8 @@ static bool data_transfer_layersmapping_cdlayers(
ret = data_transfer_layersmapping_cdlayers_multisrc_to_dst(
r_map, cddata_type, mix_mode, mix_factor, mix_weights,
num_elem_dst, use_create, use_delete, cd_src, cd_dst, use_dupref_dst,
- tolayers, use_layers_src, num_src);
+ tolayers, use_layers_src, num_src,
+ interp, interp_data);
if (use_layers_src) {
MEM_freeN(use_layers_src);
@@ -751,10 +755,14 @@ static bool data_transfer_layersmapping_cdlayers(
static bool data_transfer_layersmapping_generate(
ListBase *r_map, Object *ob_src, Object *ob_dst, DerivedMesh *dm_src, DerivedMesh *dm_dst, Mesh *me_dst,
const int elem_type, int cddata_type, int mix_mode, float mix_factor, const float *mix_weights,
- const int num_elem_dst, const bool use_create, const bool use_delete, const int fromlayers, const int tolayers)
+ const int num_elem_dst, const bool use_create, const bool use_delete, const int fromlayers, const int tolayers,
+ SpaceTransform *space_transform)
{
CustomData *cd_src, *cd_dst;
+ cd_datatransfer_interp interp = NULL;
+ void *interp_data = NULL;
+
if (elem_type == ME_VERT) {
if (!(cddata_type & CD_FAKE)) {
cd_src = dm_src->getVertDataLayout(dm_src);
@@ -763,7 +771,8 @@ static bool data_transfer_layersmapping_generate(
if (!data_transfer_layersmapping_cdlayers(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
num_elem_dst, use_create, use_delete,
cd_src, cd_dst, dm_dst != NULL,
- fromlayers, tolayers))
+ fromlayers, tolayers,
+ interp, interp_data))
{
/* We handle specific source selection cases here. */
return false;
@@ -795,7 +804,7 @@ static bool data_transfer_layersmapping_generate(
dm_src->getNumVerts(dm_src),
dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert,
elem_size, data_size, data_offset, data_flag,
- data_transfer_interp_char);
+ data_transfer_interp_char, interp_data);
}
return true;
}
@@ -827,7 +836,8 @@ static bool data_transfer_layersmapping_generate(
if (!data_transfer_layersmapping_cdlayers(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
num_elem_dst, use_create, use_delete,
cd_src, cd_dst, dm_dst != NULL,
- fromlayers, tolayers))
+ fromlayers, tolayers,
+ interp, interp_data))
{
/* We handle specific source selection cases here. */
return false;
@@ -859,7 +869,7 @@ static bool data_transfer_layersmapping_generate(
dm_src->getNumEdges(dm_src),
dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge,
elem_size, data_size, data_offset, data_flag,
- data_transfer_interp_char);
+ data_transfer_interp_char, interp_data);
}
return true;
}
@@ -888,7 +898,7 @@ static bool data_transfer_layersmapping_generate(
dm_src->getNumEdges(dm_src),
dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge,
elem_size, data_size, data_offset, data_flag,
- data_transfer_interp_char);
+ data_transfer_interp_char, interp_data);
}
return true;
}
@@ -904,7 +914,7 @@ static bool data_transfer_layersmapping_generate(
dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge,
dm_src->getNumEdges(dm_src),
dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge,
- elem_size, data_size, data_offset, data_flag, NULL);
+ elem_size, data_size, data_offset, data_flag, NULL, interp_data);
return true;
}
else {
@@ -918,6 +928,8 @@ static bool data_transfer_layersmapping_generate(
else if (cddata_type == CD_FAKE_LNOR) {
/* Preprocess should have generated it, Postprocess will convert it back to CD_CUSTOMLOOPNORMAL. */
cddata_type = CD_NORMAL;
+ interp_data = space_transform;
+ interp = customdata_data_transfer_interp_normal_normals;
}
if (!(cddata_type & CD_FAKE)) {
@@ -927,7 +939,8 @@ static bool data_transfer_layersmapping_generate(
if (!data_transfer_layersmapping_cdlayers(
r_map, cddata_type, mix_mode, mix_factor, mix_weights,
num_elem_dst, use_create, use_delete, cd_src, cd_dst, dm_dst != NULL,
- fromlayers, tolayers))
+ fromlayers, tolayers,
+ interp, interp_data))
{
/* We handle specific source selection cases here. */
return false;
@@ -950,7 +963,8 @@ static bool data_transfer_layersmapping_generate(
if (!data_transfer_layersmapping_cdlayers(
r_map, cddata_type, mix_mode, mix_factor, mix_weights,
num_elem_dst, use_create, use_delete, cd_src, cd_dst, dm_dst != NULL,
- fromlayers, tolayers))
+ fromlayers, tolayers,
+ interp, interp_data))
{
/* We handle specific source selection cases here. */
return false;
@@ -969,7 +983,7 @@ static bool data_transfer_layersmapping_generate(
dm_dst ? dm_dst->getPolyArray(dm_dst) : me_dst->mpoly,
dm_src->getNumPolys(dm_src),
dm_dst ? dm_dst->getNumPolys(dm_dst) : me_dst->totpoly,
- elem_size, data_size, data_offset, data_flag, NULL);
+ elem_size, data_size, data_offset, data_flag, NULL, interp_data);
return true;
}
else {
@@ -1035,28 +1049,28 @@ void BKE_object_data_transfer_layout(
data_transfer_layersmapping_generate(
NULL, ob_src, ob_dst, dm_src, NULL, me_dst, ME_VERT, cddata_type, 0, 0.0f, NULL,
- num_elem_dst, use_create, use_delete, fromlayers, tolayers);
+ num_elem_dst, use_create, use_delete, fromlayers, tolayers, NULL);
}
if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
const int num_elem_dst = me_dst->totedge;
data_transfer_layersmapping_generate(
NULL, ob_src, ob_dst, dm_src, NULL, me_dst, ME_EDGE, cddata_type, 0, 0.0f, NULL,
- num_elem_dst, use_create, use_delete, fromlayers, tolayers);
+ num_elem_dst, use_create, use_delete, fromlayers, tolayers, NULL);
}
if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
const int num_elem_dst = me_dst->totloop;
data_transfer_layersmapping_generate(
NULL, ob_src, ob_dst, dm_src, NULL, me_dst, ME_LOOP, cddata_type, 0, 0.0f, NULL,
- num_elem_dst, use_create, use_delete, fromlayers, tolayers);
+ num_elem_dst, use_create, use_delete, fromlayers, tolayers, NULL);
}
if (DT_DATATYPE_IS_POLY(dtdata_type)) {
const int num_elem_dst = me_dst->totpoly;
data_transfer_layersmapping_generate(
NULL, ob_src, ob_dst, dm_src, NULL, me_dst, ME_POLY, cddata_type, 0, 0.0f, NULL,
- num_elem_dst, use_create, use_delete, fromlayers, tolayers);
+ num_elem_dst, use_create, use_delete, fromlayers, tolayers, NULL);
}
}
}
@@ -1198,7 +1212,7 @@ bool BKE_object_data_transfer_dm(
if (data_transfer_layersmapping_generate(
&lay_map, ob_src, ob_dst, dm_src, dm_dst, me_dst, ME_VERT,
cddata_type, mix_mode, mix_factor, weights[VDATA],
- num_verts_dst, use_create, use_delete, fromlayers, tolayers))
+ num_verts_dst, use_create, use_delete, fromlayers, tolayers, space_transform))
{
CustomDataTransferLayerMap *lay_mapit;
@@ -1249,7 +1263,7 @@ bool BKE_object_data_transfer_dm(
if (data_transfer_layersmapping_generate(
&lay_map, ob_src, ob_dst, dm_src, dm_dst, me_dst, ME_EDGE,
cddata_type, mix_mode, mix_factor, weights[EDATA],
- num_edges_dst, use_create, use_delete, fromlayers, tolayers))
+ num_edges_dst, use_create, use_delete, fromlayers, tolayers, space_transform))
{
CustomDataTransferLayerMap *lay_mapit;
@@ -1312,7 +1326,7 @@ bool BKE_object_data_transfer_dm(
if (data_transfer_layersmapping_generate(
&lay_map, ob_src, ob_dst, dm_src, dm_dst, me_dst, ME_LOOP,
cddata_type, mix_mode, mix_factor, weights[LDATA],
- num_loops_dst, use_create, use_delete, fromlayers, tolayers))
+ num_loops_dst, use_create, use_delete, fromlayers, tolayers, space_transform))
{
CustomDataTransferLayerMap *lay_mapit;
@@ -1367,7 +1381,7 @@ bool BKE_object_data_transfer_dm(
if (data_transfer_layersmapping_generate(
&lay_map, ob_src, ob_dst, dm_src, dm_dst, me_dst, ME_POLY,
cddata_type, mix_mode, mix_factor, weights[PDATA],
- num_polys_dst, use_create, use_delete, fromlayers, tolayers))
+ num_polys_dst, use_create, use_delete, fromlayers, tolayers, space_transform))
{
CustomDataTransferLayerMap *lay_mapit;
diff --git a/source/blender/blenkernel/intern/data_transfer_intern.h b/source/blender/blenkernel/intern/data_transfer_intern.h
index 501b749..352eedc 100644
--- a/source/blender/blenkernel/intern/data_transfer_intern.h
+++ b/source/blender/blenkernel/intern/data_transfer_intern.h
@@ -45,7 +45,7 @@ void data_transfer_layersmapping_add_item(
const float mix_factor, const float *mix_weights,
const void *data_src, void *data_dst, const int data_src_n, const int data_dst_n,
const size_t elem_size, const size_t data_size, const size_t data_offset, const uint64_t data_flag,
- cd_datatransfer_interp interp);
+ cd_datatransfer_interp interp, void *interp_data);
/* Type-specific. */
@@ -55,4 +55,10 @@ bool data_transfer_layersmapping_vgroups(
struct Object *ob_src, struct Object *ob_dst, struct CustomData *cd_src, struct CustomData *cd_dst,
const bool use_dupref_dst, const int fromlayers, const int tolayers);
+/* Defined in customdata.c */
+void customdata_data_transfer_interp_normal_normals(
+ const CustomDataTransferLayerMap *laymap, void *data_dst,
+ const void **sources, const float *weights, const int count,
+ const float mix_factor);
+
#endif /* __DATA_TRANSFER_INTERN_H__ */
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 6670c33..f904369 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -1163,7 +1163,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(
}
data_transfer_layersmapping_add_item(r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights,
data_src, data_dst, idx_src, idx_src,
- elem_size, 0, 0, 0, vgroups_datatransfer_interp);
+ elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL);
}
}
break;
@@ -1211,7 +1211,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(
data_transfer_layersmapping_add_item(
r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights,
data_src, data_dst, idx_src, idx_dst,
- elem_size, 0, 0, 0, vgroups_datatransfer_interp);
+ elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL);
}
}
break;
@@ -1317,7 +1317,7 @@ bool data_transfer_layersmapping_vgroups(
data_transfer_layersmapping_add_item(r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights,
data_src, data_dst, idx_src, idx_dst,
- elem_size, 0, 0, 0, vgroups_datatransfer_interp);
+ elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL);
}
}
else {
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 4373e79..ea8475f 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1140,7 +1140,7 @@ void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel
/* TODO(sergey): Find a better place for this. */
#ifdef WITH_OPENSUBDIV
- if ((rel & DAG_RL_DATA_DATA) != 0) {
+ if ((rel & (DAG_RL_DATA_DATA | DAG_RL_DATA_OB)) != 0) {
if (fob1->type == ID_OB) {
if ((fob1->eval_flags & DAG_EVAL_NEED_CPU) == 0) {
Object *ob2 = fob2->ob;
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 840935c..b2bb73b 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -1248,7 +1248,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B
GLubyte col[4];
if (attribs->mcol[i].em_offset != -1) {
const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
- copy_v4_v4_char((char *)col, &cp->r);
+ copy_v4_v4_char((char *)col, (char *)&cp->r);
}
else {
col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 36aeb97..5eb8e7d 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -280,14 +280,9 @@ void BKE_image_free_packedfiles(Image *ima)
image_free_packedfiles(ima);
}
-static void image_free_views(Image *ima)
-{
- BLI_freelistN(&ima->views);
-}
-
void BKE_image_free_views(Image *image)
{
- image_free_views(image);
+ BLI_freelistN(&image->views);
}
static void image_free_anims(Image *ima)
@@ -350,7 +345,7 @@ void BKE_image_free(Image *ima)
}
}
- image_free_views(ima);
+ BKE_image_free_views(ima);
MEM_freeN(ima->stereo3d_format);
}
@@ -873,8 +868,6 @@ Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int hei
}
ima->ok = IMA_OK_LOADED;
- if (stereo3d)
- ima->flag |= IMA_IS_STEREO | IMA_IS_MULTIVIEW;
}
return ima;
@@ -964,7 +957,7 @@ void BKE_image_memorypack(Image *ima)
{
ImBuf *ibuf;
- if ((ima->flag & IMA_IS_MULTIVIEW)) {
+ if (BKE_image_is_multiview(ima)) {
image_memorypack_multiview(ima);
return;
}
@@ -1370,6 +1363,7 @@ char BKE_imtype_valid_channels(const char imtype, bool write_file)
if (write_file) break;
/* fall-through */
case R_IMF_IMTYPE_TARGA:
+ case R_IMF_IMTYPE_RAWTGA:
case R_IMF_IMTYPE_IRIS:
case R_IMF_IMTYPE_PNG:
case R_IMF_IMTYPE_RADHDR:
@@ -2474,15 +2468,8 @@ void BKE_image_verify_viewer_views(const RenderData *rd, Image *ima, ImageUser *
BLI_lock_thread(LOCK_DRAW_IMAGE);
- if (BKE_scene_multiview_is_stereo3d(rd)) {
- ima->flag |= IMA_IS_STEREO;
- ima->flag |= IMA_IS_MULTIVIEW;
- }
- else {
- ima->flag &= ~IMA_IS_STEREO;
- ima->flag &= ~IMA_IS_MULTIVIEW;
+ if (!BKE_scene_multiview_is_stereo3d(rd))
iuser->flag &= ~IMA_SHOW_STEREO;
- }
/* see if all scene render views are in the image view list */
do_reset = (BKE_scene_multiview_num_views_get(rd) != BLI_listbase_count(&ima->views));
@@ -2528,6 +2515,17 @@ void BKE_image_walk_all_users(const Main *mainp, void *customdata,
if (tex->type == TEX_IMAGE && tex->ima) {
callback(tex->ima, &tex->iuser, customdata);
}
+
+ if (tex->nodetree) {
+ bNode *node;
+ for (node = tex->nodetree->nodes.first; node; node = node->next) {
+ if (node->id && node->type == TEX_NODE_IMAGE) {
+ Image *ima = (Image *)node->id;
+ ImageUser *iuser = node->storage;
+ callback(ima, iuser, customdata);
+ }
+ }
+ }
}
/* image window, compo node users */
@@ -2812,7 +2810,7 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
void BKE_image_multiview_index(Image *ima, ImageUser *iuser)
{
if (iuser) {
- bool is_stereo = (ima->flag & IMA_IS_STEREO) && (iuser->flag & IMA_SHOW_STEREO);
+ bool is_stereo = BKE_image_is_stereo(ima) && (iuser->flag & IMA_SHOW_STEREO);
if (is_stereo) {
iuser->multi_index = iuser->multiview_eye;
}
@@ -2845,27 +2843,38 @@ bool BKE_image_is_multilayer(Image *ima)
return false;
}
-static void image_init_multilayer_multiview_flag(Image *ima, RenderResult *rr)
+bool BKE_image_is_multiview(Image *ima)
{
+ return (BLI_listbase_count_ex(&ima->views, 2) > 1);
+}
+
+bool BKE_image_is_stereo(Image *ima)
+{
+ return BKE_image_is_multiview(ima) &&
+ (BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)) &&
+ BLI_findstring(&ima->views, STEREO_RIGHT_NAME, offsetof(ImageView, name)));
+}
+
+static void image_view_from_render_view(ImageView *iv_dst, RenderView *rv_src)
+{
+ BLI_strncpy(iv_dst->name, rv_src->name, sizeof(iv_dst->name));
+}
+
+static void image_init_multilayer_multiview(Image *ima, RenderResult *rr)
+{
+ BKE_image_free_views(ima);
if (rr) {
- if (RE_RenderResult_is_stereo(rr)) {
- ima->flag |= IMA_IS_STEREO;
- ima->flag |= IMA_IS_MULTIVIEW;
- }
- else {
- ima->flag &= ~IMA_IS_STEREO;
- if (BLI_listbase_count_ex(&rr->views, 2) > 1)
- ima->flag |= IMA_IS_MULTIVIEW;
- else
- ima->flag &= ~IMA_IS_MULTIVIEW;
+ RenderView *rv_src;
+ for (rv_src = rr->views.first; rv_src; rv_src = rv_src->next) {
+ ImageView *iv_dst;
+ iv_dst = MEM_callocN(sizeof(ImageView), "Viewer Image View");
+ image_view_from_render_view(iv_dst, rv_src);
+ BLI_addhead(&ima->views, iv_dst);
}
}
- else {
- ima->flag &= ~IMA_IS_STEREO;
- ima->flag &= ~IMA_IS_MULTIVIEW;
- }
}
+
RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima)
{
RenderResult *rr = NULL;
@@ -2878,8 +2887,8 @@ RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima)
else
rr = ima->renders[ima->render_slot];
- /* set proper multiview flag */
- image_init_multilayer_multiview_flag(ima, rr);
+ /* set proper views */
+ image_init_multilayer_multiview(ima, rr);
}
return rr;
@@ -3037,39 +3046,15 @@ static void image_add_buffer_cb(void *base, const char *str, ImBuf *ibuf, const
}
#endif /* WITH_OPENEXR */
-#ifdef WITH_OPENEXR
-static void image_update_multiview_flags(Image *ima)
-{
- if (BLI_listbase_count_ex(&ima->views, 2) > 1) {
- ima->flag |= IMA_IS_MULTIVIEW;
-
- if (BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)) &&
- BLI_findstring(&ima->views, STEREO_RIGHT_NAME, offsetof(ImageView, name)))
- {
- ima->flag |= IMA_IS_STEREO;
- }
- else {
- ima->flag &= ~IMA_IS_STEREO;
- }
- }
- else {
- ima->flag &= ~IMA_IS_STEREO;
- ima->flag &= ~IMA_IS_MULTIVIEW;
- }
-}
-#endif /* WITH_OPENEXR */
-
/* after imbuf load, openexr type can return with a exrhandle open */
/* in that case we have to build a render-result */
#ifdef WITH_OPENEXR
static void image_create_multiview(Image *ima, ImBuf *ibuf, const int frame)
{
- image_free_views(ima);
+ BKE_image_free_views(ima);
IMB_exr_multiview_convert(ibuf->userdata, ima, image_add_view_cb, image_add_buffer_cb, frame);
- image_update_multiview_flags(ima);
-
IMB_exr_close(ibuf->userdata);
}
#endif /* WITH_OPENEXR */
@@ -3082,7 +3067,9 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
const char *colorspace = ima->colorspace_settings.name;
bool predivide = (ima->alpha_mode == IMA_ALPHA_PREMUL);
- ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y);
+ /* only load rr once for multiview */
+ if (!ima->rr)
+ ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y);
IMB_exr_close(ibuf->userdata);
@@ -3090,8 +3077,8 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
if (ima->rr)
ima->rr->framenr = framenr;
- /* set proper multiview flag */
- image_init_multilayer_multiview_flag(ima, ima->rr);
+ /* set proper views */
+ image_init_multilayer_multiview(ima, ima->rr);
}
#endif /* WITH_OPENEXR */
@@ -3129,7 +3116,7 @@ static int imbuf_alpha_flags_for_image(Image *ima)
/* the number of files will vary according to the stereo format */
static size_t image_num_files(Image *ima)
{
- const bool is_multiview = (ima->flag & IMA_IS_MULTIVIEW) != 0;
+ const bool is_multiview = BKE_image_is_multiview(ima);
if (!is_multiview) {
return 1;
@@ -3211,7 +3198,7 @@ static ImBuf *load_sequence_single(Image *ima, ImageUser *iuser, int frame, cons
static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
{
struct ImBuf *ibuf = NULL;
- const bool is_multiview = (ima->flag & IMA_IS_MULTIVIEW) != 0;
+ const bool is_multiview = BKE_image_is_multiview(ima);
const size_t totfiles = image_num_files(ima);
bool assign = false;
@@ -3231,7 +3218,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
for (i = 0; i < totfiles; i++)
ibuf_arr[i] = load_sequence_single(ima, iuser, frame, i, &assign);
- if ((ima->flag & IMA_IS_STEREO) && ima->views_format == R_IMF_VIEWS_STEREO_3D)
+ if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D)
IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]);
/* return the original requested ImBuf */
@@ -3368,7 +3355,7 @@ static ImBuf *load_movie_single(Image *ima, ImageUser *iuser, int frame, const s
static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
{
struct ImBuf *ibuf = NULL;
- const bool is_multiview = (ima->flag & IMA_IS_MULTIVIEW) != 0;
+ const bool is_multiview = BKE_image_is_multiview(ima);
const size_t totfiles = image_num_files(ima);
size_t i;
@@ -3396,7 +3383,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
ibuf_arr[i] = load_movie_single(ima, iuser, frame, i);
}
- if ((ima->flag & IMA_IS_STEREO) && ima->views_format == R_IMF_VIEWS_STEREO_3D)
+ if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D)
IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]);
for (i = 0; i < totviews; i++) {
@@ -3524,7 +3511,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
{
struct ImBuf *ibuf = NULL;
bool assign = false;
- const bool is_multiview = (ima->flag & IMA_IS_MULTIVIEW) != 0;
+ const bool is_multiview = BKE_image_is_multiview(ima);
const size_t totfiles = image_num_files(ima);
bool has_packed = BKE_image_has_packedfile(ima);
@@ -3557,7 +3544,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
ibuf_arr[i] = load_image_single(ima, iuser, cfra, i, has_packed, &assign);
/* multi-views/multi-layers OpenEXR files directly populate ima, and return NULL ibuf... */
- if ((ima->flag & IMA_IS_STEREO) && ima->views_format == R_IMF_VIEWS_STEREO_3D &&
+ if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D &&
ibuf_arr[0] && totfiles == 1 && totviews >= 2)
{
IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]);
@@ -3657,7 +3644,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
pass = iuser->pass;
actview = iuser->view;
- if ((ima->flag & IMA_IS_STEREO) && (iuser->flag & IMA_SHOW_STEREO))
+ if (BKE_image_is_stereo(ima) && (iuser->flag & IMA_SHOW_STEREO))
actview = iuser->multiview_eye;
if (from_render) {
@@ -3831,12 +3818,12 @@ static size_t image_get_multiview_index(Image *ima, ImageUser *iuser)
return iuser ? iuser->multi_index : index;
}
else if (is_backdrop) {
- if ((ima->flag & IMA_IS_STEREO)) {
+ if (BKE_image_is_stereo(ima)) {
/* backdrop hackaround (since there is no iuser */
return ima->eye;
}
}
- else if ((ima->flag & IMA_IS_MULTIVIEW)) {
+ else if (BKE_image_is_multiview(ima)) {
return iuser ? iuser->multi_index : index;
}
@@ -4325,9 +4312,12 @@ void BKE_image_update_frame(const Main *bmain, int cfra)
void BKE_image_user_file_path(ImageUser *iuser, Image *ima, char *filepath)
{
- if ((ima->flag & IMA_IS_MULTIVIEW) && (ima->rr == NULL)) {
+ if (BKE_image_is_multiview(ima) && (ima->rr == NULL)) {
ImageView *iv = BLI_findlink(&ima->views, iuser->view);
- BLI_strncpy(filepath, iv->filepath, FILE_MAX);
+ if (iv->filepath[0])
+ BLI_strncpy(filepath, iv->filepath, FILE_MAX);
+ else
+ BLI_strncpy(filepath, ima->name, FILE_MAX);
}
else {
BLI_strncpy(filepath, ima->name, FILE_MAX);
@@ -4622,15 +4612,12 @@ static void image_update_views_format(Image *ima, ImageUser *iuser)
BKE_image_free_views(ima);
if (!is_multiview) {
- goto monoview;
+ /* nothing to do */
}
else if (ima->views_format == R_IMF_VIEWS_STEREO_3D) {
size_t i;
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
- ima->flag |= IMA_IS_MULTIVIEW;
- ima->flag |= IMA_IS_STEREO;
-
for (i = 0; i < 2; i++) {
image_add_view(ima, names[i], ima->name);
}
@@ -4645,7 +4632,8 @@ static void image_update_views_format(Image *ima, ImageUser *iuser)
BKE_scene_multiview_view_prefix_get(scene, name, prefix, &ext);
if (prefix[0] == '\0') {
- goto monoview;
+ BKE_image_free_views(ima);
+ return;
}
/* create all the image views */
@@ -4681,15 +4669,7 @@ static void image_update_views_format(Image *ima, ImageUser *iuser)
}
/* all good */
- if (BLI_listbase_count_ex(&ima->views, 2) > 1) {
- ima->flag |= IMA_IS_MULTIVIEW;
- if (BKE_scene_multiview_is_stereo3d(&scene->r))
- ima->flag |= IMA_IS_STEREO;
- }
- else {
-monoview:
- ima->flag &= ~IMA_IS_STEREO;
- ima->flag &= ~IMA_IS_MULTIVIEW;
+ if (!BKE_image_is_multiview(ima)) {
BKE_image_free_views(ima);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index c3b88b8..b4f55d0 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -455,14 +455,13 @@ void BKE_mesh_remap_calc_verts_from_dm(
BVHTreeNearest nearest = {0};
BVHTreeRayHit rayhit = {0};
float hit_dist;
+ float tmp_co[3], tmp_no[3];
if (mode == MREMAP_MODE_VERT_NEAREST) {
bvhtree_from_mesh_verts(&treedata, dm_src, 0.0f, 2, 6);
nearest.index = -1;
for (i = 0; i < numverts_dst; i++) {
- float tmp_co[3];
-
copy_v3_v3(tmp_co, verts_dst[i].co);
/* Convert the vertex to tree coordinates, if needed. */
@@ -488,8 +487,6 @@ void BKE_mesh_remap_calc_verts_from_dm(
nearest.index = -1;
for (i = 0; i < numverts_dst; i++) {
- float tmp_co[3];
-
copy_v3_v3(tmp_co, verts_dst[i].co);
/* Convert the vertex to tree coordinates, if needed. */
@@ -548,8 +545,6 @@ void BKE_mesh_remap_calc_verts_from_dm(
if (mode == MREMAP_MODE_VERT_POLYINTERP_VNORPROJ) {
for (i = 0; i < numverts_dst; i++) {
- float tmp_co[3], tmp_no[3];
-
copy_v3_v3(tmp_co, verts_dst[i].co);
normal_short_to_float_v3(tmp_no, verts_dst[i].no);
@@ -580,8 +575,6 @@ void BKE_mesh_remap_calc_verts_from_dm(
nearest.index = -1;
for (i = 0; i < numverts_dst; i++) {
- float tmp_co[3];
-
copy_v3_v3(tmp_co, verts_dst[i].co);
/* Convert the vertex to tree coordinates, if needed. */
@@ -656,6 +649,7 @@ void BKE_mesh_remap_calc_edges_from_dm(
BVHTreeNearest nearest = {0};
BVHTreeRayHit rayhit = {0};
float hit_dist;
+ float tmp_co[3], tmp_no[3];
if (mode == MREMAP_MODE_EDGE_VERT_NEAREST) {
const int num_verts_src = dm_src->getNumVerts(dm_src);
@@ -694,8 +688,6 @@ void BKE_mesh_remap_calc_edges_from_dm(
/* Compute closest verts only once! */
if (v_dst_to_src_map[vidx_dst].hit_dist == -1.0f) {
- float tmp_co[3];
-
copy_v3_v3(tmp_co, verts_dst[vidx_dst].co);
/* Convert the vertex to tree coordinates, if needed. */
@@ -786,8 +778,6 @@ void BKE_mesh_remap_calc_edges_from_dm(
nearest.index = -1;
for (i = 0; i < numedges_dst; i++) {
- float tmp_co[3];
-
interp_v3_v3v3(tmp_co, verts_dst[edges_dst[i].v1].co, verts_dst[edges_dst[i].v2].co, 0.5f);
/* Convert the vertex to tree coordinates, if needed. */
@@ -814,8 +804,6 @@ void BKE_mesh_remap_calc_edges_from_dm(
bvhtree_from_mesh_looptri(&treedata, dm_src, 0.0f, 2, 6);
for (i = 0; i < numedges_dst; i++) {
- float tmp_co[3];
-
interp_v3_v3v3(tmp_co, verts_dst[edges_dst[i].v1].co, verts_dst[edges_dst[i].v2].co, 0.5f);
/* Convert the vertex to tree coordinates, if needed. */
@@ -872,8 +860,8 @@ void BKE_mesh_remap_calc_edges_from_dm(
/* For each dst edge, we sample some rays from it (interpolated from its vertices)
* and use their hits to interpolate from source edges. */
const MEdge *me = &edges_dst[i];
- float tmp_co[3], v1_co[3], v2_co[3];
- float tmp_no[3], v1_no[3], v2_no[3];
+ float v1_co[3], v2_co[3];
+ float v1_no[3], v2_no[3];
int grid_size;
float edge_dst_len;
@@ -1150,6 +1138,7 @@ void BKE_mesh_remap_calc_loops_from_dm(
BVHTreeRayHit rayhit = {0};
int num_trees = 0;
float hit_dist;
+ float tmp_co[3], tmp_no[3];
const bool use_from_vert = (mode & MREMAP_USE_VERT);
@@ -1440,13 +1429,18 @@ void BKE_mesh_remap_calc_loops_from_dm(
}
for (pidx_dst = 0, mp_dst = polys_dst; pidx_dst < numpolys_dst; pidx_dst++, mp_dst++) {
- float (*pnor_dst)[3] = &poly_nors_dst[pidx_dst];
+ float pnor_dst[3];
/* Only in use_from_vert case, we may need polys' centers as fallback in case we cannot decide which
* corner to use from normals only. */
float pcent_dst[3];
bool pcent_dst_valid = false;
+ if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) {
+ copy_v3_v3(pnor_dst, poly_nors_dst[pidx_dst]);
+ BLI_space_transform_apply_normal(space_transform, pnor_dst);
+ }
+
if ((size_t)mp_dst->totloop > islands_res_buff_size) {
islands_res_buff_size = (size_t)mp_dst->totloop + MREMAP_DEFAULT_BUFSIZE;
for (tindex = 0; tindex < num_trees; tindex++) {
@@ -1460,7 +1454,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
ml_dst = &loops_dst[mp_dst->loopstart];
for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++, ml_dst++) {
if (use_from_vert) {
- float tmp_co[3];
MeshElemMap *vert_to_refelem_map_src = NULL;
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
@@ -1479,12 +1472,14 @@ void BKE_mesh_remap_calc_loops_from_dm(
int best_index_src = -1;
if (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) {
- nor_dst = &loop_nors_dst[plidx_dst + mp_dst->loopstart];
+ copy_v3_v3(tmp_no, loop_nors_dst[plidx_dst + mp_dst->loopstart]);
+ BLI_space_transform_apply_normal(space_transform, tmp_no);
+ nor_dst = &tmp_no;
nors_src = loop_nors_src;
vert_to_refelem_map_src = vert_to_loop_map_src;
}
else { /* if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) { */
- nor_dst = pnor_dst;
+ nor_dst = &pnor_dst;
nors_src = poly_nors_src;
vert_to_refelem_map_src = vert_to_poly_map_src;
}
@@ -1556,8 +1551,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
}
}
else if (mode & MREMAP_USE_NORPROJ) {
- float tmp_co[3], tmp_no[3];
-
int n = (ray_radius > 0.0f) ? MREMAP_RAYCAST_APPROXIMATE_NR : 1;
float w = 1.0f;
@@ -1615,8 +1608,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
}
}
else { /* Nearest poly either to use all its loops/verts or just closest one. */
- float tmp_co[3];
-
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
nearest.index = -1;
@@ -1739,7 +1730,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
* Note we could be much more subtle here, again that's for later... */
int j;
float best_dist_sq = FLT_MAX;
- float tmp_co[3];
ml_dst = &loops_dst[lidx_dst];
copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
@@ -1824,7 +1814,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
/* Find a new valid loop in that new poly (nearest point on poly for now).
* Note we could be much more subtle here, again that's for later... */
float best_dist_sq = FLT_MAX;
- float tmp_co[3];
int j;
ml_dst = &loops_dst[lidx_dst];
@@ -1987,6 +1976,7 @@ void BKE_mesh_remap_calc_polys_from_dm(
const float full_weight = 1.0f;
const float max_dist_sq = max_dist * max_dist;
float (*poly_nors_dst)[3] = NULL;
+ float tmp_co[3], tmp_no[3];
int i;
BLI_assert(mode & MREMAP_MODE_POLY);
@@ -2028,7 +2018,6 @@ void BKE_mesh_remap_calc_polys_from_dm(
for (i = 0; i < numpolys_dst; i++) {
MPoly *mp = &polys_dst[i];
- float tmp_co[3];
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
@@ -2055,7 +2044,6 @@ void BKE_mesh_remap_calc_polys_from_dm(
for (i = 0; i < numpolys_dst; i++) {
MPoly *mp = &polys_dst[i];
- float tmp_co[3], tmp_no[3];
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
@@ -2104,7 +2092,6 @@ void BKE_mesh_remap_calc_polys_from_dm(
* and use their hits to interpolate from source polys. */
/* Note: dst poly is early-converted into src space! */
MPoly *mp = &polys_dst[i];
- float tmp_co[3], tmp_no[3];
int tot_rays, done_rays = 0;
float poly_area_2d_inv, done_area = 0.0f;
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 151889b..a1669c7 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -582,7 +582,7 @@ int unpackImage(ReportList *reports, Image *ima, int how)
{
int ret_value = RET_ERROR;
- if (ima != NULL && ima->name[0]) {
+ if (ima != NULL) {
while (ima->packedfiles.last) {
char localname[FILE_MAX], absname[FILE_MAX];
char *newname;
@@ -605,7 +605,9 @@ int unpackImage(ReportList *reports, Image *ima, int how)
}
/* keep the new name in the image for non-pack specific reasons */
- BLI_strncpy(ima->name, newname, sizeof(imapf->filepath));
+ if (how != PF_REMOVE) {
+ BLI_strncpy(ima->name, newname, sizeof(imapf->filepath));
+ }
MEM_freeN(newname);
}
else {
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index dfdab89..ca6dcb4 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -3444,7 +3444,7 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa
float nr = give_stripelem_index(seq, cfra);
/* all effects are handled similarly with the exception of speed effect */
int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type;
- bool is_preprocessed = !ELEM(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE);
+ bool is_preprocessed = !ELEM(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP);
ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index cec455e..cc39a1b 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -213,8 +213,6 @@ static int start_avi(void *context_v, Scene *UNUSED(scene), RenderData *rd, int
if (AVI_open_compress(name, avi, 1, format) != AVI_ERROR_NONE) {
BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file");
- MEM_freeN(avi);
- avi = NULL;
return 0;
}
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index bc734a9..a2fa201 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -809,7 +809,7 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
AVFormatContext *of;
AVOutputFormat *fmt;
AVDictionary *opts = NULL;
- char name[256], error[1024];
+ char name[FILE_MAX], error[1024];
const char **exts;
context->ffmpeg_type = rd->ffcodecdata.type;
@@ -847,7 +847,10 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
BKE_report(reports, RPT_ERROR, "Error opening output file");
return 0;
}
-
+
+
+ /* Returns after this must 'goto fail;' */
+
of->oformat = fmt;
of->packet_size = rd->ffcodecdata.mux_packet_size;
if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE) {
@@ -900,15 +903,15 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
if (fmt->video_codec == AV_CODEC_ID_DVVIDEO) {
if (rectx != 720) {
BKE_report(reports, RPT_ERROR, "Render width has to be 720 pixels for DV!");
- return 0;
+ goto fail;
}
if (rd->frs_sec != 25 && recty != 480) {
BKE_report(reports, RPT_ERROR, "Render height has to be 480 pixels for DV-NTSC!");
- return 0;
+ goto fail;
}
if (rd->frs_sec == 25 && recty != 576) {
BKE_report(reports, RPT_ERROR, "Render height has to be 576 pixels for DV-PAL!");
- return 0;
+ goto fail;
}
}
@@ -916,8 +919,7 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
fmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2) {
BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!");
- av_dict_free(&opts);
- return 0;
+ goto fail;
}
}
@@ -929,9 +931,7 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
BKE_report(reports, RPT_ERROR, error);
else
BKE_report(reports, RPT_ERROR, "Error initializing video stream");
-
- av_dict_free(&opts);
- return 0;
+ goto fail;
}
}
@@ -942,22 +942,18 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
BKE_report(reports, RPT_ERROR, error);
else
BKE_report(reports, RPT_ERROR, "Error initializing audio stream");
- av_dict_free(&opts);
- return 0;
+ goto fail;
}
}
if (!(fmt->flags & AVFMT_NOFILE)) {
if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) {
BKE_report(reports, RPT_ERROR, "Could not open file for writing");
- av_dict_free(&opts);
- return 0;
+ goto fail;
}
}
if (avformat_write_header(of, NULL) < 0) {
BKE_report(reports, RPT_ERROR, "Could not initialize streams, probably unsupported codec combination");
- av_dict_free(&opts);
- avio_close(of->pb);
- return 0;
+ goto fail;
}
context->outfile = of;
@@ -965,6 +961,26 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
av_dict_free(&opts);
return 1;
+
+
+fail:
+ if (of->pb) {
+ avio_close(of->pb);
+ }
+
+ if (context->video_stream && context->video_stream->codec) {
+ avcodec_close(context->video_stream->codec);
+ context->video_stream = NULL;
+ }
+
+ if (context->audio_stream && context->audio_stream->codec) {
+ avcodec_close(context->audio_stream->codec);
+ context->audio_stream = NULL;
+ }
+
+ av_dict_free(&opts);
+ avformat_free_context(of);
+ return 0;
}
/**
@@ -1234,6 +1250,11 @@ static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit)
context->video_stream = 0;
}
+ if (context->audio_stream && context->audio_stream->codec) {
+ avcodec_close(context->audio_stream->codec);
+ context->audio_stream = 0;
+ }
+
/* free the temp buffer */
if (context->current_frame) {
delete_picture(context->current_frame);
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index dad2a2f..e005809 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -1384,16 +1384,14 @@ bool isect_ray_tri_watertight_v3(
const float cy = c_ky - sy * c_kz;
/* Calculate scaled barycentric coordinates. */
- float u = cx * by - cy * bx;
- int sign_mask = (float_as_int(u) & (int)0x80000000);
- float v = ax * cy - ay * cx;
- float w, det;
+ const float u = cx * by - cy * bx;
+ const float v = ax * cy - ay * cx;
+ const float w = bx * ay - by * ax;
+ float det;
- if (sign_mask != (float_as_int(v) & (int)0x80000000)) {
- return false;
- }
- w = bx * ay - by * ax;
- if (sign_mask != (float_as_int(w) & (int)0x80000000)) {
+ if ((u < 0.0f || v < 0.0f || w < 0.0f) &&
+ (u > 0.0f || v > 0.0f || w > 0.0f))
+ {
return false;
}
@@ -1406,8 +1404,9 @@ bool isect_ray_tri_watertight_v3(
/* Calculate scaled z-coordinates of vertices and use them to calculate
* the hit distance.
*/
+ const int sign_det = (float_as_int(det) & (int)0x80000000);
const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
- const float sign_t = xor_fl(t, sign_mask);
+ const float sign_t = xor_fl(t, sign_det);
if ((sign_t < 0.0f)
/* differ from Cycles, don't read r_lambda's original value
* otherwise we won't match any of the other intersect functions here...
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 4692af0..7c3af302 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -191,31 +191,6 @@ int BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
}
/**
- * Looks for a string of digits within name (using BLI_stringdec) and adjusts it by add.
- */
-void BLI_newname(char *name, int add)
-{
- char head[UNIQUE_NAME_MAX], tail[UNIQUE_NAME_MAX];
- int pic;
- unsigned short digits;
-
- pic = BLI_stringdec(name, head, tail, &digits);
-
- /* are we going from 100 -> 99 or from 10 -> 9 */
- if (add < 0 && digits < 4 && digits > 0) {
- int i, exp;
- exp = 1;
- for (i = digits; i > 1; i--) exp *= 10;
- if (pic >= exp && (pic + add) < exp) digits--;
- }
-
- pic += add;
-
- if (digits == 4 && pic < 0) pic = 0;
- BLI_stringenc(name, head, tail, digits, pic);
-}
-
-/**
* Ensures name is unique (according to criteria specified by caller in unique_check callback),
* incrementing its numeric suffix as necessary. Returns true if name had to be adjusted.
*
@@ -453,6 +428,8 @@ void BLI_cleanup_file(const char *relabase, char *path)
*
* \note Space case ' ' is a bit of an edge case here - in theory it is allowed, but again can be an issue
* in some cases, so we simply replace it by an underscore too (good practice anyway).
+ * REMOVED based on popular demand (see T45900).
+ * Percent '%' char is a bit same case - not recommended to use it, but supported by all decent FS/OS around...
*
* \note On Windows, it also ensures there is no '.' (dot char) at the end of the file, this can lead to issues...
*
@@ -461,9 +438,9 @@ void BLI_cleanup_file(const char *relabase, char *path)
*/
bool BLI_filename_make_safe(char *fname)
{
- const char *invalid = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ const char *invalid = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
- "/\\?%*:|\"<> ";
+ "/\\?*:|\"<>";
char *fn;
bool changed = false;
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index 25074ef..947f945 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -343,7 +343,7 @@ static void do_versions_mesh_mloopcol_swap_2_62_1(Mesh *me)
if (layer->type == CD_MLOOPCOL) {
mloopcol = (MLoopCol *)layer->data;
for (i = 0; i < me->totloop; i++, mloopcol++) {
- SWAP(char, mloopcol->r, mloopcol->b);
+ SWAP(unsigned char, mloopcol->r, mloopcol->b);
}
}
}
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 17b6d1d..cd3c832 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -102,6 +102,7 @@ static bool bm_vert_is_edge_select_any(const BMVert *v)
}
#endif
+#if 0
static bool bm_edge_is_face_select_any_other(BMLoop *l_first)
{
const BMLoop *l_iter = l_first;
@@ -114,6 +115,7 @@ static bool bm_edge_is_face_select_any_other(BMLoop *l_first)
}
return false;
}
+#endif
#if 0
static bool bm_edge_is_face_select_any(const BMEdge *e)
@@ -498,6 +500,20 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
BM_elem_flag_disable(f, BM_ELEM_SELECT);
bm->totfacesel -= 1;
}
+ /**
+ * \note This allows a temporarily invalid state - where for eg
+ * an edge bay be de-selected, but an adjacent face remains selected.
+ *
+ * Rely on #BM_mesh_select_mode_flush to correct these cases.
+ */
+#if 1
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_vert_select_set(bm, l_iter->v, false);
+ BM_edge_select_set(bm, l_iter->e, false);
+ } while ((l_iter = l_iter->next) != l_first);
+#else
+ /* disabled, see T46494 */
/* flush down to edges */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
@@ -515,6 +531,7 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
BM_vert_select_set(bm, l_iter->v, false);
}
} while ((l_iter = l_iter->next) != l_first);
+#endif
}
}
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index 6ddce75..fd08e1e 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -255,9 +255,13 @@ void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone
{
BoneExtended *dominant_child = NULL;
int maxlen = 0;
- Bone *child = (Bone *)parentbone->childbase.first;
- if (child && (import_settings->find_chains || child->next==NULL) )
- {
+ Bone *child;
+
+ if (parentbone == NULL)
+ return;
+
+ child = (Bone *)parentbone->childbase.first;
+ if (child && (import_settings->find_chains || child->next==NULL)) {
for (; child; child = child->next) {
BoneExtended *be = extended_bones[child->name];
if (be != NULL) {
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 7802161..671c590 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1100,7 +1100,7 @@ static bool ui_but_event_property_operator_string(const bContext *C, uiBut *but,
/* check each until one works... */
for (i = 0; (i < num_ops) && (ctx_toggle_opnames[i]); i++) {
- //printf("\t%s\n", ctx_toggle_opnames[i]);
+ printf("\t%s\n", ctx_toggle_opnames[i]);
if (WM_key_event_operator_string(C, ctx_toggle_opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false,
buf_len, buf))
{
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 3fd2ba6..1b52140 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -7517,8 +7517,14 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
else if (data->state == BUTTON_STATE_NUM_EDITING) {
ui_numedit_end(but, data);
- if (but->flag & UI_BUT_DRIVEN)
- WM_report(C, RPT_INFO, "Can't edit driven number value, see graph editor for the driver setup.");
+ if (but->flag & UI_BUT_DRIVEN) {
+ /* Only warn when editing stepping/dragging the value.
+ * No warnings should show for editing driver expressions though!
+ */
+ if (state != BUTTON_STATE_TEXT_EDITING) {
+ WM_report(C, RPT_INFO, "Can't edit driven number value, see graph editor for the driver setup.");
+ }
+ }
if (ui_but_is_cursor_warp(but)) {
diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c
index e1a58d5..9a2635c 100644
--- a/source/blender/editors/mask/mask_edit.c
+++ b/source/blender/editors/mask/mask_edit.c
@@ -403,6 +403,10 @@ bool ED_mask_selected_minmax(const bContext *C, float min[2], float max[2])
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *mask_layer;
bool ok = false;
+
+ if (mask == NULL)
+ return ok;
+
INIT_MINMAX2(min, max);
for (mask_layer = mask->masklayers.first;
mask_layer != NULL;
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index c718dfa..9235dd4 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -228,13 +228,8 @@ static void screen_opengl_views_setup(OGLRender *oglrender)
}
BLI_lock_thread(LOCK_DRAW_IMAGE);
- if (is_multiview && BKE_scene_multiview_is_stereo3d(rd)) {
- oglrender->ima->flag |= IMA_IS_STEREO;
- }
- else {
- oglrender->ima->flag &= ~IMA_IS_STEREO;
+ if (!(is_multiview && BKE_scene_multiview_is_stereo3d(rd)))
oglrender->iuser.flag &= ~IMA_SHOW_STEREO;
- }
BLI_unlock_thread(LOCK_DRAW_IMAGE);
/* will only work for non multiview correctly */
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 569d611..71f6064 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -42,6 +42,7 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -2195,7 +2196,7 @@ bool ED_screen_stereo3d_required(bScreen *screen)
/* images should always show in stereo, even if
* the file doesn't have views enabled */
sima = sa->spacedata.first;
- if (sima->image && (sima->image->flag & IMA_IS_STEREO) &&
+ if (sima->image && BKE_image_is_stereo(sima->image) &&
(sima->iuser.flag & IMA_SHOW_STEREO))
{
return true;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index f1489f2..73a3cce 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -4324,7 +4324,7 @@ static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, flo
}
else {
premul_float_to_straight_uchar(rgba_ub, rgba);
- blend_color_interpolate_byte(rgba_ub, rgba_ub, projPixel->pixel.ch_pt, mask);
+ blend_color_interpolate_byte(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, mask);
}
BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
}
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 08b6564..328b09d 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1973,6 +1973,37 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot)
}
+/**
+ * Looks for a string of digits within name (using BLI_stringdec) and adjusts it by add.
+ */
+static void filenum_newname(char *name, size_t name_size, int add)
+{
+ char head[FILE_MAXFILE], tail[FILE_MAXFILE];
+ char name_temp[FILE_MAXFILE];
+ int pic;
+ unsigned short digits;
+
+ pic = BLI_stringdec(name, head, tail, &digits);
+
+ /* are we going from 100 -> 99 or from 10 -> 9 */
+ if (add < 0 && digits > 0) {
+ int i, exp;
+ exp = 1;
+ for (i = digits; i > 1; i--) {
+ exp *= 10;
+ }
+ if (pic >= exp && (pic + add) < exp) {
+ digits--;
+ }
+ }
+
+ pic += add;
+ if (pic < 0)
+ pic = 0;
+ BLI_stringenc(name_temp, head, tail, digits, pic);
+ BLI_strncpy(name, name_temp, name_size);
+}
+
static int file_filenum_exec(bContext *C, wmOperator *op)
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1980,7 +2011,7 @@ static int file_filenum_exec(bContext *C, wmOperator *op)
int inc = RNA_int_get(op->ptr, "increment");
if (sfile->params && (inc != 0)) {
- BLI_newname(sfile->params->file, inc);
+ filenum_newname(sfile->params->file, sizeof(sfile->params->file), inc);
ED_area_tag_redraw(sa);
file_draw_check(C);
// WM_event_add_notifier(C, NC_WINDOW, NULL);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 8e5c85d..07c16fa 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -166,6 +166,8 @@ static int graphview_cursor_modal(bContext *C, wmOperator *op, const wmEvent *ev
case ESCKEY:
if (screen)
screen->scrubbing = false;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, CTX_data_scene(C));
return OPERATOR_FINISHED;
case MOUSEMOVE:
@@ -183,6 +185,8 @@ static int graphview_cursor_modal(bContext *C, wmOperator *op, const wmEvent *ev
if (event->val == KM_RELEASE) {
if (screen)
screen->scrubbing = false;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, CTX_data_scene(C));
return OPERATOR_FINISHED;
}
break;
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 4c7ac53..ea5cd56 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -240,7 +240,7 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar)
UI_view2d_view_ortho(v2d);
/* grid */
- unitx = (sipo->flag & SIPO_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE;
+ unitx = ((sipo->mode == SIPO_MODE_ANIMATION) && (sipo->flag & SIPO_DRAWTIME)) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE;
grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 6b5cc38..2f87d43 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -715,8 +715,8 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes
}
/* stereo image */
- else if (((image->flag & IMA_IS_STEREO) && (!show_stereo)) ||
- ((image->flag & IMA_IS_MULTIVIEW) && ((image->flag & IMA_IS_STEREO) == 0)))
+ else if ((BKE_image_is_stereo(image) && (!show_stereo)) ||
+ (BKE_image_is_multiview(image) && !BKE_image_is_stereo(image)))
{
ImageView *iv;
int nr = 0;
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 3a178ed..792b1e7 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -813,7 +813,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
show_viewer = (ima && ima->source == IMA_SRC_VIEWER) != 0;
show_render = (show_viewer && ima->type == IMA_TYPE_R_RESULT) != 0;
show_paint = (ima && (sima->mode == SI_MODE_PAINT) && (show_viewer == false) && (show_render == false));
- show_stereo3d = (ima && (ima->flag & IMA_IS_STEREO) && (sima->iuser.flag & IMA_SHOW_STEREO));
+ show_stereo3d = (ima && BKE_image_is_stereo(ima) && (sima->iuser.flag & IMA_SHOW_STEREO));
show_multilayer = ima && BKE_image_is_multilayer(ima);
if (show_viewer) {
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 3c5aff4..faba61c 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1153,8 +1153,6 @@ static int image_open_exec(bContext *C, wmOperator *op)
}
else {
ima->flag &= ~IMA_USE_VIEWS;
- ima->flag &= ~IMA_IS_STEREO;
- ima->flag &= ~IMA_IS_MULTIVIEW;
BKE_image_free_views(ima);
}
@@ -1703,7 +1701,7 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
/* we need renderresult for exr and rendered multiview */
scene = CTX_data_scene(C);
rr = BKE_image_acquire_renderresult(scene, ima);
- is_mono = rr ? BLI_listbase_count_ex(&rr->views, 2) < 2 : (ima->flag & IMA_IS_MULTIVIEW) == 0;
+ is_mono = rr ? BLI_listbase_count_ex(&rr->views, 2) < 2 : BLI_listbase_count_ex(&ima->views, 2) < 2;
/* error handling */
if (!rr) {
@@ -1714,7 +1712,7 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
}
else {
if (imf->views_format == R_IMF_VIEWS_STEREO_3D) {
- if ((ima->flag & IMA_IS_STEREO) == 0) {
+ if (!BKE_image_is_stereo(ima)) {
BKE_reportf(op->reports, RPT_ERROR, "Did not write, the image doesn't have a \"%s\" and \"%s\" views",
STEREO_LEFT_NAME, STEREO_RIGHT_NAME);
goto cleanup;
@@ -1959,9 +1957,9 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
/* show multiview save options only if image has multiviews */
prop = RNA_struct_find_property(op->ptr, "show_multiview");
- RNA_property_boolean_set(op->ptr, prop, (ima->flag & IMA_IS_MULTIVIEW) != 0);
+ RNA_property_boolean_set(op->ptr, prop, BKE_image_is_multiview(ima));
prop = RNA_struct_find_property(op->ptr, "use_multiview");
- RNA_property_boolean_set(op->ptr, prop, (ima->flag & IMA_IS_MULTIVIEW) != 0);
+ RNA_property_boolean_set(op->ptr, prop, BKE_image_is_multiview(ima));
image_filesel(C, op, simopts.filepath);
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index c89a1bb..f10e6be 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -150,8 +150,15 @@ int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, boo
/* outliner_edit.c ---------------------------------------------- */
-void outliner_do_object_operation(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
- void (*operation_cb)(struct bContext *C, struct Scene *scene, struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *));
+void outliner_do_object_operation_ex(
+ struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
+ void (*operation_cb)(struct bContext *C, struct Scene *scene,
+ struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *),
+ bool recurse_selected);
+void outliner_do_object_operation(
+ struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
+ void (*operation_cb)(struct bContext *C, struct Scene *scene,
+ struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *));
int common_restrict_check(struct bContext *C, struct Object *ob);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 50171d7..863f09d 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -516,15 +516,20 @@ static void group_instance_cb(bContext *C, Scene *scene, TreeElement *UNUSED(te)
id_lib_extern(&group->id);
}
-void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb,
- void (*operation_cb)(bContext *C, Scene *scene, TreeElement *,
- TreeStoreElem *, TreeStoreElem *))
+/**
+ * \param select_recurse: Set to false for operations which are already recursively operating on their children.
+ */
+void outliner_do_object_operation_ex(
+ bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb,
+ void (*operation_cb)(bContext *C, Scene *scene, TreeElement *,
+ TreeStoreElem *, TreeStoreElem *),
+ bool select_recurse)
{
TreeElement *te;
- TreeStoreElem *tselem;
for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
+ bool select_handled = false;
if (tselem->flag & TSE_SELECTED) {
if (tselem->type == 0 && te->idcode == ID_OB) {
// when objects selected in other scenes... dunno if that should be allowed
@@ -536,14 +541,25 @@ void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soop
* only use 'scene_act' when 'scene_owner' is NULL, which can happen when the
* outliner isn't showing scenes: Visible Layer draw mode for eg. */
operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem);
+ select_handled = true;
}
}
if (TSELEM_OPEN(tselem, soops)) {
- outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb);
+ if ((select_handled == false) || select_recurse) {
+ outliner_do_object_operation_ex(C, scene_act, soops, &te->subtree, operation_cb, select_recurse);
+ }
}
}
}
+void outliner_do_object_operation(
+ bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb,
+ void (*operation_cb)(bContext *C, Scene *scene, TreeElement *,
+ TreeStoreElem *, TreeStoreElem *))
+{
+ outliner_do_object_operation_ex(C, scene_act, soops, lb, operation_cb, true);
+}
+
/* ******************************************** */
static void clear_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te),
@@ -876,7 +892,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
}
else if (event == OL_OP_SELECT_HIERARCHY) {
Scene *sce = scene; // to be able to delete, scenes are set...
- outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_hierarchy_cb);
+ outliner_do_object_operation_ex(C, scene, soops, &soops->tree, object_select_hierarchy_cb, false);
if (scene != sce) {
ED_screen_set_scene(C, CTX_wm_screen(C), sce);
}
@@ -903,7 +919,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
else if (event == OL_OP_DELETE_HIERARCHY) {
- outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_hierarchy_cb);
+ outliner_do_object_operation_ex(C, scene, soops, &soops->tree, object_delete_hierarchy_cb, false);
/* XXX: See OL_OP_DELETE comment above. */
outliner_cleanup_tree(soops);
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index d806dfa..10c75eb 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -410,7 +410,8 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
solidtex = false;
Gtexdraw.is_lit = 0;
}
- else if (v3d->drawtype == OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype != OB_TEXTURE)) {
+ else if (v3d->drawtype == OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype != OB_TEXTURE) ||
+ (BKE_scene_use_new_shading_nodes(scene) && (ob->mode & OB_MODE_TEXTURE_PAINT))) {
/* draw with default lights in solid draw mode and edit mode */
solidtex = true;
Gtexdraw.is_lit = -1;
@@ -664,7 +665,7 @@ static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol)
else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
int loop_index = mp->loopstart;
for (j = 0; j < mp->totloop; j++, loop_index++) {
- copy_v3_v3_char(&finalCol[loop_index].r, (char *)Gtexdraw.obcol);
+ copy_v3_v3_char((char *)&finalCol[loop_index].r, (char *)Gtexdraw.obcol);
}
copy_mode = COPY_PREV;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index d9ad481..95c8cd5 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1618,7 +1618,7 @@ exit:
static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
{
- if ((ima->flag & IMA_IS_STEREO)) {
+ if (BKE_image_is_stereo(ima)) {
iuser->flag |= IMA_SHOW_STEREO;
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 8e867eb..9ae18c1 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -3085,6 +3085,7 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
float value;
int i;
char str[MAX_INFO_LEN];
+ const bool is_local_center = transdata_check_local_center(t, t->around);
copy_m3_m4(persmat, t->viewmat);
invert_m3_m3(persinv, persmat);
@@ -3120,8 +3121,10 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
mul_m3_m3m3(tmat, smat, persmat);
mul_m3_m3m3(totmat, persinv, tmat);
-
+
for (i = 0; i < t->total; i++, td++) {
+ const float *center, *co;
+
if (td->flag & TD_NOACTION)
break;
@@ -3136,12 +3139,22 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
else {
copy_m3_m3(tmat, totmat);
}
- sub_v3_v3v3(vec, td->center, t->center);
+
+ if (is_local_center) {
+ center = td->center;
+ co = td->loc;
+ }
+ else {
+ center = t->center;
+ co = td->center;
+ }
+
+ sub_v3_v3v3(vec, co, center);
mul_m3_v3(tmat, vec);
- add_v3_v3(vec, t->center);
- sub_v3_v3(vec, td->center);
+ add_v3_v3(vec, center);
+ sub_v3_v3(vec, co);
mul_v3_fl(vec, td->factor);
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 61b2dea..3b8d87c 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -39,6 +39,11 @@
#include "MEM_guardedalloc.h"
+struct InputTrackBall_Data {
+ float value_accum[2];
+ float value_prev[2];
+};
+
/* ************************** INPUT FROM MOUSE *************************** */
static void InputVector(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
@@ -102,18 +107,23 @@ static void InputSpringDelta(TransInfo *t, MouseInput *mi, const int mval[2], fl
static void InputTrackBall(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float output[3])
{
+ struct InputTrackBall_Data *data = mi->data;
+ float dxy[2];
+ float dxy_accum[2];
+
+ dxy[0] = (mi->imval[1] - mval[1]);
+ dxy[1] = (mval[0] - mi->imval[0]);
+
+ sub_v2_v2v2(dxy_accum, dxy, data->value_prev);
+
+ add_v2_v2(data->value_prev, dxy_accum);
if (mi->precision) {
- output[0] = (mi->imval[1] - mi->precision_mval[1]) + (mi->precision_mval[1] - mval[1]) * 0.1f;
- output[1] = (mi->precision_mval[0] - mi->imval[0]) + (mval[0] - mi->precision_mval[0]) * 0.1f;
- }
- else {
- output[0] = (float)(mi->imval[1] - mval[1]);
- output[1] = (float)(mval[0] - mi->imval[0]);
+ mul_v2_fl(dxy_accum, 1.0f / 30.0f);
}
- output[0] *= mi->factor;
- output[1] *= mi->factor;
+ add_v2_v2(data->value_accum, dxy_accum);
+ mul_v2_v2fl(output, data->value_accum, mi->factor);
}
static void InputHorizontalRatio(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
@@ -358,6 +368,7 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
case INPUT_TRACKBALL:
/* factor has to become setting or so */
mi->factor = 0.01f;
+ mi->data = MEM_callocN(sizeof(struct InputTrackBall_Data), "angle accumulator");
mi->apply = InputTrackBall;
t->helpline = HLP_TRACKBALL;
break;
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 6075261..bdebeb7 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -85,6 +85,8 @@
#define TRANSFORM_DIST_MAX_PX 1000.0f
#define TRANSFORM_SNAP_MAX_PX 100.0f
+#define TRANSFORM_DIST_INVALID -FLT_MAX
+
/* use half of flt-max so we can scale up without an exception */
/********************* PROTOTYPES ***********************/
@@ -887,17 +889,20 @@ static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3])
sub_v3_v3v3(d1, p1, t->center_global);
sub_v3_v3v3(d2, p2, t->center_global);
-
- project_v3_v3v3(d1, d1, d2);
if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
mul_m3_v3(t->con.pmtx, d1);
mul_m3_v3(t->con.pmtx, d2);
}
+
+ project_v3_v3v3(d1, d1, d2);
len_d1 = len_v3(d1);
- return len_d1 != 0.0f ? len_v3(d2) / len_d1 : 1;
+ /* Use 'invalid' dist when `center == p1` (after projecting),
+ * in this case scale will _never_ move the point in relation to the center,
+ * so it makes no sense to take it into account when scaling. see: T46503 */
+ return len_d1 != 0.0f ? len_v3(d2) / len_d1 : TRANSFORM_DIST_INVALID;
}
/********************** CALC **************************/
@@ -1177,8 +1182,10 @@ static void TargetSnapClosest(TransInfo *t)
mul_m4_v3(td->ext->obmat, loc);
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
-
- if (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)) {
+
+ if ((dist != TRANSFORM_DIST_INVALID) &&
+ (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)))
+ {
copy_v3_v3(t->tsnap.snapTarget, loc);
closest = td;
t->tsnap.dist = dist;
@@ -1193,8 +1200,10 @@ static void TargetSnapClosest(TransInfo *t)
copy_v3_v3(loc, td->center);
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
-
- if (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)) {
+
+ if ((dist != TRANSFORM_DIST_INVALID) &&
+ (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)))
+ {
copy_v3_v3(t->tsnap.snapTarget, loc);
closest = td;
t->tsnap.dist = dist;
@@ -1217,7 +1226,9 @@ static void TargetSnapClosest(TransInfo *t)
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
- if (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)) {
+ if ((dist != TRANSFORM_DIST_INVALID) &&
+ (closest == NULL || fabsf(dist) < fabsf(t->tsnap.dist)))
+ {
copy_v3_v3(t->tsnap.snapTarget, loc);
closest = td;
t->tsnap.dist = dist;
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 71d557f..3fc0b65 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -4119,7 +4119,13 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
}
}
- me->drawflag |= ME_DRAWSEAMS;
+ if (mark_seams) {
+ me->drawflag |= ME_DRAWSEAMS;
+ }
+ if (mark_sharp) {
+ me->drawflag |= ME_DRAWSHARP;
+ }
+
BM_uv_vert_map_free(vmap);
@@ -4189,6 +4195,10 @@ static int uv_mark_seam_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
uiPopupMenu *pup;
uiLayout *layout;
+ if (RNA_struct_property_is_set(op->ptr, "clear")) {
+ return uv_mark_seam_exec(C, op);
+ }
+
pup = UI_popup_menu_begin(C, IFACE_("Edges"), ICON_NONE);
layout = UI_popup_menu_layout(pup);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index f915a4b..3ff3e29 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -344,7 +344,8 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
{
ParamHandle *handle;
/* index pointers */
- MFace *face;
+ MPoly *mpoly;
+ MLoop *mloop;
MEdge *edge;
int i;
@@ -356,11 +357,12 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* Used to hold subsurfed Mesh */
DerivedMesh *derivedMesh, *initialDerived;
/* holds original indices for subsurfed mesh */
- const int *origVertIndices, *origEdgeIndices, *origFaceIndices, *origPolyIndices;
+ const int *origVertIndices, *origEdgeIndices, *origPolyIndices;
/* Holds vertices of subsurfed mesh */
MVert *subsurfedVerts;
MEdge *subsurfedEdges;
- MFace *subsurfedFaces;
+ MPoly *subsurfedPolys;
+ MLoop *subsurfedLoops;
/* number of vertices and faces for subsurfed mesh*/
int numOfEdges, numOfFaces;
@@ -398,15 +400,15 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* get the derived data */
subsurfedVerts = derivedMesh->getVertArray(derivedMesh);
subsurfedEdges = derivedMesh->getEdgeArray(derivedMesh);
- subsurfedFaces = derivedMesh->getTessFaceArray(derivedMesh);
+ subsurfedPolys = derivedMesh->getPolyArray(derivedMesh);
+ subsurfedLoops = derivedMesh->getLoopArray(derivedMesh);
origVertIndices = derivedMesh->getVertDataArray(derivedMesh, CD_ORIGINDEX);
origEdgeIndices = derivedMesh->getEdgeDataArray(derivedMesh, CD_ORIGINDEX);
- origFaceIndices = derivedMesh->getTessFaceDataArray(derivedMesh, CD_ORIGINDEX);
origPolyIndices = derivedMesh->getPolyDataArray(derivedMesh, CD_ORIGINDEX);
numOfEdges = derivedMesh->getNumEdges(derivedMesh);
- numOfFaces = derivedMesh->getNumTessFaces(derivedMesh);
+ numOfFaces = derivedMesh->getNumPolys(derivedMesh);
faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map");
@@ -415,7 +417,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* map subsurfed faces to original editFaces */
for (i = 0; i < numOfFaces; i++)
- faceMap[i] = BM_face_at_index(em->bm, DM_origindex_mface_mpoly(origFaceIndices, origPolyIndices, i));
+ faceMap[i] = BM_face_at_index(em->bm, origPolyIndices[i]);
edgeMap = MEM_mallocN(numOfEdges * sizeof(BMEdge *), "unwrap_edit_edge_map");
@@ -427,15 +429,13 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
}
/* Prepare and feed faces to the solver */
- for (i = 0; i < numOfFaces; i++) {
+ for (i = 0, mpoly = subsurfedPolys; i < numOfFaces; i++, mpoly++) {
ParamKey key, vkeys[4];
ParamBool pin[4], select[4];
float *co[4];
float *uv[4];
BMFace *origFace = faceMap[i];
- face = subsurfedFaces + i;
-
if (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
if (BM_elem_flag_test(origFace, BM_ELEM_HIDDEN))
continue;
@@ -445,24 +445,27 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
continue;
}
+ mloop = &subsurfedLoops[mpoly->loopstart];
+
/* We will not check for v4 here. Subsurfed mfaces always have 4 vertices. */
- key = (ParamKey)face;
- vkeys[0] = (ParamKey)face->v1;
- vkeys[1] = (ParamKey)face->v2;
- vkeys[2] = (ParamKey)face->v3;
- vkeys[3] = (ParamKey)face->v4;
-
- co[0] = subsurfedVerts[face->v1].co;
- co[1] = subsurfedVerts[face->v2].co;
- co[2] = subsurfedVerts[face->v3].co;
- co[3] = subsurfedVerts[face->v4].co;
+ BLI_assert(mpoly->totloop == 4);
+ key = (ParamKey)mpoly;
+ vkeys[0] = (ParamKey)mloop[0].v;
+ vkeys[1] = (ParamKey)mloop[1].v;
+ vkeys[2] = (ParamKey)mloop[2].v;
+ vkeys[3] = (ParamKey)mloop[3].v;
+
+ co[0] = subsurfedVerts[mloop[0].v].co;
+ co[1] = subsurfedVerts[mloop[1].v].co;
+ co[2] = subsurfedVerts[mloop[2].v].co;
+ co[3] = subsurfedVerts[mloop[3].v].co;
/* This is where all the magic is done. If the vertex exists in the, we pass the original uv pointer to the solver, thus
* flushing the solution to the edit mesh. */
- texface_from_original_index(origFace, origVertIndices[face->v1], &uv[0], &pin[0], &select[0], scene, cd_loop_uv_offset);
- texface_from_original_index(origFace, origVertIndices[face->v2], &uv[1], &pin[1], &select[1], scene, cd_loop_uv_offset);
- texface_from_original_index(origFace, origVertIndices[face->v3], &uv[2], &pin[2], &select[2], scene, cd_loop_uv_offset);
- texface_from_original_index(origFace, origVertIndices[face->v4], &uv[3], &pin[3], &select[3], scene, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[mloop[0].v], &uv[0], &pin[0], &select[0], scene, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[mloop[1].v], &uv[1], &pin[1], &select[1], scene, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[mloop[2].v], &uv[2], &pin[2], &select[2], scene, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[mloop[3].v], &uv[3], &pin[3], &select[3], scene, cd_loop_uv_offset);
param_face_add(handle, key, 4, vkeys, co, uv, pin, select, NULL);
}
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index 8983a78..eb6a470 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -106,7 +106,9 @@ Controller::Controller()
_ProgressBar = new ProgressBar;
_SceneNumFaces = 0;
+#if 0
_minEdgeSize = DBL_MAX;
+#endif
_EPSILON = 1.0e-6;
_bboxDiag = 0;
@@ -264,9 +266,11 @@ int Controller::LoadMesh(Render *re, SceneRenderLayer *srl)
}
_SceneNumFaces += loader.numFacesRead();
+#if 0
if (loader.minEdgeSize() < _minEdgeSize) {
_minEdgeSize = loader.minEdgeSize();
}
+#endif
#if 0 // DEBUG
ScenePrettyPrinter spp;
@@ -406,7 +410,9 @@ void Controller::DeleteWingedEdge()
_Grid.clear();
_Scene3dBBox.clear();
_SceneNumFaces = 0;
+#if 0
_minEdgeSize = DBL_MAX;
+#endif
}
void Controller::DeleteViewMap(bool freeCache)
diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h
index 22eaaf5..6f3cb3b 100644
--- a/source/blender/freestyle/intern/application/Controller.h
+++ b/source/blender/freestyle/intern/application/Controller.h
@@ -209,7 +209,9 @@ private:
BBox<Vec3r> _Scene3dBBox;
unsigned int _SceneNumFaces;
+#if 0
real _minEdgeSize;
+#endif
real _EPSILON;
real _bboxDiag;
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index 2b0d3b1..ea5a557 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -38,7 +38,9 @@ BlenderFileLoader::BlenderFileLoader(Render *re, SceneRenderLayer *srl)
_srl = srl;
_Scene = NULL;
_numFacesRead = 0;
+#if 0
_minEdgeSize = DBL_MAX;
+#endif
_smooth = (srl->freestyleConfig.flags & FREESTYLE_FACE_SMOOTHNESS_FLAG) != 0;
_pRenderMonitor = NULL;
}
@@ -262,7 +264,10 @@ void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v
float n1[3], float n2[3], float n3[3],
bool fm, bool em1, bool em2, bool em3)
{
- float *fv[3], *fn[3], len;
+ float *fv[3], *fn[3];
+#if 0
+ float len;
+#endif
unsigned int i, j;
IndexedFaceSet::FaceEdgeMark marks = 0;
@@ -289,9 +294,11 @@ void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v
ls->maxBBox[j] = ls->pv[j];
}
+#if 0
len = len_v3v3(fv[i], fv[(i + 1) % 3]);
if (_minEdgeSize > len)
_minEdgeSize = len;
+#endif
*ls->pvi = ls->currentIndex;
*ls->pni = ls->currentIndex;
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
index d16a311..894f8ee 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
@@ -87,8 +87,10 @@ public:
/*! Gets the number of read faces */
inline unsigned int numFacesRead() {return _numFacesRead;}
+#if 0
/*! Gets the smallest edge size read */
inline real minEdgeSize() {return _minEdgeSize;}
+#endif
/*! Modifiers */
inline void setRenderMonitor(RenderMonitor *iRenderMonitor) {_pRenderMonitor = iRenderMonitor;}
@@ -115,7 +117,9 @@ protected:
SceneRenderLayer *_srl;
NodeGroup *_Scene;
unsigned _numFacesRead;
+#if 0
real _minEdgeSize;
+#endif
bool _smooth; /* if true, face smoothness is taken into account */
float _viewplane_left;
float _viewplane_right;
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 64ef49d..7c10591 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -55,6 +55,8 @@ extern "C" {
#include "BLI_ghash.h"
#include "BLI_listbase.h"
+#include "BLI_math_color.h"
+#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "RE_pipeline.h"
@@ -113,7 +115,6 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str
BLI_strncpy(freestyle_scene->r.engine, old_scene->r.engine, sizeof(freestyle_scene->r.engine));
freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA;
freestyle_scene->r.im_format.imtype = R_IMF_IMTYPE_PNG;
- BKE_scene_disable_color_management(freestyle_scene);
if (G.debug & G_DEBUG_FREESTYLE) {
printf("%s: %d thread(s)\n", __func__, BKE_render_num_threads(&freestyle_scene->r));
@@ -871,38 +872,24 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
}
}
- // colors and alpha transparency
+ // colors and alpha transparency. vertex colors are in sRGB
+ // space by convention, so convert from linear
+ float rgba[3][4];
+
+ for (int i = 0; i < 3; i++) {
+ copy_v3fl_v3db(rgba[i], &svRep[i]->color()[0]);
+ rgba[i][3] = svRep[i]->alpha();
+ }
+
if (is_odd) {
- colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
- colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
- colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
- colors[0].a = (short)(255.0f * svRep[2]->alpha());
-
- colors[1].r = (short)(255.0f * svRep[0]->color()[0]);
- colors[1].g = (short)(255.0f * svRep[0]->color()[1]);
- colors[1].b = (short)(255.0f * svRep[0]->color()[2]);
- colors[1].a = (short)(255.0f * svRep[0]->alpha());
-
- colors[2].r = (short)(255.0f * svRep[1]->color()[0]);
- colors[2].g = (short)(255.0f * svRep[1]->color()[1]);
- colors[2].b = (short)(255.0f * svRep[1]->color()[2]);
- colors[2].a = (short)(255.0f * svRep[1]->alpha());
+ linearrgb_to_srgb_uchar4(&colors[0].r, rgba[2]);
+ linearrgb_to_srgb_uchar4(&colors[1].r, rgba[0]);
+ linearrgb_to_srgb_uchar4(&colors[2].r, rgba[1]);
}
else {
- colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
- colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
- colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
- colors[0].a = (short)(255.0f * svRep[2]->alpha());
-
- colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
- colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
- colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
- colors[1].a = (short)(255.0f * svRep[1]->alpha());
-
- colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
- colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
- colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
- colors[2].a = (short)(255.0f * svRep[0]->alpha());
+ linearrgb_to_srgb_uchar4(&colors[0].r, rgba[2]);
+ linearrgb_to_srgb_uchar4(&colors[1].r, rgba[1]);
+ linearrgb_to_srgb_uchar4(&colors[2].r, rgba[0]);
}
transp[0].r = transp[0].g = transp[0].b = colors[0].a;
transp[1].r = transp[1].g = transp[1].b = colors[1].a;
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
index 6e253b7..c07f94c 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
@@ -54,25 +54,6 @@ PyDoc_STRVAR(ChainPredicateIterator_doc,
"predicate is kept as the next one. If none of the potential next\n"
"ViewEdge respects these two predicates, None is returned.\n"
"\n"
-".. method:: __init__(restrict_to_selection=True, restrict_to_unvisited=True, begin=None, orientation=True)\n"
-"\n"
-" Builds a ChainPredicateIterator from a starting ViewEdge and its\n"
-" orientation.\n"
-"\n"
-" :arg restrict_to_selection: Indicates whether to force the chaining\n"
-" to stay within the set of selected ViewEdges or not.\n"
-" :type restrict_to_selection: bool\n"
-" :arg restrict_to_unvisited: Indicates whether a ViewEdge that has\n"
-" already been chained must be ignored ot not.\n"
-" :type restrict_to_unvisited: bool\n"
-" :arg begin: The ViewEdge from where to start the iteration.\n"
-" :type begin: :class:`freestyle.types.ViewEdge` or None\n"
-" :arg orientation: If true, we'll look for the next ViewEdge among\n"
-" the ViewEdges that surround the ending ViewVertex of begin. If\n"
-" false, we'll search over the ViewEdges surrounding the ending\n"
-" ViewVertex of begin. \n"
-" :type orientation: bool\n"
-"\n"
".. method:: __init__(upred, bpred, restrict_to_selection=True, restrict_to_unvisited=True, begin=None, "
"orientation=True)\n"
"\n"
@@ -118,11 +99,14 @@ static int ChainPredicateIterator_init(BPy_ChainPredicateIterator *self, PyObjec
static const char *kwlist_1[] = {"brother", NULL};
static const char *kwlist_2[] = {"upred", "bpred", "restrict_to_selection", "restrict_to_unvisited", "begin",
"orientation", NULL};
- static const char *kwlist_3[] = {"restrict_to_selection", "restrict_to_unvisited", "begin", "orientation", NULL};
PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0, *obj4 = 0, *obj5 = 0, *obj6 = 0;
- if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_1, &ChainingIterator_Type, &obj1)) {
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_1, &ChainPredicateIterator_Type, &obj1)) {
self->cp_it = new ChainPredicateIterator(*(((BPy_ChainPredicateIterator *)obj1)->cp_it));
+ self->upred = ((BPy_ChainPredicateIterator *)obj1)->upred;
+ self->bpred = ((BPy_ChainPredicateIterator *)obj1)->bpred;
+ Py_INCREF(self->upred);
+ Py_INCREF(self->bpred);
}
else if (PyErr_Clear(), (obj3 = obj4 = obj5 = obj6 = 0),
PyArg_ParseTupleAndKeywords(args, kwds, "O!O!|O!O!O&O!", (char **)kwlist_2,
@@ -143,19 +127,6 @@ static int ChainPredicateIterator_init(BPy_ChainPredicateIterator *self, PyObjec
Py_INCREF(self->upred);
Py_INCREF(self->bpred);
}
- else if (PyErr_Clear(), (obj1 = obj2 = obj3 = obj4 = 0),
- PyArg_ParseTupleAndKeywords(args, kwds, "|O!O!O&O!", (char **)kwlist_3,
- &PyBool_Type, &obj1, &PyBool_Type, &obj2, check_begin, &obj3,
- &PyBool_Type, &obj4))
- {
- bool restrict_to_selection = (!obj1) ? true : bool_from_PyBool(obj1);
- bool restrict_to_unvisited = (!obj2) ? true : bool_from_PyBool(obj2);
- ViewEdge *begin = (!obj3 || obj3 == Py_None) ? NULL : ((BPy_ViewEdge *)obj3)->ve;
- bool orientation = (!obj4) ? true : bool_from_PyBool(obj4);
- self->cp_it = new ChainPredicateIterator(restrict_to_selection, restrict_to_unvisited, begin, orientation);
- self->upred = NULL;
- self->bpred = NULL;
- }
else {
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
return -1;
diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
index 84d770a..6cacdfe 100644
--- a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
+++ b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
@@ -191,6 +191,8 @@ int ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait)
int ChainPredicateIterator::traverse(const AdjacencyIterator& ait)
{
+ if (!_unary_predicate || !_binary_predicate)
+ return -1;
AdjacencyIterator it(ait);
// Iterates over next edges to see if one of them respects the predicate:
while (!it.isEnd()) {
diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp
index 87ba34e..dfb50d9 100644
--- a/source/blender/freestyle/intern/stroke/Operators.cpp
+++ b/source/blender/freestyle/intern/stroke/Operators.cpp
@@ -996,6 +996,8 @@ public:
inline bool operator()(Interface1D *i1, Interface1D *i2)
{
+ if (i1 == i2)
+ return false;
if ((*_pred)(*i1, *i2) < 0)
throw std::runtime_error("comparison failed");
return _pred->result;
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 08ce9c0..e9dcf2d 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -67,32 +67,34 @@ typedef struct DDSData {
*/
/* ibuf->ftype flag, main image types */
+/* Warning: Keep explicit value assignements here, this file is included in areas where not all format defines
+ * are set (e.g. intern/dds only get WITH_DDS, even if TIFF, HDR etc are also defined). See T46524. */
enum eImbTypes {
- IMB_FTYPE_PNG = 1,
- IMB_FTYPE_TGA,
- IMB_FTYPE_JPG,
- IMB_FTYPE_BMP,
- IMB_FTYPE_OPENEXR,
- IMB_FTYPE_IMAGIC,
+ IMB_FTYPE_PNG = 1,
+ IMB_FTYPE_TGA = 2,
+ IMB_FTYPE_JPG = 3,
+ IMB_FTYPE_BMP = 4,
+ IMB_FTYPE_OPENEXR = 5,
+ IMB_FTYPE_IMAGIC = 6,
#ifdef WITH_OPENIMAGEIO
- IMB_FTYPE_PSD,
+ IMB_FTYPE_PSD = 7,
#endif
#ifdef WITH_OPENJPEG
- IMB_FTYPE_JP2,
+ IMB_FTYPE_JP2 = 8,
#endif
#ifdef WITH_HDR
- IMB_FTYPE_RADHDR,
+ IMB_FTYPE_RADHDR = 9,
#endif
#ifdef WITH_TIFF
- IMB_FTYPE_TIF,
+ IMB_FTYPE_TIF = 10,
#endif
#ifdef WITH_CINEON
- IMB_FTYPE_CINEON,
- IMB_FTYPE_DPX,
+ IMB_FTYPE_CINEON = 11,
+ IMB_FTYPE_DPX = 12,
#endif
#ifdef WITH_DDS
- IMB_FTYPE_DDS,
+ IMB_FTYPE_DDS = 13,
#endif
};
@@ -124,12 +126,6 @@ enum eImbTypes {
#define RAWTGA 1
-#define JPG_STD 0
-#define JPG_VID 1
-#define JPG_JST 2
-#define JPG_MAX 3
-#define JPG_MSK 0x03
-
#ifdef WITH_TIFF
#define TIF_16BIT (1 << 8 )
#endif
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index ff2a976..35c7b63 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -54,12 +54,6 @@
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
-// #define IS_jpg(x) (x->ftype & JPG) // UNUSED
-#define IS_stdjpg(x) ((x->foptions.flag & JPG_MSK) == JPG_STD)
-// #define IS_vidjpg(x) ((x->foptions & JPG_MSK) == JPG_VID) // UNUSED
-#define IS_jstjpg(x) ((x->foptions.flag & JPG_MSK) == JPG_JST)
-#define IS_maxjpg(x) ((x->foptions.flag & JPG_MSK) == JPG_MAX)
-
/* the types are from the jpeg lib */
static void jpeg_error(j_common_ptr cinfo) ATTR_NORETURN;
static void init_source(j_decompress_ptr cinfo);
@@ -70,22 +64,8 @@ static void memory_source(j_decompress_ptr cinfo, const unsigned char *buffer, s
static boolean handle_app1(j_decompress_ptr cinfo);
static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int flags);
-
-/*
- * In principle there are 4 jpeg formats.
- *
- * 1. jpeg - standard printing, u & v at quarter of resolution
- * 2. jvid - standard video, u & v half resolution, frame not interlaced
- *
- * type 3 is unsupported as of jul 05 2000 Frank.
- *
- * 3. jstr - as 2, but written in 2 separate fields
- *
- * 4. jmax - no scaling in the components
- */
-
-static int jpeg_default_quality;
-static int ibuf_foptions;
+static const uchar jpeg_default_quality = 75;
+static uchar ibuf_quality;
int imb_is_a_jpeg(const unsigned char *mem)
{
@@ -254,6 +234,13 @@ static void memory_source(j_decompress_ptr cinfo, const unsigned char *buffer, s
bytes_in_buffer--; \
V += GETJOCTET(*next_input_byte++); )
+struct NeoGeo_Word {
+ uchar pad1;
+ uchar pad2;
+ uchar pad3;
+ uchar quality;
+} ;
+BLI_STATIC_ASSERT(sizeof(struct NeoGeo_Word) == 4, "Must be 4 bytes");
static boolean handle_app1(j_decompress_ptr cinfo)
{
@@ -267,13 +254,19 @@ static boolean handle_app1(j_decompress_ptr cinfo)
length -= 2;
if (length < 16) {
- for (i = 0; i < length; i++) INPUT_BYTE(cinfo, neogeo[i], return false);
+ for (i = 0; i < length; i++) {
+ INPUT_BYTE(cinfo, neogeo[i], return false);
+ }
length = 0;
- if (STREQLEN(neogeo, "NeoGeo", 6)) memcpy(&ibuf_foptions, neogeo + 6, 4);
- ibuf_foptions = BIG_LONG(ibuf_foptions);
+ if (STREQLEN(neogeo, "NeoGeo", 6)) {
+ struct NeoGeo_Word *neogeo_word = (struct NeoGeo_Word *)(neogeo + 6);
+ ibuf_quality = neogeo_word->quality;
+ }
}
INPUT_SYNC(cinfo); /* do before skip_input_data */
- if (length > 0) (*cinfo->src->skip_input_data)(cinfo, length);
+ if (length > 0) {
+ (*cinfo->src->skip_input_data)(cinfo, length);
+ }
return true;
}
@@ -290,7 +283,7 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
char *str, *key, *value;
/* install own app1 handler */
- ibuf_foptions = 0;
+ ibuf_quality = jpeg_default_quality;
jpeg_set_marker_processor(cinfo, 0xe1, handle_app1);
cinfo->dct_method = JDCT_FLOAT;
jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
@@ -304,14 +297,6 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
jpeg_start_decompress(cinfo);
- if (ibuf_foptions == 0) {
- ibuf_foptions = JPG_STD;
- if (cinfo->max_v_samp_factor == 1) {
- if (cinfo->max_h_samp_factor == 1) ibuf_foptions = JPG_MAX;
- else ibuf_foptions = JPG_VID;
- }
- }
-
if (flags & IB_test) {
jpeg_abort_decompress(cinfo);
ibuf = IMB_allocImBuf(x, y, 8 * depth, 0);
@@ -436,7 +421,7 @@ next_stamp_marker:
jpeg_destroy((j_common_ptr) cinfo);
if (ibuf) {
ibuf->ftype = IMB_FTYPE_JPG;
- ibuf->foptions.flag = ibuf_foptions;
+ ibuf->foptions.quality = MIN2(ibuf_quality, 100);
}
}
@@ -481,16 +466,16 @@ static void write_jpeg(struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf)
uchar *rect;
int x, y;
char neogeo[128];
+ struct NeoGeo_Word *neogeo_word;
char *text;
jpeg_start_compress(cinfo, true);
strcpy(neogeo, "NeoGeo");
- ibuf_foptions = BIG_LONG((((int)ibuf->foptions.flag) << 8) | (int)ibuf->foptions.quality);
-
- memcpy(neogeo + 6, &ibuf_foptions, 4);
+ neogeo_word = (struct NeoGeo_Word *)(neogeo + 6);
+ memset(neogeo_word, 0, sizeof(*neogeo_word));
+ neogeo_word->quality = ibuf->foptions.quality;
jpeg_write_marker(cinfo, 0xe1, (JOCTET *) neogeo, 10);
-
if (ibuf->metadata) {
IDProperty *prop;
/* key + max value + "Blender" */
@@ -613,113 +598,8 @@ static int save_stdjpeg(const char *name, struct ImBuf *ibuf)
struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
struct my_error_mgr jerr;
- if ((outfile = BLI_fopen(name, "wb")) == NULL) return 0;
- jpeg_default_quality = 75;
-
- cinfo->err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = jpeg_error;
-
- /* Establish the setjmp return context for jpeg_error to use. */
- if (setjmp(jerr.setjmp_buffer)) {
- /* If we get here, the JPEG code has signaled an error.
- * We need to clean up the JPEG object, close the input file, and return.
- */
- jpeg_destroy_compress(cinfo);
- fclose(outfile);
- remove(name);
+ if ((outfile = BLI_fopen(name, "wb")) == NULL)
return 0;
- }
-
- init_jpeg(outfile, cinfo, ibuf);
-
- write_jpeg(cinfo, ibuf);
-
- fclose(outfile);
- jpeg_destroy_compress(cinfo);
-
- return 1;
-}
-
-
-static int save_vidjpeg(const char *name, struct ImBuf *ibuf)
-{
- FILE *outfile;
- struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
- struct my_error_mgr jerr;
-
- if ((outfile = BLI_fopen(name, "wb")) == NULL) return 0;
- jpeg_default_quality = 90;
-
- cinfo->err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = jpeg_error;
-
- /* Establish the setjmp return context for jpeg_error to use. */
- if (setjmp(jerr.setjmp_buffer)) {
- /* If we get here, the JPEG code has signaled an error.
- * We need to clean up the JPEG object, close the input file, and return.
- */
- jpeg_destroy_compress(cinfo);
- fclose(outfile);
- remove(name);
- return 0;
- }
-
- init_jpeg(outfile, cinfo, ibuf);
-
- /* adjust scaling factors */
- if (cinfo->in_color_space == JCS_RGB) {
- cinfo->comp_info[0].h_samp_factor = 2;
- cinfo->comp_info[0].v_samp_factor = 1;
- }
-
- write_jpeg(cinfo, ibuf);
-
- fclose(outfile);
- jpeg_destroy_compress(cinfo);
-
- return 1;
-}
-
-static int save_jstjpeg(const char *name, struct ImBuf *ibuf)
-{
- char fieldname[1024];
- struct ImBuf *tbuf;
- int oldy, returnval;
-
- tbuf = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 24, IB_rect);
- tbuf->ftype = ibuf->ftype;
- tbuf->foptions = ibuf->foptions;
- tbuf->flags = ibuf->flags;
-
- oldy = ibuf->y;
- ibuf->x *= 2;
- ibuf->y /= 2;
-
- IMB_rectcpy(tbuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
- sprintf(fieldname, "%s.jf0", name);
-
- returnval = save_vidjpeg(fieldname, tbuf);
- if (returnval == 1) {
- IMB_rectcpy(tbuf, ibuf, 0, 0, tbuf->x, 0, ibuf->x, ibuf->y);
- sprintf(fieldname, "%s.jf1", name);
- returnval = save_vidjpeg(fieldname, tbuf);
- }
-
- ibuf->y = oldy;
- ibuf->x /= 2;
- IMB_freeImBuf(tbuf);
-
- return returnval;
-}
-
-static int save_maxjpeg(const char *name, struct ImBuf *ibuf)
-{
- FILE *outfile;
- struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
- struct my_error_mgr jerr;
-
- if ((outfile = BLI_fopen(name, "wb")) == NULL) return 0;
- jpeg_default_quality = 100;
cinfo->err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = jpeg_error;
@@ -737,12 +617,6 @@ static int save_maxjpeg(const char *name, struct ImBuf *ibuf)
init_jpeg(outfile, cinfo, ibuf);
- /* adjust scaling factors */
- if (cinfo->in_color_space == JCS_RGB) {
- cinfo->comp_info[0].h_samp_factor = 1;
- cinfo->comp_info[0].v_samp_factor = 1;
- }
-
write_jpeg(cinfo, ibuf);
fclose(outfile);
@@ -755,9 +629,5 @@ int imb_savejpeg(struct ImBuf *ibuf, const char *name, int flags)
{
ibuf->flags = flags;
- if (IS_stdjpg(ibuf)) return save_stdjpeg(name, ibuf);
- if (IS_jstjpg(ibuf)) return save_jstjpeg(name, ibuf);
- if (IS_maxjpg(ibuf)) return save_maxjpeg(name, ibuf);
- return save_vidjpeg(name, ibuf);
+ return save_stdjpeg(name, ibuf);
}
-
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index e3c0273..80a4a33 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
+#include <stdexcept>
#include <fstream>
#include <string>
#include <set>
@@ -427,6 +428,14 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *name, const int flags
const size_t offset = view_id * width * height;
RGBAZ *to = pixels + offset;
+ /* TODO (dfelinto)
+ * In some cases we get NULL ibufs, it needs investigation, meanwhile prevent crash
+ * Multiview Render + Image Editor + OpenEXR + Multi-View
+ */
+ if (view_ibuf == NULL) {
+ throw std::runtime_error(std::string("Missing data to write to ") + name);
+ }
+
/* indicate used buffers */
frameBuffer.insert(insertViewName("R", views, view_id), Slice(HALF, (char *) &pixels[offset].r, xstride, ystride));
frameBuffer.insert(insertViewName("G", views, view_id), Slice(HALF, (char *) &pixels[offset].g, xstride, ystride));
@@ -541,6 +550,14 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *name, const int flag
float *rect[4] = {NULL, NULL, NULL, NULL};
ImBuf *view_ibuf = is_multiview ? getbuffer(ibuf->userdata, view_id) : ibuf;
+ /* TODO (dfelinto)
+ * In some cases we get NULL ibufs, it needs investigation, meanwhile prevent crash
+ * Multiview Render + Image Editor + OpenEXR + Multi-View
+ */
+ if (view_ibuf == NULL) {
+ throw std::runtime_error(std::string("Missing data to write to ") + name);
+ }
+
/* last scanline, stride negative */
rect[0] = view_ibuf->rect_float + channels * (height - 1) * width;
rect[1] = (channels >= 2) ? rect[0] + 1 : rect[0];
@@ -1806,8 +1823,15 @@ static void imb_exr_type_by_channels(ChannelList& channels, StringVector& views,
/* will not include empty layer names */
channels.layers(layerNames);
- if (views.size() && views[0] != "")
+ if (views.size() && views[0] != "") {
*r_multiview = true;
+ }
+ else {
+ *r_singlelayer = false;
+ *r_multilayer = true;
+ *r_multiview = false;
+ return;
+ }
if (layerNames.size()) {
/* if layerNames is not empty, it means at least one layer is non-empty,
@@ -1824,7 +1848,7 @@ static void imb_exr_type_by_channels(ChannelList& channels, StringVector& views,
std::string layerName = *i;
size_t pos = layerName.rfind ('.');
- if (pos != std::string::npos) {
+ if (pos == std::string::npos) {
*r_multilayer = true;
*r_singlelayer = false;
return;
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 56a8842..d112790 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -172,8 +172,8 @@ enum {
IMA_IGNORE_ALPHA = (1 << 12),
IMA_DEINTERLACE = (1 << 13),
IMA_USE_VIEWS = (1 << 14),
- IMA_IS_STEREO = (1 << 15),
- IMA_IS_MULTIVIEW = (1 << 16), /* similar to stereo, but a more general case */
+ // IMA_IS_STEREO = (1 << 15), /* deprecated */
+ // IMA_IS_MULTIVIEW = (1 << 16), /* deprecated */
};
/* Image.tpageflag */
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 59e6f28..621807d 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -71,7 +71,7 @@ typedef struct MVert {
* at the moment alpha is abused for vertex painting and not used for transparency, note that red and blue are swapped
*/
typedef struct MCol {
- char a, r, g, b;
+ unsigned char a, r, g, b;
} MCol;
/* new face structure, replaces MFace, which is now only used for storing tessellations.*/
@@ -224,7 +224,7 @@ enum {
* \note red and blue are _not_ swapped, as they are with #MCol
*/
typedef struct MLoopCol {
- char r, g, b, a;
+ unsigned char r, g, b, a;
} MLoopCol;
#define MESH_MLOOPCOL_FROM_MCOL(_mloopcol, _mcol) \
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 6dac2e2..860ed5e 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -412,6 +412,7 @@ static void rna_Constraint_followTrack_camera_set(PointerRNA *ptr, PointerRNA va
if (ob) {
if (ob->type == OB_CAMERA && ob != (Object *)ptr->id.data) {
data->camera = ob;
+ id_lib_extern((ID *)ob);
}
}
else {
@@ -428,6 +429,7 @@ static void rna_Constraint_followTrack_depthObject_set(PointerRNA *ptr, PointerR
if (ob) {
if (ob->type == OB_MESH && ob != (Object *)ptr->id.data) {
data->depth_ob = ob;
+ id_lib_extern((ID *)ob);
}
}
else {
@@ -457,6 +459,7 @@ static void rna_Constraint_objectSolver_camera_set(PointerRNA *ptr, PointerRNA v
if (ob) {
if (ob->type == OB_CAMERA && ob != (Object *)ptr->id.data) {
data->camera = ob;
+ id_lib_extern((ID *)ob);
}
}
else {
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index e1e9fc1..65175e3 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -385,6 +385,7 @@ static void rna_Curve_bevelObject_set(PointerRNA *ptr, PointerRNA value)
/* set as bevobj, there could be infinity loop in displist calculation */
if (ob->type == OB_CURVE && ob->data != cu) {
cu->bevobj = ob;
+ id_lib_extern((ID *)ob);
}
}
else {
@@ -427,6 +428,7 @@ static void rna_Curve_taperObject_set(PointerRNA *ptr, PointerRNA value)
/* set as bevobj, there could be infinity loop in displist calculation */
if (ob->type == OB_CURVE && ob->data != cu) {
cu->taperobj = ob;
+ id_lib_extern((ID *)ob);
}
}
else {
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 561f5c9..2fa2fde 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -78,6 +78,16 @@ static void rna_Image_animated_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
}
}
+static int rna_Image_is_stereo_3d_get(PointerRNA *ptr)
+{
+ return BKE_image_is_stereo((Image *)ptr->data);
+}
+
+static int rna_Image_is_multiview_get(PointerRNA *ptr)
+{
+ return BKE_image_is_multiview((Image *)ptr->data);
+}
+
static int rna_Image_dirty_get(PointerRNA *ptr)
{
return BKE_image_is_dirty((Image *)ptr->data);
@@ -716,12 +726,12 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_views_format_update");
prop = RNA_def_property(srna, "is_stereo_3d", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_IS_STEREO);
+ RNA_def_property_boolean_funcs(prop, "rna_Image_is_stereo_3d_get", NULL);
RNA_def_property_ui_text(prop, "Stereo 3D", "Image has left and right views");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_multiview", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_IS_MULTIVIEW);
+ RNA_def_property_boolean_funcs(prop, "rna_Image_is_multiview_get", NULL);
RNA_def_property_ui_text(prop, "Multiple Views", "Image has more than one view");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 27c4bf0..9bddb6c 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -549,9 +549,11 @@ RNA_MOD_OBJECT_SET(Shrinkwrap, auxTarget, OB_MESH);
static void rna_HookModifier_object_set(PointerRNA *ptr, PointerRNA value)
{
HookModifierData *hmd = ptr->data;
+ Object *ob = (Object *)value.data;
- hmd->object = (Object *)value.data;
- BKE_object_modifier_hook_reset((Object *)ptr->id.data, hmd);
+ hmd->object = ob;
+ id_lib_extern((ID *)ob);
+ BKE_object_modifier_hook_reset(ob, hmd);
}
static PointerRNA rna_UVProjector_object_get(PointerRNA *ptr)
@@ -562,8 +564,10 @@ static PointerRNA rna_UVProjector_object_get(PointerRNA *ptr)
static void rna_UVProjector_object_set(PointerRNA *ptr, PointerRNA value)
{
- Object **ob = (Object **)ptr->data;
- *ob = value.data;
+ Object **ob_p = (Object **)ptr->data;
+ Object *ob = (Object *)value.data;
+ id_lib_extern((ID *)ob);
+ *ob_p = ob;
}
#undef RNA_MOD_OBJECT_SET
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 54f1798..01547e7 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -535,11 +535,14 @@ static void rna_Object_dup_group_set(PointerRNA *ptr, PointerRNA value)
/* must not let this be set if the object belongs in this group already,
* thus causing a cycle/infinite-recursion leading to crashes on load [#25298]
*/
- if (BKE_group_object_exists(grp, ob) == 0)
+ if (BKE_group_object_exists(grp, ob) == 0) {
ob->dup_group = grp;
- else
+ id_lib_extern((ID *)grp);
+ }
+ else {
BKE_report(NULL, RPT_ERROR,
"Cannot set dupli-group as object belongs in group being instanced, thus causing a cycle");
+ }
}
static void rna_VertexGroup_name_set(PointerRNA *ptr, const char *value)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 176c218..4578fae 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -554,6 +554,7 @@ static void rna_Scene_set_set(PointerRNA *ptr, PointerRNA value)
return;
}
+ id_lib_extern((ID *)set);
scene->set = set;
}
@@ -1950,7 +1951,7 @@ static void rna_Stereo3dFormat_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
ImBuf *ibuf;
void *lock;
- if ((ima->flag & IMA_IS_STEREO) == 0)
+ if (!BKE_image_is_stereo(ima))
return;
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index e819d33..e2fa053 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -420,7 +420,7 @@ void RNA_api_wm(StructRNA *srna)
/* Progress bar interface */
func = RNA_def_function(srna, "progress_begin", "rna_progress_begin");
- RNA_def_function_ui_description(func, "Start Progress bar");
+ RNA_def_function_ui_description(func, "Start progress report");
parm = RNA_def_property(func, "min", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(parm, "min", "any value in range [0,9999]");
@@ -436,7 +436,7 @@ void RNA_api_wm(StructRNA *srna)
RNA_def_property_ui_text(parm, "value", "any value between min and max as set in progress_begin()");
func = RNA_def_function(srna, "progress_end", "rna_progress_end");
- RNA_def_function_ui_description(func, "Terminate Progress bar");
+ RNA_def_function_ui_description(func, "Terminate progress report");
/* invoke functions, for use with python */
func = RNA_def_function(srna, "invoke_props_popup", "rna_Operator_props_popup");
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index cbd7bc9..23ab618 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -108,10 +108,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
#ifdef WITH_OPENSUBDIV
const bool allow_gpu = (flag & MOD_APPLY_ALLOW_GPU) != 0;
- const bool do_cddm_convert = useRenderParams || (!isFinalCalc && !smd->use_opensubdiv);
-#else
- const bool do_cddm_convert = useRenderParams || !isFinalCalc;
#endif
+ bool do_cddm_convert = useRenderParams || !isFinalCalc;
if (useRenderParams)
subsurf_flags |= SUBSURF_USE_RENDER_PARAMS;
@@ -134,6 +132,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
else if ((DAG_get_eval_flags_for_object(md->scene, ob) & DAG_EVAL_NEED_CPU) == 0) {
subsurf_flags |= SUBSURF_USE_GPU_BACKEND;
+ do_cddm_convert = false;
}
else {
modifier_setError(md, "OpenSubdiv is disabled due to dependencies");
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index bf06b88..9deb57d 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -352,7 +352,7 @@ static PyObject *py_bvhtree_ray_cast(PyBVHTree *self, PyObject *args)
if (!PyArg_ParseTuple(
args, (char *)"OO|f:ray_cast",
- &py_co, &py_direction, max_dist))
+ &py_co, &py_direction, &max_dist))
{
return NULL;
}
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 0224798..a4ca252 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -415,7 +415,9 @@ static PyObject *M_Geometry_volume_tetrahedron(PyObject *UNUSED(self), PyObject
PyDoc_STRVAR(M_Geometry_intersect_line_line_2d_doc,
".. function:: intersect_line_line_2d(lineA_p1, lineA_p2, lineB_p1, lineB_p2)\n"
"\n"
-" Takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None.\n"
+" Takes 2 segments (defined by 4 vectors) and returns a vector for their point of intersection or None.\n"
+"\n"
+" .. warning:: Despite its name, this function works on segments, and not on lines..."
"\n"
" :arg lineA_p1: First point of the first line\n"
" :type lineA_p1: :class:`mathutils.Vector`\n"
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index 87cdd87..d1dba50 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -86,6 +86,8 @@
#include "render_types.h"
#include "zbuf.h"
+/* Remove when Cycles moves from MFace to MLoopTri */
+#define USE_MFACE_WORKAROUND
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
@@ -352,6 +354,27 @@ static bool cast_ray_highpoly(
return hit_mesh != -1;
}
+#ifdef USE_MFACE_WORKAROUND
+/**
+ * Until cycles moves to #MLoopTri, we need to keep face-rotation in sync with #test_index_face
+ *
+ * We only need to consider quads since #BKE_mesh_recalc_tessellation doesn't execute this on triangles.
+ */
+static void test_index_face_looptri(const MPoly *mp, MLoop *mloop, MLoopTri *lt)
+{
+ if (mp->totloop == 4) {
+ if (UNLIKELY((mloop[mp->loopstart + 2].v == 0) ||
+ (mloop[mp->loopstart + 3].v == 0)))
+ {
+ /* remap: (2, 3, 0, 1) */
+ unsigned int l = mp->loopstart;
+ ARRAY_SET_ITEMS(lt[0].tri, l + 2, l + 3, l + 0);
+ ARRAY_SET_ITEMS(lt[1].tri, l + 2, l + 0, l + 1);
+ }
+ }
+}
+#endif
+
/**
* This function populates an array of verts for the triangles of a mesh
* Tangent and Normals are also stored
@@ -373,6 +396,10 @@ static TriTessFace *mesh_calc_tri_tessface(
unsigned int mpoly_prev = UINT_MAX;
float no[3];
+#ifdef USE_MFACE_WORKAROUND
+ unsigned int mpoly_prev_testindex = UINT_MAX;
+#endif
+
mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
triangles = MEM_mallocN(sizeof(TriTessFace) * tottri, __func__);
@@ -395,8 +422,15 @@ static TriTessFace *mesh_calc_tri_tessface(
looptri);
for (i = 0; i < tottri; i++) {
- MLoopTri *lt = &looptri[i];
- MPoly *mp = &me->mpoly[lt->poly];
+ const MLoopTri *lt = &looptri[i];
+ const MPoly *mp = &me->mpoly[lt->poly];
+
+#ifdef USE_MFACE_WORKAROUND
+ if (lt->poly != mpoly_prev_testindex) {
+ test_index_face_looptri(mp, me->mloop, &looptri[i]);
+ mpoly_prev_testindex = lt->poly;
+ }
+#endif
triangles[i].mverts[0] = &mvert[me->mloop[lt->tri[0]].v];
triangles[i].mverts[1] = &mvert[me->mloop[lt->tri[1]].v];
@@ -586,6 +620,9 @@ void RE_bake_pixels_populate(
const MLoopUV *mloopuv;
const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
MLoopTri *looptri;
+#ifdef USE_MFACE_WORKAROUND
+ unsigned int mpoly_prev_testindex = UINT_MAX;
+#endif
/* we can't bake in edit mode */
if (me->edit_btmesh)
@@ -633,6 +670,13 @@ void RE_bake_pixels_populate(
bd.bk_image = &bake_images->data[image_id];
bd.primitive_id = ++p_id;
+#ifdef USE_MFACE_WORKAROUND
+ if (lt->poly != mpoly_prev_testindex) {
+ test_index_face_looptri(mp, me->mloop, &looptri[i]);
+ mpoly_prev_testindex = lt->poly;
+ }
+#endif
+
for (a = 0; a < 3; a++) {
const float *uv = mloopuv[lt->tri[a]].uv;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 98279da..64e6c14 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2108,9 +2108,10 @@ static void ntree_render_scenes(Render *re)
/* bad call... need to think over proper method still */
static void render_composit_stats(void *UNUSED(arg), const char *str)
{
- R.i.infostr = str;
- R.stats_draw(R.sdh, &R.i);
- R.i.infostr = NULL;
+ RenderStats i;
+ memcpy(&i, &R.i, sizeof(i));
+ i.infostr = str;
+ R.stats_draw(R.sdh, &i);
}
#ifdef WITH_FREESTYLE
@@ -3168,11 +3169,17 @@ void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render
void RE_RenderFreestyleExternal(Render *re)
{
if (!re->test_break(re->tbh)) {
- RE_Database_FromScene(re, re->main, re->scene, re->lay, 1);
- RE_Database_Preprocess(re);
+ RenderView *rv;
+
init_freestyle(re);
- add_freestyle(re, 1);
- RE_Database_Free(re);
+
+ for (rv = re->result->views.first; rv; rv = rv->next) {
+ RE_SetActiveRenderView(re, rv->name);
+ RE_Database_FromScene(re, re->main, re->scene, re->lay, 1);
+ RE_Database_Preprocess(re);
+ add_freestyle(re, 1);
+ RE_Database_Free(re);
+ }
}
}
#endif
@@ -3480,6 +3487,18 @@ static void get_videos_dimensions(Render *re, RenderData *rd, size_t *r_width, s
BKE_scene_multiview_videos_dimensions_get(rd, width, height, r_width, r_height);
}
+static void re_movie_free_all(Render *re, bMovieHandle *mh, size_t totvideos)
+{
+ size_t i;
+
+ for (i = 0; i < totvideos; i++) {
+ mh->end_movie(re->movie_ctx_arr[i]);
+ mh->context_free(re->movie_ctx_arr[i]);
+ }
+
+ MEM_SAFE_FREE(re->movie_ctx_arr);
+}
+
/* saves images to disk */
void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_override,
unsigned int lay_override, int sfra, int efra, int tfra)
@@ -3504,15 +3523,10 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
BKE_report(re->reports, RPT_ERROR, "Frame Server only support stereo output for multiview rendering");
return;
}
-
- /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
- /* is also set by caller renderwin.c */
- G.is_rendering = true;
-
- re->flag |= R_ANIMATION;
if (is_movie) {
size_t i, width, height;
+ bool is_error = false;
get_videos_dimensions(re, &rd, &width, &height);
@@ -3524,11 +3538,25 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
re->movie_ctx_arr[i] = mh->context_create();
- if (!mh->start_movie(re->movie_ctx_arr[i], scene, &re->r, width, height, re->reports, false, suffix))
- G.is_break = true;
+ if (!mh->start_movie(re->movie_ctx_arr[i], scene, &re->r, width, height, re->reports, false, suffix)) {
+ is_error = true;
+ break;
+ }
+ }
+
+ if (is_error) {
+ /* report is handled above */
+ re_movie_free_all(re, mh, i + 1);
+ return;
}
}
+ /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
+ /* is also set by caller renderwin.c */
+ G.is_rendering = true;
+
+ re->flag |= R_ANIMATION;
+
if (mh && mh->get_next_frame) {
/* MULTIVIEW_TODO:
* in case a new video format is added that implements get_next_frame multiview has to be addressed
@@ -3712,15 +3740,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
/* end movie */
if (is_movie) {
- size_t i;
- for (i = 0; i < totvideos; i++) {
- mh->end_movie(re->movie_ctx_arr[i]);
- mh->context_free(re->movie_ctx_arr[i]);
- }
-
- if (re->movie_ctx_arr) {
- MEM_freeN(re->movie_ctx_arr);
- }
+ re_movie_free_all(re, mh, totvideos);
}
if (totskipped && totrendered == 0)
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 5098df2..9d2ca35 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -1783,7 +1783,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
}
/* UV Editor */
else if (STRPREFIX(opname, "UV_OT")) {
- km = WM_keymap_find_all(C, "UV Editor", sl->spacetype, 0);
+ km = WM_keymap_find_all(C, "UV Editor", 0, 0);
}
/* Node Editor */
else if (STRPREFIX(opname, "NODE_OT")) {
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index bf30fd8..64f77e7 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -383,7 +383,6 @@ static void build_pict_list_ex(PlayState *ps, const char *first, int totframes,
// short val;
PlayAnimPict *picture = NULL;
struct ImBuf *ibuf = NULL;
- char str[32 + FILE_MAX];
struct anim *anim;
if (IMB_isanim(first)) {
@@ -402,8 +401,7 @@ static void build_pict_list_ex(PlayState *ps, const char *first, int totframes,
picture->anim = anim;
picture->frame = pic;
picture->IB_flags = IB_rect;
- BLI_snprintf(str, sizeof(str), "%s : %4.d", first, pic + 1);
- picture->name = strdup(str);
+ picture->name = BLI_sprintfN("%s : %4.d", first, pic + 1);
BLI_addtail(&picsbase, picture);
}
}
@@ -414,7 +412,14 @@ static void build_pict_list_ex(PlayState *ps, const char *first, int totframes,
else {
int count = 0;
+ int fp_framenr;
+ struct {
+ char head[FILE_MAX], tail[FILE_MAX];
+ unsigned short digits;
+ } fp_decoded;
+
BLI_strncpy(filepath, first, sizeof(filepath));
+ fp_framenr = BLI_stringdec(filepath, fp_decoded.head, fp_decoded.tail, &fp_decoded.digits);
pupdate_time();
ptottime = 1.0;
@@ -480,8 +485,8 @@ static void build_pict_list_ex(PlayState *ps, const char *first, int totframes,
}
picture->mem = mem;
- picture->name = strdup(filepath);
- picture->frame = count; /* not exact but should work for positioning */
+ picture->name = BLI_strdup(filepath);
+ picture->frame = count;
close(file);
BLI_addtail(&picsbase, picture);
count++;
@@ -505,7 +510,9 @@ static void build_pict_list_ex(PlayState *ps, const char *first, int totframes,
ptottime = 0.0;
}
- BLI_newname(filepath, +fstep);
+ /* create a new filepath each time */
+ fp_framenr += fstep;
+ BLI_stringenc(filepath, fp_decoded.head, fp_decoded.tail, fp_decoded.digits, fp_framenr);
while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0))) {
if (hasevent) {
@@ -544,17 +551,16 @@ static void update_sound_fps(void)
static void change_frame(PlayState *ps, int cx)
{
int sizex, sizey;
- int i;
+ int i, i_last;
- playanim_window_get_size(&sizex, &sizey);
- ps->picture = picsbase.first;
- /* TODO - store in ps direct? */
- i = 0;
- while (ps->picture) {
- i++;
- ps->picture = ps->picture->next;
+ if (BLI_listbase_is_empty(&picsbase)) {
+ return;
}
- i = (i * cx) / sizex;
+
+ playanim_window_get_size(&sizex, &sizey);
+ i_last = ((struct PlayAnimPict *)picsbase.last)->frame;
+ i = (i_last * cx) / sizex;
+ CLAMP(i, 0, i_last);
#ifdef WITH_AUDASPACE
if (scrub_handle) {
@@ -588,11 +594,8 @@ static void change_frame(PlayState *ps, int cx)
}
#endif
- ps->picture = picsbase.first;
- for (; i > 0; i--) {
- if (ps->picture->next == NULL) break;
- ps->picture = ps->picture->next;
- }
+ ps->picture = BLI_findlink(&picsbase, i);
+ BLI_assert(ps->picture != NULL);
ps->sstep = true;
ps->wait2 = false;
@@ -977,6 +980,19 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
GHOST_TEventCursorData *cd = GHOST_GetEventData(evt);
int cx, cy;
+ /* Ignore 'in-between' events, since they can make scrubbing lag.
+ *
+ * Ideally we would keep into the event queue and see if this is the last motion event.
+ * however the API currently doesn't support this. */
+ {
+ int x_test, y_test;
+ GHOST_GetCursorPosition(g_WS.ghost_system, &x_test, &y_test);
+ if (x_test != cd->x || y_test != cd->y) {
+ /* we're not the last event... skipping */
+ break;
+ }
+ }
+
GHOST_ScreenToClient(g_WS.ghost_window, cd->x, cd->y, &cx, &cy);
change_frame(ps, cx);
@@ -1093,7 +1109,6 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
GHOST_TUns32 maxwinx, maxwiny;
int i;
/* This was done to disambiguate the name for use under c++. */
- struct anim *anim = NULL;
int start_x = 0, start_y = 0;
int sfra = -1;
int efra = -1;
@@ -1200,6 +1215,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
if (IMB_isanim(filepath)) {
/* OCIO_TODO: support different input color spaces */
+ struct anim *anim;
anim = IMB_open_anim(filepath, IB_rect, 0, NULL);
if (anim) {
ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
@@ -1471,13 +1487,13 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
}
}
}
- ps.picture = picsbase.first;
- anim = NULL;
- while (ps.picture) {
- if (ps.picture && ps.picture->anim && (anim != ps.picture->anim)) {
- // to prevent divx crashes
- anim = ps.picture->anim;
- IMB_close_anim(anim);
+ while ((ps.picture = BLI_pophead(&picsbase))) {
+ if (ps.picture->anim) {
+ if ((ps.picture->next == NULL) ||
+ (ps.picture->next->anim != ps.picture->anim))
+ {
+ IMB_close_anim(ps.picture->anim);
+ }
}
if (ps.picture->ibuf) {
@@ -1487,7 +1503,8 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
MEM_freeN(ps.picture->mem);
}
- ps.picture = ps.picture->next;
+ MEM_freeN((void *)ps.picture->name);
+ MEM_freeN(ps.picture);
}
/* cleanup */
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 3b36e09..7b62f07 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -421,7 +421,7 @@ void BL_ConvertActuators(const char* maggiename,
soundActuatorType);
// if we made it mono, we have to free it
- if(snd_sound != sound->playback_handle && snd_sound != NULL)
+ if(sound && snd_sound && snd_sound != sound->playback_handle)
AUD_Sound_free(snd_sound);
tmpsoundact->SetName(bact->name);
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
index 12a1cae..d22b9f0 100644
--- a/source/gameengine/Ketsji/BL_Action.cpp
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -56,6 +56,15 @@ extern "C" {
#include "BKE_library.h"
#include "BKE_global.h"
+#include "BLI_threads.h" // for lock
+
+/* Lock to solve animation thread issues.
+ * A spin lock is better than a mutex in case of short wait
+ * because spin lock stop the thread by a loop contrary to mutex
+ * which switch all memory, process.
+ */
+static SpinLock BL_ActionLock;
+
BL_Action::BL_Action(class KX_GameObject* gameobj)
:
m_action(NULL),
@@ -506,15 +515,23 @@ void BL_Action::Update(float curtime)
}
}
- // This isn't thread-safe, so we move it into it's own function for now
- //m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_lock(&BL_ActionLock);
+ /* This function is not thread safe because of recursive scene graph transform
+ * updates on children. e.g: If an object and one of its children is animated,
+ * the both can write transform at the same time. A thread lock avoid problems. */
+ m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_unlock(&BL_ActionLock);
if (m_done)
ClearControllerList();
}
-void BL_Action::UpdateIPOs()
+void BL_Action::InitLock()
+{
+ BLI_spin_init(&BL_ActionLock);
+}
+
+void BL_Action::EndLock()
{
- if (!m_done)
- m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_end(&BL_ActionLock);
}
diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h
index 379dd52..d4f50c1 100644
--- a/source/gameengine/Ketsji/BL_Action.h
+++ b/source/gameengine/Ketsji/BL_Action.h
@@ -105,10 +105,6 @@ public:
* Update the action's frame, etc.
*/
void Update(float curtime);
- /**
- * Update object IPOs (note: not thread-safe!)
- */
- void UpdateIPOs();
// Accessors
float GetFrame();
@@ -144,6 +140,11 @@ public:
ACT_IPOFLAG_CHILD = 8,
};
+ /// Initialize a lock for animation thread issues.
+ static void InitLock();
+ /// Finalize a lock for animation thread issues.
+ static void EndLock();
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_Action")
#endif
diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp
index 9e46905..3aefb36 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.cpp
+++ b/source/gameengine/Ketsji/BL_ActionManager.cpp
@@ -170,13 +170,3 @@ void BL_ActionManager::Update(float curtime)
}
}
}
-
-void BL_ActionManager::UpdateIPOs()
-{
- BL_ActionMap::iterator it;
- for (it = m_layers.begin(); it != m_layers.end(); ++it)
- {
- if (!it->second->IsDone())
- it->second->UpdateIPOs();
- }
-}
diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h
index 97d6d88..599ee28 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.h
+++ b/source/gameengine/Ketsji/BL_ActionManager.h
@@ -129,11 +129,6 @@ public:
*/
void Update(float);
- /**
- * Update object IPOs (note: not thread-safe!)
- */
- void UpdateIPOs();
-
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_ActionManager")
#endif
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index c3da80b..e7ba5ea 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -484,11 +484,6 @@ void KX_GameObject::UpdateActionManager(float curtime)
GetActionManager()->Update(curtime);
}
-void KX_GameObject::UpdateActionIPOs()
-{
- GetActionManager()->UpdateIPOs();
-}
-
float KX_GameObject::GetActionFrame(short layer)
{
return GetActionManager()->GetActionFrame(layer);
@@ -952,6 +947,9 @@ void KX_GameObject::InitIPO(bool ipo_as_force,
void KX_GameObject::UpdateIPO(float curframetime,
bool recurse)
{
+ /* This function shouldn't call BL_Action::Update, not even indirectly,
+ * as it will cause deadlock due to the lock in BL_Action::Update. */
+
// just the 'normal' update procedure.
GetSGNode()->SetSimulatedTime(curframetime,recurse);
GetSGNode()->UpdateWorldData(curframetime);
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index c10802a..a5b6d12 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -321,12 +321,6 @@ public:
*/
void UpdateActionManager(float curtime);
- /**
- * Have the action manager update IPOs
- * note: not thread-safe!
- */
- void UpdateActionIPOs();
-
/*********************************
* End Animation API
*********************************/
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 72c5125..c6e5f73 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -75,6 +75,8 @@
#include "KX_NavMeshObject.h"
+#include "BL_Action.h" // For managing action lock.
+
#define DEFAULT_LOGIC_TIC_RATE 60.0
//#define DEFAULT_PHYSICS_TIC_RATE 60.0
@@ -181,6 +183,8 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
#endif
m_taskscheduler = BLI_task_scheduler_create(TASK_SCHEDULER_AUTO_THREADS);
+
+ BL_Action::InitLock();
}
@@ -200,6 +204,8 @@ KX_KetsjiEngine::~KX_KetsjiEngine()
if (m_taskscheduler)
BLI_task_scheduler_free(m_taskscheduler);
+
+ BL_Action::EndLock();
}
@@ -1019,6 +1025,10 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect
void KX_KetsjiEngine::UpdateAnimations(KX_Scene *scene)
{
+ if (scene->IsSuspended()) {
+ return;
+ }
+
// Handle the animations independently of the logic time step
if (GetRestrictAnimationFPS()) {
double anim_timestep = 1.0 / KX_GetActiveScene()->GetAnimationFPS();
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 7237369..56707bf 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -1678,10 +1678,6 @@ void KX_Scene::UpdateAnimations(double curtime)
BLI_task_pool_work_and_wait(pool);
BLI_task_pool_free(pool);
-
- for (int i=0; i<m_animatedlist->GetCount(); ++i) {
- ((KX_GameObject*)m_animatedlist->GetValue(i))->UpdateActionIPOs();
- }
}
void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index 02b1071..f6f09dd 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -65,7 +65,7 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
KX_SOUNDACT_TYPE type)//,
: SCA_IActuator(gameobj, KX_ACT_SOUND)
{
- m_sound = AUD_Sound_copy(sound);
+ m_sound = sound ? AUD_Sound_copy(sound) : NULL;
m_handle = NULL;
m_volume = volume;
m_pitch = pitch;
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index dbaa925..1076ac5 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -1858,9 +1858,11 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject *meshobj, DerivedMesh *dm,
if (!dm) {
free_dm = true;
dm = CDDM_from_mesh(meshobj->GetMesh());
- DM_ensure_tessface(dm);
}
+ // Some meshes with modifiers returns 0 polys, call DM_ensure_tessface avoid this.
+ DM_ensure_tessface(dm);
+
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getTessFaceArray(dm);
numpolys = dm->getNumTessFaces(dm);
--
blender packaging
More information about the pkg-multimedia-commits
mailing list