Cycles Hair: Multiple vertex colours and UV coordinates
authorStuart Broadfoot <gbroadfoot@hotmail.com>
Wed, 23 Jan 2013 17:15:45 +0000 (17:15 +0000)
committerStuart Broadfoot <gbroadfoot@hotmail.com>
Wed, 23 Jan 2013 17:15:45 +0000 (17:15 +0000)
Added export of multiple UV coordinates and vertex colour attributes.

A debugging option to export the strands without using the cache has also been removed.

intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_curves.cpp
intern/cycles/render/curves.cpp
intern/cycles/render/curves.h
source/blender/makesrna/intern/rna_particle.c

index 18a829a9ef0081fe46d9237231ffdf98537177f5..3661274ae434837afa17751bd77e648458679ba0 100644 (file)
@@ -685,10 +685,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
                 description="Correct the tangent normal for the strand's slope",
                 default=False,
                 )
-        cls.use_cache = BoolProperty(
-                name="Export Cached data",
-                default=True,
-                )
         cls.use_parents = BoolProperty(
                 name="Use parent strands",
                 description="Use parents with children",
index 214d28e393ed5c924afca94160ab6d45908a9b4d..fded07ab2270657eb062cc4d5480a0d78ad88323 100644 (file)
@@ -1009,9 +1009,7 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
                 row.prop(ccscene, "segments", text="Segments")
 
             row = layout.row()
-            row.prop(ccscene, "use_cache", text="Export cache with children")
-            if ccscene.use_cache:
-                row.prop(ccscene, "use_parents", text="Include parents")
+            row.prop(ccscene, "use_parents", text="Include parents")
 
 
 class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
index f8795ec0a9489209202d4ae227d22f0ba9bb6e2c..e1cc35a532227fd98b6192e378493ecca2c376f5 100644 (file)
@@ -37,8 +37,7 @@ void curveinterp_v3_v3v3v3v3(float3 *p, float3 *v1, float3 *v2, float3 *v3, floa
 void interp_weights(float t, float data[4], int type);
 float shaperadius(float shape, float root, float tip, float time);
 void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData, int interpolation);
-bool ObtainParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData);
-bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents);
+bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int uv_num);
 bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int vcol_num);
 bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents);
 void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, float3 RotCam);
@@ -152,93 +151,6 @@ void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyl
                curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t);
 }
 
-bool ObtainParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData)
-{
-
-       int curvenum = 0;
-       int keyno = 0;
-
-       if(!(mesh && b_mesh && b_ob && CData))
-               return false;
-
-       BL::Object::modifiers_iterator b_mod;
-       for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
-               if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
-
-                       BL::ParticleSystemModifier psmd(b_mod->ptr);
-
-                       BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
-
-                       BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
-
-                       if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
-
-                               int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
-                               int shader = mesh->used_shaders[mi];
-
-                               int totcurves = b_psys.particles.length();
-
-                               if(totcurves == 0)
-                                       continue;
-
-                               PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
-
-                               CData->psys_firstcurve.push_back(curvenum);
-                               CData->psys_curvenum.push_back(totcurves);
-                               CData->psys_shader.push_back(shader);
-
-                               float radius = b_psys.settings().particle_size() * 0.5f;
-       
-                               CData->psys_rootradius.push_back(radius * get_float(cpsys, "root_width"));
-                               CData->psys_tipradius.push_back(radius * get_float(cpsys, "tip_width"));
-                               CData->psys_shape.push_back(get_float(cpsys, "shape"));
-                               CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip"));
-
-                               BL::ParticleSystem::particles_iterator b_pa;
-                               for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) {
-                                       CData->curve_firstkey.push_back(keyno);
-
-                                       int keylength = b_pa->hair_keys.length();
-                                       CData->curve_keynum.push_back(keylength);
-
-                                       float curve_length = 0.0f;
-                                       float3 pcKey;
-                                       int step_no = 0;
-                                       BL::Particle::hair_keys_iterator b_cKey;
-                                       for(b_pa->hair_keys.begin(b_cKey); b_cKey != b_pa->hair_keys.end(); ++b_cKey) {
-                                               float nco[3];
-                                               b_cKey->co_object( *b_ob, psmd, *b_pa, nco);
-                                               float3 cKey = make_float3(nco[0],nco[1],nco[2]);
-                                               if(step_no > 0)
-                                                       curve_length += len(cKey - pcKey);
-                                               CData->curvekey_co.push_back(cKey);
-                                               CData->curvekey_time.push_back(curve_length);
-                                               pcKey = cKey;
-                                               keyno++;
-                                               step_no++;
-                                       }
-
-                                       CData->curve_length.push_back(curve_length);
-                                       /*add uvs*/
-                                       BL::Mesh::tessface_uv_textures_iterator l;
-                                       b_mesh->tessface_uv_textures.begin(l);
-
-                                       float3 uv = make_float3(0.0f, 0.0f, 0.0f);
-                                       if(b_mesh->tessface_uv_textures.length())
-                                               b_pa->uv_on_emitter(psmd,&uv.x);
-                                       CData->curve_uv.push_back(uv);
-
-                                       curvenum++;
-
-                               }
-                       }
-               }
-       }
-
-       return true;
-
-}
-
 bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents)
 {
 
@@ -328,7 +240,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
 
 }
 
-bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents)
+bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int uv_num)
 {
 #if 0
        int keyno = 0;
@@ -342,6 +254,8 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti
        Transform itfm = transform_quick_inverse(tfm);
 #endif
 
+       CData->curve_uv.clear();
+
        BL::Object::modifiers_iterator b_mod;
        for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
                if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
@@ -384,7 +298,7 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti
 
                                        float3 uv = make_float3(0.0f, 0.0f, 0.0f);
                                        if(b_mesh->tessface_uv_textures.length())
-                                               b_psys.uv_on_emitter(psmd, *b_pa, pa_no, &uv.x);
+                                               b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
                                        CData->curve_uv.push_back(uv);
 
                                        if(pa_no < totparts && b_pa != b_psys.particles.end())
@@ -413,6 +327,8 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
        Transform itfm = transform_quick_inverse(tfm);
 #endif
 
+       CData->curve_vcol.clear();
+
        BL::Object::modifiers_iterator b_mod;
        for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
                if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
@@ -782,10 +698,8 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa
        if(!(mesh->curves.empty() && mesh->curve_keys.empty()))
                return;
 
-       Attribute *attr_uv = NULL, *attr_intercept = NULL;
+       Attribute *attr_intercept = NULL;
        
-       if(mesh->need_attribute(scene, ATTR_STD_UV))
-               attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
        if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
                attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
 
@@ -831,9 +745,6 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa
                        }
 
                        mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]);
-                       if(attr_uv)
-                               attr_uv->add(CData->curve_uv[curve]);
-
                        num_keys += num_curve_keys;
                        num_curves++;
                }
@@ -934,7 +845,6 @@ void BlenderSync::sync_curve_settings()
                curve_system_manager->normalmix = get_float(csscene, "normalmix");
                curve_system_manager->encasing_ratio = get_float(csscene, "encasing_ratio");
 
-               curve_system_manager->use_cache = get_boolean(csscene, "use_cache");
                curve_system_manager->use_parents = get_boolean(csscene, "use_parents");
                curve_system_manager->use_encasing = get_boolean(csscene, "use_encasing");
                curve_system_manager->use_backfacing = get_boolean(csscene, "use_backfacing");
@@ -948,7 +858,6 @@ void BlenderSync::sync_curve_settings()
                curve_system_manager->interpolation = CURVE_CARDINAL;
                curve_system_manager->normalmix = 1.0f;
                curve_system_manager->encasing_ratio = 1.01f;
-               curve_system_manager->use_cache = true;
                curve_system_manager->use_parents = false;
                curve_system_manager->segments = 1;
                curve_system_manager->use_joined = false;
@@ -1029,7 +938,6 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
        int resolution = scene->curve_system_manager->resolution;
        int segments = scene->curve_system_manager->segments;
        bool use_smooth = scene->curve_system_manager->use_smooth;
-       bool use_cache = scene->curve_system_manager->use_cache;
        bool use_parents = scene->curve_system_manager->use_parents;
        bool export_tgs = scene->curve_system_manager->use_joined;
 
@@ -1037,12 +945,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
 
        ParticleCurveData CData;
 
-       if(use_cache) {
-               ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents);
-               ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, use_parents);
-       }
-       else
-               ObtainParticleData(mesh, &b_mesh, &b_ob, &CData);
+       ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents);
 
        /* attach strands to mesh */
        BL::Object b_CamOb = b_scene.camera();
@@ -1056,6 +959,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
 
        if(primitive == CURVE_TRIANGLES){
                int vert_num = mesh->triangles.size() * 3;
+               ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, use_parents, 0);
                if(triangle_method == CURVE_CAMERA_TRIANGLES) {
                        ExportCurveTrianglePlanes(mesh, &CData, interpolation, use_smooth, segments, RotCam);
                        ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, 1);
@@ -1089,44 +993,76 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
 
                /* generated coordinates from first key. we should ideally get this from
                 * blender to handle deforming objects */
-               if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
-                       float3 loc, size;
-                       mesh_texture_space(b_mesh, loc, size);
+               {
+                       if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+                               float3 loc, size;
+                               mesh_texture_space(b_mesh, loc, size);
+
+                               Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
+                               float3 *generated = attr_generated->data_float3();
+                               size_t i = 0;
+
+                               foreach(Mesh::Curve& curve, mesh->curves) {
+                                       float3 co = mesh->curve_keys[curve.first_key].co;
+                                       generated[i++] = co*size - loc;
+                               }
+                       }
+               }
+
+               /* create vertex color attributes */
+               {
+                       BL::Mesh::tessface_vertex_colors_iterator l;
+                       int vcol_num = 0;
 
-                       Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
-                       float3 *generated = attr_generated->data_float3();
-                       size_t i = 0;
+                       for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l, vcol_num++) {
+                               if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+                                       continue;
+
+                               Attribute *attr_vcol = mesh->curve_attributes.add(
+                                       ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE);
+
+                               ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, use_parents, vcol_num);
 
-                       foreach(Mesh::Curve& curve, mesh->curves) {
-                               float3 co = mesh->curve_keys[curve.first_key].co;
-                               generated[i++] = co*size - loc;
+                               float3 *vcol = attr_vcol->data_float3();
+
+                               if(vcol) {
+                                       for(size_t curve = 0; curve < CData.curve_vcol.size() ;curve++)
+                                               vcol[curve] = color_srgb_to_scene_linear(CData.curve_vcol[curve]);
+                               }
                        }
                }
 
-               /* create vertex color attributes */
-               BL::Mesh::tessface_vertex_colors_iterator l;
-               int vcol_num = 0;
+               /* create uv map attributes */
+               {
+                       BL::Mesh::tessface_uv_textures_iterator l;
+                       int uv_num = 0;
 
-               for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l, vcol_num++) {
-                       if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
-                               continue;
+                       for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l, uv_num++) {
+                               bool active_render = l->active_render();
+                               AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
+                               ustring name = ustring(l->name().c_str());
 
-                       /*error occurs with more than one vertex colour attribute so avoided*/
-                       if(vcol_num!=0)
-                               break;
+                               /* UV map */
+                               if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
+                                       Attribute *attr;
 
-                       Attribute *attr_vcol = mesh->curve_attributes.add(
-                               ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE);
+                                       Attribute *attr_uv = NULL, *attr_intercept = NULL;
+       
+                                       if(active_render)
+                                               attr = mesh->curve_attributes.add(std, name);
+                                       else
+                                               attr = mesh->curve_attributes.add(name, TypeDesc::TypePoint,  ATTR_ELEMENT_CURVE);
 
-                       ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, use_parents, 0);
+                                       ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, use_parents, uv_num);
 
-                       float3 *vcol = attr_vcol->data_float3();
+                                       float3 *uv = attr->data_float3();
 
-                       if(vcol) {
-                               for(size_t curve = 0; curve < CData.curve_vcol.size() ;curve++)
-                                       vcol[curve] = color_srgb_to_scene_linear(CData.curve_vcol[curve]);
+                                       if(uv) {
+                                               for(size_t curve = 0; curve < CData.curve_uv.size() ;curve++)
+                                                       uv[curve] = CData.curve_uv[curve];
+                                       }
+                               }                       
                        }
-
                }
 
        }
index 3ee441ef095c2a8cc1b692e26c0053917a22c4e5..9fa867ae723e5b31760585546c638106efa53d0d 100644 (file)
@@ -92,7 +92,6 @@ CurveSystemManager::CurveSystemManager()
 
        use_curves = true;
        use_smooth = true;
-       use_cache = true;
        use_parents = false;
        use_encasing = true;
        use_backfacing = false;
@@ -175,7 +174,6 @@ bool CurveSystemManager::modified(const CurveSystemManager& CurveSystemManager)
                encasing_ratio == CurveSystemManager.encasing_ratio &&
                use_backfacing == CurveSystemManager.use_backfacing &&
                normalmix == CurveSystemManager.normalmix &&
-               use_cache == CurveSystemManager.use_cache &&
                use_smooth == CurveSystemManager.use_smooth &&
                triangle_method == CurveSystemManager.triangle_method &&
                resolution == CurveSystemManager.resolution &&
@@ -196,8 +194,7 @@ bool CurveSystemManager::modified_mesh(const CurveSystemManager& CurveSystemMana
                resolution == CurveSystemManager.resolution &&
                use_curves == CurveSystemManager.use_curves &&
                use_joined == CurveSystemManager.use_joined &&
-               segments == CurveSystemManager.segments &&
-               use_cache == CurveSystemManager.use_cache);
+               segments == CurveSystemManager.segments);
 }
 
 void CurveSystemManager::tag_update(Scene *scene)
index 4e6166c6916013f4f1bd0569f3a41333b99a0d7e..3a12d33d0a713eaa6904e379c164fc09ef338c3f 100644 (file)
@@ -108,7 +108,6 @@ public:
 
        bool use_curves;
        bool use_smooth;
-       bool use_cache;
        bool use_parents;
        bool use_encasing;
        bool use_backfacing;
index d8884654435c35d4bc9aff238ea92732fcd0b430..bd3e4e6862d24696b9557be99b78edb0feb8695b 100644 (file)
@@ -359,7 +359,7 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
 
 }
 
-static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no,
+static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, int uv_no,
                                              float n_uv[2])
 {
        ParticleSettings *part = 0;
@@ -398,7 +398,7 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Par
                if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
                        if (num != DMCACHE_NOTFOUND) {
                                MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
-                               MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
+                               MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, uv_no);
                                mtface += num;
                                
                                psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv);
@@ -3365,6 +3365,7 @@ static void rna_def_particle_system(BlenderRNA *brna)
        prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
        prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
        prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
+       prop = RNA_def_int(func, "uv_no", 0, INT_MIN, INT_MAX, "UV no", "", INT_MIN, INT_MAX);
        prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS);
        RNA_def_property_array(prop, 2);
        RNA_def_property_flag(prop, PROP_THICK_WRAP);