New feature; User definable Clipping Planes.
[blender-staging.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_object_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_lattice_types.h"
50 #include "DNA_curve_types.h"
51 #include "DNA_key_types.h"
52 #include "DNA_view3d_types.h"
53
54 #include "BKE_key.h"
55 #include "BKE_depsgraph.h"
56 #include "BKE_lattice.h"
57 #include "BKE_global.h"
58 #include "BKE_utildefines.h"
59
60 #include "BIF_space.h"
61 #include "BIF_screen.h"
62 #include "BIF_editlattice.h"
63 #include "BIF_editmode_undo.h"
64 #include "BIF_editkey.h"
65 #include "BIF_toolbox.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 "BKE_armature.h"
76
77 /* ***************************** */
78
79 void free_editLatt(void)
80 {
81         if(editLatt) {
82                 if(editLatt->def) MEM_freeN(editLatt->def);
83                 MEM_freeN(editLatt);
84                 editLatt= 0;
85         }
86 }
87
88
89 static void setflagsLatt(int flag)
90 {
91         BPoint *bp;
92         int a;
93         
94         bp= editLatt->def;
95         
96         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
97         
98         while(a--) {
99                 if(bp->hide==0) {
100                         bp->f1= flag;
101                 }
102                 bp++;
103         }
104 }
105
106
107
108 void make_editLatt(void)
109 {
110         Lattice *lt;
111         KeyBlock *actkey;
112         
113         free_editLatt();
114         
115         lt= G.obedit->data;
116
117         actkey = key_get_active(lt->key);
118         if(actkey) {
119                 strcpy(G.editModeTitleExtra, "(Key) ");
120                 key_to_latt(actkey, lt);
121         }
122
123         editLatt= MEM_dupallocN(lt);
124         editLatt->def= MEM_dupallocN(lt->def);
125         
126         setflagsLatt(0);
127         BIF_undo_push("original");
128 }
129
130
131 void load_editLatt(void)
132 {
133         Lattice *lt;
134         KeyBlock *actkey;
135         BPoint *bp;
136         float *fp;
137         int tot;
138         
139         lt= G.obedit->data;
140         
141         actkey = key_get_active(lt->key);
142         if(actkey) {
143                 /* active key: vertices */
144                 tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
145                 
146                 if(actkey->data) MEM_freeN(actkey->data);
147                 
148                 fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data");
149                 actkey->totelem= tot;
150         
151                 bp= editLatt->def;
152                 while(tot--) {
153                         VECCOPY(fp, bp->vec);
154                         fp+= 3;
155                         bp++;
156                 }
157         }
158         else {
159
160                 MEM_freeN(lt->def);
161         
162                 lt->def= MEM_dupallocN(editLatt->def);
163
164                 lt->flag= editLatt->flag;
165
166                 lt->pntsu= editLatt->pntsu;
167                 lt->pntsv= editLatt->pntsv;
168                 lt->pntsw= editLatt->pntsw;
169                 
170                 lt->typeu= editLatt->typeu;
171                 lt->typev= editLatt->typev;
172                 lt->typew= editLatt->typew;
173         }
174 }
175
176 void remake_editLatt(void)
177 {
178         if(okee("Reload original data")==0) return;
179         
180         make_editLatt();
181         allqueue(REDRAWVIEW3D, 0);
182         allqueue(REDRAWBUTSEDIT, 0);
183
184         BIF_undo_push("Reload original");
185 }
186
187
188 void deselectall_Latt(void)
189 {
190         BPoint *bp;
191         int a;
192         
193         bp= editLatt->def;
194         
195         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
196         
197         allqueue(REDRAWVIEW3D, 0);
198         
199         while(a--) {
200                 if(bp->hide==0) {
201                         if(bp->f1) {
202                                 setflagsLatt(0);
203                                 BIF_undo_push("(De)select all");
204                                 return;
205                         }
206                 }
207                 bp++;
208         }
209         setflagsLatt(1);
210
211         BIF_undo_push("(De)select all");
212 }
213
214 static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y)
215 {
216         struct { BPoint *bp; short dist, select, mval[2]; } *data = userData;
217         float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
218         
219         if ((bp->f1&1)==data->select) temp += 5;
220         if (temp<data->dist) {
221                 data->dist = temp;
222
223                 data->bp = bp;
224         }
225 }
226 static BPoint *findnearestLattvert(int sel)
227 {
228                 /* sel==1: selected gets a disadvantage */
229                 /* in nurb and bezt or bp the nearest is written */
230                 /* return 0 1 2: handlepunt */
231         struct { BPoint *bp; short dist, select, mval[2]; } data = {0};
232
233         data.dist = 100;
234         data.select = sel;
235         getmouseco_areawin(data.mval);
236
237         lattice_foreachScreenVert(findnearestLattvert__doClosest, &data);
238
239         return data.bp;
240 }
241
242
243 void mouse_lattice(void)
244 {
245         BPoint *bp=0;
246
247         bp= findnearestLattvert(1);
248
249         if(bp) {
250                 if((G.qual & LR_SHIFTKEY)==0) {
251                 
252                         setflagsLatt(0);
253                         bp->f1 |= 1;
254
255                         allqueue(REDRAWVIEW3D, 0);
256                 }
257                 else {
258                         
259                         if(bp->f1 & 1) bp->f1 &= ~1;
260                         else bp->f1 |= 1;
261
262                         allqueue(REDRAWVIEW3D, 0);
263
264                 }
265
266                 countall();
267                 BIF_undo_push("Select");
268         }
269
270         rightmouse_transform();
271         
272 }
273
274
275 /* **************** undo for lattice object ************** */
276
277 static void undoLatt_to_editLatt(void *defv)
278 {
279         int a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
280
281         memcpy(editLatt->def, defv, a*sizeof(BPoint));
282 }
283
284 static void *editLatt_to_undoLatt(void)
285 {
286         
287         return MEM_dupallocN(editLatt->def);
288 }
289
290 static void free_undoLatt(void *defv)
291 {
292         MEM_freeN(defv);
293 }
294
295 /* and this is all the undo system needs to know */
296 void undo_push_lattice(char *name)
297 {
298         undo_editmode_push(name, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt);
299 }
300
301
302
303 /***/