[Bf-blender-cvs] [45f0f3dc045] strand_editmode: Merge branch 'blender2.8' into strand_editmode
Lukas Tönne
noreply at git.blender.org
Sun Aug 20 09:30:58 CEST 2017
Commit: 45f0f3dc0457a53a25103784f0e0d100c7a17cbe
Author: Lukas Tönne
Date: Sat Aug 19 12:02:03 2017 +0100
Branches: strand_editmode
https://developer.blender.org/rB45f0f3dc0457a53a25103784f0e0d100c7a17cbe
Merge branch 'blender2.8' into strand_editmode
===================================================================
===================================================================
diff --cc source/blender/blenkernel/intern/mesh_sample.c
index 53d14c9dd16,00000000000..8e823350fce
mode 100644,000000..100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@@ -1,855 -1,0 +1,855 @@@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/mesh_sample.c
+ * \ingroup bke
+ *
+ * Sample a mesh surface or volume and evaluate samples on deformed meshes.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_rand.h"
+
+#include "BKE_bvhutils.h"
+#include "BKE_mesh_sample.h"
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+
+#include "BLI_strict_flags.h"
+
+/* ==== Evaluate ==== */
+
+bool BKE_mesh_sample_is_volume_sample(const MeshSample *sample)
+{
+ return sample->orig_verts[0] == 0 && sample->orig_verts[1] == 0;
+}
+
+bool BKE_mesh_sample_eval(DerivedMesh *dm, const MeshSample *sample, float loc[3], float nor[3], float tang[3])
+{
+ MVert *mverts = dm->getVertArray(dm);
+ unsigned int totverts = (unsigned int)dm->getNumVerts(dm);
+ MVert *v1, *v2, *v3;
+
+ zero_v3(loc);
+ zero_v3(nor);
+ zero_v3(tang);
+
+ if (BKE_mesh_sample_is_volume_sample(sample)) {
+ /* VOLUME SAMPLE */
+
+ if (is_zero_v3(sample->orig_weights))
+ return false;
+
+ copy_v3_v3(loc, sample->orig_weights);
+ return true;
+ }
+ else {
+ /* SURFACE SAMPLE */
+ if (sample->orig_verts[0] >= totverts ||
+ sample->orig_verts[1] >= totverts ||
+ sample->orig_verts[2] >= totverts)
+ return false;
+
+ v1 = &mverts[sample->orig_verts[0]];
+ v2 = &mverts[sample->orig_verts[1]];
+ v3 = &mverts[sample->orig_verts[2]];
+
+ { /* location */
+ madd_v3_v3fl(loc, v1->co, sample->orig_weights[0]);
+ madd_v3_v3fl(loc, v2->co, sample->orig_weights[1]);
+ madd_v3_v3fl(loc, v3->co, sample->orig_weights[2]);
+ }
+
+ { /* normal */
+ float vnor[3];
+
+ normal_short_to_float_v3(vnor, v1->no);
+ madd_v3_v3fl(nor, vnor, sample->orig_weights[0]);
+ normal_short_to_float_v3(vnor, v2->no);
+ madd_v3_v3fl(nor, vnor, sample->orig_weights[1]);
+ normal_short_to_float_v3(vnor, v3->no);
+ madd_v3_v3fl(nor, vnor, sample->orig_weights[2]);
+
+ normalize_v3(nor);
+ }
+
+ { /* tangent */
+ float edge[3];
+
+ /* XXX simply using the v1-v2 edge as a tangent vector for now ...
+ * Eventually mikktspace generated tangents (CD_TANGENT tessface layer)
+ * should be used for consistency, but requires well-defined tessface
+ * indices for the mesh surface samples.
+ */
+
+ sub_v3_v3v3(edge, v2->co, v1->co);
+ /* make edge orthogonal to nor */
+ madd_v3_v3fl(edge, nor, -dot_v3v3(edge, nor));
+ normalize_v3_v3(tang, edge);
+ }
+
+ return true;
+ }
+}
+
+bool BKE_mesh_sample_shapekey(Key *key, KeyBlock *kb, const MeshSample *sample, float loc[3])
+{
+ float *v1, *v2, *v3;
+
+ (void)key; /* Unused in release builds. */
+
+ BLI_assert(key->elemsize == 3 * sizeof(float));
+ BLI_assert(sample->orig_verts[0] < (unsigned int)kb->totelem);
+ BLI_assert(sample->orig_verts[1] < (unsigned int)kb->totelem);
+ BLI_assert(sample->orig_verts[2] < (unsigned int)kb->totelem);
+
+ v1 = (float *)kb->data + sample->orig_verts[0] * 3;
+ v2 = (float *)kb->data + sample->orig_verts[1] * 3;
+ v3 = (float *)kb->data + sample->orig_verts[2] * 3;
+
+ zero_v3(loc);
+ madd_v3_v3fl(loc, v1, sample->orig_weights[0]);
+ madd_v3_v3fl(loc, v2, sample->orig_weights[1]);
+ madd_v3_v3fl(loc, v3, sample->orig_weights[2]);
+
+ /* TODO use optional vgroup weights to determine if a shapeky actually affects the sample */
+ return true;
+}
+
+void BKE_mesh_sample_clear(MeshSample *sample)
+{
+ memset(sample, 0, sizeof(MeshSample));
+}
+
+
+/* ==== Sampling Utilities ==== */
+
+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]];
+}
+
+/* ==== Sampling ==== */
+
+typedef void (*GeneratorFreeFp)(struct MeshSampleGenerator *gen);
+typedef bool (*GeneratorMakeSampleFp)(struct MeshSampleGenerator *gen, struct MeshSample *sample);
+
+typedef struct MeshSampleGenerator
+{
+ GeneratorFreeFp free;
+ GeneratorMakeSampleFp make_sample;
+} MeshSampleGenerator;
+
+static void sample_generator_init(MeshSampleGenerator *gen, GeneratorFreeFp free, GeneratorMakeSampleFp make_sample)
+{
+ gen->free = free;
+ gen->make_sample = make_sample;
+}
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct MSurfaceSampleGenerator_Vertices {
+ MeshSampleGenerator base;
+
+ DerivedMesh *dm;
+ int (*vert_loop_map)[3];
+ int cur_vert;
+} MSurfaceSampleGenerator_Vertices;
+
+static void generator_vertices_free(MSurfaceSampleGenerator_Vertices *gen)
+{
+ if (gen->vert_loop_map) {
+ MEM_freeN(gen->vert_loop_map);
+ }
+ MEM_freeN(gen);
+}
+
+static bool generator_vertices_make_sample(MSurfaceSampleGenerator_Vertices *gen, MeshSample *sample)
+{
+ DerivedMesh *dm = gen->dm;
+ const int num_verts = dm->getNumVerts(dm);
+ const MLoop *mloops = dm->getLoopArray(dm);
+
+ while (gen->cur_vert < num_verts) {
+ int cur_vert = gen->cur_vert++;
+
+ const int *loops = gen->vert_loop_map[cur_vert];
+ if (loops[0] >= 0) {
+ sample->orig_poly = -1;
+
+ sample->orig_loops[0] = (unsigned int)loops[0];
+ sample->orig_loops[1] = (unsigned int)loops[1];
+ sample->orig_loops[2] = (unsigned int)loops[2];
+
+ sample->orig_verts[0] = mloops[loops[0]].v;
+ sample->orig_verts[1] = mloops[loops[1]].v;
+ sample->orig_verts[2] = mloops[loops[2]].v;
+
+ sample->orig_weights[0] = 1.0f;
+ sample->orig_weights[1] = 0.0f;
+ sample->orig_weights[2] = 0.0f;
+
+ return true;
+ }
+ }
+ return false;
+}
+
+MeshSampleGenerator *BKE_mesh_sample_gen_surface_vertices(DerivedMesh *dm)
+{
+ MSurfaceSampleGenerator_Vertices *gen;
+
+ DM_ensure_normals(dm);
+
+ gen = MEM_callocN(sizeof(MSurfaceSampleGenerator_Vertices), "MSurfaceSampleGenerator_Vertices");
+ sample_generator_init(&gen->base, (GeneratorFreeFp)generator_vertices_free, (GeneratorMakeSampleFp)generator_vertices_make_sample);
+
+ gen->dm = dm;
+ gen->cur_vert = 0;
+
+ {
+ const int num_verts = dm->getNumVerts(dm);
+ int (*vert_loop_map)[3] = MEM_mallocN(sizeof(int) * 3 * (unsigned int)num_verts, "vertex loop map");
+
+ for (int i = 0; i < num_verts; ++i) {
+ vert_loop_map[i][0] = -1;
+ vert_loop_map[i][1] = -1;
+ vert_loop_map[i][2] = -1;
+ }
+
+ const int num_polys = dm->getNumPolys(dm);
+ const MLoop *mloops = dm->getLoopArray(dm);
+ const MPoly *mp = dm->getPolyArray(dm);
+ for (int i = 0; i < num_polys; ++i, ++mp) {
+ if (mp->totloop < 3) {
+ continue;
+ }
+
+ const MLoop *ml = mloops + mp->loopstart;
+ for (int k = 0; k < mp->totloop; ++k, ++ml) {
+ int *vmap = vert_loop_map[ml->v];
+ if (vmap[0] < 0) {
+ vmap[0] = mp->loopstart + k;
+ vmap[1] = mp->loopstart + (k + 1) % mp->totloop;
+ vmap[2] = mp->loopstart + (k + 2) % mp->totloop;
+ }
+ }
+ }
+
+ gen->vert_loop_map = vert_loop_map;
+ }
+
+ return &gen->base;
+}
+
+/* ------------------------------------------------------------------------- */
+
+//#define USE_DEBUG_COUNT
+
+typedef struct MSurfaceSampleGenerator_Random {
+ MeshSampleGenerator base;
+
+ DerivedMesh *dm;
+ RNG *rng;
+ float *tri_weights;
+ float *vertex_weights;
+
+#ifdef USE_DEBUG_COUNT
+ int *debug_count;
+#endif
+} MSurfaceSampleGenerator_Random;
+
+static void generator_random_free(MSurfaceSampleGenerator_Random *gen)
+{
+#ifdef USE_DEBUG_COUNT
+ if (gen->debug_count) {
+ if (gen->tri_weights) {
+ int num = gen->dm->getNumLoopTri(gen->dm);
+ int i;
+ int totsamples = 0;
+
+ printf("Surface Sampling (n=%d):\n", num);
+ for (i = 0; i < num; ++i)
+ totsamples += gen->debug_count[i];
+
+ for (i = 0; i < num; ++i) {
+ float weight = i > 0 ? gen->tri_weights[i] - gen->tri_weights[i-1] : gen->tri_weights[i];
+ int samples = gen->debug_count[i];
+ printf(" %d: W = %f, N = %d/%d = %f\n", i, weight, samples, totsamples, (float)samples / (float)totsamples);
+ }
+ }
+ MEM_freeN(gen->debug_count);
+ }
+#endif
+ if (gen->tri_weights)
+ MEM_freeN(gen->tri_weights);
+ if (gen->vertex_weights)
+ MEM_freeN(gen->vertex_weights);
+ if (gen->rng)
+ BLI_rng_free(gen->rng);
+ MEM_freeN(gen);
+}
+
+/* Find the index in "sum" ar
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list