Blender V2.61 - r43446

object_group.c

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