/* used by metaballs * doesn't return the original duplicated object, only dupli's */ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob) { int run_again = 1; /* init */ if (val == 0) { iter->fase = F_START; iter->dupob = NULL; iter->duplilist = NULL; } else { /* run_again is set when a duplilist has been ended */ while (run_again) { run_again = 0; /* the first base */ if (iter->fase == F_START) { *base = (*scene)->base.first; if (*base) { *ob = (*base)->object; iter->fase = F_SCENE; } else { /* exception: empty scene */ while ((*scene)->set) { (*scene) = (*scene)->set; if ((*scene)->base.first) { *base = (*scene)->base.first; *ob = (*base)->object; iter->fase = F_SCENE; break; } } } } else { if (*base && iter->fase != F_DUPLI) { *base = (*base)->next; if (*base) { *ob = (*base)->object; } else { if (iter->fase == F_SCENE) { /* (*scene) is finished, now do the set */ while ((*scene)->set) { (*scene) = (*scene)->set; if ((*scene)->base.first) { *base = (*scene)->base.first; *ob = (*base)->object; break; } } } } } } if (*base == NULL) { iter->fase = F_START; } else { if (iter->fase != F_DUPLI) { if ( (*base)->object->transflag & OB_DUPLI) { /* groups cannot be duplicated for mballs yet, * this enters eternal loop because of * makeDispListMBall getting called inside of group_duplilist */ if ((*base)->object->dup_group == NULL) { iter->duplilist = object_duplilist_ex(eval_ctx, (*scene), (*base)->object, false); iter->dupob = iter->duplilist->first; if (!iter->dupob) free_object_duplilist(iter->duplilist); } } } /* handle dupli's */ if (iter->dupob) { copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->mat); (*base)->flag |= OB_FROMDUPLI; *ob = iter->dupob->ob; iter->fase = F_DUPLI; iter->dupob = iter->dupob->next; } else if (iter->fase == F_DUPLI) { iter->fase = F_SCENE; (*base)->flag &= ~OB_FROMDUPLI; for (iter->dupob = iter->duplilist->first; iter->dupob; iter->dupob = iter->dupob->next) { copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->omat); } free_object_duplilist(iter->duplilist); iter->duplilist = NULL; run_again = 1; } } } } #if 0 if (ob && *ob) { printf("Scene: '%s', '%s'\n", (*scene)->id.name + 2, (*ob)->id.name + 2); } #endif return iter->fase; }
/* note: previously updating was always done, this is why it defaults to be on * but there are likely places it can be called without updating */ ListBase *object_duplilist(EvaluationContext *eval_ctx, Scene *sce, Object *ob) { return object_duplilist_ex(eval_ctx, sce, ob, true); }
/* note: previously updating was always done, this is why it defaults to be on * but there are likely places it can be called without updating */ ListBase *object_duplilist(Scene *sce, Object *ob, int for_render) { return object_duplilist_ex(sce, ob, TRUE, for_render); }