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:
authorSergej Reich <sergej.reich@googlemail.com>2012-10-20 20:48:54 +0400
committerSergej Reich <sergej.reich@googlemail.com>2012-10-20 20:48:54 +0400
commit0a590aadf5655175f73af5b59e61acfb0fe0b144 (patch)
tree337b9aa216d33a1c4f84d1d5d3364ca927309753 /source/blender
parentd20128bbbcae252e9b39af14246dfcc6534dc0d6 (diff)
Add option to set object origin to the center of mass
This uses the weighted average of polygon centroids based on area It work well in most cases but will be slightly wrong when polygons have many vertices.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_mesh.h1
-rw-r--r--source/blender/blenkernel/intern/mesh.c26
-rw-r--r--source/blender/editors/object/object_transform.c7
3 files changed, 32 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 9fffb71785b..2f889084d0e 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -292,6 +292,7 @@ void create_vert_edge_map(MeshElemMap **map, int **mem,
int BKE_mesh_minmax(struct Mesh *me, float r_min[3], float r_max[3]);
int BKE_mesh_center_median(struct Mesh *me, float cent[3]);
int BKE_mesh_center_bounds(struct Mesh *me, float cent[3]);
+int BKE_mesh_center_centroid(struct Mesh *me, float cent[3]);
void BKE_mesh_translate(struct Mesh *me, float offset[3], int do_keys);
/* mesh_validate.c */
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index c244317ccb7..30eaf461430 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -3175,6 +3175,32 @@ int BKE_mesh_center_bounds(Mesh *me, float cent[3])
return 0;
}
+int BKE_mesh_center_centroid(Mesh *me, float cent[3])
+{
+ int i = me->totpoly;
+ MPoly *mpoly;
+ float poly_area;
+ float total_area = 0.0f;
+ float poly_cent[3];
+
+ zero_v3(cent);
+
+ /* calculate a weighted average of polygon centroids */
+ for (mpoly = me->mpoly; i--; mpoly++) {
+ BKE_mesh_calc_poly_center(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
+ poly_area = BKE_mesh_calc_poly_area(mpoly, me->mloop + mpoly->loopstart, me->mvert, NULL);
+
+ madd_v3_v3fl(cent, poly_cent, poly_area);
+ total_area += poly_area;
+ }
+ /* otherwise we get NAN for 0 polys */
+ if (me->totpoly) {
+ mul_v3_fl(cent, 1.0f / total_area);
+ }
+
+ return (me->totpoly != 0);
+}
+
void BKE_mesh_translate(Mesh *me, float offset[3], int do_keys)
{
int i = me->totvert;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 4c95884a51a..9bf1bbfa102 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -654,7 +654,8 @@ void OBJECT_OT_transform_apply(wmOperatorType *ot)
enum {
GEOMETRY_TO_ORIGIN = 0,
ORIGIN_TO_GEOMETRY,
- ORIGIN_TO_CURSOR
+ ORIGIN_TO_CURSOR,
+ ORIGIN_TO_CENTER_OF_MASS
};
static int object_origin_set_exec(bContext *C, wmOperator *op)
@@ -785,6 +786,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
Mesh *me = ob->data;
if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
+ else if (centermode == ORIGIN_TO_CENTER_OF_MASS) { BKE_mesh_center_centroid(me, cent); }
else if (around == V3D_CENTROID) { BKE_mesh_center_median(me, cent); }
else { BKE_mesh_center_bounds(me, cent); }
@@ -980,6 +982,8 @@ void OBJECT_OT_origin_set(wmOperatorType *ot)
"Move object origin to center of object geometry"},
{ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor",
"Move object origin to position of the 3D cursor"},
+ {ORIGIN_TO_CENTER_OF_MASS, "ORIGIN_CENTER_OF_MASS", 0, "Origin to Center of Mass",
+ "Move object origin to the object center of mass (assuming uniform density)"},
{0, NULL, 0, NULL, NULL}
};
@@ -1006,4 +1010,3 @@ void OBJECT_OT_origin_set(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_set_center_types, 0, "Type", "");
RNA_def_enum(ot->srna, "center", prop_set_bounds_types, V3D_CENTROID, "Center", "");
}
-