4c5f660249eea8fd7f6705bb13015ba433b3a546
[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 <math.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #ifdef WIN32
42 #include "BLI_winstuff.h"
43 #endif
44 #include "MEM_guardedalloc.h"
45
46 #include "BLI_blenlib.h"
47 #include "BLI_arithb.h"
48
49 #include "DNA_object_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_lattice_types.h"
52 #include "DNA_curve_types.h"
53 #include "DNA_key_types.h"
54 #include "DNA_view3d_types.h"
55
56 #include "BKE_key.h"
57 #include "BKE_displist.h"
58 #include "BKE_lattice.h"
59 #include "BKE_global.h"
60
61 #include "BIF_toolbox.h"
62 #include "BIF_space.h"
63 #include "BIF_screen.h"
64 #include "BIF_editlattice.h"
65 #include "BIF_editkey.h"
66
67 #include "BSE_edit.h"
68
69 #include "BDR_editobject.h"
70 #include "BDR_drawobject.h"
71
72 #include "blendef.h"
73 #include "mydevice.h"
74
75 #include "render.h"
76
77 #include "BKE_armature.h"
78
79 void apply_lattice(void)
80 {
81         Base *base;
82         Object *par;
83         
84         if(okee("Apply Lattice Deform")==0) return;
85         
86         base= FIRSTBASE;
87         while(base) {
88                 if TESTBASELIB(base) {
89                         if( (par= base->object->parent) ) {
90                                 if(par->type==OB_LATTICE) {
91                                         
92                                         lt_applyflag= 1;
93                                         object_deform(base->object);
94                                         lt_applyflag= 0;
95                                         
96                                         base->object->parent= 0;
97                                 }
98                         }
99                 }
100                 base= base->next;
101         }
102         
103         allqueue(REDRAWVIEW3D, 0);
104 }
105
106 /* ***************************** */
107
108
109
110
111 void free_editLatt(void)
112 {
113         if(editLatt) {
114                 if(editLatt->def) MEM_freeN(editLatt->def);
115                 MEM_freeN(editLatt);
116                 editLatt= 0;
117         }
118 }
119
120
121 static void setflagsLatt(int flag)
122 {
123         BPoint *bp;
124         int a;
125         
126         bp= editLatt->def;
127         
128         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
129         
130         while(a--) {
131                 if(bp->hide==0) {
132                         bp->f1= flag;
133                 }
134                 bp++;
135         }
136 }
137
138
139
140 void make_editLatt(void)
141 {
142         Lattice *lt;
143         KeyBlock *actkey=0;
144         
145         free_editLatt();
146         
147         lt= G.obedit->data;
148
149         /* keys? */
150         if(lt->key) {
151                 actkey= lt->key->block.first;
152                 while(actkey) {
153                         if(actkey->flag & SELECT) break;
154                         actkey= actkey->next;
155                 }
156         }
157
158         if(actkey) {
159                 key_to_latt(actkey, lt);
160         }
161
162         editLatt= MEM_dupallocN(lt);
163         
164         editLatt->def= MEM_dupallocN(lt->def);
165         
166         setflagsLatt(0);
167 }
168
169
170 void load_editLatt(void)
171 {
172         Lattice *lt;
173         KeyBlock *actkey=0;
174         BPoint *bp;
175         float *fp;
176         int tot;
177         
178         lt= G.obedit->data;
179         
180         /* are there keys? */
181         if(lt->key) {
182                 actkey= lt->key->block.first;
183                 while(actkey) {
184                         if(actkey->flag & SELECT) break;
185                         actkey= actkey->next;
186                 }
187         }
188
189         if(actkey) {
190                 /* active key: vertices */
191                 tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
192                 
193                 if(actkey->data) MEM_freeN(actkey->data);
194                 
195                 fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data");
196                 actkey->totelem= tot;
197         
198                 bp= editLatt->def;
199                 while(tot--) {
200                         VECCOPY(fp, bp->vec);
201                         fp+= 3;
202                         bp++;
203                 }
204                 
205                 if(actkey) do_spec_key(lt->key);
206         }
207         else {
208
209                 MEM_freeN(lt->def);
210         
211                 lt->def= MEM_dupallocN(editLatt->def);
212
213                 lt->flag= editLatt->flag;
214
215                 lt->pntsu= editLatt->pntsu;
216                 lt->pntsv= editLatt->pntsv;
217                 lt->pntsw= editLatt->pntsw;
218                 
219                 lt->typeu= editLatt->typeu;
220                 lt->typev= editLatt->typev;
221                 lt->typew= editLatt->typew;
222         }
223 }
224
225 void remake_editLatt(void)
226 {
227         if(okee("Reload Original data")==0) return;
228         
229         make_editLatt();
230         allqueue(REDRAWVIEW3D, 0);
231         allqueue(REDRAWBUTSEDIT, 0);
232 }
233
234
235 void deselectall_Latt(void)
236 {
237         BPoint *bp;
238         int a;
239         
240         bp= editLatt->def;
241         
242         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
243         
244         allqueue(REDRAWVIEW3D, 0);
245         
246         while(a--) {
247                 if(bp->hide==0) {
248                         if(bp->f1) {
249                                 setflagsLatt(0);
250                                 return;
251                         }
252                 }
253                 bp++;
254         }
255         setflagsLatt(1);
256 }
257
258
259 static BPoint *findnearestLattvert(int sel)
260 {
261         /* sel==1: selected get a disadvantage */
262         /* in bp nearest is written */
263         BPoint *bp1, *bp;
264         short dist= 100, temp, mval[2], a;
265
266         bp= 0;
267
268         /* do projection */
269         calc_lattverts_ext();   /* drawobject.c */
270         
271         getmouseco_areawin(mval);
272
273                         
274         bp1= editLatt->def;
275         
276         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
277         
278         while(a--) {
279                 if(bp1->hide==0) {
280                         temp= abs(mval[0]- bp1->s[0])+ abs(mval[1]- bp1->s[1]);
281                         if( (bp1->f1 & 1)==sel) temp+=5;
282                         if(temp<dist) { 
283                                 bp= bp1; 
284                                 dist= temp; 
285                         }
286                 }
287                 bp1++;
288         }
289
290         return bp;
291 }
292
293
294 void mouse_lattice(void)
295 {
296         BPoint *bp=0;
297
298         bp= findnearestLattvert(1);
299
300         if(bp) {
301                 if((G.qual & LR_SHIFTKEY)==0) {
302                 
303                         setflagsLatt(0);
304                         bp->f1 |= 1;
305
306                         allqueue(REDRAWVIEW3D, 0);
307                 }
308                 else {
309                         
310                         if(bp->f1 & 1) bp->f1 &= ~1;
311                         else bp->f1 |= 1;
312
313                         allqueue(REDRAWVIEW3D, 0);
314
315                 }
316
317                 countall();
318         }
319
320         rightmouse_transform();
321         
322 }