Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r--source/blender/editors/object/object_add.c57
-rw-r--r--source/blender/editors/object/object_bake_api.c7
-rw-r--r--source/blender/editors/object/object_constraint.c41
-rw-r--r--source/blender/editors/object/object_edit.c66
-rw-r--r--source/blender/editors/object/object_facemap_ops.c128
-rw-r--r--source/blender/editors/object/object_modifier.c2
-rw-r--r--source/blender/editors/object/object_relations.c131
-rw-r--r--source/blender/editors/object/object_remesh.c4
-rw-r--r--source/blender/editors/object/object_vgroup.c183
9 files changed, 374 insertions, 245 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 81b8cd70353..72180d58ecb 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1450,6 +1450,7 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
return OPERATOR_FINISHED;
}
@@ -2647,7 +2648,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ob_gpencil = ED_gpencil_add_object(C, ob->loc, local_view_bits);
copy_v3_v3(ob_gpencil->rot, ob->rot);
copy_v3_v3(ob_gpencil->scale, ob->scale);
- BKE_gpencil_convert_curve(bmain, scene, ob_gpencil, ob, false, false, true);
+ BKE_gpencil_convert_curve(bmain, scene, ob_gpencil, ob, false, 1.0f, 0.0f);
gpencilConverted = true;
}
}
@@ -2783,6 +2784,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
return OPERATOR_FINISHED;
}
@@ -3003,6 +3005,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
return OPERATOR_FINISHED;
}
@@ -3094,6 +3097,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
ED_outliner_select_sync_from_object_tag(C);
return OPERATOR_FINISHED;
@@ -3163,20 +3167,45 @@ static int object_join_exec(bContext *C, wmOperator *op)
}
}
+ int ret = OPERATOR_CANCELLED;
if (ob->type == OB_MESH) {
- return ED_mesh_join_objects_exec(C, op);
- }
- if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
- return ED_curve_join_objects_exec(C, op);
- }
- if (ob->type == OB_ARMATURE) {
- return ED_armature_join_objects_exec(C, op);
- }
- if (ob->type == OB_GPENCIL) {
- return ED_gpencil_join_objects_exec(C, op);
- }
-
- return OPERATOR_CANCELLED;
+ ret = ED_mesh_join_objects_exec(C, op);
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ ret = ED_curve_join_objects_exec(C, op);
+ }
+ else if (ob->type == OB_ARMATURE) {
+ ret = ED_armature_join_objects_exec(C, op);
+ }
+ else if (ob->type == OB_GPENCIL) {
+ ret = ED_gpencil_join_objects_exec(C, op);
+ }
+
+ if (ret & OPERATOR_FINISHED) {
+ /* Even though internally failure to invert is accounted for with a fallback,
+ * show a warning since the result may not be what the user expects. See T80077.
+ *
+ * Failure to invert the matrix is typically caused by zero scaled axes
+ * (which can be caused by constraints, even if the input scale isn't zero).
+ *
+ * Internally the join functions use #invert_m4_m4_safe_ortho which creates
+ * an inevitable matrix from one that has one or more degenerate axes.
+ *
+ * In most cases we don't worry about special handling for non-inevitable matrices however for
+ * joining objects there may be flat 2D objects where it's not obvious the scale is zero.
+ * In this case, using #invert_m4_m4_safe_ortho works as well as we can expect,
+ * joining the contents, flattening on the axis that's zero scaled.
+ * If the zero scale is removed, the data on this axis remains un-scaled
+ * (something that wouldn't work for #invert_m4_m4_safe). */
+ float imat_test[4][4];
+ if (!invert_m4_m4(imat_test, ob->obmat)) {
+ BKE_report(op->reports,
+ RPT_WARNING,
+ "Active object final transform has one or more zero scaled axes");
+ }
+ }
+
+ return ret;
}
void OBJECT_OT_join(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index cb92fab3cb0..4d55aff1d1f 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -745,7 +745,7 @@ static int bake(Render *re,
/* We build a depsgraph for the baking,
* so we don't need to change the original data to adjust visibility and modifiers. */
Depsgraph *depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
- DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer);
+ DEG_graph_build_from_view_layer(depsgraph);
int op_result = OPERATOR_CANCELLED;
bool ok = false;
@@ -1596,9 +1596,8 @@ static void bake_set_props(wmOperator *op, Scene *scene)
prop = RNA_struct_find_property(op->ptr, "cage_object");
if (!RNA_property_is_set(op->ptr, prop)) {
- if (bake->cage_object) {
- RNA_property_string_set(op->ptr, prop, bake->cage_object->id.name + 2);
- }
+ RNA_property_string_set(
+ op->ptr, prop, (bake->cage_object) ? bake->cage_object->id.name + 2 : "");
}
prop = RNA_struct_find_property(op->ptr, "normal_space");
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index bcb1b8afbdd..70404af6433 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -663,10 +663,13 @@ static const EnumPropertyItem constraint_owner_items[] = {
{0, NULL, 0, NULL, NULL},
};
-static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
+static bool edit_constraint_poll_generic(bContext *C,
+ StructRNA *rna_type,
+ const bool is_liboverride_allowed)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", rna_type);
Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
+ bConstraint *con = ptr.data;
if (!ob) {
CTX_wm_operator_poll_msg_set(C, "Context missing active object");
@@ -678,9 +681,11 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
return false;
}
- if (ID_IS_OVERRIDE_LIBRARY(ob) && ptr.data != NULL) {
- CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override");
- return (((bConstraint *)ptr.data)->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0;
+ if (ID_IS_OVERRIDE_LIBRARY(ob) && !is_liboverride_allowed) {
+ if ((con == NULL) || (con->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override");
+ return false;
+ }
}
return true;
@@ -688,7 +693,14 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
static bool edit_constraint_poll(bContext *C)
{
- return edit_constraint_poll_generic(C, &RNA_Constraint);
+ return edit_constraint_poll_generic(C, &RNA_Constraint, false);
+}
+
+/* Used by operators performing actions allowed also on constraints from the overridden linked
+ * object (not only from added 'local' ones). */
+static bool edit_constraint_liboverride_allowed_poll(bContext *C)
+{
+ return edit_constraint_poll_generic(C, &RNA_Constraint, true);
}
static void edit_constraint_properties(wmOperatorType *ot)
@@ -864,7 +876,7 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot)
/* callbacks */
ot->invoke = stretchto_reset_invoke;
ot->exec = stretchto_reset_exec;
- ot->poll = edit_constraint_poll;
+ ot->poll = edit_constraint_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -919,7 +931,7 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot)
/* callbacks */
ot->invoke = limitdistance_reset_invoke;
ot->exec = limitdistance_reset_exec;
- ot->poll = edit_constraint_poll;
+ ot->poll = edit_constraint_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -997,7 +1009,7 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot)
/* callbacks */
ot->invoke = childof_set_inverse_invoke;
ot->exec = childof_set_inverse_exec;
- ot->poll = edit_constraint_poll;
+ ot->poll = edit_constraint_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1046,7 +1058,7 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot)
/* callbacks */
ot->invoke = childof_clear_inverse_invoke;
ot->exec = childof_clear_inverse_exec;
- ot->poll = edit_constraint_poll;
+ ot->poll = edit_constraint_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1693,8 +1705,8 @@ void POSE_OT_constraints_clear(wmOperatorType *ot)
/* callbacks */
ot->exec = pose_constraints_clear_exec;
- ot->poll =
- ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected bones too?
+ ot->poll = ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected
+ // bones too?
}
static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1942,7 +1954,8 @@ static bool get_new_constraint_target(
/* perform some special operations on the target */
if (only_curve) {
- /* Curve-Path option must be enabled for follow-path constraints to be able to work */
+ /* Curve-Path option must be enabled for follow-path constraints to be able to work
+ */
Curve *cu = (Curve *)ob->data;
cu->flag |= CU_PATH;
}
@@ -2214,8 +2227,8 @@ void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot)
/* identifiers */
ot->name = "Add Constraint (with Targets)";
ot->description =
- "Add a constraint to the active object, with target (where applicable) set to the selected "
- "Objects/Bones";
+ "Add a constraint to the active object, with target (where applicable) set to the "
+ "selected Objects/Bones";
ot->idname = "OBJECT_OT_constraint_add_with_targets";
/* api callbacks */
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 04113f70e52..966aeed75ab 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -145,6 +145,72 @@ Object *ED_object_active_context(const bContext *C)
return ob;
}
+/**
+ * Return an array of objects:
+ * - When in the property space, return the pinned or active object.
+ * - When in edit-mode/pose-mode, return an array of objects in the mode.
+ * - Otherwise return selected objects,
+ * the callers \a filter_fn needs to check of they are editable
+ * (assuming they need to be modified).
+ */
+Object **ED_object_array_in_mode_or_selected(bContext *C,
+ bool (*filter_fn)(Object *ob, void *user_data),
+ void *filter_user_data,
+ uint *r_objects_len)
+{
+ ScrArea *area = CTX_wm_area(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob_active = OBACT(view_layer);
+ Object **objects;
+
+ Object *ob = NULL;
+ bool use_ob = true;
+ if (area && (area->spacetype == SPACE_PROPERTIES)) {
+ /* May return pinned object. */
+ ob = ED_object_context(C);
+ }
+ else if (ob_active && (ob_active->mode &
+ (OB_MODE_ALL_PAINT | OB_MODE_ALL_SCULPT | OB_MODE_ALL_PAINT_GPENCIL))) {
+ /* When painting, limit to active. */
+ ob = ob_active;
+ }
+ else {
+ /* Otherwise use full selection. */
+ use_ob = false;
+ }
+
+ if (use_ob) {
+ if ((ob != NULL) && !filter_fn(ob, filter_user_data)) {
+ ob = NULL;
+ }
+ *r_objects_len = (ob != NULL) ? 1 : 0;
+ objects = MEM_mallocN(sizeof(*objects) * *r_objects_len, __func__);
+ if (ob != NULL) {
+ objects[0] = ob;
+ }
+ }
+ else {
+ const View3D *v3d = (area && area->spacetype == SPACE_VIEW3D) ? area->spacedata.first : NULL;
+ /* When in a mode that supports multiple active objects, use "objects in mode"
+ * instead of the object's selection. */
+ if ((ob_active != NULL) && (ob_active->mode & (OB_MODE_EDIT | OB_MODE_POSE))) {
+ objects = BKE_view_layer_array_from_objects_in_mode(
+ view_layer,
+ v3d,
+ r_objects_len,
+ {.no_dup_data = true, .filter_fn = filter_fn, .filter_userdata = filter_user_data});
+ }
+ else {
+ objects = BKE_view_layer_array_selected_objects(
+ view_layer,
+ v3d,
+ r_objects_len,
+ {.no_dup_data = true, .filter_fn = filter_fn, .filter_userdata = filter_user_data});
+ }
+ }
+ return objects;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/object/object_facemap_ops.c b/source/blender/editors/object/object_facemap_ops.c
index 6e0376358bb..32668598df1 100644
--- a/source/blender/editors/object/object_facemap_ops.c
+++ b/source/blender/editors/object/object_facemap_ops.c
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
+#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
@@ -99,71 +100,61 @@ void ED_object_facemap_face_remove(Object *ob, bFaceMap *fmap, int facenum)
}
}
-static void object_fmap_swap_edit_mode(Object *ob, int num1, int num2)
+static void object_fmap_remap_edit_mode(Object *ob, const int *remap)
{
- if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
+ if (ob->type != OB_MESH) {
+ return;
+ }
+
+ Mesh *me = ob->data;
+ if (me->edit_mesh) {
+ BMEditMesh *em = me->edit_mesh;
+ const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
- if (me->edit_mesh) {
- BMEditMesh *em = me->edit_mesh;
- const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
-
- if (cd_fmap_offset != -1) {
- BMFace *efa;
- BMIter iter;
- int *map;
-
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
-
- if (map) {
- if (num1 != -1) {
- if (*map == num1) {
- *map = num2;
- }
- else if (*map == num2) {
- *map = num1;
- }
- }
- }
+ if (cd_fmap_offset != -1) {
+ BMFace *efa;
+ BMIter iter;
+ int *map;
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
+
+ if (map && *map != -1) {
+ *map = remap[*map];
}
}
}
}
}
-static void object_fmap_swap_object_mode(Object *ob, int num1, int num2)
+static void object_fmap_remap_object_mode(Object *ob, const int *remap)
{
- if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
+ if (ob->type != OB_MESH) {
+ return;
+ }
- if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
- int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP);
- int i;
-
- if (map) {
- for (i = 0; i < me->totpoly; i++) {
- if (num1 != -1) {
- if (map[i] == num1) {
- map[i] = num2;
- }
- else if (map[i] == num2) {
- map[i] = num1;
- }
- }
+ Mesh *me = ob->data;
+ if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
+ int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP);
+ int i;
+
+ if (map) {
+ for (i = 0; i < me->totpoly; i++) {
+ if (map[i] != -1) {
+ map[i] = remap[map[i]];
}
}
}
}
}
-static void object_facemap_swap(Object *ob, int num1, int num2)
+static void object_facemap_remap(Object *ob, const int *remap)
{
if (BKE_object_is_in_editmode(ob)) {
- object_fmap_swap_edit_mode(ob, num1, num2);
+ object_fmap_remap_edit_mode(ob, remap);
}
else {
- object_fmap_swap_object_mode(ob, num1, num2);
+ object_fmap_remap_object_mode(ob, remap);
}
}
@@ -432,45 +423,46 @@ static int face_map_move_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_context(C);
bFaceMap *fmap;
int dir = RNA_enum_get(op->ptr, "direction");
- int pos1, pos2 = -1, count;
fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (!fmap) {
return OPERATOR_CANCELLED;
}
- count = BLI_listbase_count(&ob->fmaps);
- pos1 = BLI_findindex(&ob->fmaps, fmap);
+ if (!fmap->prev && !fmap->next) {
+ return OPERATOR_CANCELLED;
+ }
- if (dir == 1) { /*up*/
- void *prev = fmap->prev;
+ int pos1 = BLI_findindex(&ob->fmaps, fmap);
+ int pos2 = pos1 - dir;
+ int len = BLI_listbase_count(&ob->fmaps);
+ int *map = MEM_mallocN(len * sizeof(*map), __func__);
- if (prev) {
- pos2 = pos1 - 1;
- }
- else {
- pos2 = count - 1;
+ if (!IN_RANGE(pos2, -1, len)) {
+ const int offset = len - dir;
+ for (int i = 0; i < len; i++) {
+ map[i] = (i + offset) % len;
}
+ pos2 = map[pos1];
+ }
+ else {
+ range_vn_i(map, len, 0);
+ SWAP(int, map[pos1], map[pos2]);
+ }
- BLI_remlink(&ob->fmaps, fmap);
+ void *prev = fmap->prev;
+ void *next = fmap->next;
+ BLI_remlink(&ob->fmaps, fmap);
+ if (dir == 1) { /*up*/
BLI_insertlinkbefore(&ob->fmaps, prev, fmap);
}
else { /*down*/
- void *next = fmap->next;
-
- if (next) {
- pos2 = pos1 + 1;
- }
- else {
- pos2 = 0;
- }
-
- BLI_remlink(&ob->fmaps, fmap);
BLI_insertlinkafter(&ob->fmaps, next, fmap);
}
- /* iterate through mesh and substitute the indices as necessary */
- object_facemap_swap(ob, pos2, pos1);
+ /* Iterate through mesh and substitute the indices as necessary. */
+ object_facemap_remap(ob, map);
+ MEM_freeN(map);
ob->actfmap = pos2 + 1;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index ceb6553bdf6..14882ab8ffc 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -107,7 +107,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
BKE_object_eval_reset(ob_eval);
if (ob->type == OB_MESH) {
- Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
+ Mesh *me_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
BKE_mesh_eval_delete(me_eval);
}
else if (ob->type == OB_LATTICE) {
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 732d2f6ad52..d9196425098 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -134,13 +134,11 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = CTX_data_edit_object(C);
- BMVert *eve;
- BMIter iter;
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
Object *par;
- int a, v1 = 0, v2 = 0, v3 = 0, v4 = 0, nr = 1;
+
+#define INDEX_UNSET -1
+ int par1, par2, par3, par4;
+ par1 = par2 = par3 = par4 = INDEX_UNSET;
/* we need 1 to 3 selected vertices */
@@ -165,114 +163,108 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
* objects are also up to date. */
BKE_scene_graph_update_tagged(depsgraph, bmain);
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ BMVert *eve;
+ BMIter iter;
+ int curr_index;
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, curr_index) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- if (v1 == 0) {
- v1 = nr;
+ if (par1 == INDEX_UNSET) {
+ par1 = curr_index;
}
- else if (v2 == 0) {
- v2 = nr;
+ else if (par2 == INDEX_UNSET) {
+ par2 = curr_index;
}
- else if (v3 == 0) {
- v3 = nr;
+ else if (par3 == INDEX_UNSET) {
+ par3 = curr_index;
}
- else if (v4 == 0) {
- v4 = nr;
+ else if (par4 == INDEX_UNSET) {
+ par4 = curr_index;
}
else {
break;
}
}
- nr++;
}
}
else if (ELEM(obedit->type, OB_SURF, OB_CURVE)) {
ListBase *editnurb = object_editcurve_get(obedit);
- nu = editnurb->first;
- while (nu) {
+ for (Nurb *nu = editnurb->first; nu != NULL; nu = nu->next) {
if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
+ BezTriple *bezt = nu->bezt;
+ for (int curr_index = 0; curr_index < nu->pntsu; curr_index++, bezt++) {
if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- if (v1 == 0) {
- v1 = nr;
+ if (par1 == INDEX_UNSET) {
+ par1 = curr_index;
}
- else if (v2 == 0) {
- v2 = nr;
+ else if (par2 == INDEX_UNSET) {
+ par2 = curr_index;
}
- else if (v3 == 0) {
- v3 = nr;
+ else if (par3 == INDEX_UNSET) {
+ par3 = curr_index;
}
- else if (v4 == 0) {
- v4 = nr;
+ else if (par4 == INDEX_UNSET) {
+ par4 = curr_index;
}
else {
break;
}
}
- nr++;
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
+ BPoint *bp = nu->bp;
+ const int num_points = nu->pntsu * nu->pntsv;
+ for (int curr_index = 0; curr_index < num_points; curr_index++, bp++) {
if (bp->f1 & SELECT) {
- if (v1 == 0) {
- v1 = nr;
+ if (par1 == INDEX_UNSET) {
+ par1 = curr_index;
}
- else if (v2 == 0) {
- v2 = nr;
+ else if (par2 == INDEX_UNSET) {
+ par2 = curr_index;
}
- else if (v3 == 0) {
- v3 = nr;
+ else if (par3 == INDEX_UNSET) {
+ par3 = curr_index;
}
- else if (v4 == 0) {
- v4 = nr;
+ else if (par4 == INDEX_UNSET) {
+ par4 = curr_index;
}
else {
break;
}
}
- nr++;
- bp++;
}
}
- nu = nu->next;
}
}
else if (obedit->type == OB_LATTICE) {
Lattice *lt = obedit->data;
- a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
- bp = lt->editlatt->latt->def;
- while (a--) {
+ const int num_points = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv *
+ lt->editlatt->latt->pntsw;
+ BPoint *bp = lt->editlatt->latt->def;
+ for (int curr_index = 0; curr_index < num_points; curr_index++, bp++) {
if (bp->f1 & SELECT) {
- if (v1 == 0) {
- v1 = nr;
+ if (par1 == INDEX_UNSET) {
+ par1 = curr_index;
}
- else if (v2 == 0) {
- v2 = nr;
+ else if (par2 == INDEX_UNSET) {
+ par2 = curr_index;
}
- else if (v3 == 0) {
- v3 = nr;
+ else if (par3 == INDEX_UNSET) {
+ par3 = curr_index;
}
- else if (v4 == 0) {
- v4 = nr;
+ else if (par4 == INDEX_UNSET) {
+ par4 = curr_index;
}
else {
break;
}
}
- nr++;
- bp++;
}
}
- if (v4 || !((v1 && v2 == 0 && v3 == 0) || (v1 && v2 && v3))) {
+ if (par4 != INDEX_UNSET || par1 == INDEX_UNSET || (par2 != INDEX_UNSET && par3 == INDEX_UNSET)) {
BKE_report(op->reports, RPT_ERROR, "Select either 1 or 3 vertices to parent to");
return OPERATOR_CANCELLED;
}
@@ -289,11 +281,11 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
Object workob;
ob->parent = BASACT(view_layer)->object;
- if (v3) {
+ if (par3 != INDEX_UNSET) {
ob->partype = PARVERT3;
- ob->par1 = v1 - 1;
- ob->par2 = v2 - 1;
- ob->par3 = v3 - 1;
+ ob->par1 = par1;
+ ob->par2 = par2;
+ ob->par3 = par3;
/* inverse parent matrix */
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
@@ -301,7 +293,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
}
else {
ob->partype = PARVERT1;
- ob->par1 = v1 - 1;
+ ob->par1 = par1;
/* inverse parent matrix */
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
@@ -317,6 +309,8 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT, NULL);
return OPERATOR_FINISHED;
+
+#undef INDEX_UNSET
}
void OBJECT_OT_vertex_parent_set(wmOperatorType *ot)
@@ -1474,7 +1468,8 @@ static int make_links_scene_exec(bContext *C, wmOperator *op)
/* redraw the 3D view because the object center points are colored differently */
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
- /* one day multiple scenes will be visible, then we should have some update function for them */
+ /* one day multiple scenes will be visible, then we should have some update function for them
+ */
return OPERATOR_FINISHED;
}
@@ -1794,9 +1789,9 @@ static Collection *single_object_users_collection(Main *bmain,
if (is_master_collection && copy_collections && child->collection != collection_child_new) {
/* We do not want a collection sync here, our collections are in a complete uninitialized
- * state currently. With current code, that would lead to a memory leak - because of reasons.
- * It would be a useless loss of computing anyway, since caller has to fully refresh
- * view-layers/collections caching at the end. */
+ * state currently. With current code, that would lead to a memory leak - because of
+ * reasons. It would be a useless loss of computing anyway, since caller has to fully
+ * refresh view-layers/collections caching at the end. */
BKE_collection_child_add_no_sync(collection, collection_child_new);
BLI_remlink(&collection->children, child);
MEM_freeN(child);
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index 8d8f01dd61a..f14c734da4e 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -294,7 +294,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar),
{
VoxelSizeEditCustomData *cd = arg;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -363,7 +363,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar),
GPU_matrix_pop();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 253287c382e..de9cca38a6e 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -72,15 +72,32 @@
#include "ED_mesh.h"
#include "ED_object.h"
+#include "ED_screen.h"
#include "UI_resources.h"
#include "object_intern.h"
+static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob);
+
/* -------------------------------------------------------------------- */
-/** \name Public Utility Functions
+/** \name Local Utility Functions
* \{ */
+static bool object_array_for_wpaint_filter(Object *ob, void *user_data)
+{
+ bContext *C = user_data;
+ if (vertex_group_supported_poll_ex(C, ob)) {
+ return true;
+ }
+ return false;
+}
+
+static Object **object_array_for_wpaint(bContext *C, uint *r_objects_len)
+{
+ return ED_object_array_in_mode_or_selected(C, object_array_for_wpaint_filter, C, r_objects_len);
+}
+
static bool vertex_group_use_vert_sel(Object *ob)
{
if (ob->mode == OB_MODE_EDIT) {
@@ -100,6 +117,12 @@ static Lattice *vgroup_edit_lattice(Object *ob)
return (lt->editlatt) ? lt->editlatt->latt : lt;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Public Utility Functions
+ * \{ */
+
bool ED_vgroup_sync_from_pose(Object *ob)
{
Object *armobj = BKE_object_pose_armature_get(ob);
@@ -2407,7 +2430,7 @@ void ED_vgroup_mirror(Object *ob,
goto cleanup;
}
- EDBM_verts_mirror_cache_begin(em, 0, true, false, use_topology);
+ EDBM_verts_mirror_cache_begin(em, 0, true, false, false, use_topology);
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
@@ -2659,14 +2682,21 @@ static void vgroup_assign_verts(Object *ob, const float weight)
/** \name Shared Operator Poll Functions
* \{ */
+static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob)
+{
+ if (!ED_operator_object_active_local_editable_ex(C, ob)) {
+ return false;
+ }
+ const ID *data = ob->data;
+ return (OB_TYPE_SUPPORT_VGROUP(ob->type) &&
+ /* Data checks. */
+ (data != NULL) && !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
+}
+
static bool vertex_group_supported_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
-
- return (ob && !ID_IS_LINKED(ob) && OB_TYPE_SUPPORT_VGROUP(ob->type) &&
- !ID_IS_OVERRIDE_LIBRARY(ob) && data && !ID_IS_LINKED(data) &&
- !ID_IS_OVERRIDE_LIBRARY(data));
+ return vertex_group_supported_poll_ex(C, ob);
}
static bool vertex_group_poll(bContext *C)
@@ -3077,6 +3107,12 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Copy Operator
+ * \{ */
+
static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
@@ -3090,12 +3126,6 @@ static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Vertex Group Copy Operator
- * \{ */
-
void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
{
/* identifiers */
@@ -3111,6 +3141,12 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Levels Operator
+ * \{ */
+
static int vertex_group_levels_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3133,12 +3169,6 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Vertex Group Levels Operator
- * \{ */
-
void OBJECT_OT_vertex_group_levels(wmOperatorType *ot)
{
/* identifiers */
@@ -3161,6 +3191,12 @@ void OBJECT_OT_vertex_group_levels(wmOperatorType *ot)
ot->srna, "gain", 1.f, 0.f, FLT_MAX, "Gain", "Value to multiply weights by", 0.0f, 10.f);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Normalize Operator
+ * \{ */
+
static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
@@ -3178,12 +3214,6 @@ static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Vertex Group Normalize Operator
- * \{ */
-
void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot)
{
/* identifiers */
@@ -3200,6 +3230,12 @@ void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Normalize All Operator
+ * \{ */
+
static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3226,12 +3262,6 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Vertex Group Normalize All Operator
- * \{ */
-
void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
{
/* identifiers */
@@ -3512,22 +3542,11 @@ static int vertex_group_smooth_exec(bContext *C, wmOperator *op)
{
const float fac = RNA_float_get(op->ptr, "factor");
const int repeat = RNA_int_get(op->ptr, "repeat");
- eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
+ const eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
const float fac_expand = RNA_float_get(op->ptr, "expand");
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob_ctx = ED_object_context(C);
uint objects_len;
- Object **objects;
- if (ob_ctx->mode == OB_MODE_WEIGHT_PAINT) {
- /* Until weight paint supports multi-edit, use only the active. */
- objects_len = 1;
- objects = &ob_ctx;
- }
- else {
- objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len, ob_ctx->mode);
- }
+ Object **objects = object_array_for_wpaint(C, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -3544,9 +3563,7 @@ static int vertex_group_smooth_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
}
- if (objects != &ob_ctx) {
- MEM_freeN(objects);
- }
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -3588,22 +3605,29 @@ void OBJECT_OT_vertex_group_smooth(wmOperatorType *ot)
static int vertex_group_clean_exec(bContext *C, wmOperator *op)
{
- Object *ob = ED_object_context(C);
+ const float limit = RNA_float_get(op->ptr, "limit");
+ const bool keep_single = RNA_boolean_get(op->ptr, "keep_single");
+ const eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
- float limit = RNA_float_get(op->ptr, "limit");
- bool keep_single = RNA_boolean_get(op->ptr, "keep_single");
- eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
+ uint objects_len;
+ Object **objects = object_array_for_wpaint(C, &objects_len);
- int subset_count, vgroup_tot;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
- const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
- ob, subset_type, &vgroup_tot, &subset_count);
- vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single);
- MEM_freeN((void *)vgroup_validmap);
+ int subset_count, vgroup_tot;
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
+ ob, subset_type, &vgroup_tot, &subset_count);
+
+ vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single);
+ MEM_freeN((void *)vgroup_validmap);
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ }
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -3611,7 +3635,7 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op)
void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Clean Vertex Group";
+ ot->name = "Clean Vertex Group Weights";
ot->idname = "OBJECT_OT_vertex_group_clean";
ot->description = "Remove vertex group assignments which are not required";
@@ -3692,25 +3716,36 @@ void OBJECT_OT_vertex_group_quantize(wmOperatorType *ot)
static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
{
- Object *ob = ED_object_context(C);
-
const int limit = RNA_int_get(op->ptr, "limit");
- eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
+ const eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
+ int remove_multi_count = 0;
- int subset_count, vgroup_tot;
+ uint objects_len;
+ Object **objects = object_array_for_wpaint(C, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
- const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
- ob, subset_type, &vgroup_tot, &subset_count);
- int remove_tot = vgroup_limit_total_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit);
- MEM_freeN((void *)vgroup_validmap);
+ int subset_count, vgroup_tot;
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
+ ob, subset_type, &vgroup_tot, &subset_count);
+ const int remove_count = vgroup_limit_total_subset(
+ ob, vgroup_validmap, vgroup_tot, subset_count, limit);
+ MEM_freeN((void *)vgroup_validmap);
- BKE_reportf(
- op->reports, remove_tot ? RPT_INFO : RPT_WARNING, "%d vertex weights limited", remove_tot);
+ if (remove_count != 0) {
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ }
+ remove_multi_count += remove_count;
+ }
+ MEM_freeN(objects);
- if (remove_tot) {
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ if (remove_multi_count) {
+ BKE_reportf(op->reports,
+ remove_multi_count ? RPT_INFO : RPT_WARNING,
+ "%d vertex weights limited",
+ remove_multi_count);
return OPERATOR_FINISHED;
}