Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/object/object_modifier.c')
-rw-r--r--source/blender/editors/object/object_modifier.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 04243660440..5458e4c173f 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -58,11 +58,13 @@
#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"
#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"
@@ -2369,3 +2371,122 @@ void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(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);
+
+ {
+ BKE_hair_guide_curves_begin(hsys, totguides);
+
+ MeshSample *sample = buffer;
+ for (int i = 0; i < totguides; ++i, ++sample)
+ {
+ BKE_hair_set_guide_curve(hsys, i, sample, 2);
+ }
+
+ BKE_hair_guide_curves_end(hsys);
+ }
+
+ {
+ int vertstart = 0;
+ MeshSample *sample = buffer;
+ for (int i = 0; i < totguides; ++i, ++sample)
+ {
+ 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 += 2;
+ }
+ }
+
+ 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);
+}
+
+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_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);
+
+ 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);
+}