Blender V2.61 - r43446

crazyspace.c

Go to the documentation of this file.
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 }