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/blenkernel/intern/object_dupli.cc')
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc100
1 files changed, 86 insertions, 14 deletions
diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc
index e28aaabb4e1..15a4a0bbb32 100644
--- a/source/blender/blenkernel/intern/object_dupli.cc
+++ b/source/blender/blenkernel/intern/object_dupli.cc
@@ -24,8 +24,10 @@
#include "DNA_anim_types.h"
#include "DNA_collection_types.h"
+#include "DNA_curves_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
@@ -44,6 +46,7 @@
#include "BKE_mesh.h"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
@@ -53,13 +56,15 @@
#include "DEG_depsgraph_query.h"
#include "BLI_hash.h"
-#include "BLI_strict_flags.h"
+
+#include "NOD_geometry_nodes_log.hh"
using blender::Array;
using blender::float3;
using blender::float4x4;
using blender::Span;
using blender::Vector;
+namespace geo_log = blender::nodes::geo_eval_log;
/* -------------------------------------------------------------------- */
/** \name Internal Duplicate Context
@@ -75,6 +80,15 @@ struct DupliContext {
Scene *scene;
Object *object;
float space_mat[4][4];
+ /**
+ * Index of the top-level instance that contains this context or -1 when unused.
+ * This is an index into the instances component of #preview_base_geometry.
+ */
+ int preview_instance_index;
+ /**
+ * Top level geometry set that is previewed.
+ */
+ const GeometrySet *preview_base_geometry;
/**
* A stack that contains all the "parent" objects of a particular instance when recursive
@@ -127,6 +141,8 @@ static void init_context(DupliContext *r_ctx,
r_ctx->gen = get_dupli_generator(r_ctx);
r_ctx->duplilist = nullptr;
+ r_ctx->preview_instance_index = -1;
+ r_ctx->preview_base_geometry = nullptr;
}
/**
@@ -139,7 +155,7 @@ static bool copy_dupli_context(
/* XXX annoying, previously was done by passing an ID* argument,
* this at least is more explicit. */
- if (ctx->gen->type == OB_DUPLICOLLECTION) {
+ if (ctx->gen && ctx->gen->type == OB_DUPLICOLLECTION) {
r_ctx->collection = ctx->object->instance_collection;
}
@@ -183,7 +199,9 @@ static DupliObject *make_dupli(
dob->ob = ob;
dob->ob_data = const_cast<ID *>(object_data);
mul_m4_m4m4(dob->mat, (float(*)[4])ctx->space_mat, mat);
- dob->type = ctx->gen->type;
+ dob->type = ctx->gen == nullptr ? 0 : ctx->gen->type;
+ dob->preview_base_geometry = ctx->preview_base_geometry;
+ dob->preview_instance_index = ctx->preview_instance_index;
/* Set persistent id, which is an array with a persistent index for each level
* (particle number, vertex number, ..). by comparing this we can find the same
@@ -780,7 +798,8 @@ static const DupliGenerator gen_dupli_verts_font = {
static void make_duplis_geometry_set_impl(const DupliContext *ctx,
const GeometrySet &geometry_set,
const float parent_transform[4][4],
- bool geometry_set_is_instance)
+ bool geometry_set_is_instance,
+ bool use_new_curves_type)
{
int component_index = 0;
if (ctx->object->type != OB_MESH || geometry_set_is_instance) {
@@ -795,8 +814,15 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
}
if (!ELEM(ctx->object->type, OB_CURVES_LEGACY, OB_FONT, OB_CURVES) || geometry_set_is_instance) {
if (const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>()) {
- if (const Curve *curve = component->get_curve_for_render()) {
- make_dupli(ctx, ctx->object, &curve->id, parent_transform, component_index++);
+ if (use_new_curves_type) {
+ if (const Curves *curves = component->get_for_read()) {
+ make_dupli(ctx, ctx->object, &curves->id, parent_transform, component_index++);
+ }
+ }
+ else {
+ if (const Curve *curve = component->get_curve_for_render()) {
+ make_dupli(ctx, ctx->object, &curve->id, parent_transform, component_index++);
+ }
}
}
}
@@ -832,17 +858,26 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
const InstanceReference &reference = references[instance_reference_handles[i]];
const int id = almost_unique_ids[i];
+ const DupliContext *ctx_for_instance = instances_ctx;
+ /* Set the #preview_instance_index when necessary. */
+ DupliContext tmp_ctx_for_instance;
+ if (instances_ctx->preview_base_geometry == &geometry_set) {
+ tmp_ctx_for_instance = *instances_ctx;
+ tmp_ctx_for_instance.preview_instance_index = i;
+ ctx_for_instance = &tmp_ctx_for_instance;
+ }
+
switch (reference.type()) {
case InstanceReference::Type::Object: {
Object &object = reference.object();
float matrix[4][4];
mul_m4_m4m4(matrix, parent_transform, instance_offset_matrices[i].values);
- make_dupli(instances_ctx, &object, matrix, id);
+ make_dupli(ctx_for_instance, &object, matrix, id);
float space_matrix[4][4];
mul_m4_m4m4(space_matrix, instance_offset_matrices[i].values, object.imat);
mul_m4_m4_pre(space_matrix, parent_transform);
- make_recursive_duplis(instances_ctx, &object, space_matrix, id);
+ make_recursive_duplis(ctx_for_instance, &object, space_matrix, id);
break;
}
case InstanceReference::Type::Collection: {
@@ -854,14 +889,15 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
mul_m4_m4_pre(collection_matrix, parent_transform);
DupliContext sub_ctx;
- if (!copy_dupli_context(&sub_ctx, instances_ctx, instances_ctx->object, nullptr, id)) {
+ if (!copy_dupli_context(
+ &sub_ctx, ctx_for_instance, ctx_for_instance->object, nullptr, id)) {
break;
}
- eEvaluationMode mode = DEG_get_mode(instances_ctx->depsgraph);
+ eEvaluationMode mode = DEG_get_mode(ctx_for_instance->depsgraph);
int object_id = 0;
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (&collection, object, mode) {
- if (object == instances_ctx->object) {
+ if (object == ctx_for_instance->object) {
continue;
}
@@ -879,8 +915,10 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
mul_m4_m4m4(new_transform, parent_transform, instance_offset_matrices[i].values);
DupliContext sub_ctx;
- if (copy_dupli_context(&sub_ctx, instances_ctx, instances_ctx->object, nullptr, id)) {
- make_duplis_geometry_set_impl(&sub_ctx, reference.geometry_set(), new_transform, true);
+ if (copy_dupli_context(
+ &sub_ctx, ctx_for_instance, ctx_for_instance->object, nullptr, id)) {
+ make_duplis_geometry_set_impl(
+ &sub_ctx, reference.geometry_set(), new_transform, true, false);
}
break;
}
@@ -894,7 +932,7 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
static void make_duplis_geometry_set(const DupliContext *ctx)
{
const GeometrySet *geometry_set = ctx->object->runtime.geometry_set_eval;
- make_duplis_geometry_set_impl(ctx, *geometry_set, ctx->object->obmat, false);
+ make_duplis_geometry_set_impl(ctx, *geometry_set, ctx->object->obmat, false, false);
}
static const DupliGenerator gen_dupli_geometry_set = {
@@ -1632,6 +1670,40 @@ ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
return duplilist;
}
+ListBase *object_duplilist_preview(Depsgraph *depsgraph,
+ Scene *sce,
+ Object *ob_eval,
+ const ViewerPath *viewer_path)
+{
+ ListBase *duplilist = MEM_cnew<ListBase>("duplilist");
+ DupliContext ctx;
+ Vector<Object *> instance_stack;
+ instance_stack.append(ob_eval);
+ init_context(&ctx, depsgraph, sce, ob_eval, nullptr, instance_stack);
+ ctx.duplilist = duplilist;
+
+ Object *ob_orig = DEG_get_original_object(ob_eval);
+
+ LISTBASE_FOREACH (ModifierData *, md_orig, &ob_orig->modifiers) {
+ if (md_orig->type != eModifierType_Nodes) {
+ continue;
+ }
+ NodesModifierData *nmd_orig = reinterpret_cast<NodesModifierData *>(md_orig);
+ if (nmd_orig->runtime_eval_log == nullptr) {
+ continue;
+ }
+ geo_log::GeoModifierLog *log = static_cast<geo_log::GeoModifierLog *>(
+ nmd_orig->runtime_eval_log);
+ if (const geo_log::ViewerNodeLog *viewer_log = log->find_viewer_node_log_for_path(
+ *viewer_path)) {
+ ctx.preview_base_geometry = &viewer_log->geometry;
+ make_duplis_geometry_set_impl(
+ &ctx, viewer_log->geometry, ob_eval->obmat, true, ob_eval->type == OB_CURVES);
+ }
+ }
+ return duplilist;
+}
+
void free_object_duplilist(ListBase *lb)
{
BLI_freelistN(lb);