[Bf-blender-cvs] [77802b21a68] strand_editmode: Operator for generating a hair follicle distribution.

Lukas Tönne noreply at git.blender.org
Mon Aug 7 13:29:50 CEST 2017


Commit: 77802b21a68e544feb92286de27e063cf09bfa12
Author: Lukas Tönne
Date:   Mon Aug 7 12:26:35 2017 +0100
Branches: strand_editmode
https://developer.blender.org/rB77802b21a68e544feb92286de27e063cf09bfa12

Operator for generating a hair follicle distribution.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenkernel/BKE_hair.h
M	source/blender/blenkernel/intern/hair.c
M	source/blender/editors/object/CMakeLists.txt
A	source/blender/editors/object/object_hair.c
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_ops.c
M	source/blender/makesdna/DNA_modifier_types.h

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 9f62bf89204..3bd7d434aeb 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1529,7 +1529,14 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
             layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind")
 
     def HAIR(self, layout, ob, md):
-        pass
+        hair = md.hair
+
+        col = layout.column()
+        col.label(text="Follicles:")
+        row = col.row(align = True)
+        row.enabled = False
+        row.prop(hair, "num_follicles")
+        col.operator("object.hair_follicles_generate", text="Generate")
 
 
 classes = (
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 0aa5d96231d..1f96cdcb81b 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -36,6 +36,7 @@
 
 struct HairFollicle;
 struct HairPattern;
+struct DerivedMesh;
 
 static const unsigned int STRAND_INDEX_NONE = 0xFFFFFFFF;
 
@@ -43,7 +44,8 @@ struct HairPattern* BKE_hair_new(void);
 struct HairPattern* BKE_hair_copy(struct HairPattern *hair);
 void BKE_hair_free(struct HairPattern *hair);
 
-void BKE_hair_set_num_follicles(struct HairPattern *hair, int num_follicles);
+void BKE_hair_set_num_follicles(struct HairPattern *hair, int count);
+void BKE_hair_follicles_generate(struct HairPattern *hair, struct DerivedMesh *scalp, int count, unsigned int seed);
 
 /* ================================= */
 
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 778c1460f77..fa8bf398cd7 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -73,12 +73,48 @@ void BKE_hair_free(struct HairPattern *hair)
 	MEM_freeN(hair);
 }
 
-void BKE_hair_set_num_follicles(HairPattern *hair, int num_follicles)
+void BKE_hair_set_num_follicles(HairPattern *hair, int count)
 {
-	if (hair->num_follicles != num_follicles) {
-		hair->follicles = MEM_reallocN_id(hair->follicles, sizeof(HairFollicle) * num_follicles, "hair follicles");
-		hair->num_follicles = num_follicles;
+	if (hair->num_follicles != count) {
+		if (count > 0) {
+			if (hair->follicles) {
+				hair->follicles = MEM_reallocN_id(hair->follicles, sizeof(HairFollicle) * count, "hair follicles");
+			}
+			else {
+				hair->follicles = MEM_callocN(sizeof(HairFollicle) * count, "hair follicles");
+			}
+		}
+		else {
+			if (hair->follicles) {
+				MEM_freeN(hair->follicles);
+				hair->follicles = NULL;
+			}
+		}
+		hair->num_follicles = count;
+	}
+}
+
+void BKE_hair_follicles_generate(HairPattern *hair, DerivedMesh *scalp, int count, unsigned int seed)
+{
+	BKE_hair_set_num_follicles(hair, count);
+	if (count == 0) {
+		return;
 	}
+	
+	MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_random(scalp, seed);
+	unsigned int i;
+	
+	HairFollicle *foll = hair->follicles;
+	for (i = 0; i < count; ++i, ++foll) {
+		bool ok = BKE_mesh_sample_generate(gen, &foll->mesh_sample);
+		if (!ok) {
+			/* clear remaining samples */
+			memset(foll, 0, sizeof(HairFollicle) * (count - i));
+			break;
+		}
+	}
+	
+	BKE_mesh_sample_free_generator(gen);
 }
 
 /* ================================= */
@@ -284,7 +320,7 @@ HairFiber* BKE_hair_fibers_create(const StrandsView *strands,
 		}
 		else {
 			/* clear remaining samples */
-			memset(fiber, 0, sizeof(HairFiber) * amount - i);
+			memset(fiber, 0, sizeof(HairFiber) * (amount - i));
 			break;
 		}
 	}
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index 8050508983b..69c897359e6 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -49,6 +49,7 @@ set(SRC
 	object_edit.c
 	object_facemap_ops.c
 	object_group.c
+	object_hair.c
 	object_hook.c
 	object_lattice.c
 	object_lod.c
diff --git a/source/blender/editors/object/object_hair.c b/source/blender/editors/object/object_hair.c
new file mode 100644
index 00000000000..6e4f1cfe9f0
--- /dev/null
+++ b/source/blender/editors/object/object_hair.c
@@ -0,0 +1,115 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/object_hair.c
+ *  \ingroup edobj
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "DNA_hair_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "BKE_context.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_hair.h"
+#include "DEG_depsgraph.h"
+
+#include "ED_object.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "object_intern.h"
+
+/************************ Hair Follicle Generation Operator *********************/
+
+static int hair_follicles_generate_poll(bContext *C)
+{
+	return edit_modifier_poll_generic(C, &RNA_HairModifier, 0);
+}
+
+static int hair_follicles_generate_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene = CTX_data_scene(C);
+	Object *ob = ED_object_active_context(C);
+	HairModifierData *hmd = (HairModifierData *)edit_modifier_property_get(op, ob, eModifierType_Hair);
+	
+	if (!hmd)
+		return OPERATOR_CANCELLED;
+	
+	CustomDataMask mask = CD_MASK_BAREMESH;
+	DerivedMesh *scalp = mesh_get_derived_final(scene, ob, mask);
+	if (!scalp)
+		return OPERATOR_CANCELLED;
+	
+	int count = RNA_int_get(op->ptr, "count");
+	unsigned int seed = RNA_int_get(op->ptr, "seed");
+	
+	BKE_hair_follicles_generate(hmd->hair, scalp, count, seed);
+	
+	DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+	return OPERATOR_FINISHED;
+}
+
+static int hair_follicles_generate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+	if (edit_modifier_invoke_properties(C, op)) {
+		return WM_operator_props_popup_confirm(C, op, event);
+	}
+	else {
+		return OPERATOR_CANCELLED;
+	}
+}
+
+void OBJECT_OT_hair_follicles_generate(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Generate Hair Follicles";
+	ot->description = "Generate hair follicle data";
+	ot->idname = "OBJECT_OT_hair_follicles_generate";
+	
+	/* api callbacks */
+	ot->poll = hair_follicles_generate_poll;
+	ot->invoke = hair_follicles_generate_invoke;
+	ot->exec = hair_follicles_generate_exec;
+	
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+	
+	edit_modifier_properties(ot);
+	RNA_def_int(ot->srna, "count", 1000, 0, INT_MAX, "Count", "Number of hair follicles to generate", 1, 1000000);
+	RNA_def_int(ot->srna, "seed", 0, 0, INT_MAX, "Seed", "Seed value for randomization", 0, INT_MAX);
+}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index f6fb3cc75b8..00a94928749 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -285,5 +285,8 @@ void TRANSFORM_OT_vertex_random(struct wmOperatorType *ot);
 void OBJECT_OT_data_transfer(struct wmOperatorType *ot);
 void OBJECT_OT_datalayout_transfer(struct wmOperatorType *ot);
 
+/* object_hair.c */
+void OBJECT_OT_hair_follicles_generate(struct wmOperatorType *ot);
+
 #endif /* __OBJECT_INTERN_H__ */
 
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index ca02457ba39..7204ed820ce 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -259,6 +259,8 @@ 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_hair_follicles_generate);
 }
 
 void ED_operatormacros_object(void)
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index ef5f9df2298..6d5f7b39cb5 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1626,7 +1626,6 @@ typedef struct HairModifierData {
 	struct HairPattern *hair;
 	
 	struct BMEditStrands *edit;         /* edit data (runtime) */
-	
 } HairModifierData;
 
 #endif  /* __DNA_MODIFIER_TYPES_H__ */




More information about the Bf-blender-cvs mailing list