2.5
[blender.git] / source / blender / editors / object / editgroup.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) Blender Foundation
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <string.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_blenlib.h"
35 #include "BLI_arithb.h"
36
37 #include "DNA_group_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_view3d_types.h"
41
42 #include "BKE_depsgraph.h"
43 #include "BKE_group.h"
44 #include "BKE_global.h"
45 #include "BKE_context.h"
46 #include "BKE_main.h"
47 #include "BKE_report.h"
48
49 #include "ED_view3d.h"
50 #include "ED_space_api.h"
51 #include "ED_screen.h"
52 #include "ED_types.h"
53 #include "ED_util.h"
54
55 #include "UI_interface.h"
56 #include "UI_resources.h"
57
58 #include "WM_api.h"
59 #include "WM_types.h"
60
61 #include "RNA_access.h"
62 #include "RNA_define.h"
63
64 #include "object_intern.h"
65
66 static int objects_add_active_exec(bContext *C, wmOperator *op)
67 {
68         Scene *scene= CTX_data_scene(C);
69         Object *ob= OBACT, *obt;
70         Group *group;
71         int ok = 0;
72         
73         if (!ob) return OPERATOR_CANCELLED;
74         
75         /* linking to same group requires its own loop so we can avoid
76            looking up the active objects groups each time */
77
78         group= G.main->group.first;
79         while(group) {
80                 if(object_in_group(ob, group)) {
81                         /* Assign groups to selected objects */
82                         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
83                                 obt= base->object;
84                                 add_to_group(group, obt);
85                                 obt->flag |= OB_FROMGROUP;
86                                 base->flag |= OB_FROMGROUP;
87                                 base->object->recalc= OB_RECALC_OB;
88                                 ok = 1;
89                         }
90                         CTX_DATA_END;
91                 }
92                 group= group->id.next;
93         }
94         
95         if (!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups");
96         
97         DAG_scene_sort(CTX_data_scene(C));
98
99         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
100         
101         return OPERATOR_FINISHED;
102
103 }
104
105 void GROUP_OT_objects_add_active(wmOperatorType *ot)
106 {
107         
108         /* identifiers */
109         ot->name= "Add Selected To Active Group";
110         ot->idname= "GROUP_OT_objects_add_active";
111         
112         /* api callbacks */
113         ot->exec= objects_add_active_exec;      
114         ot->poll= ED_operator_scene_editable;
115
116         /* flags */
117         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
118 }
119
120 static int objects_remove_active_exec(bContext *C, wmOperator *op)
121 {
122         Scene *scene= CTX_data_scene(C);
123         Object *ob= OBACT, *obt;
124         Group *group;
125         int ok = 0;
126         
127         if (!ob) return OPERATOR_CANCELLED;
128         
129         /* linking to same group requires its own loop so we can avoid
130            looking up the active objects groups each time */
131
132         group= G.main->group.first;
133         while(group) {
134                 if(object_in_group(ob, group)) {
135                         /* Assign groups to selected objects */
136                         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
137                                 obt= base->object;
138                                 rem_from_group(group, obt);
139                                 obt->flag &= ~OB_FROMGROUP;
140                                 base->flag &= ~OB_FROMGROUP;
141                                 base->object->recalc= OB_RECALC_OB;
142                                 ok = 1;
143                         }
144                         CTX_DATA_END;
145                 }
146                 group= group->id.next;
147         }
148         
149         if (!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups");
150         
151         DAG_scene_sort(CTX_data_scene(C));
152
153         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
154         
155         return OPERATOR_FINISHED;
156
157 }
158
159 void GROUP_OT_objects_remove_active(wmOperatorType *ot)
160 {
161         
162         /* identifiers */
163         ot->name= "Remove Selected From active group";
164         ot->idname= "GROUP_OT_objects_remove_active";
165         
166         /* api callbacks */
167         ot->exec= objects_remove_active_exec;   
168         ot->poll= ED_operator_scene_editable;
169         
170         /* flags */
171         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
172 }
173
174 static int group_remove_exec(bContext *C, wmOperator *op)
175 {
176         Group *group= NULL;
177
178         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
179                 group = NULL;
180                 while( (group = find_group(base->object, group)) ) {
181                         rem_from_group(group, base->object);
182                 }
183                 base->object->flag &= ~OB_FROMGROUP;
184                 base->flag &= ~OB_FROMGROUP;
185                 base->object->recalc= OB_RECALC_OB;
186         }
187         CTX_DATA_END;
188
189         DAG_scene_sort(CTX_data_scene(C));
190
191         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
192         
193         return OPERATOR_FINISHED;
194
195 }
196
197 void GROUP_OT_group_remove(wmOperatorType *ot)
198 {
199         
200         /* identifiers */
201         ot->name= "remove Selected from group";
202         ot->idname= "GROUP_OT_group_remove";
203         
204         /* api callbacks */
205         ot->exec= group_remove_exec;    
206         ot->poll= ED_operator_scene_editable;
207         
208         /* flags */
209         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
210 }
211
212 static int group_create_exec(bContext *C, wmOperator *op)
213 {
214         Group *group= NULL;
215         char gid[32]; //group id
216         
217         RNA_string_get(op->ptr, "GID", gid);
218         
219         group= add_group(gid);
220                 
221         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
222                 add_to_group(group, base->object);
223                 base->object->flag |= OB_FROMGROUP;
224                 base->flag |= OB_FROMGROUP;
225                 base->object->recalc= OB_RECALC_OB;
226         }
227         CTX_DATA_END;
228
229         DAG_scene_sort(CTX_data_scene(C));
230
231         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
232         
233         return OPERATOR_FINISHED;
234
235 }
236
237 void GROUP_OT_group_create(wmOperatorType *ot)
238 {
239         
240         /* identifiers */
241         ot->name= "Create New Group";
242         ot->idname= "GROUP_OT_group_create";
243         
244         /* api callbacks */
245         ot->exec= group_create_exec;    
246         ot->poll= ED_operator_scene_editable;
247         
248         /* flags */
249         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
250         
251         RNA_def_string(ot->srna, "GID", "Group", 32, "Name", "Name of the new group");
252 }
253