Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/object_dupli.cc
| Show First 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | struct DupliContext { | ||||
| /** | /** | ||||
| * A stack that contains all the "parent" objects of a particular instance when recursive | * A stack that contains all the "parent" objects of a particular instance when recursive | ||||
| * instancing is used. This is used to prevent objects from instancing themselves accidentally. | * instancing is used. This is used to prevent objects from instancing themselves accidentally. | ||||
| * Use a vector instead of a stack because we want to use the #contains method. | * Use a vector instead of a stack because we want to use the #contains method. | ||||
| */ | */ | ||||
| Vector<Object *> *instance_stack; | Vector<Object *> *instance_stack; | ||||
| /** | |||||
| * Older code relies on the "dupli generator type" for various visibility or processing | |||||
| * decisions. However, new code uses geometry instances in places that weren't using the dupli | |||||
| * system previously. To fix this, keep track of the last dupli generator type that wasn't a | |||||
| * geometry set instance. | |||||
| * */ | |||||
| Vector<short> *dupli_gen_type_stack; | |||||
| int persistent_id[MAX_DUPLI_RECUR]; | int persistent_id[MAX_DUPLI_RECUR]; | ||||
| int64_t instance_idx[MAX_DUPLI_RECUR]; | int64_t instance_idx[MAX_DUPLI_RECUR]; | ||||
| const GeometrySet *instance_data[MAX_DUPLI_RECUR]; | const GeometrySet *instance_data[MAX_DUPLI_RECUR]; | ||||
| int level; | int level; | ||||
| const struct DupliGenerator *gen; | const struct DupliGenerator *gen; | ||||
| /** Result containers. */ | /** Result containers. */ | ||||
| Show All 10 Lines | |||||
| /** | /** | ||||
| * Create initial context for root object. | * Create initial context for root object. | ||||
| */ | */ | ||||
| static void init_context(DupliContext *r_ctx, | static void init_context(DupliContext *r_ctx, | ||||
| Depsgraph *depsgraph, | Depsgraph *depsgraph, | ||||
| Scene *scene, | Scene *scene, | ||||
| Object *ob, | Object *ob, | ||||
| const float space_mat[4][4], | const float space_mat[4][4], | ||||
| Vector<Object *> &instance_stack) | Vector<Object *> &instance_stack, | ||||
| Vector<short> &dupli_gen_type_stack) | |||||
| { | { | ||||
| r_ctx->depsgraph = depsgraph; | r_ctx->depsgraph = depsgraph; | ||||
| r_ctx->scene = scene; | r_ctx->scene = scene; | ||||
| r_ctx->collection = nullptr; | r_ctx->collection = nullptr; | ||||
| r_ctx->object = ob; | r_ctx->object = ob; | ||||
| r_ctx->obedit = OBEDIT_FROM_OBACT(ob); | r_ctx->obedit = OBEDIT_FROM_OBACT(ob); | ||||
| r_ctx->instance_stack = &instance_stack; | r_ctx->instance_stack = &instance_stack; | ||||
| r_ctx->dupli_gen_type_stack = &dupli_gen_type_stack; | |||||
| if (space_mat) { | if (space_mat) { | ||||
| copy_m4_m4(r_ctx->space_mat, space_mat); | copy_m4_m4(r_ctx->space_mat, space_mat); | ||||
| } | } | ||||
| else { | else { | ||||
| unit_m4(r_ctx->space_mat); | unit_m4(r_ctx->space_mat); | ||||
| } | } | ||||
| r_ctx->level = 0; | r_ctx->level = 0; | ||||
| r_ctx->gen = get_dupli_generator(r_ctx); | r_ctx->gen = get_dupli_generator(r_ctx); | ||||
| if (r_ctx->gen && r_ctx->gen->type != 0) { | |||||
| r_ctx->dupli_gen_type_stack->append(r_ctx->gen->type); | |||||
| } | |||||
| r_ctx->duplilist = nullptr; | r_ctx->duplilist = nullptr; | ||||
| r_ctx->preview_instance_index = -1; | r_ctx->preview_instance_index = -1; | ||||
| r_ctx->preview_base_geometry = nullptr; | r_ctx->preview_base_geometry = nullptr; | ||||
| } | } | ||||
| /** | /** | ||||
| * Create sub-context for recursive duplis. | * Create sub-context for recursive duplis. | ||||
| Show All 25 Lines | static bool copy_dupli_context(DupliContext *r_ctx, | ||||
| ++r_ctx->level; | ++r_ctx->level; | ||||
| if (r_ctx->level == MAX_DUPLI_RECUR - 1) { | if (r_ctx->level == MAX_DUPLI_RECUR - 1) { | ||||
| std::cerr << "Warning: Maximum instance recursion level reached.\n"; | std::cerr << "Warning: Maximum instance recursion level reached.\n"; | ||||
| return false; | return false; | ||||
| } | } | ||||
| r_ctx->gen = get_dupli_generator(r_ctx); | r_ctx->gen = get_dupli_generator(r_ctx); | ||||
| if (r_ctx->gen && r_ctx->gen->type != 0) { | |||||
| r_ctx->dupli_gen_type_stack->append(r_ctx->gen->type); | |||||
| } | |||||
| return true; | return true; | ||||
| } | } | ||||
| /** | /** | ||||
| * Generate a dupli instance. | * Generate a dupli instance. | ||||
| * | * | ||||
| * \param mat: is transform of the object relative to current context (including | * \param mat: is transform of the object relative to current context (including | ||||
| * #Object.object_to_world). | * #Object.object_to_world). | ||||
| Show All 16 Lines | static DupliObject *make_dupli(const DupliContext *ctx, | ||||
| } | } | ||||
| else { | else { | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| dob->ob = ob; | dob->ob = ob; | ||||
| dob->ob_data = const_cast<ID *>(object_data); | dob->ob_data = const_cast<ID *>(object_data); | ||||
| mul_m4_m4m4(dob->mat, (float(*)[4])ctx->space_mat, mat); | mul_m4_m4m4(dob->mat, (float(*)[4])ctx->space_mat, mat); | ||||
| dob->type = ctx->gen == nullptr ? 0 : ctx->gen->type; | dob->type = ctx->gen == nullptr ? 0 : ctx->dupli_gen_type_stack->last(); | ||||
| dob->preview_base_geometry = ctx->preview_base_geometry; | dob->preview_base_geometry = ctx->preview_base_geometry; | ||||
| dob->preview_instance_index = ctx->preview_instance_index; | dob->preview_instance_index = ctx->preview_instance_index; | ||||
| /* Set persistent id, which is an array with a persistent index for each level | /* 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 | * (particle number, vertex number, ..). by comparing this we can find the same | ||||
| * dupli-object between frames, which is needed for motion blur. | * dupli-object between frames, which is needed for motion blur. | ||||
| * The last level is ordered first in the array. */ | * The last level is ordered first in the array. */ | ||||
| dob->persistent_id[0] = index; | dob->persistent_id[0] = index; | ||||
| ▲ Show 20 Lines • Show All 1,472 Lines • ▼ Show 20 Lines | |||||
| /** \name Dupli-Container Implementation | /** \name Dupli-Container Implementation | ||||
| * \{ */ | * \{ */ | ||||
| ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob) | ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob) | ||||
| { | { | ||||
| ListBase *duplilist = MEM_cnew<ListBase>("duplilist"); | ListBase *duplilist = MEM_cnew<ListBase>("duplilist"); | ||||
| DupliContext ctx; | DupliContext ctx; | ||||
| Vector<Object *> instance_stack; | Vector<Object *> instance_stack; | ||||
| Vector<short> dupli_gen_type_stack({0}); | |||||
| instance_stack.append(ob); | instance_stack.append(ob); | ||||
| init_context(&ctx, depsgraph, sce, ob, nullptr, instance_stack); | init_context(&ctx, depsgraph, sce, ob, nullptr, instance_stack, dupli_gen_type_stack); | ||||
| if (ctx.gen) { | if (ctx.gen) { | ||||
| ctx.duplilist = duplilist; | ctx.duplilist = duplilist; | ||||
| ctx.gen->make_duplis(&ctx); | ctx.gen->make_duplis(&ctx); | ||||
| } | } | ||||
| return duplilist; | return duplilist; | ||||
| } | } | ||||
| ListBase *object_duplilist_preview(Depsgraph *depsgraph, | ListBase *object_duplilist_preview(Depsgraph *depsgraph, | ||||
| Scene *sce, | Scene *sce, | ||||
| Object *ob_eval, | Object *ob_eval, | ||||
| const ViewerPath *viewer_path) | const ViewerPath *viewer_path) | ||||
| { | { | ||||
| ListBase *duplilist = MEM_cnew<ListBase>("duplilist"); | ListBase *duplilist = MEM_cnew<ListBase>("duplilist"); | ||||
| DupliContext ctx; | DupliContext ctx; | ||||
| Vector<Object *> instance_stack; | Vector<Object *> instance_stack; | ||||
| Vector<short> dupli_gen_type_stack({0}); | |||||
| instance_stack.append(ob_eval); | instance_stack.append(ob_eval); | ||||
| init_context(&ctx, depsgraph, sce, ob_eval, nullptr, instance_stack); | init_context(&ctx, depsgraph, sce, ob_eval, nullptr, instance_stack, dupli_gen_type_stack); | ||||
| ctx.duplilist = duplilist; | ctx.duplilist = duplilist; | ||||
| Object *ob_orig = DEG_get_original_object(ob_eval); | Object *ob_orig = DEG_get_original_object(ob_eval); | ||||
| LISTBASE_FOREACH (ModifierData *, md_orig, &ob_orig->modifiers) { | LISTBASE_FOREACH (ModifierData *, md_orig, &ob_orig->modifiers) { | ||||
| if (md_orig->type != eModifierType_Nodes) { | if (md_orig->type != eModifierType_Nodes) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 206 Lines • Show Last 20 Lines | |||||