Fix for mirroring issues in particle mode, where the particles were

not mirrored exactly, though the problem is not completely solved.
The way local frames are computed for particles is still not fully
symmetric, which shows especially on long hairs...

Also made the shift+o subsurf switch work recursively into
dupli-groups, did only the first level before.
This commit is contained in:
2007-12-11 20:02:21 +00:00
parent 160e6afdb8
commit 457057a9e8
7 changed files with 93 additions and 84 deletions

View File

@@ -63,7 +63,7 @@ void make_local_mesh(struct Mesh *me);
void boundbox_mesh(struct Mesh *me, float *loc, float *size);
void tex_space_mesh(struct Mesh *me);
float *get_mesh_orco_verts(struct Object *ob);
void transform_mesh_orco_verts(struct Mesh *me, float (*orco)[3], int totvert);
void transform_mesh_orco_verts(struct Mesh *me, float (*orco)[3], int totvert, int invert);
void test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
struct Mesh *get_mesh(struct Object *ob);
void set_mesh(struct Object *ob, struct Mesh *me);

View File

@@ -1861,7 +1861,7 @@ static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
else
orco= (float(*)[3])get_mesh_orco_verts(ob);
transform_mesh_orco_verts(ob->data, orco, totvert);
transform_mesh_orco_verts(ob->data, orco, totvert, 0);
if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
memcpy(layerorco, orco, sizeof(float)*totvert);

View File

@@ -515,18 +515,28 @@ float *get_mesh_orco_verts(Object *ob)
return (float*)vcos;
}
void transform_mesh_orco_verts(Mesh *me, float (*orco)[3], int totvert)
void transform_mesh_orco_verts(Mesh *me, float (*orco)[3], int totvert, int invert)
{
float loc[3], size[3];
int a;
mesh_get_texspace(me->texcomesh?me->texcomesh:me, loc, NULL, size);
for(a=0; a<totvert; a++) {
float *co = orco[a];
co[0] = (co[0]-loc[0])/size[0];
co[1] = (co[1]-loc[1])/size[1];
co[2] = (co[2]-loc[2])/size[2];
if(invert) {
for(a=0; a<totvert; a++) {
float *co = orco[a];
co[0] = co[0]*size[0] + loc[0];
co[1] = co[1]*size[1] + loc[1];
co[2] = co[2]*size[2] + loc[2];
}
}
else {
for(a=0; a<totvert; a++) {
float *co = orco[a];
co[0] = (co[0]-loc[0])/size[0];
co[1] = (co[1]-loc[1])/size[1];
co[2] = (co[2]-loc[2])/size[2];
}
}
}

View File

@@ -76,6 +76,7 @@
#include "BKE_depsgraph.h"
#include "BKE_bad_level_calls.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "blendef.h"
#include "RE_render_ext.h"
@@ -2240,9 +2241,9 @@ static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat
Crossf(mat[0], mat[1], mat[2]);
}
static void psys_face_mat(DerivedMesh *dm, ParticleData *pa, float mat[][4], int orco)
static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[][4], int orco)
{
float v1[3], v2[3], v3[3];
float v[3][3];
MFace *mface;
OrigSpaceFace *osface;
float (*orcodata)[3];
@@ -2255,24 +2256,28 @@ static void psys_face_mat(DerivedMesh *dm, ParticleData *pa, float mat[][4], int
osface=dm->getFaceData(dm,i,CD_ORIGSPACE);
if(orco && (orcodata=dm->getVertDataArray(dm, CD_ORCO))) {
VECCOPY(v1, orcodata[mface->v1]);
VECCOPY(v2, orcodata[mface->v2]);
VECCOPY(v3, orcodata[mface->v3]);
VECCOPY(v[0], orcodata[mface->v1]);
VECCOPY(v[1], orcodata[mface->v2]);
VECCOPY(v[2], orcodata[mface->v3]);
/* ugly hack to use non-transformed orcos, since only those
* give symmetric results for mirroring in particle mode */
transform_mesh_orco_verts(ob->data, v, 3, 1);
}
else {
dm->getVertCo(dm,mface->v1,v1);
dm->getVertCo(dm,mface->v2,v2);
dm->getVertCo(dm,mface->v3,v3);
dm->getVertCo(dm,mface->v1,v[0]);
dm->getVertCo(dm,mface->v2,v[1]);
dm->getVertCo(dm,mface->v3,v[2]);
}
triatomat(v1, v2, v3, (osface)? osface->uv: NULL, mat);
triatomat(v[0], v[1], v[2], (osface)? osface->uv: NULL, mat);
}
void psys_mat_hair_to_object(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
{
float vec[3];
psys_face_mat(dm, pa, hairmat, 0);
psys_face_mat(0, dm, pa, hairmat, 0);
psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0, 0);
VECCOPY(hairmat[3],vec);
}
@@ -2281,8 +2286,11 @@ void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData
{
float vec[3], orco[3];
psys_face_mat(dm, pa, hairmat, 1);
psys_face_mat(ob, dm, pa, hairmat, 1);
psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco, 0);
/* see psys_face_mat for why this function is called */
transform_mesh_orco_verts(ob->data, orco, 1, 1);
VECCOPY(hairmat[3],orco);
}
@@ -2338,7 +2346,7 @@ void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float *vec)//to_geo
{
float mat[4][4];
psys_face_mat(dm, pa, mat, 0);
psys_face_mat(0, dm, pa, mat, 0);
Mat4Transp(mat); /* cheap inverse for rotation matrix */
Mat4Mul3Vecfl(mat, vec);
}

View File

@@ -2822,44 +2822,51 @@ void convertmenu(void)
* level==-1 then toggle subsurf, else set to level.
* *set allows to toggle multiple selections
*/
static void object_flip_subdivison(Object *ob, int *set, int level, int mode)
static void object_flip_subdivison(Object *ob, int *set, int level, int mode, int ingroup)
{
ModifierData *md;
if(ob->type!=OB_MESH)
return;
if(ob->type==OB_MESH) {
md = modifiers_findByType(ob, eModifierType_Subsurf);
md = modifiers_findByType(ob, eModifierType_Subsurf);
if (md) {
SubsurfModifierData *smd = (SubsurfModifierData*) md;
if (md) {
SubsurfModifierData *smd = (SubsurfModifierData*) md;
if (level == -1) {
if(*set == -1)
*set= smd->modifier.mode&(mode);
if (level == -1) {
if(*set == -1)
*set= smd->modifier.mode&(mode);
if (*set) {
smd->modifier.mode &= ~(mode);
if (*set) {
smd->modifier.mode &= ~(mode);
} else {
smd->modifier.mode |= (mode);
}
} else {
smd->modifier.mode |= (mode);
smd->levels = level;
}
} else {
smd->levels = level;
}
}
else if(*set != 0) {
SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
else if(!ingroup && *set != 0) {
SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
BLI_addtail(&ob->modifiers, smd);
BLI_addtail(&ob->modifiers, smd);
if (level!=-1) {
smd->levels = level;
if (level!=-1) {
smd->levels = level;
}
if(*set == -1)
*set= 1;
}
if(*set == -1)
*set= 1;
ob->recalc |= OB_RECALC_DATA;
}
if(ob->dup_group) {
GroupObject *go;
for(go= ob->dup_group->gobject.first; go; go= go->next)
object_flip_subdivison(go->ob, set, level, mode, 1);
}
ob->recalc |= OB_RECALC_DATA;
}
/* Change subdivision properties of mesh object ob, if
@@ -2877,18 +2884,9 @@ void flip_subdivison(int level)
else
mode= eModifierMode_Render|eModifierMode_Realtime;
for(base= G.scene->base.first; base; base= base->next) {
if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base))) {
object_flip_subdivison(base->object, &set, level, mode);
if(base->object->dup_group) {
GroupObject *go;
for(go= base->object->dup_group->gobject.first; go; go= go->next)
if( modifiers_findByType(go->ob, eModifierType_Subsurf)) /* only when exists */
object_flip_subdivison(go->ob, &set, level, mode);
}
}
}
for(base= G.scene->base.first; base; base= base->next)
if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base)))
object_flip_subdivison(base->object, &set, level, mode, 0);
countall();
allqueue(REDRAWVIEW3D, 0);

View File

@@ -56,6 +56,7 @@
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
@@ -599,11 +600,11 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys
edit= psys->edit;
i= pa - psys->particles;
if(!edit->mirror_cache)
PE_update_mirror_cache(ob, psys);
/* find mirrored particle if needed */
if(!mpa) {
if(!edit->mirror_cache)
PE_update_mirror_cache(ob, psys);
mi= edit->mirror_cache[i];
if(mi == -1)
return;

View File

@@ -725,6 +725,7 @@ static struct {
MocNode **table;
float offs[3], div[3];
float (*orco)[3];
float orcoloc[3];
} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}, NULL};
/* mode is 's' start, or 'e' end, or 'u' use */
@@ -767,6 +768,7 @@ long mesh_octree_table(Object *ob, float *co, char mode)
int a, totvert;
MeshOctree.orco= mesh_getRefKeyCos(me, &totvert);
mesh_get_texspace(me, MeshOctree.orcoloc, NULL, NULL);
for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
co= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
@@ -838,7 +840,9 @@ int mesh_get_x_mirror_vert(Object *ob, int index)
float vec[3];
if(MeshOctree.orco) {
vec[0]= -MeshOctree.orco[index][0];
float *loc= MeshOctree.orcoloc;
vec[0]= -(MeshOctree.orco[index][0] + loc[0]) - loc[0];
vec[1]= MeshOctree.orco[index][1];
vec[2]= MeshOctree.orco[index][2];
}
@@ -920,7 +924,6 @@ int *mesh_get_x_mirror_faces(Object *ob)
MFace mirrormf, *mf, *hashmf, *mface= me->mface;
GHash *fhash;
int *mirrorverts, *mirrorfaces;
float vec[3];
int a;
mirrorverts= MEM_callocN(sizeof(int)*me->totvert, "MirrorVerts");
@@ -928,19 +931,8 @@ int *mesh_get_x_mirror_faces(Object *ob)
mesh_octree_table(ob, NULL, 's');
for(a=0, mv=mvert; a<me->totvert; a++, mv++) {
if(MeshOctree.orco) {
vec[0]= -MeshOctree.orco[a][0];
vec[1]= MeshOctree.orco[a][1];
vec[2]= MeshOctree.orco[a][2];
}
else {
vec[0]= -mv->co[0];
vec[1]= mv->co[1];
vec[2]= mv->co[2];
}
mirrorverts[a]= mesh_octree_table(ob, vec, 'u');
}
for(a=0, mv=mvert; a<me->totvert; a++, mv++)
mirrorverts[a]= mesh_get_x_mirror_vert(ob, a);
mesh_octree_table(ob, NULL, 'e');