forked from bartvdbraak/blender
Particles
========= - Normalize strand coordinates over the length of the strand, not cut off when with e.g. length texture control. - Weight paint and particle mode x-mirror now works with deformation and shape keys active. - X-ray is now disabled in particle mode, messed up depth tests.
This commit is contained in:
parent
ff52c8f2d6
commit
51322964f4
@ -265,6 +265,7 @@ void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float
|
|||||||
//void psys_vec_rot_from_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec);
|
//void psys_vec_rot_from_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec);
|
||||||
void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
||||||
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
||||||
|
void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
||||||
|
|
||||||
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
|
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
|
||||||
void psys_get_texture(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
|
void psys_get_texture(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
|
||||||
|
@ -2482,7 +2482,7 @@ static void mesh_build_data(Object *ob, CustomDataMask dataMask)
|
|||||||
ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
|
ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
|
||||||
|
|
||||||
if(!ob->bb)
|
if(!ob->bb)
|
||||||
ob->bb= MEM_mallocN(sizeof(BoundBox), "bb");
|
ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
|
||||||
boundbox_set_from_min_max(ob->bb, min, max);
|
boundbox_set_from_min_max(ob->bb, min, max);
|
||||||
|
|
||||||
ob->derivedFinal->needsFree = 0;
|
ob->derivedFinal->needsFree = 0;
|
||||||
@ -2520,7 +2520,7 @@ static void editmesh_build_data(CustomDataMask dataMask)
|
|||||||
em->derivedFinal->getMinMax(em->derivedFinal, min, max);
|
em->derivedFinal->getMinMax(em->derivedFinal, min, max);
|
||||||
|
|
||||||
if(!G.obedit->bb)
|
if(!G.obedit->bb)
|
||||||
G.obedit->bb= MEM_mallocN(sizeof(BoundBox), "bb");
|
G.obedit->bb= MEM_callocN(sizeof(BoundBox), "bb");
|
||||||
boundbox_set_from_min_max(G.obedit->bb, min, max);
|
boundbox_set_from_min_max(G.obedit->bb, min, max);
|
||||||
|
|
||||||
em->derivedFinal->needsFree = 0;
|
em->derivedFinal->needsFree = 0;
|
||||||
|
@ -2240,33 +2240,52 @@ static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat
|
|||||||
Crossf(mat[0], mat[1], mat[2]);
|
Crossf(mat[0], mat[1], mat[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void psys_face_mat(DerivedMesh *dm, ParticleData *pa, float mat[][4])
|
static void psys_face_mat(DerivedMesh *dm, ParticleData *pa, float mat[][4], int orco)
|
||||||
{
|
{
|
||||||
float v1[3], v2[3], v3[3];
|
float v1[3], v2[3], v3[3];
|
||||||
MFace *mface;
|
MFace *mface;
|
||||||
OrigSpaceFace *osface;
|
OrigSpaceFace *osface;
|
||||||
|
float (*orcodata)[3];
|
||||||
|
|
||||||
int i = pa->num_dmcache==DMCACHE_NOTFOUND ? pa->num : pa->num_dmcache;
|
int i = pa->num_dmcache==DMCACHE_NOTFOUND ? pa->num : pa->num_dmcache;
|
||||||
|
|
||||||
if (i==-1 || i >= dm->getNumFaces(dm)) { Mat4One(mat); return; }
|
if (i==-1 || i >= dm->getNumFaces(dm)) { Mat4One(mat); return; }
|
||||||
|
|
||||||
mface=dm->getFaceData(dm,i,CD_MFACE);
|
mface=dm->getFaceData(dm,i,CD_MFACE);
|
||||||
osface=dm->getFaceData(dm,i,CD_ORIGSPACE);
|
osface=dm->getFaceData(dm,i,CD_ORIGSPACE);
|
||||||
|
|
||||||
dm->getVertCo(dm,mface->v1,v1);
|
if(orco && (orcodata=dm->getVertDataArray(dm, CD_ORCO))) {
|
||||||
dm->getVertCo(dm,mface->v2,v2);
|
VECCOPY(v1, orcodata[mface->v1]);
|
||||||
dm->getVertCo(dm,mface->v3,v3);
|
VECCOPY(v2, orcodata[mface->v2]);
|
||||||
|
VECCOPY(v3, orcodata[mface->v3]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dm->getVertCo(dm,mface->v1,v1);
|
||||||
|
dm->getVertCo(dm,mface->v2,v2);
|
||||||
|
dm->getVertCo(dm,mface->v3,v3);
|
||||||
|
}
|
||||||
|
|
||||||
triatomat(v1, v2, v3, (osface)? osface->uv: NULL, mat);
|
triatomat(v1, v2, v3, (osface)? osface->uv: NULL, mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void psys_mat_hair_to_object(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
|
void psys_mat_hair_to_object(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
|
||||||
{
|
{
|
||||||
float vec[3];
|
float vec[3];
|
||||||
|
|
||||||
psys_face_mat(dm, pa, hairmat);
|
psys_face_mat(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);
|
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);
|
VECCOPY(hairmat[3],vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
|
||||||
|
{
|
||||||
|
float vec[3], orco[3];
|
||||||
|
|
||||||
|
psys_face_mat(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);
|
||||||
|
VECCOPY(hairmat[3],orco);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void psys_key_to_geometry(DerivedMesh *dm, ParticleData *pa, ParticleKey *key)
|
void psys_key_to_geometry(DerivedMesh *dm, ParticleData *pa, ParticleKey *key)
|
||||||
{
|
{
|
||||||
@ -2319,7 +2338,7 @@ void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float *vec)//to_geo
|
|||||||
{
|
{
|
||||||
float mat[4][4];
|
float mat[4][4];
|
||||||
|
|
||||||
psys_face_mat(dm, pa, mat);
|
psys_face_mat(dm, pa, mat, 0);
|
||||||
Mat4Transp(mat); /* cheap inverse for rotation matrix */
|
Mat4Transp(mat); /* cheap inverse for rotation matrix */
|
||||||
Mat4Mul3Vecfl(mat, vec);
|
Mat4Mul3Vecfl(mat, vec);
|
||||||
}
|
}
|
||||||
|
@ -1734,7 +1734,7 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
|
|||||||
StrandRen *strand=0;
|
StrandRen *strand=0;
|
||||||
RNG *rng= 0;
|
RNG *rng= 0;
|
||||||
float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
|
float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
|
||||||
float *orco=0,*surfnor=0,*uvco=0;
|
float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f;
|
||||||
float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
|
float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
|
||||||
float loc_tex[3], size_tex[3], adapt_angle=0.0, adapt_pix=0.0, random;
|
float loc_tex[3], size_tex[3], adapt_angle=0.0, adapt_pix=0.0, random;
|
||||||
int i, a, k, max_k=0, totpart, totvlako, totverto, totuv=0, override_uv=-1;
|
int i, a, k, max_k=0, totpart, totvlako, totverto, totuv=0, override_uv=-1;
|
||||||
@ -2043,6 +2043,7 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
|
|||||||
orco[2] = (orco[2]-loc_tex[2])/size_tex[2];
|
orco[2] = (orco[2]-loc_tex[2])/size_tex[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* surface normal shading setup */
|
||||||
if(ma->mode_l & MA_STR_SURFDIFF) {
|
if(ma->mode_l & MA_STR_SURFDIFF) {
|
||||||
Mat3MulVecfl(nmat, nor);
|
Mat3MulVecfl(nmat, nor);
|
||||||
surfnor= nor;
|
surfnor= nor;
|
||||||
@ -2050,7 +2051,8 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
|
|||||||
else
|
else
|
||||||
surfnor= NULL;
|
surfnor= NULL;
|
||||||
|
|
||||||
if(strandbuf) { /* strand render */
|
/* strand render setup */
|
||||||
|
if(strandbuf) {
|
||||||
strand= RE_findOrAddStrand(re, re->totstrand++);
|
strand= RE_findOrAddStrand(re, re->totstrand++);
|
||||||
strand->buffer= strandbuf;
|
strand->buffer= strandbuf;
|
||||||
strand->vert= svert;
|
strand->vert= svert;
|
||||||
@ -2073,9 +2075,17 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* strandco computation setup */
|
||||||
|
if(path_nbr) {
|
||||||
|
strandlen= 0.0f;
|
||||||
|
curlen= 0.0f;
|
||||||
|
for(k=1; k<=path_nbr; k++)
|
||||||
|
if(k<=max_k)
|
||||||
|
strandlen += VecLenf((cache+k-1)->co, (cache+k)->co);
|
||||||
|
}
|
||||||
|
|
||||||
for(k=0; k<=path_nbr; k++){
|
for(k=0; k<=path_nbr; k++){
|
||||||
if(path_nbr){
|
if(path_nbr){
|
||||||
time=(float)k/(float)path_nbr;
|
|
||||||
if(k<=max_k){
|
if(k<=max_k){
|
||||||
//bti->convert_bake_key(bsys,cache+k,0,(void*)&state);
|
//bti->convert_bake_key(bsys,cache+k,0,(void*)&state);
|
||||||
//copy_particle_key(&state,cache+k,0);
|
//copy_particle_key(&state,cache+k,0);
|
||||||
@ -2084,6 +2094,10 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(k > 0)
|
||||||
|
curlen += VecLenf((cache+k-1)->co, (cache+k)->co);
|
||||||
|
time= curlen/strandlen;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
time=0.0f;
|
time=0.0f;
|
||||||
|
@ -548,11 +548,11 @@ float *RE_strandren_get_uv(Render *re, StrandRen *strand, int n, char **name, in
|
|||||||
float **uv= node->uv;
|
float **uv= node->uv;
|
||||||
int size= (n+1)*256;
|
int size= (n+1)*256;
|
||||||
|
|
||||||
node->uv= MEM_callocN(size*sizeof(MCol*), "Strand uv");
|
node->uv= MEM_callocN(size*sizeof(float*), "Strand uv");
|
||||||
|
|
||||||
if(uv) {
|
if(uv) {
|
||||||
size= node->totuv*256;
|
size= node->totuv*256;
|
||||||
memcpy(node->uv, uv, size*sizeof(MCol*));
|
memcpy(node->uv, uv, size*sizeof(float*));
|
||||||
MEM_freeN(uv);
|
MEM_freeN(uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4706,10 +4706,13 @@ void draw_object(Base *base, int flag)
|
|||||||
|
|
||||||
/* xray delay? */
|
/* xray delay? */
|
||||||
if((flag & DRAW_PICKING)==0 && (base->flag & OB_FROMDUPLI)==0) {
|
if((flag & DRAW_PICKING)==0 && (base->flag & OB_FROMDUPLI)==0) {
|
||||||
/* xray and transp are set when it is drawing the 2nd/3rd pass */
|
/* don't do xray in particle mode, need the z-buffer */
|
||||||
if(!G.vd->xray && !G.vd->transp && (ob->dtx & OB_DRAWXRAY)) {
|
if(!(G.f & G_PARTICLEEDIT)) {
|
||||||
add_view3d_after(G.vd, base, V3D_XRAY);
|
/* xray and transp are set when it is drawing the 2nd/3rd pass */
|
||||||
return;
|
if(!G.vd->xray && !G.vd->transp && (ob->dtx & OB_DRAWXRAY)) {
|
||||||
|
add_view3d_after(G.vd, base, V3D_XRAY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +546,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
|
|||||||
|
|
||||||
/* insert particles into kd tree */
|
/* insert particles into kd tree */
|
||||||
LOOP_PARTICLES(i,pa) {
|
LOOP_PARTICLES(i,pa) {
|
||||||
psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, mat);
|
psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat);
|
||||||
VECCOPY(co, pa->hair[0].co);
|
VECCOPY(co, pa->hair[0].co);
|
||||||
Mat4MulVecfl(mat, co);
|
Mat4MulVecfl(mat, co);
|
||||||
BLI_kdtree_insert(tree, i, co, NULL);
|
BLI_kdtree_insert(tree, i, co, NULL);
|
||||||
@ -559,7 +559,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
|
|||||||
edit->mirror_cache= MEM_callocN(sizeof(int)*totpart, "PE mirror cache");
|
edit->mirror_cache= MEM_callocN(sizeof(int)*totpart, "PE mirror cache");
|
||||||
|
|
||||||
LOOP_PARTICLES(i,pa) {
|
LOOP_PARTICLES(i,pa) {
|
||||||
psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, mat);
|
psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat);
|
||||||
VECCOPY(co, pa->hair[0].co);
|
VECCOPY(co, pa->hair[0].co);
|
||||||
Mat4MulVecfl(mat, co);
|
Mat4MulVecfl(mat, co);
|
||||||
co[0]= -co[0];
|
co[0]= -co[0];
|
||||||
@ -628,8 +628,8 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* mirror positions and tags */
|
/* mirror positions and tags */
|
||||||
psys_mat_hair_to_object(ob, dm, psys->part->from, pa, mat);
|
psys_mat_hair_to_orco(ob, dm, psys->part->from, pa, mat);
|
||||||
psys_mat_hair_to_object(ob, dm, psys->part->from, mpa, mmat);
|
psys_mat_hair_to_orco(ob, dm, psys->part->from, mpa, mmat);
|
||||||
Mat4Invert(immat, mmat);
|
Mat4Invert(immat, mmat);
|
||||||
|
|
||||||
hkey=pa->hair;
|
hkey=pa->hair;
|
||||||
|
@ -686,7 +686,7 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
|
static long mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mvert, float *co)
|
||||||
{
|
{
|
||||||
float *vec;
|
float *vec;
|
||||||
int a;
|
int a;
|
||||||
@ -697,7 +697,12 @@ static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
|
|||||||
for(a=0; a<MOC_NODE_RES; a++) {
|
for(a=0; a<MOC_NODE_RES; a++) {
|
||||||
if((*bt)->index[a]) {
|
if((*bt)->index[a]) {
|
||||||
/* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */
|
/* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */
|
||||||
if(mvert) {
|
if(orco) {
|
||||||
|
vec= orco[(*bt)->index[a]-1];
|
||||||
|
if(FloatCompare(vec, co, MOC_THRESH))
|
||||||
|
return (*bt)->index[a]-1;
|
||||||
|
}
|
||||||
|
else if(mvert) {
|
||||||
vec= (mvert+(*bt)->index[a]-1)->co;
|
vec= (mvert+(*bt)->index[a]-1)->co;
|
||||||
if(FloatCompare(vec, co, MOC_THRESH))
|
if(FloatCompare(vec, co, MOC_THRESH))
|
||||||
return (*bt)->index[a]-1;
|
return (*bt)->index[a]-1;
|
||||||
@ -711,84 +716,116 @@ static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
|
|||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
if( (*bt)->next)
|
if( (*bt)->next)
|
||||||
return mesh_octree_find_index(&(*bt)->next, mvert, co);
|
return mesh_octree_find_index(&(*bt)->next, orco, mvert, co);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
MocNode **table;
|
||||||
|
float offs[3], div[3];
|
||||||
|
float (*orco)[3];
|
||||||
|
} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}, NULL};
|
||||||
|
|
||||||
/* mode is 's' start, or 'e' end, or 'u' use */
|
/* mode is 's' start, or 'e' end, or 'u' use */
|
||||||
/* if end, ob can be NULL */
|
/* if end, ob can be NULL */
|
||||||
long mesh_octree_table(Object *ob, float *co, char mode)
|
long mesh_octree_table(Object *ob, float *co, char mode)
|
||||||
{
|
{
|
||||||
MocNode **bt;
|
MocNode **bt;
|
||||||
static MocNode **basetable= NULL;
|
|
||||||
static float offs[3], div[3];
|
|
||||||
|
|
||||||
if(mode=='u') { /* use table */
|
if(mode=='u') { /* use table */
|
||||||
if(basetable==NULL)
|
if(MeshOctree.table==NULL)
|
||||||
mesh_octree_table(ob, NULL, 's');
|
mesh_octree_table(ob, NULL, 's');
|
||||||
|
|
||||||
if(basetable) {
|
if(MeshOctree.table) {
|
||||||
Mesh *me= ob->data;
|
Mesh *me= ob->data;
|
||||||
bt= basetable + mesh_octree_get_base_offs(co, offs, div);
|
bt= MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div);
|
||||||
if(ob==G.obedit)
|
if(ob==G.obedit)
|
||||||
return mesh_octree_find_index(bt, NULL, co);
|
return mesh_octree_find_index(bt, NULL, NULL, co);
|
||||||
else
|
else
|
||||||
return mesh_octree_find_index(bt, me->mvert, co);
|
return mesh_octree_find_index(bt, MeshOctree.orco, me->mvert, co);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if(mode=='s') { /* start table */
|
else if(mode=='s') { /* start table */
|
||||||
Mesh *me= ob->data;
|
Mesh *me= ob->data;
|
||||||
BoundBox *bb = mesh_get_bb(ob);
|
float min[3], max[3];
|
||||||
|
|
||||||
|
/* we compute own bounding box and don't reuse ob->bb because
|
||||||
|
* we are using the undeformed coordinates*/
|
||||||
|
INIT_MINMAX(min, max);
|
||||||
|
|
||||||
|
if(ob==G.obedit) {
|
||||||
|
EditVert *eve;
|
||||||
|
|
||||||
|
for(eve= G.editMesh->verts.first; eve; eve= eve->next)
|
||||||
|
DO_MINMAX(eve->co, min, max)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MVert *mvert;
|
||||||
|
float *co;
|
||||||
|
int a, totvert;
|
||||||
|
|
||||||
|
MeshOctree.orco= mesh_getRefKeyCos(me, &totvert);
|
||||||
|
|
||||||
|
for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
|
||||||
|
co= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
|
||||||
|
DO_MINMAX(co, min, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* for quick unit coordinate calculus */
|
/* for quick unit coordinate calculus */
|
||||||
VECCOPY(offs, bb->vec[0]);
|
VECCOPY(MeshOctree.offs, min);
|
||||||
offs[0]-= MOC_THRESH; /* we offset it 1 threshold unit extra */
|
MeshOctree.offs[0]-= MOC_THRESH; /* we offset it 1 threshold unit extra */
|
||||||
offs[1]-= MOC_THRESH;
|
MeshOctree.offs[1]-= MOC_THRESH;
|
||||||
offs[2]-= MOC_THRESH;
|
MeshOctree.offs[2]-= MOC_THRESH;
|
||||||
|
|
||||||
VecSubf(div, bb->vec[6], bb->vec[0]);
|
|
||||||
div[0]+= 2*MOC_THRESH; /* and divide with 2 threshold unit more extra (try 8x8 unit grid on paint) */
|
|
||||||
div[1]+= 2*MOC_THRESH;
|
|
||||||
div[2]+= 2*MOC_THRESH;
|
|
||||||
|
|
||||||
VecMulf(div, 1.0f/MOC_RES);
|
VecSubf(MeshOctree.div, max, min);
|
||||||
if(div[0]==0.0f) div[0]= 1.0f;
|
MeshOctree.div[0]+= 2*MOC_THRESH; /* and divide with 2 threshold unit more extra (try 8x8 unit grid on paint) */
|
||||||
if(div[1]==0.0f) div[1]= 1.0f;
|
MeshOctree.div[1]+= 2*MOC_THRESH;
|
||||||
if(div[2]==0.0f) div[2]= 1.0f;
|
MeshOctree.div[2]+= 2*MOC_THRESH;
|
||||||
|
|
||||||
|
VecMulf(MeshOctree.div, 1.0f/MOC_RES);
|
||||||
|
if(MeshOctree.div[0]==0.0f) MeshOctree.div[0]= 1.0f;
|
||||||
|
if(MeshOctree.div[1]==0.0f) MeshOctree.div[1]= 1.0f;
|
||||||
|
if(MeshOctree.div[2]==0.0f) MeshOctree.div[2]= 1.0f;
|
||||||
|
|
||||||
if(basetable) /* happens when entering this call without ending it */
|
if(MeshOctree.table) /* happens when entering this call without ending it */
|
||||||
mesh_octree_table(ob, co, 'e');
|
mesh_octree_table(ob, co, 'e');
|
||||||
|
|
||||||
basetable= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table");
|
MeshOctree.table= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table");
|
||||||
|
|
||||||
if(ob==G.obedit) {
|
if(ob==G.obedit) {
|
||||||
EditVert *eve;
|
EditVert *eve;
|
||||||
|
|
||||||
for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
|
for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
|
||||||
mesh_octree_add_nodes(basetable, eve->co, offs, div, (long)(eve));
|
mesh_octree_add_nodes(MeshOctree.table, eve->co, MeshOctree.offs, MeshOctree.div, (long)(eve));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MVert *mvert;
|
MVert *mvert;
|
||||||
long a;
|
float *co;
|
||||||
|
int a;
|
||||||
|
|
||||||
for(a=1, mvert= me->mvert; a<=me->totvert; a++, mvert++) {
|
for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
|
||||||
mesh_octree_add_nodes(basetable, mvert->co, offs, div, a);
|
co= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
|
||||||
|
mesh_octree_add_nodes(MeshOctree.table, co, MeshOctree.offs, MeshOctree.div, a+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(mode=='e') { /* end table */
|
else if(mode=='e') { /* end table */
|
||||||
if(basetable) {
|
if(MeshOctree.table) {
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
for(a=0, bt=basetable; a<MOC_RES*MOC_RES*MOC_RES; a++, bt++) {
|
for(a=0, bt=MeshOctree.table; a<MOC_RES*MOC_RES*MOC_RES; a++, bt++) {
|
||||||
if(*bt) mesh_octree_free_node(bt);
|
if(*bt) mesh_octree_free_node(bt);
|
||||||
}
|
}
|
||||||
MEM_freeN(basetable);
|
MEM_freeN(MeshOctree.table);
|
||||||
basetable= NULL;
|
MeshOctree.table= NULL;
|
||||||
|
}
|
||||||
|
if(MeshOctree.orco) {
|
||||||
|
MEM_freeN(MeshOctree.orco);
|
||||||
|
MeshOctree.orco= NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -797,12 +834,20 @@ long mesh_octree_table(Object *ob, float *co, char mode)
|
|||||||
int mesh_get_x_mirror_vert(Object *ob, int index)
|
int mesh_get_x_mirror_vert(Object *ob, int index)
|
||||||
{
|
{
|
||||||
Mesh *me= ob->data;
|
Mesh *me= ob->data;
|
||||||
MVert *mvert= me->mvert+index;
|
MVert *mvert;
|
||||||
float vec[3];
|
float vec[3];
|
||||||
|
|
||||||
vec[0]= -mvert->co[0];
|
if(MeshOctree.orco) {
|
||||||
vec[1]= mvert->co[1];
|
vec[0]= -MeshOctree.orco[index][0];
|
||||||
vec[2]= mvert->co[2];
|
vec[1]= MeshOctree.orco[index][1];
|
||||||
|
vec[2]= MeshOctree.orco[index][2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mvert= me->mvert+index;
|
||||||
|
vec[0]= -mvert->co[0];
|
||||||
|
vec[1]= mvert->co[1];
|
||||||
|
vec[2]= mvert->co[2];
|
||||||
|
}
|
||||||
|
|
||||||
return mesh_octree_table(ob, vec, 'u');
|
return mesh_octree_table(ob, vec, 'u');
|
||||||
}
|
}
|
||||||
@ -884,9 +929,16 @@ int *mesh_get_x_mirror_faces(Object *ob)
|
|||||||
mesh_octree_table(ob, NULL, 's');
|
mesh_octree_table(ob, NULL, 's');
|
||||||
|
|
||||||
for(a=0, mv=mvert; a<me->totvert; a++, mv++) {
|
for(a=0, mv=mvert; a<me->totvert; a++, mv++) {
|
||||||
vec[0]= -mv->co[0];
|
if(MeshOctree.orco) {
|
||||||
vec[1]= mv->co[1];
|
vec[0]= -MeshOctree.orco[a][0];
|
||||||
vec[2]= mv->co[2];
|
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');
|
mirrorverts[a]= mesh_octree_table(ob, vec, 'u');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user