[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