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/modifiers')
-rw-r--r--source/blender/modifiers/CMakeLists.txt10
-rw-r--r--source/blender/modifiers/MOD_modifiertypes.h4
-rw-r--r--source/blender/modifiers/intern/MOD_bparticles.c227
-rw-r--r--source/blender/modifiers/intern/MOD_bparticles.h10
-rw-r--r--source/blender/modifiers/intern/MOD_bparticles_output.c134
-rw-r--r--source/blender/modifiers/intern/MOD_functiondeform.c128
-rw-r--r--source/blender/modifiers/intern/MOD_functiondeform_cxx.cc82
-rw-r--r--source/blender/modifiers/intern/MOD_functionpoints.c113
-rw-r--r--source/blender/modifiers/intern/MOD_functionpoints_cxx.cc80
-rw-r--r--source/blender/modifiers/intern/MOD_util.c4
10 files changed, 792 insertions, 0 deletions
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 48acbdc17f3..30961e4e029 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -26,6 +26,8 @@ set(INC
../blenlib
../bmesh
../depsgraph
+ ../functions
+ ../simulations
../makesdna
../makesrna
../render/extern/include
@@ -42,6 +44,8 @@ set(SRC
intern/MOD_array.c
intern/MOD_bevel.c
intern/MOD_boolean.c
+ intern/MOD_bparticles.c
+ intern/MOD_bparticles_output.c
intern/MOD_build.c
intern/MOD_cast.c
intern/MOD_cloth.c
@@ -55,6 +59,10 @@ set(SRC
intern/MOD_edgesplit.c
intern/MOD_explode.c
intern/MOD_fluid.c
+ intern/MOD_functiondeform_cxx.cc
+ intern/MOD_functiondeform.c
+ intern/MOD_functionpoints_cxx.cc
+ intern/MOD_functionpoints.c
intern/MOD_hook.c
intern/MOD_laplaciandeform.c
intern/MOD_laplaciansmooth.c
@@ -111,6 +119,8 @@ set(SRC
set(LIB
bf_blenkernel
bf_blenlib
+ bf_functions
+ bf_simulations
)
if(WITH_ALEMBIC)
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index 5dc4adf4393..e881b0e12bf 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -86,6 +86,10 @@ extern ModifierTypeInfo modifierType_CorrectiveSmooth;
extern ModifierTypeInfo modifierType_MeshSequenceCache;
extern ModifierTypeInfo modifierType_SurfaceDeform;
extern ModifierTypeInfo modifierType_WeightedNormal;
+extern ModifierTypeInfo modifierType_FunctionDeform;
+extern ModifierTypeInfo modifierType_FunctionPoints;
+extern ModifierTypeInfo modifierType_BParticles;
+extern ModifierTypeInfo modifierType_BParticlesOutput;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);
diff --git a/source/blender/modifiers/intern/MOD_bparticles.c b/source/blender/modifiers/intern/MOD_bparticles.c
new file mode 100644
index 00000000000..6ef04684593
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_bparticles.c
@@ -0,0 +1,227 @@
+/*
+ * ***** 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) 2019 by the Blender Foundation.
+ * All rights reserved.
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_bparticles.c
+ * \ingroup modifiers
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_lib_query.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_scene.h"
+
+#include "BLI_math.h"
+
+#include "MOD_bparticles.h"
+#include "MOD_util.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+typedef struct RuntimeData {
+ BParticlesSimulationState simulation_state;
+ float last_simulated_frame;
+} RuntimeData;
+
+static RuntimeData *get_or_create_runtime_struct(BParticlesModifierData *bpmd)
+{
+ if (bpmd->modifier.runtime == NULL) {
+ RuntimeData *runtime = MEM_callocN(sizeof(RuntimeData), __func__);
+ runtime->simulation_state = NULL;
+ runtime->last_simulated_frame = 0.0f;
+ bpmd->modifier.runtime = runtime;
+ }
+
+ return bpmd->modifier.runtime;
+}
+
+static RuntimeData *get_runtime_struct(BParticlesModifierData *bpmd)
+{
+ return bpmd->modifier.runtime;
+}
+
+static void free_runtime_data(RuntimeData *runtime)
+{
+ BParticles_simulation_free(runtime->simulation_state);
+ MEM_freeN(runtime);
+}
+
+static void free_modifier_runtime_data(BParticlesModifierData *bpmd)
+{
+ RuntimeData *runtime = (RuntimeData *)bpmd->modifier.runtime;
+ if (runtime != NULL) {
+ free_runtime_data(runtime);
+ bpmd->modifier.runtime = NULL;
+ }
+}
+
+BParticlesSimulationState MOD_bparticles_find_simulation_state(Object *object)
+{
+ BLI_assert(object != NULL);
+ BParticlesModifierData *bpmd = (BParticlesModifierData *)modifiers_findByType(
+ object, eModifierType_BParticles);
+ if (bpmd == NULL) {
+ return NULL;
+ }
+ RuntimeData *runtime = get_runtime_struct(bpmd);
+ if (runtime == NULL) {
+ return NULL;
+ }
+ return runtime->simulation_state;
+}
+
+static Mesh *applyModifier(ModifierData *md, const struct ModifierEvalContext *ctx, Mesh *mesh)
+{
+ BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+ BParticlesModifierData *bpmd_orig = (BParticlesModifierData *)modifier_get_original(
+ &bpmd->modifier);
+
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ float current_frame = BKE_scene_frame_get(scene);
+
+ RuntimeData *runtime = get_or_create_runtime_struct(bpmd);
+
+ if (runtime->simulation_state == NULL) {
+ runtime->simulation_state = BParticles_new_simulation();
+ }
+
+ if (current_frame == runtime->last_simulated_frame) {
+ /* do nothing */
+ }
+ else if (current_frame == runtime->last_simulated_frame + 1.0f) {
+ BParticles_simulate_modifier(bpmd, ctx->depsgraph, runtime->simulation_state, 1.0f / FPS);
+ runtime->last_simulated_frame = current_frame;
+ }
+ else {
+ free_modifier_runtime_data(bpmd);
+ runtime = get_or_create_runtime_struct(bpmd);
+ runtime->simulation_state = BParticles_new_simulation();
+ runtime->last_simulated_frame = current_frame;
+ BParticles_modifier_free_cache(bpmd_orig);
+
+ BParticles_simulate_modifier(bpmd, ctx->depsgraph, runtime->simulation_state, 0.0f);
+ runtime->last_simulated_frame = current_frame;
+ }
+
+ if (bpmd->output_type == MOD_BPARTICLES_OUTPUT_POINTS) {
+ return BParticles_modifier_point_mesh_from_state(runtime->simulation_state);
+ }
+ else if (bpmd->output_type == MOD_BPARTICLES_OUTPUT_TETRAHEDONS) {
+ Mesh *new_mesh = BParticles_modifier_mesh_from_state(runtime->simulation_state);
+ BKE_mesh_copy_settings(new_mesh, mesh);
+ return new_mesh;
+ }
+ else {
+ return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+ }
+}
+
+static void initData(ModifierData *UNUSED(md))
+{
+}
+
+static void freeData(ModifierData *md)
+{
+ BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+ free_modifier_runtime_data(bpmd);
+ BParticles_modifier_free_cache(bpmd);
+}
+
+static void copyData(const ModifierData *md, ModifierData *target, const int flag)
+{
+ BParticlesModifierData *tbpmd = (BParticlesModifierData *)target;
+
+ modifier_copyData_generic(md, target, flag);
+ tbpmd->num_cached_frames = 0;
+ tbpmd->cached_frames = NULL;
+}
+
+static void freeRuntimeData(void *runtime_data_v)
+{
+ if (runtime_data_v == NULL) {
+ return;
+ }
+ RuntimeData *runtime = (RuntimeData *)runtime_data_v;
+ free_runtime_data(runtime);
+}
+
+static bool dependsOnTime(ModifierData *UNUSED(md))
+{
+ return true;
+}
+
+static void updateDepsgraph(ModifierData *UNUSED(md),
+ const ModifierUpdateDepsgraphContext *UNUSED(ctx))
+{
+}
+
+static void foreachObjectLink(ModifierData *UNUSED(md),
+ Object *UNUSED(ob),
+ ObjectWalkFunc UNUSED(walk),
+ void *UNUSED(userData))
+{
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+ walk(userData, ob, (ID **)&bpmd->node_tree, IDWALK_CB_NOP);
+
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+}
+
+ModifierTypeInfo modifierType_BParticles = {
+ /* name */ "BParticles",
+ /* structName */ "BParticlesModifierData",
+ /* structSize */ sizeof(BParticlesModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh,
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ freeRuntimeData,
+};
diff --git a/source/blender/modifiers/intern/MOD_bparticles.h b/source/blender/modifiers/intern/MOD_bparticles.h
new file mode 100644
index 00000000000..c0d31b85f6b
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_bparticles.h
@@ -0,0 +1,10 @@
+#include "BParticles.h"
+
+#ifndef __MOD_BPARTICLES_H__
+# define __MOD_BPARTICLES_H__
+
+struct Object;
+
+BParticlesSimulationState MOD_bparticles_find_simulation_state(struct Object *object);
+
+#endif /* __MOD_BPARTICLES_H__ */
diff --git a/source/blender/modifiers/intern/MOD_bparticles_output.c b/source/blender/modifiers/intern/MOD_bparticles_output.c
new file mode 100644
index 00000000000..0482a17feac
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_bparticles_output.c
@@ -0,0 +1,134 @@
+/*
+ * ***** 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) 2019 by the Blender Foundation.
+ * All rights reserved.
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_bparticles_output.c
+ * \ingroup modifiers
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_lib_query.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_scene.h"
+
+#include "BLI_math.h"
+
+#include "MOD_bparticles.h"
+#include "MOD_util.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "BParticles.h"
+
+static Mesh *applyModifier(ModifierData *md,
+ const struct ModifierEvalContext *UNUSED(ctx),
+ Mesh *mesh)
+{
+ BParticlesOutputModifierData *bpmd = (BParticlesOutputModifierData *)md;
+ if (bpmd->source_object == NULL) {
+ return mesh;
+ }
+
+ BParticlesSimulationState simulation_state = MOD_bparticles_find_simulation_state(
+ bpmd->source_object);
+ if (simulation_state == NULL) {
+ return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+ }
+
+ if (bpmd->output_type == MOD_BPARTICLES_OUTPUT_TETRAHEDONS) {
+ Mesh *new_mesh = BParticles_state_extract_type__tetrahedons(simulation_state,
+ bpmd->source_particle_system);
+ BKE_mesh_copy_settings(new_mesh, mesh);
+ return new_mesh;
+ }
+ else if (bpmd->output_type == MOD_BPARTICLES_OUTPUT_POINTS) {
+ return BParticles_state_extract_type__points(simulation_state, bpmd->source_particle_system);
+ }
+ else {
+ return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+ }
+}
+
+static void initData(ModifierData *UNUSED(md))
+{
+}
+
+static void freeData(ModifierData *UNUSED(md))
+{
+}
+
+static void copyData(const ModifierData *md, ModifierData *target, const int flag)
+{
+ modifier_copyData_generic(md, target, flag);
+}
+
+static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
+{
+ BParticlesOutputModifierData *bpmd = (BParticlesOutputModifierData *)md;
+ if (bpmd->source_object) {
+ DEG_add_object_relation(
+ ctx->node, bpmd->source_object, DEG_OB_COMP_GEOMETRY, "BParticles Output Modifier");
+ }
+}
+
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+{
+ BParticlesOutputModifierData *bpmd = (BParticlesOutputModifierData *)md;
+ walk(userData, ob, &bpmd->source_object, IDWALK_CB_NOP);
+}
+
+ModifierTypeInfo modifierType_BParticlesOutput = {
+ /* name */ "BParticles Output",
+ /* structName */ "BParticlesOutputModifierData",
+ /* structSize */ sizeof(BParticlesOutputModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh,
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_functiondeform.c b/source/blender/modifiers/intern/MOD_functiondeform.c
new file mode 100644
index 00000000000..ec746a4f73d
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_functiondeform.c
@@ -0,0 +1,128 @@
+/*
+ * ***** 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) 2005 by the Blender Foundation.
+ * All rights reserved.
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_functiondeform.c
+ * \ingroup modifiers
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_lib_query.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_scene.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "MOD_util.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+#include "time.h"
+
+void MOD_functiondeform_do(FunctionDeformModifierData *fdmd,
+ float (*vertexCos)[3],
+ int numVerts,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh);
+
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
+{
+ MOD_functiondeform_do((FunctionDeformModifierData *)md, vertexCos, numVerts, ctx, mesh);
+}
+
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *UNUSED(em),
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
+{
+ MOD_functiondeform_do((FunctionDeformModifierData *)md, vertexCos, numVerts, ctx, mesh);
+}
+
+static void initData(ModifierData *md)
+{
+ FunctionDeformModifierData *fdmd = (FunctionDeformModifierData *)md;
+ fdmd->control1 = 1.0f;
+ fdmd->control2 = 0;
+}
+
+static bool dependsOnTime(ModifierData *UNUSED(md))
+{
+ return true;
+}
+
+static void updateDepsgraph(ModifierData *UNUSED(md),
+ const ModifierUpdateDepsgraphContext *UNUSED(ctx))
+{
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ FunctionDeformModifierData *fdmd = (FunctionDeformModifierData *)md;
+
+ walk(userData, ob, (ID **)&fdmd->function_tree, IDWALK_CB_USER);
+}
+
+ModifierTypeInfo modifierType_FunctionDeform = {
+ /* name */ "Function Deform",
+ /* structName */ "FunctionDeformModifierData",
+ /* structSize */ sizeof(FunctionDeformModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc b/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc
new file mode 100644
index 00000000000..579cc5eec35
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc
@@ -0,0 +1,82 @@
+#include "DNA_modifier_types.h"
+
+#include "FN_multi_function_common_contexts.h"
+#include "FN_multi_function_dependencies.h"
+#include "FN_multi_functions.h"
+#include "FN_node_tree_multi_function_network_generation.h"
+
+#include "BKE_id_data_cache.h"
+#include "BKE_modifier.h"
+
+#include "DEG_depsgraph_query.h"
+
+using BKE::VNode;
+using BLI::ArrayRef;
+using BLI::float3;
+using BLI::IndexRange;
+using BLI::Vector;
+using FN::FunctionTree;
+using FN::MFContext;
+using FN::MFContextBuilder;
+using FN::MFInputSocket;
+using FN::MFOutputSocket;
+using FN::MFParamsBuilder;
+
+extern "C" {
+void MOD_functiondeform_do(FunctionDeformModifierData *fdmd,
+ float (*vertexCos)[3],
+ int numVerts,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh);
+}
+
+void MOD_functiondeform_do(FunctionDeformModifierData *fdmd,
+ float (*vertexCos)[3],
+ int numVerts,
+ const ModifierEvalContext *ctx,
+ Mesh *UNUSED(mesh))
+{
+ if (fdmd->function_tree == nullptr) {
+ return;
+ }
+
+ bNodeTree *btree = (bNodeTree *)DEG_get_original_id((ID *)fdmd->function_tree);
+
+ FN::BTreeVTreeMap vtrees;
+ FunctionTree function_tree(btree, vtrees);
+
+ BLI::ResourceCollector resources;
+ auto function = FN::MFGeneration::generate_node_tree_multi_function(function_tree, resources);
+
+ MFParamsBuilder params_builder(*function, numVerts);
+ params_builder.add_readonly_single_input(ArrayRef<float3>((float3 *)vertexCos, numVerts));
+ params_builder.add_readonly_single_input(&fdmd->control1);
+ params_builder.add_readonly_single_input(&fdmd->control2);
+
+ Vector<float3> output_vectors(numVerts);
+ params_builder.add_single_output<float3>(output_vectors);
+
+ float current_time = DEG_get_ctime(ctx->depsgraph);
+
+ FN::SceneTimeContext time_context;
+ time_context.time = current_time;
+
+ FN::VertexPositionArray vertex_positions_context;
+ vertex_positions_context.positions = ArrayRef<float3>((float3 *)vertexCos, numVerts);
+
+ BKE::IDHandleLookup id_handle_lookup;
+ FN::add_ids_used_by_nodes(id_handle_lookup, function_tree);
+
+ BKE::IDDataCache id_data_cache;
+
+ MFContextBuilder context_builder;
+ context_builder.add_global_context(id_handle_lookup);
+ context_builder.add_global_context(time_context);
+ context_builder.add_global_context(id_data_cache);
+ context_builder.add_element_context(vertex_positions_context,
+ FN::MFElementContextIndices::FromDirectMapping());
+
+ function->call(IndexRange(numVerts), params_builder, context_builder);
+
+ memcpy(vertexCos, output_vectors.begin(), output_vectors.size() * sizeof(float3));
+}
diff --git a/source/blender/modifiers/intern/MOD_functionpoints.c b/source/blender/modifiers/intern/MOD_functionpoints.c
new file mode 100644
index 00000000000..f61e8be373d
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_functionpoints.c
@@ -0,0 +1,113 @@
+/*
+ * ***** 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) 2005 by the Blender Foundation.
+ * All rights reserved.
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_functiondeform.c
+ * \ingroup modifiers
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_lib_query.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_scene.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "MOD_util.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+#include "time.h"
+
+Mesh *MOD_functionpoints_do(FunctionPointsModifierData *fpmd,
+ const struct ModifierEvalContext *ctx);
+
+static Mesh *applyModifier(ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct Mesh *UNUSED(mesh))
+{
+ return MOD_functionpoints_do((FunctionPointsModifierData *)md, ctx);
+}
+
+static void initData(ModifierData *md)
+{
+ FunctionPointsModifierData *fpmd = (FunctionPointsModifierData *)md;
+ fpmd->control1 = 1.0f;
+ fpmd->control2 = 0;
+}
+
+static bool dependsOnTime(ModifierData *UNUSED(md))
+{
+ return true;
+}
+
+static void updateDepsgraph(ModifierData *UNUSED(md),
+ const ModifierUpdateDepsgraphContext *UNUSED(ctx))
+{
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ FunctionPointsModifierData *fpmd = (FunctionPointsModifierData *)md;
+
+ walk(userData, ob, (ID **)&fpmd->function_tree, IDWALK_CB_USER);
+}
+
+ModifierTypeInfo modifierType_FunctionPoints = {
+ /* name */ "Function Points",
+ /* structName */ "FunctionPointsModifierData",
+ /* structSize */ sizeof(FunctionPointsModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh,
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_functionpoints_cxx.cc b/source/blender/modifiers/intern/MOD_functionpoints_cxx.cc
new file mode 100644
index 00000000000..087a2f46b5d
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_functionpoints_cxx.cc
@@ -0,0 +1,80 @@
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+
+#include "BKE_id_data_cache.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+
+#include "BLI_math.h"
+
+#include "FN_multi_function_common_contexts.h"
+#include "FN_multi_function_dependencies.h"
+#include "FN_multi_functions.h"
+#include "FN_node_tree_multi_function_network_generation.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+using BKE::VNode;
+using BLI::ArrayRef;
+using BLI::float3;
+using BLI::IndexRange;
+using BLI::Vector;
+using FN::FunctionTree;
+using FN::MFContext;
+using FN::MFInputSocket;
+using FN::MFOutputSocket;
+using FN::MFParamsBuilder;
+
+extern "C" {
+Mesh *MOD_functionpoints_do(FunctionPointsModifierData *fpmd,
+ const struct ModifierEvalContext *ctx);
+}
+
+Mesh *MOD_functionpoints_do(FunctionPointsModifierData *fpmd,
+ const struct ModifierEvalContext *ctx)
+{
+ if (fpmd->function_tree == nullptr) {
+ return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+ }
+
+ bNodeTree *btree = (bNodeTree *)DEG_get_original_id((ID *)fpmd->function_tree);
+
+ FN::BTreeVTreeMap vtrees;
+ FunctionTree function_tree(btree, vtrees);
+
+ BLI::ResourceCollector resources;
+ auto function = FN::MFGeneration::generate_node_tree_multi_function(function_tree, resources);
+
+ MFParamsBuilder params_builder(*function, 1);
+ params_builder.add_readonly_single_input(&fpmd->control1);
+ params_builder.add_readonly_single_input(&fpmd->control2);
+
+ FN::GenericVectorArray vector_array{FN::CPPType_float3, 1};
+ params_builder.add_vector_output(vector_array);
+
+ FN::SceneTimeContext time_context;
+ time_context.time = DEG_get_ctime(ctx->depsgraph);
+
+ BKE::IDHandleLookup id_handle_lookup;
+ FN::add_ids_used_by_nodes(id_handle_lookup, function_tree);
+
+ BKE::IDDataCache id_data_cache;
+
+ FN::MFContextBuilder context_builder;
+ context_builder.add_global_context(id_handle_lookup);
+ context_builder.add_global_context(time_context);
+ context_builder.add_global_context(id_data_cache);
+
+ function->call(BLI::IndexMask(1), params_builder, context_builder);
+
+ ArrayRef<float3> output_points = vector_array[0].as_typed_ref<float3>();
+
+ Mesh *mesh = BKE_mesh_new_nomain(output_points.size(), 0, 0, 0, 0);
+ for (uint i = 0; i < output_points.size(); i++) {
+ copy_v3_v3(mesh->mvert[i].co, output_points[i]);
+ }
+
+ return mesh;
+}
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index f6b7c829c13..21680e77654 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -337,5 +337,9 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(MeshSequenceCache);
INIT_TYPE(SurfaceDeform);
INIT_TYPE(WeightedNormal);
+ INIT_TYPE(FunctionDeform);
+ INIT_TYPE(FunctionPoints);
+ INIT_TYPE(BParticles);
+ INIT_TYPE(BParticlesOutput);
#undef INIT_TYPE
}