Two in one:
[blender.git] / source / blender / src / editlattice.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * i.t.t. wat de naam doet vermoeden: ook algemene lattice (calc) functies
32  */
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <math.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include "MEM_guardedalloc.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_arithb.h"
46
47 #include "DNA_curve_types.h"
48 #include "DNA_key_types.h"
49 #include "DNA_lattice_types.h"
50 #include "DNA_meshdata_types.h"
51 #include "DNA_object_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_view3d_types.h"
54
55 #include "BKE_depsgraph.h"
56 #include "BKE_global.h"
57 #include "BKE_key.h"
58 #include "BKE_lattice.h"
59 #include "BKE_mesh.h"
60 #include "BKE_utildefines.h"
61
62 #include "BIF_editlattice.h"
63 #include "BIF_editmode_undo.h"
64 #include "BIF_editkey.h"
65 #include "BIF_space.h"
66 #include "BIF_screen.h"
67 #include "BIF_toolbox.h"
68
69 #include "BSE_edit.h"
70
71 #include "BDR_editobject.h"
72 #include "BDR_drawobject.h"
73
74 #include "blendef.h"
75 #include "mydevice.h"
76
77 #include "BKE_armature.h"
78
79 /* ***************************** */
80
81 void free_editLatt(void)
82 {
83         if(editLatt) {
84                 if(editLatt->def) MEM_freeN(editLatt->def);
85                 if(editLatt->dvert) 
86                         free_dverts(editLatt->dvert, editLatt->pntsu*editLatt->pntsv*editLatt->pntsw);
87                 
88                 MEM_freeN(editLatt);
89                 editLatt= NULL;
90         }
91 }
92
93
94 static void setflagsLatt(int flag)
95 {
96         BPoint *bp;
97         int a;
98         
99         bp= editLatt->def;
100         
101         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
102         
103         while(a--) {
104                 if(bp->hide==0) {
105                         bp->f1= flag;
106                 }
107                 bp++;
108         }
109 }
110
111
112
113 void make_editLatt(void)
114 {
115         Lattice *lt;
116         KeyBlock *actkey;
117         
118         free_editLatt();
119         
120         lt= G.obedit->data;
121
122         actkey = ob_get_keyblock(G.obedit);
123         if(actkey) {
124                 strcpy(G.editModeTitleExtra, "(Key) ");
125                 key_to_latt(actkey, lt);
126         }
127
128         editLatt= MEM_dupallocN(lt);
129         editLatt->def= MEM_dupallocN(lt->def);
130         
131         if(lt->dvert) {
132                 int tot= lt->pntsu*lt->pntsv*lt->pntsw;
133                 editLatt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
134                 copy_dverts(editLatt->dvert, lt->dvert, tot);
135         }
136         
137         BIF_undo_push("original");
138 }
139
140
141 void load_editLatt(void)
142 {
143         Lattice *lt;
144         KeyBlock *actkey;
145         BPoint *bp;
146         float *fp;
147         int tot;
148         
149         lt= G.obedit->data;
150         
151         actkey = ob_get_keyblock(G.obedit);
152         if(actkey) {
153                 /* active key: vertices */
154                 tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
155                 
156                 if(actkey->data) MEM_freeN(actkey->data);
157                 
158                 fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data");
159                 actkey->totelem= tot;
160         
161                 bp= editLatt->def;
162                 while(tot--) {
163                         VECCOPY(fp, bp->vec);
164                         fp+= 3;
165                         bp++;
166                 }
167         }
168         else {
169
170                 MEM_freeN(lt->def);
171         
172                 lt->def= MEM_dupallocN(editLatt->def);
173
174                 lt->flag= editLatt->flag;
175
176                 lt->pntsu= editLatt->pntsu;
177                 lt->pntsv= editLatt->pntsv;
178                 lt->pntsw= editLatt->pntsw;
179                 
180                 lt->typeu= editLatt->typeu;
181                 lt->typev= editLatt->typev;
182                 lt->typew= editLatt->typew;
183         }
184         
185         if(lt->dvert) {
186                 free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
187                 lt->dvert= NULL;
188         }
189         
190         if(editLatt->dvert) {
191                 int tot= lt->pntsu*lt->pntsv*lt->pntsw;
192                 
193                 lt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
194                 copy_dverts(lt->dvert, editLatt->dvert, tot);
195         }
196         
197 }
198
199 void remake_editLatt(void)
200 {
201         if(okee("Reload original data")==0) return;
202         
203         make_editLatt();
204         allqueue(REDRAWVIEW3D, 0);
205         allqueue(REDRAWBUTSEDIT, 0);
206
207         BIF_undo_push("Reload original");
208 }
209
210
211 void deselectall_Latt(void)
212 {
213         BPoint *bp;
214         int a;
215         
216         bp= editLatt->def;
217         
218         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
219         
220         allqueue(REDRAWVIEW3D, 0);
221         
222         while(a--) {
223                 if(bp->hide==0) {
224                         if(bp->f1) {
225                                 setflagsLatt(0);
226                                 countall();
227                                 BIF_undo_push("(De)select all");
228                                 return;
229                         }
230                 }
231                 bp++;
232         }
233         setflagsLatt(1);
234         countall();
235         BIF_undo_push("(De)select all");
236 }
237
238 static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y)
239 {
240         struct { BPoint *bp; short dist, select, mval[2]; } *data = userData;
241         float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
242         
243         if ((bp->f1&1)==data->select) temp += 5;
244         if (temp<data->dist) {
245                 data->dist = temp;
246
247                 data->bp = bp;
248         }
249 }
250 static BPoint *findnearestLattvert(int sel)
251 {
252                 /* sel==1: selected gets a disadvantage */
253                 /* in nurb and bezt or bp the nearest is written */
254                 /* return 0 1 2: handlepunt */
255         struct { BPoint *bp; short dist, select, mval[2]; } data = {0};
256
257         data.dist = 100;
258         data.select = sel;
259         getmouseco_areawin(data.mval);
260
261         lattice_foreachScreenVert(findnearestLattvert__doClosest, &data);
262
263         return data.bp;
264 }
265
266
267 void mouse_lattice(void)
268 {
269         BPoint *bp=0;
270
271         bp= findnearestLattvert(1);
272
273         if(bp) {
274                 if((G.qual & LR_SHIFTKEY)==0) {
275                 
276                         setflagsLatt(0);
277                         bp->f1 |= 1;
278
279                         allqueue(REDRAWVIEW3D, 0);
280                 }
281                 else {
282                         
283                         if(bp->f1 & 1) bp->f1 &= ~1;
284                         else bp->f1 |= 1;
285
286                         allqueue(REDRAWVIEW3D, 0);
287
288                 }
289
290                 countall();
291                 BIF_undo_push("Select");
292         }
293
294         rightmouse_transform();
295         
296 }
297
298
299 /* **************** undo for lattice object ************** */
300
301 static void undoLatt_to_editLatt(void *defv)
302 {
303         int a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
304
305         memcpy(editLatt->def, defv, a*sizeof(BPoint));
306 }
307
308 static void *editLatt_to_undoLatt(void)
309 {
310         
311         return MEM_dupallocN(editLatt->def);
312 }
313
314 static void free_undoLatt(void *defv)
315 {
316         MEM_freeN(defv);
317 }
318
319 /* and this is all the undo system needs to know */
320 void undo_push_lattice(char *name)
321 {
322         undo_editmode_push(name, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt);
323 }
324
325
326
327 /***/