Fix #30337: missed Set Origin for Metaball
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 26 Feb 2012 08:55:31 +0000 (08:55 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 26 Feb 2012 08:55:31 +0000 (08:55 +0000)
Implemented Set Origin operator for Meta Balls.

source/blender/blenkernel/BKE_mball.h
source/blender/blenkernel/intern/mball.c
source/blender/editors/object/object_transform.c

index e3b5a006edfff6c6305c736d3cb8c2185fc9a9a7..0bfbec9f1b946763d2673b5182884f87378a9887 100644 (file)
@@ -174,5 +174,10 @@ void *new_pgn_element(int size);
 int nextcwedge (int edge, int face);
 void BKE_freecubetable(void);
 
+int BKE_metaball_minmax(struct MetaBall *mb, float min[3], float max[3]);
+int BKE_metaball_center_median(struct MetaBall *mb, float cent[3]);
+int BKE_metaball_center_bounds(struct MetaBall *mb, float cent[3]);
+void BKE_metaball_translate(struct MetaBall *mb, float offset[3]);
+
 #endif
 
index 7f05aaed9b0475d5f895fe96c650722784fca660..2e8c026b75e9270d3e02f86eb03dd965c69b7852 100644 (file)
@@ -2282,3 +2282,55 @@ void metaball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
        freepolygonize(&mbproc);
 }
 
+/* basic vertex data functions */
+int BKE_metaball_minmax(MetaBall *mb, float min[3], float max[3])
+{
+       MetaElem *ml;
+
+       INIT_MINMAX(min, max);
+
+       for (ml = mb->elems.first; ml; ml = ml->next) {
+               DO_MINMAX(&ml->x, min, max);
+       }
+
+       return (mb->elems.first != NULL);
+}
+
+int BKE_metaball_center_median(MetaBall *mb, float cent[3])
+{
+       MetaElem *ml;
+       int total= 0;
+
+       zero_v3(cent);
+
+       for (ml = mb->elems.first; ml; ml = ml->next) {
+               add_v3_v3(cent, &ml->x);
+       }
+
+       if (total)
+               mul_v3_fl(cent, 1.0f/(float)total);
+
+       return (total != 0);
+}
+
+int BKE_metaball_center_bounds(MetaBall *mb, float cent[3])
+{
+       float min[3], max[3];
+
+       if (BKE_metaball_minmax(mb, min, max)) {
+               mid_v3_v3v3(cent, min, max);
+               return 1;
+       }
+
+       return 0;
+}
+
+void BKE_metaball_translate(MetaBall *mb, float offset[3])
+{
+       MetaElem *ml;
+       int i;
+
+       for (ml = mb->elems.first; ml; ml = ml->next) {
+               add_v3_v3(&ml->x, offset);
+       }
+}
index aac8ef4c5e3f67bb54c1a9f5e39c039788172156..45db21749a5fee58ea4ca6ca78467c863bcba016 100644 (file)
@@ -36,6 +36,7 @@
 #include "DNA_key_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_meta_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_group_types.h"
@@ -48,6 +49,7 @@
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_main.h"
+#include "BKE_mball.h"
 #include "BKE_mesh.h"
 #include "BKE_object.h"
 #include "BKE_report.h"
@@ -836,6 +838,27 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
                                                break;
                                }
                        }
+                       else if (ob->type == OB_MBALL) {
+                               MetaBall *mb = ob->data;
+
+                               if(centermode == ORIGIN_TO_CURSOR) { /* done */ }
+                               else if(around==V3D_CENTROID) { BKE_metaball_center_median(mb, cent); }
+                               else { BKE_metaball_center_bounds(mb, cent);    }
+
+                               negate_v3_v3(cent_neg, cent);
+                               BKE_metaball_translate(mb, cent_neg);
+
+                               tot_change++;
+                               mb->id.flag |= LIB_DOIT;
+                               do_inverse_offset= TRUE;
+
+                               if(obedit) {
+                                       if (centermode == GEOMETRY_TO_ORIGIN) {
+                                               DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+                                       }
+                                       break;
+                               }
+                       }
 
                        /* offset other selected objects */
                        if(do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {