Commit: 188874af2f53a993ff9b478ae2e8dff6427139c4
Author: Lukas Tönne
Date:   Sat Aug 26 12:13:52 2017 +0100
Branches: strand_editmode
https://developer.blender.org/rB188874af2f53a993ff9b478ae2e8dff6427139c4

Separate step for mesh sample generators to bind them to a specific mesh.

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

M       source/blender/blenkernel/BKE_mesh_sample.h
M       source/blender/blenkernel/intern/hair.c
M       source/blender/blenkernel/intern/mesh_sample.c
M       source/blender/editors/hair/hair_stroke.c
M       tests/gtests/blenkernel/BKE_mesh_sample_test.cc

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

diff --git a/source/blender/blenkernel/BKE_mesh_sample.h 
b/source/blender/blenkernel/BKE_mesh_sample.h
index f089a098288..7add4dfadba 100644
--- a/source/blender/blenkernel/BKE_mesh_sample.h
+++ b/source/blender/blenkernel/BKE_mesh_sample.h
@@ -40,6 +40,11 @@ typedef void* (*MeshSampleThreadContextCreateFp)(void 
*userdata, int start);
 typedef void (*MeshSampleThreadContextFreeFp)(void *userdata, void 
*thread_ctx);
 typedef bool (*MeshSampleRayFp)(void *userdata, void *thread_ctx, float 
ray_start[3], float ray_end[3]);
 
+/* ==== Utility Functions ==== */
+
+float* BKE_mesh_sample_calc_triangle_weights(struct DerivedMesh *dm, 
MeshSampleVertexWeightFp vertex_weight_cb, void *userdata, float *r_area);
+
+
 /* ==== Evaluate ==== */
 
 bool BKE_mesh_sample_is_volume_sample(const struct MeshSample *sample);
@@ -50,33 +55,35 @@ bool BKE_mesh_sample_shapekey(struct Key *key, struct 
KeyBlock *kb, const struct
 void BKE_mesh_sample_clear(struct MeshSample *sample);
 
 
-/* ==== Sampling ==== */
-
-float* BKE_mesh_sample_calc_triangle_weights(struct DerivedMesh *dm, 
MeshSampleVertexWeightFp vertex_weight_cb, void *userdata, float *r_area);
+/* ==== Generator Types ==== */
 
-struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_vertices(struct 
DerivedMesh *dm);
+struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_vertices(void);
 
-/* face_weights is optional */
-struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_random(struct 
DerivedMesh *dm, unsigned int seed, MeshSampleVertexWeightFp vertex_weight_cb, 
void *userdata);
-struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_random_ex(struct 
DerivedMesh *dm, unsigned int seed, float *tri_weights);
+/* vertex_weight_cb is optional */
+struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_random(unsigned int 
seed, bool use_area_weight,
+                                                               
MeshSampleVertexWeightFp vertex_weight_cb, void *userdata);
 
 struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_raycast(
-        struct DerivedMesh *dm,
         MeshSampleThreadContextCreateFp thread_context_create_cb,
         MeshSampleThreadContextFreeFp thread_context_free_cb,
         MeshSampleRayFp ray_cb,
         void *userdata);
 
-int BKE_mesh_sample_poissondisk_max_samples(float mindist, float area, int 
max_samples);
-struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_poissondisk_ex(struct 
DerivedMesh *dm, unsigned int seed, float mindist,
-                                                                       int 
num_uniform_samples, float *tri_weights);
-struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_poissondisk(struct 
DerivedMesh *dm, unsigned int seed, float mindist, int max_samples,
+struct MeshSampleGenerator *BKE_mesh_sample_gen_surface_poissondisk(unsigned 
int seed, float mindist, unsigned int max_samples,
                                                                     
MeshSampleVertexWeightFp vertex_weight_cb, void *userdata);
 
-struct MeshSampleGenerator *BKE_mesh_sample_gen_volume_random_bbray(struct 
DerivedMesh *dm, unsigned int seed, float density);
+struct MeshSampleGenerator *BKE_mesh_sample_gen_volume_random_bbray(unsigned 
int seed, float density);
 
 void BKE_mesh_sample_free_generator(struct MeshSampleGenerator *gen);
 
+
+/* ==== Sampling ==== */
+
+void BKE_mesh_sample_generator_bind(struct MeshSampleGenerator *gen, struct 
DerivedMesh *dm);
+void BKE_mesh_sample_generator_unbind(struct MeshSampleGenerator *gen);
+
+unsigned int BKE_mesh_sample_gen_get_max_samples(const struct 
MeshSampleGenerator *gen);
+
 /* Generate a single sample.
  * Not threadsafe!
  */
diff --git a/source/blender/blenkernel/intern/hair.c 
b/source/blender/blenkernel/intern/hair.c
index 493f7220dd9..48444b453f7 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -125,7 +125,8 @@ void BKE_hair_follicles_generate(HairPattern *hair, 
DerivedMesh *scalp, int coun
                return;
        }
        
-       MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_random(scalp, 
seed, NULL, NULL);
+       MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_random(seed, 
true, NULL, NULL);
+       BKE_mesh_sample_generator_bind(gen, scalp);
        unsigned int i;
        
        HairFollicle *foll = hair->follicles;
@@ -320,7 +321,8 @@ static void get_strand_roots_normals(const 
HairDrawDataInterface* hairdata_, str
        const HairGroupDrawDataInterface *hairdata = 
(HairGroupDrawDataInterface *)hairdata_;
        DerivedMesh *scalp = hairdata->base.scalp;
        
-       MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_vertices(scalp);
+       MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_vertices();
+       BKE_mesh_sample_generator_bind(gen, scalp);
        
        int i = 0;
        for (; i < hairdata->numstrands; ++i)
@@ -343,7 +345,8 @@ static void get_strand_vertices_normals(const 
HairDrawDataInterface* hairdata_,
        const HairGroupDrawDataInterface *hairdata = 
(HairGroupDrawDataInterface *)hairdata_;
        DerivedMesh *scalp = hairdata->base.scalp;
        
-       MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_vertices(scalp);
+       MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_vertices();
+       BKE_mesh_sample_generator_bind(gen, scalp);
        
        int i = 0;
        for (; i < hairdata->numstrands; ++i)
diff --git a/source/blender/blenkernel/intern/mesh_sample.c 
b/source/blender/blenkernel/intern/mesh_sample.c
index c4259c4b3b2..911d2496892 100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@ -48,6 +48,136 @@
 
 #define DEFAULT_TASK_SIZE 1024
 
+/* ==== Utility Functions ==== */
+
+static float calc_mesh_area(DerivedMesh *dm)
+{
+       int numtris = dm->getNumLoopTri(dm);
+       MVert *mverts = dm->getVertArray(dm);
+       MLoop *mloops = dm->getLoopArray(dm);
+       
+       float totarea = 0.0;
+       const MLoopTri *tri = dm->getLoopTriArray(dm);
+       for (int i = 0; i < numtris; ++i, ++tri) {
+               unsigned int index1 = mloops[tri->tri[0]].v;
+               unsigned int index2 = mloops[tri->tri[1]].v;
+               unsigned int index3 = mloops[tri->tri[2]].v;
+               MVert *v1 = &mverts[index1];
+               MVert *v2 = &mverts[index2];
+               MVert *v3 = &mverts[index3];
+               totarea += area_tri_v3(v1->co, v2->co, v3->co);
+       }
+       
+       return totarea;
+}
+
+BLI_INLINE float triangle_weight(DerivedMesh *dm, const MLoopTri *tri, const 
float *vert_weights, float *r_area)
+{
+       MVert *mverts = dm->getVertArray(dm);
+       MLoop *mloops = dm->getLoopArray(dm);
+       unsigned int index1 = mloops[tri->tri[0]].v;
+       unsigned int index2 = mloops[tri->tri[1]].v;
+       unsigned int index3 = mloops[tri->tri[2]].v;
+       MVert *v1 = &mverts[index1];
+       MVert *v2 = &mverts[index2];
+       MVert *v3 = &mverts[index3];
+       
+       float weight = area_tri_v3(v1->co, v2->co, v3->co);
+       if (r_area) {
+               *r_area = weight;
+       }
+       
+       if (vert_weights) {
+               float w1 = vert_weights[index1];
+               float w2 = vert_weights[index2];
+               float w3 = vert_weights[index3];
+               
+               weight *= (w1 + w2 + w3) / 3.0f;
+       }
+       
+       return weight;
+}
+
+float* BKE_mesh_sample_calc_triangle_weights(DerivedMesh *dm, 
MeshSampleVertexWeightFp vertex_weight_cb, void *userdata, float *r_area)
+{
+       int numverts = dm->getNumVerts(dm);
+       int numtris = dm->getNumLoopTri(dm);
+       int numweights = numtris;
+       
+       float *vert_weights = NULL;
+       if (vertex_weight_cb) {
+               vert_weights = MEM_mallocN(sizeof(float) * (size_t)numverts, 
"mesh sample vertex weights");
+               {
+                       MVert *mv = dm->getVertArray(dm);
+                       for (int i = 0; i < numtris; ++i, ++mv) {
+                               vert_weights[i] = vertex_weight_cb(dm, mv, 
(unsigned int)i, userdata);
+                       }
+               }
+       }
+       
+       float *tri_weights = MEM_mallocN(sizeof(float) * (size_t)numweights, 
"mesh sample triangle weights");
+       /* accumulate weights */
+       float totarea = 0.0;
+       float totweight = 0.0f;
+       {
+               const MLoopTri *mt = dm->getLoopTriArray(dm);
+               for (int i = 0; i < numtris; ++i, ++mt) {
+                       tri_weights[i] = totweight;
+                       
+                       float triarea;
+                       float triweight = triangle_weight(dm, mt, vert_weights, 
&triarea);
+                       totarea += triarea;
+                       totweight += triweight;
+               }
+       }
+       
+       if (vert_weights) {
+               MEM_freeN(vert_weights);
+       }
+       
+       /* normalize */
+       if (totweight > 0.0f) {
+               float norm = 1.0f / totweight;
+               const MLoopTri *mt = dm->getLoopTriArray(dm);
+               for (int i = 0; i < numtris; ++i, ++mt) {
+                       tri_weights[i] *= norm;
+               }
+       }
+       else {
+               /* invalid weights, remove to avoid invalid binary search */
+               MEM_freeN(tri_weights);
+               tri_weights = NULL;
+       }
+       
+       if (r_area) {
+               *r_area = totarea;
+       }
+       return tri_weights;
+}
+
+BLI_INLINE void mesh_sample_weights_from_loc(MeshSample *sample, DerivedMesh 
*dm, int face_index, const float loc[3])
+{
+       MFace *face = &dm->getTessFaceArray(dm)[face_index];
+       unsigned int index[4] = { face->v1, face->v2, face->v3, face->v4 };
+       MVert *mverts = dm->getVertArray(dm);
+       
+       float *v1 = mverts[face->v1].co;
+       float *v2 = mverts[face->v2].co;
+       float *v3 = mverts[face->v3].co;
+       float *v4 = face->v4 ? mverts[face->v4].co : NULL;
+       float w[4];
+       int tri[3];
+       
+       interp_weights_quad_v3_index(tri, w, v1, v2, v3, v4, loc);
+       
+       sample->orig_verts[0] = index[tri[0]];
+       sample->orig_verts[1] = index[tri[1]];
+       sample->orig_verts[2] = index[tri[2]];
+       sample->orig_weights[0] = w[tri[0]];
+       sample->orig_weights[1] = w[tri[1]];
+       sample->orig_weights[2] = w[tri[2]];
+}
+
 /* ==== Evaluate ==== */
 
 bool BKE_mesh_sample_is_volume_sample(const MeshSample *sample)
@@ -153,44 +283,32 @@ void BKE_mesh_sample_clear(MeshSample *sample)
 }
 
 
-/* ==== Sampling Utilities ==== */
+/* ==== Generator Types ==== */
 
-BLI_INLINE void mesh_sample_weights_from_loc(MeshSample *sample, DerivedMesh 
*dm, int face_index, const float loc[3])
-{
-       MFace *face = &dm->getTessFaceArray(dm)[face_index];
-       unsigned int index[4] = { face->v1, face->v2, face->v3, face->v4 };
-       MVert *mverts = dm->getVertArray(dm);
-       
-       float *v1 = mverts[face->v1].co;
-       float *v2 = mverts[face->v2].co;
-       float *v3 = mverts[face->v3].co;
-       float *v4 = face->v4 ? mverts[face->v4].co : NULL;
-       float w[4];
-       int tri[3];
-       
-       interp_weights_quad_v3_index(tri, w, v1, v2, v3, v4, loc);
-       
-       sample->orig_verts[0] = index[tri[0]];
-       sample->orig_verts[1] = index[tri[1]];
-       sample->orig_verts[2] = index[tri[2]];
-       sample->orig_weights[0] = w[tri[0]];
-       sample->orig_weights[1] = w[tri[1]];
-       sample->orig_weights[2] = w[tri[2]];
-}

@@ Diff output truncated at 10240 characters. @@

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

Reply via email to