forked from blender/blender
me-main #1
@ -120,7 +120,7 @@ void shrinkwrapGpencilModifier_deform(struct ShrinkwrapGpencilModifierData *mmd,
|
|||||||
int numVerts);
|
int numVerts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used in `editmesh_mask_extract.c` to shrink-wrap the extracted mesh to the sculpt.
|
* Used in `editmesh_mask_extract.cc` to shrink-wrap the extracted mesh to the sculpt.
|
||||||
*/
|
*/
|
||||||
void BKE_shrinkwrap_mesh_nearest_surface_deform(struct bContext *C,
|
void BKE_shrinkwrap_mesh_nearest_surface_deform(struct bContext *C,
|
||||||
struct Object *ob_source,
|
struct Object *ob_source,
|
||||||
|
@ -1598,7 +1598,7 @@ struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mo
|
|||||||
void BKE_brush_debug_print_state(Brush *br)
|
void BKE_brush_debug_print_state(Brush *br)
|
||||||
{
|
{
|
||||||
/* create a fake brush and set it to the defaults */
|
/* create a fake brush and set it to the defaults */
|
||||||
Brush def = {{nullptr}};
|
Brush def = blender::dna::shallow_zero_initialize();
|
||||||
brush_defaults(&def);
|
brush_defaults(&def);
|
||||||
|
|
||||||
#define BR_TEST(field, t) \
|
#define BR_TEST(field, t) \
|
||||||
|
@ -28,7 +28,7 @@ bool ED_sculpt_mask_box_select(struct bContext *C,
|
|||||||
const struct rcti *rect,
|
const struct rcti *rect,
|
||||||
bool select);
|
bool select);
|
||||||
|
|
||||||
/* sculpt_transform.c */
|
/* sculpt_transform.cc */
|
||||||
|
|
||||||
void ED_sculpt_update_modal_transform(struct bContext *C, struct Object *ob);
|
void ED_sculpt_update_modal_transform(struct bContext *C, struct Object *ob);
|
||||||
void ED_sculpt_init_transform(struct bContext *C,
|
void ED_sculpt_init_transform(struct bContext *C,
|
||||||
|
@ -39,7 +39,7 @@ set(SRC
|
|||||||
editmesh_knife.c
|
editmesh_knife.c
|
||||||
editmesh_knife_project.c
|
editmesh_knife_project.c
|
||||||
editmesh_loopcut.c
|
editmesh_loopcut.c
|
||||||
editmesh_mask_extract.c
|
editmesh_mask_extract.cc
|
||||||
editmesh_path.c
|
editmesh_path.c
|
||||||
editmesh_polybuild.c
|
editmesh_polybuild.c
|
||||||
editmesh_preselect_edgering.c
|
editmesh_preselect_edgering.c
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
static bool geometry_extract_poll(bContext *C)
|
static bool geometry_extract_poll(bContext *C)
|
||||||
{
|
{
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
if (ob != NULL && ob->mode == OB_MODE_SCULPT) {
|
if (ob != nullptr && ob->mode == OB_MODE_SCULPT) {
|
||||||
if (ob->sculpt->bm) {
|
if (ob->sculpt->bm) {
|
||||||
CTX_wm_operator_poll_msg_set(C, "The geometry can not be extracted with dyntopo activated");
|
CTX_wm_operator_poll_msg_set(C, "The geometry can not be extracted with dyntopo activated");
|
||||||
return false;
|
return false;
|
||||||
@ -59,7 +59,7 @@ static bool geometry_extract_poll(bContext *C)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct GeometryExtactParams {
|
struct GeometryExtractParams {
|
||||||
/* For extracting Face Sets. */
|
/* For extracting Face Sets. */
|
||||||
int active_face_set;
|
int active_face_set;
|
||||||
|
|
||||||
@ -71,17 +71,17 @@ typedef struct GeometryExtactParams {
|
|||||||
int num_smooth_iterations;
|
int num_smooth_iterations;
|
||||||
bool apply_shrinkwrap;
|
bool apply_shrinkwrap;
|
||||||
bool add_solidify;
|
bool add_solidify;
|
||||||
} GeometryExtractParams;
|
};
|
||||||
|
|
||||||
/* Function that tags in BMesh the faces that should be deleted in the extracted object. */
|
/* Function that tags in BMesh the faces that should be deleted in the extracted object. */
|
||||||
typedef void(GeometryExtractTagMeshFunc)(struct BMesh *, GeometryExtractParams *);
|
using GeometryExtractTagMeshFunc = void(BMesh *, GeometryExtractParams *);
|
||||||
|
|
||||||
static int geometry_extract_apply(bContext *C,
|
static int geometry_extract_apply(bContext *C,
|
||||||
wmOperator *op,
|
wmOperator *op,
|
||||||
GeometryExtractTagMeshFunc *tag_fn,
|
GeometryExtractTagMeshFunc *tag_fn,
|
||||||
GeometryExtractParams *params)
|
GeometryExtractParams *params)
|
||||||
{
|
{
|
||||||
struct Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
View3D *v3d = CTX_wm_view3d(C);
|
View3D *v3d = CTX_wm_view3d(C);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
@ -89,28 +89,24 @@ static int geometry_extract_apply(bContext *C,
|
|||||||
|
|
||||||
ED_object_sculptmode_exit(C, depsgraph);
|
ED_object_sculptmode_exit(C, depsgraph);
|
||||||
|
|
||||||
BKE_sculpt_mask_layers_ensure(depsgraph, bmain, ob, NULL);
|
BKE_sculpt_mask_layers_ensure(depsgraph, bmain, ob, nullptr);
|
||||||
|
|
||||||
/* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to
|
/* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to
|
||||||
* extract the geometry. */
|
* extract the geometry. */
|
||||||
CTX_data_ensure_evaluated_depsgraph(C);
|
CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
|
|
||||||
Mesh *mesh = ob->data;
|
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||||
Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
|
Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
|
||||||
|
|
||||||
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh);
|
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh);
|
||||||
BMesh *bm;
|
BMeshCreateParams bm_create_params{};
|
||||||
bm = BM_mesh_create(&allocsize,
|
bm_create_params.use_toolflags = true;
|
||||||
&((struct BMeshCreateParams){
|
BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params);
|
||||||
.use_toolflags = true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
BM_mesh_bm_from_me(bm,
|
BMeshFromMeshParams mesh_to_bm_params{};
|
||||||
new_mesh,
|
mesh_to_bm_params.calc_face_normal = true;
|
||||||
(&(struct BMeshFromMeshParams){
|
mesh_to_bm_params.calc_vert_normal = true;
|
||||||
.calc_face_normal = true,
|
BM_mesh_bm_from_me(bm, new_mesh, &mesh_to_bm_params);
|
||||||
.calc_vert_normal = true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
BMEditMesh *em = BKE_editmesh_create(bm);
|
BMEditMesh *em = BKE_editmesh_create(bm);
|
||||||
|
|
||||||
@ -186,11 +182,9 @@ static int geometry_extract_apply(bContext *C,
|
|||||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
|
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
|
||||||
|
|
||||||
BKE_id_free(bmain, new_mesh);
|
BKE_id_free(bmain, new_mesh);
|
||||||
new_mesh = BKE_mesh_from_bmesh_nomain(bm,
|
BMeshToMeshParams bm_to_mesh_params{};
|
||||||
(&(struct BMeshToMeshParams){
|
bm_to_mesh_params.calc_object_remap = false;
|
||||||
.calc_object_remap = false,
|
new_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
|
||||||
}),
|
|
||||||
mesh);
|
|
||||||
|
|
||||||
BKE_editmesh_free_data(em);
|
BKE_editmesh_free_data(em);
|
||||||
MEM_freeN(em);
|
MEM_freeN(em);
|
||||||
@ -204,12 +198,13 @@ static int geometry_extract_apply(bContext *C,
|
|||||||
if (v3d && v3d->localvd) {
|
if (v3d && v3d->localvd) {
|
||||||
local_view_bits = v3d->local_view_uuid;
|
local_view_bits = v3d->local_view_uuid;
|
||||||
}
|
}
|
||||||
Object *new_ob = ED_object_add_type(C, OB_MESH, NULL, ob->loc, ob->rot, false, local_view_bits);
|
Object *new_ob = ED_object_add_type(
|
||||||
BKE_mesh_nomain_to_mesh(new_mesh, new_ob->data, new_ob);
|
C, OB_MESH, nullptr, ob->loc, ob->rot, false, local_view_bits);
|
||||||
|
BKE_mesh_nomain_to_mesh(new_mesh, static_cast<Mesh *>(new_ob->data), new_ob);
|
||||||
|
|
||||||
/* Remove the Face Sets as they need to be recreated when entering Sculpt Mode in the new object.
|
/* Remove the Face Sets as they need to be recreated when entering Sculpt Mode in the new object.
|
||||||
* TODO(pablodobarro): In the future we can try to preserve them from the original mesh. */
|
* TODO(pablodobarro): In the future we can try to preserve them from the original mesh. */
|
||||||
Mesh *new_ob_mesh = new_ob->data;
|
Mesh *new_ob_mesh = static_cast<Mesh *>(new_ob->data);
|
||||||
CustomData_free_layer_named(&new_ob_mesh->pdata, ".sculpt_face_set", new_ob_mesh->totpoly);
|
CustomData_free_layer_named(&new_ob_mesh->pdata, ".sculpt_face_set", new_ob_mesh->totpoly);
|
||||||
|
|
||||||
/* Remove the mask from the new object so it can be sculpted directly after extracting. */
|
/* Remove the mask from the new object so it can be sculpted directly after extracting. */
|
||||||
@ -232,7 +227,7 @@ static int geometry_extract_apply(bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob);
|
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob);
|
||||||
BKE_mesh_batch_cache_dirty_tag(new_ob->data, BKE_MESH_BATCH_DIRTY_ALL);
|
BKE_mesh_batch_cache_dirty_tag(static_cast<Mesh *>(new_ob->data), BKE_MESH_BATCH_DIRTY_ALL);
|
||||||
DEG_relations_tag_update(bmain);
|
DEG_relations_tag_update(bmain);
|
||||||
DEG_id_tag_update(&new_ob->id, ID_RECALC_GEOMETRY);
|
DEG_id_tag_update(&new_ob->id, ID_RECALC_GEOMETRY);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, new_ob->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_DATA, new_ob->data);
|
||||||
@ -363,7 +358,7 @@ void MESH_OT_paint_mask_extract(wmOperatorType *ot)
|
|||||||
geometry_extract_props(ot->srna);
|
geometry_extract_props(ot->srna);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int face_set_extract_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e))
|
static int face_set_extract_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||||
{
|
{
|
||||||
ED_workspace_status_text(C, TIP_("Click on the mesh to select a Face Set"));
|
ED_workspace_status_text(C, TIP_("Click on the mesh to select a Face Set"));
|
||||||
WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
|
WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
|
||||||
@ -377,7 +372,7 @@ static int face_set_extract_modal(bContext *C, wmOperator *op, const wmEvent *ev
|
|||||||
case LEFTMOUSE:
|
case LEFTMOUSE:
|
||||||
if (event->val == KM_PRESS) {
|
if (event->val == KM_PRESS) {
|
||||||
WM_cursor_modal_restore(CTX_wm_window(C));
|
WM_cursor_modal_restore(CTX_wm_window(C));
|
||||||
ED_workspace_status_text(C, NULL);
|
ED_workspace_status_text(C, nullptr);
|
||||||
|
|
||||||
/* This modal operator uses and eyedropper to pick a Face Set from the mesh. This ensures
|
/* This modal operator uses and eyedropper to pick a Face Set from the mesh. This ensures
|
||||||
* that the mouse clicked in a viewport region and its coordinates can be used to ray-cast
|
* that the mouse clicked in a viewport region and its coordinates can be used to ray-cast
|
||||||
@ -389,8 +384,8 @@ static int face_set_extract_modal(bContext *C, wmOperator *op, const wmEvent *ev
|
|||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float mval[2] = {event->xy[0] - region->winrct.xmin,
|
const float mval[2] = {float(event->xy[0] - region->winrct.xmin),
|
||||||
event->xy[1] - region->winrct.ymin};
|
float(event->xy[1] - region->winrct.ymin)};
|
||||||
|
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
const int face_set_id = ED_sculpt_face_sets_active_update_and_get(C, ob, mval);
|
const int face_set_id = ED_sculpt_face_sets_active_update_and_get(C, ob, mval);
|
||||||
@ -410,7 +405,7 @@ static int face_set_extract_modal(bContext *C, wmOperator *op, const wmEvent *ev
|
|||||||
case EVT_ESCKEY:
|
case EVT_ESCKEY:
|
||||||
case RIGHTMOUSE: {
|
case RIGHTMOUSE: {
|
||||||
WM_cursor_modal_restore(CTX_wm_window(C));
|
WM_cursor_modal_restore(CTX_wm_window(C));
|
||||||
ED_workspace_status_text(C, NULL);
|
ED_workspace_status_text(C, nullptr);
|
||||||
|
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
@ -488,40 +483,34 @@ static void slice_paint_mask(BMesh *bm, bool invert, bool fill_holes, float mask
|
|||||||
|
|
||||||
static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
struct Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
View3D *v3d = CTX_wm_view3d(C);
|
View3D *v3d = CTX_wm_view3d(C);
|
||||||
|
|
||||||
BKE_sculpt_mask_layers_ensure(NULL, NULL, ob, NULL);
|
BKE_sculpt_mask_layers_ensure(nullptr, nullptr, ob, nullptr);
|
||||||
|
|
||||||
Mesh *mesh = ob->data;
|
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||||
Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
|
Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
|
||||||
|
|
||||||
if (ob->mode == OB_MODE_SCULPT) {
|
if (ob->mode == OB_MODE_SCULPT) {
|
||||||
ED_sculpt_undo_geometry_begin(ob, op);
|
ED_sculpt_undo_geometry_begin(ob, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
BMesh *bm;
|
|
||||||
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh);
|
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh);
|
||||||
bm = BM_mesh_create(&allocsize,
|
BMeshCreateParams bm_create_params{};
|
||||||
&((struct BMeshCreateParams){
|
bm_create_params.use_toolflags = true;
|
||||||
.use_toolflags = true,
|
BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params);
|
||||||
}));
|
|
||||||
|
|
||||||
BM_mesh_bm_from_me(bm,
|
BMeshFromMeshParams mesh_to_bm_params{};
|
||||||
new_mesh,
|
mesh_to_bm_params.calc_face_normal = true;
|
||||||
(&(struct BMeshFromMeshParams){
|
BM_mesh_bm_from_me(bm, new_mesh, &mesh_to_bm_params);
|
||||||
.calc_face_normal = true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
slice_paint_mask(
|
slice_paint_mask(
|
||||||
bm, false, RNA_boolean_get(op->ptr, "fill_holes"), RNA_float_get(op->ptr, "mask_threshold"));
|
bm, false, RNA_boolean_get(op->ptr, "fill_holes"), RNA_float_get(op->ptr, "mask_threshold"));
|
||||||
BKE_id_free(bmain, new_mesh);
|
BKE_id_free(bmain, new_mesh);
|
||||||
new_mesh = BKE_mesh_from_bmesh_nomain(bm,
|
BMeshToMeshParams bm_to_mesh_params{};
|
||||||
(&(struct BMeshToMeshParams){
|
bm_to_mesh_params.calc_object_remap = false;
|
||||||
.calc_object_remap = false,
|
new_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
|
||||||
}),
|
|
||||||
mesh);
|
|
||||||
BM_mesh_free(bm);
|
BM_mesh_free(bm);
|
||||||
|
|
||||||
if (RNA_boolean_get(op->ptr, "new_object")) {
|
if (RNA_boolean_get(op->ptr, "new_object")) {
|
||||||
@ -530,64 +519,53 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
|||||||
local_view_bits = v3d->local_view_uuid;
|
local_view_bits = v3d->local_view_uuid;
|
||||||
}
|
}
|
||||||
Object *new_ob = ED_object_add_type(
|
Object *new_ob = ED_object_add_type(
|
||||||
C, OB_MESH, NULL, ob->loc, ob->rot, false, local_view_bits);
|
C, OB_MESH, nullptr, ob->loc, ob->rot, false, local_view_bits);
|
||||||
Mesh *new_ob_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
|
Mesh *new_ob_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
|
||||||
|
|
||||||
const BMAllocTemplate allocsize_new_ob = BMALLOC_TEMPLATE_FROM_ME(new_ob_mesh);
|
const BMAllocTemplate allocsize_new_ob = BMALLOC_TEMPLATE_FROM_ME(new_ob_mesh);
|
||||||
bm = BM_mesh_create(&allocsize_new_ob,
|
bm = BM_mesh_create(&allocsize_new_ob, &bm_create_params);
|
||||||
&((struct BMeshCreateParams){
|
|
||||||
.use_toolflags = true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
BM_mesh_bm_from_me(bm,
|
BM_mesh_bm_from_me(bm, new_ob_mesh, &mesh_to_bm_params);
|
||||||
new_ob_mesh,
|
|
||||||
(&(struct BMeshFromMeshParams){
|
|
||||||
.calc_face_normal = true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
slice_paint_mask(bm,
|
slice_paint_mask(bm,
|
||||||
true,
|
true,
|
||||||
RNA_boolean_get(op->ptr, "fill_holes"),
|
RNA_boolean_get(op->ptr, "fill_holes"),
|
||||||
RNA_float_get(op->ptr, "mask_threshold"));
|
RNA_float_get(op->ptr, "mask_threshold"));
|
||||||
BKE_id_free(bmain, new_ob_mesh);
|
BKE_id_free(bmain, new_ob_mesh);
|
||||||
new_ob_mesh = BKE_mesh_from_bmesh_nomain(bm,
|
new_ob_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
|
||||||
(&(struct BMeshToMeshParams){
|
|
||||||
.calc_object_remap = false,
|
|
||||||
}),
|
|
||||||
mesh);
|
|
||||||
BM_mesh_free(bm);
|
BM_mesh_free(bm);
|
||||||
|
|
||||||
/* Remove the mask from the new object so it can be sculpted directly after slicing. */
|
/* Remove the mask from the new object so it can be sculpted directly after slicing. */
|
||||||
CustomData_free_layers(&new_ob_mesh->vdata, CD_PAINT_MASK, new_ob_mesh->totvert);
|
CustomData_free_layers(&new_ob_mesh->vdata, CD_PAINT_MASK, new_ob_mesh->totvert);
|
||||||
|
|
||||||
BKE_mesh_nomain_to_mesh(new_ob_mesh, new_ob->data, new_ob);
|
Mesh *new_mesh = static_cast<Mesh *>(new_ob->data);
|
||||||
BKE_mesh_copy_parameters_for_eval(new_ob->data, mesh);
|
BKE_mesh_nomain_to_mesh(new_ob_mesh, new_mesh, new_ob);
|
||||||
|
BKE_mesh_copy_parameters_for_eval(new_mesh, mesh);
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob);
|
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob);
|
||||||
BKE_mesh_batch_cache_dirty_tag(new_ob->data, BKE_MESH_BATCH_DIRTY_ALL);
|
BKE_mesh_batch_cache_dirty_tag(new_mesh, BKE_MESH_BATCH_DIRTY_ALL);
|
||||||
DEG_relations_tag_update(bmain);
|
DEG_relations_tag_update(bmain);
|
||||||
DEG_id_tag_update(&new_ob->id, ID_RECALC_GEOMETRY);
|
DEG_id_tag_update(&new_ob->id, ID_RECALC_GEOMETRY);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, new_ob->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_DATA, new_mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
BKE_mesh_nomain_to_mesh(new_mesh, ob->data, ob);
|
mesh = static_cast<Mesh *>(ob->data);
|
||||||
|
BKE_mesh_nomain_to_mesh(new_mesh, mesh, ob);
|
||||||
|
|
||||||
if (ob->mode == OB_MODE_SCULPT) {
|
if (ob->mode == OB_MODE_SCULPT) {
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
ss->face_sets = CustomData_get_layer_named_for_write(&((Mesh *)ob->data)->pdata,
|
ss->face_sets = static_cast<int *>(CustomData_get_layer_named_for_write(
|
||||||
CD_PROP_INT32,
|
&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly));
|
||||||
".sculpt_face_set",
|
|
||||||
((Mesh *)ob->data)->totpoly);
|
|
||||||
if (ss->face_sets) {
|
if (ss->face_sets) {
|
||||||
/* Assign a new Face Set ID to the new faces created by the slice operation. */
|
/* Assign a new Face Set ID to the new faces created by the slice operation. */
|
||||||
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data);
|
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(mesh);
|
||||||
ED_sculpt_face_sets_initialize_none_to_id(ob->data, next_face_set_id);
|
ED_sculpt_face_sets_initialize_none_to_id(mesh, next_face_set_id);
|
||||||
}
|
}
|
||||||
ED_sculpt_undo_geometry_end(ob);
|
ED_sculpt_undo_geometry_end(ob);
|
||||||
}
|
}
|
||||||
|
|
||||||
BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
|
BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL);
|
||||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_DATA, mesh);
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
@ -296,7 +296,7 @@ void MESH_OT_smooth_normals(struct wmOperatorType *ot);
|
|||||||
void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot);
|
void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot);
|
||||||
void MESH_OT_flip_quad_tessellation(struct wmOperatorType *ot);
|
void MESH_OT_flip_quad_tessellation(struct wmOperatorType *ot);
|
||||||
|
|
||||||
/* *** editmesh_mask_extract.c *** */
|
/* *** editmesh_mask_extract.cc *** */
|
||||||
|
|
||||||
void MESH_OT_paint_mask_extract(struct wmOperatorType *ot);
|
void MESH_OT_paint_mask_extract(struct wmOperatorType *ot);
|
||||||
void MESH_OT_face_set_extract(struct wmOperatorType *ot);
|
void MESH_OT_face_set_extract(struct wmOperatorType *ot);
|
||||||
|
@ -62,26 +62,26 @@ set(SRC
|
|||||||
paint_vertex_weight_utils.c
|
paint_vertex_weight_utils.c
|
||||||
sculpt.cc
|
sculpt.cc
|
||||||
sculpt_automasking.cc
|
sculpt_automasking.cc
|
||||||
sculpt_boundary.c
|
sculpt_boundary.cc
|
||||||
sculpt_brush_types.c
|
sculpt_brush_types.cc
|
||||||
sculpt_cloth.c
|
sculpt_cloth.cc
|
||||||
sculpt_detail.c
|
sculpt_detail.cc
|
||||||
sculpt_dyntopo.cc
|
sculpt_dyntopo.cc
|
||||||
sculpt_expand.cc
|
sculpt_expand.cc
|
||||||
sculpt_face_set.cc
|
sculpt_face_set.cc
|
||||||
sculpt_filter_color.c
|
sculpt_filter_color.cc
|
||||||
sculpt_filter_mask.c
|
sculpt_filter_mask.cc
|
||||||
sculpt_filter_mesh.c
|
sculpt_filter_mesh.cc
|
||||||
sculpt_geodesic.cc
|
sculpt_geodesic.cc
|
||||||
sculpt_mask_expand.c
|
sculpt_mask_expand.cc
|
||||||
sculpt_mask_init.c
|
sculpt_mask_init.cc
|
||||||
sculpt_multiplane_scrape.c
|
sculpt_multiplane_scrape.cc
|
||||||
sculpt_ops.c
|
sculpt_ops.cc
|
||||||
sculpt_paint_color.c
|
sculpt_paint_color.cc
|
||||||
sculpt_paint_image.cc
|
sculpt_paint_image.cc
|
||||||
sculpt_pose.c
|
sculpt_pose.cc
|
||||||
sculpt_smooth.c
|
sculpt_smooth.cc
|
||||||
sculpt_transform.c
|
sculpt_transform.cc
|
||||||
sculpt_undo.cc
|
sculpt_undo.cc
|
||||||
sculpt_uv.c
|
sculpt_uv.c
|
||||||
|
|
||||||
|
@ -325,10 +325,10 @@ float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss,
|
|||||||
return iter->co;
|
return iter->co;
|
||||||
}
|
}
|
||||||
|
|
||||||
char SCULPT_mesh_symmetry_xyz_get(Object *object)
|
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(Object *object)
|
||||||
{
|
{
|
||||||
const Mesh *mesh = BKE_mesh_from_object(object);
|
const Mesh *mesh = BKE_mesh_from_object(object);
|
||||||
return mesh->symmetry;
|
return ePaintSymmetryFlags(mesh->symmetry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sculpt Face Sets and Visibility. */
|
/* Sculpt Face Sets and Visibility. */
|
||||||
|
@ -28,13 +28,13 @@
|
|||||||
#include "GPU_immediate.h"
|
#include "GPU_immediate.h"
|
||||||
#include "GPU_state.h"
|
#include "GPU_state.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
#define BOUNDARY_VERTEX_NONE -1
|
#define BOUNDARY_VERTEX_NONE -1
|
||||||
#define BOUNDARY_STEPS_NONE -1
|
#define BOUNDARY_STEPS_NONE -1
|
||||||
|
|
||||||
typedef struct BoundaryInitialVertexFloodFillData {
|
struct BoundaryInitialVertexFloodFillData {
|
||||||
PBVHVertRef initial_vertex;
|
PBVHVertRef initial_vertex;
|
||||||
int initial_vertex_i;
|
int initial_vertex_i;
|
||||||
int boundary_initial_vertex_steps;
|
int boundary_initial_vertex_steps;
|
||||||
@ -42,12 +42,13 @@ typedef struct BoundaryInitialVertexFloodFillData {
|
|||||||
int boundary_initial_vertex_i;
|
int boundary_initial_vertex_i;
|
||||||
int *floodfill_steps;
|
int *floodfill_steps;
|
||||||
float radius_sq;
|
float radius_sq;
|
||||||
} BoundaryInitialVertexFloodFillData;
|
};
|
||||||
|
|
||||||
static bool boundary_initial_vertex_floodfill_cb(
|
static bool boundary_initial_vertex_floodfill_cb(
|
||||||
SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
||||||
{
|
{
|
||||||
BoundaryInitialVertexFloodFillData *data = userdata;
|
BoundaryInitialVertexFloodFillData *data = static_cast<BoundaryInitialVertexFloodFillData *>(
|
||||||
|
userdata);
|
||||||
|
|
||||||
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
||||||
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||||
@ -91,15 +92,13 @@ static PBVHVertRef sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss
|
|||||||
SCULPT_floodfill_init(ss, &flood);
|
SCULPT_floodfill_init(ss, &flood);
|
||||||
SCULPT_floodfill_add_initial(&flood, initial_vertex);
|
SCULPT_floodfill_add_initial(&flood, initial_vertex);
|
||||||
|
|
||||||
BoundaryInitialVertexFloodFillData fdata = {
|
BoundaryInitialVertexFloodFillData fdata{};
|
||||||
.initial_vertex = initial_vertex,
|
fdata.initial_vertex = initial_vertex;
|
||||||
.boundary_initial_vertex = {BOUNDARY_VERTEX_NONE},
|
fdata.boundary_initial_vertex = {BOUNDARY_VERTEX_NONE};
|
||||||
.boundary_initial_vertex_steps = INT_MAX,
|
fdata.boundary_initial_vertex_steps = INT_MAX;
|
||||||
.radius_sq = radius * radius,
|
fdata.radius_sq = radius * radius;
|
||||||
};
|
|
||||||
|
|
||||||
fdata.floodfill_steps = MEM_calloc_arrayN(
|
fdata.floodfill_steps = MEM_cnew_array<int>(SCULPT_vertex_count_get(ss), __func__);
|
||||||
SCULPT_vertex_count_get(ss), sizeof(int), "floodfill steps");
|
|
||||||
|
|
||||||
SCULPT_floodfill_execute(ss, &flood, boundary_initial_vertex_floodfill_cb, &fdata);
|
SCULPT_floodfill_execute(ss, &flood, boundary_initial_vertex_floodfill_cb, &fdata);
|
||||||
SCULPT_floodfill_free(&flood);
|
SCULPT_floodfill_free(&flood);
|
||||||
@ -131,8 +130,8 @@ static void sculpt_boundary_index_add(SculptBoundary *boundary,
|
|||||||
boundary->verts_num++;
|
boundary->verts_num++;
|
||||||
if (boundary->verts_num >= boundary->verts_capacity) {
|
if (boundary->verts_num >= boundary->verts_capacity) {
|
||||||
boundary->verts_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
|
boundary->verts_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
|
||||||
boundary->verts = MEM_reallocN_id(
|
boundary->verts = static_cast<PBVHVertRef *>(MEM_reallocN_id(
|
||||||
boundary->verts, boundary->verts_capacity * sizeof(PBVHVertRef), "boundary indices");
|
boundary->verts, boundary->verts_capacity * sizeof(PBVHVertRef), "boundary indices"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,9 +146,10 @@ static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary,
|
|||||||
|
|
||||||
if (boundary->edges_num >= boundary->edges_capacity) {
|
if (boundary->edges_num >= boundary->edges_capacity) {
|
||||||
boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
|
boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
|
||||||
boundary->edges = MEM_reallocN_id(boundary->edges,
|
boundary->edges = static_cast<SculptBoundaryPreviewEdge *>(
|
||||||
|
MEM_reallocN_id(boundary->edges,
|
||||||
boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge),
|
boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge),
|
||||||
"boundary edges");
|
"boundary edges"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -196,14 +196,13 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss,
|
|||||||
/* Flood fill that adds to the boundary data all the vertices from a boundary and its duplicates.
|
/* Flood fill that adds to the boundary data all the vertices from a boundary and its duplicates.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct BoundaryFloodFillData {
|
struct BoundaryFloodFillData {
|
||||||
SculptBoundary *boundary;
|
SculptBoundary *boundary;
|
||||||
GSet *included_verts;
|
GSet *included_verts;
|
||||||
EdgeSet *preview_edges;
|
EdgeSet *preview_edges;
|
||||||
|
|
||||||
PBVHVertRef last_visited_vertex;
|
PBVHVertRef last_visited_vertex;
|
||||||
|
};
|
||||||
} BoundaryFloodFillData;
|
|
||||||
|
|
||||||
static bool boundary_floodfill_cb(
|
static bool boundary_floodfill_cb(
|
||||||
SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
||||||
@ -211,7 +210,7 @@ static bool boundary_floodfill_cb(
|
|||||||
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
||||||
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||||
|
|
||||||
BoundaryFloodFillData *data = userdata;
|
BoundaryFloodFillData *data = static_cast<BoundaryFloodFillData *>(userdata);
|
||||||
SculptBoundary *boundary = data->boundary;
|
SculptBoundary *boundary = data->boundary;
|
||||||
if (!SCULPT_vertex_is_boundary(ss, to_v)) {
|
if (!SCULPT_vertex_is_boundary(ss, to_v)) {
|
||||||
return false;
|
return false;
|
||||||
@ -236,14 +235,14 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
|
|||||||
{
|
{
|
||||||
|
|
||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
boundary->verts = MEM_malloc_arrayN(
|
boundary->verts = static_cast<PBVHVertRef *>(
|
||||||
BOUNDARY_INDICES_BLOCK_SIZE, sizeof(PBVHVertRef), "boundary indices");
|
MEM_malloc_arrayN(BOUNDARY_INDICES_BLOCK_SIZE, sizeof(PBVHVertRef), __func__));
|
||||||
|
|
||||||
if (init_boundary_distances) {
|
if (init_boundary_distances) {
|
||||||
boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances");
|
boundary->distance = static_cast<float *>(MEM_calloc_arrayN(totvert, sizeof(float), __func__));
|
||||||
}
|
}
|
||||||
boundary->edges = MEM_malloc_arrayN(
|
boundary->edges = static_cast<SculptBoundaryPreviewEdge *>(
|
||||||
BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), "boundary edges");
|
MEM_malloc_arrayN(BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), __func__));
|
||||||
|
|
||||||
GSet *included_verts = BLI_gset_int_new_ex("included verts", BOUNDARY_INDICES_BLOCK_SIZE);
|
GSet *included_verts = BLI_gset_int_new_ex("included verts", BOUNDARY_INDICES_BLOCK_SIZE);
|
||||||
SculptFloodFill flood;
|
SculptFloodFill flood;
|
||||||
@ -260,12 +259,10 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
|
|||||||
boundary, initial_boundary_vertex, initial_boundary_index, 0.0f, included_verts);
|
boundary, initial_boundary_vertex, initial_boundary_index, 0.0f, included_verts);
|
||||||
SCULPT_floodfill_add_initial(&flood, boundary->initial_vertex);
|
SCULPT_floodfill_add_initial(&flood, boundary->initial_vertex);
|
||||||
|
|
||||||
BoundaryFloodFillData fdata = {
|
BoundaryFloodFillData fdata{};
|
||||||
.boundary = boundary,
|
fdata.boundary = boundary;
|
||||||
.included_verts = included_verts,
|
fdata.included_verts = included_verts;
|
||||||
.last_visited_vertex = {BOUNDARY_VERTEX_NONE},
|
fdata.last_visited_vertex = {BOUNDARY_VERTEX_NONE};
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
SCULPT_floodfill_execute(ss, &flood, boundary_floodfill_cb, &fdata);
|
SCULPT_floodfill_execute(ss, &flood, boundary_floodfill_cb, &fdata);
|
||||||
SCULPT_floodfill_free(&flood);
|
SCULPT_floodfill_free(&flood);
|
||||||
@ -284,7 +281,7 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
|
|||||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_gset_free(included_verts, NULL);
|
BLI_gset_free(included_verts, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -302,8 +299,8 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
|||||||
|
|
||||||
const bool has_duplicates = BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
|
const bool has_duplicates = BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
|
||||||
|
|
||||||
boundary->edit_info = MEM_malloc_arrayN(
|
boundary->edit_info = static_cast<SculptBoundaryEditInfo *>(
|
||||||
totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info");
|
MEM_malloc_arrayN(totvert, sizeof(SculptBoundaryEditInfo), __func__));
|
||||||
|
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
boundary->edit_info[i].original_vertex_i = BOUNDARY_VERTEX_NONE;
|
boundary->edit_info[i].original_vertex_i = BOUNDARY_VERTEX_NONE;
|
||||||
@ -496,7 +493,7 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object,
|
|||||||
SculptSession *ss = object->sculpt;
|
SculptSession *ss = object->sculpt;
|
||||||
|
|
||||||
if (initial_vertex.i == PBVH_REF_NONE) {
|
if (initial_vertex.i == PBVH_REF_NONE) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCULPT_vertex_random_access_ensure(ss);
|
SCULPT_vertex_random_access_ensure(ss);
|
||||||
@ -506,16 +503,16 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object,
|
|||||||
ss, initial_vertex, radius);
|
ss, initial_vertex, radius);
|
||||||
|
|
||||||
if (boundary_initial_vertex.i == BOUNDARY_VERTEX_NONE) {
|
if (boundary_initial_vertex.i == BOUNDARY_VERTEX_NONE) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Starting from a vertex that is the limit of a boundary is ambiguous, so return NULL instead of
|
/* Starting from a vertex that is the limit of a boundary is ambiguous, so return nullptr instead
|
||||||
* forcing a random active boundary from a corner. */
|
* of forcing a random active boundary from a corner. */
|
||||||
if (!sculpt_boundary_is_vertex_in_editable_boundary(ss, initial_vertex)) {
|
if (!sculpt_boundary_is_vertex_in_editable_boundary(ss, initial_vertex)) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptBoundary *boundary = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data");
|
SculptBoundary *boundary = MEM_cnew<SculptBoundary>(__func__);
|
||||||
|
|
||||||
const bool init_boundary_distances = brush ? brush->boundary_falloff_type !=
|
const bool init_boundary_distances = brush ? brush->boundary_falloff_type !=
|
||||||
BRUSH_BOUNDARY_FALLOFF_CONSTANT :
|
BRUSH_BOUNDARY_FALLOFF_CONSTANT :
|
||||||
@ -548,9 +545,10 @@ void SCULPT_boundary_data_free(SculptBoundary *boundary)
|
|||||||
static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *boundary)
|
static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *boundary)
|
||||||
{
|
{
|
||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
boundary->bend.pivot_rotation_axis = MEM_calloc_arrayN(
|
boundary->bend.pivot_rotation_axis = static_cast<float(*)[3]>(
|
||||||
totvert, sizeof(float[3]), "pivot rotation axis");
|
MEM_calloc_arrayN(totvert, sizeof(float[3]), __func__));
|
||||||
boundary->bend.pivot_positions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "pivot positions");
|
boundary->bend.pivot_positions = static_cast<float(*)[3]>(
|
||||||
|
MEM_calloc_arrayN(totvert, sizeof(float[3]), __func__));
|
||||||
|
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
if (boundary->edit_info[i].propagation_steps_num != boundary->max_propagation_steps) {
|
if (boundary->edit_info[i].propagation_steps_num != boundary->max_propagation_steps) {
|
||||||
@ -588,7 +586,8 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
|
|||||||
static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary)
|
static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary)
|
||||||
{
|
{
|
||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
boundary->slide.directions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "slide directions");
|
boundary->slide.directions = static_cast<float(*)[3]>(
|
||||||
|
MEM_calloc_arrayN(totvert, sizeof(float[3]), "slide directions"));
|
||||||
|
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
if (boundary->edit_info[i].propagation_steps_num != boundary->max_propagation_steps) {
|
if (boundary->edit_info[i].propagation_steps_num != boundary->max_propagation_steps) {
|
||||||
@ -614,7 +613,8 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b
|
|||||||
static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *boundary)
|
static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *boundary)
|
||||||
{
|
{
|
||||||
zero_v3(boundary->twist.pivot_position);
|
zero_v3(boundary->twist.pivot_position);
|
||||||
float(*poly_verts)[3] = MEM_malloc_arrayN(boundary->verts_num, sizeof(float[3]), "poly verts");
|
float(*poly_verts)[3] = static_cast<float(*)[3]>(
|
||||||
|
MEM_malloc_arrayN(boundary->verts_num, sizeof(float[3]), "poly verts"));
|
||||||
for (int i = 0; i < boundary->verts_num; i++) {
|
for (int i = 0; i < boundary->verts_num; i++) {
|
||||||
add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->verts[i]));
|
add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->verts[i]));
|
||||||
copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->verts[i]));
|
copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->verts[i]));
|
||||||
@ -648,9 +648,9 @@ static float sculpt_boundary_displacement_from_grab_delta_get(SculptSession *ss,
|
|||||||
/* Deformation tasks callbacks. */
|
/* Deformation tasks callbacks. */
|
||||||
static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
|
static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const int symm_area = ss->cache->mirror_symmetry_pass;
|
const int symm_area = ss->cache->mirror_symmetry_pass;
|
||||||
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
||||||
@ -707,9 +707,9 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
|
|||||||
|
|
||||||
static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
|
static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const int symm_area = ss->cache->mirror_symmetry_pass;
|
const int symm_area = ss->cache->mirror_symmetry_pass;
|
||||||
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
||||||
@ -758,9 +758,9 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
|
|||||||
|
|
||||||
static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
|
static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const int symm_area = ss->cache->mirror_symmetry_pass;
|
const int symm_area = ss->cache->mirror_symmetry_pass;
|
||||||
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
||||||
@ -809,9 +809,9 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
|
|||||||
|
|
||||||
static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
|
static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const int symm_area = ss->cache->mirror_symmetry_pass;
|
const int symm_area = ss->cache->mirror_symmetry_pass;
|
||||||
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
||||||
@ -857,9 +857,9 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
|
|||||||
|
|
||||||
static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
|
static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const int symm_area = ss->cache->mirror_symmetry_pass;
|
const int symm_area = ss->cache->mirror_symmetry_pass;
|
||||||
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
SculptBoundary *boundary = ss->cache->boundaries[symm_area];
|
||||||
@ -916,9 +916,9 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
|
|||||||
|
|
||||||
static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
|
static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const int symmetry_pass = ss->cache->mirror_symmetry_pass;
|
const int symmetry_pass = ss->cache->mirror_symmetry_pass;
|
||||||
const SculptBoundary *boundary = ss->cache->boundaries[symmetry_pass];
|
const SculptBoundary *boundary = ss->cache->boundaries[symmetry_pass];
|
||||||
@ -978,7 +978,7 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
|
|||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||||
|
|
||||||
const int symm_area = ss->cache->mirror_symmetry_pass;
|
const ePaintSymmetryFlags symm_area = ss->cache->mirror_symmetry_pass;
|
||||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||||
|
|
||||||
PBVHVertRef initial_vertex;
|
PBVHVertRef initial_vertex;
|
||||||
@ -1024,12 +1024,11 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
@ -35,9 +35,9 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name SculptProjectVector
|
/** \name SculptProjectVector
|
||||||
@ -45,13 +45,12 @@
|
|||||||
* Fast-path for #project_plane_v3_v3v3
|
* Fast-path for #project_plane_v3_v3v3
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
typedef struct SculptProjectVector {
|
struct SculptProjectVector {
|
||||||
float plane[3];
|
float plane[3];
|
||||||
float len_sq;
|
float len_sq;
|
||||||
float len_sq_inv_neg;
|
float len_sq_inv_neg;
|
||||||
bool is_valid;
|
bool is_valid;
|
||||||
|
};
|
||||||
} SculptProjectVector;
|
|
||||||
|
|
||||||
static bool plane_point_side_flip(const float co[3], const float plane[4], const bool flip)
|
static bool plane_point_side_flip(const float co[3], const float plane[4], const bool flip)
|
||||||
{
|
{
|
||||||
@ -239,7 +238,7 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *offset = data->offset;
|
const float *offset = data->offset;
|
||||||
@ -305,13 +304,12 @@ void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
|||||||
BKE_curvemapping_init(brush->curve);
|
BKE_curvemapping_init(brush->curve);
|
||||||
|
|
||||||
/* Threaded loop over nodes. */
|
/* Threaded loop over nodes. */
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.offset = offset,
|
data.offset = offset;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -328,7 +326,7 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *area_no = data->area_no;
|
const float *area_no = data->area_no;
|
||||||
@ -416,14 +414,13 @@ void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
|||||||
mul_v3_fl(temp, displace);
|
mul_v3_fl(temp, displace);
|
||||||
add_v3_v3(area_co, temp);
|
add_v3_v3(area_co, temp);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.area_no = area_no,
|
data.area_no = area_no;
|
||||||
.area_co = area_co,
|
data.area_co = area_co;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -434,7 +431,7 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *area_no = data->area_no;
|
const float *area_no = data->area_no;
|
||||||
@ -521,14 +518,13 @@ void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
|
|||||||
mul_v3_fl(temp, displace);
|
mul_v3_fl(temp, displace);
|
||||||
add_v3_v3(area_co, temp);
|
add_v3_v3(area_co, temp);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.area_no = area_no,
|
data.area_no = area_no;
|
||||||
.area_co = area_co,
|
data.area_co = area_co;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -545,7 +541,7 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
float(*mat)[4] = data->mat;
|
float(*mat)[4] = data->mat;
|
||||||
@ -700,16 +696,15 @@ void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
|||||||
float clay_strength = ss->cache->bstrength *
|
float clay_strength = ss->cache->bstrength *
|
||||||
SCULPT_clay_thumb_get_stabilized_pressure(ss->cache);
|
SCULPT_clay_thumb_get_stabilized_pressure(ss->cache);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.area_no_sp = area_no_sp,
|
data.area_no_sp = area_no_sp;
|
||||||
.area_co = ss->cache->location,
|
data.area_co = ss->cache->location;
|
||||||
.mat = mat,
|
data.mat = mat;
|
||||||
.clay_strength = clay_strength,
|
data.clay_strength = clay_strength;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -726,7 +721,7 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *area_no = data->area_no;
|
const float *area_no = data->area_no;
|
||||||
@ -808,14 +803,13 @@ void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
|
|||||||
mul_v3_fl(temp, displace);
|
mul_v3_fl(temp, displace);
|
||||||
add_v3_v3(area_co, temp);
|
add_v3_v3(area_co, temp);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.area_no = area_no,
|
data.area_no = area_no;
|
||||||
.area_co = area_co,
|
data.area_co = area_co;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -828,18 +822,18 @@ void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
|
|||||||
/** \name Sculpt Clay Brush
|
/** \name Sculpt Clay Brush
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
typedef struct ClaySampleData {
|
struct ClaySampleData {
|
||||||
float plane_dist[2];
|
float plane_dist[2];
|
||||||
} ClaySampleData;
|
};
|
||||||
|
|
||||||
static void calc_clay_surface_task_cb(void *__restrict userdata,
|
static void calc_clay_surface_task_cb(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
ClaySampleData *csd = tls->userdata_chunk;
|
ClaySampleData *csd = static_cast<ClaySampleData *>(tls->userdata_chunk);
|
||||||
const float *area_no = data->area_no;
|
const float *area_no = data->area_no;
|
||||||
const float *area_co = data->area_co;
|
const float *area_co = data->area_co;
|
||||||
float plane[4];
|
float plane[4];
|
||||||
@ -877,12 +871,12 @@ static void calc_clay_surface_task_cb(void *__restrict userdata,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calc_clay_surface_reduce(const void *__restrict UNUSED(userdata),
|
static void calc_clay_surface_reduce(const void *__restrict /*userdata*/,
|
||||||
void *__restrict chunk_join,
|
void *__restrict chunk_join,
|
||||||
void *__restrict chunk)
|
void *__restrict chunk)
|
||||||
{
|
{
|
||||||
ClaySampleData *join = chunk_join;
|
ClaySampleData *join = static_cast<ClaySampleData *>(chunk_join);
|
||||||
ClaySampleData *csd = chunk;
|
ClaySampleData *csd = static_cast<ClaySampleData *>(chunk);
|
||||||
join->plane_dist[0] = MIN2(csd->plane_dist[0], join->plane_dist[0]);
|
join->plane_dist[0] = MIN2(csd->plane_dist[0], join->plane_dist[0]);
|
||||||
join->plane_dist[1] = MIN2(csd->plane_dist[1], join->plane_dist[1]);
|
join->plane_dist[1] = MIN2(csd->plane_dist[1], join->plane_dist[1]);
|
||||||
}
|
}
|
||||||
@ -891,7 +885,7 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *area_no = data->area_no;
|
const float *area_no = data->area_no;
|
||||||
@ -965,15 +959,14 @@ void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
|||||||
|
|
||||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
|
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
|
||||||
|
|
||||||
SculptThreadedTaskData sample_data = {
|
SculptThreadedTaskData sample_data{};
|
||||||
.sd = NULL,
|
sample_data.sd = nullptr;
|
||||||
.ob = ob,
|
sample_data.ob = ob;
|
||||||
.brush = brush,
|
sample_data.brush = brush;
|
||||||
.nodes = nodes,
|
sample_data.nodes = nodes;
|
||||||
.totnode = totnode,
|
sample_data.totnode = totnode;
|
||||||
.area_no = area_no,
|
sample_data.area_no = area_no;
|
||||||
.area_co = ss->cache->location,
|
sample_data.area_co = ss->cache->location;
|
||||||
};
|
|
||||||
|
|
||||||
ClaySampleData csd = {{0}};
|
ClaySampleData csd = {{0}};
|
||||||
|
|
||||||
@ -999,14 +992,13 @@ void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
|||||||
copy_v3_v3(area_co, ss->cache->location);
|
copy_v3_v3(area_co, ss->cache->location);
|
||||||
add_v3_v3(area_co, temp);
|
add_v3_v3(area_co, temp);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.area_no = area_no,
|
data.area_no = area_no;
|
||||||
.area_co = area_co,
|
data.area_co = area_co;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1017,7 +1009,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
float(*mat)[4] = data->mat;
|
float(*mat)[4] = data->mat;
|
||||||
@ -1159,15 +1151,14 @@ void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
|||||||
|
|
||||||
invert_m4_m4(mat, tmat);
|
invert_m4_m4(mat, tmat);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.area_no_sp = area_no_sp,
|
data.area_no_sp = area_no_sp;
|
||||||
.area_co = area_co,
|
data.area_co = area_co;
|
||||||
.mat = mat,
|
data.mat = mat;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1178,7 +1169,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
SculptProjectVector *spvc = data->spvc;
|
SculptProjectVector *spvc = data->spvc;
|
||||||
@ -1314,14 +1305,13 @@ void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
|||||||
sculpt_project_v3_cache_init(&spvc, grab_delta);
|
sculpt_project_v3_cache_init(&spvc, grab_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.spvc = &spvc,
|
data.spvc = &spvc;
|
||||||
.grab_delta = grab_delta,
|
data.grab_delta = grab_delta;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1332,7 +1322,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *cono = data->cono;
|
const float *cono = data->cono;
|
||||||
@ -1368,7 +1358,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
orig_data.co,
|
orig_data.co,
|
||||||
sqrtf(test.dist),
|
sqrtf(test.dist),
|
||||||
orig_data.no,
|
orig_data.no,
|
||||||
NULL,
|
nullptr,
|
||||||
vd.mask ? *vd.mask : 0.0f,
|
vd.mask ? *vd.mask : 0.0f,
|
||||||
vd.vertex,
|
vd.vertex,
|
||||||
thread_id,
|
thread_id,
|
||||||
@ -1395,13 +1385,12 @@ void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||||||
cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
|
cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
|
||||||
cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
|
cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.cono = cono,
|
data.cono = cono;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1412,7 +1401,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float angle = data->angle;
|
const float angle = data->angle;
|
||||||
@ -1450,7 +1439,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
orig_data.co,
|
orig_data.co,
|
||||||
sqrtf(test.dist),
|
sqrtf(test.dist),
|
||||||
orig_data.no,
|
orig_data.no,
|
||||||
NULL,
|
nullptr,
|
||||||
vd.mask ? *vd.mask : 0.0f,
|
vd.mask ? *vd.mask : 0.0f,
|
||||||
vd.vertex,
|
vd.vertex,
|
||||||
thread_id,
|
thread_id,
|
||||||
@ -1477,13 +1466,12 @@ void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
|
|||||||
static const int flip[8] = {1, -1, -1, 1, -1, 1, 1, -1};
|
static const int flip[8] = {1, -1, -1, 1, -1, 1, 1, -1};
|
||||||
const float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];
|
const float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.angle = angle,
|
data.angle = angle;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1494,7 +1482,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
Sculpt *sd = data->sd;
|
Sculpt *sd = data->sd;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
@ -1598,17 +1586,16 @@ void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||||
|
|
||||||
if (ss->cache->layer_displacement_factor == NULL) {
|
if (ss->cache->layer_displacement_factor == nullptr) {
|
||||||
ss->cache->layer_displacement_factor = MEM_callocN(sizeof(float) * SCULPT_vertex_count_get(ss),
|
ss->cache->layer_displacement_factor = MEM_cnew_array<float>(SCULPT_vertex_count_get(ss),
|
||||||
"layer displacement factor");
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1619,7 +1606,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
|
|
||||||
@ -1677,12 +1664,11 @@ void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
|
|||||||
{
|
{
|
||||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1693,7 +1679,7 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *cono = data->cono;
|
const float *cono = data->cono;
|
||||||
@ -1751,13 +1737,12 @@ void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||||||
cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
|
cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
|
||||||
cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
|
cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.cono = cono,
|
data.cono = cono;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1777,7 +1762,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
SculptProjectVector *spvc = data->spvc;
|
SculptProjectVector *spvc = data->spvc;
|
||||||
@ -1878,15 +1863,14 @@ void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
|
|||||||
sculpt_project_v3_cache_init(&spvc, ss->cache->sculpt_normal_symm);
|
sculpt_project_v3_cache_init(&spvc, ss->cache->sculpt_normal_symm);
|
||||||
|
|
||||||
/* Threaded loop over nodes. */
|
/* Threaded loop over nodes. */
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.spvc = &spvc,
|
data.spvc = &spvc;
|
||||||
.offset = offset,
|
data.offset = offset;
|
||||||
.flippedbstrength = flippedbstrength,
|
data.flippedbstrength = flippedbstrength;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -1897,7 +1881,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
float(*stroke_xz)[3] = data->stroke_xz;
|
float(*stroke_xz)[3] = data->stroke_xz;
|
||||||
@ -2001,13 +1985,12 @@ void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||||||
normalize_v3_v3(stroke_xz[0], mat[0]);
|
normalize_v3_v3(stroke_xz[0], mat[0]);
|
||||||
normalize_v3_v3(stroke_xz[1], mat[2]);
|
normalize_v3_v3(stroke_xz[1], mat[2]);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.stroke_xz = stroke_xz,
|
data.stroke_xz = stroke_xz;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -2018,7 +2001,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *grab_delta = data->grab_delta;
|
const float *grab_delta = data->grab_delta;
|
||||||
@ -2056,7 +2039,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
orig_data.co,
|
orig_data.co,
|
||||||
sqrtf(test.dist),
|
sqrtf(test.dist),
|
||||||
orig_data.no,
|
orig_data.no,
|
||||||
NULL,
|
nullptr,
|
||||||
vd.mask ? *vd.mask : 0.0f,
|
vd.mask ? *vd.mask : 0.0f,
|
||||||
vd.vertex,
|
vd.vertex,
|
||||||
thread_id,
|
thread_id,
|
||||||
@ -2094,13 +2077,12 @@ void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
|||||||
sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
|
sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.grab_delta = grab_delta,
|
data.grab_delta = grab_delta;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -2109,9 +2091,9 @@ void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
|||||||
|
|
||||||
static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
|
static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *grab_delta = data->grab_delta;
|
const float *grab_delta = data->grab_delta;
|
||||||
@ -2209,13 +2191,12 @@ void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
|
|||||||
sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
|
sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.grab_delta = grab_delta,
|
data.grab_delta = grab_delta;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -2232,7 +2213,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float *offset = data->offset;
|
const float *offset = data->offset;
|
||||||
@ -2267,7 +2248,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
orig_data.co,
|
orig_data.co,
|
||||||
sqrtf(test.dist),
|
sqrtf(test.dist),
|
||||||
orig_data.no,
|
orig_data.no,
|
||||||
NULL,
|
nullptr,
|
||||||
vd.mask ? *vd.mask : 0.0f,
|
vd.mask ? *vd.mask : 0.0f,
|
||||||
vd.vertex,
|
vd.vertex,
|
||||||
thread_id,
|
thread_id,
|
||||||
@ -2301,13 +2282,12 @@ void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
|||||||
BKE_curvemapping_init(brush->curve);
|
BKE_curvemapping_init(brush->curve);
|
||||||
|
|
||||||
/* Threaded loop over nodes. */
|
/* Threaded loop over nodes. */
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.offset = offset,
|
data.offset = offset;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -2324,7 +2304,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
|
|
||||||
@ -2357,7 +2337,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
|
|||||||
orig_data.co,
|
orig_data.co,
|
||||||
sqrtf(test.dist),
|
sqrtf(test.dist),
|
||||||
orig_data.no,
|
orig_data.no,
|
||||||
NULL,
|
nullptr,
|
||||||
vd.mask ? *vd.mask : 0.0f,
|
vd.mask ? *vd.mask : 0.0f,
|
||||||
vd.vertex,
|
vd.vertex,
|
||||||
thread_id,
|
thread_id,
|
||||||
@ -2488,7 +2468,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = ss->cache->bstrength;
|
const float bstrength = ss->cache->bstrength;
|
||||||
@ -2521,7 +2501,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata,
|
|||||||
orig_data.co,
|
orig_data.co,
|
||||||
sqrtf(test.dist),
|
sqrtf(test.dist),
|
||||||
orig_data.no,
|
orig_data.no,
|
||||||
NULL,
|
nullptr,
|
||||||
vd.mask ? *vd.mask : 0.0f,
|
vd.mask ? *vd.mask : 0.0f,
|
||||||
vd.vertex,
|
vd.vertex,
|
||||||
thread_id,
|
thread_id,
|
||||||
@ -2546,12 +2526,11 @@ void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
|||||||
|
|
||||||
BKE_curvemapping_init(brush->curve);
|
BKE_curvemapping_init(brush->curve);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -2576,7 +2555,7 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f);
|
const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f);
|
||||||
@ -2629,12 +2608,11 @@ void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **node
|
|||||||
BKE_curvemapping_init(brush->curve);
|
BKE_curvemapping_init(brush->curve);
|
||||||
|
|
||||||
/* Threaded loop over nodes. */
|
/* Threaded loop over nodes. */
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -2651,7 +2629,7 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f);
|
const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f);
|
||||||
@ -2743,9 +2721,9 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void do_displacement_smear_store_prev_disp_task_cb_ex(
|
static void do_displacement_smear_store_prev_disp_task_cb_ex(
|
||||||
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
|
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
|
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
@ -2766,9 +2744,10 @@ void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes
|
|||||||
|
|
||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
if (!ss->cache->prev_displacement) {
|
if (!ss->cache->prev_displacement) {
|
||||||
ss->cache->prev_displacement = MEM_malloc_arrayN(
|
ss->cache->prev_displacement = static_cast<float(*)[3]>(
|
||||||
totvert, sizeof(float[3]), "prev displacement");
|
MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__));
|
||||||
ss->cache->limit_surface_co = MEM_malloc_arrayN(totvert, sizeof(float[3]), "limit surface co");
|
ss->cache->limit_surface_co = static_cast<float(*)[3]>(
|
||||||
|
MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__));
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||||
|
|
||||||
@ -2779,12 +2758,11 @@ void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Threaded loop over nodes. */
|
/* Threaded loop over nodes. */
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -2803,7 +2781,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
Sculpt *sd = data->sd;
|
Sculpt *sd = data->sd;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
@ -2885,13 +2863,13 @@ void SCULPT_bmesh_topology_rake(
|
|||||||
|
|
||||||
for (iteration = 0; iteration <= count; iteration++) {
|
for (iteration = 0; iteration <= count; iteration++) {
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.strength = factor,
|
data.strength = factor;
|
||||||
};
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
|
|
||||||
@ -2909,7 +2887,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = ss->cache->bstrength;
|
const float bstrength = ss->cache->bstrength;
|
||||||
@ -2958,12 +2936,11 @@ void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
|
|||||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||||
|
|
||||||
/* Threaded loop over nodes. */
|
/* Threaded loop over nodes. */
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
@ -49,9 +49,9 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
static void cloth_brush_simulation_location_get(SculptSession *ss,
|
static void cloth_brush_simulation_location_get(SculptSession *ss,
|
||||||
const Brush *brush,
|
const Brush *brush,
|
||||||
@ -75,30 +75,28 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss,
|
|||||||
{
|
{
|
||||||
BLI_assert(ss->cache);
|
BLI_assert(ss->cache);
|
||||||
BLI_assert(brush->sculpt_tool == SCULPT_TOOL_CLOTH);
|
BLI_assert(brush->sculpt_tool == SCULPT_TOOL_CLOTH);
|
||||||
PBVHNode **nodes = NULL;
|
PBVHNode **nodes = nullptr;
|
||||||
|
|
||||||
switch (brush->cloth_simulation_area_type) {
|
switch (brush->cloth_simulation_area_type) {
|
||||||
case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: {
|
case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: {
|
||||||
SculptSearchSphereData data = {
|
SculptSearchSphereData data{};
|
||||||
.ss = ss,
|
data.ss = ss;
|
||||||
.radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)),
|
data.radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit));
|
||||||
.original = false,
|
data.original = false;
|
||||||
.ignore_fully_ineffective = false,
|
data.ignore_fully_ineffective = false;
|
||||||
.center = ss->cache->initial_location,
|
data.center = ss->cache->initial_location;
|
||||||
};
|
|
||||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
|
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
|
||||||
} break;
|
} break;
|
||||||
case BRUSH_CLOTH_SIMULATION_AREA_GLOBAL:
|
case BRUSH_CLOTH_SIMULATION_AREA_GLOBAL:
|
||||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, r_totnode);
|
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, r_totnode);
|
||||||
break;
|
break;
|
||||||
case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: {
|
case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: {
|
||||||
SculptSearchSphereData data = {
|
SculptSearchSphereData data{};
|
||||||
.ss = ss,
|
data.ss = ss;
|
||||||
.radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)),
|
data.radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit));
|
||||||
.original = false,
|
data.original = false;
|
||||||
.ignore_fully_ineffective = false,
|
data.ignore_fully_ineffective = false;
|
||||||
.center = ss->cache->location,
|
data.center = ss->cache->location;
|
||||||
};
|
|
||||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
|
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -159,10 +157,10 @@ static void cloth_brush_reallocate_constraints(SculptClothSimulation *cloth_sim)
|
|||||||
{
|
{
|
||||||
if (cloth_sim->tot_length_constraints >= cloth_sim->capacity_length_constraints) {
|
if (cloth_sim->tot_length_constraints >= cloth_sim->capacity_length_constraints) {
|
||||||
cloth_sim->capacity_length_constraints += CLOTH_LENGTH_CONSTRAINTS_BLOCK;
|
cloth_sim->capacity_length_constraints += CLOTH_LENGTH_CONSTRAINTS_BLOCK;
|
||||||
cloth_sim->length_constraints = MEM_reallocN_id(cloth_sim->length_constraints,
|
cloth_sim->length_constraints = static_cast<SculptClothLengthConstraint *>(MEM_reallocN_id(
|
||||||
cloth_sim->capacity_length_constraints *
|
cloth_sim->length_constraints,
|
||||||
sizeof(SculptClothLengthConstraint),
|
cloth_sim->capacity_length_constraints * sizeof(SculptClothLengthConstraint),
|
||||||
"length constraints");
|
"length constraints"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,10 +287,11 @@ static void cloth_brush_add_deformation_constraint(SculptClothSimulation *cloth_
|
|||||||
cloth_brush_reallocate_constraints(cloth_sim);
|
cloth_brush_reallocate_constraints(cloth_sim);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_cloth_brush_build_constraints_task_cb_ex(
|
static void do_cloth_brush_build_constraints_task_cb_ex(void *__restrict userdata,
|
||||||
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
|
const int n,
|
||||||
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
PBVHNode *node = data->nodes[n];
|
PBVHNode *node = data->nodes[n];
|
||||||
@ -305,16 +304,16 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
|
|||||||
|
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
|
|
||||||
const bool pin_simulation_boundary = ss->cache != NULL && brush != NULL &&
|
const bool pin_simulation_boundary = ss->cache != nullptr && brush != nullptr &&
|
||||||
brush->flag2 & BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY &&
|
brush->flag2 & BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY &&
|
||||||
brush->cloth_simulation_area_type !=
|
brush->cloth_simulation_area_type !=
|
||||||
BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC;
|
BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC;
|
||||||
|
|
||||||
const bool use_persistent = brush != NULL && brush->flag & BRUSH_PERSISTENT;
|
const bool use_persistent = brush != nullptr && brush->flag & BRUSH_PERSISTENT;
|
||||||
|
|
||||||
/* Brush can be NULL in tools that use the solver without relying of constraints with deformation
|
/* Brush can be nullptr in tools that use the solver without relying of constraints with
|
||||||
* positions. */
|
* deformation positions. */
|
||||||
const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL &&
|
const bool cloth_is_deform_brush = ss->cache != nullptr && brush != nullptr &&
|
||||||
SCULPT_is_cloth_deform_brush(brush);
|
SCULPT_is_cloth_deform_brush(brush);
|
||||||
|
|
||||||
const bool use_falloff_plane = brush->cloth_force_falloff_type ==
|
const bool use_falloff_plane = brush->cloth_force_falloff_type ==
|
||||||
@ -417,7 +416,7 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
|
|||||||
BKE_pbvh_vertex_iter_end;
|
BKE_pbvh_vertex_iter_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cloth_brush_apply_force_to_vertex(SculptSession *UNUSED(ss),
|
static void cloth_brush_apply_force_to_vertex(SculptSession * /*ss*/,
|
||||||
SculptClothSimulation *cloth_sim,
|
SculptClothSimulation *cloth_sim,
|
||||||
const float force[3],
|
const float force[3],
|
||||||
const int vertex_index)
|
const int vertex_index)
|
||||||
@ -429,7 +428,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
SculptClothSimulation *cloth_sim = ss->cache->cloth_sim;
|
SculptClothSimulation *cloth_sim = ss->cache->cloth_sim;
|
||||||
@ -589,7 +588,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
|
|||||||
|
|
||||||
static ListBase *cloth_brush_collider_cache_create(Object *object, Depsgraph *depsgraph)
|
static ListBase *cloth_brush_collider_cache_create(Object *object, Depsgraph *depsgraph)
|
||||||
{
|
{
|
||||||
ListBase *cache = NULL;
|
ListBase *cache = nullptr;
|
||||||
DEGObjectIterSettings deg_iter_settings = {0};
|
DEGObjectIterSettings deg_iter_settings = {0};
|
||||||
deg_iter_settings.depsgraph = depsgraph;
|
deg_iter_settings.depsgraph = depsgraph;
|
||||||
deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
|
deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
|
||||||
@ -608,11 +607,11 @@ static ListBase *cloth_brush_collider_cache_create(Object *object, Depsgraph *de
|
|||||||
if (!cmd->bvhtree) {
|
if (!cmd->bvhtree) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cache == NULL) {
|
if (cache == nullptr) {
|
||||||
cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
|
cache = MEM_cnew<ListBase>(__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
|
ColliderCache *col = MEM_cnew<ColliderCache>(__func__);
|
||||||
col->ob = ob;
|
col->ob = ob;
|
||||||
col->collmd = cmd;
|
col->collmd = cmd;
|
||||||
collision_move_object(cmd, 1.0, 0.0, true);
|
collision_move_object(cmd, 1.0, 0.0, true);
|
||||||
@ -622,10 +621,10 @@ static ListBase *cloth_brush_collider_cache_create(Object *object, Depsgraph *de
|
|||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct ClothBrushCollision {
|
struct ClothBrushCollision {
|
||||||
CollisionModifierData *col_data;
|
CollisionModifierData *col_data;
|
||||||
struct IsectRayPrecalc isect_precalc;
|
IsectRayPrecalc isect_precalc;
|
||||||
} ClothBrushCollision;
|
};
|
||||||
|
|
||||||
static void cloth_brush_collision_cb(void *userdata,
|
static void cloth_brush_collision_cb(void *userdata,
|
||||||
int index,
|
int index,
|
||||||
@ -644,7 +643,7 @@ static void cloth_brush_collision_cb(void *userdata,
|
|||||||
float dist = 0.0f;
|
float dist = 0.0f;
|
||||||
|
|
||||||
bool tri_hit = isect_ray_tri_watertight_v3(
|
bool tri_hit = isect_ray_tri_watertight_v3(
|
||||||
ray->origin, &col->isect_precalc, UNPACK3(tri), &dist, NULL);
|
ray->origin, &col->isect_precalc, UNPACK3(tri), &dist, nullptr);
|
||||||
normal_tri_v3(no, UNPACK3(tri));
|
normal_tri_v3(no, UNPACK3(tri));
|
||||||
madd_v3_v3v3fl(co, ray->origin, ray->direction, dist);
|
madd_v3_v3v3fl(co, ray->origin, ray->direction, dist);
|
||||||
|
|
||||||
@ -669,7 +668,8 @@ static void cloth_brush_solve_collision(Object *object,
|
|||||||
float obmat_inv[4][4];
|
float obmat_inv[4][4];
|
||||||
invert_m4_m4(obmat_inv, object->object_to_world);
|
invert_m4_m4(obmat_inv, object->object_to_world);
|
||||||
|
|
||||||
for (collider_cache = cloth_sim->collider_list->first; collider_cache;
|
for (collider_cache = static_cast<ColliderCache *>(cloth_sim->collider_list->first);
|
||||||
|
collider_cache;
|
||||||
collider_cache = collider_cache->next) {
|
collider_cache = collider_cache->next) {
|
||||||
float ray_start[3], ray_normal[3];
|
float ray_start[3], ray_normal[3];
|
||||||
float pos_world_space[3], prev_pos_world_space[3];
|
float pos_world_space[3], prev_pos_world_space[3];
|
||||||
@ -720,10 +720,11 @@ static void cloth_brush_solve_collision(Object *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_cloth_brush_solve_simulation_task_cb_ex(
|
static void do_cloth_brush_solve_simulation_task_cb_ex(void *__restrict userdata,
|
||||||
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
|
const int n,
|
||||||
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
|
|
||||||
@ -771,7 +772,7 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
|
|||||||
madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
|
madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
|
||||||
madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
|
madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
|
||||||
|
|
||||||
if (cloth_sim->collider_list != NULL) {
|
if (cloth_sim->collider_list != nullptr) {
|
||||||
cloth_brush_solve_collision(data->ob, cloth_sim, i);
|
cloth_brush_solve_collision(data->ob, cloth_sim, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -910,14 +911,13 @@ void SCULPT_cloth_brush_do_simulation_step(
|
|||||||
cloth_brush_satisfy_constraints(ss, brush, cloth_sim);
|
cloth_brush_satisfy_constraints(ss, brush, cloth_sim);
|
||||||
|
|
||||||
/* Solve the simulation and write the final step to the mesh. */
|
/* Solve the simulation and write the final step to the mesh. */
|
||||||
SculptThreadedTaskData solve_simulation_data = {
|
SculptThreadedTaskData solve_simulation_data{};
|
||||||
.sd = sd,
|
solve_simulation_data.sd = sd;
|
||||||
.ob = ob,
|
solve_simulation_data.ob = ob;
|
||||||
.brush = brush,
|
solve_simulation_data.brush = brush;
|
||||||
.nodes = nodes,
|
solve_simulation_data.nodes = nodes;
|
||||||
.cloth_time_step = CLOTH_SIMULATION_TIME_STEP,
|
solve_simulation_data.cloth_time_step = CLOTH_SIMULATION_TIME_STEP;
|
||||||
.cloth_sim = cloth_sim,
|
solve_simulation_data.cloth_sim = cloth_sim;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -937,15 +937,14 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
|
|||||||
float imat[4][4];
|
float imat[4][4];
|
||||||
float offset[3];
|
float offset[3];
|
||||||
|
|
||||||
SculptThreadedTaskData apply_forces_data = {
|
SculptThreadedTaskData apply_forces_data{};
|
||||||
.sd = sd,
|
apply_forces_data.sd = sd;
|
||||||
.ob = ob,
|
apply_forces_data.ob = ob;
|
||||||
.brush = brush,
|
apply_forces_data.brush = brush;
|
||||||
.nodes = nodes,
|
apply_forces_data.nodes = nodes;
|
||||||
.area_no = area_no,
|
apply_forces_data.area_no = area_no;
|
||||||
.area_co = area_co,
|
apply_forces_data.area_co = area_co;
|
||||||
.mat = imat,
|
apply_forces_data.mat = imat;
|
||||||
};
|
|
||||||
|
|
||||||
BKE_curvemapping_init(brush->curve);
|
BKE_curvemapping_init(brush->curve);
|
||||||
|
|
||||||
@ -1016,10 +1015,10 @@ static void cloth_sim_initialize_default_node_state(SculptSession *ss,
|
|||||||
{
|
{
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
int totnode;
|
int totnode;
|
||||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
|
|
||||||
cloth_sim->node_state = MEM_malloc_arrayN(
|
cloth_sim->node_state = static_cast<eSculptClothNodeSimState *>(
|
||||||
totnode, sizeof(eSculptClothNodeSimState), "node sim state");
|
MEM_malloc_arrayN(totnode, sizeof(eSculptClothNodeSimState), "node sim state"));
|
||||||
cloth_sim->node_state_index = BLI_ghash_ptr_new("node sim state indices");
|
cloth_sim->node_state_index = BLI_ghash_ptr_new("node sim state indices");
|
||||||
for (int i = 0; i < totnode; i++) {
|
for (int i = 0; i < totnode; i++) {
|
||||||
cloth_sim->node_state[i] = SCULPT_CLOTH_NODE_UNINITIALIZED;
|
cloth_sim->node_state[i] = SCULPT_CLOTH_NODE_UNINITIALIZED;
|
||||||
@ -1039,34 +1038,27 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob,
|
|||||||
const int totverts = SCULPT_vertex_count_get(ss);
|
const int totverts = SCULPT_vertex_count_get(ss);
|
||||||
SculptClothSimulation *cloth_sim;
|
SculptClothSimulation *cloth_sim;
|
||||||
|
|
||||||
cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints");
|
cloth_sim = MEM_cnew<SculptClothSimulation>(__func__);
|
||||||
|
|
||||||
cloth_sim->length_constraints = MEM_callocN(sizeof(SculptClothLengthConstraint) *
|
cloth_sim->length_constraints = MEM_cnew_array<SculptClothLengthConstraint>(
|
||||||
CLOTH_LENGTH_CONSTRAINTS_BLOCK,
|
CLOTH_LENGTH_CONSTRAINTS_BLOCK, __func__);
|
||||||
"cloth length constraints");
|
|
||||||
cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK;
|
cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK;
|
||||||
|
|
||||||
cloth_sim->acceleration = MEM_calloc_arrayN(
|
cloth_sim->acceleration = MEM_cnew_array<float[3]>(totverts, __func__);
|
||||||
totverts, sizeof(float[3]), "cloth sim acceleration");
|
cloth_sim->pos = MEM_cnew_array<float[3]>(totverts, __func__);
|
||||||
cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos");
|
cloth_sim->prev_pos = MEM_cnew_array<float[3]>(totverts, __func__);
|
||||||
cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim prev pos");
|
cloth_sim->last_iteration_pos = MEM_cnew_array<float[3]>(totverts, __func__);
|
||||||
cloth_sim->last_iteration_pos = MEM_calloc_arrayN(
|
cloth_sim->init_pos = MEM_cnew_array<float[3]>(totverts, __func__);
|
||||||
totverts, sizeof(float[3]), "cloth sim last iteration pos");
|
cloth_sim->init_no = MEM_cnew_array<float[3]>(totverts, __func__);
|
||||||
cloth_sim->init_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init pos");
|
cloth_sim->length_constraint_tweak = MEM_cnew_array<float>(totverts, __func__);
|
||||||
cloth_sim->init_no = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init normals");
|
|
||||||
cloth_sim->length_constraint_tweak = MEM_calloc_arrayN(
|
|
||||||
totverts, sizeof(float), "cloth sim length tweak");
|
|
||||||
|
|
||||||
if (needs_deform_coords) {
|
if (needs_deform_coords) {
|
||||||
cloth_sim->deformation_pos = MEM_calloc_arrayN(
|
cloth_sim->deformation_pos = MEM_cnew_array<float[3]>(totverts, __func__);
|
||||||
totverts, sizeof(float[3]), "cloth sim deformation positions");
|
cloth_sim->deformation_strength = MEM_cnew_array<float>(totverts, __func__);
|
||||||
cloth_sim->deformation_strength = MEM_calloc_arrayN(
|
|
||||||
totverts, sizeof(float), "cloth sim deformation strength");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cloth_softbody_strength > 0.0f) {
|
if (cloth_softbody_strength > 0.0f) {
|
||||||
cloth_sim->softbody_pos = MEM_calloc_arrayN(
|
cloth_sim->softbody_pos = MEM_cnew_array<float[3]>(totverts, __func__);
|
||||||
totverts, sizeof(float[3]), "cloth sim softbody pos");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cloth_sim->mass = cloth_mass;
|
cloth_sim->mass = cloth_mass;
|
||||||
@ -1104,15 +1096,15 @@ void SCULPT_cloth_brush_ensure_nodes_constraints(
|
|||||||
|
|
||||||
cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints");
|
cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints");
|
||||||
|
|
||||||
SculptThreadedTaskData build_constraints_data = {
|
SculptThreadedTaskData build_constraints_data{};
|
||||||
.sd = sd,
|
build_constraints_data.sd = sd;
|
||||||
.ob = ob,
|
build_constraints_data.ob = ob;
|
||||||
.brush = brush,
|
build_constraints_data.brush = brush;
|
||||||
.nodes = nodes,
|
build_constraints_data.nodes = nodes;
|
||||||
.cloth_sim = cloth_sim,
|
build_constraints_data.cloth_sim = cloth_sim;
|
||||||
.cloth_sim_initial_location = initial_location,
|
build_constraints_data.cloth_sim_initial_location = initial_location;
|
||||||
.cloth_sim_radius = radius,
|
build_constraints_data.cloth_sim_radius = radius;
|
||||||
};
|
|
||||||
BLI_task_parallel_range(
|
BLI_task_parallel_range(
|
||||||
0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings);
|
0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings);
|
||||||
|
|
||||||
@ -1122,8 +1114,8 @@ void SCULPT_cloth_brush_ensure_nodes_constraints(
|
|||||||
void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim)
|
void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim)
|
||||||
{
|
{
|
||||||
const int totverts = SCULPT_vertex_count_get(ss);
|
const int totverts = SCULPT_vertex_count_get(ss);
|
||||||
const bool has_deformation_pos = cloth_sim->deformation_pos != NULL;
|
const bool has_deformation_pos = cloth_sim->deformation_pos != nullptr;
|
||||||
const bool has_softbody_pos = cloth_sim->softbody_pos != NULL;
|
const bool has_softbody_pos = cloth_sim->softbody_pos != nullptr;
|
||||||
for (int i = 0; i < totverts; i++) {
|
for (int i = 0; i < totverts; i++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||||
|
|
||||||
@ -1232,7 +1224,7 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||||||
SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
|
SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim)
|
void SCULPT_cloth_simulation_free(SculptClothSimulation *cloth_sim)
|
||||||
{
|
{
|
||||||
MEM_SAFE_FREE(cloth_sim->pos);
|
MEM_SAFE_FREE(cloth_sim->pos);
|
||||||
MEM_SAFE_FREE(cloth_sim->last_iteration_pos);
|
MEM_SAFE_FREE(cloth_sim->last_iteration_pos);
|
||||||
@ -1246,7 +1238,7 @@ void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim)
|
|||||||
MEM_SAFE_FREE(cloth_sim->init_no);
|
MEM_SAFE_FREE(cloth_sim->init_no);
|
||||||
MEM_SAFE_FREE(cloth_sim->deformation_strength);
|
MEM_SAFE_FREE(cloth_sim->deformation_strength);
|
||||||
MEM_SAFE_FREE(cloth_sim->node_state);
|
MEM_SAFE_FREE(cloth_sim->node_state);
|
||||||
BLI_ghash_free(cloth_sim->node_state_index, NULL, NULL);
|
BLI_ghash_free(cloth_sim->node_state_index, nullptr, nullptr);
|
||||||
if (cloth_sim->collider_list) {
|
if (cloth_sim->collider_list) {
|
||||||
BKE_collider_cache_free(&cloth_sim->collider_list);
|
BKE_collider_cache_free(&cloth_sim->collider_list);
|
||||||
}
|
}
|
||||||
@ -1339,7 +1331,7 @@ static EnumPropertyItem prop_cloth_filter_type[] = {
|
|||||||
0,
|
0,
|
||||||
"Scale",
|
"Scale",
|
||||||
"Scales the mesh as a soft body using the origin of the object as scale"},
|
"Scales the mesh as a soft body using the origin of the object as scale"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static EnumPropertyItem prop_cloth_filter_orientation_items[] = {
|
static EnumPropertyItem prop_cloth_filter_orientation_items[] = {
|
||||||
@ -1358,7 +1350,7 @@ static EnumPropertyItem prop_cloth_filter_orientation_items[] = {
|
|||||||
0,
|
0,
|
||||||
"View",
|
"View",
|
||||||
"Use the view axis to limit the force and set the gravity direction"},
|
"Use the view axis to limit the force and set the gravity direction"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum eClothFilterForceAxis {
|
typedef enum eClothFilterForceAxis {
|
||||||
@ -1371,7 +1363,7 @@ static EnumPropertyItem prop_cloth_filter_force_axis_items[] = {
|
|||||||
{CLOTH_FILTER_FORCE_X, "X", 0, "X", "Apply force in the X axis"},
|
{CLOTH_FILTER_FORCE_X, "X", 0, "X", "Apply force in the X axis"},
|
||||||
{CLOTH_FILTER_FORCE_Y, "Y", 0, "Y", "Apply force in the Y axis"},
|
{CLOTH_FILTER_FORCE_Y, "Y", 0, "Y", "Apply force in the Y axis"},
|
||||||
{CLOTH_FILTER_FORCE_Z, "Z", 0, "Z", "Apply force in the Z axis"},
|
{CLOTH_FILTER_FORCE_Z, "Z", 0, "Z", "Apply force in the Z axis"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool cloth_filter_is_deformation_filter(eSculptClothFilterType filter_type)
|
static bool cloth_filter_is_deformation_filter(eSculptClothFilterType filter_type)
|
||||||
@ -1400,21 +1392,21 @@ static void cloth_filter_apply_forces_to_vertices(const int v_index,
|
|||||||
copy_v3_v3(final_force, force);
|
copy_v3_v3(final_force, force);
|
||||||
SCULPT_filter_zero_disabled_axis_components(final_force, filter_cache);
|
SCULPT_filter_zero_disabled_axis_components(final_force, filter_cache);
|
||||||
add_v3_v3(final_force, gravity);
|
add_v3_v3(final_force, gravity);
|
||||||
cloth_brush_apply_force_to_vertex(NULL, filter_cache->cloth_sim, final_force, v_index);
|
cloth_brush_apply_force_to_vertex(nullptr, filter_cache->cloth_sim, final_force, v_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
|
static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
|
||||||
const int i,
|
const int i,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
Sculpt *sd = data->sd;
|
Sculpt *sd = data->sd;
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
|
|
||||||
SculptClothSimulation *cloth_sim = ss->filter_cache->cloth_sim;
|
SculptClothSimulation *cloth_sim = ss->filter_cache->cloth_sim;
|
||||||
|
|
||||||
const eSculptClothFilterType filter_type = data->filter_type;
|
const eSculptClothFilterType filter_type = eSculptClothFilterType(data->filter_type);
|
||||||
const bool is_deformation_filter = cloth_filter_is_deformation_filter(filter_type);
|
const bool is_deformation_filter = cloth_filter_is_deformation_filter(filter_type);
|
||||||
|
|
||||||
float sculpt_gravity[3] = {0.0f};
|
float sculpt_gravity[3] = {0.0f};
|
||||||
@ -1530,13 +1522,12 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
|
|||||||
copy_v3_v3(ss->filter_cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, vertex));
|
copy_v3_v3(ss->filter_cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, vertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = ss->filter_cache->nodes,
|
data.nodes = ss->filter_cache->nodes;
|
||||||
.filter_type = filter_type,
|
data.filter_type = filter_type;
|
||||||
.filter_strength = filter_strength,
|
data.filter_strength = filter_strength;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||||
@ -1565,10 +1556,10 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
|
|
||||||
const eSculptClothFilterType filter_type = RNA_enum_get(op->ptr, "type");
|
const eSculptClothFilterType filter_type = eSculptClothFilterType(RNA_enum_get(op->ptr, "type"));
|
||||||
|
|
||||||
/* Update the active vertex */
|
/* Update the active vertex */
|
||||||
float mval_fl[2] = {UNPACK2(event->mval)};
|
float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||||
SculptCursorGeometryInfo sgi;
|
SculptCursorGeometryInfo sgi;
|
||||||
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
||||||
|
|
||||||
@ -1583,7 +1574,7 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
SCULPT_filter_cache_init(
|
SCULPT_filter_cache_init(
|
||||||
C, ob, sd, SCULPT_UNDO_COORDS, event->mval, RNA_float_get(op->ptr, "area_normal_radius"));
|
C, ob, sd, SCULPT_UNDO_COORDS, event->mval, RNA_float_get(op->ptr, "area_normal_radius"));
|
||||||
|
|
||||||
ss->filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob);
|
ss->filter_cache->automasking = SCULPT_automasking_cache_init(sd, nullptr, ob);
|
||||||
|
|
||||||
const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass");
|
const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass");
|
||||||
const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping");
|
const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping");
|
||||||
@ -1622,14 +1613,15 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
ss->filter_cache->enabled_force_axis[1] = force_axis & CLOTH_FILTER_FORCE_Y;
|
ss->filter_cache->enabled_force_axis[1] = force_axis & CLOTH_FILTER_FORCE_Y;
|
||||||
ss->filter_cache->enabled_force_axis[2] = force_axis & CLOTH_FILTER_FORCE_Z;
|
ss->filter_cache->enabled_force_axis[2] = force_axis & CLOTH_FILTER_FORCE_Z;
|
||||||
|
|
||||||
SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation");
|
SculptFilterOrientation orientation = SculptFilterOrientation(
|
||||||
|
RNA_enum_get(op->ptr, "orientation"));
|
||||||
ss->filter_cache->orientation = orientation;
|
ss->filter_cache->orientation = orientation;
|
||||||
|
|
||||||
WM_event_add_modal_handler(C, op);
|
WM_event_add_modal_handler(C, op);
|
||||||
return OPERATOR_RUNNING_MODAL;
|
return OPERATOR_RUNNING_MODAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_OT_cloth_filter(struct wmOperatorType *ot)
|
void SCULPT_OT_cloth_filter(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
/* Identifiers. */
|
/* Identifiers. */
|
||||||
ot->name = "Filter Cloth";
|
ot->name = "Filter Cloth";
|
@ -37,21 +37,21 @@
|
|||||||
#include "RNA_access.h"
|
#include "RNA_access.h"
|
||||||
#include "RNA_define.h"
|
#include "RNA_define.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Internal Utilities
|
/** \name Internal Utilities
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
typedef struct {
|
struct SculptDetailRaycastData {
|
||||||
const float *ray_start;
|
const float *ray_start;
|
||||||
bool hit;
|
bool hit;
|
||||||
float depth;
|
float depth;
|
||||||
float edge_length;
|
float edge_length;
|
||||||
|
|
||||||
struct IsectRayPrecalc isect_precalc;
|
IsectRayPrecalc isect_precalc;
|
||||||
} SculptDetailRaycastData;
|
};
|
||||||
|
|
||||||
static bool sculpt_and_constant_or_manual_detail_poll(bContext *C)
|
static bool sculpt_and_constant_or_manual_detail_poll(bContext *C)
|
||||||
{
|
{
|
||||||
@ -85,7 +85,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
|
|||||||
int totnodes;
|
int totnodes;
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
|
|
||||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnodes);
|
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnodes);
|
||||||
|
|
||||||
if (!totnodes) {
|
if (!totnodes) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
@ -107,10 +107,10 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
|
|||||||
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
|
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
|
||||||
|
|
||||||
SCULPT_undo_push_begin(ob, op);
|
SCULPT_undo_push_begin(ob, op);
|
||||||
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS);
|
SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_COORDS);
|
||||||
|
|
||||||
while (BKE_pbvh_bmesh_update_topology(
|
while (BKE_pbvh_bmesh_update_topology(
|
||||||
ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, NULL, size, false, false)) {
|
ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, nullptr, size, false, false)) {
|
||||||
for (int i = 0; i < totnodes; i++) {
|
for (int i = 0; i < totnodes; i++) {
|
||||||
BKE_pbvh_node_mark_topology_update(nodes[i]);
|
BKE_pbvh_node_mark_topology_update(nodes[i]);
|
||||||
}
|
}
|
||||||
@ -155,21 +155,21 @@ typedef enum eSculptSampleDetailModeTypes {
|
|||||||
static EnumPropertyItem prop_sculpt_sample_detail_mode_types[] = {
|
static EnumPropertyItem prop_sculpt_sample_detail_mode_types[] = {
|
||||||
{SAMPLE_DETAIL_DYNTOPO, "DYNTOPO", 0, "Dyntopo", "Sample dyntopo detail"},
|
{SAMPLE_DETAIL_DYNTOPO, "DYNTOPO", 0, "Dyntopo", "Sample dyntopo detail"},
|
||||||
{SAMPLE_DETAIL_VOXEL, "VOXEL", 0, "Voxel", "Sample mesh voxel size"},
|
{SAMPLE_DETAIL_VOXEL, "VOXEL", 0, "Voxel", "Sample mesh voxel size"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sample_detail_voxel(bContext *C, ViewContext *vc, const int mval[2])
|
static void sample_detail_voxel(bContext *C, ViewContext *vc, const int mval[2])
|
||||||
{
|
{
|
||||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||||
Object *ob = vc->obact;
|
Object *ob = vc->obact;
|
||||||
Mesh *mesh = ob->data;
|
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||||
|
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
SculptCursorGeometryInfo sgi;
|
SculptCursorGeometryInfo sgi;
|
||||||
SCULPT_vertex_random_access_ensure(ss);
|
SCULPT_vertex_random_access_ensure(ss);
|
||||||
|
|
||||||
/* Update the active vertex. */
|
/* Update the active vertex. */
|
||||||
const float mval_fl[2] = {UNPACK2(mval)};
|
const float mval_fl[2] = {float(mval[0]), float(mval[1])};
|
||||||
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
||||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
|
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
|
||||||
|
|
||||||
@ -185,14 +185,14 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, const int mval[2])
|
|||||||
}
|
}
|
||||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||||
if (tot > 0) {
|
if (tot > 0) {
|
||||||
mesh->remesh_voxel_size = edge_length / (float)tot;
|
mesh->remesh_voxel_size = edge_length / float(tot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin)
|
static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin)
|
||||||
{
|
{
|
||||||
if (BKE_pbvh_node_get_tmin(node) < *tmin) {
|
if (BKE_pbvh_node_get_tmin(node) < *tmin) {
|
||||||
SculptDetailRaycastData *srd = data_v;
|
SculptDetailRaycastData *srd = static_cast<SculptDetailRaycastData *>(data_v);
|
||||||
if (BKE_pbvh_bmesh_node_raycast_detail(
|
if (BKE_pbvh_bmesh_node_raycast_detail(
|
||||||
node, srd->ray_start, &srd->isect_precalc, &srd->depth, &srd->edge_length)) {
|
node, srd->ray_start, &srd->isect_precalc, &srd->depth, &srd->edge_length)) {
|
||||||
srd->hit = true;
|
srd->hit = true;
|
||||||
@ -209,7 +209,7 @@ static void sample_detail_dyntopo(bContext *C, ViewContext *vc, const int mval[2
|
|||||||
|
|
||||||
SCULPT_stroke_modifiers_check(C, ob, brush);
|
SCULPT_stroke_modifiers_check(C, ob, brush);
|
||||||
|
|
||||||
const float mval_fl[2] = {UNPACK2(mval)};
|
const float mval_fl[2] = {float(mval[0]), float(mval[1])};
|
||||||
float ray_start[3], ray_end[3], ray_normal[3];
|
float ray_start[3], ray_end[3], ray_normal[3];
|
||||||
float depth = SCULPT_raycast_init(vc, mval_fl, ray_start, ray_end, ray_normal, false);
|
float depth = SCULPT_raycast_init(vc, mval_fl, ray_start, ray_end, ray_normal, false);
|
||||||
|
|
||||||
@ -233,8 +233,8 @@ static int sample_detail(bContext *C, const int event_xy[2], int mode)
|
|||||||
/* Find 3D view to pick from. */
|
/* Find 3D view to pick from. */
|
||||||
bScreen *screen = CTX_wm_screen(C);
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, event_xy);
|
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, event_xy);
|
||||||
ARegion *region = (area) ? BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, event_xy) : NULL;
|
ARegion *region = (area) ? BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, event_xy) : nullptr;
|
||||||
if (region == NULL) {
|
if (region == nullptr) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ static int sample_detail(bContext *C, const int event_xy[2], int mode)
|
|||||||
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
||||||
|
|
||||||
Object *ob = vc.obact;
|
Object *ob = vc.obact;
|
||||||
if (ob == NULL) {
|
if (ob == nullptr) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ static int sculpt_sample_detail_size_exec(bContext *C, wmOperator *op)
|
|||||||
return sample_detail(C, ss_co, mode);
|
return sample_detail(C, ss_co, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sculpt_sample_detail_size_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e))
|
static int sculpt_sample_detail_size_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||||
{
|
{
|
||||||
ED_workspace_status_text(C, TIP_("Click on the mesh to set the detail"));
|
ED_workspace_status_text(C, TIP_("Click on the mesh to set the detail"));
|
||||||
WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
|
WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
|
||||||
@ -316,8 +316,8 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm
|
|||||||
|
|
||||||
RNA_int_set_array(op->ptr, "location", event->xy);
|
RNA_int_set_array(op->ptr, "location", event->xy);
|
||||||
WM_cursor_modal_restore(CTX_wm_window(C));
|
WM_cursor_modal_restore(CTX_wm_window(C));
|
||||||
ED_workspace_status_text(C, NULL);
|
ED_workspace_status_text(C, nullptr);
|
||||||
WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
|
WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, nullptr);
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
@ -325,7 +325,7 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm
|
|||||||
case EVT_ESCKEY:
|
case EVT_ESCKEY:
|
||||||
case RIGHTMOUSE: {
|
case RIGHTMOUSE: {
|
||||||
WM_cursor_modal_restore(CTX_wm_window(C));
|
WM_cursor_modal_restore(CTX_wm_window(C));
|
||||||
ED_workspace_status_text(C, NULL);
|
ED_workspace_status_text(C, nullptr);
|
||||||
|
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
|
|||||||
RNA_def_int_array(ot->srna,
|
RNA_def_int_array(ot->srna,
|
||||||
"location",
|
"location",
|
||||||
2,
|
2,
|
||||||
NULL,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
SHRT_MAX,
|
SHRT_MAX,
|
||||||
"Location",
|
"Location",
|
||||||
@ -409,12 +409,12 @@ static void sculpt_detail_size_set_radial_control(bContext *C)
|
|||||||
RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_size");
|
RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_size");
|
||||||
}
|
}
|
||||||
|
|
||||||
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, NULL);
|
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, nullptr);
|
||||||
|
|
||||||
WM_operator_properties_free(&props_ptr);
|
WM_operator_properties_free(&props_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sculpt_set_detail_size_exec(bContext *C, wmOperator *UNUSED(op))
|
static int sculpt_set_detail_size_exec(bContext *C, wmOperator * /*op*/)
|
||||||
{
|
{
|
||||||
sculpt_detail_size_set_radial_control(C);
|
sculpt_detail_size_set_radial_control(C);
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ void SCULPT_OT_set_detail_size(wmOperatorType *ot)
|
|||||||
#define DETAIL_SIZE_DELTA_SPEED 0.08f
|
#define DETAIL_SIZE_DELTA_SPEED 0.08f
|
||||||
#define DETAIL_SIZE_DELTA_ACCURATE_SPEED 0.004f
|
#define DETAIL_SIZE_DELTA_ACCURATE_SPEED 0.004f
|
||||||
|
|
||||||
typedef struct DyntopoDetailSizeEditCustomData {
|
struct DyntopoDetailSizeEditCustomData {
|
||||||
void *draw_handle;
|
void *draw_handle;
|
||||||
Object *active_object;
|
Object *active_object;
|
||||||
|
|
||||||
@ -465,7 +465,7 @@ typedef struct DyntopoDetailSizeEditCustomData {
|
|||||||
|
|
||||||
float preview_tri[3][3];
|
float preview_tri[3][3];
|
||||||
float gizmo_mat[4][4];
|
float gizmo_mat[4][4];
|
||||||
} DyntopoDetailSizeEditCustomData;
|
};
|
||||||
|
|
||||||
static void dyntopo_detail_size_parallel_lines_draw(uint pos3d,
|
static void dyntopo_detail_size_parallel_lines_draw(uint pos3d,
|
||||||
DyntopoDetailSizeEditCustomData *cd,
|
DyntopoDetailSizeEditCustomData *cd,
|
||||||
@ -485,7 +485,7 @@ static void dyntopo_detail_size_parallel_lines_draw(uint pos3d,
|
|||||||
object_space_constant_detail *= 0.7f;
|
object_space_constant_detail *= 0.7f;
|
||||||
|
|
||||||
const float total_len = len_v3v3(cd->preview_tri[0], cd->preview_tri[1]);
|
const float total_len = len_v3v3(cd->preview_tri[0], cd->preview_tri[1]);
|
||||||
const int tot_lines = (int)(total_len / object_space_constant_detail) + 1;
|
const int tot_lines = int(total_len / object_space_constant_detail) + 1;
|
||||||
const float tot_lines_fl = total_len / object_space_constant_detail;
|
const float tot_lines_fl = total_len / object_space_constant_detail;
|
||||||
float spacing_disp[3];
|
float spacing_disp[3];
|
||||||
sub_v3_v3v3(spacing_disp, end_co, start_co);
|
sub_v3_v3v3(spacing_disp, end_co, start_co);
|
||||||
@ -499,10 +499,10 @@ static void dyntopo_detail_size_parallel_lines_draw(uint pos3d,
|
|||||||
for (int i = 0; i < tot_lines; i++) {
|
for (int i = 0; i < tot_lines; i++) {
|
||||||
float line_length;
|
float line_length;
|
||||||
if (flip) {
|
if (flip) {
|
||||||
line_length = total_len * ((float)i / (float)tot_lines_fl);
|
line_length = total_len * (float(i) / float(tot_lines_fl));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
line_length = total_len * (1.0f - ((float)i / (float)tot_lines_fl));
|
line_length = total_len * (1.0f - (float(i) / float(tot_lines_fl)));
|
||||||
}
|
}
|
||||||
float line_start[3];
|
float line_start[3];
|
||||||
copy_v3_v3(line_start, start_co);
|
copy_v3_v3(line_start, start_co);
|
||||||
@ -515,11 +515,9 @@ static void dyntopo_detail_size_parallel_lines_draw(uint pos3d,
|
|||||||
immEnd();
|
immEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyntopo_detail_size_edit_draw(const bContext *UNUSED(C),
|
static void dyntopo_detail_size_edit_draw(const bContext * /*C*/, ARegion * /*region*/, void *arg)
|
||||||
ARegion *UNUSED(ar),
|
|
||||||
void *arg)
|
|
||||||
{
|
{
|
||||||
DyntopoDetailSizeEditCustomData *cd = arg;
|
DyntopoDetailSizeEditCustomData *cd = static_cast<DyntopoDetailSizeEditCustomData *>(arg);
|
||||||
GPU_blend(GPU_BLEND_ALPHA);
|
GPU_blend(GPU_BLEND_ALPHA);
|
||||||
GPU_line_smooth(true);
|
GPU_line_smooth(true);
|
||||||
|
|
||||||
@ -567,11 +565,12 @@ static void dyntopo_detail_size_edit_cancel(bContext *C, wmOperator *op)
|
|||||||
Object *active_object = CTX_data_active_object(C);
|
Object *active_object = CTX_data_active_object(C);
|
||||||
SculptSession *ss = active_object->sculpt;
|
SculptSession *ss = active_object->sculpt;
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
DyntopoDetailSizeEditCustomData *cd = op->customdata;
|
DyntopoDetailSizeEditCustomData *cd = static_cast<DyntopoDetailSizeEditCustomData *>(
|
||||||
|
op->customdata);
|
||||||
ED_region_draw_cb_exit(region->type, cd->draw_handle);
|
ED_region_draw_cb_exit(region->type, cd->draw_handle);
|
||||||
ss->draw_faded_cursor = false;
|
ss->draw_faded_cursor = false;
|
||||||
MEM_freeN(op->customdata);
|
MEM_freeN(op->customdata);
|
||||||
ED_workspace_status_text(C, NULL);
|
ED_workspace_status_text(C, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyntopo_detail_size_sample_from_surface(Object *ob,
|
static void dyntopo_detail_size_sample_from_surface(Object *ob,
|
||||||
@ -602,7 +601,7 @@ static void dyntopo_detail_size_sample_from_surface(Object *ob,
|
|||||||
static void dyntopo_detail_size_update_from_mouse_delta(DyntopoDetailSizeEditCustomData *cd,
|
static void dyntopo_detail_size_update_from_mouse_delta(DyntopoDetailSizeEditCustomData *cd,
|
||||||
const wmEvent *event)
|
const wmEvent *event)
|
||||||
{
|
{
|
||||||
const float mval[2] = {event->mval[0], event->mval[1]};
|
const float mval[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||||
|
|
||||||
float detail_size_delta;
|
float detail_size_delta;
|
||||||
if (cd->accurate_mode) {
|
if (cd->accurate_mode) {
|
||||||
@ -633,7 +632,8 @@ static int dyntopo_detail_size_edit_modal(bContext *C, wmOperator *op, const wmE
|
|||||||
Object *active_object = CTX_data_active_object(C);
|
Object *active_object = CTX_data_active_object(C);
|
||||||
SculptSession *ss = active_object->sculpt;
|
SculptSession *ss = active_object->sculpt;
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
DyntopoDetailSizeEditCustomData *cd = op->customdata;
|
DyntopoDetailSizeEditCustomData *cd = static_cast<DyntopoDetailSizeEditCustomData *>(
|
||||||
|
op->customdata);
|
||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
|
|
||||||
/* Cancel modal operator */
|
/* Cancel modal operator */
|
||||||
@ -653,7 +653,7 @@ static int dyntopo_detail_size_edit_modal(bContext *C, wmOperator *op, const wmE
|
|||||||
ss->draw_faded_cursor = false;
|
ss->draw_faded_cursor = false;
|
||||||
MEM_freeN(op->customdata);
|
MEM_freeN(op->customdata);
|
||||||
ED_region_tag_redraw(region);
|
ED_region_tag_redraw(region);
|
||||||
ED_workspace_status_text(C, NULL);
|
ED_workspace_status_text(C, nullptr);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,8 +696,7 @@ static int dyntopo_detail_size_edit_invoke(bContext *C, wmOperator *op, const wm
|
|||||||
Object *active_object = CTX_data_active_object(C);
|
Object *active_object = CTX_data_active_object(C);
|
||||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||||
|
|
||||||
DyntopoDetailSizeEditCustomData *cd = MEM_callocN(sizeof(DyntopoDetailSizeEditCustomData),
|
DyntopoDetailSizeEditCustomData *cd = MEM_cnew<DyntopoDetailSizeEditCustomData>(__func__);
|
||||||
"Dyntopo Detail Size Edit OP Custom Data");
|
|
||||||
|
|
||||||
/* Initial operator Custom Data setup. */
|
/* Initial operator Custom Data setup. */
|
||||||
cd->draw_handle = ED_region_draw_cb_activate(
|
cd->draw_handle = ED_region_draw_cb_activate(
|
@ -30,10 +30,10 @@
|
|||||||
#include "RNA_access.h"
|
#include "RNA_access.h"
|
||||||
#include "RNA_define.h"
|
#include "RNA_define.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
typedef enum eSculptColorFilterTypes {
|
enum eSculptColorFilterTypes {
|
||||||
COLOR_FILTER_FILL,
|
COLOR_FILTER_FILL,
|
||||||
COLOR_FILTER_HUE,
|
COLOR_FILTER_HUE,
|
||||||
COLOR_FILTER_SATURATION,
|
COLOR_FILTER_SATURATION,
|
||||||
@ -44,7 +44,7 @@ typedef enum eSculptColorFilterTypes {
|
|||||||
COLOR_FILTER_GREEN,
|
COLOR_FILTER_GREEN,
|
||||||
COLOR_FILTER_BLUE,
|
COLOR_FILTER_BLUE,
|
||||||
COLOR_FILTER_SMOOTH,
|
COLOR_FILTER_SMOOTH,
|
||||||
} eSculptColorFilterTypes;
|
};
|
||||||
|
|
||||||
static EnumPropertyItem prop_color_filter_types[] = {
|
static EnumPropertyItem prop_color_filter_types[] = {
|
||||||
{COLOR_FILTER_FILL, "FILL", 0, "Fill", "Fill with a specific color"},
|
{COLOR_FILTER_FILL, "FILL", 0, "Fill", "Fill with a specific color"},
|
||||||
@ -60,14 +60,14 @@ static EnumPropertyItem prop_color_filter_types[] = {
|
|||||||
{COLOR_FILTER_RED, "RED", 0, "Red", "Change red channel"},
|
{COLOR_FILTER_RED, "RED", 0, "Red", "Change red channel"},
|
||||||
{COLOR_FILTER_GREEN, "GREEN", 0, "Green", "Change green channel"},
|
{COLOR_FILTER_GREEN, "GREEN", 0, "Green", "Change green channel"},
|
||||||
{COLOR_FILTER_BLUE, "BLUE", 0, "Blue", "Change blue channel"},
|
{COLOR_FILTER_BLUE, "BLUE", 0, "Blue", "Change blue channel"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void color_filter_task_cb(void *__restrict userdata,
|
static void color_filter_task_cb(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
|
|
||||||
const int mode = data->filter_type;
|
const int mode = data->filter_type;
|
||||||
@ -222,8 +222,8 @@ static void sculpt_color_presmooth_init(SculptSession *ss)
|
|||||||
int totvert = SCULPT_vertex_count_get(ss);
|
int totvert = SCULPT_vertex_count_get(ss);
|
||||||
|
|
||||||
if (!ss->filter_cache->pre_smoothed_color) {
|
if (!ss->filter_cache->pre_smoothed_color) {
|
||||||
ss->filter_cache->pre_smoothed_color = MEM_malloc_arrayN(
|
ss->filter_cache->pre_smoothed_color = static_cast<float(*)[4]>(
|
||||||
totvert, sizeof(float) * 4, "ss->filter_cache->pre_smoothed_color");
|
MEM_malloc_arrayN(totvert, sizeof(float[4]), __func__));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
@ -248,7 +248,7 @@ static void sculpt_color_presmooth_init(SculptSession *ss)
|
|||||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||||
|
|
||||||
if (total > 0) {
|
if (total > 0) {
|
||||||
mul_v4_fl(avg, 1.0f / (float)total);
|
mul_v4_fl(avg, 1.0f / float(total));
|
||||||
interp_v4_v4v4(ss->filter_cache->pre_smoothed_color[i],
|
interp_v4_v4v4(ss->filter_cache->pre_smoothed_color[i],
|
||||||
ss->filter_cache->pre_smoothed_color[i],
|
ss->filter_cache->pre_smoothed_color[i],
|
||||||
avg,
|
avg,
|
||||||
@ -288,14 +288,13 @@ static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent
|
|||||||
sculpt_color_presmooth_init(ss);
|
sculpt_color_presmooth_init(ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = ss->filter_cache->nodes,
|
data.nodes = ss->filter_cache->nodes;
|
||||||
.filter_type = mode,
|
data.filter_type = mode;
|
||||||
.filter_strength = filter_strength,
|
data.filter_strength = filter_strength;
|
||||||
.filter_fill_color = fill_color,
|
data.filter_fill_color = fill_color;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BLI_parallel_range_settings_defaults(&settings);
|
BLI_parallel_range_settings_defaults(&settings);
|
||||||
@ -319,14 +318,14 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
v3d->shading.color_type = V3D_SHADING_VERTEX_COLOR;
|
v3d->shading.color_type = V3D_SHADING_VERTEX_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, NULL);
|
const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, nullptr);
|
||||||
if (use_automasking) {
|
if (use_automasking) {
|
||||||
/* Increment stroke id for auto-masking system. */
|
/* Increment stroke id for auto-masking system. */
|
||||||
SCULPT_stroke_id_next(ob);
|
SCULPT_stroke_id_next(ob);
|
||||||
|
|
||||||
/* Update the active face set manually as the paint cursor is not enabled when using the Mesh
|
/* Update the active face set manually as the paint cursor is not enabled when using the Mesh
|
||||||
* Filter Tool. */
|
* Filter Tool. */
|
||||||
float mval_fl[2] = {UNPACK2(event->mval)};
|
float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||||
SculptCursorGeometryInfo sgi;
|
SculptCursorGeometryInfo sgi;
|
||||||
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
||||||
}
|
}
|
||||||
@ -352,14 +351,14 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
C, ob, sd, SCULPT_UNDO_COLOR, event->mval, RNA_float_get(op->ptr, "area_normal_radius"));
|
C, ob, sd, SCULPT_UNDO_COLOR, event->mval, RNA_float_get(op->ptr, "area_normal_radius"));
|
||||||
FilterCache *filter_cache = ss->filter_cache;
|
FilterCache *filter_cache = ss->filter_cache;
|
||||||
filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
|
filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
|
||||||
filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob);
|
filter_cache->automasking = SCULPT_automasking_cache_init(sd, nullptr, ob);
|
||||||
ED_paint_tool_update_sticky_shading_color(C, ob);
|
ED_paint_tool_update_sticky_shading_color(C, ob);
|
||||||
|
|
||||||
WM_event_add_modal_handler(C, op);
|
WM_event_add_modal_handler(C, op);
|
||||||
return OPERATOR_RUNNING_MODAL;
|
return OPERATOR_RUNNING_MODAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_OT_color_filter(struct wmOperatorType *ot)
|
void SCULPT_OT_color_filter(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
/* identifiers */
|
/* identifiers */
|
||||||
ot->name = "Filter Color";
|
ot->name = "Filter Color";
|
||||||
@ -379,6 +378,6 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot)
|
|||||||
RNA_def_enum(ot->srna, "type", prop_color_filter_types, COLOR_FILTER_HUE, "Filter Type", "");
|
RNA_def_enum(ot->srna, "type", prop_color_filter_types, COLOR_FILTER_HUE, "Filter Type", "");
|
||||||
|
|
||||||
PropertyRNA *prop = RNA_def_float_color(
|
PropertyRNA *prop = RNA_def_float_color(
|
||||||
ot->srna, "fill_color", 3, NULL, 0.0f, FLT_MAX, "Fill Color", "", 0.0f, 1.0f);
|
ot->srna, "fill_color", 3, nullptr, 0.0f, FLT_MAX, "Fill Color", "", 0.0f, 1.0f);
|
||||||
RNA_def_property_subtype(prop, PROP_COLOR_GAMMA);
|
RNA_def_property_subtype(prop, PROP_COLOR_GAMMA);
|
||||||
}
|
}
|
@ -30,17 +30,17 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
typedef enum eSculptMaskFilterTypes {
|
enum eSculptMaskFilterTypes {
|
||||||
MASK_FILTER_SMOOTH = 0,
|
MASK_FILTER_SMOOTH = 0,
|
||||||
MASK_FILTER_SHARPEN = 1,
|
MASK_FILTER_SHARPEN = 1,
|
||||||
MASK_FILTER_GROW = 2,
|
MASK_FILTER_GROW = 2,
|
||||||
MASK_FILTER_SHRINK = 3,
|
MASK_FILTER_SHRINK = 3,
|
||||||
MASK_FILTER_CONTRAST_INCREASE = 5,
|
MASK_FILTER_CONTRAST_INCREASE = 5,
|
||||||
MASK_FILTER_CONTRAST_DECREASE = 6,
|
MASK_FILTER_CONTRAST_DECREASE = 6,
|
||||||
} eSculptMaskFilterTypes;
|
};
|
||||||
|
|
||||||
static EnumPropertyItem prop_mask_filter_types[] = {
|
static EnumPropertyItem prop_mask_filter_types[] = {
|
||||||
{MASK_FILTER_SMOOTH, "SMOOTH", 0, "Smooth Mask", "Smooth mask"},
|
{MASK_FILTER_SMOOTH, "SMOOTH", 0, "Smooth Mask", "Smooth mask"},
|
||||||
@ -57,14 +57,14 @@ static EnumPropertyItem prop_mask_filter_types[] = {
|
|||||||
0,
|
0,
|
||||||
"Decrease Contrast",
|
"Decrease Contrast",
|
||||||
"Decrease the contrast of the paint mask"},
|
"Decrease the contrast of the paint mask"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mask_filter_task_cb(void *__restrict userdata,
|
static void mask_filter_task_cb(void *__restrict userdata,
|
||||||
const int i,
|
const int i,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
bool update = false;
|
bool update = false;
|
||||||
@ -182,14 +182,14 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
int num_verts = SCULPT_vertex_count_get(ss);
|
int num_verts = SCULPT_vertex_count_get(ss);
|
||||||
|
|
||||||
BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
SCULPT_undo_push_begin(ob, op);
|
SCULPT_undo_push_begin(ob, op);
|
||||||
|
|
||||||
for (int i = 0; i < totnode; i++) {
|
for (int i = 0; i < totnode; i++) {
|
||||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
|
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
float *prev_mask = NULL;
|
float *prev_mask = nullptr;
|
||||||
int iterations = RNA_int_get(op->ptr, "iterations");
|
int iterations = RNA_int_get(op->ptr, "iterations");
|
||||||
|
|
||||||
/* Auto iteration count calculates the number of iteration based on the vertices of the mesh to
|
/* Auto iteration count calculates the number of iteration based on the vertices of the mesh to
|
||||||
@ -197,25 +197,24 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
|||||||
* One iteration per 50000 vertices in the mesh should be fine in most cases.
|
* One iteration per 50000 vertices in the mesh should be fine in most cases.
|
||||||
* Maybe we want this to be configurable. */
|
* Maybe we want this to be configurable. */
|
||||||
if (RNA_boolean_get(op->ptr, "auto_iteration_count")) {
|
if (RNA_boolean_get(op->ptr, "auto_iteration_count")) {
|
||||||
iterations = (int)(num_verts / 50000.0f) + 1;
|
iterations = int(num_verts / 50000.0f) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < iterations; i++) {
|
for (int i = 0; i < iterations; i++) {
|
||||||
if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) {
|
if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) {
|
||||||
prev_mask = MEM_mallocN(num_verts * sizeof(float), "prevmask");
|
prev_mask = static_cast<float *>(MEM_mallocN(num_verts * sizeof(float), __func__));
|
||||||
for (int j = 0; j < num_verts; j++) {
|
for (int j = 0; j < num_verts; j++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, j);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, j);
|
||||||
prev_mask[j] = SCULPT_vertex_mask_get(ss, vertex);
|
prev_mask[j] = SCULPT_vertex_mask_get(ss, vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.filter_type = filter_type,
|
data.filter_type = filter_type;
|
||||||
.prev_mask = prev_mask,
|
data.prev_mask = prev_mask;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -238,12 +237,11 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
|||||||
void SCULPT_mask_filter_smooth_apply(
|
void SCULPT_mask_filter_smooth_apply(
|
||||||
Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, const int smooth_iterations)
|
Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, const int smooth_iterations)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.filter_type = MASK_FILTER_SMOOTH,
|
data.filter_type = MASK_FILTER_SMOOTH;
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < smooth_iterations; i++) {
|
for (int i = 0; i < smooth_iterations; i++) {
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
@ -252,7 +250,7 @@ void SCULPT_mask_filter_smooth_apply(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_OT_mask_filter(struct wmOperatorType *ot)
|
void SCULPT_OT_mask_filter(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
/* Identifiers. */
|
/* Identifiers. */
|
||||||
ot->name = "Mask Filter";
|
ot->name = "Mask Filter";
|
@ -35,10 +35,10 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache)
|
void SCULPT_filter_to_orientation_space(float r_v[3], FilterCache *filter_cache)
|
||||||
{
|
{
|
||||||
switch (filter_cache->orientation) {
|
switch (filter_cache->orientation) {
|
||||||
case SCULPT_FILTER_ORIENTATION_LOCAL:
|
case SCULPT_FILTER_ORIENTATION_LOCAL:
|
||||||
@ -54,7 +54,7 @@ void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache)
|
void SCULPT_filter_to_object_space(float r_v[3], FilterCache *filter_cache)
|
||||||
{
|
{
|
||||||
switch (filter_cache->orientation) {
|
switch (filter_cache->orientation) {
|
||||||
case SCULPT_FILTER_ORIENTATION_LOCAL:
|
case SCULPT_FILTER_ORIENTATION_LOCAL:
|
||||||
@ -70,7 +70,7 @@ void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cach
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCache *filter_cache)
|
void SCULPT_filter_zero_disabled_axis_components(float r_v[3], FilterCache *filter_cache)
|
||||||
{
|
{
|
||||||
SCULPT_filter_to_orientation_space(r_v, filter_cache);
|
SCULPT_filter_to_orientation_space(r_v, filter_cache);
|
||||||
for (int axis = 0; axis < 3; axis++) {
|
for (int axis = 0; axis < 3; axis++) {
|
||||||
@ -83,12 +83,12 @@ void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCach
|
|||||||
|
|
||||||
static void filter_cache_init_task_cb(void *__restrict userdata,
|
static void filter_cache_init_task_cb(void *__restrict userdata,
|
||||||
const int i,
|
const int i,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
|
|
||||||
SCULPT_undo_push_node(data->ob, node, data->filter_undo_type);
|
SCULPT_undo_push_node(data->ob, node, SculptUndoType(data->filter_undo_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_filter_cache_init(bContext *C,
|
void SCULPT_filter_cache_init(bContext *C,
|
||||||
@ -101,7 +101,7 @@ void SCULPT_filter_cache_init(bContext *C,
|
|||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
PBVH *pbvh = ob->sculpt->pbvh;
|
PBVH *pbvh = ob->sculpt->pbvh;
|
||||||
|
|
||||||
ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache");
|
ss->filter_cache = MEM_cnew<FilterCache>(__func__);
|
||||||
|
|
||||||
ss->filter_cache->random_seed = rand();
|
ss->filter_cache->random_seed = rand();
|
||||||
|
|
||||||
@ -110,13 +110,12 @@ void SCULPT_filter_cache_init(bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float center[3] = {0.0f};
|
const float center[3] = {0.0f};
|
||||||
SculptSearchSphereData search_data = {
|
SculptSearchSphereData search_data{};
|
||||||
.original = true,
|
search_data.original = true;
|
||||||
.center = center,
|
search_data.center = center;
|
||||||
.radius_squared = FLT_MAX,
|
search_data.radius_squared = FLT_MAX;
|
||||||
.ignore_fully_ineffective = true,
|
search_data.ignore_fully_ineffective = true;
|
||||||
|
|
||||||
};
|
|
||||||
BKE_pbvh_search_gather(pbvh,
|
BKE_pbvh_search_gather(pbvh,
|
||||||
SCULPT_search_sphere_cb,
|
SCULPT_search_sphere_cb,
|
||||||
&search_data,
|
&search_data,
|
||||||
@ -130,15 +129,14 @@ void SCULPT_filter_cache_init(bContext *C,
|
|||||||
/* `mesh->runtime.subdiv_ccg` is not available. Updating of the normals is done during drawing.
|
/* `mesh->runtime.subdiv_ccg` is not available. Updating of the normals is done during drawing.
|
||||||
* Filters can't use normals in multi-resolution. */
|
* Filters can't use normals in multi-resolution. */
|
||||||
if (BKE_pbvh_type(ss->pbvh) != PBVH_GRIDS) {
|
if (BKE_pbvh_type(ss->pbvh) != PBVH_GRIDS) {
|
||||||
BKE_pbvh_update_normals(ss->pbvh, NULL);
|
BKE_pbvh_update_normals(ss->pbvh, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = ss->filter_cache->nodes,
|
data.nodes = ss->filter_cache->nodes;
|
||||||
.filter_undo_type = undo_type,
|
data.filter_undo_type = undo_type;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||||
@ -161,7 +159,7 @@ void SCULPT_filter_cache_init(bContext *C,
|
|||||||
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
|
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
|
||||||
|
|
||||||
float co[3];
|
float co[3];
|
||||||
float mval_fl[2] = {(float)mval[0], (float)mval[1]};
|
float mval_fl[2] = {float(mval[0]), float(mval[1])};
|
||||||
|
|
||||||
if (SCULPT_stroke_get_location(C, co, mval_fl, false)) {
|
if (SCULPT_stroke_get_location(C, co, mval_fl, false)) {
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
@ -174,22 +172,21 @@ void SCULPT_filter_cache_init(bContext *C,
|
|||||||
if (brush) {
|
if (brush) {
|
||||||
if (BKE_brush_use_locked_size(scene, brush)) {
|
if (BKE_brush_use_locked_size(scene, brush)) {
|
||||||
radius = paint_calc_object_space_radius(
|
radius = paint_calc_object_space_radius(
|
||||||
&vc, co, (float)BKE_brush_size_get(scene, brush) * area_normal_radius);
|
&vc, co, float(BKE_brush_size_get(scene, brush) * area_normal_radius));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
radius = BKE_brush_unprojected_radius_get(scene, brush) * area_normal_radius;
|
radius = BKE_brush_unprojected_radius_get(scene, brush) * area_normal_radius;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
radius = paint_calc_object_space_radius(&vc, co, (float)ups->size * area_normal_radius);
|
radius = paint_calc_object_space_radius(&vc, co, float(ups->size) * area_normal_radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptSearchSphereData search_data2 = {
|
SculptSearchSphereData search_data2{};
|
||||||
.original = true,
|
search_data2.original = true;
|
||||||
.center = co,
|
search_data2.center = co;
|
||||||
.radius_squared = radius * radius,
|
search_data2.radius_squared = radius * radius;
|
||||||
.ignore_fully_ineffective = true,
|
search_data2.ignore_fully_ineffective = true;
|
||||||
};
|
|
||||||
|
|
||||||
BKE_pbvh_search_gather(pbvh, SCULPT_search_sphere_cb, &search_data2, &nodes, &totnode);
|
BKE_pbvh_search_gather(pbvh, SCULPT_search_sphere_cb, &search_data2, &nodes, &totnode);
|
||||||
|
|
||||||
@ -295,7 +292,7 @@ static EnumPropertyItem prop_mesh_filter_types[] = {
|
|||||||
0,
|
0,
|
||||||
"Erase Displacement",
|
"Erase Displacement",
|
||||||
"Deletes the displacement of the Multires Modifier"},
|
"Deletes the displacement of the Multires Modifier"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum eMeshFilterDeformAxis {
|
typedef enum eMeshFilterDeformAxis {
|
||||||
@ -308,7 +305,7 @@ static EnumPropertyItem prop_mesh_filter_deform_axis_items[] = {
|
|||||||
{MESH_FILTER_DEFORM_X, "X", 0, "X", "Deform in the X axis"},
|
{MESH_FILTER_DEFORM_X, "X", 0, "X", "Deform in the X axis"},
|
||||||
{MESH_FILTER_DEFORM_Y, "Y", 0, "Y", "Deform in the Y axis"},
|
{MESH_FILTER_DEFORM_Y, "Y", 0, "Y", "Deform in the Y axis"},
|
||||||
{MESH_FILTER_DEFORM_Z, "Z", 0, "Z", "Deform in the Z axis"},
|
{MESH_FILTER_DEFORM_Z, "Z", 0, "Z", "Deform in the Z axis"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static EnumPropertyItem prop_mesh_filter_orientation_items[] = {
|
static EnumPropertyItem prop_mesh_filter_orientation_items[] = {
|
||||||
@ -327,7 +324,7 @@ static EnumPropertyItem prop_mesh_filter_orientation_items[] = {
|
|||||||
0,
|
0,
|
||||||
"View",
|
"View",
|
||||||
"Use the view axis to limit the displacement"},
|
"Use the view axis to limit the displacement"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type)
|
static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type)
|
||||||
@ -343,13 +340,13 @@ static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type)
|
|||||||
|
|
||||||
static void mesh_filter_task_cb(void *__restrict userdata,
|
static void mesh_filter_task_cb(void *__restrict userdata,
|
||||||
const int i,
|
const int i,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
|
|
||||||
const eSculptMeshFilterType filter_type = data->filter_type;
|
const eSculptMeshFilterType filter_type = eSculptMeshFilterType(data->filter_type);
|
||||||
|
|
||||||
SculptOrigVertData orig_data;
|
SculptOrigVertData orig_data;
|
||||||
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[i], SCULPT_UNDO_COORDS);
|
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[i], SCULPT_UNDO_COORDS);
|
||||||
@ -442,7 +439,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
|
|||||||
const uint *hash_co = (const uint *)orig_co;
|
const uint *hash_co = (const uint *)orig_co;
|
||||||
const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^
|
const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^
|
||||||
BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed);
|
BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed);
|
||||||
mul_v3_fl(normal, hash * (1.0f / (float)0xFFFFFFFF) - 0.5f);
|
mul_v3_fl(normal, hash * (1.0f / float(0xFFFFFFFF)) - 0.5f);
|
||||||
mul_v3_v3fl(disp, normal, fade);
|
mul_v3_v3fl(disp, normal, fade);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -546,8 +543,8 @@ static void mesh_filter_enhance_details_init_directions(SculptSession *ss)
|
|||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
FilterCache *filter_cache = ss->filter_cache;
|
FilterCache *filter_cache = ss->filter_cache;
|
||||||
|
|
||||||
filter_cache->detail_directions = MEM_malloc_arrayN(
|
filter_cache->detail_directions = static_cast<float(*)[3]>(
|
||||||
totvert, sizeof(float[3]), "detail directions");
|
MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__));
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||||
|
|
||||||
@ -564,8 +561,8 @@ static void mesh_filter_surface_smooth_init(SculptSession *ss,
|
|||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
FilterCache *filter_cache = ss->filter_cache;
|
FilterCache *filter_cache = ss->filter_cache;
|
||||||
|
|
||||||
filter_cache->surface_smooth_laplacian_disp = MEM_malloc_arrayN(
|
filter_cache->surface_smooth_laplacian_disp = static_cast<float(*)[3]>(
|
||||||
totvert, sizeof(float[3]), "surface smooth displacement");
|
MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__));
|
||||||
filter_cache->surface_smooth_shape_preservation = shape_preservation;
|
filter_cache->surface_smooth_shape_preservation = shape_preservation;
|
||||||
filter_cache->surface_smooth_current_vertex = current_vertex_displacement;
|
filter_cache->surface_smooth_current_vertex = current_vertex_displacement;
|
||||||
}
|
}
|
||||||
@ -575,8 +572,8 @@ static void mesh_filter_init_limit_surface_co(SculptSession *ss)
|
|||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
FilterCache *filter_cache = ss->filter_cache;
|
FilterCache *filter_cache = ss->filter_cache;
|
||||||
|
|
||||||
filter_cache->limit_surface_co = MEM_malloc_arrayN(
|
filter_cache->limit_surface_co = static_cast<float(*)[3]>(
|
||||||
totvert, sizeof(float[3]), "limit surface co");
|
MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__));
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||||
|
|
||||||
@ -595,9 +592,10 @@ static void mesh_filter_sharpen_init(SculptSession *ss,
|
|||||||
filter_cache->sharpen_smooth_ratio = smooth_ratio;
|
filter_cache->sharpen_smooth_ratio = smooth_ratio;
|
||||||
filter_cache->sharpen_intensify_detail_strength = intensify_detail_strength;
|
filter_cache->sharpen_intensify_detail_strength = intensify_detail_strength;
|
||||||
filter_cache->sharpen_curvature_smooth_iterations = curvature_smooth_iterations;
|
filter_cache->sharpen_curvature_smooth_iterations = curvature_smooth_iterations;
|
||||||
filter_cache->sharpen_factor = MEM_malloc_arrayN(totvert, sizeof(float), "sharpen factor");
|
filter_cache->sharpen_factor = static_cast<float *>(
|
||||||
filter_cache->detail_directions = MEM_malloc_arrayN(
|
MEM_malloc_arrayN(totvert, sizeof(float), __func__));
|
||||||
totvert, sizeof(float[3]), "sharpen detail direction");
|
filter_cache->detail_directions = static_cast<float(*)[3]>(
|
||||||
|
MEM_malloc_arrayN(totvert, sizeof(float[3]), __func__));
|
||||||
|
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||||
@ -648,10 +646,11 @@ static void mesh_filter_sharpen_init(SculptSession *ss,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mesh_filter_surface_smooth_displace_task_cb(
|
static void mesh_filter_surface_smooth_displace_task_cb(void *__restrict userdata,
|
||||||
void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
|
const int i,
|
||||||
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
@ -688,7 +687,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
eSculptMeshFilterType filter_type = RNA_enum_get(op->ptr, "type");
|
eSculptMeshFilterType filter_type = eSculptMeshFilterType(RNA_enum_get(op->ptr, "type"));
|
||||||
float filter_strength = RNA_float_get(op->ptr, "strength");
|
float filter_strength = RNA_float_get(op->ptr, "strength");
|
||||||
|
|
||||||
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
||||||
@ -710,13 +709,12 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||||||
bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type);
|
bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type);
|
||||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false);
|
BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = ss->filter_cache->nodes,
|
data.nodes = ss->filter_cache->nodes;
|
||||||
.filter_type = filter_type,
|
data.filter_type = filter_type;
|
||||||
.filter_strength = filter_strength,
|
data.filter_strength = filter_strength;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||||
@ -753,9 +751,10 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
|
|
||||||
const eMeshFilterDeformAxis deform_axis = RNA_enum_get(op->ptr, "deform_axis");
|
const eMeshFilterDeformAxis deform_axis = eMeshFilterDeformAxis(
|
||||||
const eSculptMeshFilterType filter_type = RNA_enum_get(op->ptr, "type");
|
RNA_enum_get(op->ptr, "deform_axis"));
|
||||||
const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, NULL);
|
const eSculptMeshFilterType filter_type = eSculptMeshFilterType(RNA_enum_get(op->ptr, "type"));
|
||||||
|
const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, nullptr);
|
||||||
const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type) || use_automasking;
|
const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type) || use_automasking;
|
||||||
|
|
||||||
if (deform_axis == 0) {
|
if (deform_axis == 0) {
|
||||||
@ -769,7 +768,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
|
|
||||||
/* Update the active face set manually as the paint cursor is not enabled when using the Mesh
|
/* Update the active face set manually as the paint cursor is not enabled when using the Mesh
|
||||||
* Filter Tool. */
|
* Filter Tool. */
|
||||||
float mval_fl[2] = {UNPACK2(event->mval)};
|
float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||||
SculptCursorGeometryInfo sgi;
|
SculptCursorGeometryInfo sgi;
|
||||||
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
||||||
}
|
}
|
||||||
@ -787,7 +786,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
|
|
||||||
FilterCache *filter_cache = ss->filter_cache;
|
FilterCache *filter_cache = ss->filter_cache;
|
||||||
filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
|
filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
|
||||||
filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob);
|
filter_cache->automasking = SCULPT_automasking_cache_init(sd, nullptr, ob);
|
||||||
|
|
||||||
switch (filter_type) {
|
switch (filter_type) {
|
||||||
case MESH_FILTER_SURFACE_SMOOTH: {
|
case MESH_FILTER_SURFACE_SMOOTH: {
|
||||||
@ -823,14 +822,15 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y;
|
ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y;
|
||||||
ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z;
|
ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z;
|
||||||
|
|
||||||
SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation");
|
SculptFilterOrientation orientation = SculptFilterOrientation(
|
||||||
|
RNA_enum_get(op->ptr, "orientation"));
|
||||||
ss->filter_cache->orientation = orientation;
|
ss->filter_cache->orientation = orientation;
|
||||||
|
|
||||||
WM_event_add_modal_handler(C, op);
|
WM_event_add_modal_handler(C, op);
|
||||||
return OPERATOR_RUNNING_MODAL;
|
return OPERATOR_RUNNING_MODAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_mesh_filter_properties(struct wmOperatorType *ot)
|
void SCULPT_mesh_filter_properties(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
RNA_def_float(
|
RNA_def_float(
|
||||||
ot->srna,
|
ot->srna,
|
||||||
@ -846,7 +846,7 @@ void SCULPT_mesh_filter_properties(struct wmOperatorType *ot)
|
|||||||
ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f);
|
ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
|
void SCULPT_OT_mesh_filter(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
/* Identifiers. */
|
/* Identifiers. */
|
||||||
ot->name = "Filter Mesh";
|
ot->name = "Filter Mesh";
|
@ -908,7 +908,7 @@ float SCULPT_raycast_init(struct ViewContext *vc,
|
|||||||
bool original);
|
bool original);
|
||||||
|
|
||||||
/* Symmetry */
|
/* Symmetry */
|
||||||
char SCULPT_mesh_symmetry_xyz_get(Object *object);
|
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(Object *object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true when the step belongs to the stroke that is directly performed by the brush and
|
* Returns true when the step belongs to the stroke that is directly performed by the brush and
|
||||||
@ -1711,7 +1711,7 @@ void SCULPT_OT_dyntopo_detail_size_edit(struct wmOperatorType *ot);
|
|||||||
|
|
||||||
void SCULPT_OT_dynamic_topology_toggle(struct wmOperatorType *ot);
|
void SCULPT_OT_dynamic_topology_toggle(struct wmOperatorType *ot);
|
||||||
|
|
||||||
/* sculpt_brush_types.c */
|
/* sculpt_brush_types.cc */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Brushes
|
/** \name Brushes
|
||||||
@ -1918,13 +1918,13 @@ void SCULPT_do_mask_brush(struct Sculpt *sd,
|
|||||||
void SCULPT_bmesh_topology_rake(
|
void SCULPT_bmesh_topology_rake(
|
||||||
struct Sculpt *sd, struct Object *ob, struct PBVHNode **nodes, int totnode, float bstrength);
|
struct Sculpt *sd, struct Object *ob, struct PBVHNode **nodes, int totnode, float bstrength);
|
||||||
|
|
||||||
/* end sculpt_brush_types.c */
|
/* end sculpt_brush_types.cc */
|
||||||
|
|
||||||
/* sculpt_ops.c */
|
/* sculpt_ops.cc */
|
||||||
|
|
||||||
void SCULPT_OT_brush_stroke(struct wmOperatorType *ot);
|
void SCULPT_OT_brush_stroke(struct wmOperatorType *ot);
|
||||||
|
|
||||||
/* end sculpt_ops.c */
|
/* end sculpt_ops.cc */
|
||||||
|
|
||||||
BLI_INLINE bool SCULPT_tool_is_paint(int tool)
|
BLI_INLINE bool SCULPT_tool_is_paint(int tool)
|
||||||
{
|
{
|
||||||
|
@ -35,8 +35,8 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
|
static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
@ -70,14 +70,14 @@ static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
|
|||||||
SCULPT_filter_cache_free(ss);
|
SCULPT_filter_cache_free(ss);
|
||||||
SCULPT_undo_push_end(ob);
|
SCULPT_undo_push_end(ob);
|
||||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
||||||
ED_workspace_status_text(C, NULL);
|
ED_workspace_status_text(C, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sculpt_expand_task_cb(void *__restrict userdata,
|
static void sculpt_expand_task_cb(void *__restrict userdata,
|
||||||
const int i,
|
const int i,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
@ -148,9 +148,9 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
float prev_click_f[2];
|
float prev_click_f[2];
|
||||||
copy_v2_v2(prev_click_f, op->customdata);
|
copy_v2_v2(prev_click_f, static_cast<float *>(op->customdata));
|
||||||
const int prev_click[2] = {(int)prev_click_f[0], (int)prev_click_f[1]};
|
const int prev_click[2] = {int(prev_click_f[0]), int(prev_click_f[1])};
|
||||||
int len = (int)len_v2v2_int(prev_click, event->mval);
|
int len = int(len_v2v2_int(prev_click, event->mval));
|
||||||
len = abs(len);
|
len = abs(len);
|
||||||
int mask_speed = RNA_int_get(op->ptr, "mask_speed");
|
int mask_speed = RNA_int_get(op->ptr, "mask_speed");
|
||||||
int mask_expand_update_it = len / mask_speed;
|
int mask_expand_update_it = len / mask_speed;
|
||||||
@ -161,7 +161,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||||||
if (RNA_boolean_get(op->ptr, "use_cursor")) {
|
if (RNA_boolean_get(op->ptr, "use_cursor")) {
|
||||||
SculptCursorGeometryInfo sgi;
|
SculptCursorGeometryInfo sgi;
|
||||||
|
|
||||||
const float mval_fl[2] = {UNPACK2(event->mval)};
|
const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||||
if (SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false)) {
|
if (SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false)) {
|
||||||
int active_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, SCULPT_active_vertex_get(ss));
|
int active_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, SCULPT_active_vertex_get(ss));
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||||||
|
|
||||||
SCULPT_undo_push_end(ob);
|
SCULPT_undo_push_end(ob);
|
||||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
||||||
ED_workspace_status_text(C, NULL);
|
ED_workspace_status_text(C, nullptr);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,16 +259,16 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||||||
ss->face_sets[i] = ss->filter_cache->prev_face_set[i];
|
ss->face_sets[i] = ss->filter_cache->prev_face_set[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = ss->filter_cache->nodes,
|
data.nodes = ss->filter_cache->nodes;
|
||||||
.mask_expand_update_it = mask_expand_update_it,
|
data.mask_expand_update_it = mask_expand_update_it;
|
||||||
.mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals"),
|
data.mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals");
|
||||||
.mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert"),
|
data.mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert");
|
||||||
.mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask"),
|
data.mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask");
|
||||||
.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"),
|
data.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
|
||||||
};
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||||
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings);
|
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings);
|
||||||
@ -280,16 +280,16 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||||||
return OPERATOR_RUNNING_MODAL;
|
return OPERATOR_RUNNING_MODAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct MaskExpandFloodFillData {
|
struct MaskExpandFloodFillData {
|
||||||
float original_normal[3];
|
float original_normal[3];
|
||||||
float edge_sensitivity;
|
float edge_sensitivity;
|
||||||
bool use_normals;
|
bool use_normals;
|
||||||
} MaskExpandFloodFillData;
|
};
|
||||||
|
|
||||||
static bool mask_expand_floodfill_cb(
|
static bool mask_expand_floodfill_cb(
|
||||||
SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
||||||
{
|
{
|
||||||
MaskExpandFloodFillData *data = userdata;
|
MaskExpandFloodFillData *data = static_cast<MaskExpandFloodFillData *>(userdata);
|
||||||
|
|
||||||
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
||||||
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||||
@ -337,7 +337,7 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
const bool create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
|
const bool create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
|
||||||
|
|
||||||
SculptCursorGeometryInfo sgi;
|
SculptCursorGeometryInfo sgi;
|
||||||
const float mval_fl[2] = {UNPACK2(event->mval)};
|
const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||||
|
|
||||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
|
MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
|
||||||
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
||||||
@ -347,15 +347,16 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
SCULPT_vertex_random_access_ensure(ss);
|
SCULPT_vertex_random_access_ensure(ss);
|
||||||
|
|
||||||
op->customdata = MEM_mallocN(sizeof(float[2]), "initial mouse position");
|
op->customdata = MEM_mallocN(sizeof(float[2]), "initial mouse position");
|
||||||
copy_v2_v2(op->customdata, mval_fl);
|
copy_v2_v2(static_cast<float *>(op->customdata), mval_fl);
|
||||||
|
|
||||||
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
||||||
|
|
||||||
int vertex_count = SCULPT_vertex_count_get(ss);
|
int vertex_count = SCULPT_vertex_count_get(ss);
|
||||||
|
|
||||||
ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache");
|
ss->filter_cache = MEM_cnew<FilterCache>(__func__);
|
||||||
|
|
||||||
BKE_pbvh_search_gather(pbvh, NULL, NULL, &ss->filter_cache->nodes, &ss->filter_cache->totnode);
|
BKE_pbvh_search_gather(
|
||||||
|
pbvh, nullptr, nullptr, &ss->filter_cache->nodes, &ss->filter_cache->totnode);
|
||||||
|
|
||||||
SCULPT_undo_push_begin(ob, op);
|
SCULPT_undo_push_begin(ob, op);
|
||||||
|
|
||||||
@ -372,27 +373,24 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ss->filter_cache->mask_update_it = MEM_callocN(sizeof(int) * vertex_count,
|
ss->filter_cache->mask_update_it = MEM_cnew_array<int>(vertex_count, __func__);
|
||||||
"mask update iteration");
|
|
||||||
if (use_normals) {
|
if (use_normals) {
|
||||||
ss->filter_cache->normal_factor = MEM_callocN(sizeof(float) * vertex_count,
|
ss->filter_cache->normal_factor = MEM_cnew_array<float>(vertex_count, __func__);
|
||||||
"mask update normal factor");
|
ss->filter_cache->edge_factor = MEM_cnew_array<float>(vertex_count, __func__);
|
||||||
ss->filter_cache->edge_factor = MEM_callocN(sizeof(float) * vertex_count,
|
|
||||||
"mask update normal factor");
|
|
||||||
for (int i = 0; i < vertex_count; i++) {
|
for (int i = 0; i < vertex_count; i++) {
|
||||||
ss->filter_cache->edge_factor[i] = 1.0f;
|
ss->filter_cache->edge_factor[i] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_face_set) {
|
if (create_face_set) {
|
||||||
ss->filter_cache->prev_face_set = MEM_callocN(sizeof(float) * ss->totfaces, "prev face mask");
|
ss->filter_cache->prev_face_set = MEM_cnew_array<int>(ss->totfaces, __func__);
|
||||||
for (int i = 0; i < ss->totfaces; i++) {
|
for (int i = 0; i < ss->totfaces; i++) {
|
||||||
ss->filter_cache->prev_face_set[i] = ss->face_sets ? ss->face_sets[i] : 0;
|
ss->filter_cache->prev_face_set[i] = ss->face_sets ? ss->face_sets[i] : 0;
|
||||||
}
|
}
|
||||||
ss->filter_cache->new_face_set = SCULPT_face_set_next_available_get(ss);
|
ss->filter_cache->new_face_set = SCULPT_face_set_next_available_get(ss);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ss->filter_cache->prev_mask = MEM_callocN(sizeof(float) * vertex_count, "prev mask");
|
ss->filter_cache->prev_mask = MEM_cnew_array<float>(vertex_count, __func__);
|
||||||
for (int i = 0; i < vertex_count; i++) {
|
for (int i = 0; i < vertex_count; i++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||||
|
|
||||||
@ -412,10 +410,10 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
SCULPT_floodfill_init(ss, &flood);
|
SCULPT_floodfill_init(ss, &flood);
|
||||||
SCULPT_floodfill_add_active(sd, ob, ss, &flood, FLT_MAX);
|
SCULPT_floodfill_add_active(sd, ob, ss, &flood, FLT_MAX);
|
||||||
|
|
||||||
MaskExpandFloodFillData fdata = {
|
MaskExpandFloodFillData fdata{};
|
||||||
.use_normals = use_normals,
|
fdata.use_normals = use_normals;
|
||||||
.edge_sensitivity = RNA_int_get(op->ptr, "edge_sensitivity"),
|
fdata.edge_sensitivity = RNA_int_get(op->ptr, "edge_sensitivity");
|
||||||
};
|
|
||||||
SCULPT_active_vertex_normal_get(ss, fdata.original_normal);
|
SCULPT_active_vertex_normal_get(ss, fdata.original_normal);
|
||||||
SCULPT_floodfill_execute(ss, &flood, mask_expand_floodfill_cb, &fdata);
|
SCULPT_floodfill_execute(ss, &flood, mask_expand_floodfill_cb, &fdata);
|
||||||
SCULPT_floodfill_free(&flood);
|
SCULPT_floodfill_free(&flood);
|
||||||
@ -438,16 +436,16 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||||||
MEM_SAFE_FREE(ss->filter_cache->edge_factor);
|
MEM_SAFE_FREE(ss->filter_cache->edge_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = ss->filter_cache->nodes,
|
data.nodes = ss->filter_cache->nodes;
|
||||||
.mask_expand_update_it = 0,
|
data.mask_expand_update_it = 0;
|
||||||
.mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals"),
|
data.mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals");
|
||||||
.mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert"),
|
data.mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert");
|
||||||
.mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask"),
|
data.mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask");
|
||||||
.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"),
|
data.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
|
||||||
};
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||||
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings);
|
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings);
|
@ -36,17 +36,17 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
/* Mask Init operator. */
|
/* Mask Init operator. */
|
||||||
/* Initializes mask values for the entire mesh depending on the mode. */
|
/* Initializes mask values for the entire mesh depending on the mode. */
|
||||||
|
|
||||||
typedef enum eSculptMaskInitMode {
|
enum eSculptMaskInitMode {
|
||||||
SCULPT_MASK_INIT_RANDOM_PER_VERTEX,
|
SCULPT_MASK_INIT_RANDOM_PER_VERTEX,
|
||||||
SCULPT_MASK_INIT_RANDOM_PER_FACE_SET,
|
SCULPT_MASK_INIT_RANDOM_PER_FACE_SET,
|
||||||
SCULPT_MASK_INIT_RANDOM_PER_LOOSE_PART,
|
SCULPT_MASK_INIT_RANDOM_PER_LOOSE_PART,
|
||||||
} eSculptMaskInitMode;
|
};
|
||||||
|
|
||||||
static EnumPropertyItem prop_sculpt_mask_init_mode_types[] = {
|
static EnumPropertyItem prop_sculpt_mask_init_mode_types[] = {
|
||||||
{
|
{
|
||||||
@ -70,14 +70,14 @@ static EnumPropertyItem prop_sculpt_mask_init_mode_types[] = {
|
|||||||
"Random per Loose Part",
|
"Random per Loose Part",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mask_init_task_cb(void *__restrict userdata,
|
static void mask_init_task_cb(void *__restrict userdata,
|
||||||
const int i,
|
const int i,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
@ -119,7 +119,7 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
|
|||||||
PBVH *pbvh = ob->sculpt->pbvh;
|
PBVH *pbvh = ob->sculpt->pbvh;
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
int totnode;
|
int totnode;
|
||||||
BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
|
|
||||||
if (totnode == 0) {
|
if (totnode == 0) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
@ -131,12 +131,11 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
|
|||||||
SCULPT_topology_islands_ensure(ob);
|
SCULPT_topology_islands_ensure(ob);
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.mask_init_mode = mode,
|
data.mask_init_mode = mode;
|
||||||
.mask_init_seed = PIL_check_seconds_timer(),
|
data.mask_init_seed = PIL_check_seconds_timer();
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
@ -24,23 +24,24 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
typedef struct MultiplaneScrapeSampleData {
|
struct MultiplaneScrapeSampleData {
|
||||||
float area_cos[2][3];
|
float area_cos[2][3];
|
||||||
float area_nos[2][3];
|
float area_nos[2][3];
|
||||||
int area_count[2];
|
int area_count[2];
|
||||||
} MultiplaneScrapeSampleData;
|
};
|
||||||
|
|
||||||
static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
|
static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
MultiplaneScrapeSampleData *mssd = tls->userdata_chunk;
|
MultiplaneScrapeSampleData *mssd = static_cast<MultiplaneScrapeSampleData *>(
|
||||||
|
tls->userdata_chunk);
|
||||||
float(*mat)[4] = data->mat;
|
float(*mat)[4] = data->mat;
|
||||||
|
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
@ -98,12 +99,12 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calc_multiplane_scrape_surface_reduce(const void *__restrict UNUSED(userdata),
|
static void calc_multiplane_scrape_surface_reduce(const void *__restrict /*userdata*/,
|
||||||
void *__restrict chunk_join,
|
void *__restrict chunk_join,
|
||||||
void *__restrict chunk)
|
void *__restrict chunk)
|
||||||
{
|
{
|
||||||
MultiplaneScrapeSampleData *join = chunk_join;
|
MultiplaneScrapeSampleData *join = static_cast<MultiplaneScrapeSampleData *>(chunk_join);
|
||||||
MultiplaneScrapeSampleData *mssd = chunk;
|
MultiplaneScrapeSampleData *mssd = static_cast<MultiplaneScrapeSampleData *>(chunk);
|
||||||
|
|
||||||
add_v3_v3(join->area_cos[0], mssd->area_cos[0]);
|
add_v3_v3(join->area_cos[0], mssd->area_cos[0]);
|
||||||
add_v3_v3(join->area_cos[1], mssd->area_cos[1]);
|
add_v3_v3(join->area_cos[1], mssd->area_cos[1]);
|
||||||
@ -119,7 +120,7 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
float(*mat)[4] = data->mat;
|
float(*mat)[4] = data->mat;
|
||||||
@ -275,14 +276,13 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
|
|||||||
if (brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_DYNAMIC) {
|
if (brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_DYNAMIC) {
|
||||||
/* Sample the individual normal and area center of the two areas at both sides of the cursor.
|
/* Sample the individual normal and area center of the two areas at both sides of the cursor.
|
||||||
*/
|
*/
|
||||||
SculptThreadedTaskData sample_data = {
|
SculptThreadedTaskData sample_data{};
|
||||||
.sd = NULL,
|
sample_data.sd = nullptr;
|
||||||
.ob = ob,
|
sample_data.ob = ob;
|
||||||
.brush = brush,
|
sample_data.brush = brush;
|
||||||
.nodes = nodes,
|
sample_data.nodes = nodes;
|
||||||
.totnode = totnode,
|
sample_data.totnode = totnode;
|
||||||
.mat = mat,
|
sample_data.mat = mat;
|
||||||
};
|
|
||||||
|
|
||||||
MultiplaneScrapeSampleData mssd = {{{0}}};
|
MultiplaneScrapeSampleData mssd = {{{0}}};
|
||||||
|
|
||||||
@ -302,13 +302,13 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
|
|||||||
|
|
||||||
/* Use the area center of both planes to detect if we are sculpting along a concave or convex
|
/* Use the area center of both planes to detect if we are sculpting along a concave or convex
|
||||||
* edge. */
|
* edge. */
|
||||||
mul_v3_v3fl(sampled_plane_co[0], mssd.area_cos[0], 1.0f / (float)mssd.area_count[0]);
|
mul_v3_v3fl(sampled_plane_co[0], mssd.area_cos[0], 1.0f / float(mssd.area_count[0]));
|
||||||
mul_v3_v3fl(sampled_plane_co[1], mssd.area_cos[1], 1.0f / (float)mssd.area_count[1]);
|
mul_v3_v3fl(sampled_plane_co[1], mssd.area_cos[1], 1.0f / float(mssd.area_count[1]));
|
||||||
mid_v3_v3v3(mid_co, sampled_plane_co[0], sampled_plane_co[1]);
|
mid_v3_v3v3(mid_co, sampled_plane_co[0], sampled_plane_co[1]);
|
||||||
|
|
||||||
/* Calculate the scrape planes angle based on the sampled normals. */
|
/* Calculate the scrape planes angle based on the sampled normals. */
|
||||||
mul_v3_v3fl(sampled_plane_normals[0], mssd.area_nos[0], 1.0f / (float)mssd.area_count[0]);
|
mul_v3_v3fl(sampled_plane_normals[0], mssd.area_nos[0], 1.0f / float(mssd.area_count[0]));
|
||||||
mul_v3_v3fl(sampled_plane_normals[1], mssd.area_nos[1], 1.0f / (float)mssd.area_count[1]);
|
mul_v3_v3fl(sampled_plane_normals[1], mssd.area_nos[1], 1.0f / float(mssd.area_count[1]));
|
||||||
normalize_v3(sampled_plane_normals[0]);
|
normalize_v3(sampled_plane_normals[0]);
|
||||||
normalize_v3(sampled_plane_normals[1]);
|
normalize_v3(sampled_plane_normals[1]);
|
||||||
|
|
||||||
@ -347,14 +347,13 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.mat = mat,
|
data.mat = mat;
|
||||||
.multiplane_scrape_angle = ss->cache->multiplane_scrape_angle,
|
data.multiplane_scrape_angle = ss->cache->multiplane_scrape_angle;
|
||||||
};
|
|
||||||
|
|
||||||
/* Calculate the final left and right scrape planes. */
|
/* Calculate the final left and right scrape planes. */
|
||||||
float plane_no[3];
|
float plane_no[3];
|
@ -67,13 +67,13 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
/* Reset the copy of the mesh that is being sculpted on (currently just for the layer brush). */
|
/* Reset the copy of the mesh that is being sculpted on (currently just for the layer brush). */
|
||||||
|
|
||||||
static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
|
static int sculpt_set_persistent_base_exec(bContext *C, wmOperator * /*op*/)
|
||||||
{
|
{
|
||||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
@ -127,7 +127,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
|
|||||||
|
|
||||||
/************************* SCULPT_OT_optimize *************************/
|
/************************* SCULPT_OT_optimize *************************/
|
||||||
|
|
||||||
static int sculpt_optimize_exec(bContext *C, wmOperator *UNUSED(op))
|
static int sculpt_optimize_exec(bContext *C, wmOperator * /*op*/)
|
||||||
{
|
{
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (BKE_pbvh_type(pbvh)) {
|
switch (BKE_pbvh_type(pbvh)) {
|
||||||
case PBVH_BMESH:
|
case PBVH_BMESH: {
|
||||||
/* Dyntopo Symmetrize. */
|
/* Dyntopo Symmetrize. */
|
||||||
|
|
||||||
/* To simplify undo for symmetrize, all BMesh elements are logged
|
/* To simplify undo for symmetrize, all BMesh elements are logged
|
||||||
@ -188,7 +188,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
|
|||||||
* are logged as added (as opposed to attempting to store just the
|
* are logged as added (as opposed to attempting to store just the
|
||||||
* parts that symmetrize modifies). */
|
* parts that symmetrize modifies). */
|
||||||
SCULPT_undo_push_begin(ob, op);
|
SCULPT_undo_push_begin(ob, op);
|
||||||
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_SYMMETRIZE);
|
SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_DYNTOPO_SYMMETRIZE);
|
||||||
BM_log_before_all_removed(ss->bm, ss->bm_log);
|
BM_log_before_all_removed(ss->bm, ss->bm_log);
|
||||||
|
|
||||||
BM_mesh_toolflags_set(ss->bm, true);
|
BM_mesh_toolflags_set(ss->bm, true);
|
||||||
@ -212,17 +212,19 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
|
|||||||
SCULPT_undo_push_end(ob);
|
SCULPT_undo_push_end(ob);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PBVH_FACES:
|
}
|
||||||
|
case PBVH_FACES: {
|
||||||
/* Mesh Symmetrize. */
|
/* Mesh Symmetrize. */
|
||||||
ED_sculpt_undo_geometry_begin(ob, op);
|
ED_sculpt_undo_geometry_begin(ob, op);
|
||||||
Mesh *mesh = ob->data;
|
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||||
|
|
||||||
BKE_mesh_mirror_apply_mirror_on_axis(bmain, mesh, sd->symmetrize_direction, dist);
|
BKE_mesh_mirror_apply_mirror_on_axis(bmain, mesh, sd->symmetrize_direction, dist);
|
||||||
|
|
||||||
ED_sculpt_undo_geometry_end(ob);
|
ED_sculpt_undo_geometry_end(ob);
|
||||||
BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
|
BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PBVH_GRIDS:
|
case PBVH_GRIDS:
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
@ -266,10 +268,10 @@ static void sculpt_init_session(Main *bmain, Depsgraph *depsgraph, Scene *scene,
|
|||||||
BKE_sculpt_toolsettings_data_ensure(scene);
|
BKE_sculpt_toolsettings_data_ensure(scene);
|
||||||
|
|
||||||
/* Create sculpt mode session data. */
|
/* Create sculpt mode session data. */
|
||||||
if (ob->sculpt != NULL) {
|
if (ob->sculpt != nullptr) {
|
||||||
BKE_sculptsession_free(ob);
|
BKE_sculptsession_free(ob);
|
||||||
}
|
}
|
||||||
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
|
ob->sculpt = MEM_cnew<SculptSession>(__func__);
|
||||||
ob->sculpt->mode_type = OB_MODE_SCULPT;
|
ob->sculpt->mode_type = OB_MODE_SCULPT;
|
||||||
|
|
||||||
/* Trigger evaluation of modifier stack to ensure
|
/* Trigger evaluation of modifier stack to ensure
|
||||||
@ -359,11 +361,11 @@ void ED_object_sculptmode_enter_ex(Main *bmain,
|
|||||||
if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
|
if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
|
||||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
|
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
|
||||||
|
|
||||||
const char *message_unsupported = NULL;
|
const char *message_unsupported = nullptr;
|
||||||
if (me->totloop != me->totpoly * 3) {
|
if (me->totloop != me->totpoly * 3) {
|
||||||
message_unsupported = TIP_("non-triangle face");
|
message_unsupported = TIP_("non-triangle face");
|
||||||
}
|
}
|
||||||
else if (mmd != NULL) {
|
else if (mmd != nullptr) {
|
||||||
message_unsupported = TIP_("multi-res modifier");
|
message_unsupported = TIP_("multi-res modifier");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -388,17 +390,17 @@ void ED_object_sculptmode_enter_ex(Main *bmain,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((message_unsupported == NULL) || force_dyntopo) {
|
if ((message_unsupported == nullptr) || force_dyntopo) {
|
||||||
/* Needed because we may be entering this mode before the undo system loads. */
|
/* Needed because we may be entering this mode before the undo system loads. */
|
||||||
wmWindowManager *wm = bmain->wm.first;
|
wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
|
||||||
bool has_undo = wm->undo_stack != NULL;
|
bool has_undo = wm->undo_stack != nullptr;
|
||||||
/* Undo push is needed to prevent memory leak. */
|
/* Undo push is needed to prevent memory leak. */
|
||||||
if (has_undo) {
|
if (has_undo) {
|
||||||
SCULPT_undo_push_begin_ex(ob, "Dynamic topology enable");
|
SCULPT_undo_push_begin_ex(ob, "Dynamic topology enable");
|
||||||
}
|
}
|
||||||
SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob);
|
SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob);
|
||||||
if (has_undo) {
|
if (has_undo) {
|
||||||
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
|
SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_DYNTOPO_BEGIN);
|
||||||
SCULPT_undo_push_end(ob);
|
SCULPT_undo_push_end(ob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,7 +417,7 @@ void ED_object_sculptmode_enter_ex(Main *bmain,
|
|||||||
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
|
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_object_sculptmode_enter(struct bContext *C, Depsgraph *depsgraph, ReportList *reports)
|
void ED_object_sculptmode_enter(bContext *C, Depsgraph *depsgraph, ReportList *reports)
|
||||||
{
|
{
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
@ -480,7 +482,7 @@ void ED_object_sculptmode_exit(bContext *C, Depsgraph *depsgraph)
|
|||||||
|
|
||||||
static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
|
static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
|
wmMsgBus *mbus = CTX_wm_message_bus(C);
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
|
Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
@ -492,7 +494,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
|
|||||||
const bool is_mode_set = (ob->mode & mode_flag) != 0;
|
const bool is_mode_set = (ob->mode & mode_flag) != 0;
|
||||||
|
|
||||||
if (!is_mode_set) {
|
if (!is_mode_set) {
|
||||||
if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
|
if (!ED_object_mode_compat_set(C, ob, eObjectMode(mode_flag), op->reports)) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -508,7 +510,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
|
|||||||
BKE_paint_toolslots_brush_validate(bmain, &ts->sculpt->paint);
|
BKE_paint_toolslots_brush_validate(bmain, &ts->sculpt->paint);
|
||||||
|
|
||||||
if (ob->mode & mode_flag) {
|
if (ob->mode & mode_flag) {
|
||||||
Mesh *me = ob->data;
|
Mesh *me = static_cast<Mesh *>(ob->data);
|
||||||
/* Dyntopo adds its own undo step. */
|
/* Dyntopo adds its own undo step. */
|
||||||
if ((me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) == 0) {
|
if ((me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) == 0) {
|
||||||
/* Without this the memfile undo step is used,
|
/* Without this the memfile undo step is used,
|
||||||
@ -580,8 +582,8 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
|
|||||||
/* Assuming an average of 6 edges per vertex in a triangulated mesh. */
|
/* Assuming an average of 6 edges per vertex in a triangulated mesh. */
|
||||||
const int max_preview_verts = SCULPT_vertex_count_get(ss) * 3 * 2;
|
const int max_preview_verts = SCULPT_vertex_count_get(ss) * 3 * 2;
|
||||||
|
|
||||||
if (ss->preview_vert_list == NULL) {
|
if (ss->preview_vert_list == nullptr) {
|
||||||
ss->preview_vert_list = MEM_callocN(max_preview_verts * sizeof(PBVHVertRef), "preview lines");
|
ss->preview_vert_list = MEM_cnew_array<PBVHVertRef>(max_preview_verts, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSQueue *non_visited_verts = BLI_gsqueue_new(sizeof(PBVHVertRef));
|
GSQueue *non_visited_verts = BLI_gsqueue_new(sizeof(PBVHVertRef));
|
||||||
@ -621,7 +623,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
|
|||||||
ss->preview_vert_count = totpoints;
|
ss->preview_vert_count = totpoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e))
|
static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||||
{
|
{
|
||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
@ -718,17 +720,18 @@ static float sculpt_mask_by_color_final_mask_get(const float current_mask,
|
|||||||
return new_mask;
|
return new_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct MaskByColorContiguousFloodFillData {
|
struct MaskByColorContiguousFloodFillData {
|
||||||
float threshold;
|
float threshold;
|
||||||
bool invert;
|
bool invert;
|
||||||
float *new_mask;
|
float *new_mask;
|
||||||
float initial_color[3];
|
float initial_color[3];
|
||||||
} MaskByColorContiguousFloodFillData;
|
};
|
||||||
|
|
||||||
static void do_mask_by_color_contiguous_update_nodes_cb(
|
static void do_mask_by_color_contiguous_update_nodes_cb(void *__restrict userdata,
|
||||||
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
|
const int n,
|
||||||
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
|
|
||||||
SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK);
|
SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK);
|
||||||
@ -759,7 +762,8 @@ static bool sculpt_mask_by_color_contiguous_floodfill_cb(
|
|||||||
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
||||||
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||||
|
|
||||||
MaskByColorContiguousFloodFillData *data = userdata;
|
MaskByColorContiguousFloodFillData *data = static_cast<MaskByColorContiguousFloodFillData *>(
|
||||||
|
userdata);
|
||||||
float current_color[4];
|
float current_color[4];
|
||||||
|
|
||||||
SCULPT_vertex_color_get(ss, to_v, current_color);
|
SCULPT_vertex_color_get(ss, to_v, current_color);
|
||||||
@ -786,7 +790,7 @@ static void sculpt_mask_by_color_contiguous(Object *object,
|
|||||||
SculptSession *ss = object->sculpt;
|
SculptSession *ss = object->sculpt;
|
||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
|
|
||||||
float *new_mask = MEM_calloc_arrayN(totvert, sizeof(float), "new mask");
|
float *new_mask = MEM_cnew_array<float>(totvert, __func__);
|
||||||
|
|
||||||
if (invert) {
|
if (invert) {
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
@ -813,17 +817,16 @@ static void sculpt_mask_by_color_contiguous(Object *object,
|
|||||||
|
|
||||||
int totnode;
|
int totnode;
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.ob = object,
|
data.ob = object;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.mask_by_color_floodfill = new_mask,
|
data.mask_by_color_floodfill = new_mask;
|
||||||
.mask_by_color_vertex = vertex,
|
data.mask_by_color_vertex = vertex;
|
||||||
.mask_by_color_threshold = threshold,
|
data.mask_by_color_threshold = threshold;
|
||||||
.mask_by_color_invert = invert,
|
data.mask_by_color_invert = invert;
|
||||||
.mask_by_color_preserve_mask = preserve_mask,
|
data.mask_by_color_preserve_mask = preserve_mask;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -837,9 +840,9 @@ static void sculpt_mask_by_color_contiguous(Object *object,
|
|||||||
|
|
||||||
static void do_mask_by_color_task_cb(void *__restrict userdata,
|
static void do_mask_by_color_task_cb(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
|
|
||||||
SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK);
|
SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK);
|
||||||
@ -882,16 +885,15 @@ static void sculpt_mask_by_color_full_mesh(Object *object,
|
|||||||
|
|
||||||
int totnode;
|
int totnode;
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.ob = object,
|
data.ob = object;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.mask_by_color_vertex = vertex,
|
data.mask_by_color_vertex = vertex;
|
||||||
.mask_by_color_threshold = threshold,
|
data.mask_by_color_threshold = threshold;
|
||||||
.mask_by_color_invert = invert,
|
data.mask_by_color_invert = invert;
|
||||||
.mask_by_color_preserve_mask = preserve_mask,
|
data.mask_by_color_preserve_mask = preserve_mask;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -924,7 +926,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven
|
|||||||
/* Tools that are not brushes do not have the brush gizmo to update the vertex as the mouse move,
|
/* Tools that are not brushes do not have the brush gizmo to update the vertex as the mouse move,
|
||||||
* so it needs to be updated here. */
|
* so it needs to be updated here. */
|
||||||
SculptCursorGeometryInfo sgi;
|
SculptCursorGeometryInfo sgi;
|
||||||
const float mval_fl[2] = {UNPACK2(event->mval)};
|
const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||||
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
||||||
|
|
||||||
SCULPT_undo_push_begin(ob, op);
|
SCULPT_undo_push_begin(ob, op);
|
||||||
@ -990,34 +992,34 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
|
|||||||
1.0f);
|
1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum {
|
enum CavityBakeMixMode {
|
||||||
AUTOMASK_BAKE_MIX,
|
AUTOMASK_BAKE_MIX,
|
||||||
AUTOMASK_BAKE_MULTIPLY,
|
AUTOMASK_BAKE_MULTIPLY,
|
||||||
AUTOMASK_BAKE_DIVIDE,
|
AUTOMASK_BAKE_DIVIDE,
|
||||||
AUTOMASK_BAKE_ADD,
|
AUTOMASK_BAKE_ADD,
|
||||||
AUTOMASK_BAKE_SUBTRACT,
|
AUTOMASK_BAKE_SUBTRACT,
|
||||||
} CavityBakeMixMode;
|
};
|
||||||
|
|
||||||
typedef enum {
|
enum CavityBakeSettingsSource {
|
||||||
AUTOMASK_SETTINGS_OPERATOR,
|
AUTOMASK_SETTINGS_OPERATOR,
|
||||||
AUTOMASK_SETTINGS_SCENE,
|
AUTOMASK_SETTINGS_SCENE,
|
||||||
AUTOMASK_SETTINGS_BRUSH
|
AUTOMASK_SETTINGS_BRUSH
|
||||||
} CavityBakeSettingsSource;
|
};
|
||||||
|
|
||||||
typedef struct AutomaskBakeTaskData {
|
struct AutomaskBakeTaskData {
|
||||||
SculptSession *ss;
|
SculptSession *ss;
|
||||||
AutomaskingCache *automasking;
|
AutomaskingCache *automasking;
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
CavityBakeMixMode mode;
|
CavityBakeMixMode mode;
|
||||||
float factor;
|
float factor;
|
||||||
Object *ob;
|
Object *ob;
|
||||||
} AutomaskBakeTaskData;
|
};
|
||||||
|
|
||||||
static void sculpt_bake_cavity_exec_task_cb(void *__restrict userdata,
|
static void sculpt_bake_cavity_exec_task_cb(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
AutomaskBakeTaskData *tdata = userdata;
|
AutomaskBakeTaskData *tdata = static_cast<AutomaskBakeTaskData *>(userdata);
|
||||||
SculptSession *ss = tdata->ss;
|
SculptSession *ss = tdata->ss;
|
||||||
PBVHNode *node = tdata->nodes[n];
|
PBVHNode *node = tdata->nodes[n];
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
@ -1072,7 +1074,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
|
|||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||||
|
|
||||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
|
MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
|
||||||
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
||||||
@ -1082,13 +1084,13 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
SCULPT_undo_push_begin(ob, op);
|
SCULPT_undo_push_begin(ob, op);
|
||||||
|
|
||||||
CavityBakeMixMode mode = RNA_enum_get(op->ptr, "mix_mode");
|
CavityBakeMixMode mode = CavityBakeMixMode(RNA_enum_get(op->ptr, "mix_mode"));
|
||||||
float factor = RNA_float_get(op->ptr, "mix_factor");
|
float factor = RNA_float_get(op->ptr, "mix_factor");
|
||||||
|
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
int totnode;
|
int totnode;
|
||||||
|
|
||||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
|
|
||||||
AutomaskBakeTaskData tdata;
|
AutomaskBakeTaskData tdata;
|
||||||
|
|
||||||
@ -1096,9 +1098,9 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
|
|||||||
*/
|
*/
|
||||||
Sculpt sd2 = *sd;
|
Sculpt sd2 = *sd;
|
||||||
|
|
||||||
CavityBakeSettingsSource source = (CavityBakeSettingsSource)RNA_enum_get(op->ptr,
|
CavityBakeSettingsSource src = (CavityBakeSettingsSource)RNA_enum_get(op->ptr,
|
||||||
"settings_source");
|
"settings_source");
|
||||||
switch (source) {
|
switch (src) {
|
||||||
case AUTOMASK_SETTINGS_OPERATOR:
|
case AUTOMASK_SETTINGS_OPERATOR:
|
||||||
if (RNA_boolean_get(op->ptr, "invert")) {
|
if (RNA_boolean_get(op->ptr, "invert")) {
|
||||||
sd2.automasking_flags = BRUSH_AUTOMASKING_CAVITY_INVERTED;
|
sd2.automasking_flags = BRUSH_AUTOMASKING_CAVITY_INVERTED;
|
||||||
@ -1146,7 +1148,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create copy of brush with cleared automasking settings. */
|
/* Create copy of brush with cleared automasking settings. */
|
||||||
Brush brush2 = *brush;
|
Brush brush2 = blender::dna::shallow_copy(*brush);
|
||||||
brush2.automasking_flags = 0;
|
brush2.automasking_flags = 0;
|
||||||
brush2.automasking_boundary_edges_propagation_steps = 1;
|
brush2.automasking_boundary_edges_propagation_steps = 1;
|
||||||
brush2.automasking_cavity_curve = sd2.automasking_cavity_curve;
|
brush2.automasking_cavity_curve = sd2.automasking_cavity_curve;
|
||||||
@ -1180,7 +1182,7 @@ static void cavity_bake_ui(bContext *C, wmOperator *op)
|
|||||||
{
|
{
|
||||||
uiLayout *layout = op->layout;
|
uiLayout *layout = op->layout;
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
Sculpt *sd = scene->toolsettings ? scene->toolsettings->sculpt : NULL;
|
Sculpt *sd = scene->toolsettings ? scene->toolsettings->sculpt : nullptr;
|
||||||
|
|
||||||
uiLayoutSetPropSep(layout, true);
|
uiLayoutSetPropSep(layout, true);
|
||||||
uiLayoutSetPropDecorate(layout, false);
|
uiLayoutSetPropDecorate(layout, false);
|
||||||
@ -1193,13 +1195,13 @@ static void cavity_bake_ui(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case AUTOMASK_SETTINGS_OPERATOR: {
|
case AUTOMASK_SETTINGS_OPERATOR: {
|
||||||
uiItemR(layout, op->ptr, "mix_mode", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "mix_mode", 0, nullptr, ICON_NONE);
|
||||||
uiItemR(layout, op->ptr, "mix_factor", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "mix_factor", 0, nullptr, ICON_NONE);
|
||||||
uiItemR(layout, op->ptr, "settings_source", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "settings_source", 0, nullptr, ICON_NONE);
|
||||||
uiItemR(layout, op->ptr, "factor", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "factor", 0, nullptr, ICON_NONE);
|
||||||
uiItemR(layout, op->ptr, "blur_steps", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "blur_steps", 0, nullptr, ICON_NONE);
|
||||||
uiItemR(layout, op->ptr, "invert", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "invert", 0, nullptr, ICON_NONE);
|
||||||
uiItemR(layout, op->ptr, "use_curve", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "use_curve", 0, nullptr, ICON_NONE);
|
||||||
|
|
||||||
if (sd && RNA_boolean_get(op->ptr, "use_curve")) {
|
if (sd && RNA_boolean_get(op->ptr, "use_curve")) {
|
||||||
PointerRNA sculpt_ptr;
|
PointerRNA sculpt_ptr;
|
||||||
@ -1212,9 +1214,9 @@ static void cavity_bake_ui(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
case AUTOMASK_SETTINGS_BRUSH:
|
case AUTOMASK_SETTINGS_BRUSH:
|
||||||
case AUTOMASK_SETTINGS_SCENE:
|
case AUTOMASK_SETTINGS_SCENE:
|
||||||
uiItemR(layout, op->ptr, "mix_mode", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "mix_mode", 0, nullptr, ICON_NONE);
|
||||||
uiItemR(layout, op->ptr, "mix_factor", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "mix_factor", 0, nullptr, ICON_NONE);
|
||||||
uiItemR(layout, op->ptr, "settings_source", 0, NULL, ICON_NONE);
|
uiItemR(layout, op->ptr, "settings_source", 0, nullptr, ICON_NONE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1234,7 +1236,7 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot)
|
|||||||
{AUTOMASK_BAKE_DIVIDE, "DIVIDE", ICON_NONE, "Divide", ""},
|
{AUTOMASK_BAKE_DIVIDE, "DIVIDE", ICON_NONE, "Divide", ""},
|
||||||
{AUTOMASK_BAKE_ADD, "ADD", ICON_NONE, "Add", ""},
|
{AUTOMASK_BAKE_ADD, "ADD", ICON_NONE, "Add", ""},
|
||||||
{AUTOMASK_BAKE_SUBTRACT, "SUBTRACT", ICON_NONE, "Subtract", ""},
|
{AUTOMASK_BAKE_SUBTRACT, "SUBTRACT", ICON_NONE, "Subtract", ""},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
@ -1254,7 +1256,7 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot)
|
|||||||
"Use settings from operator properties"},
|
"Use settings from operator properties"},
|
||||||
{AUTOMASK_SETTINGS_BRUSH, "BRUSH", ICON_NONE, "Brush", "Use settings from brush"},
|
{AUTOMASK_SETTINGS_BRUSH, "BRUSH", ICON_NONE, "Brush", "Use settings from brush"},
|
||||||
{AUTOMASK_SETTINGS_SCENE, "SCENE", ICON_NONE, "Scene", "Use settings from scene"},
|
{AUTOMASK_SETTINGS_SCENE, "SCENE", ICON_NONE, "Scene", "Use settings from scene"},
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, nullptr, 0, nullptr, nullptr}};
|
||||||
|
|
||||||
RNA_def_enum(ot->srna,
|
RNA_def_enum(ot->srna,
|
||||||
"settings_source",
|
"settings_source",
|
||||||
@ -1304,7 +1306,7 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op)
|
|||||||
int totnode;
|
int totnode;
|
||||||
bool with_bmesh = BKE_pbvh_type(ss->pbvh) == PBVH_BMESH;
|
bool with_bmesh = BKE_pbvh_type(ss->pbvh) == PBVH_BMESH;
|
||||||
|
|
||||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
|
|
||||||
if (!totnode) {
|
if (!totnode) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
@ -1330,7 +1332,7 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op)
|
|||||||
* reduced memory usage without manually clearing it later, and allows sculpt operations to
|
* reduced memory usage without manually clearing it later, and allows sculpt operations to
|
||||||
* avoid checking element's hide status. */
|
* avoid checking element's hide status. */
|
||||||
CustomData_free_layer_named(&mesh->pdata, ".hide_poly", mesh->totpoly);
|
CustomData_free_layer_named(&mesh->pdata, ".hide_poly", mesh->totpoly);
|
||||||
ss->hide_poly = NULL;
|
ss->hide_poly = nullptr;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_HIDDEN);
|
SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_HIDDEN);
|
@ -29,14 +29,14 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
static void do_color_smooth_task_cb_exec(void *__restrict userdata,
|
static void do_color_smooth_task_cb_exec(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = ss->cache->bstrength;
|
const float bstrength = ss->cache->bstrength;
|
||||||
@ -85,7 +85,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = fabsf(ss->cache->bstrength);
|
const float bstrength = fabsf(ss->cache->bstrength);
|
||||||
@ -168,7 +168,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
float noise = 1.0f;
|
float noise = 1.0f;
|
||||||
const float density = ss->cache->paint_brush.density;
|
const float density = ss->cache->paint_brush.density;
|
||||||
if (density < 1.0f) {
|
if (density < 1.0f) {
|
||||||
const float hash_noise = (float)BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
|
const float hash_noise = float(BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index));
|
||||||
if (hash_noise > density) {
|
if (hash_noise > density) {
|
||||||
noise = density * hash_noise;
|
noise = density * hash_noise;
|
||||||
fade = fade * noise;
|
fade = fade * noise;
|
||||||
@ -196,25 +196,25 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
|
|
||||||
float col[4];
|
float col[4];
|
||||||
SCULPT_vertex_color_get(ss, vd.vertex, col);
|
SCULPT_vertex_color_get(ss, vd.vertex, col);
|
||||||
IMB_blend_color_float(col, orig_data.col, buffer_color, brush->blend);
|
IMB_blend_color_float(col, orig_data.col, buffer_color, IMB_BlendMode(brush->blend));
|
||||||
CLAMP4(col, 0.0f, 1.0f);
|
CLAMP4(col, 0.0f, 1.0f);
|
||||||
SCULPT_vertex_color_set(ss, vd.vertex, col);
|
SCULPT_vertex_color_set(ss, vd.vertex, col);
|
||||||
}
|
}
|
||||||
BKE_pbvh_vertex_iter_end;
|
BKE_pbvh_vertex_iter_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct SampleWetPaintTLSData {
|
struct SampleWetPaintTLSData {
|
||||||
int tot_samples;
|
int tot_samples;
|
||||||
float color[4];
|
float color[4];
|
||||||
} SampleWetPaintTLSData;
|
};
|
||||||
|
|
||||||
static void do_sample_wet_paint_task_cb(void *__restrict userdata,
|
static void do_sample_wet_paint_task_cb(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
SampleWetPaintTLSData *swptd = tls->userdata_chunk;
|
SampleWetPaintTLSData *swptd = static_cast<SampleWetPaintTLSData *>(tls->userdata_chunk);
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
|
|
||||||
SculptBrushTest test;
|
SculptBrushTest test;
|
||||||
@ -238,12 +238,12 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata,
|
|||||||
BKE_pbvh_vertex_iter_end;
|
BKE_pbvh_vertex_iter_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sample_wet_paint_reduce(const void *__restrict UNUSED(userdata),
|
static void sample_wet_paint_reduce(const void *__restrict /*userdata*/,
|
||||||
void *__restrict chunk_join,
|
void *__restrict chunk_join,
|
||||||
void *__restrict chunk)
|
void *__restrict chunk)
|
||||||
{
|
{
|
||||||
SampleWetPaintTLSData *join = chunk_join;
|
SampleWetPaintTLSData *join = static_cast<SampleWetPaintTLSData *>(chunk_join);
|
||||||
SampleWetPaintTLSData *swptd = chunk;
|
SampleWetPaintTLSData *swptd = static_cast<SampleWetPaintTLSData *>(chunk);
|
||||||
|
|
||||||
join->tot_samples += swptd->tot_samples;
|
join->tot_samples += swptd->tot_samples;
|
||||||
add_v4_v4(join->color, swptd->color);
|
add_v4_v4(join->color, swptd->color);
|
||||||
@ -271,7 +271,7 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
|||||||
|
|
||||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||||
ss->cache->density_seed = (float)BLI_hash_int_01(ss->cache->location[0] * 1000);
|
ss->cache->density_seed = float(BLI_hash_int_01(ss->cache->location[0] * 1000));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -309,13 +309,12 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
|||||||
|
|
||||||
/* Smooth colors mode. */
|
/* Smooth colors mode. */
|
||||||
if (ss->cache->alt_smooth) {
|
if (ss->cache->alt_smooth) {
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.mat = mat,
|
data.mat = mat;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -328,12 +327,11 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
|||||||
/* Wet paint color sampling. */
|
/* Wet paint color sampling. */
|
||||||
float wet_color[4] = {0.0f};
|
float wet_color[4] = {0.0f};
|
||||||
if (ss->cache->paint_brush.wet_mix > 0.0f) {
|
if (ss->cache->paint_brush.wet_mix > 0.0f) {
|
||||||
SculptThreadedTaskData task_data = {
|
SculptThreadedTaskData task_data{};
|
||||||
.sd = sd,
|
task_data.sd = sd;
|
||||||
.ob = ob,
|
task_data.ob = ob;
|
||||||
.nodes = nodes,
|
task_data.nodes = nodes;
|
||||||
.brush = brush,
|
task_data.brush = brush;
|
||||||
};
|
|
||||||
|
|
||||||
SampleWetPaintTLSData swptd;
|
SampleWetPaintTLSData swptd;
|
||||||
swptd.tot_samples = 0;
|
swptd.tot_samples = 0;
|
||||||
@ -364,14 +362,13 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Threaded loop over nodes. */
|
/* Threaded loop over nodes. */
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.wet_mix_sampled_color = wet_color,
|
data.wet_mix_sampled_color = wet_color;
|
||||||
.mat = mat,
|
data.mat = mat;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -382,7 +379,7 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = ss->cache->bstrength;
|
const float bstrength = ss->cache->bstrength;
|
||||||
@ -533,9 +530,9 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
|
|||||||
|
|
||||||
static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata,
|
static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
|
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
@ -557,7 +554,7 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
|
|
||||||
if (!ss->cache->prev_colors) {
|
if (!ss->cache->prev_colors) {
|
||||||
ss->cache->prev_colors = MEM_callocN(sizeof(float[4]) * totvert, "prev colors");
|
ss->cache->prev_colors = MEM_cnew_array<float[4]>(totvert, __func__);
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||||
|
|
||||||
@ -567,12 +564,11 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||||||
|
|
||||||
BKE_curvemapping_init(brush->curve);
|
BKE_curvemapping_init(brush->curve);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
static void pose_solve_ik_chain(SculptPoseIKChain *ik_chain,
|
static void pose_solve_ik_chain(SculptPoseIKChain *ik_chain,
|
||||||
const float initial_target[3],
|
const float initial_target[3],
|
||||||
@ -136,9 +136,9 @@ static void pose_solve_scale_chain(SculptPoseIKChain *ik_chain, const float scal
|
|||||||
|
|
||||||
static void do_pose_brush_task_cb_ex(void *__restrict userdata,
|
static void do_pose_brush_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
|
SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
|
||||||
SculptPoseIKChainSegment *segments = ik_chain->segments;
|
SculptPoseIKChainSegment *segments = ik_chain->segments;
|
||||||
@ -169,9 +169,9 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
|
|
||||||
/* Get the transform matrix for the vertex symmetry area to calculate a displacement in the
|
/* Get the transform matrix for the vertex symmetry area to calculate a displacement in the
|
||||||
* vertex. */
|
* vertex. */
|
||||||
mul_m4_v3(segments[ik].pivot_mat_inv[(int)symm_area], new_co);
|
mul_m4_v3(segments[ik].pivot_mat_inv[int(symm_area)], new_co);
|
||||||
mul_m4_v3(segments[ik].trans_mat[(int)symm_area], new_co);
|
mul_m4_v3(segments[ik].trans_mat[int(symm_area)], new_co);
|
||||||
mul_m4_v3(segments[ik].pivot_mat[(int)symm_area], new_co);
|
mul_m4_v3(segments[ik].pivot_mat[int(symm_area)], new_co);
|
||||||
|
|
||||||
/* Apply the segment weight of the vertex to the displacement. */
|
/* Apply the segment weight of the vertex to the displacement. */
|
||||||
sub_v3_v3v3(disp, new_co, orig_data.co);
|
sub_v3_v3v3(disp, new_co, orig_data.co);
|
||||||
@ -200,17 +200,17 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
BKE_pbvh_vertex_iter_end;
|
BKE_pbvh_vertex_iter_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct PoseGrowFactorTLSData {
|
struct PoseGrowFactorTLSData {
|
||||||
float pos_avg[3];
|
float pos_avg[3];
|
||||||
int pos_count;
|
int pos_count;
|
||||||
} PoseGrowFactorTLSData;
|
};
|
||||||
|
|
||||||
static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata,
|
static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
PoseGrowFactorTLSData *gftd = tls->userdata_chunk;
|
PoseGrowFactorTLSData *gftd = static_cast<PoseGrowFactorTLSData *>(tls->userdata_chunk);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const char symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
|
const char symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
@ -238,12 +238,12 @@ static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata,
|
|||||||
BKE_pbvh_vertex_iter_end;
|
BKE_pbvh_vertex_iter_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pose_brush_grow_factor_reduce(const void *__restrict UNUSED(userdata),
|
static void pose_brush_grow_factor_reduce(const void *__restrict /*userdata*/,
|
||||||
void *__restrict chunk_join,
|
void *__restrict chunk_join,
|
||||||
void *__restrict chunk)
|
void *__restrict chunk)
|
||||||
{
|
{
|
||||||
PoseGrowFactorTLSData *join = chunk_join;
|
PoseGrowFactorTLSData *join = static_cast<PoseGrowFactorTLSData *>(chunk_join);
|
||||||
PoseGrowFactorTLSData *gftd = chunk;
|
PoseGrowFactorTLSData *gftd = static_cast<PoseGrowFactorTLSData *>(chunk);
|
||||||
add_v3_v3(join->pos_avg, gftd->pos_avg);
|
add_v3_v3(join->pos_avg, gftd->pos_avg);
|
||||||
join->pos_count += gftd->pos_count;
|
join->pos_count += gftd->pos_count;
|
||||||
}
|
}
|
||||||
@ -263,14 +263,13 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd,
|
|||||||
PBVH *pbvh = ob->sculpt->pbvh;
|
PBVH *pbvh = ob->sculpt->pbvh;
|
||||||
int totnode;
|
int totnode;
|
||||||
|
|
||||||
BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.totnode = totnode,
|
data.totnode = totnode;
|
||||||
.pose_factor = pose_factor,
|
data.pose_factor = pose_factor;
|
||||||
};
|
|
||||||
|
|
||||||
data.pose_initial_co = pose_target;
|
data.pose_initial_co = pose_target;
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
@ -284,7 +283,8 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd,
|
|||||||
|
|
||||||
bool grow_next_iteration = true;
|
bool grow_next_iteration = true;
|
||||||
float prev_len = FLT_MAX;
|
float prev_len = FLT_MAX;
|
||||||
data.prev_mask = MEM_mallocN(SCULPT_vertex_count_get(ss) * sizeof(float), "prev mask");
|
data.prev_mask = static_cast<float *>(
|
||||||
|
MEM_malloc_arrayN(SCULPT_vertex_count_get(ss), sizeof(float), __func__));
|
||||||
while (grow_next_iteration) {
|
while (grow_next_iteration) {
|
||||||
zero_v3(gftd.pos_avg);
|
zero_v3(gftd.pos_avg);
|
||||||
gftd.pos_count = 0;
|
gftd.pos_count = 0;
|
||||||
@ -292,7 +292,7 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd,
|
|||||||
BLI_task_parallel_range(0, totnode, &data, pose_brush_grow_factor_task_cb_ex, &settings);
|
BLI_task_parallel_range(0, totnode, &data, pose_brush_grow_factor_task_cb_ex, &settings);
|
||||||
|
|
||||||
if (gftd.pos_count != 0) {
|
if (gftd.pos_count != 0) {
|
||||||
mul_v3_fl(gftd.pos_avg, 1.0f / (float)gftd.pos_count);
|
mul_v3_fl(gftd.pos_avg, 1.0f / float(gftd.pos_count));
|
||||||
if (pose_origin) {
|
if (pose_origin) {
|
||||||
/* Test with pose origin. Used when growing the factors to compensate the Origin Offset. */
|
/* Test with pose origin. Used when growing the factors to compensate the Origin Offset. */
|
||||||
/* Stop when the factor's avg_pos starts moving away from the origin instead of getting
|
/* Stop when the factor's avg_pos starts moving away from the origin instead of getting
|
||||||
@ -344,7 +344,7 @@ static bool sculpt_pose_brush_is_vertex_inside_brush_radius(const float vertex[3
|
|||||||
for (char i = 0; i <= symm; ++i) {
|
for (char i = 0; i <= symm; ++i) {
|
||||||
if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
|
if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
|
||||||
float location[3];
|
float location[3];
|
||||||
flip_v3_v3(location, br_co, (char)i);
|
flip_v3_v3(location, br_co, ePaintSymmetryFlags(i));
|
||||||
if (len_v3v3(location, vertex) < radius) {
|
if (len_v3v3(location, vertex) < radius) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -353,7 +353,7 @@ static bool sculpt_pose_brush_is_vertex_inside_brush_radius(const float vertex[3
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct PoseFloodFillData {
|
struct PoseFloodFillData {
|
||||||
float pose_initial_co[3];
|
float pose_initial_co[3];
|
||||||
float radius;
|
float radius;
|
||||||
int symm;
|
int symm;
|
||||||
@ -393,17 +393,14 @@ typedef struct PoseFloodFillData {
|
|||||||
int masked_face_set_it;
|
int masked_face_set_it;
|
||||||
int masked_face_set;
|
int masked_face_set;
|
||||||
int target_face_set;
|
int target_face_set;
|
||||||
} PoseFloodFillData;
|
};
|
||||||
|
|
||||||
static bool pose_topology_floodfill_cb(SculptSession *ss,
|
static bool pose_topology_floodfill_cb(
|
||||||
PBVHVertRef UNUSED(from_v),
|
SculptSession *ss, PBVHVertRef /*from_v*/, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
||||||
PBVHVertRef to_v,
|
|
||||||
bool is_duplicate,
|
|
||||||
void *userdata)
|
|
||||||
{
|
{
|
||||||
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||||
|
|
||||||
PoseFloodFillData *data = userdata;
|
PoseFloodFillData *data = static_cast<PoseFloodFillData *>(userdata);
|
||||||
const float *co = SCULPT_vertex_co_get(ss, to_v);
|
const float *co = SCULPT_vertex_co_get(ss, to_v);
|
||||||
|
|
||||||
if (data->pose_factor) {
|
if (data->pose_factor) {
|
||||||
@ -429,13 +426,10 @@ static bool pose_topology_floodfill_cb(SculptSession *ss,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pose_face_sets_floodfill_cb(SculptSession *ss,
|
static bool pose_face_sets_floodfill_cb(
|
||||||
PBVHVertRef UNUSED(from_v),
|
SculptSession *ss, PBVHVertRef /*from_v*/, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
||||||
PBVHVertRef to_v,
|
|
||||||
bool is_duplicate,
|
|
||||||
void *userdata)
|
|
||||||
{
|
{
|
||||||
PoseFloodFillData *data = userdata;
|
PoseFloodFillData *data = static_cast<PoseFloodFillData *>(userdata);
|
||||||
|
|
||||||
const int index = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
const int index = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||||
const PBVHVertRef vertex = to_v;
|
const PBVHVertRef vertex = to_v;
|
||||||
@ -547,12 +541,12 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd,
|
|||||||
SCULPT_floodfill_init(ss, &flood);
|
SCULPT_floodfill_init(ss, &flood);
|
||||||
SCULPT_floodfill_add_active(sd, ob, ss, &flood, (r_pose_factor) ? radius : 0.0f);
|
SCULPT_floodfill_add_active(sd, ob, ss, &flood, (r_pose_factor) ? radius : 0.0f);
|
||||||
|
|
||||||
PoseFloodFillData fdata = {
|
PoseFloodFillData fdata{};
|
||||||
.radius = radius,
|
fdata.radius = radius;
|
||||||
.symm = SCULPT_mesh_symmetry_xyz_get(ob),
|
fdata.symm = SCULPT_mesh_symmetry_xyz_get(ob);
|
||||||
.pose_factor = r_pose_factor,
|
fdata.pose_factor = r_pose_factor;
|
||||||
.tot_co = 0,
|
fdata.tot_co = 0;
|
||||||
};
|
|
||||||
zero_v3(fdata.pose_origin);
|
zero_v3(fdata.pose_origin);
|
||||||
copy_v3_v3(fdata.pose_initial_co, initial_location);
|
copy_v3_v3(fdata.pose_initial_co, initial_location);
|
||||||
copy_v3_v3(fdata.fallback_floodfill_origin, initial_location);
|
copy_v3_v3(fdata.fallback_floodfill_origin, initial_location);
|
||||||
@ -560,7 +554,7 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd,
|
|||||||
SCULPT_floodfill_free(&flood);
|
SCULPT_floodfill_free(&flood);
|
||||||
|
|
||||||
if (fdata.tot_co > 0) {
|
if (fdata.tot_co > 0) {
|
||||||
mul_v3_fl(fdata.pose_origin, 1.0f / (float)fdata.tot_co);
|
mul_v3_fl(fdata.pose_origin, 1.0f / float(fdata.tot_co));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(fdata.pose_origin, fdata.fallback_floodfill_origin);
|
copy_v3_v3(fdata.pose_origin, fdata.fallback_floodfill_origin);
|
||||||
@ -577,15 +571,15 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd,
|
|||||||
*/
|
*/
|
||||||
if (pose_offset != 0.0f && r_pose_factor) {
|
if (pose_offset != 0.0f && r_pose_factor) {
|
||||||
sculpt_pose_grow_pose_factor(
|
sculpt_pose_grow_pose_factor(
|
||||||
sd, ob, ss, fdata.pose_origin, fdata.pose_origin, 0, NULL, r_pose_factor);
|
sd, ob, ss, fdata.pose_origin, fdata.pose_origin, 0, nullptr, r_pose_factor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pose_brush_init_task_cb_ex(void *__restrict userdata,
|
static void pose_brush_init_task_cb_ex(void *__restrict userdata,
|
||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHVertexIter vd;
|
PBVHVertexIter vd;
|
||||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
|
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
|
||||||
@ -608,12 +602,11 @@ static void pose_brush_init_task_cb_ex(void *__restrict userdata,
|
|||||||
/* Init the IK chain with empty weights. */
|
/* Init the IK chain with empty weights. */
|
||||||
static SculptPoseIKChain *pose_ik_chain_new(const int totsegments, const int totverts)
|
static SculptPoseIKChain *pose_ik_chain_new(const int totsegments, const int totverts)
|
||||||
{
|
{
|
||||||
SculptPoseIKChain *ik_chain = MEM_callocN(sizeof(SculptPoseIKChain), "Pose IK Chain");
|
SculptPoseIKChain *ik_chain = MEM_cnew<SculptPoseIKChain>(__func__);
|
||||||
ik_chain->tot_segments = totsegments;
|
ik_chain->tot_segments = totsegments;
|
||||||
ik_chain->segments = MEM_callocN(totsegments * sizeof(SculptPoseIKChainSegment),
|
ik_chain->segments = MEM_cnew_array<SculptPoseIKChainSegment>(totsegments, __func__);
|
||||||
"Pose IK Chain Segments");
|
|
||||||
for (int i = 0; i < totsegments; i++) {
|
for (int i = 0; i < totsegments; i++) {
|
||||||
ik_chain->segments[i].weights = MEM_callocN(totverts * sizeof(float), "Pose IK weights");
|
ik_chain->segments[i].weights = MEM_cnew_array<float>(totverts, __func__);
|
||||||
}
|
}
|
||||||
return ik_chain;
|
return ik_chain;
|
||||||
}
|
}
|
||||||
@ -674,11 +667,10 @@ static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd,
|
|||||||
* added to the IK chain. */
|
* added to the IK chain. */
|
||||||
|
|
||||||
/* This stores the whole pose factors values as they grow through the mesh. */
|
/* This stores the whole pose factors values as they grow through the mesh. */
|
||||||
float *pose_factor_grow = MEM_callocN(totvert * sizeof(float), "Pose Factor Grow");
|
float *pose_factor_grow = MEM_cnew_array<float>(totvert, __func__);
|
||||||
|
|
||||||
/* This stores the previous status of the factors when growing a new iteration. */
|
/* This stores the previous status of the factors when growing a new iteration. */
|
||||||
float *pose_factor_grow_prev = MEM_callocN(totvert * sizeof(float),
|
float *pose_factor_grow_prev = MEM_cnew_array<float>(totvert, __func__);
|
||||||
"Pose Factor Grow Prev Iteration");
|
|
||||||
|
|
||||||
pose_factor_grow[nearest_vertex_index] = 1.0f;
|
pose_factor_grow[nearest_vertex_index] = 1.0f;
|
||||||
|
|
||||||
@ -712,7 +704,7 @@ static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd,
|
|||||||
sculpt_pose_grow_pose_factor(sd,
|
sculpt_pose_grow_pose_factor(sd,
|
||||||
ob,
|
ob,
|
||||||
ss,
|
ss,
|
||||||
NULL,
|
nullptr,
|
||||||
next_chain_segment_target,
|
next_chain_segment_target,
|
||||||
chain_segment_len,
|
chain_segment_len,
|
||||||
ik_chain->segments[i].orig,
|
ik_chain->segments[i].orig,
|
||||||
@ -763,19 +755,19 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
|
|||||||
|
|
||||||
BLI_gset_add(visited_face_sets, POINTER_FROM_INT(current_face_set));
|
BLI_gset_add(visited_face_sets, POINTER_FROM_INT(current_face_set));
|
||||||
|
|
||||||
PoseFloodFillData fdata = {
|
PoseFloodFillData fdata{};
|
||||||
.radius = radius,
|
fdata.radius = radius;
|
||||||
.symm = SCULPT_mesh_symmetry_xyz_get(ob),
|
fdata.symm = SCULPT_mesh_symmetry_xyz_get(ob);
|
||||||
.pose_factor = ik_chain->segments[s].weights,
|
fdata.pose_factor = ik_chain->segments[s].weights;
|
||||||
.tot_co = 0,
|
fdata.tot_co = 0;
|
||||||
.fallback_count = 0,
|
fdata.fallback_count = 0;
|
||||||
.current_face_set = current_face_set,
|
fdata.current_face_set = current_face_set;
|
||||||
.prev_face_set = prev_face_set,
|
fdata.prev_face_set = prev_face_set;
|
||||||
.visited_face_sets = visited_face_sets,
|
fdata.visited_face_sets = visited_face_sets;
|
||||||
.is_weighted = is_weighted,
|
fdata.is_weighted = is_weighted;
|
||||||
.next_face_set_found = false,
|
fdata.next_face_set_found = false;
|
||||||
.is_first_iteration = s == 0,
|
fdata.is_first_iteration = s == 0;
|
||||||
};
|
|
||||||
zero_v3(fdata.pose_origin);
|
zero_v3(fdata.pose_origin);
|
||||||
zero_v3(fdata.fallback_origin);
|
zero_v3(fdata.fallback_origin);
|
||||||
copy_v3_v3(fdata.pose_initial_co, SCULPT_vertex_co_get(ss, current_vertex));
|
copy_v3_v3(fdata.pose_initial_co, SCULPT_vertex_co_get(ss, current_vertex));
|
||||||
@ -783,11 +775,11 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
|
|||||||
SCULPT_floodfill_free(&flood);
|
SCULPT_floodfill_free(&flood);
|
||||||
|
|
||||||
if (fdata.tot_co > 0) {
|
if (fdata.tot_co > 0) {
|
||||||
mul_v3_fl(fdata.pose_origin, 1.0f / (float)fdata.tot_co);
|
mul_v3_fl(fdata.pose_origin, 1.0f / float(fdata.tot_co));
|
||||||
copy_v3_v3(ik_chain->segments[s].orig, fdata.pose_origin);
|
copy_v3_v3(ik_chain->segments[s].orig, fdata.pose_origin);
|
||||||
}
|
}
|
||||||
else if (fdata.fallback_count > 0) {
|
else if (fdata.fallback_count > 0) {
|
||||||
mul_v3_fl(fdata.fallback_origin, 1.0f / (float)fdata.fallback_count);
|
mul_v3_fl(fdata.fallback_origin, 1.0f / float(fdata.fallback_count));
|
||||||
copy_v3_v3(ik_chain->segments[s].orig, fdata.fallback_origin);
|
copy_v3_v3(ik_chain->segments[s].orig, fdata.fallback_origin);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -799,7 +791,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
|
|||||||
current_vertex = fdata.next_vertex;
|
current_vertex = fdata.next_vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_gset_free(visited_face_sets, NULL);
|
BLI_gset_free(visited_face_sets, nullptr);
|
||||||
|
|
||||||
pose_ik_chain_origin_heads_init(ik_chain, SCULPT_active_vertex_co_get(ss));
|
pose_ik_chain_origin_heads_init(ik_chain, SCULPT_active_vertex_co_get(ss));
|
||||||
|
|
||||||
@ -811,7 +803,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
|
|||||||
static bool pose_face_sets_fk_find_masked_floodfill_cb(
|
static bool pose_face_sets_fk_find_masked_floodfill_cb(
|
||||||
SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata)
|
||||||
{
|
{
|
||||||
PoseFloodFillData *data = userdata;
|
PoseFloodFillData *data = static_cast<PoseFloodFillData *>(userdata);
|
||||||
|
|
||||||
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
||||||
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||||
@ -846,12 +838,12 @@ static bool pose_face_sets_fk_find_masked_floodfill_cb(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool pose_face_sets_fk_set_weights_floodfill_cb(SculptSession *ss,
|
static bool pose_face_sets_fk_set_weights_floodfill_cb(SculptSession *ss,
|
||||||
PBVHVertRef UNUSED(from_v),
|
PBVHVertRef /*from_v*/,
|
||||||
PBVHVertRef to_v,
|
PBVHVertRef to_v,
|
||||||
bool UNUSED(is_duplicate),
|
bool /*is_duplicate*/,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
PoseFloodFillData *data = userdata;
|
PoseFloodFillData *data = static_cast<PoseFloodFillData *>(userdata);
|
||||||
|
|
||||||
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||||
|
|
||||||
@ -875,7 +867,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
|
|||||||
SCULPT_floodfill_init(ss, &flood);
|
SCULPT_floodfill_init(ss, &flood);
|
||||||
SCULPT_floodfill_add_initial(&flood, active_vertex);
|
SCULPT_floodfill_add_initial(&flood, active_vertex);
|
||||||
PoseFloodFillData fdata;
|
PoseFloodFillData fdata;
|
||||||
fdata.floodfill_it = MEM_calloc_arrayN(totvert, sizeof(int), "floodfill iteration");
|
fdata.floodfill_it = static_cast<int *>(MEM_calloc_arrayN(totvert, sizeof(int), __func__));
|
||||||
fdata.floodfill_it[active_vertex_index] = 1;
|
fdata.floodfill_it[active_vertex_index] = 1;
|
||||||
fdata.initial_face_set = active_face_set;
|
fdata.initial_face_set = active_face_set;
|
||||||
fdata.masked_face_set = SCULPT_FACE_SET_NONE;
|
fdata.masked_face_set = SCULPT_FACE_SET_NONE;
|
||||||
@ -884,7 +876,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
|
|||||||
fdata.visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", 3);
|
fdata.visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", 3);
|
||||||
SCULPT_floodfill_execute(ss, &flood, pose_face_sets_fk_find_masked_floodfill_cb, &fdata);
|
SCULPT_floodfill_execute(ss, &flood, pose_face_sets_fk_find_masked_floodfill_cb, &fdata);
|
||||||
SCULPT_floodfill_free(&flood);
|
SCULPT_floodfill_free(&flood);
|
||||||
BLI_gset_free(fdata.visited_face_sets, NULL);
|
BLI_gset_free(fdata.visited_face_sets, nullptr);
|
||||||
|
|
||||||
int origin_count = 0;
|
int origin_count = 0;
|
||||||
float origin_acc[3] = {0.0f};
|
float origin_acc[3] = {0.0f};
|
||||||
@ -950,7 +942,7 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd,
|
|||||||
const float initial_location[3],
|
const float initial_location[3],
|
||||||
const float radius)
|
const float radius)
|
||||||
{
|
{
|
||||||
SculptPoseIKChain *ik_chain = NULL;
|
SculptPoseIKChain *ik_chain = nullptr;
|
||||||
|
|
||||||
const bool use_fake_neighbors = !(br->flag2 & BRUSH_USE_CONNECTED_ONLY);
|
const bool use_fake_neighbors = !(br->flag2 & BRUSH_USE_CONNECTED_ONLY);
|
||||||
|
|
||||||
@ -984,14 +976,13 @@ void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br
|
|||||||
PBVH *pbvh = ob->sculpt->pbvh;
|
PBVH *pbvh = ob->sculpt->pbvh;
|
||||||
int totnode;
|
int totnode;
|
||||||
|
|
||||||
BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = br,
|
data.brush = br;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
/* Init the IK chain that is going to be used to deform the vertices. */
|
/* Init the IK chain that is going to be used to deform the vertices. */
|
||||||
ss->cache->pose_ik_chain = SCULPT_pose_ik_chain_init(
|
ss->cache->pose_ik_chain = SCULPT_pose_ik_chain_init(
|
||||||
@ -1094,7 +1085,7 @@ static void sculpt_pose_do_scale_translate_deform(SculptSession *ss, Brush *brus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sculpt_pose_do_squash_stretch_deform(SculptSession *ss, Brush *UNUSED(brush))
|
static void sculpt_pose_do_squash_stretch_deform(SculptSession *ss, Brush * /*brush*/)
|
||||||
{
|
{
|
||||||
float ik_target[3];
|
float ik_target[3];
|
||||||
SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
|
SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
|
||||||
@ -1169,7 +1160,7 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
|||||||
float symm_orig[3];
|
float symm_orig[3];
|
||||||
float symm_initial_orig[3];
|
float symm_initial_orig[3];
|
||||||
|
|
||||||
ePaintSymmetryAreas symm_area = symm_it;
|
ePaintSymmetryAreas symm_area = ePaintSymmetryAreas(symm_it);
|
||||||
|
|
||||||
copy_qt_qt(symm_rot, ik_chain->segments[i].rot);
|
copy_qt_qt(symm_rot, ik_chain->segments[i].rot);
|
||||||
copy_v3_v3(symm_orig, ik_chain->segments[i].orig);
|
copy_v3_v3(symm_orig, ik_chain->segments[i].orig);
|
||||||
@ -1218,12 +1209,11 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
|
void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
|
||||||
float result[3],
|
float result[3],
|
||||||
@ -180,7 +180,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
Sculpt *sd = data->sd;
|
Sculpt *sd = data->sd;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
@ -241,8 +241,8 @@ static void SCULPT_enhance_details_brush(Sculpt *sd,
|
|||||||
|
|
||||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||||
const int totvert = SCULPT_vertex_count_get(ss);
|
const int totvert = SCULPT_vertex_count_get(ss);
|
||||||
ss->cache->detail_directions = MEM_malloc_arrayN(
|
ss->cache->detail_directions = static_cast<float(*)[3]>(
|
||||||
totvert, sizeof(float[3]), "details directions");
|
MEM_malloc_arrayN(totvert, sizeof(float[3]), "details directions"));
|
||||||
|
|
||||||
for (int i = 0; i < totvert; i++) {
|
for (int i = 0; i < totvert; i++) {
|
||||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||||
@ -253,12 +253,11 @@ static void SCULPT_enhance_details_brush(Sculpt *sd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -269,7 +268,7 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
|
|||||||
const int n,
|
const int n,
|
||||||
const TaskParallelTLS *__restrict tls)
|
const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
Sculpt *sd = data->sd;
|
Sculpt *sd = data->sd;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
@ -345,7 +344,7 @@ void SCULPT_smooth(Sculpt *sd,
|
|||||||
|
|
||||||
CLAMP(bstrength, 0.0f, 1.0f);
|
CLAMP(bstrength, 0.0f, 1.0f);
|
||||||
|
|
||||||
count = (int)(bstrength * max_iterations);
|
count = int(bstrength * max_iterations);
|
||||||
last = max_iterations * (bstrength - count * fract);
|
last = max_iterations * (bstrength - count * fract);
|
||||||
|
|
||||||
if (type == PBVH_FACES && !ss->pmap) {
|
if (type == PBVH_FACES && !ss->pmap) {
|
||||||
@ -359,14 +358,13 @@ void SCULPT_smooth(Sculpt *sd,
|
|||||||
for (iteration = 0; iteration <= count; iteration++) {
|
for (iteration = 0; iteration <= count; iteration++) {
|
||||||
const float strength = (iteration != count) ? 1.0f : last;
|
const float strength = (iteration != count) ? 1.0f : last;
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
.smooth_mask = smooth_mask,
|
data.smooth_mask = smooth_mask;
|
||||||
.strength = strength,
|
data.strength = strength;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||||
@ -447,7 +445,7 @@ void SCULPT_surface_smooth_displace_step(SculptSession *ss,
|
|||||||
static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
|
static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
|
||||||
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
|
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = ss->cache->bstrength;
|
const float bstrength = ss->cache->bstrength;
|
||||||
@ -499,7 +497,7 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
|
|||||||
static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
|
static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
|
||||||
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
|
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
|
||||||
{
|
{
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
const Brush *brush = data->brush;
|
const Brush *brush = data->brush;
|
||||||
const float bstrength = ss->cache->bstrength;
|
const float bstrength = ss->cache->bstrength;
|
||||||
@ -543,12 +541,11 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
|
|||||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||||
|
|
||||||
/* Threaded loop over nodes. */
|
/* Threaded loop over nodes. */
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.brush = brush,
|
data.brush = brush;
|
||||||
.nodes = nodes,
|
data.nodes = nodes;
|
||||||
};
|
|
||||||
|
|
||||||
TaskParallelSettings settings;
|
TaskParallelSettings settings;
|
||||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
@ -34,13 +34,10 @@
|
|||||||
|
|
||||||
#include "bmesh.h"
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
void ED_sculpt_init_transform(struct bContext *C,
|
void ED_sculpt_init_transform(bContext *C, Object *ob, const int mval[2], const char *undo_name)
|
||||||
Object *ob,
|
|
||||||
const int mval[2],
|
|
||||||
const char *undo_name)
|
|
||||||
{
|
{
|
||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
@ -72,7 +69,7 @@ void ED_sculpt_init_transform(struct bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void sculpt_transform_matrices_init(SculptSession *ss,
|
static void sculpt_transform_matrices_init(SculptSession *ss,
|
||||||
const char symm,
|
const ePaintSymmetryFlags symm,
|
||||||
const SculptTransformDisplacementMode t_mode,
|
const SculptTransformDisplacementMode t_mode,
|
||||||
float r_transform_mats[8][4][4])
|
float r_transform_mats[8][4][4])
|
||||||
{
|
{
|
||||||
@ -96,7 +93,7 @@ static void sculpt_transform_matrices_init(SculptSession *ss,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < PAINT_SYMM_AREAS; i++) {
|
for (int i = 0; i < PAINT_SYMM_AREAS; i++) {
|
||||||
ePaintSymmetryAreas v_symm = i;
|
ePaintSymmetryAreas v_symm = ePaintSymmetryAreas(i);
|
||||||
|
|
||||||
copy_v3_v3(final_pivot_pos, ss->pivot_pos);
|
copy_v3_v3(final_pivot_pos, ss->pivot_pos);
|
||||||
|
|
||||||
@ -137,10 +134,10 @@ static void sculpt_transform_matrices_init(SculptSession *ss,
|
|||||||
|
|
||||||
static void sculpt_transform_task_cb(void *__restrict userdata,
|
static void sculpt_transform_task_cb(void *__restrict userdata,
|
||||||
const int i,
|
const int i,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
|
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
|
|
||||||
@ -168,7 +165,7 @@ static void sculpt_transform_task_cb(void *__restrict userdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
copy_v3_v3(transformed_co, start_co);
|
copy_v3_v3(transformed_co, start_co);
|
||||||
mul_m4_v3(data->transform_mats[(int)symm_area], transformed_co);
|
mul_m4_v3(data->transform_mats[int(symm_area)], transformed_co);
|
||||||
sub_v3_v3v3(disp, transformed_co, start_co);
|
sub_v3_v3v3(disp, transformed_co, start_co);
|
||||||
mul_v3_fl(disp, 1.0f - fade);
|
mul_v3_fl(disp, 1.0f - fade);
|
||||||
add_v3_v3v3(vd.co, start_co, disp);
|
add_v3_v3v3(vd.co, start_co, disp);
|
||||||
@ -185,13 +182,12 @@ static void sculpt_transform_task_cb(void *__restrict userdata,
|
|||||||
static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob)
|
static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob)
|
||||||
{
|
{
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
|
const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(ob);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = ss->filter_cache->nodes,
|
data.nodes = ss->filter_cache->nodes;
|
||||||
};
|
|
||||||
|
|
||||||
sculpt_transform_matrices_init(
|
sculpt_transform_matrices_init(
|
||||||
ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats);
|
ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats);
|
||||||
@ -206,10 +202,10 @@ static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob)
|
|||||||
|
|
||||||
static void sculpt_elastic_transform_task_cb(void *__restrict userdata,
|
static void sculpt_elastic_transform_task_cb(void *__restrict userdata,
|
||||||
const int i,
|
const int i,
|
||||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
const TaskParallelTLS *__restrict /*tls*/)
|
||||||
{
|
{
|
||||||
|
|
||||||
SculptThreadedTaskData *data = userdata;
|
SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
|
||||||
SculptSession *ss = data->ob->sculpt;
|
SculptSession *ss = data->ob->sculpt;
|
||||||
PBVHNode *node = data->nodes[i];
|
PBVHNode *node = data->nodes[i];
|
||||||
|
|
||||||
@ -262,14 +258,13 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float
|
|||||||
BLI_assert(ss->filter_cache->transform_displacement_mode ==
|
BLI_assert(ss->filter_cache->transform_displacement_mode ==
|
||||||
SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL);
|
SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL);
|
||||||
|
|
||||||
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
|
const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(ob);
|
||||||
|
|
||||||
SculptThreadedTaskData data = {
|
SculptThreadedTaskData data{};
|
||||||
.sd = sd,
|
data.sd = sd;
|
||||||
.ob = ob,
|
data.ob = ob;
|
||||||
.nodes = ss->filter_cache->nodes,
|
data.nodes = ss->filter_cache->nodes;
|
||||||
.elastic_transform_radius = transform_radius,
|
data.elastic_transform_radius = transform_radius;
|
||||||
};
|
|
||||||
|
|
||||||
sculpt_transform_matrices_init(
|
sculpt_transform_matrices_init(
|
||||||
ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats);
|
ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats);
|
||||||
@ -279,7 +274,7 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float
|
|||||||
|
|
||||||
/* Elastic transform needs to apply all transform matrices to all vertices and then combine the
|
/* Elastic transform needs to apply all transform matrices to all vertices and then combine the
|
||||||
* displacement proxies as all vertices are modified by all symmetry passes. */
|
* displacement proxies as all vertices are modified by all symmetry passes. */
|
||||||
for (ePaintSymmetryFlags symmpass = 0; symmpass <= symm; symmpass++) {
|
for (ePaintSymmetryFlags symmpass = PAINT_SYMM_NONE; symmpass <= symm; symmpass++) {
|
||||||
if (SCULPT_is_symmetry_iteration_valid(symmpass, symm)) {
|
if (SCULPT_is_symmetry_iteration_valid(symmpass, symm)) {
|
||||||
flip_v3_v3(data.elastic_transform_pivot, ss->pivot_pos, symmpass);
|
flip_v3_v3(data.elastic_transform_pivot, ss->pivot_pos, symmpass);
|
||||||
flip_v3_v3(data.elastic_transform_pivot_init, ss->init_pivot_pos, symmpass);
|
flip_v3_v3(data.elastic_transform_pivot_init, ss->init_pivot_pos, symmpass);
|
||||||
@ -293,7 +288,7 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float
|
|||||||
SCULPT_combine_transform_proxies(sd, ob);
|
SCULPT_combine_transform_proxies(sd, ob);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_sculpt_update_modal_transform(struct bContext *C, Object *ob)
|
void ED_sculpt_update_modal_transform(bContext *C, Object *ob)
|
||||||
{
|
{
|
||||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
@ -340,7 +335,7 @@ void ED_sculpt_update_modal_transform(struct bContext *C, Object *ob)
|
|||||||
SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
|
SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_sculpt_end_transform(struct bContext *C, Object *ob)
|
void ED_sculpt_end_transform(bContext *C, Object *ob)
|
||||||
{
|
{
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
if (ss->filter_cache) {
|
if (ss->filter_cache) {
|
||||||
@ -349,13 +344,13 @@ void ED_sculpt_end_transform(struct bContext *C, Object *ob)
|
|||||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
|
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum eSculptPivotPositionModes {
|
enum eSculptPivotPositionModes {
|
||||||
SCULPT_PIVOT_POSITION_ORIGIN = 0,
|
SCULPT_PIVOT_POSITION_ORIGIN = 0,
|
||||||
SCULPT_PIVOT_POSITION_UNMASKED = 1,
|
SCULPT_PIVOT_POSITION_UNMASKED = 1,
|
||||||
SCULPT_PIVOT_POSITION_MASK_BORDER = 2,
|
SCULPT_PIVOT_POSITION_MASK_BORDER = 2,
|
||||||
SCULPT_PIVOT_POSITION_ACTIVE_VERTEX = 3,
|
SCULPT_PIVOT_POSITION_ACTIVE_VERTEX = 3,
|
||||||
SCULPT_PIVOT_POSITION_CURSOR_SURFACE = 4,
|
SCULPT_PIVOT_POSITION_CURSOR_SURFACE = 4,
|
||||||
} eSculptPivotPositionModes;
|
};
|
||||||
|
|
||||||
static EnumPropertyItem prop_sculpt_pivot_position_types[] = {
|
static EnumPropertyItem prop_sculpt_pivot_position_types[] = {
|
||||||
{SCULPT_PIVOT_POSITION_ORIGIN,
|
{SCULPT_PIVOT_POSITION_ORIGIN,
|
||||||
@ -383,7 +378,7 @@ static EnumPropertyItem prop_sculpt_pivot_position_types[] = {
|
|||||||
0,
|
0,
|
||||||
"Surface",
|
"Surface",
|
||||||
"Sets the pivot position to the surface under the cursor"},
|
"Sets the pivot position to the surface under the cursor"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
|
static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
|
||||||
@ -420,7 +415,7 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
|
|||||||
else {
|
else {
|
||||||
PBVHNode **nodes;
|
PBVHNode **nodes;
|
||||||
int totnode;
|
int totnode;
|
||||||
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
|
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||||
|
|
||||||
float avg[3];
|
float avg[3];
|
||||||
int total = 0;
|
int total = 0;
|
@ -47,14 +47,14 @@ set(SRC
|
|||||||
transform_convert_object_texspace.c
|
transform_convert_object_texspace.c
|
||||||
transform_convert_paintcurve.c
|
transform_convert_paintcurve.c
|
||||||
transform_convert_particle.c
|
transform_convert_particle.c
|
||||||
transform_convert_sculpt.c
|
transform_convert_sculpt.cc
|
||||||
transform_convert_sequencer.c
|
transform_convert_sequencer.c
|
||||||
transform_convert_sequencer_image.c
|
transform_convert_sequencer_image.c
|
||||||
transform_convert_tracking.c
|
transform_convert_tracking.c
|
||||||
transform_draw_cursors.c
|
transform_draw_cursors.c
|
||||||
transform_generics.c
|
transform_generics.c
|
||||||
transform_gizmo_2d.c
|
transform_gizmo_2d.c
|
||||||
transform_gizmo_3d.c
|
transform_gizmo_3d.cc
|
||||||
transform_gizmo_extrude_3d.c
|
transform_gizmo_extrude_3d.c
|
||||||
transform_input.c
|
transform_input.c
|
||||||
transform_mode.c
|
transform_mode.c
|
||||||
|
@ -260,7 +260,7 @@ extern TransConvertTypeInfo TransConvertType_PaintCurve;
|
|||||||
|
|
||||||
extern TransConvertTypeInfo TransConvertType_Particle;
|
extern TransConvertTypeInfo TransConvertType_Particle;
|
||||||
|
|
||||||
/* transform_convert_sculpt.c */
|
/* transform_convert_sculpt.cc */
|
||||||
|
|
||||||
extern TransConvertTypeInfo TransConvertType_Sculpt;
|
extern TransConvertTypeInfo TransConvertType_Sculpt;
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ static void createTransSculpt(bContext *C, TransInfo *t)
|
|||||||
TransDataContainer *tc = t->data_container;
|
TransDataContainer *tc = t->data_container;
|
||||||
tc->data_len = 1;
|
tc->data_len = 1;
|
||||||
tc->is_active = 1;
|
tc->is_active = 1;
|
||||||
td = tc->data = MEM_callocN(sizeof(TransData), "TransSculpt");
|
td = tc->data = MEM_cnew<TransData>(__func__);
|
||||||
td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransSculpt");
|
td->ext = tc->data_ext = MEM_cnew<TransDataExtension>(__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
td->flag = TD_SELECTED;
|
td->flag = TD_SELECTED;
|
||||||
@ -63,9 +63,9 @@ static void createTransSculpt(bContext *C, TransInfo *t)
|
|||||||
copy_m3_m4(obmat_inv, ob->object_to_world);
|
copy_m3_m4(obmat_inv, ob->object_to_world);
|
||||||
invert_m3(obmat_inv);
|
invert_m3(obmat_inv);
|
||||||
|
|
||||||
td->ext->rot = NULL;
|
td->ext->rot = nullptr;
|
||||||
td->ext->rotAxis = NULL;
|
td->ext->rotAxis = nullptr;
|
||||||
td->ext->rotAngle = NULL;
|
td->ext->rotAngle = nullptr;
|
||||||
td->ext->quat = ss->pivot_rot;
|
td->ext->quat = ss->pivot_rot;
|
||||||
copy_m4_m4(td->ext->obmat, ob->object_to_world);
|
copy_m4_m4(td->ext->obmat, ob->object_to_world);
|
||||||
copy_m3_m3(td->ext->l_smtx, obmat_inv);
|
copy_m3_m3(td->ext->l_smtx, obmat_inv);
|
@ -8,10 +8,10 @@
|
|||||||
* Used for 3D View
|
* Used for 3D View
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <float.h>
|
#include <cfloat>
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include "DNA_armature_types.h"
|
#include "DNA_armature_types.h"
|
||||||
#include "DNA_curve_types.h"
|
#include "DNA_curve_types.h"
|
||||||
@ -70,8 +70,8 @@
|
|||||||
|
|
||||||
#include "GPU_state.h"
|
#include "GPU_state.h"
|
||||||
|
|
||||||
static wmGizmoGroupType *g_GGT_xform_gizmo = NULL;
|
static wmGizmoGroupType *g_GGT_xform_gizmo = nullptr;
|
||||||
static wmGizmoGroupType *g_GGT_xform_gizmo_context = NULL;
|
static wmGizmoGroupType *g_GGT_xform_gizmo_context = nullptr;
|
||||||
|
|
||||||
static void gizmogroup_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
static void gizmogroup_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
||||||
const float twmat[4][4],
|
const float twmat[4][4],
|
||||||
@ -148,7 +148,7 @@ enum {
|
|||||||
MAN_AXES_SCALE,
|
MAN_AXES_SCALE,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct GizmoGroup {
|
struct GizmoGroup {
|
||||||
bool all_hidden;
|
bool all_hidden;
|
||||||
int twtype;
|
int twtype;
|
||||||
|
|
||||||
@ -165,8 +165,8 @@ typedef struct GizmoGroup {
|
|||||||
/* Only for Rotate operator. */
|
/* Only for Rotate operator. */
|
||||||
float rotation;
|
float rotation;
|
||||||
|
|
||||||
struct wmGizmo *gizmos[MAN_AXIS_LAST];
|
wmGizmo *gizmos[MAN_AXIS_LAST];
|
||||||
} GizmoGroup;
|
};
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Utilities
|
/** \name Utilities
|
||||||
@ -187,7 +187,7 @@ typedef struct GizmoGroup {
|
|||||||
|
|
||||||
static wmGizmo *gizmo_get_axis_from_index(const GizmoGroup *ggd, const short axis_idx)
|
static wmGizmo *gizmo_get_axis_from_index(const GizmoGroup *ggd, const short axis_idx)
|
||||||
{
|
{
|
||||||
BLI_assert(IN_RANGE_INCL(axis_idx, (float)MAN_AXIS_TRANS_X, (float)MAN_AXIS_LAST));
|
BLI_assert(IN_RANGE_INCL(axis_idx, float(MAN_AXIS_TRANS_X), float(MAN_AXIS_LAST)));
|
||||||
return ggd->gizmos[axis_idx];
|
return ggd->gizmos[axis_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ static void gizmo_get_axis_constraint(const int axis_idx, bool r_axis[3])
|
|||||||
|
|
||||||
/* **************** Preparation Stuff **************** */
|
/* **************** Preparation Stuff **************** */
|
||||||
|
|
||||||
static void reset_tw_center(struct TransformBounds *tbounds)
|
static void reset_tw_center(TransformBounds *tbounds)
|
||||||
{
|
{
|
||||||
INIT_MINMAX(tbounds->min, tbounds->max);
|
INIT_MINMAX(tbounds->min, tbounds->max);
|
||||||
zero_v3(tbounds->center);
|
zero_v3(tbounds->center);
|
||||||
@ -446,7 +446,7 @@ static void reset_tw_center(struct TransformBounds *tbounds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* transform widget center calc helper for below */
|
/* transform widget center calc helper for below */
|
||||||
static void calc_tw_center(struct TransformBounds *tbounds, const float co[3])
|
static void calc_tw_center(TransformBounds *tbounds, const float co[3])
|
||||||
{
|
{
|
||||||
minmax_v3v3_v3(tbounds->min, tbounds->max, co);
|
minmax_v3v3_v3(tbounds->min, tbounds->max, co);
|
||||||
add_v3_v3(tbounds->center, co);
|
add_v3_v3(tbounds->center, co);
|
||||||
@ -458,7 +458,7 @@ static void calc_tw_center(struct TransformBounds *tbounds, const float co[3])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calc_tw_center_with_matrix(struct TransformBounds *tbounds,
|
static void calc_tw_center_with_matrix(TransformBounds *tbounds,
|
||||||
const float co[3],
|
const float co[3],
|
||||||
const bool use_matrix,
|
const bool use_matrix,
|
||||||
const float matrix[4][4])
|
const float matrix[4][4])
|
||||||
@ -620,8 +620,8 @@ bool gimbal_axis_object(Object *ob, float gmat[3][3])
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ED_transform_calc_gizmo_stats(const bContext *C,
|
int ED_transform_calc_gizmo_stats(const bContext *C,
|
||||||
const struct TransformCalcParams *params,
|
const TransformCalcParams *params,
|
||||||
struct TransformBounds *tbounds)
|
TransformBounds *tbounds)
|
||||||
{
|
{
|
||||||
ScrArea *area = CTX_wm_area(C);
|
ScrArea *area = CTX_wm_area(C);
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
@ -630,8 +630,8 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
* Is it fine to possibly evaluate dependency graph here? */
|
* Is it fine to possibly evaluate dependency graph here? */
|
||||||
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
View3D *v3d = area->spacedata.first;
|
View3D *v3d = static_cast<View3D *>(area->spacedata.first);
|
||||||
RegionView3D *rv3d = region->regiondata;
|
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||||
Base *base;
|
Base *base;
|
||||||
bGPdata *gpd = CTX_data_gpencil_data(C);
|
bGPdata *gpd = CTX_data_gpencil_data(C);
|
||||||
const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
|
const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
|
||||||
@ -648,7 +648,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
Object *obedit = OBEDIT_FROM_OBACT(ob);
|
Object *obedit = OBEDIT_FROM_OBACT(ob);
|
||||||
if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
|
if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
|
||||||
Object *obpose = BKE_object_pose_armature_get(ob);
|
Object *obpose = BKE_object_pose_armature_get(ob);
|
||||||
if (obpose != NULL) {
|
if (obpose != nullptr) {
|
||||||
ob = obpose;
|
ob = obpose;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -662,7 +662,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
zero_v3(rv3d->tw_axis_min);
|
zero_v3(rv3d->tw_axis_min);
|
||||||
zero_v3(rv3d->tw_axis_max);
|
zero_v3(rv3d->tw_axis_max);
|
||||||
|
|
||||||
rv3d->twdrawflag = 0xFFFF;
|
rv3d->twdrawflag = short(0xFFFF);
|
||||||
|
|
||||||
/* global, local or normal orientation?
|
/* global, local or normal orientation?
|
||||||
* if we could check 'totsel' now, this should be skipped with no selection. */
|
* if we could check 'totsel' now, this should be skipped with no selection. */
|
||||||
@ -695,7 +695,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||||
/* only editable and visible layers are considered */
|
/* only editable and visible layers are considered */
|
||||||
|
|
||||||
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != nullptr)) {
|
||||||
|
|
||||||
/* calculate difference matrix */
|
/* calculate difference matrix */
|
||||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
|
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||||
@ -707,7 +707,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_curve_edit) {
|
if (is_curve_edit) {
|
||||||
if (gps->editcurve == NULL) {
|
if (gps->editcurve == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,7 +748,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
|
|
||||||
/* selection center */
|
/* selection center */
|
||||||
if (totsel) {
|
if (totsel) {
|
||||||
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
|
mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (obedit) {
|
else if (obedit) {
|
||||||
@ -800,7 +800,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
} /* end editmesh */
|
} /* end editmesh */
|
||||||
else if (obedit->type == OB_ARMATURE) {
|
else if (obedit->type == OB_ARMATURE) {
|
||||||
FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
|
FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
|
||||||
bArmature *arm = ob_iter->data;
|
bArmature *arm = static_cast<bArmature *>(ob_iter->data);
|
||||||
|
|
||||||
float mat_local[4][4];
|
float mat_local[4][4];
|
||||||
if (use_mat_local) {
|
if (use_mat_local) {
|
||||||
@ -814,7 +814,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
}
|
}
|
||||||
if ((ebo->flag & BONE_ROOTSEL) &&
|
if ((ebo->flag & BONE_ROOTSEL) &&
|
||||||
/* don't include same point multiple times */
|
/* don't include same point multiple times */
|
||||||
((ebo->flag & BONE_CONNECTED) && (ebo->parent != NULL) &&
|
((ebo->flag & BONE_CONNECTED) && (ebo->parent != nullptr) &&
|
||||||
(ebo->parent->flag & BONE_TIPSEL) && EBONE_VISIBLE(arm, ebo->parent)) == 0) {
|
(ebo->parent->flag & BONE_TIPSEL) && EBONE_VISIBLE(arm, ebo->parent)) == 0) {
|
||||||
calc_tw_center_with_matrix(tbounds, ebo->head, use_mat_local, mat_local);
|
calc_tw_center_with_matrix(tbounds, ebo->head, use_mat_local, mat_local);
|
||||||
totsel++;
|
totsel++;
|
||||||
@ -829,8 +829,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
}
|
}
|
||||||
else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
|
else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
|
||||||
FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
|
FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
|
||||||
Curve *cu = ob_iter->data;
|
Curve *cu = static_cast<Curve *>(ob_iter->data);
|
||||||
Nurb *nu;
|
|
||||||
BezTriple *bezt;
|
BezTriple *bezt;
|
||||||
BPoint *bp;
|
BPoint *bp;
|
||||||
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
|
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
|
||||||
@ -840,7 +839,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
mul_m4_m4m4(mat_local, obedit->world_to_object, ob_iter->object_to_world);
|
mul_m4_m4m4(mat_local, obedit->world_to_object, ob_iter->object_to_world);
|
||||||
}
|
}
|
||||||
|
|
||||||
nu = nurbs->first;
|
Nurb *nu = static_cast<Nurb *>(nurbs->first);
|
||||||
while (nu) {
|
while (nu) {
|
||||||
if (nu->type == CU_BEZIER) {
|
if (nu->type == CU_BEZIER) {
|
||||||
bezt = nu->bezt;
|
bezt = nu->bezt;
|
||||||
@ -936,7 +935,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
|
|
||||||
/* selection center */
|
/* selection center */
|
||||||
if (totsel) {
|
if (totsel) {
|
||||||
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
|
mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */
|
||||||
mul_m4_v3(obedit->object_to_world, tbounds->center);
|
mul_m4_v3(obedit->object_to_world, tbounds->center);
|
||||||
mul_m4_v3(obedit->object_to_world, tbounds->min);
|
mul_m4_v3(obedit->object_to_world, tbounds->min);
|
||||||
mul_m4_v3(obedit->object_to_world, tbounds->max);
|
mul_m4_v3(obedit->object_to_world, tbounds->max);
|
||||||
@ -974,7 +973,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
MEM_freeN(objects);
|
MEM_freeN(objects);
|
||||||
|
|
||||||
if (totsel) {
|
if (totsel) {
|
||||||
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
|
mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */
|
||||||
mul_m4_v3(ob->object_to_world, tbounds->center);
|
mul_m4_v3(ob->object_to_world, tbounds->center);
|
||||||
mul_m4_v3(ob->object_to_world, tbounds->min);
|
mul_m4_v3(ob->object_to_world, tbounds->min);
|
||||||
mul_m4_v3(ob->object_to_world, tbounds->max);
|
mul_m4_v3(ob->object_to_world, tbounds->max);
|
||||||
@ -1012,7 +1011,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
|
|
||||||
/* selection center */
|
/* selection center */
|
||||||
if (totsel) {
|
if (totsel) {
|
||||||
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
|
mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1021,26 +1020,27 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
/* we need the one selected object, if its not active */
|
/* we need the one selected object, if its not active */
|
||||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||||
base = BKE_view_layer_active_base_get(view_layer);
|
base = BKE_view_layer_active_base_get(view_layer);
|
||||||
ob = base ? base->object : NULL;
|
ob = base ? base->object : nullptr;
|
||||||
if (base && ((base->flag & BASE_SELECTED) == 0)) {
|
if (base && ((base->flag & BASE_SELECTED) == 0)) {
|
||||||
ob = NULL;
|
ob = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (base = BKE_view_layer_object_bases_get(view_layer)->first; base; base = base->next) {
|
for (base = static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first); base;
|
||||||
|
base = base->next) {
|
||||||
if (!BASE_SELECTED_EDITABLE(v3d, base)) {
|
if (!BASE_SELECTED_EDITABLE(v3d, base)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ob == NULL) {
|
if (ob == nullptr) {
|
||||||
ob = base->object;
|
ob = base->object;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the boundbox out of the evaluated object. */
|
/* Get the boundbox out of the evaluated object. */
|
||||||
const BoundBox *bb = NULL;
|
const BoundBox *bb = nullptr;
|
||||||
if (params->use_only_center == false) {
|
if (params->use_only_center == false) {
|
||||||
bb = BKE_object_boundbox_get(base->object);
|
bb = BKE_object_boundbox_get(base->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->use_only_center || (bb == NULL)) {
|
if (params->use_only_center || (bb == nullptr)) {
|
||||||
calc_tw_center(tbounds, base->object->object_to_world[3]);
|
calc_tw_center(tbounds, base->object->object_to_world[3]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1065,7 +1065,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||||||
|
|
||||||
/* selection center */
|
/* selection center */
|
||||||
if (totsel) {
|
if (totsel) {
|
||||||
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
|
mul_v3_fl(tbounds->center, 1.0f / float(totsel)); /* centroid! */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,7 +1093,7 @@ static void gizmo_get_idot(const RegionView3D *rv3d, float r_idot[3])
|
|||||||
|
|
||||||
static void gizmo_prepare_mat(const bContext *C,
|
static void gizmo_prepare_mat(const bContext *C,
|
||||||
RegionView3D *rv3d,
|
RegionView3D *rv3d,
|
||||||
const struct TransformBounds *tbounds)
|
const TransformBounds *tbounds)
|
||||||
{
|
{
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
@ -1106,7 +1106,7 @@ static void gizmo_prepare_mat(const bContext *C,
|
|||||||
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
|
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
|
||||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||||
Object *ob = BKE_view_layer_active_object_get(view_layer);
|
Object *ob = BKE_view_layer_active_object_get(view_layer);
|
||||||
if (ob != NULL) {
|
if (ob != nullptr) {
|
||||||
/* Grease Pencil uses object origin. */
|
/* Grease Pencil uses object origin. */
|
||||||
bGPdata *gpd = CTX_data_gpencil_data(C);
|
bGPdata *gpd = CTX_data_gpencil_data(C);
|
||||||
if (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
|
if (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
|
||||||
@ -1172,23 +1172,22 @@ static void gizmo_line_range(const int twtype, const short axis_type, float *r_s
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
|
static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
|
||||||
struct wmMsgBus *mbus,
|
wmMsgBus *mbus,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
bScreen *screen,
|
bScreen *screen,
|
||||||
ScrArea *area,
|
ScrArea *area,
|
||||||
ARegion *region,
|
ARegion *region,
|
||||||
const void *type_fn)
|
void (*type_fn)(wmGizmoGroupType *))
|
||||||
{
|
{
|
||||||
/* Subscribe to view properties */
|
/* Subscribe to view properties */
|
||||||
wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
|
wmMsgSubscribeValue msg_sub_value_gz_tag_refresh{};
|
||||||
.owner = region,
|
msg_sub_value_gz_tag_refresh.owner = region;
|
||||||
.user_data = gzgroup->parent_gzmap,
|
msg_sub_value_gz_tag_refresh.user_data = gzgroup->parent_gzmap;
|
||||||
.notify = WM_gizmo_do_msg_notify_tag_refresh,
|
msg_sub_value_gz_tag_refresh.notify = WM_gizmo_do_msg_notify_tag_refresh;
|
||||||
};
|
|
||||||
|
|
||||||
int orient_flag = 0;
|
int orient_flag = 0;
|
||||||
if (type_fn == VIEW3D_GGT_xform_gizmo) {
|
if (type_fn == VIEW3D_GGT_xform_gizmo) {
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
orient_flag = ggd->twtype_init;
|
orient_flag = ggd->twtype_init;
|
||||||
}
|
}
|
||||||
else if (type_fn == VIEW3D_GGT_xform_cage) {
|
else if (type_fn == VIEW3D_GGT_xform_cage) {
|
||||||
@ -1220,7 +1219,7 @@ static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
|
|||||||
/* We could be more specific here, for now subscribe to any cursor change. */
|
/* We could be more specific here, for now subscribe to any cursor change. */
|
||||||
PointerRNA cursor_ptr;
|
PointerRNA cursor_ptr;
|
||||||
RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &cursor_ptr);
|
RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &cursor_ptr);
|
||||||
WM_msg_subscribe_rna(mbus, &cursor_ptr, NULL, &msg_sub_value_gz_tag_refresh, __func__);
|
WM_msg_subscribe_rna(mbus, &cursor_ptr, nullptr, &msg_sub_value_gz_tag_refresh, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1263,7 +1262,7 @@ static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
|
|||||||
RNA_pointer_create(&screen->id, &RNA_SpaceView3D, area->spacedata.first, &view3d_ptr);
|
RNA_pointer_create(&screen->id, &RNA_SpaceView3D, area->spacedata.first, &view3d_ptr);
|
||||||
|
|
||||||
if (type_fn == VIEW3D_GGT_xform_gizmo) {
|
if (type_fn == VIEW3D_GGT_xform_gizmo) {
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
if (ggd->use_twtype_refresh) {
|
if (ggd->use_twtype_refresh) {
|
||||||
const PropertyRNA *props[] = {
|
const PropertyRNA *props[] = {
|
||||||
&rna_SpaceView3D_show_gizmo_object_translate,
|
&rna_SpaceView3D_show_gizmo_object_translate,
|
||||||
@ -1327,13 +1326,13 @@ static void gizmo_3d_dial_matrixbasis_calc(const ARegion *region,
|
|||||||
/** Offset of the two-axis planes, depends on the gizmos scale. Define to avoid repeating. */
|
/** Offset of the two-axis planes, depends on the gizmos scale. Define to avoid repeating. */
|
||||||
#define MAN_AXIS_SCALE_PLANE_OFFSET 7.0f
|
#define MAN_AXIS_SCALE_PLANE_OFFSET 7.0f
|
||||||
|
|
||||||
static void rotation_get_fn(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value)
|
static void rotation_get_fn(const wmGizmo * /*gz*/, wmGizmoProperty *gz_prop, void *value)
|
||||||
{
|
{
|
||||||
const GizmoGroup *ggd = (const GizmoGroup *)gz_prop->custom_func.user_data;
|
const GizmoGroup *ggd = (const GizmoGroup *)gz_prop->custom_func.user_data;
|
||||||
*(float *)value = ggd->rotation;
|
*(float *)value = ggd->rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rotation_set_fn(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value)
|
static void rotation_set_fn(const wmGizmo * /*gz*/, wmGizmoProperty *gz_prop, const void *value)
|
||||||
{
|
{
|
||||||
GizmoGroup *ggd = (GizmoGroup *)gz_prop->custom_func.user_data;
|
GizmoGroup *ggd = (GizmoGroup *)gz_prop->custom_func.user_data;
|
||||||
ggd->rotation = *(const float *)value;
|
ggd->rotation = *(const float *)value;
|
||||||
@ -1504,31 +1503,31 @@ static void gizmo_3d_setup_draw_modal(wmGizmo *axis, const int axis_idx)
|
|||||||
|
|
||||||
static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
|
static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
|
||||||
{
|
{
|
||||||
GizmoGroup *ggd;
|
GizmoGroup *ggd = MEM_cnew<GizmoGroup>(__func__);
|
||||||
|
|
||||||
ggd = MEM_callocN(sizeof(GizmoGroup), "gizmo_data");
|
|
||||||
|
|
||||||
const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
|
const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
|
||||||
const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
|
const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
|
||||||
const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true);
|
const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true);
|
||||||
|
|
||||||
wmGizmoPropertyFnParams params = {
|
wmGizmoPropertyFnParams params{};
|
||||||
.value_get_fn = rotation_get_fn, .value_set_fn = rotation_set_fn, .user_data = ggd};
|
params.value_get_fn = rotation_get_fn;
|
||||||
|
params.value_set_fn = rotation_set_fn;
|
||||||
|
params.user_data = ggd;
|
||||||
|
|
||||||
#define GIZMO_NEW_ARROW(v) \
|
#define GIZMO_NEW_ARROW(v) \
|
||||||
{ \
|
{ \
|
||||||
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); \
|
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr); \
|
||||||
} \
|
} \
|
||||||
((void)0)
|
((void)0)
|
||||||
#define GIZMO_NEW_DIAL(v) \
|
#define GIZMO_NEW_DIAL(v) \
|
||||||
{ \
|
{ \
|
||||||
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \
|
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, nullptr); \
|
||||||
WM_gizmo_target_property_def_func(ggd->gizmos[v], "offset", ¶ms); \
|
WM_gizmo_target_property_def_func(ggd->gizmos[v], "offset", ¶ms); \
|
||||||
} \
|
} \
|
||||||
((void)0)
|
((void)0)
|
||||||
#define GIZMO_NEW_PRIM(v) \
|
#define GIZMO_NEW_PRIM(v) \
|
||||||
{ \
|
{ \
|
||||||
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_prim, gzgroup, NULL); \
|
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_prim, gzgroup, nullptr); \
|
||||||
} \
|
} \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
|
||||||
@ -1576,7 +1575,7 @@ static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
|
|||||||
static int gizmo_modal(bContext *C,
|
static int gizmo_modal(bContext *C,
|
||||||
wmGizmo *widget,
|
wmGizmo *widget,
|
||||||
const wmEvent *event,
|
const wmEvent *event,
|
||||||
eWM_GizmoFlagTweak UNUSED(tweak_flag))
|
eWM_GizmoFlagTweak /*tweak_flag*/)
|
||||||
{
|
{
|
||||||
/* Avoid unnecessary updates, partially address: T55458. */
|
/* Avoid unnecessary updates, partially address: T55458. */
|
||||||
if (ELEM(event->type, TIMER, INBETWEEN_MOUSEMOVE)) {
|
if (ELEM(event->type, TIMER, INBETWEEN_MOUSEMOVE)) {
|
||||||
@ -1584,7 +1583,7 @@ static int gizmo_modal(bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
RegionView3D *rv3d = region->regiondata;
|
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||||
wmGizmoGroup *gzgroup = widget->parent_gzgroup;
|
wmGizmoGroup *gzgroup = widget->parent_gzgroup;
|
||||||
|
|
||||||
/* Recalculating the orientation has two problems.
|
/* Recalculating the orientation has two problems.
|
||||||
@ -1596,55 +1595,56 @@ static int gizmo_modal(bContext *C,
|
|||||||
* when scaling.
|
* when scaling.
|
||||||
*/
|
*/
|
||||||
if (false) {
|
if (false) {
|
||||||
struct TransformBounds tbounds;
|
TransformBounds tbounds;
|
||||||
|
|
||||||
if (ED_transform_calc_gizmo_stats(C,
|
TransformCalcParams calc_params{};
|
||||||
&(struct TransformCalcParams){
|
calc_params.use_only_center = true;
|
||||||
.use_only_center = true,
|
if (ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds)) {
|
||||||
},
|
|
||||||
&tbounds)) {
|
|
||||||
gizmo_prepare_mat(C, rv3d, &tbounds);
|
gizmo_prepare_mat(C, rv3d, &tbounds);
|
||||||
for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) {
|
for (wmGizmo *gz = static_cast<wmGizmo *>(gzgroup->gizmos.first); gz; gz = gz->next) {
|
||||||
WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
|
WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wmWindow *win = CTX_wm_window(C);
|
wmWindow *win = CTX_wm_window(C);
|
||||||
wmOperator *op = NULL;
|
wmOperator *op = nullptr;
|
||||||
for (int i = 0; i < widget->op_data_len; i++) {
|
for (int i = 0; i < widget->op_data_len; i++) {
|
||||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(widget, i);
|
wmGizmoOpElem *gzop = WM_gizmo_operator_get(widget, i);
|
||||||
op = WM_operator_find_modal_by_type(win, gzop->type);
|
op = WM_operator_find_modal_by_type(win, gzop->type);
|
||||||
if (op != NULL) {
|
if (op != nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op != NULL) {
|
if (op != nullptr) {
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &widget);
|
const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &widget);
|
||||||
const short axis_type = gizmo_get_axis_type(axis_idx);
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
||||||
|
|
||||||
float twmat[4][4];
|
float twmat[4][4];
|
||||||
float scale_buf[3];
|
float scale_buf[3];
|
||||||
float *scale = NULL;
|
float *scale = nullptr;
|
||||||
bool update = false;
|
bool update = false;
|
||||||
copy_m4_m4(twmat, rv3d->twmat);
|
copy_m4_m4(twmat, rv3d->twmat);
|
||||||
|
|
||||||
if (axis_type == MAN_AXES_SCALE) {
|
if (axis_type == MAN_AXES_SCALE) {
|
||||||
scale = scale_buf;
|
scale = scale_buf;
|
||||||
transform_final_value_get(op->customdata, scale, 3);
|
transform_final_value_get(static_cast<const TransInfo *>(op->customdata), scale, 3);
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
else if (axis_type == MAN_AXES_ROTATE) {
|
else if (axis_type == MAN_AXES_ROTATE) {
|
||||||
transform_final_value_get(op->customdata, &ggd->rotation, 1);
|
transform_final_value_get(
|
||||||
|
static_cast<const TransInfo *>(op->customdata), &ggd->rotation, 1);
|
||||||
if (widget != ggd->gizmos[MAN_AXIS_ROT_C]) {
|
if (widget != ggd->gizmos[MAN_AXIS_ROT_C]) {
|
||||||
ggd->rotation *= -1;
|
ggd->rotation *= -1;
|
||||||
}
|
}
|
||||||
RNA_float_set(
|
RNA_float_set(
|
||||||
widget->ptr, "incremental_angle", transform_snap_increment_get(op->customdata));
|
widget->ptr,
|
||||||
|
"incremental_angle",
|
||||||
|
transform_snap_increment_get(static_cast<const TransInfo *>(op->customdata)));
|
||||||
}
|
}
|
||||||
else if (transform_apply_matrix(op->customdata, twmat)) {
|
else if (transform_apply_matrix(static_cast<TransInfo *>(op->customdata), twmat)) {
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1662,13 +1662,13 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
|
|||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
wmOperatorType *translate, *rotate, *trackball, *resize;
|
wmOperatorType *translate, *rotate, *trackball, *resize;
|
||||||
} ot_store = {NULL};
|
} ot_store = {nullptr};
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
|
|
||||||
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
||||||
const short axis_type = gizmo_get_axis_type(axis_idx);
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
||||||
bool constraint_axis[3] = {1, 0, 0};
|
bool constraint_axis[3] = {1, 0, 0};
|
||||||
PointerRNA *ptr = NULL;
|
PointerRNA *ptr = nullptr;
|
||||||
|
|
||||||
gizmo_get_axis_constraint(axis_idx, constraint_axis);
|
gizmo_get_axis_constraint(axis_idx, constraint_axis);
|
||||||
|
|
||||||
@ -1679,33 +1679,33 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
|
|||||||
|
|
||||||
switch (axis_type) {
|
switch (axis_type) {
|
||||||
case MAN_AXES_TRANSLATE:
|
case MAN_AXES_TRANSLATE:
|
||||||
if (ot_store.translate == NULL) {
|
if (ot_store.translate == nullptr) {
|
||||||
ot_store.translate = WM_operatortype_find("TRANSFORM_OT_translate", true);
|
ot_store.translate = WM_operatortype_find("TRANSFORM_OT_translate", true);
|
||||||
}
|
}
|
||||||
ptr = WM_gizmo_operator_set(axis, 0, ot_store.translate, NULL);
|
ptr = WM_gizmo_operator_set(axis, 0, ot_store.translate, nullptr);
|
||||||
break;
|
break;
|
||||||
case MAN_AXES_ROTATE: {
|
case MAN_AXES_ROTATE: {
|
||||||
wmOperatorType *ot_rotate;
|
wmOperatorType *ot_rotate;
|
||||||
if (axis_idx == MAN_AXIS_ROT_T) {
|
if (axis_idx == MAN_AXIS_ROT_T) {
|
||||||
if (ot_store.trackball == NULL) {
|
if (ot_store.trackball == nullptr) {
|
||||||
ot_store.trackball = WM_operatortype_find("TRANSFORM_OT_trackball", true);
|
ot_store.trackball = WM_operatortype_find("TRANSFORM_OT_trackball", true);
|
||||||
}
|
}
|
||||||
ot_rotate = ot_store.trackball;
|
ot_rotate = ot_store.trackball;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ot_store.rotate == NULL) {
|
if (ot_store.rotate == nullptr) {
|
||||||
ot_store.rotate = WM_operatortype_find("TRANSFORM_OT_rotate", true);
|
ot_store.rotate = WM_operatortype_find("TRANSFORM_OT_rotate", true);
|
||||||
}
|
}
|
||||||
ot_rotate = ot_store.rotate;
|
ot_rotate = ot_store.rotate;
|
||||||
}
|
}
|
||||||
ptr = WM_gizmo_operator_set(axis, 0, ot_rotate, NULL);
|
ptr = WM_gizmo_operator_set(axis, 0, ot_rotate, nullptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MAN_AXES_SCALE: {
|
case MAN_AXES_SCALE: {
|
||||||
if (ot_store.resize == NULL) {
|
if (ot_store.resize == nullptr) {
|
||||||
ot_store.resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
|
ot_store.resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
|
||||||
}
|
}
|
||||||
ptr = WM_gizmo_operator_set(axis, 0, ot_store.resize, NULL);
|
ptr = WM_gizmo_operator_set(axis, 0, ot_store.resize, nullptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1776,7 +1776,7 @@ static void gizmo_refresh_from_matrix(wmGizmo *axis,
|
|||||||
const float scale[3])
|
const float scale[3])
|
||||||
{
|
{
|
||||||
const short axis_type = gizmo_get_axis_type(axis_idx);
|
const short axis_type = gizmo_get_axis_type(axis_idx);
|
||||||
const int aidx_norm = gizmo_orientation_axis(axis_idx, NULL);
|
const int aidx_norm = gizmo_orientation_axis(axis_idx, nullptr);
|
||||||
|
|
||||||
WM_gizmo_set_matrix_location(axis, twmat[3]);
|
WM_gizmo_set_matrix_location(axis, twmat[3]);
|
||||||
switch (axis_idx) {
|
switch (axis_idx) {
|
||||||
@ -1841,7 +1841,7 @@ static void gizmogroup_refresh_from_matrix(wmGizmoGroup *gzgroup,
|
|||||||
const float scale[3],
|
const float scale[3],
|
||||||
const bool ignore_hidden)
|
const bool ignore_hidden)
|
||||||
{
|
{
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
|
|
||||||
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
||||||
if (ignore_hidden && axis->flag & WM_GIZMO_HIDDEN) {
|
if (ignore_hidden && axis->flag & WM_GIZMO_HIDDEN) {
|
||||||
@ -1863,12 +1863,12 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
ScrArea *area = CTX_wm_area(C);
|
ScrArea *area = CTX_wm_area(C);
|
||||||
View3D *v3d = area->spacedata.first;
|
View3D *v3d = static_cast<View3D *>(area->spacedata.first);
|
||||||
RegionView3D *rv3d = region->regiondata;
|
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||||
struct TransformBounds tbounds;
|
TransformBounds tbounds;
|
||||||
|
|
||||||
if (ggd->use_twtype_refresh) {
|
if (ggd->use_twtype_refresh) {
|
||||||
ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init;
|
ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init;
|
||||||
@ -1881,23 +1881,21 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
|||||||
const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, ggd->twtype_init);
|
const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, ggd->twtype_init);
|
||||||
|
|
||||||
/* skip, we don't draw anything anyway */
|
/* skip, we don't draw anything anyway */
|
||||||
if ((ggd->all_hidden = (ED_transform_calc_gizmo_stats(C,
|
TransformCalcParams calc_params{};
|
||||||
&(struct TransformCalcParams){
|
calc_params.use_only_center = true;
|
||||||
.use_only_center = true,
|
calc_params.orientation_index = orient_index + 1;
|
||||||
.orientation_index = orient_index + 1,
|
if ((ggd->all_hidden = (ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0))) {
|
||||||
},
|
|
||||||
&tbounds) == 0))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gizmo_prepare_mat(C, rv3d, &tbounds);
|
gizmo_prepare_mat(C, rv3d, &tbounds);
|
||||||
|
|
||||||
gizmogroup_refresh_from_matrix(gzgroup, rv3d->twmat, NULL, false);
|
gizmogroup_refresh_from_matrix(gzgroup, rv3d->twmat, nullptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C,
|
static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C,
|
||||||
wmGizmoGroup *gzgroup,
|
wmGizmoGroup *gzgroup,
|
||||||
struct wmMsgBus *mbus)
|
wmMsgBus *mbus)
|
||||||
{
|
{
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
bScreen *screen = CTX_wm_screen(C);
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
@ -1917,11 +1915,11 @@ static void gizmogroup_hide_all(GizmoGroup *ggd)
|
|||||||
|
|
||||||
static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
||||||
{
|
{
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
// ScrArea *area = CTX_wm_area(C);
|
// ScrArea *area = CTX_wm_area(C);
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
// View3D *v3d = area->spacedata.first;
|
// View3D *v3d =static_cast< View3D *> (area->spacedata.first);
|
||||||
RegionView3D *rv3d = region->regiondata;
|
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||||
float viewinv_m3[3][3];
|
float viewinv_m3[3][3];
|
||||||
copy_m3_m4(viewinv_m3, rv3d->viewinv);
|
copy_m3_m4(viewinv_m3, rv3d->viewinv);
|
||||||
float idot[3];
|
float idot[3];
|
||||||
@ -2003,10 +2001,10 @@ static void gizmo_3d_draw_invoke(wmGizmoGroup *gzgroup,
|
|||||||
const int axis_idx_active,
|
const int axis_idx_active,
|
||||||
const float mval[2])
|
const float mval[2])
|
||||||
{
|
{
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
const RegionView3D *rv3d = region->regiondata;
|
const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
|
||||||
|
|
||||||
struct wmGizmo *axis_active = ggd->gizmos[axis_idx_active];
|
wmGizmo *axis_active = ggd->gizmos[axis_idx_active];
|
||||||
|
|
||||||
const short axis_active_type = gizmo_get_axis_type(axis_idx_active);
|
const short axis_active_type = gizmo_get_axis_type(axis_idx_active);
|
||||||
if (axis_active_type == MAN_AXES_ROTATE) {
|
if (axis_active_type == MAN_AXES_ROTATE) {
|
||||||
@ -2046,7 +2044,7 @@ static void gizmo_3d_draw_invoke(wmGizmoGroup *gzgroup,
|
|||||||
if (axis->flag & WM_GIZMO_HIDDEN) {
|
if (axis->flag & WM_GIZMO_HIDDEN) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
gizmo_refresh_from_matrix(axis, axis_idx, ggd->twtype, rv3d->twmat, NULL);
|
gizmo_refresh_from_matrix(axis, axis_idx, ggd->twtype, rv3d->twmat, nullptr);
|
||||||
|
|
||||||
if (ELEM(axis_idx, MAN_AXIS_TRANS_C, MAN_AXIS_SCALE_C, MAN_AXIS_ROT_C, MAN_AXIS_ROT_T)) {
|
if (ELEM(axis_idx, MAN_AXIS_TRANS_C, MAN_AXIS_SCALE_C, MAN_AXIS_ROT_C, MAN_AXIS_ROT_T)) {
|
||||||
WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]);
|
WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]);
|
||||||
@ -2072,10 +2070,11 @@ static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C,
|
|||||||
wmGizmo *gz,
|
wmGizmo *gz,
|
||||||
const wmEvent *event)
|
const wmEvent *event)
|
||||||
{
|
{
|
||||||
GizmoGroup *ggd = gzgroup->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||||
const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &gz);
|
const int axis_idx = BLI_array_findindex(ggd->gizmos, ARRAY_SIZE(ggd->gizmos), &gz);
|
||||||
|
|
||||||
gizmo_3d_draw_invoke(gzgroup, CTX_wm_region(C), axis_idx, (float[2]){UNPACK2(event->mval)});
|
const float mval[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||||
|
gizmo_3d_draw_invoke(gzgroup, CTX_wm_region(C), axis_idx, mval);
|
||||||
|
|
||||||
/* Support gizmo specific orientation. */
|
/* Support gizmo specific orientation. */
|
||||||
if (gz != ggd->gizmos[MAN_AXIS_ROT_T]) {
|
if (gz != ggd->gizmos[MAN_AXIS_ROT_T]) {
|
||||||
@ -2147,11 +2146,10 @@ static bool WIDGETGROUP_gizmo_poll_generic(View3D *v3d)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool WIDGETGROUP_gizmo_poll_context(const struct bContext *C,
|
static bool WIDGETGROUP_gizmo_poll_context(const bContext *C, wmGizmoGroupType * /*gzgt*/)
|
||||||
struct wmGizmoGroupType *UNUSED(gzgt))
|
|
||||||
{
|
{
|
||||||
ScrArea *area = CTX_wm_area(C);
|
ScrArea *area = CTX_wm_area(C);
|
||||||
View3D *v3d = area->spacedata.first;
|
View3D *v3d = static_cast<View3D *>(area->spacedata.first);
|
||||||
if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
|
if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2172,14 +2170,14 @@ static bool WIDGETGROUP_gizmo_poll_context(const struct bContext *C,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool WIDGETGROUP_gizmo_poll_tool(const struct bContext *C, struct wmGizmoGroupType *gzgt)
|
static bool WIDGETGROUP_gizmo_poll_tool(const bContext *C, wmGizmoGroupType *gzgt)
|
||||||
{
|
{
|
||||||
if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
|
if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrArea *area = CTX_wm_area(C);
|
ScrArea *area = CTX_wm_area(C);
|
||||||
View3D *v3d = area->spacedata.first;
|
View3D *v3d = static_cast<View3D *>(area->spacedata.first);
|
||||||
if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
|
if (!WIDGETGROUP_gizmo_poll_generic(v3d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2218,7 +2216,7 @@ void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt)
|
|||||||
{V3D_GIZMO_SHOW_OBJECT_ROTATE, "ROTATE", 0, "Rotate", ""},
|
{V3D_GIZMO_SHOW_OBJECT_ROTATE, "ROTATE", 0, "Rotate", ""},
|
||||||
{V3D_GIZMO_SHOW_OBJECT_SCALE, "SCALE", 0, "Scale", ""},
|
{V3D_GIZMO_SHOW_OBJECT_SCALE, "SCALE", 0, "Scale", ""},
|
||||||
{0, "NONE", 0, "None", ""},
|
{0, "NONE", 0, "None", ""},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
RNA_def_enum(gzgt->srna,
|
RNA_def_enum(gzgt->srna,
|
||||||
"drag_action",
|
"drag_action",
|
||||||
@ -2278,12 +2276,12 @@ static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *gzg
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
|
static void WIDGETGROUP_xform_cage_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
|
||||||
{
|
{
|
||||||
struct XFormCageWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup),
|
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(
|
||||||
__func__);
|
MEM_mallocN(sizeof(XFormCageWidgetGroup), __func__));
|
||||||
const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
|
const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
|
||||||
xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL);
|
xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, nullptr);
|
||||||
wmGizmo *gz = xgzgroup->gizmo;
|
wmGizmo *gz = xgzgroup->gizmo;
|
||||||
|
|
||||||
RNA_enum_set(
|
RNA_enum_set(
|
||||||
@ -2299,16 +2297,16 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup
|
|||||||
PointerRNA *ptr;
|
PointerRNA *ptr;
|
||||||
|
|
||||||
/* assign operator */
|
/* assign operator */
|
||||||
PropertyRNA *prop_release_confirm = NULL;
|
PropertyRNA *prop_release_confirm = nullptr;
|
||||||
PropertyRNA *prop_constraint_axis = NULL;
|
PropertyRNA *prop_constraint_axis = nullptr;
|
||||||
|
|
||||||
int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
||||||
for (int x = 0; x < 3; x++) {
|
for (int x = 0; x < 3; x++) {
|
||||||
for (int y = 0; y < 3; y++) {
|
for (int y = 0; y < 3; y++) {
|
||||||
for (int z = 0; z < 3; z++) {
|
for (int z = 0; z < 3; z++) {
|
||||||
const bool constraint[3] = {x != 1, y != 1, z != 1};
|
const bool constraint[3] = {x != 1, y != 1, z != 1};
|
||||||
ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL);
|
ptr = WM_gizmo_operator_set(gz, i, ot_resize, nullptr);
|
||||||
if (prop_release_confirm == NULL) {
|
if (prop_release_confirm == nullptr) {
|
||||||
prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
|
prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
|
||||||
prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
|
prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
|
||||||
}
|
}
|
||||||
@ -2324,22 +2322,20 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup
|
|||||||
static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
||||||
{
|
{
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
RegionView3D *rv3d = region->regiondata;
|
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
|
|
||||||
struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
|
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(gzgroup->customdata);
|
||||||
wmGizmo *gz = xgzgroup->gizmo;
|
wmGizmo *gz = xgzgroup->gizmo;
|
||||||
|
|
||||||
struct TransformBounds tbounds;
|
TransformBounds tbounds;
|
||||||
|
|
||||||
const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, SCE_ORIENT_SCALE);
|
const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, SCE_ORIENT_SCALE);
|
||||||
|
|
||||||
if ((ED_transform_calc_gizmo_stats(C,
|
TransformCalcParams calc_params{};
|
||||||
&(struct TransformCalcParams){
|
calc_params.use_local_axis = true;
|
||||||
.use_local_axis = true,
|
calc_params.orientation_index = orient_index + 1;
|
||||||
.orientation_index = orient_index + 1,
|
if ((ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0) ||
|
||||||
},
|
|
||||||
&tbounds) == 0) ||
|
|
||||||
equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) {
|
equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) {
|
||||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
|
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
|
||||||
}
|
}
|
||||||
@ -2368,18 +2364,18 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgr
|
|||||||
float matrix_offset_global[4][4];
|
float matrix_offset_global[4][4];
|
||||||
mul_m4_m4m4(matrix_offset_global, gz->matrix_space, gz->matrix_offset);
|
mul_m4_m4m4(matrix_offset_global, gz->matrix_space, gz->matrix_offset);
|
||||||
|
|
||||||
PropertyRNA *prop_center_override = NULL;
|
PropertyRNA *prop_center_override = nullptr;
|
||||||
float center[3];
|
float center[3];
|
||||||
float center_global[3];
|
float center_global[3];
|
||||||
int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
||||||
for (int x = 0; x < 3; x++) {
|
for (int x = 0; x < 3; x++) {
|
||||||
center[0] = (float)(1 - x) * dims[0];
|
center[0] = float(1 - x) * dims[0];
|
||||||
for (int y = 0; y < 3; y++) {
|
for (int y = 0; y < 3; y++) {
|
||||||
center[1] = (float)(1 - y) * dims[1];
|
center[1] = float(1 - y) * dims[1];
|
||||||
for (int z = 0; z < 3; z++) {
|
for (int z = 0; z < 3; z++) {
|
||||||
center[2] = (float)(1 - z) * dims[2];
|
center[2] = float(1 - z) * dims[2];
|
||||||
struct wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i);
|
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i);
|
||||||
if (prop_center_override == NULL) {
|
if (prop_center_override == nullptr) {
|
||||||
prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
|
prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
|
||||||
}
|
}
|
||||||
mul_v3_m4v3(center_global, matrix_offset_global, center);
|
mul_v3_m4v3(center_global, matrix_offset_global, center);
|
||||||
@ -2396,7 +2392,7 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgr
|
|||||||
|
|
||||||
static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C,
|
static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C,
|
||||||
wmGizmoGroup *gzgroup,
|
wmGizmoGroup *gzgroup,
|
||||||
struct wmMsgBus *mbus)
|
wmMsgBus *mbus)
|
||||||
{
|
{
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
bScreen *screen = CTX_wm_screen(C);
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
@ -2407,7 +2403,7 @@ static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C,
|
|||||||
|
|
||||||
static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
||||||
{
|
{
|
||||||
struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
|
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(gzgroup->customdata);
|
||||||
|
|
||||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||||
{
|
{
|
||||||
@ -2477,10 +2473,10 @@ static bool WIDGETGROUP_xform_shear_poll(const bContext *C, wmGizmoGroupType *gz
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WIDGETGROUP_xform_shear_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
|
static void WIDGETGROUP_xform_shear_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
|
||||||
{
|
{
|
||||||
struct XFormShearWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormShearWidgetGroup),
|
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(
|
||||||
__func__);
|
MEM_mallocN(sizeof(XFormShearWidgetGroup), __func__));
|
||||||
const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
|
const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
|
||||||
wmOperatorType *ot_shear = WM_operatortype_find("TRANSFORM_OT_shear", true);
|
wmOperatorType *ot_shear = WM_operatortype_find("TRANSFORM_OT_shear", true);
|
||||||
|
|
||||||
@ -2491,26 +2487,26 @@ static void WIDGETGROUP_xform_shear_setup(const bContext *UNUSED(C), wmGizmoGrou
|
|||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
|
wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr);
|
||||||
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
||||||
const int i_ortho_a = (i + j + 1) % 3;
|
const int i_ortho_a = (i + j + 1) % 3;
|
||||||
const int i_ortho_b = (i + (1 - j) + 1) % 3;
|
const int i_ortho_b = (i + (1 - j) + 1) % 3;
|
||||||
interp_v3_v3v3(gz->color, axis_color[i_ortho_a], axis_color[i_ortho_b], 0.75f);
|
interp_v3_v3v3(gz->color, axis_color[i_ortho_a], axis_color[i_ortho_b], 0.75f);
|
||||||
gz->color[3] = 0.5f;
|
gz->color[3] = 0.5f;
|
||||||
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, NULL);
|
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, nullptr);
|
||||||
RNA_boolean_set(ptr, "release_confirm", 1);
|
RNA_boolean_set(ptr, "release_confirm", 1);
|
||||||
xgzgroup->gizmo[i][j] = gz;
|
xgzgroup->gizmo[i][j] = gz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
|
wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr);
|
||||||
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
||||||
RNA_enum_set(gz->ptr, "draw_options", 0); /* No stem. */
|
RNA_enum_set(gz->ptr, "draw_options", 0); /* No stem. */
|
||||||
copy_v3_fl(gz->color, 1.0f);
|
copy_v3_fl(gz->color, 1.0f);
|
||||||
gz->color[3] = 0.5f;
|
gz->color[3] = 0.5f;
|
||||||
WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true);
|
WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true);
|
||||||
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, NULL);
|
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, nullptr);
|
||||||
RNA_boolean_set(ptr, "release_confirm", 1);
|
RNA_boolean_set(ptr, "release_confirm", 1);
|
||||||
xgzgroup->gizmo_view[i] = gz;
|
xgzgroup->gizmo_view[i] = gz;
|
||||||
|
|
||||||
@ -2529,10 +2525,10 @@ static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzg
|
|||||||
{
|
{
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
RegionView3D *rv3d = region->regiondata;
|
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||||
|
|
||||||
struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata;
|
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(gzgroup->customdata);
|
||||||
struct TransformBounds tbounds;
|
TransformBounds tbounds;
|
||||||
|
|
||||||
/* Needed to test view orientation changes. */
|
/* Needed to test view orientation changes. */
|
||||||
copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
|
copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
|
||||||
@ -2541,12 +2537,10 @@ static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzg
|
|||||||
scene, SCE_ORIENT_ROTATE);
|
scene, SCE_ORIENT_ROTATE);
|
||||||
const int orient_index = BKE_scene_orientation_slot_get_index(orient_slot);
|
const int orient_index = BKE_scene_orientation_slot_get_index(orient_slot);
|
||||||
|
|
||||||
if (ED_transform_calc_gizmo_stats(C,
|
TransformCalcParams calc_params{};
|
||||||
&(struct TransformCalcParams){
|
calc_params.use_local_axis = false;
|
||||||
.use_local_axis = false,
|
calc_params.orientation_index = orient_index + 1;
|
||||||
.orientation_index = orient_index + 1,
|
if (ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0) {
|
||||||
},
|
|
||||||
&tbounds) == 0) {
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
wmGizmo *gz = xgzgroup->gizmo[i][j];
|
wmGizmo *gz = xgzgroup->gizmo[i][j];
|
||||||
@ -2593,7 +2587,7 @@ static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzg
|
|||||||
|
|
||||||
static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C,
|
static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C,
|
||||||
wmGizmoGroup *gzgroup,
|
wmGizmoGroup *gzgroup,
|
||||||
struct wmMsgBus *mbus)
|
wmMsgBus *mbus)
|
||||||
{
|
{
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
bScreen *screen = CTX_wm_screen(C);
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
@ -2605,7 +2599,7 @@ static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C,
|
|||||||
|
|
||||||
static void WIDGETGROUP_xform_shear_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
static void WIDGETGROUP_xform_shear_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
||||||
{
|
{
|
||||||
struct XFormShearWidgetGroup *xgzgroup = gzgroup->customdata;
|
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(gzgroup->customdata);
|
||||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||||
{
|
{
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
@ -2708,14 +2702,14 @@ static wmGizmoGroup *gizmogroup_xform_find(TransInfo *t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform_gizmo_3d_model_from_constraint_and_mode_init(TransInfo *t)
|
void transform_gizmo_3d_model_from_constraint_and_mode_init(TransInfo *t)
|
||||||
{
|
{
|
||||||
wmGizmo *gizmo_modal_current = t->region && t->region->gizmo_map ?
|
wmGizmo *gizmo_modal_current = t->region && t->region->gizmo_map ?
|
||||||
WM_gizmomap_get_modal(t->region->gizmo_map) :
|
WM_gizmomap_get_modal(t->region->gizmo_map) :
|
||||||
NULL;
|
nullptr;
|
||||||
if (!gizmo_modal_current || !ELEM(gizmo_modal_current->parent_gzgroup->type,
|
if (!gizmo_modal_current || !ELEM(gizmo_modal_current->parent_gzgroup->type,
|
||||||
g_GGT_xform_gizmo,
|
g_GGT_xform_gizmo,
|
||||||
g_GGT_xform_gizmo_context)) {
|
g_GGT_xform_gizmo_context)) {
|
||||||
@ -2730,7 +2724,7 @@ void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
wmGizmoGroup *gzgroup_xform = gizmogroup_xform_find(t);
|
wmGizmoGroup *gzgroup_xform = gizmogroup_xform_find(t);
|
||||||
if (gzgroup_xform == NULL) {
|
if (gzgroup_xform == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2781,12 +2775,12 @@ void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t)
|
|||||||
|
|
||||||
wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(t->region->gizmo_map);
|
wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(t->region->gizmo_map);
|
||||||
if (axis_idx != -1) {
|
if (axis_idx != -1) {
|
||||||
RegionView3D *rv3d = t->region->regiondata;
|
RegionView3D *rv3d = static_cast<RegionView3D *>(t->region->regiondata);
|
||||||
bool update_orientation = !(equals_v3v3(rv3d->twmat[0], t->spacemtx[0]) &&
|
bool update_orientation = !(equals_v3v3(rv3d->twmat[0], t->spacemtx[0]) &&
|
||||||
equals_v3v3(rv3d->twmat[1], t->spacemtx[1]) &&
|
equals_v3v3(rv3d->twmat[1], t->spacemtx[1]) &&
|
||||||
equals_v3v3(rv3d->twmat[2], t->spacemtx[2]));
|
equals_v3v3(rv3d->twmat[2], t->spacemtx[2]));
|
||||||
|
|
||||||
GizmoGroup *ggd = gzgroup_xform->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup_xform->customdata);
|
||||||
wmGizmo *gizmo_expected = ggd->gizmos[axis_idx];
|
wmGizmo *gizmo_expected = ggd->gizmos[axis_idx];
|
||||||
if (update_orientation || gizmo_modal_current != gizmo_expected) {
|
if (update_orientation || gizmo_modal_current != gizmo_expected) {
|
||||||
if (update_orientation) {
|
if (update_orientation) {
|
||||||
@ -2794,14 +2788,14 @@ void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t)
|
|||||||
copy_v3_v3(rv3d->twmat[3], t->center_global);
|
copy_v3_v3(rv3d->twmat[3], t->center_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
wmEvent event = {NULL};
|
wmEvent event = {nullptr};
|
||||||
|
|
||||||
/* Set the initial mouse value. Used for rotation gizmos. */
|
/* Set the initial mouse value. Used for rotation gizmos. */
|
||||||
copy_v2_v2_int(event.mval, t->mouse.imval);
|
copy_v2_v2_int(event.mval, t->mouse.imval);
|
||||||
|
|
||||||
/* We need to update the position of the gizmo before invoking otherwise
|
/* We need to update the position of the gizmo before invoking otherwise
|
||||||
* #wmGizmo::scale_final could be calculated wrong. */
|
* #wmGizmo::scale_final could be calculated wrong. */
|
||||||
gizmo_refresh_from_matrix(gizmo_expected, axis_idx, ggd->twtype, rv3d->twmat, NULL);
|
gizmo_refresh_from_matrix(gizmo_expected, axis_idx, ggd->twtype, rv3d->twmat, nullptr);
|
||||||
|
|
||||||
BLI_assert_msg(!gizmo_modal_current || gizmo_modal_current->highlight_part == 0,
|
BLI_assert_msg(!gizmo_modal_current || gizmo_modal_current->highlight_part == 0,
|
||||||
"Avoid changing the highlight part");
|
"Avoid changing the highlight part");
|
||||||
@ -2811,7 +2805,7 @@ void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gizmo_modal_current) {
|
else if (gizmo_modal_current) {
|
||||||
WM_gizmo_modal_set_while_modal(t->region->gizmo_map, t->context, NULL, NULL);
|
WM_gizmo_modal_set_while_modal(t->region->gizmo_map, t->context, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2822,11 +2816,11 @@ void transform_gizmo_3d_model_from_constraint_and_mode_restore(TransInfo *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
wmGizmoGroup *gzgroup_xform = gizmogroup_xform_find(t);
|
wmGizmoGroup *gzgroup_xform = gizmogroup_xform_find(t);
|
||||||
if (gzgroup_xform == NULL) {
|
if (gzgroup_xform == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GizmoGroup *ggd = gzgroup_xform->customdata;
|
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup_xform->customdata);
|
||||||
|
|
||||||
/* #wmGizmoGroup::draw_prepare will handle the rest. */
|
/* #wmGizmoGroup::draw_prepare will handle the rest. */
|
||||||
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
@ -10,6 +10,7 @@
|
|||||||
#include "DNA_ID.h"
|
#include "DNA_ID.h"
|
||||||
#include "DNA_brush_enums.h"
|
#include "DNA_brush_enums.h"
|
||||||
#include "DNA_curve_types.h"
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_defs.h"
|
||||||
#include "DNA_texture_types.h" /* for MTex */
|
#include "DNA_texture_types.h" /* for MTex */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -165,6 +166,8 @@ typedef struct BrushCurvesSculptSettings {
|
|||||||
} BrushCurvesSculptSettings;
|
} BrushCurvesSculptSettings;
|
||||||
|
|
||||||
typedef struct Brush {
|
typedef struct Brush {
|
||||||
|
DNA_DEFINE_CXX_METHODS(Brush)
|
||||||
|
|
||||||
ID id;
|
ID id;
|
||||||
|
|
||||||
struct BrushClone clone;
|
struct BrushClone clone;
|
||||||
|
@ -2429,6 +2429,7 @@ typedef enum ePaintFlags {
|
|||||||
* (for now just a duplicate of sculpt symmetry flags).
|
* (for now just a duplicate of sculpt symmetry flags).
|
||||||
*/
|
*/
|
||||||
typedef enum ePaintSymmetryFlags {
|
typedef enum ePaintSymmetryFlags {
|
||||||
|
PAINT_SYMM_NONE = 0,
|
||||||
PAINT_SYMM_X = (1 << 0),
|
PAINT_SYMM_X = (1 << 0),
|
||||||
PAINT_SYMM_Y = (1 << 1),
|
PAINT_SYMM_Y = (1 << 1),
|
||||||
PAINT_SYMM_Z = (1 << 2),
|
PAINT_SYMM_Z = (1 << 2),
|
||||||
@ -2438,6 +2439,13 @@ typedef enum ePaintSymmetryFlags {
|
|||||||
PAINT_TILE_Z = (1 << 6),
|
PAINT_TILE_Z = (1 << 6),
|
||||||
} ePaintSymmetryFlags;
|
} ePaintSymmetryFlags;
|
||||||
ENUM_OPERATORS(ePaintSymmetryFlags, PAINT_TILE_Z);
|
ENUM_OPERATORS(ePaintSymmetryFlags, PAINT_TILE_Z);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
inline ePaintSymmetryFlags operator++(ePaintSymmetryFlags &flags, int)
|
||||||
|
{
|
||||||
|
flags = ePaintSymmetryFlags(char(flags) + 1);
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PAINT_SYMM_AXIS_ALL (PAINT_SYMM_X | PAINT_SYMM_Y | PAINT_SYMM_Z)
|
#define PAINT_SYMM_AXIS_ALL (PAINT_SYMM_X | PAINT_SYMM_Y | PAINT_SYMM_Z)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user