Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/multires.c')
-rw-r--r--source/blender/blenkernel/intern/multires.c197
1 files changed, 148 insertions, 49 deletions
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 83f04db9cd7..4b54114505e 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -29,27 +29,20 @@
#include "MEM_guardedalloc.h"
-#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_view3d_types.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
+#include "BLI_math.h"
#include "BLI_pbvh.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_customdata.h"
-#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
-#include "BKE_object.h"
+#include "BKE_paint.h"
#include "BKE_scene.h"
#include "BKE_subsurf.h"
#include "BKE_utildefines.h"
@@ -67,19 +60,33 @@ static const int multires_side_tot[] = {0, 2, 3, 5, 9, 17, 33, 65, 129,
static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert);
static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl);
-MultiresModifierData *find_multires_modifier(Object *ob)
+DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob)
+{
+ ModifierData *md= (ModifierData *)mmd;
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ DerivedMesh *tdm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+ DerivedMesh *dm;
+
+ dm = mti->applyModifier(md, ob, tdm, 0, 1);
+ if (dm == tdm) {
+ dm = CDDM_copy(tdm, 0);
+ }
+
+ return dm;
+}
+
+MultiresModifierData *find_multires_modifier_before(Scene *scene, ModifierData *lastmd)
{
ModifierData *md;
- MultiresModifierData *mmd = NULL;
- for(md = ob->modifiers.first; md; md = md->next) {
+ for(md = lastmd; md; md = md->prev) {
if(md->type == eModifierType_Multires) {
- mmd = (MultiresModifierData*)md;
- break;
+ if (modifier_isEnabled(scene, md, eModifierMode_Realtime))
+ return (MultiresModifierData*)md;
}
}
- return mmd;
+ return NULL;
}
static int multires_get_level(Object *ob, MultiresModifierData *mmd, int render)
@@ -117,14 +124,27 @@ void multires_mark_as_modified(Object *ob)
void multires_force_update(Object *ob)
{
-
- if(ob && ob->derivedFinal) {
- ob->derivedFinal->needsFree =1;
- ob->derivedFinal->release(ob->derivedFinal);
- ob->derivedFinal = NULL;
+ if(ob) {
+ if(ob->derivedFinal) {
+ ob->derivedFinal->needsFree =1;
+ ob->derivedFinal->release(ob->derivedFinal);
+ ob->derivedFinal = NULL;
+ }
+ if(ob->sculpt && ob->sculpt->pbvh) {
+ BLI_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh= NULL;
+ }
}
}
+void multires_force_external_reload(Object *ob)
+{
+ Mesh *me = get_mesh(ob);
+
+ CustomData_external_reload(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
+ multires_force_update(ob);
+}
+
void multires_force_render_update(Object *ob)
{
if(ob && (ob->mode & OB_MODE_SCULPT) && modifiers_findByType(ob, eModifierType_Multires))
@@ -193,24 +213,97 @@ void multiresModifier_join(Object *ob)
}
#endif
-/* Returns 1 on success, 0 if the src's totvert doesn't match */
-int multiresModifier_reshape(MultiresModifierData *mmd, Object *dst, Object *src)
+int multiresModifier_reshapeFromDM(Scene *scene, MultiresModifierData *mmd,
+ Object *ob, DerivedMesh *srcdm)
{
- DerivedMesh *srcdm = src->derivedFinal;
- DerivedMesh *mrdm = dst->derivedFinal;
+ DerivedMesh *mrdm = get_multires_dm (scene, mmd, ob);
if(mrdm && srcdm && mrdm->getNumVerts(mrdm) == srcdm->getNumVerts(srcdm)) {
multires_mvert_to_ss(mrdm, srcdm->getVertArray(srcdm));
multires_dm_mark_as_modified(mrdm);
- multires_force_update(dst);
+ multires_force_update(ob);
+
+ mrdm->release(mrdm);
return 1;
}
+ mrdm->release(mrdm);
+
return 0;
}
+/* Returns 1 on success, 0 if the src's totvert doesn't match */
+int multiresModifier_reshape(Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
+{
+ DerivedMesh *srcdm = mesh_get_derived_final(scene, src, CD_MASK_BAREMESH);
+ return multiresModifier_reshapeFromDM(scene, mmd, dst, srcdm);
+}
+
+int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mmd,
+ Object *ob, ModifierData *md)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ DerivedMesh *dm, *ndm;
+ int numVerts, result;
+ float (*deformedVerts)[3];
+
+ if(multires_get_level(ob, mmd, 0) == 0)
+ return 0;
+
+ /* Create DerivedMesh for deformation modifier */
+ dm = get_multires_dm(scene, mmd, ob);
+ numVerts= dm->getNumVerts(dm);
+ deformedVerts= MEM_callocN(sizeof(float)*numVerts*3, "multiresReshape_deformVerts");
+
+ dm->getVertCos(dm, deformedVerts);
+ mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0, 0);
+
+ ndm= CDDM_copy(dm, 0);
+ CDDM_apply_vert_coords(ndm, deformedVerts);
+
+ MEM_freeN(deformedVerts);
+ dm->release(dm);
+
+ /* Reshaping */
+ result= multiresModifier_reshapeFromDM(scene, mmd, ob, ndm);
+
+ /* Cleanup */
+ ndm->release(ndm);
+
+ return result;
+}
+
+static void multires_set_tot_mdisps(Mesh *me, int lvl)
+{
+ MDisps *mdisps= CustomData_get_layer(&me->ldata, CD_MDISPS);
+ int i;
+
+ if(mdisps) {
+ for(i = 0; i < me->totloop; i++, mdisps++) {
+ mdisps->totdisp = multires_grid_tot[lvl];
+ }
+ }
+}
+
+static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl)
+{
+ int i;
+
+ /* reallocate displacements to be filled in */
+ for(i = 0; i < me->totloop; ++i) {
+ int totdisp = multires_grid_tot[lvl];
+ float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
+
+ if(mdisps[i].disps)
+ MEM_freeN(mdisps[i].disps);
+
+ mdisps[i].disps = disps;
+ mdisps[i].totdisp = totdisp;
+ }
+}
+
static void column_vectors_to_mat3(float mat[][3], float v1[3], float v2[3], float v3[3])
{
copy_v3_v3(mat[0], v1);
@@ -266,6 +359,7 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire
int levels = mmd->totlvl - lvl;
MDisps *mdisps;
+ multires_set_tot_mdisps(me, mmd->totlvl);
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
mdisps= CustomData_get_layer(&me->ldata, CD_MDISPS);
@@ -338,23 +432,6 @@ static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl
return subsurf_make_derived_from_derived(dm, &smd, 0, NULL, 0, 0);
}
-static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl)
-{
- int i;
-
- /* reallocate displacements to be filled in */
- for(i = 0; i < me->totloop; ++i) {
- int totdisp = multires_grid_tot[lvl];
- float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
-
- if(mdisps[i].disps)
- MEM_freeN(mdisps[i].disps);
-
- mdisps[i].disps = disps;
- mdisps[i].totdisp = totdisp;
- }
-}
-
void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updateblock, int simple)
{
Mesh *me = ob->data;
@@ -380,6 +457,7 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updat
/* create subsurf DM from original mesh at high level */
cddm = CDDM_from_mesh(me, NULL);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0);
/* create multires DM from original mesh at low level */
@@ -483,7 +561,8 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int
k = 0; /*current loop/mdisp index within the mloop array*/
- #pragma omp parallel for private(i) schedule(static)
+ #pragma omp parallel for private(i) if(me->totloop*gridSize*gridSize >= CCG_OMP_LIMIT)
+
for(i = 0; i < me->totpoly; ++i) {
const int numVerts = mpoly[i].totloop;
int S, x, y, gIndex = gridOffset[i];
@@ -563,6 +642,8 @@ static void multiresModifier_update(DerivedMesh *dm)
ob = ccgdm->multires.ob;
me = ccgdm->multires.ob->data;
mmd = ccgdm->multires.mmd;
+
+ multires_set_tot_mdisps(me, mmd->totlvl);
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
@@ -578,7 +659,10 @@ static void multiresModifier_update(DerivedMesh *dm)
int i, j, numGrids, highGridSize, lowGridSize;
/* create subsurf DM from original mesh at high level */
- cddm = CDDM_from_mesh(me, NULL);
+ if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform, 0);
+ else cddm = CDDM_from_mesh(me, NULL);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
+
highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0);
/* create multires DM from original mesh and displacements */
@@ -629,7 +713,10 @@ static void multiresModifier_update(DerivedMesh *dm)
else {
DerivedMesh *cddm, *subdm;
- cddm = CDDM_from_mesh(me, NULL);
+ if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform, 0);
+ else cddm = CDDM_from_mesh(me, NULL);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
+
subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0);
cddm->release(cddm);
@@ -660,7 +747,7 @@ void multires_stitch_grids(Object *ob)
}
DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int local_mmd, DerivedMesh *dm, Object *ob,
- int useRenderParams, int isFinalCalc)
+ int useRenderParams, int isFinalCalc)
{
Mesh *me= ob->data;
DerivedMesh *result;
@@ -698,7 +785,10 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int loca
memcpy(subGridData[i], gridData[i], sizeof(DMGridData)*gridSize*gridSize);
}
+ multires_set_tot_mdisps(me, mmd->totlvl);
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
+
+ /*run displacement*/
multiresModifier_disp_run(result, ob->data, 0, 0, subGridData, mmd->totlvl);
for(i = 0; i < numGrids; i++)
@@ -868,7 +958,7 @@ void multires_free(Multires *mr)
}
static void create_old_vert_face_map(ListBase **map, IndexNode **mem, const MultiresFace *mface,
- const int totvert, const int totface)
+ const int totvert, const int totface)
{
int i,j;
IndexNode *node = NULL;
@@ -887,7 +977,7 @@ static void create_old_vert_face_map(ListBase **map, IndexNode **mem, const Mult
}
static void create_old_vert_edge_map(ListBase **map, IndexNode **mem, const MultiresEdge *medge,
- const int totvert, const int totedge)
+ const int totvert, const int totedge)
{
int i,j;
IndexNode *node = NULL;
@@ -953,7 +1043,7 @@ static void multires_load_old_edges(ListBase **emap, MultiresLevel *lvl, int *vv
}
static void multires_load_old_faces(ListBase **fmap, ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst,
- int v1, int v2, int v3, int v4, int st2, int st3)
+ int v1, int v2, int v3, int v4, int st2, int st3)
{
int fmid;
int emid13, emid14, emid23, emid24;
@@ -1223,6 +1313,7 @@ void multires_load_old(Object *ob, Mesh *me)
ModifierData *md;
MultiresModifierData *mmd;
DerivedMesh *dm, *orig;
+ CustomDataLayer *l;
int i;
/* Load original level into the mesh */
@@ -1268,6 +1359,14 @@ void multires_load_old(Object *ob, Mesh *me)
dm->release(dm);
orig->release(orig);
+ /* Copy the first-level data to the mesh */
+ for(i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i, ++l)
+ CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert);
+ for(i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l)
+ CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface);
+ memset(&me->mr->vdata, 0, sizeof(CustomData));
+ memset(&me->mr->fdata, 0, sizeof(CustomData));
+
/* Remove the old multires */
multires_free(me->mr);
me->mr= NULL;