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