[Bf-blender-cvs] [2d241893698] hair_guides: Extend the fur generate modifier to also create guide curves.
Lukas Tönne
noreply at git.blender.org
Thu Nov 23 21:29:31 CET 2017
Commit: 2d24189369815aff49c61c01faac3fe83d68d167
Author: Lukas Tönne
Date: Thu Nov 23 20:29:08 2017 +0000
Branches: hair_guides
https://developer.blender.org/rB2d24189369815aff49c61c01faac3fe83d68d167
Extend the fur generate modifier to also create guide curves.
===================================================================
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/object_modifier.c
M source/blender/makesdna/DNA_modifier_types.h
M source/blender/makesrna/intern/rna_modifier.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 81338efc807..1fcd69983d0 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1550,9 +1550,17 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
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")
col = split.column()
+ col.label("Guide Curves:")
+ col.prop(md, "guides_count")
+
+ col = layout.column()
+ col.operator("object.fur_generate_follicles", text="Generate")
+
+ col.separator()
+
+ col = layout.column()
col.label("Drawing:")
ds = md.draw_settings
col.prop(ds, "follicle_mode", expand=True)
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 48200a68dfb..4d57f7e5462 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -62,10 +62,16 @@ void BKE_hair_guide_curves_end(struct HairSystem *hsys);
/* Calculate surface area of a scalp mesh */
float BKE_hair_calc_surface_area(struct DerivedMesh *scalp);
-/* Calculate a density value based on surface area and count */
+
+/* Calculate a density value based on surface area and sample count */
float BKE_hair_calc_density_from_count(float area, int count);
+/* Calculate maximum sample count based on surface area and density */
+int BKE_hair_calc_max_count_from_density(float area, float density);
+
/* Calculate a density value based on a minimum distance */
float BKE_hair_calc_density_from_min_distance(float min_distance);
+/* Calculate a minimum distance based on density */
+float BKE_hair_calc_min_distance_from_density(float density);
/* Distribute hair follicles on a scalp mesh */
void BKE_hair_generate_follicles(
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 3df3a430a73..3785759eb57 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -71,6 +71,15 @@ HairSystem* BKE_hair_copy(HairSystem *hsys)
nhsys->pattern->follicles = MEM_dupallocN(hsys->pattern->follicles);
}
+ if (hsys->curves)
+ {
+ nhsys->curves = MEM_dupallocN(hsys->curves);
+ }
+ if (hsys->verts)
+ {
+ nhsys->verts = MEM_dupallocN(hsys->verts);
+ }
+
nhsys->draw_batch_cache = NULL;
nhsys->draw_texture_cache = NULL;
@@ -81,6 +90,15 @@ void BKE_hair_free(HairSystem *hsys)
{
BKE_hair_batch_cache_free(hsys);
+ if (hsys->curves)
+ {
+ MEM_freeN(hsys->curves);
+ }
+ if (hsys->verts)
+ {
+ MEM_freeN(hsys->verts);
+ }
+
if (hsys->pattern)
{
if (hsys->pattern->follicles)
@@ -111,12 +129,18 @@ float BKE_hair_calc_surface_area(struct DerivedMesh *scalp)
return area;
}
-/* Calculate a density value based on surface area and count */
+/* Calculate a density value based on surface area and sample count */
float BKE_hair_calc_density_from_count(float area, int count)
{
return area > 0.0f ? count / area : 0.0f;
}
+/* Calculate maximum sample count based on surface area and density */
+int BKE_hair_calc_max_count_from_density(float area, float density)
+{
+ return (int)(density * area);
+}
+
/* Calculate a density value based on a minimum distance */
float BKE_hair_calc_density_from_min_distance(float min_distance)
{
@@ -126,6 +150,15 @@ float BKE_hair_calc_density_from_min_distance(float min_distance)
return min_distance > 0.0f ? max_factor / (min_distance * min_distance) : 0.0f;
}
+/* Calculate a minimum distance based on density */
+float BKE_hair_calc_min_distance_from_density(float density)
+{
+ // max. circle packing density (sans pi factor): 1 / (2 * sqrt(3))
+ static const float max_factor = 0.288675135;
+
+ return density > 0.0f ? sqrt(max_factor / density) : 0.0f;
+}
+
/* Distribute hair follicles on a scalp mesh */
void BKE_hair_generate_follicles(
HairSystem* hsys,
@@ -174,13 +207,15 @@ void BKE_hair_guide_curves_begin(HairSystem *hsys, int totcurves, int totverts)
if (totcurves != hsys->totcurves)
{
hsys->curves = MEM_reallocN(hsys->curves, sizeof(HairGuideCurve) * totcurves);
+ hsys->totcurves = totcurves;
hsys->flag |= HAIR_SYSTEM_UPDATE_GUIDE_VERT_OFFSET | HAIR_SYSTEM_UPDATE_FOLLICLE_BINDING;
BKE_hair_batch_cache_dirty(hsys, BKE_HAIR_BATCH_DIRTY_ALL);
}
if (totverts != hsys->totverts)
{
- hsys->verts = MEM_reallocN(hsys->curves, sizeof(HairGuideCurve) * totverts);
+ hsys->verts = MEM_reallocN(hsys->verts, sizeof(HairGuideVertex) * totverts);
+ hsys->totverts = totverts;
BKE_hair_batch_cache_dirty(hsys, BKE_HAIR_BATCH_DIRTY_ALL);
}
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 934120730bd..63226828853 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -64,6 +64,7 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_sample.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_report.h"
@@ -2374,6 +2375,50 @@ void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
/************************ Fur follicle generate operator *********************/
+static void fur_create_guide_curves(struct HairSystem *hsys, unsigned int seed, DerivedMesh *scalp, int count)
+{
+ float area = BKE_hair_calc_surface_area(scalp);
+ float density = BKE_hair_calc_density_from_count(area, count);
+ float min_distance = BKE_hair_calc_min_distance_from_density(density);
+ MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_poissondisk(seed, min_distance, count, NULL, NULL);
+
+ BKE_mesh_sample_generator_bind(gen, scalp);
+
+ {
+ MeshSample *buffer = MEM_mallocN(sizeof(MeshSample) * count, "mesh sample buffer");
+ int totguides = BKE_mesh_sample_generate_batch(gen, buffer, count);
+ int totverts = 2 * totguides; // TODO
+
+ BKE_hair_guide_curves_begin(hsys, totguides, totverts);
+
+ MeshSample *sample = buffer;
+ int vertstart = 0;
+ for (int i = 0; i < totguides; ++i, ++sample)
+ {
+ int numverts = 2; // TODO
+
+ BKE_hair_set_guide_curve(hsys, i, sample, numverts);
+
+ float co[3], nor[3], tang[3];
+ BKE_mesh_sample_eval(scalp, sample, co, nor, tang);
+ BKE_hair_set_guide_vertex(hsys, vertstart, 0, co);
+
+ madd_v3_v3fl(co, nor, 0.1f);
+ BKE_hair_set_guide_vertex(hsys, vertstart + 1, 0, co);
+
+ vertstart += numverts;
+ }
+
+ BKE_hair_guide_curves_end(hsys);
+
+ MEM_freeN(buffer);
+ }
+
+ BKE_mesh_sample_free_generator(gen);
+
+ BKE_hair_bind_follicles(hsys, scalp);
+}
+
static int fur_generate_follicles_poll(bContext *C)
{
return edit_modifier_poll_generic(C, &RNA_FurModifier, 0);
@@ -2403,6 +2448,15 @@ static int fur_generate_follicles_exec(bContext *C, wmOperator *op)
fmd->follicle_min_distance,
fmd->follicle_max_count);
+ {
+ unsigned int guides_seed = fmd->follicle_seed ^ 0xFFFF;
+ fur_create_guide_curves(
+ fmd->hair_system,
+ guides_seed,
+ dm,
+ fmd->guides_count);
+ }
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 38270f47445..ebb5d5e0351 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1641,7 +1641,8 @@ typedef struct FurModifierData {
int follicle_seed;
float follicle_min_distance;
int follicle_max_count;
- int pad2;
+
+ int guides_count;
} 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 43480f0d8f6..ae818c56e4b 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4826,6 +4826,12 @@ static void rna_def_modifier_fur(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 1e5, 1, 1);
RNA_def_property_ui_text(prop, "Max Count", "Maximum follicle number");
+ prop = RNA_def_property(srna, "guides_count", PROP_INT, PROP_NONE);
+ RNA_def_property_int_default(prop, 100);
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 1e3, 1, 1);
+ RNA_def_property_ui_text(prop, "Guides Count", "Number of guide curves");
+
prop = RNA_def_property(srna, "draw_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Draw Settings", "Hair draw settings");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
More information about the Bf-blender-cvs
mailing list