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:
authorCampbell Barton <ideasman42@gmail.com>2020-08-25 07:32:10 +0300
committerJeroen Bakker <jeroen@blender.org>2020-08-26 12:47:41 +0300
commitdedab68dcce0f2880f0678e7cfa80e0261b0de72 (patch)
tree7ed5dc6b7332e8ea2d5bad293431efbe28793ba6
parent19fe5529d7373b0d27a478fe1c4cef62b7fa9199 (diff)
Fix T80077: Objects disappear when joining with a zero scaled axis
Use invert_m4_m4_safe_ortho when joining objects so zero scaled axis doesn't cause all points to be scaled to zero. Instead geometry is left un-scaled on degenerate axes. Report a warning in this case since users may want to adjust the active objects scale.
-rw-r--r--source/blender/editors/armature/armature_relations.c7
-rw-r--r--source/blender/editors/curve/editcurve.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c7
-rw-r--r--source/blender/editors/mesh/meshtools.c5
-rw-r--r--source/blender/editors/object/object_add.c39
5 files changed, 48 insertions, 15 deletions
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index d544aed5481..a33baee46cd 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -304,7 +304,11 @@ int join_armature_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* Get editbones of active armature to add editbones to */
+ /* Inverse transform for all selected armatures in this object,
+ * See #object_join_exec for detailed comment on why the safe version is used. */
+ invert_m4_m4_safe_ortho(oimat, ob_active->obmat);
+
+ /* Get edit-bones of active armature to add edit-bones to */
ED_armature_to_edit(arm);
/* get pose of active object and move it out of posemode */
@@ -334,7 +338,6 @@ int join_armature_exec(bContext *C, wmOperator *op)
// BASACT->flag &= ~OB_MODE_POSE;
/* Find the difference matrix */
- invert_m4_m4(oimat, ob_active->obmat);
mul_m4_m4m4(mat, oimat, ob_iter->obmat);
/* Copy bones and posechannels from the object to the edit armature */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index d6256f67066..240f5261960 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -6925,8 +6925,9 @@ int join_curve_exec(bContext *C, wmOperator *op)
BLI_listbase_clear(&tempbase);
- /* trasnform all selected curves inverse in obact */
- invert_m4_m4(imat, ob_active->obmat);
+ /* Inverse transform for all selected curves in this object,
+ * See #object_join_exec for detailed comment on why the safe version is used. */
+ invert_m4_m4_safe_ortho(imat, ob_active->obmat);
CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
if (ob_iter->type == ob_active->type) {
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index c7b46858df9..a047c1b8494 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -2675,7 +2675,10 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
sub_v3_v3v3(offset_global, ob_active->loc, ob_iter->obmat[3]);
copy_m3_m4(bmat, ob_active->obmat);
- invert_m3_m3(imat, bmat);
+
+ /* Inverse transform for all selected curves in this object,
+ * See #object_join_exec for detailed comment on why the safe version is used. */
+ invert_m3_m3_safe_ortho(imat, bmat);
mul_m3_v3(imat, offset_global);
mul_v3_m3v3(offset_local, imat, offset_global);
@@ -2686,7 +2689,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
/* recalculate all stroke points */
BKE_gpencil_parent_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
- invert_m4_m4(inverse_diff_mat, diff_mat);
+ invert_m4_m4_safe_ortho(inverse_diff_mat, diff_mat);
Material *ma_src = NULL;
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_new->frames) {
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 917bbe61e3d..1f72fe281e3 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -551,8 +551,9 @@ int join_mesh_exec(bContext *C, wmOperator *op)
loopofs = 0;
polyofs = 0;
- /* inverse transform for all selected meshes in this object */
- invert_m4_m4(imat, ob->obmat);
+ /* Inverse transform for all selected meshes in this object,
+ * See #object_join_exec for detailed comment on why the safe version is used. */
+ invert_m4_m4_safe_ortho(imat, ob->obmat);
/* Add back active mesh first.
* This allows to keep things similar as they were, as much as possible
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 916c26e7667..63bc7c4071c 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -2929,20 +2929,45 @@ static int join_exec(bContext *C, wmOperator *op)
}
}
+ int ret = OPERATOR_CANCELLED;
if (ob->type == OB_MESH) {
- return join_mesh_exec(C, op);
+ ret = join_mesh_exec(C, op);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
- return join_curve_exec(C, op);
+ ret = join_curve_exec(C, op);
}
else if (ob->type == OB_ARMATURE) {
- return join_armature_exec(C, op);
+ ret = join_armature_exec(C, op);
}
else if (ob->type == OB_GPENCIL) {
- return ED_gpencil_join_objects_exec(C, op);
- }
-
- return OPERATOR_CANCELLED;
+ 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)