static void make_child_duplis_verts(const DupliContext *ctx, void *userdata, Object *child) { VertexDupliData *vdd = userdata; DerivedMesh *dm = vdd->dm; vdd->inst_ob = child; invert_m4_m4(child->imat, child->obmat); /* relative transform from parent to child space */ mul_m4_m4m4(vdd->child_imat, child->imat, ctx->object->obmat); if (vdd->edit_btmesh) { dm->foreachMappedVert(dm, vertex_dupli__mapFunc, vdd, vdd->use_rotation ? DM_FOREACH_USE_NORMAL : 0); } else { int a, totvert = vdd->totvert; float vec[3], no[3]; if (vdd->use_rotation) { for (a = 0; a < totvert; a++) { dm->getVertCo(dm, a, vec); dm->getVertNo(dm, a, no); vertex_dupli__mapFunc(vdd, a, vec, no, NULL); } } else { for (a = 0; a < totvert; a++) { dm->getVertCo(dm, a, vec); vertex_dupli__mapFunc(vdd, a, vec, NULL, NULL); } } } }
static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated) { Object *ob, *ob_iter; Mesh *me= par->data; Base *base = NULL; DerivedMesh *dm; vertexDupliData vdd; Scene *sce = NULL; Group *group = NULL; GroupObject * go = NULL; BMEditMesh *em; float vec[3], no[3], pmat[4][4]; int totvert, a, oblay; unsigned int lay; copy_m4_m4(pmat, par->obmat); /* simple preventing of too deep nested groups */ if (level>MAX_DUPLI_RECUR) return; em = me->edit_btmesh; if (em) { dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); } else dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); if (G.rendering) { vdd.orco= (float(*)[3])get_mesh_orco_verts(par); transform_mesh_orco_verts(me, vdd.orco, me->totvert, 0); } else vdd.orco= NULL; totvert = dm->getNumVerts(dm); /* having to loop on scene OR group objects is NOT FUN */ if (GS(id->name) == ID_SCE) { sce = (Scene *)id; lay= sce->lay; base= sce->base.first; } else { group = (Group *)id; lay= group->layer; go = group->gobject.first; } /* Start looping on Scene OR Group objects */ while (base || go) { if (sce) { ob_iter= base->object; oblay = base->lay; } else { ob_iter= go->ob; oblay = ob_iter->lay; } if (lay & oblay && scene->obedit!=ob_iter) { ob=ob_iter->parent; while (ob) { if (ob==par) { ob = ob_iter; /* End Scene/Group object loop, below is generic */ /* par_space_mat - only used for groups so we can modify the space dupli's are in * when par_space_mat is NULL ob->obmat can be used instead of ob__obmat */ if (par_space_mat) mult_m4_m4m4(vdd.obmat, par_space_mat, ob->obmat); else copy_m4_m4(vdd.obmat, ob->obmat); vdd.id= id; vdd.level= level; vdd.animated= animated; vdd.lb= lb; vdd.ob= ob; vdd.scene= scene; vdd.par= par; copy_m4_m4(vdd.pmat, pmat); /* mballs have a different dupli handling */ if (ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ if (me->edit_btmesh) { dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd); } else { for (a=0; a<totvert; a++) { dm->getVertCo(dm, a, vec); dm->getVertNo(dm, a, no); vertex_dupli__mapFunc(&vdd, a, vec, no, NULL); } } if (sce) { /* Set proper layer in case of scene looping, * in case of groups the object layer will be * changed when it's duplicated due to the * group duplication. */ ob->lay = vdd.par->lay; } break; } ob= ob->parent; } } if (sce) base= base->next; /* scene loop */ else go= go->next; /* group loop */ } if (vdd.orco) MEM_freeN(vdd.orco); dm->release(dm); }