* Improved multires projection some more in bmesh_interp.c

This commit is contained in:
Joseph Eagar 2020-10-18 18:10:16 -07:00
parent 49f57d8de8
commit f61d4b2e3a
16 changed files with 287 additions and 187 deletions

View File

@ -71,7 +71,8 @@ extern "C" {
/* *** mesh.c *** */
struct BMesh *BKE_mesh_to_bmesh_ex(const struct Mesh *me,
struct BMesh *BKE_mesh_to_bmesh_ex(const struct Object *ob,
const struct Mesh *me,
const struct BMeshCreateParams *create_params,
const struct BMeshFromMeshParams *convert_params);
struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me,

View File

@ -33,7 +33,8 @@ struct MirrorModifierData;
struct ModifierEvalContext;
struct Object;
struct Mesh *BKE_mesh_mirror_bisect_on_mirror_plane(struct MirrorModifierData *mmd,
struct Mesh *BKE_mesh_mirror_bisect_on_mirror_plane(struct Object *ob,
struct MirrorModifierData *mmd,
const struct Mesh *mesh,
int axis,
const float plane_co[3],

View File

@ -1015,7 +1015,8 @@ Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference)
return result;
}
BMesh *BKE_mesh_to_bmesh_ex(const Mesh *me,
BMesh *BKE_mesh_to_bmesh_ex(const Object *ob,
const Mesh *me,
const struct BMeshCreateParams *create_params,
const struct BMeshFromMeshParams *convert_params)
{
@ -1023,7 +1024,7 @@ BMesh *BKE_mesh_to_bmesh_ex(const Mesh *me,
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
bm = BM_mesh_create(&allocsize, create_params);
BM_mesh_bm_from_me(NULL, bm, me, convert_params);
BM_mesh_bm_from_me(ob, bm, me, convert_params);
return bm;
}
@ -1033,7 +1034,8 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me,
const bool add_key_index,
const struct BMeshCreateParams *params)
{
return BKE_mesh_to_bmesh_ex(me,
return BKE_mesh_to_bmesh_ex(ob,
me,
params,
&(struct BMeshFromMeshParams){
.calc_face_normal = false,

View File

@ -41,7 +41,8 @@
#include "MOD_modifiertypes.h"
Mesh *BKE_mesh_mirror_bisect_on_mirror_plane(MirrorModifierData *mmd,
Mesh *BKE_mesh_mirror_bisect_on_mirror_plane(Object *ob,
MirrorModifierData *mmd,
const Mesh *mesh,
int axis,
const float plane_co[3],
@ -58,7 +59,8 @@ Mesh *BKE_mesh_mirror_bisect_on_mirror_plane(MirrorModifierData *mmd,
BMIter viter;
BMVert *v, *v_next;
bm = BKE_mesh_to_bmesh_ex(mesh,
bm = BKE_mesh_to_bmesh_ex(ob,
mesh,
&(struct BMeshCreateParams){0},
&(struct BMeshFromMeshParams){
.calc_face_normal = true,
@ -157,7 +159,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis(MirrorModifierData *mmd,
Mesh *mesh_bisect = NULL;
if (do_bisect) {
mesh_bisect = BKE_mesh_mirror_bisect_on_mirror_plane(mmd, mesh, axis, plane_co, plane_no);
mesh_bisect = BKE_mesh_mirror_bisect_on_mirror_plane(ob, mmd, mesh, axis, plane_co, plane_no);
mesh = mesh_bisect;
}

View File

@ -1309,12 +1309,11 @@ static void multires_bmesh_space_set_cb(void *__restrict userdata,
// try to prevent errors
float len = len_v3(data);
/*
if (len > maxlen) {
mul_v3_fl(data, maxlen/len);
} else if (isnan(len)) {
zero_v3(data);
}*/
}
break;
}
}
@ -1344,6 +1343,8 @@ void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
return;
}
bm->multiresSpace = mode;
Mesh _me, *me = &_me;
memset(me, 0, sizeof(Mesh));
CustomData_reset(&me->vdata);
@ -1624,8 +1625,8 @@ static void multiresModifier_disp_run(
BLI_task_parallel_range(0, totpoly, &data, multires_disp_run_cb, &settings);
if (op == APPLY_DISPLACEMENTS) {
ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
}
}

View File

@ -49,7 +49,7 @@
#include <limits.h>
#define LEAF_LIMIT 700
#define LEAF_LIMIT 4000
//#define PERFCNTRS

View File

@ -174,10 +174,12 @@ void BKE_subdiv_eval_limit_point(
BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, r_P, NULL, NULL);
}
#if 0
static bool close_zero(float c[3]) {
const float eps = 0.00001;
return fabs(c[0]) < eps && fabs(c[1]) < eps && fabs(c[2]) < eps;
}
#endif
void BKE_subdiv_eval_limit_point_and_derivatives(Subdiv *subdiv,
const int ptex_face_index,
@ -201,7 +203,8 @@ void BKE_subdiv_eval_limit_point_and_derivatives(Subdiv *subdiv,
* that giving totally unusable derivatives. */
if (r_dPdu != NULL && r_dPdv != NULL) {
if ((close_zero(r_dPdu) || close_zero(r_dPdv)) || equals_v3v3(r_dPdu, r_dPdv)) {
//if ((close_zero(r_dPdu) || close_zero(r_dPdv)) || equals_v3v3(r_dPdu, r_dPdv)) {
if ((is_zero_v3(r_dPdu) || is_zero_v3(r_dPdv)) || equals_v3v3(r_dPdu, r_dPdv)) {
subdiv->evaluator->evaluateLimit(subdiv->evaluator,
ptex_face_index,
u * 0.999f + 0.0005f,

View File

@ -27,13 +27,13 @@
#include "DNA_meshdata_types.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
#include "BLI_array.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_task.h"
#include "BLI_array.h"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_multires.h"
@ -325,11 +325,11 @@ static bool quad_co(const float v1[3],
copy_v3_v3(projverts2[i], projverts[i]);
}
//expand quad a bit
// expand quad a bit
#if 1
float eps = FLT_EPSILON * 400000;
float c[3];
mid_v3_v3v3v3v3(c, projverts[0], projverts[1], projverts[2], projverts[3]);
sub_v3_v3(projverts2[0], c);
@ -344,8 +344,7 @@ static bool quad_co(const float v1[3],
add_v3_v3(projverts2[1], c);
add_v3_v3(projverts2[2], c);
add_v3_v3(projverts2[3], c);
#endif
#endif
if (!isect_point_quad_v2(origin, projverts2[0], projverts2[1], projverts2[2], projverts2[3])) {
return false;
@ -353,7 +352,7 @@ static bool quad_co(const float v1[3],
resolve_quad_uv_v2(r_uv, origin, projverts[0], projverts[3], projverts[2], projverts[1]);
//if (r_uv[0] < -eps || r_uv[1] < -eps || r_uv[0] > 1.0+eps || r_uv[1] > 1.0+eps) {
// if (r_uv[0] < -eps || r_uv[1] < -eps || r_uv[0] > 1.0+eps || r_uv[1] > 1.0+eps) {
// return false;
//}
@ -400,7 +399,6 @@ static bool mdisp_in_mdispquad(BMLoop *l_src,
compute_mdisp_quad(l_dst, l_dst_f_center, v1, v2, v3, v4, e1, e2);
/* expand quad a bit */
#if 0
float c[3];
float eps = FLT_EPSILON * 400;
mid_v3_v3v3v3v3(c, v1, v2, v3, v4);
@ -417,7 +415,6 @@ static bool mdisp_in_mdispquad(BMLoop *l_src,
add_v3_v3(v2, c);
add_v3_v3(v3, c);
add_v3_v3(v4, c);
#endif
if (!quad_co(v1, v2, v3, v4, p, l_src->v->no, r_uv)) {
return 0;
@ -567,8 +564,8 @@ static void loop_interp_multires_cb(void *__restrict userdata,
negate_v3(n2);
}
th = acos(dot_v3v3(n1, n2)*0.999999f);
if (th > M_PI*0.1) {
th = acos(dot_v3v3(n1, n2) * 0.999999f);
if (th > M_PI * 0.1) {
continue;
}
@ -587,23 +584,24 @@ static void loop_interp_multires_cb(void *__restrict userdata,
float l = len_v3v3(disp, baseco);
if (l < mindis) {
mindis = l;
//tot++;
//copy_v3_v3(sum, disp);
// tot++;
// copy_v3_v3(sum, disp);
}
add_v3_v3(sum, disp);
tot++;
//break;
// break;
}
} while ((l_iter = l_iter->next) != l_first);
if (tot) {
mul_v3_fl(sum, 1.0 / (float)tot);
copy_v3_v3(md_dst->disps[iy * res + ix], sum);
} else {
//printf("failed to set disp: %f %f\n", x, y);
}
else {
// printf("failed to set disp: %f %f\n", x, y);
if (space == MULTIRES_SPACE_ABSOLUTE) {
//copy_v3_v3(md_dst->disps[iy * res + ix], baseco);
//copy_v3_v3(md_dst->disps[iy * res + ix], baseco);
// copy_v3_v3(md_dst->disps[iy * res + ix], baseco);
// copy_v3_v3(md_dst->disps[iy * res + ix], baseco);
}
}
}
@ -718,10 +716,12 @@ void BM_face_interp_multires(BMesh *bm, BMFace *f_dst, const BMFace *f_src)
}
}
void BM_multires_smooth(BMesh *bm, BMFace *f, bool no_boundary) {
// smooth with weight falloff towards center of grids
static void bm_multires_smooth(BMesh *bm, BMFace *f, bool no_boundary)
{
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
float (*orig)[3] = NULL;
BLI_array_staticdeclare(orig, 256*256);
float(*orig)[3] = NULL;
BLI_array_staticdeclare(orig, 256 * 256);
if (cd_loop_mdisp_offset < 0) {
return;
@ -740,53 +740,53 @@ void BM_multires_smooth(BMesh *bm, BMFace *f, bool no_boundary) {
mul_v3_fl(cent, 1.0f / (float)ctot);
const int offs[][2] = {
{0, 0},
// {-1, -1},
{-1, 0},
// {-1, 1},
{0, 1},
// {1, 1},
{1, 0},
// {1, -1},
{0, -1},
{0, 0},
// {-1, -1},
{-1, 0},
// {-1, 1},
{0, 1},
// {1, 1},
{1, 0},
// {1, -1},
{0, -1},
};
int totoff = sizeof(offs) / sizeof(*offs);
#ifndef ABS
#define ABS(a) ((a) < 0 ? -(a) : (a))
# define ABS(a) ((a) < 0 ? -(a) : (a))
#endif
//int space = bm->multiresSpace;
// int space = bm->multiresSpace;
BMLoop *l = f->l_first;
do {
MDisps *md = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
if (!md->disps) continue;
if (!md->disps)
continue;
int res = (int)floor(sqrt((double)md->totdisp) + 0.000001);
int start = no_boundary ? 1 : 0;
int end = no_boundary ? res-1 : res;
float df = 1.0f / (float)(res-1);
int end = no_boundary ? res - 1 : res;
float df = 1.0f / (float)(res - 1);
float u = 0.0;
BLI_array_clear(orig);
BLI_array_reserve(orig, md->totdisp*3);
memcpy(orig, md->disps, sizeof(float)*3*md->totdisp);
BLI_array_reserve(orig, md->totdisp * 3);
memcpy(orig, md->disps, sizeof(float) * 3 * md->totdisp);
for (int x=start; x<end; x++, u += df) {
for (int x = start; x < end; x++, u += df) {
float v = 0.0;
/*x < 0, x >= res, y < 0, y >= res, winding_matches*/
for (int y=start; y<end; y++, v += df) {
for (int y = start; y < end; y++, v += df) {
float co[3];
float tot = 0.0f;
zero_v3(co);
int idx1 = y*res + x;
int idx1 = y * res + x;
for (int oi=0; oi<totoff; oi++) {
for (int oi = 0; oi < totoff; oi++) {
int ox = x + offs[oi][0];
int oy = y + offs[oi][1];
MDisps *md2 = md;
@ -794,107 +794,101 @@ void BM_multires_smooth(BMesh *bm, BMFace *f, bool no_boundary) {
if (1 && (ox < 0 || oy < 0 || ox >= res || oy >= res)) {
BMLoop *l2 = NULL;
BMLoop *ls = l;
if (ox < 0 && oy < 0) {
l2 = ls->next->next;
ox = ABS(ox);
oy = ABS(oy);
} else if (ox < 0 && oy >= 0 && oy < res-1) {
}
else if (ox < 0 && oy >= 0 && oy < res) {
l2 = ls->prev;
int t = oy;
oy = -ox;
ox = t;
} else if (oy < 0 && ox >= 0 && ox < res-1) {
}
else if (oy < 0 && ox >= 0 && ox < res) {
l2 = ls->next;
int t = oy;
oy = ox;
ox = -t;
} else if (ox >= res && oy >= 0 && oy < res) {
l2 = ls->radial_next;
}
else if (ox >= res && oy >= 0 && oy < res) {
l2 = ls->radial_next->next;
if (ls->v != l2->v) {
l2 = l2->next;
if (ls->v == l2->v) {
int t = oy;
oy = 2*res - ox - 1;
oy = 2 * res - ox - 1;
ox = t;
} else {
}
else {
l2 = l2->prev;
ox = res - ox;
}
//XXX disables this branch
//ox = oy = -1;
} else if (ox >= res && oy < 0) {
l2 = ls->radial_next;
if (l2->v != ls->v) {
oy = -oy;
ox = 2*res - ox - 1;
} else {
l2 = l2->next;
int t = ox;
ox = -oy;
oy = 2*res - t - 1;
}
//XXX disables this branch
//ox = oy = -1;
} else if (oy >= res && ox >= 0 && ox < res) {
// XXX disables this branch
// ox = oy = -1;
}
else if (oy >= res && ox >= 0 && ox < res) {
l2 = ls->prev->radial_next;
if (l2->v == ls->v) {
int t = ox;
ox = 2*res - oy - 1;
ox = 2 * res - oy - 1;
oy = t;
} else {
}
else {
l2 = l2->next;
oy = 2*res - oy - 1;
}
//XXX disables this branch
//ox = oy = -1;
} else if (ox >= res && oy >= res) {
l2 = ls->prev->radial_next->prev->radial_prev;
if (l2->v == ls->v) {
int t = ox;
ox = oy;
oy = t;
ox = 2*res - ox - 1;
oy = 2*res - oy - 1;
//XXX disables this branch
//ox = oy = -1;
} else {
printf("ignoring non-4-valence multires corner");
l2 = NULL;
oy = 2 * res - oy - 1;
}
// XXX disables this branch
// ox = oy = -1;
}
else {
printf("ignoring non-4-valence multires corner %d %d %d %d : %d %d %d\t",
ox,
oy,
offs[oi][0],
offs[oi][1],
x,
y,
res);
l2 = NULL;
}
if (l2) {
//ox = res - ox - 1;
//oy = res - oy - 1;
// ox = res - ox - 1;
// oy = res - oy - 1;
md2 = BM_ELEM_CD_GET_VOID_P(l2, cd_loop_mdisp_offset);
}
}
}
if (!md2->disps || oy < 0 || oy >= res || ox < 0 || ox >= res) {
continue;
}
int idx2 = oy*res + ox;
int idx2 = oy * res + ox;
float *oco2 = md == md2 ? orig[idx2] : md2->disps[idx2];
float co2[3];
copy_v3_v3(co2, oco2);
float dx = 0.5f*(float)offs[oi][0];
float dy = 0.5f*(float)offs[oi][1];
float w = M_SQRT2 - dx*dx + dy*dy;
if (no_boundary && (ox == 0 || oy == 0 || ox == res-1 || oy == res-1)) {
// w = 2.0;
} else if (ox == x && oy == y) {
// w = 1.0;
float dx = (float)offs[oi][0];
float dy = (float)offs[oi][1];
float w = 2.0f - dx * dx + dy * dy;
if (no_boundary && (ox == 0 || oy == 0 || ox == res - 1 || oy == res - 1)) {
// w = 2.0;
}
else if (ox == x && oy == y) {
// blend less away from edges
float au = fabs(u - 0.5) * 2.0, av = fabs(v - 0.5) * 2.0;
float w2 = au * au + av * av;
w = 4.0 * w2;
}
w = 1.0;
@ -929,7 +923,11 @@ void BM_multires_smooth(BMesh *bm, BMFace *f, bool no_boundary) {
BLI_array_free(orig);
}
void bmo_test_mres_smooth_exec(BMesh *bm, BMOperator *op) {
struct Object *multires_dump_grids_bmesh(struct Object *bmob, BMesh *bm);
void bmo_test_mres_smooth_exec(BMesh *bm, BMOperator *op)
{
BMIter iter;
BMFace *f;
@ -937,7 +935,7 @@ void bmo_test_mres_smooth_exec(BMesh *bm, BMOperator *op) {
return;
}
BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
bool ok = !!BM_elem_flag_test(f, BM_ELEM_SELECT);
ok = ok && !BM_elem_flag_test(f, BM_ELEM_HIDDEN);
@ -945,10 +943,27 @@ void bmo_test_mres_smooth_exec(BMesh *bm, BMOperator *op) {
continue;
}
BM_multires_smooth(bm, f, false);
//BM_multires_smooth(bm, f, false);
//BM_multires_smooth(bm, f, false);
//BM_face_multires_bounds_smooth(bm, f);
//bm_multires_smooth(bm, f, true);
// BM_multires_smooth(bm, f, false);
// BM_multires_smooth(bm, f, false);
//for (int i=0; i<5; i++) {
BM_face_multires_bounds_smooth(bm, f);
// }
}
multires_dump_grids_bmesh(NULL, bm);
}
void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
{
return;
if (bm->multiresSpace == MULTIRES_SPACE_ABSOLUTE) {
BM_face_multires_stitch(bm, f);
//for (int i=0; i<5; i++) {
//bm_multires_smooth(bm, f, true);
//}
}
}
@ -956,55 +971,23 @@ void bmo_test_mres_smooth_exec(BMesh *bm, BMOperator *op) {
* smooths boundaries between multires grids,
* including some borders in adjacent faces
*/
void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
void BM_face_multires_stitch(BMesh *bm, BMFace *f)
{
return;
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
BMLoop *l;
BMIter liter;
float co[3];
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
int sides = 0;
if (cd_loop_mdisp_offset == -1) {
return;
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset);
MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
MDisps *mdn = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset);
float co1[3];
int sides;
int y;
/**
* mdisps is a grid of displacements, ordered thus:
* <pre>
* v4/next
* |
* | v1/cent-----mid2 ---> x
* | | |
* | | |
* v2/prev---mid1-----v3/cur
* |
* V
* y
* </pre>
*/
sides = (int)sqrt(mdp->totdisp);
for (y = 0; y < sides; y++) {
mid_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]);
copy_v3_v3(mdn->disps[y * sides], co1);
copy_v3_v3(mdl->disps[y], co1);
}
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
MDisps *mdl2;
float co1[3], co2[3], co[3];
int sides;
int y;
float co1[3], co2[3];
int x, y;
/**
* mdisps is a grid of displacements, ordered thus:
@ -1032,7 +1015,7 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset);
}
sides = (int)floor(sqrt(mdl1->totdisp)+FLT_EPSILON);
sides = (int)floor(sqrt(mdl1->totdisp) + FLT_EPSILON);
for (y = 0; y < sides; y++) {
int a1, a2, o1, o2;
@ -1044,26 +1027,128 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
o2 = (sides - 1) * sides + y;
}
else {
a1 = sides * y + sides - 2;
a2 = sides * y + sides - 2;
o1 = sides * y + sides - 1;
o2 = sides * y + sides - 1;
}
interp_v3_v3v3(co1, mdl1->disps[a1], mdl2->disps[a2], 0.5f);
interp_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2], 0.5f);
/* magic blending numbers, hardcoded! */
//mul_v3_fl(co1, 0.18);
//add_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2]);
//mul_v3_fl(co2, 0.32);
interp_v3_v3v3(co, co1, co2, 0.5f);
//add_v3_v3v3(co, co1, co2);
mid_v3_v3v3(co, mdl1->disps[o1], mdl2->disps[o2]);
copy_v3_v3(mdl1->disps[o1], co);
copy_v3_v3(mdl2->disps[o2], co);
}
BMLoop *l2 = l->prev->radial_next;
bool reverse = false;
if (l2->v != l->v) {
reverse = true;
l2 = l2->next;
}
mdl2 = BM_ELEM_CD_GET_VOID_P(l2, cd_loop_mdisp_offset);
y = sides - 1;
if (!mdl2->disps) {
continue;
}
for (x = 0; x < sides; x++) {
int x2, y2, o1, o2;
if (!reverse) {
x2 = sides - 1;
y2 = x;
}
else {
x2 = x;
y2 = y;
}
o1 = y * sides + x;
o2 = y2 * sides + x2;
mid_v3_v3v3(co, mdl1->disps[o1], mdl2->disps[o2]);
copy_v3_v3(mdl1->disps[o1], co);
copy_v3_v3(mdl2->disps[o2], co);
}
}
// do exterior corners
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *md1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
BMIter l2iter;
BMLoop *l2;
int x = sides - 1, y = sides - 1;
int idx = y * sides + x;
int tot = 1;
zero_v3(co);
if (!md1->disps) {
continue;
}
add_v3_v3(co, md1->disps[idx]);
BM_ITER_ELEM (l2, &l2iter, l->v, BM_LOOPS_OF_VERT) {
if (l2->v != l->v) { // winding is flipped
l2 = l2->next;
}
MDisps *md2 = BM_ELEM_CD_GET_VOID_P(l2, cd_loop_mdisp_offset);
if (l == l2 || !md2->disps) {
continue;
}
add_v3_v3(co, md2->disps[idx]);
tot++;
}
mul_v3_fl(co, 1.0f / (float)tot);
BM_ITER_ELEM (l2, &l2iter, l->v, BM_LOOPS_OF_VERT) {
if (l2->v != l->v) { // winding is flipped
l2 = l2->next;
}
MDisps *md2 = BM_ELEM_CD_GET_VOID_P(l2, cd_loop_mdisp_offset);
if (l == l2 || !md2->disps) {
continue;
}
copy_v3_v3(md2->disps[idx], co);
}
}
// do interior corners
int tot = 0;
zero_v3(co);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *md1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
if (!md1->disps) {
continue;
}
add_v3_v3(co, md1->disps[0]);
tot++;
}
if (tot) {
mul_v3_fl(co, 1.0f / (float)tot);
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *md1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
if (!md1->disps) {
continue;
}
copy_v3_v3(md1->disps[0], co);
}
}

View File

@ -1,3 +1,4 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,6 +24,7 @@
struct LinkNode;
struct MemArena;
void BM_face_multires_stitch(BMesh *bm, BMFace *f);
void BM_loop_interp_multires_ex(BMesh *bm,
BMLoop *l_dst,
const BMFace *f_src,

View File

@ -752,7 +752,7 @@ static void quadriflow_update_job(void *customdata, float progress, int *cancel)
*(qj->progress) = progress;
}
static Mesh *remesh_symmetry_bisect(Mesh *mesh, eSymmetryAxes symmetry_axes)
static Mesh *remesh_symmetry_bisect(Object *ob, Mesh *mesh, eSymmetryAxes symmetry_axes)
{
MirrorModifierData mmd = {{0}};
mmd.tolerance = QUADRIFLOW_MIRROR_BISECT_TOLERANCE;
@ -774,7 +774,7 @@ static Mesh *remesh_symmetry_bisect(Mesh *mesh, eSymmetryAxes symmetry_axes)
plane_no[axis] = -1.0f;
mesh_bisect_temp = mesh_bisect;
mesh_bisect = BKE_mesh_mirror_bisect_on_mirror_plane(
&mmd, mesh_bisect, axis, plane_co, plane_no);
ob, &mmd, mesh_bisect, axis, plane_co, plane_no);
if (mesh_bisect_temp != mesh_bisect) {
BKE_id_free(NULL, mesh_bisect_temp);
}
@ -842,7 +842,7 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update
bisect_mesh = BKE_mesh_copy_for_eval(mesh, false);
/* Bisect the input mesh using the paint symmetry settings */
bisect_mesh = remesh_symmetry_bisect(bisect_mesh, qj->symmetry_axes);
bisect_mesh = remesh_symmetry_bisect(ob, bisect_mesh, qj->symmetry_axes);
new_mesh = BKE_mesh_remesh_quadriflow_to_mesh_nomain(
bisect_mesh,

View File

@ -189,7 +189,7 @@ void ABCGenericMeshWriter::do_write(HierarchyContext &context)
struct BMeshCreateParams bmcp = {false};
struct BMeshFromMeshParams bmfmp = {true, false, false, 0};
BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmcp, &bmfmp);
BMesh *bm = BKE_mesh_to_bmesh_ex(object, mesh, &bmcp, &bmfmp);
BM_mesh_triangulate(bm, quad_method, ngon_method, 4, tag_only, nullptr, nullptr, nullptr);

View File

@ -122,7 +122,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const float spread = bmd->spread;
const bool invert_vgroup = (bmd->flags & MOD_BEVEL_INVERT_VGROUP) != 0;
bm = BKE_mesh_to_bmesh_ex(mesh,
bm = BKE_mesh_to_bmesh_ex(ctx->object, mesh,
&(struct BMeshCreateParams){0},
&(struct BMeshFromMeshParams){
.calc_face_normal = true,

View File

@ -171,7 +171,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
}
bm = BKE_mesh_to_bmesh_ex(mesh,
bm = BKE_mesh_to_bmesh_ex(ctx->object,
mesh,
&(struct BMeshCreateParams){0},
&(struct BMeshFromMeshParams){
.calc_face_normal = calc_face_normal,

View File

@ -53,7 +53,7 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
static Mesh *doEdgeSplit(Mesh *mesh, EdgeSplitModifierData *emd)
static Mesh *doEdgeSplit(Object *ob, Mesh *mesh, EdgeSplitModifierData *emd)
{
Mesh *result;
BMesh *bm;
@ -65,7 +65,8 @@ static Mesh *doEdgeSplit(Mesh *mesh, EdgeSplitModifierData *emd)
const bool do_split_all = do_split_angle && emd->split_angle < FLT_EPSILON;
const bool calc_face_normals = do_split_angle && !do_split_all;
bm = BKE_mesh_to_bmesh_ex(mesh,
bm = BKE_mesh_to_bmesh_ex(ob,
mesh,
&(struct BMeshCreateParams){0},
&(struct BMeshFromMeshParams){
.calc_face_normal = calc_face_normals,
@ -125,7 +126,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(emd, DNA_struct_default_get(EdgeSplitModifierData), modifier);
}
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
Mesh *result;
EdgeSplitModifierData *emd = (EdgeSplitModifierData *)md;
@ -134,7 +135,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
return mesh;
}
result = doEdgeSplit(mesh, emd);
result = doEdgeSplit(ctx->object, mesh, emd);
return result;
}

View File

@ -48,7 +48,7 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
static Mesh *triangulate_mesh(Mesh *mesh,
static Mesh *triangulate_mesh(Object *ob, Mesh *mesh,
const int quad_method,
const int ngon_method,
const int min_vertices,
@ -70,7 +70,8 @@ static Mesh *triangulate_mesh(Mesh *mesh,
cd_mask_extra.lmask |= CD_MASK_NORMAL;
}
bm = BKE_mesh_to_bmesh_ex(mesh,
bm = BKE_mesh_to_bmesh_ex(ob,
mesh,
&((struct BMeshCreateParams){0}),
&((struct BMeshFromMeshParams){
.calc_face_normal = true,
@ -118,11 +119,11 @@ static void initData(ModifierData *md)
md->mode |= eModifierMode_Editmode;
}
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
TriangulateModifierData *tmd = (TriangulateModifierData *)md;
Mesh *result;
if (!(result = triangulate_mesh(
if (!(result = triangulate_mesh(ctx->object,
mesh, tmd->quad_method, tmd->ngon_method, tmd->min_vertices, tmd->flag))) {
return mesh;
}

View File

@ -78,7 +78,7 @@ static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh *
const int defgrp_index = BKE_object_defgroup_name_index(ob, wmd->defgrp_name);
bm = BKE_mesh_to_bmesh_ex(mesh,
bm = BKE_mesh_to_bmesh_ex(ob, mesh,
&(struct BMeshCreateParams){0},
&(struct BMeshFromMeshParams){
.calc_face_normal = true,