doxygen: blender/editors tagged.
[blender.git] / source / blender / editors / util / crazyspace.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
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.
10  *
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.
15  *
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.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  *
24  * Contributor(s): Blender Foundation,
25  *                 Sergey Sharybin
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file blender/editors/util/crazyspace.c
31  *  \ingroup edutil
32  */
33
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_scene_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_modifier_types.h"
40 #include "DNA_meshdata_types.h"
41
42 #include "BKE_DerivedMesh.h"
43 #include "BKE_modifier.h"
44 #include "BKE_multires.h"
45 #include "BKE_mesh.h"
46
47 #include "BLI_utildefines.h"
48 #include "BLI_math.h"
49 #include "BLI_editVert.h"
50
51 #include "ED_util.h"
52
53 #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])
54 static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
55 {
56         float vecu[3], vecv[3];
57         float q1[4], q2[4];
58
59         TAN_MAKE_VEC(vecu, v1, v2);
60         TAN_MAKE_VEC(vecv, v1, v3);
61         tri_to_quat( q1,v1, vecu, vecv);
62
63         TAN_MAKE_VEC(vecu, def1, def2);
64         TAN_MAKE_VEC(vecv, def1, def3);
65         tri_to_quat( q2,def1, vecu, vecv);
66
67         sub_qt_qtqt(quat, q2, q1);
68 }
69 #undef TAN_MAKE_VEC
70
71 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
72 {
73         float *vec = userData;
74
75         vec+= 3*index;
76         VECCOPY(vec, co);
77 }
78
79 static int modifiers_disable_subsurf_temporary(Object *ob)
80 {
81         ModifierData *md;
82         int disabled = 0;
83
84         for(md=ob->modifiers.first; md; md=md->next)
85                 if(md->type==eModifierType_Subsurf)
86                         if(md->mode & eModifierMode_OnCage) {
87                                 md->mode ^= eModifierMode_DisableTemporary;
88                                 disabled= 1;
89                         }
90
91         return disabled;
92 }
93
94 /* disable subsurf temporal, get mapped cos, and enable it */
95 float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit)
96 {
97         Mesh *me= obedit->data;
98         DerivedMesh *dm;
99         float *vertexcos;
100
101         /* disable subsurf temporal, get mapped cos, and enable it */
102         if(modifiers_disable_subsurf_temporary(obedit)) {
103                 /* need to make new derivemesh */
104                 makeDerivedMesh(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH);
105         }
106
107         /* now get the cage */
108         dm= editmesh_get_derived_cage(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH);
109
110         vertexcos= MEM_mallocN(3*sizeof(float)*me->edit_mesh->totvert, "vertexcos map");
111         dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
112
113         dm->release(dm);
114
115         /* set back the flag, no new cage needs to be built, transform does it */
116         modifiers_disable_subsurf_temporary(obedit);
117
118         return vertexcos;
119 }
120
121 void crazyspace_set_quats_editmesh(EditMesh *em, float *origcos, float *mappedcos, float *quats)
122 {
123         EditVert *eve, *prev;
124         EditFace *efa;
125         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
126         intptr_t index= 0;
127
128         /* two abused locations in vertices */
129         for(eve= em->verts.first; eve; eve= eve->next, index++) {
130                 eve->tmp.p = NULL;
131                 eve->prev= (EditVert *)index;
132         }
133
134         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
135         for(efa= em->faces.first; efa; efa= efa->next) {
136
137                 /* retrieve mapped coordinates */
138                 v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
139                 v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
140                 v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
141
142                 co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
143                 co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
144                 co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
145
146                 if(efa->v2->tmp.p==NULL && efa->v2->f1) {
147                         set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
148                         efa->v2->tmp.p= (void*)quats;
149                         quats+= 4;
150                 }
151
152                 if(efa->v4) {
153                         v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
154                         co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
155
156                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
157                                 set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
158                                 efa->v1->tmp.p= (void*)quats;
159                                 quats+= 4;
160                         }
161                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
162                                 set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
163                                 efa->v3->tmp.p= (void*)quats;
164                                 quats+= 4;
165                         }
166                         if(efa->v4->tmp.p==NULL && efa->v4->f1) {
167                                 set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
168                                 efa->v4->tmp.p= (void*)quats;
169                                 quats+= 4;
170                         }
171                 }
172                 else {
173                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
174                                 set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
175                                 efa->v1->tmp.p= (void*)quats;
176                                 quats+= 4;
177                         }
178                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
179                                 set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
180                                 efa->v3->tmp.p= (void*)quats;
181                                 quats+= 4;
182                         }
183                 }
184         }
185
186         /* restore abused prev pointer */
187         for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
188                 eve->prev= prev;
189
190 }
191
192 void crazyspace_set_quats_mesh(Mesh *me, float *origcos, float *mappedcos, float *quats)
193 {
194         int i;
195         MVert *mvert;
196         MFace *mface;
197         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
198
199         mvert= me->mvert;
200         for(i=0; i<me->totvert; i++, mvert++)
201                 mvert->flag&= ~ME_VERT_TMP_TAG;
202
203         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
204         mvert= me->mvert;
205         mface= me->mface;
206         for(i=0; i<me->totface; i++, mface++) {
207
208                 /* retrieve mapped coordinates */
209                 v1= mappedcos + 3*mface->v1;
210                 v2= mappedcos + 3*mface->v2;
211                 v3= mappedcos + 3*mface->v3;
212
213                 co1= (origcos)? origcos + 3*mface->v1: mvert[mface->v1].co;
214                 co2= (origcos)? origcos + 3*mface->v2: mvert[mface->v2].co;
215                 co3= (origcos)? origcos + 3*mface->v3: mvert[mface->v3].co;
216
217                 if((mvert[mface->v2].flag&ME_VERT_TMP_TAG)==0) {
218                         set_crazy_vertex_quat(&quats[mface->v2*4], co2, co3, co1, v2, v3, v1);
219                         mvert[mface->v2].flag|= ME_VERT_TMP_TAG;
220                 }
221
222                 if(mface->v4) {
223                         v4= mappedcos + 3*mface->v4;
224                         co4= (origcos)? origcos + 3*mface->v4: mvert[mface->v4].co;
225
226                         if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
227                                 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co4, v1, v2, v4);
228                                 mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
229                         }
230                         if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
231                                 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co4, co2, v3, v4, v2);
232                                 mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
233                         }
234                         if((mvert[mface->v4].flag&ME_VERT_TMP_TAG)==0) {
235                                 set_crazy_vertex_quat(&quats[mface->v4*4], co4, co1, co3, v4, v1, v3);
236                                 mvert[mface->v4].flag|= ME_VERT_TMP_TAG;
237                         }
238                 }
239                 else {
240                         if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
241                                 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co3, v1, v2, v3);
242                                 mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
243                         }
244                         if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
245                                 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co1, co2, v3, v1, v2);
246                                 mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
247                         }
248                 }
249         }
250 }
251
252 int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
253 {
254         ModifierData *md;
255         DerivedMesh *dm;
256         int i, a, numleft = 0, numVerts = 0;
257         int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
258         float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
259
260         modifiers_clearErrors(ob);
261
262         dm = NULL;
263         md = modifiers_getVirtualModifierList(ob);
264
265         /* compute the deformation matrices and coordinates for the first
266            modifiers with on cage editing that are enabled and support computing
267            deform matrices */
268         for(i = 0; md && i <= cageIndex; i++, md = md->next) {
269                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
270
271                 if(!editmesh_modifier_is_enabled(scene, md, dm))
272                         continue;
273
274                 if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
275                         if(!defmats) {
276                                 dm= editmesh_get_derived(em, NULL);
277                                 deformedVerts= editmesh_get_vertex_cos(em, &numVerts);
278                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
279
280                                 for(a=0; a<numVerts; a++)
281                                         unit_m3(defmats[a]);
282                         }
283
284                         mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
285                                 numVerts);
286                 }
287                 else
288                         break;
289         }
290
291         for(; md && i <= cageIndex; md = md->next, i++)
292                 if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
293                         numleft++;
294
295         if(dm)
296                 dm->release(dm);
297
298         *deformmats= defmats;
299         *deformcos= deformedVerts;
300
301         return numleft;
302 }
303
304 int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
305 {
306         ModifierData *md;
307         DerivedMesh *dm;
308         int a, numVerts= 0;
309         float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL;
310         MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
311         int has_multires = mmd != NULL && mmd->sculptlvl > 0;
312         int numleft= 0;
313
314         if(has_multires) {
315                 *deformmats= NULL;
316                 *deformcos= NULL;
317                 return numleft;
318         }
319
320         dm= NULL;
321         md= modifiers_getVirtualModifierList(ob);
322
323         for(; md; md= md->next) {
324                 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
325
326                 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
327
328                 if(mti->type==eModifierTypeType_OnlyDeform) {
329                         if(!defmats) {
330                                 Mesh *me= (Mesh*)ob->data;
331                                 dm= mesh_create_derived(me, ob, NULL);
332                                 deformedVerts= mesh_getVertexCos(me, &numVerts);
333                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
334
335                                 for(a=0; a<numVerts; a++)
336                                         unit_m3(defmats[a]);
337                         }
338
339                         if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
340                         else break;
341                 }
342         }
343
344         for(; md; md= md->next) {
345                 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
346
347                 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
348
349                 if(mti->type==eModifierTypeType_OnlyDeform)
350                         numleft++;
351         }
352
353         if(dm)
354                 dm->release(dm);
355
356         *deformmats= defmats;
357         *deformcos= deformedVerts;
358
359         return numleft;
360 }
361
362 void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
363 {
364         int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);
365
366         if(totleft) {
367                 /* there are deformation modifier which doesn't support deformation matricies
368                    calculation. Need additional crazyspace correction */
369
370                 float (*deformedVerts)[3]= *deformcos;
371                 float (*origVerts)[3]= MEM_dupallocN(deformedVerts);
372                 float *quats= NULL;
373                 int i, deformed= 0;
374                 ModifierData *md= modifiers_getVirtualModifierList(ob);
375                 Mesh *me= (Mesh*)ob->data;
376
377                 for(; md; md= md->next) {
378                         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
379
380                         if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
381
382                         if(mti->type==eModifierTypeType_OnlyDeform) {
383                                 /* skip leading modifiers which have been alredy
384                                    handled in sculpt_get_first_deform_matrices */
385                                 if(mti->deformMatrices && !deformed)
386                                         continue;
387
388                                 mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0);
389                                 deformed= 1;
390                         }
391                 }
392
393                 quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats");
394
395                 crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats);
396
397                 for(i=0; i<me->totvert; i++) {
398                         float qmat[3][3], tmat[3][3];
399
400                         quat_to_mat3(qmat, &quats[i*4]);
401                         mul_m3_m3m3(tmat, qmat, (*deformmats)[i]);
402                         copy_m3_m3((*deformmats)[i], tmat);
403                 }
404
405                 MEM_freeN(origVerts);
406                 MEM_freeN(quats);
407         }
408 }