Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2005 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * 00022 * Contributor(s): Blender Foundation, 00023 * Sergey Sharybin 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include "MEM_guardedalloc.h" 00034 00035 #include "DNA_scene_types.h" 00036 #include "DNA_object_types.h" 00037 #include "DNA_modifier_types.h" 00038 #include "DNA_meshdata_types.h" 00039 00040 #include "BKE_DerivedMesh.h" 00041 #include "BKE_modifier.h" 00042 #include "BKE_multires.h" 00043 #include "BKE_mesh.h" 00044 00045 #include "BLI_utildefines.h" 00046 #include "BLI_math.h" 00047 #include "BLI_editVert.h" 00048 00049 #include "ED_util.h" 00050 00051 typedef struct { 00052 float *vertexcos; 00053 short *flags; 00054 } MappedUserData; 00055 00056 #define TAN_MAKE_VEC(a, b, c) a[0]= b[0] + 0.2f*(b[0]-c[0]); a[1]= b[1] + 0.2f*(b[1]-c[1]); a[2]= b[2] + 0.2f*(b[2]-c[2]) 00057 static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3) 00058 { 00059 float vecu[3], vecv[3]; 00060 float q1[4], q2[4]; 00061 00062 TAN_MAKE_VEC(vecu, v1, v2); 00063 TAN_MAKE_VEC(vecv, v1, v3); 00064 tri_to_quat( q1,v1, vecu, vecv); 00065 00066 TAN_MAKE_VEC(vecu, def1, def2); 00067 TAN_MAKE_VEC(vecv, def1, def3); 00068 tri_to_quat( q2,def1, vecu, vecv); 00069 00070 sub_qt_qtqt(quat, q2, q1); 00071 } 00072 #undef TAN_MAKE_VEC 00073 00074 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) 00075 { 00076 MappedUserData *mappedData= (MappedUserData*)userData; 00077 float *vec = mappedData->vertexcos; 00078 00079 vec+= 3*index; 00080 if(!mappedData->flags[index]) { 00081 /* we need coord from prototype vertex, not it clones or images, 00082 suppose they stored in the beginning of vertex array stored in DM */ 00083 copy_v3_v3(vec, co); 00084 mappedData->flags[index]= 1; 00085 } 00086 } 00087 00088 static int modifiers_disable_subsurf_temporary(Object *ob) 00089 { 00090 ModifierData *md; 00091 int disabled = 0; 00092 00093 for(md=ob->modifiers.first; md; md=md->next) 00094 if(md->type==eModifierType_Subsurf) 00095 if(md->mode & eModifierMode_OnCage) { 00096 md->mode ^= eModifierMode_DisableTemporary; 00097 disabled= 1; 00098 } 00099 00100 return disabled; 00101 } 00102 00103 /* disable subsurf temporal, get mapped cos, and enable it */ 00104 float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit) 00105 { 00106 Mesh *me= obedit->data; 00107 DerivedMesh *dm; 00108 float *vertexcos; 00109 int nverts= me->edit_mesh->totvert; 00110 short *flags; 00111 MappedUserData userData; 00112 00113 /* disable subsurf temporal, get mapped cos, and enable it */ 00114 if(modifiers_disable_subsurf_temporary(obedit)) { 00115 /* need to make new derivemesh */ 00116 makeDerivedMesh(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH); 00117 } 00118 00119 /* now get the cage */ 00120 dm= editmesh_get_derived_cage(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH); 00121 00122 vertexcos= MEM_callocN(3*sizeof(float)*nverts, "vertexcos map"); 00123 flags= MEM_callocN(sizeof(short)*nverts, "vertexcos flags"); 00124 00125 userData.vertexcos= vertexcos; 00126 userData.flags= flags; 00127 dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData); 00128 00129 dm->release(dm); 00130 00131 /* set back the flag, no new cage needs to be built, transform does it */ 00132 modifiers_disable_subsurf_temporary(obedit); 00133 00134 MEM_freeN(flags); 00135 00136 return vertexcos; 00137 } 00138 00139 void crazyspace_set_quats_editmesh(EditMesh *em, float *origcos, float *mappedcos, float *quats) 00140 { 00141 EditVert *eve, *prev; 00142 EditFace *efa; 00143 float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4; 00144 intptr_t index= 0; 00145 00146 /* two abused locations in vertices */ 00147 for(eve= em->verts.first; eve; eve= eve->next, index++) { 00148 eve->tmp.p = NULL; 00149 eve->prev= (EditVert *)index; 00150 } 00151 00152 /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ 00153 for(efa= em->faces.first; efa; efa= efa->next) { 00154 00155 /* retrieve mapped coordinates */ 00156 v1= mappedcos + 3*(intptr_t)(efa->v1->prev); 00157 v2= mappedcos + 3*(intptr_t)(efa->v2->prev); 00158 v3= mappedcos + 3*(intptr_t)(efa->v3->prev); 00159 00160 co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co; 00161 co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co; 00162 co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co; 00163 00164 if(efa->v2->tmp.p==NULL && efa->v2->f1) { 00165 set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1); 00166 efa->v2->tmp.p= (void*)quats; 00167 quats+= 4; 00168 } 00169 00170 if(efa->v4) { 00171 v4= mappedcos + 3*(intptr_t)(efa->v4->prev); 00172 co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co; 00173 00174 if(efa->v1->tmp.p==NULL && efa->v1->f1) { 00175 set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4); 00176 efa->v1->tmp.p= (void*)quats; 00177 quats+= 4; 00178 } 00179 if(efa->v3->tmp.p==NULL && efa->v3->f1) { 00180 set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2); 00181 efa->v3->tmp.p= (void*)quats; 00182 quats+= 4; 00183 } 00184 if(efa->v4->tmp.p==NULL && efa->v4->f1) { 00185 set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3); 00186 efa->v4->tmp.p= (void*)quats; 00187 quats+= 4; 00188 } 00189 } 00190 else { 00191 if(efa->v1->tmp.p==NULL && efa->v1->f1) { 00192 set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3); 00193 efa->v1->tmp.p= (void*)quats; 00194 quats+= 4; 00195 } 00196 if(efa->v3->tmp.p==NULL && efa->v3->f1) { 00197 set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2); 00198 efa->v3->tmp.p= (void*)quats; 00199 quats+= 4; 00200 } 00201 } 00202 } 00203 00204 /* restore abused prev pointer */ 00205 for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next) 00206 eve->prev= prev; 00207 00208 } 00209 00210 void crazyspace_set_quats_mesh(Mesh *me, float *origcos, float *mappedcos, float *quats) 00211 { 00212 int i; 00213 MVert *mvert; 00214 MFace *mface; 00215 float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4; 00216 00217 mvert= me->mvert; 00218 for(i=0; i<me->totvert; i++, mvert++) 00219 mvert->flag&= ~ME_VERT_TMP_TAG; 00220 00221 /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ 00222 mvert= me->mvert; 00223 mface= me->mface; 00224 for(i=0; i<me->totface; i++, mface++) { 00225 00226 /* retrieve mapped coordinates */ 00227 v1= mappedcos + 3*mface->v1; 00228 v2= mappedcos + 3*mface->v2; 00229 v3= mappedcos + 3*mface->v3; 00230 00231 co1= (origcos)? origcos + 3*mface->v1: mvert[mface->v1].co; 00232 co2= (origcos)? origcos + 3*mface->v2: mvert[mface->v2].co; 00233 co3= (origcos)? origcos + 3*mface->v3: mvert[mface->v3].co; 00234 00235 if((mvert[mface->v2].flag&ME_VERT_TMP_TAG)==0) { 00236 set_crazy_vertex_quat(&quats[mface->v2*4], co2, co3, co1, v2, v3, v1); 00237 mvert[mface->v2].flag|= ME_VERT_TMP_TAG; 00238 } 00239 00240 if(mface->v4) { 00241 v4= mappedcos + 3*mface->v4; 00242 co4= (origcos)? origcos + 3*mface->v4: mvert[mface->v4].co; 00243 00244 if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) { 00245 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co4, v1, v2, v4); 00246 mvert[mface->v1].flag|= ME_VERT_TMP_TAG; 00247 } 00248 if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) { 00249 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co4, co2, v3, v4, v2); 00250 mvert[mface->v3].flag|= ME_VERT_TMP_TAG; 00251 } 00252 if((mvert[mface->v4].flag&ME_VERT_TMP_TAG)==0) { 00253 set_crazy_vertex_quat(&quats[mface->v4*4], co4, co1, co3, v4, v1, v3); 00254 mvert[mface->v4].flag|= ME_VERT_TMP_TAG; 00255 } 00256 } 00257 else { 00258 if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) { 00259 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co3, v1, v2, v3); 00260 mvert[mface->v1].flag|= ME_VERT_TMP_TAG; 00261 } 00262 if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) { 00263 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co1, co2, v3, v1, v2); 00264 mvert[mface->v3].flag|= ME_VERT_TMP_TAG; 00265 } 00266 } 00267 } 00268 } 00269 00270 int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3]) 00271 { 00272 ModifierData *md; 00273 DerivedMesh *dm; 00274 int i, a, numleft = 0, numVerts = 0; 00275 int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1); 00276 float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL; 00277 00278 modifiers_clearErrors(ob); 00279 00280 dm = NULL; 00281 md = modifiers_getVirtualModifierList(ob); 00282 00283 /* compute the deformation matrices and coordinates for the first 00284 modifiers with on cage editing that are enabled and support computing 00285 deform matrices */ 00286 for(i = 0; md && i <= cageIndex; i++, md = md->next) { 00287 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00288 00289 if(!editmesh_modifier_is_enabled(scene, md, dm)) 00290 continue; 00291 00292 if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) { 00293 if(!defmats) { 00294 dm= editmesh_get_derived(em, NULL); 00295 deformedVerts= editmesh_get_vertex_cos(em, &numVerts); 00296 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats"); 00297 00298 for(a=0; a<numVerts; a++) 00299 unit_m3(defmats[a]); 00300 } 00301 00302 mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats, 00303 numVerts); 00304 } 00305 else 00306 break; 00307 } 00308 00309 for(; md && i <= cageIndex; md = md->next, i++) 00310 if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md)) 00311 numleft++; 00312 00313 if(dm) 00314 dm->release(dm); 00315 00316 *deformmats= defmats; 00317 *deformcos= deformedVerts; 00318 00319 return numleft; 00320 } 00321 00322 int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) 00323 { 00324 ModifierData *md; 00325 DerivedMesh *dm; 00326 int a, numVerts= 0; 00327 float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL; 00328 MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0); 00329 int has_multires = mmd != NULL && mmd->sculptlvl > 0; 00330 int numleft= 0; 00331 00332 if(has_multires) { 00333 *deformmats= NULL; 00334 *deformcos= NULL; 00335 return numleft; 00336 } 00337 00338 dm= NULL; 00339 md= modifiers_getVirtualModifierList(ob); 00340 00341 for(; md; md= md->next) { 00342 ModifierTypeInfo *mti= modifierType_getInfo(md->type); 00343 00344 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; 00345 00346 if(mti->type==eModifierTypeType_OnlyDeform) { 00347 if(!defmats) { 00348 Mesh *me= (Mesh*)ob->data; 00349 dm= mesh_create_derived(me, ob, NULL); 00350 deformedVerts= mesh_getVertexCos(me, &numVerts); 00351 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats"); 00352 00353 for(a=0; a<numVerts; a++) 00354 unit_m3(defmats[a]); 00355 } 00356 00357 if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts); 00358 else break; 00359 } 00360 } 00361 00362 for(; md; md= md->next) { 00363 ModifierTypeInfo *mti= modifierType_getInfo(md->type); 00364 00365 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; 00366 00367 if(mti->type==eModifierTypeType_OnlyDeform) 00368 numleft++; 00369 } 00370 00371 if(dm) 00372 dm->release(dm); 00373 00374 *deformmats= defmats; 00375 *deformcos= deformedVerts; 00376 00377 return numleft; 00378 } 00379 00380 void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) 00381 { 00382 int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos); 00383 00384 if(totleft) { 00385 /* there are deformation modifier which doesn't support deformation matrices 00386 calculation. Need additional crazyspace correction */ 00387 00388 float (*deformedVerts)[3]= *deformcos; 00389 float (*origVerts)[3]= MEM_dupallocN(deformedVerts); 00390 float *quats= NULL; 00391 int i, deformed= 0; 00392 ModifierData *md= modifiers_getVirtualModifierList(ob); 00393 Mesh *me= (Mesh*)ob->data; 00394 00395 for(; md; md= md->next) { 00396 ModifierTypeInfo *mti= modifierType_getInfo(md->type); 00397 00398 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; 00399 00400 if(mti->type==eModifierTypeType_OnlyDeform) { 00401 /* skip leading modifiers which have been already 00402 handled in sculpt_get_first_deform_matrices */ 00403 if(mti->deformMatrices && !deformed) 00404 continue; 00405 00406 mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0); 00407 deformed= 1; 00408 } 00409 } 00410 00411 quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats"); 00412 00413 crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats); 00414 00415 for(i=0; i<me->totvert; i++) { 00416 float qmat[3][3], tmat[3][3]; 00417 00418 quat_to_mat3(qmat, &quats[i*4]); 00419 mul_m3_m3m3(tmat, qmat, (*deformmats)[i]); 00420 copy_m3_m3((*deformmats)[i], tmat); 00421 } 00422 00423 MEM_freeN(origVerts); 00424 MEM_freeN(quats); 00425 } 00426 00427 if(!*deformmats) { 00428 int a, numVerts; 00429 Mesh *me= (Mesh*)ob->data; 00430 00431 *deformcos= mesh_getVertexCos(me, &numVerts); 00432 *deformmats= MEM_callocN(sizeof(*(*deformmats))*numVerts, "defmats"); 00433 00434 for(a=0; a<numVerts; a++) 00435 unit_m3((*deformmats)[a]); 00436 } 00437 }