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/object_add.cc')
-rw-r--r--source/blender/editors/object/object_add.cc264
1 files changed, 154 insertions, 110 deletions
diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc
index c651affd96a..6075e4250eb 100644
--- a/source/blender/editors/object/object_add.cc
+++ b/source/blender/editors/object/object_add.cc
@@ -287,7 +287,7 @@ void ED_object_rotation_from_quat(float rot[3], const float viewquat[4], const c
}
case 'Y': {
quat_to_eul(rot, viewquat);
- rot[0] -= (float)M_PI_2;
+ rot[0] -= float(M_PI_2);
break;
}
case 'Z': {
@@ -322,7 +322,7 @@ void ED_object_base_init_transform_on_add(Object *object, const float loc[3], co
copy_v3_v3(object->rot, rot);
}
- BKE_object_to_mat4(object, object->obmat);
+ BKE_object_to_mat4(object, object->object_to_world);
}
float ED_object_new_primitive_matrix(bContext *C,
@@ -342,14 +342,14 @@ float ED_object_new_primitive_matrix(bContext *C,
invert_m3(rmat);
/* inverse transform for initial rotation and object */
- copy_m3_m4(mat, obedit->obmat);
+ copy_m3_m4(mat, obedit->object_to_world);
mul_m3_m3m3(cmat, rmat, mat);
invert_m3_m3(imat, cmat);
copy_m4_m3(r_primmat, imat);
/* center */
copy_v3_v3(r_primmat[3], loc);
- sub_v3_v3v3(r_primmat[3], r_primmat[3], obedit->obmat[3]);
+ sub_v3_v3v3(r_primmat[3], r_primmat[3], obedit->object_to_world[3]);
invert_m3_m3(imat, mat);
mul_m3_v3(imat, r_primmat[3]);
@@ -372,8 +372,8 @@ float ED_object_new_primitive_matrix(bContext *C,
/** \name Add Object Operator
* \{ */
-static void view_align_update(struct Main *UNUSED(main),
- struct Scene *UNUSED(scene),
+static void view_align_update(struct Main * /*main*/,
+ struct Scene * /*scene*/,
struct PointerRNA *ptr)
{
RNA_struct_idprops_unset(ptr, "rotation");
@@ -609,6 +609,7 @@ Object *ED_object_add_type_with_obdata(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit != nullptr) {
ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
@@ -619,17 +620,18 @@ Object *ED_object_add_type_with_obdata(bContext *C,
Object *ob;
if (obdata != nullptr) {
BLI_assert(type == BKE_object_obdata_to_type(obdata));
- ob = BKE_object_add_for_data(bmain, view_layer, type, name, obdata, true);
+ ob = BKE_object_add_for_data(bmain, scene, view_layer, type, name, obdata, true);
const short *materials_len_p = BKE_id_material_len_p(obdata);
if (materials_len_p && *materials_len_p > 0) {
BKE_object_materials_test(bmain, ob, static_cast<ID *>(ob->data));
}
}
else {
- ob = BKE_object_add(bmain, view_layer, type, name);
+ ob = BKE_object_add(bmain, scene, view_layer, type, name);
}
- Base *ob_base_act = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *ob_base_act = BKE_view_layer_active_base_get(view_layer);
/* While not getting a valid base is not a good thing, it can happen in convoluted corner cases,
* better not crash on it in releases. */
BLI_assert(ob_base_act != nullptr);
@@ -990,6 +992,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
}
bool newob = false;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit == nullptr || obedit->type != OB_MBALL) {
obedit = ED_object_add_type(C, OB_MBALL, nullptr, loc, rot, true, local_view_bits);
@@ -1099,6 +1102,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -1471,7 +1475,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void object_add_ui(bContext *UNUSED(C), wmOperator *op)
+static void object_add_ui(bContext * /*C*/, wmOperator *op)
{
uiLayout *layout = op->layout;
@@ -2080,7 +2084,7 @@ static int object_curves_empty_hair_add_exec(bContext *C, wmOperator *op)
Object *curves_ob = ED_object_add_type(
C, OB_CURVES, nullptr, nullptr, nullptr, false, local_view_bits);
- BKE_object_apply_mat4(curves_ob, surface_ob->obmat, false, false);
+ BKE_object_apply_mat4(curves_ob, surface_ob->object_to_world, false, false);
/* Set surface object. */
Curves *curves_id = static_cast<Curves *>(curves_ob->data);
@@ -2534,6 +2538,7 @@ static void make_object_duplilist_real(bContext *C,
}
BKE_collection_object_add_from(bmain, scene, base->object, ob_dst);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base_dst = BKE_view_layer_base_find(view_layer, ob_dst);
BLI_assert(base_dst != nullptr);
@@ -2556,8 +2561,8 @@ static void make_object_duplilist_real(bContext *C,
id_us_min((ID *)ob_dst->instance_collection);
ob_dst->instance_collection = nullptr;
- copy_m4_m4(ob_dst->obmat, dob->mat);
- BKE_object_apply_mat4(ob_dst, ob_dst->obmat, false, false);
+ copy_m4_m4(ob_dst->object_to_world, dob->mat);
+ BKE_object_apply_mat4(ob_dst, ob_dst->object_to_world, false, false);
BLI_ghash_insert(dupli_gh, dob, ob_dst);
if (parent_gh) {
@@ -2831,6 +2836,7 @@ static Base *duplibase_for_convert(
DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
BKE_collection_object_add_from(bmain, scene, ob, obn);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *basen = BKE_view_layer_base_find(view_layer, obn);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_select(base, BA_DESELECT);
@@ -3011,7 +3017,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
float loc[3], size[3], rot[3][3], eul[3];
float matrix[4][4];
- mat4_to_loc_rot_size(loc, rot, size, ob->obmat);
+ mat4_to_loc_rot_size(loc, rot, size, ob->object_to_world);
mat3_to_eul(eul, rot);
Object *ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits);
@@ -3301,7 +3307,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
baseob = BKE_mball_basis_find(scene, ob);
if (ob != baseob) {
- /* if motherball is converting it would be marked as done later */
+ /* If mother-ball is converting it would be marked as done later. */
ob->flag |= OB_DONE;
}
@@ -3443,9 +3449,13 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ED_object_base_activate(C, basact);
view_layer->basact = basact;
}
- else if (view_layer->basact->object->flag & OB_DONE) {
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, view_layer->basact->object);
- WM_event_add_notifier(C, NC_OBJECT | ND_DATA, view_layer->basact->object);
+ else {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *object = BKE_view_layer_active_object_get(view_layer);
+ if (object->flag & OB_DONE) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DATA, object);
+ }
}
DEG_relations_tag_update(bmain);
@@ -3457,7 +3467,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void object_convert_ui(bContext *UNUSED(C), wmOperator *op)
+static void object_convert_ui(bContext * /*C*/, wmOperator *op)
{
uiLayout *layout = op->layout;
@@ -3500,11 +3510,12 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(
ot->srna, "target", convert_target_items, OB_MESH, "Target", "Type of object to convert to");
- RNA_def_boolean(ot->srna,
- "keep_original",
- false,
- "Keep Original",
- "Keep original objects instead of replacing them");
+ prop = RNA_def_boolean(ot->srna,
+ "keep_original",
+ false,
+ "Keep Original",
+ "Keep original objects instead of replacing them");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_OBJECT);
RNA_def_boolean(
ot->srna,
@@ -3545,11 +3556,62 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/** \name Duplicate Object Operator
* \{ */
+static void object_add_sync_base_collection(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_src, Object *object_new)
+{
+ if ((base_src != nullptr) && (base_src->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT)) {
+ BKE_collection_object_add_from(bmain, scene, base_src->object, object_new);
+ }
+ else {
+ LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
+ BKE_collection_object_add(bmain, layer_collection->collection, object_new);
+ }
+}
+
+static void object_add_sync_local_view(Base *base_src, Base *base_new)
+{
+ base_new->local_view_bits = base_src->local_view_bits;
+}
+
+static void object_add_sync_rigid_body(Main *bmain, Object *object_src, Object *object_new)
+{
+ /* 1) duplis should end up in same collection as the original
+ * 2) Rigid Body sim participants MUST always be part of a collection...
+ */
+ /* XXX: is 2) really a good measure here? */
+ if (object_src->rigidbody_object || object_src->rigidbody_constraint) {
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ if (BKE_collection_has_object(collection, object_src)) {
+ BKE_collection_object_add(bmain, collection, object_new);
+ }
+ }
+ }
+}
+
/**
* - Assumes `id.new` is correct.
* - Leaves selection of base/object unaltered.
* - Sets #ID.newid pointers.
*/
+static void object_add_duplicate_internal(Main *bmain,
+ Object *ob,
+ const eDupli_ID_Flags dupflag,
+ const eLibIDDuplicateFlags duplicate_options,
+ Object **r_ob_new)
+{
+ if (ob->mode & OB_MODE_POSE) {
+ return;
+ }
+
+ Object *obn = static_cast<Object *>(
+ ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag, duplicate_options)));
+ if (r_ob_new) {
+ *r_ob_new = obn;
+ }
+ DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ return;
+}
+
static Base *object_add_duplicate_internal(Main *bmain,
Scene *scene,
ViewLayer *view_layer,
@@ -3558,47 +3620,25 @@ static Base *object_add_duplicate_internal(Main *bmain,
const eLibIDDuplicateFlags duplicate_options,
Object **r_ob_new)
{
- Base *base, *basen = nullptr;
- Object *obn;
-
- if (ob->mode & OB_MODE_POSE) {
- /* nothing? */
+ Object *object_new = nullptr;
+ object_add_duplicate_internal(bmain, ob, dupflag, duplicate_options, &object_new);
+ if (r_ob_new) {
+ *r_ob_new = object_new;
+ }
+ if (object_new == nullptr) {
+ return nullptr;
}
- else {
- obn = static_cast<Object *>(
- ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag, duplicate_options)));
- if (r_ob_new) {
- *r_ob_new = obn;
- }
- DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
-
- base = BKE_view_layer_base_find(view_layer, ob);
- if ((base != nullptr) && (base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT)) {
- BKE_collection_object_add_from(bmain, scene, ob, obn);
- }
- else {
- LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
- BKE_collection_object_add(bmain, layer_collection->collection, obn);
- }
-
- basen = BKE_view_layer_base_find(view_layer, obn);
- if (base != nullptr && basen != nullptr) {
- basen->local_view_bits = base->local_view_bits;
- }
- /* 1) duplis should end up in same collection as the original
- * 2) Rigid Body sim participants MUST always be part of a collection...
- */
- /* XXX: is 2) really a good measure here? */
- if (ob->rigidbody_object || ob->rigidbody_constraint) {
- LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
- if (BKE_collection_has_object(collection, ob)) {
- BKE_collection_object_add(bmain, collection, obn);
- }
- }
- }
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base_src = BKE_view_layer_base_find(view_layer, ob);
+ object_add_sync_base_collection(bmain, scene, view_layer, base_src, object_new);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base_new = BKE_view_layer_base_find(view_layer, object_new);
+ if (base_src && base_new) {
+ object_add_sync_local_view(base_src, base_new);
}
- return basen;
+ object_add_sync_rigid_body(bmain, ob, object_new);
+ return base_new;
}
Base *ED_object_add_duplicate(
@@ -3652,68 +3692,70 @@ static int duplicate_exec(bContext *C, wmOperator *op)
* we also want to remap pointers between those... */
BKE_main_id_newptr_and_tag_clear(bmain);
- /* Do not do collection re-syncs for each object; will do it once afterwards.
- * However this means we can't get to new duplicated Base's immediately, will
- * have to process them after the sync. */
- BKE_layer_collection_resync_forbid();
-
/* Duplicate the selected objects, remember data needed to process
- * after the sync (the base of the original object, and the copy of the
- * original object). */
- blender::Vector<std::pair<Base *, Object *>> source_bases_new_objects;
- Object *ob_new_active = nullptr;
+ * after the sync. */
+ struct DuplicateObjectLink {
+ Base *base_src = nullptr;
+ Object *object_new = nullptr;
+
+ DuplicateObjectLink(Base *base_src) : base_src(base_src)
+ {
+ }
+ };
+ blender::Vector<DuplicateObjectLink> object_base_links;
CTX_DATA_BEGIN (C, Base *, base, selected_bases) {
- Object *ob_new = nullptr;
+ object_base_links.append(DuplicateObjectLink(base));
+ }
+ CTX_DATA_END;
+
+ bool new_objects_created = false;
+ for (DuplicateObjectLink &link : object_base_links) {
object_add_duplicate_internal(bmain,
- scene,
- view_layer,
- base->object,
+ link.base_src->object,
dupflag,
LIB_ID_DUPLICATE_IS_SUBPROCESS | LIB_ID_DUPLICATE_IS_ROOT_ID,
- &ob_new);
- if (ob_new == nullptr) {
- continue;
- }
- source_bases_new_objects.append({base, ob_new});
-
- /* note that this is safe to do with this context iterator,
- * the list is made in advance */
- ED_object_base_select(base, BA_DESELECT);
-
- /* new object will become active */
- if (view_layer->basact == base) {
- ob_new_active = ob_new;
+ &link.object_new);
+ if (link.object_new) {
+ new_objects_created = true;
}
}
- CTX_DATA_END;
- BKE_layer_collection_resync_allow();
- if (source_bases_new_objects.is_empty()) {
+ if (!new_objects_created) {
return OPERATOR_CANCELLED;
}
- /* Sync the collection now, after everything is duplicated. */
- BKE_main_collection_sync(bmain);
+ /* Sync that could tag the view_layer out of sync. */
+ for (DuplicateObjectLink &link : object_base_links) {
+ /* note that this is safe to do with this context iterator,
+ * the list is made in advance */
+ ED_object_base_select(link.base_src, BA_DESELECT);
+ if (link.object_new) {
+ object_add_sync_base_collection(bmain, scene, view_layer, link.base_src, link.object_new);
+ object_add_sync_rigid_body(bmain, link.base_src->object, link.object_new);
+ }
+ }
- /* After sync we can get to the new Base data, process it here. */
- for (const auto &item : source_bases_new_objects) {
- Object *ob_new = item.second;
- Base *base_source = item.first;
- Base *base_new = BKE_view_layer_base_find(view_layer, ob_new);
- if (base_new == nullptr) {
+ /* Sync the view layer. Everything else should not tag the view_layer out of sync. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ const Base *active_base = BKE_view_layer_active_base_get(view_layer);
+ for (DuplicateObjectLink &link : object_base_links) {
+ if (!link.object_new) {
continue;
}
+
+ Base *base_new = BKE_view_layer_base_find(view_layer, link.object_new);
+ BLI_assert(base_new);
ED_object_base_select(base_new, BA_SELECT);
- if (ob_new == ob_new_active) {
+ if (active_base == link.base_src) {
ED_object_base_activate(C, base_new);
}
- if (base_new->object->data) {
- DEG_id_tag_update(static_cast<ID *>(base_new->object->data), 0);
+
+ if (link.object_new->data) {
+ DEG_id_tag_update(static_cast<ID *>(link.object_new->data), 0);
}
- /* #object_add_duplicate_internal will not have done this, since
- * before the collection sync it would not have found the new base yet. */
- base_new->local_view_bits = base_source->local_view_bits;
+
+ object_add_sync_local_view(link.base_src, base_new);
}
/* Note that this will also clear newid pointers and tags. */
@@ -3811,7 +3853,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
/* object_add_duplicate_internal() doesn't deselect other objects, unlike object_add_common() or
* BKE_view_layer_base_deselect_all(). */
- ED_object_base_deselect_all(view_layer, nullptr, SEL_DESELECT);
+ ED_object_base_deselect_all(scene, view_layer, nullptr, SEL_DESELECT);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_activate(C, basen);
@@ -3829,8 +3871,8 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
PropertyRNA *prop_matrix = RNA_struct_find_property(op->ptr, "matrix");
if (RNA_property_is_set(op->ptr, prop_matrix)) {
Object *ob_add = basen->object;
- RNA_property_float_get_array(op->ptr, prop_matrix, &ob_add->obmat[0][0]);
- BKE_object_apply_mat4(ob_add, ob_add->obmat, true, true);
+ RNA_property_float_get_array(op->ptr, prop_matrix, &ob_add->object_to_world[0][0]);
+ BKE_object_apply_mat4(ob_add, ob_add->object_to_world, true, true);
DEG_id_tag_update(&ob_add->id, ID_RECALC_TRANSFORM);
}
@@ -3888,12 +3930,14 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
static int object_transform_to_mouse_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = reinterpret_cast<Object *>(
WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_OB));
if (!ob) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
}
@@ -3925,7 +3969,7 @@ static int object_transform_to_mouse_exec(bContext *C, wmOperator *op)
float mat_dst_unit[4][4];
float final_delta[4][4];
- normalize_m4_m4(mat_src_unit, ob->obmat);
+ normalize_m4_m4(mat_src_unit, ob->object_to_world);
normalize_m4_m4(mat_dst_unit, matrix);
invert_m4(mat_src_unit);
mul_m4_m4m4(final_delta, mat_dst_unit, mat_src_unit);
@@ -4080,7 +4124,7 @@ static int object_join_exec(bContext *C, wmOperator *op)
* 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)) {
+ if (!invert_m4_m4(imat_test, ob->object_to_world)) {
BKE_report(op->reports,
RPT_WARNING,
"Active object final transform has one or more zero scaled axes");