4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2005 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Blender Foundation,
27 * ***** END GPL LICENSE BLOCK *****
30 /** \file blender/editors/util/crazyspace.c
35 #include "MEM_guardedalloc.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_modifier_types.h"
40 #include "DNA_meshdata_types.h"
42 #include "BKE_DerivedMesh.h"
43 #include "BKE_modifier.h"
44 #include "BKE_multires.h"
47 #include "BLI_utildefines.h"
49 #include "BLI_editVert.h"
58 #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])
59 static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
61 float vecu[3], vecv[3];
64 TAN_MAKE_VEC(vecu, v1, v2);
65 TAN_MAKE_VEC(vecv, v1, v3);
66 tri_to_quat( q1,v1, vecu, vecv);
68 TAN_MAKE_VEC(vecu, def1, def2);
69 TAN_MAKE_VEC(vecv, def1, def3);
70 tri_to_quat( q2,def1, vecu, vecv);
72 sub_qt_qtqt(quat, q2, q1);
76 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
78 MappedUserData *mappedData= (MappedUserData*)userData;
79 float *vec = mappedData->vertexcos;
82 if(!mappedData->flags[index]) {
83 /* we need coord from prototype vertex, not it clones or images,
84 suppose they stored in the beginning of vertex array stored in DM */
86 mappedData->flags[index]= 1;
90 static int modifiers_disable_subsurf_temporary(Object *ob)
95 for(md=ob->modifiers.first; md; md=md->next)
96 if(md->type==eModifierType_Subsurf)
97 if(md->mode & eModifierMode_OnCage) {
98 md->mode ^= eModifierMode_DisableTemporary;
105 /* disable subsurf temporal, get mapped cos, and enable it */
106 float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit)
108 Mesh *me= obedit->data;
111 int nverts= me->edit_mesh->totvert;
113 MappedUserData userData;
115 /* disable subsurf temporal, get mapped cos, and enable it */
116 if(modifiers_disable_subsurf_temporary(obedit)) {
117 /* need to make new derivemesh */
118 makeDerivedMesh(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH);
121 /* now get the cage */
122 dm= editmesh_get_derived_cage(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH);
124 vertexcos= MEM_callocN(3*sizeof(float)*nverts, "vertexcos map");
125 flags= MEM_callocN(sizeof(short)*nverts, "vertexcos flags");
127 userData.vertexcos= vertexcos;
128 userData.flags= flags;
129 dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData);
133 /* set back the flag, no new cage needs to be built, transform does it */
134 modifiers_disable_subsurf_temporary(obedit);
141 void crazyspace_set_quats_editmesh(EditMesh *em, float *origcos, float *mappedcos, float *quats)
143 EditVert *eve, *prev;
145 float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
148 /* two abused locations in vertices */
149 for(eve= em->verts.first; eve; eve= eve->next, index++) {
151 eve->prev= (EditVert *)index;
154 /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
155 for(efa= em->faces.first; efa; efa= efa->next) {
157 /* retrieve mapped coordinates */
158 v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
159 v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
160 v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
162 co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
163 co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
164 co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
166 if(efa->v2->tmp.p==NULL && efa->v2->f1) {
167 set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
168 efa->v2->tmp.p= (void*)quats;
173 v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
174 co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
176 if(efa->v1->tmp.p==NULL && efa->v1->f1) {
177 set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
178 efa->v1->tmp.p= (void*)quats;
181 if(efa->v3->tmp.p==NULL && efa->v3->f1) {
182 set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
183 efa->v3->tmp.p= (void*)quats;
186 if(efa->v4->tmp.p==NULL && efa->v4->f1) {
187 set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
188 efa->v4->tmp.p= (void*)quats;
193 if(efa->v1->tmp.p==NULL && efa->v1->f1) {
194 set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
195 efa->v1->tmp.p= (void*)quats;
198 if(efa->v3->tmp.p==NULL && efa->v3->f1) {
199 set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
200 efa->v3->tmp.p= (void*)quats;
206 /* restore abused prev pointer */
207 for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
212 void crazyspace_set_quats_mesh(Mesh *me, float *origcos, float *mappedcos, float *quats)
217 float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
220 for(i=0; i<me->totvert; i++, mvert++)
221 mvert->flag&= ~ME_VERT_TMP_TAG;
223 /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
226 for(i=0; i<me->totface; i++, mface++) {
228 /* retrieve mapped coordinates */
229 v1= mappedcos + 3*mface->v1;
230 v2= mappedcos + 3*mface->v2;
231 v3= mappedcos + 3*mface->v3;
233 co1= (origcos)? origcos + 3*mface->v1: mvert[mface->v1].co;
234 co2= (origcos)? origcos + 3*mface->v2: mvert[mface->v2].co;
235 co3= (origcos)? origcos + 3*mface->v3: mvert[mface->v3].co;
237 if((mvert[mface->v2].flag&ME_VERT_TMP_TAG)==0) {
238 set_crazy_vertex_quat(&quats[mface->v2*4], co2, co3, co1, v2, v3, v1);
239 mvert[mface->v2].flag|= ME_VERT_TMP_TAG;
243 v4= mappedcos + 3*mface->v4;
244 co4= (origcos)? origcos + 3*mface->v4: mvert[mface->v4].co;
246 if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
247 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co4, v1, v2, v4);
248 mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
250 if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
251 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co4, co2, v3, v4, v2);
252 mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
254 if((mvert[mface->v4].flag&ME_VERT_TMP_TAG)==0) {
255 set_crazy_vertex_quat(&quats[mface->v4*4], co4, co1, co3, v4, v1, v3);
256 mvert[mface->v4].flag|= ME_VERT_TMP_TAG;
260 if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
261 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co3, v1, v2, v3);
262 mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
264 if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
265 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co1, co2, v3, v1, v2);
266 mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
272 int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
276 int i, a, numleft = 0, numVerts = 0;
277 int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
278 float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
280 modifiers_clearErrors(ob);
283 md = modifiers_getVirtualModifierList(ob);
285 /* compute the deformation matrices and coordinates for the first
286 modifiers with on cage editing that are enabled and support computing
288 for(i = 0; md && i <= cageIndex; i++, md = md->next) {
289 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
291 if(!editmesh_modifier_is_enabled(scene, md, dm))
294 if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
296 dm= editmesh_get_derived(em, NULL);
297 deformedVerts= editmesh_get_vertex_cos(em, &numVerts);
298 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
300 for(a=0; a<numVerts; a++)
304 mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
311 for(; md && i <= cageIndex; md = md->next, i++)
312 if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
318 *deformmats= defmats;
319 *deformcos= deformedVerts;
324 int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
329 float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL;
330 MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
331 int has_multires = mmd != NULL && mmd->sculptlvl > 0;
341 md= modifiers_getVirtualModifierList(ob);
343 for(; md; md= md->next) {
344 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
346 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
348 if(mti->type==eModifierTypeType_OnlyDeform) {
350 Mesh *me= (Mesh*)ob->data;
351 dm= mesh_create_derived(me, ob, NULL);
352 deformedVerts= mesh_getVertexCos(me, &numVerts);
353 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
355 for(a=0; a<numVerts; a++)
359 if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
364 for(; md; md= md->next) {
365 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
367 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
369 if(mti->type==eModifierTypeType_OnlyDeform)
376 *deformmats= defmats;
377 *deformcos= deformedVerts;
382 void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
384 int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);
387 /* there are deformation modifier which doesn't support deformation matricies
388 calculation. Need additional crazyspace correction */
390 float (*deformedVerts)[3]= *deformcos;
391 float (*origVerts)[3]= MEM_dupallocN(deformedVerts);
394 ModifierData *md= modifiers_getVirtualModifierList(ob);
395 Mesh *me= (Mesh*)ob->data;
397 for(; md; md= md->next) {
398 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
400 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
402 if(mti->type==eModifierTypeType_OnlyDeform) {
403 /* skip leading modifiers which have been already
404 handled in sculpt_get_first_deform_matrices */
405 if(mti->deformMatrices && !deformed)
408 mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0);
413 quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats");
415 crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats);
417 for(i=0; i<me->totvert; i++) {
418 float qmat[3][3], tmat[3][3];
420 quat_to_mat3(qmat, &quats[i*4]);
421 mul_m3_m3m3(tmat, qmat, (*deformmats)[i]);
422 copy_m3_m3((*deformmats)[i], tmat);
425 MEM_freeN(origVerts);