[Bf-blender-cvs] [34a2660] mesh-transfer-data: Add new mapping code for M2MMAP_MODE_EDGE_EDGEINTERP_VNORPROJ.
Bastien Montagne
noreply at git.blender.org
Wed Oct 15 21:37:22 CEST 2014
Commit: 34a2660f2b2e3559d88b01f89887f1f7ba5ead5c
Author: Bastien Montagne
Date: Wed Oct 15 19:32:55 2014 +0200
Branches: mesh-transfer-data
https://developer.blender.org/rB34a2660f2b2e3559d88b01f89887f1f7ba5ead5c
Add new mapping code for M2MMAP_MODE_EDGE_EDGEINTERP_VNORPROJ.
This is similar to M2MMAP_MODE_POLY_POLYINTERP_PNORPROJ, but for edges.
Also fixed a bunch of logical flaws in this poly one.
All this remains 100% theory currently, not tested at all yet.
Also some minor cleanup.
===================================================================
M source/blender/blenkernel/BKE_mesh_mapping.h
M source/blender/blenkernel/intern/bvhutils.c
M source/blender/blenkernel/intern/mesh_mapping.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index a4e25f2..bb783da 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -240,8 +240,8 @@ enum {
/* Nearest edge of nearest poly (using mid-point). */
M2MMAP_MODE_EDGE_POLY_NEAREST = M2MMAP_MODE_EDGE | M2MMAP_USE_POLY | M2MMAP_USE_NEAREST,
- /* Project dest edge along both its vertices' normals, and use shortest edge-path between hitting points. */
- //M2MMAP_MODE_EDGE_EDGEINTERP_VNORPROJ = M2MMAP_MODE_EDGE | M2MMAP_USE_VERT | M2MMAP_USE_NORPROJ | M2MMAP_USE_INTERP,
+ /* Cast a set of rays from along dest edge, interpolating its vertices' normals, and use hit source edges. */
+ M2MMAP_MODE_EDGE_EDGEINTERP_VNORPROJ = M2MMAP_MODE_EDGE | M2MMAP_USE_VERT | M2MMAP_USE_NORPROJ | M2MMAP_USE_INTERP,
/* ***** Target's polygons ***** */
M2MMAP_MODE_POLY = 1 << 26,
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 6053ae3..db2ef85 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -254,9 +254,8 @@ static float dot_v3v3v3(const float p[3], const float a[3], const float b[3])
/* Helper, does all the point-spherecast work actually. */
static void mesh_verts_spherecast_do(
- const BVHTreeFromMesh *data, int index, const float v[3], const BVHTreeRay *ray, BVHTreeRayHit *hit)
+ const BVHTreeFromMesh *UNUSED(data), int index, const float v[3], const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
- const float radius_sq = SQUARE(data->sphere_radius);
float dist;
const float *r1;
float r2[3], i1[3];
@@ -291,7 +290,6 @@ static void mesh_edges_spherecast(void *userdata, int index, const BVHTreeRay *r
MVert *vert = data->vert;
MEdge *edge = &data->edge[index];
- const float radius_sq = SQUARE(data->sphere_radius);
float dist;
const float *v1, *v2, *r1;
float r2[3], i1[3], i2[3];
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 9a46dc5..6ecb0dc 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -1254,6 +1254,94 @@ void BKE_dm2mesh_mapping_edges_compute(
MEM_freeN(vcos_src);
}
+ else if (mode == M2MMAP_MODE_EDGE_EDGEINTERP_VNORPROJ) {
+ const int numedges_src = dm_src->getNumEdges(dm_src);
+
+ /* Here it's simpler to just allocate for all edges :/ */
+ int *indices = MEM_mallocN(sizeof(*indices) * (size_t)numedges_src, __func__);
+ float *weights = MEM_mallocN(sizeof(*weights) * (size_t)numedges_src, __func__);
+
+ bvhtree_from_mesh_edges(&treedata, dm_src, 0.0f, 2, 6);
+
+ for (i = 0; i < numedges_dst; i++) {
+ /* For each dst edge, we sample some rays from it (interpolated from its vertices)
+ * and use their hits to interpolate from source edges. */
+ const MEdge *me = &edges_dst[i];
+ float tmp_co[3], v1_co[3], v2_co[3];
+ float tmp_no[3], v1_no[3], v2_no[3];
+
+ int grid_size;
+ float edge_dst_len;
+ float grid_step;
+
+ float totweights = 0.0f;
+ float hitdist_accum = 0.0f;
+ int nbr_sources = 0;
+ int j;
+
+ copy_v3_v3(v1_co, verts_dst[me->v1].co);
+ copy_v3_v3(v2_co, verts_dst[me->v2].co);
+
+ normal_short_to_float_v3(v1_no, verts_dst[me->v1].no);
+ normal_short_to_float_v3(v2_no, verts_dst[me->v2].no);
+
+ /* We do our transform here, allows to interpolate from normals already in src space. */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, v1_co);
+ BLI_space_transform_apply(space_transform, v2_co);
+ BLI_space_transform_apply_normal(space_transform, v1_no);
+ BLI_space_transform_apply_normal(space_transform, v2_no);
+ }
+
+ fill_vn_fl(weights, (int)numedges_src, 0.0f);
+
+ /* We adjust our ray-casting grid to ray_radius (the smaller, the more rays are cast),
+ * with lower/upper bounds. */
+ edge_dst_len = len_v3v3(v1_co, v2_co);
+
+ grid_size = (int)((edge_dst_len / ray_radius) + 0.5f);
+ CLAMP(grid_size, 5, 100); /* min 5 rays/edge, max 100. */
+
+ grid_step = edge_dst_len / (float)grid_size;
+
+ /* And now we can cast all our rays, and see what we get! */
+ for (j = 0; j < grid_size; j++) {
+ const float fac = grid_step * (float)j;
+ interp_v3_v3v3(tmp_co, v1_co, v2_co, fac);
+ interp_v3_v3v3_slerp_safe(tmp_no, v1_no, v2_no, fac);
+
+ /* Note we handle dest to src space conversion ourself, here! */
+ hitdist = bke_mesh2mesh_bvhtree_query_raycast(&treedata, &rayhit, NULL,
+ tmp_co, tmp_no, ray_radius, max_dist);
+
+ if (rayhit.index >= 0 && hitdist <= max_dist) {
+ weights[rayhit.index] += 1.0f;
+ totweights += 1.0f;
+ hitdist_accum += hitdist;
+ }
+ }
+ if (totweights > 0.0f) {
+ for (j = 0; j < (int)numedges_src; j++) {
+ if (!weights[j]) {
+ continue;
+ }
+ /* Note: nbr_sources is always <= j! */
+ weights[nbr_sources] = weights[j] / totweights;
+ indices[nbr_sources] = j;
+ nbr_sources++;
+ }
+ bke_mesh2mesh_mapping_item_define(r_map, i, hitdist_accum / totweights, 0,
+ nbr_sources, indices, weights);
+ }
+ else {
+ /* No source for this dest edge! */
+ bke_mesh2mesh_mapping_item_define(r_map, i, FLT_MAX, 0, 0, NULL, NULL);
+ }
+ }
+
+ MEM_freeN(indices);
+ MEM_freeN(weights);
+ }
else {
printf("WARNING! Unsupported mesh-to-mesh edge mapping mode (%d)!\n", mode);
memset(r_map->items, 0, sizeof(*r_map->items) * (size_t)numedges_dst);
@@ -1335,13 +1423,12 @@ void BKE_dm2mesh_mapping_polys_compute(
for (i = 0; i < numpolys_dst; i++) {
MPoly *mp = &polys_dst[i];
float tmp_co[3], tmp_no[3];
- const float radius = 1.0e-6f;
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
hitdist = bke_mesh2mesh_bvhtree_query_raycast(&treedata, &rayhit, space_transform,
- tmp_co, tmp_no, radius, max_dist);
+ tmp_co, tmp_no, ray_radius, max_dist);
if (rayhit.index >= 0 && hitdist <= max_dist) {
bke_mesh2mesh_mapping_item_define(r_map, i, rayhit.dist, 0,
@@ -1366,15 +1453,16 @@ void BKE_dm2mesh_mapping_polys_compute(
for (i = 0; i < numpolys_dst; i++) {
/* For each dst poly, we sample some rays from it (2D grid in pnor space)
* and use their hits to interpolate from source polys. */
+ /* Note: dst poly is early-converted into src space! */
MPoly *mp = &polys_dst[i];
float tmp_co[3], tmp_no[3];
- const float radius = 1.0e-6f;
- const int grid_size = 10;
+ int grid_size;
const float zvec[3] = {0.0f, 0.0f, 1.0f};
float pcent_dst[3];
float to_pnor_2d_mat[3][3], from_pnor_2d_mat[3][3];
float poly_dst_2d_min_x, poly_dst_2d_min_y, poly_dst_2d_max_x, poly_dst_2d_max_y, poly_dst_2d_z;
+ float poly_dst_2d_size_x, poly_dst_2d_size_y;
float grid_step_x, grid_step_y;
float totweights = 0.0f;
@@ -1382,7 +1470,14 @@ void BKE_dm2mesh_mapping_polys_compute(
int nbr_sources = 0;
int j, k;
+ BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, pcent_dst);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
+ /* We do our transform here, else it'd be redone by raycast helper for each ray, ugh! */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, pcent_dst);
+ BLI_space_transform_apply_normal(space_transform, tmp_no);
+ }
+
fill_vn_fl(weights, (int)numpolys_src, 0.0f);
if ((size_t)mp->totloop > tmp_poly_size) {
@@ -1390,21 +1485,23 @@ void BKE_dm2mesh_mapping_polys_compute(
poly_vcos_2d = MEM_reallocN(poly_vcos_2d, sizeof(*poly_vcos_2d) * tmp_poly_size);
}
- rotation_between_vecs_to_mat3(to_pnor_2d_mat, poly_nors_dst[i], zvec);
+ rotation_between_vecs_to_mat3(to_pnor_2d_mat, tmp_no, zvec);
invert_m3_m3(from_pnor_2d_mat, to_pnor_2d_mat);
- BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, pcent_dst);
-
- mul_m3_v3(to_pnor_2d_mat, tmp_co);
- poly_dst_2d_z = tmp_co[2];
- printf("%f\n", tmp_co[2]);
+ mul_m3_v3(to_pnor_2d_mat, pcent_dst);
+ poly_dst_2d_z = pcent_dst[2];
+ printf("%f\n", pcent_dst[2]);
+ /* Get (2D) bounding square of our poly. */
poly_dst_2d_min_x = poly_dst_2d_min_y = FLT_MAX;
poly_dst_2d_max_x = poly_dst_2d_max_y = -FLT_MAX;
for (j = 0; j < mp->totloop; j++) {
MLoop *ml = &loops_dst[j + mp->loopstart];
copy_v3_v3(tmp_co, verts_dst[ml->v].co);
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, tmp_co);
+ }
mul_m3_v3(to_pnor_2d_mat, tmp_co);
copy_v2_v2(poly_vcos_2d[j], tmp_co);
printf("%f\n", tmp_co[2]);
@@ -1414,9 +1511,18 @@ void BKE_dm2mesh_mapping_polys_compute(
if (tmp_co[1] < poly_dst_2d_min_y) poly_dst_2d_min_y = tmp_co[1];
}
- grid_step_x = (poly_dst_2d_max_x - poly_dst_2d_min_x) / (float)grid_size;
- grid_step_y = (poly_dst_2d_max_y - poly_dst_2d_min_y) / (float)grid_size;
+ /* We adjust our ray-casting grid to ray_radius (the smaller, the more rays are cast),
+ * with lower/upper bounds. */
+ poly_dst_2d_size_x = poly_dst_2d_max_x - poly_dst_2d_min_x;
+ poly_dst_2d_size_y = poly_dst_2d_max_y - poly_dst_2d_min_y;
+ grid_size = (int)((max_ff(poly_dst_2d_size_x, poly_dst_2d_size_y) / ray_radius) + 0.5f);
+ CLAMP(grid_size, 4, 20); /* min 16 rays/face, max 400. */
+
+ grid_step_x = poly_dst_2d_size_x / (float)grid_size;
+ grid_step_y = poly_dst_2d_size_y / (float)grid_size;
+
+ /* And now we can cast all our rays, and see what we get! */
for (j = 0; j < grid_size; j++) {
for (k = 0; k < grid_size; k++) {
tmp_co[0] = poly_dst_2d_min_x + grid_step_x * (float)j;
@@ -1431,12 +1537,11 @@ void BKE_dm2mesh_mapping_polys_compute(
tmp_co[2] = poly_dst_2d_z;
mul_m3_v3(from_pnor_2d_mat, tmp
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list