[Bf-blender-cvs] [ab500eb] master: Hair edit: Add operator to uniform length of selected hairs

Sergey Sharybin noreply at git.blender.org
Tue Apr 26 16:08:07 CEST 2016


Commit: ab500eb3f343e90eff633a9afaf24aa8209a7847
Author: Sergey Sharybin
Date:   Tue Apr 26 16:05:52 2016 +0200
Branches: master
https://developer.blender.org/rBab500eb3f343e90eff633a9afaf24aa8209a7847

Hair edit: Add operator to uniform length of selected hairs

Request by Andy, should help him a lot doing weird and wonderful hair styles.

A bit experimental yet, details of behavior might be changed after some real
usage feedback.

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

M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/physics/particle_edit.c
M	source/blender/editors/physics/physics_intern.h
M	source/blender/editors/physics/physics_ops.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 8db6f81..374bc98 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1902,6 +1902,7 @@ class VIEW3D_MT_particle(Menu):
         if particle_edit.select_mode == 'POINT':
             layout.operator("particle.subdivide")
 
+        layout.operator("particle.unify_length")
         layout.operator("particle.rekey")
         layout.operator("particle.weight_set")
 
@@ -1921,6 +1922,7 @@ class VIEW3D_MT_particle_specials(Menu):
         layout.operator("particle.rekey")
         layout.operator("particle.delete")
         layout.operator("particle.remove_doubles")
+        layout.operator("particle.unify_length")
 
         if particle_edit.select_mode == 'POINT':
             layout.operator("particle.subdivide")
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 29824a3..d206886 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -4809,3 +4809,113 @@ void PARTICLE_OT_edited_clear(wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/************************ Unify length operator ************************/
+
+static float calculate_point_length(PTCacheEditPoint *point)
+{
+	float length = 0.0f;
+	KEY_K;
+	LOOP_KEYS {
+		if (k > 0) {
+			length += len_v3v3((key - 1)->co, key->co);;
+		}
+	}
+	return length;
+}
+
+static float calculate_average_length(PTCacheEdit *edit)
+{
+	int num_selected = 0;
+	float total_length = 0;
+	POINT_P;
+	LOOP_SELECTED_POINTS {
+		total_length += calculate_point_length(point);
+		++num_selected;
+	}
+	if (num_selected == 0) {
+		return 0.0f;
+	}
+	return total_length / num_selected;
+}
+
+static void scale_point_factor(PTCacheEditPoint *point, float factor)
+{
+	float orig_prev_co[3], prev_co[3];
+	KEY_K;
+	LOOP_KEYS {
+		if (k == 0) {
+			copy_v3_v3(orig_prev_co, key->co);
+			copy_v3_v3(prev_co, key->co);
+		}
+		else {
+			float new_co[3];
+			float delta[3];
+
+			sub_v3_v3v3(delta, key->co, orig_prev_co);
+			mul_v3_fl(delta, factor);
+			add_v3_v3v3(new_co, prev_co, delta);
+
+			copy_v3_v3(orig_prev_co, key->co);
+			copy_v3_v3(key->co, new_co);
+			copy_v3_v3(prev_co, key->co);
+		}
+	}
+	point->flag |= PEP_EDIT_RECALC;
+}
+
+static void scale_point_to_length(PTCacheEditPoint *point, float length)
+{
+	const float point_length = calculate_point_length(point);
+	if (point_length != 0.0f) {
+		const float factor = length / point_length;
+		scale_point_factor(point, factor);
+	}
+}
+
+static void scale_points_to_length(PTCacheEdit *edit, float length)
+{
+	POINT_P;
+	LOOP_SELECTED_POINTS {
+		scale_point_to_length(point, length);
+	}
+	recalc_lengths(edit);
+}
+
+static int unify_length_exec(bContext *C, wmOperator *UNUSED(op))
+{
+	Object *ob = CTX_data_active_object(C);
+	Scene *scene = CTX_data_scene(C);
+	PTCacheEdit *edit = PE_get_current(scene, ob);
+	float average_length = calculate_average_length(edit);
+	if (average_length == 0.0f) {
+		return OPERATOR_CANCELLED;
+	}
+	scale_points_to_length(edit, average_length);
+
+	PE_update_object(scene, ob, 1);
+	if (edit->psys) {
+		WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
+	}
+	else {
+		DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+		WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+	}
+
+	return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_unify_length(struct wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Unify Length";
+	ot->idname = "PARTICLE_OT_unify_length";
+	ot->description = "Make selected hair the same length";
+
+	/* api callbacks */
+	ot->exec = unify_length_exec;
+	ot->poll = PE_poll_view3d;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h
index 666ed23..361c058 100644
--- a/source/blender/editors/physics/physics_intern.h
+++ b/source/blender/editors/physics/physics_intern.h
@@ -61,6 +61,8 @@ void PARTICLE_OT_shape_cut(struct wmOperatorType *ot);
 void PARTICLE_OT_particle_edit_toggle(struct wmOperatorType *ot);
 void PARTICLE_OT_edited_clear(struct wmOperatorType *ot);
 
+void PARTICLE_OT_unify_length(struct wmOperatorType *ot);
+
 /* particle_object.c */
 void OBJECT_OT_particle_system_add(struct wmOperatorType *ot);
 void OBJECT_OT_particle_system_remove(struct wmOperatorType *ot);
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index c765bff..5074a41 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -69,6 +69,8 @@ static void operatortypes_particle(void)
 	WM_operatortype_append(PARTICLE_OT_particle_edit_toggle);
 	WM_operatortype_append(PARTICLE_OT_edited_clear);
 
+	WM_operatortype_append(PARTICLE_OT_unify_length);
+
 
 	WM_operatortype_append(OBJECT_OT_particle_system_add);
 	WM_operatortype_append(OBJECT_OT_particle_system_remove);




More information about the Bf-blender-cvs mailing list