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.cc219
1 files changed, 123 insertions, 96 deletions
diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc
index 3ce39b695e0..6075e4250eb 100644
--- a/source/blender/editors/object/object_add.cc
+++ b/source/blender/editors/object/object_add.cc
@@ -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]);
@@ -2084,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);
@@ -2561,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) {
@@ -3017,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);
@@ -3556,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,
@@ -3569,49 +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);
-
- BKE_view_layer_synced_ensure(scene, view_layer);
- 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);
- }
-
- BKE_view_layer_synced_ensure(scene, view_layer);
- 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(
@@ -3665,70 +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 */
- BKE_view_layer_synced_ensure(scene, view_layer);
- if (BKE_view_layer_active_base_get(view_layer) == 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;
- BKE_view_layer_synced_ensure(scene, view_layer);
- 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. */
@@ -3844,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);
}
@@ -3942,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);
@@ -4097,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");