[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