Cleanup: Sculpt: Use references for SculptSession variables
This commit is contained in:
parent
2079507ca5
commit
385cc4fb3b
@ -453,8 +453,8 @@ void multires_force_sculpt_rebuild(Object *object)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptSession *ss = object->sculpt;
|
SculptSession &ss = *object->sculpt;
|
||||||
bke::pbvh::free(ss->pbvh);
|
bke::pbvh::free(ss.pbvh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void multires_force_external_reload(Object *object)
|
void multires_force_external_reload(Object *object)
|
||||||
|
@ -1399,16 +1399,16 @@ void BKE_sculptsession_free_vwpaint_data(SculptSession *ss)
|
|||||||
*/
|
*/
|
||||||
static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
|
static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
|
||||||
{
|
{
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession &ss = *ob->sculpt;
|
||||||
|
|
||||||
if (ss->bm) {
|
if (ss.bm) {
|
||||||
if (ob->data) {
|
if (ob->data) {
|
||||||
if (reorder) {
|
if (reorder) {
|
||||||
BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
|
BM_log_mesh_elems_reorder(ss.bm, ss.bm_log);
|
||||||
}
|
}
|
||||||
BMeshToMeshParams params{};
|
BMeshToMeshParams params{};
|
||||||
params.calc_object_remap = false;
|
params.calc_object_remap = false;
|
||||||
BM_mesh_bm_to_me(nullptr, ss->bm, static_cast<Mesh *>(ob->data), ¶ms);
|
BM_mesh_bm_to_me(nullptr, ss.bm, static_cast<Mesh *>(ob->data), ¶ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1624,13 +1624,13 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
|
|||||||
*/
|
*/
|
||||||
static void sculpt_update_persistent_base(Object *ob)
|
static void sculpt_update_persistent_base(Object *ob)
|
||||||
{
|
{
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession &ss = *ob->sculpt;
|
||||||
|
|
||||||
ss->attrs.persistent_co = BKE_sculpt_attribute_get(
|
ss.attrs.persistent_co = BKE_sculpt_attribute_get(
|
||||||
ob, AttrDomain::Point, CD_PROP_FLOAT3, SCULPT_ATTRIBUTE_NAME(persistent_co));
|
ob, AttrDomain::Point, CD_PROP_FLOAT3, SCULPT_ATTRIBUTE_NAME(persistent_co));
|
||||||
ss->attrs.persistent_no = BKE_sculpt_attribute_get(
|
ss.attrs.persistent_no = BKE_sculpt_attribute_get(
|
||||||
ob, AttrDomain::Point, CD_PROP_FLOAT3, SCULPT_ATTRIBUTE_NAME(persistent_no));
|
ob, AttrDomain::Point, CD_PROP_FLOAT3, SCULPT_ATTRIBUTE_NAME(persistent_no));
|
||||||
ss->attrs.persistent_disp = BKE_sculpt_attribute_get(
|
ss.attrs.persistent_disp = BKE_sculpt_attribute_get(
|
||||||
ob, AttrDomain::Point, CD_PROP_FLOAT, SCULPT_ATTRIBUTE_NAME(persistent_disp));
|
ob, AttrDomain::Point, CD_PROP_FLOAT, SCULPT_ATTRIBUTE_NAME(persistent_disp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1641,7 +1641,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
|
|||||||
{
|
{
|
||||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||||
Sculpt *sd = scene->toolsettings->sculpt;
|
Sculpt *sd = scene->toolsettings->sculpt;
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession &ss = *ob->sculpt;
|
||||||
Mesh *mesh_orig = BKE_object_get_original_mesh(ob);
|
Mesh *mesh_orig = BKE_object_get_original_mesh(ob);
|
||||||
Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
|
Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
|
||||||
MultiresModifierData *mmd = sculpt_multires_modifier_get(scene, ob, true);
|
MultiresModifierData *mmd = sculpt_multires_modifier_get(scene, ob, true);
|
||||||
@ -1655,93 +1655,93 @@ static void sculpt_update_object(Depsgraph *depsgraph,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss->depsgraph = depsgraph;
|
ss.depsgraph = depsgraph;
|
||||||
|
|
||||||
ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob);
|
ss.deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob);
|
||||||
|
|
||||||
ss->building_vp_handle = false;
|
ss.building_vp_handle = false;
|
||||||
|
|
||||||
ss->scene = scene;
|
ss.scene = scene;
|
||||||
|
|
||||||
ss->shapekey_active = (mmd == nullptr) ? BKE_keyblock_from_object(ob) : nullptr;
|
ss.shapekey_active = (mmd == nullptr) ? BKE_keyblock_from_object(ob) : nullptr;
|
||||||
|
|
||||||
/* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
|
/* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
|
||||||
* so no extra checks is needed here. */
|
* so no extra checks is needed here. */
|
||||||
if (mmd) {
|
if (mmd) {
|
||||||
ss->multires.active = true;
|
ss.multires.active = true;
|
||||||
ss->multires.modifier = mmd;
|
ss.multires.modifier = mmd;
|
||||||
ss->multires.level = mmd->sculptlvl;
|
ss.multires.level = mmd->sculptlvl;
|
||||||
ss->totvert = mesh_eval->verts_num;
|
ss.totvert = mesh_eval->verts_num;
|
||||||
ss->faces_num = mesh_eval->faces_num;
|
ss.faces_num = mesh_eval->faces_num;
|
||||||
ss->totfaces = mesh_orig->faces_num;
|
ss.totfaces = mesh_orig->faces_num;
|
||||||
|
|
||||||
/* These are assigned to the base mesh in Multires. This is needed because Face Sets operators
|
/* These are assigned to the base mesh in Multires. This is needed because Face Sets operators
|
||||||
* and tools use the Face Sets data from the base mesh when Multires is active. */
|
* and tools use the Face Sets data from the base mesh when Multires is active. */
|
||||||
ss->vert_positions = mesh_orig->vert_positions_for_write();
|
ss.vert_positions = mesh_orig->vert_positions_for_write();
|
||||||
ss->faces = mesh_orig->faces();
|
ss.faces = mesh_orig->faces();
|
||||||
ss->corner_verts = mesh_orig->corner_verts();
|
ss.corner_verts = mesh_orig->corner_verts();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ss->totvert = mesh_orig->verts_num;
|
ss.totvert = mesh_orig->verts_num;
|
||||||
ss->faces_num = mesh_orig->faces_num;
|
ss.faces_num = mesh_orig->faces_num;
|
||||||
ss->totfaces = mesh_orig->faces_num;
|
ss.totfaces = mesh_orig->faces_num;
|
||||||
ss->vert_positions = mesh_orig->vert_positions_for_write();
|
ss.vert_positions = mesh_orig->vert_positions_for_write();
|
||||||
ss->faces = mesh_orig->faces();
|
ss.faces = mesh_orig->faces();
|
||||||
ss->corner_verts = mesh_orig->corner_verts();
|
ss.corner_verts = mesh_orig->corner_verts();
|
||||||
ss->multires.active = false;
|
ss.multires.active = false;
|
||||||
ss->multires.modifier = nullptr;
|
ss.multires.modifier = nullptr;
|
||||||
ss->multires.level = 0;
|
ss.multires.level = 0;
|
||||||
|
|
||||||
CustomDataLayer *layer;
|
CustomDataLayer *layer;
|
||||||
AttrDomain domain;
|
AttrDomain domain;
|
||||||
if (BKE_pbvh_get_color_layer(mesh_orig, &layer, &domain)) {
|
if (BKE_pbvh_get_color_layer(mesh_orig, &layer, &domain)) {
|
||||||
if (layer->type == CD_PROP_COLOR) {
|
if (layer->type == CD_PROP_COLOR) {
|
||||||
ss->vcol = static_cast<MPropCol *>(layer->data);
|
ss.vcol = static_cast<MPropCol *>(layer->data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ss->mcol = static_cast<MLoopCol *>(layer->data);
|
ss.mcol = static_cast<MLoopCol *>(layer->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ss->vcol_domain = domain;
|
ss.vcol_domain = domain;
|
||||||
ss->vcol_type = static_cast<eCustomDataType>(layer->type);
|
ss.vcol_type = static_cast<eCustomDataType>(layer->type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ss->vcol = nullptr;
|
ss.vcol = nullptr;
|
||||||
ss->mcol = nullptr;
|
ss.mcol = nullptr;
|
||||||
|
|
||||||
ss->vcol_type = (eCustomDataType)-1;
|
ss.vcol_type = (eCustomDataType)-1;
|
||||||
ss->vcol_domain = AttrDomain::Point;
|
ss.vcol_domain = AttrDomain::Point;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sculpt Face Sets. */
|
/* Sculpt Face Sets. */
|
||||||
if (use_face_sets) {
|
if (use_face_sets) {
|
||||||
ss->face_sets = static_cast<const int *>(
|
ss.face_sets = static_cast<const int *>(
|
||||||
CustomData_get_layer_named(&mesh_orig->face_data, CD_PROP_INT32, ".sculpt_face_set"));
|
CustomData_get_layer_named(&mesh_orig->face_data, CD_PROP_INT32, ".sculpt_face_set"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ss->face_sets = nullptr;
|
ss.face_sets = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss->hide_poly = (bool *)CustomData_get_layer_named(
|
ss.hide_poly = (bool *)CustomData_get_layer_named(
|
||||||
&mesh_orig->face_data, CD_PROP_BOOL, ".hide_poly");
|
&mesh_orig->face_data, CD_PROP_BOOL, ".hide_poly");
|
||||||
|
|
||||||
ss->subdiv_ccg = mesh_eval->runtime->subdiv_ccg.get();
|
ss.subdiv_ccg = mesh_eval->runtime->subdiv_ccg.get();
|
||||||
|
|
||||||
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
|
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
|
||||||
BLI_assert(pbvh == ss->pbvh.get());
|
BLI_assert(pbvh == ss.pbvh.get());
|
||||||
UNUSED_VARS_NDEBUG(pbvh);
|
UNUSED_VARS_NDEBUG(pbvh);
|
||||||
|
|
||||||
BKE_pbvh_subdiv_cgg_set(*ss->pbvh, ss->subdiv_ccg);
|
BKE_pbvh_subdiv_cgg_set(*ss.pbvh, ss.subdiv_ccg);
|
||||||
|
|
||||||
sculpt_attribute_update_refs(ob, BKE_pbvh_type(*ss->pbvh));
|
sculpt_attribute_update_refs(ob, BKE_pbvh_type(*ss.pbvh));
|
||||||
sculpt_update_persistent_base(ob);
|
sculpt_update_persistent_base(ob);
|
||||||
|
|
||||||
if (ob->type == OB_MESH) {
|
if (ob->type == OB_MESH) {
|
||||||
ss->vert_to_face_map = mesh_orig->vert_to_face_map();
|
ss.vert_to_face_map = mesh_orig->vert_to_face_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss->deform_modifiers_active) {
|
if (ss.deform_modifiers_active) {
|
||||||
/* Painting doesn't need crazyspace, use already evaluated mesh coordinates if possible. */
|
/* Painting doesn't need crazyspace, use already evaluated mesh coordinates if possible. */
|
||||||
bool used_me_eval = false;
|
bool used_me_eval = false;
|
||||||
|
|
||||||
@ -1755,67 +1755,67 @@ static void sculpt_update_object(Depsgraph *depsgraph,
|
|||||||
me_eval_deform->corners_num == mesh_eval->corners_num &&
|
me_eval_deform->corners_num == mesh_eval->corners_num &&
|
||||||
me_eval_deform->verts_num == mesh_eval->verts_num)
|
me_eval_deform->verts_num == mesh_eval->verts_num)
|
||||||
{
|
{
|
||||||
BKE_sculptsession_free_deformMats(ss);
|
BKE_sculptsession_free_deformMats(&ss);
|
||||||
|
|
||||||
BLI_assert(me_eval_deform->verts_num == mesh_orig->verts_num);
|
BLI_assert(me_eval_deform->verts_num == mesh_orig->verts_num);
|
||||||
|
|
||||||
ss->deform_cos = mesh_eval->vert_positions();
|
ss.deform_cos = mesh_eval->vert_positions();
|
||||||
BKE_pbvh_vert_coords_apply(*ss->pbvh, ss->deform_cos);
|
BKE_pbvh_vert_coords_apply(*ss.pbvh, ss.deform_cos);
|
||||||
|
|
||||||
used_me_eval = true;
|
used_me_eval = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss->orig_cos.is_empty() && !used_me_eval) {
|
if (ss.orig_cos.is_empty() && !used_me_eval) {
|
||||||
BKE_sculptsession_free_deformMats(ss);
|
BKE_sculptsession_free_deformMats(&ss);
|
||||||
|
|
||||||
ss->orig_cos = (ss->shapekey_active) ?
|
ss.orig_cos = (ss.shapekey_active) ?
|
||||||
Span(static_cast<const float3 *>(ss->shapekey_active->data),
|
Span(static_cast<const float3 *>(ss.shapekey_active->data),
|
||||||
mesh_orig->verts_num) :
|
mesh_orig->verts_num) :
|
||||||
mesh_orig->vert_positions();
|
mesh_orig->vert_positions();
|
||||||
|
|
||||||
BKE_crazyspace_build_sculpt(depsgraph, scene, ob, ss->deform_imats, ss->deform_cos);
|
BKE_crazyspace_build_sculpt(depsgraph, scene, ob, ss.deform_imats, ss.deform_cos);
|
||||||
BKE_pbvh_vert_coords_apply(*ss->pbvh, ss->deform_cos);
|
BKE_pbvh_vert_coords_apply(*ss.pbvh, ss.deform_cos);
|
||||||
|
|
||||||
for (blender::float3x3 &matrix : ss->deform_imats) {
|
for (blender::float3x3 &matrix : ss.deform_imats) {
|
||||||
matrix = blender::math::invert(matrix);
|
matrix = blender::math::invert(matrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_sculptsession_free_deformMats(ss);
|
BKE_sculptsession_free_deformMats(&ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss->shapekey_active != nullptr && ss->deform_cos.is_empty()) {
|
if (ss.shapekey_active != nullptr && ss.deform_cos.is_empty()) {
|
||||||
ss->deform_cos = Span(static_cast<const float3 *>(ss->shapekey_active->data),
|
ss.deform_cos = Span(static_cast<const float3 *>(ss.shapekey_active->data),
|
||||||
mesh_orig->verts_num);
|
mesh_orig->verts_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if pbvh is deformed, key block is already applied to it */
|
/* if pbvh is deformed, key block is already applied to it */
|
||||||
if (ss->shapekey_active) {
|
if (ss.shapekey_active) {
|
||||||
bool pbvh_deformed = BKE_pbvh_is_deformed(*ss->pbvh);
|
bool pbvh_deformed = BKE_pbvh_is_deformed(*ss.pbvh);
|
||||||
if (!pbvh_deformed || ss->deform_cos.is_empty()) {
|
if (!pbvh_deformed || ss.deform_cos.is_empty()) {
|
||||||
const Span key_data(static_cast<const float3 *>(ss->shapekey_active->data),
|
const Span key_data(static_cast<const float3 *>(ss.shapekey_active->data),
|
||||||
mesh_orig->verts_num);
|
mesh_orig->verts_num);
|
||||||
|
|
||||||
if (key_data.data() != nullptr) {
|
if (key_data.data() != nullptr) {
|
||||||
if (!pbvh_deformed) {
|
if (!pbvh_deformed) {
|
||||||
/* apply shape keys coordinates to PBVH */
|
/* apply shape keys coordinates to PBVH */
|
||||||
BKE_pbvh_vert_coords_apply(*ss->pbvh, key_data);
|
BKE_pbvh_vert_coords_apply(*ss.pbvh, key_data);
|
||||||
}
|
}
|
||||||
if (ss->deform_cos.is_empty()) {
|
if (ss.deform_cos.is_empty()) {
|
||||||
ss->deform_cos = key_data;
|
ss.deform_cos = key_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_paint_tool) {
|
if (is_paint_tool) {
|
||||||
if (ss->vcol_domain == AttrDomain::Corner) {
|
if (ss.vcol_domain == AttrDomain::Corner) {
|
||||||
/* Ensure pbvh nodes have loop indices; the sculpt undo system
|
/* Ensure pbvh nodes have loop indices; the sculpt undo system
|
||||||
* needs them for color attributes.
|
* needs them for color attributes.
|
||||||
*/
|
*/
|
||||||
BKE_pbvh_ensure_node_loops(*ss->pbvh);
|
BKE_pbvh_ensure_node_loops(*ss.pbvh);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1824,14 +1824,14 @@ static void sculpt_update_object(Depsgraph *depsgraph,
|
|||||||
* The relevant changes are stored/encoded in the paint canvas key.
|
* The relevant changes are stored/encoded in the paint canvas key.
|
||||||
* These include the active uv map, and resolutions.
|
* These include the active uv map, and resolutions.
|
||||||
*/
|
*/
|
||||||
if (U.experimental.use_sculpt_texture_paint && ss->pbvh) {
|
if (U.experimental.use_sculpt_texture_paint && ss.pbvh) {
|
||||||
char *paint_canvas_key = BKE_paint_canvas_key_get(&scene->toolsettings->paint_mode, ob);
|
char *paint_canvas_key = BKE_paint_canvas_key_get(&scene->toolsettings->paint_mode, ob);
|
||||||
if (ss->last_paint_canvas_key == nullptr ||
|
if (ss.last_paint_canvas_key == nullptr ||
|
||||||
!STREQ(paint_canvas_key, ss->last_paint_canvas_key))
|
!STREQ(paint_canvas_key, ss.last_paint_canvas_key))
|
||||||
{
|
{
|
||||||
MEM_SAFE_FREE(ss->last_paint_canvas_key);
|
MEM_SAFE_FREE(ss.last_paint_canvas_key);
|
||||||
ss->last_paint_canvas_key = paint_canvas_key;
|
ss.last_paint_canvas_key = paint_canvas_key;
|
||||||
BKE_pbvh_mark_rebuild_pixels(*ss->pbvh);
|
BKE_pbvh_mark_rebuild_pixels(*ss.pbvh);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MEM_freeN(paint_canvas_key);
|
MEM_freeN(paint_canvas_key);
|
||||||
@ -2257,14 +2257,14 @@ int BKE_sculptsession_vertex_count(const SculptSession *ss)
|
|||||||
*/
|
*/
|
||||||
static CustomData *sculpt_get_cdata(Object *ob, AttrDomain domain)
|
static CustomData *sculpt_get_cdata(Object *ob, AttrDomain domain)
|
||||||
{
|
{
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession &ss = *ob->sculpt;
|
||||||
|
|
||||||
if (ss->bm) {
|
if (ss.bm) {
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case AttrDomain::Point:
|
case AttrDomain::Point:
|
||||||
return &ss->bm->vdata;
|
return &ss.bm->vdata;
|
||||||
case AttrDomain::Face:
|
case AttrDomain::Face:
|
||||||
return &ss->bm->pdata;
|
return &ss.bm->pdata;
|
||||||
default:
|
default:
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -2276,7 +2276,7 @@ static CustomData *sculpt_get_cdata(Object *ob, AttrDomain domain)
|
|||||||
switch (domain) {
|
switch (domain) {
|
||||||
case AttrDomain::Point:
|
case AttrDomain::Point:
|
||||||
/* Cannot get vertex domain for multires grids. */
|
/* Cannot get vertex domain for multires grids. */
|
||||||
if (ss->pbvh && BKE_pbvh_type(*ss->pbvh) == PBVH_GRIDS) {
|
if (ss.pbvh && BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2292,14 +2292,14 @@ static CustomData *sculpt_get_cdata(Object *ob, AttrDomain domain)
|
|||||||
|
|
||||||
static int sculpt_attr_elem_count_get(Object *ob, AttrDomain domain)
|
static int sculpt_attr_elem_count_get(Object *ob, AttrDomain domain)
|
||||||
{
|
{
|
||||||
SculptSession *ss = ob->sculpt;
|
const SculptSession &ss = *ob->sculpt;
|
||||||
|
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case AttrDomain::Point:
|
case AttrDomain::Point:
|
||||||
return BKE_sculptsession_vertex_count(ss);
|
return BKE_sculptsession_vertex_count(&ss);
|
||||||
break;
|
break;
|
||||||
case AttrDomain::Face:
|
case AttrDomain::Face:
|
||||||
return ss->totfaces;
|
return ss.totfaces;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
|
@ -73,7 +73,7 @@ void triangulate(BMesh *bm)
|
|||||||
|
|
||||||
void enable_ex(Main &bmain, Depsgraph &depsgraph, Object &ob)
|
void enable_ex(Main &bmain, Depsgraph &depsgraph, Object &ob)
|
||||||
{
|
{
|
||||||
SculptSession *ss = ob.sculpt;
|
SculptSession &ss = *ob.sculpt;
|
||||||
Mesh *mesh = static_cast<Mesh *>(ob.data);
|
Mesh *mesh = static_cast<Mesh *>(ob.data);
|
||||||
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
|
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
|
||||||
|
|
||||||
@ -85,28 +85,28 @@ void enable_ex(Main &bmain, Depsgraph &depsgraph, Object &ob)
|
|||||||
/* Create triangles-only BMesh. */
|
/* Create triangles-only BMesh. */
|
||||||
BMeshCreateParams create_params{};
|
BMeshCreateParams create_params{};
|
||||||
create_params.use_toolflags = false;
|
create_params.use_toolflags = false;
|
||||||
ss->bm = BM_mesh_create(&allocsize, &create_params);
|
ss.bm = BM_mesh_create(&allocsize, &create_params);
|
||||||
|
|
||||||
BMeshFromMeshParams convert_params{};
|
BMeshFromMeshParams convert_params{};
|
||||||
convert_params.calc_face_normal = true;
|
convert_params.calc_face_normal = true;
|
||||||
convert_params.calc_vert_normal = true;
|
convert_params.calc_vert_normal = true;
|
||||||
convert_params.use_shapekey = true;
|
convert_params.use_shapekey = true;
|
||||||
convert_params.active_shapekey = ob.shapenr;
|
convert_params.active_shapekey = ob.shapenr;
|
||||||
BM_mesh_bm_from_me(ss->bm, mesh, &convert_params);
|
BM_mesh_bm_from_me(ss.bm, mesh, &convert_params);
|
||||||
triangulate(ss->bm);
|
triangulate(ss.bm);
|
||||||
|
|
||||||
BM_data_layer_ensure_named(ss->bm, &ss->bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
|
BM_data_layer_ensure_named(ss.bm, &ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
|
||||||
|
|
||||||
/* Make sure the data for existing faces are initialized. */
|
/* Make sure the data for existing faces are initialized. */
|
||||||
if (mesh->faces_num != ss->bm->totface) {
|
if (mesh->faces_num != ss.bm->totface) {
|
||||||
BM_mesh_normals_update(ss->bm);
|
BM_mesh_normals_update(ss.bm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable dynamic topology. */
|
/* Enable dynamic topology. */
|
||||||
mesh->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
|
mesh->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
|
||||||
|
|
||||||
/* Enable logging for undo/redo. */
|
/* Enable logging for undo/redo. */
|
||||||
ss->bm_log = BM_log_create(ss->bm);
|
ss.bm_log = BM_log_create(ss.bm);
|
||||||
|
|
||||||
/* Update dependency graph, so modifiers that depend on dyntopo being enabled
|
/* Update dependency graph, so modifiers that depend on dyntopo being enabled
|
||||||
* are re-evaluated and the PBVH is re-created. */
|
* are re-evaluated and the PBVH is re-created. */
|
||||||
|
@ -321,7 +321,7 @@ static void flip_for_symmetry_pass(GestureData &gesture_data, const ePaintSymmet
|
|||||||
|
|
||||||
static Vector<PBVHNode *> update_affected_nodes_by_line_plane(GestureData &gesture_data)
|
static Vector<PBVHNode *> update_affected_nodes_by_line_plane(GestureData &gesture_data)
|
||||||
{
|
{
|
||||||
SculptSession *ss = gesture_data.ss;
|
SculptSession &ss = *gesture_data.ss;
|
||||||
float clip_planes[3][4];
|
float clip_planes[3][4];
|
||||||
copy_v4_v4(clip_planes[0], gesture_data.line.plane);
|
copy_v4_v4(clip_planes[0], gesture_data.line.plane);
|
||||||
copy_v4_v4(clip_planes[1], gesture_data.line.side_plane[0]);
|
copy_v4_v4(clip_planes[1], gesture_data.line.side_plane[0]);
|
||||||
@ -331,14 +331,14 @@ static Vector<PBVHNode *> update_affected_nodes_by_line_plane(GestureData &gestu
|
|||||||
frustum.planes = clip_planes;
|
frustum.planes = clip_planes;
|
||||||
frustum.num_planes = gesture_data.line.use_side_planes ? 3 : 1;
|
frustum.num_planes = gesture_data.line.use_side_planes ? 3 : 1;
|
||||||
|
|
||||||
return gesture_data.nodes = bke::pbvh::search_gather(*ss->pbvh, [&](PBVHNode &node) {
|
return gesture_data.nodes = bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
|
||||||
return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum);
|
return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_affected_nodes_by_clip_planes(GestureData &gesture_data)
|
static void update_affected_nodes_by_clip_planes(GestureData &gesture_data)
|
||||||
{
|
{
|
||||||
SculptSession *ss = gesture_data.ss;
|
SculptSession &ss = *gesture_data.ss;
|
||||||
float clip_planes[4][4];
|
float clip_planes[4][4];
|
||||||
copy_m4_m4(clip_planes, gesture_data.clip_planes);
|
copy_m4_m4(clip_planes, gesture_data.clip_planes);
|
||||||
negate_m4(clip_planes);
|
negate_m4(clip_planes);
|
||||||
@ -347,7 +347,7 @@ static void update_affected_nodes_by_clip_planes(GestureData &gesture_data)
|
|||||||
frustum.planes = clip_planes;
|
frustum.planes = clip_planes;
|
||||||
frustum.num_planes = 4;
|
frustum.num_planes = 4;
|
||||||
|
|
||||||
gesture_data.nodes = bke::pbvh::search_gather(*ss->pbvh, [&](PBVHNode &node) {
|
gesture_data.nodes = bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
|
||||||
switch (gesture_data.selection_type) {
|
switch (gesture_data.selection_type) {
|
||||||
case SelectionType::Inside:
|
case SelectionType::Inside:
|
||||||
return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum);
|
return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum);
|
||||||
|
@ -85,9 +85,9 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa
|
|||||||
|
|
||||||
static void gesture_end(bContext &C, gesture::GestureData &gesture_data)
|
static void gesture_end(bContext &C, gesture::GestureData &gesture_data)
|
||||||
{
|
{
|
||||||
SculptSession *ss = gesture_data.ss;
|
SculptSession &ss = *gesture_data.ss;
|
||||||
const Sculpt &sd = *CTX_data_tool_settings(&C)->sculpt;
|
const Sculpt &sd = *CTX_data_tool_settings(&C)->sculpt;
|
||||||
if (ss->deform_modifiers_active || ss->shapekey_active) {
|
if (ss.deform_modifiers_active || ss.shapekey_active) {
|
||||||
SCULPT_flush_stroke_deform(sd, *gesture_data.vc.obact, true);
|
SCULPT_flush_stroke_deform(sd, *gesture_data.vc.obact, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,10 +438,10 @@ static bool test_swap_v3_v3(float3 &a, float3 &b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool restore_deformed(
|
static bool restore_deformed(
|
||||||
const SculptSession *ss, Node &unode, int uindex, int oindex, float3 &coord)
|
const SculptSession &ss, Node &unode, int uindex, int oindex, float3 &coord)
|
||||||
{
|
{
|
||||||
if (test_swap_v3_v3(coord, unode.orig_position[uindex])) {
|
if (test_swap_v3_v3(coord, unode.orig_position[uindex])) {
|
||||||
copy_v3_v3(unode.position[uindex], ss->deform_cos[oindex]);
|
copy_v3_v3(unode.position[uindex], ss.deform_cos[oindex]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -454,13 +454,13 @@ static bool restore_coords(bContext *C,
|
|||||||
Node &unode,
|
Node &unode,
|
||||||
MutableSpan<bool> modified_verts)
|
MutableSpan<bool> modified_verts)
|
||||||
{
|
{
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
|
SubdivCCG *subdiv_ccg = ss.subdiv_ccg;
|
||||||
|
|
||||||
if (unode.mesh_verts_num) {
|
if (unode.mesh_verts_num) {
|
||||||
/* Regular mesh restore. */
|
/* Regular mesh restore. */
|
||||||
|
|
||||||
if (ss->shapekey_active && ss->shapekey_active->name != step_data.active_shape_key_name) {
|
if (ss.shapekey_active && ss.shapekey_active->name != step_data.active_shape_key_name) {
|
||||||
/* Shape key has been changed before calling undo operator. */
|
/* Shape key has been changed before calling undo operator. */
|
||||||
|
|
||||||
Key *key = BKE_key_from_object(&object);
|
Key *key = BKE_key_from_object(&object);
|
||||||
@ -481,14 +481,14 @@ static bool restore_coords(bContext *C,
|
|||||||
|
|
||||||
/* No need for float comparison here (memory is exactly equal or not). */
|
/* No need for float comparison here (memory is exactly equal or not). */
|
||||||
const Span<int> index = unode.vert_indices.as_span().take_front(unode.unique_verts_num);
|
const Span<int> index = unode.vert_indices.as_span().take_front(unode.unique_verts_num);
|
||||||
MutableSpan<float3> positions = ss->vert_positions;
|
MutableSpan<float3> positions = ss.vert_positions;
|
||||||
|
|
||||||
if (ss->shapekey_active) {
|
if (ss.shapekey_active) {
|
||||||
float(*vertCos)[3] = BKE_keyblock_convert_to_vertcos(&object, ss->shapekey_active);
|
float(*vertCos)[3] = BKE_keyblock_convert_to_vertcos(&object, ss.shapekey_active);
|
||||||
MutableSpan key_positions(reinterpret_cast<float3 *>(vertCos), ss->shapekey_active->totelem);
|
MutableSpan key_positions(reinterpret_cast<float3 *>(vertCos), ss.shapekey_active->totelem);
|
||||||
|
|
||||||
if (!unode.orig_position.is_empty()) {
|
if (!unode.orig_position.is_empty()) {
|
||||||
if (ss->deform_modifiers_active) {
|
if (ss.deform_modifiers_active) {
|
||||||
for (const int i : index.index_range()) {
|
for (const int i : index.index_range()) {
|
||||||
restore_deformed(ss, unode, i, index[i], key_positions[index[i]]);
|
restore_deformed(ss, unode, i, index[i], key_positions[index[i]]);
|
||||||
}
|
}
|
||||||
@ -506,17 +506,17 @@ static bool restore_coords(bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Propagate new coords to keyblock. */
|
/* Propagate new coords to keyblock. */
|
||||||
SCULPT_vertcos_to_key(object, ss->shapekey_active, key_positions);
|
SCULPT_vertcos_to_key(object, ss.shapekey_active, key_positions);
|
||||||
|
|
||||||
/* PBVH uses its own vertex array, so coords should be */
|
/* PBVH uses its own vertex array, so coords should be */
|
||||||
/* propagated to PBVH here. */
|
/* propagated to PBVH here. */
|
||||||
BKE_pbvh_vert_coords_apply(*ss->pbvh, key_positions);
|
BKE_pbvh_vert_coords_apply(*ss.pbvh, key_positions);
|
||||||
|
|
||||||
MEM_freeN(vertCos);
|
MEM_freeN(vertCos);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!unode.orig_position.is_empty()) {
|
if (!unode.orig_position.is_empty()) {
|
||||||
if (ss->deform_modifiers_active) {
|
if (ss.deform_modifiers_active) {
|
||||||
for (const int i : index.index_range()) {
|
for (const int i : index.index_range()) {
|
||||||
restore_deformed(ss, unode, i, index[i], positions[index[i]]);
|
restore_deformed(ss, unode, i, index[i], positions[index[i]]);
|
||||||
modified_verts[index[i]] = true;
|
modified_verts[index[i]] = true;
|
||||||
@ -559,8 +559,8 @@ static bool restore_coords(bContext *C,
|
|||||||
|
|
||||||
static bool restore_hidden(Object &object, Node &unode, MutableSpan<bool> modified_vertices)
|
static bool restore_hidden(Object &object, Node &unode, MutableSpan<bool> modified_vertices)
|
||||||
{
|
{
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
|
SubdivCCG *subdiv_ccg = ss.subdiv_ccg;
|
||||||
|
|
||||||
if (unode.mesh_verts_num) {
|
if (unode.mesh_verts_num) {
|
||||||
Mesh &mesh = *static_cast<Mesh *>(object.data);
|
Mesh &mesh = *static_cast<Mesh *>(object.data);
|
||||||
@ -628,7 +628,7 @@ static bool restore_hidden_face(Object &object, Node &unode, MutableSpan<bool> m
|
|||||||
static bool restore_color(Object &object, Node &unode, MutableSpan<bool> modified_vertices)
|
static bool restore_color(Object &object, Node &unode, MutableSpan<bool> modified_vertices)
|
||||||
{
|
{
|
||||||
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
|
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
@ -636,12 +636,12 @@ static bool restore_color(Object &object, Node &unode, MutableSpan<bool> modifie
|
|||||||
* vertex colors for original data lookup. */
|
* vertex colors for original data lookup. */
|
||||||
if (!unode.col.is_empty() && unode.loop_col.is_empty()) {
|
if (!unode.col.is_empty() && unode.loop_col.is_empty()) {
|
||||||
BKE_pbvh_swap_colors(
|
BKE_pbvh_swap_colors(
|
||||||
*ss->pbvh, unode.vert_indices.as_span().take_front(unode.unique_verts_num), unode.col);
|
*ss.pbvh, unode.vert_indices.as_span().take_front(unode.unique_verts_num), unode.col);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unode.loop_col.is_empty() && unode.mesh_corners_num == mesh.corners_num) {
|
if (!unode.loop_col.is_empty() && unode.mesh_corners_num == mesh.corners_num) {
|
||||||
BKE_pbvh_swap_colors(*ss->pbvh, unode.corner_indices, unode.loop_col);
|
BKE_pbvh_swap_colors(*ss.pbvh, unode.corner_indices, unode.loop_col);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,8 +655,8 @@ static bool restore_color(Object &object, Node &unode, MutableSpan<bool> modifie
|
|||||||
static bool restore_mask(Object &object, Node &unode, MutableSpan<bool> modified_vertices)
|
static bool restore_mask(Object &object, Node &unode, MutableSpan<bool> modified_vertices)
|
||||||
{
|
{
|
||||||
Mesh *mesh = BKE_object_get_original_mesh(&object);
|
Mesh *mesh = BKE_object_get_original_mesh(&object);
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
|
SubdivCCG *subdiv_ccg = ss.subdiv_ccg;
|
||||||
|
|
||||||
if (unode.mesh_verts_num) {
|
if (unode.mesh_verts_num) {
|
||||||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||||
@ -715,19 +715,19 @@ static bool restore_face_sets(Object &object,
|
|||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bmesh_restore_generic(Node &unode, Object &object, SculptSession *ss)
|
static void bmesh_restore_generic(Node &unode, Object &object, SculptSession &ss)
|
||||||
{
|
{
|
||||||
if (unode.applied) {
|
if (unode.applied) {
|
||||||
BM_log_undo(ss->bm, ss->bm_log);
|
BM_log_undo(ss.bm, ss.bm_log);
|
||||||
unode.applied = false;
|
unode.applied = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BM_log_redo(ss->bm, ss->bm_log);
|
BM_log_redo(ss.bm, ss.bm_log);
|
||||||
unode.applied = true;
|
unode.applied = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unode.type == Type::Mask) {
|
if (unode.type == Type::Mask) {
|
||||||
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss->pbvh, {});
|
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
|
||||||
for (PBVHNode *node : nodes) {
|
for (PBVHNode *node : nodes) {
|
||||||
BKE_pbvh_node_mark_redraw(node);
|
BKE_pbvh_node_mark_redraw(node);
|
||||||
}
|
}
|
||||||
@ -740,7 +740,7 @@ static void bmesh_restore_generic(Node &unode, Object &object, SculptSession *ss
|
|||||||
/* Create empty sculpt BMesh and enable logging. */
|
/* Create empty sculpt BMesh and enable logging. */
|
||||||
static void bmesh_enable(Object &object, Node &unode)
|
static void bmesh_enable(Object &object, Node &unode)
|
||||||
{
|
{
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
Mesh *mesh = static_cast<Mesh *>(object.data);
|
Mesh *mesh = static_cast<Mesh *>(object.data);
|
||||||
|
|
||||||
SCULPT_pbvh_clear(object);
|
SCULPT_pbvh_clear(object);
|
||||||
@ -749,16 +749,16 @@ static void bmesh_enable(Object &object, Node &unode)
|
|||||||
BMeshCreateParams bmesh_create_params{};
|
BMeshCreateParams bmesh_create_params{};
|
||||||
bmesh_create_params.use_toolflags = false;
|
bmesh_create_params.use_toolflags = false;
|
||||||
|
|
||||||
ss->bm = BM_mesh_create(&bm_mesh_allocsize_default, &bmesh_create_params);
|
ss.bm = BM_mesh_create(&bm_mesh_allocsize_default, &bmesh_create_params);
|
||||||
BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
|
BM_data_layer_add_named(ss.bm, &ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
|
||||||
|
|
||||||
mesh->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
|
mesh->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
|
||||||
|
|
||||||
/* Restore the BMLog using saved entries. */
|
/* Restore the BMLog using saved entries. */
|
||||||
ss->bm_log = BM_log_from_existing_entries_create(ss->bm, unode.bm_entry);
|
ss.bm_log = BM_log_from_existing_entries_create(ss.bm, unode.bm_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bmesh_restore_begin(bContext *C, Node &unode, Object &object, SculptSession *ss)
|
static void bmesh_restore_begin(bContext *C, Node &unode, Object &object, SculptSession &ss)
|
||||||
{
|
{
|
||||||
if (unode.applied) {
|
if (unode.applied) {
|
||||||
dyntopo::disable(C, &unode);
|
dyntopo::disable(C, &unode);
|
||||||
@ -768,19 +768,19 @@ static void bmesh_restore_begin(bContext *C, Node &unode, Object &object, Sculpt
|
|||||||
bmesh_enable(object, unode);
|
bmesh_enable(object, unode);
|
||||||
|
|
||||||
/* Restore the mesh from the first log entry. */
|
/* Restore the mesh from the first log entry. */
|
||||||
BM_log_redo(ss->bm, ss->bm_log);
|
BM_log_redo(ss.bm, ss.bm_log);
|
||||||
|
|
||||||
unode.applied = true;
|
unode.applied = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bmesh_restore_end(bContext *C, Node &unode, Object &object, SculptSession *ss)
|
static void bmesh_restore_end(bContext *C, Node &unode, Object &object, SculptSession &ss)
|
||||||
{
|
{
|
||||||
if (unode.applied) {
|
if (unode.applied) {
|
||||||
bmesh_enable(object, unode);
|
bmesh_enable(object, unode);
|
||||||
|
|
||||||
/* Restore the mesh from the last log entry. */
|
/* Restore the mesh from the last log entry. */
|
||||||
BM_log_undo(ss->bm, ss->bm_log);
|
BM_log_undo(ss.bm, ss.bm_log);
|
||||||
|
|
||||||
unode.applied = false;
|
unode.applied = false;
|
||||||
}
|
}
|
||||||
@ -869,7 +869,7 @@ static void restore_geometry(Node &unode, Object &object)
|
|||||||
*
|
*
|
||||||
* Returns true if this was a dynamic-topology undo step, otherwise
|
* Returns true if this was a dynamic-topology undo step, otherwise
|
||||||
* returns false to indicate the non-dyntopo code should run. */
|
* returns false to indicate the non-dyntopo code should run. */
|
||||||
static int bmesh_restore(bContext *C, Node &unode, Object &object, SculptSession *ss)
|
static int bmesh_restore(bContext *C, Node &unode, Object &object, SculptSession &ss)
|
||||||
{
|
{
|
||||||
switch (unode.type) {
|
switch (unode.type) {
|
||||||
case Type::DyntopoBegin:
|
case Type::DyntopoBegin:
|
||||||
@ -880,7 +880,7 @@ static int bmesh_restore(bContext *C, Node &unode, Object &object, SculptSession
|
|||||||
bmesh_restore_end(C, unode, object, ss);
|
bmesh_restore_end(C, unode, object, ss);
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
if (ss->bm_log) {
|
if (ss.bm_log) {
|
||||||
bmesh_restore_generic(unode, object, ss);
|
bmesh_restore_generic(unode, object, ss);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -904,12 +904,12 @@ static int bmesh_restore(bContext *C, Node &unode, Object &object, SculptSession
|
|||||||
* Note that the dependency graph is ensured to be evaluated prior to the undo step is decoded,
|
* Note that the dependency graph is ensured to be evaluated prior to the undo step is decoded,
|
||||||
* so if the object's modifier stack references other object it is all fine. */
|
* so if the object's modifier stack references other object it is all fine. */
|
||||||
static void refine_subdiv(Depsgraph *depsgraph,
|
static void refine_subdiv(Depsgraph *depsgraph,
|
||||||
SculptSession *ss,
|
SculptSession &ss,
|
||||||
Object &object,
|
Object &object,
|
||||||
bke::subdiv::Subdiv *subdiv)
|
bke::subdiv::Subdiv *subdiv)
|
||||||
{
|
{
|
||||||
Array<float3> deformed_verts = BKE_multires_create_deformed_base_mesh_vert_coords(
|
Array<float3> deformed_verts = BKE_multires_create_deformed_base_mesh_vert_coords(
|
||||||
depsgraph, &object, ss->multires.modifier);
|
depsgraph, &object, ss.multires.modifier);
|
||||||
|
|
||||||
bke::subdiv::eval_refine_from_mesh(subdiv,
|
bke::subdiv::eval_refine_from_mesh(subdiv,
|
||||||
static_cast<const Mesh *>(object.data),
|
static_cast<const Mesh *>(object.data),
|
||||||
@ -927,12 +927,12 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Mesh &mesh = *static_cast<Mesh *>(object.data);
|
Mesh &mesh = *static_cast<Mesh *>(object.data);
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
|
SubdivCCG *subdiv_ccg = ss.subdiv_ccg;
|
||||||
|
|
||||||
/* Restore pivot. */
|
/* Restore pivot. */
|
||||||
ss->pivot_pos = step_data.pivot_pos;
|
ss.pivot_pos = step_data.pivot_pos;
|
||||||
ss->pivot_rot = step_data.pivot_rot;
|
ss.pivot_rot = step_data.pivot_rot;
|
||||||
|
|
||||||
bool clear_automask_cache = false;
|
bool clear_automask_cache = false;
|
||||||
for (const std::unique_ptr<Node> &unode : step_data.nodes) {
|
for (const std::unique_ptr<Node> &unode : step_data.nodes) {
|
||||||
@ -942,7 +942,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clear_automask_cache) {
|
if (clear_automask_cache) {
|
||||||
ss->last_automasking_settings_hash = 0;
|
ss.last_automasking_settings_hash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!step_data.nodes.is_empty()) {
|
if (!step_data.nodes.is_empty()) {
|
||||||
@ -982,7 +982,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
|||||||
for (std::unique_ptr<Node> &unode : step_data.nodes) {
|
for (std::unique_ptr<Node> &unode : step_data.nodes) {
|
||||||
/* Check if undo data matches current data well enough to continue. */
|
/* Check if undo data matches current data well enough to continue. */
|
||||||
if (unode->mesh_verts_num) {
|
if (unode->mesh_verts_num) {
|
||||||
if (ss->totvert != unode->mesh_verts_num) {
|
if (ss.totvert != unode->mesh_verts_num) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -998,37 +998,37 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
|||||||
|
|
||||||
switch (unode->type) {
|
switch (unode->type) {
|
||||||
case Type::Position:
|
case Type::Position:
|
||||||
modified_verts_position.resize(ss->totvert, false);
|
modified_verts_position.resize(ss.totvert, false);
|
||||||
if (restore_coords(C, object, depsgraph, step_data, *unode, modified_verts_position)) {
|
if (restore_coords(C, object, depsgraph, step_data, *unode, modified_verts_position)) {
|
||||||
changed_position = true;
|
changed_position = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Type::HideVert:
|
case Type::HideVert:
|
||||||
modified_verts_hide.resize(ss->totvert, false);
|
modified_verts_hide.resize(ss.totvert, false);
|
||||||
if (restore_hidden(object, *unode, modified_verts_hide)) {
|
if (restore_hidden(object, *unode, modified_verts_hide)) {
|
||||||
changed_hide_vert = true;
|
changed_hide_vert = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Type::HideFace:
|
case Type::HideFace:
|
||||||
modified_faces_hide.resize(ss->totfaces, false);
|
modified_faces_hide.resize(ss.totfaces, false);
|
||||||
if (restore_hidden_face(object, *unode, modified_faces_hide)) {
|
if (restore_hidden_face(object, *unode, modified_faces_hide)) {
|
||||||
changed_hide_face = true;
|
changed_hide_face = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Type::Mask:
|
case Type::Mask:
|
||||||
modified_verts_mask.resize(ss->totvert, false);
|
modified_verts_mask.resize(ss.totvert, false);
|
||||||
if (restore_mask(object, *unode, modified_verts_mask)) {
|
if (restore_mask(object, *unode, modified_verts_mask)) {
|
||||||
changed_mask = true;
|
changed_mask = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Type::FaceSet:
|
case Type::FaceSet:
|
||||||
modified_faces_face_set.resize(ss->totfaces, false);
|
modified_faces_face_set.resize(ss.totfaces, false);
|
||||||
if (restore_face_sets(object, *unode, modified_faces_face_set)) {
|
if (restore_face_sets(object, *unode, modified_faces_face_set)) {
|
||||||
changed_face_sets = true;
|
changed_face_sets = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Type::Color:
|
case Type::Color:
|
||||||
modified_verts_color.resize(ss->totvert, false);
|
modified_verts_color.resize(ss.totvert, false);
|
||||||
if (restore_color(object, *unode, modified_verts_color)) {
|
if (restore_color(object, *unode, modified_verts_color)) {
|
||||||
changed_color = true;
|
changed_color = true;
|
||||||
}
|
}
|
||||||
@ -1073,7 +1073,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
|||||||
data.changed_position = changed_position;
|
data.changed_position = changed_position;
|
||||||
data.changed_hide_vert = changed_hide_vert;
|
data.changed_hide_vert = changed_hide_vert;
|
||||||
data.changed_mask = changed_mask;
|
data.changed_mask = changed_mask;
|
||||||
data.pbvh = ss->pbvh.get();
|
data.pbvh = ss.pbvh.get();
|
||||||
data.modified_grids = modified_grids;
|
data.modified_grids = modified_grids;
|
||||||
data.modified_position_verts = modified_verts_position;
|
data.modified_position_verts = modified_verts_position;
|
||||||
data.modified_hidden_verts = modified_verts_hide;
|
data.modified_hidden_verts = modified_verts_hide;
|
||||||
@ -1083,30 +1083,30 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
|||||||
data.modified_face_set_faces = modified_faces_face_set;
|
data.modified_face_set_faces = modified_faces_face_set;
|
||||||
if (use_multires_undo) {
|
if (use_multires_undo) {
|
||||||
bke::pbvh::search_callback(
|
bke::pbvh::search_callback(
|
||||||
*ss->pbvh, {}, [&](PBVHNode &node) { update_modified_node_grids(node, data); });
|
*ss.pbvh, {}, [&](PBVHNode &node) { update_modified_node_grids(node, data); });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bke::pbvh::search_callback(
|
bke::pbvh::search_callback(
|
||||||
*ss->pbvh, {}, [&](PBVHNode &node) { update_modified_node_mesh(mesh, node, data); });
|
*ss.pbvh, {}, [&](PBVHNode &node) { update_modified_node_mesh(mesh, node, data); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed_position) {
|
if (changed_position) {
|
||||||
bke::pbvh::update_bounds(*ss->pbvh);
|
bke::pbvh::update_bounds(*ss.pbvh);
|
||||||
bke::pbvh::store_bounds_orig(*ss->pbvh);
|
bke::pbvh::store_bounds_orig(*ss.pbvh);
|
||||||
}
|
}
|
||||||
if (changed_mask) {
|
if (changed_mask) {
|
||||||
bke::pbvh::update_mask(*ss->pbvh);
|
bke::pbvh::update_mask(*ss.pbvh);
|
||||||
}
|
}
|
||||||
if (changed_hide_face) {
|
if (changed_hide_face) {
|
||||||
hide::sync_all_from_faces(object);
|
hide::sync_all_from_faces(object);
|
||||||
bke::pbvh::update_visibility(*ss->pbvh);
|
bke::pbvh::update_visibility(*ss.pbvh);
|
||||||
}
|
}
|
||||||
if (changed_hide_vert) {
|
if (changed_hide_vert) {
|
||||||
if (ELEM(BKE_pbvh_type(*ss->pbvh), PBVH_FACES, PBVH_GRIDS)) {
|
if (ELEM(BKE_pbvh_type(*ss.pbvh), PBVH_FACES, PBVH_GRIDS)) {
|
||||||
Mesh &mesh = *static_cast<Mesh *>(object.data);
|
Mesh &mesh = *static_cast<Mesh *>(object.data);
|
||||||
BKE_pbvh_sync_visibility_from_verts(*ss->pbvh, &mesh);
|
BKE_pbvh_sync_visibility_from_verts(*ss.pbvh, &mesh);
|
||||||
}
|
}
|
||||||
bke::pbvh::update_visibility(*ss->pbvh);
|
bke::pbvh::update_visibility(*ss.pbvh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BKE_sculpt_multires_active(scene, &object)) {
|
if (BKE_sculpt_multires_active(scene, &object)) {
|
||||||
@ -1119,14 +1119,14 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bool tag_update = ID_REAL_USERS(object.data) > 1 ||
|
const bool tag_update = ID_REAL_USERS(object.data) > 1 ||
|
||||||
!BKE_sculptsession_use_pbvh_draw(&object, rv3d) || ss->shapekey_active ||
|
!BKE_sculptsession_use_pbvh_draw(&object, rv3d) || ss.shapekey_active ||
|
||||||
ss->deform_modifiers_active;
|
ss.deform_modifiers_active;
|
||||||
|
|
||||||
if (tag_update) {
|
if (tag_update) {
|
||||||
Mesh *mesh = static_cast<Mesh *>(object.data);
|
Mesh *mesh = static_cast<Mesh *>(object.data);
|
||||||
if (changed_position) {
|
if (changed_position) {
|
||||||
mesh->tag_positions_changed();
|
mesh->tag_positions_changed();
|
||||||
BKE_sculptsession_free_deformMats(ss);
|
BKE_sculptsession_free_deformMats(&ss);
|
||||||
}
|
}
|
||||||
DEG_id_tag_update(&object.id, ID_RECALC_GEOMETRY);
|
DEG_id_tag_update(&object.id, ID_RECALC_GEOMETRY);
|
||||||
}
|
}
|
||||||
@ -1155,12 +1155,12 @@ Node *get_node(const PBVHNode *node, const Type type)
|
|||||||
return step_data->undo_nodes_by_pbvh_node.lookup_default({node, type}, nullptr);
|
return step_data->undo_nodes_by_pbvh_node.lookup_default({node, type}, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t alloc_and_store_hidden(const SculptSession *ss, const PBVHNode &node, Node *unode)
|
static size_t alloc_and_store_hidden(const SculptSession &ss, const PBVHNode &node, Node *unode)
|
||||||
{
|
{
|
||||||
if (!ss->subdiv_ccg) {
|
if (!ss.subdiv_ccg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const BitGroupVector<> grid_hidden = ss->subdiv_ccg->grid_hidden;
|
const BitGroupVector<> grid_hidden = ss.subdiv_ccg->grid_hidden;
|
||||||
if (grid_hidden.is_empty()) {
|
if (grid_hidden.is_empty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1208,7 +1208,7 @@ static Node *find_or_alloc_node_type(const Type type)
|
|||||||
static Node *alloc_node(const Object &object, const PBVHNode *node, const Type type)
|
static Node *alloc_node(const Object &object, const PBVHNode *node, const Type type)
|
||||||
{
|
{
|
||||||
StepData *step_data = get_step_data();
|
StepData *step_data = get_step_data();
|
||||||
const SculptSession *ss = object.sculpt;
|
const SculptSession &ss = *object.sculpt;
|
||||||
|
|
||||||
Node *unode = alloc_node_type(type);
|
Node *unode = alloc_node_type(type);
|
||||||
step_data->undo_nodes_by_pbvh_node.add({node, type}, unode);
|
step_data->undo_nodes_by_pbvh_node.add({node, type}, unode);
|
||||||
@ -1216,9 +1216,9 @@ static Node *alloc_node(const Object &object, const PBVHNode *node, const Type t
|
|||||||
const Mesh &mesh = *static_cast<Mesh *>(object.data);
|
const Mesh &mesh = *static_cast<Mesh *>(object.data);
|
||||||
|
|
||||||
int verts_num;
|
int verts_num;
|
||||||
if (BKE_pbvh_type(*ss->pbvh) == PBVH_GRIDS) {
|
if (BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS) {
|
||||||
unode->mesh_grids_num = ss->subdiv_ccg->grids.size();
|
unode->mesh_grids_num = ss.subdiv_ccg->grids.size();
|
||||||
unode->grid_size = ss->subdiv_ccg->grid_size;
|
unode->grid_size = ss.subdiv_ccg->grid_size;
|
||||||
|
|
||||||
unode->grids = bke::pbvh::node_grid_indices(*node);
|
unode->grids = bke::pbvh::node_grid_indices(*node);
|
||||||
step_data->undo_size += unode->grids.as_span().size_in_bytes();
|
step_data->undo_size += unode->grids.as_span().size_in_bytes();
|
||||||
@ -1227,7 +1227,7 @@ static Node *alloc_node(const Object &object, const PBVHNode *node, const Type t
|
|||||||
verts_num = unode->grids.size() * grid_area;
|
verts_num = unode->grids.size() * grid_area;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unode->mesh_verts_num = ss->totvert;
|
unode->mesh_verts_num = ss.totvert;
|
||||||
|
|
||||||
unode->vert_indices = bke::pbvh::node_verts(*node);
|
unode->vert_indices = bke::pbvh::node_verts(*node);
|
||||||
unode->unique_verts_num = bke::pbvh::node_unique_verts(*node).size();
|
unode->unique_verts_num = bke::pbvh::node_unique_verts(*node).size();
|
||||||
@ -1248,11 +1248,11 @@ static Node *alloc_node(const Object &object, const PBVHNode *node, const Type t
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (need_faces) {
|
if (need_faces) {
|
||||||
if (BKE_pbvh_type(*ss->pbvh) == PBVH_FACES) {
|
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
|
||||||
bke::pbvh::node_face_indices_calc_mesh(mesh.corner_tri_faces(), *node, unode->face_indices);
|
bke::pbvh::node_face_indices_calc_mesh(mesh.corner_tri_faces(), *node, unode->face_indices);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bke::pbvh::node_face_indices_calc_grids(*ss->pbvh, *node, unode->face_indices);
|
bke::pbvh::node_face_indices_calc_grids(*ss.pbvh, *node, unode->face_indices);
|
||||||
}
|
}
|
||||||
step_data->undo_size += unode->face_indices.as_span().size_in_bytes();
|
step_data->undo_size += unode->face_indices.as_span().size_in_bytes();
|
||||||
}
|
}
|
||||||
@ -1268,7 +1268,7 @@ static Node *alloc_node(const Object &object, const PBVHNode *node, const Type t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Type::HideVert: {
|
case Type::HideVert: {
|
||||||
if (BKE_pbvh_type(*ss->pbvh) == PBVH_GRIDS) {
|
if (BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS) {
|
||||||
step_data->undo_size += alloc_and_store_hidden(ss, *node, unode);
|
step_data->undo_size += alloc_and_store_hidden(ss, *node, unode);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1295,7 +1295,7 @@ static Node *alloc_node(const Object &object, const PBVHNode *node, const Type t
|
|||||||
step_data->undo_size += unode->col.as_span().size_in_bytes();
|
step_data->undo_size += unode->col.as_span().size_in_bytes();
|
||||||
|
|
||||||
/* Allocate loop colors separately too. */
|
/* Allocate loop colors separately too. */
|
||||||
if (ss->vcol_domain == bke::AttrDomain::Corner) {
|
if (ss.vcol_domain == bke::AttrDomain::Corner) {
|
||||||
unode->loop_col.reinitialize(unode->corner_indices.size());
|
unode->loop_col.reinitialize(unode->corner_indices.size());
|
||||||
unode->undo_size += unode->loop_col.as_span().size_in_bytes();
|
unode->undo_size += unode->loop_col.as_span().size_in_bytes();
|
||||||
}
|
}
|
||||||
@ -1318,7 +1318,7 @@ static Node *alloc_node(const Object &object, const PBVHNode *node, const Type t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss->deform_modifiers_active) {
|
if (ss.deform_modifiers_active) {
|
||||||
unode->orig_position.reinitialize(unode->vert_indices.size());
|
unode->orig_position.reinitialize(unode->vert_indices.size());
|
||||||
step_data->undo_size += unode->orig_position.as_span().size_in_bytes();
|
step_data->undo_size += unode->orig_position.as_span().size_in_bytes();
|
||||||
}
|
}
|
||||||
@ -1328,10 +1328,10 @@ static Node *alloc_node(const Object &object, const PBVHNode *node, const Type t
|
|||||||
|
|
||||||
static void store_coords(const Object &object, Node *unode)
|
static void store_coords(const Object &object, Node *unode)
|
||||||
{
|
{
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
|
|
||||||
if (!unode->grids.is_empty()) {
|
if (!unode->grids.is_empty()) {
|
||||||
const SubdivCCG &subdiv_ccg = *ss->subdiv_ccg;
|
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
|
||||||
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
|
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
|
||||||
const Span<CCGElem *> grids = subdiv_ccg.grids;
|
const Span<CCGElem *> grids = subdiv_ccg.grids;
|
||||||
{
|
{
|
||||||
@ -1356,14 +1356,14 @@ static void store_coords(const Object &object, Node *unode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
array_utils::gather(BKE_pbvh_get_vert_positions(*ss->pbvh).as_span(),
|
array_utils::gather(BKE_pbvh_get_vert_positions(*ss.pbvh).as_span(),
|
||||||
unode->vert_indices.as_span(),
|
unode->vert_indices.as_span(),
|
||||||
unode->position.as_mutable_span());
|
unode->position.as_mutable_span());
|
||||||
array_utils::gather(BKE_pbvh_get_vert_normals(*ss->pbvh),
|
array_utils::gather(BKE_pbvh_get_vert_normals(*ss.pbvh),
|
||||||
unode->vert_indices.as_span(),
|
unode->vert_indices.as_span(),
|
||||||
unode->normal.as_mutable_span());
|
unode->normal.as_mutable_span());
|
||||||
if (ss->deform_modifiers_active) {
|
if (ss.deform_modifiers_active) {
|
||||||
array_utils::gather(ss->orig_cos.as_span(),
|
array_utils::gather(ss.orig_cos.as_span(),
|
||||||
unode->vert_indices.as_span(),
|
unode->vert_indices.as_span(),
|
||||||
unode->orig_position.as_mutable_span());
|
unode->orig_position.as_mutable_span());
|
||||||
}
|
}
|
||||||
@ -1407,10 +1407,10 @@ static void store_face_hidden(const Object &object, Node &unode)
|
|||||||
|
|
||||||
static void store_mask(const Object &object, Node *unode)
|
static void store_mask(const Object &object, Node *unode)
|
||||||
{
|
{
|
||||||
const SculptSession *ss = object.sculpt;
|
const SculptSession &ss = *object.sculpt;
|
||||||
|
|
||||||
if (!unode->grids.is_empty()) {
|
if (!unode->grids.is_empty()) {
|
||||||
const SubdivCCG &subdiv_ccg = *ss->subdiv_ccg;
|
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
|
||||||
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
|
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
|
||||||
if (key.has_mask) {
|
if (key.has_mask) {
|
||||||
const Span<CCGElem *> grids = subdiv_ccg.grids;
|
const Span<CCGElem *> grids = subdiv_ccg.grids;
|
||||||
@ -1442,19 +1442,19 @@ static void store_mask(const Object &object, Node *unode)
|
|||||||
static void store_color(const Object &object, Node *unode)
|
static void store_color(const Object &object, Node *unode)
|
||||||
{
|
{
|
||||||
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
|
|
||||||
BLI_assert(BKE_pbvh_type(*ss->pbvh) == PBVH_FACES);
|
BLI_assert(BKE_pbvh_type(*ss.pbvh) == PBVH_FACES);
|
||||||
|
|
||||||
/* NOTE: even with loop colors we still store (derived)
|
/* NOTE: even with loop colors we still store (derived)
|
||||||
* vertex colors for original data lookup. */
|
* vertex colors for original data lookup. */
|
||||||
BKE_pbvh_store_colors_vertex(*ss->pbvh,
|
BKE_pbvh_store_colors_vertex(*ss.pbvh,
|
||||||
mesh.vert_to_face_map(),
|
mesh.vert_to_face_map(),
|
||||||
unode->vert_indices.as_span().take_front(unode->unique_verts_num),
|
unode->vert_indices.as_span().take_front(unode->unique_verts_num),
|
||||||
unode->col);
|
unode->col);
|
||||||
|
|
||||||
if (!unode->loop_col.is_empty() && !unode->corner_indices.is_empty()) {
|
if (!unode->loop_col.is_empty() && !unode->corner_indices.is_empty()) {
|
||||||
BKE_pbvh_store_colors(*ss->pbvh, unode->corner_indices, unode->loop_col);
|
BKE_pbvh_store_colors(*ss.pbvh, unode->corner_indices, unode->loop_col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1492,7 +1492,7 @@ static void store_face_sets(const Mesh &mesh, Node &unode)
|
|||||||
static Node *bmesh_push(const Object &object, const PBVHNode *node, Type type)
|
static Node *bmesh_push(const Object &object, const PBVHNode *node, Type type)
|
||||||
{
|
{
|
||||||
StepData *step_data = get_step_data();
|
StepData *step_data = get_step_data();
|
||||||
const SculptSession *ss = object.sculpt;
|
const SculptSession &ss = *object.sculpt;
|
||||||
|
|
||||||
Node *unode = step_data->nodes.is_empty() ? nullptr : step_data->nodes.first().get();
|
Node *unode = step_data->nodes.is_empty() ? nullptr : step_data->nodes.first().get();
|
||||||
|
|
||||||
@ -1504,8 +1504,8 @@ static Node *bmesh_push(const Object &object, const PBVHNode *node, Type type)
|
|||||||
unode->applied = true;
|
unode->applied = true;
|
||||||
|
|
||||||
if (type == Type::DyntopoEnd) {
|
if (type == Type::DyntopoEnd) {
|
||||||
unode->bm_entry = BM_log_entry_add(ss->bm_log);
|
unode->bm_entry = BM_log_entry_add(ss.bm_log);
|
||||||
BM_log_before_all_removed(ss->bm, ss->bm_log);
|
BM_log_before_all_removed(ss.bm, ss.bm_log);
|
||||||
}
|
}
|
||||||
else if (type == Type::DyntopoBegin) {
|
else if (type == Type::DyntopoBegin) {
|
||||||
/* Store a copy of the mesh's current vertices, loops, and
|
/* Store a copy of the mesh's current vertices, loops, and
|
||||||
@ -1516,17 +1516,17 @@ static Node *bmesh_push(const Object &object, const PBVHNode *node, Type type)
|
|||||||
NodeGeometry *geometry = &unode->geometry_bmesh_enter;
|
NodeGeometry *geometry = &unode->geometry_bmesh_enter;
|
||||||
store_geometry_data(geometry, object);
|
store_geometry_data(geometry, object);
|
||||||
|
|
||||||
unode->bm_entry = BM_log_entry_add(ss->bm_log);
|
unode->bm_entry = BM_log_entry_add(ss.bm_log);
|
||||||
BM_log_all_added(ss->bm, ss->bm_log);
|
BM_log_all_added(ss.bm, ss.bm_log);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unode->bm_entry = BM_log_entry_add(ss->bm_log);
|
unode->bm_entry = BM_log_entry_add(ss.bm_log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
const int cd_vert_mask_offset = CustomData_get_offset_named(
|
const int cd_vert_mask_offset = CustomData_get_offset_named(
|
||||||
&ss->bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
|
&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
|
||||||
|
|
||||||
/* The vertices and node aren't changed, though pointers to them are stored in the log. */
|
/* The vertices and node aren't changed, though pointers to them are stored in the log. */
|
||||||
PBVHNode *node_mut = const_cast<PBVHNode *>(node);
|
PBVHNode *node_mut = const_cast<PBVHNode *>(node);
|
||||||
@ -1537,24 +1537,24 @@ static Node *bmesh_push(const Object &object, const PBVHNode *node, Type type)
|
|||||||
/* Before any vertex values get modified, ensure their
|
/* Before any vertex values get modified, ensure their
|
||||||
* original positions are logged. */
|
* original positions are logged. */
|
||||||
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node_mut)) {
|
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node_mut)) {
|
||||||
BM_log_vert_before_modified(ss->bm_log, vert, cd_vert_mask_offset);
|
BM_log_vert_before_modified(ss.bm_log, vert, cd_vert_mask_offset);
|
||||||
}
|
}
|
||||||
for (BMVert *vert : BKE_pbvh_bmesh_node_other_verts(node_mut)) {
|
for (BMVert *vert : BKE_pbvh_bmesh_node_other_verts(node_mut)) {
|
||||||
BM_log_vert_before_modified(ss->bm_log, vert, cd_vert_mask_offset);
|
BM_log_vert_before_modified(ss.bm_log, vert, cd_vert_mask_offset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type::HideFace:
|
case Type::HideFace:
|
||||||
case Type::HideVert: {
|
case Type::HideVert: {
|
||||||
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node_mut)) {
|
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node_mut)) {
|
||||||
BM_log_vert_before_modified(ss->bm_log, vert, cd_vert_mask_offset);
|
BM_log_vert_before_modified(ss.bm_log, vert, cd_vert_mask_offset);
|
||||||
}
|
}
|
||||||
for (BMVert *vert : BKE_pbvh_bmesh_node_other_verts(node_mut)) {
|
for (BMVert *vert : BKE_pbvh_bmesh_node_other_verts(node_mut)) {
|
||||||
BM_log_vert_before_modified(ss->bm_log, vert, cd_vert_mask_offset);
|
BM_log_vert_before_modified(ss.bm_log, vert, cd_vert_mask_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (BMFace *f : BKE_pbvh_bmesh_node_faces(node_mut)) {
|
for (BMFace *f : BKE_pbvh_bmesh_node_faces(node_mut)) {
|
||||||
BM_log_face_modified(ss->bm_log, f);
|
BM_log_face_modified(ss.bm_log, f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1574,7 +1574,7 @@ static Node *bmesh_push(const Object &object, const PBVHNode *node, Type type)
|
|||||||
|
|
||||||
Node *push_node(const Object &object, const PBVHNode *node, Type type)
|
Node *push_node(const Object &object, const PBVHNode *node, Type type)
|
||||||
{
|
{
|
||||||
SculptSession *ss = object.sculpt;
|
SculptSession &ss = *object.sculpt;
|
||||||
|
|
||||||
Node *unode;
|
Node *unode;
|
||||||
|
|
||||||
@ -1583,10 +1583,10 @@ Node *push_node(const Object &object, const PBVHNode *node, Type type)
|
|||||||
/* List is manipulated by multiple threads, so we lock. */
|
/* List is manipulated by multiple threads, so we lock. */
|
||||||
std::scoped_lock lock(step_data->nodes_mutex);
|
std::scoped_lock lock(step_data->nodes_mutex);
|
||||||
|
|
||||||
ss->needs_flush_to_id = 1;
|
ss.needs_flush_to_id = 1;
|
||||||
|
|
||||||
threading::isolate_task([&]() {
|
threading::isolate_task([&]() {
|
||||||
if (ss->bm || ELEM(type, Type::DyntopoBegin, Type::DyntopoEnd)) {
|
if (ss.bm || ELEM(type, Type::DyntopoBegin, Type::DyntopoEnd)) {
|
||||||
/* Dynamic topology stores only one undo node per stroke,
|
/* Dynamic topology stores only one undo node per stroke,
|
||||||
* regardless of the number of PBVH nodes modified. */
|
* regardless of the number of PBVH nodes modified. */
|
||||||
unode = bmesh_push(object, node, type);
|
unode = bmesh_push(object, node, type);
|
||||||
@ -2027,7 +2027,7 @@ static bool use_multires_mesh(bContext *C)
|
|||||||
|
|
||||||
static void push_all_grids(Object *object)
|
static void push_all_grids(Object *object)
|
||||||
{
|
{
|
||||||
SculptSession *ss = object->sculpt;
|
SculptSession &ss = *object->sculpt;
|
||||||
|
|
||||||
/* It is possible that undo push is done from an object state where there is no PBVH. This
|
/* It is possible that undo push is done from an object state where there is no PBVH. This
|
||||||
* happens, for example, when an operation which tagged for geometry update was performed prior
|
* happens, for example, when an operation which tagged for geometry update was performed prior
|
||||||
@ -2037,11 +2037,11 @@ static void push_all_grids(Object *object)
|
|||||||
* ensure PBVH for the new base geometry, which will have same coordinates as if we create PBVH
|
* ensure PBVH for the new base geometry, which will have same coordinates as if we create PBVH
|
||||||
* here.
|
* here.
|
||||||
*/
|
*/
|
||||||
if (ss->pbvh == nullptr) {
|
if (ss.pbvh == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss->pbvh, {});
|
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
|
||||||
for (PBVHNode *node : nodes) {
|
for (PBVHNode *node : nodes) {
|
||||||
push_node(*object, node, Type::Position);
|
push_node(*object, node, Type::Position);
|
||||||
}
|
}
|
||||||
|
@ -362,9 +362,7 @@ static bool stats_is_object_dynamic_topology_sculpt(const Object *ob)
|
|||||||
|
|
||||||
static void stats_object_sculpt(const Object *ob, SceneStats *stats)
|
static void stats_object_sculpt(const Object *ob, SceneStats *stats)
|
||||||
{
|
{
|
||||||
|
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
|
|
||||||
if (ss == nullptr || ss->pbvh == nullptr) {
|
if (ss == nullptr || ss->pbvh == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user