diff options
Diffstat (limited to 'intern')
28 files changed, 358 insertions, 229 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 938794f09ec..0c1784f8a3c 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -367,14 +367,14 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.dicing_rate = FloatProperty( name="Dicing Rate", description="Size of a micropolygon in pixels", - min=0.1, max=1000.0, + min=0.1, max=1000.0, soft_min=0.5, default=1.0, subtype="PIXEL" ) cls.preview_dicing_rate = FloatProperty( name="Preview Dicing Rate", description="Size of a micropolygon in pixels during preview render", - min=0.1, max=1000.0, + min=0.1, max=1000.0, soft_min=0.5, default=8.0, subtype="PIXEL" ) @@ -1011,7 +1011,7 @@ class CyclesObjectSettings(bpy.types.PropertyGroup): cls.dicing_rate = FloatProperty( name="Dicing Scale", description="Multiplier for scene dicing rate (located in the Geometry Panel)", - min=0.1, max=1000.0, + min=0.1, max=1000.0, soft_min=0.5, default=1.0, ) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index c33bc4c263f..ff1d49ffd12 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -606,7 +606,7 @@ static void create_mesh(Scene *scene, int numtris = 0; int numcorners = 0; int numngons = 0; - bool use_loop_normals = b_mesh.use_auto_smooth(); + bool use_loop_normals = b_mesh.use_auto_smooth() && (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK); BL::Mesh::vertices_iterator v; BL::Mesh::tessfaces_iterator f; @@ -959,25 +959,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); - mesh->subdivision_type = Mesh::SUBDIVISION_NONE; - - PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles"); - - if(cobj.data && b_ob.modifiers.length() > 0 && experimental) { - BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length()-1]; - bool enabled = preview ? mod.show_viewport() : mod.show_render(); - - if(enabled && mod.type() == BL::Modifier::type_SUBSURF && RNA_boolean_get(&cobj, "use_adaptive_subdivision")) { - BL::SubsurfModifier subsurf(mod); - - if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) { - mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK; - } - else { - mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR; - } - } - } + mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental); BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed, mesh->subdivision_type); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index be395b9f253..e77cc122cc5 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -102,26 +102,6 @@ bool BlenderSync::sync_recalc() if(b_lamp->is_updated() || (b_lamp->node_tree() && b_lamp->node_tree().is_updated())) shader_map.set_recalc(*b_lamp); - BL::BlendData::objects_iterator b_ob; - - for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) { - if(b_ob->is_updated()) { - object_map.set_recalc(*b_ob); - light_map.set_recalc(*b_ob); - } - - if(object_is_mesh(*b_ob)) { - if(b_ob->is_updated_data() || b_ob->data().is_updated()) { - BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data(); - mesh_map.set_recalc(key); - } - } - else if(object_is_light(*b_ob)) { - if(b_ob->is_updated_data() || b_ob->data().is_updated()) - light_map.set_recalc(*b_ob); - } - } - bool dicing_prop_changed = false; if(experimental) { @@ -143,21 +123,36 @@ bool BlenderSync::sync_recalc() } } + BL::BlendData::objects_iterator b_ob; + + for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) { + if(b_ob->is_updated()) { + object_map.set_recalc(*b_ob); + light_map.set_recalc(*b_ob); + } + + if(object_is_mesh(*b_ob)) { + if(b_ob->is_updated_data() || b_ob->data().is_updated() || + (dicing_prop_changed && object_subdivision_type(*b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) + { + BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data(); + mesh_map.set_recalc(key); + } + } + else if(object_is_light(*b_ob)) { + if(b_ob->is_updated_data() || b_ob->data().is_updated()) + light_map.set_recalc(*b_ob); + } + } + BL::BlendData::meshes_iterator b_mesh; for(b_data.meshes.begin(b_mesh); b_mesh != b_data.meshes.end(); ++b_mesh) { if(b_mesh->is_updated()) { mesh_map.set_recalc(*b_mesh); } - else if(dicing_prop_changed) { - PointerRNA cmesh = RNA_pointer_get(&b_mesh->ptr, "cycles"); - - if(RNA_enum_get(&cmesh, "subdivision_type")) - mesh_map.set_recalc(*b_mesh); - } } - BL::BlendData::worlds_iterator b_world; for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) { diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 348cc5edce8..ba696a83867 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -17,6 +17,8 @@ #ifndef __BLENDER_UTIL_H__ #define __BLENDER_UTIL_H__ +#include "mesh.h" + #include "util_map.h" #include "util_path.h" #include "util_set.h" @@ -55,11 +57,10 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data, BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1]; subsurf_mod_show_render = subsurf_mod.show_render(); - subsurf_mod_show_viewport = subsurf_mod.show_render(); + subsurf_mod_show_viewport = subsurf_mod.show_viewport(); subsurf_mod.show_render(false); subsurf_mod.show_viewport(false); - } BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed); @@ -561,6 +562,29 @@ static inline BL::DomainFluidSettings object_fluid_domain_find(BL::Object b_ob) return BL::DomainFluidSettings(PointerRNA_NULL); } +static inline Mesh::SubdivisionType object_subdivision_type(BL::Object& b_ob, bool preview, bool experimental) +{ + PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles"); + + if(cobj.data && b_ob.modifiers.length() > 0 && experimental) { + BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length()-1]; + bool enabled = preview ? mod.show_viewport() : mod.show_render(); + + if(enabled && mod.type() == BL::Modifier::type_SUBSURF && RNA_boolean_get(&cobj, "use_adaptive_subdivision")) { + BL::SubsurfModifier subsurf(mod); + + if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) { + return Mesh::SUBDIVISION_CATMULL_CLARK; + } + else { + return Mesh::SUBDIVISION_LINEAR; + } + } + } + + return Mesh::SUBDIVISION_NONE; +} + /* ID Map * * Utility class to keep in sync with blender data. diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 3c37bc0b045..06089b4014a 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -34,6 +34,7 @@ set(SRC_BVH_HEADERS bvh/bvh_shadow_all.h bvh/bvh_subsurface.h bvh/bvh_traversal.h + bvh/bvh_types.h bvh/bvh_volume.h bvh/bvh_volume_all.h bvh/qbvh_nodes.h diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h index 59881738195..85bfd931e6e 100644 --- a/intern/cycles/kernel/bvh/bvh.h +++ b/intern/cycles/kernel/bvh/bvh.h @@ -28,54 +28,7 @@ CCL_NAMESPACE_BEGIN -/* Don't inline intersect functions on GPU, this is faster */ -#ifdef __KERNEL_GPU__ -# define ccl_device_intersect ccl_device_noinline -#else -# define ccl_device_intersect ccl_device_inline -#endif - -/* bottom-most stack entry, indicating the end of traversal */ -#define ENTRYPOINT_SENTINEL 0x76543210 - -/* 64 object BVH + 64 mesh BVH + 64 object node splitting */ -#define BVH_STACK_SIZE 192 -#define BVH_QSTACK_SIZE 384 - -/* BVH intersection function variations */ - -#define BVH_INSTANCING 1 -#define BVH_MOTION 2 -#define BVH_HAIR 4 -#define BVH_HAIR_MINIMUM_WIDTH 8 - -#define BVH_NAME_JOIN(x,y) x ## _ ## y -#define BVH_NAME_EVAL(x,y) BVH_NAME_JOIN(x,y) -#define BVH_FUNCTION_FULL_NAME(prefix) BVH_NAME_EVAL(prefix, BVH_FUNCTION_NAME) - -#define BVH_FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0) - -/* Debugging heleprs */ -#ifdef __KERNEL_DEBUG__ -# define BVH_DEBUG_INIT() \ - do { \ - isect->num_traversal_steps = 0; \ - isect->num_traversed_instances = 0; \ - } while(0) -# define BVH_DEBUG_NEXT_STEP() \ - do { \ - ++isect->num_traversal_steps; \ - } while(0) -# define BVH_DEBUG_NEXT_INSTANCE() \ - do { \ - ++isect->num_traversed_instances; \ - } while(0) -#else /* __KERNEL_DEBUG__ */ -# define BVH_DEBUG_INIT() -# define BVH_DEBUG_NEXT_STEP() -# define BVH_DEBUG_NEXT_INSTANCE() -#endif /* __KERNEL_DEBUG__ */ - +#include "bvh_types.h" /* Common QBVH functions. */ #ifdef __QBVH__ @@ -120,13 +73,13 @@ CCL_NAMESPACE_BEGIN # define BVH_FUNCTION_NAME bvh_intersect_subsurface # define BVH_FUNCTION_FEATURES BVH_HAIR # include "bvh_subsurface.h" -#endif -#if defined(__SUBSURFACE__) && defined(__OBJECT_MOTION__) -# define BVH_FUNCTION_NAME bvh_intersect_subsurface_motion -# define BVH_FUNCTION_FEATURES BVH_MOTION|BVH_HAIR -# include "bvh_subsurface.h" -#endif +# if defined(__OBJECT_MOTION__) +# define BVH_FUNCTION_NAME bvh_intersect_subsurface_motion +# define BVH_FUNCTION_FEATURES BVH_MOTION|BVH_HAIR +# include "bvh_subsurface.h" +# endif +#endif /* __SUBSURFACE__ */ /* Volume BVH traversal */ @@ -134,19 +87,19 @@ CCL_NAMESPACE_BEGIN # define BVH_FUNCTION_NAME bvh_intersect_volume # define BVH_FUNCTION_FEATURES BVH_HAIR # include "bvh_volume.h" -#endif - -#if defined(__VOLUME__) && defined(__INSTANCING__) -# define BVH_FUNCTION_NAME bvh_intersect_volume_instancing -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR -# include "bvh_volume.h" -#endif -#if defined(__VOLUME__) && defined(__OBJECT_MOTION__) -# define BVH_FUNCTION_NAME bvh_intersect_volume_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION|BVH_HAIR -# include "bvh_volume.h" -#endif +# if defined(__INSTANCING__) +# define BVH_FUNCTION_NAME bvh_intersect_volume_instancing +# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR +# include "bvh_volume.h" +# endif + +# if defined(__OBJECT_MOTION__) +# define BVH_FUNCTION_NAME bvh_intersect_volume_motion +# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION|BVH_HAIR +# include "bvh_volume.h" +# endif +#endif /* __VOLUME__ */ /* Record all intersections - Shadow BVH traversal */ @@ -154,31 +107,31 @@ CCL_NAMESPACE_BEGIN # define BVH_FUNCTION_NAME bvh_intersect_shadow_all # define BVH_FUNCTION_FEATURES 0 # include "bvh_shadow_all.h" -#endif - -#if defined(__SHADOW_RECORD_ALL__) && defined(__INSTANCING__) -# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_instancing -# define BVH_FUNCTION_FEATURES BVH_INSTANCING -# include "bvh_shadow_all.h" -#endif -#if defined(__SHADOW_RECORD_ALL__) && defined(__HAIR__) -# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR -# include "bvh_shadow_all.h" -#endif - -#if defined(__SHADOW_RECORD_ALL__) && defined(__OBJECT_MOTION__) -# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION -# include "bvh_shadow_all.h" -#endif - -#if defined(__SHADOW_RECORD_ALL__) && defined(__HAIR__) && defined(__OBJECT_MOTION__) -# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION -# include "bvh_shadow_all.h" -#endif +# if defined(__INSTANCING__) +# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_instancing +# define BVH_FUNCTION_FEATURES BVH_INSTANCING +# include "bvh_shadow_all.h" +# endif + +# if defined(__HAIR__) +# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair +# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR +# include "bvh_shadow_all.h" +# endif + +# if defined(__OBJECT_MOTION__) +# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_motion +# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION +# include "bvh_shadow_all.h" +# endif + +# if defined(__HAIR__) && defined(__OBJECT_MOTION__) +# define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair_motion +# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION +# include "bvh_shadow_all.h" +# endif +#endif /* __SHADOW_RECORD_ALL__ */ /* Record all intersections - Volume BVH traversal */ @@ -186,19 +139,19 @@ CCL_NAMESPACE_BEGIN # define BVH_FUNCTION_NAME bvh_intersect_volume_all # define BVH_FUNCTION_FEATURES BVH_HAIR # include "bvh_volume_all.h" -#endif -#if defined(__VOLUME_RECORD_ALL__) && defined(__INSTANCING__) -# define BVH_FUNCTION_NAME bvh_intersect_volume_all_instancing -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR -# include "bvh_volume_all.h" -#endif - -#if defined(__VOLUME_RECORD_ALL__) && defined(__OBJECT_MOTION__) -# define BVH_FUNCTION_NAME bvh_intersect_volume_all_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION|BVH_HAIR -# include "bvh_volume_all.h" -#endif +# if defined(__INSTANCING__) +# define BVH_FUNCTION_NAME bvh_intersect_volume_all_instancing +# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR +# include "bvh_volume_all.h" +# endif + +# if defined(__OBJECT_MOTION__) +# define BVH_FUNCTION_NAME bvh_intersect_volume_all_motion +# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION|BVH_HAIR +# include "bvh_volume_all.h" +# endif +#endif /* __VOLUME_RECORD_ALL__ */ #undef BVH_FEATURE #undef BVH_NAME_JOIN diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h index f9da2a3caaa..294362ea995 100644 --- a/intern/cycles/kernel/bvh/bvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h @@ -108,7 +108,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, do { /* traverse internal nodes */ while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) { - int node_addr_ahild1, traverse_mask; + int node_addr_child1, traverse_mask; float dist[2]; float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr+0); @@ -141,25 +141,25 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, #endif // __KERNEL_SSE2__ node_addr = __float_as_int(cnodes.z); - node_addr_ahild1 = __float_as_int(cnodes.w); + node_addr_child1 = __float_as_int(cnodes.w); if(traverse_mask == 3) { /* Both children were intersected, push the farther one. */ bool is_closest_child1 = (dist[1] < dist[0]); if(is_closest_child1) { int tmp = node_addr; - node_addr = node_addr_ahild1; - node_addr_ahild1 = tmp; + node_addr = node_addr_child1; + node_addr_child1 = tmp; } ++stack_ptr; kernel_assert(stack_ptr < BVH_STACK_SIZE); - traversal_stack[stack_ptr] = node_addr_ahild1; + traversal_stack[stack_ptr] = node_addr_child1; } else { /* One child was intersected. */ if(traverse_mask == 2) { - node_addr = node_addr_ahild1; + node_addr = node_addr_child1; } else if(traverse_mask == 0) { /* Neither child was intersected. */ @@ -343,6 +343,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(stack_ptr >= 0) { kernel_assert(object != OBJECT_NONE); + /* Instance pop. */ if(num_hits_in_instance) { float t_fac; @@ -355,8 +356,9 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, triangle_intersect_precalc(dir, &isect_precalc); /* scale isect->t to adjust for instancing */ - for(int i = 0; i < num_hits_in_instance; i++) + for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; + } } else { float ignore_t = FLT_MAX; diff --git a/intern/cycles/kernel/bvh/bvh_types.h b/intern/cycles/kernel/bvh/bvh_types.h new file mode 100644 index 00000000000..bcba6e65fe5 --- /dev/null +++ b/intern/cycles/kernel/bvh/bvh_types.h @@ -0,0 +1,73 @@ +/* + * Adapted from code Copyright 2009-2010 NVIDIA Corporation + * Modifications Copyright 2011, Blender Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BVH_TYPES__ +#define __BVH_TYPES__ + +CCL_NAMESPACE_BEGIN + +/* Don't inline intersect functions on GPU, this is faster */ +#ifdef __KERNEL_GPU__ +# define ccl_device_intersect ccl_device_noinline +#else +# define ccl_device_intersect ccl_device_inline +#endif + +/* bottom-most stack entry, indicating the end of traversal */ +#define ENTRYPOINT_SENTINEL 0x76543210 + +/* 64 object BVH + 64 mesh BVH + 64 object node splitting */ +#define BVH_STACK_SIZE 192 +#define BVH_QSTACK_SIZE 384 + +/* BVH intersection function variations */ + +#define BVH_INSTANCING 1 +#define BVH_MOTION 2 +#define BVH_HAIR 4 +#define BVH_HAIR_MINIMUM_WIDTH 8 + +#define BVH_NAME_JOIN(x,y) x ## _ ## y +#define BVH_NAME_EVAL(x,y) BVH_NAME_JOIN(x,y) +#define BVH_FUNCTION_FULL_NAME(prefix) BVH_NAME_EVAL(prefix, BVH_FUNCTION_NAME) + +#define BVH_FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0) + +/* Debugging heleprs */ +#ifdef __KERNEL_DEBUG__ +# define BVH_DEBUG_INIT() \ + do { \ + isect->num_traversal_steps = 0; \ + isect->num_traversed_instances = 0; \ + } while(0) +# define BVH_DEBUG_NEXT_STEP() \ + do { \ + ++isect->num_traversal_steps; \ + } while(0) +# define BVH_DEBUG_NEXT_INSTANCE() \ + do { \ + ++isect->num_traversed_instances; \ + } while(0) +#else /* __KERNEL_DEBUG__ */ +# define BVH_DEBUG_INIT() +# define BVH_DEBUG_NEXT_STEP() +# define BVH_DEBUG_NEXT_INSTANCE() +#endif /* __KERNEL_DEBUG__ */ + +CCL_NAMESPACE_END + +#endif /* __BVH_TYPES__ */ diff --git a/intern/cycles/kernel/bvh/bvh_volume_all.h b/intern/cycles/kernel/bvh/bvh_volume_all.h index 1f6515c9862..529848ebe7b 100644 --- a/intern/cycles/kernel/bvh/bvh_volume_all.h +++ b/intern/cycles/kernel/bvh/bvh_volume_all.h @@ -99,7 +99,7 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, ssef tsplat(0.0f, 0.0f, -isect_t, -isect_t); gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz); -#endif +#endif /* __KERNEL_SSE2__ */ IsectPrecalc isect_precalc; triangle_intersect_precalc(dir, &isect_precalc); @@ -334,6 +334,7 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(stack_ptr >= 0) { kernel_assert(object != OBJECT_NONE); + /* Instance pop. */ if(num_hits_in_instance) { float t_fac; # if BVH_FEATURE(BVH_MOTION) @@ -377,7 +378,7 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, node_addr = traversal_stack[stack_ptr]; --stack_ptr; } -#endif /* FEATURE(BVH_MOTION) */ +#endif /* FEATURE(BVH_INSTANCING) */ } while(node_addr != ENTRYPOINT_SENTINEL); return num_hits; diff --git a/intern/cycles/kernel/bvh/qbvh_shadow_all.h b/intern/cycles/kernel/bvh/qbvh_shadow_all.h index 5043965c979..3136c495b38 100644 --- a/intern/cycles/kernel/bvh/qbvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/qbvh_shadow_all.h @@ -40,6 +40,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, uint *num_hits) { /* TODO(sergey): + * - Test if pushing distance on the stack helps. * - Likely and unlikely for if() statements. * - Test restrict attribute for pointers. */ @@ -77,7 +78,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, int num_hits_in_instance = 0; #endif - ssef tnear(0.0f), tfar(tmax); + ssef tnear(0.0f), tfar(isect_t); #if BVH_FEATURE(BVH_HAIR) sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z)); #endif @@ -125,12 +126,12 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, #ifdef __KERNEL_AVX2__ P_idir4, #endif -# if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__) +#if BVH_FEATURE(BVH_HAIR) || !defined(__KERNEL_AVX2__) org4, -# endif -# if BVH_FEATURE(BVH_HAIR) +#endif +#if BVH_FEATURE(BVH_HAIR) dir4, -# endif +#endif idir4, near_x, near_y, near_z, far_x, far_y, far_z, @@ -427,22 +428,21 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(stack_ptr >= 0) { kernel_assert(object != OBJECT_NONE); + /* Instance pop. */ if(num_hits_in_instance) { float t_fac; - # if BVH_FEATURE(BVH_MOTION) bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); # else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); # endif - - /* scale isect->t to adjust for instancing */ - for(int i = 0; i < num_hits_in_instance; i++) + /* Scale isect->t to adjust for instancing. */ + for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; + } } else { float ignore_t = FLT_MAX; - # if BVH_FEATURE(BVH_MOTION) bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); # else @@ -456,7 +456,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; } if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; } if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; } - tfar = ssef(tmax); + tfar = ssef(isect_t); # if BVH_FEATURE(BVH_HAIR) dir4 = sse3f(ssef(dir.x), ssef(dir.y), ssef(dir.z)); # endif diff --git a/intern/cycles/kernel/bvh/qbvh_volume.h b/intern/cycles/kernel/bvh/qbvh_volume.h index 847a11d8ad4..aff9f559ab8 100644 --- a/intern/cycles/kernel/bvh/qbvh_volume.h +++ b/intern/cycles/kernel/bvh/qbvh_volume.h @@ -103,8 +103,9 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, do { /* Traverse internal nodes. */ while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) { -#ifdef __VISIBILITY_FLAG__ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0); + +#ifdef __VISIBILITY_FLAG__ if((__float_as_uint(inodes.x) & visibility) == 0) { /* Pop. */ node_addr = traversal_stack[stack_ptr].addr; diff --git a/intern/cycles/kernel/bvh/qbvh_volume_all.h b/intern/cycles/kernel/bvh/qbvh_volume_all.h index ab4b70085e8..5d9b2edb4ba 100644 --- a/intern/cycles/kernel/bvh/qbvh_volume_all.h +++ b/intern/cycles/kernel/bvh/qbvh_volume_all.h @@ -69,7 +69,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, #ifndef __KERNEL_SSE41__ if(!isfinite(P.x)) { - return false; + return 0; } #endif @@ -107,8 +107,9 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, do { /* Traverse internal nodes. */ while(node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) { -#ifdef __VISIBILITY_FLAG__ float4 inodes = kernel_tex_fetch(__bvh_nodes, node_addr+0); + +#ifdef __VISIBILITY_FLAG__ if((__float_as_uint(inodes.x) & visibility) == 0) { /* Pop. */ node_addr = traversal_stack[stack_ptr].addr; @@ -405,7 +406,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, # else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); # endif - triangle_intersect_precalc(dir, &isect_precalc); /* Scale isect->t to adjust for instancing. */ for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -418,9 +418,11 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, # else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); # endif - triangle_intersect_precalc(dir, &isect_precalc); } + isect_t = tmax; + isect_array->t = isect_t; + if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; } if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; } if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; } @@ -438,8 +440,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, # endif triangle_intersect_precalc(dir, &isect_precalc); - isect_t = tmax; - isect_array->t = isect_t; object = OBJECT_NONE; node_addr = traversal_stack[stack_ptr].addr; diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h index db2fc84834a..95b57404a77 100644 --- a/intern/cycles/kernel/kernel_shadow.h +++ b/intern/cycles/kernel/kernel_shadow.h @@ -125,14 +125,14 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, ShaderData *shadow_sd, /* stop if all light is blocked */ if(is_zero(throughput)) { - /* free dynamic storage */ return true; } /* move ray forward */ ray->P = shadow_sd->P; - if(ray->t != FLT_MAX) + if(ray->t != FLT_MAX) { ray->D = normalize_len(Pend - ray->P, &ray->t); + } #ifdef __VOLUME__ /* exit/enter volume */ @@ -234,8 +234,9 @@ ccl_device_noinline bool shadow_blocked(KernelGlobals *kg, return false; } - if(!shader_transparent_shadow(kg, isect)) + if(!shader_transparent_shadow(kg, isect)) { return true; + } #ifdef __VOLUME__ /* attenuation between last surface and next surface */ @@ -258,13 +259,16 @@ ccl_device_noinline bool shadow_blocked(KernelGlobals *kg, throughput *= shader_bsdf_transparency(kg, shadow_sd); } - if(is_zero(throughput)) + /* stop if all light is blocked */ + if(is_zero(throughput)) { return true; + } /* move ray forward */ ray->P = ray_offset(ccl_fetch(shadow_sd, P), -ccl_fetch(shadow_sd, Ng)); - if(ray->t != FLT_MAX) + if(ray->t != FLT_MAX) { ray->D = normalize_len(Pend - ray->P, &ray->t); + } #ifdef __VOLUME__ /* exit/enter volume */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 548bc1c1ccc..734b4462a91 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -829,7 +829,7 @@ typedef ccl_addr_space struct ShaderData { ccl_soa_member(differential3, ray_dP); #ifdef __OSL__ - struct KernelGlobals * osl_globals; + struct KernelGlobals *osl_globals; struct PathState *osl_path_state; #endif } ShaderData; diff --git a/intern/cycles/kernel/split/kernel_background_buffer_update.h b/intern/cycles/kernel/split/kernel_background_buffer_update.h index f42d0a985bb..9bfa71c75ef 100644 --- a/intern/cycles/kernel/split/kernel_background_buffer_update.h +++ b/intern/cycles/kernel/split/kernel_background_buffer_update.h @@ -232,7 +232,8 @@ ccl_device char kernel_background_buffer_update( #endif ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED); enqueue_flag = 1; - } else { + } + else { /* These rays do not participate in path-iteration. */ float4 L_rad = make_float4(0.0f, 0.0f, 0.0f, 0.0f); /* Accumulate result in output buffer. */ diff --git a/intern/cycles/kernel/split/kernel_data_init.h b/intern/cycles/kernel/split/kernel_data_init.h index e3dbc43757e..6e158d53d23 100644 --- a/intern/cycles/kernel/split/kernel_data_init.h +++ b/intern/cycles/kernel/split/kernel_data_init.h @@ -215,7 +215,8 @@ ccl_device void kernel_data_init( #ifdef __KERNEL_DEBUG__ debug_data_init(&debugdata_coop[ray_index]); #endif - } else { + } + else { /* These rays do not participate in path-iteration. */ float4 L_rad = make_float4(0.0f, 0.0f, 0.0f, 0.0f); /* Accumulate result in output buffer. */ diff --git a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h index 78dada82d89..435d1171d5c 100644 --- a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h +++ b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h @@ -212,7 +212,8 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao( if(terminate >= probability) { ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER); *enqueue_flag = 1; - } else { + } + else { throughput_coop[ray_index] = throughput/probability; } } diff --git a/intern/cycles/kernel/split/kernel_next_iteration_setup.h b/intern/cycles/kernel/split/kernel_next_iteration_setup.h index 74da80b52cc..816f3a6fbff 100644 --- a/intern/cycles/kernel/split/kernel_next_iteration_setup.h +++ b/intern/cycles/kernel/split/kernel_next_iteration_setup.h @@ -126,7 +126,7 @@ ccl_device char kernel_next_iteration_setup( if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) { ccl_global float3 *throughput = &throughput_coop[ray_index]; ccl_global Ray *ray = &Ray_coop[ray_index]; - ccl_global RNG* rng = &rng_coop[ray_index]; + ccl_global RNG *rng = &rng_coop[ray_index]; state = &PathState_coop[ray_index]; L = &PathRadiance_coop[ray_index]; diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index b387c2c2f98..7e24664b3fe 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -587,8 +587,7 @@ bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_ } if(depth <= 1) { - int scanlinesize = width*components*sizeof(float); - + size_t scanlinesize = ((size_t)width)*components*sizeof(float); in->read_image(TypeDesc::FLOAT, (uchar*)readpixels + (height-1)*scanlinesize, AutoStride, @@ -696,8 +695,7 @@ bool ImageManager::file_load_half_image(Image *img, ImageDataType type, device_v } if(depth <= 1) { - int scanlinesize = width*components*sizeof(half); - + size_t scanlinesize = ((size_t)width)*components*sizeof(half); in->read_image(TypeDesc::HALF, (uchar*)readpixels + (height-1)*scanlinesize, AutoStride, diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 2d297c33446..3eff35bae9e 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -601,6 +601,12 @@ void Mesh::add_undisplaced() /* copy verts */ size_t size = attr->buffer_size(this, (subdivision_type == SUBDIVISION_NONE) ? ATTR_PRIM_TRIANGLE : ATTR_PRIM_SUBD); + + /* Center points for ngons aren't stored in Mesh::verts but are included in size since they will be + * calculated later, we subtract them from size here so we don't have an overflow while copying. + */ + size -= num_ngons * attr->data_sizeof(); + if(size) { memcpy(data, verts.data(), size); } diff --git a/intern/cycles/render/mesh_subdivision.cpp b/intern/cycles/render/mesh_subdivision.cpp index 3b4841f5b20..0ae5ff742c2 100644 --- a/intern/cycles/render/mesh_subdivision.cpp +++ b/intern/cycles/render/mesh_subdivision.cpp @@ -16,12 +16,14 @@ #include "mesh.h" #include "attribute.h" +#include "camera.h" #include "subd_split.h" #include "subd_patch.h" #include "subd_patch_table.h" #include "util_foreach.h" +#include "util_algorithm.h" CCL_NAMESPACE_BEGIN @@ -177,7 +179,7 @@ public: Far::TopologyRefinerFactory<Mesh>::Options(type, options)); /* adaptive refinement */ - int max_isolation = 10; + int max_isolation = calculate_max_isolation(); refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation)); /* create patch table */ @@ -248,6 +250,42 @@ public: } } + int calculate_max_isolation() + { + /* loop over all edges to find longest in screen space */ + const Far::TopologyLevel& level = refiner->GetLevel(0); + Transform objecttoworld = mesh->subd_params->objecttoworld; + Camera* cam = mesh->subd_params->camera; + + float longest_edge = 0.0f; + + for(size_t i = 0; i < level.GetNumEdges(); i++) { + Far::ConstIndexArray verts = level.GetEdgeVertices(i); + + float3 a = mesh->verts[verts[0]]; + float3 b = mesh->verts[verts[1]]; + + float edge_len; + + if(cam) { + a = transform_point(&objecttoworld, a); + b = transform_point(&objecttoworld, b); + + edge_len = len(a - b) / cam->world_to_raster_size((a + b) * 0.5f); + } + else { + edge_len = len(a - b); + } + + longest_edge = max(longest_edge, edge_len); + } + + /* calculate isolation level */ + int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f); + + return min(isolation, 10); + } + friend struct OsdPatch; friend class Mesh; }; diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index c2f1ce176ad..8186eaa759d 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -138,6 +138,8 @@ private: //static CGLEWContext *s_cglewContext; + const bool m_debug; + /** The first created OpenGL context (for sharing display lists) */ static NSOpenGLContext *s_sharedOpenGLContext; static int s_sharedCount; diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm index 6a39d76e752..1ab0301f7b2 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.mm +++ b/intern/ghost/intern/GHOST_ContextCGL.mm @@ -59,7 +59,8 @@ GHOST_ContextCGL::GHOST_ContextCGL( int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), m_openGLView(openGLView), - m_openGLContext(nil) + m_openGLContext(nil), + m_debug(contextFlags) { assert(openGLView != nil); @@ -186,27 +187,27 @@ GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext() static void makeAttribList( std::vector<NSOpenGLPixelFormatAttribute>& attribs, - bool coreProfile, bool stereoVisual, int numOfAASamples, bool needAlpha, - bool needStencil) + bool needStencil, + bool softwareGL) { + attribs.clear(); + attribs.push_back(NSOpenGLPFAOpenGLProfile); attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy); // Pixel Format Attributes for the windowed NSOpenGLContext attribs.push_back(NSOpenGLPFADoubleBuffer); - // Force software OpenGL, for debugging - /* XXX jwilkins: fixed this to work on Intel macs? useful feature for Windows and Linux too? - * Maybe a command line flag is better... */ - if (getenv("BLENDER_SOFTWAREGL")) { + if (softwareGL) { attribs.push_back(NSOpenGLPFARendererID); attribs.push_back(kCGLRendererGenericFloatID); } else { attribs.push_back(NSOpenGLPFAAccelerated); + attribs.push_back(NSOpenGLPFANoRecovery); } attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); // for automatic GPU switching @@ -239,13 +240,21 @@ static void makeAttribList( attribs.push_back(NSOpenGLPFASamples); attribs.push_back((NSOpenGLPixelFormatAttribute) numOfAASamples); - - attribs.push_back(NSOpenGLPFANoRecovery); } attribs.push_back((NSOpenGLPixelFormatAttribute) 0); } +// TODO(merwin): make this available to all platforms +static void getVersion(int *major, int *minor) +{ +#if 1 // legacy GL + sscanf((const char*)glGetString(GL_VERSION), "%d.%d", major, minor); +#else // 3.0+ + glGetIntegerv(GL_MAJOR_VERSION, major); + glGetIntegerv(GL_MINOR_VERSION, minor); +#endif +} GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext() { @@ -268,9 +277,12 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext() static const bool needStencil = false; #endif - makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil); - + static bool softwareGL = getenv("BLENDER_SOFTWAREGL"); // command-line argument would be better + GLint major = 0, minor = 0; NSOpenGLPixelFormat *pixelFormat; + // TODO: keep pixel format for subsequent windows/contexts instead of recreating each time + + makeAttribList(attribs, coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL); pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; @@ -281,7 +293,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext() // (Now that I think about it, does WGL really require the code that it has for finding a lesser match?) attribs.clear(); - makeAttribList(attribs, m_coreProfile, m_stereoVisual, 0, needAlpha, needStencil); + makeAttribList(attribs, coreProfile, m_stereoVisual, 0, needAlpha, needStencil, softwareGL); pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; } @@ -302,25 +314,47 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext() } } - [m_openGLView setPixelFormat:pixelFormat]; + m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext]; + [pixelFormat release]; - m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext]; // +1 refCount to pixelFormat + [m_openGLContext makeCurrentContext]; - if (m_openGLContext == nil) - goto error; + getVersion(&major, &minor); + if (m_debug) { + fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : ""); + fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER)); + } - if (s_sharedCount == 0) - s_sharedOpenGLContext = m_openGLContext; - - [pixelFormat release]; // -1 refCount to pixelFormat - - s_sharedCount++; + if (major < 2 || (major == 2 && minor < 1)) { + // fall back to software renderer if GL < 2.1 + fprintf(stderr, "OpenGL 2.1 is not supported on your hardware, falling back to software"); + softwareGL = true; + + // discard hardware GL context + [NSOpenGLContext clearCurrentContext]; + [m_openGLContext release]; + + // create software GL context + makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL); + pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; + m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext]; + [pixelFormat release]; + + [m_openGLContext makeCurrentContext]; + + getVersion(&major, &minor); + if (m_debug) { + fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : ""); + fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER)); + } + } #ifdef GHOST_MULTITHREADED_OPENGL //Switch openGL to multhreaded mode CGLContextObj cglCtx = (CGLContextObj)[tmpOpenGLContext CGLContextObj]; if (CGLEnable(cglCtx, kCGLCEMPEngine) == kCGLNoError) - printf("\nSwitched openGL to multithreaded mode\n"); + if (m_debug) + fprintf(stderr, "\nSwitched OpenGL to multithreaded mode\n"); #endif #ifdef GHOST_WAIT_FOR_VSYNC @@ -331,10 +365,16 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext() } #endif + initContextGLEW(); + [m_openGLView setOpenGLContext:m_openGLContext]; [m_openGLContext setView:m_openGLView]; - initContextGLEW(); + if (s_sharedCount == 0) + s_sharedOpenGLContext = m_openGLContext; + + s_sharedCount++; + initClearGL(); [m_openGLContext flushBuffer]; diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index b0d5ab31ce3..f31cba498e5 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -562,7 +562,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( // Add contentRect.origin.y to respect docksize bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y; - window = new GHOST_WindowCocoa (this, title, left, bottom, width, height, state, type, ((glSettings.flags & GHOST_glStereoVisual) != 0), glSettings.numOfAASamples); + window = new GHOST_WindowCocoa(this, title, left, bottom, width, height, state, type, glSettings.flags & GHOST_glStereoVisual, glSettings.numOfAASamples, glSettings.flags & GHOST_glDebugContext); if (window->getValid()) { // Store the pointer to the window diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index f884b0fadb1..60e7815ccbb 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -41,7 +41,7 @@ #include <shlobj.h> #include <tlhelp32.h> -#include <Psapi.h> +#include <psapi.h> #include <windowsx.h> #include "utfconv.h" diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 3ed88086184..b234291396b 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -74,7 +74,8 @@ public: GHOST_TWindowState state, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, const bool stereoVisual = false, - const GHOST_TUns16 numOfAASamples = 0 + const GHOST_TUns16 numOfAASamples = 0, + bool is_debug = false ); /** @@ -305,6 +306,7 @@ protected: bool m_lionStyleFullScreen; bool m_immediateDraw; + bool m_debug_context; // for debug messages during context setup }; #endif // __GHOST_WINDOWCOCOA_H__ diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 383734be3e6..b0feb11a6af 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -528,10 +528,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - const bool stereoVisual, const GHOST_TUns16 numOfAASamples + const bool stereoVisual, const GHOST_TUns16 numOfAASamples, bool is_debug ) : GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples), - m_customCursor(0) + m_customCursor(0), + m_debug_context(is_debug) { m_systemCocoa = systemCocoa; m_fullScreen = false; diff --git a/intern/mikktspace/mikktspace.c b/intern/mikktspace/mikktspace.c index 7e5861ea9ed..8d51816b132 100644 --- a/intern/mikktspace/mikktspace.c +++ b/intern/mikktspace/mikktspace.c @@ -579,11 +579,10 @@ static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], cons { // make bbox int c=0, l=0, channel=0; - float fvMin[3], fvMax[3]; + float fvMin[3] = {INFINITY, INFINITY, INFINITY}; + float fvMax[3] = {-INFINITY, -INFINITY, -INFINITY}; float dx=0, dy=0, dz=0, fSep=0; - for (c=0; c<3; c++) - { fvMin[c]=pTmpVert[iL_in].vert[c]; fvMax[c]=fvMin[c]; } - for (l=(iL_in+1); l<=iR_in; l++) + for (l=iL_in; l<=iR_in; l++) for (c=0; c<3; c++) if (fvMin[c]>pTmpVert[l].vert[c]) fvMin[c]=pTmpVert[l].vert[c]; else if (fvMax[c]<pTmpVert[l].vert[c]) fvMax[c]=pTmpVert[l].vert[c]; @@ -598,6 +597,10 @@ static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], cons fSep = 0.5f*(fvMax[channel]+fvMin[channel]); + // stop if all vertices are NaNs + if (!isfinite(fSep)) + return; + // terminate recursion when the separation/average value // is no longer strictly between fMin and fMax values. if (fSep>=fvMax[channel] || fSep<=fvMin[channel]) |