Compare commits
8 Commits
temp-geome
...
vertex_pai
Author | SHA1 | Date | |
---|---|---|---|
8d72d1cca7 | |||
89572e277d | |||
5e224fb934 | |||
366663a7e0 | |||
10aee127d4 | |||
0e41965f76 | |||
b253ed3b0f | |||
89333638a8 |
@@ -149,6 +149,7 @@ void paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, struct Brus
|
||||
|
||||
void BKE_paint_stroke_get_average(struct Scene *scene, struct Object *ob, float stroke[3]);
|
||||
|
||||
|
||||
/* Session data (mode-specific) */
|
||||
|
||||
typedef struct SculptSession {
|
||||
@@ -173,8 +174,6 @@ typedef struct SculptSession {
|
||||
/* Undo/redo log for dynamic topology sculpting */
|
||||
struct BMLog *bm_log;
|
||||
|
||||
/* PBVH acceleration structure */
|
||||
struct PBVH *pbvh;
|
||||
bool show_diffuse_color;
|
||||
|
||||
/* Painting on deformed mesh */
|
||||
@@ -182,14 +181,7 @@ typedef struct SculptSession {
|
||||
float (*orig_cos)[3]; /* coords of undeformed mesh */
|
||||
float (*deform_cos)[3]; /* coords of deformed mesh but without stroke displacement */
|
||||
float (*deform_imats)[3][3]; /* crazyspace deformation matrices */
|
||||
|
||||
/* Partial redraw */
|
||||
bool partial_redraw;
|
||||
|
||||
/* Used to cache the render of the active texture */
|
||||
unsigned int texcache_side, *texcache, texcache_actual;
|
||||
struct ImagePool *tex_pool;
|
||||
|
||||
/* Layer brush persistence between strokes */
|
||||
float (*layer_co)[3]; /* Copy of the mesh vertices' locations */
|
||||
|
||||
@@ -197,6 +189,24 @@ typedef struct SculptSession {
|
||||
struct StrokeCache *cache;
|
||||
} SculptSession;
|
||||
|
||||
/* Session data (common) */
|
||||
typedef struct PaintSession {
|
||||
/* PBVH acceleration structure */
|
||||
struct PBVH *pbvh;
|
||||
|
||||
/* Used to cache the render of the active texture */
|
||||
unsigned int texcache_side, *texcache, texcache_actual;
|
||||
struct ImagePool *tex_pool;
|
||||
|
||||
/* Partial redraw */
|
||||
bool partial_redraw;
|
||||
|
||||
/* mode specific stuff */
|
||||
SculptSession *sculpt;
|
||||
} PaintSession;
|
||||
|
||||
void BKE_free_paintsession(struct Object *ob);
|
||||
|
||||
void BKE_free_sculptsession(struct Object *ob);
|
||||
void BKE_free_sculptsession_deformMats(struct SculptSession *ss);
|
||||
void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
|
||||
|
@@ -62,7 +62,7 @@ typedef void (*BKE_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *
|
||||
|
||||
PBVH *BKE_pbvh_new(void);
|
||||
void BKE_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts,
|
||||
int totface, int totvert, struct CustomData *vdata);
|
||||
int totface, int totvert, struct CustomData *vdata, struct CustomData *ldata);
|
||||
void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
|
||||
struct DMGridAdjacency *gridadj, int totgrid,
|
||||
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
|
||||
@@ -115,7 +115,7 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
|
||||
int (*setMaterial)(int matnr, void *attribs), bool wireframe);
|
||||
|
||||
/* PBVH Access */
|
||||
typedef enum {
|
||||
typedef enum PBVHType {
|
||||
PBVH_FACES,
|
||||
PBVH_GRIDS,
|
||||
PBVH_BMESH
|
||||
|
@@ -1515,8 +1515,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
||||
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
|
||||
const bool has_multires = (mmd && mmd->sculptlvl != 0);
|
||||
bool multires_applied = false;
|
||||
const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams;
|
||||
const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams;
|
||||
const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->paint && ob->paint->sculpt && !useRenderParams;
|
||||
const bool sculpt_dyntopo = (sculpt_mode && ob->paint->sculpt->bm) && !useRenderParams;
|
||||
const int draw_flag = dm_drawflag_calc(scene->toolsettings);
|
||||
|
||||
/* Generic preview only in object mode! */
|
||||
@@ -2313,12 +2313,17 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
|
||||
ob->derivedDeform->needsFree = 0;
|
||||
ob->lastDataMask = dataMask;
|
||||
|
||||
if ((ob->mode & OB_MODE_SCULPT) && ob->sculpt) {
|
||||
if ((ob->mode & OB_MODE_SCULPT) && ob->paint && ob->paint->sculpt) {
|
||||
/* create PBVH immediately (would be created on the fly too,
|
||||
* but this avoids waiting on first stroke) */
|
||||
|
||||
BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false);
|
||||
}
|
||||
else if ((ob->mode & OB_MODE_VERTEX_PAINT) && ob->paint) {
|
||||
/* needs to be called after we ensure tessface */
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
||||
ob->paint->pbvh = dm->getPBVH(ob, dm);
|
||||
}
|
||||
|
||||
BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS));
|
||||
}
|
||||
|
@@ -222,23 +222,26 @@ static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm)
|
||||
|
||||
static bool check_sculpt_object_deformed(Object *object, bool for_construction)
|
||||
{
|
||||
SculptSession *ss = object->paint->sculpt;
|
||||
bool deformed = false;
|
||||
|
||||
if (!ss)
|
||||
return deformed;
|
||||
/* Active modifiers means extra deformation, which can't be handled correct
|
||||
* on birth of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
|
||||
* stuff and show final DerivedMesh so user would see actual object shape.
|
||||
*/
|
||||
deformed |= object->sculpt->modifiers_active;
|
||||
deformed |= ss->modifiers_active;
|
||||
|
||||
if (for_construction) {
|
||||
deformed |= object->sculpt->kb != NULL;
|
||||
deformed |= ss->kb != NULL;
|
||||
}
|
||||
else {
|
||||
/* As in case with modifiers, we can't synchronize deformation made against
|
||||
* PBVH and non-locked keyblock, so also use PBVH only for brushes and
|
||||
* final DM to give final result to user.
|
||||
*/
|
||||
deformed |= object->sculpt->kb && (object->shapeflag & OB_SHAPE_LOCK) == 0;
|
||||
deformed |= ss->kb && (object->shapeflag & OB_SHAPE_LOCK) == 0;
|
||||
}
|
||||
|
||||
return deformed;
|
||||
@@ -254,37 +257,40 @@ static bool can_pbvh_draw(Object *ob, DerivedMesh *dm)
|
||||
return false;
|
||||
}
|
||||
|
||||
return cddm->mvert == me->mvert || ob->sculpt->kb;
|
||||
return cddm->mvert == me->mvert || (ob->paint->sculpt && ob->paint->sculpt->kb);
|
||||
}
|
||||
|
||||
static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
|
||||
{
|
||||
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
|
||||
SculptSession *ss;
|
||||
|
||||
if (!ob) {
|
||||
cddm->pbvh = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ob->sculpt)
|
||||
if (!ob->paint)
|
||||
return NULL;
|
||||
|
||||
if (ob->sculpt->pbvh) {
|
||||
cddm->pbvh = ob->sculpt->pbvh;
|
||||
if (ob->paint->pbvh) {
|
||||
cddm->pbvh = ob->paint->pbvh;
|
||||
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
|
||||
}
|
||||
|
||||
ss = ob->paint->sculpt;
|
||||
|
||||
/* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */
|
||||
if (!cddm->pbvh && ob->sculpt->bm) {
|
||||
if (!cddm->pbvh && ss && ss->bm) {
|
||||
cddm->pbvh = BKE_pbvh_new();
|
||||
cddm->pbvh_draw = true;
|
||||
|
||||
BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm,
|
||||
ob->sculpt->bm_smooth_shading,
|
||||
ob->sculpt->bm_log, ob->sculpt->cd_vert_node_offset,
|
||||
ob->sculpt->cd_face_node_offset);
|
||||
BKE_pbvh_build_bmesh(cddm->pbvh, ss->bm,
|
||||
ss->bm_smooth_shading,
|
||||
ss->bm_log, ss->cd_vert_node_offset,
|
||||
ss->cd_face_node_offset);
|
||||
|
||||
pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
|
||||
pbvh_show_diffuse_color_set(cddm->pbvh, ss->show_diffuse_color);
|
||||
}
|
||||
|
||||
|
||||
@@ -301,11 +307,15 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
|
||||
BKE_mesh_tessface_ensure(me);
|
||||
|
||||
BKE_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
|
||||
me->totface, me->totvert, &me->vdata);
|
||||
me->totface, me->totvert, &me->vdata, &me->ldata);
|
||||
|
||||
pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
|
||||
if (ss) {
|
||||
pbvh_show_diffuse_color_set(cddm->pbvh, ss->show_diffuse_color);
|
||||
|
||||
deformed = check_sculpt_object_deformed(ob, true);
|
||||
deformed = check_sculpt_object_deformed(ob, true);
|
||||
}
|
||||
else
|
||||
deformed = false;
|
||||
|
||||
if (deformed && ob->derivedDeform) {
|
||||
DerivedMesh *deformdm = ob->derivedDeform;
|
||||
|
@@ -377,9 +377,9 @@ void multires_force_update(Object *ob)
|
||||
if (ob) {
|
||||
BKE_object_free_derived_caches(ob);
|
||||
|
||||
if (ob->sculpt && ob->sculpt->pbvh) {
|
||||
BKE_pbvh_free(ob->sculpt->pbvh);
|
||||
ob->sculpt->pbvh = NULL;
|
||||
if (ob->paint && ob->paint->pbvh) {
|
||||
BKE_pbvh_free(ob->paint->pbvh);
|
||||
ob->paint->pbvh = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -434,7 +434,7 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
|
||||
if (ob->bsoft) bsbFree(ob->bsoft);
|
||||
if (ob->gpulamp.first) GPU_lamp_free(ob);
|
||||
|
||||
BKE_free_sculptsession(ob);
|
||||
BKE_free_paintsession(ob);
|
||||
|
||||
if (ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
|
||||
|
||||
@@ -1523,7 +1523,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
|
||||
BKE_constraints_copy(&obn->constraints, &ob->constraints, true);
|
||||
|
||||
obn->mode = OB_MODE_OBJECT;
|
||||
obn->sculpt = NULL;
|
||||
obn->paint = NULL;
|
||||
|
||||
/* increase user numbers */
|
||||
id_us_plus((ID *)obn->data);
|
||||
@@ -3232,25 +3232,26 @@ void BKE_object_handle_update(EvaluationContext *eval_ctx, Scene *scene, Object
|
||||
|
||||
void BKE_object_sculpt_modifiers_changed(Object *ob)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
SculptSession *ss = psession ? psession->sculpt : NULL;
|
||||
|
||||
if (ss) {
|
||||
if (!ss->cache) {
|
||||
/* we free pbvh on changes, except during sculpt since it can't deal with
|
||||
* changing PVBH node organization, we hope topology does not change in
|
||||
* the meantime .. weak */
|
||||
if (ss->pbvh) {
|
||||
BKE_pbvh_free(ss->pbvh);
|
||||
ss->pbvh = NULL;
|
||||
if (psession->pbvh) {
|
||||
BKE_pbvh_free(psession->pbvh);
|
||||
psession->pbvh = NULL;
|
||||
}
|
||||
|
||||
BKE_free_sculptsession_deformMats(ob->sculpt);
|
||||
BKE_free_sculptsession_deformMats(psession->sculpt);
|
||||
}
|
||||
else {
|
||||
PBVHNode **nodes;
|
||||
int n, totnode;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
|
||||
BKE_pbvh_search_gather(psession->pbvh, NULL, NULL, &nodes, &totnode);
|
||||
|
||||
for (n = 0; n < totnode; n++)
|
||||
BKE_pbvh_node_mark_update(nodes[n]);
|
||||
|
@@ -573,7 +573,7 @@ void BKE_free_sculptsession_deformMats(SculptSession *ss)
|
||||
/* Write out the sculpt dynamic-topology BMesh to the Mesh */
|
||||
static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SculptSession *ss = ob->paint->sculpt;
|
||||
|
||||
if (ss->bm) {
|
||||
if (ob->data) {
|
||||
@@ -591,7 +591,7 @@ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
|
||||
|
||||
void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
|
||||
{
|
||||
if (ob && ob->sculpt) {
|
||||
if (ob && ob->paint && ob->paint->sculpt) {
|
||||
sculptsession_bm_to_me_update_data_only(ob, reorder);
|
||||
|
||||
/* ensure the objects DerivedMesh mesh doesn't hold onto arrays now realloc'd in the mesh [#34473] */
|
||||
@@ -601,8 +601,11 @@ void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
|
||||
|
||||
void BKE_sculptsession_bm_to_me_for_render(Object *object)
|
||||
{
|
||||
if (object && object->sculpt) {
|
||||
if (object->sculpt->bm) {
|
||||
if (object && object->paint && object->paint->sculpt) {
|
||||
PaintSession *psession = object->paint;
|
||||
SculptSession *ss = psession->sculpt;
|
||||
|
||||
if (ss->bm) {
|
||||
/* Ensure no points to old arrays are stored in DM
|
||||
*
|
||||
* Apparently, we could not use DAG_id_tag_update
|
||||
@@ -611,9 +614,9 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object)
|
||||
*/
|
||||
BKE_object_free_derived_caches(object);
|
||||
|
||||
if (object->sculpt->pbvh) {
|
||||
BKE_pbvh_free(object->sculpt->pbvh);
|
||||
object->sculpt->pbvh = NULL;
|
||||
if (psession->pbvh) {
|
||||
BKE_pbvh_free(psession->pbvh);
|
||||
psession->pbvh = NULL;
|
||||
}
|
||||
|
||||
sculptsession_bm_to_me_update_data_only(object, false);
|
||||
@@ -628,29 +631,18 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object)
|
||||
|
||||
void BKE_free_sculptsession(Object *ob)
|
||||
{
|
||||
if (ob && ob->sculpt) {
|
||||
SculptSession *ss = ob->sculpt;
|
||||
DerivedMesh *dm = ob->derivedFinal;
|
||||
if (ob && ob->paint && ob->paint->sculpt) {
|
||||
PaintSession *psession = ob->paint;
|
||||
SculptSession *ss = psession->sculpt;
|
||||
|
||||
if (ss->bm) {
|
||||
BKE_sculptsession_bm_to_me(ob, true);
|
||||
BM_mesh_free(ss->bm);
|
||||
}
|
||||
|
||||
if (ss->pbvh)
|
||||
BKE_pbvh_free(ss->pbvh);
|
||||
if (ss->bm_log)
|
||||
BM_log_free(ss->bm_log);
|
||||
|
||||
if (dm && dm->getPBVH)
|
||||
dm->getPBVH(NULL, dm); /* signal to clear */
|
||||
|
||||
if (ss->texcache)
|
||||
MEM_freeN(ss->texcache);
|
||||
|
||||
if (ss->tex_pool)
|
||||
BKE_image_pool_free(ss->tex_pool);
|
||||
|
||||
if (ss->layer_co)
|
||||
MEM_freeN(ss->layer_co);
|
||||
|
||||
@@ -663,10 +655,37 @@ void BKE_free_sculptsession(Object *ob)
|
||||
|
||||
MEM_freeN(ss);
|
||||
|
||||
ob->sculpt = NULL;
|
||||
psession->sculpt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_free_paintsession(Object *ob) {
|
||||
|
||||
if (ob && ob->paint) {
|
||||
PaintSession *psession = ob->paint;
|
||||
DerivedMesh *dm = ob->derivedFinal;
|
||||
|
||||
if (psession->pbvh)
|
||||
BKE_pbvh_free(psession->pbvh);
|
||||
|
||||
if (psession->texcache)
|
||||
MEM_freeN(psession->texcache);
|
||||
|
||||
if (psession->tex_pool)
|
||||
BKE_image_pool_free(psession->tex_pool);
|
||||
|
||||
if (dm && dm->getPBVH)
|
||||
dm->getPBVH(NULL, dm); /* signal to clear */
|
||||
|
||||
if (psession->sculpt)
|
||||
BKE_free_sculptsession(ob);
|
||||
|
||||
MEM_freeN(psession);
|
||||
ob->paint = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Sculpt mode handles multires differently from regular meshes, but only if
|
||||
* it's the last modifier on the stack and it is not on the first level */
|
||||
MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob)
|
||||
@@ -675,7 +694,7 @@ MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob)
|
||||
ModifierData *md;
|
||||
VirtualModifierData virtualModifierData;
|
||||
|
||||
if (ob->sculpt && ob->sculpt->bm) {
|
||||
if (ob->paint && ob->paint->sculpt && ob->paint->sculpt->bm) {
|
||||
/* can't combine multires and dynamic topology */
|
||||
return NULL;
|
||||
}
|
||||
@@ -709,7 +728,7 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
|
||||
VirtualModifierData virtualModifierData;
|
||||
|
||||
if (mmd || ob->sculpt->bm)
|
||||
if (mmd || ob->paint->sculpt->bm)
|
||||
return false;
|
||||
|
||||
/* non-locked shape keys could be handled in the same way as deformed mesh */
|
||||
@@ -738,7 +757,8 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
|
||||
bool need_pmap, bool need_mask)
|
||||
{
|
||||
DerivedMesh *dm;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
SculptSession *ss = psession->sculpt;
|
||||
Mesh *me = ob->data;
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
|
||||
|
||||
@@ -767,7 +787,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
|
||||
}
|
||||
|
||||
/* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */
|
||||
BKE_mesh_tessface_ensure(me);
|
||||
//BKE_mesh_tessface_ensure(me);
|
||||
|
||||
if (!mmd) ss->kb = BKE_keyblock_from_object(ob);
|
||||
else ss->kb = NULL;
|
||||
@@ -795,10 +815,10 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
|
||||
ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
|
||||
}
|
||||
|
||||
ss->pbvh = dm->getPBVH(ob, dm);
|
||||
psession->pbvh = dm->getPBVH(ob, dm);
|
||||
ss->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL;
|
||||
|
||||
pbvh_show_diffuse_color_set(ss->pbvh, ss->show_diffuse_color);
|
||||
pbvh_show_diffuse_color_set(psession->pbvh, ss->show_diffuse_color);
|
||||
|
||||
if (ss->modifiers_active) {
|
||||
if (!ss->orig_cos) {
|
||||
@@ -809,7 +829,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
|
||||
ss->orig_cos = (ss->kb) ? BKE_keyblock_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
|
||||
|
||||
BKE_crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
|
||||
BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
|
||||
BKE_pbvh_apply_vertCos(psession->pbvh, ss->deform_cos);
|
||||
|
||||
for (a = 0; a < me->totvert; ++a) {
|
||||
invert_m3(ss->deform_imats[a]);
|
||||
@@ -826,14 +846,14 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
|
||||
|
||||
/* if pbvh is deformed, key block is already applied to it */
|
||||
if (ss->kb) {
|
||||
bool pbvh_deformd = BKE_pbvh_isDeformed(ss->pbvh);
|
||||
bool pbvh_deformd = BKE_pbvh_isDeformed(psession->pbvh);
|
||||
if (!pbvh_deformd || ss->deform_cos == NULL) {
|
||||
float (*vertCos)[3] = BKE_keyblock_convert_to_vertcos(ob, ss->kb);
|
||||
|
||||
if (vertCos) {
|
||||
if (!pbvh_deformd) {
|
||||
/* apply shape keys coordinates to PBVH */
|
||||
BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
|
||||
BKE_pbvh_apply_vertCos(psession->pbvh, vertCos);
|
||||
}
|
||||
if (ss->deform_cos == NULL) {
|
||||
ss->deform_cos = vertCos;
|
||||
|
@@ -533,7 +533,7 @@ static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
|
||||
}
|
||||
|
||||
/* Do a full rebuild with on Mesh data structure */
|
||||
void BKE_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert, struct CustomData *vdata)
|
||||
void BKE_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert, struct CustomData *vdata, CustomData *ldata)
|
||||
{
|
||||
BBC *prim_bbc = NULL;
|
||||
BB cb;
|
||||
@@ -546,7 +546,11 @@ void BKE_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int
|
||||
bvh->totvert = totvert;
|
||||
bvh->leaf_limit = LEAF_LIMIT;
|
||||
bvh->vdata = vdata;
|
||||
|
||||
bvh->ldata = ldata;
|
||||
|
||||
if (bvh->ldata) {
|
||||
bvh->drawtype |= PBVH_DRAW_NO_INDEXED;
|
||||
}
|
||||
BB_reset(&cb);
|
||||
|
||||
/* For each face, store the AABB and the AABB centroid */
|
||||
@@ -1090,7 +1094,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
||||
GPU_build_mesh_pbvh_buffers(node->face_vert_indices,
|
||||
bvh->faces, bvh->verts,
|
||||
node->prim_indices,
|
||||
node->totprim);
|
||||
node->totprim, (bvh->drawtype & PBVH_DRAW_NO_INDEXED) != 0);
|
||||
break;
|
||||
case PBVH_BMESH:
|
||||
node->draw_buffers =
|
||||
@@ -1121,6 +1125,8 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
||||
node->face_verts,
|
||||
CustomData_get_layer(bvh->vdata,
|
||||
CD_PAINT_MASK),
|
||||
CustomData_get_layer(bvh->ldata,
|
||||
CD_MLOOPCOL),
|
||||
node->face_vert_indices,
|
||||
bvh->show_diffuse_color);
|
||||
break;
|
||||
|
@@ -116,11 +116,18 @@ typedef enum {
|
||||
PBVH_DYNTOPO_SMOOTH_SHADING = 1
|
||||
} PBVHFlags;
|
||||
|
||||
/* don't use indexed drawing even if smooth shaded because we need to sample per face face data */
|
||||
typedef enum {
|
||||
PBVH_DRAW_NO_INDEXED = 1
|
||||
} PBVHDraw;
|
||||
|
||||
typedef struct PBVHBMeshLog PBVHBMeshLog;
|
||||
typedef enum PBVHType PBVHType;
|
||||
|
||||
struct PBVH {
|
||||
PBVHType type;
|
||||
PBVHFlags flags;
|
||||
PBVHDraw drawtype;
|
||||
|
||||
PBVHNode *nodes;
|
||||
int node_mem_count, totnode;
|
||||
@@ -135,6 +142,7 @@ struct PBVH {
|
||||
MVert *verts;
|
||||
MFace *faces;
|
||||
CustomData *vdata;
|
||||
CustomData *ldata;
|
||||
|
||||
/* Grid Data */
|
||||
CCGKey gridkey;
|
||||
|
@@ -3296,23 +3296,23 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ob->sculpt)
|
||||
if (!ob->paint)
|
||||
return NULL;
|
||||
|
||||
grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
|
||||
|
||||
if (ob->sculpt->pbvh) {
|
||||
if (ob->paint->pbvh) {
|
||||
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, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces,
|
||||
BKE_pbvh_grids_update(ob->paint->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces,
|
||||
ccgdm->gridFlagMats, ccgdm->gridHidden);
|
||||
}
|
||||
|
||||
ccgdm->pbvh = ob->sculpt->pbvh;
|
||||
ccgdm->pbvh = ob->paint->pbvh;
|
||||
}
|
||||
|
||||
if (ccgdm->pbvh)
|
||||
@@ -3326,20 +3326,21 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
|
||||
|
||||
numGrids = ccgDM_getNumGrids(dm);
|
||||
|
||||
ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
|
||||
ob->paint->pbvh = ccgdm->pbvh = BKE_pbvh_new();
|
||||
BKE_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
|
||||
numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
|
||||
}
|
||||
else if (ob->type == OB_MESH) {
|
||||
Mesh *me = ob->data;
|
||||
ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
|
||||
void *ldata = (ob->mode & OB_MODE_VERTEX_PAINT) ? &me->ldata : NULL;
|
||||
ob->paint->pbvh = ccgdm->pbvh = BKE_pbvh_new();
|
||||
BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH ONLY complain if mpoly is valid but not mface */
|
||||
BKE_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
|
||||
me->totface, me->totvert, &me->vdata);
|
||||
me->totface, me->totvert, &me->vdata, ldata);
|
||||
}
|
||||
|
||||
if (ccgdm->pbvh)
|
||||
pbvh_show_diffuse_color_set(ccgdm->pbvh, ob->sculpt->show_diffuse_color);
|
||||
if (ccgdm->pbvh && ob->paint->sculpt)
|
||||
pbvh_show_diffuse_color_set(ccgdm->pbvh, ob->paint->sculpt->show_diffuse_color);
|
||||
|
||||
return ccgdm->pbvh;
|
||||
}
|
||||
|
@@ -5186,8 +5186,8 @@ static void direct_link_object(FileData *fd, Object *ob)
|
||||
/* in case this value changes in future, clamp else we get undefined behavior */
|
||||
CLAMP(ob->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
|
||||
|
||||
if (ob->sculpt) {
|
||||
ob->sculpt = MEM_callocN(sizeof(SculptSession), "reload sculpt session");
|
||||
if (ob->paint) {
|
||||
ob->paint = MEM_callocN(sizeof(PaintSession), "reload paint session");
|
||||
}
|
||||
|
||||
link_list(fd, &ob->lodlevels);
|
||||
|
@@ -1538,7 +1538,7 @@ static const char *object_mode_op_string(int mode)
|
||||
if (mode == OB_MODE_SCULPT)
|
||||
return "SCULPT_OT_sculptmode_toggle";
|
||||
if (mode == OB_MODE_VERTEX_PAINT)
|
||||
return "PAINT_OT_vertex_paint_toggle";
|
||||
return "PAINT_OT_vertex_paint_pbvh_toggle";
|
||||
if (mode == OB_MODE_WEIGHT_PAINT)
|
||||
return "PAINT_OT_weight_paint_toggle";
|
||||
if (mode == OB_MODE_TEXTURE_PAINT)
|
||||
|
@@ -52,6 +52,7 @@ set(SRC
|
||||
paint_undo.c
|
||||
paint_utils.c
|
||||
paint_vertex.c
|
||||
paint_vertex_pbvh.c
|
||||
paint_vertex_proj.c
|
||||
sculpt.c
|
||||
sculpt_undo.c
|
||||
|
@@ -534,7 +534,7 @@ static bool sculpt_get_brush_geometry(
|
||||
mouse[0] = x;
|
||||
mouse[1] = y;
|
||||
|
||||
if (vc->obact->sculpt && vc->obact->sculpt->pbvh &&
|
||||
if (vc->obact->paint && vc->obact->paint->pbvh &&
|
||||
sculpt_stroke_get_location(C, location, mouse))
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(paint);
|
||||
@@ -1004,7 +1004,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
||||
|
||||
/* TODO: as sculpt and other paint modes are unified, this
|
||||
* special mode of drawing will go away */
|
||||
if ((mode == PAINT_SCULPT) && vc.obact->sculpt) {
|
||||
if ((mode == PAINT_SCULPT) && vc.obact->paint->sculpt) {
|
||||
float location[3];
|
||||
int pixel_radius;
|
||||
bool hit;
|
||||
|
@@ -384,7 +384,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
|
||||
|
||||
dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH);
|
||||
pbvh = dm->getPBVH(ob, dm);
|
||||
ob->sculpt->pbvh = pbvh;
|
||||
ob->paint->pbvh = pbvh;
|
||||
|
||||
get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area);
|
||||
pbvh_type = BKE_pbvh_type(pbvh);
|
||||
|
@@ -121,6 +121,9 @@ void PAINT_OT_weight_gradient(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vertex_paint_toggle(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
|
||||
|
||||
void PAINT_OT_vertex_paint_pbvh_toggle(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vertex_paint_pbvh(struct wmOperatorType *ot);
|
||||
|
||||
unsigned int vpaint_get_current_col(struct Scene *scene, struct VPaint *vp);
|
||||
|
||||
|
||||
@@ -219,6 +222,7 @@ void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4],
|
||||
void paint_sample_color(bContext *C, struct ARegion *ar, int x, int y, bool texpaint_proj, bool palette);
|
||||
|
||||
void paint_stroke_operator_properties(struct wmOperatorType *ot);
|
||||
float paint_pbvh_raycast_init(struct ViewContext *vc, const float mouse[2], float ray_start[3], float ray_end[3], float ray_normal[3], bool original);
|
||||
|
||||
void BRUSH_OT_curve_preset(struct wmOperatorType *ot);
|
||||
|
||||
|
@@ -108,7 +108,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
|
||||
value = RNA_float_get(op->ptr, "value");
|
||||
|
||||
BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
|
||||
pbvh = ob->sculpt->pbvh;
|
||||
pbvh = ob->paint->pbvh;
|
||||
multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
|
||||
@@ -216,7 +216,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
|
||||
negate_m4(clip_planes);
|
||||
|
||||
BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
|
||||
pbvh = ob->sculpt->pbvh;
|
||||
pbvh = ob->paint->pbvh;
|
||||
multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
|
||||
|
||||
sculpt_undo_push_begin("Mask box fill");
|
||||
@@ -362,7 +362,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
|
||||
negate_m4(clip_planes);
|
||||
|
||||
BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
|
||||
pbvh = ob->sculpt->pbvh;
|
||||
pbvh = ob->paint->pbvh;
|
||||
multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
|
||||
|
||||
sculpt_undo_push_begin("Mask lasso fill");
|
||||
|
@@ -1111,7 +1111,9 @@ void ED_operatortypes_paint(void)
|
||||
|
||||
/* vertex */
|
||||
WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
|
||||
WM_operatortype_append(PAINT_OT_vertex_paint_pbvh_toggle);
|
||||
WM_operatortype_append(PAINT_OT_vertex_paint);
|
||||
WM_operatortype_append(PAINT_OT_vertex_paint_pbvh);
|
||||
WM_operatortype_append(PAINT_OT_vertex_color_set);
|
||||
WM_operatortype_append(PAINT_OT_vertex_color_smooth);
|
||||
|
||||
|
@@ -54,6 +54,7 @@
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
@@ -225,6 +226,35 @@ void paint_stroke_operator_properties(wmOperatorType *ot)
|
||||
|
||||
}
|
||||
|
||||
float paint_pbvh_raycast_init(ViewContext *vc, const float mouse[2], float ray_start[3], float ray_end[3], float ray_normal[3], bool original)
|
||||
{
|
||||
float obimat[4][4];
|
||||
float dist;
|
||||
Object *ob = vc->obact;
|
||||
RegionView3D *rv3d = vc->ar->regiondata;
|
||||
|
||||
/* TODO: what if the segment is totally clipped? (return == 0) */
|
||||
ED_view3d_win_to_segment(vc->ar, vc->v3d, mouse, ray_start, ray_end, true);
|
||||
|
||||
invert_m4_m4(obimat, ob->obmat);
|
||||
mul_m4_v3(obimat, ray_start);
|
||||
mul_m4_v3(obimat, ray_end);
|
||||
|
||||
sub_v3_v3v3(ray_normal, ray_end, ray_start);
|
||||
dist = normalize_v3(ray_normal);
|
||||
|
||||
if (!rv3d->is_persp) {
|
||||
BKE_pbvh_raycast_project_ray_root(ob->paint->pbvh, original, ray_start, ray_end, ray_normal);
|
||||
|
||||
/* recalculate the normal */
|
||||
sub_v3_v3v3(ray_normal, ray_end, ray_start);
|
||||
dist = normalize_v3(ray_normal);
|
||||
}
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
|
||||
/* 3D Paint */
|
||||
|
||||
static void imapaint_project(float matrix[4][4], const float co[3], float pco[4])
|
||||
|
393
source/blender/editors/sculpt_paint/paint_vertex_pbvh.c
Normal file
393
source/blender/editors/sculpt_paint/paint_vertex_pbvh.c
Normal file
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/editors/sculpt_paint/paint_vertex_pbvh.c
|
||||
* \ingroup edsculpt
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_bitmap.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_mapping.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_object_deform.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_colortools.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "GPU_buffers.h"
|
||||
|
||||
#include "ED_armature.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "paint_intern.h"
|
||||
|
||||
typedef struct {
|
||||
PaintSession *psession;
|
||||
const float *ray_start, *ray_normal;
|
||||
bool hit;
|
||||
float dist;
|
||||
} VPaintRaycastData;
|
||||
|
||||
|
||||
static void vpaint_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
|
||||
{
|
||||
if (BKE_pbvh_node_get_tmin(node) < *tmin) {
|
||||
VPaintRaycastData *vrd = data_v;
|
||||
|
||||
if (BKE_pbvh_node_raycast(vrd->psession->pbvh, node, NULL, false,
|
||||
vrd->ray_start, vrd->ray_normal, &vrd->dist))
|
||||
{
|
||||
vrd->hit = 1;
|
||||
*tmin = vrd->dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool vpaint_stroke_get_location(bContext *C, float out[3], const float mouse[2])
|
||||
{
|
||||
Object *ob;
|
||||
PaintSession *psession;
|
||||
float ray_start[3], ray_end[3], ray_normal[3], dist;
|
||||
VPaintRaycastData vrd;
|
||||
ViewContext vc;
|
||||
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
ob = vc.obact;
|
||||
|
||||
psession = ob->paint;
|
||||
|
||||
//sculpt_stroke_modifiers_check(C, ob);
|
||||
|
||||
dist = paint_pbvh_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false);
|
||||
|
||||
vrd.psession = psession;
|
||||
vrd.hit = 0;
|
||||
vrd.ray_start = ray_start;
|
||||
vrd.ray_normal = ray_normal;
|
||||
vrd.dist = dist;
|
||||
|
||||
BKE_pbvh_raycast(psession->pbvh, vpaint_raycast_cb, &vrd,
|
||||
ray_start, ray_normal, false);
|
||||
|
||||
copy_v3_v3(out, ray_normal);
|
||||
mul_v3_fl(out, vrd.dist);
|
||||
add_v3_v3(out, ray_start);
|
||||
|
||||
return vrd.hit;
|
||||
}
|
||||
|
||||
static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *UNUSED(op),
|
||||
const float mouse[2])
|
||||
{
|
||||
float co[3];
|
||||
/* Don't start the stroke until mouse goes over the mesh.
|
||||
* note: mouse will only be null when re-executing the saved stroke. */
|
||||
if (!mouse || vpaint_stroke_get_location(C, co, mouse)) {
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
|
||||
ED_view3d_init_mats_rv3d(ob, CTX_wm_region_view3d(C));
|
||||
|
||||
// sculpt_update_cache_invariants(C, sd, psession, op, mouse);
|
||||
|
||||
// sculpt_undo_push_begin(sculpt_tool_name(sd));
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
int retval;
|
||||
|
||||
// op->customdata = paint_stroke_new(C, op, NULL, vpaint_stroke_test_start,
|
||||
// vpaint_stroke_update_step, NULL,
|
||||
// vpaint_stroke_done, event->type);
|
||||
(void)vpaint_stroke_test_start;
|
||||
|
||||
if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
|
||||
paint_stroke_data_free(op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
OPERATOR_RETVAL_CHECK(retval);
|
||||
BLI_assert(retval == OPERATOR_RUNNING_MODAL);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
void PAINT_OT_vertex_paint_pbvh(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Vertex Paint";
|
||||
ot->idname = "PAINT_OT_vertex_paint_pbvh";
|
||||
ot->description = "Paint a stroke in the active vertex color layer";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = vpaint_invoke;
|
||||
ot->modal = paint_stroke_modal;
|
||||
// ot->exec = vpaint_exec;
|
||||
ot->poll = vertex_paint_poll;
|
||||
// ot->cancel = vpaint_cancel;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
|
||||
paint_stroke_operator_properties(ot);
|
||||
}
|
||||
|
||||
|
||||
/* if the polygons from the mesh and the 'derivedFinal' match
|
||||
* we can assume that no modifiers are applied and that its worth adding tessellated faces
|
||||
* so 'vertex_paint_use_fast_update_check()' returns true */
|
||||
static bool vertex_paint_use_tessface_check(Object *ob, Mesh *me)
|
||||
{
|
||||
DerivedMesh *dm = ob->derivedFinal;
|
||||
|
||||
if (me && dm) {
|
||||
return (me->mpoly == CustomData_get_layer(&dm->polyData, CD_MPOLY));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void update_tessface_data(Object *ob, Mesh *me)
|
||||
{
|
||||
if (vertex_paint_use_tessface_check(ob, me)) {
|
||||
/* assume if these exist, that they are up to date & valid */
|
||||
if (!me->mcol || !me->mface) {
|
||||
/* should always be true */
|
||||
/* XXX Why this clearing? tessface_calc will reset it anyway! */
|
||||
#if 0
|
||||
if (me->mcol) {
|
||||
memset(me->mcol, 255, 4 * sizeof(MCol) * me->totface);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* create tessfaces because they will be used for drawing & fast updates */
|
||||
BKE_mesh_tessface_calc(me); /* does own call to update pointers */
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (me->totface) {
|
||||
/* this wont be used, theres no need to keep it */
|
||||
BKE_mesh_tessface_clear(me);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool make_vertexcol(Object *ob) /* single ob */
|
||||
{
|
||||
Mesh *me;
|
||||
|
||||
if ((ob->id.lib) ||
|
||||
((me = BKE_mesh_from_object(ob)) == NULL) ||
|
||||
(me->totpoly == 0) ||
|
||||
(me->edit_btmesh))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* copies from shadedisplist to mcol */
|
||||
if (!me->mloopcol && me->totloop) {
|
||||
if (!me->mcol) {
|
||||
CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
|
||||
}
|
||||
if (!me->mloopcol) {
|
||||
CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop);
|
||||
}
|
||||
BKE_mesh_update_customdata_pointers(me, true);
|
||||
}
|
||||
|
||||
update_tessface_data(ob, me);
|
||||
|
||||
DAG_id_tag_update(&me->id, 0);
|
||||
|
||||
return (me->mloopcol != NULL);
|
||||
}
|
||||
|
||||
static void vpaint_init_session(Scene *scene, Object *ob)
|
||||
{
|
||||
PaintSession *psession = ob->paint;
|
||||
/* needs to be called after we ensure tessface */
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
||||
|
||||
if (!psession) {
|
||||
psession = ob->paint = MEM_callocN(sizeof(PaintSession), "sculpt session");
|
||||
}
|
||||
|
||||
psession->pbvh = dm->getPBVH(ob, dm);
|
||||
|
||||
// BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, false);
|
||||
}
|
||||
|
||||
static VPaint *new_vpaint(int wpaint)
|
||||
{
|
||||
VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint");
|
||||
|
||||
vp->flag = (wpaint) ? 0 : VP_SPRAY;
|
||||
vp->paint.flags |= PAINT_SHOW_BRUSH;
|
||||
|
||||
return vp;
|
||||
}
|
||||
|
||||
static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
const int mode_flag = OB_MODE_VERTEX_PAINT;
|
||||
const bool is_mode_set = (ob->mode & mode_flag) != 0;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
VPaint *vp = scene->toolsettings->vpaint;
|
||||
Mesh *me;
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
|
||||
int flush_recalc = 0;
|
||||
|
||||
if (!is_mode_set) {
|
||||
if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* multires in sculpt mode could have different from object mode subdivision level */
|
||||
flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl;
|
||||
|
||||
me = BKE_mesh_from_object(ob);
|
||||
|
||||
/* toggle: end vpaint */
|
||||
if (is_mode_set) {
|
||||
ob->mode &= ~mode_flag;
|
||||
|
||||
if (mmd)
|
||||
multires_force_update(ob);
|
||||
|
||||
if (flush_recalc)
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
|
||||
if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
|
||||
BKE_mesh_flush_select_from_polys(me);
|
||||
}
|
||||
|
||||
BKE_free_paintsession(ob);
|
||||
|
||||
paint_cursor_delete_textures();
|
||||
}
|
||||
else {
|
||||
ob->mode |= mode_flag;
|
||||
|
||||
if (me->mloopcol == NULL) {
|
||||
make_vertexcol(ob);
|
||||
}
|
||||
|
||||
if (vp == NULL) {
|
||||
vp = scene->toolsettings->vpaint = new_vpaint(0);
|
||||
|
||||
/* Turn on X plane mirror symmetry by default */
|
||||
vp->paint.symmetry_flags |= PAINT_SYMM_X;
|
||||
vp->paint.flags |= PAINT_SHOW_BRUSH;
|
||||
}
|
||||
|
||||
/* Create sculpt mode session data */
|
||||
if (ob->paint)
|
||||
BKE_free_paintsession(ob);
|
||||
|
||||
vpaint_init_session(scene, ob);
|
||||
|
||||
paint_cursor_start(C, vertex_paint_poll);
|
||||
|
||||
BKE_paint_init(&scene->toolsettings->unified_paint_settings, &vp->paint, PAINT_CURSOR_VERTEX_PAINT);
|
||||
}
|
||||
|
||||
/* update modifier stack for mapping requirements */
|
||||
DAG_id_tag_update(&me->id, 0);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* for switching to/from mode */
|
||||
static int paint_poll_test(bContext *C)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
if (ob == NULL || ob->type != OB_MESH)
|
||||
return 0;
|
||||
if (!ob->data || ((ID *)ob->data)->lib)
|
||||
return 0;
|
||||
if (CTX_data_edit_object(C))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void PAINT_OT_vertex_paint_pbvh_toggle(wmOperatorType *ot)
|
||||
{
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Vertex Paint Mode";
|
||||
ot->idname = "PAINT_OT_vertex_paint_pbvh_toggle";
|
||||
ot->description = "Toggle the vertex paint mode in 3D view";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = vpaint_mode_toggle_exec;
|
||||
ot->poll = paint_poll_test;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,7 @@ int sculpt_poll_view3d(struct bContext *C);
|
||||
bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]);
|
||||
|
||||
/* Dynamic topology */
|
||||
void sculpt_pbvh_clear(Object *ob);
|
||||
void paint_pbvh_clear(Object *ob);
|
||||
void sculpt_dyntopo_node_layers_add(struct SculptSession *ss);
|
||||
void sculpt_update_after_dynamic_topology_toggle(bContext *C);
|
||||
void sculpt_dynamic_topology_enable(struct bContext *C);
|
||||
|
@@ -97,7 +97,8 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SculptSession *ss = ob->paint->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
MVert *mvert;
|
||||
int *index, i, j;
|
||||
|
||||
@@ -144,7 +145,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
|
||||
|
||||
/* pbvh uses it's own mvert array, so coords should be */
|
||||
/* propagated to pbvh here */
|
||||
BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
|
||||
BKE_pbvh_apply_vertCos(psession->pbvh, vertCos);
|
||||
|
||||
MEM_freeN(vertCos);
|
||||
}
|
||||
@@ -188,7 +189,7 @@ static int sculpt_undo_restore_hidden(bContext *C, DerivedMesh *dm,
|
||||
SculptUndoNode *unode)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SculptSession *ss = ob->paint->sculpt;
|
||||
int i;
|
||||
|
||||
if (unode->maxvert) {
|
||||
@@ -225,7 +226,7 @@ static int sculpt_undo_restore_hidden(bContext *C, DerivedMesh *dm,
|
||||
static int sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNode *unode)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SculptSession *ss = ob->paint->sculpt;
|
||||
MVert *mvert;
|
||||
float *vmask;
|
||||
int *index, i, j;
|
||||
@@ -268,7 +269,8 @@ static int sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNode
|
||||
static void sculpt_undo_bmesh_restore_generic(bContext *C,
|
||||
SculptUndoNode *unode,
|
||||
Object *ob,
|
||||
SculptSession *ss)
|
||||
SculptSession *ss,
|
||||
PaintSession *psession)
|
||||
{
|
||||
if (unode->applied) {
|
||||
BM_log_undo(ss->bm, ss->bm_log);
|
||||
@@ -289,7 +291,7 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
|
||||
(void)C;
|
||||
#endif
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
|
||||
BKE_pbvh_search_gather(psession->pbvh, NULL, NULL, &nodes, &totnode);
|
||||
|
||||
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
|
||||
for (i = 0; i < totnode; i++) {
|
||||
@@ -300,7 +302,7 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
else {
|
||||
sculpt_pbvh_clear(ob);
|
||||
paint_pbvh_clear(ob);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,10 +310,10 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
|
||||
static void sculpt_undo_bmesh_enable(Object *ob,
|
||||
SculptUndoNode *unode)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SculptSession *ss = ob->paint->sculpt;
|
||||
Mesh *me = ob->data;
|
||||
|
||||
sculpt_pbvh_clear(ob);
|
||||
paint_pbvh_clear(ob);
|
||||
|
||||
/* Create empty BMesh and enable logging */
|
||||
ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
|
||||
@@ -370,7 +372,7 @@ static void sculpt_undo_bmesh_restore_end(bContext *C,
|
||||
static int sculpt_undo_bmesh_restore(bContext *C,
|
||||
SculptUndoNode *unode,
|
||||
Object *ob,
|
||||
SculptSession *ss)
|
||||
SculptSession *ss, PaintSession *psession)
|
||||
{
|
||||
switch (unode->type) {
|
||||
case SCULPT_UNDO_DYNTOPO_BEGIN:
|
||||
@@ -383,7 +385,7 @@ static int sculpt_undo_bmesh_restore(bContext *C,
|
||||
|
||||
default:
|
||||
if (ss->bm_log) {
|
||||
sculpt_undo_bmesh_restore_generic(C, unode, ob, ss);
|
||||
sculpt_undo_bmesh_restore_generic(C, unode, ob, ss, psession);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@@ -398,7 +400,8 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
|
||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
DerivedMesh *dm;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
SculptSession *ss = psession->sculpt;
|
||||
SculptUndoNode *unode;
|
||||
bool update = false, rebuild = false;
|
||||
bool need_mask = false;
|
||||
@@ -419,7 +422,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
|
||||
/* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */
|
||||
dm = mesh_get_derived_final(scene, ob, 0);
|
||||
|
||||
if (lb->first && sculpt_undo_bmesh_restore(C, lb->first, ob, ss))
|
||||
if (lb->first && sculpt_undo_bmesh_restore(C, lb->first, ob, ss, psession))
|
||||
return;
|
||||
|
||||
for (unode = lb->first; unode; unode = unode->next) {
|
||||
@@ -467,8 +470,8 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
|
||||
/* we update all nodes still, should be more clever, but also
|
||||
* needs to work correct when exiting/entering sculpt mode and
|
||||
* the nodes get recreated, though in that case it could do all */
|
||||
BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
|
||||
BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
|
||||
BKE_pbvh_search_callback(psession->pbvh, NULL, NULL, update_cb, &rebuild);
|
||||
BKE_pbvh_update(psession->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
|
||||
|
||||
if (BKE_sculpt_multires_active(scene, ob)) {
|
||||
if (rebuild)
|
||||
@@ -599,7 +602,8 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
|
||||
{
|
||||
ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
|
||||
SculptUndoNode *unode;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
SculptSession *ss = psession->sculpt;
|
||||
int totvert, allvert, totgrid, maxgrid, gridsize, *grids;
|
||||
|
||||
unode = MEM_callocN(sizeof(SculptUndoNode), "SculptUndoNode");
|
||||
@@ -608,8 +612,8 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
|
||||
unode->node = node;
|
||||
|
||||
if (node) {
|
||||
BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
|
||||
BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
|
||||
BKE_pbvh_node_num_verts(psession->pbvh, node, &totvert, &allvert);
|
||||
BKE_pbvh_node_get_grids(psession->pbvh, node, &grids, &totgrid,
|
||||
&maxgrid, &gridsize, NULL, NULL);
|
||||
|
||||
unode->totvert = totvert;
|
||||
@@ -631,7 +635,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
|
||||
break;
|
||||
case SCULPT_UNDO_HIDDEN:
|
||||
if (maxgrid)
|
||||
sculpt_undo_alloc_and_store_hidden(ss->pbvh, unode);
|
||||
sculpt_undo_alloc_and_store_hidden(psession->pbvh, unode);
|
||||
else
|
||||
unode->vert_hidden = BLI_BITMAP_NEW(allvert, "SculptUndoNode.vert_hidden");
|
||||
|
||||
@@ -670,10 +674,11 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
|
||||
|
||||
static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
SculptSession *ss = psession->sculpt;
|
||||
PBVHVertexIter vd;
|
||||
|
||||
BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
|
||||
BKE_pbvh_vertex_iter_begin(psession->pbvh, unode->node, vd, PBVH_ITER_ALL)
|
||||
{
|
||||
copy_v3_v3(unode->co[vd.i], vd.co);
|
||||
if (vd.no) copy_v3_v3_short(unode->no[vd.i], vd.no);
|
||||
@@ -687,7 +692,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
|
||||
|
||||
static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
|
||||
{
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
PBVH *pbvh = ob->paint->pbvh;
|
||||
PBVHNode *node = unode->node;
|
||||
|
||||
if (unode->grids) {
|
||||
@@ -709,10 +714,10 @@ static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
|
||||
|
||||
static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
PBVHVertexIter vd;
|
||||
|
||||
BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
|
||||
BKE_pbvh_vertex_iter_begin(psession->pbvh, unode->node, vd, PBVH_ITER_ALL)
|
||||
{
|
||||
unode->mask[vd.i] = *vd.mask;
|
||||
}
|
||||
@@ -725,7 +730,8 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
|
||||
{
|
||||
ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
|
||||
SculptUndoNode *unode = lb->first;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
SculptSession *ss = psession->sculpt;
|
||||
PBVHVertexIter vd;
|
||||
|
||||
if (!lb->first) {
|
||||
@@ -776,7 +782,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
|
||||
case SCULPT_UNDO_MASK:
|
||||
/* Before any vertex values get modified, ensure their
|
||||
* original positions are logged */
|
||||
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
|
||||
BKE_pbvh_vertex_iter_begin(psession->pbvh, node, vd, PBVH_ITER_ALL) {
|
||||
BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset);
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
@@ -786,7 +792,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
|
||||
{
|
||||
GSetIterator gs_iter;
|
||||
GSet *faces = BKE_pbvh_bmesh_node_faces(node);
|
||||
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
|
||||
BKE_pbvh_vertex_iter_begin(psession->pbvh, node, vd, PBVH_ITER_ALL) {
|
||||
BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset);
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
@@ -811,7 +817,8 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
|
||||
SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
|
||||
SculptUndoType type)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PaintSession *psession = ob->paint;
|
||||
SculptSession *ss = psession->sculpt;
|
||||
SculptUndoNode *unode;
|
||||
|
||||
/* list is manipulated by multiple threads, so we lock */
|
||||
@@ -841,14 +848,14 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
|
||||
|
||||
if (unode->grids) {
|
||||
int totgrid, *grids;
|
||||
BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
|
||||
BKE_pbvh_node_get_grids(psession->pbvh, node, &grids, &totgrid,
|
||||
NULL, NULL, NULL, NULL);
|
||||
memcpy(unode->grids, grids, sizeof(int) * totgrid);
|
||||
}
|
||||
else {
|
||||
int *vert_indices, allvert;
|
||||
BKE_pbvh_node_num_verts(ss->pbvh, node, NULL, &allvert);
|
||||
BKE_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL);
|
||||
BKE_pbvh_node_num_verts(psession->pbvh, node, NULL, &allvert);
|
||||
BKE_pbvh_node_get_verts(psession->pbvh, node, &vert_indices, NULL);
|
||||
memcpy(unode->index, vert_indices, sizeof(int) * unode->totvert);
|
||||
}
|
||||
|
||||
|
@@ -263,8 +263,8 @@ static void stats_object_pose(Object *ob, SceneStats *stats)
|
||||
|
||||
static void stats_object_sculpt_dynamic_topology(Object *ob, SceneStats *stats)
|
||||
{
|
||||
stats->totvert = ob->sculpt->bm->totvert;
|
||||
stats->tottri = ob->sculpt->bm->totface;
|
||||
stats->totvert = ob->paint->sculpt->bm->totvert;
|
||||
stats->tottri = ob->paint->sculpt->bm->totface;
|
||||
}
|
||||
|
||||
static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
|
||||
@@ -338,7 +338,7 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
|
||||
static bool stats_is_object_dynamic_topology_sculpt(Object *ob)
|
||||
{
|
||||
return (ob && (ob->mode & OB_MODE_SCULPT) &&
|
||||
ob->sculpt && ob->sculpt->bm);
|
||||
ob->paint && ob->paint->sculpt && ob->paint->sculpt->bm);
|
||||
}
|
||||
|
||||
/* Statistics displayed in info header. Called regularly on scene changes. */
|
||||
|
@@ -3754,17 +3754,17 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
|
||||
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
|
||||
|
||||
if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene))) {
|
||||
if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->paint && ob->paint->sculpt && (p = BKE_paint_get_active(scene))) {
|
||||
GPUVertexAttribs gattribs;
|
||||
float planes[4][4];
|
||||
float (*fpl)[4] = NULL;
|
||||
const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
|
||||
|
||||
if (ob->sculpt->partial_redraw) {
|
||||
if (ob->paint->partial_redraw) {
|
||||
if (ar->do_draw & RGN_DRAW_PARTIAL) {
|
||||
ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
|
||||
fpl = planes;
|
||||
ob->sculpt->partial_redraw = 0;
|
||||
ob->paint->partial_redraw = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3811,7 +3811,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
|
||||
(base->flag & SELECT) &&
|
||||
(draw_wire == OBDRAW_WIRE_OFF) &&
|
||||
(ob->sculpt == NULL))
|
||||
(!ob->paint || !ob->paint->sculpt))
|
||||
{
|
||||
draw_mesh_object_outline(v3d, ob, dm);
|
||||
}
|
||||
@@ -3843,7 +3843,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
|
||||
(base->flag & SELECT) &&
|
||||
(draw_wire == OBDRAW_WIRE_OFF) &&
|
||||
(ob->sculpt == NULL))
|
||||
(!ob->paint || !ob->paint->sculpt))
|
||||
{
|
||||
draw_mesh_object_outline(v3d, ob, dm);
|
||||
}
|
||||
@@ -3853,16 +3853,16 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
glEnable(GL_LIGHTING);
|
||||
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
|
||||
|
||||
if (ob->sculpt && (p = BKE_paint_get_active(scene))) {
|
||||
if (ob->paint && ob->paint->sculpt && (p = BKE_paint_get_active(scene))) {
|
||||
float planes[4][4];
|
||||
float (*fpl)[4] = NULL;
|
||||
const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
|
||||
|
||||
if (ob->sculpt->partial_redraw) {
|
||||
if (ob->paint->partial_redraw) {
|
||||
if (ar->do_draw & RGN_DRAW_PARTIAL) {
|
||||
ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
|
||||
fpl = planes;
|
||||
ob->sculpt->partial_redraw = 0;
|
||||
ob->paint->partial_redraw = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3878,7 +3878,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
|
||||
|
||||
if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
|
||||
if ((!ob->paint || !ob->paint->sculpt) && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
|
||||
if ((dflag & DRAW_CONSTCOLOR) == 0) {
|
||||
glColor3ubv(ob_wire_col);
|
||||
}
|
||||
@@ -7415,7 +7415,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
|
||||
dt = OB_SOLID;
|
||||
}
|
||||
|
||||
if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
|
||||
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
|
||||
dt = OB_PAINT;
|
||||
}
|
||||
|
||||
|
@@ -165,7 +165,7 @@ typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
|
||||
/* build */
|
||||
GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(int (*face_vert_indices)[4],
|
||||
struct MFace *mface, struct MVert *mvert,
|
||||
int *face_indices, int totface);
|
||||
int *face_indices, int totface, bool no_indexed);
|
||||
|
||||
GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
|
||||
unsigned int **grid_hidden, int gridsize);
|
||||
@@ -175,7 +175,7 @@ GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading);
|
||||
/* update */
|
||||
|
||||
void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
|
||||
int *vert_indices, int totvert, const float *vmask,
|
||||
int *vert_indices, int totvert, const float *vmask, const int *lcol,
|
||||
int (*face_vert_indices)[4], bool show_diffuse_color);
|
||||
|
||||
void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
|
||||
|
@@ -1577,7 +1577,7 @@ static void gpu_color_from_mask_quad_set(const CCGKey *key,
|
||||
}
|
||||
|
||||
void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
|
||||
int *vert_indices, int totvert, const float *vmask,
|
||||
int *vert_indices, int totvert, const float *vmask, const int *lcol,
|
||||
int (*face_vert_indices)[4], bool show_diffuse_color)
|
||||
{
|
||||
VertexBufferFormat *vert_data;
|
||||
@@ -1627,7 +1627,11 @@ void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
|
||||
VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \
|
||||
if (vmask) \
|
||||
gpu_color_from_mask_copy(vmask[vertex], diffuse_color, out->color); \
|
||||
else \
|
||||
else if (lcol) { \
|
||||
char *lc = (char *)(lcol + vertex); \
|
||||
copy_v3_v3_char((char *)out->color, lc); \
|
||||
printf("updating vcol\n"); \
|
||||
} else \
|
||||
rgb_float_to_uchar(out->color, diffuse_color); \
|
||||
} (void)0
|
||||
|
||||
@@ -1692,9 +1696,13 @@ void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
|
||||
|
||||
if (vmask)
|
||||
gpu_color_from_mask_copy(fmask, diffuse_color, out->color);
|
||||
else
|
||||
if (lcol) {
|
||||
char *lc = (char *)(lcol + fv[vi[j][k]]);
|
||||
copy_v3_v3_char((char *)out->color, lc);
|
||||
printf("updating vcol\n");
|
||||
} else
|
||||
rgb_float_to_uchar(out->color, diffuse_color);
|
||||
|
||||
|
||||
vert_data++;
|
||||
}
|
||||
}
|
||||
@@ -1717,7 +1725,7 @@ void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
|
||||
GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(int (*face_vert_indices)[4],
|
||||
MFace *mface, MVert *mvert,
|
||||
int *face_indices,
|
||||
int totface)
|
||||
int totface, bool no_indexed)
|
||||
{
|
||||
GPU_PBVH_Buffers *buffers;
|
||||
unsigned short *tri_data;
|
||||
@@ -1725,7 +1733,7 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(int (*face_vert_indices)[4],
|
||||
|
||||
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
|
||||
buffers->index_type = GL_UNSIGNED_SHORT;
|
||||
buffers->smooth = mface[face_indices[0]].flag & ME_SMOOTH;
|
||||
buffers->smooth = (mface[face_indices[0]].flag & ME_SMOOTH) && !no_indexed;
|
||||
|
||||
buffers->show_diffuse_color = false;
|
||||
buffers->use_matcaps = false;
|
||||
|
@@ -117,7 +117,7 @@ typedef struct Object {
|
||||
ID id;
|
||||
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
|
||||
|
||||
struct SculptSession *sculpt;
|
||||
struct PaintSession *paint;
|
||||
|
||||
short type, partype;
|
||||
int par1, par2, par3; /* can be vertexnrs */
|
||||
|
@@ -1502,8 +1502,8 @@ int rna_DupliObject_index_get(PointerRNA *ptr)
|
||||
|
||||
int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr)
|
||||
{
|
||||
SculptSession *ss = ((Object *)ptr->id.data)->sculpt;
|
||||
return (ss && ss->bm);
|
||||
PaintSession *psession = ((Object *)ptr->id.data)->paint;
|
||||
return (psession && psession && psession->sculpt->bm);
|
||||
}
|
||||
|
||||
static void rna_Object_lod_distance_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
|
@@ -233,9 +233,9 @@ static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNU
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
|
||||
|
||||
if (ob->sculpt) {
|
||||
ob->sculpt->bm_smooth_shading = ((scene->toolsettings->sculpt->flags &
|
||||
SCULPT_DYNTOPO_SMOOTH_SHADING) != 0);
|
||||
if (ob->paint && ob->paint->sculpt) {
|
||||
ob->paint->sculpt->bm_smooth_shading = ((scene->toolsettings->sculpt->flags &
|
||||
SCULPT_DYNTOPO_SMOOTH_SHADING) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,12 +244,12 @@ static void rna_Sculpt_ShowDiffuseColor_update(Main *UNUSED(bmain), Scene *scene
|
||||
{
|
||||
Object *ob = (scene->basact) ? scene->basact->object : NULL;
|
||||
|
||||
if (ob && ob->sculpt) {
|
||||
if (ob && ob->paint && ob->paint->sculpt) {
|
||||
Sculpt *sd = scene->toolsettings->sculpt;
|
||||
ob->sculpt->show_diffuse_color = ((sd->flags & SCULPT_SHOW_DIFFUSE) != 0);
|
||||
ob->paint->sculpt->show_diffuse_color = ((sd->flags & SCULPT_SHOW_DIFFUSE) != 0);
|
||||
|
||||
if (ob->sculpt->pbvh)
|
||||
pbvh_show_diffuse_color_set(ob->sculpt->pbvh, ob->sculpt->show_diffuse_color);
|
||||
if (ob->paint->pbvh)
|
||||
pbvh_show_diffuse_color_set(ob->paint->pbvh, ob->paint->sculpt->show_diffuse_color);
|
||||
|
||||
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
|
||||
}
|
||||
|
Reference in New Issue
Block a user