commit multires patch
This commit is contained in:
parent
7447eb7e74
commit
4659855b0f
|
@ -1016,6 +1016,7 @@ Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference)
|
|||
}
|
||||
|
||||
BMesh *BKE_mesh_to_bmesh_ex(const Mesh *me,
|
||||
const Object *ob,
|
||||
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(bm, me, convert_params);
|
||||
BM_mesh_bm_from_me(ob, bm, me, convert_params);
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
@ -1034,6 +1035,7 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me,
|
|||
const struct BMeshCreateParams *params)
|
||||
{
|
||||
return BKE_mesh_to_bmesh_ex(me,
|
||||
ob,
|
||||
params,
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = false,
|
||||
|
@ -1049,7 +1051,7 @@ Mesh *BKE_mesh_from_bmesh_nomain(BMesh *bm,
|
|||
{
|
||||
BLI_assert(params->calc_object_remap == false);
|
||||
Mesh *mesh = BKE_id_new_nomain(ID_ME, NULL);
|
||||
BM_mesh_bm_to_me(NULL, bm, mesh, params);
|
||||
BM_mesh_bm_to_me(NULL, NULL, bm, mesh, params);
|
||||
BKE_mesh_copy_settings(mesh, me_settings);
|
||||
return mesh;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ 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,
|
||||
|
|
|
@ -443,7 +443,7 @@ struct Mesh *BKE_mesh_remesh_voxel_fix_poles(struct Mesh *mesh)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mesh_mapping.h"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_modifier.h"
|
||||
|
@ -49,7 +50,9 @@
|
|||
#include "BKE_pbvh.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
#include "BKE_subdiv_eval.h"
|
||||
#include "BKE_subsurf.h"
|
||||
#include "BKE_subdiv.h"
|
||||
|
||||
#include "BKE_object.h"
|
||||
|
||||
|
@ -58,6 +61,8 @@
|
|||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "multires_reshape.h"
|
||||
#include "multires_inline.h"
|
||||
#include "bmesh.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
@ -957,31 +962,16 @@ 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 == 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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
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));
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1000,21 +990,336 @@ static void grid_tangent_matrix(float mat[3][3], const CCGKey *key, int x, int y
|
|||
|
||||
typedef struct MultiresThreadedData {
|
||||
DispOp op;
|
||||
MultiResSpace bmop;
|
||||
BMesh *bm;
|
||||
int lvl;
|
||||
CCGElem **gridData, **subGridData;
|
||||
CCGKey *key;
|
||||
CCGKey *sub_key;
|
||||
Subdiv *sd;
|
||||
MPoly *mpoly;
|
||||
MDisps *mdisps;
|
||||
GridPaintMask *grid_paint_mask;
|
||||
int *gridOffset;
|
||||
int cd_mdisps_off;
|
||||
int gridSize, dGridSize, dSkip;
|
||||
float (*smat)[3];
|
||||
} MultiresThreadedData;
|
||||
|
||||
static void multires_bmesh_space_set_cb(void *__restrict userdata,
|
||||
const int pidx,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
||||
{
|
||||
MultiresThreadedData *tdata = userdata;
|
||||
|
||||
int cd_mdisps_off = tdata->cd_mdisps_off;
|
||||
BMesh *bm = tdata->bm;
|
||||
MultiResSpace op = tdata->bmop;
|
||||
CCGElem **gridData = tdata->gridData;
|
||||
CCGElem **subGridData = tdata->subGridData;
|
||||
CCGKey *key = tdata->key;
|
||||
BMFace *f = bm->ftable[pidx];
|
||||
MDisps *mdisps = tdata->mdisps;
|
||||
GridPaintMask *grid_paint_mask = tdata->grid_paint_mask;
|
||||
int *gridOffset = tdata->gridOffset;
|
||||
int gridSize = tdata->gridSize;
|
||||
int dGridSize = tdata->dGridSize;
|
||||
int dSkip = tdata->dSkip;
|
||||
|
||||
int S, x, y, gIndex = gridOffset[pidx];
|
||||
|
||||
BMLoop *l = f->l_first;
|
||||
float cent[3];
|
||||
int tot = 0;
|
||||
|
||||
zero_v3(cent);
|
||||
|
||||
do {
|
||||
add_v3_v3(cent, l->v->co);
|
||||
tot++;
|
||||
l = l->next;
|
||||
} while (l != f->l_first);
|
||||
|
||||
mul_v3_fl(cent, 1.0f / (float)tot);
|
||||
|
||||
float simplemat[3][3];
|
||||
|
||||
l = f->l_first;
|
||||
S = 0;
|
||||
do {
|
||||
//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];
|
||||
CCGElem *grid = gridData[gIndex];
|
||||
CCGElem *subgrid = subGridData[gIndex];
|
||||
float(*dispgrid)[3] = NULL;
|
||||
|
||||
dispgrid = mdisp->disps;
|
||||
|
||||
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;
|
||||
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[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 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;
|
||||
if (f->len == 4) {
|
||||
BKE_subdiv_rotate_grid_to_quad(corner, grid_u, grid_v, &u, &v);
|
||||
//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));
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
S++;
|
||||
gIndex++;
|
||||
l = l->next;
|
||||
} while (l != f->l_first);
|
||||
}
|
||||
|
||||
/* 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())! */
|
||||
void BKE_multires_bmesh_space_set(Object *ob, BMesh *bm, int mode)
|
||||
{
|
||||
if (!bm->totface || !CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MultiresModifierData *mmd = bm->haveMultiResSettings ? &bm->multires : NULL;
|
||||
|
||||
if (!mmd && ob) {
|
||||
mmd = get_multires_modifier(NULL, ob, true);
|
||||
}
|
||||
|
||||
if (!mmd || !CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Mesh _me, *me = &_me;
|
||||
memset(me, 0, sizeof(Mesh));
|
||||
CustomData_reset(&me->vdata);
|
||||
CustomData_reset(&me->edata);
|
||||
CustomData_reset(&me->ldata);
|
||||
CustomData_reset(&me->fdata);
|
||||
CustomData_reset(&me->pdata);
|
||||
|
||||
CustomData_MeshMasks extra = CD_MASK_DERIVEDMESH;
|
||||
extra.lmask |= CD_MASK_MDISPS;
|
||||
|
||||
//CustomData_MeshMasks extra = {0};
|
||||
BM_mesh_bm_to_me_for_eval(bm, me, &extra);
|
||||
DerivedMesh *cddm = CDDM_from_mesh(me);
|
||||
//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);
|
||||
|
||||
//ensure we control the level
|
||||
MultiresModifierData mmdcpy = *mmd;
|
||||
mmdcpy.lvl = mmdcpy.sculptlvl = mmdcpy.renderlvl = mmdcpy.totlvl;
|
||||
|
||||
BKE_multires_subdiv_settings_init(&settings2, &mmdcpy);
|
||||
Subdiv *sd = BKE_subdiv_new_from_mesh(&settings2, me);
|
||||
BKE_subdiv_eval_begin_from_mesh(sd, me, NULL);
|
||||
|
||||
Object fakeob;
|
||||
if (ob) {
|
||||
fakeob = *ob;
|
||||
fakeob.sculpt = NULL;
|
||||
} 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);
|
||||
|
||||
CCGElem **gridData, **subGridData;
|
||||
CCGKey key;
|
||||
GridPaintMask *grid_paint_mask = NULL;
|
||||
int *gridOffset;
|
||||
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;
|
||||
|
||||
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);
|
||||
gridData = ccgdm->dm.getGridData(&ccgdm->dm);
|
||||
gridOffset = ccgdm->dm.getGridOffset(&ccgdm->dm);
|
||||
ccgdm->dm.getGridKey(&ccgdm->dm, &key);
|
||||
subGridData = gridData;
|
||||
|
||||
dGridSize = multires_side_tot[mmd->totlvl];
|
||||
dSkip = (dGridSize - 1) / (gridSize - 1);
|
||||
|
||||
/* multires paint masks */
|
||||
if (key.has_mask) {
|
||||
grid_paint_mask = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
|
||||
}
|
||||
|
||||
/* when adding new faces in edit mode, need to allocate disps */
|
||||
int cd_disp_off = CustomData_get_offset(&bm->ldata, CD_MDISPS);
|
||||
|
||||
BMFace *f;
|
||||
BMIter iter;
|
||||
i = 0;
|
||||
int i2 = 0;
|
||||
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) {
|
||||
MDisps *mdisp = BM_ELEM_CD_GET_VOID_P(l, cd_disp_off);
|
||||
if (!mdisp->disps) {
|
||||
multires_reallocate_mdisps(1, mdisp, mmd->totlvl);
|
||||
}
|
||||
|
||||
if (f->len != 4) {
|
||||
l->head.index = i++;
|
||||
} else {
|
||||
l->head.index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (f->len == 4) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
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,
|
||||
};
|
||||
|
||||
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);
|
||||
//}
|
||||
|
||||
ccgdm->dm.release(&ccgdm->dm);
|
||||
DM_release(cddm);
|
||||
BKE_mesh_free(me);
|
||||
BKE_subdiv_free(sd);
|
||||
}
|
||||
|
||||
static void multires_disp_run_cb(void *__restrict userdata,
|
||||
const int pidx,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
||||
{
|
||||
return;
|
||||
MultiresThreadedData *tdata = userdata;
|
||||
|
||||
DispOp op = tdata->op;
|
||||
|
@ -1049,7 +1354,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);
|
||||
|
@ -1186,8 +1491,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1352,6 +1657,7 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
|
|||
|
||||
void multires_stitch_grids(Object *ob)
|
||||
{
|
||||
return; //XXX
|
||||
if (ob == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -1372,7 +1678,7 @@ void multires_stitch_grids(Object *ob)
|
|||
int num_faces;
|
||||
BKE_pbvh_get_grid_updates(pbvh, false, (void ***)&faces, &num_faces);
|
||||
if (num_faces) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1491,7 +1797,7 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u,
|
|||
|
||||
urat = u - x;
|
||||
vrat = v - y;
|
||||
uopp = 1 - urat;
|
||||
uopp = 1.0f - urat;
|
||||
|
||||
mul_v3_v3fl(d[0], disps[y * st + x], uopp);
|
||||
mul_v3_v3fl(d[1], disps[y * st + x2], urat);
|
||||
|
@ -1500,7 +1806,7 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u,
|
|||
|
||||
add_v3_v3v3(d2[0], d[0], d[1]);
|
||||
add_v3_v3v3(d2[1], d[2], d[3]);
|
||||
mul_v3_fl(d2[0], 1 - vrat);
|
||||
mul_v3_fl(d2[0], 1.0f - vrat);
|
||||
mul_v3_fl(d2[1], vrat);
|
||||
|
||||
add_v3_v3v3(out, d2[0], d2[1]);
|
||||
|
|
|
@ -881,7 +881,8 @@ static BMesh *get_bmesh_from_mesh(Mesh *mesh)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -1151,6 +1152,7 @@ bool multires_unsubdivide_to_basemesh(MultiresUnsubdivideContext *context)
|
|||
/* Store the new base-mesh as a mesh in context, free bmesh. */
|
||||
context->base_mesh = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
|
||||
BM_mesh_bm_to_me(NULL,
|
||||
NULL,
|
||||
bm_base_mesh,
|
||||
context->base_mesh,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
|
|
@ -1316,6 +1316,7 @@ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
|
|||
BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
|
||||
}
|
||||
BM_mesh_bm_to_me(NULL,
|
||||
NULL,
|
||||
ss->bm,
|
||||
ob->data,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
|
|
@ -1453,6 +1453,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
|
|||
if (check_rendered_viewport_visible(bmain)) {
|
||||
BMesh *bm = mesh->edit_mesh->bm;
|
||||
BM_mesh_bm_to_me(bmain,
|
||||
NULL,
|
||||
bm,
|
||||
mesh,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
|
|
@ -986,6 +986,7 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG *subdiv_ccg,
|
|||
CCGKey *key,
|
||||
SubdivCCGFace *face)
|
||||
{
|
||||
return; //XXX
|
||||
CCGElem **grids = subdiv_ccg->grids;
|
||||
const int num_face_grids = face->num_grids;
|
||||
const int grid_size = subdiv_ccg->grid_size;
|
||||
|
@ -1043,6 +1044,7 @@ static void subdiv_ccg_average_grids_boundary(SubdivCCG *subdiv_ccg,
|
|||
SubdivCCGAdjacentEdge *adjacent_edge,
|
||||
AverageGridsBoundariesTLSData *tls)
|
||||
{
|
||||
return; //XXXX
|
||||
const int num_adjacent_faces = adjacent_edge->num_adjacent_faces;
|
||||
const int grid_size2 = subdiv_ccg->grid_size * 2;
|
||||
if (num_adjacent_faces == 1) {
|
||||
|
@ -1106,6 +1108,7 @@ static void subdiv_ccg_average_grids_corners(SubdivCCG *subdiv_ccg,
|
|||
CCGKey *key,
|
||||
SubdivCCGAdjacentVertex *adjacent_vertex)
|
||||
{
|
||||
return;
|
||||
const int num_adjacent_faces = adjacent_vertex->num_adjacent_faces;
|
||||
if (num_adjacent_faces == 1) {
|
||||
/* Nothing to average with. */
|
||||
|
@ -1131,6 +1134,7 @@ static void subdiv_ccg_average_grids_corners_task(void *__restrict userdata_v,
|
|||
const int adjacent_vertex_index,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls_v))
|
||||
{
|
||||
return;
|
||||
AverageGridsCornerData *data = userdata_v;
|
||||
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
|
||||
CCGKey *key = data->key;
|
||||
|
@ -1140,6 +1144,7 @@ static void subdiv_ccg_average_grids_corners_task(void *__restrict userdata_v,
|
|||
|
||||
static void subdiv_ccg_average_all_boundaries(SubdivCCG *subdiv_ccg, CCGKey *key)
|
||||
{
|
||||
return;
|
||||
TaskParallelSettings parallel_range_settings;
|
||||
BLI_parallel_range_settings_defaults(¶llel_range_settings);
|
||||
AverageGridsBoundariesData boundaries_data = {
|
||||
|
@ -1159,6 +1164,7 @@ static void subdiv_ccg_average_all_boundaries(SubdivCCG *subdiv_ccg, CCGKey *key
|
|||
|
||||
static void subdiv_ccg_average_all_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
|
||||
{
|
||||
return;
|
||||
TaskParallelSettings parallel_range_settings;
|
||||
BLI_parallel_range_settings_defaults(¶llel_range_settings);
|
||||
AverageGridsCornerData corner_data = {
|
||||
|
@ -1174,12 +1180,14 @@ static void subdiv_ccg_average_all_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
|
|||
|
||||
static void subdiv_ccg_average_all_boundaries_and_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
|
||||
{
|
||||
return;
|
||||
subdiv_ccg_average_all_boundaries(subdiv_ccg, key);
|
||||
subdiv_ccg_average_all_corners(subdiv_ccg, key);
|
||||
}
|
||||
|
||||
void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg)
|
||||
{
|
||||
return;
|
||||
CCGKey key;
|
||||
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
|
||||
TaskParallelSettings parallel_range_settings;
|
||||
|
@ -1190,6 +1198,7 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg)
|
|||
.subdiv_ccg = subdiv_ccg,
|
||||
.key = &key,
|
||||
};
|
||||
return;
|
||||
BLI_task_parallel_range(0,
|
||||
subdiv_ccg->num_faces,
|
||||
&inner_data,
|
||||
|
@ -1209,6 +1218,7 @@ static void subdiv_ccg_stitch_face_inner_grids_task(
|
|||
const int face_index,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls_v))
|
||||
{
|
||||
return; //XXXX
|
||||
StitchFacesInnerGridsData *data = userdata_v;
|
||||
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
|
||||
CCGKey *key = data->key;
|
||||
|
@ -1222,6 +1232,7 @@ void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
|
|||
struct CCGFace **effected_faces,
|
||||
int num_effected_faces)
|
||||
{
|
||||
return; //XXX
|
||||
CCGKey key;
|
||||
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
|
||||
StitchFacesInnerGridsData data = {
|
||||
|
|
|
@ -186,6 +186,7 @@ static void average_read_displacement_object(MultiresDisplacementData *data,
|
|||
const int corner_index,
|
||||
float r_D[3])
|
||||
{
|
||||
return;
|
||||
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
|
||||
const MPoly *poly = &data->mpoly[poly_corner->poly_index];
|
||||
/* Get (u, v) coordinate within the other ptex face which corresponds to
|
||||
|
@ -231,6 +232,7 @@ static void average_with_other(SubdivDisplacement *displacement,
|
|||
const int corner_delta,
|
||||
float r_D[3])
|
||||
{
|
||||
return;
|
||||
MultiresDisplacementData *data = displacement->user_data;
|
||||
const MDisps *other_displacement_grid = displacement_get_other_grid(
|
||||
displacement, ptex_face_index, corner, corner_delta);
|
||||
|
@ -295,6 +297,7 @@ static void average_displacement(SubdivDisplacement *displacement,
|
|||
const float grid_v,
|
||||
float r_D[3])
|
||||
{
|
||||
return;
|
||||
switch (average_with) {
|
||||
case AVERAGE_WITH_ALL:
|
||||
average_with_all(displacement, ptex_face_index, corner, grid_u, grid_v, r_D);
|
||||
|
@ -360,8 +363,9 @@ static void eval_displacement(SubdivDisplacement *displacement,
|
|||
BKE_multires_construct_tangent_matrix(tangent_matrix, dPdu, dPdv, corner_of_quad);
|
||||
mul_v3_m3v3(r_D, tangent_matrix, tangent_D);
|
||||
/* For the boundary points of grid average two (or all) neighbor grids. */
|
||||
const int corner = displacement_get_face_corner(data, ptex_face_index, u, v);
|
||||
average_displacement(displacement, average_with, ptex_face_index, corner, grid_u, grid_v, r_D);
|
||||
//XXX
|
||||
//const int corner = displacement_get_face_corner(data, ptex_face_index, u, v);
|
||||
//average_displacement(displacement, average_with, ptex_face_index, corner, grid_u, grid_v, r_D);
|
||||
}
|
||||
|
||||
static void free_displacement(SubdivDisplacement *displacement)
|
||||
|
|
|
@ -174,6 +174,11 @@ void BKE_subdiv_eval_limit_point(
|
|||
BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, r_P, NULL, NULL);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void BKE_subdiv_eval_limit_point_and_derivatives(Subdiv *subdiv,
|
||||
const int ptex_face_index,
|
||||
const float u,
|
||||
|
@ -196,7 +201,7 @@ void BKE_subdiv_eval_limit_point_and_derivatives(Subdiv *subdiv,
|
|||
* that giving totally unusable derivatives. */
|
||||
|
||||
if (r_dPdu != NULL && r_dPdv != NULL) {
|
||||
if ((is_zero_v3(r_dPdu) || is_zero_v3(r_dPdv)) || equals_v3v3(r_dPdu, r_dPdv)) {
|
||||
if ((close_zero(r_dPdu) || close_zero(r_dPdv)) || equals_v3v3(r_dPdu, r_dPdv)) {
|
||||
subdiv->evaluator->evaluateLimit(subdiv->evaluator,
|
||||
ptex_face_index,
|
||||
u * 0.999f + 0.0005f,
|
||||
|
|
|
@ -182,9 +182,9 @@ set(LIB
|
|||
extern_rangetree
|
||||
)
|
||||
|
||||
if(MSVC AND NOT MSVC_CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX /wd4101")
|
||||
endif()
|
||||
#if(MSVC AND NOT MSVC_CLANG)
|
||||
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX /wd4101")
|
||||
#endif()
|
||||
|
||||
if(WITH_BULLET)
|
||||
list(APPEND INC_SYS
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_modifier_types.h"
|
||||
|
||||
/** \file
|
||||
* \ingroup bmesh
|
||||
*/
|
||||
|
@ -266,6 +268,9 @@ typedef struct BMesh {
|
|||
ListBase errorstack;
|
||||
|
||||
void *py_handle;
|
||||
MultiresModifierData multires; //copy of multires settings
|
||||
bool haveMultiResSettings;
|
||||
int multiresSpace;
|
||||
} BMesh;
|
||||
|
||||
/* BMHeader->htype (char) */
|
||||
|
|
|
@ -27,11 +27,13 @@
|
|||
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_array.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_multires.h"
|
||||
|
@ -314,17 +316,50 @@ static bool quad_co(const float v1[3],
|
|||
/* rotate */
|
||||
poly_rotate_plane(n, projverts, 5);
|
||||
|
||||
float projverts2[4][3];
|
||||
|
||||
/* subtract origin */
|
||||
for (i = 0; i < 4; i++) {
|
||||
sub_v2_v2(projverts[i], projverts[4]);
|
||||
|
||||
copy_v3_v3(projverts2[i], projverts[i]);
|
||||
}
|
||||
|
||||
if (!isect_point_quad_v2(origin, projverts[0], projverts[1], projverts[2], projverts[3])) {
|
||||
//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);
|
||||
sub_v3_v3(projverts2[1], c);
|
||||
sub_v3_v3(projverts2[2], c);
|
||||
sub_v3_v3(projverts2[3], c);
|
||||
mul_v3_fl(projverts2[0], 1.0f + eps);
|
||||
mul_v3_fl(projverts2[1], 1.0f + eps);
|
||||
mul_v3_fl(projverts2[2], 1.0f + eps);
|
||||
mul_v3_fl(projverts2[3], 1.0f + eps);
|
||||
add_v3_v3(projverts2[0], c);
|
||||
add_v3_v3(projverts2[1], c);
|
||||
add_v3_v3(projverts2[2], c);
|
||||
add_v3_v3(projverts2[3], c);
|
||||
#endif
|
||||
|
||||
|
||||
if (!isect_point_quad_v2(origin, projverts2[0], projverts2[1], projverts2[2], projverts2[3])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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) {
|
||||
// return false;
|
||||
//}
|
||||
|
||||
CLAMP(r_uv[0], 0.0f, 0.99999f);
|
||||
CLAMP(r_uv[1], 0.0f, 0.99999f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -353,8 +388,7 @@ static bool mdisp_in_mdispquad(BMLoop *l_src,
|
|||
float r_axis_y[3],
|
||||
float r_uv[2])
|
||||
{
|
||||
float v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3];
|
||||
float eps = FLT_EPSILON * 4000;
|
||||
float v1[3], v2[3], v3[3], v4[3], e1[3], e2[3];
|
||||
|
||||
if (is_zero_v3(l_src->v->no)) {
|
||||
BM_vert_normal_update_all(l_src->v);
|
||||
|
@ -366,6 +400,9 @@ 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);
|
||||
|
||||
sub_v3_v3(v1, c);
|
||||
|
@ -380,6 +417,7 @@ 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;
|
||||
|
@ -447,8 +485,10 @@ typedef struct BMLoopInterpMultiresData {
|
|||
BMLoop *l_src_first;
|
||||
int cd_loop_mdisp_offset;
|
||||
|
||||
int space;
|
||||
MDisps *md_dst;
|
||||
const float *f_src_center;
|
||||
const float *f_dst_center;
|
||||
|
||||
float *axis_x, *axis_y;
|
||||
float *v1, *v4;
|
||||
|
@ -467,6 +507,7 @@ static void loop_interp_multires_cb(void *__restrict userdata,
|
|||
BMLoop *l_first = data->l_src_first;
|
||||
BMLoop *l_dst = data->l_dst;
|
||||
const int cd_loop_mdisp_offset = data->cd_loop_mdisp_offset;
|
||||
int space = data->space;
|
||||
|
||||
MDisps *md_dst = data->md_dst;
|
||||
const float *f_src_center = data->f_src_center;
|
||||
|
@ -481,6 +522,19 @@ static void loop_interp_multires_cb(void *__restrict userdata,
|
|||
|
||||
const int res = data->res;
|
||||
const float d = data->d;
|
||||
float quad[4][3];
|
||||
|
||||
float n1[3], n2[3];
|
||||
normal_tri_v3(n1, l_dst->v->co, l_dst->next->v->co, data->f_dst_center);
|
||||
|
||||
if (space == MULTIRES_SPACE_ABSOLUTE) {
|
||||
BMLoop *l = l_dst;
|
||||
|
||||
copy_v3_v3(quad[0], data->f_dst_center);
|
||||
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 x = d * ix, y;
|
||||
int iy;
|
||||
|
@ -492,24 +546,70 @@ static void loop_interp_multires_cb(void *__restrict userdata,
|
|||
madd_v3_v3v3fl(co2, v4, e2, y);
|
||||
interp_v3_v3v3(co, co1, co2, x);
|
||||
|
||||
float sum[3];
|
||||
int tot = 0;
|
||||
zero_v3(sum);
|
||||
float mindis = 1e17;
|
||||
|
||||
float baseco[3];
|
||||
if (space == MULTIRES_SPACE_ABSOLUTE) {
|
||||
interp_bilinear_quad_v3(quad, x, y, baseco);
|
||||
}
|
||||
|
||||
do {
|
||||
MDisps *md_src;
|
||||
float src_axis_x[3], src_axis_y[3];
|
||||
float uv[2];
|
||||
|
||||
normal_tri_v3(n2, l_iter->v->co, l_iter->next->v->co, data->f_src_center);
|
||||
float th = dot_v3v3(n1, n2);
|
||||
if (th < 0.0f) {
|
||||
negate_v3(n2);
|
||||
}
|
||||
|
||||
th = acos(dot_v3v3(n1, n2)*0.999999f);
|
||||
if (th > M_PI*0.1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
|
||||
|
||||
if (mdisp_in_mdispquad(l_dst, l_iter, f_src_center, co, res, src_axis_x, src_axis_y, uv)) {
|
||||
old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, uv[0], uv[1]);
|
||||
bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md_dst->disps[iy * res + ix]);
|
||||
float disp[3];
|
||||
copy_v3_v3(disp, md_dst->disps[iy * res + ix]);
|
||||
|
||||
break;
|
||||
old_mdisps_bilinear(disp, md_src->disps, res, uv[0], uv[1]);
|
||||
|
||||
if (space == MULTIRES_SPACE_TANGENT) {
|
||||
bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, disp);
|
||||
}
|
||||
|
||||
float l = len_v3v3(disp, baseco);
|
||||
if (l < mindis) {
|
||||
mindis = l;
|
||||
//tot++;
|
||||
//copy_v3_v3(sum, disp);
|
||||
}
|
||||
add_v3_v3(sum, disp);
|
||||
tot++;
|
||||
//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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BM_loop_interp_multires_ex(BMesh *UNUSED(bm),
|
||||
void BM_loop_interp_multires_ex(BMesh *bm,
|
||||
BMLoop *l_dst,
|
||||
const BMFace *f_src,
|
||||
const float f_dst_center[3],
|
||||
|
@ -551,7 +651,9 @@ void BM_loop_interp_multires_ex(BMesh *UNUSED(bm),
|
|||
.cd_loop_mdisp_offset = cd_loop_mdisp_offset,
|
||||
.md_dst = md_dst,
|
||||
.f_src_center = f_src_center,
|
||||
.f_dst_center = f_dst_center,
|
||||
.axis_x = axis_x,
|
||||
.space = bm->multiresSpace,
|
||||
.axis_y = axis_y,
|
||||
.v1 = v1,
|
||||
.v4 = v4,
|
||||
|
@ -597,6 +699,8 @@ void BM_face_interp_multires_ex(BMesh *bm,
|
|||
BM_loop_interp_multires_ex(
|
||||
bm, l_iter, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset);
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
||||
BM_face_multires_bounds_smooth(bm, f_dst);
|
||||
}
|
||||
|
||||
void BM_face_interp_multires(BMesh *bm, BMFace *f_dst, const BMFace *f_src)
|
||||
|
@ -614,12 +718,247 @@ 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) {
|
||||
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
|
||||
float (*orig)[3] = NULL;
|
||||
BLI_array_staticdeclare(orig, 256*256);
|
||||
|
||||
if (cd_loop_mdisp_offset < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
float cent[3];
|
||||
zero_v3(cent);
|
||||
|
||||
int ctot = 0;
|
||||
BMLoop *cl = f->l_first;
|
||||
do {
|
||||
add_v3_v3(cent, cl->v->co);
|
||||
cl = cl->next;
|
||||
ctot++;
|
||||
} while (cl != f->l_first);
|
||||
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},
|
||||
};
|
||||
|
||||
int totoff = sizeof(offs) / sizeof(*offs);
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(a) ((a) < 0 ? -(a) : (a))
|
||||
#endif
|
||||
|
||||
//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;
|
||||
|
||||
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);
|
||||
float u = 0.0;
|
||||
|
||||
BLI_array_clear(orig);
|
||||
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) {
|
||||
float v = 0.0;
|
||||
|
||||
/*x < 0, x >= res, y < 0, y >= res, winding_matches*/
|
||||
for (int y=start; y<end; y++, v += df) {
|
||||
float co[3];
|
||||
float tot = 0.0f;
|
||||
|
||||
zero_v3(co);
|
||||
|
||||
int idx1 = y*res + x;
|
||||
|
||||
for (int oi=0; oi<totoff; oi++) {
|
||||
int ox = x + offs[oi][0];
|
||||
int oy = y + offs[oi][1];
|
||||
MDisps *md2 = md;
|
||||
|
||||
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) {
|
||||
l2 = ls->prev;
|
||||
int t = oy;
|
||||
|
||||
oy = -ox;
|
||||
ox = t;
|
||||
} else if (oy < 0 && ox >= 0 && ox < res-1) {
|
||||
l2 = ls->next;
|
||||
int t = oy;
|
||||
|
||||
oy = ox;
|
||||
ox = -t;
|
||||
} else if (ox >= res && oy >= 0 && oy < res) {
|
||||
l2 = ls->radial_next;
|
||||
|
||||
if (ls->v != l2->v) {
|
||||
l2 = l2->next;
|
||||
int t = oy;
|
||||
|
||||
oy = 2*res - ox - 1;
|
||||
ox = t;
|
||||
} else {
|
||||
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) {
|
||||
l2 = ls->prev->radial_next;
|
||||
if (l2->v == ls->v) {
|
||||
int t = ox;
|
||||
|
||||
ox = 2*res - oy - 1;
|
||||
oy = t;
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (l2) {
|
||||
//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;
|
||||
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;
|
||||
}
|
||||
w = 1.0;
|
||||
|
||||
mul_v3_fl(co2, w);
|
||||
|
||||
tot += w;
|
||||
add_v3_v3(co, co2);
|
||||
}
|
||||
|
||||
/*
|
||||
float vec[3];
|
||||
copy_v3_v3(vec, f->no);
|
||||
mul_v3_fl(vec, 0.4);
|
||||
|
||||
add_v3_v3(md->disps[idx1], vec);
|
||||
sub_v3_v3(md->disps[idx1], cent);
|
||||
mul_v3_fl(md->disps[idx1], 1.2);
|
||||
add_v3_v3(md->disps[idx1], cent);
|
||||
|
||||
continue;
|
||||
//*/
|
||||
|
||||
if (tot > 0.0f) {
|
||||
mul_v3_fl(co, 1.0f / tot);
|
||||
copy_v3_v3(md->disps[idx1], co);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
} while (l != f->l_first);
|
||||
|
||||
BLI_array_free(orig);
|
||||
}
|
||||
void bmo_test_mres_smooth_exec(BMesh *bm, BMOperator *op) {
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
|
||||
if (!CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!ok) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* smooths boundaries between multires grids,
|
||||
* including some borders in adjacent faces
|
||||
*/
|
||||
void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
|
||||
{
|
||||
return;
|
||||
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
|
||||
BMLoop *l;
|
||||
BMIter liter;
|
||||
|
@ -693,7 +1032,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)sqrt(mdl1->totdisp);
|
||||
sides = (int)floor(sqrt(mdl1->totdisp)+FLT_EPSILON);
|
||||
for (y = 0; y < sides; y++) {
|
||||
int a1, a2, o1, o2;
|
||||
|
||||
|
@ -711,14 +1050,16 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
|
|||
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! */
|
||||
add_v3_v3v3(co1, mdl1->disps[a1], mdl2->disps[a2]);
|
||||
mul_v3_fl(co1, 0.18);
|
||||
//mul_v3_fl(co1, 0.18);
|
||||
|
||||
add_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2]);
|
||||
mul_v3_fl(co2, 0.32);
|
||||
//add_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2]);
|
||||
//mul_v3_fl(co2, 0.32);
|
||||
|
||||
add_v3_v3v3(co, co1, co2);
|
||||
interp_v3_v3v3(co, co1, co2, 0.5f);
|
||||
//add_v3_v3v3(co, co1, co2);
|
||||
|
||||
copy_v3_v3(mdl1->disps[o1], co);
|
||||
copy_v3_v3(mdl2->disps[o2], co);
|
||||
|
|
|
@ -1954,6 +1954,11 @@ void BM_custom_loop_normals_from_vector_layer(BMesh *bm, bool add_sharp_edges)
|
|||
bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL);
|
||||
}
|
||||
|
||||
static void bmesh_convert_space(BMesh *bm, MultiResSpace from, MultiResSpace to)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief BMesh Begin Edit
|
||||
*
|
||||
|
@ -1961,24 +1966,22 @@ void BM_custom_loop_normals_from_vector_layer(BMesh *bm, bool add_sharp_edges)
|
|||
* the editing operations are done. These are called by the tools/operator
|
||||
* API for each time a tool is executed.
|
||||
*/
|
||||
void bmesh_edit_begin(BMesh *UNUSED(bm), BMOpTypeFlag UNUSED(type_flag))
|
||||
void bmesh_edit_begin(BMesh *bm, BMOpTypeFlag type_flag)
|
||||
{
|
||||
/* Most operators seem to be using BMO_OPTYPE_FLAG_UNTAN_MULTIRES to change the MDisps to
|
||||
* absolute space during mesh edits. With this enabled, changes to the topology
|
||||
* (loop cuts, edge subdivides, etc) are not reflected in the higher levels of
|
||||
* the mesh at all, which doesn't seem right. Turning off completely for now,
|
||||
* until this is shown to be better for certain types of mesh edits. */
|
||||
#ifdef BMOP_UNTAN_MULTIRES_ENABLED
|
||||
/* switch multires data out of tangent space */
|
||||
if ((type_flag & BMO_OPTYPE_FLAG_UNTAN_MULTIRES) &&
|
||||
CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
|
||||
bmesh_mdisps_space_set(bm, MULTIRES_SPACE_TANGENT, MULTIRES_SPACE_ABSOLUTE);
|
||||
|
||||
//bmesh_mdisps_space_set(bm, MULTIRES_SPACE_TANGENT, MULTIRES_SPACE_ABSOLUTE);
|
||||
BM_enter_multires_space(NULL, bm, MULTIRES_SPACE_ABSOLUTE);
|
||||
/* ensure correct normals, if possible */
|
||||
bmesh_rationalize_normals(bm, 0);
|
||||
BM_mesh_normals_update(bm);
|
||||
//bmesh_rationalize_normals(bm, 0);
|
||||
//BM_mesh_normals_update(bm);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1989,17 +1992,10 @@ void bmesh_edit_end(BMesh *bm, BMOpTypeFlag type_flag)
|
|||
ListBase select_history;
|
||||
|
||||
/* BMO_OPTYPE_FLAG_UNTAN_MULTIRES disabled for now, see comment above in bmesh_edit_begin. */
|
||||
#ifdef BMOP_UNTAN_MULTIRES_ENABLED
|
||||
/* switch multires data into tangent space */
|
||||
if ((flag & BMO_OPTYPE_FLAG_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
|
||||
/* set normals to their previous winding */
|
||||
bmesh_rationalize_normals(bm, 1);
|
||||
bmesh_mdisps_space_set(bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT);
|
||||
if ((type_flag & BMO_OPTYPE_FLAG_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
|
||||
BM_enter_multires_space(NULL, bm, MULTIRES_SPACE_TANGENT);
|
||||
}
|
||||
else if (flag & BMO_OP_FLAG_RATIONALIZE_NORMALS) {
|
||||
bmesh_rationalize_normals(bm, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* compute normals, clear temp flags and flush selections */
|
||||
if (type_flag & BMO_OPTYPE_FLAG_NORMALS_CALC) {
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
|
||||
#include "bmesh_class.h"
|
||||
|
||||
typedef enum {
|
||||
MULTIRES_SPACE_TANGENT, //convert absolute to tangent
|
||||
MULTIRES_SPACE_ABSOLUTE //convert tangent to absolute
|
||||
} MultiResSpace;
|
||||
|
||||
struct BMAllocTemplate;
|
||||
struct BMLoopNorEditDataArray;
|
||||
struct MLoopNorSpaceArray;
|
||||
|
|
|
@ -176,8 +176,27 @@ static BMFace *bm_face_create_from_mpoly(
|
|||
return BM_face_create(bm, verts, edges, mp->totloop, NULL, BM_CREATE_SKIP_CD);
|
||||
}
|
||||
|
||||
void BM_enter_multires_space(Object *ob, BMesh *bm, int space) {
|
||||
if (!bm->haveMultiResSettings && ob) {
|
||||
MultiresModifierData *mmd = get_multires_modifier(NULL, ob, true);
|
||||
if (mmd) {
|
||||
bm->multires = *mmd;
|
||||
bm->haveMultiResSettings = true;
|
||||
bm->multiresSpace = MULTIRES_SPACE_TANGENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bm->haveMultiResSettings || !CustomData_has_layer(&bm->ldata, CD_MDISPS) || space == bm->multiresSpace) {
|
||||
return;
|
||||
}
|
||||
|
||||
BKE_multires_bmesh_space_set(ob, bm, space);
|
||||
bm->multiresSpace = space;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mesh -> BMesh
|
||||
* \param ob: object that owns bm, may be NULL (which will disable multires space change)
|
||||
* \param bm: The mesh to write into, while this is typically a newly created BMesh,
|
||||
* merging into existing data is supported.
|
||||
* Note the custom-data layout isn't used.
|
||||
|
@ -186,7 +205,7 @@ static BMFace *bm_face_create_from_mpoly(
|
|||
*
|
||||
* \warning This function doesn't calculate face normals.
|
||||
*/
|
||||
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
|
||||
void BM_mesh_bm_from_me(Object *ob, BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
|
||||
{
|
||||
const bool is_new = !(bm->totvert || (bm->vdata.totlayer || bm->edata.totlayer ||
|
||||
bm->pdata.totlayer || bm->ldata.totlayer));
|
||||
|
@ -203,6 +222,15 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
|
|||
CustomData_MeshMasks mask = CD_MASK_BMESH;
|
||||
CustomData_MeshMasks_update(&mask, ¶ms->cd_mask_extra);
|
||||
|
||||
MultiresModifierData *mmd = ob ? get_multires_modifier(NULL, ob, true) : NULL;
|
||||
if (mmd) {
|
||||
bm->multires = *mmd;
|
||||
bm->haveMultiResSettings = true;
|
||||
bm->multiresSpace = MULTIRES_SPACE_TANGENT;
|
||||
} else {
|
||||
bm->haveMultiResSettings = false;
|
||||
}
|
||||
|
||||
if (!me || !me->totvert) {
|
||||
if (me && is_new) { /* No verts? still copy custom-data layout. */
|
||||
CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_ASSIGN, 0);
|
||||
|
@ -568,7 +596,7 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
|
|||
*
|
||||
* \param bmain: May be NULL in case \a calc_object_remap parameter option is not set.
|
||||
*/
|
||||
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
|
||||
void BM_mesh_bm_to_me(Main *bmain, Object *ob, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
|
||||
{
|
||||
MEdge *med;
|
||||
BMVert *v, *eve;
|
||||
|
@ -577,6 +605,11 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
|
|||
BMIter iter;
|
||||
int i, j;
|
||||
|
||||
//ensure multires space is correct
|
||||
if (bm->haveMultiResSettings && bm->multiresSpace != MULTIRES_SPACE_TANGENT) {
|
||||
BM_enter_multires_space(ob, bm, MULTIRES_SPACE_TANGENT);
|
||||
}
|
||||
|
||||
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
|
||||
const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
|
||||
const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
|
||||
|
|
|
@ -43,7 +43,9 @@ struct BMeshFromMeshParams {
|
|||
int active_shapekey;
|
||||
struct CustomData_MeshMasks cd_mask_extra;
|
||||
};
|
||||
void BM_mesh_bm_from_me(BMesh *bm, const struct Mesh *me, const struct BMeshFromMeshParams *params)
|
||||
|
||||
struct Object;
|
||||
void BM_mesh_bm_from_me(struct Object *ob, BMesh *bm, const struct Mesh *me, const struct BMeshFromMeshParams *params)
|
||||
ATTR_NONNULL(1, 3);
|
||||
|
||||
struct BMeshToMeshParams {
|
||||
|
@ -61,7 +63,11 @@ struct BMeshToMeshParams {
|
|||
uint update_shapekey_indices : 1;
|
||||
struct CustomData_MeshMasks cd_mask_extra;
|
||||
};
|
||||
|
||||
void BM_enter_multires_space(struct Object *ob, struct BMesh *bm, int space);
|
||||
|
||||
void BM_mesh_bm_to_me(struct Main *bmain,
|
||||
struct Object *ob,
|
||||
BMesh *bm,
|
||||
struct Mesh *me,
|
||||
const struct BMeshToMeshParams *params) ATTR_NONNULL(2, 3, 4);
|
||||
|
|
|
@ -1064,6 +1064,21 @@ static BMOpDefine bmo_extrude_face_region_def = {
|
|||
(BMO_OPTYPE_FLAG_NORMALS_CALC),
|
||||
};
|
||||
|
||||
extern void bmo_test_mres_smooth_exec(BMesh *bm, BMOperator *op);
|
||||
|
||||
static BMOpDefine bmo_test_mres_smooth_def = {
|
||||
"test_mres_smooth",
|
||||
/* slots_in */
|
||||
{{{'\0'}}}, /* no input */
|
||||
{{{'\0'}}}, /* no output */
|
||||
bmo_test_mres_smooth_exec,
|
||||
(
|
||||
BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
|
||||
BMO_OPTYPE_FLAG_NORMALS_CALC |
|
||||
BMO_OPTYPE_FLAG_SELECT_FLUSH |
|
||||
BMO_OPTYPE_FLAG_SELECT_VALIDATE)
|
||||
};
|
||||
|
||||
/*
|
||||
* Dissolve Verts.
|
||||
*/
|
||||
|
@ -1911,7 +1926,7 @@ static BMOpDefine bmo_inset_individual_def = {
|
|||
},
|
||||
bmo_inset_individual_exec,
|
||||
/* caller needs to handle BMO_OPTYPE_FLAG_SELECT_FLUSH */
|
||||
(BMO_OPTYPE_FLAG_NORMALS_CALC),
|
||||
(BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_UNTAN_MULTIRES),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1940,7 +1955,7 @@ static BMOpDefine bmo_inset_region_def = {
|
|||
},
|
||||
bmo_inset_region_exec,
|
||||
(BMO_OPTYPE_FLAG_NORMALS_CALC |
|
||||
BMO_OPTYPE_FLAG_SELECT_FLUSH),
|
||||
BMO_OPTYPE_FLAG_SELECT_FLUSH | BMO_OPTYPE_FLAG_UNTAN_MULTIRES),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1961,7 +1976,7 @@ static BMOpDefine bmo_offset_edgeloops_def = {
|
|||
},
|
||||
bmo_offset_edgeloops_exec,
|
||||
(BMO_OPTYPE_FLAG_NORMALS_CALC |
|
||||
BMO_OPTYPE_FLAG_SELECT_FLUSH),
|
||||
BMO_OPTYPE_FLAG_SELECT_FLUSH | BMO_OPTYPE_FLAG_UNTAN_MULTIRES),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -2179,6 +2194,7 @@ const BMOpDefine *bmo_opdefines[] = {
|
|||
&bmo_unsubdivide_def,
|
||||
&bmo_weld_verts_def,
|
||||
&bmo_wireframe_def,
|
||||
&bmo_test_mres_smooth_def
|
||||
};
|
||||
|
||||
const int bmo_opdefines_total = ARRAY_SIZE(bmo_opdefines);
|
||||
|
|
|
@ -39,7 +39,8 @@ void bmo_mesh_to_bmesh_exec(BMesh *bm, BMOperator *op)
|
|||
Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh");
|
||||
bool set_key = BMO_slot_bool_get(op->slots_in, "use_shapekey");
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
me,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.use_shapekey = set_key,
|
||||
|
@ -66,6 +67,7 @@ void bmo_bmesh_to_mesh_exec(BMesh *bm, BMOperator *op)
|
|||
/* Object *ob = BMO_slot_ptr_get(op, "object"); */
|
||||
|
||||
BM_mesh_bm_to_me(G.main,
|
||||
NULL,
|
||||
bm,
|
||||
me,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
|
|
@ -116,7 +116,7 @@ static int geometry_extract_apply(bContext *C,
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
new_mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -507,7 +507,7 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
new_mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -538,7 +538,7 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
new_ob_mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -4205,7 +4205,7 @@ static Base *mesh_separate_tagged(
|
|||
|
||||
BM_mesh_normals_update(bm_new);
|
||||
|
||||
BM_mesh_bm_to_me(bmain, bm_new, base_new->object->data, (&(struct BMeshToMeshParams){0}));
|
||||
BM_mesh_bm_to_me(bmain, base_new->object, bm_new, base_new->object->data, (&(struct BMeshToMeshParams){0}));
|
||||
|
||||
BM_mesh_free(bm_new);
|
||||
((Mesh *)base_new->object->data)->edit_mesh = NULL;
|
||||
|
@ -4266,7 +4266,7 @@ static Base *mesh_separate_arrays(Main *bmain,
|
|||
BM_vert_kill(bm_old, verts[i]);
|
||||
}
|
||||
|
||||
BM_mesh_bm_to_me(bmain, bm_new, base_new->object->data, (&(struct BMeshToMeshParams){0}));
|
||||
BM_mesh_bm_to_me(bmain, base_new->object, bm_new, base_new->object->data, (&(struct BMeshToMeshParams){0}));
|
||||
|
||||
BM_mesh_free(bm_new);
|
||||
((Mesh *)base_new->object->data)->edit_mesh = NULL;
|
||||
|
@ -4449,7 +4449,7 @@ static bool mesh_separate_loose(
|
|||
BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
|
||||
|
||||
if (clear_object_data) {
|
||||
BM_mesh_bm_to_me(NULL,
|
||||
BM_mesh_bm_to_me(NULL, base_old->object,
|
||||
bm_old,
|
||||
me_old,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
@ -4536,7 +4536,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm_old, me, (&(struct BMeshFromMeshParams){0}));
|
||||
BM_mesh_bm_from_me(NULL, bm_old, me, (&(struct BMeshFromMeshParams){0}));
|
||||
|
||||
switch (type) {
|
||||
case MESH_SEPARATE_MATERIAL:
|
||||
|
@ -4552,6 +4552,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
|
|||
|
||||
if (retval_iter) {
|
||||
BM_mesh_bm_to_me(bmain,
|
||||
ob,
|
||||
bm_old,
|
||||
me,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
@ -5699,7 +5700,7 @@ static void edbm_dissolve_prop__use_boundary_tear(wmOperatorType *ot)
|
|||
"Split off face corners instead of merging faces");
|
||||
}
|
||||
|
||||
static int edbm_dissolve_verts_exec(bContext *C, wmOperator *op)
|
||||
static int edbm_mres_test_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");
|
||||
|
@ -5721,10 +5722,64 @@ static int edbm_dissolve_verts_exec(bContext *C, wmOperator *op)
|
|||
|
||||
if (!EDBM_op_callf(em,
|
||||
op,
|
||||
"dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
|
||||
BM_ELEM_SELECT,
|
||||
use_face_split,
|
||||
use_boundary_tear)) {
|
||||
"test_mres_smooth")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BM_custom_loop_normals_from_vector_layer(em->bm, false);
|
||||
EDBM_update_generic(obedit->data, true, true);
|
||||
}
|
||||
|
||||
MEM_freeN(objects);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
||||
void MESH_OT_mres_test(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Test Multires Boundary Smooth";
|
||||
ot->description = "Test multires boundary smooth";
|
||||
ot->idname = "MESH_OT_mres_test";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = edbm_mres_test_exec;
|
||||
ot->poll = ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
edbm_dissolve_prop__use_face_split(ot);
|
||||
edbm_dissolve_prop__use_boundary_tear(ot);
|
||||
}
|
||||
|
||||
|
||||
static int edbm_dissolve_verts_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);
|
||||
|
||||
if (em->bm->totvertsel == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BM_custom_loop_normals_to_vector_layer(em->bm);
|
||||
|
||||
if (!EDBM_op_callf(em,
|
||||
op,
|
||||
"dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
|
||||
BM_ELEM_SELECT,
|
||||
use_face_split,
|
||||
use_boundary_tear)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -5737,6 +5792,7 @@ static int edbm_dissolve_verts_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
||||
void MESH_OT_dissolve_verts(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
|
|
|
@ -520,7 +520,7 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key)
|
|||
/* BM_mesh_validate(em->bm); */ /* for troubleshooting */
|
||||
|
||||
BM_mesh_bm_to_me(
|
||||
NULL,
|
||||
NULL, NULL,
|
||||
em->bm,
|
||||
&um->me,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
@ -596,7 +596,7 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
&um->me,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -352,6 +352,7 @@ void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
|
|||
}
|
||||
|
||||
BM_mesh_bm_to_me(bmain,
|
||||
ob,
|
||||
bm,
|
||||
me,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
|
|
@ -259,6 +259,7 @@ void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot);
|
|||
void MESH_OT_average_normals(struct wmOperatorType *ot);
|
||||
void MESH_OT_smooth_normals(struct wmOperatorType *ot);
|
||||
void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot);
|
||||
void MESH_OT_mres_test(struct wmOperatorType *ot);
|
||||
|
||||
/* *** editmesh_mask_extract.c *** */
|
||||
void MESH_OT_paint_mask_extract(struct wmOperatorType *ot);
|
||||
|
|
|
@ -208,6 +208,8 @@ void ED_operatortypes_mesh(void)
|
|||
WM_operatortype_append(MESH_OT_average_normals);
|
||||
WM_operatortype_append(MESH_OT_smooth_normals);
|
||||
WM_operatortype_append(MESH_OT_mod_weighted_strength);
|
||||
WM_operatortype_append(MESH_OT_mres_test);
|
||||
|
||||
}
|
||||
|
||||
#if 0 /* UNUSED, remove? */
|
||||
|
|
|
@ -880,7 +880,7 @@ static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
trim_mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -1089,13 +1089,15 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
|
|||
.use_toolflags = false,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
trim_mesh,
|
||||
&((struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
sculpt_mesh,
|
||||
&((struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -165,7 +165,8 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene
|
|||
.use_toolflags = false,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(ss->bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
ss->bm,
|
||||
me,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -382,7 +382,8 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -561,7 +562,8 @@ static void sculpt_face_sets_init_flood_fill(Object *ob,
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -634,7 +636,8 @@ static void sculpt_face_sets_init_loop(Object *ob, const int mode)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -2839,7 +2839,8 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
|
|||
|
||||
ED_mesh_uv_texture_ensure(me, NULL);
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
me,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -449,7 +449,7 @@ void bc_triangulate_mesh(Mesh *me)
|
|||
BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default, &bm_create_params);
|
||||
BMeshFromMeshParams bm_from_me_params = {0};
|
||||
bm_from_me_params.calc_face_normal = true;
|
||||
BM_mesh_bm_from_me(bm, me, &bm_from_me_params);
|
||||
BM_mesh_bm_from_me(NULL, bm, me, &bm_from_me_params);
|
||||
BM_mesh_triangulate(bm, quad_method, use_beauty, 4, tag_only, NULL, NULL, NULL);
|
||||
|
||||
BMeshToMeshParams bm_to_me_params = {0};
|
||||
|
|
|
@ -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(mesh, NULL,
|
||||
&(struct BMeshCreateParams){0},
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -250,7 +250,7 @@ static BMesh *BMD_mesh_bm_create(
|
|||
.use_toolflags = false,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
mesh_operand_ob,
|
||||
&((struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -265,7 +265,7 @@ static BMesh *BMD_mesh_bm_create(
|
|||
}
|
||||
}
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
mesh,
|
||||
&((struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -457,7 +457,7 @@ static Mesh *collection_boolean_exact(BooleanModifierData *bmd,
|
|||
Mesh *me = meshes[i];
|
||||
Object *ob = objects[i];
|
||||
/* Need normals for triangulation. */
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
me,
|
||||
&((struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -655,7 +655,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
BMD_mesh_intersection(bm, md, ctx, mesh_operand_ob, object, operand_ob, is_flip);
|
||||
|
||||
/* Needed for multiple objects to work. */
|
||||
BM_mesh_bm_to_me(NULL,
|
||||
BM_mesh_bm_to_me(NULL, NULL,
|
||||
bm,
|
||||
mesh,
|
||||
(&(struct BMeshToMeshParams){
|
||||
|
|
|
@ -171,7 +171,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
}
|
||||
}
|
||||
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh,
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh, NULL,
|
||||
&(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,
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh, NULL,
|
||||
&(struct BMeshCreateParams){0},
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = calc_face_normals,
|
||||
|
|
|
@ -251,7 +251,7 @@ static void deformVertsEM(ModifierData *md,
|
|||
const bool do_temp_mesh = (mesh == NULL);
|
||||
if (do_temp_mesh) {
|
||||
mesh = BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name);
|
||||
BM_mesh_bm_to_me(NULL, editData->bm, mesh, &((BMeshToMeshParams){0}));
|
||||
BM_mesh_bm_to_me(NULL, NULL, editData->bm, mesh, &((BMeshToMeshParams){0}));
|
||||
}
|
||||
|
||||
deformVerts(md, ob, mesh, vertexCos, numVerts);
|
||||
|
|
|
@ -70,7 +70,7 @@ 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(mesh, NULL,
|
||||
&((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,
|
||||
bm = BKE_mesh_to_bmesh_ex(mesh, NULL,
|
||||
&(struct BMeshCreateParams){0},
|
||||
&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
|
|
@ -1169,7 +1169,8 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject
|
|||
|
||||
bm = self->bm;
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
me_eval,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = use_fnorm,
|
||||
|
@ -1226,7 +1227,8 @@ static PyObject *bpy_bmesh_from_mesh(BPy_BMesh *self, PyObject *args, PyObject *
|
|||
|
||||
bm = self->bm;
|
||||
|
||||
BM_mesh_bm_from_me(bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
me,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = use_fnorm,
|
||||
|
|
Loading…
Reference in New Issue