New branch to fix multires topology editing. WIP
Changes: * Brought back bmesh_mdisps_space_set, written from scratch using subdiv api, not ccg. * Wrote a function to smooth multigres grids from within bmesh. I might not need it; unless anyone thinks of a use for it I'll go ahead and delete it. Todo: * Purge code of all usages of CCG for multires. This commit: * Wrote a utility function to dump multires displacements into a (new) scene object. * Consequently, I now know that the CCG_based multires code is not compatible with the OpenSubdiv based code. The former produces gaps between grids when converting displacements to object space.
This commit is contained in:
parent
4659855b0f
commit
64c7bad391
|
@ -1 +1 @@
|
|||
Subproject commit 8ad9de7c1e1022dee907ddce78f4c357111fc09e
|
||||
Subproject commit a1f229202345c5e705f3035e2ff418bc3a9fe669
|
|
@ -1 +1 @@
|
|||
Subproject commit 26a8b2eadc7abb2a30fac50eb5505aa24daf5785
|
||||
Subproject commit eae381b698248e70e4a3c62bdf239f9d5a0470a9
|
|
@ -41,6 +41,7 @@ struct MultiresModifierData;
|
|||
struct Object;
|
||||
struct Scene;
|
||||
struct SubdivCCG;
|
||||
struct BMesh;
|
||||
|
||||
struct MLoop;
|
||||
struct MLoopTri;
|
||||
|
@ -229,6 +230,8 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3]
|
|||
const float dPdv[3],
|
||||
const int corner);
|
||||
|
||||
void BKE_multires_bmesh_space_set(struct Object *ob, struct BMesh *bm, int mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -59,7 +59,6 @@ Mesh *BKE_mesh_mirror_bisect_on_mirror_plane(MirrorModifierData *mmd,
|
|||
BMVert *v, *v_next;
|
||||
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh,
|
||||
NULL,
|
||||
&(struct BMeshCreateParams){0},
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -33,26 +33,32 @@
|
|||
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_edgehash.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_mapping.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_subdiv.h"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
#include "BKE_subdiv_eval.h"
|
||||
#include "BKE_subsurf.h"
|
||||
#include "BKE_subdiv.h"
|
||||
|
||||
#include "BKE_object.h"
|
||||
|
||||
|
@ -60,9 +66,9 @@
|
|||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "multires_reshape.h"
|
||||
#include "multires_inline.h"
|
||||
#include "bmesh.h"
|
||||
#include "multires_inline.h"
|
||||
#include "multires_reshape.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
@ -962,20 +968,36 @@ void multiresModifier_subdivide_legacy(
|
|||
static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
|
||||
{
|
||||
if (axis == 0) {
|
||||
if (x == 0) {
|
||||
sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x+1, y), CCG_grid_elem_co(key, grid, x, y));
|
||||
} else {
|
||||
sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x-1, y));
|
||||
if (x == key->grid_size - 1) {
|
||||
if (y == key->grid_size - 1) {
|
||||
sub_v3_v3v3(
|
||||
t, CCG_grid_elem_co(key, grid, x, y - 1), CCG_grid_elem_co(key, grid, x - 1, y - 1));
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x - 1, y));
|
||||
}
|
||||
}
|
||||
} else if (axis == 1) {
|
||||
if (y == 0) {
|
||||
sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y+1), CCG_grid_elem_co(key, grid, x, y));
|
||||
} else {
|
||||
sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x, y-1));
|
||||
else {
|
||||
sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x + 1, y), CCG_grid_elem_co(key, grid, x, y));
|
||||
}
|
||||
}
|
||||
else if (axis == 1) {
|
||||
if (y == key->grid_size - 1) {
|
||||
if (x == key->grid_size - 1) {
|
||||
sub_v3_v3v3(
|
||||
t, CCG_grid_elem_co(key, grid, x - 1, y), CCG_grid_elem_co(key, grid, x - 1, (y - 1)));
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x, (y - 1)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, (y + 1)), CCG_grid_elem_co(key, grid, x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Construct 3x3 tangent-space matrix in 'mat' */
|
||||
static void grid_tangent_matrix(float mat[3][3], const CCGKey *key, int x, int y, CCGElem *grid)
|
||||
{
|
||||
|
@ -1006,9 +1028,206 @@ typedef struct MultiresThreadedData {
|
|||
float (*smat)[3];
|
||||
} MultiresThreadedData;
|
||||
|
||||
Object *multires_dump_grids_bmesh(BMesh *bm)
|
||||
{
|
||||
if (!CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
|
||||
printf("multires_dump_grids_bmesh: error: no multires grids\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bool spaceset = false;
|
||||
|
||||
if (bm->multiresSpace != MULTIRES_SPACE_ABSOLUTE) {
|
||||
BKE_multires_bmesh_space_set(NULL, bm, MULTIRES_SPACE_ABSOLUTE);
|
||||
spaceset = true;
|
||||
}
|
||||
|
||||
Main *bmain = G.main;
|
||||
char *name = "multires_dump";
|
||||
|
||||
bContext *ctx = CTX_create();
|
||||
CTX_data_main_set(ctx, bmain);
|
||||
CTX_wm_manager_set(ctx, G.main->wm.first);
|
||||
CTX_data_scene_set(ctx, G.main->scenes.first);
|
||||
|
||||
Scene *scene = CTX_data_scene(ctx);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(ctx);
|
||||
Object *ob = BKE_object_add_only_object(bmain, OB_MESH, name);
|
||||
Base *base;
|
||||
LayerCollection *layer_collection;
|
||||
|
||||
ob->data = BKE_object_obdata_add_from_type(bmain, OB_MESH, name);
|
||||
DEG_id_tag_update_ex(
|
||||
bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
|
||||
//DEG_id_tag_update_ex(
|
||||
// bmain, &ob->data, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
|
||||
|
||||
layer_collection = BKE_layer_collection_get_active(view_layer);
|
||||
BKE_collection_object_add(bmain, layer_collection->collection, ob);
|
||||
|
||||
DEG_id_type_tag(bmain, ID_OB);
|
||||
DEG_relations_tag_update(bmain);
|
||||
if (ob->data != NULL) {
|
||||
DEG_id_tag_update_ex(bmain, (ID *)ob->data, ID_RECALC_EDITORS);
|
||||
}
|
||||
|
||||
ob->modifiers.first = ob->modifiers.last = NULL;
|
||||
zero_v3(ob->loc);
|
||||
|
||||
printf("users: %d\n", ob->id.us);
|
||||
|
||||
Mesh *me = ob->data;
|
||||
|
||||
BMIter iter;
|
||||
BMVert *v;
|
||||
BMEdge *e;
|
||||
BMFace *f;
|
||||
|
||||
int cd_mdisp_off = CustomData_get_offset(&bm->ldata, CD_MDISPS);
|
||||
int dimen = 0;
|
||||
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l = f->l_first;
|
||||
MDisps *md = BM_ELEM_CD_GET_VOID_P(l, cd_mdisp_off);
|
||||
dimen = (int)floor(sqrt(md->totdisp) + 0.00001);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!dimen) {
|
||||
printf("multires_dump_grids_bmesh: error: corrupted multires data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int totvert = bm->totloop * dimen * dimen;
|
||||
int totface = bm->totloop * (dimen - 1) * (dimen - 1);
|
||||
int totloop = totface * 4;
|
||||
|
||||
CustomData_free(&me->vdata, me->totvert);
|
||||
CustomData_free(&me->edata, me->totedge);
|
||||
CustomData_free(&me->fdata, me->totface);
|
||||
CustomData_free(&me->ldata, me->totloop);
|
||||
CustomData_free(&me->pdata, me->totpoly);
|
||||
|
||||
me->totvert = totvert;
|
||||
me->totpoly = totface;
|
||||
me->totloop = totloop;
|
||||
me->totedge = totvert + totface;
|
||||
me->totface = 0;
|
||||
me->act_face = -1;
|
||||
|
||||
EdgeHash *eh = BLI_edgehash_new_ex("multires_dump_bmesh", me->totedge);
|
||||
|
||||
MVert *mvert = me->totvert ?
|
||||
MEM_callocN(sizeof(MVert) * me->totvert, "multires_dump_grids_bmesh.vert") :
|
||||
NULL;
|
||||
MEdge *medge = me->totedge ?
|
||||
MEM_callocN(sizeof(MEdge) * me->totedge, "multires_dump_grids_bmesh.edge") :
|
||||
NULL;
|
||||
MLoop *mloop = me->totloop ?
|
||||
MEM_callocN(sizeof(MLoop) * me->totloop, "multires_dump_grids_bmesh.loop") :
|
||||
NULL;
|
||||
MPoly *mpoly = me->totpoly ?
|
||||
MEM_callocN(sizeof(MPoly) * me->totpoly, "multires_dump_grids_bmesh.poly") :
|
||||
NULL;
|
||||
|
||||
me->cd_flag = 0;
|
||||
|
||||
CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
|
||||
CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
|
||||
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
|
||||
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
|
||||
|
||||
BKE_mesh_update_customdata_pointers(me, 0);
|
||||
|
||||
int loopi = 0;
|
||||
int outli = 0;
|
||||
int medi = 0;
|
||||
|
||||
#define VINDEX(i, j) (loopi * dimen * dimen + ((j)*dimen + (i)))
|
||||
|
||||
// CustomData_daata_
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l = f->l_first;
|
||||
do {
|
||||
MDisps *md = BM_ELEM_CD_GET_VOID_P(l, cd_mdisp_off);
|
||||
|
||||
for (int i = 0; i < dimen; i++) {
|
||||
for (int j = 0; j < dimen; j++) {
|
||||
int vidx = loopi * dimen * dimen + (j * dimen + i);
|
||||
int idx = j * dimen + i;
|
||||
float *co = md->disps[idx];
|
||||
|
||||
MVert *mv = mvert + vidx;
|
||||
copy_v3_v3(mv->co, co);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < dimen-1; i++) {
|
||||
for (int j = 0; j < dimen-1; j++) {
|
||||
// do face
|
||||
int fidx = loopi * (dimen - 1) * (dimen - 1) + (j * (dimen - 1) + i);
|
||||
MPoly *mp = mpoly + fidx;
|
||||
|
||||
mp->totloop = 4;
|
||||
mp->loopstart = outli;
|
||||
|
||||
MLoop *ml = mloop + outli;
|
||||
|
||||
ml[0].v = VINDEX(i, j);
|
||||
ml[1].v = VINDEX(i, j + 1);
|
||||
ml[2].v = VINDEX(i + 1, j + 1);
|
||||
ml[3].v = VINDEX(i + 1, j);
|
||||
|
||||
for (int i2=0; i2<4; i2++) {
|
||||
int a = ml[i2].v, b = ml[(i2+1) % 4].v;
|
||||
int e;
|
||||
|
||||
if (!BLI_edgehash_haskey(eh, a, b)) {
|
||||
BLI_edgehash_insert(eh, a, b, (void*)medi);
|
||||
e = medi;
|
||||
|
||||
MEdge *med = medge + medi;
|
||||
|
||||
med->v1 = a;
|
||||
med->v2 = b;
|
||||
|
||||
medi++;
|
||||
} else {
|
||||
e = (int)BLI_edgehash_lookup(eh, a, b);
|
||||
}
|
||||
|
||||
ml[i2].e = e;
|
||||
}
|
||||
|
||||
outli += 4;
|
||||
}
|
||||
}
|
||||
|
||||
loopi++;
|
||||
l = l->next;
|
||||
} while (l != f->l_first);
|
||||
}
|
||||
|
||||
for (int i=0; i<me->totpoly; i++) {
|
||||
if (!mpoly[i].totloop) {
|
||||
printf("error 1! %d %d\n", i, me->totpoly);
|
||||
}
|
||||
if (mpoly[i].loopstart >= me->totloop) {
|
||||
printf("error 2! %d %d l: %d totl: %d\n", i, me->totpoly, mpoly[i].loopstart, mpoly[i].totloop);
|
||||
}
|
||||
}
|
||||
|
||||
if (spaceset) {
|
||||
BKE_multires_bmesh_space_set(NULL, bm, MULTIRES_SPACE_TANGENT);
|
||||
}
|
||||
|
||||
BKE_mesh_calc_normals(me);
|
||||
BKE_mesh_tessface_calc(me);
|
||||
}
|
||||
|
||||
static void multires_bmesh_space_set_cb(void *__restrict userdata,
|
||||
const int pidx,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
||||
const int pidx,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
||||
{
|
||||
MultiresThreadedData *tdata = userdata;
|
||||
|
||||
|
@ -1047,10 +1266,10 @@ static void multires_bmesh_space_set_cb(void *__restrict userdata,
|
|||
l = f->l_first;
|
||||
S = 0;
|
||||
do {
|
||||
//for (S = 0; S < numVerts; S++, gIndex++) {
|
||||
|
||||
// for (S = 0; S < numVerts; S++, gIndex++) {
|
||||
|
||||
GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : NULL;
|
||||
MDisps *mdisp = BM_ELEM_CD_GET_VOID_P(l, cd_mdisps_off); //&mdisps[mpoly[pidx].loopstart + S];
|
||||
MDisps *mdisp = BM_ELEM_CD_GET_VOID_P(l, cd_mdisps_off); //&mdisps[mpoly[pidx].loopstart + S];
|
||||
CCGElem *grid = gridData[gIndex];
|
||||
CCGElem *subgrid = subGridData[gIndex];
|
||||
float(*dispgrid)[3] = NULL;
|
||||
|
@ -1059,86 +1278,62 @@ static void multires_bmesh_space_set_cb(void *__restrict userdata,
|
|||
|
||||
float quad[4][3];
|
||||
|
||||
//copy_v3_v3(quad[0], cent);
|
||||
//interp_v3_v3v3(quad[1], l->v->co, l->next->v->co, 0.5);
|
||||
//copy_v3_v3(quad[2], l->v->co);
|
||||
//interp_v3_v3v3(quad[3], l->v->co, l->prev->v->co, 0.5);
|
||||
float maxlen = len_v3v3(l->v->co, cent)*15.0f;
|
||||
// copy_v3_v3(quad[0], cent);
|
||||
// interp_v3_v3v3(quad[1], l->v->co, l->next->v->co, 0.5);
|
||||
// copy_v3_v3(quad[2], l->v->co);
|
||||
// interp_v3_v3v3(quad[3], l->v->co, l->prev->v->co, 0.5);
|
||||
float maxlen = len_v3v3(l->v->co, cent) * 15.0f;
|
||||
maxlen = MAX2(maxlen, 0.00001f);
|
||||
|
||||
for (y = 0; y < gridSize; y++) {
|
||||
for (x = 0; x < gridSize; x++) {
|
||||
//float *sco = CCG_grid_elem_co(key, grid, x, y);
|
||||
//float *sco = CCG_grid_elem_co(key, subgrid, x, y);
|
||||
// float *sco = CCG_grid_elem_co(key, grid, x, y);
|
||||
// float *sco = CCG_grid_elem_co(key, subgrid, x, y);
|
||||
float sco[8], udv[3], vdv[3];
|
||||
float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
|
||||
float mat[3][3], disp[3], d[3], mask;
|
||||
//float baseco[3];
|
||||
// float baseco[3];
|
||||
|
||||
float grid_u = (float)x / (float)(dGridSize-1);
|
||||
float grid_v = (float)y / (float)(dGridSize-1);
|
||||
float grid_u = (float)x / (float)(dGridSize - 1);
|
||||
float grid_v = (float)y / (float)(dGridSize - 1);
|
||||
float u, v;
|
||||
|
||||
int corner = l->head.index - f->head.index;
|
||||
int corner = S;
|
||||
if (f->len == 4) {
|
||||
BKE_subdiv_rotate_grid_to_quad(corner, grid_u, grid_v, &u, &v);
|
||||
//continue;
|
||||
} else {
|
||||
// continue;
|
||||
}
|
||||
else {
|
||||
u = 1.0 - grid_v;
|
||||
v = 1.0 - grid_u;
|
||||
}
|
||||
|
||||
BKE_subdiv_eval_limit_point_and_derivatives(tdata->sd, l->head.index, u, v, sco, udv, vdv);
|
||||
//float tan[3];
|
||||
//grid_tangent(key, x, y, 1, grid, tan);
|
||||
|
||||
//negate_v3(udv);
|
||||
|
||||
//normalize_v3(tan);
|
||||
//normalize_v3(vdv);
|
||||
//printf("%.4f\n", len_v3v3(tan, vdv));
|
||||
//printf(" %.3f %.3f %.3f\n", tan[0], tan[1], tan[2]);
|
||||
//printf(" %.3f %.3f %.3f\n", vdv[0], vdv[1], vdv[2]);
|
||||
|
||||
//negate_v3(udv);
|
||||
//negate_v3(vdv);
|
||||
BKE_multires_construct_tangent_matrix(mat, udv, vdv, corner);
|
||||
|
||||
//BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv);
|
||||
|
||||
//interp_bilinear_quad_v3(quad, (float)x/(float)gridSize, (float)y/(float)gridSize, baseco);
|
||||
|
||||
/* construct tangent space matrix */
|
||||
//grid_tangent_matrix(mat, key, x, y, grid);
|
||||
|
||||
//copy_v3_v3(sco, CCG_grid_elem_co(key, grid, x, y));
|
||||
|
||||
//sub_v3_v3(sco, CCG_grid_elem_co(key, grid, x, y));
|
||||
//oprintf("%.3f %.3f %.3f\n", sco[0], sco[1], sco[2]);
|
||||
//copy_v3_v3(sco, CCG_grid_elem_co(key, grid, x, y));
|
||||
BKE_multires_construct_tangent_matrix(mat, udv, vdv, f->len == 4 ? corner : 0);
|
||||
|
||||
copy_v3_v3(disp, data);
|
||||
|
||||
|
||||
switch (op) {
|
||||
case MULTIRES_SPACE_ABSOLUTE:
|
||||
/* Convert displacement to object space
|
||||
* and add to grid points */
|
||||
mul_v3_m3v3(disp, mat, data);
|
||||
add_v3_v3v3(data, disp, sco);
|
||||
break;
|
||||
case MULTIRES_SPACE_TANGENT:
|
||||
/* Calculate displacement between new and old
|
||||
* grid points and convert to tangent space */
|
||||
invert_m3(mat);
|
||||
case MULTIRES_SPACE_ABSOLUTE:
|
||||
/* Convert displacement to object space
|
||||
* and add to grid points */
|
||||
mul_v3_m3v3(disp, mat, data);
|
||||
add_v3_v3v3(data, disp, sco);
|
||||
//copy_v3_v3(data, sco);
|
||||
break;
|
||||
case MULTIRES_SPACE_TANGENT:
|
||||
/* Calculate displacement between new and old
|
||||
* grid points and convert to tangent space */
|
||||
invert_m3(mat);
|
||||
|
||||
sub_v3_v3v3(disp, data, sco);
|
||||
mul_v3_m3v3(data, mat, disp);
|
||||
sub_v3_v3v3(disp, data, sco);
|
||||
mul_v3_m3v3(data, mat, disp);
|
||||
|
||||
//float len = len_v3(data);
|
||||
//if (len > maxlen) {
|
||||
// mul_v3_fl(data, maxlen/len);
|
||||
//}
|
||||
break;
|
||||
// float len = len_v3(data);
|
||||
// if (len > maxlen) {
|
||||
// mul_v3_fl(data, maxlen/len);
|
||||
//}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1150,8 +1345,8 @@ static void multires_bmesh_space_set_cb(void *__restrict userdata,
|
|||
}
|
||||
|
||||
/* XXX WARNING: subsurf elements from dm and oldGridData *must* be of the same format (size),
|
||||
* because this code uses CCGKey's info from dm to access oldGridData's normals
|
||||
* (through the call to grid_tangent_matrix())! */
|
||||
* because this code uses CCGKey's info from dm to access oldGridData's normals
|
||||
* (through the call to grid_tangent_matrix())! */
|
||||
void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
|
||||
{
|
||||
if (!bm->totface || !CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
|
||||
|
@ -1168,7 +1363,6 @@ void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
Mesh _me, *me = &_me;
|
||||
memset(me, 0, sizeof(Mesh));
|
||||
CustomData_reset(&me->vdata);
|
||||
|
@ -1180,17 +1374,18 @@ void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
|
|||
CustomData_MeshMasks extra = CD_MASK_DERIVEDMESH;
|
||||
extra.lmask |= CD_MASK_MDISPS;
|
||||
|
||||
//CustomData_MeshMasks extra = {0};
|
||||
// CustomData_MeshMasks extra = {0};
|
||||
BM_mesh_bm_to_me_for_eval(bm, me, &extra);
|
||||
DerivedMesh *cddm = CDDM_from_mesh(me);
|
||||
//cddm->dm.
|
||||
// cddm->dm.
|
||||
|
||||
SubdivSettings settings2;
|
||||
//cddm ignores MDISPS layer. this turns out to be a good thing.
|
||||
//CustomData_reset(&cddm->loopData);
|
||||
//CustomData_merge(&me->ldata, &cddm->loopData, CD_MASK_MESH.lmask & ~CD_MASK_MDISPS, CD_REFERENCE, me->totloop);
|
||||
// cddm ignores MDISPS layer. this turns out to be a good thing.
|
||||
// CustomData_reset(&cddm->loopData);
|
||||
// CustomData_merge(&me->ldata, &cddm->loopData, CD_MASK_MESH.lmask & ~CD_MASK_MDISPS,
|
||||
// CD_REFERENCE, me->totloop);
|
||||
|
||||
//ensure we control the level
|
||||
// ensure we control the level
|
||||
MultiresModifierData mmdcpy = *mmd;
|
||||
mmdcpy.lvl = mmdcpy.sculptlvl = mmdcpy.renderlvl = mmdcpy.totlvl;
|
||||
|
||||
|
@ -1202,24 +1397,27 @@ void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
|
|||
if (ob) {
|
||||
fakeob = *ob;
|
||||
fakeob.sculpt = NULL;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memset(&fakeob, 0, sizeof(fakeob));
|
||||
fakeob.data = me;
|
||||
BLI_addtail(&fakeob.modifiers, &mmdcpy);
|
||||
}
|
||||
|
||||
//MULTIRES_USE_LOCAL_MMD
|
||||
//CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) multires_make_derived_from_derived(cddm, &mmdcpy, NULL, &fakeob, MULTIRES_IGNORE_SIMPLIFY|MULTIRES_USE_LOCAL_MMD);
|
||||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) subsurf_dm_create_local(NULL,
|
||||
&fakeob,
|
||||
cddm,
|
||||
mmd->totlvl,
|
||||
mmd->simple,
|
||||
0,
|
||||
mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
|
||||
false,
|
||||
false,
|
||||
SUBSURF_IGNORE_SIMPLIFY);
|
||||
// MULTIRES_USE_LOCAL_MMD
|
||||
// CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) multires_make_derived_from_derived(cddm, &mmdcpy,
|
||||
// NULL, &fakeob, MULTIRES_IGNORE_SIMPLIFY|MULTIRES_USE_LOCAL_MMD);
|
||||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)subsurf_dm_create_local(NULL,
|
||||
&fakeob,
|
||||
cddm,
|
||||
mmd->totlvl,
|
||||
mmd->simple,
|
||||
0,
|
||||
mmd->uv_smooth ==
|
||||
SUBSURF_UV_SMOOTH_NONE,
|
||||
false,
|
||||
false,
|
||||
0);
|
||||
|
||||
CCGElem **gridData, **subGridData;
|
||||
CCGKey key;
|
||||
|
@ -1228,12 +1426,12 @@ void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
|
|||
int i, gridSize, dGridSize, dSkip;
|
||||
int totpoly = bm->totface;
|
||||
|
||||
//paranoia recalc of indices/tables
|
||||
bm->elem_index_dirty |= BM_FACE|BM_VERT;
|
||||
bm->elem_table_dirty |= BM_FACE|BM_VERT;
|
||||
// paranoia recalc of indices/tables
|
||||
bm->elem_index_dirty |= BM_FACE | BM_VERT;
|
||||
bm->elem_table_dirty |= BM_FACE | BM_VERT;
|
||||
|
||||
BM_mesh_elem_index_ensure(bm, BM_FACE|BM_VERT);
|
||||
BM_mesh_elem_table_ensure(bm, BM_FACE|BM_VERT);
|
||||
BM_mesh_elem_index_ensure(bm, BM_FACE | BM_VERT);
|
||||
BM_mesh_elem_table_ensure(bm, BM_FACE | BM_VERT);
|
||||
|
||||
/*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/
|
||||
gridSize = ccgdm->dm.getGridSize(&ccgdm->dm);
|
||||
|
@ -1257,22 +1455,22 @@ void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
|
|||
BMIter iter;
|
||||
i = 0;
|
||||
int i2 = 0;
|
||||
BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BMIter iter2;
|
||||
BMLoop *l;
|
||||
|
||||
f->head.index = i;
|
||||
|
||||
BM_ITER_ELEM(l, &iter2, f, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM (l, &iter2, f, BM_LOOPS_OF_FACE) {
|
||||
MDisps *mdisp = BM_ELEM_CD_GET_VOID_P(l, cd_disp_off);
|
||||
if (!mdisp->disps) {
|
||||
multires_reallocate_mdisps(1, mdisp, mmd->totlvl);
|
||||
}
|
||||
|
||||
l->head.index = i;
|
||||
|
||||
if (f->len != 4) {
|
||||
l->head.index = i++;
|
||||
} else {
|
||||
l->head.index = i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1286,27 +1484,27 @@ void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
|
|||
settings.min_iter_per_thread = CCG_TASK_LIMIT;
|
||||
|
||||
MultiresThreadedData data = {
|
||||
.bmop = mode,
|
||||
.sd = sd,
|
||||
.gridData = gridData,
|
||||
.subGridData = subGridData,
|
||||
.key = &key,
|
||||
.lvl = mmd->totlvl,
|
||||
.bm = bm,
|
||||
.cd_mdisps_off = cd_disp_off,
|
||||
.grid_paint_mask = grid_paint_mask,
|
||||
.gridOffset = gridOffset,
|
||||
.gridSize = gridSize,
|
||||
.dGridSize = dGridSize,
|
||||
.dSkip = dSkip,
|
||||
.bmop = mode,
|
||||
.sd = sd,
|
||||
.gridData = gridData,
|
||||
.subGridData = subGridData,
|
||||
.key = &key,
|
||||
.lvl = mmd->totlvl,
|
||||
.bm = bm,
|
||||
.cd_mdisps_off = cd_disp_off,
|
||||
.grid_paint_mask = grid_paint_mask,
|
||||
.gridOffset = gridOffset,
|
||||
.gridSize = gridSize,
|
||||
.dGridSize = dGridSize,
|
||||
.dSkip = dSkip,
|
||||
};
|
||||
|
||||
BLI_task_parallel_range(0, totpoly, &data, multires_bmesh_space_set_cb, &settings);
|
||||
|
||||
//MDisps = CustomData_get
|
||||
//if (mode == MULTIRES_SPACE_TANGENT) {
|
||||
//ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
|
||||
//ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
|
||||
// MDisps = CustomData_get
|
||||
// if (mode == MULTIRES_SPACE_TANGENT) {
|
||||
// ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
|
||||
// ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
|
||||
//}
|
||||
|
||||
ccgdm->dm.release(&ccgdm->dm);
|
||||
|
@ -1354,7 +1552,7 @@ static void multires_disp_run_cb(void *__restrict userdata,
|
|||
}
|
||||
gpm->data = MEM_calloc_arrayN(key->grid_area, sizeof(float), "gpm.data");
|
||||
}
|
||||
|
||||
|
||||
for (y = 0; y < gridSize; y++) {
|
||||
for (x = 0; x < gridSize; x++) {
|
||||
float *co = CCG_grid_elem_co(key, grid, x, y);
|
||||
|
@ -1491,8 +1689,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1657,7 +1855,7 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
|
|||
|
||||
void multires_stitch_grids(Object *ob)
|
||||
{
|
||||
return; //XXX
|
||||
return; // XXX
|
||||
if (ob == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -1678,7 +1876,7 @@ void multires_stitch_grids(Object *ob)
|
|||
int num_faces;
|
||||
BKE_pbvh_get_grid_updates(pbvh, false, (void ***)&faces, &num_faces);
|
||||
if (num_faces) {
|
||||
//XXX BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, faces, num_faces);
|
||||
// XXX BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, faces, num_faces);
|
||||
MEM_freeN(faces);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5735,6 +5735,61 @@ static int edbm_mres_test_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
|
||||
extern Object *multires_dump_grids_bmesh(BMesh *bm);
|
||||
|
||||
static int edbm_dump_mres_grids_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool use_face_split = RNA_boolean_get(op->ptr, "use_face_split");
|
||||
const bool use_boundary_tear = RNA_boolean_get(op->ptr, "use_boundary_tear");
|
||||
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
uint objects_len = 0;
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
|
||||
view_layer, CTX_wm_view3d(C), &objects_len);
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
multires_dump_grids_bmesh(em->bm);
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
|
||||
|
||||
MEM_freeN(objects);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static bool mres_test_poll(bContext *C)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
if (obedit && obedit->type == OB_MESH) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
if (!em || !CustomData_has_layer(&em->bm->ldata, CD_MDISPS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MESH_OT_dump_mres_grids(wmOperatorType *ot) {
|
||||
/* identifiers */
|
||||
ot->name = "Dump Multires Grids";
|
||||
ot->description = "Dump Multires Grids";
|
||||
ot->idname = "MESH_OT_dump_mres_grids";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = edbm_dump_mres_grids_exec;
|
||||
ot->poll = mres_test_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
void MESH_OT_mres_test(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
|
@ -5744,13 +5799,10 @@ void MESH_OT_mres_test(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = edbm_mres_test_exec;
|
||||
ot->poll = ED_operator_editmesh;
|
||||
ot->poll = mres_test_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
edbm_dissolve_prop__use_face_split(ot);
|
||||
edbm_dissolve_prop__use_boundary_tear(ot);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -286,3 +286,4 @@ void MESH_OT_customdata_skin_add(struct wmOperatorType *ot);
|
|||
void MESH_OT_customdata_skin_clear(struct wmOperatorType *ot);
|
||||
void MESH_OT_customdata_custom_splitnormals_add(struct wmOperatorType *ot);
|
||||
void MESH_OT_customdata_custom_splitnormals_clear(struct wmOperatorType *ot);
|
||||
void MESH_OT_dump_mres_grids(struct wmOperatorType *ot);
|
||||
|
|
|
@ -209,6 +209,7 @@ void ED_operatortypes_mesh(void)
|
|||
WM_operatortype_append(MESH_OT_smooth_normals);
|
||||
WM_operatortype_append(MESH_OT_mod_weighted_strength);
|
||||
WM_operatortype_append(MESH_OT_mres_test);
|
||||
WM_operatortype_append(MESH_OT_dump_mres_grids);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2851,7 +2851,7 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
|
|||
/* set the margin really quickly before the packing operation*/
|
||||
scene->toolsettings->uvcalc_margin = 0.001f;
|
||||
uvedit_pack_islands(scene, ob, bm);
|
||||
BM_mesh_bm_to_me(bmain, bm, me, (&(struct BMeshToMeshParams){0}));
|
||||
BM_mesh_bm_to_me(bmain, NULL, bm, me, (&(struct BMeshToMeshParams){0}));
|
||||
BM_mesh_free(bm);
|
||||
|
||||
if (sync_selection) {
|
||||
|
|
|
@ -454,7 +454,7 @@ void bc_triangulate_mesh(Mesh *me)
|
|||
|
||||
BMeshToMeshParams bm_to_me_params = {0};
|
||||
bm_to_me_params.calc_object_remap = false;
|
||||
BM_mesh_bm_to_me(NULL, bm, me, &bm_to_me_params);
|
||||
BM_mesh_bm_to_me(NULL, NULL, bm, me, &bm_to_me_params);
|
||||
BM_mesh_free(bm);
|
||||
}
|
||||
|
||||
|
|
|
@ -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, NULL,
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh,
|
||||
&(struct BMeshCreateParams){0},
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -171,7 +171,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
}
|
||||
}
|
||||
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh, NULL,
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh,
|
||||
&(struct BMeshCreateParams){0},
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = calc_face_normal,
|
||||
|
|
|
@ -65,7 +65,7 @@ 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, NULL,
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh,
|
||||
&(struct BMeshCreateParams){0},
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = calc_face_normals,
|
||||
|
|
|
@ -70,7 +70,7 @@ static Mesh *triangulate_mesh(Mesh *mesh,
|
|||
cd_mask_extra.lmask |= CD_MASK_NORMAL;
|
||||
}
|
||||
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh, NULL,
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh,
|
||||
&((struct BMeshCreateParams){0}),
|
||||
&((struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -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, NULL,
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh,
|
||||
&(struct BMeshCreateParams){0},
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -1056,7 +1056,7 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
|
|||
params.calc_object_remap = true;
|
||||
}
|
||||
|
||||
BM_mesh_bm_to_me(bmain, bm, me, ¶ms);
|
||||
BM_mesh_bm_to_me(bmain, NULL, bm, me, ¶ms);
|
||||
|
||||
/* we could have the user do this but if they forget blender can easy crash
|
||||
* since the references arrays for the objects derived meshes are now invalid */
|
||||
|
|
Loading…
Reference in New Issue