Cycles code refactor: changes to make adding new primitive types easier.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 29 Mar 2014 12:03:46 +0000 (13:03 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 29 Mar 2014 12:03:46 +0000 (13:03 +0100)
24 files changed:
intern/cycles/bvh/bvh.cpp
intern/cycles/bvh/bvh.h
intern/cycles/bvh/bvh_build.cpp
intern/cycles/bvh/bvh_build.h
intern/cycles/bvh/bvh_params.h
intern/cycles/bvh/bvh_sort.cpp
intern/cycles/bvh/bvh_split.cpp
intern/cycles/kernel/geom/geom_bvh_subsurface.h
intern/cycles/kernel/geom/geom_bvh_traversal.h
intern/cycles/kernel/geom/geom_curve.h
intern/cycles/kernel/geom/geom_triangle.h
intern/cycles/kernel/kernel_emission.h
intern/cycles/kernel/kernel_primitive.h
intern/cycles/kernel/kernel_shader.h
intern/cycles/kernel/kernel_textures.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/osl/osl_services.cpp
intern/cycles/kernel/osl/osl_shader.cpp
intern/cycles/kernel/svm/svm_attribute.h
intern/cycles/kernel/svm/svm_closure.h
intern/cycles/kernel/svm/svm_geometry.h
intern/cycles/kernel/svm/svm_wireframe.h
intern/cycles/render/mesh.cpp
intern/cycles/render/scene.h

index 6c636ac5c8d28acc543a64adfc9dde6fd20bf86d..0d46638c82d535ab2d02954350ad9e595dcc5a2d 100644 (file)
@@ -97,7 +97,7 @@ bool BVH::cache_read(CacheData& key)
                value.read(pack.nodes);
                value.read(pack.object_node);
                value.read(pack.tri_woop);
-               value.read(pack.prim_segment);
+               value.read(pack.prim_type);
                value.read(pack.prim_visibility);
                value.read(pack.prim_index);
                value.read(pack.prim_object);
@@ -119,7 +119,7 @@ void BVH::cache_write(CacheData& key)
        value.add(pack.nodes);
        value.add(pack.object_node);
        value.add(pack.tri_woop);
-       value.add(pack.prim_segment);
+       value.add(pack.prim_type);
        value.add(pack.prim_visibility);
        value.add(pack.prim_index);
        value.add(pack.prim_object);
@@ -165,11 +165,11 @@ void BVH::build(Progress& progress)
        }
 
        /* build nodes */
-       vector<int> prim_segment;
+       vector<int> prim_type;
        vector<int> prim_index;
        vector<int> prim_object;
 
-       BVHBuild bvh_build(objects, prim_segment, prim_index, prim_object, params, progress);
+       BVHBuild bvh_build(objects, prim_type, prim_index, prim_object, params, progress);
        BVHNode *root = bvh_build.run();
 
        if(progress.get_cancel()) {
@@ -178,7 +178,7 @@ void BVH::build(Progress& progress)
        }
 
        /* todo: get rid of this copy */
-       pack.prim_segment = prim_segment;
+       pack.prim_type = prim_type;
        pack.prim_index = prim_index;
        pack.prim_object = prim_object;
 
@@ -280,7 +280,7 @@ void BVH::pack_curve_segment(int idx, float4 woop[3])
        int tob = pack.prim_object[idx];
        const Mesh *mesh = objects[tob]->mesh;
        int tidx = pack.prim_index[idx];
-       int segment = pack.prim_segment[idx];
+       int segment = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[idx]);
        int k0 = mesh->curves[tidx].first_key + segment;
        int k1 = mesh->curves[tidx].first_key + segment + 1;
        float3 v0 = mesh->curve_keys[k0].co;
@@ -324,7 +324,7 @@ void BVH::pack_primitives()
                if(pack.prim_index[i] != -1) {
                        float4 woop[3];
 
-                       if(pack.prim_segment[i] != ~0)
+                       if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
                                pack_curve_segment(i, woop);
                        else
                                pack_triangle(i, woop);
@@ -335,7 +335,7 @@ void BVH::pack_primitives()
                        Object *ob = objects[tob];
                        pack.prim_visibility[i] = ob->visibility;
 
-                       if(pack.prim_segment[i] != ~0)
+                       if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
                                pack.prim_visibility[i] |= PATH_RAY_CURVE;
                }
                else {
@@ -359,7 +359,7 @@ void BVH::pack_instances(size_t nodes_size)
         * meshes with transform applied and already in the top level BVH */
        for(size_t i = 0; i < pack.prim_index.size(); i++)
                if(pack.prim_index[i] != -1) {
-                       if(pack.prim_segment[i] != ~0)
+                       if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
                                pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
                        else
                                pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
@@ -401,7 +401,7 @@ void BVH::pack_instances(size_t nodes_size)
        mesh_map.clear();
 
        pack.prim_index.resize(prim_index_size);
-       pack.prim_segment.resize(prim_index_size);
+       pack.prim_type.resize(prim_index_size);
        pack.prim_object.resize(prim_index_size);
        pack.prim_visibility.resize(prim_index_size);
        pack.tri_woop.resize(tri_woop_size);
@@ -409,7 +409,7 @@ void BVH::pack_instances(size_t nodes_size)
        pack.object_node.resize(objects.size());
 
        int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
-       int *pack_prim_segment = (pack.prim_segment.size())? &pack.prim_segment[0]: NULL;
+       int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
        int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
        uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
        float4 *pack_tri_woop = (pack.tri_woop.size())? &pack.tri_woop[0]: NULL;
@@ -454,16 +454,16 @@ void BVH::pack_instances(size_t nodes_size)
                if(bvh->pack.prim_index.size()) {
                        size_t bvh_prim_index_size = bvh->pack.prim_index.size();
                        int *bvh_prim_index = &bvh->pack.prim_index[0];
-                       int *bvh_prim_segment = &bvh->pack.prim_segment[0];
+                       int *bvh_prim_type = &bvh->pack.prim_type[0];
                        uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
 
                        for(size_t i = 0; i < bvh_prim_index_size; i++) {
-                               if(bvh->pack.prim_segment[i] != ~0)
+                               if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
                                        pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
                                else
                                        pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
 
-                               pack_prim_segment[pack_prim_index_offset] = bvh_prim_segment[i];
+                               pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
                                pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
                                pack_prim_object[pack_prim_index_offset] = 0;  // unused for instances
                                pack_prim_index_offset++;
@@ -629,10 +629,10 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
                                /* primitives */
                                const Mesh *mesh = ob->mesh;
 
-                               if(pack.prim_segment[prim] != ~0) {
+                               if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
                                        /* curves */
                                        int str_offset = (params.top_level)? mesh->curve_offset: 0;
-                                       int k0 = mesh->curves[pidx - str_offset].first_key + pack.prim_segment[prim]; // XXX!
+                                       int k0 = mesh->curves[pidx - str_offset].first_key + PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
                                        int k1 = k0 + 1;
 
                                        float3 p[4];
index f2c96638b8454d817beb80b26a336080f304bef6..5fcaaaa988c95ad7efc09760e0c23feb437bf9b9 100644 (file)
@@ -52,8 +52,8 @@ struct PackedBVH {
        array<int> object_node; 
        /* precomputed triangle intersection data, one triangle is 4x float4 */
        array<float4> tri_woop;
-       /* primitive type - triangle or strand (should be moved to flag?) */
-       array<int> prim_segment;
+       /* primitive type - triangle or strand */
+       array<int> prim_type;
        /* visibility visibilitys for primitives */
        array<uint> prim_visibility;
        /* mapping from BVH primitive index to true primitive index, as primitives
index b21b20a87e511e4d95c8711de1e52e769bce2dc8..aa8ba36f8916eb4772b4e7dac7956c937479da04 100644 (file)
@@ -49,10 +49,10 @@ public:
 /* Constructor / Destructor */
 
 BVHBuild::BVHBuild(const vector<Object*>& objects_,
-       vector<int>& prim_segment_, vector<int>& prim_index_, vector<int>& prim_object_,
+       vector<int>& prim_type_, vector<int>& prim_index_, vector<int>& prim_object_,
        const BVHParams& params_, Progress& progress_)
 : objects(objects_),
-  prim_segment(prim_segment_),
+  prim_type(prim_type_),
   prim_index(prim_index_),
   prim_object(prim_object_),
   params(params_),
@@ -73,6 +73,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
        for(uint j = 0; j < mesh->triangles.size(); j++) {
                Mesh::Triangle t = mesh->triangles[j];
                BoundBox bounds = BoundBox::empty;
+               PrimitiveType type = PRIMITIVE_TRIANGLE;
 
                for(int k = 0; k < 3; k++) {
                        float3 co = mesh->verts[t.v[k]];
@@ -80,7 +81,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
                }
 
                if(bounds.valid()) {
-                       references.push_back(BVHReference(bounds, j, i, ~0));
+                       references.push_back(BVHReference(bounds, j, i, type));
                        root.grow(bounds);
                        center.grow(bounds.center2());
                }
@@ -88,6 +89,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
 
        for(uint j = 0; j < mesh->curves.size(); j++) {
                Mesh::Curve curve = mesh->curves[j];
+               PrimitiveType type = PRIMITIVE_CURVE;
 
                for(int k = 0; k < curve.num_keys - 1; k++) {
                        BoundBox bounds = BoundBox::empty;
@@ -108,7 +110,9 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
                        bounds.grow(upper, mr);
 
                        if(bounds.valid()) {
-                               references.push_back(BVHReference(bounds, j, i, k));
+                               int packed_type = PRIMITIVE_PACK_SEGMENT(type, k);
+                               
+                               references.push_back(BVHReference(bounds, j, i, packed_type));
                                root.grow(bounds);
                                center.grow(bounds.center2());
                        }
@@ -118,7 +122,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
 
 void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i)
 {
-       references.push_back(BVHReference(ob->bounds, -1, i, false));
+       references.push_back(BVHReference(ob->bounds, -1, i, 0));
        root.grow(ob->bounds);
        center.grow(ob->bounds.center2());
 }
@@ -207,7 +211,7 @@ BVHNode* BVHBuild::run()
        progress_total = references.size();
        progress_original_total = progress_total;
 
-       prim_segment.resize(references.size());
+       prim_type.resize(references.size());
        prim_index.resize(references.size());
        prim_object.resize(references.size());
 
@@ -373,12 +377,12 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
                if(start == prim_index.size()) {
                        assert(params.use_spatial_split);
 
-                       prim_segment.push_back(ref->prim_segment());
+                       prim_type.push_back(ref->prim_type());
                        prim_index.push_back(ref->prim_index());
                        prim_object.push_back(ref->prim_object());
                }
                else {
-                       prim_segment[start] = ref->prim_segment();
+                       prim_type[start] = ref->prim_type();
                        prim_index[start] = ref->prim_index();
                        prim_object[start] = ref->prim_object();
                }
@@ -401,7 +405,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
 
 BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
 {
-       vector<int>& p_segment = prim_segment;
+       vector<int>& p_type = prim_type;
        vector<int>& p_index = prim_index;
        vector<int>& p_object = prim_object;
        BoundBox bounds = BoundBox::empty;
@@ -415,12 +419,12 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
                        if(range.start() + num == prim_index.size()) {
                                assert(params.use_spatial_split);
 
-                               p_segment.push_back(ref.prim_segment());
+                               p_type.push_back(ref.prim_type());
                                p_index.push_back(ref.prim_index());
                                p_object.push_back(ref.prim_object());
                        }
                        else {
-                               p_segment[range.start() + num] = ref.prim_segment();
+                               p_type[range.start() + num] = ref.prim_type();
                                p_index[range.start() + num] = ref.prim_index();
                                p_object[range.start() + num] = ref.prim_object();
                        }
index 3df4da1739a2902440176e9fd74680ee9426f49b..ba10eb494126c51f8a842acba868b560630d3543 100644 (file)
@@ -44,7 +44,7 @@ public:
        /* Constructor/Destructor */
        BVHBuild(
                const vector<Object*>& objects,
-               vector<int>& prim_segment,
+               vector<int>& prim_type,
                vector<int>& prim_index,
                vector<int>& prim_object,
                const BVHParams& params,
@@ -88,7 +88,7 @@ protected:
        int num_original_references;
 
        /* output primitive indexes and objects */
-       vector<int>& prim_segment;
+       vector<int>& prim_type;
        vector<int>& prim_index;
        vector<int>& prim_object;
 
index ad36bdfa32601e96ca936142916f31150714d3c8..3e93c0c56a02cbc1dc8a170c43028b5663e1983b 100644 (file)
@@ -98,22 +98,22 @@ class BVHReference
 public:
        __forceinline BVHReference() {}
 
-       __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_segment)
+       __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_type)
        : rbounds(bounds_)
        {
                rbounds.min.w = __int_as_float(prim_index_);
                rbounds.max.w = __int_as_float(prim_object_);
-               segment = prim_segment;
+               type = prim_type;
        }
 
        __forceinline const BoundBox& bounds() const { return rbounds; }
        __forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
        __forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
-       __forceinline int prim_segment() const { return segment; }
+       __forceinline int prim_type() const { return type; }
 
 protected:
        BoundBox rbounds;
-       uint segment;
+       uint type;
 };
 
 /* BVH Range
index d7dbae36336d477f600286aee79ba526211c1f17..3140bf23376e8395caa0b2cfd8bf6b290e8adc3d 100644 (file)
@@ -52,8 +52,8 @@ public:
                else if(ra.prim_object() > rb.prim_object()) return false;
                else if(ra.prim_index() < rb.prim_index()) return true;
                else if(ra.prim_index() > rb.prim_index()) return false;
-               else if(ra.prim_segment() < rb.prim_segment()) return true;
-               else if(ra.prim_segment() > rb.prim_segment()) return false;
+               else if(ra.prim_type() < rb.prim_type()) return true;
+               else if(ra.prim_type() > rb.prim_type()) return false;
 
                return false;
        }
index 03ff69d7b6dcba810d47067f014ffcd7a839b0e5..864626da134ef4e00f323ca8c49e49bdec4e11d6 100644 (file)
@@ -253,7 +253,7 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
        Object *ob = builder->objects[ref.prim_object()];
        const Mesh *mesh = ob->mesh;
 
-       if (ref.prim_segment() == ~0) {
+       if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
                const int *inds = mesh->triangles[ref.prim_index()].v;
                const float3 *verts = &mesh->verts[0];
                const float3* v1 = &verts[inds[2]];
@@ -282,7 +282,7 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
        }
        else {
                /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
-               const int k0 = mesh->curves[ref.prim_index()].first_key + ref.prim_segment();
+               const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type());
                const int k1 = k0 + 1;
                const float3* v0 = &mesh->curve_keys[k0].co;
                const float3* v1 = &mesh->curve_keys[k1].co;
@@ -318,8 +318,8 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
        right_bounds.intersect(ref.bounds());
 
        /* set references */
-       left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
-       right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
+       left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
+       right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
 }
 
 CCL_NAMESPACE_END
index 6529f58c0d26bf4134282921bc829861cfe23e15..d61929405ef254a4f542870d3f19512b207e94d3 100644 (file)
@@ -204,19 +204,23 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
 
                                        /* primitive intersection */
                                        for(; primAddr < primAddr2; primAddr++) {
-#if FEATURE(BVH_HAIR)
-                                               uint segment = kernel_tex_fetch(__prim_segment, primAddr);
-                                               if(segment != ~0)
-                                                       continue;
-#endif
-
                                                /* only primitives from the same object */
                                                uint tri_object = (object == ~0)? kernel_tex_fetch(__prim_object, primAddr): object;
 
-                                               if(tri_object == subsurface_object) {
+                                               if(tri_object != subsurface_object)
+                                                       continue;
 
-                                                       /* intersect ray against primitive */
-                                                       triangle_intersect_subsurface(kg, isect_array, P, idir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
+                                               /* intersect ray against primitive */
+                                               uint type = kernel_tex_fetch(__prim_type, primAddr);
+
+                                               switch(type & PRIMITIVE_ALL) {
+                                                       case PRIMITIVE_TRIANGLE: {
+                                                               triangle_intersect_subsurface(kg, isect_array, P, idir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
+                                                               break;
+                                                       }
+                                                       default: {
+                                                               break;
+                                                       }
                                                }
                                        }
                                }
index 3a50ffedfde2ae36d98b89f240be4209765f15ba..1abefb51976c13f48addb86c2349fe6352d1251c 100644 (file)
@@ -249,26 +249,35 @@ ccl_device bool BVH_FUNCTION_NAME
                                        /* primitive intersection */
                                        while(primAddr < primAddr2) {
                                                bool hit;
+                                               uint type = kernel_tex_fetch(__prim_type, primAddr);
 
-                                               /* intersect ray against primitive */
+                                               switch(type & PRIMITIVE_ALL) {
+                                                       case PRIMITIVE_TRIANGLE: {
+                                                               hit = triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
+                                                               break;
+                                                       }
 #if FEATURE(BVH_HAIR)
-                                               uint segment = kernel_tex_fetch(__prim_segment, primAddr);
-                                               if(segment != ~0) {
-
-                                                       if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) 
+                                                       case PRIMITIVE_CURVE: {
 #if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
-                                                               hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, segment, lcg_state, difl, extmax);
-                                                       else
-                                                               hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, segment, lcg_state, difl, extmax);
+                                                               if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) 
+                                                                       hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+                                                               else
+                                                                       hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
 #else
-                                                               hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, segment);
-                                                       else
-                                                               hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, segment);
+                                                               if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) 
+                                                                       hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type);
+                                                               else
+                                                                       hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type);
 #endif
-                                               }
-                                               else
+
+                                                               break;
+                                                       }
 #endif
-                                                       hit = triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
+                                                       default: {
+                                                               hit = false;
+                                                               break;
+                                                       }
+                                               }
 
                                                /* shadow ray early termination */
 #if defined(__KERNEL_SSE2__)
index ec9081a6c75082e423daf339ff2dba9f87ad79f1..484f3ae6eb944d5ee4deb3a24c9ec1d63a537230 100644 (file)
@@ -30,7 +30,7 @@ ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd,
        }
        else if(elem == ATTR_ELEMENT_CURVE_KEY || elem == ATTR_ELEMENT_CURVE_KEY_MOTION) {
                float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
-               int k0 = __float_as_int(curvedata.x) + sd->segment;
+               int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
                int k1 = k0 + 1;
 
                float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
@@ -69,7 +69,7 @@ ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd
        }
        else if(elem == ATTR_ELEMENT_CURVE_KEY || elem == ATTR_ELEMENT_CURVE_KEY_MOTION) {
                float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
-               int k0 = __float_as_int(curvedata.x) + sd->segment;
+               int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
                int k1 = k0 + 1;
 
                float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
@@ -98,9 +98,9 @@ ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
 {
        float r = 0.0f;
 
-       if(sd->segment != ~0) {
+       if(sd->type & PRIMITIVE_ALL_CURVE) {
                float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
-               int k0 = __float_as_int(curvedata.x) + sd->segment;
+               int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
                int k1 = k0 + 1;
 
                float4 P1 = kernel_tex_fetch(__curve_keys, k0);
@@ -115,7 +115,7 @@ ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
 {      
        float3 tgN = make_float3(0.0f,0.0f,0.0f);
 
-       if(sd->segment != ~0) {
+       if(sd->type & PRIMITIVE_ALL_CURVE) {
 
                tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) / len_squared(sd->dPdu)));
                tgN = normalize(tgN);
@@ -192,12 +192,13 @@ ccl_device_inline __m128 transform_point_T3(const __m128 t[3], const __m128 &a)
 #ifdef __KERNEL_SSE2__
 /* Pass P and idir by reference to aligned vector */
 ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
-       const float3 &P, const float3 &idir, uint visibility, int object, int curveAddr, float time, int segment, uint *lcg_state, float difl, float extmax)
+       const float3 &P, const float3 &idir, uint visibility, int object, int curveAddr, float time, int type, uint *lcg_state, float difl, float extmax)
 #else
 ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
-       float3 P, float3 idir, uint visibility, int object, int curveAddr, float time, int segment, uint *lcg_state, float difl, float extmax)
+       float3 P, float3 idir, uint visibility, int object, int curveAddr, float time,int type, uint *lcg_state, float difl, float extmax)
 #endif
 {
+       int segment = PRIMITIVE_UNPACK_SEGMENT(type);
        float epsilon = 0.0f;
        float r_st, r_en;
 
@@ -548,7 +549,7 @@ ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersect
                                /* record intersection */
                                isect->prim = curveAddr;
                                isect->object = object;
-                               isect->segment = segment;
+                               isect->type = type;
                                isect->u = u;
                                isect->v = 0.0f;
                                /*isect->v = 1.0f - coverage; */
@@ -569,7 +570,7 @@ ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersect
 }
 
 ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
-       float3 P, float3 idir, uint visibility, int object, int curveAddr, float time, int segment, uint *lcg_state, float difl, float extmax)
+       float3 P, float3 idir, uint visibility, int object, int curveAddr, float time, int type, uint *lcg_state, float difl, float extmax)
 {
        /* define few macros to minimize code duplication for SSE */
 #ifndef __KERNEL_SSE2__
@@ -578,6 +579,7 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec
 #define dot3(x, y) dot(x, y)
 #endif
 
+       int segment = PRIMITIVE_UNPACK_SEGMENT(type);
        /* curve Intersection check */
        int flags = kernel_data.curve.curveflags;
 
@@ -768,7 +770,7 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec
                                /* record intersection */
                                isect->prim = curveAddr;
                                isect->object = object;
-                               isect->segment = segment;
+                               isect->type = type;
                                isect->u = z*invl;
                                isect->v = td/(4*a*a);
                                /*isect->v = 1.0f - adjradius;*/
@@ -841,7 +843,7 @@ ccl_device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, con
        int prim = kernel_tex_fetch(__prim_index, isect->prim);
        float4 v00 = kernel_tex_fetch(__curves, prim);
 
-       int k0 = __float_as_int(v00.x) + sd->segment;
+       int k0 = __float_as_int(v00.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
        int k1 = k0 + 1;
 
        float3 tg;
index 1bdc76445f9e17664793e094b735adbe10ead1b9..7b115daa022037bdde0eb2438f44ae23ac4f5dfc 100644 (file)
@@ -290,6 +290,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, Intersection *isect
                                        /* record intersection */
                                        isect->prim = triAddr;
                                        isect->object = object;
+                                       isect->type = PRIMITIVE_TRIANGLE;
                                        isect->u = u;
                                        isect->v = v;
                                        isect->t = t;
@@ -353,6 +354,7 @@ ccl_device_inline void triangle_intersect_subsurface(KernelGlobals *kg, Intersec
                                Intersection *isect = &isect_array[hit];
                                isect->prim = triAddr;
                                isect->object = object;
+                               isect->type = PRIMITIVE_TRIANGLE;
                                isect->u = u;
                                isect->v = v;
                                isect->t = t;
index cbcec4291bdfcd95c5434e218efeb05ac3a000db..44c2572efc23f4b012155af48c6558541ac58044 100644 (file)
@@ -43,12 +43,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
        else
 #endif
        {
-#ifdef __HAIR__
-               if(ls->type == LIGHT_STRAND)
-                       shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ls->prim);
-               else
-#endif
-                       shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ~0);
+               shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1);
 
                ls->Ng = sd.Ng;
 
@@ -171,7 +166,7 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader
        float3 L = shader_emissive_eval(kg, sd);
 
 #ifdef __HAIR__
-       if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->segment == ~0)) {
+       if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->type & PRIMITIVE_ALL_TRIANGLE)) {
 #else
        if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS)) {
 #endif
index fa450c97cbf9bdad3e5edd067b6d08048589f193..f9efdd2cf562f97e78fe8d5b142a598f6ef21f93 100644 (file)
@@ -36,7 +36,7 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id,
                /* for SVM, find attribute by unique id */
                uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
 #ifdef __HAIR__
-               attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+               attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
 #endif
                uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
                
@@ -58,7 +58,7 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id,
 ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
 {
 #ifdef __HAIR__
-       if(sd->segment == ~0)
+       if(sd->type & PRIMITIVE_ALL_TRIANGLE)
 #endif
                return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
 #ifdef __HAIR__
@@ -70,7 +70,7 @@ ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *
 ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
 {
 #ifdef __HAIR__
-       if(sd->segment == ~0)
+       if(sd->type & PRIMITIVE_ALL_TRIANGLE)
 #endif
                return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
 #ifdef __HAIR__
@@ -126,7 +126,7 @@ ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, in
 ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
 {
 #ifdef __HAIR__
-       if(sd->segment != ~0)
+       if(sd->type & PRIMITIVE_ALL_CURVE)
 #ifdef __DPDU__
                return normalize(sd->dPdu);
 #else
index 0f327f16419bf6190cb32e39925f9d1fc1cd5c74..95cdfd1a80a2afab1e40d7fa9b08ad35c34a3bb6 100644 (file)
@@ -55,6 +55,7 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
        sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
 #endif
 
+       sd->type = isect->type;
        sd->flag = kernel_tex_fetch(__object_flag, sd->object);
 
        /* matrices and time */
@@ -67,34 +68,27 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
        sd->ray_length = isect->t;
        sd->ray_depth = bounce;
 
+#ifdef __UV__
+       sd->u = isect->u;
+       sd->v = isect->v;
+#endif
+
 #ifdef __HAIR__
-       if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
-               /* Strand Shader setting*/
+       if(sd->type & PRIMITIVE_ALL_CURVE) {
+               /* curve */
                float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
 
                sd->shader = __float_as_int(curvedata.z);
-               sd->segment = isect->segment;
                sd->P = bvh_curve_refine(kg, sd, isect, ray);
        }
-       else {
+       else
 #endif
+       {
                /* fetch triangle data */
                float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
                float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
                sd->shader = __float_as_int(Ns.w);
 
-#ifdef __HAIR__
-               sd->segment = ~0;
-               /*elements for minimum hair width using transparency bsdf*/
-               /*sd->curve_transparency = 0.0f;*/
-               /*sd->curve_radius = 0.0f;*/
-#endif
-
-#ifdef __UV__
-               sd->u = isect->u;
-               sd->v = isect->v;
-#endif
-
                /* vectors */
                sd->P = triangle_refine(kg, sd, isect, ray);
                sd->Ng = Ng;
@@ -108,10 +102,7 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
                /* dPdu/dPdv */
                triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
 #endif
-
-#ifdef __HAIR__
        }
-#endif
 
        sd->I = -ray->D;
 
@@ -161,34 +152,32 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat
        /* object, matrices, time, ray_length stay the same */
        sd->flag = kernel_tex_fetch(__object_flag, sd->object);
        sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
-
-       /* fetch triangle data */
-       float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
-       float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
-       sd->shader = __float_as_int(Ns.w);
-
-#ifdef __HAIR__
-       sd->segment = ~0;
-#endif
+       sd->type = isect->type;
 
 #ifdef __UV__
        sd->u = isect->u;
        sd->v = isect->v;
 #endif
 
-       /* vectors */
-       sd->P = triangle_refine_subsurface(kg, sd, isect, ray);
-       sd->Ng = Ng;
-       sd->N = Ng;
-       
-       /* smooth normal */
-       if(sd->shader & SHADER_SMOOTH_NORMAL)
-               sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
+       /* fetch triangle data */
+       {
+               float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
+               float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
+               sd->shader = __float_as_int(Ns.w);
+
+               /* static triangle */
+               sd->P = triangle_refine_subsurface(kg, sd, isect, ray);
+               sd->Ng = Ng;
+               sd->N = Ng;
+
+               if(sd->shader & SHADER_SMOOTH_NORMAL)
+                       sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
 
 #ifdef __DPDU__
-       /* dPdu/dPdv */
-       triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
+               /* dPdu/dPdv */
+               triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
 #endif
+       }
 
        sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
 
@@ -231,7 +220,7 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat
 
 ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        const float3 P, const float3 Ng, const float3 I,
-       int shader, int object, int prim, float u, float v, float t, float time, int bounce, int segment)
+       int shader, int object, int prim, float u, float v, float t, float time, int bounce)
 {
        /* vectors */
        sd->P = P;
@@ -239,9 +228,7 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        sd->Ng = Ng;
        sd->I = I;
        sd->shader = shader;
-#ifdef __HAIR__
-       sd->segment = segment;
-#endif
+       sd->type = (prim == ~0)? PRIMITIVE_NONE: PRIMITIVE_TRIANGLE;
 
        /* primitive */
 #ifdef __INSTANCING__
@@ -283,35 +270,19 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        }
 #endif
 
-       /* smooth normal */
-#ifdef __HAIR__
-       if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
-               sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
-#else
-       if(sd->shader & SHADER_SMOOTH_NORMAL) {
-               sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
-#endif
+       if(sd->type & PRIMITIVE_TRIANGLE) {
+               /* smooth normal */
+               if(sd->shader & SHADER_SMOOTH_NORMAL) {
+                       sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
 
 #ifdef __INSTANCING__
-               if(instanced)
-                       object_normal_transform(kg, sd, &sd->N);
+                       if(instanced)
+                               object_normal_transform(kg, sd, &sd->N);
 #endif
-       }
+               }
 
+               /* dPdu/dPdv */
 #ifdef __DPDU__
-       /* dPdu/dPdv */
-#ifdef __HAIR__
-       if(sd->prim == ~0 || sd->segment != ~0) {
-               sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
-               sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
-       }
-#else
-       if(sd->prim == ~0) {
-               sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
-               sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
-       }
-#endif
-       else {
                triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
 
 #ifdef __INSTANCING__
@@ -319,9 +290,15 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
                        object_dir_transform(kg, sd, &sd->dPdu);
                        object_dir_transform(kg, sd, &sd->dPdv);
                }
+#endif
 #endif
        }
+       else {
+#ifdef __DPDU__
+               sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+               sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
 #endif
+       }
 
        /* backfacing test */
        if(sd->prim != ~0) {
@@ -362,7 +339,7 @@ ccl_device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
 
        /* watch out: no instance transform currently */
 
-       shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0, ~0);
+       shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0);
 }
 
 /* ShaderData setup from ray into background */
@@ -429,9 +406,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s
        sd->object = ~0; /* todo: fill this for texture coordinates */
 #endif
        sd->prim = ~0;
-#ifdef __HAIR__
-       sd->segment = ~0;
-#endif
+       sd->type = PRIMITIVE_NONE;
 
 #ifdef __UV__
        sd->u = 0.0f;
@@ -1146,7 +1121,7 @@ ccl_device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect
        int shader = 0;
 
 #ifdef __HAIR__
-       if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
+       if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
 #endif
                float4 Ns = kernel_tex_fetch(__tri_normal, prim);
                shader = __float_as_int(Ns.w);
index f06fa119cfc5c551881d313eb127926c3c9cf849..c8734d67c3bb90deca33a7a389000442428f6790 100644 (file)
@@ -25,7 +25,7 @@
 /* bvh */
 KERNEL_TEX(float4, texture_float4, __bvh_nodes)
 KERNEL_TEX(float4, texture_float4, __tri_woop)
-KERNEL_TEX(uint, texture_uint, __prim_segment)
+KERNEL_TEX(uint, texture_uint, __prim_type)
 KERNEL_TEX(uint, texture_uint, __prim_visibility)
 KERNEL_TEX(uint, texture_uint, __prim_index)
 KERNEL_TEX(uint, texture_uint, __prim_object)
index 70fafdfec9229a2aefceb5ef557bb09c83c41d39..b260a3d11ac1218718a0b94a61cc9a95bc8244fa 100644 (file)
@@ -420,9 +420,27 @@ typedef struct Intersection {
        float t, u, v;
        int prim;
        int object;
-       int segment;
+       int type;
 } Intersection;
 
+/* Primitives */
+
+typedef enum PrimitiveType {
+       PRIMITIVE_NONE = 0,
+       PRIMITIVE_TRIANGLE = 1,
+       PRIMITIVE_MOTION_TRIANGLE = 2,
+       PRIMITIVE_CURVE = 4,
+       PRIMITIVE_MOTION_CURVE = 8,
+
+       PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE|PRIMITIVE_MOTION_TRIANGLE),
+       PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE|PRIMITIVE_MOTION_CURVE),
+       PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE|PRIMITIVE_MOTION_CURVE),
+       PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE|PRIMITIVE_ALL_CURVE)
+} PrimitiveType;
+
+#define PRIMITIVE_PACK_SEGMENT(type, segment) ((segment << 16) | type)
+#define PRIMITIVE_UNPACK_SEGMENT(type) (type >> 16)
+
 /* Attributes */
 
 #define ATTR_PRIM_TYPES                2
@@ -565,13 +583,9 @@ typedef struct ShaderData {
        /* primitive id if there is one, ~0 otherwise */
        int prim;
 
-#ifdef __HAIR__
-       /* for curves, segment number in curve, ~0 for triangles */
-       int segment;
-       /* variables for minimum hair width using transparency bsdf */
-       /*float curve_transparency; */
-       /*float curve_radius; */
-#endif
+       /* combined type and curve segment for hair */
+       int type;
+
        /* parametric coordinates
         * - barycentric weights for triangles */
        float u, v;
index a25d2fe03b53feab991b2d4f24b27a15f5199fa8..6768114e5fd3fae49c488b833e43dfbd332bb59d 100644 (file)
@@ -643,7 +643,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
        }
        else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices)
 #ifdef __HAIR__
-                    && sd->segment == ~0) {
+                    && sd->type & PRIMITIVE_ALL_TRIANGLE) {
 #else
                ) {
 #endif
@@ -669,7 +669,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
 #ifdef __HAIR__
        /* Hair Attributes */
        else if (name == u_is_curve) {
-               float f = (sd->segment != ~0);
+               float f = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
                return set_attribute_float(f, type, derivatives, val);
        }
        else if (name == u_curve_thickness) {
@@ -732,7 +732,8 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
 {
        ShaderData *sd = (ShaderData *)renderstate;
        KernelGlobals *kg = sd->osl_globals;
-       int object, prim, segment;
+       bool is_curve;
+       int object, prim;
 
        /* lookup of attribute on another object */
        if (object_name != u_empty) {
@@ -743,23 +744,19 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
 
                object = it->second;
                prim = ~0;
-               segment = ~0;
+               is_curve = false;
        }
        else {
                object = sd->object;
                prim = sd->prim;
-#ifdef __HAIR__
-               segment = sd->segment;
-#else
-               segment = ~0;
-#endif
+               is_curve = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
 
                if (object == ~0)
                        return get_background_attribute(kg, sd, name, type, derivatives, val);
        }
 
        /* find attribute on object */
-       object = object*ATTR_PRIM_TYPES + (segment != ~0);
+       object = object*ATTR_PRIM_TYPES + (is_curve == true);
        OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
        OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
 
index 34d9ebefdb35dd7f4c8cdba08996445faae99518..b5842d1013e6aaccac474d1a3308882a7c63e914 100644 (file)
@@ -536,7 +536,7 @@ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id,
        /* for OSL, a hash map is used to lookup the attribute by name. */
        int object = sd->object*ATTR_PRIM_TYPES;
 #ifdef __HAIR__
-       if(sd->segment != ~0) object += ATTR_PRIM_CURVE;
+       if(sd->type & PRIMITIVE_ALL_CURVE) object += ATTR_PRIM_CURVE;
 #endif
 
        OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
index 4c53bfd74fa6e3bfd889a8ef8bd0c940a926c3df..aae52ec3d84ab58a85f81d919386c7d37b945d63 100644 (file)
@@ -27,7 +27,7 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
                uint id = node.y;
                uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
 #ifdef __HAIR__
-               attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+               attr_offset = (sd->type & PRIMITIVE_ALL_TRIANGLE)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
 #endif
                uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
                
index 2813e38d8f78bd35a52f5194e8cdae4f6af3fd22..49d99ead03e69c078e772b41f482214bac21457a 100644 (file)
@@ -364,7 +364,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
                case CLOSURE_BSDF_HAIR_REFLECTION_ID:
                case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
                        
-                       if(sd->flag & SD_BACKFACING && sd->segment != ~0) {
+                       if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) {
                                ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
                                if(sc) {
                                        sc->weight = make_float3(1.0f,1.0f,1.0f);
@@ -381,7 +381,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
                                        sc->data0 = param1;
                                        sc->data1 = param2;
                                        sc->offset = -stack_load_float(stack, data_node.z);
-                                       if(sd->segment == ~0) {
+                                       if(sd->type & PRIMITIVE_ALL_CURVE) {
                                                sc->T = normalize(sd->dPdv);
                                                sc->offset = 0.0f;
                                        }
index ad0cacb027a3db54b26b3a0037401cf6ab5226fb..1ed6a4b1916962447147f58a7430848f051013e7 100644 (file)
@@ -153,7 +153,7 @@ ccl_device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *sta
 
        switch(type) {
                case NODE_INFO_CURVE_IS_STRAND: {
-                       data = (sd->segment != ~0);
+                       data = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
                        stack_store_float(stack, out_offset, data);
                        break;
                }
index e560e6303ccff02579f3f5696f95fb4a84a9eb86..a20dcfa3fae0cab7d85236059eb4ff94a43538fc 100644 (file)
@@ -45,7 +45,7 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta
 
        /* Calculate wireframe */
 #ifdef __HAIR__
-       if (sd->prim != ~0 && sd->segment == ~0) {
+       if (sd->prim != ~0 && sd->type & PRIMITIVE_ALL_TRIANGLE) {
 #else
        if (sd->prim != ~0) {
 #endif
index 1c92eb584c1e6c5a5afbd4033391a217db4a3fdd..717ebb42f5cb4d0df217e73df68b87fcc4c7b7a4 100644 (file)
@@ -873,9 +873,9 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
                dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size());
                device->tex_alloc("__tri_woop", dscene->tri_woop);
        }
-       if(pack.prim_segment.size()) {
-               dscene->prim_segment.reference((uint*)&pack.prim_segment[0], pack.prim_segment.size());
-               device->tex_alloc("__prim_segment", dscene->prim_segment);
+       if(pack.prim_type.size()) {
+               dscene->prim_type.reference((uint*)&pack.prim_type[0], pack.prim_type.size());
+               device->tex_alloc("__prim_type", dscene->prim_type);
        }
        if(pack.prim_visibility.size()) {
                dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
@@ -986,7 +986,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
        device->tex_free(dscene->bvh_nodes);
        device->tex_free(dscene->object_node);
        device->tex_free(dscene->tri_woop);
-       device->tex_free(dscene->prim_segment);
+       device->tex_free(dscene->prim_type);
        device->tex_free(dscene->prim_visibility);
        device->tex_free(dscene->prim_index);
        device->tex_free(dscene->prim_object);
@@ -1003,7 +1003,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
        dscene->bvh_nodes.clear();
        dscene->object_node.clear();
        dscene->tri_woop.clear();
-       dscene->prim_segment.clear();
+       dscene->prim_type.clear();
        dscene->prim_visibility.clear();
        dscene->prim_index.clear();
        dscene->prim_object.clear();
index 2c22319253650a1400b7d1026dde24053648c459..b6a4d6c04362d3969a829bb66fa1ad72e4bbc21f 100644 (file)
@@ -60,7 +60,7 @@ public:
        device_vector<float4> bvh_nodes;
        device_vector<uint> object_node;
        device_vector<float4> tri_woop;
-       device_vector<uint> prim_segment;
+       device_vector<uint> prim_type;
        device_vector<uint> prim_visibility;
        device_vector<uint> prim_index;
        device_vector<uint> prim_object;