b86ebef82cdda00f6587a15d48332d0c356cdaf2
[blender-staging.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         ED_undo_push(C,"Add To Active Group");
99
100         WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C));
101         
102         return OPERATOR_FINISHED;
103
104 }
105
106 void GROUP_OT_objects_add_active(wmOperatorType *ot)
107 {
108         
109         /* identifiers */
110         ot->name= "Add Selected To Active Group";
111         ot->idname= "GROUP_OT_objects_add_active";
112         
113         /* api callbacks */
114         ot->exec= objects_add_active_exec;      
115         ot->poll= ED_operator_scene_editable;
116 }
117
118 static int objects_remove_active_exec(bContext *C, wmOperator *op)
119 {
120         Scene *scene= CTX_data_scene(C);
121         Object *ob= OBACT, *obt;
122         Group *group;
123         int ok = 0;
124         
125         if (!ob) return OPERATOR_CANCELLED;
126         
127         /* linking to same group requires its own loop so we can avoid
128            looking up the active objects groups each time */
129
130         group= G.main->group.first;
131         while(group) {
132                 if(object_in_group(ob, group)) {
133                         /* Assign groups to selected objects */
134                         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
135                                 obt= base->object;
136                                 rem_from_group(group, obt);
137                                 obt->flag &= ~OB_FROMGROUP;
138                                 base->flag &= ~OB_FROMGROUP;
139                                 base->object->recalc= OB_RECALC_OB;
140                                 ok = 1;
141                         }
142                         CTX_DATA_END;
143                 }
144                 group= group->id.next;
145         }
146         
147         if (!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups");
148         
149         DAG_scene_sort(CTX_data_scene(C));
150         ED_undo_push(C,"Remove From Active Group");
151
152         WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C));
153         
154         return OPERATOR_FINISHED;
155
156 }
157
158 void GROUP_OT_objects_remove_active(wmOperatorType *ot)
159 {
160         
161         /* identifiers */
162         ot->name= "Remove Selected From active group";
163         ot->idname= "GROUP_OT_objects_remove_active";
164         
165         /* api callbacks */
166         ot->exec= objects_remove_active_exec;   
167         ot->poll= ED_operator_scene_editable;
168 }
169
170 static int group_remove_exec(bContext *C, wmOperator *op)
171 {
172         Group *group= NULL;
173
174         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
175                 group = NULL;
176                 while( (group = find_group(base->object, group)) ) {
177                         rem_from_group(group, base->object);
178                 }
179                 base->object->flag &= ~OB_FROMGROUP;
180                 base->flag &= ~OB_FROMGROUP;
181                 base->object->recalc= OB_RECALC_OB;
182         }
183         CTX_DATA_END;
184
185         DAG_scene_sort(CTX_data_scene(C));
186         ED_undo_push(C,"Remove From Group");
187
188         WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C));
189         
190         return OPERATOR_FINISHED;
191
192 }
193
194 void GROUP_OT_group_remove(wmOperatorType *ot)
195 {
196         
197         /* identifiers */
198         ot->name= "remove Selected from group";
199         ot->idname= "GROUP_OT_group_remove";
200         
201         /* api callbacks */
202         ot->exec= group_remove_exec;    
203         ot->poll= ED_operator_scene_editable;
204 }
205
206 static int group_create_exec(bContext *C, wmOperator *op)
207 {
208         Group *group= NULL;
209         char gid[32]; //group id
210         
211         RNA_string_get(op->ptr, "GID", gid);
212         
213         group= add_group(gid);
214                 
215         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
216                 add_to_group(group, base->object);
217                 base->object->flag |= OB_FROMGROUP;
218                 base->flag |= OB_FROMGROUP;
219                 base->object->recalc= OB_RECALC_OB;
220         }
221         CTX_DATA_END;
222
223         DAG_scene_sort(CTX_data_scene(C));
224         ED_undo_push(C,"Create Group");
225
226         WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C));
227         
228         return OPERATOR_FINISHED;
229
230 }
231
232 void GROUP_OT_group_create(wmOperatorType *ot)
233 {
234         
235         /* identifiers */
236         ot->name= "Create New Group";
237         ot->idname= "GROUP_OT_group_create";
238         
239         /* api callbacks */
240         ot->exec= group_create_exec;    
241         ot->poll= ED_operator_scene_editable;
242         
243         RNA_def_string(ot->srna, "GID", "Group", 32, "Name", "Name of the new group");
244 }
245