Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[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->description = "Add the object to an object group that contains the active object.";
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         /* flags */
118         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
119 }
120
121 static int objects_remove_active_exec(bContext *C, wmOperator *op)
122 {
123         Scene *scene= CTX_data_scene(C);
124         Object *ob= OBACT, *obt;
125         Group *group;
126         int ok = 0;
127         
128         if (!ob) return OPERATOR_CANCELLED;
129         
130         /* linking to same group requires its own loop so we can avoid
131            looking up the active objects groups each time */
132
133         group= G.main->group.first;
134         while(group) {
135                 if(object_in_group(ob, group)) {
136                         /* Assign groups to selected objects */
137                         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
138                                 obt= base->object;
139                                 rem_from_group(group, obt);
140                                 obt->flag &= ~OB_FROMGROUP;
141                                 base->flag &= ~OB_FROMGROUP;
142                                 base->object->recalc= OB_RECALC_OB;
143                                 ok = 1;
144                         }
145                         CTX_DATA_END;
146                 }
147                 group= group->id.next;
148         }
149         
150         if (!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups");
151         
152         DAG_scene_sort(CTX_data_scene(C));
153
154         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
155         
156         return OPERATOR_FINISHED;
157
158 }
159
160 void GROUP_OT_objects_remove_active(wmOperatorType *ot)
161 {
162         
163         /* identifiers */
164         ot->name= "Remove Selected From Active Group";
165         ot->description = "Remove the object from an object group that contains the active object.";
166         ot->idname= "GROUP_OT_objects_remove_active";
167         
168         /* api callbacks */
169         ot->exec= objects_remove_active_exec;   
170         ot->poll= ED_operator_scene_editable;
171         
172         /* flags */
173         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
174 }
175
176 static int group_remove_exec(bContext *C, wmOperator *op)
177 {
178         Group *group= NULL;
179
180         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
181                 group = NULL;
182                 while( (group = find_group(base->object, group)) ) {
183                         rem_from_group(group, base->object);
184                 }
185                 base->object->flag &= ~OB_FROMGROUP;
186                 base->flag &= ~OB_FROMGROUP;
187                 base->object->recalc= OB_RECALC_OB;
188         }
189         CTX_DATA_END;
190
191         DAG_scene_sort(CTX_data_scene(C));
192
193         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
194         
195         return OPERATOR_FINISHED;
196
197 }
198
199 void GROUP_OT_objects_remove(wmOperatorType *ot)
200 {
201         
202         /* identifiers */
203         ot->name= "Remove From Groups";
204         ot->description = "Remove selected objects from all groups.";
205         ot->idname= "GROUP_OT_objects_remove";
206         
207         /* api callbacks */
208         ot->exec= group_remove_exec;    
209         ot->poll= ED_operator_scene_editable;
210         
211         /* flags */
212         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
213 }
214
215 static int group_create_exec(bContext *C, wmOperator *op)
216 {
217         Group *group= NULL;
218         char gid[32]; //group id
219         
220         RNA_string_get(op->ptr, "GID", gid);
221         
222         group= add_group(gid);
223                 
224         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
225                 add_to_group(group, base->object);
226                 base->object->flag |= OB_FROMGROUP;
227                 base->flag |= OB_FROMGROUP;
228                 base->object->recalc= OB_RECALC_OB;
229         }
230         CTX_DATA_END;
231
232         DAG_scene_sort(CTX_data_scene(C));
233
234         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
235         
236         return OPERATOR_FINISHED;
237
238 }
239
240 void GROUP_OT_group_create(wmOperatorType *ot)
241 {
242         
243         /* identifiers */
244         ot->name= "Create New Group";
245         ot->description = "Create an object group.";
246         ot->idname= "GROUP_OT_group_create";
247         
248         /* api callbacks */
249         ot->exec= group_create_exec;    
250         ot->poll= ED_operator_scene_editable;
251         
252         /* flags */
253         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
254         
255         RNA_def_string(ot->srna, "GID", "Group", 32, "Name", "Name of the new group");
256 }
257