Simulation: Add modifier to access simulation data

For now the "Simulation" modifier only exists for point cloud objects, because
we need this for the particle system. Right now, the modifier is doing nothing.

There is a new `DEG_add_simulation_relation` function that is used
by the modifier to make sure that the simulation is evaluated before
the modifier is executed.

Reviewers: brecht, sergey

Differential Revision: https://developer.blender.org/D7549
This commit is contained in:
Jacques Lucke 2020-05-13 12:39:17 +02:00
parent 23fd95458c
commit b55c78a289
21 changed files with 212 additions and 1 deletions

View File

@ -1826,6 +1826,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "thresh", text="Threshold")
col.prop(md, "face_influence")
def SIMULATION(self, layout, ob, md):
layout.prop(md, "simulation")
layout.prop(md, "data_path")
class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel):
bl_label = "Modifiers"

View File

@ -23,9 +23,12 @@ extern "C" {
struct Main;
struct Simulation;
struct Depsgraph;
void *BKE_simulation_add(struct Main *bmain, const char *name);
void BKE_simulation_data_update(struct Depsgraph *depsgraph, struct Scene *scene);
#ifdef __cplusplus
}
#endif

View File

@ -22,6 +22,7 @@
#include "DNA_ID.h"
#include "DNA_defaults.h"
#include "DNA_scene_types.h"
#include "DNA_simulation_types.h"
#include "BLI_compiler_compat.h"
@ -44,6 +45,8 @@
#include "BLT_translation.h"
#include "DEG_depsgraph.h"
static void simulation_init_data(ID *id)
{
Simulation *simulation = (Simulation *)id;
@ -108,3 +111,7 @@ IDTypeInfo IDType_ID_SIM = {
/* free_data */ simulation_free_data,
/* make_local */ nullptr,
};
void BKE_simulation_data_update(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene))
{
}

View File

@ -39,6 +39,7 @@ struct ID;
struct Main;
struct Object;
struct Scene;
struct Simulation;
struct ViewLayer;
struct bNodeTree;
@ -153,6 +154,9 @@ void DEG_add_object_relation(struct DepsNodeHandle *node_handle,
struct Object *object,
eDepsObjectComponentType component,
const char *description);
void DEG_add_simulation_relation(struct DepsNodeHandle *node_handle,
struct Simulation *simulation,
const char *description);
void DEG_add_bone_relation(struct DepsNodeHandle *handle,
struct Object *object,
const char *bone_name,

View File

@ -97,6 +97,7 @@
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_simulation.h"
#include "BKE_sound.h"
#include "BKE_tracking.h"
#include "BKE_volume.h"
@ -1753,6 +1754,11 @@ void DepsgraphNodeBuilder::build_simulation(Simulation *simulation)
add_id_node(&simulation->id);
build_animdata(&simulation->id);
build_parameters(&simulation->id);
add_operation_node(&simulation->id,
NodeType::SIMULATION,
OperationCode::SIMULATION_EVAL,
function_bind(BKE_simulation_data_update, _1, get_cow_datablock(scene_)));
}
void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)

View File

@ -2578,6 +2578,11 @@ void DepsgraphRelationBuilder::build_simulation(Simulation *simulation)
}
build_animdata(&simulation->id);
build_parameters(&simulation->id);
OperationKey simulation_update_key(
&simulation->id, NodeType::SIMULATION, OperationCode::SIMULATION_EVAL);
TimeSourceKey time_src_key;
add_relation(time_src_key, simulation_update_key, "TimeSrc -> Simulation");
}
void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)

View File

@ -439,7 +439,8 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, const Node *node)
case NodeType::SYNCHRONIZATION:
case NodeType::AUDIO:
case NodeType::ARMATURE:
case NodeType::GENERIC_DATABLOCK: {
case NodeType::GENERIC_DATABLOCK:
case NodeType::SIMULATION: {
ComponentNode *comp_node = (ComponentNode *)node;
if (!comp_node->operations.empty()) {
deg_debug_graphviz_node_cluster_begin(ctx, node);

View File

@ -34,6 +34,7 @@
#include "DNA_cachefile_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_simulation_types.h"
#include "BKE_main.h"
#include "BKE_scene.h"
@ -103,6 +104,16 @@ void DEG_add_object_relation(DepsNodeHandle *node_handle,
deg_node_handle->builder->add_node_handle_relation(comp_key, deg_node_handle, description);
}
void DEG_add_simulation_relation(DepsNodeHandle *node_handle,
Simulation *simulation,
const char *description)
{
DEG::OperationKey operation_key(
&simulation->id, DEG::NodeType::SIMULATION, DEG::OperationCode::SIMULATION_EVAL);
DEG::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
deg_node_handle->builder->add_node_handle_relation(operation_key, deg_node_handle, description);
}
void DEG_add_object_cache_relation(DepsNodeHandle *node_handle,
CacheFile *cache_file,
eDepsObjectComponentType component,

View File

@ -114,6 +114,8 @@ const char *nodeTypeAsString(NodeType type)
return "ARMATURE";
case NodeType::GENERIC_DATABLOCK:
return "GENERIC_DATABLOCK";
case NodeType::SIMULATION:
return "SIMULATION";
/* Total number of meaningful node types. */
case NodeType::NUM_TYPES:
@ -172,6 +174,7 @@ eDepsSceneComponentType nodeTypeToSceneComponent(NodeType type)
case NodeType::SHADING:
case NodeType::CACHE:
case NodeType::PROXY:
case NodeType::SIMULATION:
return DEG_SCENE_COMP_PARAMETERS;
}
BLI_assert(!"Unhandled node type, not suppsed to happen.");
@ -245,6 +248,7 @@ eDepsObjectComponentType nodeTypeToObjectComponent(NodeType type)
case NodeType::BATCH_CACHE:
case NodeType::DUPLI:
case NodeType::SYNCHRONIZATION:
case NodeType::SIMULATION:
case NodeType::UNDEFINED:
case NodeType::NUM_TYPES:
return DEG_OB_COMP_PARAMETERS;

View File

@ -127,6 +127,8 @@ enum class NodeType {
DUPLI,
/* Synchronization back to original datablock. */
SYNCHRONIZATION,
/* Simulation component. */
SIMULATION,
/* Total number of meaningful node types. */
NUM_TYPES,

View File

@ -333,6 +333,7 @@ DEG_COMPONENT_NODE_DEFINE(Synchronization, SYNCHRONIZATION, 0);
DEG_COMPONENT_NODE_DEFINE(Audio, AUDIO, 0);
DEG_COMPONENT_NODE_DEFINE(Armature, ARMATURE, 0);
DEG_COMPONENT_NODE_DEFINE(GenericDatablock, GENERIC_DATABLOCK, 0);
DEG_COMPONENT_NODE_DEFINE(Simulation, SIMULATION, 0);
/* Node Types Register =================================== */
@ -362,6 +363,7 @@ void deg_register_component_depsnodes()
register_node_typeinfo(&DNTI_AUDIO);
register_node_typeinfo(&DNTI_ARMATURE);
register_node_typeinfo(&DNTI_GENERIC_DATABLOCK);
register_node_typeinfo(&DNTI_SIMULATION);
}
} // namespace DEG

View File

@ -191,6 +191,7 @@ DEG_COMPONENT_NODE_DECLARE_GENERIC(Synchronization);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Audio);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Armature);
DEG_COMPONENT_NODE_DECLARE_GENERIC(GenericDatablock);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Simulation);
/* Bone Component */
struct BoneComponentNode : public ComponentNode {

View File

@ -194,6 +194,8 @@ const char *operationCodeAsString(OperationCode opcode)
/* instancing/duplication. */
case OperationCode::DUPLI:
return "DUPLI";
case OperationCode::SIMULATION_EVAL:
return "SIMULATION_EVAL";
}
BLI_assert(!"Unhandled operation code, should never happen.");
return "UNKNOWN";

View File

@ -198,6 +198,9 @@ enum class OperationCode {
/* Duplication/instancing system. --------------------------------------- */
DUPLI,
/* Simulation. ---------------------------------------------------------- */
SIMULATION_EVAL,
};
const char *operationCodeAsString(OperationCode opcode);

View File

@ -2191,6 +2191,9 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case eModifierType_WeightedNormal:
data.icon = ICON_MOD_NORMALEDIT;
break;
case eModifierType_Simulation:
data.icon = ICON_PHYSICS; /* TODO: Use correct icon. */
break;
/* Default */
case eModifierType_None:
case eModifierType_ShapeKey:

View File

@ -94,6 +94,7 @@ typedef enum ModifierType {
eModifierType_WeightedNormal = 54,
eModifierType_Weld = 55,
eModifierType_Fluid = 56,
eModifierType_Simulation = 57,
NUM_MODIFIER_TYPES,
} ModifierType;
@ -2118,6 +2119,13 @@ enum {
#define MOD_MESHSEQ_READ_ALL \
(MOD_MESHSEQ_READ_VERT | MOD_MESHSEQ_READ_POLY | MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)
typedef struct SimulationModifierData {
ModifierData modifier;
struct Simulation *simulation;
char data_path[64];
} SimulationModifierData;
#ifdef __cplusplus
}
#endif

View File

@ -289,6 +289,13 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
"Spawn particles from the shape"},
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
{eModifierType_Surface, "SURFACE", ICON_MODIFIER, "Surface", ""},
#ifdef WITH_NEW_SIMULATION_TYPE
{eModifierType_Simulation,
"SIMULATION",
ICON_PHYSICS,
"Simulation",
""}, /* TODO: Use correct icon. */
#endif
{0, NULL, 0, NULL, NULL},
};
@ -716,6 +723,8 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
return &RNA_SurfaceDeformModifier;
case eModifierType_WeightedNormal:
return &RNA_WeightedNormalModifier;
case eModifierType_Simulation:
return &RNA_SimulationModifier;
/* Default */
case eModifierType_Fluidsim: /* deprecated */
case eModifierType_None:
@ -6552,6 +6561,29 @@ static void rna_def_modifier_weightednormal(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_simulation_access(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "SimulationModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Simulation Modifier", "");
RNA_def_struct_sdna(srna, "SimulationModifierData");
RNA_def_struct_ui_icon(srna, ICON_PHYSICS); /* TODO: Use correct icon. */
# ifdef WITH_NEW_SIMULATION_TYPE
prop = RNA_def_property(srna, "simulation", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Simulation", "Simulation to access");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
# endif
prop = RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(
prop, "Data Path", "Identifier of the simulation component that should be accessed");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
void RNA_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@ -6677,6 +6709,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_meshseqcache(brna);
rna_def_modifier_surfacedeform(brna);
rna_def_modifier_weightednormal(brna);
rna_def_modifier_simulation_access(brna);
}
#endif

View File

@ -78,6 +78,7 @@ set(SRC
intern/MOD_shapekey.c
intern/MOD_shrinkwrap.c
intern/MOD_simpledeform.c
intern/MOD_simulation.cc
intern/MOD_skin.c
intern/MOD_smooth.c
intern/MOD_softbody.c

View File

@ -86,6 +86,7 @@ extern ModifierTypeInfo modifierType_CorrectiveSmooth;
extern ModifierTypeInfo modifierType_MeshSequenceCache;
extern ModifierTypeInfo modifierType_SurfaceDeform;
extern ModifierTypeInfo modifierType_WeightedNormal;
extern ModifierTypeInfo modifierType_Simulation;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);

View File

@ -0,0 +1,109 @@
/*
* 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.
*/
/** \file
* \ingroup modifiers
*/
#include <iostream>
#include <string>
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_simulation_types.h"
#include "BKE_customdata.h"
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
#include "MOD_modifiertypes.h"
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
SimulationModifierData *smd = (SimulationModifierData *)md;
if (smd->simulation) {
DEG_add_simulation_relation(ctx->node, smd->simulation, "Accessed Simulation");
}
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
SimulationModifierData *smd = (SimulationModifierData *)md;
walk(userData, ob, (ID **)&smd->simulation, IDWALK_CB_USER);
}
static bool isDisabled(const struct Scene *UNUSED(scene),
ModifierData *md,
bool UNUSED(useRenderParams))
{
SimulationModifierData *smd = (SimulationModifierData *)md;
return smd->simulation == nullptr;
}
static PointCloud *modifyPointCloud(ModifierData *md,
const ModifierEvalContext *UNUSED(ctx),
PointCloud *pointcloud)
{
SimulationModifierData *smd = (SimulationModifierData *)md;
UNUSED_VARS(smd);
return pointcloud;
}
ModifierTypeInfo modifierType_Simulation = {
/* name */ "Simulation",
/* structName */ "SimulationModifierData",
/* structSize */ sizeof(SimulationModifierData),
/* type */ eModifierTypeType_None,
/* flags */ (ModifierTypeFlag)0,
/* copyData */ BKE_modifier_copydata_generic,
/* deformVerts */ NULL,
/* deformMatrices */ NULL,
/* deformVertsEM */ NULL,
/* deformMatricesEM */ NULL,
/* modifyMesh */ NULL,
/* modifyHair */ NULL,
/* modifyPointCloud */ modifyPointCloud,
/* modifyVolume */ NULL,
/* initData */ NULL,
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
/* foreachObjectLink */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
};

View File

@ -337,5 +337,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(MeshSequenceCache);
INIT_TYPE(SurfaceDeform);
INIT_TYPE(WeightedNormal);
INIT_TYPE(Simulation);
#undef INIT_TYPE
}