Sculpt-dev: Cleanup sculpt temp attribute API
* The sculpt code now handles lifetime ownership of SculptCustomLayer structs. This removes the need to create temp attributes and get their SculptCustomLayer reference structs in seperate steps, as the code can internally update e.g. bmesh block offsets for all SculptCustomLayer instances. * Removed ss->custom_layers. The SCULPT_SCL_XXX enums are no longer used to reference standard attributes (though they are used, at the moment, to provide names for them). Instead a new accessor struct, ss->scl, has pointers to standard attributes (e.g. ss->scl.automasking_factor, ss->scl.fairing_mask, etc). This is the final version of the API that will be ported to master (possibly minus the SCULPT_xxx alias functions that simply call BKE_sculptsession_XXX equivalents).
This commit is contained in:
parent
93b96bab9a
commit
ed8ffec61f
|
@ -1037,7 +1037,7 @@ static void MemorY_ErroR(const char *block, const char *error)
|
|||
print_error("Memoryblock %s: %s\n", block, error);
|
||||
|
||||
#ifdef WITH_ASSERT_ABORT
|
||||
abort();
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -641,10 +641,16 @@ typedef struct SculptFakeNeighbors {
|
|||
/* Custom Temporary Attributes */
|
||||
|
||||
typedef struct SculptLayerParams {
|
||||
int simple_array : 1; // cannot be combined with permanent
|
||||
int permanent : 1; // cannot be combined with simple_array
|
||||
/* Allocate a flat array outside the CustomData system. Cannot be combined with permanent. */
|
||||
int simple_array : 1;
|
||||
|
||||
/* Do not mark CustomData layer as temporary. Cannot be combined with simple_array. Doesn't
|
||||
* work with PBVH_GRIDS.
|
||||
*/
|
||||
int permanent : 1; // cannot be combined with simple_array
|
||||
int nocopy : 1;
|
||||
int nointerp : 1;
|
||||
int stroke_only : 1; /* release layer at end of struct, except for PBVH_BMESH */
|
||||
} SculptLayerParams;
|
||||
|
||||
typedef struct SculptCustomLayer {
|
||||
|
@ -665,10 +671,7 @@ typedef struct SculptCustomLayer {
|
|||
bool ready;
|
||||
} SculptCustomLayer;
|
||||
|
||||
/* These custom attributes have references
|
||||
(SculptCustomLayer pointers) inside of ss->custom_layers
|
||||
that are kept up to date with SCULPT_update_customdata_refs.
|
||||
*/
|
||||
/* Standard names for sculpt attributes. */
|
||||
typedef enum {
|
||||
SCULPT_SCL_FAIRING_MASK,
|
||||
SCULPT_SCL_FAIRING_FADE,
|
||||
|
@ -688,6 +691,8 @@ typedef enum {
|
|||
|
||||
#define SCULPT_SCL_GET_NAME(stdattr) ("__" #stdattr)
|
||||
|
||||
#define SCULPT_MAX_TEMP_LAYERS 64
|
||||
|
||||
typedef struct SculptSession {
|
||||
/* Mesh data (not copied) can come either directly from a Mesh, or from a MultiresDM */
|
||||
struct { /* Special handling for multires meshes */
|
||||
|
@ -897,17 +902,41 @@ typedef struct SculptSession {
|
|||
struct MSculptVert *mdyntopo_verts; // for non-bmesh
|
||||
int mdyntopo_verts_size;
|
||||
|
||||
/*list of up to date custom layer references,
|
||||
note that entries can be NULL if layer doesn't
|
||||
exist. See SCULPT_SCL_XXX enum above.*/
|
||||
struct SculptCustomLayer *custom_layers[SCULPT_SCL_LAYER_MAX];
|
||||
/* This is a fixed-size array so we can pass pointers to its elements
|
||||
* to client code. This is important to keep bmesh offsets up to date.
|
||||
*/
|
||||
struct SculptCustomLayer temp_layers[SCULPT_MAX_TEMP_LAYERS];
|
||||
|
||||
/*
|
||||
PBVH_GRIDS cannot store customdata layers in real CustomDataLayers,
|
||||
so we queue the memory allocated for them to free later
|
||||
*/
|
||||
struct SculptCustomLayer **layers_to_free;
|
||||
int tot_layers_to_free;
|
||||
/* Convienence SculptCusotmLayer pointers. */
|
||||
|
||||
struct {
|
||||
/* Persistent base. */
|
||||
SculptCustomLayer *persistent_co;
|
||||
SculptCustomLayer *persistent_no;
|
||||
SculptCustomLayer *persistent_disp;
|
||||
|
||||
/* Fairing. */
|
||||
SculptCustomLayer *fairing_fade;
|
||||
SculptCustomLayer *fairing_mask;
|
||||
SculptCustomLayer *prefairing_co;
|
||||
|
||||
/* Automasking. */
|
||||
SculptCustomLayer *automasking_factor;
|
||||
|
||||
/* Layer brush. */
|
||||
SculptCustomLayer *layer_disp;
|
||||
SculptCustomLayer *layer_id;
|
||||
|
||||
/* Limit Surface */
|
||||
SculptCustomLayer *limit_surface;
|
||||
|
||||
/* Smooth */
|
||||
SculptCustomLayer *smooth_bdist;
|
||||
SculptCustomLayer *smooth_vel;
|
||||
|
||||
/* Face Sets */
|
||||
SculptCustomLayer *orig_fsets;
|
||||
} scl;
|
||||
|
||||
bool save_temp_layers;
|
||||
|
||||
|
@ -943,12 +972,12 @@ void BKE_sculptsession_bmesh_attr_update_internal(struct Object *ob);
|
|||
void BKE_sculptsession_sync_attributes(struct Object *ob, struct Mesh *me);
|
||||
|
||||
void BKE_sculptsession_bmesh_add_layers(struct Object *ob);
|
||||
bool BKE_sculptsession_attr_get_layer(struct Object *ob,
|
||||
eAttrDomain domain,
|
||||
int proptype,
|
||||
const char *name,
|
||||
SculptCustomLayer *scl,
|
||||
SculptLayerParams *params);
|
||||
SculptCustomLayer *BKE_sculptsession_attr_layer_get(struct Object *ob,
|
||||
eAttrDomain domain,
|
||||
int proptype,
|
||||
const char *name,
|
||||
SculptLayerParams *params,
|
||||
bool *r_is_new);
|
||||
bool BKE_sculptsession_attr_release_layer(struct Object *ob, SculptCustomLayer *scl);
|
||||
void BKE_sculptsession_update_attr_refs(struct Object *ob);
|
||||
|
||||
|
|
|
@ -1104,7 +1104,7 @@ void reset_clay_mappings(BrushChannelSet *chset, bool strips)
|
|||
}
|
||||
|
||||
// adds any missing channels to brushes
|
||||
ATTR_NO_OPT void BKE_brush_builtin_patch(Brush *brush, int tool)
|
||||
void BKE_brush_builtin_patch(Brush *brush, int tool)
|
||||
{
|
||||
check_builtin_init();
|
||||
|
||||
|
|
|
@ -4245,6 +4245,10 @@ void BKE_object_sculpt_data_create(Object *ob)
|
|||
BLI_assert((ob->sculpt == nullptr) && (ob->mode & OB_MODE_ALL_SCULPT));
|
||||
ob->sculpt = MEM_cnew<SculptSession>(__func__);
|
||||
ob->sculpt->mode_type = (eObjectMode)ob->mode;
|
||||
|
||||
for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
|
||||
ob->sculpt->temp_layers[i].released = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool BKE_object_obdata_texspace_get(Object *ob, char **r_texflag, float **r_loc, float **r_size)
|
||||
|
|
|
@ -1543,28 +1543,18 @@ void BKE_sculptsession_free(Object *ob)
|
|||
|
||||
sculptsession_free_pbvh(ob);
|
||||
|
||||
for (int i = 0; i < SCULPT_SCL_LAYER_MAX; i++) {
|
||||
MEM_SAFE_FREE(ss->custom_layers[i]);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(ss->epmap);
|
||||
MEM_SAFE_FREE(ss->epmap_mem);
|
||||
|
||||
MEM_SAFE_FREE(ss->vemap);
|
||||
MEM_SAFE_FREE(ss->vemap_mem);
|
||||
|
||||
bool SCULPT_attr_release_layer(
|
||||
SculptSession * ss, Object * ob, struct SculptCustomLayer * scl);
|
||||
for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
|
||||
SculptCustomLayer *scl = ss->temp_layers + i;
|
||||
|
||||
if (ss->layers_to_free) {
|
||||
for (int i = 0; i < ss->tot_layers_to_free; i++) {
|
||||
if (ss->layers_to_free[i]) {
|
||||
SCULPT_attr_release_layer(ss, ob, ss->layers_to_free[i]);
|
||||
// SCULPT_attr_release_layer frees layers_to_free[i] itself
|
||||
}
|
||||
if (!scl->released && !scl->is_cdlayer) {
|
||||
BKE_sculptsession_attr_release_layer(ob, scl);
|
||||
}
|
||||
|
||||
MEM_freeN(ss->layers_to_free);
|
||||
}
|
||||
|
||||
if (ss->tex_pool) {
|
||||
|
@ -2192,6 +2182,8 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
|
|||
if (object->sculpt && object->sculpt->pbvh) {
|
||||
BKE_pbvh_update_active_vcol(object->sculpt->pbvh, orig_me);
|
||||
}
|
||||
|
||||
BKE_sculptsession_update_attr_refs(object);
|
||||
}
|
||||
|
||||
void BKE_sculpt_update_object_for_edit(
|
||||
|
@ -3264,31 +3256,6 @@ static bool sculpt_attr_get_layer(SculptSession *ss,
|
|||
out->elemsize = elemsize;
|
||||
out->ready = true;
|
||||
|
||||
/*grids cannot store normal customdata layers, and thus
|
||||
we cannot rely on the customdata api to keep track of
|
||||
and free their memory for us.
|
||||
|
||||
so instead we queue them in a dynamic array inside of
|
||||
SculptSession.
|
||||
*/
|
||||
if (ss->pbvh && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
|
||||
ss->tot_layers_to_free++;
|
||||
|
||||
if (!ss->layers_to_free) {
|
||||
ss->layers_to_free = MEM_calloc_arrayN(
|
||||
ss->tot_layers_to_free, sizeof(void *), "ss->layers_to_free");
|
||||
}
|
||||
else {
|
||||
ss->layers_to_free = MEM_recallocN(ss->layers_to_free,
|
||||
sizeof(void *) * ss->tot_layers_to_free);
|
||||
}
|
||||
|
||||
SculptCustomLayer *cpy = MEM_callocN(sizeof(SculptCustomLayer), "SculptCustomLayer cpy");
|
||||
*cpy = *out;
|
||||
|
||||
ss->layers_to_free[ss->tot_layers_to_free - 1] = cpy;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3446,23 +3413,51 @@ static bool sculpt_attr_get_layer(SculptSession *ss,
|
|||
}
|
||||
|
||||
out->ready = true;
|
||||
out->released = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BKE_sculptsession_attr_get_layer(Object *ob,
|
||||
eAttrDomain domain,
|
||||
int proptype,
|
||||
const char *name,
|
||||
SculptCustomLayer *scl,
|
||||
SculptLayerParams *params)
|
||||
SculptCustomLayer *BKE_sculptsession_attr_layer_get(Object *ob,
|
||||
eAttrDomain domain,
|
||||
int proptype,
|
||||
const char *name,
|
||||
SculptLayerParams *params,
|
||||
bool *r_is_new)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
bool ret = sculpt_attr_get_layer(ss, ob, domain, proptype, name, scl, true, params);
|
||||
for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
|
||||
SculptCustomLayer *scl = ss->temp_layers + i;
|
||||
|
||||
if (!scl->released && STREQ(scl->name, name) && scl->proptype == proptype &&
|
||||
scl->domain == domain) {
|
||||
if (r_is_new) {
|
||||
*r_is_new = true;
|
||||
}
|
||||
|
||||
return scl;
|
||||
}
|
||||
}
|
||||
|
||||
SculptCustomLayer *scl = NULL;
|
||||
for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
|
||||
if (ss->temp_layers[i].released) {
|
||||
scl = ss->temp_layers + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert(scl != NULL);
|
||||
bool is_newlayer = sculpt_attr_get_layer(ss, ob, domain, proptype, name, scl, true, params);
|
||||
|
||||
if (r_is_new) {
|
||||
*r_is_new = is_newlayer;
|
||||
}
|
||||
|
||||
BKE_sculptsession_update_attr_refs(ob);
|
||||
|
||||
return ret;
|
||||
return scl;
|
||||
}
|
||||
|
||||
void BKE_sculptsession_bmesh_attr_update_internal(Object *ob)
|
||||
|
@ -3488,14 +3483,10 @@ void BKE_sculptsession_update_attr_refs(Object *ob)
|
|||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
/* run twice, in case SCULPT_attr_get_layer had to recreate a layer and
|
||||
messed up the ordering. */
|
||||
messed up the bmesh offsets. */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < SCULPT_SCL_LAYER_MAX; j++) {
|
||||
SculptCustomLayer *scl = ss->custom_layers[j];
|
||||
|
||||
if (!scl || !scl->ready) {
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < SCULPT_MAX_TEMP_LAYERS; j++) {
|
||||
SculptCustomLayer *scl = ss->temp_layers + j;
|
||||
|
||||
if (!scl->released && !scl->params.simple_array) {
|
||||
sculpt_attr_get_layer(
|
||||
|
@ -3555,37 +3546,56 @@ bool BKE_sculptsession_attr_release_layer(Object *ob, SculptCustomLayer *scl)
|
|||
eAttrDomain domain = scl->domain;
|
||||
|
||||
if (scl->released) {
|
||||
return false;
|
||||
return false; /* layer already released? */
|
||||
}
|
||||
|
||||
// remove from layers_to_free list if necassary
|
||||
for (int i = 0; scl->data && i < ss->tot_layers_to_free; i++) {
|
||||
if (ss->layers_to_free[i] && ss->layers_to_free[i]->data == scl->data) {
|
||||
MEM_freeN(ss->layers_to_free[i]);
|
||||
ss->layers_to_free[i] = NULL;
|
||||
/* Remove from internal temp_layers array. */
|
||||
for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
|
||||
SculptCustomLayer *scl2 = ss->temp_layers + i;
|
||||
|
||||
if (STREQ(scl2->name, scl->name) && scl2->domain == scl->domain &&
|
||||
scl2->proptype == scl->proptype) {
|
||||
|
||||
scl2->released = true;
|
||||
}
|
||||
}
|
||||
|
||||
scl->released = true;
|
||||
|
||||
if (!scl->from_bmesh) {
|
||||
// for now, don't clean up bmesh temp layers
|
||||
if (scl->is_cdlayer && BKE_pbvh_type(ss->pbvh) != PBVH_GRIDS) {
|
||||
/* TODO: support PBVH_BMESH */
|
||||
|
||||
if (scl->is_cdlayer) {
|
||||
CustomData *cdata = NULL;
|
||||
int totelem = 0;
|
||||
|
||||
switch (domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
cdata = ss->vdata;
|
||||
totelem = ss->totvert;
|
||||
break;
|
||||
case ATTR_DOMAIN_FACE:
|
||||
cdata = ss->pdata;
|
||||
totelem = ss->totfaces;
|
||||
break;
|
||||
default:
|
||||
printf("error, unknown domain in %s\n", __func__);
|
||||
return false;
|
||||
if (BKE_pbvh_type(ss->pbvh) != PBVH_GRIDS) {
|
||||
switch (domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
cdata = ss->vdata;
|
||||
totelem = ss->totvert;
|
||||
break;
|
||||
case ATTR_DOMAIN_FACE:
|
||||
cdata = ss->pdata;
|
||||
totelem = ss->totfaces;
|
||||
break;
|
||||
default:
|
||||
printf("error, unknown domain in %s\n", __func__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
cdata = &ss->temp_vdata;
|
||||
totelem = ss->temp_vdata_elems;
|
||||
break;
|
||||
case ATTR_DOMAIN_FACE:
|
||||
cdata = &ss->temp_pdata;
|
||||
totelem = ss->temp_pdata_elems;
|
||||
break;
|
||||
default:
|
||||
printf("error, unknown domain in %s\n", __func__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CustomData_free_layer(cdata, scl->layer->type, totelem, scl->layer - cdata->layers);
|
||||
|
@ -3597,5 +3607,11 @@ bool BKE_sculptsession_attr_release_layer(Object *ob, SculptCustomLayer *scl)
|
|||
|
||||
scl->data = NULL;
|
||||
}
|
||||
else {
|
||||
/* TODO: implement me! */
|
||||
}
|
||||
|
||||
scl->released = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4827,6 +4827,7 @@ bool BKE_pbvh_cache_is_valid(const struct Object *ob,
|
|||
{
|
||||
if (pbvh->invalid) {
|
||||
printf("pbvh invalid!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pbvh->type != pbvh_type) {
|
||||
|
@ -4837,6 +4838,19 @@ bool BKE_pbvh_cache_is_valid(const struct Object *ob,
|
|||
int totvert = 0, totedge = 0, totloop = 0, totpoly = 0;
|
||||
const CustomData *vdata, *edata, *ldata, *pdata;
|
||||
|
||||
MultiresModifierData *mmd = NULL;
|
||||
|
||||
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
||||
if (md->type == eModifierType_Multires) {
|
||||
mmd = (MultiresModifierData *)md;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mmd && (mmd->flags & eModifierMode_Realtime)) {
|
||||
// return false;
|
||||
}
|
||||
|
||||
switch (pbvh_type) {
|
||||
case PBVH_BMESH:
|
||||
if (!pbvh->bm || pbvh->bm != pbvh->cached_data.bm) {
|
||||
|
@ -4865,15 +4879,6 @@ bool BKE_pbvh_cache_is_valid(const struct Object *ob,
|
|||
pdata = &me->pdata;
|
||||
break;
|
||||
case PBVH_GRIDS: {
|
||||
MultiresModifierData *mmd = NULL;
|
||||
|
||||
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
||||
if (md->type == eModifierType_Multires) {
|
||||
mmd = (MultiresModifierData *)md;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mmd) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1174,7 +1174,7 @@ static void vertex_paint_init_session(Depsgraph *depsgraph,
|
|||
BKE_sculpt_toolsettings_data_ensure(scene);
|
||||
|
||||
BLI_assert(ob->sculpt == nullptr);
|
||||
ob->sculpt = (SculptSession *)MEM_callocN(sizeof(SculptSession), "sculpt session");
|
||||
BKE_object_sculpt_data_create(ob);
|
||||
ob->sculpt->mode_type = object_mode;
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, true);
|
||||
}
|
||||
|
|
|
@ -458,8 +458,7 @@ void SCULPT_vertex_normal_get(SculptSession *ss, SculptVertRef vertex, float no[
|
|||
bool SCULPT_has_persistent_base(SculptSession *ss)
|
||||
{
|
||||
if (!ss->pbvh) {
|
||||
// just see if ss->custom_layer entries exist
|
||||
return ss->custom_layers[SCULPT_SCL_PERS_CO] != NULL;
|
||||
return ss->scl.persistent_co;
|
||||
}
|
||||
|
||||
int idx = -1;
|
||||
|
@ -472,7 +471,7 @@ bool SCULPT_has_persistent_base(SculptSession *ss)
|
|||
idx = CustomData_get_named_layer_index(ss->vdata, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_CO);
|
||||
break;
|
||||
case PBVH_GRIDS:
|
||||
return ss->custom_layers[SCULPT_SCL_PERS_CO];
|
||||
return ss->scl.persistent_co;
|
||||
}
|
||||
|
||||
return idx >= 0;
|
||||
|
@ -480,8 +479,8 @@ bool SCULPT_has_persistent_base(SculptSession *ss)
|
|||
|
||||
const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, SculptVertRef index)
|
||||
{
|
||||
if (ss->custom_layers[SCULPT_SCL_PERS_CO]) {
|
||||
return (float *)SCULPT_attr_vertex_data(index, ss->custom_layers[SCULPT_SCL_PERS_CO]);
|
||||
if (ss->scl.persistent_co) {
|
||||
return (float *)SCULPT_attr_vertex_data(index, ss->scl.persistent_co);
|
||||
}
|
||||
|
||||
return SCULPT_vertex_co_get(ss, index);
|
||||
|
@ -507,8 +506,8 @@ const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, SculptVertR
|
|||
void SCULPT_vertex_limit_surface_get(SculptSession *ss, SculptVertRef vertex, float r_co[3])
|
||||
{
|
||||
if (BKE_pbvh_type(ss->pbvh) != PBVH_GRIDS) {
|
||||
if (ss->custom_layers[SCULPT_SCL_LIMIT_SURFACE]) {
|
||||
float *f = SCULPT_attr_vertex_data(vertex, ss->custom_layers[SCULPT_SCL_LIMIT_SURFACE]);
|
||||
if (ss->scl.limit_surface) {
|
||||
float *f = SCULPT_attr_vertex_data(vertex, ss->scl.limit_surface);
|
||||
copy_v3_v3(r_co, f);
|
||||
}
|
||||
else {
|
||||
|
@ -530,8 +529,8 @@ void SCULPT_vertex_limit_surface_get(SculptSession *ss, SculptVertRef vertex, fl
|
|||
|
||||
void SCULPT_vertex_persistent_normal_get(SculptSession *ss, SculptVertRef vertex, float no[3])
|
||||
{
|
||||
if (ss->custom_layers[SCULPT_SCL_PERS_NO]) {
|
||||
float *no2 = SCULPT_attr_vertex_data(vertex, ss->custom_layers[SCULPT_SCL_PERS_NO]);
|
||||
if (ss->scl.persistent_no) {
|
||||
float *no2 = SCULPT_attr_vertex_data(vertex, ss->scl.persistent_no);
|
||||
copy_v3_v3(no, no2);
|
||||
}
|
||||
else {
|
||||
|
@ -574,17 +573,10 @@ bool SCULPT_attr_ensure_layer(SculptSession *ss,
|
|||
const char *name,
|
||||
SculptLayerParams *params)
|
||||
{
|
||||
SculptCustomLayer scl;
|
||||
bool is_newlayer;
|
||||
BKE_sculptsession_attr_layer_get(ob, domain, proptype, name, params, &is_newlayer);
|
||||
|
||||
// call SCULPT_update_customdata_refs before and after,
|
||||
// thoeretically it can allocate new layers
|
||||
SCULPT_update_customdata_refs(ss, ob);
|
||||
|
||||
bool ret = SCULPT_attr_get_layer(ss, ob, domain, proptype, name, &scl, params);
|
||||
|
||||
SCULPT_update_customdata_refs(ss, ob);
|
||||
|
||||
return ret;
|
||||
return is_newlayer;
|
||||
}
|
||||
|
||||
/* TODO: thoroughly test this function */
|
||||
|
@ -629,15 +621,14 @@ bool SCULPT_attr_release_layer(SculptSession *ss, Object *ob, SculptCustomLayer
|
|||
return BKE_sculptsession_attr_release_layer(ob, scl);
|
||||
}
|
||||
|
||||
bool SCULPT_attr_get_layer(SculptSession *ss,
|
||||
Object *ob,
|
||||
eAttrDomain domain,
|
||||
int proptype,
|
||||
const char *name,
|
||||
SculptCustomLayer *scl,
|
||||
SculptLayerParams *params)
|
||||
SculptCustomLayer *SCULPT_attr_get_layer(SculptSession *ss,
|
||||
Object *ob,
|
||||
eAttrDomain domain,
|
||||
int proptype,
|
||||
const char *name,
|
||||
SculptLayerParams *params)
|
||||
{
|
||||
return BKE_sculptsession_attr_get_layer(ob, domain, proptype, name, scl, params);
|
||||
return BKE_sculptsession_attr_layer_get(ob, domain, proptype, name, params, NULL);
|
||||
}
|
||||
|
||||
SculptVertRef SCULPT_active_vertex_get(SculptSession *ss)
|
||||
|
@ -5332,13 +5323,13 @@ typedef struct BrushRunCommandData {
|
|||
float radius_max;
|
||||
} BrushRunCommandData;
|
||||
|
||||
ATTR_NO_OPT static void get_nodes_undo(Sculpt *sd,
|
||||
Object *ob,
|
||||
Brush *brush,
|
||||
UnifiedPaintSettings *ups,
|
||||
PaintModeSettings *paint_mode_settings,
|
||||
BrushRunCommandData *data,
|
||||
int tool)
|
||||
static void get_nodes_undo(Sculpt *sd,
|
||||
Object *ob,
|
||||
Brush *brush,
|
||||
UnifiedPaintSettings *ups,
|
||||
PaintModeSettings *paint_mode_settings,
|
||||
BrushRunCommandData *data,
|
||||
int tool)
|
||||
{
|
||||
PBVHNode **nodes = NULL;
|
||||
int totnode = 0;
|
||||
|
@ -5528,12 +5519,12 @@ bool SCULPT_needs_area_normal(SculptSession *ss, Sculpt *sd, Brush *brush)
|
|||
SCULPT_get_float(ss, tip_scale_x, sd, brush) != 1.0f;
|
||||
}
|
||||
|
||||
ATTR_NO_OPT static void SCULPT_run_command(Sculpt *sd,
|
||||
Object *ob,
|
||||
Brush *brush,
|
||||
UnifiedPaintSettings *ups,
|
||||
PaintModeSettings *paint_mode_settings,
|
||||
void *userdata)
|
||||
static void SCULPT_run_command(Sculpt *sd,
|
||||
Object *ob,
|
||||
Brush *brush,
|
||||
UnifiedPaintSettings *ups,
|
||||
PaintModeSettings *paint_mode_settings,
|
||||
void *userdata)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
BrushRunCommandData *data = userdata;
|
||||
|
@ -6605,16 +6596,30 @@ void SCULPT_cache_free(SculptSession *ss, Object *ob, StrokeCache *cache)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (ss->custom_layers[SCULPT_SCL_LAYER_DISP]) {
|
||||
SCULPT_attr_release_layer(ss, ob, ss->custom_layers[SCULPT_SCL_LAYER_DISP]);
|
||||
MEM_freeN(ss->custom_layers[SCULPT_SCL_LAYER_DISP]);
|
||||
ss->custom_layers[SCULPT_SCL_LAYER_DISP] = NULL;
|
||||
}
|
||||
/* Free a few temporary attributes if it's cheap to do so, otherwise wait for sculpt mode exit.
|
||||
*/
|
||||
if (BKE_pbvh_type(ss->pbvh) != PBVH_BMESH) {
|
||||
SculptCustomLayer **ptrs = (SculptCustomLayer **)&ss->scl;
|
||||
int ptrs_num = sizeof(ss->scl) / sizeof(void *);
|
||||
|
||||
if (ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID]) {
|
||||
SCULPT_attr_release_layer(ss, ob, ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID]);
|
||||
MEM_freeN(ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID]);
|
||||
ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID] = NULL;
|
||||
/* Go over pointers inside of ss->scl first. */
|
||||
for (int i = 0; i < ptrs_num; i++) {
|
||||
SculptCustomLayer *scl = ptrs[i];
|
||||
|
||||
if (scl && !scl->released && scl->params.stroke_only) {
|
||||
SCULPT_attr_release_layer(ss, ob, scl);
|
||||
ptrs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now go over the main attribute array and release any remaining attributes. */
|
||||
for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
|
||||
SculptCustomLayer *scl = ss->temp_layers + i;
|
||||
|
||||
if (scl && !scl->released && scl->params.stroke_only) {
|
||||
SCULPT_attr_release_layer(ss, ob, scl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(cache->prev_colors);
|
||||
|
@ -6624,26 +6629,6 @@ void SCULPT_cache_free(SculptSession *ss, Object *ob, StrokeCache *cache)
|
|||
BKE_brush_commandlist_free(ss->cache->commandlist);
|
||||
}
|
||||
|
||||
if (ss->custom_layers[SCULPT_SCL_FAIRING_MASK]) {
|
||||
SCULPT_attr_release_layer(ss, ob, ss->custom_layers[SCULPT_SCL_FAIRING_MASK]);
|
||||
MEM_freeN(ss->custom_layers[SCULPT_SCL_FAIRING_MASK]);
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_MASK] = NULL;
|
||||
}
|
||||
|
||||
if (ss->custom_layers[SCULPT_SCL_FAIRING_FADE]) {
|
||||
SCULPT_attr_release_layer(ss, ob, ss->custom_layers[SCULPT_SCL_FAIRING_FADE]);
|
||||
|
||||
MEM_freeN(ss->custom_layers[SCULPT_SCL_FAIRING_FADE]);
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_FADE] = NULL;
|
||||
}
|
||||
|
||||
if (ss->custom_layers[SCULPT_SCL_PREFAIRING_CO]) {
|
||||
SCULPT_attr_release_layer(ss, ob, ss->custom_layers[SCULPT_SCL_PREFAIRING_CO]);
|
||||
|
||||
MEM_freeN(ss->custom_layers[SCULPT_SCL_PREFAIRING_CO]);
|
||||
ss->custom_layers[SCULPT_SCL_PREFAIRING_CO] = NULL;
|
||||
}
|
||||
|
||||
if (ss->cache->channels_final) {
|
||||
BKE_brush_channelset_free(ss->cache->channels_final);
|
||||
}
|
||||
|
@ -6687,26 +6672,22 @@ void SCULPT_cache_free(SculptSession *ss, Object *ob, StrokeCache *cache)
|
|||
|
||||
void SCULPT_release_attributes(SculptSession *ss, Object *ob, bool non_customdata_only)
|
||||
{
|
||||
for (int i = 0; i < SCULPT_SCL_LAYER_MAX; i++) {
|
||||
if (ss->custom_layers[i]) {
|
||||
if (non_customdata_only && !ss->custom_layers[i]->params.simple_array) {
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
|
||||
SculptCustomLayer *scl = ss->temp_layers + i;
|
||||
|
||||
SCULPT_attr_release_layer(ss, ob, ss->custom_layers[i]);
|
||||
|
||||
MEM_freeN(ss->custom_layers[i]);
|
||||
ss->custom_layers[i] = NULL;
|
||||
if (scl->released || (non_customdata_only && !scl->params.simple_array)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SCULPT_attr_release_layer(ss, ob, scl);
|
||||
}
|
||||
|
||||
memset(&ss->scl, 0, sizeof(ss->scl));
|
||||
}
|
||||
|
||||
void SCULPT_clear_scl_pointers(SculptSession *ss)
|
||||
{
|
||||
for (int i = 0; i < SCULPT_SCL_LAYER_MAX; i++) {
|
||||
MEM_SAFE_FREE(ss->custom_layers[i]);
|
||||
ss->custom_layers[i] = NULL;
|
||||
}
|
||||
memset(&ss->scl, 0, sizeof(ss->scl));
|
||||
}
|
||||
|
||||
/* Initialize mirror modifier clipping. */
|
||||
|
|
|
@ -86,28 +86,10 @@ static void sculpt_array_datalayers_init(Object *ob, SculptArray *array, SculptS
|
|||
{
|
||||
SculptLayerParams params = {.permanent = true, .simple_array = false};
|
||||
|
||||
if (!array->scl_inst) {
|
||||
array->scl_inst = MEM_callocN(sizeof(SculptCustomLayer), __func__);
|
||||
}
|
||||
|
||||
if (!array->scl_sym) {
|
||||
array->scl_sym = MEM_callocN(sizeof(SculptCustomLayer), __func__);
|
||||
}
|
||||
|
||||
SCULPT_attr_ensure_layer(
|
||||
array->scl_inst = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_INT32, array_instance_cd_name, ¶ms);
|
||||
SCULPT_attr_ensure_layer(
|
||||
array->scl_sym = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_INT32, array_symmetry_pass_cd_name, ¶ms);
|
||||
|
||||
SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_INT32, array_instance_cd_name, array->scl_inst, ¶ms);
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
array_symmetry_pass_cd_name,
|
||||
array->scl_sym,
|
||||
¶ms);
|
||||
}
|
||||
|
||||
static void sculpt_array_datalayers_add(SculptArray *array, SculptSession *ss, Mesh *mesh)
|
||||
|
@ -161,24 +143,10 @@ void SCULPT_array_datalayers_free(SculptArray *array, Object *ob)
|
|||
SculptLayerParams params = {.permanent = true, .simple_array = false};
|
||||
|
||||
if (array->scl_inst) {
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
array_instance_cd_name,
|
||||
array->scl_inst,
|
||||
¶ms);
|
||||
SCULPT_attr_release_layer(ss, ob, array->scl_inst);
|
||||
}
|
||||
|
||||
if (array->scl_sym) {
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
array_symmetry_pass_cd_name,
|
||||
array->scl_sym,
|
||||
¶ms);
|
||||
SCULPT_attr_release_layer(ss, ob, array->scl_sym);
|
||||
}
|
||||
|
||||
|
@ -353,15 +321,10 @@ static void sculpt_array_ensure_geometry_indices(Object *ob, SculptArray *array)
|
|||
|
||||
SculptLayerParams params = {.permanent = true, .simple_array = false};
|
||||
|
||||
SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_INT32, array_instance_cd_name, array->scl_inst, ¶ms);
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
array_symmetry_pass_cd_name,
|
||||
array->scl_sym,
|
||||
¶ms);
|
||||
array->scl_inst = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_INT32, array_instance_cd_name, ¶ms);
|
||||
array->scl_sym = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_INT32, array_symmetry_pass_cd_name, ¶ms);
|
||||
|
||||
array->copy_index = MEM_malloc_arrayN(totvert, sizeof(int), "array copy index");
|
||||
array->symmetry_pass = MEM_malloc_arrayN(totvert, sizeof(int), "array symmetry pass index");
|
||||
|
|
|
@ -260,11 +260,10 @@ void SCULPT_automasking_cache_free(SculptSession *ss, Object *ob, AutomaskingCac
|
|||
return;
|
||||
}
|
||||
|
||||
if (ss->custom_layers[SCULPT_SCL_AUTOMASKING]) {
|
||||
SCULPT_attr_release_layer(ss, ob, ss->custom_layers[SCULPT_SCL_AUTOMASKING]);
|
||||
|
||||
MEM_SAFE_FREE(ss->custom_layers[SCULPT_SCL_AUTOMASKING]);
|
||||
ss->custom_layers[SCULPT_SCL_AUTOMASKING] = NULL;
|
||||
/* Not worth reallocating bmesh customdata blocks here. */
|
||||
if (ss->scl.automasking_factor && (!ss->pbvh || BKE_pbvh_type(ss->pbvh) != PBVH_BMESH)) {
|
||||
SCULPT_attr_release_layer(ss, ob, ss->scl.automasking_factor);
|
||||
ss->scl.automasking_factor = nullptr;
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(automasking);
|
||||
|
@ -558,33 +557,21 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, const Brush *brush,
|
|||
SCULPT_vertex_random_access_ensure(ss);
|
||||
SCULPT_face_random_access_ensure(ss);
|
||||
|
||||
if (!ss->custom_layers[SCULPT_SCL_AUTOMASKING]) {
|
||||
ss->custom_layers[SCULPT_SCL_AUTOMASKING] = (SculptCustomLayer *)MEM_callocN(
|
||||
sizeof(SculptCustomLayer), "automasking->factorlayer");
|
||||
|
||||
if (!ss->scl.automasking_factor) {
|
||||
SculptLayerParams params;
|
||||
params.permanent = false;
|
||||
params.simple_array = false;
|
||||
|
||||
if (!SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_AUTOMASKING),
|
||||
ss->custom_layers[SCULPT_SCL_AUTOMASKING],
|
||||
¶ms)) {
|
||||
// failed
|
||||
MEM_freeN(ss->custom_layers[SCULPT_SCL_AUTOMASKING]);
|
||||
ss->custom_layers[SCULPT_SCL_AUTOMASKING] = NULL;
|
||||
|
||||
return automasking;
|
||||
}
|
||||
ss->scl.automasking_factor = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_AUTOMASKING),
|
||||
¶ms);
|
||||
}
|
||||
|
||||
automasking->factorlayer = ss->custom_layers[SCULPT_SCL_AUTOMASKING];
|
||||
automasking->factorlayer = ss->scl.automasking_factor;
|
||||
|
||||
// automasking->factorlayer = SCULPT_attr_ensure_layer()
|
||||
// automasking->factor = MEM_malloc_arrayN(totvert, sizeof(float), "automask_factor");
|
||||
for (int i : IndexRange(totvert)) {
|
||||
SculptVertRef vertex = BKE_pbvh_table_index_to_vertex(ss->pbvh, i);
|
||||
float *f = (float *)SCULPT_attr_vertex_data(vertex, automasking->factorlayer);
|
||||
|
|
|
@ -307,9 +307,9 @@ static void sculpt_project_v3_normal_align(SculptSession *ss,
|
|||
/** \name Sculpt Draw Brush
|
||||
* \{ */
|
||||
|
||||
ATTR_NO_OPT static void do_draw_brush_task_cb_ex(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
static void do_draw_brush_task_cb_ex(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
{
|
||||
SculptThreadedTaskData *data = userdata;
|
||||
SculptSession *ss = data->ob->sculpt;
|
||||
|
@ -1794,7 +1794,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
|
|||
const bool is_bmesh = BKE_pbvh_type(ss->pbvh) == PBVH_BMESH;
|
||||
|
||||
if (is_bmesh) {
|
||||
use_persistent_base = use_persistent_base && ss->custom_layers[SCULPT_SCL_PERS_CO];
|
||||
use_persistent_base = use_persistent_base && ss->scl.persistent_co;
|
||||
|
||||
#if 0
|
||||
// check if we need to zero displacement factor
|
||||
|
@ -1820,7 +1820,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
|
|||
#endif
|
||||
}
|
||||
else {
|
||||
use_persistent_base = use_persistent_base && ss->custom_layers[SCULPT_SCL_PERS_CO];
|
||||
use_persistent_base = use_persistent_base && ss->scl.persistent_co;
|
||||
}
|
||||
|
||||
SculptCustomLayer *scl_disp = data->scl;
|
||||
|
@ -1865,8 +1865,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
|
|||
float *disp_factor;
|
||||
|
||||
if (use_persistent_base) {
|
||||
disp_factor = (float *)SCULPT_attr_vertex_data(vd.vertex,
|
||||
ss->custom_layers[SCULPT_SCL_PERS_DISP]);
|
||||
disp_factor = (float *)SCULPT_attr_vertex_data(vd.vertex, ss->scl.persistent_disp);
|
||||
}
|
||||
else {
|
||||
disp_factor = (float *)SCULPT_attr_vertex_data(vd.vertex, scl_disp);
|
||||
|
@ -1996,37 +1995,14 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
|
|||
|
||||
void SCULPT_ensure_persistent_layers(SculptSession *ss, Object *ob)
|
||||
{
|
||||
if (!ss->custom_layers[SCULPT_SCL_PERS_CO]) {
|
||||
SculptLayerParams params = {.permanent = true, .simple_array = false};
|
||||
SculptLayerParams params = {.permanent = true, .simple_array = false};
|
||||
|
||||
ss->custom_layers[SCULPT_SCL_PERS_CO] = MEM_callocN(sizeof(SculptCustomLayer), "scl_pers_co");
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
SCULPT_LAYER_PERS_CO,
|
||||
ss->custom_layers[SCULPT_SCL_PERS_CO],
|
||||
¶ms);
|
||||
|
||||
ss->custom_layers[SCULPT_SCL_PERS_NO] = MEM_callocN(sizeof(SculptCustomLayer), "scl_pers_no");
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
SCULPT_LAYER_PERS_NO,
|
||||
ss->custom_layers[SCULPT_SCL_PERS_NO],
|
||||
¶ms);
|
||||
|
||||
ss->custom_layers[SCULPT_SCL_PERS_DISP] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"scl_pers_disp");
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT,
|
||||
SCULPT_LAYER_PERS_DISP,
|
||||
ss->custom_layers[SCULPT_SCL_PERS_DISP],
|
||||
¶ms);
|
||||
}
|
||||
ss->scl.persistent_co = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_CO, ¶ms);
|
||||
ss->scl.persistent_no = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_NO, ¶ms);
|
||||
ss->scl.persistent_disp = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT, SCULPT_LAYER_PERS_DISP, ¶ms);
|
||||
}
|
||||
|
||||
void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
|
@ -2046,41 +2022,32 @@ void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
SCULPT_ensure_persistent_layers(ss, ob);
|
||||
}
|
||||
|
||||
if (!ss->custom_layers[SCULPT_SCL_LAYER_DISP]) {
|
||||
ss->custom_layers[SCULPT_SCL_LAYER_DISP] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"layer disp scl");
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT,
|
||||
SCULPT_LAYER_DISP,
|
||||
ss->custom_layers[SCULPT_SCL_LAYER_DISP],
|
||||
&((SculptLayerParams){.permanent = false, .simple_array = false}));
|
||||
}
|
||||
|
||||
if (!ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID]) {
|
||||
ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"layer disp scl");
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_STROKE_ID),
|
||||
ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID],
|
||||
&((SculptLayerParams){.permanent = false, .simple_array = false}));
|
||||
}
|
||||
SculptCustomLayer *disp_scl = ss->scl.layer_disp = SCULPT_attr_get_layer(
|
||||
ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_DISP),
|
||||
&((SculptLayerParams){.permanent = false, .simple_array = false, .stroke_only = true}));
|
||||
SculptCustomLayer *id_scl = ss->scl.layer_id = SCULPT_attr_get_layer(
|
||||
ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_STROKE_ID),
|
||||
&((SculptLayerParams){.permanent = false, .simple_array = false, .stroke_only = true}));
|
||||
|
||||
if (BKE_pbvh_type(ss->pbvh) != PBVH_BMESH) {
|
||||
ss->cache->layer_displacement_factor = ss->custom_layers[SCULPT_SCL_LAYER_DISP]->data;
|
||||
ss->cache->layer_stroke_id = ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID]->data;
|
||||
ss->cache->layer_displacement_factor = disp_scl->data;
|
||||
ss->cache->layer_stroke_id = id_scl->data;
|
||||
}
|
||||
|
||||
SculptThreadedTaskData data = {.sd = sd,
|
||||
.ob = ob,
|
||||
.brush = brush,
|
||||
.nodes = nodes,
|
||||
.scl = ss->custom_layers[SCULPT_SCL_LAYER_DISP],
|
||||
.scl2 = ss->custom_layers[SCULPT_SCL_LAYER_STROKE_ID],
|
||||
.scl = disp_scl,
|
||||
.scl2 = id_scl,
|
||||
#ifdef LAYER_FACE_SET_MODE
|
||||
.face_set = fset,
|
||||
.face_set2 = fset + 1
|
||||
|
@ -3443,8 +3410,7 @@ static void do_fairing_brush_tag_store_task_cb_ex(void *__restrict userdata,
|
|||
continue;
|
||||
}
|
||||
|
||||
float *prefair = SCULPT_attr_vertex_data(vd.vertex,
|
||||
ss->custom_layers[SCULPT_SCL_PREFAIRING_CO]);
|
||||
float *prefair = SCULPT_attr_vertex_data(vd.vertex, ss->scl.prefairing_co);
|
||||
|
||||
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
|
||||
brush,
|
||||
|
@ -3460,10 +3426,8 @@ static void do_fairing_brush_tag_store_task_cb_ex(void *__restrict userdata,
|
|||
continue;
|
||||
}
|
||||
|
||||
float *fairing_fade = SCULPT_attr_vertex_data(vd.vertex,
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_FADE]);
|
||||
uchar *fairing_mask = SCULPT_attr_vertex_data(vd.vertex,
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_MASK]);
|
||||
float *fairing_fade = SCULPT_attr_vertex_data(vd.vertex, ss->scl.fairing_fade);
|
||||
uchar *fairing_mask = SCULPT_attr_vertex_data(vd.vertex, ss->scl.fairing_mask);
|
||||
|
||||
*fairing_fade = max_ff(fade, *fairing_fade);
|
||||
*fairing_mask = true;
|
||||
|
@ -3486,57 +3450,37 @@ void SCULPT_do_fairing_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
|
|||
SCULPT_vertex_random_access_ensure(ss);
|
||||
SCULPT_face_random_access_ensure(ss);
|
||||
|
||||
if (!ss->custom_layers[SCULPT_SCL_FAIRING_MASK]) {
|
||||
// SCULPT_attr_ensure_layer(ss, ATTR_DOMAIN_POINT, CD_PROP_BOOL, "fairing_mask");
|
||||
// SCULPT_attr_ensure_layer(ss, ATTR_DOMAIN_POINT, CD_PROP_FLOAT, "fairing_fade");
|
||||
// SCULPT_attr_ensure_layer(ss, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, "prefairing_co");
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = true, .stroke_only = true};
|
||||
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_MASK] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"ss->Cache->fairing_mask");
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_FADE] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"ss->Cache->fairing_fade");
|
||||
ss->custom_layers[SCULPT_SCL_PREFAIRING_CO] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"ss->Cache->prefairing_co");
|
||||
ss->scl.fairing_mask = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_BOOL,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_FAIRING_MASK),
|
||||
¶ms);
|
||||
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = true};
|
||||
ss->scl.fairing_fade = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_FAIRING_FADE),
|
||||
¶ms);
|
||||
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_BOOL,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_FAIRING_MASK),
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_MASK],
|
||||
¶ms);
|
||||
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_FAIRING_FADE),
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_FADE],
|
||||
¶ms);
|
||||
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_PREFAIRING_CO),
|
||||
ss->custom_layers[SCULPT_SCL_PREFAIRING_CO],
|
||||
¶ms);
|
||||
|
||||
SCULPT_update_customdata_refs(ss, ob);
|
||||
}
|
||||
ss->scl.prefairing_co = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_PREFAIRING_CO),
|
||||
¶ms);
|
||||
|
||||
if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
SculptVertRef vertex = BKE_pbvh_table_index_to_vertex(ss->pbvh, i);
|
||||
|
||||
*(uchar *)SCULPT_attr_vertex_data(vertex,
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_MASK]) = false;
|
||||
*(float *)SCULPT_attr_vertex_data(vertex, ss->custom_layers[SCULPT_SCL_FAIRING_FADE]) = 0.0f;
|
||||
copy_v3_v3(
|
||||
(float *)SCULPT_attr_vertex_data(vertex, ss->custom_layers[SCULPT_SCL_PREFAIRING_CO]),
|
||||
SCULPT_vertex_co_get(ss, vertex));
|
||||
*(uchar *)SCULPT_attr_vertex_data(vertex, ss->scl.fairing_mask) = false;
|
||||
*(float *)SCULPT_attr_vertex_data(vertex, ss->scl.fairing_fade) = 0.0f;
|
||||
copy_v3_v3((float *)SCULPT_attr_vertex_data(vertex, ss->scl.prefairing_co),
|
||||
SCULPT_vertex_co_get(ss, vertex));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3563,19 +3507,13 @@ static void do_fairing_brush_displace_task_cb_ex(void *__restrict userdata,
|
|||
SculptSession *ss = data->ob->sculpt;
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
|
||||
if (!*(uchar *)SCULPT_attr_vertex_data(vd.vertex,
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_MASK])) {
|
||||
if (!*(uchar *)SCULPT_attr_vertex_data(vd.vertex, ss->scl.fairing_mask)) {
|
||||
continue;
|
||||
}
|
||||
float disp[3];
|
||||
sub_v3_v3v3(disp,
|
||||
vd.co,
|
||||
SCULPT_attr_vertex_data(vd.vertex, ss->custom_layers[SCULPT_SCL_PREFAIRING_CO]));
|
||||
mul_v3_fl(
|
||||
disp,
|
||||
*(float *)SCULPT_attr_vertex_data(vd.vertex, ss->custom_layers[SCULPT_SCL_FAIRING_FADE]));
|
||||
copy_v3_v3(vd.co,
|
||||
SCULPT_attr_vertex_data(vd.vertex, ss->custom_layers[SCULPT_SCL_PREFAIRING_CO]));
|
||||
sub_v3_v3v3(disp, vd.co, SCULPT_attr_vertex_data(vd.vertex, ss->scl.prefairing_co));
|
||||
mul_v3_fl(disp, *(float *)SCULPT_attr_vertex_data(vd.vertex, ss->scl.fairing_fade));
|
||||
copy_v3_v3(vd.co, SCULPT_attr_vertex_data(vd.vertex, ss->scl.prefairing_co));
|
||||
add_v3_v3(vd.co, disp);
|
||||
if (vd.mvert) {
|
||||
BKE_pbvh_vert_mark_update(ss->pbvh, vd.vertex);
|
||||
|
@ -3592,22 +3530,20 @@ void SCULPT_fairing_brush_exec_fairing_for_cache(Sculpt *sd, Object *ob)
|
|||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
Mesh *mesh = ob->data;
|
||||
|
||||
if (!ss->custom_layers[SCULPT_SCL_FAIRING_MASK]) {
|
||||
if (!ss->scl.fairing_mask) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (BKE_pbvh_type(ss->pbvh)) {
|
||||
case PBVH_FACES: {
|
||||
MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
|
||||
BKE_mesh_prefair_and_fair_vertices(mesh,
|
||||
mvert,
|
||||
ss->custom_layers[SCULPT_SCL_FAIRING_MASK]->data,
|
||||
MESH_FAIRING_DEPTH_TANGENCY);
|
||||
BKE_mesh_prefair_and_fair_vertices(
|
||||
mesh, mvert, ss->scl.fairing_mask->data, MESH_FAIRING_DEPTH_TANGENCY);
|
||||
} break;
|
||||
case PBVH_BMESH: {
|
||||
// note that we allocated fairing_mask.data in simple array mode
|
||||
BKE_bmesh_prefair_and_fair_vertices(
|
||||
ss->bm, ss->custom_layers[SCULPT_SCL_FAIRING_MASK]->data, MESH_FAIRING_DEPTH_TANGENCY);
|
||||
ss->bm, ss->scl.fairing_mask->data, MESH_FAIRING_DEPTH_TANGENCY);
|
||||
} break;
|
||||
case PBVH_GRIDS:
|
||||
BLI_assert(false);
|
||||
|
|
|
@ -2187,9 +2187,9 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(SculptSession *ss,
|
|||
if (SCULPT_has_persistent_base(ss)) {
|
||||
SCULPT_ensure_persistent_layers(ss, ob);
|
||||
|
||||
cloth_sim->cd_pers_co = ss->custom_layers[SCULPT_SCL_PERS_CO]->cd_offset;
|
||||
cloth_sim->cd_pers_no = ss->custom_layers[SCULPT_SCL_PERS_NO]->cd_offset;
|
||||
cloth_sim->cd_pers_disp = ss->custom_layers[SCULPT_SCL_PERS_DISP]->cd_offset;
|
||||
cloth_sim->cd_pers_co = ss->scl.persistent_co->cd_offset;
|
||||
cloth_sim->cd_pers_no = ss->scl.persistent_no->cd_offset;
|
||||
cloth_sim->cd_pers_disp = ss->scl.persistent_disp->cd_offset;
|
||||
}
|
||||
else {
|
||||
cloth_sim->cd_pers_co = cloth_sim->cd_pers_no = cloth_sim->cd_pers_disp = -1;
|
||||
|
|
|
@ -117,11 +117,11 @@ const char orig_faceset_attr_name[] = "_sculpt_original_fsets";
|
|||
|
||||
void SCULPT_face_check_origdata(SculptSession *ss, SculptFaceRef face)
|
||||
{
|
||||
if (!ss->custom_layers[SCULPT_SCL_ORIG_FSETS]) {
|
||||
if (!ss->scl.orig_fsets) {
|
||||
return;
|
||||
}
|
||||
|
||||
short *s = (short *)SCULPT_attr_face_data(face, ss->custom_layers[SCULPT_SCL_ORIG_FSETS]);
|
||||
short *s = (short *)SCULPT_attr_face_data(face, ss->scl.orig_fsets);
|
||||
|
||||
// pack ss->stroke_id in higher 16 bits
|
||||
if (s[1] != ss->stroke_id) {
|
||||
|
@ -132,11 +132,11 @@ void SCULPT_face_check_origdata(SculptSession *ss, SculptFaceRef face)
|
|||
|
||||
int SCULPT_face_set_original_get(SculptSession *ss, SculptFaceRef face)
|
||||
{
|
||||
if (!ss->custom_layers[SCULPT_SCL_ORIG_FSETS]) {
|
||||
if (!ss->scl.orig_fsets) {
|
||||
return SCULPT_face_set_get(ss, face);
|
||||
}
|
||||
|
||||
short *s = (short *)SCULPT_attr_face_data(face, ss->custom_layers[SCULPT_SCL_ORIG_FSETS]);
|
||||
short *s = (short *)SCULPT_attr_face_data(face, ss->scl.orig_fsets);
|
||||
|
||||
if (s[1] != ss->stroke_id) {
|
||||
s[0] = SCULPT_face_set_get(ss, face);
|
||||
|
@ -148,21 +148,13 @@ int SCULPT_face_set_original_get(SculptSession *ss, SculptFaceRef face)
|
|||
|
||||
void SCULPT_face_ensure_original(SculptSession *ss, Object *ob)
|
||||
{
|
||||
if (ss->custom_layers[SCULPT_SCL_ORIG_FSETS]) {
|
||||
return;
|
||||
}
|
||||
|
||||
SculptCustomLayer *scl = MEM_callocN(sizeof(*scl), "orig fset scl");
|
||||
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_FACE,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_ORIG_FSETS),
|
||||
scl,
|
||||
&((SculptLayerParams){.permanent = false, .simple_array = false}));
|
||||
|
||||
ss->custom_layers[SCULPT_SCL_ORIG_FSETS] = scl;
|
||||
ss->scl.orig_fsets = SCULPT_attr_get_layer(
|
||||
ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_FACE,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_ORIG_FSETS),
|
||||
&((SculptLayerParams){.permanent = false, .simple_array = false}));
|
||||
}
|
||||
|
||||
int SCULPT_face_set_flag_get(SculptSession *ss, SculptFaceRef face, char flag)
|
||||
|
|
|
@ -385,15 +385,14 @@ static void mesh_filter_task_cb(void *__restrict userdata,
|
|||
ss,
|
||||
avg,
|
||||
vd.vertex,
|
||||
&((SculptSmoothArgs){
|
||||
.projection = 0.0f,
|
||||
.slide_fset = slide_fset, // 1.0f - hard_edge_fac,
|
||||
.bound_smooth = bsmooth,
|
||||
.preserve_fset_boundaries = preserve_fset_boundaries,
|
||||
.do_weighted_smooth = weighted,
|
||||
.bound_smooth_radius = bound_smooth_radius,
|
||||
.bevel_smooth_factor = bevel_smooth_fac,
|
||||
.bound_scl = bsmooth > 0.0f ? ss->custom_layers[SCULPT_SCL_SMOOTH_BDIS] : NULL}));
|
||||
&((SculptSmoothArgs){.projection = 0.0f,
|
||||
.slide_fset = slide_fset, // 1.0f - hard_edge_fac,
|
||||
.bound_smooth = bsmooth,
|
||||
.preserve_fset_boundaries = preserve_fset_boundaries,
|
||||
.do_weighted_smooth = weighted,
|
||||
.bound_smooth_radius = bound_smooth_radius,
|
||||
.bevel_smooth_factor = bevel_smooth_fac,
|
||||
.bound_scl = bsmooth > 0.0f ? ss->scl.smooth_bdist : NULL}));
|
||||
|
||||
sub_v3_v3v3(val, avg, orig_co);
|
||||
madd_v3_v3v3fl(val, orig_co, val, fade);
|
||||
|
@ -903,7 +902,6 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||
ss->filter_cache->bevel_smooth_fac = RNA_float_get(op->ptr, "bevel_smooth_fac");
|
||||
|
||||
if (filter_type == MESH_FILTER_SMOOTH && ss->filter_cache->bound_smooth_radius != 0.0f) {
|
||||
/*ensure ss->custom_layers[SCULPT_SCL_SMOOTH_BDIS] exists*/
|
||||
SCULPT_bound_smooth_ensure(ss, ob);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -127,9 +127,9 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
SCULPT_ensure_persistent_layers(ss, ob);
|
||||
|
||||
scl_co = ss->custom_layers[SCULPT_SCL_PERS_CO];
|
||||
scl_no = ss->custom_layers[SCULPT_SCL_PERS_NO];
|
||||
scl_disp = ss->custom_layers[SCULPT_SCL_PERS_DISP];
|
||||
scl_co = ss->scl.persistent_co;
|
||||
scl_no = ss->scl.persistent_no;
|
||||
scl_disp = ss->scl.persistent_disp;
|
||||
|
||||
const int totvert = SCULPT_vertex_count_get(ss);
|
||||
|
||||
|
@ -376,7 +376,8 @@ static void sculpt_init_session(Main *bmain, Depsgraph *depsgraph, Scene *scene,
|
|||
BKE_sculptsession_free(ob);
|
||||
}
|
||||
|
||||
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
|
||||
BKE_object_sculpt_data_create(ob);
|
||||
|
||||
ob->sculpt->mode_type = OB_MODE_SCULPT;
|
||||
ob->sculpt->active_face_index.i = SCULPT_REF_NONE;
|
||||
ob->sculpt->active_vertex_index.i = SCULPT_REF_NONE;
|
||||
|
@ -1352,22 +1353,16 @@ static int sculpt_set_limit_surface_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
SCULPT_vertex_random_access_ensure(ss);
|
||||
|
||||
if (!ss->custom_layers[SCULPT_SCL_LIMIT_SURFACE]) {
|
||||
ss->custom_layers[SCULPT_SCL_LIMIT_SURFACE] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"SculptCustomLayer");
|
||||
}
|
||||
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = false};
|
||||
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LIMIT_SURFACE),
|
||||
ss->custom_layers[SCULPT_SCL_LIMIT_SURFACE],
|
||||
¶ms);
|
||||
ss->scl.limit_surface = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LIMIT_SURFACE),
|
||||
¶ms);
|
||||
|
||||
const SculptCustomLayer *scl = ss->custom_layers[SCULPT_SCL_LIMIT_SURFACE];
|
||||
const SculptCustomLayer *scl = ss->scl.limit_surface;
|
||||
|
||||
const int totvert = SCULPT_vertex_count_get(ss);
|
||||
const bool weighted = false;
|
||||
|
|
|
@ -410,32 +410,24 @@ void SCULPT_do_paint_brush(
|
|||
}
|
||||
}
|
||||
|
||||
SculptCustomLayer buffer_scl;
|
||||
SculptCustomLayer stroke_id_scl;
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = false};
|
||||
SculptLayerParams params_id = {
|
||||
.permanent = false, .simple_array = false, .nocopy = false, .nointerp = true};
|
||||
SculptCustomLayer *buffer_scl;
|
||||
SculptCustomLayer *stroke_id_scl;
|
||||
|
||||
// reuse smear's buffer name
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = false, .stroke_only = true};
|
||||
SculptLayerParams params_id = {.permanent = false,
|
||||
.simple_array = false,
|
||||
.nocopy = false,
|
||||
.nointerp = true,
|
||||
.stroke_only = true};
|
||||
|
||||
SCULPT_attr_ensure_layer(
|
||||
buffer_scl = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_COLOR, "_sculpt_smear_previous", ¶ms);
|
||||
SCULPT_attr_ensure_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_STROKE_ID),
|
||||
¶ms_id);
|
||||
|
||||
SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_COLOR, "_sculpt_smear_previous", &buffer_scl, ¶ms);
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_STROKE_ID),
|
||||
&stroke_id_scl,
|
||||
¶ms_id);
|
||||
stroke_id_scl = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_STROKE_ID),
|
||||
¶ms_id);
|
||||
|
||||
/* Threaded loop over nodes. */
|
||||
SculptThreadedTaskData data = {
|
||||
|
@ -446,8 +438,8 @@ void SCULPT_do_paint_brush(
|
|||
.wet_mix_sampled_color = wet_color,
|
||||
.mat = mat,
|
||||
.hue_offset = SCULPT_get_float(ss, hue_offset, sd, brush),
|
||||
.scl = &buffer_scl,
|
||||
.scl2 = &stroke_id_scl,
|
||||
.scl = buffer_scl,
|
||||
.scl2 = stroke_id_scl,
|
||||
.brush_color = brush_color,
|
||||
};
|
||||
|
||||
|
@ -639,20 +631,16 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
|
||||
SCULPT_vertex_random_access_ensure(ss);
|
||||
|
||||
SculptCustomLayer prev_scl;
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = false};
|
||||
|
||||
SCULPT_attr_ensure_layer(
|
||||
SculptCustomLayer *prev_scl = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_COLOR, "_sculpt_smear_previous", ¶ms);
|
||||
SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_COLOR, "_sculpt_smear_previous", &prev_scl, ¶ms);
|
||||
|
||||
BKE_curvemapping_init(brush->curve);
|
||||
|
||||
SculptThreadedTaskData data = {
|
||||
.sd = sd,
|
||||
.ob = ob,
|
||||
.scl = &prev_scl,
|
||||
.scl = prev_scl,
|
||||
.brush = brush,
|
||||
.nodes = nodes,
|
||||
};
|
||||
|
|
|
@ -1654,7 +1654,7 @@ void SCULPT_enhance_details_brush(
|
|||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptCustomLayer strokeid_scl;
|
||||
SculptCustomLayer *strokeid_scl;
|
||||
|
||||
bool use_area_weights = (ss->cache->brush->flag2 & BRUSH_SMOOTH_USE_AREA_WEIGHT);
|
||||
|
||||
|
@ -1680,28 +1680,18 @@ void SCULPT_enhance_details_brush(
|
|||
|
||||
SCULPT_boundary_info_ensure(ob);
|
||||
|
||||
SculptCustomLayer scl;
|
||||
SculptCustomLayer *scl;
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = false};
|
||||
bool weighted = SCULPT_get_int(ss, use_weighted_smooth, sd, brush);
|
||||
|
||||
SCULPT_attr_ensure_layer(
|
||||
scl = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, "__dyntopo_detail_dir", ¶ms);
|
||||
SCULPT_attr_ensure_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_STROKE_ID),
|
||||
¶ms);
|
||||
|
||||
SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, "__dyntopo_detail_dir", &scl, ¶ms);
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_STROKE_ID),
|
||||
&strokeid_scl,
|
||||
¶ms);
|
||||
strokeid_scl = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_INT32,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_LAYER_STROKE_ID),
|
||||
¶ms);
|
||||
|
||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||
SCULPT_vertex_random_access_ensure(ss);
|
||||
|
@ -1787,8 +1777,8 @@ void SCULPT_enhance_details_brush(
|
|||
.cd_temp = 0,
|
||||
.cd_temp2 = 0,
|
||||
.nodes = nodes,
|
||||
.scl = &scl,
|
||||
.scl2 = &strokeid_scl};
|
||||
.scl = scl,
|
||||
.scl2 = strokeid_scl};
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
|
@ -1997,17 +1987,13 @@ void SCULPT_bound_smooth_ensure(SculptSession *ss, Object *ob)
|
|||
{
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = false};
|
||||
|
||||
if (!ss->custom_layers[SCULPT_SCL_SMOOTH_BDIS]) {
|
||||
ss->custom_layers[SCULPT_SCL_SMOOTH_BDIS] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"bound_scl");
|
||||
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_COLOR,
|
||||
"t__smooth_bdist",
|
||||
ss->custom_layers[SCULPT_SCL_SMOOTH_BDIS],
|
||||
¶ms);
|
||||
if (!ss->scl.smooth_bdist) {
|
||||
ss->scl.smooth_bdist = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_COLOR,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_SMOOTH_BDIS),
|
||||
¶ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2048,19 +2034,13 @@ void SCULPT_smooth(Sculpt *sd,
|
|||
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = false};
|
||||
|
||||
if (do_vel_smooth) {
|
||||
if (!ss->custom_layers[SCULPT_SCL_SMOOTH_VEL]) {
|
||||
ss->custom_layers[SCULPT_SCL_SMOOTH_VEL] = MEM_callocN(sizeof(SculptCustomLayer),
|
||||
"vel_smooth_scl");
|
||||
|
||||
SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
"__scl_smooth_vel",
|
||||
ss->custom_layers[SCULPT_SCL_SMOOTH_VEL],
|
||||
¶ms);
|
||||
}
|
||||
if (do_vel_smooth && !ss->scl.smooth_vel) {
|
||||
ss->scl.smooth_vel = SCULPT_attr_get_layer(ss,
|
||||
ob,
|
||||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
SCULPT_SCL_GET_NAME(SCULPT_SCL_SMOOTH_VEL),
|
||||
¶ms);
|
||||
}
|
||||
|
||||
float bstrength2 = bstrength;
|
||||
|
@ -2103,7 +2083,6 @@ void SCULPT_smooth(Sculpt *sd,
|
|||
if (bound_smooth > 0.0f) {
|
||||
bound_smooth = powf(ss->cache->brush->boundary_smooth_factor, BOUNDARY_SMOOTH_EXP);
|
||||
|
||||
/* ensure ss->custom_layers[SCULPT_SCL_SMOOTH_BDIS] exists */
|
||||
SCULPT_bound_smooth_ensure(ss, ob);
|
||||
}
|
||||
|
||||
|
@ -2137,8 +2116,8 @@ void SCULPT_smooth(Sculpt *sd,
|
|||
.smooth_projection = projection,
|
||||
.fset_slide = fset_slide,
|
||||
.bound_smooth = bound_smooth,
|
||||
.scl = do_vel ? ss->custom_layers[SCULPT_SCL_SMOOTH_VEL] : NULL,
|
||||
.scl2 = bound_smooth > 0.0f ? ss->custom_layers[SCULPT_SCL_SMOOTH_BDIS] : NULL,
|
||||
.scl = do_vel ? ss->scl.smooth_vel : NULL,
|
||||
.scl2 = bound_smooth > 0.0f ? ss->scl.smooth_bdist : NULL,
|
||||
.vel_smooth_fac = vel_fac,
|
||||
.do_origco = do_origco,
|
||||
.iterations = count + 1,
|
||||
|
@ -2360,14 +2339,9 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
|
|||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
SculptCustomLayer scl;
|
||||
|
||||
SculptLayerParams params = {.permanent = false, .simple_array = false};
|
||||
|
||||
SCULPT_attr_ensure_layer(
|
||||
SculptCustomLayer *scl = SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, "__dyntopo_lapsmooth", ¶ms);
|
||||
SCULPT_attr_get_layer(
|
||||
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, "__dyntopo_lapsmooth", &scl, ¶ms);
|
||||
|
||||
if (SCULPT_stroke_is_first_brush_step(ss->cache) &&
|
||||
(ss->cache->brush->flag2 & BRUSH_SMOOTH_USE_AREA_WEIGHT)) {
|
||||
|
@ -2380,7 +2354,7 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
|
|||
.brush = brush,
|
||||
.nodes = nodes,
|
||||
.smooth_projection = brush->autosmooth_projection,
|
||||
.scl = &scl};
|
||||
.scl = scl};
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
#include "BKE_attribute.h"
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
#include "BKE_global.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_buffers.h"
|
||||
|
@ -1743,7 +1743,7 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(PBVHGPUFormat *vbo_id,
|
|||
}
|
||||
|
||||
if (have_uv) {
|
||||
for (int j = 0; j < cd_uv_count; j++) {
|
||||
for (int j = 0; j < vbo_id->totuv; j++) {
|
||||
MLoopUV *mu = BM_ELEM_CD_GET_VOID_P(l, cd_uvs[j].cd_offset);
|
||||
GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->uv[j], i, mu->uv);
|
||||
}
|
||||
|
@ -1994,7 +1994,7 @@ void GPU_pbvh_bmesh_buffers_update(PBVHGPUFormat *vbo_id, PBVHGPUBuildArgs *args
|
|||
cd_vcol_count);
|
||||
|
||||
if (have_uv) {
|
||||
for (int k = 0; k < cd_uv_count; k++) {
|
||||
for (int k = 0; k < vbo_id->totuv; k++) {
|
||||
MLoopUV *mu = BM_ELEM_CD_GET_VOID_P(l[j], cd_uvs[k].cd_offset);
|
||||
GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->uv[k], v_index, mu->uv);
|
||||
}
|
||||
|
@ -2057,7 +2057,7 @@ bool GPU_pbvh_attribute_names_update(PBVHType pbvh_type,
|
|||
&vbo_id->format, "msk", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
|
||||
vbo_id->totcol = 0;
|
||||
if (pbvh_type == PBVH_FACES) {
|
||||
if (ELEM(pbvh_type, PBVH_FACES, PBVH_BMESH)) {
|
||||
int ci = 0;
|
||||
|
||||
Mesh me_query;
|
||||
|
@ -2117,7 +2117,8 @@ bool GPU_pbvh_attribute_names_update(PBVHType pbvh_type,
|
|||
&vbo_id->format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
|
||||
vbo_id->totuv = 0;
|
||||
if (pbvh_type == PBVH_FACES && ldata && CustomData_has_layer(ldata, CD_MLOOPUV)) {
|
||||
if (ELEM(pbvh_type, PBVH_FACES, PBVH_BMESH) && ldata &&
|
||||
CustomData_has_layer(ldata, CD_MLOOPUV)) {
|
||||
GPUAttrRef uv_layers[MAX_GPU_ATTR];
|
||||
CustomDataLayer *active = NULL, *render = NULL;
|
||||
|
||||
|
|
|
@ -4108,7 +4108,7 @@ void *BPy_bm_new_customdata_layout_pre(BMesh *bm, CustomData *cdata, char htype)
|
|||
return ptrs;
|
||||
}
|
||||
|
||||
ATTR_NO_OPT void BPy_bm_new_customdata_layout(BMesh *bm, CustomData *cdata, void *state, char htype)
|
||||
void BPy_bm_new_customdata_layout(BMesh *bm, CustomData *cdata, void *state, char htype)
|
||||
{
|
||||
/*
|
||||
* Un-invalidate python pointers, which got invalidated when the customdata layout
|
||||
|
|
Loading…
Reference in New Issue