[Bf-blender-cvs] [8856e155c9a] hair_object: Merge remote-tracking branch 'origin/blender2.8' into hair_object
Lukas Tönne
noreply at git.blender.org
Sun Nov 4 12:25:54 CET 2018
Commit: 8856e155c9af26246d738aae58194f1bd7615aca
Author: Lukas Tönne
Date: Sun Nov 4 11:25:45 2018 +0000
Branches: hair_object
https://developer.blender.org/rB8856e155c9af26246d738aae58194f1bd7615aca
Merge remote-tracking branch 'origin/blender2.8' into hair_object
===================================================================
===================================================================
diff --cc source/blender/blenkernel/intern/mesh_sample.c
index 76d3626f709,00000000000..eec9d830fa2
mode 100644,000000..100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@@ -1,1746 -1,0 +1,1746 @@@
+/*
+ * ***** 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 <limits.h>
+
+#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_ghash.h"
+#include "BLI_math.h"
+#include "BLI_rand.h"
+#include "BLI_sort.h"
+#include "BLI_task.h"
+
+#include "BKE_bvhutils.h"
+#include "BKE_customdata.h"
+#include "BKE_mesh_sample.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
+
+#include "BLI_strict_flags.h"
+
+#define SAMPLE_INDEX_INVALID 0xFFFFFFFF
+
+#define DEFAULT_TASK_SIZE 1024
+
+/* ==== Utility Functions ==== */
+
+static float calc_mesh_area(Mesh *mesh)
+{
+ int numtris = BKE_mesh_runtime_looptri_len(mesh);
+ MVert *mverts = mesh->mvert;
+ MLoop *mloops = mesh->mloop;
+
+ float totarea = 0.0;
+ const MLoopTri *tri = BKE_mesh_runtime_looptri_ensure(mesh);
+ 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(Mesh *mesh, const MLoopTri *tri, const float *loop_weights, float *r_area)
+{
+ const MVert *mverts = mesh->mvert;
+ const MLoop *mloops = mesh->mloop;
+ const unsigned int index1 = tri->tri[0];
+ const unsigned int index2 = tri->tri[1];
+ const unsigned int index3 = tri->tri[2];
+ const MVert *v1 = &mverts[mloops[index1].v];
+ const MVert *v2 = &mverts[mloops[index2].v];
+ const MVert *v3 = &mverts[mloops[index3].v];
+
+ float weight = area_tri_v3(v1->co, v2->co, v3->co);
+ if (r_area) {
+ *r_area = weight;
+ }
+
+ if (loop_weights) {
+ float w1 = loop_weights[index1];
+ float w2 = loop_weights[index2];
+ float w3 = loop_weights[index3];
+
+ weight *= (w1 + w2 + w3) / 3.0f;
+ }
+
+ return weight;
+}
+
+float* BKE_mesh_sample_calc_triangle_weights(Mesh *mesh, const float *loop_weights, float *r_area)
+{
+ int numtris = BKE_mesh_runtime_looptri_len(mesh);
+ int numweights = numtris;
+
+ 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 = BKE_mesh_runtime_looptri_ensure(mesh);
+ for (int i = 0; i < numtris; ++i, ++mt) {
+ tri_weights[i] = totweight;
+
+ float triarea;
+ float triweight = triangle_weight(mesh, mt, loop_weights, &triarea);
+ totarea += triarea;
+ totweight += triweight;
+ }
+ }
+
+ /* normalize */
+ if (totweight > 0.0f) {
+ float norm = 1.0f / totweight;
+ const MLoopTri *mt = BKE_mesh_runtime_looptri_ensure(mesh);
+ 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;
+}
+
+void BKE_mesh_sample_weights_from_loc(MeshSample *sample, Mesh *mesh, int looptri_index, const float loc[3])
+{
+ const MLoop *mloops = mesh->mloop;
+ const MLoopTri *looptri = &BKE_mesh_runtime_looptri_ensure(mesh)[looptri_index];
+ const MVert *mverts = mesh->mvert;
+
+ const unsigned int i1 = mloops[looptri->tri[0]].v;
+ const unsigned int i2 = mloops[looptri->tri[1]].v;
+ const unsigned int i3 = mloops[looptri->tri[2]].v;
+ const float *v1 = mverts[i1].co;
+ const float *v2 = mverts[i2].co;
+ const float *v3 = mverts[i3].co;
+ float w[3];
+
+ interp_weights_tri_v3(w, v1, v2, v3, loc);
+
+ sample->orig_verts[0] = i1;
+ sample->orig_verts[1] = i2;
+ sample->orig_verts[2] = i3;
+ sample->orig_loops[0] = looptri->tri[0];
+ sample->orig_loops[1] = looptri->tri[1];
+ sample->orig_loops[2] = looptri->tri[2];
+ sample->orig_poly = looptri->poly;
+ copy_v3_v3(sample->orig_weights, w);
+}
+
+/* ==== Evaluate ==== */
+
+bool BKE_mesh_sample_is_valid(const struct MeshSample *sample)
+{
+ const unsigned int *v = sample->orig_verts;
+
+ if (BKE_mesh_sample_is_volume_sample(sample))
+ {
+ /* volume sample stores position in the weight vector directly */
+ return true;
+ }
+
+ if (v[0] == SAMPLE_INDEX_INVALID || v[1] == SAMPLE_INDEX_INVALID || v[2] == SAMPLE_INDEX_INVALID)
+ {
+ /* must have 3 valid indices */
+ return false;
+ }
+
+ return true;
+}
+
+bool BKE_mesh_sample_is_volume_sample(const MeshSample *sample)
+{
+ const unsigned int *v = sample->orig_verts;
+ return v[0] == SAMPLE_INDEX_INVALID && v[1] == SAMPLE_INDEX_INVALID && v[2] == SAMPLE_INDEX_INVALID;
+}
+
+/* Evaluate position and normal on the given mesh */
+
+bool BKE_mesh_sample_eval(const Mesh *mesh, const MeshSample *sample, float loc[3], float nor[3], float tang[3])
+{
+ 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 */
+
+ const MVert *mverts = mesh->mvert;
+ const unsigned int totverts = (unsigned int)mesh->totvert;
+ const MVert *v1, *v2, *v3;
+
+ 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;
+ }
+}
+
+/* Evaluate UV coordinates on the given mesh */
+
+bool BKE_mesh_sample_eval_uv(const Mesh *mesh, const MeshSample *sample, int uv_layer, float uv[2])
+{
+ if (BKE_mesh_sample_is_volume_sample(sample)) {
+ /* VOLUME SAMPLE */
+ zero_v2(uv);
+ return true;
+ }
+ else {
+ /* SURFACE SAMPLE */
+
+ const unsigned int totloops = (unsigned int)mesh->totloop;
+ if (sample->orig_loops[0] >= totloops ||
+ sample->orig_loops[1] >= totloops ||
+ sample->orig_loops[2] >= totloops )
+ return false;
+
+ const MLoopUV *mloopuvs = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, uv_layer);
+ if (!mloopuvs)
+ {
+ return false;
+ }
+
+ madd_v2_v2fl(uv, mloopuvs[sample->orig_loops[0]].uv, sample->orig_weights[0]);
+ madd_v2_v2fl(uv, mloopuvs[sample->orig_loops[1]].uv, sample->orig_weights[1]);
+ madd_v2_v2fl(uv, mloopuvs[sample->orig_loops[2]].uv, sample->orig_weights[2]);
+
+ return true;
+ }
+}
+
+/* Evaluate vertex color on the given mesh */
+
+bool BKE_mesh_sample_eval_col(const Mesh *mesh, const MeshSample *sample, int col_layer, MLoopCol *col)
+{
+ if (BKE_mesh_sample_is_volume_sample(sample)) {
+ /* VOLUME SAMPLE */
+ col->r = col->g = col->b = col->a = 0;
+ return true;
+ }
+ else {
+ /* SURFACE SAMPLE */
+
+ const unsigned int totloops = (unsigned int)mesh->totloop;
+ if (sample->orig_loops[0] >= totloops ||
+ sample->orig_loops[1] >= totloops ||
+ sample->orig_loops[2] >= totloops )
+ return false;
+
+ MLoopCol *mloopcols = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPCOL, col_layer);
+ if (!mloopcols)
+ {
+ return false;
+ }
+
+ const unsigned char *col1 = &mloopcols[sample->orig_loops[0]].r;
+ const unsigned char *col2 = &mloopcols[sample->orig_loops[1]].r;
+ const unsigned char *col3 = &mloopcols[sample->orig_loops[2]].r;
+ for (int i = 0; i < 4; ++i)
+ {
+ float f = 0.0f;
+ f += (float)col1[i] * sample->orig_weights[0];
+ f += (float)col2[i] * sample->orig_weights[1];
+ f += (float)col3[i] * sample->orig_weights[2];
+ ((unsigned char *)col)[i] = (unsigned cha
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list