- added object_apply_deform, removed lt_applyflag global
[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                                         object_apply_deform(base->object);
92                                         
93                                         base->object->parent= 0;
94                                 }
95                         }
96                 }
97                 base= base->next;
98         }
99         
100         allqueue(REDRAWVIEW3D, 0);
101 }
102
103 /* ***************************** */
104
105
106
107
108 void free_editLatt(void)
109 {
110         if(editLatt) {
111                 if(editLatt->def) MEM_freeN(editLatt->def);
112                 MEM_freeN(editLatt);
113                 editLatt= 0;
114         }
115 }
116
117
118 static void setflagsLatt(int flag)
119 {
120         BPoint *bp;
121         int a;
122         
123         bp= editLatt->def;
124         
125         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
126         
127         while(a--) {
128                 if(bp->hide==0) {
129                         bp->f1= flag;
130                 }
131                 bp++;
132         }
133 }
134
135
136
137 void make_editLatt(void)
138 {
139         Lattice *lt;
140         KeyBlock *actkey=0;
141         
142         free_editLatt();
143         
144         lt= G.obedit->data;
145
146         /* keys? */
147         if(lt->key) {
148                 actkey= lt->key->block.first;
149                 while(actkey) {
150                         if(actkey->flag & SELECT) break;
151                         actkey= actkey->next;
152                 }
153         }
154
155         if(actkey) {
156                 key_to_latt(actkey, lt);
157         }
158
159         editLatt= MEM_dupallocN(lt);
160         
161         editLatt->def= MEM_dupallocN(lt->def);
162         
163         setflagsLatt(0);
164 }
165
166
167 void load_editLatt(void)
168 {
169         Lattice *lt;
170         KeyBlock *actkey=0;
171         BPoint *bp;
172         float *fp;
173         int tot;
174         
175         lt= G.obedit->data;
176         
177         /* are there keys? */
178         if(lt->key) {
179                 actkey= lt->key->block.first;
180                 while(actkey) {
181                         if(actkey->flag & SELECT) break;
182                         actkey= actkey->next;
183                 }
184         }
185
186         if(actkey) {
187                 /* active key: vertices */
188                 tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
189                 
190                 if(actkey->data) MEM_freeN(actkey->data);
191                 
192                 fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data");
193                 actkey->totelem= tot;
194         
195                 bp= editLatt->def;
196                 while(tot--) {
197                         VECCOPY(fp, bp->vec);
198                         fp+= 3;
199                         bp++;
200                 }
201                 
202                 if(actkey) do_spec_key(lt->key);
203         }
204         else {
205
206                 MEM_freeN(lt->def);
207         
208                 lt->def= MEM_dupallocN(editLatt->def);
209
210                 lt->flag= editLatt->flag;
211
212                 lt->pntsu= editLatt->pntsu;
213                 lt->pntsv= editLatt->pntsv;
214                 lt->pntsw= editLatt->pntsw;
215                 
216                 lt->typeu= editLatt->typeu;
217                 lt->typev= editLatt->typev;
218                 lt->typew= editLatt->typew;
219         }
220 }
221
222 void remake_editLatt(void)
223 {
224         if(okee("Reload Original data")==0) return;
225         
226         make_editLatt();
227         allqueue(REDRAWVIEW3D, 0);
228         allqueue(REDRAWBUTSEDIT, 0);
229 }
230
231
232 void deselectall_Latt(void)
233 {
234         BPoint *bp;
235         int a;
236         
237         bp= editLatt->def;
238         
239         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
240         
241         allqueue(REDRAWVIEW3D, 0);
242         
243         while(a--) {
244                 if(bp->hide==0) {
245                         if(bp->f1) {
246                                 setflagsLatt(0);
247                                 return;
248                         }
249                 }
250                 bp++;
251         }
252         setflagsLatt(1);
253 }
254
255
256 static BPoint *findnearestLattvert(int sel)
257 {
258         /* sel==1: selected get a disadvantage */
259         /* in bp nearest is written */
260         BPoint *bp1, *bp;
261         short dist= 100, temp, mval[2], a;
262
263         bp= 0;
264
265         /* do projection */
266         calc_lattverts_ext();   /* drawobject.c */
267         
268         getmouseco_areawin(mval);
269
270                         
271         bp1= editLatt->def;
272         
273         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
274         
275         while(a--) {
276                 if(bp1->hide==0) {
277                         temp= abs(mval[0]- bp1->s[0])+ abs(mval[1]- bp1->s[1]);
278                         if( (bp1->f1 & 1)==sel) temp+=5;
279                         if(temp<dist) { 
280                                 bp= bp1; 
281                                 dist= temp; 
282                         }
283                 }
284                 bp1++;
285         }
286
287         return bp;
288 }
289
290
291 void mouse_lattice(void)
292 {
293         BPoint *bp=0;
294
295         bp= findnearestLattvert(1);
296
297         if(bp) {
298                 if((G.qual & LR_SHIFTKEY)==0) {
299                 
300                         setflagsLatt(0);
301                         bp->f1 |= 1;
302
303                         allqueue(REDRAWVIEW3D, 0);
304                 }
305                 else {
306                         
307                         if(bp->f1 & 1) bp->f1 &= ~1;
308                         else bp->f1 |= 1;
309
310                         allqueue(REDRAWVIEW3D, 0);
311
312                 }
313
314                 countall();
315         }
316
317         rightmouse_transform();
318         
319 }