diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-01-07 11:56:54 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-01-07 11:56:54 +0400 |
commit | d8e2ed8ae2257c9e301dd85127cab5d6cc2b6a58 (patch) | |
tree | b8402f51476ad78d175411f2ef733816dd7a4fcd | |
parent | 5323a2f18f0e004a2e2cf6d619a6f93456c47f03 (diff) | |
parent | db5682ac8c53377e819fd50357de580c02405fca (diff) |
svn merge ^/trunk/blender -r50999:51100soc-2012-bratwurst
172 files changed, 4531 insertions, 3192 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 984c3e221b7..56968297e1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -575,7 +575,7 @@ if(UNIX AND NOT APPLE) # lame, but until we have propper find module for ffmpeg set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include) if(EXISTS "${FFMPEG}/include/ffmpeg/") - set(FFMPEG_INCLUDE_DIRS "${FFMPEG_INCLUDE_DIRS} ${FFMPEG}/include/ffmpeg") + list(APPEND FFMPEG_INCLUDE_DIRS "${FFMPEG}/include/ffmpeg") endif() # end lameness diff --git a/build_files/package_spec/rpm/blender.spec.in b/build_files/package_spec/rpm/blender.spec.in index 85a689031a3..a95fce80103 100644 --- a/build_files/package_spec/rpm/blender.spec.in +++ b/build_files/package_spec/rpm/blender.spec.in @@ -76,6 +76,7 @@ fi || : %defattr(-,root,root,-) %{_bindir}/%{name} %{_datadir}/%{name}/%{blender_api}/datafiles/fonts +%{_datadir}/%{name}/%{blender_api}/datafiles/colormanagement %{_datadir}/%{name}/%{blender_api}/scripts %{_datadir}/icons/hicolor/*/apps/%{name}.* %{_datadir}/applications/%{name}.desktop diff --git a/doc/manpage/blender.1 b/doc/manpage/blender.1 index c7a762f08c7..e7164fcb96b 100644 --- a/doc/manpage/blender.1 +++ b/doc/manpage/blender.1 @@ -1,4 +1,4 @@ -.TH "BLENDER" "1" "July 19, 2012" "Blender Blender 2\&.63 (sub 14)" +.TH "BLENDER" "1" "October 04, 2012" "Blender Blender 2\&.64 (sub 0)" .SH NAME blender \- a 3D modelling and rendering package @@ -15,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business http://www.blender.org .SH OPTIONS -Blender 2.63 (sub 14) +Blender 2.64 (sub 0) Usage: blender [args ...] [file] [args ...] .br .SS "Render Options:" diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst index 0d1d0df88c3..260a86f7c59 100644 --- a/doc/python_api/rst/bge.logic.rst +++ b/doc/python_api/rst/bge.logic.rst @@ -2,9 +2,9 @@ Game Logic (bge.logic) ====================== -***** -Intro -***** +************ +Introduction +************ Module to access logic functions, imported automatically into the python controllers namespace. diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index 31ae45b9bf0..f4374f7f355 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -4,6 +4,33 @@ Game Types (bge.types) .. module:: bge.types +************ +Introduction +************ + +This module contains the classes that appear as instances in the Game Engine. A +script must interact with these classes if it is to affect the behaviour of +objects in a game. + +The following example would move an object (i.e. an instance of +:class:`KX_GameObject`) one unit up. + +.. code-block:: python + + # bge.types.SCA_PythonController + cont = bge.logic.getCurrentController() + + # bge.types.KX_GameObject + obj = cont.owner + obj.worldPosition.z += 1 + +To run the code, it could be placed in a Blender text block and executed with +a :class:`SCA_PythonController` logic brick. + +***** +Types +***** + .. class:: PyObjectPlus PyObjectPlus base class of most other types in the Game Engine. @@ -854,6 +881,52 @@ Game Types (bge.types) Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, if an object may have been removed since last accessing it use the :data:`invalid` attribute to check. + KX_GameObject can be subclassed to extend functionality. For example: + + .. code-block:: python + + import bge + + class CustomGameObject(bge.types.KX_GameObject): + RATE = 0.05 + + def __init__(self, old_owner): + # "old_owner" can just be ignored. At this point, "self" is + # already the object in the scene, and "old_owner" has been + # destroyed. + + # New attributes can be defined - but we could also use a game + # property, like "self['rate']". + self.rate = CustomGameObject.RATE + + def update(self): + self.worldPosition.z += self.rate + + # switch direction + if self.worldPosition.z > 1.0: + self.rate = -CustomGameObject.RATE + elif self.worldPosition.z < 0.0: + self.rate = CustomGameObject.RATE + + # Called first + def mutate(cont): + old_object = cont.owner + mutated_object = CustomGameObject(cont.owner) + + # After calling the constructor above, references to the old object + # should not be used. + assert(old_object is not mutated_object) + assert(old_object.invalid) + assert(mutated_object is cont.owner) + + # Called later - note we are now working with the mutated object. + def update(cont): + cont.owner.update() + + When subclassing objects other than empties and meshes, the specific type + should be used - e.g. inherit from :class:`BL_ArmatureObject` when the object + to mutate is an armature. + .. attribute:: name The object's name. (read-only). diff --git a/extern/carve/CMakeLists.txt b/extern/carve/CMakeLists.txt index 3916047ff32..5e917ac1e44 100644 --- a/extern/carve/CMakeLists.txt +++ b/extern/carve/CMakeLists.txt @@ -158,7 +158,7 @@ if(WITH_BOOST) -DCARVE_SYSTEM_BOOST ) - list(APPEND INC + list(APPEND INC_SYS ${BOOST_INCLUDE_DIR} ) endif() diff --git a/intern/bsp/CMakeLists.txt b/intern/bsp/CMakeLists.txt index e492c04423e..136c168bdb8 100644 --- a/intern/bsp/CMakeLists.txt +++ b/intern/bsp/CMakeLists.txt @@ -62,7 +62,7 @@ if(WITH_BOOST) -DCARVE_SYSTEM_BOOST ) - list(APPEND INC + list(APPEND INC_SYS ${BOOST_INCLUDE_DIR} ) endif() diff --git a/intern/bsp/intern/BOP_CarveInterface.cpp b/intern/bsp/intern/BOP_CarveInterface.cpp index 255d885007c..1f9c989cbc8 100644 --- a/intern/bsp/intern/BOP_CarveInterface.cpp +++ b/intern/bsp/intern/BOP_CarveInterface.cpp @@ -58,7 +58,7 @@ static bool isQuadPlanar(carve::geom3d::Vector &v1, carve::geom3d::Vector &v2, cross = carve::geom::cross(vec1, vec2); float production = carve::geom::dot(cross, vec3); - float magnitude = 1e-6 * cross.length(); + float magnitude = 1e-5 * cross.length(); return fabs(production) < magnitude; } diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index eb9deb0de2d..e51a6db5791 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -194,8 +194,10 @@ void BlenderSync::sync_background_light() /* Object */ -void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag, int motion, int particle_id) +void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, int particle_id) { + BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent); + /* light is handled separately */ if(object_is_light(b_ob)) { if(!motion) @@ -274,6 +276,15 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, object->visibility &= ~PATH_RAY_CAMERA; } + if (b_dupli_ob) { + object->dupli_generated = get_float3(b_dupli_ob.orco()); + object->dupli_uv = get_float2(b_dupli_ob.uv()); + } + else { + object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f); + object->dupli_uv = make_float2(0.0f, 0.0f); + } + object->particle_id = particle_id; object->tag_update(scene); @@ -328,7 +339,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); if(!(b_dup->hide() || dup_hide)) { - sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); + sync_object(*b_ob, b_index, *b_dup, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); } ++b_index; @@ -346,7 +357,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) if(!hide) { /* object itself */ Transform tfm = get_transform(b_ob->matrix_world()); - sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion, 0); + sync_object(*b_ob, 0, PointerRNA_NULL, tfm, ob_layer, motion, 0); } particle_offset += num_particles; diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index ebf8bb45420..b6d5cc623bb 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -490,7 +490,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph break; } case BL::ShaderNode::type_TEX_COORD: { - node = new TextureCoordinateNode(); + BL::ShaderNodeTexCoord b_tex_coord_node(b_node); + TextureCoordinateNode *tex_coord = new TextureCoordinateNode(); + tex_coord->from_dupli = b_tex_coord_node.from_dupli(); + node = tex_coord; break; } case BL::ShaderNode::type_TEX_SKY: { diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 27f6b6ee4ee..ce563087b4a 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -81,7 +81,7 @@ private: void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool object_updated); - void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag, int motion, int particle_id); + void sync_object(BL::Object b_parent, int b_index, BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion, int particle_id); void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm); void sync_background_light(); void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 46fbead9bc1..da8f30ea169 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -36,7 +36,7 @@ struct RenderResult; ID *rna_Object_to_mesh(void *_self, void *reports, void *scene, int apply_modifiers, int settings); void rna_Main_meshes_remove(void *bmain, void *reports, void *mesh); -void rna_Object_create_duplilist(void *ob, void *reports, void *sce); +void rna_Object_create_duplilist(void *ob, void *reports, void *sce, int settings); void rna_Object_free_duplilist(void *ob); void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values); void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values); @@ -84,7 +84,7 @@ static inline void object_remove_mesh(BL::BlendData data, BL::Mesh mesh) static inline void object_create_duplilist(BL::Object self, BL::Scene scene) { - rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data); + rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data, 2); } static inline void object_free_duplilist(BL::Object self) diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 222ade504cc..01da5050c8d 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -23,7 +23,8 @@ enum ObjectTransform { OBJECT_INVERSE_TRANSFORM = 3, OBJECT_PROPERTIES = 6, OBJECT_TRANSFORM_MOTION_PRE = 8, - OBJECT_TRANSFORM_MOTION_POST = 12 + OBJECT_TRANSFORM_MOTION_POST = 12, + OBJECT_DUPLI = 16 }; __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type) @@ -164,6 +165,27 @@ __device_inline uint object_particle_id(KernelGlobals *kg, int object) return __float_as_int(f.w); } +__device_inline float3 object_dupli_generated(KernelGlobals *kg, int object) +{ + if(object == ~0) + return make_float3(0.0f, 0.0f, 0.0f); + + int offset = object*OBJECT_SIZE + OBJECT_DUPLI; + float4 f = kernel_tex_fetch(__objects, offset); + return make_float3(f.x, f.y, f.z); +} + +__device_inline float3 object_dupli_uv(KernelGlobals *kg, int object) +{ + if(object == ~0) + return make_float3(0.0f, 0.0f, 0.0f); + + int offset = object*OBJECT_SIZE + OBJECT_DUPLI; + float4 f = kernel_tex_fetch(__objects, offset + 1); + return make_float3(f.x, f.y, 0.0f); +} + + __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd) { return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index ce21ab994f0..48e271a9f3f 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN /* constants */ -#define OBJECT_SIZE 16 +#define OBJECT_SIZE 18 #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 98ede0e4f60..ea508dcb660 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -139,15 +139,27 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, float sample_weight = fabsf(average(weight)) * albedo; sc.sample_weight = sample_weight; - sc.type = CLOSURE_BSDF_ID; /* scattering flags */ - if (scattering == OSL::Labels::DIFFUSE) + if (scattering == OSL::Labels::DIFFUSE) { sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; - else if (scattering == OSL::Labels::GLOSSY) + sc.type = CLOSURE_BSDF_DIFFUSE_ID; + } + else if (scattering == OSL::Labels::GLOSSY) { sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY; - else + sc.type = CLOSURE_BSDF_GLOSSY_ID; + } + else if (scattering == OSL::Labels::STRAIGHT) { sd->flag |= SD_BSDF; + sc.type = CLOSURE_BSDF_TRANSPARENT_ID; + } + else { + /* todo: we don't actually have a way to determine if + * this closure will reflect/transmit. could add our own + * own scattering flag that do give this info */ + sd->flag |= SD_BSDF; + sc.type = CLOSURE_BSDF_GLOSSY_ID; + } /* add */ sd->closure[sd->num_closure++] = sc; diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index fbaf253177d..6bd8f2ac69c 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -92,6 +92,14 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack data = sd->I; break; } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } } stack_store_float3(stack, out_offset, data); @@ -141,6 +149,14 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa data = sd->I; break; } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } } stack_store_float3(stack, out_offset, data); @@ -193,6 +209,14 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa data = sd->I; break; } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } } stack_store_float3(stack, out_offset, data); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index c82eafc790a..ee423573cdf 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -43,6 +43,7 @@ typedef enum NodeType { NODE_TEX_IMAGE_BOX, NODE_TEX_SKY, NODE_GEOMETRY, + NODE_GEOMETRY_DUPLI, NODE_LIGHT_PATH, NODE_VALUE_F, NODE_VALUE_V, @@ -149,7 +150,9 @@ typedef enum NodeTexCoord { NODE_TEXCO_OBJECT, NODE_TEXCO_CAMERA, NODE_TEXCO_WINDOW, - NODE_TEXCO_REFLECTION + NODE_TEXCO_REFLECTION, + NODE_TEXCO_DUPLI_GENERATED, + NODE_TEXCO_DUPLI_UV } NodeTexCoord; typedef enum NodeMix { @@ -284,16 +287,18 @@ typedef enum ClosureType { CLOSURE_BSDF_DIFFUSE_ID, CLOSURE_BSDF_OREN_NAYAR_ID, + CLOSURE_BSDF_GLOSSY_ID, CLOSURE_BSDF_REFLECTION_ID, CLOSURE_BSDF_MICROFACET_GGX_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_ID, CLOSURE_BSDF_WARD_ID, + CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, CLOSURE_BSDF_WESTIN_SHEEN_ID, + CLOSURE_BSDF_TRANSMISSION_ID, CLOSURE_BSDF_TRANSLUCENT_ID, CLOSURE_BSDF_REFRACTION_ID, CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, - CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, CLOSURE_BSDF_GLASS_ID, @@ -317,8 +322,8 @@ typedef enum ClosureType { /* watch this, being lazy with memory usage */ #define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID) #define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_OREN_NAYAR_ID) -#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_WESTIN_SHEEN_ID) -#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_GLASS_ID) +#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_WESTIN_SHEEN_ID) +#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_GLASS_ID) #define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_ISOTROPIC_ID) #define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID) #define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID) diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index 6b8e3702d03..e75a3b37f3b 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -7,7 +7,6 @@ set(INC ../kernel/osl ../bvh ../util - ${GLEW_INCLUDE_PATH} ) set(INC_SYS ${GLEW_INCLUDE_PATH} diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 20fbfa0cf27..62758128a73 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -181,14 +181,14 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to) assert(from && to); if(to->link) { - fprintf(stderr, "ShaderGraph connect: input already connected.\n"); + fprintf(stderr, "Cycles shader graph connect: input already connected.\n"); return; } if(from->type != to->type) { /* for closures we can't do automatic conversion */ if(from->type == SHADER_SOCKET_CLOSURE || to->type == SHADER_SOCKET_CLOSURE) { - fprintf(stderr, "ShaderGraph connect: can only connect closure to closure " + fprintf(stderr, "Cycles shader graph connect: can only connect closure to closure " "(ShaderNode:%s, ShaderOutput:%s , type:%d -> to ShaderNode:%s, ShaderInput:%s, type:%d).\n", from->parent->name.c_str(), from->name, (int)from->type, to->parent->name.c_str(), to->name, (int)to->type); @@ -363,7 +363,7 @@ void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<b if(on_stack[depnode->id]) { /* break cycle */ disconnect(input); - fprintf(stderr, "ShaderGraph: detected cycle in graph, connection removed.\n"); + fprintf(stderr, "Cycles shader graph: detected cycle in graph, connection removed.\n"); } else if(!visited[depnode->id]) { /* visit dependencies */ diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index eabb97e7238..8173f5d0af2 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1644,6 +1644,8 @@ TextureCoordinateNode::TextureCoordinateNode() add_output("Camera", SHADER_SOCKET_POINT); add_output("Window", SHADER_SOCKET_POINT); add_output("Reflection", SHADER_SOCKET_NORMAL); + + from_dupli = false; } void TextureCoordinateNode::attributes(AttributeRequestSet *attributes) @@ -1681,9 +1683,15 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler) compiler.add_node(geom_node, NODE_GEOM_P, out->stack_offset); } else { - int attr = compiler.attribute(ATTR_STD_GENERATED); - compiler.stack_assign(out); - compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3); + if(from_dupli) { + compiler.stack_assign(out); + compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, out->stack_offset); + } + else { + int attr = compiler.attribute(ATTR_STD_GENERATED); + compiler.stack_assign(out); + compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3); + } } } @@ -1695,9 +1703,15 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler) out = output("UV"); if(!out->links.empty()) { - int attr = compiler.attribute(ATTR_STD_UV); - compiler.stack_assign(out); - compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3); + if(from_dupli) { + int attr = compiler.attribute(ATTR_STD_UV); + compiler.stack_assign(out); + compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3); + } + else { + compiler.stack_assign(out); + compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, out->stack_offset); + } } out = output("Object"); diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 82bead7e41a..e8e584dd8ef 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -284,6 +284,8 @@ class TextureCoordinateNode : public ShaderNode { public: SHADER_NODE_CLASS(TextureCoordinateNode) void attributes(AttributeRequestSet *attributes); + + bool from_dupli; }; class LightPathNode : public ShaderNode { diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 7389b239627..d78a82d589a 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -235,6 +235,10 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene } } + /* dupli object coords */ + objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); + objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); + /* object flag */ if(ob->use_holdout) flag |= SD_HOLDOUT_MASK; diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 88677d79dff..e2c3ad4e071 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -49,6 +49,9 @@ public: bool use_motion; bool use_holdout; + float3 dupli_generated; + float2 dupli_uv; + int particle_id; Object(); diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 844ce01569f..da287a10199 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -274,6 +274,17 @@ void SVMCompiler::stack_clear_users(ShaderNode *node, set<ShaderNode*>& done) foreach(ShaderInput *in, output->links) in->stack_offset = SVM_STACK_INVALID; + + /* unmark any nodes that have no more valid outputs, see [#31806] */ + if(done.find(output->parent) != done.end()) { + all_done = true; + foreach(ShaderOutput *pout, output->parent->outputs) + if(pout->stack_offset != SVM_STACK_INVALID) + all_done = false; + + if(all_done) + done.erase(output->parent); + } } } } diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index 479bbd3ab0a..d46b09cf76a 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -23,40 +23,42 @@ # # ***** END GPL LICENSE BLOCK ***** +set(INC + . + ../guardedalloc + ../../source/blender/blenlib +) + +set(INC_SYS +) + +set(SRC + ocio_capi.cc + fallback_impl.cc + + ocio_capi.h + ocio_impl.h +) + if(WITH_OPENCOLORIO) - set(INC - . + add_definitions( + -DWITH_OCIO + ) + + list(APPEND INC_SYS ${OPENCOLORIO_INCLUDE_DIRS} ) - set(SRC - ocio_capi.cpp - ocio_capi.h + list(APPEND SRC + ocio_impl.cc ) if(WIN32 AND NOT MINGW) - list(APPEND INC + list(APPEND INC_SYS ${BOOST_INCLUDE_DIR} ) endif() -else() - set(INC - . - ../../source/blender/blenlib - ) - - set(SRC - ocio_capi_stub.cpp - ocio_capi.h - ) endif() -set(INC_SYS - ../guardedalloc -) - -add_definitions( -) blender_add_lib(bf_intern_opencolorio "${SRC}" "${INC}" "${INC_SYS}") - diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript index fec07662735..a4d21f3e440 100644 --- a/intern/opencolorio/SConscript +++ b/intern/opencolorio/SConscript @@ -2,18 +2,18 @@ Import('env') -sources = env.Glob('*.cpp') +sources = env.Glob('*.cc') incs = '. ../guardedalloc ../../source/blender/blenlib' +defs = [] if env['WITH_BF_OCIO']: - sources.remove('ocio_capi_stub.cpp') - + defs.append('WITH_OCIO') incs += ' ' + env['BF_OCIO_INC'] if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): incs += ' ' + env['BF_BOOST_INC'] else: - sources.remove('ocio_capi.cpp') + sources.remove('ocio_impl.cc') -env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), [], libtype=['extern','player'], priority=[10, 185]) +env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185]) diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc new file mode 100644 index 00000000000..44c02d1442b --- /dev/null +++ b/intern/opencolorio/fallback_impl.cc @@ -0,0 +1,382 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Brecht van Lommel + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" +#include "BLI_math_color.h" + +#include "ocio_impl.h" + +#define CONFIG_DEFAULT ((OCIO_ConstConfigRcPtr*)1) + +#define PROCESSOR_LINEAR_TO_SRGB ((OCIO_ConstProcessorRcPtr*)1) +#define PROCESSOR_SRGB_TO_LINEAR ((OCIO_ConstProcessorRcPtr*)2) +#define PROCESSOR_UNKNOWN ((OCIO_ConstProcessorRcPtr*)3) + +#define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr*)1) +#define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr*)2) + +typedef struct OCIO_PackedImageDescription { + float *data; + long width; + long height; + long numChannels; + long chanStrideBytes; + long xStrideBytes; + long yStrideBytes; +} OCIO_PackedImageDescription; + +OCIO_ConstConfigRcPtr *FallbackImpl::getCurrentConfig(void) +{ + return CONFIG_DEFAULT; +} + +void FallbackImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *) +{ +} + +OCIO_ConstConfigRcPtr *FallbackImpl::configCreateFromEnv(void) +{ + return CONFIG_DEFAULT; +} + +OCIO_ConstConfigRcPtr *FallbackImpl::configCreateFromFile(const char *) +{ + return CONFIG_DEFAULT; +} + +void FallbackImpl::configRelease(OCIO_ConstConfigRcPtr *) +{ +} + +int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *) +{ + return 2; +} + +const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *, int index) +{ + if (index == 0) + return "Linear"; + else if (index == 1) + return "sRGB"; + + return NULL; +} + +OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *, const char *name) +{ + if (strcmp(name, "scene_linear") == 0) + return COLORSPACE_LINEAR; + else if (strcmp(name, "color_picking") == 0) + return COLORSPACE_SRGB; + else if (strcmp(name, "texture_paint") == 0) + return COLORSPACE_LINEAR; + else if (strcmp(name, "default_byte") == 0) + return COLORSPACE_SRGB; + else if (strcmp(name, "default_float") == 0) + return COLORSPACE_LINEAR; + else if (strcmp(name, "default_sequencer") == 0) + return COLORSPACE_SRGB; + else if (strcmp(name, "Linear") == 0) + return COLORSPACE_LINEAR; + else if (strcmp(name, "sRGB") == 0) + return COLORSPACE_SRGB; + + return NULL; +} + +int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name); + + if (cs == COLORSPACE_LINEAR) + return 0; + else if (cs == COLORSPACE_SRGB) + return 1; + + return -1; +} + +const char *FallbackImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr *) +{ + return "sRGB"; +} + +int FallbackImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr* config) +{ + return 1; +} + +const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr *, int index) +{ + if (index == 0) + return "sRGB"; + + return NULL; +} + +const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *, const char *) +{ + return "Default"; +} + +int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr *, const char *) +{ + return 1; +} + +const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr *, const char *, int index) +{ + if (index == 0) + return "Default"; + + return NULL; +} + +const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *, const char *, const char *) +{ + return "sRGB"; +} + +int FallbackImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) +{ + return 1; +} + +int FallbackImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) +{ + return 0; +} + +void FallbackImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) +{ +} + +OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) +{ + OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName); + OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName); + + if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) + return PROCESSOR_LINEAR_TO_SRGB; + else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) + return PROCESSOR_SRGB_TO_LINEAR; + + return 0; +} + +OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr *, OCIO_ConstTransformRcPtr *tfm) +{ + return (OCIO_ConstProcessorRcPtr*)tfm; +} + +void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + /* OCIO_TODO stride not respected, channels must be 3 or 4 */ + OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img; + int channels = desc->numChannels; + float *pixels = desc->data; + int width = desc->width; + int height = desc->height; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + float *pixel = pixels + channels * (y * width + x); + + if (channels == 4) + processorApplyRGBA(processor, pixel); + else if (channels == 3) + processorApplyRGB(processor, pixel); + } + } +} + +void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + /* OCIO_TODO stride not respected, channels must be 3 or 4 */ + OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img; + int channels = desc->numChannels; + float *pixels = desc->data; + int width = desc->width; + int height = desc->height; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + float *pixel = pixels + channels * (y * width + x); + + if (channels == 4) + processorApplyRGBA_predivide(processor, pixel); + else if (channels == 3) + processorApplyRGB(processor, pixel); + } + } +} + +void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + if (processor == PROCESSOR_LINEAR_TO_SRGB) + linearrgb_to_srgb_v3_v3(pixel, pixel); + else if (processor == PROCESSOR_SRGB_TO_LINEAR) + srgb_to_linearrgb_v3_v3(pixel, pixel); +} + +void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + if (processor == PROCESSOR_LINEAR_TO_SRGB) + linearrgb_to_srgb_v4(pixel, pixel); + else if (processor == PROCESSOR_SRGB_TO_LINEAR) + srgb_to_linearrgb_v4(pixel, pixel); +} + +void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + if (pixel[3] == 1.0f || pixel[3] == 0.0f) { + processorApplyRGBA(processor, pixel); + } + else { + float alpha, inv_alpha; + + alpha = pixel[3]; + inv_alpha = 1.0f / alpha; + + pixel[0] *= inv_alpha; + pixel[1] *= inv_alpha; + pixel[2] *= inv_alpha; + + processorApplyRGBA(processor, pixel); + + pixel[0] *= alpha; + pixel[1] *= alpha; + pixel[2] *= alpha; + } +} + +void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *) +{ +} + +const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) +{ + if (cs == COLORSPACE_LINEAR) + return "Linear"; + else if (cs == COLORSPACE_SRGB) + return "sRGB"; + + return NULL; +} + +const char *FallbackImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *) +{ + return ""; +} + +const char *FallbackImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *) +{ + return ""; +} + +OCIO_DisplayTransformRcPtr *FallbackImpl::createDisplayTransform(void) +{ + return (OCIO_DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB; +} + +void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *, const char *) +{ +} + +void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *, const char *) +{ +} + +void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr *, const char *) +{ +} + +void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *, OCIO_ConstTransformRcPtr *) +{ +} + +void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *, OCIO_ConstTransformRcPtr *) +{ +} + +void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *) +{ +} + +OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) +{ + OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription"); + + desc->data = data; + desc->width = width; + desc->height = height; + desc->numChannels = numChannels; + desc->chanStrideBytes = chanStrideBytes; + desc->xStrideBytes = xStrideBytes; + desc->yStrideBytes = yStrideBytes; + + return (OCIO_PackedImageDesc*)desc; +} + +void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) +{ + MEM_freeN(id); +} + +OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void) +{ + return (OCIO_ExponentTransformRcPtr*)PROCESSOR_UNKNOWN; +} + +void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *, const float *) +{ +} + +void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr *) +{ +} + +OCIO_MatrixTransformRcPtr *FallbackImpl::createMatrixTransform(void) +{ + return (OCIO_MatrixTransformRcPtr*)PROCESSOR_UNKNOWN; +} + +void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *, const float *, const float *) +{ +} + +void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *) +{ +} + +void FallbackImpl::matrixTransformScale(float * , float * , const float *) +{ +} diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc new file mode 100644 index 00000000000..18fa4b7cb1b --- /dev/null +++ b/intern/opencolorio/ocio_capi.cc @@ -0,0 +1,284 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "MEM_guardedalloc.h" + +#include "ocio_impl.h" + +static IOCIOImpl *impl = NULL; + +void OCIO_init(void) +{ +#ifdef WITH_OCIO + impl = new OCIOImpl(); +#else + impl = new FallbackImpl(); +#endif +} + +void OCIO_exit(void) +{ + delete impl; + impl = NULL; +} + +OCIO_ConstConfigRcPtr *OCIO_getCurrentConfig(void) +{ + return impl->getCurrentConfig(); +} + +OCIO_ConstConfigRcPtr *OCIO_configCreateFallback(void) +{ + delete impl; + impl = new FallbackImpl(); + + return impl->getCurrentConfig(); +} + +void OCIO_setCurrentConfig(const OCIO_ConstConfigRcPtr *config) +{ + impl->setCurrentConfig(config); +} + +OCIO_ConstConfigRcPtr *OCIO_configCreateFromEnv(void) +{ + return impl->configCreateFromEnv(); +} + +OCIO_ConstConfigRcPtr *OCIO_configCreateFromFile(const char *filename) +{ + return impl->configCreateFromFile(filename); +} + +void OCIO_configRelease(OCIO_ConstConfigRcPtr *config) +{ + impl->configRelease(config); +} + +int OCIO_configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) +{ + return impl->configGetNumColorSpaces(config); +} + +const char *OCIO_configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) +{ + return impl->configGetColorSpaceNameByIndex(config, index); +} + +OCIO_ConstColorSpaceRcPtr *OCIO_configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + return impl->configGetColorSpace(config, name); +} + +int OCIO_configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + return impl->configGetIndexForColorSpace(config, name); +} + +const char *OCIO_configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) +{ + return impl->configGetDefaultDisplay(config); +} + +int OCIO_configGetNumDisplays(OCIO_ConstConfigRcPtr* config) +{ + return impl->configGetNumDisplays(config); +} + +const char *OCIO_configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) +{ + return impl->configGetDisplay(config, index); +} + +const char *OCIO_configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) +{ + return impl->configGetDefaultView(config, display); +} + +int OCIO_configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) +{ + return impl->configGetNumViews(config, display); +} + +const char *OCIO_configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index) +{ + return impl->configGetView(config, display, index); +} + +const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view) +{ + return impl->configGetDisplayColorSpaceName(config, display, view); +} + +int OCIO_colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceIsInvertible(cs); +} + +int OCIO_colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceIsData(cs); +} + +void OCIO_colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) +{ + impl->colorSpaceRelease(cs); +} + +OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) +{ + return impl->configGetProcessorWithNames(config, srcName, dstName); +} + +OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform) +{ + return impl->configGetProcessor(config, transform); +} + +void OCIO_processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + impl->processorApply(processor, img); +} + +void OCIO_processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + impl->processorApply_predivide(processor, img); +} + +void OCIO_processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + impl->processorApplyRGB(processor, pixel); +} + +void OCIO_processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + impl->processorApplyRGBA(processor, pixel); +} + +void OCIO_processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + impl->processorApplyRGBA_predivide(processor, pixel); +} + +void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *p) +{ + impl->processorRelease(p); +} + +const char *OCIO_colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceGetName(cs); +} + +const char *OCIO_colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceGetDescription(cs); +} + +const char *OCIO_colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) +{ + return impl->colorSpaceGetFamily(cs); +} + +OCIO_DisplayTransformRcPtr *OCIO_createDisplayTransform(void) +{ + return impl->createDisplayTransform(); +} + +void OCIO_displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + impl->displayTransformSetInputColorSpaceName(dt, name); +} + +void OCIO_displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + impl->displayTransformSetDisplay(dt, name); +} + +void OCIO_displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + impl->displayTransformSetView(dt, name); +} + +void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t) +{ + impl->displayTransformSetDisplayCC(dt, t); +} + +void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t) +{ + impl->displayTransformSetLinearCC(dt, t); +} + +void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) +{ + impl->displayTransformRelease(dt); +} + +OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) +{ + return impl->createOCIO_PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); +} + +void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) +{ + impl->OCIO_PackedImageDescRelease(id); +} + +OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void) +{ + return impl->createExponentTransform(); +} + +void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent) +{ + impl->exponentTransformSetValue(et, exponent); +} + +void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) +{ + impl->exponentTransformRelease(et); +} + +OCIO_MatrixTransformRcPtr *OCIO_createMatrixTransform(void) +{ + return impl->createMatrixTransform(); +} + +void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4) +{ + impl->matrixTransformSetValue(mt, m44, offset4); +} + +void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) +{ + impl->matrixTransformRelease(mt); +} + +void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4f) +{ + impl->matrixTransformScale(m44, offset4, scale4f); +} diff --git a/intern/opencolorio/ocio_capi.cpp b/intern/opencolorio/ocio_capi.cpp deleted file mode 100644 index 152b537ab9b..00000000000 --- a/intern/opencolorio/ocio_capi.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2012 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Xavier Thomas - * Lukas Toene, - * Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include <iostream> -#include <string.h> - -#include <OpenColorIO/OpenColorIO.h> - -#include "MEM_guardedalloc.h" - -#define OCIO_CAPI_IMPLEMENTATION -#include "ocio_capi.h" - -#if !defined(WITH_ASSERT_ABORT) -# define OCIO_abort() -#else -# include <stdlib.h> -# define OCIO_abort() abort() -#endif - -#if defined(_MSC_VER) -# define __func__ __FUNCTION__ -#endif - -#define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type() -#define MEM_DELETE(what, type) if(what) { what->~type(); MEM_freeN(what); } (void)0 - -static void OCIO_reportError(const char *err) -{ - std::cerr << "OpenColorIO Error: " << err << std::endl; - - OCIO_abort(); -} - -static void OCIO_reportException(Exception &exception) -{ - OCIO_reportError(exception.what()); -} - -ConstConfigRcPtr *OCIO_getCurrentConfig(void) -{ - ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); - - try { - *config = GetCurrentConfig(); - - if(*config) - return config; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(config, ConstConfigRcPtr); - - return NULL; -} - -ConstConfigRcPtr *OCIO_getDefaultConfig(void) -{ - return NULL; -} - -void OCIO_setCurrentConfig(const ConstConfigRcPtr *config) -{ - try { - SetCurrentConfig(*config); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } -} - -ConstConfigRcPtr *OCIO_configCreateFromEnv(void) -{ - ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); - - try { - *config = Config::CreateFromEnv(); - - if (*config) - return config; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(config, ConstConfigRcPtr); - - return NULL; -} - - -ConstConfigRcPtr *OCIO_configCreateFromFile(const char *filename) -{ - ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); - - try { - *config = Config::CreateFromFile(filename); - - if (*config) - return config; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(config, ConstConfigRcPtr); - - return NULL; -} - -void OCIO_configRelease(ConstConfigRcPtr *config) -{ - MEM_DELETE(config, ConstConfigRcPtr); -} - -int OCIO_configGetNumColorSpaces(ConstConfigRcPtr *config) -{ - try { - return (*config)->getNumColorSpaces(); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return 0; -} - -const char *OCIO_configGetColorSpaceNameByIndex(ConstConfigRcPtr *config, int index) -{ - try { - return (*config)->getColorSpaceNameByIndex(index); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *config, const char *name) -{ - ConstColorSpaceRcPtr *cs = MEM_NEW(ConstColorSpaceRcPtr); - - try { - *cs = (*config)->getColorSpace(name); - - if (*cs) - return cs; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(cs, ConstColorSpaceRcPtr); - - return NULL; -} - -int OCIO_configGetIndexForColorSpace(ConstConfigRcPtr *config, const char *name) -{ - try { - return (*config)->getIndexForColorSpace(name); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return -1; -} - -const char *OCIO_configGetDefaultDisplay(ConstConfigRcPtr *config) -{ - try { - return (*config)->getDefaultDisplay(); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -int OCIO_configGetNumDisplays(ConstConfigRcPtr* config) -{ - try { - return (*config)->getNumDisplays(); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return 0; -} - -const char *OCIO_configGetDisplay(ConstConfigRcPtr *config, int index) -{ - try { - return (*config)->getDisplay(index); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -const char *OCIO_configGetDefaultView(ConstConfigRcPtr *config, const char *display) -{ - try { - return (*config)->getDefaultView(display); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -int OCIO_configGetNumViews(ConstConfigRcPtr *config, const char *display) -{ - try { - return (*config)->getNumViews(display); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return 0; -} - -const char *OCIO_configGetView(ConstConfigRcPtr *config, const char *display, int index) -{ - try { - return (*config)->getView(display, index); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -const char *OCIO_configGetDisplayColorSpaceName(ConstConfigRcPtr *config, const char *display, const char *view) -{ - try { - return (*config)->getDisplayColorSpaceName(display, view); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs) -{ - const char *family = (*cs)->getFamily(); - - if (!strcmp(family, "rrt") || !strcmp(family, "display")) { - /* assume display and rrt transformations are not invertible - * in fact some of them could be, but it doesn't make much sense to allow use them as invertible - */ - return false; - } - - if ((*cs)->isData()) { - /* data color spaces don't have transformation at all */ - return true; - } - - if ((*cs)->getTransform(COLORSPACE_DIR_TO_REFERENCE)) { - /* if there's defined transform to reference space, color space could be converted to scene linear */ - return true; - } - - return true; -} - -int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs) -{ - return ((*cs)->isData()); -} - -void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs) -{ - MEM_DELETE(cs, ConstColorSpaceRcPtr); -} - -ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(ConstConfigRcPtr *config, const char *srcName, const char *dstName) -{ - ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr); - - try { - *p = (*config)->getProcessor(srcName, dstName); - - if (*p) - return p; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(p, ConstProcessorRcPtr); - - return 0; -} - -ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *config, ConstTransformRcPtr *transform) -{ - ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr); - - try { - *p = (*config)->getProcessor(*transform); - - if (*p) - return p; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - MEM_DELETE(p, ConstProcessorRcPtr); - - return NULL; -} - -void OCIO_processorApply(ConstProcessorRcPtr *processor, PackedImageDesc *img) -{ - try { - (*processor)->apply(*img); - } - catch (Exception &exception) { - OCIO_reportException(exception); - } -} - -void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img) -{ - try { - int channels = img->getNumChannels(); - - if (channels == 4) { - float *pixels = img->getData(); - - int width = img->getWidth(); - int height = img->getHeight(); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - float *pixel = pixels + 4 * (y * width + x); - - OCIO_processorApplyRGBA_predivide(processor, pixel); - } - } - } - else { - (*processor)->apply(*img); - } - } - catch (Exception &exception) { - OCIO_reportException(exception); - } -} - -void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel) -{ - (*processor)->applyRGB(pixel); -} - -void OCIO_processorApplyRGBA(ConstProcessorRcPtr *processor, float *pixel) -{ - (*processor)->applyRGBA(pixel); -} - -void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel) -{ - if (pixel[3] == 1.0f || pixel[3] == 0.0f) { - (*processor)->applyRGBA(pixel); - } - else { - float alpha, inv_alpha; - - alpha = pixel[3]; - inv_alpha = 1.0f / alpha; - - pixel[0] *= inv_alpha; - pixel[1] *= inv_alpha; - pixel[2] *= inv_alpha; - - (*processor)->applyRGBA(pixel); - - pixel[0] *= alpha; - pixel[1] *= alpha; - pixel[2] *= alpha; - } -} - -void OCIO_processorRelease(ConstProcessorRcPtr *p) -{ - p->~ConstProcessorRcPtr(); - MEM_freeN(p); -} - -const char *OCIO_colorSpaceGetName(ConstColorSpaceRcPtr *cs) -{ - return (*cs)->getName(); -} - -const char *OCIO_colorSpaceGetDescription(ConstColorSpaceRcPtr *cs) -{ - return (*cs)->getDescription(); -} - -const char *OCIO_colorSpaceGetFamily(ConstColorSpaceRcPtr *cs) -{ - return (*cs)->getFamily(); -} - -DisplayTransformRcPtr *OCIO_createDisplayTransform(void) -{ - DisplayTransformRcPtr *dt = MEM_NEW(DisplayTransformRcPtr); - - *dt = DisplayTransform::Create(); - - return dt; -} - -void OCIO_displayTransformSetInputColorSpaceName(DisplayTransformRcPtr *dt, const char *name) -{ - (*dt)->setInputColorSpaceName(name); -} - -void OCIO_displayTransformSetDisplay(DisplayTransformRcPtr *dt, const char *name) -{ - (*dt)->setDisplay(name); -} - -void OCIO_displayTransformSetView(DisplayTransformRcPtr *dt, const char *name) -{ - (*dt)->setView(name); -} - -void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *t) -{ - (*dt)->setDisplayCC(*t); -} - -void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *t) -{ - (*dt)->setLinearCC(*t); -} - -void OCIO_displayTransformRelease(DisplayTransformRcPtr *dt) -{ - MEM_DELETE(dt, DisplayTransformRcPtr); -} - -PackedImageDesc *OCIO_createPackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) -{ - try { - void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__); - PackedImageDesc *id = new(mem) PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); - - return id; - } - catch (Exception &exception) { - OCIO_reportException(exception); - } - - return NULL; -} - -void OCIO_packedImageDescRelease(PackedImageDesc* id) -{ - MEM_DELETE(id, PackedImageDesc); -} - -ExponentTransformRcPtr *OCIO_createExponentTransform(void) -{ - ExponentTransformRcPtr *et = MEM_NEW(ExponentTransformRcPtr); - - *et = ExponentTransform::Create(); - - return et; -} - -void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *et, const float *exponent) -{ - (*et)->setValue(exponent); -} - -void OCIO_exponentTransformRelease(ExponentTransformRcPtr *et) -{ - MEM_DELETE(et, ExponentTransformRcPtr); -} - -MatrixTransformRcPtr *OCIO_createMatrixTransform(void) -{ - MatrixTransformRcPtr *mt = MEM_NEW(MatrixTransformRcPtr); - - *mt = MatrixTransform::Create(); - - return mt; -} - -void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *mt, const float *m44, const float *offset4) -{ - (*mt)->setValue(m44, offset4); -} - -void OCIO_matrixTransformRelease(MatrixTransformRcPtr *mt) -{ - MEM_DELETE(mt, MatrixTransformRcPtr); -} - -void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4f) -{ - MatrixTransform::Scale(m44, offset4, scale4f); -} diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 0218ccfafcd..0ce5f8a1456 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -28,98 +28,94 @@ #ifndef __OCIO_CAPI_H__ #define __OCIO_CAPI_H__ - - #ifdef __cplusplus -using namespace OCIO_NAMESPACE; extern "C" { #endif #define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name - -#ifndef OCIO_CAPI_IMPLEMENTATION - #define OCIO_ROLE_SCENE_LINEAR "scene_linear" - #define OCIO_ROLE_COLOR_PICKING "color_picking" - #define OCIO_ROLE_TEXTURE_PAINT "texture_paint" - #define OCIO_ROLE_DEFAULT_BYTE "default_byte" - #define OCIO_ROLE_DEFAULT_FLOAT "default_float" - #define OCIO_ROLE_DEFAULT_SEQUENCER "default_sequencer" - - OCIO_DECLARE_HANDLE(ConstConfigRcPtr); - OCIO_DECLARE_HANDLE(ConstColorSpaceRcPtr); - OCIO_DECLARE_HANDLE(ConstProcessorRcPtr); - OCIO_DECLARE_HANDLE(ConstContextRcPtr); - OCIO_DECLARE_HANDLE(PackedImageDesc); - OCIO_DECLARE_HANDLE(DisplayTransformRcPtr); - OCIO_DECLARE_HANDLE(ConstTransformRcPtr); - OCIO_DECLARE_HANDLE(ExponentTransformRcPtr); - OCIO_DECLARE_HANDLE(MatrixTransformRcPtr); -#endif - - -ConstConfigRcPtr *OCIO_getCurrentConfig(void); -ConstConfigRcPtr *OCIO_getDefaultConfig(void); -void OCIO_setCurrentConfig(const ConstConfigRcPtr *config); - -ConstConfigRcPtr *OCIO_configCreateFromEnv(void); -ConstConfigRcPtr *OCIO_configCreateFromFile(const char* filename); - -void OCIO_configRelease(ConstConfigRcPtr *config); - -int OCIO_configGetNumColorSpaces(ConstConfigRcPtr *config); -const char *OCIO_configGetColorSpaceNameByIndex(ConstConfigRcPtr *config, int index); -ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *config, const char *name); -int OCIO_configGetIndexForColorSpace(ConstConfigRcPtr *config, const char *name); - -int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs); -int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs); - -void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs); - -const char *OCIO_configGetDefaultDisplay(ConstConfigRcPtr *config); -int OCIO_configGetNumDisplays(ConstConfigRcPtr *config); -const char *OCIO_configGetDisplay(ConstConfigRcPtr *config, int index); -const char *OCIO_configGetDefaultView(ConstConfigRcPtr *config, const char *display); -int OCIO_configGetNumViews(ConstConfigRcPtr *config, const char *display); -const char *OCIO_configGetView(ConstConfigRcPtr *config, const char *display, int index); -const char *OCIO_configGetDisplayColorSpaceName(ConstConfigRcPtr *config, const char *display, const char *view); - -ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(ConstConfigRcPtr *config, const char *srcName, const char *dstName); -ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *config, ConstTransformRcPtr *transform); - -void OCIO_processorApply(ConstProcessorRcPtr *processor, PackedImageDesc *img); -void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img); -void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel); -void OCIO_processorApplyRGBA(ConstProcessorRcPtr *processor, float *pixel); -void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel); - -void OCIO_processorRelease(ConstProcessorRcPtr *p); - -const char *OCIO_colorSpaceGetName(ConstColorSpaceRcPtr *cs); -const char *OCIO_colorSpaceGetDescription(ConstColorSpaceRcPtr *cs); -const char *OCIO_colorSpaceGetFamily(ConstColorSpaceRcPtr *cs); - -DisplayTransformRcPtr *OCIO_createDisplayTransform(void); -void OCIO_displayTransformSetInputColorSpaceName(DisplayTransformRcPtr *dt, const char *name); -void OCIO_displayTransformSetDisplay(DisplayTransformRcPtr *dt, const char *name); -void OCIO_displayTransformSetView(DisplayTransformRcPtr *dt, const char *name); -void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *et); -void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *et); -void OCIO_displayTransformRelease(DisplayTransformRcPtr *dt); - -PackedImageDesc *OCIO_createPackedImageDesc(float *data, long width, long height, long numChannels, +#define OCIO_ROLE_SCENE_LINEAR "scene_linear" +#define OCIO_ROLE_COLOR_PICKING "color_picking" +#define OCIO_ROLE_TEXTURE_PAINT "texture_paint" +#define OCIO_ROLE_DEFAULT_BYTE "default_byte" +#define OCIO_ROLE_DEFAULT_FLOAT "default_float" +#define OCIO_ROLE_DEFAULT_SEQUENCER "default_sequencer" + +OCIO_DECLARE_HANDLE(OCIO_ConstConfigRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ConstColorSpaceRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ConstProcessorRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ConstContextRcPtr); +OCIO_DECLARE_HANDLE(OCIO_PackedImageDesc); +OCIO_DECLARE_HANDLE(OCIO_DisplayTransformRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ConstTransformRcPtr); +OCIO_DECLARE_HANDLE(OCIO_ExponentTransformRcPtr); +OCIO_DECLARE_HANDLE(OCIO_MatrixTransformRcPtr); + +void OCIO_init(void); +void OCIO_exit(void); + +OCIO_ConstConfigRcPtr *OCIO_getCurrentConfig(void); +void OCIO_setCurrentConfig(const OCIO_ConstConfigRcPtr *config); + +OCIO_ConstConfigRcPtr *OCIO_configCreateFromEnv(void); +OCIO_ConstConfigRcPtr *OCIO_configCreateFromFile(const char* filename); +OCIO_ConstConfigRcPtr *OCIO_configCreateFallback(void); + +void OCIO_configRelease(OCIO_ConstConfigRcPtr *config); + +int OCIO_configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config); +const char *OCIO_configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index); +OCIO_ConstColorSpaceRcPtr *OCIO_configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); +int OCIO_configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + +int OCIO_colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs); +int OCIO_colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs); + +void OCIO_colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs); + +const char *OCIO_configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config); +int OCIO_configGetNumDisplays(OCIO_ConstConfigRcPtr *config); +const char *OCIO_configGetDisplay(OCIO_ConstConfigRcPtr *config, int index); +const char *OCIO_configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display); +int OCIO_configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display); +const char *OCIO_configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index); +const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view); + +OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName); +OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform); + +void OCIO_processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); +void OCIO_processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); +void OCIO_processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel); +void OCIO_processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel); +void OCIO_processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel); + +void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *p); + +const char *OCIO_colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs); +const char *OCIO_colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs); +const char *OCIO_colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs); + +OCIO_DisplayTransformRcPtr *OCIO_createDisplayTransform(void); +void OCIO_displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name); +void OCIO_displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name); +void OCIO_displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name); +void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); +void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); +void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt); + +OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, long chanStrideBytes, long xStrideBytes, long yStrideBytes); -void OCIO_packedImageDescRelease(PackedImageDesc *p); +void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); -ExponentTransformRcPtr *OCIO_createExponentTransform(void); -void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *et, const float *exponent); -void OCIO_exponentTransformRelease(ExponentTransformRcPtr *et); +OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void); +void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent); +void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et); -MatrixTransformRcPtr *OCIO_createMatrixTransform(void); -void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *et, const float *m44, const float *offset4); -void OCIO_matrixTransformRelease(MatrixTransformRcPtr *mt); +OCIO_MatrixTransformRcPtr *OCIO_createMatrixTransform(void); +void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *et, const float *m44, const float *offset4); +void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4); @@ -127,4 +123,4 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale } #endif -#endif //OCIO_CAPI_H +#endif /* OCIO_CAPI_H */ diff --git a/intern/opencolorio/ocio_capi_stub.cpp b/intern/opencolorio/ocio_capi_stub.cpp deleted file mode 100644 index 2112b88ad72..00000000000 --- a/intern/opencolorio/ocio_capi_stub.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2012 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Brecht van Lommel - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include <string.h> - -#include "MEM_guardedalloc.h" -#include "BLI_math_color.h" - -namespace OCIO_NAMESPACE {}; - -#include "ocio_capi.h" - -#define CONFIG_DEFAULT ((ConstConfigRcPtr*)1) - -#define PROCESSOR_LINEAR_TO_SRGB ((ConstProcessorRcPtr*)1) -#define PROCESSOR_SRGB_TO_LINEAR ((ConstProcessorRcPtr*)2) -#define PROCESSOR_UNKNOWN ((ConstProcessorRcPtr*)3) - -#define COLORSPACE_LINEAR ((ConstColorSpaceRcPtr*)1) -#define COLORSPACE_SRGB ((ConstColorSpaceRcPtr*)2) - -typedef struct PackedImageDescription { - float *data; - long width; - long height; - long numChannels; - long chanStrideBytes; - long xStrideBytes; - long yStrideBytes; -} PackedImageDescription; - -ConstConfigRcPtr *OCIO_getCurrentConfig(void) -{ - return CONFIG_DEFAULT; -} - -ConstConfigRcPtr *OCIO_getDefaultConfig(void) -{ - return CONFIG_DEFAULT; -} - -void OCIO_setCurrentConfig(const ConstConfigRcPtr *) -{ -} - -ConstConfigRcPtr *OCIO_configCreateFromEnv(void) -{ - return CONFIG_DEFAULT; -} - -ConstConfigRcPtr *OCIO_configCreateFromFile(const char *) -{ - return CONFIG_DEFAULT; -} - -void OCIO_configRelease(ConstConfigRcPtr *) -{ -} - -int OCIO_configGetNumColorSpaces(ConstConfigRcPtr *) -{ - return 2; -} - -const char *OCIO_configGetColorSpaceNameByIndex(ConstConfigRcPtr *, int index) -{ - if (index == 0) - return "Linear"; - else if (index == 1) - return "sRGB"; - - return NULL; -} - -ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *, const char *name) -{ - if (strcmp(name, "scene_linear") == 0) - return COLORSPACE_LINEAR; - else if (strcmp(name, "color_picking") == 0) - return COLORSPACE_SRGB; - else if (strcmp(name, "texture_paint") == 0) - return COLORSPACE_LINEAR; - else if (strcmp(name, "default_byte") == 0) - return COLORSPACE_SRGB; - else if (strcmp(name, "default_float") == 0) - return COLORSPACE_LINEAR; - else if (strcmp(name, "default_sequencer") == 0) - return COLORSPACE_SRGB; - else if (strcmp(name, "Linear") == 0) - return COLORSPACE_LINEAR; - else if (strcmp(name, "sRGB") == 0) - return COLORSPACE_SRGB; - - return NULL; -} - -int OCIO_configGetIndexForColorSpace(ConstConfigRcPtr *config, const char *name) -{ - ConstColorSpaceRcPtr *cs = OCIO_configGetColorSpace(config, name); - - if (cs == COLORSPACE_LINEAR) - return 0; - else if (cs == COLORSPACE_SRGB) - return 1; - - return -1; -} - -const char *OCIO_configGetDefaultDisplay(ConstConfigRcPtr *) -{ - return "sRGB"; -} - -int OCIO_configGetNumDisplays(ConstConfigRcPtr* config) -{ - return 1; -} - -const char *OCIO_configGetDisplay(ConstConfigRcPtr *, int index) -{ - if (index == 0) - return "sRGB"; - - return NULL; -} - -const char *OCIO_configGetDefaultView(ConstConfigRcPtr *, const char *) -{ - return "Default"; -} - -int OCIO_configGetNumViews(ConstConfigRcPtr *, const char *) -{ - return 1; -} - -const char *OCIO_configGetView(ConstConfigRcPtr *, const char *, int index) -{ - if (index == 0) - return "Default"; - - return NULL; -} - -const char *OCIO_configGetDisplayColorSpaceName(ConstConfigRcPtr *, const char *, const char *) -{ - return "sRGB"; -} - -int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs) -{ - return 1; -} - -int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs) -{ - return 0; -} - -void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs) -{ -} - -ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(ConstConfigRcPtr *config, const char *srcName, const char *dstName) -{ - ConstColorSpaceRcPtr *cs_src = OCIO_configGetColorSpace(config, srcName); - ConstColorSpaceRcPtr *cs_dst = OCIO_configGetColorSpace(config, dstName); - - if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) - return PROCESSOR_LINEAR_TO_SRGB; - else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) - return PROCESSOR_SRGB_TO_LINEAR; - - return 0; -} - -ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *, ConstTransformRcPtr *tfm) -{ - return (ConstProcessorRcPtr*)tfm; -} - -void OCIO_processorApply(ConstProcessorRcPtr *processor, PackedImageDesc *img) -{ - /* OCIO_TODO stride not respected, channels must be 3 or 4 */ - PackedImageDescription *desc = (PackedImageDescription*)img; - int channels = desc->numChannels; - float *pixels = desc->data; - int width = desc->width; - int height = desc->height; - int x, y; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - float *pixel = pixels + channels * (y * width + x); - - if (channels == 4) - OCIO_processorApplyRGBA(processor, pixel); - else if (channels == 3) - OCIO_processorApplyRGB(processor, pixel); - } - } -} - -void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img) -{ - /* OCIO_TODO stride not respected, channels must be 3 or 4 */ - PackedImageDescription *desc = (PackedImageDescription*)img; - int channels = desc->numChannels; - float *pixels = desc->data; - int width = desc->width; - int height = desc->height; - int x, y; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - float *pixel = pixels + channels * (y * width + x); - - if (channels == 4) - OCIO_processorApplyRGBA_predivide(processor, pixel); - else if (channels == 3) - OCIO_processorApplyRGB(processor, pixel); - } - } -} - -void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel) -{ - if (processor == PROCESSOR_LINEAR_TO_SRGB) - linearrgb_to_srgb_v3_v3(pixel, pixel); - else if (processor == PROCESSOR_SRGB_TO_LINEAR) - srgb_to_linearrgb_v3_v3(pixel, pixel); -} - -void OCIO_processorApplyRGBA(ConstProcessorRcPtr *processor, float *pixel) -{ - if (processor == PROCESSOR_LINEAR_TO_SRGB) - linearrgb_to_srgb_v4(pixel, pixel); - else if (processor == PROCESSOR_SRGB_TO_LINEAR) - srgb_to_linearrgb_v4(pixel, pixel); -} - -void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel) -{ - if (pixel[3] == 1.0f || pixel[3] == 0.0f) { - OCIO_processorApplyRGBA(processor, pixel); - } - else { - float alpha, inv_alpha; - - alpha = pixel[3]; - inv_alpha = 1.0f / alpha; - - pixel[0] *= inv_alpha; - pixel[1] *= inv_alpha; - pixel[2] *= inv_alpha; - - OCIO_processorApplyRGBA(processor, pixel); - - pixel[0] *= alpha; - pixel[1] *= alpha; - pixel[2] *= alpha; - } -} - -void OCIO_processorRelease(ConstProcessorRcPtr *) -{ -} - -const char *OCIO_colorSpaceGetName(ConstColorSpaceRcPtr *cs) -{ - if (cs == COLORSPACE_LINEAR) - return "Linear"; - else if (cs == COLORSPACE_SRGB) - return "sRGB"; - - return NULL; -} - -const char *OCIO_colorSpaceGetDescription(ConstColorSpaceRcPtr *) -{ - return ""; -} - -const char *OCIO_colorSpaceGetFamily(ConstColorSpaceRcPtr *) -{ - return ""; -} - -DisplayTransformRcPtr *OCIO_createDisplayTransform(void) -{ - return (DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB; -} - -void OCIO_displayTransformSetInputColorSpaceName(DisplayTransformRcPtr *, const char *) -{ -} - -void OCIO_displayTransformSetDisplay(DisplayTransformRcPtr *, const char *) -{ -} - -void OCIO_displayTransformSetView(DisplayTransformRcPtr *, const char *) -{ -} - -void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *, ConstTransformRcPtr *) -{ -} - -void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *, ConstTransformRcPtr *) -{ -} - -void OCIO_displayTransformRelease(DisplayTransformRcPtr *) -{ -} - -PackedImageDesc *OCIO_createPackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) -{ - PackedImageDescription *desc = (PackedImageDescription*)MEM_callocN(sizeof(PackedImageDescription), "PackedImageDescription"); - - desc->data = data; - desc->width = width; - desc->height = height; - desc->numChannels = numChannels; - desc->chanStrideBytes = chanStrideBytes; - desc->xStrideBytes = xStrideBytes; - desc->yStrideBytes = yStrideBytes; - - return (PackedImageDesc*)desc; -} - -void OCIO_packedImageDescRelease(PackedImageDesc* id) -{ - MEM_freeN(id); -} - -ExponentTransformRcPtr *OCIO_createExponentTransform(void) -{ - return (ExponentTransformRcPtr*)PROCESSOR_UNKNOWN; -} - -void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *, const float *) -{ -} - -void OCIO_exponentTransformRelease(ExponentTransformRcPtr *) -{ -} - -MatrixTransformRcPtr *OCIO_createMatrixTransform(void) -{ - return (MatrixTransformRcPtr*)PROCESSOR_UNKNOWN; -} - -void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *, const float *, const float *) -{ -} - -void OCIO_matrixTransformRelease(MatrixTransformRcPtr *) -{ -} - -void OCIO_matrixTransformScale(float * , float * , const float *) -{ -} - diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc new file mode 100644 index 00000000000..49fc44d1e12 --- /dev/null +++ b/intern/opencolorio/ocio_impl.cc @@ -0,0 +1,544 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Xavier Thomas + * Lukas Toene, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <iostream> +#include <string.h> + +#include <OpenColorIO/OpenColorIO.h> + +using namespace OCIO_NAMESPACE; + +#include "MEM_guardedalloc.h" + +#include "ocio_impl.h" + +#if !defined(WITH_ASSERT_ABORT) +# define OCIO_abort() +#else +# include <stdlib.h> +# define OCIO_abort() abort() +#endif + +#if defined(_MSC_VER) +# define __func__ __FUNCTION__ +#endif + +#define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type() +#define MEM_DELETE(what, type) if(what) { (what)->~type(); MEM_freeN(what); } (void)0 + +static void OCIO_reportError(const char *err) +{ + std::cerr << "OpenColorIO Error: " << err << std::endl; + + OCIO_abort(); +} + +static void OCIO_reportException(Exception &exception) +{ + OCIO_reportError(exception.what()); +} + +OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void) +{ + ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); + + try { + *config = GetCurrentConfig(); + + if (*config) + return (OCIO_ConstConfigRcPtr *) config; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(config, ConstConfigRcPtr); + + return NULL; +} + +void OCIOImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *config) +{ + try { + SetCurrentConfig(*(ConstConfigRcPtr *) config); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } +} + +OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void) +{ + ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); + + try { + *config = Config::CreateFromEnv(); + + if (*config) + return (OCIO_ConstConfigRcPtr *) config; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(config, ConstConfigRcPtr); + + return NULL; +} + + +OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename) +{ + ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr); + + try { + *config = Config::CreateFromFile(filename); + + if (*config) + return (OCIO_ConstConfigRcPtr *) config; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(config, ConstConfigRcPtr); + + return NULL; +} + +void OCIOImpl::configRelease(OCIO_ConstConfigRcPtr *config) +{ + MEM_DELETE((ConstConfigRcPtr *) config, ConstConfigRcPtr); +} + +int OCIOImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) +{ + try { + return (*(ConstConfigRcPtr *) config)->getNumColorSpaces(); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return 0; +} + +const char *OCIOImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) +{ + try { + return (*(ConstConfigRcPtr *) config)->getColorSpaceNameByIndex(index); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + ConstColorSpaceRcPtr *cs = MEM_NEW(ConstColorSpaceRcPtr); + + try { + *cs = (*(ConstConfigRcPtr *) config)->getColorSpace(name); + + if (*cs) + return (OCIO_ConstColorSpaceRcPtr *) cs; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(cs, ConstColorSpaceRcPtr); + + return NULL; +} + +int OCIOImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +{ + try { + return (*(ConstConfigRcPtr *) config)->getIndexForColorSpace(name); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return -1; +} + +const char *OCIOImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) +{ + try { + return (*(ConstConfigRcPtr *) config)->getDefaultDisplay(); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +int OCIOImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr* config) +{ + try { + return (*(ConstConfigRcPtr *) config)->getNumDisplays(); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return 0; +} + +const char *OCIOImpl::configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) +{ + try { + return (*(ConstConfigRcPtr *) config)->getDisplay(index); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +const char *OCIOImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) +{ + try { + return (*(ConstConfigRcPtr *) config)->getDefaultView(display); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +int OCIOImpl::configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) +{ + try { + return (*(ConstConfigRcPtr *) config)->getNumViews(display); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return 0; +} + +const char *OCIOImpl::configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index) +{ + try { + return (*(ConstConfigRcPtr *) config)->getView(display, index); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +const char *OCIOImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view) +{ + try { + return (*(ConstConfigRcPtr *) config)->getDisplayColorSpaceName(display, view); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +int OCIOImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs_) +{ + ConstColorSpaceRcPtr *cs = (ConstColorSpaceRcPtr *) cs_; + const char *family = (*cs)->getFamily(); + + if (!strcmp(family, "rrt") || !strcmp(family, "display")) { + /* assume display and rrt transformations are not invertible + * in fact some of them could be, but it doesn't make much sense to allow use them as invertible + */ + return false; + } + + if ((*cs)->isData()) { + /* data color spaces don't have transformation at all */ + return true; + } + + if ((*cs)->getTransform(COLORSPACE_DIR_TO_REFERENCE)) { + /* if there's defined transform to reference space, color space could be converted to scene linear */ + return true; + } + + return true; +} + +int OCIOImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) +{ + return (*(ConstColorSpaceRcPtr *) cs)->isData(); +} + +void OCIOImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) +{ + MEM_DELETE((ConstColorSpaceRcPtr *) cs, ConstColorSpaceRcPtr); +} + +OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) +{ + ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr); + + try { + *p = (*(ConstConfigRcPtr *) config)->getProcessor(srcName, dstName); + + if (*p) + return (OCIO_ConstProcessorRcPtr *) p; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(p, ConstProcessorRcPtr); + + return 0; +} + +OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform) +{ + ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr); + + try { + *p = (*(ConstConfigRcPtr *) config)->getProcessor(*(ConstTransformRcPtr *) transform); + + if (*p) + return (OCIO_ConstProcessorRcPtr *) p; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + MEM_DELETE(p, ConstProcessorRcPtr); + + return NULL; +} + +void OCIOImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +{ + try { + (*(ConstProcessorRcPtr *) processor)->apply(*(PackedImageDesc *) img); + } + catch (Exception &exception) { + OCIO_reportException(exception); + } +} + +void OCIOImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img_) +{ + try { + PackedImageDesc *img = (PackedImageDesc *) img_; + int channels = img->getNumChannels(); + + if (channels == 4) { + float *pixels = img->getData(); + + int width = img->getWidth(); + int height = img->getHeight(); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + float *pixel = pixels + 4 * (y * width + x); + + processorApplyRGBA_predivide(processor, pixel); + } + } + } + else { + (*(ConstProcessorRcPtr *) processor)->apply(*img); + } + } + catch (Exception &exception) { + OCIO_reportException(exception); + } +} + +void OCIOImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + (*(ConstProcessorRcPtr *) processor)->applyRGB(pixel); +} + +void OCIOImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel); +} + +void OCIOImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) +{ + if (pixel[3] == 1.0f || pixel[3] == 0.0f) { + (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel); + } + else { + float alpha, inv_alpha; + + alpha = pixel[3]; + inv_alpha = 1.0f / alpha; + + pixel[0] *= inv_alpha; + pixel[1] *= inv_alpha; + pixel[2] *= inv_alpha; + + (*(ConstProcessorRcPtr *) processor)->applyRGBA(pixel); + + pixel[0] *= alpha; + pixel[1] *= alpha; + pixel[2] *= alpha; + } +} + +void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *p) +{ + p->~OCIO_ConstProcessorRcPtr(); + MEM_freeN(p); +} + +const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) +{ + return (*(ConstColorSpaceRcPtr *) cs)->getName(); +} + +const char *OCIOImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) +{ + return (*(ConstColorSpaceRcPtr *) cs)->getDescription(); +} + +const char *OCIOImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) +{ + return (*(ConstColorSpaceRcPtr *)cs)->getFamily(); +} + +OCIO_DisplayTransformRcPtr *OCIOImpl::createDisplayTransform(void) +{ + DisplayTransformRcPtr *dt = MEM_NEW(DisplayTransformRcPtr); + + *dt = DisplayTransform::Create(); + + return (OCIO_DisplayTransformRcPtr *) dt; +} + +void OCIOImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + (*(DisplayTransformRcPtr *) dt)->setInputColorSpaceName(name); +} + +void OCIOImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + (*(DisplayTransformRcPtr *) dt)->setDisplay(name); +} + +void OCIOImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) +{ + (*(DisplayTransformRcPtr *) dt)->setView(name); +} + +void OCIOImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t) +{ + (*(DisplayTransformRcPtr *) dt)->setDisplayCC(* (ConstTransformRcPtr *) t); +} + +void OCIOImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t) +{ + (*(DisplayTransformRcPtr *) dt)->setLinearCC(*(ConstTransformRcPtr *) t); +} + +void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) +{ + MEM_DELETE((DisplayTransformRcPtr *) dt, DisplayTransformRcPtr); +} + +OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) +{ + try { + void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__); + PackedImageDesc *id = new(mem) PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); + + return (OCIO_PackedImageDesc *) id; + } + catch (Exception &exception) { + OCIO_reportException(exception); + } + + return NULL; +} + +void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) +{ + MEM_DELETE((PackedImageDesc *) id, PackedImageDesc); +} + +OCIO_ExponentTransformRcPtr *OCIOImpl::createExponentTransform(void) +{ + ExponentTransformRcPtr *et = MEM_NEW(ExponentTransformRcPtr); + + *et = ExponentTransform::Create(); + + return (OCIO_ExponentTransformRcPtr *) et; +} + +void OCIOImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent) +{ + (*(ExponentTransformRcPtr *) et)->setValue(exponent); +} + +void OCIOImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) +{ + MEM_DELETE((ExponentTransformRcPtr *) et, ExponentTransformRcPtr); +} + +OCIO_MatrixTransformRcPtr *OCIOImpl::createMatrixTransform(void) +{ + MatrixTransformRcPtr *mt = MEM_NEW(MatrixTransformRcPtr); + + *mt = MatrixTransform::Create(); + + return (OCIO_MatrixTransformRcPtr *) mt; +} + +void OCIOImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const float *m44, const float *offset4) +{ + (*(MatrixTransformRcPtr *) mt)->setValue(m44, offset4); +} + +void OCIOImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) +{ + MEM_DELETE((MatrixTransformRcPtr *) mt, MatrixTransformRcPtr); +} + +void OCIOImpl::matrixTransformScale(float * m44, float * offset4, const float *scale4f) +{ + MatrixTransform::Scale(m44, offset4, scale4f); +} diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h new file mode 100644 index 00000000000..64cf5ec3322 --- /dev/null +++ b/intern/opencolorio/ocio_impl.h @@ -0,0 +1,240 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __OCIO_IMPL_H__ +#define __OCIO_IMPL_H__ + +#include "ocio_capi.h" + +class IOCIOImpl { +public: + virtual ~IOCIOImpl() {}; + + virtual OCIO_ConstConfigRcPtr *getCurrentConfig(void) = 0; + virtual void setCurrentConfig(const OCIO_ConstConfigRcPtr *config) = 0; + + virtual OCIO_ConstConfigRcPtr *configCreateFromEnv(void) = 0; + virtual OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename) = 0; + + virtual void configRelease(OCIO_ConstConfigRcPtr *config) = 0; + + virtual int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) = 0; + virtual const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0; + virtual OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) = 0; + virtual int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) = 0; + + virtual int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) = 0; + virtual int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) = 0; + + virtual void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) = 0; + + virtual const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) = 0; + virtual int configGetNumDisplays(OCIO_ConstConfigRcPtr *config) = 0; + virtual const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) = 0; + virtual const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) = 0; + virtual int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) = 0; + virtual const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index) = 0; + virtual const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view) = 0; + + virtual OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) = 0; + virtual OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform) = 0; + + virtual void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) = 0; + virtual void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) = 0; + virtual void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0; + virtual void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0; + virtual void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0; + + virtual void processorRelease(OCIO_ConstProcessorRcPtr *p) = 0; + + virtual const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) = 0; + virtual const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) = 0; + virtual const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) = 0; + + virtual OCIO_DisplayTransformRcPtr *createDisplayTransform(void) = 0; + virtual void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0; + virtual void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0; + virtual void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0; + virtual void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et) = 0; + virtual void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et) = 0; + virtual void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) = 0; + + virtual OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) = 0; + + virtual void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p) = 0; + + virtual OCIO_ExponentTransformRcPtr *createExponentTransform(void) = 0; + virtual void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent) = 0; + virtual void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) = 0; + + virtual OCIO_MatrixTransformRcPtr *createMatrixTransform(void) = 0; + virtual void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *et, const float *m44, const float *offset4) = 0; + virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0; + + virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0; +}; + +class FallbackImpl : public IOCIOImpl { +public: + FallbackImpl() {}; + + OCIO_ConstConfigRcPtr *getCurrentConfig(void); + void setCurrentConfig(const OCIO_ConstConfigRcPtr *config); + + OCIO_ConstConfigRcPtr *configCreateFromEnv(void); + OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename); + + void configRelease(OCIO_ConstConfigRcPtr *config); + + int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config); + const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index); + OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + + int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs); + int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs); + + void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs); + + const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config); + int configGetNumDisplays(OCIO_ConstConfigRcPtr *config); + const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index); + const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display); + int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display); + const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index); + const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view); + + OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName); + OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform); + + void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); + void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); + void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel); + void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel); + void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel); + + void processorRelease(OCIO_ConstProcessorRcPtr *p); + + const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs); + const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs); + const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs); + + OCIO_DisplayTransformRcPtr *createDisplayTransform(void); + void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); + void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); + void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt); + + OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes); + + void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); + + OCIO_ExponentTransformRcPtr *createExponentTransform(void); + void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent); + void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et); + + OCIO_MatrixTransformRcPtr *createMatrixTransform(void); + void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *et, const float *m44, const float *offset4); + void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); + + void matrixTransformScale(float * m44, float * offset4, const float * scale4); +}; + +#ifdef WITH_OCIO +class OCIOImpl : public IOCIOImpl { +public: + OCIOImpl() {}; + + OCIO_ConstConfigRcPtr *getCurrentConfig(void); + void setCurrentConfig(const OCIO_ConstConfigRcPtr *config); + + OCIO_ConstConfigRcPtr *configCreateFromEnv(void); + OCIO_ConstConfigRcPtr *configCreateFromFile(const char* filename); + + void configRelease(OCIO_ConstConfigRcPtr *config); + + int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config); + const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index); + OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name); + + int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs); + int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs); + + void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs); + + const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config); + int configGetNumDisplays(OCIO_ConstConfigRcPtr *config); + const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index); + const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display); + int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display); + const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index); + const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view); + + OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName); + OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform); + + void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); + void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img); + void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel); + void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel); + void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel); + + void processorRelease(OCIO_ConstProcessorRcPtr *p); + + const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs); + const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs); + const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs); + + OCIO_DisplayTransformRcPtr *createDisplayTransform(void); + void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name); + void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); + void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et); + void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt); + + OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes); + + void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); + + OCIO_ExponentTransformRcPtr *createExponentTransform(void); + void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent); + void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et); + + OCIO_MatrixTransformRcPtr *createMatrixTransform(void); + void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *et, const float *m44, const float *offset4); + void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); + + void matrixTransformScale(float * m44, float * offset4, const float * scale4); +}; +#endif + +#endif /* OCIO_IMPL_H */ diff --git a/intern/opennl/intern/opennl.c b/intern/opennl/intern/opennl.c index 71809cc7480..f9c63e9ecf6 100644 --- a/intern/opennl/intern/opennl.c +++ b/intern/opennl/intern/opennl.c @@ -137,14 +137,14 @@ static void __nl_should_not_have_reached(char* file, int line) { /************************************************************************************/ /* memory management */ -#define __NL_NEW(T) (T*)(calloc(1, sizeof(T))) -#define __NL_NEW_ARRAY(T,NB) (T*)(calloc((NB),sizeof(T))) +#define __NL_NEW(T) (T*)(calloc(1, sizeof(T))) +#define __NL_NEW_ARRAY(T,NB) (T*)(calloc(MAX(NB, 1),sizeof(T))) #define __NL_RENEW_ARRAY(T,x,NB) (T*)(realloc(x,(NB)*sizeof(T))) -#define __NL_DELETE(x) free(x); x = NULL -#define __NL_DELETE_ARRAY(x) free(x); x = NULL +#define __NL_DELETE(x) if(x) free(x); x = NULL +#define __NL_DELETE_ARRAY(x) if(x) free(x); x = NULL -#define __NL_CLEAR(T, x) memset(x, 0, sizeof(T)) -#define __NL_CLEAR_ARRAY(T,x,NB) memset(x, 0, (NB)*sizeof(T)) +#define __NL_CLEAR(T, x) memset(x, 0, sizeof(T)) +#define __NL_CLEAR_ARRAY(T,x,NB) if(NB) memset(x, 0, (NB)*sizeof(T)) /************************************************************************************/ /* Dynamic arrays for sparse row/columns */ @@ -1042,6 +1042,9 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation) NLuint n = context->n; NLuint nnz = __nlSparseMatrixNNZ(M); /* number of non-zero coeffs */ + /*if(n > 10) + n = 10;*/ + /* Compressed Row Storage matrix representation */ NLint *xa = __NL_NEW_ARRAY(NLint, n+1); NLfloat *rhs = __NL_NEW_ARRAY(NLfloat, n); diff --git a/intern/opennl/superlu/get_perm_c.c b/intern/opennl/superlu/get_perm_c.c index 320fe3471f4..59889645988 100644 --- a/intern/opennl/superlu/get_perm_c.c +++ b/intern/opennl/superlu/get_perm_c.c @@ -173,17 +173,19 @@ getata( /* Flag the diagonal so it's not included in the B matrix */ marker[j] = j; - for (i = colptr[j]; i < colptr[j+1]; ++i) { - /* A_kj is nonzero, add pattern of column T_*k to B_*j */ - k = rowind[i]; - for (ti = t_colptr[k]; ti < t_colptr[k+1]; ++ti) { - trow = t_rowind[ti]; - if ( marker[trow] != j ) { - marker[trow] = j; - b_rowind[num_nz++] = trow; + if ( *atanz ) { + for (i = colptr[j]; i < colptr[j+1]; ++i) { + /* A_kj is nonzero, add pattern of column T_*k to B_*j */ + k = rowind[i]; + for (ti = t_colptr[k]; ti < t_colptr[k+1]; ++ti) { + trow = t_rowind[ti]; + if ( marker[trow] != j ) { + marker[trow] = j; + b_rowind[num_nz++] = trow; + } + } + } } - } - } } b_colptr[n] = num_nz; @@ -305,21 +307,23 @@ at_plus_a( marker[j] = j; /* Add pattern of column A_*k to B_*j */ - for (i = colptr[j]; i < colptr[j+1]; ++i) { - k = rowind[i]; - if ( marker[k] != j ) { - marker[k] = j; - (*b_rowind)[num_nz++] = k; - } - } + if (*bnz) { + for (i = colptr[j]; i < colptr[j+1]; ++i) { + k = rowind[i]; + if ( marker[k] != j ) { + marker[k] = j; + (*b_rowind)[num_nz++] = k; + } + } - /* Add pattern of column T_*k to B_*j */ - for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { - k = t_rowind[i]; - if ( marker[k] != j ) { - marker[k] = j; - (*b_rowind)[num_nz++] = k; - } + /* Add pattern of column T_*k to B_*j */ + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + k = t_rowind[i]; + if ( marker[k] != j ) { + marker[k] = j; + (*b_rowind)[num_nz++] = k; + } + } } } (*b_colptr)[n] = num_nz; diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png Binary files differindex 2dab9257905..7f40ead3911 100644 --- a/release/datafiles/splash.png +++ b/release/datafiles/splash.png diff --git a/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py b/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py index 5ee5c71be8b..d28f87cf042 100755 --- a/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py +++ b/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py @@ -34,6 +34,7 @@ import sys import ctypes +import re try: import settings @@ -87,44 +88,64 @@ FRIBIDI_FLAGS_ARABIC = FRIBIDI_FLAG_SHAPE_ARAB_PRES | \ FRIBIDI_FLAG_SHAPE_ARAB_LIGA +MENU_DETECT_REGEX = re.compile("%x\\d+\\|") + + ##### Kernel processing funcs. ##### def protect_format_seq(msg): """ Find some specific escaping/formating sequences (like \", %s, etc., and protect them from any modification! """ +# LRM = "\u200E" +# RLM = "\u200F" LRE = "\u202A" + RLE = "\u202B" PDF = "\u202C" + LRO = "\u202D" + RLO = "\u202E" + uctrl = {LRE, RLE, PDF, LRO, RLO} # Most likely incomplete, but seems to cover current needs. format_codes = set("tslfd") digits = set(".0123456789") + if not msg: + return msg + elif MENU_DETECT_REGEX.search(msg): + # An ugly "menu" message, just force it whole LRE if not yet done. + if msg[0] not in {LRE, LRO}: + msg = LRE + msg + idx = 0 ret = [] ln = len(msg) while idx < ln: dlt = 1 +# # If we find a control char, skip any additional protection! +# if msg[idx] in uctrl: +# ret.append(msg[idx:]) +# break # \" or \' if idx < (ln - 1) and msg[idx] == '\\' and msg[idx + 1] in "\"\'": dlt = 2 - # %x12 - elif idx < (ln - 2) and msg[idx] == '%' and msg[idx + 1] in "x" and \ - msg[idx + 2] in digits: + # %x12| + elif idx < (ln - 2) and msg[idx] == '%' and msg[idx + 1] in "x" and msg[idx + 2] in digits: dlt = 2 - while (idx + dlt + 1) < ln and msg[idx + dlt + 1] in digits: + while (idx + dlt) < ln and msg[idx + dlt] in digits: + dlt += 1 + if (idx + dlt) < ln and msg[idx + dlt] is '|': dlt += 1 # %.4f elif idx < (ln - 3) and msg[idx] == '%' and msg[idx + 1] in digits: dlt = 2 - while (idx + dlt + 1) < ln and msg[idx + dlt + 1] in digits: + while (idx + dlt) < ln and msg[idx + dlt] in digits: dlt += 1 - if (idx + dlt + 1) < ln and msg[idx + dlt + 1] in format_codes: + if (idx + dlt) < ln and msg[idx + dlt] in format_codes: dlt += 1 else: dlt = 1 # %s - elif idx < (ln - 1) and msg[idx] == '%' and \ - msg[idx + 1] in format_codes: + elif idx < (ln - 1) and msg[idx] == '%' and msg[idx + 1] in format_codes: dlt = 2 if dlt > 1: diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml index bfeb3a0175e..fad3aa33db8 100644 --- a/release/scripts/presets/interface_theme/elsyiun.xml +++ b/release/scripts/presets/interface_theme/elsyiun.xml @@ -282,7 +282,7 @@ <ThemeInfo> <space> <ThemeSpaceGeneric header="#3b3b3b" - header_text="#8b8b8b" + header_text="#000000" header_text_hi="#000000" button="#3b3b3b" button_text="#000000" diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index 98bad276109..c5fc3c50f3f 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -189,7 +189,7 @@ class BakeAction(Operator): name="Only Selected", default=True, ) - clear_consraints = BoolProperty( + clear_constraints = BoolProperty( name="Clear Constraints", default=False, ) @@ -212,7 +212,7 @@ class BakeAction(Operator): self.only_selected, 'POSE' in self.bake_types, 'OBJECT' in self.bake_types, - self.clear_consraints, + self.clear_constraints, True, ) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 07d4096632f..21843d80742 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1028,7 +1028,7 @@ class WM_OT_properties_edit(Operator): min = rna_min max = rna_max description = StringProperty( - name="Tip", + name="Tooltip", ) def execute(self, context): diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 2d15c534e9f..8308c7fc425 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -65,10 +65,13 @@ class MotionPathButtonsPanel(): sub.prop(mpath, "frame_start", text="From") sub.prop(mpath, "frame_end", text="To") + sub = col.row(align=True) if bones: - col.operator("pose.paths_update", text="Update Paths", icon='BONE_DATA') + sub.operator("pose.paths_update", text="Update Paths", icon='BONE_DATA') + sub.operator("pose.paths_clear", text="", icon='X') else: - col.operator("object.paths_update", text="Update Paths", icon='OBJECT_DATA') + sub.operator("object.paths_update", text="Update Paths", icon='OBJECT_DATA') + sub.operator("object.paths_clear", text="", icon='X') else: sub = col.column(align=True) sub.label(text="Nothing to show yet...", icon='ERROR') diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index 3d671a0d1b7..fba7bd8712a 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -212,6 +212,7 @@ class ConstraintButtonsPanel(): def FOLLOW_PATH(self, context, layout, con): self.target_template(layout, con) + layout.operator("constraint.followpath_path_animate", text="Animate Path", icon='ANIM_DATA') split = layout.split() diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 63322ddeecb..1f4a128acad 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -196,7 +196,7 @@ class INFO_MT_mesh_add(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("mesh.primitive_plane_add", icon='MESH_PLANE', text="Plane") layout.operator("mesh.primitive_cube_add", icon='MESH_CUBE', text="Cube") layout.operator("mesh.primitive_circle_add", icon='MESH_CIRCLE', text="Circle") @@ -207,7 +207,7 @@ class INFO_MT_mesh_add(Menu): layout.separator() layout.operator("mesh.primitive_grid_add", icon='MESH_GRID', text="Grid") layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey") - layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS') + layout.operator("mesh.primitive_torus_add", icon='MESH_TORUS', text="Torus") class INFO_MT_curve_add(Menu): @@ -217,7 +217,7 @@ class INFO_MT_curve_add(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("curve.primitive_bezier_curve_add", icon='CURVE_BEZCURVE', text="Bezier") layout.operator("curve.primitive_bezier_circle_add", icon='CURVE_BEZCIRCLE', text="Circle") layout.operator("curve.primitive_nurbs_curve_add", icon='CURVE_NCURVE', text="Nurbs Curve") @@ -225,22 +225,6 @@ class INFO_MT_curve_add(Menu): layout.operator("curve.primitive_nurbs_path_add", icon='CURVE_PATH', text="Path") -class INFO_MT_edit_curve_add(Menu): - bl_idname = "INFO_MT_edit_curve_add" - bl_label = "Add" - - def draw(self, context): - is_surf = context.active_object.type == 'SURFACE' - - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - - if is_surf: - INFO_MT_surface_add.draw(self, context) - else: - INFO_MT_curve_add.draw(self, context) - - class INFO_MT_surface_add(Menu): bl_idname = "INFO_MT_surface_add" bl_label = "Surface" @@ -248,7 +232,7 @@ class INFO_MT_surface_add(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("surface.primitive_nurbs_surface_curve_add", icon='SURFACE_NCURVE', text="NURBS Curve") layout.operator("surface.primitive_nurbs_surface_circle_add", icon='SURFACE_NCIRCLE', text="NURBS Circle") layout.operator("surface.primitive_nurbs_surface_surface_add", icon='SURFACE_NSURFACE', text="NURBS Surface") @@ -257,6 +241,22 @@ class INFO_MT_surface_add(Menu): layout.operator("surface.primitive_nurbs_surface_torus_add", icon='SURFACE_NTORUS', text="NURBS Torus") +class INFO_MT_edit_curve_add(Menu): + bl_idname = "INFO_MT_edit_curve_add" + bl_label = "Add" + + def draw(self, context): + is_surf = context.active_object.type == 'SURFACE' + + layout = self.layout + layout.operator_context = 'EXEC_REGION_WIN' + + if is_surf: + INFO_MT_surface_add.draw(self, context) + else: + INFO_MT_curve_add.draw(self, context) + + class INFO_MT_armature_add(Menu): bl_idname = "INFO_MT_armature_add" bl_label = "Armature" @@ -264,7 +264,7 @@ class INFO_MT_armature_add(Menu): def draw(self, context): layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA') @@ -286,20 +286,18 @@ class INFO_MT_add(Menu): #layout.operator_menu_enum("object.surface_add", "type", text="Surface", icon='OUTLINER_OB_SURFACE') layout.menu("INFO_MT_surface_add", icon='OUTLINER_OB_SURFACE') layout.operator_menu_enum("object.metaball_add", "type", text="Metaball", icon='OUTLINER_OB_META') - layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT') layout.separator() layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE') layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE' - layout.operator("object.add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'EMPTY' + layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY') layout.separator() layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER') layout.separator() layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA') - layout.operator_context = 'EXEC_AREA' layout.operator_menu_enum("object.lamp_add", "type", text="Lamp", icon='OUTLINER_OB_LAMP') layout.separator() @@ -307,7 +305,7 @@ class INFO_MT_add(Menu): layout.separator() if(len(bpy.data.groups) > 10): - layout.operator_context = 'INVOKE_DEFAULT' + layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_EMPTY') else: layout.operator_menu_enum("object.group_instance_add", "group", text="Group Instance", icon='OUTLINER_OB_EMPTY') diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index fa765168604..5e0e96c72ea 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -807,7 +807,8 @@ class VIEW3D_MT_object_animation(Menu): layout = self.layout layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...") - layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframe...") + layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframes...") + layout.operator("anim.keyframe_clear_v3d", text="Clear Keyframes...") layout.operator("anim.keying_set_active_set", text="Change Keying Set...") layout.separator() diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h index 56eabf4bb43..278c45dac52 100644 --- a/source/blender/blenfont/BLF_translation.h +++ b/source/blender/blenfont/BLF_translation.h @@ -97,6 +97,8 @@ const char *BLF_translate_do_tooltip(const char *contex, const char *msgid); /* Default context for operator names/labels. */ #define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator" +/* Audio disambiguation context. */ +#define BLF_I18NCONTEXT_AUDIO "Audio" #endif /* __BLF_TRANSLATION_H__ */ diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index f506c67a36c..11537964e32 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -65,8 +65,8 @@ int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], fl /* ---------------------------------------------------- */ /* Dupli-Geometry */ -struct ListBase *object_duplilist_ex(struct Scene *sce, struct Object *ob, int update); -struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob); +struct ListBase *object_duplilist_ex(struct Scene *sce, struct Object *ob, int update, int for_render); +struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob, int for_render); void free_object_duplilist(struct ListBase *lb); int count_duplilist(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index d750e88ac04..a3f3beefbaf 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -132,6 +132,7 @@ Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan, int rest); /* like EBONE_VISIBLE */ #define PBONE_VISIBLE(arm, bone) (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P)) +#define PBONE_SELECTABLE(arm, bone) (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE)) #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index dd45ab19eb1..56dfdf404f8 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -41,8 +41,8 @@ extern "C" { /* these lines are grep'd, watch out for our not-so-awesome regex * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ -#define BLENDER_VERSION 263 -#define BLENDER_SUBVERSION 22 +#define BLENDER_VERSION 264 +#define BLENDER_SUBVERSION 1 /* 262 was the last editmesh release but its has compatibility code for bmesh data, * so set the minversion to 2.61 */ @@ -51,9 +51,9 @@ extern "C" { /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR a +#define BLENDER_VERSION_CHAR /* alpha/beta/rc/release, docs use this */ -#define BLENDER_VERSION_CYCLE rc +#define BLENDER_VERSION_CYCLE alpha extern char versionstr[]; /* from blender.c */ diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 0c571f62f0e..cecff2d9516 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -64,29 +64,29 @@ typedef struct SeqIterator { int valid; } SeqIterator; -void BKE_seqence_iterator_begin(struct Editing *ed, SeqIterator *iter, int use_pointer); -void BKE_seqence_iterator_next(SeqIterator *iter); -void BKE_seqence_iterator_end(SeqIterator *iter); +void BKE_sequence_iterator_begin(struct Editing *ed, SeqIterator *iter, int use_pointer); +void BKE_sequence_iterator_next(SeqIterator *iter); +void BKE_sequence_iterator_end(SeqIterator *iter); #define SEQP_BEGIN(ed, _seq) \ { \ SeqIterator iter; \ - for (BKE_seqence_iterator_begin(ed, &iter, 1); \ + for (BKE_sequence_iterator_begin(ed, &iter, 1); \ iter.valid; \ - BKE_seqence_iterator_next(&iter)) { \ + BKE_sequence_iterator_next(&iter)) { \ _seq = iter.seq; #define SEQ_BEGIN(ed, _seq) \ { \ SeqIterator iter; \ - for (BKE_seqence_iterator_begin(ed, &iter, 0); \ + for (BKE_sequence_iterator_begin(ed, &iter, 0); \ iter.valid; \ - BKE_seqence_iterator_next(&iter)) { \ + BKE_sequence_iterator_next(&iter)) { \ _seq = iter.seq; #define SEQ_END \ } \ - BKE_seqence_iterator_end(&iter); \ + BKE_sequence_iterator_end(&iter); \ } typedef struct SeqRenderData { @@ -307,7 +307,7 @@ int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char int BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur); void BKE_sequence_invalidate_cache(struct Scene *scene, struct Sequence *seq); -void BKE_sequence_invalidate_deendent(struct Scene *scene, struct Sequence *seq); +void BKE_sequence_invalidate_dependent(struct Scene *scene, struct Sequence *seq); void BKE_sequence_invalidate_cache_for_modifier(struct Scene *scene, struct Sequence *seq); void BKE_sequencer_update_sound_bounds_all(struct Scene *scene); @@ -315,9 +315,9 @@ void BKE_sequencer_update_sound_bounds(struct Scene *scene, struct Sequence *seq void BKE_sequencer_update_muting(struct Editing *ed); void BKE_sequencer_update_sound(struct Scene *scene, struct bSound *sound); -void BKE_seqence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq); +void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq); void BKE_sequence_base_dupli_recursive(struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag); -int BKE_seqence_is_valid_check(struct Sequence *seq); +int BKE_sequence_is_valid_check(struct Sequence *seq); void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 925658b84f4..66df7eccbd0 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -539,6 +539,7 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon) outPose->iksolver = src->iksolver; outPose->ikdata = NULL; outPose->ikparam = MEM_dupallocN(src->ikparam); + outPose->avs = src->avs; for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) { /* TODO: rename this argument... */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index ec15e2ea87f..58d20fff2bc 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -75,7 +75,7 @@ /* forward declarations */ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, - int level, short animated, short update); + int level, short flag); /* ******************************************************************** */ /* Animation Visualization */ @@ -700,7 +700,11 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua /* ******************************************************************** */ /* Dupli-Geometry */ -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short animated) +#define DUPLILIST_DO_UPDATE 1 +#define DUPLILIST_FOR_RENDER 2 +#define DUPLILIST_ANIMATED 4 + +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short flag) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); @@ -712,14 +716,14 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i dob->index = index; dob->particle_index = par_index; dob->type = type; - dob->animated = (type == OB_DUPLIGROUP) && animated; + dob->animated = (type == OB_DUPLIGROUP) && (flag & DUPLILIST_ANIMATED); ob->lay = lay; return dob; } static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, - int level, short animated, short update) + int level, short flag) { DupliObject *dob; Group *group; @@ -735,13 +739,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde /* handles animated groups, and */ /* we need to check update for objects that are not in scene... */ - if (update) { + if (flag & DUPLILIST_DO_UPDATE) { /* note: update is optional because we don't always need object * transformations to be correct. Also fixes bug [#29616]. */ group_handle_recalc_and_update(scene, ob, group); } - animated = animated || group_is_animated(ob, group); + if (group_is_animated(ob, group)) + flag |= DUPLILIST_ANIMATED; for (go = group->gobject.first; go; go = go->next) { /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ @@ -757,7 +762,7 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); } - dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, animated); + dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, flag); /* check the group instance and object layers match, also that the object visible flags are ok. */ if ((dob->origlay & group->layer) == 0 || @@ -772,14 +777,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde if (go->ob->transflag & OB_DUPLI) { copy_m4_m4(dob->ob->obmat, dob->mat); - object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, animated, update); + object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, flag); copy_m4_m4(dob->ob->obmat, dob->omat); } } } } -static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short animated) +static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short flag) { extern int enable_cu_speed; /* object.c */ Object copyob; @@ -827,7 +832,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra); - dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, animated); + dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, flag); copy_m4_m4(dob->omat, copyob.obmat); } } @@ -851,8 +856,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind typedef struct VertexDupliData { ID *id; /* scene or group, for recursive loops */ int level; - short animated; - short update; + short flag; ListBase *lb; float pmat[4][4]; float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */ @@ -896,7 +900,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], origlay = vdd->ob->lay; - dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->animated); + dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->flag); /* restore the original layer so that each dupli will have proper dob->origlay */ vdd->ob->lay = origlay; @@ -908,13 +912,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], float tmpmat[4][4]; copy_m4_m4(tmpmat, vdd->ob->obmat); copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->animated, vdd->update); + object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->flag); copy_m4_m4(vdd->ob->obmat, tmpmat); } } static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { Object *ob, *ob_iter; Mesh *me = par->data; @@ -942,7 +946,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl else dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); - if (G.is_rendering) { + if (flag & DUPLILIST_FOR_RENDER) { vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par); BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0); } @@ -992,8 +996,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl vdd.id = id; vdd.level = level; - vdd.animated = animated; - vdd.update = update; + vdd.flag = flag; vdd.lb = lb; vdd.ob = ob; vdd.scene = scene; @@ -1039,7 +1042,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl } static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { Object *ob, *ob_iter; Base *base = NULL; @@ -1076,8 +1079,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa mloop = dm->getLoopArray(dm); mvert = dm->getVertArray(dm); - if (G.is_rendering) { - + if (flag & DUPLILIST_FOR_RENDER) { orco = (float(*)[3])BKE_mesh_orco_verts_get(par); BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0); mloopuv = me->mloopuv; @@ -1182,8 +1184,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa copy_m4_m4(tmat, obmat); mul_m4_m4m3(obmat, tmat, mat); - dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, animated); - if (G.is_rendering) { + dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, (flag & DUPLILIST_ANIMATED)); + if (flag & DUPLILIST_FOR_RENDER) { w = 1.0f / (float)mp->totloop; if (orco) { @@ -1205,7 +1207,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa float tmpmat[4][4]; copy_m4_m4(tmpmat, ob->obmat); copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, animated, update); + object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, flag); copy_m4_m4(ob->obmat, tmpmat); } } @@ -1226,7 +1228,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa } static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys, - int level, short animated, short update) + int level, short flag) { GroupObject *go; Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL; @@ -1309,7 +1311,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* gather list of objects or single object */ if (part->ren_as == PART_DRAW_GR) { - if (update) { + if (flag & DUPLILIST_DO_UPDATE) { group_handle_recalc_and_update(scene, par, part->dup_group); } @@ -1452,9 +1454,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else copy_m4_m4(mat, tmat); - dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, animated); + dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); copy_m4_m4(dob->omat, obcopylist[b].obmat); - if (G.is_rendering) + if (flag & DUPLILIST_FOR_RENDER) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } @@ -1512,9 +1514,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if (part->draw & PART_DRAW_GLOBAL_OB) add_v3_v3v3(mat[3], mat[3], vec); - dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated); + dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); copy_m4_m4(dob->omat, oldobmat); - if (G.is_rendering) + if (flag & DUPLILIST_FOR_RENDER) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } @@ -1566,7 +1568,7 @@ static Object *find_family_object(Object **obar, char *family, char ch) } -static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short animated) +static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short flag) { Object *ob, *obar[256] = {NULL}; Curve *cu; @@ -1605,7 +1607,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde copy_m4_m4(obmat, par->obmat); copy_v3_v3(obmat[3], vec); - new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, animated); + new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, flag); } } @@ -1615,7 +1617,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde /* ------------- */ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { if ((ob->transflag & OB_DUPLI) == 0) return; @@ -1635,31 +1637,31 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas if (ob->transflag & OB_DUPLIPARTS) { ParticleSystem *psys = ob->particlesystem.first; for (; psys; psys = psys->next) - new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, animated, update); + new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, flag); } else if (ob->transflag & OB_DUPLIVERTS) { if (ob->type == OB_MESH) { - vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update); + vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag); } else if (ob->type == OB_FONT) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - font_duplilist(duplilist, scene, ob, par_index, level + 1, animated); + font_duplilist(duplilist, scene, ob, par_index, level + 1, flag); } } } else if (ob->transflag & OB_DUPLIFACES) { if (ob->type == OB_MESH) - face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update); + face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag); } else if (ob->transflag & OB_DUPLIFRAMES) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - frames_duplilist(duplilist, scene, ob, par_index, level + 1, animated); + frames_duplilist(duplilist, scene, ob, par_index, level + 1, flag); } } else if (ob->transflag & OB_DUPLIGROUP) { DupliObject *dob; - group_duplilist(duplilist, scene, ob, par_index, level + 1, animated, update); /* now recursive */ + group_duplilist(duplilist, scene, ob, par_index, level + 1, flag); /* now recursive */ if (level == 0) { for (dob = duplilist->first; dob; dob = dob->next) @@ -1671,19 +1673,24 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas /* Returns a list of DupliObject * note; group dupli's already set transform matrix. see note in group_duplilist() */ -ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update) +ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render) { ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist"); + int flag = 0; + + if(update) flag |= DUPLILIST_DO_UPDATE; + if(for_render) flag |= DUPLILIST_FOR_RENDER; + duplilist->first = duplilist->last = NULL; - object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, 0, update); + object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag); return duplilist; } /* note: previously updating was always done, this is why it defaults to be on * but there are likely places it can be called without updating */ -ListBase *object_duplilist(Scene *sce, Object *ob) +ListBase *object_duplilist(Scene *sce, Object *ob, int for_render) { - return object_duplilist_ex(sce, ob, TRUE); + return object_duplilist_ex(sce, ob, TRUE, for_render); } diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index b66bd1fd32b..1bd5786debd 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1289,9 +1289,9 @@ void BKE_color_managed_display_settings_copy(ColorManagedDisplaySettings *new_se void BKE_color_managed_view_settings_init(ColorManagedViewSettings *settings) { /* OCIO_TODO: use default view transform here when OCIO is completely integrated - * and proper versioning stuff is added. - * for now use NONE to be compatible with all current files - */ + * and proper versioning stuff is added. + * for now use NONE to be compatible with all current files + */ BLI_strncpy(settings->view_transform, "Default", sizeof(settings->view_transform)); settings->gamma = 1.0f; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 8b287eb2863..e87e3bf352d 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2563,7 +2563,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ *lock_r = re; } - /* this gives active layer, composite or seqence result */ + /* this gives active layer, composite or sequence result */ rect = (unsigned int *)rres.rect32; rectf = rres.rectf; rectz = rres.rectz; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index b2a9e229be9..3107b029c80 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1757,13 +1757,13 @@ void do_versions_ipos_to_animato(Main *main) { /* If we have any empty action actuators, assume they were - converted IPO Actuators using the object IPO */ + * converted IPO Actuators using the object IPO */ bActuator *act; bActionActuator *aa; for (act = ob->actuators.first; act; act = act->next) { /* Any actuators set to ACT_IPO at this point are actually Action Actuators that - need this converted IPO to finish converting the actuator. */ + * need this converted IPO to finish converting the actuator. */ if (act->type == ACT_IPO) { aa = (bActionActuator*)act->data; aa->act = ob->adt->action; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index ade418e409f..8cede4f51a5 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1030,9 +1030,18 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) next = node->next; /* ntreeUserIncrefID inline */ + + /* XXX, this is correct, however when freeing the entire database + * this ends up accessing freed data which isn't properly unlinking + * its self from scene nodes, SO - for now prefer invalid usercounts + * on free rather then bad memory access - Campbell */ +#if 0 if (do_id_user) { id_us_min(node->id); } +#else + (void)do_id_user; +#endif nodeFreeNode(ntree, node); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index e659441abfe..8407c94cf76 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2228,7 +2228,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u Curve *cu = ob->data; /* Use the object bounding box so that modifier output - gets taken into account */ + * gets taken into account */ if (ob->bb) bb = *(ob->bb); else { @@ -2329,7 +2329,7 @@ int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_ma ListBase *lb; DupliObject *dob; - lb = object_duplilist(scene, ob); + lb = object_duplilist(scene, ob, FALSE); for (dob = lb->first; dob; dob = dob->next) { if ((use_hidden == FALSE) && (dob->no_draw != 0)) { /* pass */ @@ -2406,7 +2406,7 @@ void BKE_scene_foreach_display_point( ListBase *lb; DupliObject *dob; - lb = object_duplilist(scene, ob); + lb = object_duplilist(scene, ob, FALSE); for (dob = lb->first; dob; dob = dob->next) { if (dob->no_draw == 0) { BKE_object_foreach_display_point(dob->ob, dob->mat, func_cb, user_data); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 780528f4a0d..e26726c9016 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1030,7 +1030,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup ListBase *lb_dupli_ob; /* don't update the dupli groups, we only wan't their pid's */ - if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE))) { + if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE, FALSE))) { DupliObject *dob; for (dob= lb_dupli_ob->first; dob; dob= dob->next) { if (dob->ob != ob) { /* avoids recursive loops with dupliframes: bug 22988 */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 3a28a4b2455..16a7dde0543 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -744,7 +744,7 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob) * this enters eternal loop because of * makeDispListMBall getting called inside of group_duplilist */ if ((*base)->object->dup_group == NULL) { - duplilist = object_duplilist((*scene), (*base)->object); + duplilist = object_duplilist((*scene), (*base)->object, FALSE); dupob = duplilist->first; diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index eaf3ec384c8..33519483843 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -609,9 +609,9 @@ static void makeGammaTables(float gamma) /* The end of the table should match 1.0 carefully. In order to avoid * rounding errors, we just set this explicitly. The last segment may - * have a different length than the other segments, but our - * interpolation is insensitive to that - */ + * have a different length than the other segments, but our + * interpolation is insensitive to that + */ color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0; gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index bb845400cef..90c3347a1df 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -461,7 +461,7 @@ static void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_point seq_build_array(&ed->seqbase, &array, 0); } -void BKE_seqence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) +void BKE_sequence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) { memset(iter, 0, sizeof(*iter)); seq_array(ed, &iter->array, &iter->tot, use_pointer); @@ -473,7 +473,7 @@ void BKE_seqence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) } } -void BKE_seqence_iterator_next(SeqIterator *iter) +void BKE_sequence_iterator_next(SeqIterator *iter) { if (++iter->cur < iter->tot) iter->seq = iter->array[iter->cur]; @@ -481,7 +481,7 @@ void BKE_seqence_iterator_next(SeqIterator *iter) iter->valid = 0; } -void BKE_seqence_iterator_end(SeqIterator *iter) +void BKE_sequence_iterator_end(SeqIterator *iter) { if (iter->array) MEM_freeN(iter->array); @@ -843,7 +843,7 @@ static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt) return 1; } -void BKE_seqence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq) +void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq) { SeqUniqueInfo sui; char *dot; @@ -3032,10 +3032,27 @@ int BKE_sequence_check_depend(Sequence *seq, Sequence *cur) return TRUE; } +static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase) +{ + Sequence *cur; + + for (cur = seqbase->first; cur; cur = cur->next) { + if (cur == seq) + continue; + + if (BKE_sequence_check_depend(seq, cur)) { + BKE_sequencer_cache_cleanup_sequence(cur); + BKE_sequencer_preprocessed_cache_cleanup_sequence(cur); + } + + if (cur->seqbase.first) + sequence_do_invalidate_dependent(seq, &cur->seqbase); + } +} + static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_self, int invalidate_preprocess) { Editing *ed = scene->ed; - Sequence *cur; /* invalidate cache for current sequence */ if (invalidate_self) @@ -3049,17 +3066,11 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidat BKE_sequencer_preprocessed_cache_cleanup_sequence(seq); /* invalidate cache for all dependent sequences */ - SEQ_BEGIN (ed, cur) - { - if (cur == seq) - continue; - if (BKE_sequence_check_depend(seq, cur)) { - BKE_sequencer_cache_cleanup_sequence(cur); - BKE_sequencer_preprocessed_cache_cleanup_sequence(cur); - } - } - SEQ_END + /* NOTE: can not use SEQ_BEGIN/SEQ_END here because that macro will change sequence's depth, + * which makes transformation routines work incorrect + */ + sequence_do_invalidate_dependent(seq, &ed->seqbase); } void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) @@ -3067,7 +3078,7 @@ void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) sequence_invalidate_cache(scene, seq, TRUE, TRUE); } -void BKE_sequence_invalidate_deendent(Scene *scene, Sequence *seq) +void BKE_sequence_invalidate_dependent(Scene *scene, Sequence *seq) { sequence_invalidate_cache(scene, seq, FALSE, TRUE); } @@ -3872,7 +3883,7 @@ static void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) { if (seq) { BLI_strncpy(seq->name + 2, seq_load->name, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); if (seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) { seq_load->start_frame += (seq->enddisp - seq->startdisp); @@ -3959,10 +3970,10 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad sound = sound_new_file(bmain, seq_load->path); /* handles relative paths */ if (sound == NULL || sound->playback_handle == NULL) { - /* +#if 0 if (op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); - */ +#endif return NULL; } @@ -3971,10 +3982,10 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad if (info.specs.channels == AUD_CHANNELS_INVALID) { sound_delete(bmain, sound); - /* +#if 0 if (op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); - */ +#endif return NULL; } @@ -3983,7 +3994,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->type = SEQ_TYPE_SOUND_RAM; seq->sound = sound; BLI_strncpy(seq->name + 2, "Sound", SEQ_NAME_MAXSTR - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); @@ -4043,7 +4054,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->anim = an; seq->anim_preseek = IMB_anim_get_preseek(an); BLI_strncpy(seq->name + 2, "Movie", SEQ_NAME_MAXSTR - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); @@ -4155,7 +4166,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup } if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seqn); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqn); if (dupe_flag & SEQ_DUPE_ANIM) BKE_sequencer_dupe_animdata(scene, seq->name + 2, seqn->name + 2); @@ -4210,7 +4221,7 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase * /* called on draw, needs to be fast, * we could cache and use a flag if we want to make checks for file paths resolving for eg. */ -int BKE_seqence_is_valid_check(Sequence *seq) +int BKE_sequence_is_valid_check(Sequence *seq) { switch (seq->type) { case SEQ_TYPE_MASK: diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 12868486abf..4eeca3206cf 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -1084,19 +1084,21 @@ void set_current_material_texture(Material *ma, Tex *newtex) { Tex *tex = NULL; bNode *node; - - if (ma && ma->use_nodes && ma->nodetree) { - node = nodeGetActiveID(ma->nodetree, ID_TE); - if (node) { - tex = (Tex *)node->id; - id_us_min(&tex->id); + if ((ma->use_nodes && ma->nodetree) && + (node = nodeGetActiveID(ma->nodetree, ID_TE))) + { + tex = (Tex *)node->id; + id_us_min(&tex->id); + if (newtex) { node->id = &newtex->id; id_us_plus(&newtex->id); - ma = NULL; + } + else { + node->id = NULL; } } - if (ma) { + else { int act = (int)ma->texact; tex = (ma->mtex[act]) ? ma->mtex[act]->tex : NULL; diff --git a/source/blender/blenlib/BLI_lasso.h b/source/blender/blenlib/BLI_lasso.h index 85a000b000c..a7e90a51e86 100644 --- a/source/blender/blenlib/BLI_lasso.h +++ b/source/blender/blenlib/BLI_lasso.h @@ -34,8 +34,8 @@ struct rcti; -void BLI_lasso_boundbox(struct rcti *rect, int mcords[][2], short moves); -int BLI_lasso_is_point_inside(int mcords[][2], short moves, const int sx, const int sy, const int error_value); -int BLI_lasso_is_edge_inside(int mcords[][2], short moves, int x0, int y0, int x1, int y1, const int error_value); +void BLI_lasso_boundbox(struct rcti *rect, const int mcords[][2], const short moves); +int BLI_lasso_is_point_inside(const int mcords[][2], const short moves, const int sx, const int sy, const int error_value); +int BLI_lasso_is_edge_inside(const int mcords[][2], const short moves, int x0, int y0, int x1, int y1, const int error_value); #endif diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso.c index 7df4da80e16..5cd8bb813a1 100644 --- a/source/blender/blenlib/intern/lasso.c +++ b/source/blender/blenlib/intern/lasso.c @@ -37,7 +37,7 @@ #include "BLI_lasso.h" /* own include */ -void BLI_lasso_boundbox(rcti *rect, int mcords[][2], short moves) +void BLI_lasso_boundbox(rcti *rect, const int mcords[][2], const short moves) { short a; @@ -53,14 +53,14 @@ void BLI_lasso_boundbox(rcti *rect, int mcords[][2], short moves) } -int BLI_lasso_is_point_inside(int mcords[][2], short moves, +int BLI_lasso_is_point_inside(const int mcords[][2], const short moves, const int sx, const int sy, const int error_value) { /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */ float angletot = 0.0, dot, ang, cross, fp1[2], fp2[2]; int a; - int *p1, *p2; + const int *p1, *p2; if (sx == error_value) { return 0; @@ -100,7 +100,7 @@ int BLI_lasso_is_point_inside(int mcords[][2], short moves, } /* edge version for lasso select. we assume boundbox check was done */ -int BLI_lasso_is_edge_inside(int mcords[][2], short moves, +int BLI_lasso_is_edge_inside(const int mcords[][2], const short moves, int x0, int y0, int x1, int y1, const int error_value) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5f5070f1173..d6853bba9b5 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -207,7 +207,7 @@ * - join all Mains * - link all LibBlocks and indirect pointers to libblocks * - initialize FileGlobal and copy pointers to Global -*/ + */ /* also occurs in library.c */ /* GS reads the memory pointed at in a specific ordering. There are, @@ -3667,7 +3667,14 @@ static void lib_link_mesh(FileData *fd, Main *main) if (me->mr && me->mr->levels.first) lib_link_customdata_mtface(fd, me, &me->mr->fdata, ((MultiresLevel*)me->mr->levels.first)->totface); - + } + } + + /* convert texface options to material */ + convert_tface_mt(fd, main); + + for (me = main->mesh.first; me; me = me->id.next) { + if (me->id.flag & LIB_NEED_LINK) { /*check if we need to convert mfaces to mpolys*/ if (me->totface && !me->totpoly) { /* temporarily switch main so that reading from @@ -3679,14 +3686,7 @@ static void lib_link_mesh(FileData *fd, Main *main) G.main = gmain; } - } - } - - /* convert texface options to material */ - convert_tface_mt(fd, main); - for (me = main->mesh.first; me; me = me->id.next) { - if (me->id.flag & LIB_NEED_LINK) { /* * Re-tessellate, even if the polys were just created from tessfaces, this * is important because it: @@ -3843,35 +3843,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) direct_link_customdata(fd, &mesh->ldata, mesh->totloop); direct_link_customdata(fd, &mesh->pdata, mesh->totpoly); - -#ifdef USE_BMESH_FORWARD_COMPAT - /* NEVER ENABLE THIS CODE INTO BMESH! - * THIS IS FOR LOADING BMESH INTO OLDER FILES ONLY */ - mesh->mpoly = newdataadr(fd, mesh->mpoly); - mesh->mloop = newdataadr(fd, mesh->mloop); - - direct_link_customdata(fd, &mesh->pdata, mesh->totpoly); - direct_link_customdata(fd, &mesh->ldata, mesh->totloop); - - if (mesh->mpoly) { - /* be clever and load polygons as mfaces */ - mesh->totface= BKE_mesh_mpoly_to_mface(&mesh->fdata, &mesh->ldata, &mesh->pdata, - mesh->totface, mesh->totloop, mesh->totpoly); - - CustomData_free(&mesh->pdata, mesh->totpoly); - memset(&mesh->pdata, 0, sizeof(CustomData)); - mesh->totpoly = 0; - - CustomData_free(&mesh->ldata, mesh->totloop); - memset(&mesh->ldata, 0, sizeof(CustomData)); - mesh->totloop = 0; - - mesh_update_customdata_pointers(mesh); - } - -#endif - - mesh->bb = NULL; mesh->edit_btmesh = NULL; @@ -7068,6 +7039,15 @@ static void do_version_ntree_keying_despill_balance(void *UNUSED(data), ID *UNUS } } +static void do_version_ntree_tex_coord_from_dupli_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) + if (node->type == SH_NODE_TEX_COORD) + node->flag |= NODE_OPTIONS; +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -8016,6 +7996,34 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* correction for files saved in blender version when BKE_pose_copy_data + * didn't copy animation visualization, which lead to deadlocks on motion + * path calculation for proxied armatures, see [#32742] + */ + if (main->versionfile < 264) { + Object *ob; + + for (ob = main->object.first; ob; ob = ob->id.next) { + if (ob->pose) { + if (ob->pose->avs.path_step == 0) { + animviz_settings_init(&ob->pose->avs); + } + } + } + } + + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 1)) { + bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER); + bNodeTree *ntree; + + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_ntree_tex_coord_from_dupli_264); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + if (ntree->type==NTREE_SHADER) + do_version_ntree_tex_coord_from_dupli_264(NULL, NULL, ntree); + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 0d39b9011b2..c1849e6ec91 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -652,7 +652,7 @@ static void do_versions_seq_unique_name_all_strips(Scene * sce, ListBase *seqbas Sequence * seq = seqbasep->first; while (seq) { - BKE_seqence_base_unique_name_recursive(&sce->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&sce->ed->seqbase, seq); if (seq->seqbase.first) { do_versions_seq_unique_name_all_strips(sce, &seq->seqbase); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index b3effa62664..51c78cd2432 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -30,46 +30,46 @@ /* -FILEFORMAT: IFF-style structure (but not IFF compatible!) - -start file: - BLENDER_V100 12 bytes (versie 1.00) - V = big endian, v = little endian - _ = 4 byte pointer, - = 8 byte pointer - -datablocks: also see struct BHead - <bh.code> 4 chars - <bh.len> int, len data after BHead - <bh.old> void, old pointer - <bh.SDNAnr> int - <bh.nr> int, in case of array: amount of structs - data - ... - ... - -Almost all data in Blender are structures. Each struct saved -gets a BHead header. With BHead the struct can be linked again -and compared with StructDNA . - -WRITE - -Preferred writing order: (not really a must, but why would you do it random?) -Any case: direct data is ALWAYS after the lib block - -(Local file data) -- for each LibBlock - - write LibBlock - - write associated direct data -(External file data) -- per library - - write library block - - per LibBlock - - write the ID of LibBlock -- write TEST (128x128, blend file preview, optional) -- write FileGlobal (some global vars) -- write SDNA -- write USER if filename is ~/X.XX/config/startup.blend -*/ + * FILEFORMAT: IFF-style structure (but not IFF compatible!) + * + * start file: + * BLENDER_V100 12 bytes (versie 1.00) + * V = big endian, v = little endian + * _ = 4 byte pointer, - = 8 byte pointer + * + * datablocks: also see struct BHead + * <bh.code> 4 chars + * <bh.len> int, len data after BHead + * <bh.old> void, old pointer + * <bh.SDNAnr> int + * <bh.nr> int, in case of array: amount of structs + * data + * ... + * ... + * + * Almost all data in Blender are structures. Each struct saved + * gets a BHead header. With BHead the struct can be linked again + * and compared with StructDNA . + * + * WRITE + * + * Preferred writing order: (not really a must, but why would you do it random?) + * Any case: direct data is ALWAYS after the lib block + * + * (Local file data) + * - for each LibBlock + * - write LibBlock + * - write associated direct data + * (External file data) + * - per library + * - write library block + * - per LibBlock + * - write the ID of LibBlock + * - write TEST (128x128, blend file preview, optional) + * - write FileGlobal (some global vars) + * - write SDNA + * - write USER if filename is ~/X.XX/config/startup.blend + */ #include <math.h> diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 034b9584e63..d71aa969080 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -88,8 +88,8 @@ extern "C" { /* - COLLADA Importer limitations: - - no multiple scene import, all objects are added to active scene + * COLLADA Importer limitations: + * - no multiple scene import, all objects are added to active scene */ // #define COLLADA_DEBUG @@ -893,7 +893,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera) } break; /* XXX correct way to do following four is probably to get also render - size and determine proper settings from that somehow */ + * size and determine proper settings from that somehow */ case COLLADAFW::Camera::ASPECTRATIO_AND_X: case COLLADAFW::Camera::SINGLE_X: case COLLADAFW::Camera::X_AND_Y: diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h index f0b79895f22..8dc20af7cac 100644 --- a/source/blender/collada/DocumentImporter.h +++ b/source/blender/collada/DocumentImporter.h @@ -82,8 +82,9 @@ public: void translate_anim_recursive(COLLADAFW::Node*, COLLADAFW::Node*, Object*); - /** This method will be called if an error in the loading process occurred and the loader cannot - continue to load. The writer should undo all operations that have been performed. + /** + * This method will be called if an error in the loading process occurred and the loader cannot + * continue to load. The writer should undo all operations that have been performed. \param errorMessage A message containing informations about the error that occurred. */ void cancel(const COLLADAFW::String& errorMessage); diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 4940dc55277..9110b8299b2 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -432,8 +432,8 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) param.push_back("X"); param.push_back("Y"); param.push_back("Z"); - /*main function, it creates <source id = "">, <float_array id = "" - count = ""> */ + /* main function, it creates <source id = "">, <float_array id = "" + * count = ""> */ source.prepareToAppendValues(); //appends data to <float_array> int i = 0; diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp index fe6ebcebf97..1fa484ea2b6 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.cpp +++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp @@ -24,7 +24,7 @@ MapUVOperation::MapUVOperation() : NodeOperation() { - this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addInputSocket(COM_DT_VECTOR); this->addOutputSocket(COM_DT_COLOR); this->m_alpha = 0.0f; diff --git a/source/blender/compositor/operations/COM_MixGlareOperation.cpp b/source/blender/compositor/operations/COM_MixGlareOperation.cpp index b6a9aa3da3c..1c6555206da 100644 --- a/source/blender/compositor/operations/COM_MixGlareOperation.cpp +++ b/source/blender/compositor/operations/COM_MixGlareOperation.cpp @@ -40,9 +40,13 @@ void MixGlareOperation::executePixel(float output[4], float x, float y, PixelSam value = inputValue[0]; float mf = 2.f - 2.f * fabsf(value - 0.5f); - output[0] = mf * ((inputColor1[0]) + value * (inputColor2[0] - inputColor1[0])); - output[1] = mf * ((inputColor1[1]) + value * (inputColor2[1] - inputColor1[1])); - output[2] = mf * ((inputColor1[2]) + value * (inputColor2[2] - inputColor1[2])); + if (inputColor1[0] < 0.0f) inputColor1[0] = 0.0f; + if (inputColor1[1] < 0.0f) inputColor1[1] = 0.0f; + if (inputColor1[2] < 0.0f) inputColor1[2] = 0.0f; + + output[0] = mf * max(inputColor1[0] + value * (inputColor2[0] - inputColor1[0]), 0.0f); + output[1] = mf * max(inputColor1[1] + value * (inputColor2[1] - inputColor1[1]), 0.0f); + output[2] = mf * max(inputColor1[2] + value * (inputColor2[2] - inputColor1[2]), 0.0f); output[3] = inputColor1[3]; clampIfNeeded(output); diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index 3a9e6f25cd9..b934719a92b 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -35,8 +35,8 @@ #include "BLI_listbase.h" /** - * Class with implementation of green screen gradient rasterization - */ + * Class with implementation of green screen gradient rasterization + */ class TrackPositionOperation : public NodeOperation { protected: enum { @@ -58,8 +58,8 @@ protected: float m_relativePos[2]; /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ + * Determine the output resolution. The resolution is retrieved from the Renderer + */ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); public: diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cpp b/source/blender/compositor/operations/COM_ZCombineOperation.cpp index 7e23e7290f8..5e4f90b0269 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.cpp +++ b/source/blender/compositor/operations/COM_ZCombineOperation.cpp @@ -69,7 +69,7 @@ void ZCombineAlphaOperation::executePixel(float output[4], float x, float y, Pix this->m_depth1Reader->read(depth1, x, y, sampler); this->m_depth2Reader->read(depth2, x, y, sampler); - if (depth1[0] < depth2[0]) { + if (depth1[0] <= depth2[0]) { this->m_image1Reader->read(color1, x, y, sampler); this->m_image2Reader->read(color2, x, y, sampler); } @@ -79,10 +79,10 @@ void ZCombineAlphaOperation::executePixel(float output[4], float x, float y, Pix } float fac = color1[3]; float ifac = 1.0f - fac; - output[0] = color1[0] + ifac * color2[0]; - output[1] = color1[1] + ifac * color2[1]; - output[2] = color1[2] + ifac * color2[2]; - output[3] = MAX2(color1[3], color2[3]); + output[0] = fac * color1[0] + ifac * color2[0]; + output[1] = fac * color1[1] + ifac * color2[1]; + output[2] = fac * color1[2] + ifac * color2[2]; + output[3] = max(color1[3], color2[3]); } void ZCombineOperation::deinitExecution() diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index cf84eb04b10..bc07bf091de 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -50,7 +50,9 @@ void ANIM_OT_keyframe_delete(struct wmOperatorType *ot); * required for each space. */ void ANIM_OT_keyframe_insert_menu(struct wmOperatorType *ot); + void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot); +void ANIM_OT_keyframe_clear_v3d(struct wmOperatorType *ot); /* Keyframe managment operators for UI buttons (RMB menu). */ void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index e24a4d49a05..f2711ec3bb5 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -290,6 +290,7 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_keyframe_delete); WM_operatortype_append(ANIM_OT_keyframe_insert_menu); WM_operatortype_append(ANIM_OT_keyframe_delete_v3d); + WM_operatortype_append(ANIM_OT_keyframe_clear_v3d); WM_operatortype_append(ANIM_OT_keyframe_insert_button); WM_operatortype_append(ANIM_OT_keyframe_delete_button); WM_operatortype_append(ANIM_OT_keyframe_clear_button); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 1791d84d90b..0454e88e320 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1186,10 +1186,9 @@ static int modify_key_op_poll(bContext *C) /* if Outliner, don't allow in some views */ if (so) { - if (ELEM4(so->outlinevis, SO_GROUPS, SO_LIBRARIES, SO_VERSE_SESSION, SO_VERSE_SESSION)) - return 0; - if (ELEM3(so->outlinevis, SO_SEQUENCE, SO_USERDEF, SO_KEYMAP)) + if (ELEM5(so->outlinevis, SO_GROUPS, SO_LIBRARIES, SO_SEQUENCE, SO_USERDEF, SO_KEYMAP)) { return 0; + } } /* TODO: checks for other space types can be added here */ @@ -1440,46 +1439,122 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot) } /* Delete Key Operator ------------------------ */ - -/* XXX WARNING: - * This is currently just a basic operator, which work in 3d-view context on objects only. - * Should this be kept? It does have advantages over a version which requires selecting a keyingset to use... - * -- Joshua Leung, Jan 2009 +/* NOTE: Although this version is simpler than the more generic version for KeyingSets, + * it is more useful for animators working in the 3D view. */ +static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) + { + /* just those in active action... */ + if ((ob->adt) && (ob->adt->action)) { + AnimData *adt = ob->adt; + bAction *act = adt->action; + FCurve *fcu, *fcn; + + for (fcu = act->curves.first; fcu; fcu = fcn) { + short can_delete = FALSE; + + fcn = fcu->next; + + /* in pose mode, only delete the F-Curve if it belongs to a selected bone */ + if (ob->mode & OB_MODE_POSE) { + if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) { + bPoseChannel *pchan; + char *bone_name; + + /* get bone-name, and check if this bone is selected */ + bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); + if (bone_name) MEM_freeN(bone_name); + + /* delete if bone is selected*/ + if ((pchan) && (pchan->bone)) { + if (pchan->bone->flag & BONE_SELECTED) + can_delete = TRUE; + } + } + } + else { + /* object mode - all of Object's F-Curves are affected */ + can_delete = TRUE; + } + + /* delete F-Curve completely */ + if (can_delete) { + ANIM_fcurve_delete_from_animdata(NULL, adt, fcu); + } + } + } + + /* update... */ + ob->recalc |= OB_RECALC_OB; + } + CTX_DATA_END; + + /* send updates */ + DAG_ids_flush_update(bmain, 0); + WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL); + + return OPERATOR_FINISHED; +} + +void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Animation"; + ot->description = "Remove all keyframe animation for selected objects"; + ot->idname = "ANIM_OT_keyframe_clear_v3d"; + + /* callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = clear_anim_v3d_exec; + + ot->poll = ED_operator_areaactive; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + static int delete_key_v3d_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap + float cfra = (float)CFRA; - // XXX more comprehensive tests will be needed CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { - ID *id = (ID *)ob; - FCurve *fcu, *fcn; - short success = 0; + ID *id = &ob->id; + int success = 0; - /* loop through all curves in animdata and delete keys on this frame */ + /* just those in active action... */ if ((ob->adt) && (ob->adt->action)) { AnimData *adt = ob->adt; bAction *act = adt->action; + FCurve *fcu, *fcn; for (fcu = act->curves.first; fcu; fcu = fcn) { fcn = fcu->next; + + /* delete keyframes on current frame + * WARNING: this can delete the next F-Curve, hence the "fcn" copying + */ success += delete_keyframe(op->reports, id, NULL, NULL, fcu->rna_path, fcu->array_index, cfra, 0); } } - BKE_reportf(op->reports, RPT_INFO, "Ob '%s' - Successfully had %d keyframes removed", id->name + 2, success); - + /* report success (or failure) */ + BKE_reportf(op->reports, RPT_INFO, "Object '%s' successfully had %d keyframes removed", id->name + 2, success); ob->recalc |= OB_RECALC_OB; } CTX_DATA_END; /* send updates */ DAG_ids_flush_update(bmain, 0); - WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL); return OPERATOR_FINISHED; @@ -1489,7 +1564,7 @@ void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot) { /* identifiers */ ot->name = "Delete Keyframe"; - ot->description = "Remove keyframes on current frame for selected object"; + ot->description = "Remove keyframes on current frame for selected objects"; ot->idname = "ANIM_OT_keyframe_delete_v3d"; /* callbacks */ @@ -1512,7 +1587,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) PointerRNA ptr = {{NULL}}; PropertyRNA *prop = NULL; char *path; - float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap + float cfra = (float)CFRA; short success = 0; int a, index, length, all = RNA_boolean_get(op->ptr, "all"); short flag = 0; @@ -1683,20 +1758,20 @@ static int clear_key_button_exec(bContext *C, wmOperator *op) if (ptr.id.data && ptr.data && prop) { path = RNA_path_from_ID_to_property(&ptr, prop); - + if (path) { if (all) { length = RNA_property_array_length(&ptr, prop); - + if (length) index = 0; else length = 1; } else length = 1; - + for (a = 0; a < length; a++) success += clear_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index + a, 0); - + MEM_freeN(path); } else if (G.debug & G_DEBUG) @@ -1710,9 +1785,9 @@ static int clear_key_button_exec(bContext *C, wmOperator *op) if (success) { /* send updates */ uiContextAnimUpdate(C); - + DAG_ids_flush_update(bmain, 0); - + /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index cb52d88f985..d8c6040d84f 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -1831,7 +1831,7 @@ void ED_armature_deselect_all_visible(Object *obedit) for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { /* first and foremost, bone must be visible and selected */ - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } } @@ -4106,7 +4106,7 @@ static void select_similar_length(bArmature *arm, EditBone *ebone_act, const flo const float len_max = ebone_act->length * (1.0f + thresh); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { if ((ebone->length >= len_min) && (ebone->length <= len_max)) { @@ -4123,7 +4123,7 @@ static void select_similar_direction(bArmature *arm, EditBone *ebone_act, const sub_v3_v3v3(dir_act, ebone_act->head, ebone_act->tail); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { float dir[3]; sub_v3_v3v3(dir, ebone->head, ebone->tail); @@ -4139,7 +4139,7 @@ static void select_similar_layer(bArmature *arm, EditBone *ebone_act) EditBone *ebone; for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { if (ebone->layer & ebone_act->layer) { ED_armature_edit_bone_select(ebone); } @@ -4161,7 +4161,7 @@ static void select_similar_prefix(bArmature *arm, EditBone *ebone_act) /* Find matches */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { char prefix_other[MAX_VGROUP_NAME]; BKE_deform_split_prefix(ebone->name, prefix_other, body_tmp); if (!strcmp(prefix_act, prefix_other)) { @@ -4185,7 +4185,7 @@ static void select_similar_suffix(bArmature *arm, EditBone *ebone_act) /* Find matches */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, ebone)) { char suffix_other[MAX_VGROUP_NAME]; BKE_deform_split_suffix(ebone->name, body_tmp, suffix_other); if (!strcmp(suffix_act, suffix_other)) { @@ -4270,7 +4270,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op) for (curbone = arm->edbo->first; curbone; curbone = curbone->next) { /* only work on bone if it is visible and its selection can change */ - if (EBONE_VISIBLE(arm, curbone) && (curbone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, curbone)) { if (curbone == arm->act_edbone) { if (direction == BONE_SELECT_PARENT) { if (curbone->parent == NULL) continue; @@ -4290,7 +4290,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op) chbone = editbone_get_child(arm, curbone, 1); if (chbone == NULL) continue; - if (EBONE_VISIBLE(arm, chbone) && (chbone->flag & BONE_UNSELECTABLE) == 0) { + if (EBONE_SELECTABLE(arm, chbone)) { chbone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_edbone = chbone; diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index f3f985fa97d..5ba4a232250 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -41,6 +41,8 @@ #include "BLI_graph.h" #include "BLI_ghash.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_sketch.h" @@ -175,7 +177,7 @@ void BIF_makeListTemplates(const bContext *C) const char *BIF_listTemplates(const bContext *UNUSED(C)) { GHashIterator ghi; - char menu_header[] = "Template%t|None%x0|"; + const char *menu_header = IFACE_("Template %t|None %x0|"); char *p; if (TEMPLATES_MENU != NULL) { @@ -194,7 +196,7 @@ const char *BIF_listTemplates(const bContext *UNUSED(C)) Object *ob = BLI_ghashIterator_getValue(&ghi); int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi)); - p += sprintf(p, "|%s%%x%i", ob->id.name + 2, key); + p += sprintf(p, "|%s %%x%i", ob->id.name + 2, key); BLI_ghashIterator_step(&ghi); } @@ -644,16 +646,17 @@ static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], in short pval[2]; int pdist; - ED_view3d_project_short_noclip(ar, stk->points[i].p, pval); + if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); + pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - if (pdist < *dist) { - *dist = pdist; - pt = stk->points + i; + if (pdist < *dist) { + *dist = pdist; + pt = stk->points + i; - if (index != NULL) { - *index = i; + if (index != NULL) { + *index = i; + } } } } @@ -679,32 +682,34 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, { copy_v3_v3(vec, bone->head); mul_m4_v3(ob->obmat, vec); - ED_view3d_project_short_noclip(ar, vec, pval); + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); + pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - if (pdist < *dist) - { - *dist = pdist; - pt = &boneSnap; - copy_v3_v3(pt->p, vec); - pt->type = PT_EXACT; + if (pdist < *dist) + { + *dist = pdist; + pt = &boneSnap; + copy_v3_v3(pt->p, vec); + pt->type = PT_EXACT; + } } } copy_v3_v3(vec, bone->tail); mul_m4_v3(ob->obmat, vec); - ED_view3d_project_short_noclip(ar, vec, pval); + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); + pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - if (pdist < *dist) - { - *dist = pdist; - pt = &boneSnap; - copy_v3_v3(pt->p, vec); - pt->type = PT_EXACT; + if (pdist < *dist) + { + *dist = pdist; + pt = &boneSnap; + copy_v3_v3(pt->p, vec); + pt->type = PT_EXACT; + } } } @@ -905,9 +910,9 @@ static void sk_interpolateDepth(bContext *C, SK_Stroke *stk, int start, int end, for (i = start; i <= end; i++) { float ray_start[3], ray_normal[3]; float delta = len_v3v3(stk->points[i].p, stk->points[i + 1].p); - float pval[2]; + float pval[2] = {0, 0}; - ED_view3d_project_float(ar, stk->points[i].p, pval); + ED_view3d_project_float_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP); ED_view3d_win_to_ray(ar, v3d, pval, ray_start, ray_normal); mul_v3_fl(ray_normal, distance * progress / length); @@ -934,10 +939,14 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr initgrabz(ar->regiondata, fp[0], fp[1], fp[2]); /* method taken from editview.c - mouse_cursor() */ - ED_view3d_project_short_noclip(ar, fp, cval); - VECSUB2D(mval_f, cval, dd->mval); - ED_view3d_win_to_delta(ar, mval_f, dvec); - sub_v3_v3v3(vec, fp, dvec); + if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + VECSUB2D(mval_f, cval, dd->mval); + ED_view3d_win_to_delta(ar, mval_f, dvec); + sub_v3_v3v3(vec, fp, dvec); + } + else { + zero_v3(vec); + } } static int sk_getStrokeDrawPoint(bContext *C, SK_Point *pt, SK_Sketch *UNUSED(sketch), SK_Stroke *stk, SK_DrawData *dd) @@ -1453,8 +1462,8 @@ static int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gestu float s_p2[3] = {0, 0, 0}; int g_i; - ED_view3d_project_float(ar, gesture->points[s_i].p, s_p1); - ED_view3d_project_float(ar, gesture->points[s_i + 1].p, s_p2); + ED_view3d_project_float_global(ar, gesture->points[s_i].p, s_p1, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, gesture->points[s_i + 1].p, s_p2, V3D_PROJ_TEST_NOP); /* start checking from second next, because two consecutive cannot intersect */ for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++) { @@ -1463,8 +1472,8 @@ static int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gestu float vi[3]; float lambda; - ED_view3d_project_float(ar, gesture->points[g_i].p, g_p1); - ED_view3d_project_float(ar, gesture->points[g_i + 1].p, g_p2); + ED_view3d_project_float_global(ar, gesture->points[g_i].p, g_p1, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, gesture->points[g_i + 1].p, g_p2, V3D_PROJ_TEST_NOP); if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) { SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection"); @@ -1531,8 +1540,8 @@ static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, S float s_p2[3] = {0, 0, 0}; int g_i; - ED_view3d_project_float(ar, stk->points[s_i].p, s_p1); - ED_view3d_project_float(ar, stk->points[s_i + 1].p, s_p2); + ED_view3d_project_float_global(ar, stk->points[s_i].p, s_p1, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, stk->points[s_i + 1].p, s_p2, V3D_PROJ_TEST_NOP); for (g_i = 0; g_i < gesture->nb_points - 1; g_i++) { float g_p1[3] = {0, 0, 0}; @@ -1540,8 +1549,8 @@ static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, S float vi[3]; float lambda; - ED_view3d_project_float(ar, gesture->points[g_i].p, g_p1); - ED_view3d_project_float(ar, gesture->points[g_i + 1].p, g_p2); + ED_view3d_project_float_global(ar, gesture->points[g_i].p, g_p1, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, gesture->points[g_i + 1].p, g_p2, V3D_PROJ_TEST_NOP); if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) { SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection"); @@ -1717,8 +1726,8 @@ void sk_applyCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UN SK_Intersection *isect; int command = 1; -// XXX -// command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3"); +/* XXX */ +/* command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3"); */ if (command < 1) return; for (isect = gest->intersections.first; isect; isect = isect->next) { @@ -1784,33 +1793,35 @@ int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketc short start_val[2], end_val[2]; short dist; - ED_view3d_project_short_noclip(ar, gest->stk->points[0].p, start_val); - ED_view3d_project_short_noclip(ar, sk_lastStrokePoint(gest->stk)->p, end_val); + if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && + (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + { - dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); + dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); - /* if gesture is a circle */ - if (dist <= 20) { - SK_Intersection *isect; + /* if gesture is a circle */ + if (dist <= 20) { + SK_Intersection *isect; - /* check if it circled around an exact point */ - for (isect = gest->intersections.first; isect; isect = isect->next) { - /* only delete strokes that are crossed twice */ - if (isect->next && isect->next->stroke == isect->stroke) { - int start_index, end_index; - int i; + /* check if it circled around an exact point */ + for (isect = gest->intersections.first; isect; isect = isect->next) { + /* only delete strokes that are crossed twice */ + if (isect->next && isect->next->stroke == isect->stroke) { + int start_index, end_index; + int i; - start_index = MIN2(isect->after, isect->next->after); - end_index = MAX2(isect->before, isect->next->before); + start_index = MIN2(isect->after, isect->next->after); + end_index = MAX2(isect->before, isect->next->before); - for (i = start_index; i <= end_index; i++) { - if (isect->stroke->points[i].type == PT_EXACT) { - return 1; /* at least one exact point found, stop detect here */ + for (i = start_index; i <= end_index; i++) { + if (isect->stroke->points[i].type == PT_EXACT) { + return 1; /* at least one exact point found, stop detect here */ + } } - } - /* skip next */ - isect = isect->next; + /* skip next */ + isect = isect->next; + } } } } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 346ed0002bd..522622ec5c4 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1113,6 +1113,9 @@ typedef struct MeshDeformBind { /* direct solver */ int *varidx; + + BVHTree *bvhtree; + BVHTreeFromMesh bvhdata; } MeshDeformBind; typedef struct MeshDeformIsect { @@ -1130,8 +1133,9 @@ typedef struct MeshDeformIsect { /* our own triangle intersection, so we can fully control the epsilons and * prevent corner case from going wrong*/ -static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], - float vert1[3], float vert2[3], float *isectco, float *uvw) +static int meshdeform_tri_intersect(const float orig[3], const float end[3], const float vert0[3], + const float vert1[3], const float vert2[3], + float r_isectco[3], float r_uvw[3]) { float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; float det, inv_det, u, v, dir[3], isectdir[3]; @@ -1148,8 +1152,10 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], /* if determinant is near zero, ray lies in plane of triangle */ det = dot_v3v3(edge1, pvec); - if (det == 0.0f) + if (UNLIKELY(det == 0.0f)) { return 0; + } + inv_det = 1.0f / det; /* calculate distance from vert0 to ray origin */ @@ -1168,16 +1174,16 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], if (v < -EPSILON || u + v > 1.0f + EPSILON) return 0; - isectco[0] = (1.0f - u - v) * vert0[0] + u * vert1[0] + v * vert2[0]; - isectco[1] = (1.0f - u - v) * vert0[1] + u * vert1[1] + v * vert2[1]; - isectco[2] = (1.0f - u - v) * vert0[2] + u * vert1[2] + v * vert2[2]; + r_isectco[0] = (1.0f - u - v) * vert0[0] + u * vert1[0] + v * vert2[0]; + r_isectco[1] = (1.0f - u - v) * vert0[1] + u * vert1[1] + v * vert2[1]; + r_isectco[2] = (1.0f - u - v) * vert0[2] + u * vert1[2] + v * vert2[2]; - uvw[0] = 1.0f - u - v; - uvw[1] = u; - uvw[2] = v; + r_uvw[0] = 1.0f - u - v; + r_uvw[1] = u; + r_uvw[2] = v; /* check if it is within the length of the line segment */ - sub_v3_v3v3(isectdir, isectco, orig); + sub_v3_v3v3(isectdir, r_isectco, orig); if (dot_v3v3(dir, isectdir) < -EPSILON) return 0; @@ -1188,83 +1194,77 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], return 1; } -static int meshdeform_intersect(MeshDeformBind *mdb, MeshDeformIsect *isec) -{ - MFace *mface; - float face[4][3], co[3], uvw[3], len, nor[3], end[3]; - int f, hit, is = 0, totface; - - isec->labda = 1e10; - - mface = mdb->cagedm->getTessFaceArray(mdb->cagedm); - totface = mdb->cagedm->getNumTessFaces(mdb->cagedm); - - add_v3_v3v3(end, isec->start, isec->vec); - - for (f = 0; f < totface; f++, mface++) { - copy_v3_v3(face[0], mdb->cagecos[mface->v1]); - copy_v3_v3(face[1], mdb->cagecos[mface->v2]); - copy_v3_v3(face[2], mdb->cagecos[mface->v3]); - - if (mface->v4) { - copy_v3_v3(face[3], mdb->cagecos[mface->v4]); - hit = meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw); - - if (hit) { - normal_tri_v3(nor, face[0], face[1], face[2]); - } - else { - hit = meshdeform_tri_intersect(isec->start, end, face[0], face[2], face[3], co, uvw); - normal_tri_v3(nor, face[0], face[2], face[3]); - } - } - else { - hit = meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw); - normal_tri_v3(nor, face[0], face[1], face[2]); - } - - if (hit) { - len = len_v3v3(isec->start, co) / len_v3v3(isec->start, end); - if (len < isec->labda) { - isec->labda = len; - isec->face = mface; - isec->isect = (dot_v3v3(isec->vec, nor) <= 0.0f); - is = 1; - } - } +static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) + { + void **data = userdata; + MeshDeformBind *mdb = data[1]; + MFace *mface = data[0], *mf; + MeshDeformIsect *isec = data[2]; + float no[3], co[3], end[3], uvw[3], dist, face[4][3]; + + mf = mface + index; + + copy_v3_v3(face[0], mdb->cagecos[mf->v1]); + copy_v3_v3(face[1], mdb->cagecos[mf->v2]); + copy_v3_v3(face[2], mdb->cagecos[mf->v3]); + if (mf->v4) + copy_v3_v3(face[3], mdb->cagecos[mf->v4]); + + add_v3_v3v3(end, isec->start, isec->vec); + + if (!meshdeform_tri_intersect(ray->origin, end, face[0], face[1], face[2], co, uvw)) + if (!mf->v4 || !meshdeform_tri_intersect(ray->origin, end, face[0], face[2], face[3], co, uvw)) + return; + + if (!mf->v4) + normal_tri_v3(no, face[0], face[1], face[2]); + else + normal_quad_v3(no, face[0], face[1], face[2], face[3]); + + dist = len_v3v3(ray->origin, co)/len_v3(isec->vec); + if (dist < hit->dist) { + hit->index = index; + hit->dist = dist; + copy_v3_v3(hit->co, co); + + isec->isect = dot_v3v3(no, ray->direction) <= 0.0; + isec->labda = dist; + isec->face = mf; } - - return is; } static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float *co1, float *co2) { MDefBoundIsect *isect; - MeshDeformIsect isec; + BVHTreeRayHit hit; + MeshDeformIsect isect_mdef; float (*cagecos)[3]; - MFace *mface; + void *data[3] = {mdb->cagedm->getTessFaceArray(mdb->cagedm), mdb, &isect_mdef}; + MFace *mface1 = data[0], *mface; float vert[4][3], len, end[3]; static float epsilon[3] = {0, 0, 0}; //1e-4, 1e-4, 1e-4}; /* setup isec */ - memset(&isec, 0, sizeof(isec)); - isec.labda = 1e10f; + memset(&isect_mdef, 0, sizeof(isect_mdef)); + isect_mdef.labda = 1e10f; - add_v3_v3v3(isec.start, co1, epsilon); + add_v3_v3v3(isect_mdef.start, co1, epsilon); add_v3_v3v3(end, co2, epsilon); - sub_v3_v3v3(isec.vec, end, isec.start); + sub_v3_v3v3(isect_mdef.vec, end, isect_mdef.start); - if (meshdeform_intersect(mdb, &isec)) { - len = isec.labda; - mface = (MFace *)isec.face; + hit.index = -1; + hit.dist = FLT_MAX; + if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, 0.0, &hit, harmonic_ray_callback, data) != -1) { + len= isect_mdef.labda; + isect_mdef.face = mface = mface1 + hit.index; /* create MDefBoundIsect */ isect = BLI_memarena_alloc(mdb->memarena, sizeof(*isect)); /* compute intersection coordinate */ - isect->co[0] = co1[0] + isec.vec[0] * len; - isect->co[1] = co1[1] + isec.vec[1] * len; - isect->co[2] = co1[2] + isec.vec[2] * len; + isect->co[0] = co1[0] + isect_mdef.vec[0] * len; + isect->co[1] = co1[1] + isect_mdef.vec[1] * len; + isect->co[2] = co1[2] + isect_mdef.vec[2] * len; isect->len = len_v3v3(co1, isect->co); if (isect->len < MESHDEFORM_LEN_THRESHOLD) @@ -1276,7 +1276,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float isect->v[3] = mface->v4; isect->nvert = (mface->v4) ? 4 : 3; - isect->facing = isec.isect; + isect->facing = isect_mdef.isect; /* compute mean value coordinates for interpolation */ cagecos = mdb->cagecos; @@ -1766,7 +1766,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi"); mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect"); mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound"); - + mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON*100, 4, 6); mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside"); if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) @@ -1882,6 +1882,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa MEM_freeN(mdb->boundisect); MEM_freeN(mdb->semibound); BLI_memarena_free(mdb->memarena); + free_bvhtree_from_mesh(&mdb->bvhdata); } #if 0 diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 2f5eaabc12b..189b2e977c2 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -492,7 +492,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) if (pchan->parent == NULL) continue; else pabone = pchan->parent->bone; - if (PBONE_VISIBLE(arm, pabone)) { + if (PBONE_SELECTABLE(arm, pabone)) { if (!add_to_sel) curbone->flag &= ~BONE_SELECTED; pabone->flag |= BONE_SELECTED; arm->act_bone = pabone; @@ -514,7 +514,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) for (pchan_child = ob->pose->chanbase.first; pchan_child; pchan_child = pchan_child->next) { /* possible we have multiple children, some invisible */ - if (PBONE_VISIBLE(arm, pchan_child->bone)) { + if (PBONE_SELECTABLE(arm, pchan_child->bone)) { if (pchan_child->parent == pchan) { chbone = pchan_child->bone; break; @@ -526,7 +526,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) if (chbone == NULL) continue; #endif - if (PBONE_VISIBLE(arm, chbone)) { + if (PBONE_SELECTABLE(arm, chbone)) { if (!add_to_sel) curbone->flag &= ~BONE_SELECTED; chbone->flag |= BONE_SELECTED; arm->act_bone = chbone; @@ -719,9 +719,7 @@ static int pose_select_same_keyingset(bContext *C, Object *ob, short extend) if (pchan) { /* select if bone is visible and can be affected */ - if ((PBONE_VISIBLE(arm, pchan->bone)) && - (pchan->bone->flag & BONE_UNSELECTABLE) == 0) - { + if (PBONE_SELECTABLE(arm, pchan->bone)) { pchan->bone->flag |= BONE_SELECTED; changed = 1; } @@ -888,16 +886,16 @@ static void pose_copy_menu(Scene *scene) if (pose_has_protected_selected(ob, 0)) { i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ if (i < 25) - nr = pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5"); + nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5"); else - nr = pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4"); + nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4"); } else { i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ if (i < 25) - nr = pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8"); + nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8"); else - nr = pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8"); + nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8"); } if (nr <= 0) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 9c13f4be6a9..afd6bc4c4b5 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -6567,18 +6567,18 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) if (!isSurf) { /* adding curve */ if (obedit == NULL || obedit->type != OB_CURVE) { Curve *cu; - + obedit = ED_object_add_type(C, OB_CURVE, loc, rot, TRUE, layer); newob = 1; cu = (Curve *)obedit->data; cu->flag |= CU_DEFORM_FILL; - + if (type & CU_PRIM_PATH) cu->flag |= CU_PATH | CU_3D; - } + } else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - } + } else { /* adding surface */ if (obedit == NULL || obedit->type != OB_SURF) { obedit = ED_object_add_type(C, OB_SURF, loc, rot, TRUE, layer); @@ -6589,7 +6589,6 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) /* rename here, the undo stack checks name for valid undo pushes */ if (newob) { - if (obedit->type == OB_CURVE) { rename_id((ID *)obedit, get_curve_defname(type)); rename_id((ID *)obedit->data, get_curve_defname(type)); @@ -6599,11 +6598,11 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) rename_id((ID *)obedit->data, get_surf_defname(type)); } } - + /* ED_object_add_type doesnt do an undo, is needed for redo operator on primitive */ if (newob && enter_editmode) ED_undo_push(C, "Enter Editmode"); - + ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); nu = add_nurbs_primitive(C, obedit, mat, type, newob); @@ -6643,12 +6642,11 @@ void CURVE_OT_primitive_bezier_curve_add(wmOperatorType *ot) ot->name = "Add Bezier"; ot->description = "Construct a Bezier Curve"; ot->idname = "CURVE_OT_primitive_bezier_curve_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_bezier_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6666,12 +6664,11 @@ void CURVE_OT_primitive_bezier_circle_add(wmOperatorType *ot) ot->name = "Add Bezier Circle"; ot->description = "Construct a Bezier Circle"; ot->idname = "CURVE_OT_primitive_bezier_circle_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_bezier_circle_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6689,12 +6686,11 @@ void CURVE_OT_primitive_nurbs_curve_add(wmOperatorType *ot) ot->name = "Add Nurbs Curve"; ot->description = "Construct a Nurbs Curve"; ot->idname = "CURVE_OT_primitive_nurbs_curve_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_curve_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6712,12 +6708,11 @@ void CURVE_OT_primitive_nurbs_circle_add(wmOperatorType *ot) ot->name = "Add Nurbs Circle"; ot->description = "Construct a Nurbs Circle"; ot->idname = "CURVE_OT_primitive_nurbs_circle_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_circle_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6735,12 +6730,11 @@ void CURVE_OT_primitive_nurbs_path_add(wmOperatorType *ot) ot->name = "Add Path"; ot->description = "Construct a Path"; ot->idname = "CURVE_OT_primitive_nurbs_path_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_curve_path_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6759,12 +6753,11 @@ void SURFACE_OT_primitive_nurbs_surface_curve_add(wmOperatorType *ot) ot->name = "Add Surface Curve"; ot->description = "Construct a Nurbs surface Curve"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_curve_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_curve_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6782,12 +6775,11 @@ void SURFACE_OT_primitive_nurbs_surface_circle_add(wmOperatorType *ot) ot->name = "Add Surface Circle"; ot->description = "Construct a Nurbs surface Circle"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_circle_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_circle_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6805,12 +6797,11 @@ void SURFACE_OT_primitive_nurbs_surface_surface_add(wmOperatorType *ot) ot->name = "Add Surface Patch"; ot->description = "Construct a Nurbs surface Patch"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_surface_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_surface_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6828,12 +6819,11 @@ void SURFACE_OT_primitive_nurbs_surface_cylinder_add(wmOperatorType *ot) ot->name = "Add Surface Cylinder"; ot->description = "Construct a Nurbs surface Cylinder"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_cylinder_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_cylinder_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6851,12 +6841,11 @@ void SURFACE_OT_primitive_nurbs_surface_sphere_add(wmOperatorType *ot) ot->name = "Add Surface Sphere"; ot->description = "Construct a Nurbs surface Sphere"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_sphere_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_sphere_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -6874,12 +6863,11 @@ void SURFACE_OT_primitive_nurbs_surface_torus_add(wmOperatorType *ot) ot->name = "Add Surface Torus"; ot->description = "Construct a Nurbs surface Torus"; ot->idname = "SURFACE_OT_primitive_nurbs_surface_torus_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_nurbs_surface_torus_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 5909c4fc270..0595f4e18bd 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -278,11 +278,15 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] gp_get_3d_reference(p, rvec); /* method taken from editview.c - mouse_cursor() */ - ED_view3d_project_int_noclip(p->ar, rvec, mval_prj); - - VECSUB2D(mval_f, mval_prj, mval); - ED_view3d_win_to_delta(p->ar, mval_f, dvec); - sub_v3_v3v3(out, rvec, dvec); + /* TODO, use ED_view3d_project_float_global */ + if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + VECSUB2D(mval_f, mval_prj, mval); + ED_view3d_win_to_delta(p->ar, mval_f, dvec); + sub_v3_v3v3(out, rvec, dvec); + } + else { + zero_v3(out); + } } } @@ -808,9 +812,14 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, else if (gps->totpoints == 1) { /* get coordinates */ if (gps->flag & GP_STROKE_3DSPACE) { - ED_view3d_project_int(p->ar, &gps->points->x, xyval); - x0 = xyval[0]; - y0 = xyval[1]; + if (ED_view3d_project_int_global(p->ar, &gps->points->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + x0 = xyval[0]; + y0 = xyval[1]; + } + else { + x0 = V2D_IS_CLIPPED; + y0 = V2D_IS_CLIPPED; + } } else if (gps->flag & GP_STROKE_2DSPACE) { UI_view2d_view_to_region(p->v2d, gps->points->x, gps->points->y, &x0, &y0); @@ -847,13 +856,22 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* get coordinates */ if (gps->flag & GP_STROKE_3DSPACE) { - ED_view3d_project_int(p->ar, &pt1->x, xyval); - x0 = xyval[0]; - y0 = xyval[1]; - - ED_view3d_project_int(p->ar, &pt2->x, xyval); - x1 = xyval[0]; - y1 = xyval[1]; + if (ED_view3d_project_int_global(p->ar, &pt1->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + x0 = xyval[0]; + y0 = xyval[1]; + } + else { + x0 = V2D_IS_CLIPPED; + y0 = V2D_IS_CLIPPED; + } + if (ED_view3d_project_int_global(p->ar, &pt2->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + x1 = xyval[0]; + y1 = xyval[1]; + } + else { + x1 = V2D_IS_CLIPPED; + y1 = V2D_IS_CLIPPED; + } } else if (gps->flag & GP_STROKE_2DSPACE) { UI_view2d_view_to_region(p->v2d, pt1->x, pt1->y, &x0, &y0); diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 4e33404be7e..b9996c87194 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -94,6 +94,7 @@ typedef struct EditBone { /* useful macros */ #define EBONE_VISIBLE(arm, ebone) (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A)) +#define EBONE_SELECTABLE(arm, ebone) (EBONE_VISIBLE(arm, ebone) && !(ebone->flag & BONE_UNSELECTABLE)) #define EBONE_EDITABLE(ebone) (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) /* used in bone_select_hierachy() */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 82d1b24dcef..629e1f4126c 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -137,7 +137,7 @@ int EDBM_backbuf_border_init(struct ViewContext *vc, short xmin, short ymin, sh int EDBM_backbuf_check(unsigned int index); void EDBM_backbuf_free(void); -int EDBM_backbuf_border_mask_init(struct ViewContext *vc, int mcords[][2], short tot, +int EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax); int EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads); @@ -173,7 +173,7 @@ void ED_spacetypes_init(void); /* editmesh_tools.c (could be moved) */ -void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct Object *obedit, struct BMEditMesh *em); +void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct BMEditMesh *em); /* editface.c */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index a08db8072f2..832c9f4b536 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -126,7 +126,6 @@ float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob, const float loc[3], const float rot[3], float primmat[][4]); void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode); -int ED_object_add_generic_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int ED_object_add_generic_get_opts(struct bContext *C, struct wmOperator *op, float loc[3], float rot[3], int *enter_editmode, unsigned int *layer, int *is_view_aligned); diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index 0076b08da99..dee97c7882a 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -61,7 +61,7 @@ void PE_update_object(struct Scene *scene, struct Object *ob, int useflag); int PE_mouse_particles(struct bContext *C, const int mval[2], int extend, int deselect, int toggle); int PE_border_select(struct bContext *C, struct rcti *rect, int select, int extend); int PE_circle_select(struct bContext *C, int selecting, const int mval[2], float rad); -int PE_lasso_select(struct bContext *C, int mcords[][2], short moves, short extend, short select); +int PE_lasso_select(struct bContext *C, const int mcords[][2], const short moves, short extend, short select); void PE_deselect_all_visible(struct PTCacheEdit *edit); /* undo */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 9536dd76581..ebf93baeabc 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -40,6 +40,7 @@ struct BPoint; struct BezTriple; struct BezTriple; struct BoundBox; +struct EditBone; struct ImBuf; struct MVert; struct Main; @@ -113,15 +114,49 @@ void ED_view3d_depth_tag_update(struct RegionView3D *rv3d); /* TODO, these functions work quite differently, we should make them behave in a uniform way * otherwise we can't be sure bugs are not added when we need to move from short->float types for eg * - Campbell */ -void ED_view3d_project_short(struct ARegion *ar, const float co[3], short r_co[2]); -void ED_view3d_project_short_noclip(struct ARegion *ar, const float vec[3], short r_co[2]); -void ED_view3d_project_int(struct ARegion *ar, const float co[3], int r_co[2]); -void ED_view3d_project_int_noclip(struct ARegion *ar, const float co[3], int r_co[2]); -void ED_view3d_project_float(struct ARegion *ar, const float co[3], float r_co[2]); -void ED_view3d_project_float_noclip(struct ARegion *ar, const float co[3], float r_co[2]); + + +/* return values for ED_view3d_project_...() */ +typedef enum { + V3D_PROJ_RET_SUCCESS = 0, + V3D_PROJ_RET_CLIP_NEAR = 1, /* can't avoid this when in perspective mode, (can't avoid) */ + V3D_PROJ_RET_CLIP_BB = 2, /* bounding box clip - RV3D_CLIPPING */ + V3D_PROJ_RET_CLIP_WIN = 3, /* outside window bounds */ + V3D_PROJ_RET_OVERFLOW = 4 /* outside range (mainly for short), (can't avoid) */ +} eV3DProjStatus; + +/* some clipping tests are optional */ +typedef enum { + V3D_PROJ_TEST_NOP = 0, + V3D_PROJ_TEST_CLIP_BB = (1 << 0), + V3D_PROJ_TEST_CLIP_WIN = (1 << 1), +} eV3DProjTest; + + +/* *** short *** */ +eV3DProjStatus ED_view3d_project_short_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], short r_co[2], eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag); + +/* *** int *** */ +eV3DProjStatus ED_view3d_project_int_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], int r_co[2], eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag); + +/* *** float *** */ +eV3DProjStatus ED_view3d_project_float_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], float r_co[2], eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag); + void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]); void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]); +/* Base's get their own function since its a common operation */ +eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base); + void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z); int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend); @@ -136,6 +171,9 @@ void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, int x, int y, int index), void *userData); void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData); void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData); +void armature_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), void *userData); +void pose_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), void *userData); + void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect); void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 313fb1179a6..f466b013c81 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -421,7 +421,6 @@ void uiBlockSetDirection(uiBlock *block, int direction); void uiBlockFlipOrder(uiBlock *block); void uiBlockSetFlag(uiBlock *block, int flag); void uiBlockClearFlag(uiBlock *block, int flag); -void uiBlockSetXOfs(uiBlock *block, int xofs); int uiButGetRetVal(uiBut *but); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 4a4b885a727..3e9709c4f75 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -996,24 +996,20 @@ void ui_fontscale(short *points, float aspect) /* project button or block (but==NULL) to pixels in regionspace */ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, uiBut *but) { - float gx, gy; - float getsizex, getsizey; + rctf rectf = (but)? but->rect: block->rect; - getsizex = ar->winx; - getsizey = ar->winy; + ui_block_to_window_fl(ar, block, &rectf.xmin, &rectf.ymin); + ui_block_to_window_fl(ar, block, &rectf.xmax, &rectf.ymax); - gx = (but ? but->rect.xmin : block->rect.xmin) + (block->panel ? block->panel->ofsx : 0.0f); - gy = (but ? but->rect.ymin : block->rect.ymin) + (block->panel ? block->panel->ofsy : 0.0f); - - rect->xmin = floorf(getsizex * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] + block->winmat[3][0]))); - rect->ymin = floorf(getsizey * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] + block->winmat[3][1]))); - - gx = (but ? but->rect.xmax : block->rect.xmax) + (block->panel ? block->panel->ofsx : 0.0f); - gy = (but ? but->rect.ymax : block->rect.ymax) + (block->panel ? block->panel->ofsy : 0.0f); - - rect->xmax = floorf(getsizex * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] + block->winmat[3][0]))); - rect->ymax = floorf(getsizey * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] + block->winmat[3][1]))); + rectf.xmin -= ar->winrct.xmin; + rectf.ymin -= ar->winrct.ymin; + rectf.xmax -= ar->winrct.xmin; + rectf.ymax -= ar->winrct.ymin; + rect->xmin = floorf(rectf.xmin); + rect->ymin = floorf(rectf.ymin); + rect->xmax = floorf(rectf.xmax); + rect->ymax = floorf(rectf.ymax); } /* uses local copy of style, to scale things down, and allow widgets to change stuff */ @@ -2175,8 +2171,6 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor wm_subwindow_getmatrix(window, region->swinid, block->winmat); wm_subwindow_getsize(window, region->swinid, &getsizex, &getsizey); - /* TODO - investigate why block->winmat[0][0] is negative - * in the image view when viewRedrawForce is called */ block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]); } else { @@ -3438,11 +3432,6 @@ void uiBlockClearFlag(uiBlock *block, int flag) block->flag &= ~flag; } -void uiBlockSetXOfs(uiBlock *block, int xofs) -{ - block->xofs = xofs; -} - void uiButSetFlag(uiBut *but, int flag) { but->flag |= flag; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 132b77576a7..18030df6d0b 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2169,6 +2169,16 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data) } } +int ui_button_open_menu_direction(uiBut *but) +{ + uiHandleButtonData *data = but->active; + + if (data && data->menu) + return data->menu->direction; + + return 0; +} + /* ***************** events for different button types *************** */ static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index f2f8d587970..5af658ce08e 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -317,7 +317,6 @@ struct uiBlock { char tooltipdisabled; /* to avoid tooltip after click */ char endblock; /* uiEndBlock done? */ - float xofs, yofs; /* offset to parent button */ eBlockBoundsCalc bounds_type; /* for doing delayed */ int mx, my; int bounds, minbounds; /* for doing delayed */ @@ -367,7 +366,8 @@ extern void ui_set_but_hsv(uiBut *but); extern void ui_get_but_vectorf(uiBut *but, float vec[3]); extern void ui_set_but_vectorf(uiBut *but, const float vec[3]); -extern void ui_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float mx, float my); +extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect, + const float mx, const float my); extern void ui_get_but_string(uiBut *but, char *str, size_t maxlen); extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen); @@ -420,6 +420,9 @@ struct uiPopupBlockHandle { int menuretval; float retvalue; float retvec[4]; + + /* menu direction */ + int direction; }; uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but); @@ -482,6 +485,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wc extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but); extern void ui_button_active_free(const struct bContext *C, uiBut *but); extern int ui_button_is_active(struct ARegion *ar); +extern int ui_button_open_menu_direction(uiBut *but); /* interface_widgets.c */ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index ff8b28e78f0..c1b369f9495 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1388,6 +1388,14 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, ui_block_to_window_fl(butregion, but->block, &butrct.xmin, &butrct.ymin); ui_block_to_window_fl(butregion, but->block, &butrct.xmax, &butrct.ymax); + /* widget_roundbox_set has this correction too, keep in sync */ + if (but->type != PULLDOWN) { + if (but->flag & UI_BUT_ALIGN_TOP) + butrct.ymax += 1.0f; + if (but->flag & UI_BUT_ALIGN_LEFT) + butrct.xmin -= 1.0f; + } + /* calc block rect */ if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) { if (block->buttons.first) { @@ -1514,9 +1522,6 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, } } - /* apply requested offset in the block */ - xof += block->xofs / block->aspect; - yof += block->yofs / block->aspect; #if 0 /* clamp to window bounds, could be made into an option if its ever annoying */ if ( (offscreen = (block->rect.ymin + yof)) < 0) yof -= offscreen; /* bottom */ @@ -1706,12 +1711,10 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut /* if this is being created from a button */ if (but) { - if (ELEM(but->type, BLOCK, PULLDOWN)) - block->xofs = -2; /* for proper alignment */ - block->aspect = but->block->aspect; ui_block_position(window, butregion, but, block); + handle->direction = block->direction; } else { /* keep a list of these, needed for pulldown menus */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 44cf55a2b21..05a1b373a6c 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -367,6 +367,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str type = idptr.type; if (flag & UI_ID_PREVIEWS) { + template->preview = TRUE; but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, TIP_(template_id_browse_tip(type))); @@ -379,7 +380,6 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str uiButSetFlag(but, UI_BUT_DISABLED); uiLayoutRow(layout, TRUE); - template->preview = 1; } else if (flag & UI_ID_BROWSE) { but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 556bd120428..439f90f06f8 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1889,53 +1889,47 @@ static void ui_hsv_cursor(float x, float y) } -void ui_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float mx, float my) +void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect, + const float mx, const float my) { /* duplication of code... well, simple is better now */ - float centx = BLI_rcti_cent_x_fl(rect); - float centy = BLI_rcti_cent_y_fl(rect); - float radius, dist; - - if (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect)) - radius = (float)BLI_rcti_size_y(rect) / 2; - else - radius = (float)BLI_rcti_size_x(rect) / 2; + const float centx = BLI_rcti_cent_x_fl(rect); + const float centy = BLI_rcti_cent_y_fl(rect); + const float radius = (float)mini(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; + const float m_delta[2] = {mx - centx, my - centy}; + const float dist_squared = len_squared_v2(m_delta); - mx -= centx; - my -= centy; - dist = sqrt(mx * mx + my * my); - if (dist < radius) - *valdist = dist / radius; - else - *valdist = 1.0f; - - *valrad = atan2f(mx, my) / (2.0f * (float)M_PI) + 0.5f; + *val_dist = (dist_squared < (radius * radius)) ? sqrtf(dist_squared) / radius : 1.0f; + *val_rad = atan2f(m_delta[0], m_delta[1]) / (2.0f * (float)M_PI) + 0.5f; } -static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, rcti *rect) +static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *rect) { + const int tot = 32; + const float radstep = 2.0f * (float)M_PI / (float)tot; + + const float centx = BLI_rcti_cent_x_fl(rect); + const float centy = BLI_rcti_cent_y_fl(rect); + float radius = (float)mini(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; + /* gouraud triangle fan */ - float radstep, ang = 0.0f; - float centx, centy, radius, cursor_radius; + const float *hsv_ptr = ui_block_hsv_get(but->block); + float ang = 0.0f; + float cursor_radius; float rgb[3], hsvo[3], hsv[3], col[3], colcent[3]; - int a, tot = 32; + int a; int color_profile = but->block->color_profile; if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) color_profile = FALSE; - radstep = 2.0f * (float)M_PI / (float)tot; - centx = BLI_rcti_cent_x_fl(rect); - centy = BLI_rcti_cent_y_fl(rect); - - if (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect)) - radius = (float)BLI_rcti_size_y(rect) / 2; - else - radius = (float)BLI_rcti_size_x(rect) / 2; - /* color */ ui_get_but_vectorf(but, rgb); - /* copy_v3_v3(hsv, ui_block_hsv_get(but->block)); */ /* UNUSED */ + + /* since we use compat functions on both 'hsv' and 'hsvo', they need to be initialized */ + hsvo[0] = hsv[0] = hsv_ptr[0]; + hsvo[1] = hsv[1] = hsv_ptr[1]; + hsvo[2] = hsv[2] = hsv_ptr[2]; rgb_to_hsv_compat_v(rgb, hsvo); @@ -2708,16 +2702,16 @@ static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat *wcol = wcol_backup; } -static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign)) +static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { if (state & UI_ACTIVE) { uiWidgetBase wtb; - float rad = 0.5f * BLI_rcti_size_y(rect); /* 4.0f */ - + float rad = 0.25f * BLI_rcti_size_y(rect); /* 4.0f */ + widget_init(&wtb); - + /* half rounded */ - round_box_edges(&wtb, UI_CNR_ALL, rect, rad); + round_box_edges(&wtb, roundboxalign, rect, rad); widgetbase_draw(&wtb, wcol); } @@ -3054,9 +3048,12 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) static int widget_roundbox_set(uiBut *but, rcti *rect) { + int roundbox = UI_CNR_ALL; + /* alignment */ - if (but->flag & UI_BUT_ALIGN) { + if ((but->flag & UI_BUT_ALIGN) && but->type != PULLDOWN) { + /* ui_block_position has this correction too, keep in sync */ if (but->flag & UI_BUT_ALIGN_TOP) rect->ymax += 1; if (but->flag & UI_BUT_ALIGN_LEFT) @@ -3064,27 +3061,50 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) switch (but->flag & UI_BUT_ALIGN) { case UI_BUT_ALIGN_TOP: - return UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT; + roundbox = UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT; + break; case UI_BUT_ALIGN_DOWN: - return UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; + roundbox = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; + break; case UI_BUT_ALIGN_LEFT: - return UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT; + roundbox = UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT; + break; case UI_BUT_ALIGN_RIGHT: - return UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT; + roundbox = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT; + break; case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT: - return UI_CNR_TOP_LEFT; + roundbox = UI_CNR_TOP_LEFT; + break; case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT: - return UI_CNR_TOP_RIGHT; + roundbox = UI_CNR_TOP_RIGHT; + break; case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT: - return UI_CNR_BOTTOM_LEFT; + roundbox = UI_CNR_BOTTOM_LEFT; + break; case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT: - return UI_CNR_BOTTOM_RIGHT; + roundbox = UI_CNR_BOTTOM_RIGHT; + break; default: - return 0; + roundbox = 0; + break; } } - return UI_CNR_ALL; + /* align with open menu */ + if (but->active) { + int direction = ui_button_open_menu_direction(but); + + if (direction == UI_TOP) + roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_TOP_LEFT); + else if (direction == UI_DOWN) + roundbox &= ~(UI_CNR_BOTTOM_RIGHT|UI_CNR_BOTTOM_LEFT); + else if (direction == UI_LEFT) + roundbox &= ~(UI_CNR_TOP_LEFT|UI_CNR_BOTTOM_LEFT); + else if (direction == UI_RIGHT) + roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_BOTTOM_RIGHT); + } + + return roundbox; } /* conversion from old to new buttons, so still messy */ diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt index 57be5a2234a..25fb9cb6430 100644 --- a/source/blender/editors/mask/CMakeLists.txt +++ b/source/blender/editors/mask/CMakeLists.txt @@ -30,10 +30,10 @@ set(INC ../../makesrna ../../windowmanager ../../../../intern/guardedalloc - ${GLEW_INCLUDE_PATH} ) set(INC_SYS + ${GLEW_INCLUDE_PATH} ) set(SRC diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index ace427f65ab..603ef818ccb 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -485,7 +485,7 @@ void MASK_OT_select_border(wmOperatorType *ot) WM_operator_properties_gesture_border(ot, TRUE); } -static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short select) +static int do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, short select) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -549,7 +549,7 @@ static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short static int clip_lasso_select_exec(bContext *C, wmOperator *op) { int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short select; diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index a677f1272a3..5fd848ccb13 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -426,7 +426,7 @@ void seam_mark_clear_tface(Scene *scene, short mode) if (me == 0 || me->totpoly == 0) return; if (mode == 0) - mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2"); + mode = pupmenu("Seams %t|Mark Border Seam %x1|Clear Seam %x2"); if (mode != 1 && mode != 2) return; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index fdaddec5246..0cf4ac48bf7 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -64,7 +64,7 @@ static Object *make_prim_init(bContext *C, const char *idname, *state = 0; if (obedit == NULL || obedit->type != OB_MESH) { obedit = ED_object_add_type(C, OB_MESH, loc, rot, FALSE, layer); - + rename_id((ID *)obedit, idname); rename_id((ID *)obedit->data, idname); @@ -103,7 +103,7 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Plane", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -125,12 +125,11 @@ void MESH_OT_primitive_plane_add(wmOperatorType *ot) ot->name = "Add Plane"; ot->description = "Construct a filled planar mesh with 4 vertices"; ot->idname = "MESH_OT_primitive_plane_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_plane_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -145,7 +144,7 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Cube", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -153,7 +152,7 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_cube mat=%m4 size=%f", mat, dia * 2.0f)) { return OPERATOR_CANCELLED; } - + /* BMESH_TODO make plane side this: M_SQRT2 - plane (diameter of 1.41 makes it unit size) */ make_prim_finish(C, obedit, &state, enter_editmode); @@ -166,12 +165,11 @@ void MESH_OT_primitive_cube_add(wmOperatorType *ot) ot->name = "Add Cube"; ot->description = "Construct a cube mesh"; ot->idname = "MESH_OT_primitive_cube_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_cube_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -192,10 +190,10 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) int enter_editmode; int state, cap_end, cap_tri; unsigned int layer; - + cap_end = RNA_enum_get(op->ptr, "fill_type"); cap_tri = (cap_end == 2); - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Circle", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -207,9 +205,9 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); - + return OPERATOR_FINISHED; } @@ -221,15 +219,14 @@ void MESH_OT_primitive_circle_add(wmOperatorType *ot) ot->name = "Add Circle"; ot->description = "Construct a circle mesh"; ot->idname = "MESH_OT_primitive_circle_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_circle_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500); prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); @@ -247,10 +244,10 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) int enter_editmode; int state, cap_end, cap_tri; unsigned int layer; - + cap_end = RNA_enum_get(op->ptr, "end_fill_type"); cap_tri = (cap_end == 2); - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Cylinder", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -266,9 +263,9 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); - + return OPERATOR_FINISHED; } @@ -280,15 +277,14 @@ void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) ot->name = "Add Cylinder"; ot->description = "Construct a cylinder mesh"; ot->idname = "MESH_OT_primitive_cylinder_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_cylinder_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500); prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); @@ -308,10 +304,10 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) int enter_editmode; int state, cap_end, cap_tri; unsigned int layer; - + cap_end = RNA_enum_get(op->ptr, "end_fill_type"); cap_tri = (cap_end == 2); - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Cone", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -324,7 +320,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); return OPERATOR_FINISHED; @@ -338,15 +334,14 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot) ot->name = "Add Cone"; ot->description = "Construct a conic mesh"; ot->idname = "MESH_OT_primitive_cone_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_cone_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500); prop = RNA_def_float(ot->srna, "radius1", 1.0f, 0.0, FLT_MAX, "Radius 1", "", 0.001, 100.00); @@ -368,7 +363,7 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Grid", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -381,8 +376,9 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); + return OPERATOR_FINISHED; } @@ -394,15 +390,14 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) ot->name = "Add Grid"; ot->description = "Construct a grid mesh"; ot->idname = "MESH_OT_primitive_grid_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_grid_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "x_subdivisions", 10, 3, INT_MAX, "X Subdivisions", "", 3, 1000); RNA_def_int(ot->srna, "y_subdivisions", 10, 3, INT_MAX, "Y Subdivisions", "", 3, 1000); @@ -420,19 +415,20 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) int enter_editmode; int state, view_aligned; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, &view_aligned); if (!view_aligned) rot[0] += (float)M_PI / 2.0f; - + obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_monkey mat=%m4", mat)) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); + return OPERATOR_FINISHED; } @@ -442,12 +438,11 @@ void MESH_OT_primitive_monkey_add(wmOperatorType *ot) ot->name = "Add Monkey"; ot->description = "Construct a Suzanne mesh"; ot->idname = "MESH_OT_primitive_monkey_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_monkey_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -462,7 +457,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Sphere", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -474,7 +469,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); return OPERATOR_FINISHED; @@ -488,15 +483,14 @@ void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) ot->name = "Add UV Sphere"; ot->description = "Construct a UV sphere mesh"; ot->idname = "MESH_OT_primitive_uv_sphere_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_uvsphere_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "segments", 32, 3, INT_MAX, "Segments", "", 3, 500); RNA_def_int(ot->srna, "ring_count", 16, 3, INT_MAX, "Rings", "", 3, 500); @@ -514,7 +508,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) int enter_editmode; int state; unsigned int layer; - + ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); obedit = make_prim_init(C, "Icosphere", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); @@ -527,10 +521,10 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) { return OPERATOR_CANCELLED; } - + make_prim_finish(C, obedit, &state, enter_editmode); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) @@ -541,15 +535,14 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) ot->name = "Add Ico Sphere"; ot->description = "Construct an Icosphere mesh"; ot->idname = "MESH_OT_primitive_ico_sphere_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = add_primitive_icosphere_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* props */ RNA_def_int(ot->srna, "subdivisions", 2, 1, INT_MAX, "Subdivisions", "", 1, 8); prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 1dcbf574b44..f0ecdfe640f 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -73,6 +73,9 @@ #define KMAXDIST 10 /* max mouse distance from edge before not detecting it */ +#define KNIFE_FLT_EPS 0.00001f +#define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS) + typedef struct KnifeColors { unsigned char line[3]; unsigned char edge[3]; @@ -430,7 +433,7 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd, KnifeEdge *kfe, float float perc, cageco[3], l12; l12 = len_v3v3(kfe->v1->co, kfe->v2->co); - if (l12 < FLT_EPSILON * 80) { + if (l12 < KNIFE_FLT_EPS) { copy_v3_v3(cageco, kfe->v1->cageco); } else { @@ -446,8 +449,8 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd, KnifeEdge *kfe, float } else { /* kfe cuts across an existing face. - If v1 and v2 are in multiple faces together (e.g., if they - are in doubled polys) then this arbitrarily chooses one of them */ + * If v1 and v2 are in multiple faces together (e.g., if they + * are in doubled polys) then this arbitrarily chooses one of them */ f = knife_find_common_face(&kfe->v1->faces, &kfe->v2->faces); if (f) knife_append_list(kcd, &newkfe->v2->faces, f); @@ -587,7 +590,7 @@ static void knife_sort_linehits(KnifeTool_OpData *kcd) * successor faces connected to the linehits at either end of the range */ for (i = 0; i < kcd->totlinehit - 1; i = nexti) { for (j = i + 1; j < kcd->totlinehit; j++) { - if (fabsf(kcd->linehits[j].l - kcd->linehits[i].l) > 80 * FLT_EPSILON) + if (fabsf(kcd->linehits[j].l - kcd->linehits[i].l) > KNIFE_FLT_EPS) break; } nexti = j; @@ -795,7 +798,7 @@ static void knife_add_cut(KnifeTool_OpData *kcd) for (i = 0; i < kcd->totlinehit; i++, (lastlh = lh), lh++) { BMFace *f = lastlh ? lastlh->f : lh->f; - if (lastlh && len_v3v3(lastlh->hit, lh->hit) == 0.0f) { + if (lastlh && len_squared_v3v3(lastlh->hit, lh->hit) == 0.0f) { if (!firstlh) firstlh = lastlh; continue; @@ -814,13 +817,13 @@ static void knife_add_cut(KnifeTool_OpData *kcd) lastlh = firstlh = NULL; } - if (len_v3v3(kcd->prev.cage, lh->realhit) < FLT_EPSILON * 80) + if (len_squared_v3v3(kcd->prev.cage, lh->realhit) < KNIFE_FLT_EPS_SQUARED) continue; - if (len_v3v3(kcd->curr.cage, lh->realhit) < FLT_EPSILON * 80) + if (len_squared_v3v3(kcd->curr.cage, lh->realhit) < KNIFE_FLT_EPS_SQUARED) continue; /* first linehit may be down face parallel to view */ - if (!lastlh && fabsf(lh->l) < FLT_EPSILON * 80) + if (!lastlh && fabsf(lh->l) < KNIFE_FLT_EPS) continue; if (kcd->prev.is_space) { @@ -841,7 +844,7 @@ static void knife_add_cut(KnifeTool_OpData *kcd) copy_v3_v3(kcd->curr.cage, lh->cagehit); /* don't draw edges down faces parallel to view */ - if (lastlh && fabsf(lastlh->l - lh->l) < FLT_EPSILON * 80) { + if (lastlh && fabsf(lastlh->l - lh->l) < KNIFE_FLT_EPS) { kcd->prev = kcd->curr; continue; } @@ -1042,6 +1045,9 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) } if (kcd->totlinehit > 0) { + const float vthresh4 = kcd->vthresh / 4.0f; + const float vthresh4_squared = vthresh4 * vthresh4; + BMEdgeHit *lh; int i; @@ -1060,12 +1066,12 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) knife_project_v3(kcd, lh->kfe->v2->cageco, sv2); knife_project_v3(kcd, lh->cagehit, lh->schit); - if (len_v2v2(lh->schit, sv1) < kcd->vthresh / 4.0f) { + if (len_squared_v2v2(lh->schit, sv1) < vthresh4_squared) { copy_v3_v3(lh->cagehit, lh->kfe->v1->cageco); glVertex3fv(lh->cagehit); lh->v = lh->kfe->v1; } - else if (len_v2v2(lh->schit, sv2) < kcd->vthresh / 4.0f) { + else if (len_squared_v2v2(lh->schit, sv2) < vthresh4_squared) { copy_v3_v3(lh->cagehit, lh->kfe->v2->cageco); glVertex3fv(lh->cagehit); lh->v = lh->kfe->v2; @@ -1134,11 +1140,11 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) static float len_v3_tri_side_max(const float v1[3], const float v2[3], const float v3[3]) { - const float s1 = len_v3v3(v1, v2); - const float s2 = len_v3v3(v2, v3); - const float s3 = len_v3v3(v3, v1); + const float s1 = len_squared_v3v3(v1, v2); + const float s2 = len_squared_v3v3(v2, v3); + const float s3 = len_squared_v3v3(v3, v1); - return MAX3(s1, s2, s3); + return sqrtf(MAX3(s1, s2, s3)); } static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, @@ -1156,7 +1162,7 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, /* for comparing distances, error of intersection depends on triangle scale. * need to scale down before squaring for accurate comparison */ - const float depsilon = 50 *FLT_EPSILON *len_v3_tri_side_max(v1, v2, v3); + const float depsilon = (KNIFE_FLT_EPS / 2.0f) * len_v3_tri_side_max(v1, v2, v3); const float depsilon_squared = depsilon * depsilon; copy_v3_v3(cos + 0, v1); @@ -1983,7 +1989,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd) ScanFillFace *sf_tri; ScanFillVert *sf_vert, *sf_vert_last; int j; - float rndscale = FLT_EPSILON * 25; + float rndscale = (KNIFE_FLT_EPS / 4.0f); f = faces[i]; BLI_smallhash_init(hash); @@ -3056,14 +3062,9 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf) static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event) { - Object *obedit; + Object *obedit = CTX_data_edit_object(C); KnifeTool_OpData *kcd = op->customdata; - if (!C) { - return OPERATOR_FINISHED; - } - - obedit = CTX_data_edit_object(C); if (!obedit || obedit->type != OB_MESH || BMEdit_FromObject(obedit) != kcd->em) { knifetool_exit(C, op); ED_area_headerprint(CTX_wm_area(C), NULL); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 4d4cc1e2ed1..801c9382c26 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -131,7 +131,7 @@ unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0; /* set in dr static char *selbuf = NULL; /* opengl doesn't support concave... */ -static void draw_triangulated(int mcords[][2], short tot) +static void draw_triangulated(const int mcords[][2], const short tot) { ListBase lb = {NULL, NULL}; DispList *dl; @@ -227,7 +227,7 @@ void EDBM_backbuf_free(void) * - grab again and compare * returns 'OK' */ -int EDBM_backbuf_border_mask_init(ViewContext *vc, int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) +int EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) { unsigned int *dr, *drm; struct ImBuf *buf, *bufmask; @@ -1050,21 +1050,27 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) /* sets as active, useful for other tools */ if (select) { if (em->selectmode & SCE_SELECT_VERTEX) { - /* Find nearest vert from mouse. */ + /* Find nearest vert from mouse + * (initialize to large values incase only one vertex can be projected) */ float v1_co[2], v2_co[2]; + float length_1 = FLT_MAX; + float length_2 = FLT_MAX; /* We can't be sure this has already been set... */ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); - ED_view3d_project_float_noclip(vc.ar, eed->v1->co, v1_co); - ED_view3d_project_float_noclip(vc.ar, eed->v2->co, v2_co); + + if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + length_1 = len_squared_v2v2(mvalf, v1_co); + } + + if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + length_2 = len_squared_v2v2(mvalf, v2_co); + } #if 0 printf("mouse to v1: %f\nmouse to v2: %f\n", len_squared_v2v2(mvalf, v1_co), len_squared_v2v2(mvalf, v2_co)); #endif - if (len_squared_v2v2(mvalf, v1_co) < len_squared_v2v2(mvalf, v2_co)) - BM_select_history_store(em->bm, eed->v1); - else - BM_select_history_store(em->bm, eed->v2); + BM_select_history_store(em->bm, (length_1 < length_2) ? eed->v1 : eed->v2); } else if (em->selectmode & SCE_SELECT_EDGE) { BM_select_history_store(em->bm, eed); @@ -1084,12 +1090,13 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) float co[2], tdist; BM_face_calc_center_mean(f, cent); - ED_view3d_project_float_noclip(vc.ar, cent, co); - tdist = len_squared_v2v2(mvalf, co); - if (tdist < best_dist) { -/* printf("Best face: %p (%f)\n", f, tdist);*/ - best_dist = tdist; - efa = f; + if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + tdist = len_squared_v2v2(mvalf, co); + if (tdist < best_dist) { +/* printf("Best face: %p (%f)\n", f, tdist);*/ + best_dist = tdist; + efa = f; + } } } } diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index bd1d13f3528..e42b95c6013 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -381,22 +381,23 @@ static BMEdge *vtx_slide_nrst_in_frame(VertexSlideOp *vso, const float mval[2]) BMEdge *edge = NULL; float v1_proj[3], v2_proj[3]; - float dist = 0; float min_dist = FLT_MAX; for (i = 0; i < vso->disk_edges; i++) { edge = vso->edge_frame[i]; mul_v3_m4v3(v1_proj, vso->obj->obmat, edge->v1->co); - ED_view3d_project_float_noclip(vso->active_region, v1_proj, v1_proj); - mul_v3_m4v3(v2_proj, vso->obj->obmat, edge->v2->co); - ED_view3d_project_float_noclip(vso->active_region, v2_proj, v2_proj); - dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj); - if (dist < min_dist) { - min_dist = dist; - cl_edge = edge; + /* we could use ED_view3d_project_float_object here, but for now dont since we dont have the context */ + if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && + (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + { + const float dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj); + if (dist < min_dist) { + min_dist = dist; + cl_edge = edge; + } } } } @@ -448,17 +449,21 @@ static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event) /* Calculate interpolation value for preview */ float t_val; - float mval_float[] = { (float)event->mval[0], (float)event->mval[1]}; + float mval_float[2] = { (float)event->mval[0], (float)event->mval[1]}; float closest_2d[2]; other = BM_edge_other_vert(edge, vso->start_vtx); /* Project points onto screen and do interpolation in 2D */ mul_v3_m4v3(start_vtx_proj, vso->obj->obmat, vso->start_vtx->co); - ED_view3d_project_float_noclip(vso->active_region, start_vtx_proj, start_vtx_proj); - mul_v3_m4v3(edge_other_proj, vso->obj->obmat, other->co); - ED_view3d_project_float_noclip(vso->active_region, edge_other_proj, edge_other_proj); + + if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || + (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS)) + { + /* not much we can do here */ + return; + } closest_to_line_v2(closest_2d, mval_float, start_vtx_proj, edge_other_proj); @@ -470,7 +475,7 @@ static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event) if (edge_len <= 0.0f) edge_len = VTX_SLIDE_SNAP_THRSH; - edge_len = (len_v3v3(edge->v1->co, edge->v2->co) * VTX_SLIDE_SNAP_THRSH) / edge_len; + edge_len = (BM_edge_calc_length(edge) * VTX_SLIDE_SNAP_THRSH) / edge_len; vso->snap_threshold = edge_len; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 14f11955f82..b78fa663936 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -153,19 +153,22 @@ void MESH_OT_subdivide(wmOperatorType *ot) } -void EMBM_project_snap_verts(bContext *C, ARegion *ar, Object *obedit, BMEditMesh *em) +void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) { + Object *obedit = em->ob; BMIter iter; BMVert *eve; + ED_view3d_init_mats_rv3d(obedit, ar->regiondata); + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - float mval[2], vec[3], no_dummy[3]; + float mval[2], co_proj[3], no_dummy[3]; int dist_dummy; - mul_v3_m4v3(vec, obedit->obmat, eve->co); - ED_view3d_project_float_noclip(ar, vec, mval); - if (snapObjectsContext(C, mval, &dist_dummy, vec, no_dummy, SNAP_NOT_OBEDIT)) { - mul_v3_m4v3(eve->co, obedit->imat, vec); + if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (snapObjectsContext(C, mval, &dist_dummy, co_proj, no_dummy, SNAP_NOT_OBEDIT)) { + mul_v3_m4v3(eve->co, obedit->imat, co_proj); + } } } } @@ -439,16 +442,17 @@ static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOpe zero_v3(nor); + /* XXX If those popup menus were to be enabled again, please get rid of this "menu string" syntax! */ if (em->selectmode & SCE_SELECT_VERTEX) { if (em->bm->totvertsel == 0) nr = 0; else if (em->bm->totvertsel == 1) nr = 4; else if (em->bm->totedgesel == 0) nr = 4; else if (em->bm->totfacesel == 0) - nr = 3; // pupmenu("Extrude %t|Only Edges%x3|Only Vertices%x4"); + nr = 3; /* pupmenu("Extrude %t|Only Edges %x3|Only Vertices %x4"); */ else if (em->bm->totfacesel == 1) - nr = 1; // pupmenu("Extrude %t|Region %x1|Only Edges%x3|Only Vertices%x4"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Only Edges% x3|Only Vertices %x4"); */ else - nr = 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3|Only Vertices%x4"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2|Only Edges %x3|Only Vertices %x4"); */ } else if (em->selectmode & SCE_SELECT_EDGE) { if (em->bm->totedgesel == 0) nr = 0; @@ -458,16 +462,16 @@ static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOpe else if (em->totedgesel == 1) nr = 3; else if (em->totfacesel == 0) nr = 3; else if (em->totfacesel == 1) - nr = 1; // pupmenu("Extrude %t|Region %x1|Only Edges%x3"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Only Edges %x3"); */ else - nr = 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2|Only Edges %x3"); */ #endif } else { if (em->bm->totfacesel == 0) nr = 0; else if (em->bm->totfacesel == 1) nr = 1; else - nr = 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2"); + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2"); */ } if (nr < 1) return 'g'; @@ -730,7 +734,10 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent short use_proj; em_setup_viewcontext(C, &vc); - + + ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); + + use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); @@ -759,26 +766,26 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent BM_ITER_MESH (eed, &iter, vc.em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { float co1[3], co2[3]; - mul_v3_m4v3(co1, vc.obedit->obmat, eed->v1->co); - mul_v3_m4v3(co2, vc.obedit->obmat, eed->v2->co); - ED_view3d_project_float_noclip(vc.ar, co1, co1); - ED_view3d_project_float_noclip(vc.ar, co2, co2); - - /* 2D rotate by 90d while adding. - * (x, y) = (y, -x) - * - * accumulate the screenspace normal in 2D, - * with screenspace edge length weighting the result. */ - if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) { - nor[0] += (co1[1] - co2[1]); - nor[1] += -(co1[0] - co2[0]); - } - else { - nor[0] += (co2[1] - co1[1]); - nor[1] += -(co2[0] - co1[0]); + + if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && + (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + { + /* 2D rotate by 90d while adding. + * (x, y) = (y, -x) + * + * accumulate the screenspace normal in 2D, + * with screenspace edge length weighting the result. */ + if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) { + nor[0] += (co1[1] - co2[1]); + nor[1] += -(co1[0] - co2[0]); + } + else { + nor[0] += (co2[1] - co1[1]); + nor[1] += -(co2[0] - co1[0]); + } + done = TRUE; } } - done = TRUE; } if (done) { @@ -835,7 +842,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent /* also project the source, for retopo workflow */ if (use_proj) - EMBM_project_snap_verts(C, vc.ar, vc.obedit, vc.em); + EMBM_project_snap_verts(C, vc.ar, vc.em); } edbm_extrude_edge(vc.obedit, vc.em, BM_ELEM_SELECT, nor); @@ -868,7 +875,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent } if (use_proj) - EMBM_project_snap_verts(C, vc.ar, vc.obedit, vc.em); + EMBM_project_snap_verts(C, vc.ar, vc.em); /* This normally happens when pushing undo but modal operators * like this one don't push undo data until after modal mode is @@ -2140,7 +2147,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) } /* if those are not found, because vertices where selected by e.g. - border or circle select, find two selected vertices */ + * border or circle select, find two selected vertices */ if (svert == NULL) { BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) @@ -2150,7 +2157,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) else if (evert == NULL) evert = eve; else { /* more than two vertices are selected, - show warning message and cancel operator */ + * show warning message and cancel operator */ svert = evert = NULL; break; } @@ -2526,11 +2533,6 @@ void MESH_OT_solidify(wmOperatorType *ot) RNA_def_property_ui_range(prop, -10, 10, 0.1, 4); } -typedef struct CutCurve { - float x; - float y; -} CutCurve; - /* ******************************************************************** */ /* Knife Subdivide Tool. Subdivides edges intersected by a mouse trail * drawn by user. @@ -2564,15 +2566,14 @@ static EnumPropertyItem knife_items[] = { /* bm_edge_seg_isect() Determines if and where a mouse trail intersects an BMEdge */ -static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, - struct GHash *gh, int *isected) +static float bm_edge_seg_isect(const float sco_a[2], const float sco_b[2], + float (*mouse_path)[2], int len, char mode, int *isected) { #define MAXSLOPE 100000 float x11, y11, x12 = 0, y12 = 0, x2max, x2min, y2max; float y2min, dist, lastdist = 0, xdiff2, xdiff1; float m1, b1, m2, b2, x21, x22, y21, y22, xi; float yi, x1min, x1max, y1max, y1min, perc = 0; - float *scr; float threshold = 0.0; int i; @@ -2580,13 +2581,11 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, // XXX threshold = scene->toolsettings->select_thresh / 100; /* Get screen coords of verts */ - scr = BLI_ghash_lookup(gh, e->v1); - x21 = scr[0]; - y21 = scr[1]; + x21 = sco_a[0]; + y21 = sco_a[1]; - scr = BLI_ghash_lookup(gh, e->v2); - x22 = scr[0]; - y22 = scr[1]; + x22 = sco_b[0]; + y22 = sco_b[1]; xdiff2 = (x22 - x21); if (xdiff2) { @@ -2608,11 +2607,11 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, y11 = y12; } else { - x11 = c[i].x; - y11 = c[i].y; + x11 = mouse_path[i][0]; + y11 = mouse_path[i][1]; } - x12 = c[i].x; - y12 = c[i].y; + x12 = mouse_path[i][0]; + y12 = mouse_path[i][1]; /* test e->v1 */ if ((x11 == x21 && y11 == y21) || (x12 == x21 && y12 == y21)) { @@ -2636,11 +2635,11 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, y11 = y12; } else { - x11 = c[i].x; - y11 = c[i].y; + x11 = mouse_path[i][0]; + y11 = mouse_path[i][1]; } - x12 = c[i].x; - y12 = c[i].y; + x12 = mouse_path[i][0]; + y12 = mouse_path[i][1]; /* Perp. Distance from point to line */ if (m2 != MAXSLOPE) dist = (y12 - m2 * x12 - b2); /* /sqrt(m2 * m2 + 1); Only looking for */ @@ -2718,9 +2717,9 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, lastdist = dist; } return perc; -} +} -#define MAX_CUTS 2048 +#define ELE_EDGE_CUT 1 static int edbm_knife_cut_exec(bContext *C, wmOperator *op) { @@ -2732,76 +2731,93 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) BMIter iter; BMEdge *be; BMOperator bmop; - CutCurve curve[MAX_CUTS]; - struct GHash *gh; float isect = 0.0f; - float *scr, co[4]; - int len = 0, isected; + int len = 0, isected, i; short numcuts = 1, mode = RNA_int_get(op->ptr, "type"); + + /* allocd vars */ + float (*screen_vert_coords)[2], (*sco)[2], (*mouse_path)[2]; /* edit-object needed for matrix, and ar->regiondata for projections to work */ if (ELEM3(NULL, obedit, ar, ar->regiondata)) return OPERATOR_CANCELLED; if (bm->totvertsel < 2) { - //error("No edges are selected to operate on"); + BKE_report(op->reports, RPT_ERROR, "No edges are selected to operate on"); + return OPERATOR_CANCELLED; + } + + len = RNA_collection_length(op->ptr, "path"); + + if (len < 2) { + BKE_report(op->reports, RPT_ERROR, "Mouse path too short"); return OPERATOR_CANCELLED; } + mouse_path = MEM_mallocN(len * sizeof(*mouse_path), __func__); + /* get the cut curve */ RNA_BEGIN(op->ptr, itemptr, "path") { - RNA_float_get_array(&itemptr, "loc", (float *)&curve[len]); - len++; - if (len >= MAX_CUTS) { - break; - } + RNA_float_get_array(&itemptr, "loc", (float *)&mouse_path[len]); } RNA_END; - - if (len < 2) { - return OPERATOR_CANCELLED; - } + + /* for ED_view3d_project_float_object */ + ED_view3d_init_mats_rv3d(obedit, ar->regiondata); + + /* TODO, investigate using index lookup for screen_vert_coords() rather then a hash table */ /* the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer */ - gh = BLI_ghash_ptr_new("knife cut exec"); - for (bv = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); bv; bv = BM_iter_step(&iter)) { - scr = MEM_mallocN(sizeof(float) * 2, "Vertex Screen Coordinates"); - copy_v3_v3(co, bv->co); - co[3] = 1.0f; - mul_m4_v4(obedit->obmat, co); - ED_view3d_project_float(ar, co, scr); - BLI_ghash_insert(gh, bv, scr); + screen_vert_coords = sco = MEM_mallocN(bm->totvert * sizeof(float) * 2, __func__); + + BM_ITER_MESH_INDEX (bv, &iter, bm, BM_VERTS_OF_MESH, i) { + if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + copy_v2_fl(*sco, FLT_MAX); /* set error value */ + } + BM_elem_index_set(bv, i); /* set_ok */ + sco++; + } + bm->elem_index_dirty &= ~BM_VERT; /* clear dirty flag */ if (!EDBM_op_init(em, &bmop, op, "subdivide_edges")) { + MEM_freeN(mouse_path); + MEM_freeN(screen_vert_coords); return OPERATOR_CANCELLED; } /* store percentage of edge cut for KNIFE_EXACT here.*/ for (be = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); be; be = BM_iter_step(&iter)) { + int is_cut = FALSE; if (BM_elem_flag_test(be, BM_ELEM_SELECT)) { - isect = bm_edge_seg_isect(be, curve, len, mode, gh, &isected); - - if (isect != 0.0f) { - if (mode != KNIFE_MULTICUT && mode != KNIFE_MIDPOINT) { - BMO_slot_map_float_insert(bm, &bmop, - "edgepercents", - be, isect); - + const float *sco_a = screen_vert_coords[BM_elem_index_get(be->v1)]; + const float *sco_b = screen_vert_coords[BM_elem_index_get(be->v2)]; + + /* check for error value (vert cant be projected) */ + if ((sco_a[0] != FLT_MAX) && (sco_b[0] != FLT_MAX)) { + isect = bm_edge_seg_isect(sco_a, sco_b, mouse_path, len, mode, &isected); + + if (isect != 0.0f) { + if (mode != KNIFE_MULTICUT && mode != KNIFE_MIDPOINT) { + BMO_slot_map_float_insert(bm, &bmop, + "edgepercents", + be, isect); + } } - BMO_elem_flag_enable(bm, be, 1); } - else { - BMO_elem_flag_disable(bm, be, 1); - } - } - else { - BMO_elem_flag_disable(bm, be, 1); } + + BMO_elem_flag_set(bm, be, ELE_EDGE_CUT, is_cut); } - - BMO_slot_buffer_from_enabled_flag(bm, &bmop, "edges", BM_EDGE, 1); + + + /* free all allocs */ + MEM_freeN(screen_vert_coords); + MEM_freeN(mouse_path); + + + BMO_slot_buffer_from_enabled_flag(bm, &bmop, "edges", BM_EDGE, ELE_EDGE_CUT); if (mode == KNIFE_MIDPOINT) numcuts = 1; BMO_slot_int_set(&bmop, "numcuts", numcuts); @@ -2816,14 +2832,14 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) if (!EDBM_op_finish(em, &bmop, op, TRUE)) { return OPERATOR_CANCELLED; } - - BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN); EDBM_update_generic(C, em, TRUE); return OPERATOR_FINISHED; } +#undef ELE_EDGE_CUT + void MESH_OT_knife_cut(wmOperatorType *ot) { PropertyRNA *prop; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index ef826c07cc1..42d82fff38e 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1237,11 +1237,12 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2], const int v_idx = me->mloop[mp->loopstart + fidx].v; dm->getVertCo(dm, v_idx, co); mul_m4_v3(ob->obmat, co); - ED_view3d_project_float_noclip(ar, co, sco); - len = len_squared_v2v2(mval_f, sco); - if (len < len_best) { - len_best = len; - v_idx_best = v_idx; + if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + len = len_squared_v2v2(mval_f, sco); + if (len < len_best) { + len_best = len; + v_idx_best = v_idx; + } } } while (fidx--); } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 4942b9e4390..43a32cd662e 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -43,6 +43,7 @@ #include "DNA_meta_types.h" #include "DNA_object_fluidsim.h" #include "DNA_object_force.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_speaker_types.h" #include "DNA_vfont_types.h" @@ -110,7 +111,7 @@ #include "object_intern.h" /* this is an exact copy of the define in rna_lamp.c - * kept here because of linking order. + * kept here because of linking order. * Icons are only defined here */ EnumPropertyItem lamp_type_items[] = { {LA_LOCAL, "POINT", ICON_LAMP_POINT, "Point", "Omnidirectional point light source"}, @@ -121,6 +122,23 @@ EnumPropertyItem lamp_type_items[] = { {0, NULL, 0, NULL, NULL} }; +/* copy from rna_object_force.c */ +static EnumPropertyItem field_type_items[] = { + {PFIELD_FORCE, "FORCE", ICON_FORCE_FORCE, "Force", ""}, + {PFIELD_WIND, "WIND", ICON_FORCE_WIND, "Wind", ""}, + {PFIELD_VORTEX, "VORTEX", ICON_FORCE_VORTEX, "Vortex", ""}, + {PFIELD_MAGNET, "MAGNET", ICON_FORCE_MAGNETIC, "Magnetic", ""}, + {PFIELD_HARMONIC, "HARMONIC", ICON_FORCE_HARMONIC, "Harmonic", ""}, + {PFIELD_CHARGE, "CHARGE", ICON_FORCE_CHARGE, "Charge", ""}, + {PFIELD_LENNARDJ, "LENNARDJ", ICON_FORCE_LENNARDJONES, "Lennard-Jones", ""}, + {PFIELD_TEXTURE, "TEXTURE", ICON_FORCE_TEXTURE, "Texture", ""}, + {PFIELD_GUIDE, "GUIDE", ICON_FORCE_CURVE, "Curve Guide", ""}, + {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, + {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""}, + {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""}, + {0, NULL, 0, NULL, NULL} +}; + /************************** Exported *****************************/ void ED_object_location_from_view(bContext *C, float loc[3]) @@ -128,7 +146,7 @@ void ED_object_location_from_view(bContext *C, float loc[3]) View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); float *cursor; - + cursor = give_cursor(scene, v3d); copy_v3_v3(loc, cursor); @@ -152,44 +170,44 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], { Object *ob = base->object; Scene *scene = CTX_data_scene(C); - + if (!scene) return; - + if (loc) copy_v3_v3(ob->loc, loc); - + if (rot) copy_v3_v3(ob->rot, rot); - + BKE_object_where_is_calc(scene, ob); } -/* uses context to figure out transform for primitive */ -/* returns standard diameter */ +/* Uses context to figure out transform for primitive. + * Returns standard diameter. */ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, const float loc[3], const float rot[3], float primmat[][4]) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3]; - + unit_m4(primmat); - + eul_to_mat3(rmat, rot); invert_m3(rmat); - + /* inverse transform for initial rotation and object */ copy_m3_m4(mat, obedit->obmat); mul_m3_m3m3(cmat, rmat, mat); invert_m3_m3(imat, cmat); copy_m4_m3(primmat, imat); - + /* center */ copy_v3_v3(primmat[3], loc); sub_v3_v3v3(primmat[3], primmat[3], obedit->obmat[3]); invert_m3_m3(imat, mat); mul_m3_v3(imat, primmat[3]); - + if (v3d) return ED_view3d_grid_scale(scene, v3d, NULL); @@ -206,7 +224,7 @@ static void view_align_update(struct Main *UNUSED(main), struct Scene *UNUSED(sc void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode) { PropertyRNA *prop; - + /* note: this property gets hidden for add-camera operator */ prop = RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view"); RNA_def_property_update_runtime(prop, view_align_update); @@ -216,112 +234,112 @@ void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode) "Enter editmode when adding this object"); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } - + prop = RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Location for the newly added object", -FLT_MAX, FLT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", "Rotation for the newly added object", (float)-M_PI * 2.0f, (float)M_PI * 2.0f); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - + prop = RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -static void object_add_generic_invoke_options(bContext *C, wmOperator *op) +int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], float rot[3], + int *enter_editmode, unsigned int *layer, int *is_view_aligned) { - if (RNA_struct_find_property(op->ptr, "enter_editmode")) /* optional */ - if (!RNA_struct_property_is_set(op->ptr, "enter_editmode")) - RNA_boolean_set(op->ptr, "enter_editmode", U.flag & USER_ADD_EDITMODE); - - if (!RNA_struct_property_is_set(op->ptr, "location")) { - float loc[3]; - - ED_object_location_from_view(C, loc); - RNA_float_set_array(op->ptr, "location", loc); - } - - if (!RNA_struct_property_is_set(op->ptr, "layers")) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - int a, values[20], layer; + View3D *v3d = CTX_wm_view3d(C); - if (v3d) { - layer = (v3d->scenelock && !v3d->localvd) ? scene->layact : v3d->layact; - } + /* Switch to Edit mode? */ + if (RNA_struct_find_property(op->ptr, "enter_editmode")) { /* optional */ + int _enter_editmode; + if (!enter_editmode) + enter_editmode = &_enter_editmode; + + if (RNA_struct_property_is_set(op->ptr, "enter_editmode") && enter_editmode) + *enter_editmode = RNA_boolean_get(op->ptr, "enter_editmode"); else { - layer = scene->layact; + *enter_editmode = U.flag & USER_ADD_EDITMODE; + RNA_boolean_set(op->ptr, "enter_editmode", *enter_editmode); } + } - for (a = 0; a < 20; a++) { - values[a] = (layer & (1 << a)); + /* Get layers! */ + { + int a, layer_values[20]; + unsigned int _layer; + if (!layer) + layer = &_layer; + + if (RNA_struct_property_is_set(op->ptr, "layers")) { + RNA_boolean_get_array(op->ptr, "layers", layer_values); + *layer = 0; + for (a = 0; a < 20; a++) { + if (layer_values[a]) + *layer |= (1 << a); + } + } + else { + Scene *scene = CTX_data_scene(C); + if (v3d) + *layer = (v3d->scenelock && !v3d->localvd) ? scene->layact : v3d->layact; + else + *layer = scene->layact; + for (a = 0; a < 20; a++) { + layer_values[a] = *layer & (1 << a); + } + RNA_boolean_set_array(op->ptr, "layers", layer_values); } - RNA_boolean_set_array(op->ptr, "layers", values); + /* in local view we additionally add local view layers, + * not part of operator properties */ + if (v3d && v3d->localvd) + *layer |= v3d->lay; } -} -int ED_object_add_generic_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) -{ - object_add_generic_invoke_options(C, op); - return op->type->exec(C, op); -} - -int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], float rot[3], - int *enter_editmode, unsigned int *layer, int *is_view_aligned) -{ - View3D *v3d = CTX_wm_view3d(C); - int a, layer_values[20]; - int view_align; - - *enter_editmode = FALSE; - if (RNA_struct_find_property(op->ptr, "enter_editmode") && RNA_boolean_get(op->ptr, "enter_editmode")) { - *enter_editmode = TRUE; - } + /* Location! */ + { + float _loc[3]; + if (!loc) + loc = _loc; - if (RNA_struct_property_is_set(op->ptr, "layers")) { - RNA_boolean_get_array(op->ptr, "layers", layer_values); - *layer = 0; - for (a = 0; a < 20; a++) { - if (layer_values[a]) - *layer |= (1 << a); - else - *layer &= ~(1 << a); + if (RNA_struct_property_is_set(op->ptr, "location")) { + RNA_float_get_array(op->ptr, "location", loc); + } + else { + ED_object_location_from_view(C, loc); + RNA_float_set_array(op->ptr, "location", loc); } - } - else { - /* not set, use the scenes layers */ - Scene *scene = CTX_data_scene(C); - *layer = scene->layact; } - /* in local view we additionally add local view layers, - * not part of operator properties */ - if (v3d && v3d->localvd) - *layer |= v3d->lay; + /* Rotation! */ + { + int _is_view_aligned; + float _rot[3]; + if (!is_view_aligned) + is_view_aligned = &_is_view_aligned; + if (!rot) + rot = _rot; + + if (RNA_struct_property_is_set(op->ptr, "rotation")) + *is_view_aligned = FALSE; + else if (RNA_struct_property_is_set(op->ptr, "view_align")) + *is_view_aligned = RNA_boolean_get(op->ptr, "view_align"); + else { + *is_view_aligned = U.flag & USER_ADD_VIEWALIGNED; + RNA_boolean_set(op->ptr, "view_align", *is_view_aligned); + } - if (RNA_struct_property_is_set(op->ptr, "rotation")) - view_align = FALSE; - else if (RNA_struct_property_is_set(op->ptr, "view_align")) - view_align = RNA_boolean_get(op->ptr, "view_align"); - else { - view_align = U.flag & USER_ADD_VIEWALIGNED; - RNA_boolean_set(op->ptr, "view_align", view_align); - } - - if (view_align) { - ED_object_rotation_from_view(C, rot); - RNA_float_set_array(op->ptr, "rotation", rot); + if (*is_view_aligned) { + ED_object_rotation_from_view(C, rot); + RNA_float_set_array(op->ptr, "rotation", rot); + } + else + RNA_float_get_array(op->ptr, "rotation", rot); } - else - RNA_float_get_array(op->ptr, "rotation", rot); - - if (is_view_aligned) - *is_view_aligned = view_align; - - RNA_float_get_array(op->ptr, "location", loc); - - if (*layer == 0) { + + if (layer && *layer == 0) { BKE_report(op->reports, RPT_ERROR, "Property 'layer' has no values set"); return 0; } @@ -329,19 +347,19 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl return 1; } -/* for object add primitive operators */ -/* do not call undo push in this function (users of this function have to) */ +/* For object add primitive operators. + * Do not call undo push in this function (users of this function have to). */ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const float rot[3], int enter_editmode, unsigned int layer) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob; - - /* for as long scene has editmode... */ + + /* For as long scene has editmode... */ if (CTX_data_edit_object(C)) ED_object_exit_editmode(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */ - + /* deselects all, sets scene->basact */ ob = BKE_object_add(scene, type); BASACT->lay = ob->lay = layer; @@ -371,12 +389,12 @@ static int object_add_exec(bContext *C, wmOperator *op) int enter_editmode; unsigned int layer; float loc[3], rot[3]; - + if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer); - + return OPERATOR_FINISHED; } @@ -386,89 +404,62 @@ void OBJECT_OT_add(wmOperatorType *ot) ot->name = "Add Object"; ot->description = "Add an object to the scene"; ot->idname = "OBJECT_OT_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = object_add_exec; - ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + RNA_def_enum(ot->srna, "type", object_type_items, 0, "Type", ""); ED_object_add_generic_props(ot, TRUE); } /********************* Add Effector Operator ********************/ -/* copy from rna_object_force.c*/ -static EnumPropertyItem field_type_items[] = { - {PFIELD_FORCE, "FORCE", ICON_FORCE_FORCE, "Force", ""}, - {PFIELD_WIND, "WIND", ICON_FORCE_WIND, "Wind", ""}, - {PFIELD_VORTEX, "VORTEX", ICON_FORCE_VORTEX, "Vortex", ""}, - {PFIELD_MAGNET, "MAGNET", ICON_FORCE_MAGNETIC, "Magnetic", ""}, - {PFIELD_HARMONIC, "HARMONIC", ICON_FORCE_HARMONIC, "Harmonic", ""}, - {PFIELD_CHARGE, "CHARGE", ICON_FORCE_CHARGE, "Charge", ""}, - {PFIELD_LENNARDJ, "LENNARDJ", ICON_FORCE_LENNARDJONES, "Lennard-Jones", ""}, - {PFIELD_TEXTURE, "TEXTURE", ICON_FORCE_TEXTURE, "Texture", ""}, - {PFIELD_GUIDE, "GUIDE", ICON_FORCE_CURVE, "Curve Guide", ""}, - {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, - {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""}, - {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""}, - {0, NULL, 0, NULL, NULL}}; -/* for effector add primitive operators */ -static Object *effector_add_type(bContext *C, wmOperator *op, int type) +/* for object add operator */ +static int effector_add_exec(bContext *C, wmOperator *op) { Object *ob; - int enter_editmode; + int type, enter_editmode; unsigned int layer; float loc[3], rot[3]; float mat[4][4]; - - object_add_generic_invoke_options(C, op); if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) - return NULL; + return OPERATOR_CANCELLED; + + type = RNA_enum_get(op->ptr, "type"); if (type == PFIELD_GUIDE) { ob = ED_object_add_type(C, OB_CURVE, loc, rot, FALSE, layer); - rename_id(&ob->id, "CurveGuide"); + if (!ob) + return OPERATOR_CANCELLED; + rename_id(&ob->id, "CurveGuide"); ((Curve *)ob->data)->flag |= CU_PATH | CU_3D; ED_object_enter_editmode(C, 0); ED_object_new_primitive_matrix(C, ob, loc, rot, mat); BLI_addtail(object_editcurve_get(ob), add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1)); - if (!enter_editmode) ED_object_exit_editmode(C, EM_FREEDATA); } else { ob = ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer); - rename_id(&ob->id, "Field"); + if (!ob) + return OPERATOR_CANCELLED; - switch (type) { - case PFIELD_WIND: - case PFIELD_VORTEX: - ob->empty_drawtype = OB_SINGLE_ARROW; - break; - } + rename_id(&ob->id, "Field"); + if (ELEM(type, PFIELD_WIND, PFIELD_VORTEX)) + ob->empty_drawtype = OB_SINGLE_ARROW; } ob->pd = object_add_collision_fields(type); DAG_scene_sort(CTX_data_main(C), CTX_data_scene(C)); - return ob; -} - -/* for object add operator */ -static int effector_add_exec(bContext *C, wmOperator *op) -{ - if (effector_add_type(C, op, RNA_enum_get(op->ptr, "type")) == NULL) - return OPERATOR_CANCELLED; - return OPERATOR_FINISHED; } @@ -478,22 +469,20 @@ void OBJECT_OT_effector_add(wmOperatorType *ot) ot->name = "Add Effector"; ot->description = "Add an empty object with a physics effector to the scene"; ot->idname = "OBJECT_OT_effector_add"; - + /* api callbacks */ - ot->invoke = WM_menu_invoke; ot->exec = effector_add_exec; - ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + ot->prop = RNA_def_enum(ot->srna, "type", field_type_items, 0, "Type", ""); ED_object_add_generic_props(ot, TRUE); } -/* ***************** Add Camera *************** */ +/********************* Add Camera Operator ********************/ static int object_camera_add_exec(bContext *C, wmOperator *op) { @@ -503,17 +492,15 @@ static int object_camera_add_exec(bContext *C, wmOperator *op) int enter_editmode; unsigned int layer; float loc[3], rot[3]; - + /* force view align for cameras */ RNA_boolean_set(op->ptr, "view_align", TRUE); - - object_add_generic_invoke_options(C, op); if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_CAMERA, loc, rot, FALSE, layer); - + if (v3d) { if (v3d->camera == NULL) v3d->camera = ob; @@ -528,81 +515,60 @@ static int object_camera_add_exec(bContext *C, wmOperator *op) void OBJECT_OT_camera_add(wmOperatorType *ot) { PropertyRNA *prop; - + /* identifiers */ ot->name = "Add Camera"; ot->description = "Add a camera object to the scene"; ot->idname = "OBJECT_OT_camera_add"; - + /* api callbacks */ ot->exec = object_camera_add_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + ED_object_add_generic_props(ot, TRUE); - + /* hide this for cameras, default */ prop = RNA_struct_type_find_property(ot->srna, "view_align"); RNA_def_property_flag(prop, PROP_HIDDEN); - } -/* ***************** add primitives *************** */ +/********************* Add Metaball Operator ********************/ + static int object_metaball_add_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); - /*MetaElem *elem;*/ /*UNUSED*/ int newob = 0; int enter_editmode; unsigned int layer; float loc[3], rot[3]; float mat[4][4]; - object_add_generic_invoke_options(C, op); /* XXX these props don't get set right when only exec() is called */ - if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; - + if (obedit == NULL || obedit->type != OB_MBALL) { obedit = ED_object_add_type(C, OB_MBALL, loc, rot, TRUE, layer); newob = 1; } - else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - + else + DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); - - /* elem= (MetaElem *) */ add_metaball_primitive(C, obedit, mat, RNA_enum_get(op->ptr, "type"), newob); + + add_metaball_primitive(C, obedit, mat, RNA_enum_get(op->ptr, "type"), newob); /* userdef */ if (newob && !enter_editmode) { ED_object_exit_editmode(C, EM_FREEDATA); } - - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); - - return OPERATOR_FINISHED; -} - -static int object_metaball_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) -{ - Object *obedit = CTX_data_edit_object(C); - uiPopupMenu *pup; - uiLayout *layout; - - object_add_generic_invoke_options(C, op); - pup = uiPupMenuBegin(C, op->type->name, ICON_NONE); - layout = uiPupMenuLayout(pup); - if (!obedit || obedit->type == OB_MBALL) - uiItemsEnumO(layout, op->type->idname, "type"); - else - uiItemsEnumO(layout, "OBJECT_OT_metaball_add", "type"); - uiPupMenuEnd(C, pup); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); - return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } void OBJECT_OT_metaball_add(wmOperatorType *ot) @@ -613,35 +579,37 @@ void OBJECT_OT_metaball_add(wmOperatorType *ot) ot->idname = "OBJECT_OT_metaball_add"; /* api callbacks */ - ot->invoke = object_metaball_add_invoke; + ot->invoke = WM_menu_invoke;/* object_metaball_add_invoke; */ ot->exec = object_metaball_add_exec; ot->poll = ED_operator_scene_editable; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", metaelem_type_items, 0, "Primitive", ""); + + ot->prop = RNA_def_enum(ot->srna, "type", metaelem_type_items, 0, "Primitive", ""); + ED_object_add_generic_props(ot, TRUE); } +/********************* Add Text Operator ********************/ + static int object_add_text_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); int enter_editmode; unsigned int layer; float loc[3], rot[3]; - - object_add_generic_invoke_options(C, op); /* XXX these props don't get set right when only exec() is called */ + if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; - + if (obedit && obedit->type == OB_FONT) return OPERATOR_CANCELLED; obedit = ED_object_add_type(C, OB_FONT, loc, rot, enter_editmode, layer); - + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); - + return OPERATOR_FINISHED; } @@ -651,17 +619,18 @@ void OBJECT_OT_text_add(wmOperatorType *ot) ot->name = "Add Text"; ot->description = "Add a text object to the scene"; ot->idname = "OBJECT_OT_text_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = object_add_text_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; ED_object_add_generic_props(ot, TRUE); } +/********************* Add Armature Operator ********************/ + static int object_armature_add_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -672,7 +641,6 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; - object_add_generic_invoke_options(C, op); /* XXX these props don't get set right when only exec() is called */ if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; @@ -687,36 +655,76 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature"); return OPERATOR_CANCELLED; } - + /* v3d and rv3d are allowed to be NULL */ add_primitive_bone(CTX_data_scene(C), v3d, rv3d); /* userdef */ if (newob && !enter_editmode) ED_object_exit_editmode(C, EM_FREEDATA); - + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); - + return OPERATOR_FINISHED; } void OBJECT_OT_armature_add(wmOperatorType *ot) -{ +{ /* identifiers */ ot->name = "Add Armature"; ot->description = "Add an armature object to the scene"; ot->idname = "OBJECT_OT_armature_add"; - + /* api callbacks */ - ot->invoke = ED_object_add_generic_invoke; ot->exec = object_armature_add_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; ED_object_add_generic_props(ot, TRUE); } +/********************* Add Empty Operator ********************/ + +static int object_empty_add_exec(bContext *C, wmOperator *op) +{ + Object *ob; + int type = RNA_enum_get(op->ptr, "type"); + unsigned int layer; + float loc[3], rot[3]; + + if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL)) + return OPERATOR_CANCELLED; + + ob = ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer); + ob->empty_drawtype = type; + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_empty_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Empty"; + ot->description = "Add an empty object to the scene"; + ot->idname = "OBJECT_OT_empty_add"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = object_empty_add_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", object_empty_drawtype_items, 0, "Type", ""); + + ED_object_add_generic_props(ot, FALSE); +} + +/********************* Add Lamp Operator ********************/ + static const char *get_lamp_defname(int type) { switch (type) { @@ -736,12 +744,10 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) Object *ob; Lamp *la; int type = RNA_enum_get(op->ptr, "type"); - int enter_editmode; unsigned int layer; float loc[3], rot[3]; - - object_add_generic_invoke_options(C, op); - if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) + + if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_LAMP, loc, rot, FALSE, layer); @@ -755,7 +761,7 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) ED_node_shader_default(scene, &la->id); la->use_nodes = TRUE; } - + return OPERATOR_FINISHED; } @@ -765,12 +771,12 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) ot->name = "Add Lamp"; ot->description = "Add a lamp object to the scene"; ot->idname = "OBJECT_OT_lamp_add"; - + /* api callbacks */ ot->invoke = WM_menu_invoke; ot->exec = object_lamp_add_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -780,16 +786,16 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) ED_object_add_generic_props(ot, FALSE); } +/********************* Add Group Instance Operator ********************/ + static int group_instance_add_exec(bContext *C, wmOperator *op) { Group *group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); - int enter_editmode; unsigned int layer; float loc[3], rot[3]; - - object_add_generic_invoke_options(C, op); - if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) + + if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; if (group) { @@ -812,20 +818,45 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } +/* only used as menu */ +void OBJECT_OT_group_instance_add(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Add Group Instance"; + ot->description = "Add a dupligroup instance"; + ot->idname = "OBJECT_OT_group_instance_add"; + + /* api callbacks */ + ot->invoke = WM_enum_search_invoke; + ot->exec = group_instance_add_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); + RNA_def_enum_funcs(prop, RNA_group_itemf); + ot->prop = prop; + ED_object_add_generic_props(ot, FALSE); +} + +/********************* Add Speaker Operator ********************/ + static int object_speaker_add_exec(bContext *C, wmOperator *op) { Object *ob; - int enter_editmode; unsigned int layer; float loc[3], rot[3]; Scene *scene = CTX_data_scene(C); - object_add_generic_invoke_options(C, op); - if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) + if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_SPEAKER, loc, rot, FALSE, layer); - + /* to make it easier to start using this immediately in NLA, a default sound clip is created * ready to be moved around to retime the sound and/or make new sound clips */ @@ -836,14 +867,14 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) NlaStrip *strip = add_nla_soundstrip(CTX_data_scene(C), ob->data); strip->start = CFRA; strip->end += strip->start; - + /* hook them up */ BKE_nlatrack_add_strip(nlt, strip); - + /* auto-name the strip, and give the track an interesting name */ strcpy(nlt->name, "SoundTrack"); BKE_nlastrip_validate_name(adt, strip); - + WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL); } @@ -867,32 +898,6 @@ void OBJECT_OT_speaker_add(wmOperatorType *ot) ED_object_add_generic_props(ot, TRUE); } -/* only used as menu */ -void OBJECT_OT_group_instance_add(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name = "Add Group Instance"; - ot->description = "Add a dupligroup instance"; - ot->idname = "OBJECT_OT_group_instance_add"; - - /* api callbacks */ - ot->invoke = WM_enum_search_invoke; - ot->exec = group_instance_add_exec; - - ot->poll = ED_operator_objectmode; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); - RNA_def_enum_funcs(prop, RNA_group_itemf); - ot->prop = prop; - ED_object_add_generic_props(ot, FALSE); -} - /**************************** Delete Object *************************/ static void object_delete_check_glsl_update(Object *ob) @@ -901,7 +906,7 @@ static void object_delete_check_glsl_update(Object *ob) * are being tagged to be updated when object is removing from scene */ if (ob->type == OB_LAMP) { - if (ob->gpulamp.first) + if (ob->gpulamp.first) GPU_lamp_free(ob); } } @@ -923,16 +928,12 @@ static int object_delete_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); const short use_global = RNA_boolean_get(op->ptr, "use_global"); - /* int is_lamp = FALSE; */ /* UNUSED */ - + if (CTX_data_edit_object(C)) return OPERATOR_CANCELLED; - + CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - - /* if (base->object->type==OB_LAMP) is_lamp = TRUE; */ - /* deselect object -- it could be used in other scenes */ base->object->flag &= ~SELECT; @@ -959,10 +960,10 @@ static int object_delete_exec(bContext *C, wmOperator *op) DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); - + WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); - + return OPERATOR_FINISHED; } @@ -972,12 +973,12 @@ void OBJECT_OT_delete(wmOperatorType *ot) ot->name = "Delete"; ot->description = "Delete selected objects"; ot->idname = "OBJECT_OT_delete"; - + /* api callbacks */ ot->invoke = WM_operator_confirm; ot->exec = object_delete_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -993,29 +994,29 @@ static void copy_object_set_idnew(bContext *C, int dupflag) Material *ma, *mao; ID *id; int a; - + /* XXX check object pointers */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { BKE_object_relink(ob); } CTX_DATA_END; - + /* materials */ if (dupflag & USER_DUP_MAT) { mao = bmain->mat.first; while (mao) { if (mao->id.newid) { - ma = (Material *)mao->id.newid; - + if (dupflag & USER_DUP_TEX) { for (a = 0; a < MAX_MTEX; a++) { if (ma->mtex[a]) { id = (ID *)ma->mtex[a]->tex; if (id) { ID_NEW_US(ma->mtex[a]->tex) - else ma->mtex[a]->tex = BKE_texture_copy(ma->mtex[a]->tex); + else + ma->mtex[a]->tex = BKE_texture_copy(ma->mtex[a]->tex); id->us--; } } @@ -1025,7 +1026,8 @@ static void copy_object_set_idnew(bContext *C, int dupflag) id = (ID *)ma->ipo; if (id) { ID_NEW_US(ma->ipo) - else ma->ipo = copy_ipo(ma->ipo); + else + ma->ipo = copy_ipo(ma->ipo); id->us--; } #endif // XXX old animation system @@ -1033,7 +1035,7 @@ static void copy_object_set_idnew(bContext *C, int dupflag) mao = mao->id.next; } } - + #if 0 // XXX old animation system /* lamps */ if (dupflag & USER_DUP_IPO) { @@ -1044,14 +1046,15 @@ static void copy_object_set_idnew(bContext *C, int dupflag) id = (ID *)lan->ipo; if (id) { ID_NEW_US(lan->ipo) - else lan->ipo = copy_ipo(lan->ipo); + else + lan->ipo = copy_ipo(lan->ipo); id->us--; } } la = la->id.next; } } - + /* ipos */ ipo = bmain->ipo.first; while (ipo) { @@ -1067,9 +1070,9 @@ static void copy_object_set_idnew(bContext *C, int dupflag) ipo = ipo->id.next; } #endif // XXX old animation system - + set_sca_new_poins(); - + clear_id_newpoins(); } @@ -1082,17 +1085,17 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, ListBase *lb; DupliObject *dob; GHash *dupli_gh = NULL, *parent_gh = NULL; - + if (!(base->object->transflag & OB_DUPLI)) return; - - lb = object_duplilist(scene, base->object); + + lb = object_duplilist(scene, base->object, FALSE); if (use_hierarchy || use_base_parent) { dupli_gh = BLI_ghash_ptr_new("make_object_duplilist_real dupli_gh"); parent_gh = BLI_ghash_pair_new("make_object_duplilist_real parent_gh"); } - + for (dob = lb->first; dob; dob = dob->next) { Base *basen; Object *ob = BKE_object_copy(dob->ob); @@ -1100,24 +1103,24 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, * should be implemented better... */ if (ob->mat == NULL) ob->totcol = 0; - + basen = MEM_dupallocN(base); basen->flag &= ~(OB_FROMDUPLI | OB_FROMGROUP); ob->flag = basen->flag; basen->lay = base->lay; BLI_addhead(&scene->base, basen); /* addhead: othwise eternal loop */ basen->object = ob; - + /* make sure apply works */ BKE_free_animdata(&ob->id); ob->adt = NULL; - + ob->parent = NULL; ob->constraints.first = ob->constraints.last = NULL; ob->disp.first = ob->disp.last = NULL; ob->transflag &= ~OB_DUPLI; ob->lay = base->lay; - + copy_m4_m4(ob->obmat, dob->mat); BKE_object_apply_mat4(ob, ob->obmat, FALSE, FALSE); @@ -1126,7 +1129,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, if (parent_gh) BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, SET_INT_IN_POINTER(dob->index)), ob); } - + if (use_hierarchy) { for (dob = lb->first; dob; dob = dob->next) { /* original parents */ @@ -1186,8 +1189,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, invert_m4_m4(ob_dst->parentinv, dob->mat); BKE_object_apply_mat4(ob_dst, dob->mat, FALSE, TRUE); DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB); - - } } @@ -1197,9 +1198,9 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, BLI_ghash_free(parent_gh, BLI_ghashutil_pairfree, NULL); copy_object_set_idnew(C, 0); - + free_object_duplilist(lb); - + base->object->transflag &= ~OB_DUPLI; } @@ -1210,9 +1211,9 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) const short use_base_parent = RNA_boolean_get(op->ptr, "use_base_parent"); const short use_hierarchy = RNA_boolean_get(op->ptr, "use_hierarchy"); - + clear_id_newpoins(); - + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { make_object_duplilist_real(C, scene, base, use_base_parent, use_hierarchy); @@ -1226,23 +1227,22 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_SCENE, scene); WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); - + return OPERATOR_FINISHED; } void OBJECT_OT_duplicates_make_real(wmOperatorType *ot) { - /* identifiers */ ot->name = "Make Duplicates Real"; ot->description = "Make dupli objects attached to this object real"; ot->idname = "OBJECT_OT_duplicates_make_real"; - + /* api callbacks */ ot->exec = object_duplicates_make_real_exec; - + ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1616,12 +1616,12 @@ void OBJECT_OT_convert(wmOperatorType *ot) ot->name = "Convert to"; ot->description = "Convert selected objects to another type"; ot->idname = "OBJECT_OT_convert"; - + /* api callbacks */ ot->invoke = WM_menu_invoke; ot->exec = convert_exec; ot->poll = convert_poll; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1655,12 +1655,12 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base else { obn = BKE_object_copy(ob); obn->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; - + basen = MEM_mallocN(sizeof(Base), "duplibase"); *basen = *base; BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */ basen->object = obn; - + if (basen->flag & OB_FROMGROUP) { Group *group; for (group = bmain->group.first; group; group = group->id.next) { @@ -1668,20 +1668,21 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base add_to_group(group, obn, scene, basen); } } - + /* duplicates using userflags */ if (dupflag & USER_DUP_ACT) { BKE_copy_animdata_id_action(&obn->id); } - + if (dupflag & USER_DUP_MAT) { for (a = 0; a < obn->totcol; a++) { id = (ID *)obn->mat[a]; if (id) { ID_NEW_US(obn->mat[a]) - else obn->mat[a] = BKE_material_copy(obn->mat[a]); + else + obn->mat[a] = BKE_material_copy(obn->mat[a]); id->us--; - + if (dupflag & USER_DUP_ACT) { BKE_copy_animdata_id_action(&obn->mat[a]->id); } @@ -1694,8 +1695,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id = (ID *) psys->part; if (id) { ID_NEW_US(psys->part) - else psys->part = BKE_particlesettings_copy(psys->part); - + else + psys->part = BKE_particlesettings_copy(psys->part); + if (dupflag & USER_DUP_ACT) { BKE_copy_animdata_id_action(&psys->part->id); } @@ -1704,21 +1706,19 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } } } - + id = obn->data; didit = 0; - + switch (obn->type) { case OB_MESH: if (dupflag & USER_DUP_MESH) { ID_NEW_US2(obn->data) else { obn->data = BKE_mesh_copy(obn->data); - if (obn->fluidsimSettings) { obn->fluidsimSettings->orgMesh = (Mesh *)obn->data; } - didit = 1; } id->us--; @@ -1774,11 +1774,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id->us--; } break; - case OB_ARMATURE: obn->recalc |= OB_RECALC_DATA; - if (obn->pose) obn->pose->flag |= POSE_RECALC; - + if (obn->pose) + obn->pose->flag |= POSE_RECALC; if (dupflag & USER_DUP_ARM) { ID_NEW_US2(obn->data) else { @@ -1788,9 +1787,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } id->us--; } - break; - case OB_LATTICE: if (dupflag != 0) { ID_NEW_US2(obn->data) @@ -1821,13 +1818,12 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id->us--; } break; - } /* check if obdata is copied */ if (didit) { Key *key = BKE_key_from_object(obn); - + if (dupflag & USER_DUP_ACT) { bActuator *act; @@ -1846,7 +1842,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } } } - + if (dupflag & USER_DUP_MAT) { matarar = give_matarar(obn); if (matarar) { @@ -1854,8 +1850,8 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id = (ID *)(*matarar)[a]; if (id) { ID_NEW_US((*matarar)[a]) - else (*matarar)[a] = BKE_material_copy((*matarar)[a]); - + else + (*matarar)[a] = BKE_material_copy((*matarar)[a]); id->us--; } } @@ -1906,14 +1902,14 @@ static int duplicate_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); int linked = RNA_boolean_get(op->ptr, "linked"); int dupflag = (linked) ? 0 : U.dupflag; - + clear_id_newpoins(); clear_sca_new_poins(); /* sensor/contr/act */ - + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { Base *basen = object_add_duplicate_internal(bmain, scene, base, dupflag); - + /* note that this is safe to do with this context iterator, * the list is made in advance */ ED_base_object_select(base, BA_DESELECT); @@ -1945,19 +1941,19 @@ static int duplicate_exec(bContext *C, wmOperator *op) void OBJECT_OT_duplicate(wmOperatorType *ot) { PropertyRNA *prop; - + /* identifiers */ ot->name = "Duplicate Objects"; ot->description = "Duplicate selected objects"; ot->idname = "OBJECT_OT_duplicate"; - + /* api callbacks */ ot->exec = duplicate_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* to give to transform */ RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data"); prop = RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); @@ -1966,7 +1962,6 @@ void OBJECT_OT_duplicate(wmOperatorType *ot) /* **************** add named object, for dragdrop ************* */ - static int add_named_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -2021,34 +2016,32 @@ void OBJECT_OT_add_named(wmOperatorType *ot) ot->name = "Add Named Object"; ot->description = "Add named object"; ot->idname = "OBJECT_OT_add_named"; - + /* api callbacks */ ot->exec = add_named_exec; ot->poll = ED_operator_objectmode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data"); RNA_def_string(ot->srna, "name", "Cube", MAX_ID_NAME - 2, "Name", "Object name to add"); } - - /**************************** Join *************************/ + static int join_poll(bContext *C) { Object *ob = CTX_data_active_object(C); - + if (!ob || ob->id.lib) return 0; - + if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE)) return ED_operator_screenactive(C); else return 0; } - static int join_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -2069,7 +2062,7 @@ static int join_exec(bContext *C, wmOperator *op) return join_curve_exec(C, op); else if (ob->type == OB_ARMATURE) return join_armature_exec(C, op); - + return OPERATOR_CANCELLED; } @@ -2079,22 +2072,23 @@ void OBJECT_OT_join(wmOperatorType *ot) ot->name = "Join"; ot->description = "Join selected objects into active object"; ot->idname = "OBJECT_OT_join"; - + /* api callbacks */ ot->exec = join_exec; ot->poll = join_poll; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /**************************** Join as Shape Key*************************/ + static int join_shapes_poll(bContext *C) { Object *ob = CTX_data_active_object(C); - + if (!ob || ob->id.lib) return 0; - + /* only meshes supported at the moment */ if (ob->type == OB_MESH) return ED_operator_screenactive(C); @@ -2106,7 +2100,7 @@ static int join_shapes_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - + if (scene->obedit) { BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode"); return OPERATOR_CANCELLED; @@ -2115,10 +2109,10 @@ static int join_shapes_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata"); return OPERATOR_CANCELLED; } - + if (ob->type == OB_MESH) return join_mesh_shapes_exec(C, op); - + return OPERATOR_CANCELLED; } @@ -2128,11 +2122,11 @@ void OBJECT_OT_join_shapes(wmOperatorType *ot) ot->name = "Join as Shapes"; ot->description = "Merge selected objects to shapes of active object"; ot->idname = "OBJECT_OT_join_shapes"; - + /* api callbacks */ ot->exec = join_shapes_exec; ot->poll = join_shapes_poll; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 1ef7c12b409..56f2426b1b0 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -40,6 +40,7 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "DNA_anim_types.h" #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_scene_types.h" @@ -51,6 +52,7 @@ #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_object.h" @@ -71,6 +73,7 @@ #include "ED_object.h" #include "ED_armature.h" +#include "ED_keyframing.h" #include "ED_screen.h" #include "UI_interface.h" @@ -655,12 +658,15 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot) ot->idname = "CONSTRAINT_OT_stretchto_reset"; ot->description = "Reset original length of bone for Stretch To Constraint"; - ot->exec = stretchto_reset_exec; + /* callbacks */ ot->invoke = stretchto_reset_invoke; + ot->exec = stretchto_reset_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -698,12 +704,15 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot) ot->idname = "CONSTRAINT_OT_limitdistance_reset"; ot->description = "Reset limiting distance for Limit Distance Constraint"; - ot->exec = limitdistance_reset_exec; + /* callbacks */ ot->invoke = limitdistance_reset_invoke; + ot->exec = limitdistance_reset_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -824,12 +833,15 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot) ot->idname = "CONSTRAINT_OT_childof_set_inverse"; ot->description = "Set inverse correction for ChildOf constraint"; - ot->exec = childof_set_inverse_exec; + /* callbacks */ ot->invoke = childof_set_inverse_invoke; + ot->exec = childof_set_inverse_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -868,13 +880,140 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot) ot->idname = "CONSTRAINT_OT_childof_clear_inverse"; ot->description = "Clear inverse correction for ChildOf constraint"; - ot->exec = childof_clear_inverse_exec; + /* callbacks */ ot->invoke = childof_clear_inverse_invoke; + ot->exec = childof_clear_inverse_exec; + ot->poll = edit_constraint_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + edit_constraint_properties(ot); +} + +/* --------------- Follow Path Constraint ------------------ */ + +static int followpath_path_animate_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_FOLLOWPATH); + bFollowPathConstraint *data = (con) ? (bFollowPathConstraint *)con->data : NULL; + + bAction *act = NULL; + FCurve *fcu = NULL; + int sfra = RNA_int_get(op->ptr, "frame_start"); + int len = RNA_int_get(op->ptr, "length"); + float standardRange = 1.0; + + /* nearly impossible sanity check */ + if (data == NULL) { + BKE_report(op->reports, RPT_ERROR, "Follow Path constraint not found"); + return OPERATOR_CANCELLED; + } + + /* add F-Curve as appropriate */ + if (data->tar) { + Curve *cu = (Curve *)data->tar->data; + + if ( ELEM(NULL, cu->adt, cu->adt->action) || + (list_find_fcurve(&cu->adt->action->curves, "eval_time", 0) == NULL)) + { + /* create F-Curve for path animation */ + act = verify_adt_action(&cu->id, 1); + fcu = verify_fcurve(act, NULL, NULL, "eval_time", 0, 1); + + /* standard vertical range - 1:1 = 100 frames */ + standardRange = 100.0f; + } + else { + /* path anim exists already - abort for now as this may well be what was intended */ + BKE_report(op->reports, RPT_WARNING, "Path is already animated"); + return OPERATOR_CANCELLED; + } + } + else { + /* animate constraint's "fixed offset" */ + PointerRNA ptr; + PropertyRNA *prop; + char *path; + + /* get RNA pointer to constraint's "offset_factor" property - to build RNA path */ + RNA_pointer_create(&ob->id, &RNA_FollowPathConstraint, con, &ptr); + prop = RNA_struct_find_property(&ptr, "offset_factor"); + + path = RNA_path_from_ID_to_property(&ptr, prop); + + /* create F-Curve for constraint */ + act = verify_adt_action(&ob->id, 1); + fcu = verify_fcurve(act, NULL, NULL, path, 0, 1); + + /* standard vertical range - 0.0 to 1.0 */ + standardRange = 1.0f; + + /* enable "Use Fixed Position" so that animating this has effect */ + data->followflag |= FOLLOWPATH_STATIC; + + /* path needs to be freed */ + if (path) + MEM_freeN(path); + } + + /* setup dummy 'generator' modifier here to get 1-1 correspondence still working + * and define basic slope of this curve based on the properties + */ + if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) { + FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR); + FMod_Generator *gen = fcm->data; + + /* Assume that we have the following equation: + * y = Ax + B + * 1 0 <-- coefficients array indices + */ + float A = standardRange / (float)(len); + float B = (float)(-sfra) * A; + + gen->coefficients[1] = A; + gen->coefficients[0] = B; + } + + /* updates... */ + WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); + return OPERATOR_FINISHED; +} + +static int followpath_path_animate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + /* hook up invoke properties for figuring out which constraint we're dealing with */ + if (edit_constraint_invoke_properties(C, op)) { + return followpath_path_animate_exec(C, op); + } + else { + return OPERATOR_CANCELLED; + } +} + +void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Auto Animate Path"; + ot->idname = "CONSTRAINT_OT_followpath_path_animate"; + ot->description = "Add default animation for path used by constraint if it isn't animated already"; + + /* callbacks */ + ot->invoke = followpath_path_animate_invoke; + ot->exec = followpath_path_animate_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ edit_constraint_properties(ot); + RNA_def_int(ot->srna, "frame_start", 1, MINAFRAME, MAXFRAME, "Start Frame", + "First frame of path animation", MINAFRAME, MAXFRAME); + RNA_def_int(ot->srna, "length", 100, 0, MAXFRAME, "Length", + "Number of frames that path animation should take", 0, MAXFRAME); } /* ------------- Object Solver Constraint ------------------ */ @@ -914,13 +1053,16 @@ void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot) ot->name = "Set Inverse"; ot->idname = "CONSTRAINT_OT_objectsolver_set_inverse"; ot->description = "Set inverse correction for ObjectSolver constraint"; - - ot->exec = objectsolver_set_inverse_exec; + + /* callbacks */ ot->invoke = objectsolver_set_inverse_invoke; + ot->exec = objectsolver_set_inverse_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -957,13 +1099,16 @@ void CONSTRAINT_OT_objectsolver_clear_inverse(wmOperatorType *ot) ot->name = "Clear Inverse"; ot->idname = "CONSTRAINT_OT_objectsolver_clear_inverse"; ot->description = "Clear inverse correction for ObjectSolver constraint"; - - ot->exec = objectsolver_clear_inverse_exec; + + /* callbacks */ ot->invoke = objectsolver_clear_inverse_invoke; + ot->exec = objectsolver_clear_inverse_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } @@ -983,13 +1128,14 @@ void ED_object_constraint_set_active(Object *ob, bConstraint *con) void ED_object_constraint_update(Object *ob) { - if (ob->pose) BKE_pose_update_constraint_flags(ob->pose); object_test_constraints(ob); - if (ob->type == OB_ARMATURE) DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); - else DAG_id_tag_update(&ob->id, OB_RECALC_OB); + if (ob->type == OB_ARMATURE) + DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); + else + DAG_id_tag_update(&ob->id, OB_RECALC_OB); } void ED_object_constraint_dependency_update(Main *bmain, Scene *scene, Object *ob) @@ -1006,6 +1152,7 @@ static int constraint_poll(bContext *C) return (ptr.id.data && ptr.data); } + static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); @@ -1020,12 +1167,12 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op)) constraints_set_active(lb, NULL); ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */ - + /* ITASC needs to be rebuilt once a constraint is removed [#26920] */ if (is_ik) { BIK_clear_data(ob->pose); } - + /* notifiers */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob); @@ -1052,6 +1199,7 @@ void CONSTRAINT_OT_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + static int constraint_move_down_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); @@ -1081,7 +1229,6 @@ static int constraint_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNU return OPERATOR_CANCELLED; } - void CONSTRAINT_OT_move_down(wmOperatorType *ot) { /* identifiers */ @@ -1090,12 +1237,14 @@ void CONSTRAINT_OT_move_down(wmOperatorType *ot) ot->description = "Move constraint down in constraint stack"; /* callbacks */ - ot->exec = constraint_move_down_exec; ot->invoke = constraint_move_down_invoke; + ot->exec = constraint_move_down_exec; ot->poll = edit_constraint_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ edit_constraint_properties(ot); } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index f95a186990e..14bc8f21615 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1017,9 +1017,9 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main * bmain, Scene * scene, View3D if (!(ob = OBACT)) return; - if (scene->obedit) { // XXX get from context -// if (ob->type == OB_MESH) -// XXX mesh_copy_menu(); + if (scene->obedit) { /* XXX get from context */ +/* if (ob->type == OB_MESH) */ +/* XXX mesh_copy_menu(); */ return; } @@ -1030,34 +1030,34 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main * bmain, Scene * scene, View3D */ strcpy(str, - "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|" - "Time Offset%x5|Dupli%x6|Object Color%x31|%l|Mass%x7|Damping%x8|All Physical Attributes%x11|Properties%x9|" - "Logic Bricks%x10|Protected Transform%x29|%l"); + "Copy Attributes %t|Location %x1|Rotation %x2|Size %x3|Draw Options %x4|" + "Time Offset %x5|Dupli %x6|Object Color %x31|%l|Mass %x7|Damping %x8|All Physical Attributes %x11|Properties %x9|" + "Logic Bricks %x10|Protected Transform %x29|%l"); - strcat(str, "|Object Constraints%x22"); - strcat(str, "|NLA Strips%x26"); + strcat(str, "|Object Constraints %x22"); + strcat(str, "|NLA Strips %x26"); -// XXX if (OB_TYPE_SUPPORT_MATERIAL(ob->type)) { -// strcat(str, "|Texture Space%x17"); -// } +/* XXX if (OB_TYPE_SUPPORT_MATERIAL(ob->type)) { */ +/* strcat(str, "|Texture Space %x17"); */ +/* } */ - if (ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19"); - if (ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19|UV Orco%x28"); + if (ob->type == OB_FONT) strcat(str, "|Font Settings %x18|Bevel Settings %x19"); + if (ob->type == OB_CURVE) strcat(str, "|Bevel Settings %x19|UV Orco %x28"); if ((ob->type == OB_FONT) || (ob->type == OB_CURVE)) { - strcat(str, "|Curve Resolution%x25"); + strcat(str, "|Curve Resolution %x25"); } if (ob->type == OB_MESH) { - strcat(str, "|Subsurf Settings%x21|AutoSmooth%x27"); + strcat(str, "|Subsurf Settings %x21|AutoSmooth %x27"); } - if (ob->soft) strcat(str, "|Soft Body Settings%x23"); + if (ob->soft) strcat(str, "|Soft Body Settings %x23"); - strcat(str, "|Pass Index%x30"); + strcat(str, "|Pass Index %x30"); if (ob->type == OB_MESH || ob->type == OB_CURVE || ob->type == OB_LATTICE || ob->type == OB_SURF) { - strcat(str, "|Modifiers ...%x24"); + strcat(str, "|Modifiers ... %x24"); } event = pupmenu(str); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b62ff676066..4c83f6ef2ce 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -112,6 +112,7 @@ void OBJECT_OT_add_named(struct wmOperatorType *ot); void OBJECT_OT_metaball_add(struct wmOperatorType *ot); void OBJECT_OT_text_add(struct wmOperatorType *ot); void OBJECT_OT_armature_add(struct wmOperatorType *ot); +void OBJECT_OT_empty_add(struct wmOperatorType *ot); void OBJECT_OT_lamp_add(struct wmOperatorType *ot); void OBJECT_OT_effector_add(struct wmOperatorType *ot); void OBJECT_OT_camera_add(struct wmOperatorType *ot); @@ -193,6 +194,7 @@ void CONSTRAINT_OT_childof_set_inverse(struct wmOperatorType *ot); void CONSTRAINT_OT_childof_clear_inverse(struct wmOperatorType *ot); void CONSTRAINT_OT_objectsolver_set_inverse(struct wmOperatorType *ot); void CONSTRAINT_OT_objectsolver_clear_inverse(struct wmOperatorType *ot); +void CONSTRAINT_OT_followpath_path_animate(struct wmOperatorType *ot); /* object_vgroup.c */ void OBJECT_OT_vertex_group_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index cec849efca7..fa40d579e2b 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -113,6 +113,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_delete); WM_operatortype_append(OBJECT_OT_text_add); WM_operatortype_append(OBJECT_OT_armature_add); + WM_operatortype_append(OBJECT_OT_empty_add); WM_operatortype_append(OBJECT_OT_lamp_add); WM_operatortype_append(OBJECT_OT_camera_add); WM_operatortype_append(OBJECT_OT_speaker_add); @@ -168,6 +169,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(CONSTRAINT_OT_childof_clear_inverse); WM_operatortype_append(CONSTRAINT_OT_objectsolver_set_inverse); WM_operatortype_append(CONSTRAINT_OT_objectsolver_clear_inverse); + WM_operatortype_append(CONSTRAINT_OT_followpath_path_animate); WM_operatortype_append(OBJECT_OT_vertex_group_add); WM_operatortype_append(OBJECT_OT_vertex_group_remove); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 72bbcda2b5e..3b1b3896e25 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -398,41 +398,41 @@ static void PE_set_view3d_data(bContext *C, PEData *data) /*************************** selection utilities *******************************/ -static int key_test_depth(PEData *data, const float co[3]) +static int key_test_depth(PEData *data, const float co[3], const int screen_co[2]) { View3D *v3d= data->vc.v3d; double ux, uy, uz; float depth; - short wco[3], x, y; /* nothing to do */ if ((v3d->drawtype<=OB_WIRE) || (v3d->flag & V3D_ZBUF_SELECT)==0) return 1; - ED_view3d_project_short(data->vc.ar, co, wco); - - if (wco[0] == IS_CLIPPED) + /* used to calculate here but all callers have the screen_co already, so pass as arg */ +#if 0 + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) + { return 0; + } +#endif gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection, (GLint *)data->mats.viewport, &ux, &uy, &uz); - x=wco[0]; - y=wco[1]; - #if 0 /* works well but too slow on some systems [#23118] */ - x+= (short)data->vc.ar->winrct.xmin; - y+= (short)data->vc.ar->winrct.ymin; + screen_co[0] += (short)data->vc.ar->winrct.xmin; + screen_co[1] += (short)data->vc.ar->winrct.ymin; /* PE_set_view3d_data calls this. no need to call here */ /* view3d_validate_backbuf(&data->vc); */ - glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + glReadPixels(screen_co[0], screen_co[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); #else /* faster to use depths, these are calculated in PE_set_view3d_data */ { ViewDepths *vd = data->vc.rv3d->depths; assert(vd && vd->depths); /* we know its not clipped */ - depth= vd->depths[y * vd->w + x]; + depth = vd->depths[screen_co[1] * vd->w + screen_co[0]]; } #endif @@ -445,21 +445,21 @@ static int key_test_depth(PEData *data, const float co[3]) static int key_inside_circle(PEData *data, float rad, const float co[3], float *distance) { float dx, dy, dist; - int sco[2]; + int screen_co[2]; - ED_view3d_project_int(data->vc.ar, co, sco); - - if (sco[0] == IS_CLIPPED) + /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */ + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { return 0; - - dx= data->mval[0] - sco[0]; - dy= data->mval[1] - sco[1]; + } + + dx= data->mval[0] - screen_co[0]; + dy= data->mval[1] - screen_co[1]; dist= sqrt(dx*dx + dy*dy); if (dist > rad) return 0; - if (key_test_depth(data, co)) { + if (key_test_depth(data, co, screen_co)) { if (distance) *distance=dist; @@ -471,17 +471,16 @@ static int key_inside_circle(PEData *data, float rad, const float co[3], float * static int key_inside_rect(PEData *data, const float co[3]) { - int sco[2]; + int screen_co[2]; - ED_view3d_project_int(data->vc.ar, co, sco); - - if (sco[0] == IS_CLIPPED) + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { return 0; + } - if (sco[0] > data->rect->xmin && sco[0] < data->rect->xmax && - sco[1] > data->rect->ymin && sco[1] < data->rect->ymax) + if (screen_co[0] > data->rect->xmin && screen_co[0] < data->rect->xmax && + screen_co[1] > data->rect->ymin && screen_co[1] < data->rect->ymax) { - return key_test_depth(data, co); + return key_test_depth(data, co, screen_co); } return 0; @@ -1634,7 +1633,7 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad) /************************ lasso select operator ************************/ -int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, short select) +int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short extend, short select) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); @@ -1645,7 +1644,7 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); POINT_P; KEY_K; float co[3], mat[4][4]= MAT4_UNITY; - int vertco[2]; + int screen_co[2]; PEData data; @@ -1666,9 +1665,9 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho LOOP_KEYS { copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - ED_view3d_project_int(ar, co, vertco); - if (BLI_lasso_is_point_inside(mcords, moves, vertco[0], vertco[1], IS_CLIPPED) && - key_test_depth(&data, co)) + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && + key_test_depth(&data, co, screen_co)) { if (select && !(key->flag & PEK_SELECT)) { key->flag |= PEK_SELECT; @@ -1686,9 +1685,9 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - ED_view3d_project_int(ar, co, vertco); - if (BLI_lasso_is_point_inside(mcords, moves, vertco[0], vertco[1], IS_CLIPPED) && - key_test_depth(&data, co)) + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && + key_test_depth(&data, co, screen_co)) { if (select && !(key->flag & PEK_SELECT)) { key->flag |= PEK_SELECT; @@ -2789,7 +2788,7 @@ static void brush_cut(PEData *data, int pa_index) float rad2, cut_time= 1.0; float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv; int k, cut, keys= (int)pow(2.0, (double)pset->draw_step); - int vertco[2]; + int screen_co[2]; /* blunt scissors */ if (BLI_frand() > data->cutfac) return; @@ -2798,13 +2797,15 @@ static void brush_cut(PEData *data, int pa_index) if (edit->points[pa_index].flag & PEP_HIDE) return; + if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) + return; + rad2= data->rad * data->rad; cut=0; - ED_view3d_project_int_noclip(ar, key->co, vertco); - x0= (float)vertco[0]; - x1= (float)vertco[1]; + x0 = (float)screen_co[0]; + x1 = (float)screen_co[1]; o0= (float)data->mval[0]; o1= (float)data->mval[1]; @@ -2813,26 +2814,27 @@ static void brush_cut(PEData *data, int pa_index) xo1= x1 - o1; /* check if root is inside circle */ - if (xo0*xo0 + xo1*xo1 < rad2 && key_test_depth(data, key->co)) { + if (xo0*xo0 + xo1*xo1 < rad2 && key_test_depth(data, key->co, screen_co)) { cut_time= -1.0f; cut= 1; } else { /* calculate path time closest to root that was inside the circle */ for (k=1, key++; k<=keys; k++, key++) { - ED_view3d_project_int_noclip(ar, key->co, vertco); - if (key_test_depth(data, key->co) == 0) { - x0= (float)vertco[0]; - x1= (float)vertco[1]; + if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || + key_test_depth(data, key->co, screen_co) == 0) + { + x0 = (float)screen_co[0]; + x1 = (float)screen_co[1]; xo0= x0 - o0; xo1= x1 - o1; continue; } - v0= (float)vertco[0] - x0; - v1= (float)vertco[1] - x1; + v0 = (float)screen_co[0] - x0; + v1 = (float)screen_co[1] - x1; dv= v0*v0 + v1*v1; @@ -2857,8 +2859,8 @@ static void brush_cut(PEData *data, int pa_index) } } - x0= (float)vertco[0]; - x1= (float)vertco[1]; + x0 = (float)screen_co[0]; + x1 = (float)screen_co[1]; xo0= x0 - o0; xo1= x1 - o1; diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 099d868a0ad..315386a947e 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -695,21 +695,21 @@ static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetF outStringsChanged=1; } - // check if modified output dir is ok + /* check if modified output dir is ok */ #if 0 if (outStringsChanged) { char dispmsg[FILE_MAX+256]; int selection=0; BLI_strncpy(dispmsg, "Output settings set to: '", sizeof(dispmsg)); strcat(dispmsg, newSurfdataPath); - strcat(dispmsg, "'%t|Continue with changed settings%x1|Discard and abort%x0"); + strcat(dispmsg, "'%t|Continue with changed settings %x1|Discard and abort %x0"); - // ask user if thats what he/she wants... + /* ask user if thats what he/she wants... */ selection = pupmenu(dispmsg); - if (selection < 1) return 0; // 0 from menu, or -1 aborted + if (selection < 1) return 0; /* 0 from menu, or -1 aborted */ BLI_strncpy(targetDir, newSurfdataPath, sizeof(targetDir)); strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR); - BLI_path_abs(targetDir, G.main->name); // fixed #frame-no + BLI_path_abs(targetDir, G.main->name); /* fixed #frame-no */ } #endif return outStringsChanged; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 30045c45dad..37dd00f6394 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1472,39 +1472,39 @@ void ED_area_prevspace(bContext *C, ScrArea *sa) static const char *editortype_pup(void) { const char *types = N_( - "Editor type:%t" + "Editor type: %t" "|3D View %x1" "|%l" - + "|Timeline %x15" "|Graph Editor %x2" "|DopeSheet %x12" "|NLA Editor %x13" - + "|%l" - + "|UV/Image Editor %x6" - + "|Video Sequence Editor %x8" "|Movie Clip Editor %x20" "|Text Editor %x9" "|Node Editor %x16" "|Logic Editor %x17" - + "|%l" - + "|Properties %x4" "|Outliner %x3" "|User Preferences %x19" - "|Info%x7" + "|Info %x7" "|%l" "|File Browser %x5" - + "|%l" - + "|Python Console %x18" ); @@ -1530,7 +1530,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D, editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y, &(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0, - TIP_("Displays current editor type. Click for menu of available types")); + TIP_("Display current editor type (click for menu of available types)")); uiButSetFunc(but, spacefunc, NULL, NULL); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 3a562fc21e5..5bda96accee 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -20,6 +20,7 @@ set(INC ../include + ../uvedit ../../blenkernel ../../blenlib ../../blenloader @@ -28,7 +29,6 @@ set(INC ../../imbuf ../../makesdna ../../makesrna - ../uvedit ../../render/extern/include ../../windowmanager ../../../../intern/guardedalloc diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index bdc621e51d5..1921a942f4a 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -522,11 +522,16 @@ static int project_brush_radius(ViewContext *vc, add_v3_v3v3(offset, location, ortho); /* project the center of the brush, and the tangent point to the view onto the screen */ - ED_view3d_project_float(vc->ar, location, p1); - ED_view3d_project_float(vc->ar, offset, p2); - - /* the distance between these points is the size of the projected brush in pixels */ - return len_v2v2(p1, p2); + if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && + (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + { + /* the distance between these points is the size of the projected brush in pixels */ + return len_v2v2(p1, p2); + } + else { + BLI_assert(0); /* assert because the code that sets up the vectors should disallow this */ + return 0; + } } static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index e309bdb99cb..697d7c63d1f 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -54,6 +54,7 @@ #include "WM_types.h" #include "ED_screen.h" +#include "ED_sculpt.h" #include "paint_intern.h" #include "sculpt_intern.h" /* for undo push */ @@ -77,7 +78,9 @@ static void mask_flood_fill_set_elem(float *elem, static int mask_flood_fill_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); + struct Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + struct MultiresModifierData *mmd = sculpt_multires_active(scene, ob); PaintMaskFloodMode mode; float value; DerivedMesh *dm; @@ -88,7 +91,9 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) mode = RNA_enum_get(op->ptr, "mode"); value = RNA_float_get(op->ptr, "value"); - dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); + ED_sculpt_mask_layers_ensure(ob, mmd); + + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); pbvh = dm->getPBVH(ob, dm); ob->sculpt->pbvh = pbvh; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 8aed92df3af..f1ee8f522d9 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -846,20 +846,22 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_nor[3], const float mval[2], const float brush_size_pressure) { - Brush *brush = paint_brush(&vp->paint); - float dist_squared; - float vertco[2], delta[2]; + float vertco[2]; - ED_view3d_project_float_noclip(vc->ar, vert_nor, vertco); - sub_v2_v2v2(delta, mval, vertco); - dist_squared = dot_v2v2(delta, delta); /* len squared */ - if (dist_squared > brush_size_pressure * brush_size_pressure) { - return 0.0f; - } - else { - const float dist = sqrtf(dist_squared); - return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); + if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + float delta[2]; + float dist_squared; + + sub_v2_v2v2(delta, mval, vertco); + dist_squared = dot_v2v2(delta, delta); /* len squared */ + if (dist_squared <= brush_size_pressure * brush_size_pressure) { + Brush *brush = paint_brush(&vp->paint); + const float dist = sqrtf(dist_squared); + return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); + } } + + return 0.0f; } static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index f4caa0f69bc..35827009da1 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4228,7 +4228,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) paint_cursor_start(C, sculpt_poll); } - WM_event_add_notifier(C, NC_SCENE | ND_MODE, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index ecc4dea8b05..75e3d8d5685 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -33,10 +33,10 @@ set(INC ../../windowmanager ../../gpu ../../../../intern/guardedalloc - ${GLEW_INCLUDE_PATH} ) set(INC_SYS + ${GLEW_INCLUDE_PATH} ) set(SRC diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 507e492497d..4f62d3fdc2f 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -413,7 +413,7 @@ void CLIP_OT_select_border(wmOperatorType *ot) /********************** lasso select operator *********************/ -static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, short select) +static int do_lasso_select_marker(bContext *C, const int mcords[][2], const short moves, short select) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); @@ -469,7 +469,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho static int clip_lasso_select_exec(bContext *C, wmOperator *op) { int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short select; diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index 0d40a6ae007..2f01483d23f 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -120,6 +120,8 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r) if (ibuf && (ibuf->rect || ibuf->rect_float)) return ibuf; } + else + *lock_r = NULL; return NULL; } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 8ad02ad7d8b..7254538af77 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1389,6 +1389,11 @@ static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), uiItemR(layout, ptr, "coloring", 0, "", ICON_NONE); } +static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "from_dupli", 0, NULL, 0); +} + static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); @@ -1470,6 +1475,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_TEX_VORONOI: ntype->uifunc = node_shader_buts_tex_voronoi; break; + case SH_NODE_TEX_COORD: + ntype->uifunc = node_shader_buts_tex_coord; + break; case SH_NODE_BSDF_GLOSSY: case SH_NODE_BSDF_GLASS: ntype->uifunc = node_shader_buts_glossy; diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index f7757ce49b4..b0916a50c37 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -539,7 +539,7 @@ void NODE_OT_select_border(wmOperatorType *ot) /* ****** Lasso Select ****** */ -static int do_lasso_select_node(bContext *C, int mcords[][2], short moves, short select) +static int do_lasso_select_node(bContext *C, const int mcords[][2], short moves, short select) { SpaceNode *snode = CTX_wm_space_node(C); bNode *node; @@ -585,7 +585,7 @@ static int do_lasso_select_node(bContext *C, int mcords[][2], short moves, short static int node_lasso_select_exec(bContext *C, wmOperator *op) { int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short select; diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 7b7170d99e0..ff895c06d57 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -242,7 +242,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) strip->us = 1; BLI_strncpy(seq->name + 2, sce_seq->id.name + 2, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); @@ -343,7 +343,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) strip->us = 1; BLI_strncpy(seq->name + 2, clip->id.name + 2, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); BKE_sequence_calc_disp(scene, seq); BKE_sequencer_sort(scene); @@ -439,7 +439,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op) strip->us = 1; BLI_strncpy(seq->name + 2, mask->id.name + 2, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); BKE_sequence_calc_disp(scene, seq); BKE_sequencer_sort(scene); @@ -820,7 +820,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) seq->type = type; BLI_strncpy(seq->name + 2, BKE_sequence_give_name(seq), sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); sh = BKE_sequence_get_effect(seq); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index c72bff12056..7bec530fae9 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -747,7 +747,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline glDisable(GL_BLEND); } - if (!BKE_seqence_is_valid_check(seq)) { + if (!BKE_sequence_is_valid_check(seq)) { glEnable(GL_POLYGON_STIPPLE); /* panic! */ diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index e7d964ba715..204930e82a6 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1143,13 +1143,13 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op) if (selected) { /* mute unselected */ if (seq->flag & SELECT) { seq->flag |= SEQ_MUTE; - BKE_sequence_invalidate_deendent(scene, seq); + BKE_sequence_invalidate_dependent(scene, seq); } } else { if ((seq->flag & SELECT) == 0) { seq->flag |= SEQ_MUTE; - BKE_sequence_invalidate_deendent(scene, seq); + BKE_sequence_invalidate_dependent(scene, seq); } } } @@ -1194,13 +1194,13 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op) if (selected) { /* unmute unselected */ if (seq->flag & SELECT) { seq->flag &= ~SEQ_MUTE; - BKE_sequence_invalidate_deendent(scene, seq); + BKE_sequence_invalidate_dependent(scene, seq); } } else { if ((seq->flag & SELECT) == 0) { seq->flag &= ~SEQ_MUTE; - BKE_sequence_invalidate_deendent(scene, seq); + BKE_sequence_invalidate_dependent(scene, seq); } } } @@ -1573,7 +1573,7 @@ static int apply_unique_name_cb(Sequence *seq, void *arg_pt) char name[sizeof(seq->name) - 2]; strcpy(name, seq->name + 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); BKE_sequencer_dupe_animdata(scene, name, seq->name + 2); return 1; @@ -1968,7 +1968,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) BKE_sequencer_update_muting(ed); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seqm); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqm); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 3d57f2f88ed..be33b782fdf 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -1109,7 +1109,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) actseq->tmp = SET_INT_IN_POINTER(TRUE); - for (BKE_seqence_iterator_begin(ed, &iter, TRUE); iter.valid; BKE_seqence_iterator_next(&iter)) { + for (BKE_sequence_iterator_begin(ed, &iter, TRUE); iter.valid; BKE_sequence_iterator_next(&iter)) { seq = iter.seq; /* Ignore all seqs already selected! */ @@ -1137,8 +1137,8 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) changed = TRUE; /* Unfortunately, we must restart checks from the beginning. */ - BKE_seqence_iterator_end(&iter); - BKE_seqence_iterator_begin(ed, &iter, TRUE); + BKE_sequence_iterator_end(&iter); + BKE_sequence_iterator_begin(ed, &iter, TRUE); } /* Video strips bellow active one, or any strip for audio (order do no matters here!). */ @@ -1147,7 +1147,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) changed = TRUE; } } - BKE_seqence_iterator_end(&iter); + BKE_sequence_iterator_end(&iter); return changed; } diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c index 5f312ff7fca..135e9b891bb 100644 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ b/source/blender/editors/space_view3d/drawanimviz.c @@ -107,11 +107,6 @@ void draw_motion_path_instance(Scene *scene, * - abort if whole range is past ends of path * - otherwise clamp endpoints to extents of path */ - if ((sfra > mpath->end_frame) || (efra < mpath->start_frame)) { - /* whole path is out of bounds */ - return; - } - if (sfra < mpath->start_frame) { /* start clamp */ sfra = mpath->start_frame; @@ -121,9 +116,14 @@ void draw_motion_path_instance(Scene *scene, efra = mpath->end_frame; } + if ((sfra > mpath->end_frame) || (efra < mpath->start_frame)) { + /* whole path is out of bounds */ + return; + } + len = efra - sfra; - if (len <= 0) { + if ((len <= 0) || (mpath->points == NULL)) { return; } @@ -180,7 +180,7 @@ void draw_motion_path_instance(Scene *scene, UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10); } - /* draw a vertex with this color */ + /* draw a vertex with this color */ glVertex3fv(mpv->co); } @@ -230,7 +230,7 @@ void draw_motion_path_instance(Scene *scene, unsigned char col[4]; UI_GetThemeColor3ubv(TH_TEXT_HI, col); col[3] = 255; - + for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) { char numstr[32]; float co[3]; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index fe4e393b45d..9e628f2f0ff 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -101,6 +101,7 @@ #include "ED_sculpt.h" #include "ED_types.h" #include "ED_curve.h" /* for curve_editnurbs */ +#include "ED_armature.h" #include "UI_resources.h" @@ -239,107 +240,6 @@ static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) return 1; } -/* ************* only use while object drawing ************** - * or after running ED_view3d_init_mats_rv3d - * */ -static void view3d_project_short_clip(ARegion *ar, const float vec[3], short adr[2], int is_local) -{ - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - adr[0] = IS_CLIPPED; - - /* clipplanes in eye space */ - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, vec, is_local)) - return; - } - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmatob, vec4); - - /* clipplanes in window space */ - if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > 0 && fx < ar->winx) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > 0.0f && fy < (float)ar->winy) { - adr[0] = (short)floorf(fx); - adr[1] = (short)floorf(fy); - } - } - } -} - -/* BMESH NOTE: this function is unused in bmesh only */ - -/* only use while object drawing */ -static void UNUSED_FUNCTION(view3d_project_short_noclip) (ARegion * ar, const float vec[3], short adr[2]) -{ - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - adr[0] = IS_CLIPPED; - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmatob, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > -32700 && fx < 32700) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > -32700.0f && fy < 32700.0f) { - adr[0] = (short)floorf(fx); - adr[1] = (short)floorf(fy); - } - } - } -} - -/* same as view3d_project_short_clip but use persmat instead of persmatob for projection */ -static void view3d_project_short_clip_persmat(ARegion *ar, const float vec[3], short adr[2], int is_local) -{ - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - adr[0] = IS_CLIPPED; - - /* clipplanes in eye space */ - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, vec, is_local)) - return; - } - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmat, vec4); - - /* clipplanes in window space */ - if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > 0 && fx < ar->winx) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > 0.0f && fy < (float)ar->winy) { - adr[0] = (short)floorf(fx); - adr[1] = (short)floorf(fy); - } - } - } -} /* ************************ */ /* check for glsl drawing */ @@ -883,13 +783,17 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa if (mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE)) mul_m4_v3(mat, vos->vec); - if (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) - view3d_project_short_clip_persmat(ar, vos->vec, vos->sco, (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0); - else - view3d_project_short_clip(ar, vos->vec, vos->sco, (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0); - - if (vos->sco[0] != IS_CLIPPED) + if (ED_view3d_project_short_ex(ar, + (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, + (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, + vos->vec, vos->sco, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { tot++; + } + else { + vos->sco[0] = IS_CLIPPED; + } } if (tot) { @@ -1974,15 +1878,17 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); float *co = dl ? dl->verts : NULL; int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - short s[2] = {IS_CLIPPED, 0}; ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ for (i = 0; i < N; i++, bp++, co += 3) { if (bp->hide == 0) { - view3d_project_short_clip(vc->ar, dl ? co : bp->vec, s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, bp, s[0], s[1]); + int screen_co[2]; + if (ED_view3d_project_int_object(vc->ar, dl ? co : bp->vec, screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + func(userData, bp, screen_co[0], screen_co[1]); + } } } } @@ -2084,19 +1990,16 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo BMVert *eve = EDBM_vert_at_index(data->vc.em, index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - short s[2] = {IS_CLIPPED, 0}; + const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ? + V3D_PROJ_TEST_NOP : + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; + int screen_co[2]; - if (data->clipVerts != V3D_CLIP_TEST_OFF) { - view3d_project_short_clip(data->vc.ar, co, s, TRUE); - } - else { - float co2[2]; - mul_v3_m4v3(co2, data->vc.obedit->obmat, co); - ED_view3d_project_short_noclip(data->vc.ar, co2, s); + if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_SUCCESS) { + return; } - if (s[0] != IS_CLIPPED) - data->func(data->userData, eve, s[0], s[1], index); + data->func(data->userData, eve, screen_co[0], screen_co[1], index); } } @@ -2157,32 +2060,34 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - short s[2][2]; + int screen_co_a[2]; + int screen_co_b[2]; + + const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ? + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : + V3D_PROJ_TEST_NOP; + + if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_SUCCESS) { + return; + } + if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_SUCCESS) { + return; + } if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) { - view3d_project_short_clip(data->vc.ar, v0co, s[0], TRUE); - view3d_project_short_clip(data->vc.ar, v1co, s[1], TRUE); + /* pass */ } else { - float v1_co[3], v2_co[3]; - - mul_v3_m4v3(v1_co, data->vc.obedit->obmat, v0co); - mul_v3_m4v3(v2_co, data->vc.obedit->obmat, v1co); - - ED_view3d_project_short_noclip(data->vc.ar, v1_co, s[0]); - ED_view3d_project_short_noclip(data->vc.ar, v2_co, s[1]); - if (data->clipVerts == V3D_CLIP_TEST_REGION) { - /* make an int copy */ - int s_int[2][2] = {{s[0][0], s[0][1]}, - {s[1][0], s[1][1]}}; - if (!BLI_rcti_isect_segment(&data->win_rect, s_int[0], s_int[1])) { + if (!BLI_rcti_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { return; } } } - data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index); + data->func(data->userData, eed, + screen_co_a[0], screen_co_a[1], + screen_co_b[0], screen_co_b[1], index); } } @@ -2221,14 +2126,11 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo BMFace *efa = EDBM_face_at_index(data->vc.em, index); if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - float cent2[3]; - short s[2]; - - mul_v3_m4v3(cent2, data->vc.obedit->obmat, cent); - ED_view3d_project_short(data->vc.ar, cent2, s); - - if (s[0] != IS_CLIPPED) { - data->func(data->userData, efa, s[0], s[1], index); + int screen_co[2]; + if (ED_view3d_project_int_object(data->vc.ar, cent, screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + data->func(data->userData, efa, screen_co[0], screen_co[1], index); } } } @@ -2245,8 +2147,7 @@ void mesh_foreachScreenFace( data.func = func; data.userData = userData; - //if (clipVerts) - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); EDBM_index_arrays_init(vc->em, 0, 0, 1); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); @@ -2261,7 +2162,6 @@ void nurbs_foreachScreenVert( void *userData) { Curve *cu = vc->obedit->data; - short s[2] = {IS_CLIPPED, 0}; Nurb *nu; int i; ListBase *nurbs = BKE_curve_editNurbs_get(cu); @@ -2274,22 +2174,31 @@ void nurbs_foreachScreenVert( BezTriple *bezt = &nu->bezt[i]; if (bezt->hide == 0) { + int screen_co[2]; if (cu->drawflag & CU_HIDE_HANDLES) { - view3d_project_short_clip(vc->ar, bezt->vec[1], s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, NULL, bezt, 1, s[0], s[1]); + if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); + } } else { - view3d_project_short_clip(vc->ar, bezt->vec[0], s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, NULL, bezt, 0, s[0], s[1]); - view3d_project_short_clip(vc->ar, bezt->vec[1], s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, NULL, bezt, 1, s[0], s[1]); - view3d_project_short_clip(vc->ar, bezt->vec[2], s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, NULL, bezt, 2, s[0], s[1]); + if (ED_view3d_project_int_object(vc->ar, bezt->vec[0], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + func(userData, nu, NULL, bezt, 0, screen_co[0], screen_co[1]); + } + if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); + } + if (ED_view3d_project_int_object(vc->ar, bezt->vec[2], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]); + } } } } @@ -2299,15 +2208,110 @@ void nurbs_foreachScreenVert( BPoint *bp = &nu->bp[i]; if (bp->hide == 0) { - view3d_project_short_clip(vc->ar, bp->vec, s, TRUE); - if (s[0] != IS_CLIPPED) - func(userData, nu, bp, NULL, -1, s[0], s[1]); + int screen_co[2]; + if (ED_view3d_project_int_object(vc->ar, bp->vec, screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + func(userData, nu, bp, NULL, -1, screen_co[0], screen_co[1]); + } } } } } } +/* ED_view3d_init_mats_rv3d must be called first */ +void armature_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), + void *userData) +{ + bArmature *arm = vc->obedit->data; + EditBone *ebone; + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone)) { + int screen_co_a[2], screen_co_b[2]; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + points_proj_tot++; + } + else { + screen_co_a[0] = IS_CLIPPED; /* weak */ + /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ + } + + /* project tail location to screenspace */ + if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + points_proj_tot++; + } + else { + screen_co_b[0] = IS_CLIPPED; /* weak */ + /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ + } + + if (points_proj_tot) { /* at least one point's projection worked */ + func(userData, ebone, + screen_co_a[0], screen_co_a[1], + screen_co_b[0], screen_co_b[1]); + } + } + } +} + +/* ED_view3d_init_mats_rv3d must be called first */ +/* almost _exact_ copy of #armature_foreachScreenBone */ +void pose_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), + void *userData) +{ + bArmature *arm = vc->obact->data; + bPose *pose = vc->obact->pose; + bPoseChannel *pchan; + + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + if (PBONE_VISIBLE(arm, pchan->bone)) { + int screen_co_a[2], screen_co_b[2]; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (ED_view3d_project_int_object(vc->ar, pchan->pose_head, screen_co_a, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + points_proj_tot++; + } + else { + screen_co_a[0] = IS_CLIPPED; /* weak */ + /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ + } + + /* project tail location to screenspace */ + if (ED_view3d_project_int_object(vc->ar, pchan->pose_tail, screen_co_b, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + points_proj_tot++; + } + else { + screen_co_b[0] = IS_CLIPPED; /* weak */ + /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ + } + + if (points_proj_tot) { /* at least one point's projection worked */ + func(userData, pchan, + screen_co_a[0], screen_co_a[1], + screen_co_b[0], screen_co_b[1]); + } + } + } +} + /* ************** DRAW MESH ****************** */ /* First section is all the "simple" draw routines, @@ -3672,7 +3676,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } } - if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { /* GPU_begin_object_materials checked if this is needed */ if (do_alpha_after) { if (ob->dtx & OB_DRAWXRAY) { @@ -6581,7 +6585,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short return; /* xray delay? */ - if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { /* don't do xray in particle mode, need the z-buffer */ if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ @@ -6616,7 +6620,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short /* which wire color */ if ((dflag & DRAW_CONSTCOLOR) == 0) { - ED_view3d_project_short(ar, ob->obmat[3], &base->sx); + ED_view3d_project_base(ar, base); draw_object_wire_color(scene, base, _ob_wire_col, warning_recursive); ob_wire_col = _ob_wire_col; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 5190605052f..bbc980ec114 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -554,32 +554,23 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) { - int mx, my, co[2]; - int flag; - + int co[2]; + /* we don't want the clipping for cursor */ - flag = v3d->flag; - v3d->flag = 0; - ED_view3d_project_int(ar, give_cursor(scene, v3d), co); - v3d->flag = flag; - - mx = co[0]; - my = co[1]; - - if (mx != IS_CLIPPED) { + if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { setlinestyle(0); cpack(0xFF); - circ((float)mx, (float)my, 10.0); + circ((float)co[0], (float)co[1], 10.0); setlinestyle(4); cpack(0xFFFFFF); - circ((float)mx, (float)my, 10.0); + circ((float)co[0], (float)co[1], 10.0); setlinestyle(0); cpack(0x0); - sdrawline(mx - 20, my, mx - 5, my); - sdrawline(mx + 5, my, mx + 20, my); - sdrawline(mx, my - 20, mx, my - 5); - sdrawline(mx, my + 5, mx, my + 20); + sdrawline(co[0] - 20, co[1], co[0] - 5, co[1]); + sdrawline(co[0] + 5, co[1], co[0] + 20, co[1]); + sdrawline(co[0], co[1] - 20, co[0], co[1] - 5); + sdrawline(co[0], co[1] + 5, co[0], co[1] + 20); } } @@ -1928,7 +1919,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas if (base->object->restrictflag & OB_RESTRICT_VIEW) return; tbase.flag = OB_FROMDUPLI | base->flag; - lb = object_duplilist(scene, base->object); + lb = object_duplilist(scene, base->object, FALSE); // BLI_sortlist(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ dob = dupli_step(lb->first); @@ -2341,7 +2332,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) if (ob->transflag & OB_DUPLI) { DupliObject *dob; - ListBase *lb = object_duplilist(scene, ob); + ListBase *lb = object_duplilist(scene, ob, FALSE); for (dob = lb->first; dob; dob = dob->next) if (dob->ob->type == OB_LAMP) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 03c5e232036..3c24fedf4a7 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1275,8 +1275,8 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot) /* -* this is basically just the pan only code + the rotate only code crammed into one function that does both -*/ + * this is basically just the pan only code + the rotate only code crammed into one function that does both + */ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event) { if (event->type != NDOF_MOTION) @@ -3571,57 +3571,49 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot) /* ***************** 3d cursor cursor op ******************* */ /* mx my in region coords */ -static int set_3dcursor_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); - float dx, dy, fz, *fp = NULL, dvec[3], oldcurs[3]; - int mval[2]; -// short ctrl= 0; // XXX + float *fp = NULL; + float mval_fl[2]; int flip; fp = give_cursor(scene, v3d); -// if (obedit && ctrl) lr_click= 1; - copy_v3_v3(oldcurs, fp); - - ED_view3d_project_int_noclip(ar, fp, mval); flip = initgrabz(rv3d, fp[0], fp[1], fp[2]); - /* reset the depth based on the view offset */ + /* reset the depth based on the view offset (we _know_ the offset is infront of us) */ if (flip) { negate_v3_v3(fp, rv3d->ofs); - - /* re initialize */ - ED_view3d_project_int_noclip(ar, fp, mval); - flip = initgrabz(rv3d, fp[0], fp[1], fp[2]); - (void)flip; + /* re initialize, no need to check flip again */ + /* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]); } - if (mval[0] != IS_CLIPPED) { - short depth_used = 0; + if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + short depth_used = FALSE; if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */ view3d_operator_needs_opengl(C); if (ED_view3d_autodist(scene, ar, v3d, event->mval, fp)) - depth_used = 1; + depth_used = TRUE; } - if (depth_used == 0) { - float mval_f[2]; - VECSUB2D(mval_f, mval, event->mval); - ED_view3d_win_to_delta(ar, mval_f, dvec); + if (depth_used == FALSE) { + float dvec[3]; + VECSUB2D(mval_fl, mval_fl, event->mval); + ED_view3d_win_to_delta(ar, mval_fl, dvec); sub_v3_v3(fp, dvec); } } else { - - dx = ((float)(event->mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2); - dy = ((float)(event->mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2); - - fz = rv3d->persmat[0][3] * fp[0] + rv3d->persmat[1][3] * fp[1] + rv3d->persmat[2][3] * fp[2] + rv3d->persmat[3][3]; - fz = fz / rv3d->zfac; + const float dx = ((float)(event->mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2); + const float dy = ((float)(event->mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2); + const float fz = (rv3d->persmat[0][3] * fp[0] + + rv3d->persmat[1][3] * fp[1] + + rv3d->persmat[2][3] * fp[2] + + rv3d->persmat[3][3]) / rv3d->zfac; fp[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy + rv3d->persinv[2][0] * fz) - rv3d->ofs[0]; fp[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy + rv3d->persinv[2][1] * fz) - rv3d->ofs[1]; @@ -3645,7 +3637,7 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot) ot->idname = "VIEW3D_OT_cursor3d"; /* api callbacks */ - ot->invoke = set_3dcursor_invoke; + ot->invoke = view3d_cursor3d_invoke; ot->poll = ED_operator_view3d_active; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index e409ad4e81e..8510e39271b 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -110,15 +110,16 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m { float dvec[3]; int mval_cpy[2]; + eV3DProjStatus ret; mval_cpy[0] = mval[0]; mval_cpy[1] = mval[1]; - ED_view3d_project_int_noclip(vc->ar, fp, mval_cpy); + ret = ED_view3d_project_int_global(vc->ar, fp, mval_cpy, V3D_PROJ_TEST_NOP); initgrabz(vc->rv3d, fp[0], fp[1], fp[2]); - if (mval_cpy[0] != IS_CLIPPED) { + if (ret == V3D_PROJ_RET_SUCCESS) { const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]), (float)(mval_cpy[1] - mval[1])}; ED_view3d_win_to_delta(vc->ar, mval_f, dvec); @@ -255,10 +256,33 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select) typedef struct LassoSelectUserData { ViewContext *vc; - rcti *rect; - int (*mcords)[2], moves, select, pass, done; + const rcti *rect; + const int (*mcords)[2]; + int moves; + int select; + + /* runtime */ + int pass; + int is_done; + int is_change; } LassoSelectUserData; +static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data, + ViewContext *vc, const rcti *rect, const int (*mcords)[2], + const int moves, const int select) +{ + r_data->vc = vc; + r_data->rect = rect; + r_data->mcords = mcords; + r_data->moves = moves; + r_data->select = select; + + /* runtime */ + r_data->pass = 0; + r_data->is_done = FALSE; + r_data->is_change = FALSE; +} + static int view3d_selectable_data(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -289,12 +313,12 @@ static int view3d_selectable_data(bContext *C) /* helper also for borderselect */ -static int edge_fully_inside_rect(rcti *rect, short x1, short y1, short x2, short y2) +static int edge_fully_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) { return BLI_rcti_isect_pt(rect, x1, y1) && BLI_rcti_isect_pt(rect, x2, y2); } -static int edge_inside_rect(rcti *rect, short x1, short y1, short x2, short y2) +static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) { int d1, d2, d3, d4; @@ -319,35 +343,70 @@ static int edge_inside_rect(rcti *rect, short x1, short y1, short x2, short y2) return 1; } -/* warning; lasso select with backbuffer-check draws in backbuf with persp(PERSP_WIN) - * and returns with persp(PERSP_VIEW). After lasso select backbuf is not OK - */ -static void do_lasso_select_pose(ViewContext *vc, Object *ob, int mcords[][2], short moves, short select) +static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) { - bPoseChannel *pchan; - float vec[3]; - int sco1[2], sco2[2]; - bArmature *arm = ob->data; - - if ((ob->type != OB_ARMATURE) || (ob->pose == NULL)) return; + LassoSelectUserData *data = userData; + bArmature *arm = data->vc->obact->data; - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if (PBONE_VISIBLE(arm, pchan->bone) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0) { - mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); - ED_view3d_project_int(vc->ar, vec, sco1); - mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); - ED_view3d_project_int(vc->ar, vec, sco2); - - if (BLI_lasso_is_edge_inside(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1], IS_CLIPPED)) { - if (select) pchan->bone->flag |= BONE_SELECTED; - else pchan->bone->flag &= ~BONE_SELECTED; + if (PBONE_SELECTABLE(arm, pchan->bone)) { + int is_point_done = FALSE; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (x0 != IS_CLIPPED) { + points_proj_tot++; + if (BLI_rcti_isect_pt(data->rect, x0, y0) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, INT_MAX)) + { + is_point_done = TRUE; + } + } + + /* project tail location to screenspace */ + if (x1 != IS_CLIPPED) { + points_proj_tot++; + if (BLI_rcti_isect_pt(data->rect, x1, y1) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, INT_MAX)) + { + is_point_done = TRUE; } } + + /* if one of points selected, we skip the bone itself */ + if ((is_point_done == TRUE) || + ((is_point_done == FALSE) && (points_proj_tot == 2) && + BLI_lasso_is_edge_inside(data->mcords, data->moves, x0, y0, x1, y1, INT_MAX))) + { + if (data->select) pchan->bone->flag |= BONE_SELECTED; + else pchan->bone->flag &= ~BONE_SELECTED; + data->is_change = TRUE; + } + data->is_change |= is_point_done; } +} +static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[][2], short moves, short select) +{ + LassoSelectUserData data; + rcti rect; - if (arm->flag & ARM_HAS_VIZ_DEPS) { - /* mask modifier ('armature' mode), etc. */ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + if ((ob->type != OB_ARMATURE) || (ob->pose == NULL)) { + return; + } + + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); + + ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); + + BLI_lasso_boundbox(&rect, mcords, moves); + + pose_foreachScreenBone(vc, do_lasso_select_pose__doSelectBone, &data); + + if (data.is_change) { + bArmature *arm = ob->data; + if (arm->flag & ARM_HAS_VIZ_DEPS) { + /* mask modifier ('armature' mode), etc. */ + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + } } } @@ -362,7 +421,7 @@ static void object_deselect_all_visible(Scene *scene, View3D *v3d) } } -static void do_lasso_select_objects(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], const short moves, short extend, short select) { Base *base; @@ -371,7 +430,7 @@ static void do_lasso_select_objects(ViewContext *vc, int mcords[][2], short move for (base = vc->scene->base.first; base; base = base->next) { if (BASE_SELECTABLE(vc->v3d, base)) { /* use this to avoid un-needed lasso lookups */ - ED_view3d_project_short(vc->ar, base->object->obmat[3], &base->sx); + ED_view3d_project_base(vc->ar, base); if (BLI_lasso_is_point_inside(mcords, moves, base->sx, base->sy, IS_CLIPPED)) { if (select) ED_base_object_select(base, BA_SELECT); @@ -406,7 +465,7 @@ static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, IS_CLIPPED)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); - data->done = TRUE; + data->is_done = TRUE; } } else { @@ -427,7 +486,7 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int } } -static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; ToolSettings *ts = vc->scene->toolsettings; @@ -439,13 +498,7 @@ static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves, /* set editmesh */ vc->em = BMEdit_FromObject(vc->obedit); - data.vc = vc; - data.rect = ▭ - data.mcords = mcords; - data.moves = moves; - data.select = select; - data.done = FALSE; - data.pass = 0; + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT); @@ -469,7 +522,7 @@ static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves, data.pass = 0; mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); - if (data.done == 0) { + if (data.is_done == 0) { data.pass = 1; mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); } @@ -521,15 +574,11 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP } } -static void do_lasso_select_curve(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; - /* set vc->editnurb */ - data.vc = vc; - data.mcords = mcords; - data.moves = moves; - data.select = select; + view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); if (extend == 0 && select) CU_deselect_all(vc->obedit); @@ -546,14 +595,11 @@ static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } -static void do_lasso_select_lattice(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; - /* set editdata in vc */ - data.mcords = mcords; - data.moves = moves; - data.select = select; + view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); if (extend == 0 && select) ED_setflagsLatt(vc->obedit, 0); @@ -562,51 +608,70 @@ static void do_lasso_select_lattice(ViewContext *vc, int mcords[][2], short move lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); } -static void do_lasso_select_armature(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) { - bArmature *arm = vc->obedit->data; - EditBone *ebone; - float vec[3]; - short sco1[2], sco2[2], didpoint; - int change = FALSE; + LassoSelectUserData *data = userData; + bArmature *arm = data->vc->obedit->data; - if (extend == 0 && select) - ED_armature_deselect_all_visible(vc->obedit); + if (EBONE_SELECTABLE(arm, ebone)) { + int is_point_done = FALSE; + int points_proj_tot = 0; - /* set editdata in vc */ - - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) { - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head); - ED_view3d_project_short(vc->ar, vec, sco1); - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail); - ED_view3d_project_short(vc->ar, vec, sco2); - - didpoint = 0; - if (BLI_lasso_is_point_inside(mcords, moves, sco1[0], sco1[1], IS_CLIPPED)) { - if (select) ebone->flag |= BONE_ROOTSEL; - else ebone->flag &= ~BONE_ROOTSEL; - didpoint = 1; - change = TRUE; - } - if (BLI_lasso_is_point_inside(mcords, moves, sco2[0], sco2[1], IS_CLIPPED)) { - if (select) ebone->flag |= BONE_TIPSEL; - else ebone->flag &= ~BONE_TIPSEL; - didpoint = 1; - change = TRUE; + /* project head location to screenspace */ + if (x0 != IS_CLIPPED) { + points_proj_tot++; + if (BLI_rcti_isect_pt(data->rect, x0, y0) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, INT_MAX)) + { + is_point_done = TRUE; + if (data->select) ebone->flag |= BONE_ROOTSEL; + else ebone->flag &= ~BONE_ROOTSEL; } - /* if one of points selected, we skip the bone itself */ - if (didpoint == 0 && - BLI_lasso_is_edge_inside(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1], IS_CLIPPED)) + } + + /* project tail location to screenspace */ + if (x1 != IS_CLIPPED) { + points_proj_tot++; + if (BLI_rcti_isect_pt(data->rect, x1, y1) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, INT_MAX)) { - if (select) ebone->flag |= BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED; - else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - change = TRUE; + is_point_done = TRUE; + if (data->select) ebone->flag |= BONE_TIPSEL; + else ebone->flag &= ~BONE_TIPSEL; } } + + /* if one of points selected, we skip the bone itself */ + if ((is_point_done == FALSE) && (points_proj_tot == 2) && + BLI_lasso_is_edge_inside(data->mcords, data->moves, x0, y0, x1, y1, INT_MAX)) + { + if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + data->is_change = TRUE; + } + + data->is_change |= is_point_done; } - - if (change) { +} + +static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) +{ + LassoSelectUserData data; + rcti rect; + + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + + BLI_lasso_boundbox(&rect, mcords, moves); + + if (extend == 0 && select) + ED_armature_deselect_all_visible(vc->obedit); + + armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data); + + if (data.is_change) { + bArmature *arm = vc->obedit->data; ED_armature_sync_selection(arm->edbo); ED_armature_validate_active(arm); WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit); @@ -614,29 +679,29 @@ static void do_lasso_select_armature(ViewContext *vc, int mcords[][2], short mov } - - -static void do_lasso_select_meta(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { MetaBall *mb = (MetaBall *)vc->obedit->data; MetaElem *ml; - float vec[3]; - short sco[2]; if (extend == 0 && select) { + /* XXX, make an editor function as is done elsewhere */ for (ml = mb->editelems->first; ml; ml = ml->next) { ml->flag &= ~SELECT; } } - for (ml = mb->editelems->first; ml; ml = ml->next) { - - mul_v3_m4v3(vec, vc->obedit->obmat, &ml->x); - ED_view3d_project_short(vc->ar, vec, sco); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - if (BLI_lasso_is_point_inside(mcords, moves, sco[0], sco[1], IS_CLIPPED)) { - if (select) ml->flag |= SELECT; - else ml->flag &= ~SELECT; + for (ml = mb->editelems->first; ml; ml = ml->next) { + int screen_co[2]; + if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + if (BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX)) { + if (select) ml->flag |= SELECT; + else ml->flag &= ~SELECT; + } } } } @@ -700,7 +765,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int return OPERATOR_FINISHED; } -static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { Object *ob = vc->obact; Mesh *me = ob ? ob->data : NULL; @@ -722,7 +787,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short mo paintvert_flush_flags(ob); } -static void do_lasso_select_paintface(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { Object *ob = vc->obact; Mesh *me = ob ? ob->data : NULL; @@ -777,7 +842,9 @@ static void do_lasso_select_node(int mcords[][2], short moves, short select) } #endif -static void view3d_lasso_select(bContext *C, ViewContext *vc, int mcords[][2], short moves, short extend, short select) +static void view3d_lasso_select(bContext *C, ViewContext *vc, + const int mcords[][2], short moves, + short extend, short select) { Object *ob = CTX_data_active_object(C); @@ -828,7 +895,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) { ViewContext vc; int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short extend, select; @@ -1059,8 +1126,7 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int } else { int temp, dist = 15; - - ED_view3d_project_short(vc->ar, base->object->obmat[3], &base->sx); + ED_view3d_project_base(vc->ar, base); temp = abs(base->sx - mval[0]) + abs(base->sy - mval[1]); if (temp < dist) @@ -1341,8 +1407,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese base = startbase; while (base) { if (BASE_SELECTABLE(v3d, base)) { - ED_view3d_project_short(ar, base->object->obmat[3], &base->sx); - + ED_view3d_project_base(ar, base); temp = abs(base->sx - mval[0]) + abs(base->sy - mval[1]); if (base == BASACT) temp += 10; if (temp < dist) { @@ -1513,19 +1578,37 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese typedef struct BoxSelectUserData { ViewContext *vc; - rcti *rect; - int select, pass, done; + const rcti *rect; + int select; + + /* runtime */ + int pass; + int is_done; + int is_change; } BoxSelectUserData; -int edge_inside_circle(int centx, int centy, int rad, int x1, int y1, int x2, int y2) +static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, + ViewContext *vc, const rcti *rect, const int select) +{ + r_data->vc = vc; + r_data->rect = rect; + r_data->select = select; + + /* runtime */ + r_data->pass = 0; + r_data->is_done = FALSE; + r_data->is_change = FALSE; +} + +int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, int y2) { - int radsq = rad * rad; + int radius_squared = radius * radius; /* check points in circle itself */ - if ((x1 - centx) * (x1 - centx) + (y1 - centy) * (y1 - centy) <= radsq) { + if ((x1 - centx) * (x1 - centx) + (y1 - centy) * (y1 - centy) <= radius_squared) { return TRUE; } - else if ((x2 - centx) * (x2 - centx) + (y2 - centy) * (y2 - centy) <= radsq) { + else if ((x2 - centx) * (x2 - centx) + (y2 - centy) * (y2 - centy) <= radius_squared) { return TRUE; } else { @@ -1533,7 +1616,7 @@ int edge_inside_circle(int centx, int centy, int rad, int x1, int y1, int x2, in const float v1[2] = {x1, y1}; const float v2[2] = {x2, y2}; /* pointdistline */ - if (dist_squared_to_line_segment_v2(cent, v1, v2) < (float)radsq) { + if (dist_squared_to_line_segment_v2(cent, v1, v2) < (float)radius_squared) { return TRUE; } } @@ -1577,9 +1660,7 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int exte { BoxSelectUserData data; - data.vc = vc; - data.rect = rect; - data.select = select; + view3d_userdata_boxselect_init(&data, vc, rect, select); if (extend == 0 && select) CU_deselect_all(vc->obedit); @@ -1602,9 +1683,7 @@ static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int ex { BoxSelectUserData data; - data.vc = vc; - data.rect = rect; - data.select = select; + view3d_userdata_boxselect_init(&data, vc, rect, select); if (extend == 0 && select) ED_setflagsLatt(vc->obedit, 0); @@ -1631,7 +1710,7 @@ static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0 if (data->pass == 0) { if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); - data->done = TRUE; + data->is_done = TRUE; } } else { @@ -1655,11 +1734,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten ToolSettings *ts = vc->scene->toolsettings; int bbsel; - data.vc = vc; - data.rect = rect; - data.select = select; - data.pass = 0; - data.done = FALSE; + view3d_userdata_boxselect_init(&data, vc, rect, select); if (extend == 0 && select) EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT); @@ -1684,7 +1759,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten data.pass = 0; mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); - if (data.done == 0) { + if (data.is_done == 0) { data.pass = 1; mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); } @@ -2142,15 +2217,32 @@ typedef struct CircleSelectUserData { short select; int mval[2]; float radius; + float radius_squared; + + /* runtime */ + int is_change; } CircleSelectUserData; +static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, + ViewContext *vc, const int select, const int mval[2], const float rad) +{ + r_data->vc = vc; + r_data->select = select; + copy_v2_v2_int(r_data->mval, mval); + r_data->radius = rad; + r_data->radius_squared = rad * rad; + + /* runtime */ + r_data->is_change = FALSE; +} + static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; - if (r <= data->radius) { + if (len_squared_v2(delta) <= data->radius_squared) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } @@ -2165,10 +2257,10 @@ static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0 static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); - - if (r <= data->radius) { + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; + + if (len_squared_v2(delta) <= data->radius_squared) { BM_face_select_set(data->vc->em->bm, efa, data->select); } } @@ -2184,11 +2276,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f vc->em = BMEdit_FromObject(vc->obedit); - data.vc = vc; - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); if (ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { @@ -2259,12 +2347,13 @@ static void paint_vertsel_circle_select(ViewContext *vc, int select, const int m static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - if (r <= data->radius) { + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; + + if (len_squared_v2(delta) <= data->radius_squared) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); @@ -2302,6 +2391,7 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval data.mval[1] = mval[1]; data.radius = rad; data.vc = vc; + data.is_change = FALSE; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data); @@ -2311,10 +2401,10 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int y) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; - if (r <= data->radius) { + if (len_squared_v2(delta) <= data->radius_squared) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } @@ -2322,12 +2412,7 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2] { CircleSelectUserData data; - /* set vc-> edit data */ - - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data); @@ -2338,10 +2423,10 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2] static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); - - if (r <= data->radius) { + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; + + if (len_squared_v2(delta) <= data->radius_squared) { if (data->select) pchan->bone->flag |= BONE_SELECTED; else @@ -2350,63 +2435,78 @@ static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int } return 0; } +static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) +{ + CircleSelectUserData *data = userData; + bArmature *arm = data->vc->obact->data; + + if (PBONE_SELECTABLE(arm, pchan->bone)) { + int is_point_done = FALSE; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (x0 != IS_CLIPPED) { + points_proj_tot++; + if (pchan_circle_doSelectJoint(data, pchan, x0, y0)) { + is_point_done = TRUE; + } + } + + /* project tail location to screenspace */ + if (x1 != IS_CLIPPED) { + points_proj_tot++; + if (pchan_circle_doSelectJoint(data, pchan, x1, y1)) { + is_point_done = TRUE; + } + } + + /* check if the head and/or tail is in the circle + * - the call to check also does the selection already + */ + + /* only if the endpoints didn't get selected, deal with the middle of the bone too + * It works nicer to only do this if the head or tail are not in the circle, + * otherwise there is no way to circle select joints alone */ + if ((is_point_done == FALSE) && (points_proj_tot == 2) && + edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1)) + { + if (data->select) pchan->bone->flag |= BONE_SELECTED; + else pchan->bone->flag &= ~BONE_SELECTED; + data->is_change = TRUE; + } + + data->is_change |= is_point_done; + } +} static void pose_circle_select(ViewContext *vc, int select, const int mval[2], float rad) { CircleSelectUserData data; - bArmature *arm = vc->obact->data; - bPose *pose = vc->obact->pose; - bPoseChannel *pchan; - int change = FALSE; - /* set vc->edit data */ - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ - /* check each PoseChannel... */ - /* TODO: could be optimized at some point */ - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - short sco1[2], sco2[2], didpoint = 0; - float vec[3]; - - /* skip invisible bones */ - if (PBONE_VISIBLE(arm, pchan->bone) == 0) - continue; - - /* project head location to screenspace */ - mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head); - ED_view3d_project_short(vc->ar, vec, sco1); - - /* project tail location to screenspace */ - mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_tail); - ED_view3d_project_short(vc->ar, vec, sco2); - - /* check if the head and/or tail is in the circle - * - the call to check also does the selection already - */ - if (pchan_circle_doSelectJoint(&data, pchan, sco1[0], sco1[1])) - didpoint = 1; - if (pchan_circle_doSelectJoint(&data, pchan, sco2[0], sco2[1])) - didpoint = 1; - - change |= didpoint; - } + pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data); + + if (data.is_change) { + bArmature *arm = vc->obact->data; - if (change) { WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obact); + + if (arm->flag & ARM_HAS_VIZ_DEPS) { + /* mask modifier ('armature' mode), etc. */ + DAG_id_tag_update(&vc->obact->id, OB_RECALC_DATA); + } } } static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head) { CircleSelectUserData *data = userData; - int mx = x - data->mval[0], my = y - data->mval[1]; - float r = sqrt(mx * mx + my * my); + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; - if (r <= data->radius) { + if (len_squared_v2(delta) <= data->radius_squared) { if (head) { if (data->select) ebone->flag |= BONE_ROOTSEL; @@ -2423,57 +2523,61 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int } return 0; } -static void armature_circle_select(ViewContext *vc, int select, const int mval[2], float rad) +static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) { - CircleSelectUserData data; - bArmature *arm = vc->obedit->data; - EditBone *ebone; - int change = FALSE; - - /* set vc->edit data */ - data.select = select; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radius = rad; + CircleSelectUserData *data = userData; + bArmature *arm = data->vc->obedit->data; + + if (EBONE_SELECTABLE(arm, ebone)) { + int is_point_done = FALSE; + int points_proj_tot = 0; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - - /* check each EditBone... */ - /* TODO: could be optimized at some point */ - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - short sco1[2], sco2[2], didpoint = 0; - float vec[3]; - /* project head location to screenspace */ - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head); - ED_view3d_project_short(vc->ar, vec, sco1); - + if (x0 != IS_CLIPPED) { + points_proj_tot++; + if (armature_circle_doSelectJoint(data, ebone, x0, y0, TRUE)) { + is_point_done = TRUE; + } + } + /* project tail location to screenspace */ - mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail); - ED_view3d_project_short(vc->ar, vec, sco2); - - /* check if the head and/or tail is in the circle - * - the call to check also does the selection already + if (x1 != IS_CLIPPED) { + points_proj_tot++; + if (armature_circle_doSelectJoint(data, ebone, x1, y1, FALSE)) { + is_point_done = TRUE; + } + } + + /* check if the head and/or tail is in the circle + * - the call to check also does the selection already */ - if (armature_circle_doSelectJoint(&data, ebone, sco1[0], sco1[1], 1)) - didpoint = 1; - if (armature_circle_doSelectJoint(&data, ebone, sco2[0], sco2[1], 0)) - didpoint = 1; - - /* only if the endpoints didn't get selected, deal with the middle of the bone too */ - /* XXX should we just do this always? */ - if ((didpoint == 0) && edge_inside_circle(mval[0], mval[1], rad, sco1[0], sco1[1], sco2[0], sco2[1])) { - if (select) - ebone->flag |= BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED; - else - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - change = TRUE; + + /* only if the endpoints didn't get selected, deal with the middle of the bone too + * It works nicer to only do this if the head or tail are not in the circle, + * otherwise there is no way to circle select joints alone */ + if ((is_point_done == FALSE) && (points_proj_tot == 2) && + edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1)) + { + if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + data->is_change = TRUE; } - - change |= didpoint; + + data->is_change |= is_point_done; } +} +static void armature_circle_select(ViewContext *vc, int select, const int mval[2], float rad) +{ + CircleSelectUserData data; + bArmature *arm = vc->obedit->data; + + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + + armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data); - if (change) { + if (data.is_change) { ED_armature_sync_selection(arm->edbo); ED_armature_validate_active(arm); WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit); @@ -2556,7 +2660,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) select = select ? BA_SELECT : BA_DESELECT; for (base = FIRSTBASE; base; base = base->next) { if (BASE_SELECTABLE(v3d, base)) { - ED_view3d_project_short(ar, base->object->obmat[3], &base->sx); + ED_view3d_project_base(ar, base); if (base->sx != IS_CLIPPED) { int dx = base->sx - x; int dy = base->sy - y; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index ff518e6ce5b..f138a95b0ef 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -858,6 +858,19 @@ void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3 } } +eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) +{ + eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN); + + if (ret != V3D_PROJ_RET_SUCCESS) { + base->sx = IS_CLIPPED; + base->sy = 0; + } + + return ret; +} + int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) { /* return 1: draw */ @@ -893,148 +906,145 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) return 0; } -void ED_view3d_project_short(ARegion *ar, const float co[3], short r_co[2]) /* clips */ +/* perspmat is typically... + * - 'rv3d->perspmat', is_local == FALSE + * - 'rv3d->perspmatob', is_local == TRUE + */ +static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, + float perspmat[4][4], const int is_local, /* normally hidden */ + const float co[3], float r_co[2], eV3DProjTest flag) { - RegionView3D *rv3d = ar->regiondata; float fx, fy, vec4[4]; - - r_co[0] = IS_CLIPPED; - - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, co, FALSE)) { - return; + + if (flag & V3D_PROJ_TEST_CLIP_BB) { + RegionView3D *rv3d = ar->regiondata; + if (rv3d->rflag & RV3D_CLIPPING) { + if (ED_view3d_clipping_test(rv3d, co, is_local)) { + return V3D_PROJ_RET_CLIP_BB; + } } } - + copy_v3_v3(vec4, co); vec4[3] = 1.0; - mul_m4_v4(rv3d->persmat, vec4); - + mul_m4_v4(perspmat, vec4); + if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > 0 && fx < ar->winx) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > 0.0f && fy < (float)ar->winy) { + fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]); + if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) { + fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]); + if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) { r_co[0] = (short)floor(fx); r_co[1] = (short)floor(fy); } + else { + return V3D_PROJ_RET_CLIP_WIN; + } } + else { + return V3D_PROJ_RET_CLIP_WIN; + } + } + else { + return V3D_PROJ_RET_CLIP_NEAR; } + + return V3D_PROJ_RET_SUCCESS; } -void ED_view3d_project_int(ARegion *ar, const float co[3], int r_co[2]) +eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], short r_co[2], eV3DProjTest flag) { - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - r_co[0] = (int)2140000000.0f; - - mul_m4_v4(rv3d->persmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > -2140000000.0f && fx < 2140000000.0f) { - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > -2140000000.0f && fy < 2140000000.0f) { - r_co[0] = (int)floor(fx); - r_co[1] = (int)floor(fy); - } + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_SUCCESS) { + if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && + (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) + { + r_co[0] = (short)floor(tvec[0]); + r_co[1] = (short)floor(tvec[1]); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; } } + return ret; } -void ED_view3d_project_int_noclip(ARegion *ar, const float co[3], int r_co[2]) +eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], int r_co[2], eV3DProjTest flag) { - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmat, vec4); - - if (fabs(vec4[3]) > BL_NEAR_CLIP) { - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - r_co[0] = (int)floor(fx); - r_co[1] = (int)floor(fy); - } - else { - r_co[0] = ar->winx / 2; - r_co[1] = ar->winy / 2; + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_SUCCESS) { + if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && + (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) + { + r_co[0] = (int)floor(tvec[0]); + r_co[1] = (int)floor(tvec[1]); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } } + return ret; } -void ED_view3d_project_short_noclip(ARegion *ar, const float co[3], short r_co[2]) +eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], float r_co[2], eV3DProjTest flag) { - RegionView3D *rv3d = ar->regiondata; - float fx, fy, vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - r_co[0] = IS_CLIPPED; - - mul_m4_v4(rv3d->persmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); - - if (fx > -32700 && fx < 32700) { - - fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); - - if (fy > -32700.0f && fy < 32700.0f) { - r_co[0] = (short)floor(fx); - r_co[1] = (short)floor(fy); - } + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_SUCCESS) { + if (finite(tvec[0]) && + finite(tvec[1])) + { + copy_v2_v2(r_co, tvec); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; } } + return ret; } -void ED_view3d_project_float(ARegion *ar, const float co[3], float r_co[2]) +/* --- short --- */ +eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} - float vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - r_co[0] = IS_CLIPPED; - - mul_m4_v4(rv3d->persmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; - r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; - } +/* --- int --- */ +eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } -void ED_view3d_project_float_noclip(ARegion *ar, const float co[3], float r_co[2]) +/* --- float --- */ +eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; - float vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - - mul_m4_v4(rv3d->persmat, vec4); - - if (fabs(vec4[3]) > BL_NEAR_CLIP) { - r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; - r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; - } - else { - r_co[0] = ar->winx / 2.0f; - r_co[1] = ar->winy / 2.0f; - } + return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } /* copies logic of get_view3d_viewplane(), keep in sync */ @@ -1309,7 +1319,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b Base tbase; tbase.flag = OB_FROMDUPLI; - lb = object_duplilist(scene, base->object); + lb = object_duplilist(scene, base->object, FALSE); for (dob = lb->first; dob; dob = dob->next) { tbase.object = dob->ob; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 38c3e832284..0458b29edda 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -57,6 +57,8 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "BLF_api.h" + #include "BKE_nla.h" #include "BKE_bmesh.h" #include "BKE_context.h" @@ -89,12 +91,14 @@ #include "BLI_linklist.h" #include "BLI_smallhash.h" #include "BLI_array.h" +#include "PIL_time.h" +#include "UI_interface_icons.h" #include "UI_resources.h" #include "transform.h" -#include <stdio.h> +#include <stdio.h> // XXX: duplicated??? static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg); static int doEdgeSlide(TransInfo *t, float perc); @@ -226,8 +230,12 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) void projectIntView(TransInfo *t, const float vec[3], int adr[2]) { if (t->spacetype == SPACE_VIEW3D) { - if (t->ar->regiontype == RGN_TYPE_WINDOW) - ED_view3d_project_int_noclip(t->ar, vec, adr); + if (t->ar->regiontype == RGN_TYPE_WINDOW) { + if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + adr[0] = (int)2140000000.0f; /* this is what was done in 2.64, perhaps we can be smarter? */ + adr[1] = (int)2140000000.0f; + } + } } else if (t->spacetype == SPACE_IMAGE) { SpaceImage *sima = t->sa->spacedata.first; @@ -345,7 +353,11 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2]) case SPACE_VIEW3D: { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - ED_view3d_project_float_noclip(t->ar, vec, adr); + if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + /* XXX, 2.64 and prior did this, weak! */ + adr[0] = t->ar->winx / 2.0f; + adr[1] = t->ar->winy / 2.0f; + } return; } break; @@ -820,7 +832,7 @@ int transformEvent(TransInfo *t, wmEvent *event) float mati[3][3] = MAT3_UNITY; char cmode = constraintModeToChar(t); int handled = 1; - + t->redraw |= handleMouseInput(t, &t->mouse, event); if (event->type == MOUSEMOVE) { @@ -1264,10 +1276,13 @@ int transformEvent(TransInfo *t, wmEvent *event) if (t->handleEvent) t->redraw |= t->handleEvent(t, event); - if (handled || t->redraw) + if (handled || t->redraw) { + t->last_update = PIL_check_seconds_timer(); return 0; - else + } + else { return OPERATOR_PASS_THROUGH; + } } int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int cent2d[2]) @@ -1550,14 +1565,63 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi drawNonPropEdge(C, t); } -#if 0 -static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg)) +/* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */ +static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) { -// TransInfo *t = arg; -// -// drawHelpline(C, t->mval[0], t->mval[1], t); + int show_warning; + + /* red border around the viewport */ + UI_ThemeColor(TH_REDALERT); + + glBegin(GL_LINE_LOOP); + glVertex2f(1, 1); + glVertex2f(1, ar->winy-1); + glVertex2f(ar->winx-1, ar->winy-1); + glVertex2f(ar->winx-1, 1); + glEnd(); + + /* Entire warning should "blink" to catch periphery attention without being overly distracting + * much like how a traditional recording sign in the corner of a camcorder works + * + * - Blink frequency here is 0.5 secs (i.e. a compromise between epilepsy-inducing flicker + too slow to notice). + * We multiply by two to speed up the odd/even time-in-seconds = on/off toggle. + * - Always start with warning shown so that animators are more likely to notice when starting to transform + */ + show_warning = (int)(t->last_update * 2.0) & 1; + + if ((show_warning) || (t->state == TRANS_STARTING)) { + const char printable[] = "Auto Keying On"; + int xco, yco; + + xco = ar->winx - BLF_width_default(printable) - 10; + yco = ar->winy - BLF_height_default(printable) - 10; + + /* red warning text */ + UI_ThemeColor(TH_REDALERT); + BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); + + /* autokey recording icon... */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + xco -= (ICON_DEFAULT_WIDTH + 2); + UI_icon_draw(xco, yco, ICON_REC); + + glDisable(GL_BLEND); + } +} + +static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg) +{ + TransInfo *t = arg; + Scene *scene = t->scene; + Object *ob = OBACT; + + /* draw autokeyframing hint in the corner */ + if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { + drawAutoKeyWarning(t, ar); + } } -#endif void saveTransform(bContext *C, TransInfo *t, wmOperator *op) { @@ -1727,7 +1791,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW); t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL); + t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL); t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t); } else if (t->spacetype == SPACE_IMAGE) { @@ -4790,12 +4854,12 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const flo sv->edge_len = len_v3v3(dw_p, up_p); mul_v3_m4v3(v_proj, t->obedit->obmat, sv->v->co); - ED_view3d_project_float_noclip(t->ar, v_proj, v_proj); - - dist = len_squared_v2v2(mval, v_proj); - if (dist < min_dist) { - min_dist = dist; - sld->curr_sv_index = i; + if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + dist = len_squared_v2v2(mval, v_proj); + if (dist < min_dist) { + min_dist = dist; + sld->curr_sv_index = i; + } } } } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 09703a76da3..f304d760da7 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -342,6 +342,8 @@ typedef struct TransInfo { float auto_values[4]; float axis[3]; float axis_orig[3]; /* TransCon can change 'axis', store the original value here */ + + double last_update; /* Time of last update (in seconds) */ void *view; struct bContext *context; /* Only valid (non null) during an operator called function. */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index bd3cd5c53a1..0bc0729accb 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -902,16 +902,20 @@ static void recalcData_view3d(TransInfo *t) /* helper for recalcData() - for sequencer transforms */ static void recalcData_sequencer(TransInfo *t) { - Editing *ed = BKE_sequencer_editing_get(t->scene, FALSE); - Sequence *seq; + TransData *td; + int a; + Sequence *seq_prev = NULL; - SEQ_BEGIN(ed, seq) - { - if (seq->flag & SELECT) { - BKE_sequence_invalidate_deendent(t->scene, seq); + for (a = 0, td = t->data; a < t->total; a++, td++) { + TransDataSeq *tdsq = (TransDataSeq *) td->extra; + Sequence *seq = tdsq->seq; + + if (seq != seq_prev) { + BKE_sequence_invalidate_dependent(t->scene, seq); } + + seq_prev = seq; } - SEQ_END BKE_sequencer_preprocessed_cache_cleanup(); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index a155ff7786a..0e25739c34a 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -402,7 +402,7 @@ EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) const char *BIF_menustringTransformOrientation(const bContext *C, const char *title) { - const char *menu = IFACE_("%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3"); + const char *menu = IFACE_("%t|Global %x0|Local %x1|Gimbal %x4|Normal %x2|View %x3"); ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts; int i = V3D_MANIP_CUSTOM; @@ -411,14 +411,14 @@ const char *BIF_menustringTransformOrientation(const bContext *C, const char *ti title = IFACE_(title); - str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), TIP_("UserTransSpace from matrix")); + str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), "UserTransSpace from matrix"); p = str_menu; p += sprintf(str_menu, "%s", title); p += sprintf(p, "%s", menu); for (ts = transform_spaces->first; ts; ts = ts->next) { - p += sprintf(p, "|%s%%x%d", ts->name, i++); + p += sprintf(p, "|%s %%x%d", ts->name, i++); } return str_menu; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 1d75be05534..2f2b31de89d 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -80,6 +80,8 @@ #define USE_BVH_FACE_SNAP +#define TRANSFORM_DIST_MAX_PX 1000 + /********************* PROTOTYPES ***********************/ static void setSnappingCallback(TransInfo *t); @@ -296,7 +298,7 @@ void applyProject(TransInfo *t) for (i = 0; i < t->total; i++, td++) { float iloc[3], loc[3], no[3]; float mval[2]; - int dist = 1000; + int dist = TRANSFORM_DIST_MAX_PX; if (td->flag & TD_NOACTION) break; @@ -315,18 +317,18 @@ void applyProject(TransInfo *t) copy_v3_v3(iloc, td->ob->obmat[3]); } - ED_view3d_project_float(t->ar, iloc, mval); - - if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { -// if (t->flag & (T_EDIT|T_POSE)) { -// mul_m4_v3(imat, loc); -// } -// - sub_v3_v3v3(tvec, loc, iloc); - - mul_m3_v3(td->smtx, tvec); - - add_v3_v3(td->loc, tvec); + if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { +// if (t->flag & (T_EDIT|T_POSE)) { +// mul_m4_v3(imat, loc); +// } + + sub_v3_v3v3(tvec, loc, iloc); + + mul_m3_v3(td->smtx, tvec); + + add_v3_v3(td->loc, tvec); + } } //XXX constraintTransLim(t, td); @@ -601,7 +603,9 @@ int updateSelectedSnapPoint(TransInfo *t) int dx, dy; int dist; - ED_view3d_project_int(t->ar, p->co, screen_loc); + if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + continue; + } dx = t->mval[0] - screen_loc[0]; dy = t->mval[1] - screen_loc[1]; @@ -1232,8 +1236,12 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh new_depth = len_v3v3(location, ray_start); - ED_view3d_project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + } + else { + new_dist = TRANSFORM_DIST_MAX_PX; + } /* 10% threshold if edge is closer but a bit further * this takes care of series of connected edges a bit slanted w.r.t the viewport @@ -1289,8 +1297,13 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], new_depth = len_v3v3(location, ray_start); - ED_view3d_project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); + } + else { + new_dist = TRANSFORM_DIST_MAX_PX; + } + if (new_dist <= *r_dist && new_depth < *r_depth) { *r_depth = new_depth; @@ -1697,7 +1710,7 @@ static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, c if (ob->transflag & OB_DUPLI) { DupliObject *dupli_ob; - ListBase *lb = object_duplilist(scene, ob); + ListBase *lb = object_duplilist(scene, ob, FALSE); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { Object *dob = dupli_ob->ob; @@ -1903,7 +1916,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L if (ob->transflag & OB_DUPLI) { DupliObject *dupli_ob; - ListBase *lb = object_duplilist(scene, ob); + ListBase *lb = object_duplilist(scene, ob, FALSE); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { Object *dob = dupli_ob->ob; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 06da1c8bfea..9f5b108b29f 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2745,7 +2745,7 @@ static void UV_OT_circle_select(wmOperatorType *ot) /* ******************** lasso select operator **************** */ -static int do_lasso_select_mesh_uv(bContext *C, int mcords[][2], short moves, short select) +static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short moves, short select) { Image *ima = CTX_data_edit_image(C); ARegion *ar = CTX_wm_region(C); @@ -2819,7 +2819,7 @@ static int do_lasso_select_mesh_uv(bContext *C, int mcords[][2], short moves, sh static int uv_lasso_select_exec(bContext *C, wmOperator *op) { int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { short select; diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index dd92b561235..87315b3f779 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -843,7 +843,7 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr) if (ob->transflag & OB_DUPLI) { DupliObject *dob; - ListBase *lb = object_duplilist(shi->gpumat->scene, ob); + ListBase *lb = object_duplilist(shi->gpumat->scene, ob, FALSE); for (dob=lb->first; dob; dob=dob->next) { Object *ob_iter = dob->ob; diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index d88f954345f..c929c97a040 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -1172,10 +1172,8 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) switch (ikchan->jointType & ~IK_TRANSY) { case 0: // fixed bone - if (!(ikchan->jointType & IK_TRANSY)) { - joint += ":F"; - ret = arm->addSegment(joint, parent, KDL::Joint::None, 0.0, tip); - } + joint += ":F"; + ret = arm->addSegment(joint, parent, KDL::Joint::None, 0.0, tip); break; case IK_XDOF: // RX only, get the X rotation diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h index 35a6ea9b207..ba9e20ac411 100644 --- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h +++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h @@ -35,7 +35,7 @@ #define BCM_CONFIG_FILE "config.ocio" -struct ConstProcessorRcPtr; +struct OCIO_ConstProcessorRcPtr; struct ImBuf; typedef struct ColorSpace { @@ -44,8 +44,8 @@ typedef struct ColorSpace { char name[64]; char description[64]; - struct ConstProcessorRcPtr *to_scene_linear; - struct ConstProcessorRcPtr *from_scene_linear; + struct OCIO_ConstProcessorRcPtr *to_scene_linear; + struct OCIO_ConstProcessorRcPtr *from_scene_linear; int is_invertible; int is_data; @@ -57,8 +57,8 @@ typedef struct ColorManagedDisplay { char name[64]; ListBase views; - struct ConstProcessorRcPtr *to_scene_linear; - struct ConstProcessorRcPtr *from_scene_linear; + struct OCIO_ConstProcessorRcPtr *to_scene_linear; + struct OCIO_ConstProcessorRcPtr *from_scene_linear; } ColorManagedDisplay; typedef struct ColorManagedView { diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 02d84819924..c7bdd532bb9 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -88,8 +88,15 @@ static int global_tot_colorspace = 0; static int global_tot_display = 0; static int global_tot_view = 0; +/* lock used by pre-cached processors getters, so processor wouldn't + * be created several times + * LOCK_COLORMANAGE can not be used since this mutex could be needed to + * be locked before pre-cached processor are creating + */ +static pthread_mutex_t processor_lock = BLI_MUTEX_INITIALIZER; + typedef struct ColormanageProcessor { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; CurveMapping *curve_mapping; } ColormanageProcessor; @@ -412,9 +419,9 @@ static void colormanage_cache_handle_release(void *cache_handle) /*********************** Initialization / De-initialization *************************/ -static void colormanage_role_color_space_name_get(ConstConfigRcPtr *config, char *colorspace_name, const char *role, const char *backup_role) +static void colormanage_role_color_space_name_get(OCIO_ConstConfigRcPtr *config, char *colorspace_name, const char *role, const char *backup_role) { - ConstColorSpaceRcPtr *ociocs; + OCIO_ConstColorSpaceRcPtr *ociocs; ociocs = OCIO_configGetColorSpace(config, role); @@ -433,7 +440,7 @@ static void colormanage_role_color_space_name_get(ConstConfigRcPtr *config, char } } -static void colormanage_load_config(ConstConfigRcPtr *config) +static void colormanage_load_config(OCIO_ConstConfigRcPtr *config) { int tot_colorspace, tot_display, tot_display_view, index, viewindex, viewindex2; const char *name; @@ -449,7 +456,7 @@ static void colormanage_load_config(ConstConfigRcPtr *config) /* load colorspaces */ tot_colorspace = OCIO_configGetNumColorSpaces(config); for (index = 0 ; index < tot_colorspace; index++) { - ConstColorSpaceRcPtr *ocio_colorspace; + OCIO_ConstColorSpaceRcPtr *ocio_colorspace; const char *description; int is_invertible, is_data; @@ -514,10 +521,10 @@ static void colormanage_free_config(void) /* free precomputer processors */ if (colorspace->to_scene_linear) - OCIO_processorRelease((ConstProcessorRcPtr *) colorspace->to_scene_linear); + OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) colorspace->to_scene_linear); if (colorspace->from_scene_linear) - OCIO_processorRelease((ConstProcessorRcPtr *) colorspace->from_scene_linear); + OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) colorspace->from_scene_linear); /* free color space itself */ MEM_freeN(colorspace); @@ -532,10 +539,10 @@ static void colormanage_free_config(void) /* free precomputer processors */ if (display->to_scene_linear) - OCIO_processorRelease((ConstProcessorRcPtr *) display->to_scene_linear); + OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) display->to_scene_linear); if (display->from_scene_linear) - OCIO_processorRelease((ConstProcessorRcPtr *) display->from_scene_linear); + OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) display->from_scene_linear); /* free list of views */ BLI_freelistN(&display->views); @@ -546,6 +553,8 @@ static void colormanage_free_config(void) /* free views */ BLI_freelistN(&global_views); + + OCIO_exit(); } void colormanagement_init(void) @@ -553,7 +562,9 @@ void colormanagement_init(void) const char *ocio_env; const char *configdir; char configfile[FILE_MAX]; - ConstConfigRcPtr *config = NULL; + OCIO_ConstConfigRcPtr *config = NULL; + + OCIO_init(); ocio_env = getenv("OCIO"); @@ -571,7 +582,9 @@ void colormanagement_init(void) } if (config == NULL) { - config = OCIO_getDefaultConfig(); + printf("Color management: using fallback mode for management\n"); + + config = OCIO_configCreateFallback(); } if (config) { @@ -636,21 +649,17 @@ static void display_transform_get_from_ctx(const bContext *C, ColorManagedViewSe static const char *display_transform_get_colorspace_name(const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - if (config) { - const char *display = display_settings->display_device; - const char *view = view_settings->view_transform; - const char *colorspace_name; - - colorspace_name = OCIO_configGetDisplayColorSpaceName(config, display, view); + const char *display = display_settings->display_device; + const char *view = view_settings->view_transform; + const char *colorspace_name; - OCIO_configRelease(config); + colorspace_name = OCIO_configGetDisplayColorSpaceName(config, display, view); - return colorspace_name; - } + OCIO_configRelease(config); - return NULL; + return colorspace_name; } static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettings *view_settings, @@ -664,18 +673,12 @@ static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettin return NULL; } -static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display, +static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display, float exposure, float gamma) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - DisplayTransformRcPtr *dt; - ConstProcessorRcPtr *processor; - - if (!config) { - /* there's no valid OCIO configuration, can't create processor */ - - return NULL; - } + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_DisplayTransformRcPtr *dt; + OCIO_ConstProcessorRcPtr *processor; dt = OCIO_createDisplayTransform(); @@ -686,7 +689,7 @@ static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_tra /* fstop exposure control */ if (exposure != 0.0f) { - MatrixTransformRcPtr *mt; + OCIO_MatrixTransformRcPtr *mt; float gain = powf(2.0f, exposure); const float scale4f[] = {gain, gain, gain, gain}; float m44[16], offset4[4]; @@ -694,25 +697,25 @@ static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_tra OCIO_matrixTransformScale(m44, offset4, scale4f); mt = OCIO_createMatrixTransform(); OCIO_matrixTransformSetValue(mt, m44, offset4); - OCIO_displayTransformSetLinearCC(dt, (ConstTransformRcPtr *) mt); + OCIO_displayTransformSetLinearCC(dt, (OCIO_ConstTransformRcPtr *) mt); OCIO_matrixTransformRelease(mt); } /* post-display gamma transform */ if (gamma != 1.0f) { - ExponentTransformRcPtr *et; + OCIO_ExponentTransformRcPtr *et; float exponent = 1.0f / MAX2(FLT_EPSILON, gamma); const float exponent4f[] = {exponent, exponent, exponent, exponent}; et = OCIO_createExponentTransform(); OCIO_exponentTransformSetValue(et, exponent4f); - OCIO_displayTransformSetDisplayCC(dt, (ConstTransformRcPtr *) et); + OCIO_displayTransformSetDisplayCC(dt, (OCIO_ConstTransformRcPtr *) et); OCIO_exponentTransformRelease(et); } - processor = OCIO_configGetProcessor(config, (ConstTransformRcPtr *) dt); + processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *) dt); OCIO_displayTransformRelease(dt); OCIO_configRelease(config); @@ -720,17 +723,11 @@ static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_tra return processor; } -static ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, +static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, const char *to_colorspace) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - ConstProcessorRcPtr *processor; - - if (!config) { - /* there's no valid OCIO configuration, can't create processor */ - - return NULL; - } + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstProcessorRcPtr *processor; processor = OCIO_configGetProcessorWithNames(config, from_colorspace, to_colorspace); @@ -739,49 +736,49 @@ static ConstProcessorRcPtr *create_colorspace_transform_processor(const char *fr return processor; } -static ConstProcessorRcPtr *colorspace_to_scene_linear_processor(ColorSpace *colorspace) +static OCIO_ConstProcessorRcPtr *colorspace_to_scene_linear_processor(ColorSpace *colorspace) { if (colorspace->to_scene_linear == NULL) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_mutex_lock(&processor_lock); if (colorspace->to_scene_linear == NULL) { - ConstProcessorRcPtr *to_scene_linear; + OCIO_ConstProcessorRcPtr *to_scene_linear; to_scene_linear = create_colorspace_transform_processor(colorspace->name, global_role_scene_linear); - colorspace->to_scene_linear = (struct ConstProcessorRcPtr *) to_scene_linear; + colorspace->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *) to_scene_linear; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_mutex_unlock(&processor_lock); } - return (ConstProcessorRcPtr *) colorspace->to_scene_linear; + return (OCIO_ConstProcessorRcPtr *) colorspace->to_scene_linear; } -static ConstProcessorRcPtr *colorspace_from_scene_linear_processor(ColorSpace *colorspace) +static OCIO_ConstProcessorRcPtr *colorspace_from_scene_linear_processor(ColorSpace *colorspace) { if (colorspace->from_scene_linear == NULL) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_mutex_lock(&processor_lock); if (colorspace->from_scene_linear == NULL) { - ConstProcessorRcPtr *from_scene_linear; + OCIO_ConstProcessorRcPtr *from_scene_linear; from_scene_linear = create_colorspace_transform_processor(global_role_scene_linear, colorspace->name); - colorspace->from_scene_linear = (struct ConstProcessorRcPtr *) from_scene_linear; + colorspace->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *) from_scene_linear; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_mutex_unlock(&processor_lock); } - return (ConstProcessorRcPtr *) colorspace->from_scene_linear; + return (OCIO_ConstProcessorRcPtr *) colorspace->from_scene_linear; } -static ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisplay *display) +static OCIO_ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisplay *display) { if (display->from_scene_linear == NULL) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_mutex_lock(&processor_lock); if (display->from_scene_linear == NULL) { const char *view_name = colormanage_view_get_default_name(display); - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - ConstProcessorRcPtr *processor = NULL; + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstProcessorRcPtr *processor = NULL; if (view_name && config) { const char *view_colorspace = OCIO_configGetDisplayColorSpaceName(config, display->name, view_name); @@ -790,24 +787,24 @@ static ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisp OCIO_configRelease(config); } - display->from_scene_linear = (struct ConstProcessorRcPtr *) processor; + display->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *) processor; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_mutex_unlock(&processor_lock); } - return (ConstProcessorRcPtr *) display->from_scene_linear; + return (OCIO_ConstProcessorRcPtr *) display->from_scene_linear; } -static ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display) +static OCIO_ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display) { if (display->to_scene_linear == NULL) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_mutex_lock(&processor_lock); if (display->to_scene_linear == NULL) { const char *view_name = colormanage_view_get_default_name(display); - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - ConstProcessorRcPtr *processor = NULL; + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstProcessorRcPtr *processor = NULL; if (view_name && config) { const char *view_colorspace = OCIO_configGetDisplayColorSpaceName(config, display->name, view_name); @@ -816,13 +813,13 @@ static ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDispla OCIO_configRelease(config); } - display->to_scene_linear = (struct ConstProcessorRcPtr *) processor; + display->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *) processor; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_mutex_unlock(&processor_lock); } - return (ConstProcessorRcPtr *) display->to_scene_linear; + return (OCIO_ConstProcessorRcPtr *) display->to_scene_linear; } static void init_default_view_settings(const ColorManagedDisplaySettings *display_settings, @@ -1273,7 +1270,7 @@ static void *do_display_buffer_apply_thread(void *handle_v) if (cm_processor == NULL) { if (display_buffer_byte) { IMB_buffer_byte_from_byte(display_buffer_byte, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB, - FALSE, width, height, width, width); + FALSE, width, height, width, width); } if (display_buffer) { @@ -1536,7 +1533,7 @@ void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspac */ void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpace *colorspace) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -1553,7 +1550,7 @@ void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpac /* same as above, but converts colors in opposite direction */ void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpace *colorspace) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -1569,7 +1566,7 @@ void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpac void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, int height, int channels, struct ColorSpace *colorspace, int predivide) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -1580,9 +1577,9 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in processor = colorspace_to_scene_linear_processor(colorspace); if (processor) { - PackedImageDesc *img; + OCIO_PackedImageDesc *img; - img = OCIO_createPackedImageDesc(buffer, width, height, channels, sizeof(float), + img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float), channels * sizeof(float), channels * sizeof(float) * width); if (predivide) @@ -1590,7 +1587,7 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in else OCIO_processorApply(processor, img); - OCIO_packedImageDescRelease(img); + OCIO_OCIO_PackedImageDescRelease(img); } } @@ -1600,7 +1597,7 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in */ void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], ColorManagedDisplay *display) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; processor = display_from_scene_linear_processor(display); @@ -1611,7 +1608,7 @@ void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], ColorManaged /* same as above, but converts color in opposite direction */ void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], ColorManagedDisplay *display) { - ConstProcessorRcPtr *processor; + OCIO_ConstProcessorRcPtr *processor; processor = display_to_scene_linear_processor(display); @@ -1895,15 +1892,9 @@ void IMB_display_buffer_release(void *cache_handle) const char *colormanage_display_get_default_name(void) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); const char *display_name; - if (!config) { - /* no valid OCIO configuration, can't get default display */ - - return NULL; - } - display_name = OCIO_configGetDefaultDisplay(config); OCIO_configRelease(config); @@ -2012,15 +2003,9 @@ const char *IMB_colormanagement_display_get_none_name(void) const char *colormanage_view_get_default_name(const ColorManagedDisplay *display) { - ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); const char *name; - if (!config) { - /* no valid OCIO configuration, can't get default view */ - - return NULL; - } - name = OCIO_configGetDefaultView(config, display->name); OCIO_configRelease(config); @@ -2526,10 +2511,10 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo } if (cm_processor->processor && channels >= 3) { - PackedImageDesc *img; + OCIO_PackedImageDesc *img; /* apply OCIO processor */ - img = OCIO_createPackedImageDesc(buffer, width, height, channels, sizeof(float), + img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float), channels * sizeof(float), channels * sizeof(float) * width); if (predivide) @@ -2537,7 +2522,7 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo else OCIO_processorApply(cm_processor->processor, img); - OCIO_packedImageDescRelease(img); + OCIO_OCIO_PackedImageDescRelease(img); } } diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 9ce5d0e30da..aa236af3507 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -43,6 +43,8 @@ #include "IMB_colormanagement.h" #include "IMB_colormanagement_intern.h" +#include "BLI_threads.h" + #include "MEM_guardedalloc.h" /**************************** Interlace/Deinterlace **************************/ @@ -599,9 +601,18 @@ void IMB_float_from_rect(ImBuf *ibuf) if (ibuf->rect == NULL) return; + /* lock the color management thread + * need this because allocated but not filled float buffer will confuse + * display transform which lead to black areas across the frame + */ + BLI_lock_thread(LOCK_COLORMANAGE); + if (ibuf->rect_float == NULL) { - if (imb_addrectfloatImBuf(ibuf) == 0) + if (imb_addrectfloatImBuf(ibuf) == 0) { + BLI_unlock_thread(LOCK_COLORMANAGE); + return; + } } /* first, create float buffer in non-linear space */ @@ -611,6 +622,8 @@ void IMB_float_from_rect(ImBuf *ibuf) /* then make float be in linear space */ IMB_colormanagement_colorspace_to_scene_linear(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, ibuf->rect_colorspace, predivide); + + BLI_unlock_thread(LOCK_COLORMANAGE); } /* no profile conversion */ diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 97316c48621..f35a4345366 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -955,9 +955,9 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, } /* process pictures still stuck in decoder engine after EOF - according to ffmpeg docs using 0-size packets. - - At least, if we haven't already stopped... */ + * according to ffmpeg docs using 0-size packets. + * + * At least, if we haven't already stopped... */ if (!*stop) { int frame_finished; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 284694f2b48..9fbe045226e 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -74,7 +74,7 @@ typedef struct Path { typedef struct BevList { struct BevList *next, *prev; int nr, dupe_nr; - short poly, hole; + int poly, hole; } BevList; /* These two Lines with # tell makesdna this struct can be excluded. */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index c22de3cb7eb..9d40af92638 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -36,8 +36,6 @@ extern "C" { #endif -#include "DNA_defs.h" /* USE_BMESH_FORWARD_COMPAT */ - /** descriptor and storage for a custom data layer */ typedef struct CustomDataLayer { int type; /* type of data in layer */ diff --git a/source/blender/makesdna/DNA_defs.h b/source/blender/makesdna/DNA_defs.h index 762e027f934..774fbcf081a 100644 --- a/source/blender/makesdna/DNA_defs.h +++ b/source/blender/makesdna/DNA_defs.h @@ -45,9 +45,6 @@ /* hrmf, we need a better include then this */ #include "../blenloader/BLO_sys_types.h" /* needed for int64_t only! */ -/* Must not be defined for BMesh, as this guards code for pre-BMesh code to load BMesh .blend files */ -/* #define USE_BMESH_FORWARD_COMPAT */ - /* non-id name variables should use this length */ #define MAX_NAME 64 diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index c7f90eea176..dd0845dbf1e 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -37,8 +37,6 @@ #include "DNA_ID.h" #include "DNA_customdata_types.h" -#include "DNA_defs.h" /* USE_BMESH_FORWARD_COMPAT */ - struct AnimData; struct DerivedMesh; struct Ipo; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index b40af805f77..99df51e9ec4 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -28,9 +28,6 @@ #include "DNA_defs.h" #include "DNA_listBase.h" - -#define MODSTACK_DEBUG 1 - /* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! * (ONLY ADD NEW ITEMS AT THE END) */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 3e5b01df864..af0c967f96b 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -264,8 +264,8 @@ typedef enum eSpaceOutliner_Mode { SO_SAME_TYPE = 5, SO_GROUPS = 6, SO_LIBRARIES = 7, - SO_VERSE_SESSION = 8, - SO_VERSE_MS = 9, + /* SO_VERSE_SESSION = 8, */ /* deprecated! */ + /* SO_VERSE_MS = 9, */ /* deprecated!*/ SO_SEQUENCE = 10, SO_DATABLOCKS = 11, SO_USERDEF = 12, diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index fec3aa22e92..88c5ea3e910 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -1187,6 +1187,13 @@ int main(int argc, char **argv) } /* include files for automatic dependencies */ + +/* extra safety check that we are aligned, + * warnings here are easier to fix the makesdna's */ +#ifdef __GNUC__ +# pragma GCC diagnostic error "-Wpadded" +#endif + #include "DNA_listBase.h" #include "DNA_vec_types.h" #include "DNA_ID.h" diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index b651d4d5e5c..0f9a00de7b6 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -38,6 +38,7 @@ extern EnumPropertyItem DummyRNA_NULL_items[]; extern EnumPropertyItem DummyRNA_DEFAULT_items[]; extern EnumPropertyItem object_mode_items[]; +extern EnumPropertyItem object_empty_drawtype_items[]; extern EnumPropertyItem metaelem_type_items[]; extern EnumPropertyItem proportional_falloff_items[]; diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c index 10e4bca67db..cff80259401 100644 --- a/source/blender/makesrna/intern/rna_actuator.c +++ b/source/blender/makesrna/intern/rna_actuator.c @@ -41,6 +41,8 @@ #include "BLI_utildefines.h" +#include "BLF_translation.h" + /* Always keep in alphabetical order */ EnumPropertyItem actuator_type_items[] = { {ACT_ACTION, "ACTION", 0, "Action", ""}, @@ -971,11 +973,13 @@ static void rna_def_sound_actuator(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 2); RNA_def_property_range(prop, 0.0, 2.0); RNA_def_property_ui_text(prop, "Volume", "Initial volume of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_update(prop, NC_LOGIC, NULL); prop = RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_range(prop, -12.0, 12.0, 1, 2); RNA_def_property_ui_text(prop, "Pitch", "Pitch of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_update(prop, NC_LOGIC, NULL); /* floats - 3D Parameters */ diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 770bdb68e38..f2454a2dcfb 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -1243,7 +1243,7 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna) prop = RNA_def_property(srna, "offset_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "offset_fac"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Offset Factor", "Percentage value defining target position along length of bone"); + RNA_def_property_ui_text(prop, "Offset Factor", "Percentage value defining target position along length of curve"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "forward_axis", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index d1bc72bb6b4..1e9fc420ed7 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -409,7 +409,7 @@ int rna_IDMaterials_assign_int(struct PointerRNA *ptr, int key, const struct Poi /* Internal functions that cycles uses so we need to declare (tsk tsk) */ struct Mesh *rna_Object_to_mesh(struct Object *ob, struct ReportList *reports, struct Scene *sce, int apply_modifiers, int settings); void rna_Main_meshes_remove(struct Main *bmain, struct ReportList *reports, struct Mesh *mesh); -void rna_Object_create_duplilist(struct Object *ob, struct ReportList *reports, struct Scene *sce); +void rna_Object_create_duplilist(struct Object *ob, struct ReportList *reports, struct Scene *sce, int settings); void rna_Object_free_duplilist(struct Object *ob); void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values); void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 679858dab34..fdc309e747a 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1720,6 +1720,16 @@ static void def_sh_tex_wave(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Node_update"); } +static void def_sh_tex_coord(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "from_dupli", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1); + RNA_def_property_ui_text(prop, "From Dupli", "Use the parent of the dupli object if possible"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + static void def_glossy(StructRNA *srna) { PropertyRNA *prop; @@ -2195,14 +2205,14 @@ static void def_cmp_inpaint(StructRNA *srna) { PropertyRNA *prop; -/* +#if 0 prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, type_items); RNA_def_property_ui_text(prop, "Type", "Type of inpaint algorithm"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); -*/ +#endif prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 0baa4cc0838..db1e1e16adf 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -92,7 +92,7 @@ DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TE DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TEX_VORONOI", TexVoronoi, "Voronoi Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) -DefNode( ShaderNode, SH_NODE_TEX_COORD, 0, "TEX_COORD", TexCoord, "Texture Coordinate","" ) +DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" ) DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" ) DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" ) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index bbd21fe4968..d6829f6f2d9 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -69,6 +69,19 @@ EnumPropertyItem object_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem object_empty_drawtype_items[] = { + {OB_PLAINAXES, "PLAIN_AXES", 0, "Plain Axes", ""}, + {OB_ARROWS, "ARROWS", 0, "Arrows", ""}, + {OB_SINGLE_ARROW, "SINGLE_ARROW", 0, "Single Arrow", ""}, + {OB_CIRCLE, "CIRCLE", 0, "Circle", ""}, + {OB_CUBE, "CUBE", 0, "Cube", ""}, + {OB_EMPTY_SPHERE, "SPHERE", 0, "Sphere", ""}, + {OB_EMPTY_CONE, "CONE", 0, "Cone", ""}, + {OB_EMPTY_IMAGE, "IMAGE", 0, "Image", ""}, + {0, NULL, 0, NULL, NULL} +}; + + static EnumPropertyItem parent_type_items[] = { {PAROBJECT, "OBJECT", 0, "Object", "The object is parented to an object"}, {PARCURVE, "CURVE", 0, "Curve", "The object is parented to a curve"}, @@ -80,7 +93,7 @@ static EnumPropertyItem parent_type_items[] = { {PARBONE, "BONE", 0, "Bone", "The object is parented to a bone"}, {0, NULL, 0, NULL, NULL} }; - + static EnumPropertyItem collision_bounds_items[] = { {OB_BOUND_BOX, "BOX", 0, "Box", ""}, {OB_BOUND_SPHERE, "SPHERE", 0, "Sphere", ""}, @@ -1874,18 +1887,6 @@ static void rna_def_object(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - - static EnumPropertyItem empty_drawtype_items[] = { - {OB_PLAINAXES, "PLAIN_AXES", 0, "Plain Axes", ""}, - {OB_ARROWS, "ARROWS", 0, "Arrows", ""}, - {OB_SINGLE_ARROW, "SINGLE_ARROW", 0, "Single Arrow", ""}, - {OB_CIRCLE, "CIRCLE", 0, "Circle", ""}, - {OB_CUBE, "CUBE", 0, "Cube", ""}, - {OB_EMPTY_SPHERE, "SPHERE", 0, "Sphere", ""}, - {OB_EMPTY_CONE, "CONE", 0, "Cone", ""}, - {OB_EMPTY_IMAGE, "IMAGE", 0, "Image", ""}, - {0, NULL, 0, NULL, NULL} - }; static EnumPropertyItem track_items[] = { {OB_POSX, "POS_X", 0, "+X", ""}, @@ -2267,7 +2268,7 @@ static void rna_def_object(BlenderRNA *brna) /* empty */ prop = RNA_def_property(srna, "empty_draw_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype"); - RNA_def_property_enum_items(prop, empty_drawtype_items); + RNA_def_property_enum_items(prop, object_empty_drawtype_items); RNA_def_property_ui_text(prop, "Empty Display Type", "Viewport display style for empties"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); @@ -2572,7 +2573,16 @@ static void rna_def_dupli_object(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text(prop, "Particle Index", "Index in the lowest-level particle dupli list"); - /* TODO: DupliObject has more properties that can be wrapped */ + prop = RNA_def_property(srna, "orco", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_float_sdna(prop, NULL, "orco"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Generated Coordinates", "Generated coordinates in parent object space"); + + prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "uv"); + RNA_def_property_array(prop, 2); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); + RNA_def_property_ui_text(prop, "UV Coordinates", "UV coordinates in parent object space"); } static void rna_def_object_base(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 1263e7716dd..da433f6c1e5 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -177,6 +177,8 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ return NULL; /* only do basis metaball */ tmpmesh = BKE_mesh_add("Mesh"); + /* BKE_mesh_add gives us a user count we don't need */ + tmpmesh->id.us--; if (render) { ListBase disp = {NULL, NULL}; @@ -186,6 +188,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ } else BKE_mesh_from_metaball(&ob->disp, tmpmesh); + break; } @@ -214,6 +217,9 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ dm->release(dm); } + /* BKE_mesh_add/copy gives us a user count we don't need */ + tmpmesh->id.us--; + break; default: BKE_report(reports, RPT_ERROR, "Object does not have geometry data"); @@ -283,9 +289,6 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ /* cycles and exporters rely on this still */ BKE_mesh_tessface_ensure(tmpmesh); - /* we don't assign it to anything */ - tmpmesh->id.us--; - /* make sure materials get updated in objects */ test_object_materials(&tmpmesh->id); @@ -337,8 +340,10 @@ static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int e dupli_render_particle_set(scene, go->ob, level + 1, enable); } /* When no longer needed, duplilist should be freed with Object.free_duplilist */ -void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce) +void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, int settings) { + int for_render = settings == eModifierMode_Render; + if (!(ob->transflag & OB_DUPLI)) { BKE_report(reports, RPT_ERROR, "Object does not have duplis"); return; @@ -353,7 +358,7 @@ void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce) } if (G.is_rendering) dupli_render_particle_set(sce, ob, 0, 1); - ob->duplilist = object_duplilist(sce, ob); + ob->duplilist = object_duplilist(sce, ob, for_render); if (G.is_rendering) dupli_render_particle_set(sce, ob, 0, 0); /* ob->duplilist should now be freed with Object.free_duplilist */ @@ -608,6 +613,7 @@ void RNA_api_object(StructRNA *srna) "objects real matrix and layers"); parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate duplis"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Generate texture coordinates for rendering"); RNA_def_function_flag(func, FUNC_USE_REPORTS); func = RNA_def_function(srna, "dupli_list_clear", "rna_Object_free_duplilist"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 899bf6a7b7c..53f6c79be7b 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3219,6 +3219,7 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Volume", "Audio volume"); + RNA_def_property_translation_context(prop, "Audio"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); #endif @@ -4630,6 +4631,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "audio.volume"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Volume", "Audio volume"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_update(prop, NC_SCENE, NULL); RNA_def_property_float_funcs(prop, NULL, "rna_Scene_volume_set", NULL); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index b11a98771ab..a589695768e 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -50,6 +50,8 @@ #include "WM_types.h" #include "BLI_math.h" +#include "BLF_translation.h" + typedef struct EffectInfo { const char *struct_name; const char *ui_name; @@ -405,7 +407,7 @@ static void rna_Sequence_name_set(PointerRNA *ptr, const char *value) BLI_strncpy_utf8(seq->name + 2, value, sizeof(seq->name) - 2); /* make sure the name is unique */ - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); /* fix all the animation data which may link to this */ @@ -1673,14 +1675,14 @@ static void rna_def_effect_inputs(StructRNA *srna, int count) RNA_def_property_ui_text(prop, "Input 2", "Second input for the effect strip"); } - /* +#if 0 if (count == 3) { // not used by any effects (perhaps one day plugins?) prop = RNA_def_property(srna, "input_3", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "seq3"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL); RNA_def_property_ui_text(prop, "Input 3", "Third input for the effect strip"); } - */ +#endif } static void rna_def_image(BlenderRNA *brna) @@ -1858,6 +1860,7 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "volume"); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Volume", "Playback volume of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_volume_set", NULL); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); @@ -1865,6 +1868,7 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "pitch"); RNA_def_property_range(prop, 0.1f, 10.0f); RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_pitch_set", NULL); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index c7c4b0817f6..f63ef6c8d76 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -81,7 +81,7 @@ static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start seq->type = type; BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); seq->strip->us = 1; diff --git a/source/blender/makesrna/intern/rna_speaker.c b/source/blender/makesrna/intern/rna_speaker.c index 1e3c8df9273..a160aaf94e2 100644 --- a/source/blender/makesrna/intern/rna_speaker.c +++ b/source/blender/makesrna/intern/rna_speaker.c @@ -35,6 +35,8 @@ #include "DNA_speaker_types.h" #include "DNA_sound_types.h" +#include "BLF_translation.h" + #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" @@ -45,7 +47,6 @@ #include "WM_api.h" #include "WM_types.h" - #else static void rna_def_speaker(BlenderRNA *brna) @@ -151,6 +152,7 @@ static void rna_def_speaker(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "volume"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Volume", "How loud the sound is"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); /* RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_set", NULL); */ /* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */ @@ -158,6 +160,7 @@ static void rna_def_speaker(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "pitch"); RNA_def_property_range(prop, 0.1f, 10.0f); RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO); /* RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_pitch_set", NULL); */ /* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */ diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 663b41d3557..a77b3ab75ee 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1733,6 +1733,7 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) prop = RNA_def_property(srna, "turbulence_strength", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "noise_fac"); RNA_def_property_range(prop, 0.01, FLT_MAX); + RNA_def_property_ui_text(prop, "Turbulence Strength", "Strength of the added turbulent noise"); RNA_def_property_update(prop, 0, "rna_Texture_update"); prop = RNA_def_property(srna, "turbulence_depth", PROP_INT, PROP_NONE); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index c9960df1345..92cc555db36 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -515,9 +515,9 @@ static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd) static void freeExecutableNode(bNodeTreeExec *exec) { /* node outputs can be freed when: - - not a render result or image node - - when node outputs go to nodes all being set NODE_FINISHED - */ + * - not a render result or image node + * - when node outputs go to nodes all being set NODE_FINISHED + */ bNodeTree *ntree = exec->nodetree; bNodeExec *nodeexec; bNode *node; diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c index 86f71f6f05b..62b1cabd491 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c @@ -57,7 +57,7 @@ void register_node_type_sh_tex_coord(bNodeTreeType *ttype) { static bNodeType ntype; - node_type_base(ttype, &ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT, 0); + node_type_base(ttype, &ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT, NODE_OPTIONS); node_type_compatibility(&ntype, NODE_NEW_SHADING); node_type_socket_templates(&ntype, NULL, sh_node_tex_coord_out); node_type_size(&ntype, 150, 60, 200); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 85f6163c721..1a481d2687f 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -251,6 +251,10 @@ void BPY_python_start(int argc, const char **argv) * an error, this is highly annoying, another stumbling block for devs, * so use a more relaxed error handler and enforce utf-8 since the rest of * blender is utf-8 too - campbell */ + + /* XXX, update: this is unreliable! 'PYTHONIOENCODING' is ignored in MS-Windows + * when dynamically linked, see: [#31555] for details. + * Python doesn't expose a good way to set this. */ BLI_setenv("PYTHONIOENCODING", "utf-8:surrogateescape"); /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to @@ -264,15 +268,6 @@ void BPY_python_start(int argc, const char **argv) Py_Initialize(); -#ifdef WIN32 - /* this is disappointing, its likely a bug in python? - * for some reason 'PYTHONIOENCODING' is ignored in windows - * see: [#31555] for details. */ - PyRun_SimpleString("import sys, io\n" - "sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='surrogateescape', line_buffering=True)\n" - "sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='surrogateescape', line_buffering=True)\n"); -#endif /* WIN32 */ - // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal /* sigh, why do python guys not have a (char **) version anymore? */ { diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index f344da9725f..114d5ccdc61 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4892,7 +4892,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp /* create list of duplis generated by this object, particle * system need to have render settings set for dupli particles */ dupli_render_particle_set(re, ob, timeoffset, 0, 1); - lb= object_duplilist(re->scene, ob); + lb= object_duplilist(re->scene, ob, TRUE); dupli_render_particle_set(re, ob, timeoffset, 0, 0); for (dob= lb->first; dob; dob= dob->next) { diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index c8aad21b322..af774c5be73 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -232,9 +232,9 @@ static void occ_build_shade(Render *re, OcclusionTree *tree) /* ------------------------- Spherical Harmonics --------------------------- */ /* Use 2nd order SH => 9 coefficients, stored in this order: -* 0 = (0,0), -* 1 = (1,-1), 2 = (1,0), 3 = (1,1), -* 4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */ + * 0 = (0,0), + * 1 = (1,-1), 2 = (1,0), 3 = (1,1), + * 4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */ static void sh_copy(float *shresult, float *sh) { @@ -1056,8 +1056,8 @@ static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, floa static __m128 sse_approx_acos(__m128 x) { /* needs a better approximation than taylor expansion of acos, since that - * gives big erros for near 1.0 values, sqrt(2*x)*acos(1-x) should work - * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */ + * gives big erros for near 1.0 values, sqrt(2*x)*acos(1-x) should work + * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */ return _mm_set_ps1(1.0f); } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 53b0c896b41..7d1a7c3fdff 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -274,7 +274,7 @@ int WM_gesture_lines_cancel(struct bContext *C, struct wmOperator *op); int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_lasso_cancel(struct bContext *C, struct wmOperator *op); -int (*WM_gesture_lasso_path_to_array(struct bContext *C, struct wmOperator *op, int *mcords_tot))[2]; +const int (*WM_gesture_lasso_path_to_array(struct bContext *C, struct wmOperator *op, int *mcords_tot))[2]; int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_straightline_cancel(struct bContext *C, struct wmOperator *op); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 6766b557324..84ceb89d8ec 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -56,6 +56,7 @@ #include "BLI_blenlib.h" #include "BLI_linklist.h" #include "BLI_utildefines.h" +#include "BLI_threads.h" #include "BLI_callbacks.h" #include "BLF_translation.h" @@ -840,7 +841,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ - if (U.flag & USER_SAVE_PREVIEWS) { + if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b199d3dfd7c..14c4f271134 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2925,7 +2925,7 @@ int WM_gesture_lines_cancel(bContext *C, wmOperator *op) * * caller must free. */ -int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *mcords_tot))[2] +const int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *mcords_tot))[2] { PropertyRNA *prop = RNA_struct_find_property(op->ptr, "path"); int (*mcords)[2] = NULL; @@ -2955,7 +2955,8 @@ int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *m *mcords_tot = 0; } - return mcords; + /* cast for 'const' */ + return (const int (*)[2])mcords; } #if 0 diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 96b56768b8f..fa0994d788a 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -28,11 +28,11 @@ set(INC ../../../intern/guardedalloc ../../../intern/moto/include ../../../intern/string - ${GLEW_INCLUDE_PATH} ) set(INC_SYS ${PTHREADS_INCLUDE_DIRS} + ${GLEW_INCLUDE_PATH} ) set(SRC |