Commit: 38023ea1c9386350a7b54711bc98301b4f6622b2
Author: Lukas Tönne
Date:   Wed Aug 13 15:43:33 2014 +0200
Branches: hair_system
https://developer.blender.org/rB38023ea1c9386350a7b54711bc98301b4f6622b2

Very basic Cycles export of hair data.

Only the simplest curve mode is currently implemented.

===================================================================

M       intern/cycles/blender/blender_curves.cpp
M       intern/cycles/blender/blender_sync.h
M       source/blender/blenkernel/BKE_hair.h
M       source/blender/blenkernel/intern/hair.c
M       source/blender/editors/space_view3d/drawhair.c
M       source/blender/makesrna/intern/rna_hair.c

===================================================================

diff --git a/intern/cycles/blender/blender_curves.cpp 
b/intern/cycles/blender/blender_curves.cpp
index 7b1a8ec..5175a1f 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -38,7 +38,6 @@ void InterpolateKeySegments(int seg, int segno, int key, int 
curve, float3 *keyl
 bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, 
ParticleCurveData *CData, bool background, int uv_num);
 bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, 
ParticleCurveData *CData, bool background, int vcol_num);
 bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, 
ParticleCurveData *CData, bool background);
-void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData);
 void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 
RotCam);
 void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int 
resolution);
 void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int 
vert_offset, int resol, float3 *uvdata);
@@ -544,7 +543,7 @@ void ExportCurveTriangleGeometry(Mesh *mesh, 
ParticleCurveData *CData, int resol
        /* texture coords still needed */
 }
 
-void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
+static void ExportParticleCurveSegments(Scene *scene, Mesh *mesh, 
ParticleCurveData *CData)
 {
        int num_keys = 0;
        int num_curves = 0;
@@ -612,7 +611,7 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, 
ParticleCurveData *CData)
        }
 }
 
-static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, 
ParticleCurveData *CData, int time_index)
+static void ExportParticleCurveSegmentsMotion(Scene *scene, Mesh *mesh, 
ParticleCurveData *CData, int time_index)
 {
        /* find attribute */
        Attribute *attr_mP = 
mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
@@ -681,6 +680,138 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh 
*mesh, ParticleCurveDat
        }
 }
 
+static void ExportHairCurveSegments(Scene *scene, Mesh *mesh, BL::HairSystem 
b_hsys)
+{
+       /* XXX TODO put these into render parameters */
+       float shape = 0.0f;
+       float root_radius = 0.01f;
+       float tip_radius = 0.01f;
+       
+       int num_keys = 0;
+       int num_curves = 0;
+       
+       if(!(mesh->curves.empty() && mesh->curve_keys.empty()))
+               return;
+       
+       Attribute *attr_intercept = NULL;
+       
+       if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
+               attr_intercept = 
mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
+       
+       BL::HairRenderIterator b_hair_iter = b_hsys.render_iterator();
+       b_hair_iter.init();
+       
+       b_hair_iter.count(&num_curves, &num_keys);
+       mesh->curve_keys.reserve(mesh->curve_keys.size() + num_keys);
+       mesh->curves.reserve(mesh->curves.size() + num_curves);
+       
+       num_keys = 0;
+       num_curves = 0;
+       for (; b_hair_iter.valid(); b_hair_iter.next()) {
+               BL::HairRenderStepIterator b_step_iter = 
b_hair_iter.step_init();
+               if (b_step_iter.totsteps() <= 1)
+                       continue;
+               
+               int num_curve_keys = 0;
+               for (; b_step_iter.valid(); b_step_iter.next()) {
+                       float time = 0.0f; // XXX
+                       float radius = shaperadius(shape, root_radius, 
tip_radius, time);
+                       float co[3], hair_radius;
+                       
+                       b_step_iter.eval(co, &hair_radius);
+                       
+                       mesh->add_curve_key(make_float3(co[0], co[1], co[2]), 
radius);
+                       if(attr_intercept)
+                               attr_intercept->add(time);
+                       
+                       ++num_curve_keys;
+               }
+               
+               mesh->add_curve(num_keys, num_curve_keys, 0);
+               num_keys += num_curve_keys;
+               num_curves++;
+       }
+       
+       /* check allocation*/
+       if((mesh->curve_keys.size() !=  num_keys) || (mesh->curves.size() !=  
num_curves)) {
+               /* allocation failed -> clear data */
+               mesh->curve_keys.clear();
+               mesh->curves.clear();
+               mesh->curve_attributes.clear();
+       }
+}
+
+static void ExportHairCurveSegmentsMotion(Scene *scene, Mesh *mesh, 
ParticleCurveData *CData, int time_index)
+{
+#if 0
+       /* find attribute */
+       Attribute *attr_mP = 
mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+       bool new_attribute = false;
+
+       /* add new attribute if it doesn't exist already */
+       if(!attr_mP) {
+               attr_mP = 
mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+               new_attribute = true;
+       }
+
+       /* export motion vectors for curve keys */
+       size_t numkeys = mesh->curve_keys.size();
+       float4 *mP = attr_mP->data_float4() + time_index*numkeys;
+       bool have_motion = false;
+       int i = 0;
+
+       for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
+               if(CData->psys_curvenum[sys] == 0)
+                       continue;
+
+               for(int curve = CData->psys_firstcurve[sys]; curve < 
CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
+                       if(CData->curve_keynum[curve] <= 1 || 
CData->curve_length[curve] == 0.0f)
+                               continue;
+
+                       for(int curvekey = CData->curve_firstkey[curve]; 
curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; 
curvekey++) {
+                               if(i < mesh->curve_keys.size()) {
+                                       float3 ickey_loc = 
CData->curvekey_co[curvekey];
+                                       float time = 
CData->curvekey_time[curvekey]/CData->curve_length[curve];
+                                       float radius = 
shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 
CData->psys_tipradius[sys], time);
+
+                                       if(CData->psys_closetip[sys] && 
(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+                                               radius = 0.0f;
+
+                                       mP[i] = float3_to_float4(ickey_loc);
+                                       mP[i].w = radius;
+
+                                       /* unlike mesh coordinates, these tend 
to be slightly different
+                                        * between frames due to particle 
transforms into/out of object
+                                        * space, so we use an epsilon to 
detect actual changes */
+                                       if(len_squared(mP[i] - 
mesh->curve_keys[i]) > 1e-5f*1e-5f)
+                                               have_motion = true;
+                               }
+
+                               i++;
+                       }
+               }
+       }
+
+       /* in case of new attribute, we verify if there really was any motion */
+       if(new_attribute) {
+               if(i != numkeys || !have_motion) {
+                       /* no motion, remove attributes again */
+                       
mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+               }
+               else if(time_index > 0) {
+                       /* motion, fill up previous steps that we might have 
skipped because
+                        * they had no motion, but we need them anyway now */
+                       for(int step = 0; step < time_index; step++) {
+                               float4 *mP = attr_mP->data_float4() + 
step*numkeys;
+
+                               for(int key = 0; key < numkeys; key++)
+                                       mP[key] = mesh->curve_keys[key];
+                       }
+               }
+       }
+#endif
+}
+
 void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int 
vert_offset, int resol, float3 *uvdata)
 {
        if(uvdata == NULL)
@@ -824,24 +955,14 @@ void BlenderSync::sync_curve_settings()
                curve_system_manager->tag_update(scene);
 }
 
-void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, 
bool motion, int time_index)
+bool BlenderSync::sync_particle_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object 
b_ob, bool motion, int time_index)
 {
-       if(!motion) {
-               /* Clear stored curve data */
-               mesh->curve_keys.clear();
-               mesh->curves.clear();
-               mesh->curve_attributes.clear();
-       }
-
-       /* obtain general settings */
-       bool use_curves = scene->curve_system_manager->use_curves;
-
-       if(!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) {
-               if(!motion)
-                       mesh->compute_bounds();
-               return;
-       }
-
+       if(b_ob.mode() == b_ob.mode_PARTICLE_EDIT)
+               return false;
+       
+       if(!preview)
+               set_resolution(mesh, &b_mesh, &b_ob, &b_scene, true);
+       
        int primitive = scene->curve_system_manager->primitive;
        int triangle_method = scene->curve_system_manager->triangle_method;
        int resolution = scene->curve_system_manager->resolution;
@@ -852,10 +973,6 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, 
BL::Object b_ob, bool
        /* extract particle hair data - should be combined with connecting to 
mesh later*/
 
        ParticleCurveData CData;
-
-       if(!preview)
-               set_resolution(mesh, &b_mesh, &b_ob, &b_scene, true);
-
        ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
 
        /* obtain camera parameters */
@@ -879,9 +996,9 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, 
BL::Object b_ob, bool
        }
        else {
                if(motion)
-                       ExportCurveSegmentsMotion(scene, mesh, &CData, 
time_index);
+                       ExportParticleCurveSegmentsMotion(scene, mesh, &CData, 
time_index);
                else
-                       ExportCurveSegments(scene, mesh, &CData);
+                       ExportParticleCurveSegments(scene, mesh, &CData);
        }
 
        /* generated coordinates from first key. we should ideally get this from
@@ -992,11 +1109,199 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh 
b_mesh, BL::Object b_ob, bool
                        }
                }
        }
-
+       
        if(!preview)
                set_resolution(mesh, &b_mesh, &b_ob, &b_scene, false);
+       
+       return true;
+}
 
-       mesh->compute_bounds();
+bool BlenderSync::sync_hair_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object 
b_ob, bool motion, int time_index)
+{
+       int primitive = scene->curve_system_manager->primitive;
+       int triangle_method = scene->curve_system_manager->triangle_method;
+       int resolution = scene->curve_system_manager->resolution;
+       size_t vert_num = mesh->verts.size();
+       size_t tri_num = mesh->triangles.size();
+       int used_res = 1;
+
+       /* extract hair data - should be combined with connecting to mesh 
later*/
+
+//     ParticleCurveData CData;
+//     ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
+
+       /* obtain camera parameters */
+       BL::Object b_CamOb = b_scene.camera();
+       float3 RotCam = make_float3(0.0f, 0.0f, 0.0f);
+       if(b_CamOb) {
+               Transform ctfm = get_transform(b_CamOb.matrix_world());
+               Transform tfm = get_transform(b_ob.matrix_world());
+               Transform itfm = transform_quick_inverse(tfm);
+               RotCam = transform_point(&itfm, make_float3(ctfm.x.w, ctfm.y.w, 
ctfm.z.w));
+       }
+
+       BL::Object::modifiers_iterator b_mod_iter;
+       for (b_ob.modifiers.begin(b_mod_iter); b_mod_iter != 
b_ob.modifiers.end(); ++b_mod_iter) {
+               if (b_mod_iter->type() != BL::Modifier::type_HAIR)
+                       continue;
+               
+               BL::HairModifier b_mod_hair(*b_mod_iter);
+               
+               /* add hair geometry to mesh */
+               if(primitive == CURVE_TRIANGLES) {
+#if 0 /* TODO */
+                       if(triangle_method == CURVE_CAMERA_TRIANGLES)
+                               ExportCurveTrianglePlanes(mesh, &CData, RotCam);
+                       else {
+                               ExportCurveTriangleGeometry(mesh, &CData, 
resolution);
+                               used_res = resolution;
+                       }
+#endif
+               }
+               else {
+//                     if(motion)
+//                             ExportParticleCurveSegmentsMotion(scene, mesh, 
&CData, time_index);
+//                     else
+                               ExportHair

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to