[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