48 const float max_dist_sq,
52 if (nearest->
index != -1) {
54 if (nearest->
dist_sq > max_dist_sq) {
66 if ((nearest->
index != -1) && (nearest->
dist_sq <= max_dist_sq)) {
86 rayhit->
dist = max_dist;
95 if (rayhit_tmp.
dist < rayhit->
dist) {
99 if ((rayhit->
index != -1) && (rayhit->
dist <= max_dist)) {
100 *r_hit_dist = rayhit->
dist;
116 const float (*vert_positions_dst)[3],
117 const int numverts_dst,
130 for (i = 0; i < numverts_dst; i++) {
136 if (space_transform) {
141 result += 1.0f / (hit_dist + 1.0f);
152 printf(
"%s: Computed difference between meshes (the lower the better): %f\n", __func__,
result);
171 const float (*vcos)[3],
175 float center[3], covmat[3][3];
176 float eigen_val[3], eigen_vec[3][3];
183 cos =
static_cast<float(*)[3]
>(
MEM_mallocN(
sizeof(*
cos) *
size_t(numverts), __func__));
184 memcpy(
cos, positions,
sizeof(
float[3]) *
size_t(numverts));
189 vcos =
static_cast<const float(*)[3]
>((
void *)
cos);
229 for (i = 0; i < 3; i++) {
230 float evi = eigen_val[i];
237 evi = (evi < 1e-6f && evi > -1e-6f) ? ((evi < 0.0f) ? -1e-3f : 1e-3f) :
sqrtf_signed(evi);
246 const int numverts_dst,
252 const float mirrors[][3] = {
262 const float(*mirr)[3];
264 float mat_src[4][4], mat_dst[4][4], best_mat_dst[4][4];
265 float best_match =
FLT_MAX, match;
267 const int numverts_src = me_src->
verts_num;
270 nullptr,
reinterpret_cast<const float(*)[3]
>(positions_src.
data()), numverts_src, mat_src);
275 r_space_transform, vert_positions_dst, numverts_dst, me_src);
280 for (mirr = mirrors; (*mirr)[0]; mirr++) {
287 r_space_transform, vert_positions_dst, numverts_dst, me_src);
288 if (match < best_match) {
323 map->
items =
nullptr;
331 const int sources_num,
332 const int *indices_src,
333 const float *weights_src)
364 const float point[3],
367 const bool use_loops,
370 const bool do_weights,
371 int *r_closest_index)
376 const int sources_num =
int(face.
size());
379 if (
size_t(sources_num) > *buff_size) {
380 *buff_size = size_t(sources_num);
381 *vcos =
static_cast<float(*)[3]
>(
MEM_reallocN(*vcos,
sizeof(**vcos) * *buff_size));
384 *weights =
static_cast<float *
>(
MEM_reallocN(*weights,
sizeof(**weights) * *buff_size));
388 for (i = 0, vco = *vcos, index = *
indices; i < sources_num; i++, vco++, index++) {
389 const int vert = corner_verts[face[i]];
390 *index = use_loops ?
int(face[i]) : vert;
392 if (r_closest_index) {
395 if (dist_sq < ref_dist_sq) {
396 ref_dist_sq = dist_sq;
397 *r_closest_index = *index;
438#define MREMAP_RAYCAST_APPROXIMATE_NR 3
440#define MREMAP_RAYCAST_APPROXIMATE_FAC 5.0f
443#define MREMAP_RAYCAST_TRI_SAMPLES_MIN 4
444#define MREMAP_RAYCAST_TRI_SAMPLES_MAX 20
447#define MREMAP_DEFAULT_BUFSIZE 32
451 const float max_dist,
452 const float ray_radius,
453 const float (*vert_positions_dst)[3],
454 const int numverts_dst,
459 const float full_weight = 1.0f;
460 const float max_dist_sq = max_dist * max_dist;
469 for (i = 0; i < numverts_dst; i++) {
478 float tmp_co[3], tmp_no[3];
484 for (i = 0; i < numverts_dst; i++) {
488 if (space_transform) {
509 for (i = 0; i < numverts_dst; i++) {
513 if (space_transform) {
520 const float *v1cos = positions_src[edge[0]];
521 const float *v2cos = positions_src[edge[1]];
526 const int index = (dist_v1 > dist_v2) ? edge[1] : edge[0];
538 CLAMP(weights[0], 0.0f, 1.0f);
539 weights[1] = 1.0f - weights[0];
562 float(*vcos)[3] =
static_cast<float(*)[3]
>(
563 MEM_mallocN(
sizeof(*vcos) * tmp_buff_size, __func__));
565 float *weights =
static_cast<float *
>(
566 MEM_mallocN(
sizeof(*weights) * tmp_buff_size, __func__));
571 for (i = 0; i < numverts_dst; i++) {
576 if (space_transform) {
582 &treedata, &rayhit, tmp_co, tmp_no, ray_radius, max_dist, &hit_dist))
584 const int face_index = tri_faces[rayhit.
index];
608 for (i = 0; i < numverts_dst; i++) {
612 if (space_transform) {
617 &treedata, &nearest, tmp_co, max_dist_sq, &hit_dist))
619 const int face_index = tri_faces[nearest.
index];
665 CLOG_WARN(&
LOG,
"Unsupported mesh-to-mesh vertex mapping mode (%d)!", mode);
666 memset(r_map->
items, 0,
sizeof(*r_map->
items) *
size_t(numverts_dst));
675 const float max_dist,
676 const float ray_radius,
677 const float (*vert_positions_dst)[3],
678 const int numverts_dst,
680 const int numedges_dst,
686 const float full_weight = 1.0f;
687 const float max_dist_sq = max_dist * max_dist;
696 for (i = 0; i < numedges_dst; i++) {
705 float tmp_co[3], tmp_no[3];
708 const int num_verts_src = me_src->
verts_num;
716 HitData *v_dst_to_src_map =
static_cast<HitData *
>(
717 MEM_mallocN(
sizeof(*v_dst_to_src_map) *
size_t(numverts_dst), __func__));
719 for (i = 0; i < numverts_dst; i++) {
720 v_dst_to_src_map[i].hit_dist = -1.0f;
726 edges_src, num_verts_src, vert_to_edge_src_offsets, vert_to_edge_src_indices);
731 for (i = 0; i < numedges_dst; i++) {
734 int best_eidx_src = -1;
738 const int vidx_dst = j ? e_dst[0] : e_dst[1];
741 if (v_dst_to_src_map[vidx_dst].hit_dist == -1.0f) {
742 copy_v3_v3(tmp_co, vert_positions_dst[vidx_dst]);
745 if (space_transform) {
750 &treedata, &nearest, tmp_co, max_dist_sq, &hit_dist))
752 v_dst_to_src_map[vidx_dst].hit_dist = hit_dist;
753 v_dst_to_src_map[vidx_dst].index = nearest.
index;
757 v_dst_to_src_map[vidx_dst].hit_dist =
FLT_MAX;
765 const int vidx_dst = j ? e_dst[0] : e_dst[1];
766 const float first_dist = v_dst_to_src_map[vidx_dst].hit_dist;
767 const int vidx_src = v_dst_to_src_map[vidx_dst].index;
775 eidx_src = vert_to_edge_src_map[vidx_src].
data();
776 k =
int(vert_to_edge_src_map[vidx_src].
size());
778 for (; k--; eidx_src++) {
780 const float *other_co_src =
782 const float *other_co_dst =
784 const float totdist = first_dist +
len_v3v3(other_co_src, other_co_dst);
786 if (totdist < best_totdist) {
787 best_totdist = totdist;
788 best_eidx_src = *eidx_src;
793 if (best_eidx_src >= 0) {
794 const float *co1_src = positions_src[edges_src[best_eidx_src][0]];
795 const float *co2_src = positions_src[edges_src[best_eidx_src][1]];
796 const float *co1_dst = vert_positions_dst[e_dst[0]];
797 const float *co2_dst = vert_positions_dst[e_dst[1]];
798 float co_src[3], co_dst[3];
802 co1_src, co2_src, co1_dst, co2_dst, co_src, co_dst);
803 if (isect_type != 0) {
806 if (fac_src < 0.0f) {
809 else if (fac_src > 1.0f) {
812 if (fac_dst < 0.0f) {
815 else if (fac_dst > 1.0f) {
819 hit_dist =
len_v3v3(co_dst, co_src);
834 for (i = 0; i < numedges_dst; i++) {
836 vert_positions_dst[edges_dst[i][0]],
837 vert_positions_dst[edges_dst[i][1]],
841 if (space_transform) {
864 for (i = 0; i < numedges_dst; i++) {
866 vert_positions_dst[edges_dst[i][0]],
867 vert_positions_dst[edges_dst[i][1]],
871 if (space_transform) {
877 const int face_index = tri_faces[nearest.
index];
879 const int *corner_edge_src = &corner_edges_src[face_src.
start()];
880 int nloops =
int(face_src.
size());
882 int best_eidx_src = -1;
884 for (; nloops--; corner_edge_src++) {
886 const float *co1_src = positions_src[edge_src[0]];
887 const float *co2_src = positions_src[edge_src[1]];
893 if (dist_sq < best_dist_sq) {
894 best_dist_sq = dist_sq;
895 best_eidx_src = *corner_edge_src;
898 if (best_eidx_src >= 0) {
909 const int num_rays_min = 5, num_rays_max = 100;
910 const int numedges_src = me_src->
edges_num;
913 int *
indices =
static_cast<int *
>(
916 float *weights =
static_cast<float *
>(
917 MEM_mallocN(
sizeof(*weights) *
size_t(numedges_src), __func__));
923 for (i = 0; i < numedges_dst; i++) {
927 float v1_co[3], v2_co[3];
928 float v1_no[3], v2_no[3];
934 float totweights = 0.0f;
935 float hit_dist_accum = 0.0f;
939 copy_v3_v3(v1_co, vert_positions_dst[edge[0]]);
940 copy_v3_v3(v2_co, vert_positions_dst[edge[1]]);
946 if (space_transform) {
957 edge_dst_len =
len_v3v3(v1_co, v2_co);
959 grid_size =
int((edge_dst_len / ray_radius) + 0.5f);
960 CLAMP(grid_size, num_rays_min, num_rays_max);
963 grid_step = 1.0f /
float(grid_size);
966 for (j = 0; j < grid_size; j++) {
967 const float fac = grid_step *
float(j);
977 &treedata, &rayhit, tmp_co, tmp_no, ray_radius /
w, max_dist, &hit_dist))
979 weights[rayhit.
index] +=
w;
981 hit_dist_accum += hit_dist;
990 if (totweights > (
float(grid_size) / 2.0f)) {
991 for (j = 0; j <
int(numedges_src); j++) {
996 weights[sources_num] = weights[j] / totweights;
1001 r_map, i, hit_dist_accum / totweights, 0, sources_num,
indices, weights);
1013 CLOG_WARN(&
LOG,
"Unsupported mesh-to-mesh edge mapping mode (%d)!", mode);
1014 memset(r_map->
items, 0,
sizeof(*r_map->
items) *
size_t(numedges_dst));
1022#define POLY_CENTER_INIT 1
1023#define POLY_COMPLETE 2
1027 const int island_index,
1035 const bool is_edge_innercut,
1036 const int *face_island_index_map,
1037 float (*face_centers)[3],
1043 for (i = 0; i < edge_to_face_map[edge_idx].
size(); i++) {
1044 const int pidx = edge_to_face_map[edge_idx][i];
1046 const int pidx_isld = islands ? face_island_index_map[pidx] : pidx;
1051 face_island_indices[i] = -1;
1056 face_island_indices[i] = pidx_isld;
1069 const int pidx_isld_other = face_island_indices[j];
1071 if (pidx_isld_other == -1 || face_status[pidx_isld_other] ==
POLY_COMPLETE) {
1075 dist_cost =
len_v3v3(face_centers[pidx_isld_other], face_centers[pidx_isld]);
1079 face_island_indices[i] = pidx_isld;
1086 const int island_index,
1098 int *face_island_index_map =
nullptr;
1101 const int node_num = islands ? island_face_map->
count :
int(
faces.size());
1103 MEM_callocN(
sizeof(*face_status) *
size_t(node_num), __func__));
1104 float(*face_centers)[3];
1111 face_centers =
static_cast<float(*)[3]
>(
1117 r_as_graph->
mem,
sizeof(*face_island_index_map) *
size_t(
faces.size())));
1118 for (i = island_face_map->
count; i--;) {
1119 face_island_index_map[island_face_map->
indices[i]] = i;
1124 for (i = island_einnercut_map->
count; i--;) {
1131 island_einnercut_map->
indices[i],
1135 face_island_index_map,
1141 for (pidx_isld = node_num; pidx_isld--;) {
1142 const int pidx = islands ? island_face_map->
indices[pidx_isld] : pidx_isld;
1148 for (
const int edge : corner_edges.
slice(
faces[pidx])) {
1163 face_island_index_map,
1175#undef POLY_CENTER_INIT
1184 const int node_idx_curr,
1185 const int node_idx_next,
1186 const int node_idx_dst)
1188 float *co_next, *co_dest;
1204 return (link ? (as_solution->
g_costs[node_idx_curr] + link->
cost) : 0.0f) +
1208#define ASTAR_STEPS_MAX 64
1212 const float max_dist,
1213 const float ray_radius,
1214 const Mesh *mesh_dst,
1215 const float (*vert_positions_dst)[3],
1216 const int numverts_dst,
1217 const int *corner_verts_dst,
1218 const int numloops_dst,
1222 const float islands_precision_src,
1226 const float full_weight = 1.0f;
1227 const float max_dist_sq = max_dist * max_dist;
1230 BLI_assert((islands_precision_src >= 0.0f) && (islands_precision_src <= 1.0f));
1237 for (
int i = 0; i < numloops_dst; i++) {
1247 float tmp_co[3], tmp_no[3];
1252 bool use_islands =
false;
1256 const int isld_steps_src = (islands_precision_src ?
1276 MeshElemMap *face_to_corner_tri_map_src =
nullptr;
1277 int *face_to_corner_tri_map_src_buff =
nullptr;
1283 const int num_verts_src = me_src->
verts_num;
1292 float(*vcos_interp)[3] =
nullptr;
1293 int *indices_interp =
nullptr;
1294 float *weights_interp =
nullptr;
1296 int tindex, pidx_dst, lidx_dst, plidx_dst, pidx_src, lidx_src, plidx_src;
1301 if (!use_from_vert) {
1302 vcos_interp =
static_cast<float(*)[3]
>(
1303 MEM_mallocN(
sizeof(*vcos_interp) * buff_size_interp, __func__));
1304 indices_interp =
static_cast<int *
>(
1305 MEM_mallocN(
sizeof(*indices_interp) * buff_size_interp, __func__));
1306 weights_interp =
static_cast<float *
>(
1307 MEM_mallocN(
sizeof(*weights_interp) * buff_size_interp, __func__));
1313 const bool need_pnors_src = need_lnors_src ||
1315 const bool need_pnors_dst = need_lnors_dst || need_pnors_src;
1317 if (need_pnors_dst) {
1318 face_normals_dst = mesh_dst->face_normals();
1320 if (need_lnors_dst) {
1321 loop_normals_dst = mesh_dst->corner_normals();
1323 if (need_pnors_src) {
1324 face_normals_src = me_src->face_normals();
1326 if (need_lnors_src) {
1327 loop_normals_src = me_src->corner_normals();
1331 if (use_from_vert) {
1332 vert_to_loop_map_src = me_src->vert_to_corner_map();
1334 vert_to_face_map_src = me_src->vert_to_face_map();
1341 int(edges_src.
size()),
1342 edge_to_face_src_offsets,
1343 edge_to_face_src_indices);
1345 if (use_from_vert) {
1346 loop_to_face_map_src = me_src->corner_to_face_map();
1350 positions_src, corner_verts_src.
slice(faces_src[i]));
1362 if (gen_islands_src) {
1363 const bool *uv_seams =
static_cast<const bool *
>(
1365 use_islands = gen_islands_src(
reinterpret_cast<const float(*)[3]
>(positions_src.
data()),
1368 int(edges_src.
size()),
1371 corner_verts_src.
data(),
1372 corner_edges_src.
data(),
1373 int(corner_verts_src.
size()),
1376 num_trees = use_islands ? island_store.
islands_num : 1;
1378 MEM_callocN(
sizeof(*treedata) *
size_t(num_trees), __func__));
1379 if (isld_steps_src) {
1381 MEM_callocN(
sizeof(*as_graphdata) *
size_t(num_trees), __func__));
1396 if (isld_steps_src) {
1402 if (isld_steps_src) {
1403 for (tindex = 0; tindex < num_trees; tindex++) {
1407 edge_to_face_map_src,
1408 int(edges_src.
size()),
1412 &as_graphdata[tindex]);
1417 if (use_from_vert) {
1421 for (tindex = 0; tindex < num_trees; tindex++) {
1423 int num_verts_active = 0;
1424 verts_active.
fill(
false);
1425 for (
int i = 0; i < isld->
count; i++) {
1426 for (
const int vidx_src : corner_verts_src.
slice(faces_src[isld->
indices[i]])) {
1427 if (!verts_active[vidx_src]) {
1428 verts_active[vidx_src].set();
1434 &treedata[tindex], positions_src, verts_active, num_verts_active, 0.0, 2, 6);
1444 corner_tris_src = me_src->corner_tris();
1445 tri_faces_src = me_src->corner_tri_faces();
1448 for (tindex = 0; tindex < num_trees; tindex++) {
1449 int corner_tris_num_active = 0;
1450 corner_tris_active.
fill(
false);
1454 corner_tris_active[i].set();
1455 corner_tris_num_active++;
1463 corner_tris_num_active,
1477 MEM_mallocN(
sizeof(*islands_res) *
size_t(num_trees), __func__));
1478 for (tindex = 0; tindex < num_trees; tindex++) {
1480 MEM_mallocN(
sizeof(**islands_res) * islands_res_buff_size, __func__));
1484 for (pidx_dst = 0; pidx_dst < faces_dst.
size(); pidx_dst++) {
1491 bool pcent_dst_valid =
false;
1494 copy_v3_v3(pnor_dst, face_normals_dst[pidx_dst]);
1495 if (space_transform) {
1500 if (
size_t(face_dst.
size()) > islands_res_buff_size) {
1502 for (tindex = 0; tindex < num_trees; tindex++) {
1504 MEM_reallocN(islands_res[tindex],
sizeof(**islands_res) * islands_res_buff_size));
1508 for (tindex = 0; tindex < num_trees; tindex++) {
1511 for (plidx_dst = 0; plidx_dst < face_dst.
size(); plidx_dst++) {
1512 const int vert_dst = corner_verts_dst[face_dst.
start() + plidx_dst];
1513 if (use_from_vert) {
1516 copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]);
1520 if (space_transform) {
1528 float best_nor_dot = -2.0f;
1529 float best_sqdist_fallback =
FLT_MAX;
1530 int best_index_src = -1;
1534 if (space_transform) {
1538 nors_src = loop_normals_src;
1539 vert_to_refelem_map_src = vert_to_loop_map_src[nearest.
index];
1542 nor_dst = &pnor_dst;
1543 nors_src = face_normals_src;
1544 vert_to_refelem_map_src = vert_to_face_map_src[nearest.
index];
1547 for (
const int index_src : vert_to_refelem_map_src) {
1549 const float dot =
dot_v3v3(nors_src[index_src], *nor_dst);
1552 loop_to_face_map_src[index_src] :
1559 int(faces_src[pidx_src].start()));
1567 if (
dot > best_nor_dot - 1e-6f) {
1573 if (!pcent_dst_valid) {
1578 pcent_dst_valid =
true;
1580 pcent_src = face_cents_src[pidx_src];
1583 if ((
dot > best_nor_dot + 1e-6f) || (sqdist < best_sqdist_fallback)) {
1585 best_sqdist_fallback = sqdist;
1586 best_index_src = index_src;
1590 if (best_index_src == -1) {
1592 best_nor_dot = -1.0f;
1599 for (plidx_src = 0; plidx_src < face_src.
size(); plidx_src++) {
1600 const int vert_src = corner_verts_src[face_src.
start() + plidx_src];
1601 if (vert_src == nearest.
index) {
1602 best_index_src = plidx_src +
int(face_src.
start());
1607 best_nor_dot = (best_nor_dot + 1.0f) * 0.5f;
1608 islands_res[tindex][plidx_dst].
factor = hit_dist ? (best_nor_dot / hit_dist) : 1e18f;
1609 islands_res[tindex][plidx_dst].
hit_dist = hit_dist;
1610 islands_res[tindex][plidx_dst].
index_src = best_index_src;
1614 islands_res[tindex][plidx_dst].
factor = 0.0f;
1616 islands_res[tindex][plidx_dst].
index_src = -1;
1623 copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]);
1627 if (space_transform) {
1634 tdata, &rayhit, tmp_co, tmp_no, ray_radius /
w, max_dist, &hit_dist))
1636 islands_res[tindex][plidx_dst].
factor = (hit_dist ? (1.0f / hit_dist) : 1e18f) *
w;
1637 islands_res[tindex][plidx_dst].
hit_dist = hit_dist;
1638 islands_res[tindex][plidx_dst].
index_src = tri_faces[rayhit.
index];
1639 copy_v3_v3(islands_res[tindex][plidx_dst].hit_point, rayhit.
co);
1652 copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]);
1656 if (space_transform) {
1662 islands_res[tindex][plidx_dst].
factor = 0.0f;
1665 tdata, &nearest, tmp_co, max_dist_sq, &hit_dist))
1667 islands_res[tindex][plidx_dst].
hit_dist = hit_dist;
1668 islands_res[tindex][plidx_dst].
index_src = tri_faces[nearest.
index];
1669 copy_v3_v3(islands_res[tindex][plidx_dst].hit_point, nearest.
co);
1674 islands_res[tindex][plidx_dst].
index_src = -1;
1679 copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]);
1683 if (space_transform) {
1689 islands_res[tindex][plidx_dst].
factor = hit_dist ? (1.0f / hit_dist) : 1e18f;
1690 islands_res[tindex][plidx_dst].
hit_dist = hit_dist;
1691 islands_res[tindex][plidx_dst].
index_src = tri_faces[nearest.
index];
1692 copy_v3_v3(islands_res[tindex][plidx_dst].hit_point, nearest.
co);
1696 islands_res[tindex][plidx_dst].
factor = 0.0f;
1698 islands_res[tindex][plidx_dst].
index_src = -1;
1718 int *face_island_index_map =
nullptr;
1719 int pidx_src_prev = -1;
1722 float best_island_fac = 0.0f;
1723 int best_island_index = -1;
1725 for (tindex = 0; tindex < num_trees; tindex++) {
1726 float island_fac = 0.0f;
1728 for (plidx_dst = 0; plidx_dst < face_dst.
size(); plidx_dst++) {
1729 island_fac += islands_res[tindex][plidx_dst].
factor;
1733 if (island_fac > best_island_fac) {
1734 best_island_fac = island_fac;
1735 best_island_index = tindex;
1739 if (best_island_index != -1 && isld_steps_src) {
1740 best_island = use_islands ? island_store.
islands[best_island_index] :
nullptr;
1741 as_graph = &as_graphdata[best_island_index];
1742 face_island_index_map = (
int *)as_graph->
custom_data;
1746 for (plidx_dst = 0; plidx_dst < face_dst.
size(); plidx_dst++) {
1748 lidx_dst = plidx_dst +
int(face_dst.
start());
1750 if (best_island_index == -1) {
1758 isld_res = &islands_res[best_island_index][plidx_dst];
1759 if (use_from_vert) {
1762 if (lidx_src >= 0) {
1763 pidx_src = loop_to_face_map_src[lidx_src];
1765 if (!
ELEM(pidx_src_prev, -1, pidx_src) && isld_steps_src) {
1766 int pidx_isld_src, pidx_isld_src_prev;
1767 if (face_island_index_map) {
1768 pidx_isld_src = face_island_index_map[pidx_src];
1769 pidx_isld_src_prev = face_island_index_map[pidx_src_prev];
1772 pidx_isld_src = pidx_src;
1773 pidx_isld_src_prev = pidx_src_prev;
1790 int last_valid_pidx_isld_src = -1;
1792 for (
int i = as_solution.
steps - 1; i--;) {
1795 pidx_isld_src = as_solution.
prev_nodes[pidx_isld_src];
1799 last_valid_pidx_isld_src = pidx_isld_src;
1802 if (last_valid_pidx_isld_src != -1) {
1807 copy_v3_v3(tmp_co, vert_positions_dst[corner_verts_dst[lidx_dst]]);
1811 if (space_transform) {
1815 pidx_src = (use_islands ? best_island->
indices[last_valid_pidx_isld_src] :
1816 last_valid_pidx_isld_src);
1818 for (
const int64_t corner : face_src) {
1819 const int vert_src = corner_verts_src[corner];
1821 if (dist_sq < best_dist_sq) {
1822 best_dist_sq = dist_sq;
1823 lidx_src =
int(corner);
1836 pidx_src_prev = pidx_src;
1843 r_map, lidx_dst,
FLT_MAX, best_island_index, 0,
nullptr,
nullptr);
1849 if (pidx_src >= 0) {
1851 int best_loop_index_src;
1855 if (!
ELEM(pidx_src_prev, -1, pidx_src) && isld_steps_src) {
1856 int pidx_isld_src, pidx_isld_src_prev;
1857 if (face_island_index_map) {
1858 pidx_isld_src = face_island_index_map[pidx_src];
1859 pidx_isld_src_prev = face_island_index_map[pidx_src_prev];
1862 pidx_isld_src = pidx_src;
1863 pidx_isld_src_prev = pidx_src_prev;
1880 int last_valid_pidx_isld_src = -1;
1882 for (
int i = as_solution.
steps - 1; i--;) {
1886 pidx_isld_src = as_solution.
prev_nodes[pidx_isld_src];
1890 last_valid_pidx_isld_src = pidx_isld_src;
1893 if (last_valid_pidx_isld_src != -1) {
1899 const int vert_dst = corner_verts_dst[lidx_dst];
1900 copy_v3_v3(tmp_co, vert_positions_dst[vert_dst]);
1904 if (space_transform) {
1908 pidx_src = (use_islands ? best_island->
indices[last_valid_pidx_isld_src] :
1909 last_valid_pidx_isld_src);
1912 if (face_to_corner_tri_map_src ==
nullptr) {
1914 &face_to_corner_tri_map_src_buff,
1916 tri_faces_src.
data(),
1917 int(tri_faces_src.
size()));
1920 for (j = face_to_corner_tri_map_src[pidx_src].
count; j--;) {
1923 corner_tris_src[face_to_corner_tri_map_src[pidx_src].
indices[j]];
1928 positions_src[corner_verts_src[tri[0]]],
1929 positions_src[corner_verts_src[tri[1]]],
1930 positions_src[corner_verts_src[tri[2]]]);
1932 if (dist_sq < best_dist_sq) {
1934 best_dist_sq = dist_sq;
1952 &best_loop_index_src);
1959 &best_loop_index_src,
1984 pidx_src_prev = pidx_src;
1991 r_map, lidx_dst,
FLT_MAX, best_island_index, 0,
nullptr,
nullptr);
2000 for (tindex = 0; tindex < num_trees; tindex++) {
2003 if (isld_steps_src) {
2010 if (isld_steps_src) {
2015 if (face_to_corner_tri_map_src) {
2018 if (face_to_corner_tri_map_src_buff) {
2019 MEM_freeN(face_to_corner_tri_map_src_buff);
2024 if (indices_interp) {
2027 if (weights_interp) {
2035 const float max_dist,
2036 const float ray_radius,
2037 const Mesh *mesh_dst,
2038 const float (*vert_positions_dst)[3],
2039 const int numverts_dst,
2040 const int *corner_verts_dst,
2045 const float full_weight = 1.0f;
2046 const float max_dist_sq = max_dist * max_dist;
2053 face_normals_dst = mesh_dst->face_normals();
2061 const int index =
int(i);
2080 {
reinterpret_cast<const blender::float3 *
>(vert_positions_dst), numverts_dst},
2081 {&corner_verts_dst[face.
start()], face.
size()});
2084 if (space_transform) {
2090 const int face_index = tri_faces[nearest.
index];
2104 {
reinterpret_cast<const blender::float3 *
>(vert_positions_dst), numverts_dst},
2105 {&corner_verts_dst[face.
start()], face.
size()});
2109 if (space_transform) {
2115 &treedata, &rayhit, tmp_co, tmp_no, ray_radius, max_dist, &hit_dist))
2117 const int face_index = tri_faces[rayhit.
index];
2132 const size_t numfaces_src = size_t(me_src->
faces_num);
2136 float *weights =
static_cast<float *
>(
2137 MEM_mallocN(
sizeof(*weights) * numfaces_src, __func__));
2140 float(*face_vcos_2d)[2] =
static_cast<float(*)[2]
>(
2141 MEM_mallocN(
sizeof(*face_vcos_2d) * tmp_face_size, __func__));
2143 int(*tri_vidx_2d)[3] =
static_cast<int(*)[3]
>(
2144 MEM_mallocN(
sizeof(*tri_vidx_2d) * (tmp_face_size - 2), __func__));
2150 const blender::IndexRange face = faces_dst[i];
2152 int tot_rays, done_rays = 0;
2153 float face_area_2d_inv, done_area = 0.0f;
2155 blender::float3 pcent_dst;
2156 float to_pnor_2d_mat[3][3], from_pnor_2d_mat[3][3];
2157 float faces_dst_2d_min[2], faces_dst_2d_max[2], faces_dst_2d_z;
2158 float faces_dst_2d_size[2];
2160 float totweights = 0.0f;
2161 float hit_dist_accum = 0.0f;
2162 int sources_num = 0;
2163 const int tris_num = int(face.size()) - 2;
2166 pcent_dst = blender::bke::mesh::face_center_calc(
2167 {reinterpret_cast<const blender::float3 *>(vert_positions_dst), numverts_dst},
2168 {&corner_verts_dst[face.start()], face.size()});
2173 if (space_transform) {
2178 copy_vn_fl(weights,
int(numfaces_src), 0.0f);
2181 tmp_face_size = size_t(face.
size());
2182 face_vcos_2d =
static_cast<float(*)[2]
>(
2183 MEM_reallocN(face_vcos_2d,
sizeof(*face_vcos_2d) * tmp_face_size));
2184 tri_vidx_2d =
static_cast<int(*)[3]
>(
2185 MEM_reallocN(tri_vidx_2d,
sizeof(*tri_vidx_2d) * (tmp_face_size - 2)));
2192 faces_dst_2d_z = pcent_dst[2];
2197 for (j = 0; j < face.
size(); j++) {
2198 const int vert = corner_verts_dst[face[j]];
2199 copy_v3_v3(tmp_co, vert_positions_dst[vert]);
2200 if (space_transform) {
2203 mul_v2_m3v3(face_vcos_2d[j], to_pnor_2d_mat, tmp_co);
2204 minmax_v2v2_v2(faces_dst_2d_min, faces_dst_2d_max, face_vcos_2d[j]);
2209 sub_v2_v2v2(faces_dst_2d_size, faces_dst_2d_max, faces_dst_2d_min);
2212 tot_rays =
int((
max_ff(faces_dst_2d_size[0], faces_dst_2d_size[1]) / ray_radius) + 0.5f);
2219 tot_rays *= tot_rays;
2223 face_area_2d_inv = 1.0f /
max_ff(face_area_2d_inv, 1e-9f);
2226 if (face.
size() == 3) {
2227 tri_vidx_2d[0][0] = 0;
2228 tri_vidx_2d[0][1] = 1;
2229 tri_vidx_2d[0][2] = 2;
2231 if (face.
size() == 4) {
2232 tri_vidx_2d[0][0] = 0;
2233 tri_vidx_2d[0][1] = 1;
2234 tri_vidx_2d[0][2] = 2;
2235 tri_vidx_2d[1][0] = 0;
2236 tri_vidx_2d[1][1] = 2;
2237 tri_vidx_2d[1][2] = 3;
2243 for (j = 0; j < tris_num; j++) {
2244 float *v1 = face_vcos_2d[tri_vidx_2d[j][0]];
2245 float *
v2 = face_vcos_2d[tri_vidx_2d[j][1]];
2246 float *v3 = face_vcos_2d[tri_vidx_2d[j][2]];
2252 rays_num =
max_ii(
int(
float(tot_rays) * done_area * face_area_2d_inv + 0.5f) - done_rays,
2254 done_rays += rays_num;
2256 while (rays_num--) {
2262 tmp_co[2] = faces_dst_2d_z;
2268 &treedata, &rayhit, tmp_co, tmp_no, ray_radius /
w, max_dist, &hit_dist))
2270 const int face_index = tri_faces[rayhit.
index];
2271 weights[face_index] +=
w;
2273 hit_dist_accum += hit_dist;
2282 if (totweights > 0.0f) {
2283 for (j = 0; j <
int(numfaces_src); j++) {
2288 weights[sources_num] = weights[j] / totweights;
2293 r_map,
int(i), hit_dist_accum / totweights, 0, sources_num,
indices, weights);
2308 CLOG_WARN(&
LOG,
"Unsupported mesh-to-mesh face mapping mode (%d)!", mode);
2309 memset(r_map->
items, 0,
sizeof(*r_map->
items) *
size_t(faces_dst.
size()));
2316#undef MREMAP_RAYCAST_APPROXIMATE_NR
2317#undef MREMAP_RAYCAST_APPROXIMATE_FAC
2318#undef MREMAP_RAYCAST_TRI_SAMPLES_MIN
2319#undef MREMAP_RAYCAST_TRI_SAMPLES_MAX
2320#undef MREMAP_DEFAULT_BUFSIZE
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
BVHTree * bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data, blender::Span< blender::float3 > vert_positions, blender::BitSpan verts_mask, int verts_num_active, float epsilon, int tree_type, int axis)
BVHTree * bvhtree_from_mesh_corner_tris_ex(BVHTreeFromMesh *data, blender::Span< blender::float3 > vert_positions, blender::Span< int > corner_verts, blender::Span< blender::int3 > corner_tris, blender::BitSpan corner_tris_mask, int corner_tris_num_active, float epsilon, int tree_type, int axis)
@ BVHTREE_FROM_CORNER_TRIS
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
bool(*)(const float(*vert_positions)[3], int totvert, const blender::int2 *edges, int totedge, const bool *uv_seams, blender::OffsetIndices< int > faces, const int *corner_verts, const int *corner_edges, int corners_num, MeshIslandStore *r_island_store) MeshRemapIslandsCalc
void BKE_mesh_loop_islands_free(MeshIslandStore *island_store)
void BKE_mesh_origindex_map_create_corner_tri(MeshElemMap **r_map, int **r_mem, blender::OffsetIndices< int > faces, const int *corner_tri_faces, int corner_tris_num)
@ MREMAP_MODE_VERT_EDGE_NEAREST
@ MREMAP_MODE_VERT_POLYINTERP_VNORPROJ
@ MREMAP_MODE_VERT_FACE_NEAREST
@ MREMAP_MODE_EDGE_POLY_NEAREST
@ MREMAP_MODE_VERT_EDGEINTERP_NEAREST
@ MREMAP_MODE_VERT_NEAREST
@ MREMAP_MODE_LOOP_NEAREST_POLYNOR
@ MREMAP_MODE_EDGE_VERT_NEAREST
@ MREMAP_MODE_EDGE_NEAREST
@ MREMAP_MODE_LOOP_NEAREST_LOOPNOR
@ MREMAP_MODE_LOOP_POLY_NEAREST
@ MREMAP_MODE_EDGE_EDGEINTERP_VNORPROJ
@ MREMAP_MODE_POLY_POLYINTERP_PNORPROJ
@ MREMAP_MODE_POLY_NEAREST
@ MREMAP_MODE_VERT_POLYINTERP_NEAREST
An implementation of the A* (AStar) algorithm to solve shortest path problem.
bool BLI_astar_graph_solve(BLI_AStarGraph *as_graph, int node_index_src, int node_index_dst, astar_f_cost f_cost_cb, BLI_AStarSolution *r_solution, int max_steps)
void BLI_astar_solution_clear(BLI_AStarSolution *as_solution)
void BLI_astar_node_init(BLI_AStarGraph *as_graph, int node_index, void *custom_data)
void BLI_astar_node_link_add(BLI_AStarGraph *as_graph, int node1_index, int node2_index, float cost, void *custom_data)
void BLI_astar_solution_init(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, void *custom_data)
void BLI_astar_graph_init(BLI_AStarGraph *as_graph, int node_num, void *custom_data)
void BLI_astar_solution_free(BLI_AStarSolution *as_solution)
void BLI_astar_graph_free(BLI_AStarGraph *as_graph)
#define BLI_BITMAP_NEW(_num, _alloc_string)
#define BLI_BITMAP_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
MINLINE float sqrtf_signed(float f)
MINLINE int compare_ff_relative(float a, float b, float max_diff, int max_ulps)
int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float r_i1[3], float r_i2[3])
MINLINE float area_tri_v2(const float v1[2], const float v2[2], const float v3[2])
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3])
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
float area_poly_v2(const float verts[][2], unsigned int nr)
void interp_weights_poly_v3(float w[], float v[][3], int n, const float co[3])
void mul_m3_v3(const float M[3][3], float r[3])
void BLI_space_transform_apply_normal(const struct SpaceTransform *data, float no[3])
void BLI_space_transform_apply(const struct SpaceTransform *data, float co[3])
void unit_m3(float m[3][3])
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void unit_m4(float m[4][4])
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void BLI_space_transform_global_from_matrices(struct SpaceTransform *data, const float local[4][4], const float target[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], float r_eigen_values[3], float r_eigen_vectors[3][3])
Compute the eigen values and/or vectors of given 3D symmetric (aka adjoint) matrix.
void BLI_covariance_m3_v3n(const float(*cos_v3)[3], int cos_v3_num, bool use_sample_correction, float r_covmat[3][3], float r_center[3])
Compute the covariance matrix of given set of 3D coordinates.
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
void copy_vn_fl(float *array_tar, int size, float val)
void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], float t)
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void * BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_MEMARENA_STD_BUFSIZE
void BLI_polyfill_calc(const float(*coords)[2], unsigned int coords_num, int coords_sign, unsigned int(*r_tris)[3])
struct RNG * BLI_rng_new(unsigned int seed)
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
void void void BLI_rng_get_tri_sample_float_v2(struct RNG *rng, const float v1[2], const float v2[2], const float v3[2], float r_pt[2]) ATTR_NONNULL()
#define INIT_MINMAX2(min, max)
#define POINTER_FROM_INT(i)
#define UNUSED_VARS_NDEBUG(...)
#define POINTER_AS_INT(i)
#define CLOG_WARN(clg_ref,...)
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
void reinitialize(const int64_t new_size)
constexpr int64_t size() const
constexpr int64_t start() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
void fill(const bool value)
IndexRange index_range() const
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float3 cos(float3 v)
#define MREMAP_RAYCAST_TRI_SAMPLES_MIN
#define MREMAP_RAYCAST_TRI_SAMPLES_MAX
static void mesh_calc_eigen_matrix(const float(*positions)[3], const float(*vcos)[3], const int numverts, float r_mat[4][4])
void BKE_mesh_remap_calc_loops_from_mesh(const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius, const Mesh *mesh_dst, const float(*vert_positions_dst)[3], const int numverts_dst, const int *corner_verts_dst, const int numloops_dst, const blender::OffsetIndices< int > faces_dst, const Mesh *me_src, MeshRemapIslandsCalc gen_islands_src, const float islands_precision_src, MeshPairRemap *r_map)
void BKE_mesh_remap_free(MeshPairRemap *map)
#define MREMAP_RAYCAST_APPROXIMATE_NR
void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index)
static void mesh_island_to_astar_graph(MeshIslandStore *islands, const int island_index, const blender::Span< blender::float3 > positions, const blender::GroupedSpan< int > edge_to_face_map, const int numedges, const blender::OffsetIndices< int > faces, const blender::Span< int > corner_verts, const blender::Span< int > corner_edges, BLI_AStarGraph *r_as_graph)
#define MREMAP_RAYCAST_APPROXIMATE_FAC
void BKE_mesh_remap_find_best_match_from_mesh(const float(*vert_positions_dst)[3], const int numverts_dst, const Mesh *me_src, SpaceTransform *r_space_transform)
static int mesh_remap_interp_face_data_get(const blender::IndexRange face, const blender::Span< int > corner_verts, const blender::Span< blender::float3 > positions_src, const float point[3], size_t *buff_size, float(**vcos)[3], const bool use_loops, int **indices, float **weights, const bool do_weights, int *r_closest_index)
static float mesh_remap_calc_loops_astar_f_cost(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, BLI_AStarGNLink *link, const int node_idx_curr, const int node_idx_next, const int node_idx_dst)
#define MREMAP_DEFAULT_BUFSIZE
static void mesh_remap_item_define(MeshPairRemap *map, const int index, const float, const int island, const int sources_num, const int *indices_src, const float *weights_src)
static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, const int island_index, BLI_AStarGraph *as_graph, const blender::Span< blender::float3 > positions, const blender::OffsetIndices< int > faces, const blender::Span< int > corner_verts, const int edge_idx, BLI_bitmap *done_edges, const blender::GroupedSpan< int > edge_to_face_map, const bool is_edge_innercut, const int *face_island_index_map, float(*face_centers)[3], uchar *face_status)
static bool mesh_remap_bvhtree_query_nearest(BVHTreeFromMesh *treedata, BVHTreeNearest *nearest, const float co[3], const float max_dist_sq, float *r_hit_dist)
static bool mesh_remap_bvhtree_query_raycast(BVHTreeFromMesh *treedata, BVHTreeRayHit *rayhit, const float co[3], const float no[3], const float radius, const float max_dist, float *r_hit_dist)
void BKE_mesh_remap_calc_edges_from_mesh(const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius, const float(*vert_positions_dst)[3], const int numverts_dst, const blender::int2 *edges_dst, const int numedges_dst, const Mesh *me_src, Mesh *me_dst, MeshPairRemap *r_map)
void BKE_mesh_remap_calc_faces_from_mesh(const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius, const Mesh *mesh_dst, const float(*vert_positions_dst)[3], const int numverts_dst, const int *corner_verts_dst, const blender::OffsetIndices< int > faces_dst, const Mesh *me_src, MeshPairRemap *r_map)
void BKE_mesh_remap_init(MeshPairRemap *map, const int items_num)
float BKE_mesh_remap_calc_difference_from_mesh(const SpaceTransform *space_transform, const float(*vert_positions_dst)[3], const int numverts_dst, const Mesh *me_src)
void BKE_mesh_remap_calc_verts_from_mesh(const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius, const float(*vert_positions_dst)[3], const int numverts_dst, const Mesh *me_src, Mesh *me_dst, MeshPairRemap *r_map)
int edge_other_vert(const int2 edge, const int vert)
GroupedSpan< int > build_edge_to_face_map(OffsetIndices< int > faces, Span< int > corner_edges, int edges_num, Array< int > &r_offsets, Array< int > &r_indices)
float3 face_center_calc(Span< float3 > vert_positions, Span< int > face_verts)
GroupedSpan< int > build_vert_to_edge_map(Span< int2 > edges, int verts_num, Array< int > &r_offsets, Array< int > &r_indices)
VecBase< int32_t, 2 > int2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
BLI_AStarGNLink ** prev_links
BVHTree_RayCastCallback raycast_callback
BVHTree_NearestPointCallback nearest_callback
MeshPairRemapItem * items