diff options
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 26 | ||||
-rw-r--r-- | source/blender/editors/object/object_transform.c | 7 |
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", ""); } - |