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:
authorBastien Montagne <montagne29@wanadoo.fr>2018-01-24 14:14:59 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2018-01-24 14:14:59 +0300
commit6a65fc34565da167d686d0ea14f11f73f909d19d (patch)
tree22b2cbcc614278faa1d3847aafb4371453b2dcf9 /source/blender/blenkernel/intern/subsurf_ccg.c
parent752fc35fa15b6bfee0309354ffcbf5c78211e8a6 (diff)
parente68771fa8760035050f476895ebe791c4857f91b (diff)
Merge branch 'master' into blender2.8
Conflicts: source/blender/modifiers/intern/MOD_wireframe.c
Diffstat (limited to 'source/blender/blenkernel/intern/subsurf_ccg.c')
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c95
1 files changed, 79 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index fa83567c3b9..1c3ff352126 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -67,6 +67,7 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_scene.h"
@@ -4190,7 +4191,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGKey key;
- int numGrids, grid_pbvh;
+ int numGrids;
CCG_key_top_level(&key, ccgdm->ss);
@@ -4202,35 +4203,85 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
if (!ob->sculpt)
return NULL;
- /* In vwpaint, we always use a grid_pbvh for multires/subsurf */
- grid_pbvh = (!(ob->mode & OB_MODE_SCULPT) || ccgDM_use_grid_pbvh(ccgdm));
+ bool grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
+ if ((ob->mode & OB_MODE_SCULPT) == 0) {
+ /* In vwpaint, we may use a grid_pbvh for multires/subsurf, under certain conditions.
+ * More complex cases break 'history' trail back to original vertices, in that case we fall back to
+ * deformed cage only (i.e. original deformed mesh). */
+ VirtualModifierData virtualModifierData;
+ ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+
+ grid_pbvh = true;
+ bool has_one_ccg_modifier = false;
+ for (; md; md = md->next) {
+ /* We can only accept to use this ccgdm if:
+ * - it's the only active ccgdm in the stack.
+ * - there is no topology-modifying modifier in the stack.
+ * Otherwise, there is no way to map back to original geometry from grid-generated PBVH.
+ */
+ const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if (!modifier_isEnabled(NULL, md, eModifierMode_Realtime)) {
+ continue;
+ }
+ if (ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical)) {
+ continue;
+ }
+
+ if (ELEM(md->type, eModifierType_Subsurf, eModifierType_Multires)) {
+ if (has_one_ccg_modifier) {
+ /* We only allow a single active ccg modifier in the stack. */
+ grid_pbvh = false;
+ break;
+ }
+ has_one_ccg_modifier = true;
+ continue;
+ }
+
+ /* Any other non-deforming modifier makes it impossible to use grid pbvh. */
+ grid_pbvh = false;
+ break;
+ }
+ }
if (ob->sculpt->pbvh) {
+ /* Note that we have to clean up exisitng pbvh instead of updating it in case it does not match current
+ * grid_pbvh status. */
if (grid_pbvh) {
- /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
- * but this can be freed on ccgdm release, this updates the pointers
- * when the ccgdm gets remade, the assumption is that the topology
- * does not change. */
- ccgdm_create_grids(dm);
- BKE_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, (void **)ccgdm->gridFaces,
- ccgdm->gridFlagMats, ccgdm->gridHidden);
+ if (BKE_pbvh_get_ccgdm(ob->sculpt->pbvh) != NULL) {
+ /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
+ * but this can be freed on ccgdm release, this updates the pointers
+ * when the ccgdm gets remade, the assumption is that the topology
+ * does not change. */
+ ccgdm_create_grids(dm);
+ BKE_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, (void **)ccgdm->gridFaces,
+ ccgdm->gridFlagMats, ccgdm->gridHidden);
+ }
+ else {
+ BKE_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh = NULL;
+ }
+ }
+ else if (BKE_pbvh_get_ccgdm(ob->sculpt->pbvh) != NULL) {
+ BKE_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh = NULL;
}
ccgdm->pbvh = ob->sculpt->pbvh;
}
if (ccgdm->pbvh) {
- /* For vertex paint, keep track of ccgdm */
- if (!(ob->mode & OB_MODE_SCULPT)) {
+ /* For grid pbvh, keep track of ccgdm */
+ if (grid_pbvh) {
BKE_pbvh_set_ccgdm(ccgdm->pbvh, ccgdm);
}
return ccgdm->pbvh;
}
- /* no pbvh exists yet, we need to create one. only in case of multires
+ /* No pbvh exists yet, we need to create one. only in case of multires
* we build a pbvh over the modified mesh, in other cases the base mesh
* is being sculpted, so we build a pbvh from that. */
- /* Note: vwpaint always builds a pbvh over the modified mesh. */
+ /* Note: vwpaint tries to always build a pbvh over the modified mesh. */
if (grid_pbvh) {
ccgdm_create_grids(dm);
@@ -4256,6 +4307,18 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
BKE_pbvh_build_mesh(ccgdm->pbvh, me->mpoly, me->mloop, me->mvert, me->totvert, &me->vdata,
looptri, looptris_num);
+
+ if (ob->sculpt->modifiers_active && ob->derivedDeform != NULL) {
+ DerivedMesh *deformdm = ob->derivedDeform;
+ float (*vertCos)[3];
+ int totvert;
+
+ totvert = deformdm->getNumVerts(deformdm);
+ vertCos = MEM_malloc_arrayN(totvert, sizeof(float[3]), "ccgDM_getPBVH vertCos");
+ deformdm->getVertCos(deformdm, vertCos);
+ BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos);
+ MEM_freeN(vertCos);
+ }
}
if (ccgdm->pbvh != NULL) {
@@ -4263,8 +4326,8 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
pbvh_show_mask_set(ccgdm->pbvh, ob->sculpt->show_mask);
}
- /* For vertex paint, keep track of ccgdm */
- if (!(ob->mode & OB_MODE_SCULPT) && ccgdm->pbvh) {
+ /* For grid pbvh, keep track of ccgdm. */
+ if (grid_pbvh && ccgdm->pbvh) {
BKE_pbvh_set_ccgdm(ccgdm->pbvh, ccgdm);
}
return ccgdm->pbvh;