diff options
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_particle.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 114 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 40 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 100 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 73 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_customdata_types.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 51 | ||||
-rw-r--r-- | source/blender/src/editparticle.c | 4 |
12 files changed, 283 insertions, 139 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index a8e4969ad43..1bba980c47b 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -62,8 +62,8 @@ void make_local_tface(struct Mesh *me); 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 *mesh_create_orco_render(struct Object *ob); -float *mesh_create_orco(struct Object *ob); +float *get_mesh_orco_verts(struct Object *ob); +void transform_mesh_orco_verts(struct Mesh *me, float (*orco)[3], int totvert); 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); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index d419eac2fab..c41a54b0ea7 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -219,7 +219,7 @@ void psys_interpolate_uvs(struct MTFace *tface, int quad, float *uv, float *uvco void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time); -void psys_particle_on_emitter(struct Object *ob, struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan); +void psys_particle_on_emitter(struct Object *ob, struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys); struct ParticleSettings *psys_new_settings(char *name, struct Main *main); @@ -268,12 +268,12 @@ void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short fr 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_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float *uv, float *vec, float *nor, float *utan, float *vtan); +void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); float psys_interpolate_value_from_verts(struct DerivedMesh *dm, short from, int index, float *fw, float *values); void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time); int psys_intersect_dm(struct Object *ob, struct DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_uv, float *face_minmax, float *pa_minmax, float radius, float *ipoint); -void psys_particle_on_dm(struct Object *ob, struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan); +void psys_particle_on_dm(struct Object *ob, struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); /* particle_system.c */ void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 5e688af14a4..e2e7b9dbd02 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1813,7 +1813,7 @@ CustomDataMask get_viewedit_datamask() View3D *view = sa->spacedata.first; if(view->drawtype == OB_SHADED) { /* this includes normals for mesh_create_shadedColors */ - mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL; + mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL | CD_MASK_ORCO; } if((view->drawtype == OB_TEXTURE) || ((view->drawtype == OB_SOLID) && (view->flag2 & V3D_SOLID_TEX))) { mask |= CD_MASK_MTFACE | CD_MASK_MCOL; @@ -1829,6 +1829,48 @@ CustomDataMask get_viewedit_datamask() return mask; } +static DerivedMesh *create_orco_dm(Object *ob, Mesh *me) +{ + DerivedMesh *dm; + float (*orco)[3]; + + dm= CDDM_from_mesh(me, ob); + orco= (float(*)[3])get_mesh_orco_verts(ob); + CDDM_apply_vert_coords(dm, orco); + CDDM_calc_normals(dm); + MEM_freeN(orco); + + return dm; +} + +static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm) +{ + float (*orco)[3], (*layerorco)[3]; + int totvert; + + totvert= dm->getNumVerts(dm); + + if(orcodm) { + orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco"); + + if(orcodm->getNumVerts(orcodm) == totvert) + orcodm->getVertCos(orcodm, orco); + else + dm->getVertCos(dm, orco); + } + else + orco= (float(*)[3])get_mesh_orco_verts(ob); + + transform_mesh_orco_verts(ob->data, orco, totvert); + + if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) { + memcpy(layerorco, orco, sizeof(float)*totvert); + MEM_freeN(orco); + } + else + DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); +} + static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform, @@ -1837,8 +1879,9 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], Mesh *me = ob->data; ModifierData *md = modifiers_getVirtualModifierList(ob); LinkNode *datamasks, *curr; + CustomDataMask mask; float (*deformedVerts)[3] = NULL; - DerivedMesh *dm; + DerivedMesh *dm, *orcodm, *finaldm; int numVerts = me->totvert; int fluidsimMeshUsed = 0; int required_mode; @@ -1936,6 +1979,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], * OnlyDeform ones. */ dm = NULL; + orcodm = NULL; #ifdef WITH_VERSE /* hack to make sure modifiers don't try to use mesh data from a verse @@ -1957,6 +2001,13 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], if(mti->isDisabled && mti->isDisabled(md)) continue; if(needMapping && !modifier_supportsMapping(md)) continue; + /* add an orco layer if needed by this modifier */ + if(dm && mti->requiredDataMask) { + mask = mti->requiredDataMask(md); + if(mask & CD_MASK_ORCO) + add_orco_dm(ob, dm, orcodm); + } + /* How to apply modifier depends on (a) what we already have as * a result of previous modifiers (could be a DerivedMesh or just * deformed vertices) and (b) what type the modifier is. @@ -1980,6 +2031,8 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], } } + if(md->type == eModifierType_ParticleSystem) + mti->deformVerts(md, ob, dm, deformedVerts, numVerts); } else { DerivedMesh *ndm; @@ -2003,13 +2056,31 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], } } + /* create an orco derivedmesh in parallel */ + mask= (CustomDataMask)curr->link; + if(mask & CD_MASK_ORCO) { + if(!orcodm) + orcodm= create_orco_dm(ob, me); + + mask &= ~CD_MASK_ORCO; + DM_set_only_copy(orcodm, mask); + ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, !inputVertexCos); + + if(ndm) { + /* if the modifier returned a new dm, release the old one */ + if(orcodm && orcodm != ndm) orcodm->release(orcodm); + orcodm = ndm; + } + } + /* set the DerivedMesh to only copy needed data */ - DM_set_only_copy(dm, (CustomDataMask)curr->link); + DM_set_only_copy(dm, mask); + /* add an origspace layer if needed */ if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE) if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) - CustomData_add_layer(&dm->faceData, CD_ORIGSPACE, CD_DEFAULT, NULL, dm->getNumFaces(dm)); - + DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); + ndm = mti->applyModifier(md, ob, dm, useRenderParams, !inputVertexCos); if(ndm) { @@ -2033,34 +2104,43 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], * DerivedMesh then we need to build one. */ if(dm && deformedVerts) { - *final_r = CDDM_copy(dm); + finaldm = CDDM_copy(dm); dm->release(dm); - CDDM_apply_vert_coords(*final_r, deformedVerts); - CDDM_calc_normals(*final_r); + CDDM_apply_vert_coords(finaldm, deformedVerts); + CDDM_calc_normals(finaldm); } else if(dm) { - *final_r = dm; + finaldm = dm; } else { #ifdef WITH_VERSE if(me->vnode) - *final_r = derivedmesh_from_versemesh(me->vnode, deformedVerts); + finaldm = derivedmesh_from_versemesh(me->vnode, deformedVerts); else { - *final_r = CDDM_from_mesh(me, ob); + finaldm = CDDM_from_mesh(me, ob); if(deformedVerts) { - CDDM_apply_vert_coords(*final_r, deformedVerts); - CDDM_calc_normals(*final_r); + CDDM_apply_vert_coords(finaldm, deformedVerts); + CDDM_calc_normals(finaldm); } } #else - *final_r = CDDM_from_mesh(me, ob); + finaldm = CDDM_from_mesh(me, ob); if(deformedVerts) { - CDDM_apply_vert_coords(*final_r, deformedVerts); - CDDM_calc_normals(*final_r); + CDDM_apply_vert_coords(finaldm, deformedVerts); + CDDM_calc_normals(finaldm); } #endif } + /* add an orco layer if needed */ + if(dataMask & CD_MASK_ORCO) + add_orco_dm(ob, finaldm, orcodm); + + *final_r = finaldm; + + if(orcodm) + orcodm->release(orcodm); + if(deformedVerts && deformedVerts != inputVertexCos) MEM_freeN(deformedVerts); @@ -2190,7 +2270,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE) if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) - CustomData_add_layer(&dm->faceData, CD_ORIGSPACE, CD_DEFAULT, NULL, dm->getNumFaces(dm)); + DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); ndm = mti->applyModifierEM(md, ob, em, dm); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index aa0dc10f4e0..d8ce311b5ca 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -449,11 +449,13 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL}, {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL, layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face}, + {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL} }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", - "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty","CDMIntProperty","CDMStringProperty", "CDOrigSpace"}; + "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty", + "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco"}; const CustomDataMask CD_MASK_BAREMESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; @@ -466,8 +468,8 @@ const CustomDataMask CD_MASK_EDITMESH = CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | - CD_MASK_MCOL | CD_MASK_ORIGINDEX | - CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE; + CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | + CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO; static const LayerTypeInfo *layerType_getInfo(int type) { diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 82a108a20eb..bea0626286e 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -485,9 +485,11 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL | CD_MASK_MTFACE | CD_MASK_NORMAL; + init_fastshade_for_ob(re, ob, &need_orco, mat, imat); - orco = (need_orco)? mesh_create_orco(ob): NULL; + if(need_orco) + dataMask |= CD_MASK_ORCO; if (onlyForMesh) dm = mesh_get_derived_deform(ob, dataMask); @@ -499,6 +501,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un nors = dm->getFaceDataArray(dm, CD_NORMAL); totvert = dm->getNumVerts(dm); totface = dm->getNumFaces(dm); + orco= dm->getVertDataArray(dm, CD_ORCO); if (onlyForMesh) { col1 = *col1_r; @@ -577,9 +580,6 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un } MEM_freeN(vnors); - if (orco) - MEM_freeN(orco); - dm->release(dm); end_fastshade_for_ob(ob); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 4e551e28885..746cc80d638 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -474,17 +474,13 @@ void mesh_get_texspace(Mesh *me, float *loc_r, float *rot_r, float *size_r) if (size_r) VECCOPY(size_r, me->size); } -static float *make_orco_mesh_internal(Object *ob, int render) +float *get_mesh_orco_verts(Object *ob) { Mesh *me = ob->data; - float (*orcoData)[3]; int a, totvert; - float loc[3], size[3]; - DerivedMesh *dm; float (*vcos)[3] = NULL; - /* Get appropriate vertex coordinates */ - + /* Get appropriate vertex coordinates */ if(me->key && me->texcomesh==0 && me->key->refkey) { vcos= mesh_getRefKeyCos(me, &totvert); } @@ -512,40 +508,22 @@ static float *make_orco_mesh_internal(Object *ob, int render) } } - /* Apply orco-changing modifiers */ - - if (render) { - dm = mesh_create_derived_no_deform_render(ob, vcos, CD_MASK_BAREMESH); - } else { - dm = mesh_create_derived_no_deform(ob, vcos, CD_MASK_BAREMESH); - } - totvert = dm->getNumVerts(dm); + return (float*)vcos; +} - orcoData = MEM_mallocN(sizeof(*orcoData)*totvert, "orcoData"); - dm->getVertCos(dm, orcoData); - dm->release(dm); - MEM_freeN(vcos); +void transform_mesh_orco_verts(Mesh *me, float (*orco)[3], int totvert) +{ + 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 = orcoData[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]; } - - return (float*) orcoData; -} - -float *mesh_create_orco_render(Object *ob) -{ - return make_orco_mesh_internal(ob, 1); -} - -float *mesh_create_orco(Object *ob) -{ - return make_orco_mesh_internal(ob, 0); } /* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0. diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index efad06adcf3..2189fed3448 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5010,7 +5010,7 @@ static void particleSystemModifier_initData(ModifierData *md) ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; psmd->psys= 0; psmd->dm=0; - + psmd->totdmvert= psmd->totdmedge= psmd->totdmface= 0; } static void particleSystemModifier_freeData(ModifierData *md) { @@ -5054,6 +5054,8 @@ CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md) /* particles only need this if they are after a non deform modifier, and * the modifier stack will only create them in that case. */ dataMask |= CD_MASK_ORIGSPACE; + + dataMask |= CD_MASK_ORCO; return dataMask; } @@ -5104,6 +5106,8 @@ static void particleSystemModifier_deformVerts( CDDM_apply_vert_coords(dm, vertexCos); //CDDM_calc_normals(dm); + + DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); needsFree=1; } @@ -5505,7 +5509,7 @@ static void explodeModifier_createFacepa(ExplodeModifierData *emd, /* make tree of emitter locations */ tree=BLI_kdtree_new(totpart); for(p=0,pa=psys->particles; p<totpart; p++,pa++){ - psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0); + psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0); BLI_kdtree_insert(tree, p, co, NULL); } BLI_kdtree_balance(tree); @@ -6076,7 +6080,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, /*duplicate & displace vertices*/ for(i=0, pa=pars; i<=totpart; i++, pa++){ if(i!=totpart){ - psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0); + psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0); Mat4MulVecfl(ob->obmat,loc0); state.time=cfra; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index f85efd23ad6..32383302485 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -417,12 +417,13 @@ static void interpolate_particle(short type, ParticleKey keys[4], float dt, Part /* Particles on a dm */ /************************************************/ /* interpolate a location on a face based on face coordinates */ -void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float *w, float *vec, float *nor, float *utan, float *vtan){ +void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], float *w, float *vec, float *nor, float *utan, float *vtan, float *orco,float *ornor){ float *v1=0, *v2=0, *v3=0, *v4=0; float e1[3],e2[3],s1,s2,t1,t2; float *uv1, *uv2, *uv3, *uv4; float n1[3], n2[3], n3[3], n4[3]; float tuv[4][2]; + float *o1, *o2, *o3, *o4; v1= (mvert+mface->v1)->co; v2= (mvert+mface->v2)->co; @@ -515,6 +516,37 @@ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float *w, utan[1] = (t1*e2[1] - t2*e1[1]); utan[2] = (t1*e2[2] - t2*e1[2]); } + + if(orco) { + if(orcodata) { + o1= orcodata[mface->v1]; + o2= orcodata[mface->v2]; + o3= orcodata[mface->v3]; + + if(mface->v4) { + o4= orcodata[mface->v4]; + orco[0]= w[0]*o1[0] + w[1]*o2[0] + w[2]*o3[0] + w[3]*o4[0]; + orco[1]= w[0]*o1[1] + w[1]*o2[1] + w[2]*o3[1] + w[3]*o4[1]; + orco[2]= w[0]*o1[2] + w[1]*o2[2] + w[2]*o3[2] + w[3]*o4[2]; + + if(ornor) + CalcNormFloat4(o1, o2, o3, o4, ornor); + } + else { + orco[0]= w[0]*o1[0] + w[1]*o2[0] + w[2]*o3[0]; + orco[1]= w[0]*o1[1] + w[1]*o2[1] + w[2]*o3[1]; + orco[2]= w[0]*o1[2] + w[1]*o2[2] + w[2]*o3[2]; + + if(ornor) + CalcNormFloat(o1, o2, o3, ornor); + } + } + else { + VECCOPY(orco, vec); + if(ornor) + VECCOPY(ornor, nor); + } + } } void psys_interpolate_uvs(MTFace *tface, int quad, float *w, float *uvco){ float v10= tface->uv[0][0]; @@ -656,8 +688,10 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float * /* interprets particle data to get a point on a mesh in object space */ #define PARTICLE_ERROR(_nor, _vec) _vec[0]=_vec[1]=_vec[2]=0.0; if(_nor){ _nor[0]=_nor[1]=0.0; _nor[2]=1.0; } -void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan) +void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) { + float (*orcodata)[3] = dm->getVertDataArray(dm, CD_ORCO); + if(index < 0){ /* 'no dm' error has happened! */ PARTICLE_ERROR(nor, vec); return; @@ -678,6 +712,12 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i dm->getVertNo(dm,index,nor); Normalize(nor); } + if(orco) + VECCOPY(orco, orcodata[index]) + if(ornor) { + dm->getVertNo(dm,index,nor); + Normalize(nor); + } } else { /* PART_FROM_FACE / PART_FROM_VOLUME */ MFace *mface; @@ -700,7 +740,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i } if(from==PART_FROM_VOLUME){ - psys_interpolate_face(mvert,mface,mtface,fw,vec,temp1,utan,vtan); + psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,temp1,utan,vtan,orco,ornor); if(nor) VECCOPY(nor,temp1); Normalize(temp1); @@ -708,7 +748,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i VECADD(vec,vec,temp1); } else - psys_interpolate_face(mvert,mface,mtface,fw,vec,nor,utan,vtan); + psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,nor,utan,vtan,orco,ornor); } } else { /* Need to support constructive modifiers, this is a bit more tricky @@ -761,7 +801,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i /* we need to modify the original weights to become weights for * the derived mesh face */ psys_origspace_to_w(osface, mface->v4, fw, fw_mod); - psys_interpolate_face(mvert,mface,mtface,fw_mod,vec,nor,utan,vtan); + psys_interpolate_face(mvert,mface,mtface,orcodata,fw_mod,vec,nor,utan,vtan,orco,ornor); } else { /* TODO PARTICLE - support verts and volume */ @@ -790,7 +830,7 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) /* Particles on a shape */ /************************************************/ /* ready for future use */ -void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan) +void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) { /* TODO */ float zerovec[3]={0.0f,0.0f,0.0f}; @@ -806,11 +846,17 @@ void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float if(vtan){ VECCOPY(vtan,zerovec); } + if(orco){ + VECCOPY(orco,zerovec); + } + if(ornor){ + VECCOPY(ornor,zerovec); + } } /************************************************/ /* Particles on emitter */ /************************************************/ -void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan){ +void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){ if(psmd){ if(psmd->psys->part->distr==PART_DISTR_GRID){ if(vec){ @@ -819,10 +865,10 @@ void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int return; } /* we cant use the num_dmcache */ - psys_particle_on_dm(ob, psmd->dm,from,index,index_dmcache,fuv,foffset,vec,nor,utan,vtan); + psys_particle_on_dm(ob, psmd->dm,from,index,index_dmcache,fuv,foffset,vec,nor,utan,vtan,orco,ornor); } else - psys_particle_on_shape(from,index,fuv,vec,nor,utan,vtan); + psys_particle_on_shape(from,index,fuv,vec,nor,utan,vtan,orco,ornor); } /************************************************/ @@ -1293,27 +1339,25 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys KDTree *tree; ChildParticle *cpa; int p, totparent,totchild=psys->totchild; - float co[3], *orcos=0; + float co[3], orco[3]; int from=PART_FROM_FACE; totparent=(int)(totchild*part->parents*0.3); tree=BLI_kdtree_new(totparent); for(p=0,cpa=psys->child; p<totparent; p++,cpa++){ - psys_particle_on_emitter(ob,psmd,from,cpa->num,-1,cpa->fuv,cpa->foffset,co,0,0,0); - BLI_kdtree_insert(tree, p, co, NULL); + psys_particle_on_emitter(ob,psmd,from,cpa->num,-1,cpa->fuv,cpa->foffset,co,0,0,0,orco,0); + BLI_kdtree_insert(tree, p, orco, NULL); } BLI_kdtree_balance(tree); for(; p<totchild; p++,cpa++){ - psys_particle_on_emitter(ob,psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0); - cpa->parent=BLI_kdtree_find_nearest(tree, co, NULL, NULL); + psys_particle_on_emitter(ob,psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0); + cpa->parent=BLI_kdtree_find_nearest(tree, orco, NULL, NULL); } BLI_kdtree_free(tree); - if(orcos) - MEM_freeN(orcos); } static void get_strand_normal(Material *ma, float *surfnor, float surfdist, float *nor) @@ -1434,7 +1478,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleData *pa; ParticleTexture ptex; float *cpa_fuv=0; - float orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3]; + float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3]; float branch_begin, branch_end, branch_prob, branchfac, rough_rand; float pa_rough1, pa_rough2, pa_roughe, length, pa_length, pa_clump, pa_kink; float max_length = 1.0f, cur_length = 0.0f; @@ -1497,10 +1541,10 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, cpa_fuv = cpa->fuv; cpa_from = PART_FROM_FACE; - psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,orco,ornor,0,0); + psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0); /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ - VECCOPY(cpa_1st,orco); + VECCOPY(cpa_1st,co); Mat4MulVecfl(ob->obmat,cpa_1st); pa=0; @@ -1523,7 +1567,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, cpa_num=pa->num; cpa_fuv=pa->fuv; - psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,orco,ornor,0,0); + psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0); } keys->steps = ctx->steps; @@ -2216,7 +2260,7 @@ void psys_mat_hair_to_object(Object *ob, DerivedMesh *dm, short from, ParticleDa float vec[3]; psys_face_mat(dm, pa, hairmat); - psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 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); } @@ -2574,7 +2618,7 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd { MTex *mtex; int m; - float value, rgba[4], texco[3]; + float value, rgba[4], co[3], texco[3]; int setvars=0; if(ma) for(m=0; m<MAX_MTEX; m++){ @@ -2604,12 +2648,12 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd /* <jahka> anyways I think it will be too small a difference to notice, so psys_get_texture should only know about the original mesh structure.. no dm needed anywhere */ /* <brecht> the code only does dm based lookup now, so passing num_dmcache anyway to avoid^ * massive slowdown here */ - psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,texco,0,0,0); + psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0); } else{ //psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->fuv,pa->offset,texco,0,0,0); /* ditto above */ - psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,texco,0,0,0); + psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0); } externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3); @@ -2740,7 +2784,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle ParticleKey *par=0, keys[4]; float t, real_t, dfra, keytime; - float orco[3]; + float co[3], orco[3]; float imat[4][4], hairmat[4][4], cpa_1st[3]; float pa_clump = 0.0, pa_kink = 0.0; int totparent = 0; @@ -2877,10 +2921,10 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle cpa_fuv = cpa->fuv; cpa_from = PART_FROM_FACE; - psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,orco,0,0,0); + psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,0,0,0,orco,0); /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ - VECCOPY(cpa_1st,orco); + VECCOPY(cpa_1st,co); //w=0; //while(w<4 && cpa->pa[w]>=0){ @@ -2909,7 +2953,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle cpa_num=pa->num; cpa_fuv=pa->fuv; - psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,orco,0,0,0); + psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,0,0,0,orco,0); } /* correct child ipo timing */ diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index c8a0c2632be..414b64cae6a 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -75,6 +75,7 @@ #include "BKE_depsgraph.h" #include "BKE_lattice.h" #include "BKE_pointcache.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BSE_headerbuttons.h" @@ -473,7 +474,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C DerivedMesh *dm= ctx->dm; ParticleData *tpars=0, *tpa; ParticleSettings *part= ctx->psys->part; - float *v1, *v2, *v3, *v4, nor[3], co1[3], co2[3], nor1[3]; + float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3]; float cur_d, min_d; int from= ctx->from; int cfrom= ctx->cfrom; @@ -492,8 +493,8 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C KDTreeNearest ptn[3]; int w, maxw; - psys_particle_on_dm(ctx->ob,ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0); - maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,co1,NULL,ptn); + psys_particle_on_dm(ctx->ob,ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0); + maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,orco1,NULL,ptn); for(w=0; w<maxw; w++){ pa->verts[w]=ptn->num; @@ -532,7 +533,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C tot=dm->getNumFaces(dm); - psys_interpolate_face(mvert,mface,0,pa->fuv,co1,nor,0,0); + psys_interpolate_face(mvert,mface,0,0,pa->fuv,co1,nor,0,0,0,0); Normalize(nor); VecMulf(nor,-100.0); @@ -631,8 +632,8 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams); - psys_particle_on_dm(ob,dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0); - maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,co1,nor1,ptn); + psys_particle_on_dm(ob,dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1); + maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn); maxd=ptn[maxw-1].dist; mind=ptn[0].dist; @@ -642,7 +643,8 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C for(w=0; w<maxw; w++){ parent[w]=ptn[w].index; pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd)); - //totw+=cpa->w[w]; + //pweight[w]= (1.0f - ptn[w].dist*ptn[w].dist/(maxd*maxd)); + //pweight[w] *= pweight[w]; } for(;w<10; w++){ parent[w]=-1; @@ -790,7 +792,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm //int *vertpart=0; int jitlevel= 1, distr; float *weight=0,*sum=0,*jitoff=0; - float cur, maxweight=0.0, tweight, totweight, co[3], nor[3]; + float cur, maxweight=0.0, tweight, totweight, co[3], nor[3], orco[3], ornor[3]; if(ob==0 || psys==0 || psys->part==0) return 0; @@ -817,8 +819,8 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm tree=BLI_kdtree_new(totpart); for(p=0,pa=psys->particles; p<totpart; p++,pa++){ - psys_particle_on_dm(ob,dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0); - BLI_kdtree_insert(tree, p, co, nor); + psys_particle_on_dm(ob,dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor); + BLI_kdtree_insert(tree, p, orco, ornor); } BLI_kdtree_balance(tree); @@ -908,16 +910,23 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm return 0; } + /* we need orco for consistent distributions */ + DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); + distr=part->distr; pa=psys->particles; if(from==PART_FROM_VERT){ - MVert *mv= dm->getVertDataArray(dm,0); + MVert *mv= dm->getVertDataArray(dm, CD_MVERT); + float (*orcodata)[3]= dm->getVertDataArray(dm, CD_ORCO); int totvert = dm->getNumVerts(dm); tree=BLI_kdtree_new(totvert); - for(p=0; p<totvert; p++,mv++){ - VECCOPY(co,mv->co); + for(p=0; p<totvert; p++){ + if(orcodata) + VECCOPY(co,orcodata[p]) + else + VECCOPY(co,mv[p].co) BLI_kdtree_insert(tree,p,co,NULL); } @@ -981,20 +990,34 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm /* 2.1 */ if((part->flag&PART_EDISTR || children) && ELEM(from,PART_FROM_PARTICLE,PART_FROM_VERT)==0){ - float totarea=0.0; + float totarea=0.0, *co1, *co2, *co3, *co4; + float (*orcodata)[3]; + + orcodata= dm->getVertDataArray(dm, CD_ORCO); for(i=0; i<tot; i++){ MFace *mf=dm->getFaceData(dm,i,CD_MFACE); - MVert *mv1=dm->getVertData(dm,mf->v1,CD_MVERT); - MVert *mv2=dm->getVertData(dm,mf->v2,CD_MVERT); - MVert *mv3=dm->getVertData(dm,mf->v3,CD_MVERT); + + if(orcodata) { + co1= orcodata[mf->v1]; + co2= orcodata[mf->v2]; + co3= orcodata[mf->v3]; + } + else { + co1= ((MVert*)dm->getVertData(dm,mf->v1,CD_MVERT))->co; + co2= ((MVert*)dm->getVertData(dm,mf->v2,CD_MVERT))->co; + co3= ((MVert*)dm->getVertData(dm,mf->v3,CD_MVERT))->co; + } if (mf->v4){ - MVert *mv4=dm->getVertData(dm,mf->v4,CD_MVERT); - cur= AreaQ3Dfl(mv1->co,mv2->co,mv3->co,mv4->co); + if(orcodata) + co4= orcodata[mf->v4]; + else + co4= ((MVert*)dm->getVertData(dm,mf->v4,CD_MVERT))->co; + cur= AreaQ3Dfl(co1, co2, co3, co4); } else - cur= AreaT3Dfl(mv1->co,mv2->co,mv3->co); + cur= AreaT3Dfl(co1, co2, co3); if(cur>maxweight) maxweight=cur; @@ -1516,7 +1539,7 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi where_is_object_time(ob,pa->time); /* get birth location from object */ - psys_particle_on_emitter(ob,psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan); + psys_particle_on_emitter(ob,psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0); /* save local coordinates for later */ VECCOPY(tloc,loc); @@ -2415,7 +2438,7 @@ static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemMo ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations"); for(p=0,pa=psys->particles; p<totpart; p++, pa++){ - psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0); + psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0); Mat4MulVecfl(ob->obmat,loc); ec->distances[p]=VecLenf(loc,vec); VECSUB(loc,loc,vec); @@ -3125,7 +3148,7 @@ static void deflect_particle(Object *pob, ParticleSystemModifierData *psmd, Part } else{ /* get deflection point & normal */ - psys_interpolate_face(mvert,mface,0,min_w,ipoint,unit_nor,0,0); + psys_interpolate_face(mvert,mface,0,0,min_w,ipoint,unit_nor,0,0,0,0); if(global){ Mat4Mul3Vecfl(ob->obmat,unit_nor); Mat4MulVecfl(ob->obmat,ipoint); @@ -3338,7 +3361,7 @@ static int boid_see_mesh(ListBase *lb, Object *pob, ParticleSystem *psys, float mvert=dm->getVertDataArray(dm,CD_MVERT); /* get deflection point & normal */ - psys_interpolate_face(mvert,mface,0,min_w,loc,nor,0,0); + psys_interpolate_face(mvert,mface,0,0,min_w,loc,nor,0,0,0,0); VECADD(nor,nor,loc); Mat4MulVecfl(ob->obmat,loc); @@ -3834,7 +3857,7 @@ static void boid_body(BoidVecFunc *bvf, ParticleData *pa, ParticleSystem *psys, mvert=dm->getVertDataArray(dm,CD_MVERT); /* get deflection point & normal */ - psys_interpolate_face(mvert,mface,0,min_w,loc,nor,0,0); + psys_interpolate_face(mvert,mface,0,0,min_w,loc,nor,0,0,0,0); Mat4MulVecfl(zob->obmat,loc); Mat4Mul3Vecfl(zob->obmat,nor); diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 249a4a5c36c..09af11fa64b 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -68,7 +68,8 @@ typedef struct CustomData { #define CD_PROP_INT 11 #define CD_PROP_STR 12 #define CD_ORIGSPACE 13 /* for modifier stack face location mapping */ -#define CD_NUMTYPES 14 +#define CD_ORCO 14 +#define CD_NUMTYPES 15 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -85,6 +86,7 @@ typedef struct CustomData { #define CD_MASK_PROP_INT (1 << CD_PROP_INT) #define CD_MASK_PROP_STR (1 << CD_PROP_STR) #define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE) +#define CD_MASK_ORCO (1 << CD_ORCO) /* CustomData.flag */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 9bf62e52f31..127f2d427d5 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -966,9 +966,7 @@ static float *get_object_orco(Render *re, Object *ob) orco = BLI_ghash_lookup(re->orco_hash, ob); if (!orco) { - if (ob->type==OB_MESH) { - orco = mesh_create_orco_render(ob); - } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { + if (ELEM(ob->type, OB_CURVE, OB_FONT)) { orco = make_orco_curve(ob); } else if (ob->type==OB_SURF) { orco = make_orco_surf(ob); @@ -981,6 +979,14 @@ static float *get_object_orco(Render *re, Object *ob) return orco; } +static void set_object_orco(Render *re, void *ob, float *orco) +{ + if (!re->orco_hash) + re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + + BLI_ghash_insert(re->orco_hash, ob, orco); +} + static void free_mesh_orco_hash(Render *re) { if (re->orco_hash) { @@ -1727,7 +1733,7 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps StrandVert *svert=0; StrandRen *strand=0; RNG *rng= 0; - float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],ornor[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 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; @@ -1859,9 +1865,7 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps if(path_nbr) { if((ma->mode & (MA_HALO|MA_WIRE))==0) { orco= MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos"); - if (!re->orco_hash) - re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - BLI_ghash_insert(re->orco_hash, psys, orco); + set_object_orco(re, psys, orco); } path=1; } @@ -1932,10 +1936,10 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps /* get orco */ if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ tpa=tpsys->particles+pa->num; - psys_particle_on_emitter(ob, psmd,tpart->from,tpa->num, -1,tpa->fuv,tpa->foffset,orco,ornor,0,0); + psys_particle_on_emitter(ob, psmd,tpart->from,tpa->num, -1,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0); } else - psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,orco,ornor,0,0); + psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,co,nor,0,0,orco,0); if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE); @@ -1988,7 +1992,7 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps /* get orco */ psys_particle_on_emitter(ob, psmd, (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE, - cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,orco,ornor,0,0); + cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,nor,0,0,orco,0); if(uvco){ layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE); @@ -2040,8 +2044,8 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps } if(ma->mode_l & MA_STR_SURFDIFF) { - Mat3MulVecfl(nmat, ornor); - surfnor= ornor; + Mat3MulVecfl(nmat, nor); + surfnor= nor; } else surfnor= NULL; @@ -2208,9 +2212,7 @@ static void render_static_particle_system(Render *re, Object *ob, PartEff *paf) /* orcos */ if(!(ma->mode & (MA_HALO|MA_WIRE))) { orco= MEM_mallocN(3*sizeof(float)*paf->totpart, "static particle orcos"); - if (!re->orco_hash) - re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - BLI_ghash_insert(re->orco_hash, paf, orco); /* pointer is particles, otherwise object uses it */ + set_object_orco(re, paf, orco); } mesh_get_texspace(ob->data, loc_tex, NULL, size_tex); @@ -2653,6 +2655,7 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts MSticky *ms = NULL; PartEff *paf; DerivedMesh *dm; + CustomDataMask mask; float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], float *orco=0; int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs; @@ -2716,14 +2719,22 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts if(test_for_displace(re, ob ) ) only_verts= 0; + mask= CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; if(!only_verts) - if(need_orco) orco = get_object_orco(re, ob); + if(need_orco) + mask |= CD_MASK_ORCO; - dm = mesh_create_derived_render(ob, - CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL); - + dm= mesh_create_derived_render(ob, mask); if(dm==NULL) return; /* in case duplicated object fails? */ + if(mask & CD_MASK_ORCO) { + orco= dm->getVertDataArray(dm, CD_ORCO); + if(orco) { + orco= MEM_dupallocN(orco); + set_object_orco(re, ob, orco); + } + } + if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&& (ob->fluidsimSettings->meshSurface) ) { @@ -4909,7 +4920,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce) /* exported call to recalculate hoco for vertices, when winmat changed */ void RE_DataBase_ApplyWindow(Render *re) { - project_renderdata(re, projectverto, 0, 0, 1); + project_renderdata(re, projectverto, 0, 0, 0); } /* setup for shaded view or bake, so only lamps and materials are initialized */ diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c index d2ac7bc5761..fc839f7e80b 100644 --- a/source/blender/src/editparticle.c +++ b/source/blender/src/editparticle.c @@ -2272,7 +2272,7 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe tree=BLI_kdtree_new(psys->totpart); for(i=0, pa=psys->particles; i<totpart; i++, pa++) { - psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,cur_co,0,0,0); + psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,cur_co,0,0,0,0,0); BLI_kdtree_insert(tree, i, cur_co, NULL); } @@ -2311,7 +2311,7 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe int w, maxw; float maxd, mind, dd, totw=0.0, weight[3]; - psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0); + psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,0,0); maxw = BLI_kdtree_find_n_nearest(tree,3,co1,NULL,ptn); maxd = ptn[maxw-1].dist; |