Cycles Hair: refactoring to store curves with the index of the first key and the
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 3 Jan 2013 12:09:09 +0000 (12:09 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 3 Jan 2013 12:09:09 +0000 (12:09 +0000)
number of keys in the curve, rather than curve segments with the indices of two
keys. ShaderData.segment now stores the segment number in the curve.

26 files changed:
intern/cycles/blender/blender_curves.cpp
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/kernel_bvh.h
intern/cycles/kernel/kernel_curve.h
intern/cycles/kernel/kernel_emission.h
intern/cycles/kernel/kernel_light.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_geometry.h
intern/cycles/render/attribute.cpp
intern/cycles/render/light.cpp
intern/cycles/render/mesh.cpp
intern/cycles/render/mesh.h
intern/cycles/render/object.cpp
intern/cycles/render/scene.h

index 61628aae53513e669720dd189af88ac6d7964e26..2e9a32f15f2fefe282ccdca682473e19ef40d95c 100644 (file)
@@ -652,11 +652,10 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter
 
 void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments)
 {
-       int cks = 0;
-       int curs = 0;
-       int segs = 0;
+       int num_keys = 0;
+       int num_curves = 0;
 
-       if(!(mesh->curve_segments.empty() && mesh->curve_keys.empty()))
+       if(!(mesh->curves.empty() && mesh->curve_keys.empty()))
                return;
 
        Attribute *attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
@@ -672,6 +671,8 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
                        if(CData->curve_keynum[curve] <= 1)
                                continue;
 
+                       size_t num_curve_keys = 0;
+
                        for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
 
                                int subv = 1;
@@ -696,26 +697,23 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
                                        mesh->add_curve_key(ickey_loc, radius);
                                        attr_intercept->add(time);
 
-                                       if(subv != 0) {
-                                               attr_uv->add(CData->curve_uv[curve]);
-                                               mesh->add_curve_segment(cks - 1, cks, CData->psys_shader[sys], curs);
-                                               segs++;
-                                       }
-
-                                       cks++;
+                                       num_curve_keys++;
                                }
                        }
 
-                       curs++;
+                       mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]);
+                       attr_uv->add(CData->curve_uv[curve]);
 
+                       num_keys += num_curve_keys;
+                       num_curves++;
                }
        }
 
        /* check allocation*/
-       if((mesh->curve_keys.size() !=  cks) || (mesh->curve_segments.size() !=  segs)) {
+       if((mesh->curve_keys.size() !=  num_keys) || (mesh->curves.size() !=  num_curves)) {
                /* allocation failed -> clear data */
                mesh->curve_keys.clear();
-               mesh->curve_segments.clear();
+               mesh->curves.clear();
                mesh->curve_attributes.clear();
        }
 }
@@ -824,7 +822,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
 {
        /* Clear stored curve data */
        mesh->curve_keys.clear();
-       mesh->curve_segments.clear();
+       mesh->curves.clear();
        mesh->curve_attributes.clear();
 
        /* obtain general settings */
index 0b43704b7b85e509c5a1257a13b894d7ff5f38f1..412b44031e63e664d89e113b95fadf4eb61d3da6 100644 (file)
@@ -76,7 +76,7 @@ bool BVH::cache_read(CacheData& key)
                key.add(ob->mesh->verts);
                key.add(ob->mesh->triangles);
                key.add(ob->mesh->curve_keys);
-               key.add(ob->mesh->curve_segments);
+               key.add(ob->mesh->curves);
                key.add(&ob->bounds, sizeof(ob->bounds));
                key.add(&ob->visibility, sizeof(ob->visibility));
                key.add(&ob->mesh->transform_applied, sizeof(bool));
@@ -93,7 +93,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_type);
+               value.read(pack.prim_segment);
                value.read(pack.prim_visibility);
                value.read(pack.prim_index);
                value.read(pack.prim_object);
@@ -115,7 +115,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_type);
+       value.add(pack.prim_segment);
        value.add(pack.prim_visibility);
        value.add(pack.prim_index);
        value.add(pack.prim_object);
@@ -161,11 +161,11 @@ void BVH::build(Progress& progress)
        }
 
        /* build nodes */
-       vector<int> prim_type;
+       vector<int> prim_segment;
        vector<int> prim_index;
        vector<int> prim_object;
 
-       BVHBuild bvh_build(objects, prim_type, prim_index, prim_object, params, progress);
+       BVHBuild bvh_build(objects, prim_segment, prim_index, prim_object, params, progress);
        BVHNode *root = bvh_build.run();
 
        if(progress.get_cancel()) {
@@ -174,7 +174,7 @@ void BVH::build(Progress& progress)
        }
 
        /* todo: get rid of this copy */
-       pack.prim_type = prim_type;
+       pack.prim_segment = prim_segment;
        pack.prim_index = prim_index;
        pack.prim_object = prim_object;
 
@@ -271,13 +271,16 @@ void BVH::pack_triangle(int idx, float4 woop[3])
 
 /* Curves*/
 
-void BVH::pack_curve_seg(int idx, float4 woop[3])
+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];
-       float3 v0 = mesh->curve_keys[mesh->curve_segments[tidx].v[0]].co;
-       float3 v1 = mesh->curve_keys[mesh->curve_segments[tidx].v[1]].co;
+       int segment = pack.prim_segment[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;
+       float3 v1 = mesh->curve_keys[k1].co;
 
        float3 d0 = v1 - v0;
        float l =  len(d0);
@@ -289,19 +292,19 @@ void BVH::pack_curve_seg(int idx, float4 woop[3])
        *       nextkey, flags/tip?,    0, 0);
        */
        Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
+       float3 tg0 = make_float3(1.0f, 0.0f, 0.0f);
        float3 tg1 = make_float3(1.0f, 0.0f, 0.0f);
-       float3 tg2 = make_float3(1.0f, 0.0f, 0.0f);
 
        if(attr_tangent) {
                const float3 *data_tangent = attr_tangent->data_float3();
 
-               tg1 = data_tangent[mesh->curve_segments[tidx].v[0]];
-               tg2 = data_tangent[mesh->curve_segments[tidx].v[1]];
+               tg0 = data_tangent[k0];
+               tg1 = data_tangent[k1];
        }
        
        Transform tfm = make_transform(
-               tg1.x, tg1.y, tg1.z, l,
-               tg2.x, tg2.y, tg2.z, 0,
+               tg0.x, tg0.y, tg0.z, l,
+               tg1.x, tg1.y, tg1.z, 0,
                0, 0, 0, 0,
                0, 0, 0, 1);
 
@@ -325,8 +328,8 @@ void BVH::pack_primitives()
                if(pack.prim_index[i] != -1) {
                        float4 woop[3];
 
-                       if(pack.prim_type[i])
-                               pack_curve_seg(i, woop);
+                       if(pack.prim_segment[i] != ~0)
+                               pack_curve_segment(i, woop);
                        else
                                pack_triangle(i, woop);
                        
@@ -353,8 +356,8 @@ 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_type[i])
-                               pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curveseg_offset;
+                       if(pack.prim_segment[i] != ~0)
+                               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;
                }
@@ -395,7 +398,7 @@ void BVH::pack_instances(size_t nodes_size)
        mesh_map.clear();
 
        pack.prim_index.resize(prim_index_size);
-       pack.prim_type.resize(prim_index_size);
+       pack.prim_segment.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);
@@ -403,7 +406,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_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
+       int *pack_prim_segment = (pack.prim_segment.size())? &pack.prim_segment[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;
@@ -434,7 +437,7 @@ void BVH::pack_instances(size_t nodes_size)
 
                int noffset = nodes_offset/nsize;
                int mesh_tri_offset = mesh->tri_offset;
-               int mesh_curve_offset = mesh->curveseg_offset;
+               int mesh_curve_offset = mesh->curve_offset;
 
                /* fill in node indexes for instances */
                if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0])
@@ -448,16 +451,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_type = &bvh->pack.prim_type[0];
+                       int *bvh_prim_segment = &bvh->pack.prim_segment[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_type[i])
+                               if(bvh->pack.prim_segment[i] != ~0)
                                        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_type[pack_prim_index_offset] = bvh_prim_type[i];
+                               pack_prim_segment[pack_prim_index_offset] = bvh_prim_segment[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++;
@@ -622,13 +625,14 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
                                /* primitives */
                                const Mesh *mesh = ob->mesh;
 
-                               if(pack.prim_type[prim]) {
-                                       /* strands */
-                                       int str_offset = (params.top_level)? mesh->curveseg_offset: 0;
-                                       const int *hidx = mesh->curve_segments[pidx - str_offset].v;
+                               if(pack.prim_segment[prim] != ~0) {
+                                       /* 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 k1 = k0 + 1;
 
-                                       bbox.grow(mesh->curve_keys[hidx[0]].co, mesh->curve_keys[hidx[0]].radius);
-                                       bbox.grow(mesh->curve_keys[hidx[1]].co, mesh->curve_keys[hidx[1]].radius);
+                                       bbox.grow(mesh->curve_keys[k0].co, mesh->curve_keys[k0].radius);
+                                       bbox.grow(mesh->curve_keys[k1].co, mesh->curve_keys[k1].radius);
                                }
                                else {
                                        /* triangles */
index d81bb312148aceeb98a86f2ee6a3a477950cb83a..00c146143b84b8acd64ee827520441a0031e9256 100644 (file)
@@ -53,7 +53,7 @@ struct PackedBVH {
        /* 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_type;
+       array<int> prim_segment;
        /* visibility visibilitys for primitives */
        array<uint> prim_visibility;
        /* mapping from BVH primitive index to true primitive index, as primitives
@@ -106,7 +106,7 @@ protected:
        /* triangles and strands*/
        void pack_primitives();
        void pack_triangle(int idx, float4 woop[3]);
-       void pack_curve_seg(int idx, float4 woop[3]);
+       void pack_curve_segment(int idx, float4 woop[3]);
 
        /* merge instance BVH's */
        void pack_instances(size_t nodes_size);
index 665c783b2d8a8e737ff435cb865fa8da6b7c803c..38fb1a15a13b755c6b841609056706496a55a5b9 100644 (file)
@@ -48,10 +48,10 @@ public:
 /* Constructor / Destructor */
 
 BVHBuild::BVHBuild(const vector<Object*>& objects_,
-       vector<int>& prim_type_, vector<int>& prim_index_, vector<int>& prim_object_,
+       vector<int>& prim_segment_, vector<int>& prim_index_, vector<int>& prim_object_,
        const BVHParams& params_, Progress& progress_)
 : objects(objects_),
-  prim_type(prim_type_),
+  prim_segment(prim_segment_),
   prim_index(prim_index_),
   prim_object(prim_object_),
   params(params_),
@@ -74,30 +74,34 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
                BoundBox bounds = BoundBox::empty;
 
                for(int k = 0; k < 3; k++) {
-                       float3 pt = mesh->verts[t.v[k]];
-                       bounds.grow(pt);
+                       float3 co = mesh->verts[t.v[k]];
+                       bounds.grow(co);
                }
 
                if(bounds.valid()) {
-                       references.push_back(BVHReference(bounds, j, i, false));
+                       references.push_back(BVHReference(bounds, j, i, ~0));
                        root.grow(bounds);
                        center.grow(bounds.center2());
                }
        }
 
-       for(uint j = 0; j < mesh->curve_segments.size(); j++) {
-               Mesh::CurveSegment s = mesh->curve_segments[j];
-               BoundBox bounds = BoundBox::empty;
+       for(uint j = 0; j < mesh->curves.size(); j++) {
+               Mesh::Curve curve = mesh->curves[j];
 
-               for(int k = 0; k < 2; k++) {
-                       float3 pt = mesh->curve_keys[s.v[k]].co;
-                       bounds.grow(pt, mesh->curve_keys[s.v[k]].radius);
-               }
+               for(int k = 0; k < curve.num_keys - 1; k++) {
+                       BoundBox bounds = BoundBox::empty;
 
-               if(bounds.valid()) {
-                       references.push_back(BVHReference(bounds, j, i, true));
-                       root.grow(bounds);
-                       center.grow(bounds.center2());
+                       float3 co0 = mesh->curve_keys[curve.first_key + k].co;
+                       float3 co1 = mesh->curve_keys[curve.first_key + k + 1].co;
+
+                       bounds.grow(co0, mesh->curve_keys[curve.first_key + k].radius);
+                       bounds.grow(co1, mesh->curve_keys[curve.first_key + k + 1].radius);
+
+                       if(bounds.valid()) {
+                               references.push_back(BVHReference(bounds, j, i, k));
+                               root.grow(bounds);
+                               center.grow(bounds.center2());
+                       }
                }
        }
 }
@@ -109,6 +113,16 @@ void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob
        center.grow(ob->bounds.center2());
 }
 
+static size_t count_curve_segments(Mesh *mesh)
+{
+       size_t num = 0, num_curves = mesh->curves.size();
+
+       for(size_t i = 0; i < num_curves; i++)
+               num += mesh->curves[i].num_keys - 1;
+       
+       return num;
+}
+
 void BVHBuild::add_references(BVHRange& root)
 {
        /* reserve space for references */
@@ -118,14 +132,14 @@ void BVHBuild::add_references(BVHRange& root)
                if(params.top_level) {
                        if(ob->mesh->transform_applied) {
                                num_alloc_references += ob->mesh->triangles.size();
-                               num_alloc_references += ob->mesh->curve_segments.size();
+                               num_alloc_references += count_curve_segments(ob->mesh);
                        }
                        else
                                num_alloc_references++;
                }
                else {
                        num_alloc_references += ob->mesh->triangles.size();
-                       num_alloc_references += ob->mesh->curve_segments.size();
+                       num_alloc_references += count_curve_segments(ob->mesh);
                }
        }
 
@@ -183,7 +197,7 @@ BVHNode* BVHBuild::run()
        progress_total = references.size();
        progress_original_total = progress_total;
 
-       prim_type.resize(references.size());
+       prim_segment.resize(references.size());
        prim_index.resize(references.size());
        prim_object.resize(references.size());
 
@@ -341,12 +355,12 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
                if(start == prim_index.size()) {
                        assert(params.use_spatial_split);
 
-                       prim_type.push_back(ref->prim_type());
+                       prim_segment.push_back(ref->prim_segment());
                        prim_index.push_back(ref->prim_index());
                        prim_object.push_back(ref->prim_object());
                }
                else {
-                       prim_type[start] = ref->prim_type();
+                       prim_segment[start] = ref->prim_segment();
                        prim_index[start] = ref->prim_index();
                        prim_object[start] = ref->prim_object();
                }
@@ -369,7 +383,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
 
 BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
 {
-       vector<int>& p_type = prim_type;
+       vector<int>& p_segment = prim_segment;
        vector<int>& p_index = prim_index;
        vector<int>& p_object = prim_object;
        BoundBox bounds = BoundBox::empty;
@@ -383,12 +397,12 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
                        if(range.start() + num == prim_index.size()) {
                                assert(params.use_spatial_split);
 
-                               p_type.push_back(ref.prim_type());
+                               p_segment.push_back(ref.prim_segment());
                                p_index.push_back(ref.prim_index());
                                p_object.push_back(ref.prim_object());
                        }
                        else {
-                               p_type[range.start() + num] = ref.prim_type();
+                               p_segment[range.start() + num] = ref.prim_segment();
                                p_index[range.start() + num] = ref.prim_index();
                                p_object[range.start() + num] = ref.prim_object();
                        }
index ba10eb494126c51f8a842acba868b560630d3543..3df4da1739a2902440176e9fd74680ee9426f49b 100644 (file)
@@ -44,7 +44,7 @@ public:
        /* Constructor/Destructor */
        BVHBuild(
                const vector<Object*>& objects,
-               vector<int>& prim_type,
+               vector<int>& prim_segment,
                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_type;
+       vector<int>& prim_segment;
        vector<int>& prim_index;
        vector<int>& prim_object;
 
index 7a1555ae5483396e106aefc35708963c8739fda4..f7bc79f71e609ee339b9c73a2b6002ebde3e08de 100644 (file)
@@ -98,22 +98,22 @@ class BVHReference
 public:
        __forceinline BVHReference() {}
 
-       __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_type)
+       __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_segment)
        : rbounds(bounds_)
        {
                rbounds.min.w = __int_as_float(prim_index_);
                rbounds.max.w = __int_as_float(prim_object_);
-               type = prim_type;
+               segment = prim_segment;
        }
 
        __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_type() const { return type; }
+       __forceinline int prim_segment() const { return segment; }
 
 protected:
        BoundBox rbounds;
-       uint type;
+       uint segment;
 };
 
 /* BVH Range
index 9a8961c8b15045208cc991bf98db47c2e6f6f432..91994be5b968f4ab0b76ccd139a322ee39f874c7 100644 (file)
@@ -43,8 +43,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_type() < rb.prim_type()) return true;
-               else if(ra.prim_type() > rb.prim_type()) return false;
+               else if(ra.prim_segment() < rb.prim_segment()) return true;
+               else if(ra.prim_segment() > rb.prim_segment()) return false;
 
                return false;
        }
index 67fdfd77657f5820c52b7c664f20d014ddc2bdd8..03ff69d7b6dcba810d47067f014ffcd7a839b0e5 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_type()) {
+       if (ref.prim_segment() == ~0) {
                const int *inds = mesh->triangles[ref.prim_index()].v;
                const float3 *verts = &mesh->verts[0];
                const float3* v1 = &verts[inds[2]];
@@ -281,11 +281,11 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
                }
        }
        else {
-               /* Strand split: NOTE - Currently ignores strand width and needs to be fixed.*/
-
-               const int *inds = mesh->curve_segments[ref.prim_index()].v;
-               const float3* v0 = &mesh->curve_keys[inds[0]].co;
-               const float3* v1 = &mesh->curve_keys[inds[1]].co;
+               /* 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 k1 = k0 + 1;
+               const float3* v0 = &mesh->curve_keys[k0].co;
+               const float3* v1 = &mesh->curve_keys[k1].co;
 
                float v0p = (*v0)[dim];
                float v1p = (*v1)[dim];
@@ -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_type());
-       right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
+       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());
 }
 
 CCL_NAMESPACE_END
index d32287f91e836e7490398e86f80af9285d2aacd9..c811d83ad78811b89921fb4cabcb8c79cd3b9c3d 100644 (file)
@@ -207,22 +207,22 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise
 
 #ifdef __HAIR__
 __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
-       float3 P, float3 idir, uint visibility, int object, int triAddr)
+       float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment)
 {
        /* curve Intersection check */
        
        int flags = kernel_data.curve_kernel_data.curveflags;
 
-       int prim = kernel_tex_fetch(__prim_index, triAddr);
-       float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+       int prim = kernel_tex_fetch(__prim_index, curveAddr);
+       float4 v00 = kernel_tex_fetch(__curves, prim);
 
-       int v1 = __float_as_int(v00.x);
-       int v2 = __float_as_int(v00.y);
+       int k0 = __float_as_int(v00.x) + segment;
+       int k1 = k0 + 1;
 
-       float4 P1 = kernel_tex_fetch(__curve_keys, v1);
-       float4 P2 = kernel_tex_fetch(__curve_keys, v2);
+       float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+       float4 P2 = kernel_tex_fetch(__curve_keys, k1);
 
-       float l = v00.w;
+       float l = len(P2 - P1); // XXX slower
        float r1 = P1.w;
        float r2 = P2.w;
        float mr = max(r1,r2);
@@ -329,14 +329,15 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
                                        return;
                        }*/
 
-       #ifdef __VISIBILITY_FLAG__
+#ifdef __VISIBILITY_FLAG__
                        /* visibility flag test. we do it here under the assumption
                         * that most triangles are culled by node flags */
-                       if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
-       #endif
+                       if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+#endif
                        {
                                /* record intersection */
-                               isect->prim = triAddr;
+                               isect->prim = curveAddr;
+                               isect->segment = segment;
                                isect->object = object;
                                isect->u = z/l;
                                isect->v = td/(4*a*a);
@@ -430,8 +431,9 @@ __device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint
                                        while(primAddr < primAddr2) {
                                                /* intersect ray against primitive */
 #ifdef __HAIR__
-                                               if(kernel_tex_fetch(__prim_type, primAddr))
-                                                       bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr);
+                                               uint segment = kernel_tex_fetch(__prim_segment, primAddr);
+                                               if(segment != ~0)
+                                                       bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
                                                else
 #endif
                                                        bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
@@ -555,8 +557,9 @@ __device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, con
                                        while(primAddr < primAddr2) {
                                                /* intersect ray against primitive */
 #ifdef __HAIR__
-                                               if(kernel_tex_fetch(__prim_type, primAddr))
-                                                       bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr);
+                                               uint segment = kernel_tex_fetch(__prim_segment, primAddr);
+                                               if(segment != ~0)
+                                                       bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
                                                else
 #endif
                                                        bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
@@ -720,14 +723,14 @@ __device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const
        }
 
        int prim = kernel_tex_fetch(__prim_index, isect->prim);
-       float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+       float4 v00 = kernel_tex_fetch(__curves, prim);
 
-       int v1 = __float_as_int(v00.x);
-       int v2 = __float_as_int(v00.y);
+       int k0 = __float_as_int(v00.x) + isect->segment;
+       int k1 = k0 + 1;
 
-       float4 P1 = kernel_tex_fetch(__curve_keys, v1);
-       float4 P2 = kernel_tex_fetch(__curve_keys, v2);
-       float l = v00.w;
+       float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+       float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+       float l = len(P2 - P1); // XXX slower
        float r1 = P1.w;
        float r2 = P2.w;
        float3 tg = float4_to_float3(P2 - P1) / l;
index fef1a48644d5b49d79d8a9c77bb23fa7829acd14..e065717888ca9e51ad8ef28ecb2c21c283ca790d 100644 (file)
@@ -24,19 +24,21 @@ CCL_NAMESPACE_BEGIN
 
 __device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
 {
-       if(elem == ATTR_ELEMENT_CURVE_SEGMENT) {
+       if(elem == ATTR_ELEMENT_CURVE) {
 #ifdef __RAY_DIFFERENTIALS__
                if(dx) *dx = 0.0f;
                if(dy) *dy = 0.0f;
 #endif
 
-               return kernel_tex_fetch(__attributes_float, offset + sd->curve_seg);
+               return kernel_tex_fetch(__attributes_float, offset + sd->prim);
        }
        else if(elem == ATTR_ELEMENT_CURVE_KEY) {
-               float4 segment = kernel_tex_fetch(__curve_segments, sd->curve_seg);
+               float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+               int k0 = __float_as_int(curvedata.x) + sd->segment;
+               int k1 = k0 + 1;
 
-               float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(segment.x));
-               float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(segment.y));
+               float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
+               float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
 
 #ifdef __RAY_DIFFERENTIALS__
                if(dx) *dx = sd->du.dx*(f1 - f0);
@@ -57,7 +59,7 @@ __device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, At
 
 __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
 {
-       if(elem == ATTR_ELEMENT_CURVE_SEGMENT) {
+       if(elem == ATTR_ELEMENT_CURVE) {
                /* idea: we can't derive any useful differentials here, but for tiled
                 * mipmap image caching it would be useful to avoid reading the highest
                 * detail level always. maybe a derivative based on the hair density
@@ -67,13 +69,15 @@ __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd,
                if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
 #endif
 
-               return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->curve_seg));
+               return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
        }
        else if(elem == ATTR_ELEMENT_CURVE_KEY) {
-               float4 segment = kernel_tex_fetch(__curve_segments, sd->curve_seg);
+               float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+               int k0 = __float_as_int(curvedata.x) + sd->segment;
+               int k1 = k0 + 1;
 
-               float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(segment.x)));
-               float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(segment.y)));
+               float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
+               float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
 
 #ifdef __RAY_DIFFERENTIALS__
                if(dx) *dx = sd->du.dx*(f1 - f0);
@@ -96,19 +100,16 @@ __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd,
 
 __device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
 {
-       int prim = sd->curve_seg;
-       float u = sd->u;
        float r = 0.0f;
 
-       if(prim != -1) {
-               float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+       if(sd->segment != ~0) {
+               float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+               int k0 = __float_as_int(curvedata.x) + sd->segment;
+               int k1 = k0 + 1;
 
-               int v1 = __float_as_int(v00.x);
-               int v2 = __float_as_int(v00.y);
-
-               float4 P1 = kernel_tex_fetch(__curve_keys, v1);
-               float4 P2 = kernel_tex_fetch(__curve_keys, v2);
-               r = (P2.w - P1.w) * u + P1.w;
+               float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+               float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+               r = (P2.w - P1.w) * sd->u + P1.w;
        }
 
        return r*2.0f;
@@ -118,7 +119,7 @@ __device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
 {      
        float3 tgN = make_float3(0.0f,0.0f,0.0f);
 
-       if(sd->curve_seg != ~0) {
+       if(sd->segment != ~0) {
                float normalmix = kernel_data.curve_kernel_data.normalmix;
 
                tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu)));
index adf7e8eca8215ed04ab373d5354f0462806f0b82..d5506ad1dd0de52b8c0f6274b6e4188ef3c8070a 100644 (file)
@@ -157,7 +157,7 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
        float3 L = shader_emissive_eval(kg, sd);
 
 #ifdef __HAIR__
-       if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->curve_seg == ~0)) {
+       if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->segment == ~0)) {
 #else
        if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
 #endif
index 09ee1f68e120b05fcad3893e88b1394b34907996..1561ddc9ddd8c92f0f4c394c84aa2d1ccf7d0235 100644 (file)
@@ -329,18 +329,20 @@ __device float triangle_light_pdf(KernelGlobals *kg,
 #ifdef __HAIR__
 /* Strand Light */
 
-__device void curve_seg_light_sample(KernelGlobals *kg, int prim, int object,
-       float randu, float randv, float time, LightSample *ls)
+__device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object,
+       int segment, float randu, float randv, float time, LightSample *ls)
 {
        /* this strand code needs completion */
-       float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+       float4 v00 = kernel_tex_fetch(__curves, prim);
+
+       int k0 = __float_as_int(v00.x) + segment;
+       int k1 = k0 + 1;
 
-       int v1 = __float_as_int(v00.x);
-       int v2 = __float_as_int(v00.y);
-       float l = v00.w;
+       float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+       float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+
+       float l = len(P2 - P1); // XXX slower
 
-       float4 P1 = kernel_tex_fetch(__curve_keys, v1);
-       float4 P2 = kernel_tex_fetch(__curve_keys, v2);
        float r1 = P1.w;
        float r2 = P2.w;
        float3 tg = float4_to_float3(P2 - P1) / l;
@@ -419,15 +421,15 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
        float4 l = kernel_tex_fetch(__light_distribution, index);
        int prim = __float_as_int(l.y);
 #ifdef __HAIR__
-/* currently use l.z to indicate is strand sample which isn't ideal */
-       bool is_curve = __float_as_int(l.z) == 0.0f;
+       int segment = __float_as_int(l.z);
 #endif
 
        if(prim >= 0) {
                int object = __float_as_int(l.w);
+
 #ifdef __HAIR__
-               if (is_curve)
-                       curve_seg_light_sample(kg, prim, object, randu, randv, time, ls);
+               if (segment != ~0)
+                       curve_segment_light_sample(kg, prim, object, segment, randu, randv, time, ls);
                else
 #endif
                        triangle_light_sample(kg, prim, object, randu, randv, time, ls);
index 2296017c6864f8e6242dfc340ac9d9b44eecb35a..7538b7107d031e90dcfa582cdeb6a5c7353843d3 100644 (file)
@@ -37,7 +37,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, A
        {
                /* for SVM, find attribute by unique id */
                uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
-               attr_offset = (sd->curve_seg == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+               attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
                uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
                
                while(attr_map.x != id) {
@@ -55,7 +55,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, A
 __device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
 {
 #ifdef __HAIR__
-       if(sd->curve_seg == ~0)
+       if(sd->segment == ~0)
 #endif
                return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
 #ifdef __HAIR__
@@ -67,7 +67,7 @@ __device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd
 __device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
 {
 #ifdef __HAIR__
-       if(sd->curve_seg == ~0)
+       if(sd->segment == ~0)
 #endif
                return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
 #ifdef __HAIR__
@@ -92,7 +92,7 @@ __device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
 __device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
 {
 #ifdef __HAIR__
-       if(sd->curve_seg != ~0)
+       if(sd->segment != ~0)
                return normalize(sd->dPdu);
 #endif
 
index 49bbc5a74abe8a41833d42b5b61f65d1da831a23..0a5a2ab54b0ffa8e864773f8190962ed54e34bdd 100644 (file)
@@ -69,25 +69,22 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
 #endif
 
        sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
-#ifdef __HAIR__
-       sd->curve_seg = ~0;
-#endif
        sd->ray_length = isect->t;
 
 #ifdef __HAIR__
-       if(kernel_tex_fetch(__prim_type, isect->prim)) {
+       if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
                /* Strand Shader setting*/
-               float4 CurSeg = kernel_tex_fetch(__curve_segments, sd->prim);
-               sd->shader = __float_as_int(CurSeg.z);
+               float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
 
-               sd->curve_seg = sd->prim;
-               sd->prim = isect->prim;
+               sd->shader = __float_as_int(curvedata.z);
+               sd->segment = isect->segment;
 
                float tcorr = isect->t;
                if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION) {
                        tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
                        sd->ray_length = tcorr;
                }
+
                sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
        }
        else {
@@ -97,6 +94,10 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
                float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
                sd->shader = __float_as_int(Ns.w);
 
+#ifdef __HAIR__
+               sd->segment = ~0;
+#endif
+
 #ifdef __UV__
                sd->u = isect->u;
                sd->v = isect->v;
@@ -107,7 +108,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
                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);
@@ -162,7 +162,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
 
 __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 curve = ~0)
+       int shader, int object, int prim, float u, float v, float t, float time, int segment = ~0)
 {
        /* vectors */
        sd->P = P;
@@ -171,7 +171,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        sd->I = I;
        sd->shader = shader;
 #ifdef __HAIR__
-       sd->curve_seg = curve;
+       sd->segment = segment;
 #endif
 
        /* primitive */
@@ -215,7 +215,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
 
        /* smooth normal */
 #ifdef __HAIR__
-       if(sd->shader & SHADER_SMOOTH_NORMAL && sd->curve_seg == ~0) {
+       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) {
@@ -231,7 +231,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
 #ifdef __DPDU__
        /* dPdu/dPdv */
 #ifdef __HAIR__
-       if(sd->prim == ~0 || sd->curve_seg != ~0) {
+       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);
        }
@@ -323,7 +323,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
 #endif
        sd->prim = ~0;
 #ifdef __HAIR__
-       sd->curve_seg = ~0;
+       sd->segment = ~0;
 #endif
 #ifdef __UV__
        sd->u = 0.0f;
@@ -781,14 +781,14 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
        int shader = 0;
 
 #ifdef __HAIR__
-       if(!kernel_tex_fetch(__prim_type, isect->prim)) {
+       if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
 #endif
                float4 Ns = kernel_tex_fetch(__tri_normal, prim);
                shader = __float_as_int(Ns.w);
 #ifdef __HAIR__
        }
        else {
-               float4 str = kernel_tex_fetch(__curve_segments, prim);
+               float4 str = kernel_tex_fetch(__curves, prim);
                shader = __float_as_int(str.z);
        }
 #endif
index 072df21a188724d62aa0c03b2d77df93288149d1..e27de95e7ab59d341833f4f0f80ee0a8c630d704 100644 (file)
@@ -27,7 +27,7 @@
 /* bvh */
 KERNEL_TEX(float4, texture_float4, __bvh_nodes)
 KERNEL_TEX(float4, texture_float4, __tri_woop)
-KERNEL_TEX(uint, texture_uint, __prim_type)
+KERNEL_TEX(uint, texture_uint, __prim_segment)
 KERNEL_TEX(uint, texture_uint, __prim_visibility)
 KERNEL_TEX(uint, texture_uint, __prim_index)
 KERNEL_TEX(uint, texture_uint, __prim_object)
@@ -44,7 +44,7 @@ KERNEL_TEX(float4, texture_float4, __tri_vindex)
 KERNEL_TEX(float4, texture_float4, __tri_verts)
 
 /* curves */
-KERNEL_TEX(float4, texture_float4, __curve_segments)
+KERNEL_TEX(float4, texture_float4, __curves)
 KERNEL_TEX(float4, texture_float4, __curve_keys)
 
 /* attributes */
index e80772bd4e240705c4173a53f8f3b038a980e9f1..2bd6b5859f371aaf83e0d82956a52d1f70a13889 100644 (file)
@@ -344,6 +344,7 @@ typedef struct Intersection {
        float t, u, v;
        int prim;
        int object;
+       int segment;
 } Intersection;
 
 /* Attributes */
@@ -357,7 +358,7 @@ typedef enum AttributeElement {
        ATTR_ELEMENT_FACE,
        ATTR_ELEMENT_VERTEX,
        ATTR_ELEMENT_CORNER,
-       ATTR_ELEMENT_CURVE_SEGMENT,
+       ATTR_ELEMENT_CURVE,
        ATTR_ELEMENT_CURVE_KEY
 } AttributeElement;
 
@@ -464,8 +465,8 @@ typedef struct ShaderData {
        int prim;
 
 #ifdef __HAIR__
-       /* strand id if there is one, -1 otherwise */
-       int curve_seg;
+       /* for curves, segment number in curve, ~0 for triangles */
+       int segment;
 #endif
        /* parametric coordinates
         * - barycentric weights for triangles */
index afa5211216b328843448f288a1460b8d7bce4daf..28742d56e3b8da09c372eae4f88be415c38fbbc2 100644 (file)
@@ -605,7 +605,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
                return set_attribute_int(3, type, derivatives, val);
        }
        else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices)
-                    && sd->curve_seg == ~0) {
+                    && sd->segment == ~0) {
                float3 P[3];
                triangle_vertices(kg, sd->prim, P);
 
@@ -625,7 +625,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
 #ifdef __HAIR__
        /* Hair Attributes */
        else if (name == u_is_curve) {
-               float f = !(sd->curve_seg == ~0);
+               float f = (sd->segment != ~0);
                return set_attribute_float(f, type, derivatives, val);
        }
        else if (name == u_curve_thickness) {
@@ -659,7 +659,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
 {
        KernelGlobals *kg = kernel_globals;
        ShaderData *sd = (ShaderData *)renderstate;
-       int object, prim, curve_seg;
+       int object, prim, segment;
 
        /* lookup of attribute on another object */
        if (object_name != u_empty || sd == NULL) {
@@ -670,19 +670,19 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
 
                object = it->second;
                prim = ~0;
-               curve_seg = ~0;
+               segment = ~0;
        }
        else {
                object = sd->object;
                prim = sd->prim;
-               curve_seg = sd->curve_seg;
+               segment = sd->segment;
 
                if (object == ~0)
                        return get_background_attribute(kg, sd, name, type, derivatives, val);
        }
 
        /* find attribute on object */
-       object = object*ATTR_PRIM_TYPES + (curve_seg != ~0);
+       object = object*ATTR_PRIM_TYPES + (segment != ~0);
        OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
        OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
 
index 18486eba114eb47634750050ddbc205ec0acef37..59e307bb40898c96b27914f0b5f0be43a3c34fd9 100644 (file)
@@ -457,7 +457,7 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_
 int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
 {
        /* for OSL, a hash map is used to lookup the attribute by name. */
-       int object = sd->object*ATTR_PRIM_TYPES + (sd->curve_seg != ~0);
+       int object = sd->object*ATTR_PRIM_TYPES + (sd->segment != ~0);
        OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
        ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
        OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
index f11b69138d1ef44ec63074901ee857e668b1163f..ea0a31610f1206693d07886fee60fccd7de92f20 100644 (file)
@@ -28,7 +28,7 @@ __device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
                /* find attribute by unique id */
                uint id = node.y;
                uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
-               attr_offset = (sd->curve_seg == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+               attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
                uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
                
                while(attr_map.x != id) {
index db8bbabe0ec907de3d1e360b854d8668c4a5d3a0..a04f4ea0fa776d83cea034311418fd047d6e9fdd 100644 (file)
@@ -155,7 +155,7 @@ __device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *stack
 
        switch(type) {
                case NODE_INFO_CURVE_IS_STRAND: {
-                       data = !(sd->curve_seg == ~0);
+                       data = (sd->segment != ~0);
                        stack_store_float(stack, out_offset, data);
                        break;
                }
index 758e4e5e8209abd80c52225740a9fb8ec1032eda..b6f6ba47fe84a8ec6d3cccc839364b7804bd4812 100644 (file)
@@ -80,7 +80,7 @@ size_t Attribute::element_size(int numverts, int numtris, int numcurves, int num
                return numtris;
        else if(element == ATTR_ELEMENT_CORNER)
                return numtris*3;
-       else if(element == ATTR_ELEMENT_CURVE_SEGMENT)
+       else if(element == ATTR_ELEMENT_CURVE)
                return numcurves;
        else if(element == ATTR_ELEMENT_CURVE_KEY)
                return numkeys;
@@ -176,7 +176,7 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme
        if(triangle_mesh)
                attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
        if(curve_mesh)
-               attr->reserve(0, 0, curve_mesh->curve_segments.size(), curve_mesh->curve_keys.size());
+               attr->reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
        
        return attr;
 }
@@ -239,9 +239,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
        }
        else if(curve_mesh) {
                if(std == ATTR_STD_UV)
-                       attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_SEGMENT);
+                       attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
                else if(std == ATTR_STD_GENERATED)
-                       attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_SEGMENT);
+                       attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
                else if(std == ATTR_STD_MOTION_PRE)
                        attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
                else if(std == ATTR_STD_MOTION_POST)
@@ -298,7 +298,7 @@ void AttributeSet::reserve()
                if(triangle_mesh)
                        attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
                if(curve_mesh)
-                       attr.reserve(0, 0, curve_mesh->curve_segments.size(), curve_mesh->curve_keys.size());
+                       attr.reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
        }
 }
 
index cab6008dd7c19de29f301661fd2249c05c91b18f..c8e3e94ec983ad4f112c4691e5da5ae59594e863 100644 (file)
@@ -171,13 +171,14 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
                                        num_triangles++;
                        }
 
-                       /* disabled for strands*/
-                       /*for(size_t i = 0; i < mesh->curve_segments.size(); i++) {
-                       *       Shader *shader = scene->shaders[mesh->curve_segments[i].shader];
-                       *
-                       *       if(shader->sample_as_light && shader->has_surface_emission)
-                       *               num_curve_segments++;
-                       }*/
+                       /* disabled for curves */
+#if 0
+                       foreach(Mesh::Curve& curve, mesh->curves) {
+                               Shader *shader = scene->shaders[curve.shader];
+
+                               if(shader->sample_as_light && shader->has_surface_emission)
+                                       num_curve_segments += curve.num_segments();
+#endif
                }
        }
 
@@ -225,7 +226,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
                                if(shader->sample_as_light && shader->has_surface_emission) {
                                        distribution[offset].x = totarea;
                                        distribution[offset].y = __int_as_float(i + mesh->tri_offset);
-                                       distribution[offset].z = 1.0f;
+                                       distribution[offset].z = __int_as_float(~0);
                                        distribution[offset].w = __int_as_float(object_id);
                                        offset++;
 
@@ -245,30 +246,38 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
                        }
 
                        /*sample as light disabled for strands*/
-                       /*for(size_t i = 0; i < mesh->curve_segments.size(); i++) {
-                       *       Shader *shader = scene->shaders[mesh->curve_segments[i].shader];
-                       *
-                       *       if(shader->sample_as_light && shader->has_surface_emission) {
-                       *               distribution[offset].x = totarea;
-                       *               distribution[offset].y = __int_as_float(i + mesh->curveseg_offset);
-                       *               distribution[offset].z = 0.0f;
-                       *               distribution[offset].w = __int_as_float(object_id);
-                       *               offset++;
-                       *
-                       *               Mesh::CurveSeg s = mesh->curve_segments[i];
-                       *               float3 p1 = mesh->curve_keys[s.v[0]].loc;
-                       *               float r1 = mesh->curve_keys[s.v[0]].radius;
-                       *               float3 p2 = mesh->curve_keys[s.v[1]].loc;
-                       *               float r2 = mesh->curve_keys[s.v[1]].radius;
-                       *
-                       *               if(!transform_applied) {
-                       *                       p1 = transform_point(&tfm, p1);
-                       *                       p2 = transform_point(&tfm, p2);
-                       *               }
-                       *
-                       *               totarea += M_PI_F * (r1 + r2) * len(p1 - p2);
-                       *       }
-                       }*/
+#if 0
+                       size_t i = 0;
+
+                       foreach(Mesh::Curve& curve, mesh->curves) {
+                               Shader *shader = scene->shaders[curve.shader];
+                               int first_key = curve.first_key;
+
+                               if(shader->sample_as_light && shader->has_surface_emission) {
+                                       for(int j = 0; j < curve.num_segments(); j++) {
+                                               distribution[offset].x = totarea;
+                                               distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code
+                                               distribution[offset].z = __int_as_float(j);
+                                               distribution[offset].w = __int_as_float(object_id);
+                                               offset++;
+                               
+                                               float3 p1 = mesh->curve_keys[first_key + j].loc;
+                                               float r1 = mesh->curve_keys[first_key + j].radius;
+                                               float3 p2 = mesh->curve_keys[first_key + j + 1].loc;
+                                               float r2 = mesh->curve_keys[first_key + j + 1].radius;
+                               
+                                               if(!transform_applied) {
+                                                       p1 = transform_point(&tfm, p1);
+                                                       p2 = transform_point(&tfm, p2);
+                                               }
+                               
+                                               totarea += M_PI_F * (r1 + r2) * len(p1 - p2);
+                                       }
+                               }
+
+                               i++;
+                       }
+#endif
                }
 
                if(progress.get_cancel()) return;
index 53cae53ef69478953030bc2d863932577d3ab30c..d4619dcff55f28c5889864b627aec26262965bd5 100644 (file)
@@ -51,7 +51,7 @@ Mesh::Mesh()
        tri_offset = 0;
        vert_offset = 0;
 
-       curveseg_offset = 0;
+       curve_offset = 0;
        curvekey_offset = 0;
 
        attributes.triangle_mesh = this;
@@ -71,7 +71,7 @@ void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys)
        shader.resize(numtris);
        smooth.resize(numtris);
        curve_keys.resize(numcurvekeys);
-       curve_segments.resize(numcurves);
+       curves.resize(numcurves);
 
        attributes.reserve();
        curve_attributes.reserve();
@@ -86,7 +86,7 @@ void Mesh::clear()
        smooth.clear();
 
        curve_keys.clear();
-       curve_segments.clear();
+       curves.clear();
 
        attributes.clear();
        curve_attributes.clear();
@@ -98,34 +98,33 @@ void Mesh::clear()
 
 void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
 {
-       Triangle t;
-       t.v[0] = v0;
-       t.v[1] = v1;
-       t.v[2] = v2;
+       Triangle tri;
+       tri.v[0] = v0;
+       tri.v[1] = v1;
+       tri.v[2] = v2;
 
-       triangles.push_back(t);
+       triangles.push_back(tri);
        shader.push_back(shader_);
        smooth.push_back(smooth_);
 }
 
 void Mesh::add_curve_key(float3 co, float radius)
 {
-       CurveKey ck;
-       ck.co = co;
-       ck.radius = radius;
+       CurveKey key;
+       key.co = co;
+       key.radius = radius;
 
-       curve_keys.push_back(ck);
+       curve_keys.push_back(key);
 }
 
-void Mesh::add_curve_segment(int v0, int v1, int shader, int curveid)
+void Mesh::add_curve(int first_key, int num_keys, int shader)
 {
-       CurveSegment s;
-       s.v[0] = v0;
-       s.v[1] = v1;
-       s.shader = shader;
-       s.curve = curveid;
+       Curve curve;
+       curve.first_key = first_key;
+       curve.num_keys = num_keys;
+       curve.shader = shader;
 
-       curve_segments.push_back(s);
+       curves.push_back(curve);
 }
 
 void Mesh::compute_bounds()
@@ -284,7 +283,7 @@ void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset)
        }
 }
 
-void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_keys, size_t curvekey_offset)
+void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
 {
        size_t curve_keys_size = curve_keys.size();
        CurveKey *keys_ptr = NULL;
@@ -302,25 +301,21 @@ void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_key
        }
 
        /* pack curve segments */
-       size_t curve_seg_num = curve_segments.size();
+       size_t curve_num = curves.size();
 
-       if(curve_seg_num) {
-               CurveSegment *curve_ptr = &curve_segments[0];
+       if(curve_num) {
+               Curve *curve_ptr = &curves[0];
                int shader_id = 0;
                
-               for(size_t i = 0; i < curve_seg_num; i++) {
-                       CurveSegment s = curve_ptr[i];
-                       shader_id = scene->shader_manager->get_shader_id(s.shader, this, false);
+               for(size_t i = 0; i < curve_num; i++) {
+                       Curve curve = curve_ptr[i];
+                       shader_id = scene->shader_manager->get_shader_id(curve.shader, this, false);
 
-                       float3 p1 = keys_ptr[s.v[0]].co;
-                       float3 p2 = keys_ptr[s.v[1]].co;
-                       float length = len(p2 - p1);
-
-                       curve_seg_keys[i] = make_float4(
-                               __int_as_float(s.v[0] + curvekey_offset),
-                               __int_as_float(s.v[1] + curvekey_offset),
+                       curve_data[i] = make_float4(
+                               __int_as_float(curve.first_key + curvekey_offset),
+                               __int_as_float(curve.num_keys),
                                __int_as_float(shader_id),
-                               length);
+                               0.0f);
                }
        }
 }
@@ -541,7 +536,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
 
                        index++;
 
-                       if(mesh->curve_segments.size()) {
+                       if(mesh->curves.size()) {
                                attr_map[index].x = id;
                                attr_map[index].y = req.curve_element;
                                attr_map[index].z = as_uint(req.curve_offset);
@@ -588,7 +583,7 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
                size_t size = mattr->element_size(
                        mesh->verts.size(),
                        mesh->triangles.size(),
-                       mesh->curve_segments.size(),
+                       mesh->curves.size(),
                        mesh->curve_keys.size());
 
                if(mattr->type == TypeDesc::TypeFloat) {
@@ -618,8 +613,8 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
                        offset -= mesh->tri_offset;
                else if(element == ATTR_ELEMENT_CORNER)
                        offset -= 3*mesh->tri_offset;
-               else if(element == ATTR_ELEMENT_CURVE_SEGMENT)
-                       offset -= mesh->curveseg_offset;
+               else if(element == ATTR_ELEMENT_CURVE)
+                       offset -= mesh->curve_offset;
                else if(element == ATTR_ELEMENT_CURVE_KEY)
                        offset -= mesh->curvekey_offset;
        }
@@ -713,20 +708,20 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
        size_t tri_size = 0;
 
        size_t curve_key_size = 0;
-       size_t curve_seg_keys = 0;
+       size_t curve_size = 0;
 
        foreach(Mesh *mesh, scene->meshes) {
                mesh->vert_offset = vert_size;
                mesh->tri_offset = tri_size;
 
                mesh->curvekey_offset = curve_key_size;
-               mesh->curveseg_offset = curve_seg_keys;
+               mesh->curve_offset = curve_size;
 
                vert_size += mesh->verts.size();
                tri_size += mesh->triangles.size();
 
                curve_key_size += mesh->curve_keys.size();
-               curve_seg_keys += mesh->curve_segments.size();
+               curve_size += mesh->curves.size();
        }
 
        if(tri_size != 0) {
@@ -754,19 +749,19 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
                device->tex_alloc("__tri_vindex", dscene->tri_vindex);
        }
 
-       if(curve_seg_keys != 0) {
+       if(curve_size != 0) {
                progress.set_status("Updating Mesh", "Copying Strands to device");
 
                float4 *curve_keys = dscene->curve_keys.resize(curve_key_size);
-               float4 *curve_segments = dscene->curve_segments.resize(curve_seg_keys);
+               float4 *curves = dscene->curves.resize(curve_size);
 
                foreach(Mesh *mesh, scene->meshes) {
-                       mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curve_segments[mesh->curveseg_offset], mesh->curvekey_offset);
+                       mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curves[mesh->curve_offset], mesh->curvekey_offset);
                        if(progress.get_cancel()) return;
                }
 
                device->tex_alloc("__curve_keys", dscene->curve_keys);
-               device->tex_alloc("__curve_segments", dscene->curve_segments);
+               device->tex_alloc("__curves", dscene->curves);
        }
 }
 
@@ -804,9 +799,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_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_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_visibility.size()) {
                dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
@@ -917,7 +912,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_type);
+       device->tex_free(dscene->prim_segment);
        device->tex_free(dscene->prim_visibility);
        device->tex_free(dscene->prim_index);
        device->tex_free(dscene->prim_object);
@@ -925,7 +920,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
        device->tex_free(dscene->tri_vnormal);
        device->tex_free(dscene->tri_vindex);
        device->tex_free(dscene->tri_verts);
-       device->tex_free(dscene->curve_segments);
+       device->tex_free(dscene->curves);
        device->tex_free(dscene->curve_keys);
        device->tex_free(dscene->attributes_map);
        device->tex_free(dscene->attributes_float);
@@ -934,7 +929,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
        dscene->bvh_nodes.clear();
        dscene->object_node.clear();
        dscene->tri_woop.clear();
-       dscene->prim_type.clear();
+       dscene->prim_segment.clear();
        dscene->prim_visibility.clear();
        dscene->prim_index.clear();
        dscene->prim_object.clear();
@@ -942,7 +937,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
        dscene->tri_vnormal.clear();
        dscene->tri_vindex.clear();
        dscene->tri_verts.clear();
-       dscene->curve_segments.clear();
+       dscene->curves.clear();
        dscene->curve_keys.clear();
        dscene->attributes_map.clear();
        dscene->attributes_float.clear();
index ca8c755671fca754e2b33cce17cfe39a5a1607c9..b83752ad8dfb4072fa6ec18ed032e0ceef4c1eac 100644 (file)
@@ -51,10 +51,13 @@ public:
        };
 
        /* Mesh Curve */
-       struct CurveSegment {
-               int v[2];
+       struct Curve {
+               int first_key;
+               int num_keys;
                uint shader;
-               int curve;
+               uint pad;
+
+               int num_segments() { return num_keys - 1; }
        };
 
        struct CurveKey {
@@ -78,7 +81,7 @@ public:
        vector<bool> smooth;
 
        vector<CurveKey> curve_keys;
-       vector<CurveSegment> curve_segments;
+       vector<Curve> curves;
 
        vector<uint> used_shaders;
        AttributeSet attributes;
@@ -98,7 +101,7 @@ public:
        size_t tri_offset;
        size_t vert_offset;
 
-       size_t curveseg_offset;
+       size_t curve_offset;
        size_t curvekey_offset;
 
        /* Functions */
@@ -109,7 +112,7 @@ public:
        void clear();
        void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
        void add_curve_key(float3 loc, float radius);
-       void add_curve_segment(int v0, int v1, int shader, int curveid);
+       void add_curve(int first_key, int num_keys, int shader);
 
        void compute_bounds();
        void add_face_normals();
@@ -117,7 +120,7 @@ public:
 
        void pack_normals(Scene *scene, float4 *normal, float4 *vnormal);
        void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset);
-       void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_keys, size_t curvekey_offset);
+       void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
        void compute_bvh(SceneParams *params, Progress *progress, int n, int total);
 
        bool need_attribute(Scene *scene, AttributeStandard std);
index 4862b47c342fc24feb9a99d586b5925c2c78dc33..a89f8afd251cf9e59e3779e5ba8bfb5e5b674f45 100644 (file)
@@ -203,14 +203,18 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
                                        surface_area += triangle_area(p1, p2, p3);
                                }
 
-                               foreach(Mesh::CurveSegment& t, mesh->curve_segments) {
-                                       float3 p1 = mesh->curve_keys[t.v[0]].co;
-                                       float r1 = mesh->curve_keys[t.v[0]].radius;
-                                       float3 p2 = mesh->curve_keys[t.v[1]].co;
-                                       float r2 = mesh->curve_keys[t.v[1]].radius;
-
-                                       /* currently ignores segment overlaps*/
-                                       surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
+                               foreach(Mesh::Curve& curve, mesh->curves) {
+                                       int first_key = curve.first_key;
+
+                                       for(int i = 0; i < curve.num_segments(); i++) {
+                                               float3 p1 = mesh->curve_keys[first_key + i].co;
+                                               float r1 = mesh->curve_keys[first_key + i].radius;
+                                               float3 p2 = mesh->curve_keys[first_key + i + 1].co;
+                                               float r2 = mesh->curve_keys[first_key + i + 1].radius;
+
+                                               /* currently ignores segment overlaps*/
+                                               surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
+                                       }
                                }
 
                                surface_area_map[mesh] = surface_area;
@@ -229,14 +233,21 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
                                surface_area += triangle_area(p1, p2, p3);
                        }
 
-                       foreach(Mesh::CurveSegment& t, mesh->curve_segments) {
-                               float3 p1 = mesh->curve_keys[t.v[0]].co;
-                               float r1 = mesh->curve_keys[t.v[0]].radius;
-                               float3 p2 = mesh->curve_keys[t.v[1]].co;
-                               float r2 = mesh->curve_keys[t.v[1]].radius;
+                       foreach(Mesh::Curve& curve, mesh->curves) {
+                               int first_key = curve.first_key;
+
+                               for(int i = 0; i < curve.num_segments(); i++) {
+                                       float3 p1 = mesh->curve_keys[first_key + i].co;
+                                       float r1 = mesh->curve_keys[first_key + i].radius;
+                                       float3 p2 = mesh->curve_keys[first_key + i + 1].co;
+                                       float r2 = mesh->curve_keys[first_key + i + 1].radius;
 
-                               /* currently ignores segment overlaps*/
-                               surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
+                                       p1 = transform_point(&tfm, p1);
+                                       p2 = transform_point(&tfm, p2);
+
+                                       /* currently ignores segment overlaps*/
+                                       surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
+                               }
                        }
                }
 
index 9490fd96be03196f2d74516d3780b8e3accab625..f6e1daea80d1294aa5966e9459f5aa2ee97761ed 100644 (file)
@@ -62,7 +62,7 @@ public:
        device_vector<float4> bvh_nodes;
        device_vector<uint> object_node;
        device_vector<float4> tri_woop;
-       device_vector<uint> prim_type;
+       device_vector<uint> prim_segment;
        device_vector<uint> prim_visibility;
        device_vector<uint> prim_index;
        device_vector<uint> prim_object;
@@ -73,7 +73,7 @@ public:
        device_vector<float4> tri_vindex;
        device_vector<float4> tri_verts;
 
-       device_vector<float4> curve_segments;
+       device_vector<float4> curves;
        device_vector<float4> curve_keys;
 
        /* objects */