[Bf-blender-cvs] [d3ba86de07d] blender2.8: Manipulator: Add b-bone spline editing

Campbell Barton noreply at git.blender.org
Tue Aug 15 09:37:11 CEST 2017


Commit: d3ba86de07debf9f85a954d845038b09847d8057
Author: Campbell Barton
Date:   Tue Aug 15 17:24:38 2017 +1000
Branches: blender2.8
https://developer.blender.org/rBd3ba86de07debf9f85a954d845038b09847d8057

Manipulator: Add b-bone spline editing

This needs some improvements since
matching handles *exactly* is a bit involved.

===================================================================

M	source/blender/editors/space_view3d/CMakeLists.txt
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/editors/space_view3d/view3d_intern.h
A	source/blender/editors/space_view3d/view3d_manipulator_armature.c

===================================================================

diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 5e04c8e10cb..db79d578b5d 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -59,6 +59,7 @@ set(SRC
 	view3d_walk.c
 	view3d_header.c
 	view3d_iterators.c
+	view3d_manipulator_armature.c
 	view3d_manipulator_camera.c
 	view3d_manipulator_empty.c
 	view3d_manipulator_forcefield.c
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 3d9d40deda1..3456d761b5b 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -742,6 +742,7 @@ static void view3d_widgets(void)
 	WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera);
 	WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera_view);
 	WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_empty_image);
+	WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_armature_spline);
 }
 
 
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 85f04518635..1f27e3b1519 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -326,6 +326,7 @@ void VIEW3D_WGT_camera(struct wmManipulatorGroupType *wgt);
 void VIEW3D_WGT_camera_view(struct wmManipulatorGroupType *wgt);
 void VIEW3D_WGT_force_field(struct wmManipulatorGroupType *wgt);
 void VIEW3D_WGT_empty_image(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_armature_spline(struct wmManipulatorGroupType *wgt);
 
 /* draw_volume.c */
 void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_armature.c b/source/blender/editors/space_view3d/view3d_manipulator_armature.c
new file mode 100644
index 00000000000..94136eb6eeb
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_armature.c
@@ -0,0 +1,220 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_armature.c
+ *  \ingroup spview3d
+ */
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "BKE_context.h"
+#include "BKE_object.h"
+
+#include "DNA_object_types.h"
+#include "DNA_armature_types.h"
+
+#include "ED_armature.h"
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h"  /* own include */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Armature Spline Manipulator
+ *
+ * \{ */
+
+/*
+ * TODO(campbell): Current conversion is a approximation (usable not correct),
+ * we'll need to take the next/previous bones into account to get the tangent directions.
+ * First last matrices from 'b_bone_spline_setup' are close but also not quite accurate
+ * since they're not at either end-points on the curve.
+ *
+ * Likely we'll need a function especially to get the first/last orientations.
+ */
+
+#define BBONE_SCALE_Y 3.0f
+
+struct BoneSplineHandle {
+	wmManipulator *manipulator;
+	bPoseChannel *pchan;
+	/* We could remove, keep since at the moment for checking the conversion. */
+	float co[3];
+	int index;
+};
+
+struct BoneSplineWidgetGroup {
+	struct BoneSplineHandle handles[2];
+};
+
+static void manipulator_bbone_offset_get(
+        const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+        void *value_p)
+{
+	struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data;
+	bPoseChannel *pchan = bh->pchan;
+
+	float *value = value_p;
+	BLI_assert(mpr_prop->type->array_length == 3);
+
+	if (bh->index == 0) {
+		bh->co[1] = pchan->bone->ease1 / BBONE_SCALE_Y;
+		bh->co[0] = pchan->curveInX;
+		bh->co[2] = pchan->curveInY;
+	}
+	else {
+		bh->co[1] = -pchan->bone->ease2 / BBONE_SCALE_Y;
+		bh->co[0] = pchan->curveOutX;
+		bh->co[2] = pchan->curveOutY;
+	}
+	copy_v3_v3(value, bh->co);
+}
+
+static void manipulator_bbone_offset_set(
+        const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+        const void *value_p)
+{
+	struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data;
+	bPoseChannel *pchan = bh->pchan;
+
+	const float *value = value_p;
+
+	BLI_assert(mpr_prop->type->array_length == 3);
+	copy_v3_v3(bh->co, value);
+
+	if (bh->index == 0) {
+		pchan->bone->ease1 = max_ff(0.0f, bh->co[1] * BBONE_SCALE_Y);
+		pchan->bone->curveInX = bh->co[0];
+		pchan->bone->curveInY = bh->co[2];
+	}
+	else {
+		pchan->bone->ease2 = max_ff(0.0f, -bh->co[1] * BBONE_SCALE_Y);
+		pchan->bone->curveOutX = bh->co[0];
+		pchan->bone->curveOutY = bh->co[2];
+	}
+
+}
+
+static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+	Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+	if (ob != NULL) {
+		const bArmature *arm = ob->data;
+		if (arm->drawtype == ARM_B_BONE) {
+			if (arm->act_bone && arm->act_bone->segments > 1) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+
+static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmManipulatorGroup *mgroup)
+{
+	Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+	bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+	const wmManipulatorType *wt_grab = WM_manipulatortype_find("MANIPULATOR_WT_grab_3d", true);
+
+	struct BoneSplineWidgetGroup *bspline_group = MEM_callocN(sizeof(struct BoneSplineWidgetGroup), __func__);
+	mgroup->customdata = bspline_group;
+
+	/* Handles */
+	for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
+		wmManipulator *mpr;
+		mpr = bspline_group->handles[i].manipulator = WM_manipulator_new_ptr(wt_grab, mgroup, NULL);
+		RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING_2D);
+		RNA_enum_set(mpr->ptr, "draw_options",
+		             ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL | ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW);
+		WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_VALUE, true);
+
+		UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+		UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+
+		mpr->scale_basis = 0.06f;
+
+		if (i == 0) {
+			copy_v3_v3(mpr->matrix_basis[3], pchan->loc);
+		}
+	}
+}
+
+static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+	Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+
+	if (!mgroup->customdata)
+		return;
+
+	struct BoneSplineWidgetGroup *bspline_group = mgroup->customdata;
+	bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+	/* Handles */
+	for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
+		wmManipulator *mpr = bspline_group->handles[i].manipulator;
+		bspline_group->handles[i].pchan = pchan;
+		bspline_group->handles[i].index = i;
+
+		float mat[4][4];
+		mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
+		copy_m4_m4(mpr->matrix_space, mat);
+
+		/* need to set property here for undo. TODO would prefer to do this in _init */
+		WM_manipulator_target_property_def_func(
+		        mpr, "offset",
+		        &(const struct wmManipulatorPropertyFnParams) {
+		            .value_get_fn = manipulator_bbone_offset_get,
+		            .value_set_fn = manipulator_bbone_offset_set,
+		            .range_get_fn = NULL,
+		            .user_data = &bspline_group->handles[i],
+		        });
+	}
+}
+
+void VIEW3D_WGT_armature_spline(wmManipulatorGroupType *wgt)
+{
+	wgt->name = "Armature Spline Widgets";
+	wgt->idname = "VIEW3D_WGT_armature_spline";
+
+	wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+	             WM_MANIPULATORGROUPTYPE_3D);
+
+	wgt->poll = WIDGETGROUP_armature_spline_poll;
+	wgt->setup = WIDGETGROUP_armature_spline_setup;
+	wgt->refresh = WIDGETGROUP_armature_spline_refresh;
+}
+
+/** \} */




More information about the Bf-blender-cvs mailing list