Blender  V2.59
object_group.c
Go to the documentation of this file.
00001 /*
00002  * $Id: object_group.c 36271 2011-04-21 13:11:51Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) Blender Foundation
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00035 #include <string.h>
00036 
00037 #include "BLI_blenlib.h"
00038 #include "BLI_utildefines.h"
00039 
00040 #include "DNA_group_types.h"
00041 #include "DNA_object_types.h"
00042 #include "DNA_scene_types.h"
00043 
00044 #include "BKE_context.h"
00045 #include "BKE_depsgraph.h"
00046 #include "BKE_group.h"
00047 #include "BKE_main.h"
00048 #include "BKE_report.h"
00049 
00050 #include "ED_screen.h"
00051 
00052 #include "WM_api.h"
00053 #include "WM_types.h"
00054 
00055 #include "RNA_access.h"
00056 #include "RNA_define.h"
00057 #include "RNA_enum_types.h"
00058 
00059 #include "object_intern.h"
00060 
00061 /********************* 3d view operators ***********************/
00062 
00063 static int objects_add_active_exec(bContext *C, wmOperator *op)
00064 {
00065         Main *bmain= CTX_data_main(C);
00066         Scene *scene= CTX_data_scene(C);
00067         Object *ob= OBACT;
00068         Group *group;
00069         int ok = 0;
00070         
00071         if(!ob) return OPERATOR_CANCELLED;
00072         
00073         /* linking to same group requires its own loop so we can avoid
00074            looking up the active objects groups each time */
00075 
00076         for(group= bmain->group.first; group; group=group->id.next) {
00077                 if(object_in_group(ob, group)) {
00078                         /* Assign groups to selected objects */
00079                         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
00080                                 add_to_group(group, base->object, scene, base);
00081                                 ok = 1;
00082                         }
00083                         CTX_DATA_END;
00084                 }
00085         }
00086         
00087         if(!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups");
00088         
00089         DAG_scene_sort(bmain, scene);
00090         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
00091         
00092         return OPERATOR_FINISHED;
00093 }
00094 
00095 void GROUP_OT_objects_add_active(wmOperatorType *ot)
00096 {
00097         /* identifiers */
00098         ot->name= "Add Selected To Active Group";
00099         ot->description = "Add the object to an object group that contains the active object";
00100         ot->idname= "GROUP_OT_objects_add_active";
00101         
00102         /* api callbacks */
00103         ot->exec= objects_add_active_exec;      
00104         ot->poll= ED_operator_objectmode;
00105 
00106         /* flags */
00107         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00108 }
00109 
00110 static int objects_remove_active_exec(bContext *C, wmOperator *op)
00111 {
00112         Main *bmain= CTX_data_main(C);
00113         Scene *scene= CTX_data_scene(C);
00114         Object *ob= OBACT;
00115         Group *group;
00116         int ok = 0;
00117         
00118         if(!ob) return OPERATOR_CANCELLED;
00119         
00120         /* linking to same group requires its own loop so we can avoid
00121            looking up the active objects groups each time */
00122 
00123         for(group= bmain->group.first; group; group=group->id.next) {
00124                 if(object_in_group(ob, group)) {
00125                         /* Assign groups to selected objects */
00126                         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
00127                                 rem_from_group(group, base->object, scene, base);
00128                                 ok = 1;
00129                         }
00130                         CTX_DATA_END;
00131                 }
00132         }
00133         
00134         if(!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups");
00135         
00136         DAG_scene_sort(bmain, scene);
00137         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
00138         
00139         return OPERATOR_FINISHED;
00140 }
00141 
00142 void GROUP_OT_objects_remove_active(wmOperatorType *ot)
00143 {
00144         /* identifiers */
00145         ot->name= "Remove Selected From Active Group";
00146         ot->description = "Remove the object from an object group that contains the active object";
00147         ot->idname= "GROUP_OT_objects_remove_active";
00148         
00149         /* api callbacks */
00150         ot->exec= objects_remove_active_exec;   
00151         ot->poll= ED_operator_objectmode;
00152         
00153         /* flags */
00154         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00155 }
00156 
00157 static int group_objects_remove_exec(bContext *C, wmOperator *UNUSED(op))
00158 {
00159         Main *bmain= CTX_data_main(C);
00160         Scene *scene= CTX_data_scene(C);
00161         Group *group= NULL;
00162 
00163         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
00164                 group = NULL;
00165                 while((group = find_group(base->object, group)))
00166                         rem_from_group(group, base->object, scene, base);
00167         }
00168         CTX_DATA_END;
00169 
00170         DAG_scene_sort(bmain, scene);
00171         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
00172         
00173         return OPERATOR_FINISHED;
00174 }
00175 
00176 void GROUP_OT_objects_remove(wmOperatorType *ot)
00177 {
00178         /* identifiers */
00179         ot->name= "Remove From Groups";
00180         ot->description = "Remove selected objects from all groups";
00181         ot->idname= "GROUP_OT_objects_remove";
00182         
00183         /* api callbacks */
00184         ot->exec= group_objects_remove_exec;    
00185         ot->poll= ED_operator_objectmode;
00186         
00187         /* flags */
00188         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00189 }
00190 
00191 static int group_create_exec(bContext *C, wmOperator *op)
00192 {
00193         Main *bmain= CTX_data_main(C);
00194         Scene *scene= CTX_data_scene(C);
00195         Group *group= NULL;
00196         char name[32]; /* id name */
00197         
00198         RNA_string_get(op->ptr, "name", name);
00199         
00200         group= add_group(name);
00201                 
00202         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
00203                 add_to_group(group, base->object, scene, base);
00204         }
00205         CTX_DATA_END;
00206 
00207         DAG_scene_sort(bmain, scene);
00208         WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL);
00209         
00210         return OPERATOR_FINISHED;
00211 }
00212 
00213 void GROUP_OT_create(wmOperatorType *ot)
00214 {
00215         /* identifiers */
00216         ot->name= "Create New Group";
00217         ot->description = "Create an object group from selected objects";
00218         ot->idname= "GROUP_OT_create";
00219         
00220         /* api callbacks */
00221         ot->exec= group_create_exec;    
00222         ot->poll= ED_operator_objectmode;
00223         
00224         /* flags */
00225         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00226         
00227         RNA_def_string(ot->srna, "name", "Group", 32, "Name", "Name of the new group");
00228 }
00229 
00230 /****************** properties window operators *********************/
00231 
00232 static int group_add_exec(bContext *C, wmOperator *UNUSED(op))
00233 {
00234         Scene *scene= CTX_data_scene(C);
00235         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00236         Group *group;
00237 
00238         if(ob == NULL)
00239                 return OPERATOR_CANCELLED;
00240 
00241         group= add_group("Group");
00242         add_to_group(group, ob, scene, NULL);
00243 
00244         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
00245 
00246         return OPERATOR_FINISHED;
00247 }
00248 
00249 void OBJECT_OT_group_add(wmOperatorType *ot)
00250 {
00251         /* identifiers */
00252         ot->name= "Add to Group";
00253         ot->idname= "OBJECT_OT_group_add";
00254         ot->description = "Add an object to a new group";
00255         
00256         /* api callbacks */
00257         ot->exec= group_add_exec;
00258 
00259         /* flags */
00260         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00261 }
00262 
00263 static int group_link_exec(bContext *C, wmOperator *op)
00264 {
00265         Scene *scene= CTX_data_scene(C);
00266         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00267         Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
00268 
00269         if(ELEM(NULL, ob, group))
00270                 return OPERATOR_CANCELLED;
00271 
00272         add_to_group(group, ob, scene, NULL);
00273 
00274         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
00275 
00276         return OPERATOR_FINISHED;
00277 }
00278 
00279 void OBJECT_OT_group_link(wmOperatorType *ot)
00280 {
00281         PropertyRNA *prop;
00282 
00283         /* identifiers */
00284         ot->name= "Link to Group";
00285         ot->idname= "OBJECT_OT_group_link";
00286         ot->description = "Add an object to an existing group";
00287         
00288         /* api callbacks */
00289         ot->exec= group_link_exec;
00290         ot->invoke= WM_enum_search_invoke;
00291 
00292         /* flags */
00293         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00294 
00295         /* properties */
00296         prop= RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "");
00297         RNA_def_enum_funcs(prop, RNA_group_local_itemf);
00298         ot->prop= prop;
00299 }
00300 
00301 static int group_remove_exec(bContext *C, wmOperator *UNUSED(op))
00302 {
00303         Scene *scene= CTX_data_scene(C);
00304         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00305         Group *group= CTX_data_pointer_get_type(C, "group", &RNA_Group).data;
00306 
00307         if(!ob || !group)
00308                 return OPERATOR_CANCELLED;
00309 
00310         rem_from_group(group, ob, scene, NULL); /* base will be used if found */
00311 
00312         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
00313         
00314         return OPERATOR_FINISHED;
00315 }
00316 
00317 void OBJECT_OT_group_remove(wmOperatorType *ot)
00318 {
00319         /* identifiers */
00320         ot->name= "Remove Group";
00321         ot->idname= "OBJECT_OT_group_remove";
00322         
00323         /* api callbacks */
00324         ot->exec= group_remove_exec;
00325 
00326         /* flags */
00327         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00328 }
00329