[Bf-blender-cvs] [c8ef6904d12] hair_guides: Operator for generating hair follicles of the fur modifier.

Lukas Tönne noreply at git.blender.org
Fri Nov 17 10:30:40 CET 2017


Commit: c8ef6904d12d70e19f357e5d3bbfd1d5ba1f96f4
Author: Lukas Tönne
Date:   Fri Nov 17 09:30:22 2017 +0000
Branches: hair_guides
https://developer.blender.org/rBc8ef6904d12d70e19f357e5d3bbfd1d5ba1f96f4

Operator for generating hair follicles of the fur modifier.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_modifier.c
M	source/blender/editors/object/object_ops.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_fur.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 429aa1df67f..02e3b8a10c8 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1543,7 +1543,14 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
             layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind")
 
     def FUR(self, layout, ob, md):
-        pass
+        split = layout.split()
+
+        col = split.column()
+        col.label("Follicles:")
+        col.prop(md, "follicle_seed")
+        col.prop(md, "follicle_min_distance")
+        col.prop(md, "follicle_max_count")
+        col.operator("object.fur_generate_follicles", text="Generate")
 
 
 classes = (
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 3e655fa04a4..4946804d31f 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -184,6 +184,7 @@ void OBJECT_OT_skin_radii_equalize(struct wmOperatorType *ot);
 void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot);
 void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot);
 void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot);
+void OBJECT_OT_fur_generate_follicles(struct wmOperatorType *ot);
 
 /* object_constraint.c */
 void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index a498e8a1564..934120730bd 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -58,6 +58,7 @@
 #include "BKE_DerivedMesh.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
+#include "BKE_hair.h"
 #include "BKE_key.h"
 #include "BKE_lattice.h"
 #include "BKE_main.h"
@@ -2370,3 +2371,65 @@ void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
 	edit_modifier_properties(ot);
 }
+
+/************************ Fur follicle generate operator *********************/
+
+static int fur_generate_follicles_poll(bContext *C)
+{
+	return edit_modifier_poll_generic(C, &RNA_FurModifier, 0);
+}
+
+static int fur_generate_follicles_exec(bContext *C, wmOperator *op)
+{
+	Object *ob = ED_object_active_context(C);
+	FurModifierData *fmd = (FurModifierData *)edit_modifier_property_get(op, ob, eModifierType_Fur);
+
+	if (!fmd)
+		return OPERATOR_CANCELLED;
+
+	BLI_assert(fmd->hair_system != NULL);
+	
+	struct Scene *scene = CTX_data_scene(C);
+	EvaluationContext eval_ctx;
+	CTX_data_eval_ctx(C, &eval_ctx);
+	
+	CustomDataMask datamask = CD_MASK_BAREMESH;
+	DerivedMesh *dm = mesh_get_derived_final(&eval_ctx, scene, ob, datamask);
+	
+	BKE_hair_generate_follicles(
+	            fmd->hair_system,
+	            dm,
+	            (unsigned int)fmd->follicle_seed,
+	            fmd->follicle_min_distance,
+	            fmd->follicle_max_count);
+
+	DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+static int fur_generate_follicles_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+	if (edit_modifier_invoke_properties(C, op))
+		return fur_generate_follicles_exec(C, op);
+	else
+		return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_fur_generate_follicles(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Fur Follicles Generate";
+	ot->description = "Generate hair follicles for a fur modifier";
+	ot->idname = "OBJECT_OT_fur_generate_follicles";
+
+	/* api callbacks */
+	ot->poll = fur_generate_follicles_poll;
+	ot->invoke = fur_generate_follicles_invoke;
+	ot->exec = fur_generate_follicles_exec;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+	edit_modifier_properties(ot);
+}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 07922f2d3b2..af724508a7a 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -260,6 +260,7 @@ void ED_operatortypes_object(void)
 	WM_operatortype_append(OBJECT_OT_data_transfer);
 	WM_operatortype_append(OBJECT_OT_datalayout_transfer);
 	WM_operatortype_append(OBJECT_OT_surfacedeform_bind);
+	WM_operatortype_append(OBJECT_OT_fur_generate_follicles);
 }
 
 void ED_operatormacros_object(void)
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 8f8e0e9bfae..b7ecf4e9daa 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1635,6 +1635,12 @@ typedef struct FurModifierData {
 	int pad;
 	
 	struct HairSystem *hair_system;
+	
+	/* Follicle distribution parameters */
+	int follicle_seed;
+	float follicle_min_distance;
+	int follicle_max_count;
+	int pad2;
 } FurModifierData;
 
 #endif  /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 597359a7d60..e9e412d4c83 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4800,15 +4800,31 @@ static void rna_def_modifier_fur(BlenderRNA *brna)
 {
 	StructRNA *srna;
 	PropertyRNA *prop;
-
+	
 	srna = RNA_def_struct(brna, "FurModifier", "Modifier");
 	RNA_def_struct_ui_text(srna, "Fur Modifier", "");
 	RNA_def_struct_sdna(srna, "FurModifierData");
 	RNA_def_struct_ui_icon(srna, ICON_STRANDS);
-
+	
 	prop = RNA_def_property(srna, "hair_system", PROP_POINTER, PROP_NONE);
 	RNA_def_property_ui_text(prop, "Hair", "Hair data");
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	
+	prop = RNA_def_property(srna, "follicle_seed", PROP_INT, PROP_NONE);
+	RNA_def_property_range(prop, 0, INT_MAX);
+	RNA_def_property_ui_text(prop, "Seed", "Follicle distribution random seed value");
+	
+	prop = RNA_def_property(srna, "follicle_min_distance", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_default(prop, 0.001f);
+	RNA_def_property_range(prop, 0.0f, FLT_MAX);
+	RNA_def_property_ui_range(prop, 1.0e-5f, 1.0f, 1.0e-4f, 5);
+	RNA_def_property_ui_text(prop, "Min Distance", "Minimum follicle distance");
+	
+	prop = RNA_def_property(srna, "follicle_max_count", PROP_INT, PROP_NONE);
+	RNA_def_property_int_default(prop, 1000);
+	RNA_def_property_range(prop, 0, INT_MAX);
+	RNA_def_property_ui_range(prop, 1, 1e5, 1, 1);
+	RNA_def_property_ui_text(prop, "Max Count", "Maximum follicle number");
 }
 
 void RNA_def_modifier(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_fur.c b/source/blender/modifiers/intern/MOD_fur.c
index 752e47176f1..3546e752177 100644
--- a/source/blender/modifiers/intern/MOD_fur.c
+++ b/source/blender/modifiers/intern/MOD_fur.c
@@ -57,6 +57,9 @@ static void initData(ModifierData *md)
 	fmd->hair_system = BKE_hair_new();
 	
 	fmd->flag |= 0;
+	
+	fmd->follicle_min_distance = 0.001f;
+	fmd->follicle_max_count = 1000;
 }
 
 static void copyData(ModifierData *md, ModifierData *target)



More information about the Bf-blender-cvs mailing list