Blender V2.61 - r43446
|
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 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 * GNU General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * along with this program; if not, write to the Free Software Foundation, 00015 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00016 * 00017 * The Original Code is Copyright (C) 2009 Blender Foundation. 00018 * All rights reserved. 00019 * 00020 * Contributor(s): Blender Foundation 00021 * 00022 * ***** END GPL LICENSE BLOCK ***** 00023 */ 00024 00029 #include <stdlib.h> 00030 #include <string.h> 00031 00032 #include "MEM_guardedalloc.h" 00033 00034 #include "DNA_curve_types.h" 00035 #include "DNA_lamp_types.h" 00036 #include "DNA_material_types.h" 00037 #include "DNA_node_types.h" 00038 #include "DNA_object_types.h" 00039 #include "DNA_particle_types.h" 00040 #include "DNA_scene_types.h" 00041 #include "DNA_space_types.h" 00042 #include "DNA_world_types.h" 00043 00044 #include "BLI_blenlib.h" 00045 #include "BLI_math.h" 00046 #include "BLI_editVert.h" 00047 #include "BLI_utildefines.h" 00048 00049 #include "BKE_animsys.h" 00050 #include "BKE_context.h" 00051 #include "BKE_curve.h" 00052 #include "BKE_depsgraph.h" 00053 #include "BKE_font.h" 00054 #include "BKE_global.h" 00055 #include "BKE_icons.h" 00056 #include "BKE_image.h" 00057 #include "BKE_library.h" 00058 #include "BKE_main.h" 00059 #include "BKE_material.h" 00060 #include "BKE_node.h" 00061 #include "BKE_report.h" 00062 #include "BKE_scene.h" 00063 #include "BKE_texture.h" 00064 #include "BKE_world.h" 00065 00066 #include "IMB_imbuf.h" 00067 #include "IMB_imbuf_types.h" 00068 00069 #include "GPU_material.h" 00070 00071 #include "RNA_access.h" 00072 00073 #include "WM_api.h" 00074 #include "WM_types.h" 00075 00076 #include "ED_object.h" 00077 #include "ED_curve.h" 00078 #include "ED_mesh.h" 00079 #include "ED_node.h" 00080 #include "ED_render.h" 00081 #include "ED_screen.h" 00082 00083 #include "RNA_define.h" 00084 00085 #include "UI_interface.h" 00086 00087 #include "RE_pipeline.h" 00088 00089 #include "render_intern.h" // own include 00090 00091 /********************** material slot operators *********************/ 00092 00093 static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) 00094 { 00095 Object *ob= ED_object_context(C); 00096 00097 if(!ob) 00098 return OPERATOR_CANCELLED; 00099 00100 object_add_material_slot(ob); 00101 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00102 WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, ob); 00103 00104 return OPERATOR_FINISHED; 00105 } 00106 00107 void OBJECT_OT_material_slot_add(wmOperatorType *ot) 00108 { 00109 /* identifiers */ 00110 ot->name= "Add Material Slot"; 00111 ot->idname= "OBJECT_OT_material_slot_add"; 00112 ot->description="Add a new material slot"; 00113 00114 /* api callbacks */ 00115 ot->exec= material_slot_add_exec; 00116 ot->poll= ED_operator_object_active_editable; 00117 00118 /* flags */ 00119 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00120 } 00121 00122 static int material_slot_remove_exec(bContext *C, wmOperator *op) 00123 { 00124 Object *ob= ED_object_context(C); 00125 00126 if(!ob) 00127 return OPERATOR_CANCELLED; 00128 00129 /* Removing material slots in edit mode screws things up, see bug #21822.*/ 00130 if(ob == CTX_data_edit_object(C)) { 00131 BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode"); 00132 return OPERATOR_CANCELLED; 00133 } 00134 00135 object_remove_material_slot(ob); 00136 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00137 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00138 WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, ob); 00139 00140 return OPERATOR_FINISHED; 00141 } 00142 00143 void OBJECT_OT_material_slot_remove(wmOperatorType *ot) 00144 { 00145 /* identifiers */ 00146 ot->name= "Remove Material Slot"; 00147 ot->idname= "OBJECT_OT_material_slot_remove"; 00148 ot->description="Remove the selected material slot"; 00149 00150 /* api callbacks */ 00151 ot->exec= material_slot_remove_exec; 00152 ot->poll= ED_operator_object_active_editable; 00153 00154 /* flags */ 00155 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00156 } 00157 00158 static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op)) 00159 { 00160 Object *ob= ED_object_context(C); 00161 00162 if(!ob) 00163 return OPERATOR_CANCELLED; 00164 00165 if(ob && ob->actcol>0) { 00166 if(ob->type == OB_MESH) { 00167 EditMesh *em= ((Mesh*)ob->data)->edit_mesh; 00168 EditFace *efa; 00169 00170 if(em) { 00171 for(efa= em->faces.first; efa; efa=efa->next) 00172 if(efa->f & SELECT) 00173 efa->mat_nr= ob->actcol-1; 00174 } 00175 } 00176 else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { 00177 Nurb *nu; 00178 ListBase *nurbs= curve_editnurbs((Curve*)ob->data); 00179 00180 if(nurbs) { 00181 for(nu= nurbs->first; nu; nu= nu->next) 00182 if(isNurbsel(nu)) 00183 nu->mat_nr= nu->charidx= ob->actcol-1; 00184 } 00185 } 00186 else if(ob->type == OB_FONT) { 00187 EditFont *ef= ((Curve*)ob->data)->editfont; 00188 int i, selstart, selend; 00189 00190 if(ef && BKE_font_getselection(ob, &selstart, &selend)) { 00191 for(i=selstart; i<=selend; i++) 00192 ef->textbufinfo[i].mat_nr = ob->actcol; 00193 } 00194 } 00195 } 00196 00197 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00198 WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); 00199 00200 return OPERATOR_FINISHED; 00201 } 00202 00203 void OBJECT_OT_material_slot_assign(wmOperatorType *ot) 00204 { 00205 /* identifiers */ 00206 ot->name= "Assign Material Slot"; 00207 ot->idname= "OBJECT_OT_material_slot_assign"; 00208 ot->description="Assign the material in the selected material slot to the selected vertices"; 00209 00210 /* api callbacks */ 00211 ot->exec= material_slot_assign_exec; 00212 ot->poll= ED_operator_object_active_editable; 00213 00214 /* flags */ 00215 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00216 } 00217 00218 static int material_slot_de_select(bContext *C, int select) 00219 { 00220 Object *ob= ED_object_context(C); 00221 00222 if(!ob) 00223 return OPERATOR_CANCELLED; 00224 00225 if(ob->type == OB_MESH) { 00226 EditMesh *em= ((Mesh*)ob->data)->edit_mesh; 00227 00228 if(em) { 00229 if(select) 00230 EM_select_by_material(em, ob->actcol-1); 00231 else 00232 EM_deselect_by_material(em, ob->actcol-1); 00233 } 00234 } 00235 else if ELEM(ob->type, OB_CURVE, OB_SURF) { 00236 ListBase *nurbs= curve_editnurbs((Curve*)ob->data); 00237 Nurb *nu; 00238 BPoint *bp; 00239 BezTriple *bezt; 00240 int a; 00241 00242 if(nurbs) { 00243 for(nu= nurbs->first; nu; nu=nu->next) { 00244 if(nu->mat_nr==ob->actcol-1) { 00245 if(nu->bezt) { 00246 a= nu->pntsu; 00247 bezt= nu->bezt; 00248 while(a--) { 00249 if(bezt->hide==0) { 00250 if(select) { 00251 bezt->f1 |= SELECT; 00252 bezt->f2 |= SELECT; 00253 bezt->f3 |= SELECT; 00254 } 00255 else { 00256 bezt->f1 &= ~SELECT; 00257 bezt->f2 &= ~SELECT; 00258 bezt->f3 &= ~SELECT; 00259 } 00260 } 00261 bezt++; 00262 } 00263 } 00264 else if(nu->bp) { 00265 a= nu->pntsu*nu->pntsv; 00266 bp= nu->bp; 00267 while(a--) { 00268 if(bp->hide==0) { 00269 if(select) bp->f1 |= SELECT; 00270 else bp->f1 &= ~SELECT; 00271 } 00272 bp++; 00273 } 00274 } 00275 } 00276 } 00277 } 00278 } 00279 00280 WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); 00281 00282 return OPERATOR_FINISHED; 00283 } 00284 00285 static int material_slot_select_exec(bContext *C, wmOperator *UNUSED(op)) 00286 { 00287 return material_slot_de_select(C, 1); 00288 } 00289 00290 void OBJECT_OT_material_slot_select(wmOperatorType *ot) 00291 { 00292 /* identifiers */ 00293 ot->name= "Select Material Slot"; 00294 ot->idname= "OBJECT_OT_material_slot_select"; 00295 ot->description="Select vertices assigned to the selected material slot"; 00296 00297 /* api callbacks */ 00298 ot->exec= material_slot_select_exec; 00299 00300 /* flags */ 00301 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00302 } 00303 00304 static int material_slot_deselect_exec(bContext *C, wmOperator *UNUSED(op)) 00305 { 00306 return material_slot_de_select(C, 0); 00307 } 00308 00309 void OBJECT_OT_material_slot_deselect(wmOperatorType *ot) 00310 { 00311 /* identifiers */ 00312 ot->name= "Deselect Material Slot"; 00313 ot->idname= "OBJECT_OT_material_slot_deselect"; 00314 ot->description="Deselect vertices assigned to the selected material slot"; 00315 00316 /* api callbacks */ 00317 ot->exec= material_slot_deselect_exec; 00318 00319 /* flags */ 00320 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00321 } 00322 00323 00324 static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op)) 00325 { 00326 Object *ob= ED_object_context(C); 00327 Material ***matar; 00328 00329 if(!ob || !(matar= give_matarar(ob))) 00330 return OPERATOR_CANCELLED; 00331 00332 CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { 00333 if(ob != ob_iter && give_matarar(ob_iter)) { 00334 if (ob->data != ob_iter->data) 00335 assign_matarar(ob_iter, matar, ob->totcol); 00336 00337 if(ob_iter->totcol==ob->totcol) { 00338 ob_iter->actcol= ob->actcol; 00339 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_iter); 00340 } 00341 } 00342 } 00343 CTX_DATA_END; 00344 00345 return OPERATOR_FINISHED; 00346 } 00347 00348 00349 void OBJECT_OT_material_slot_copy(wmOperatorType *ot) 00350 { 00351 /* identifiers */ 00352 ot->name= "Copy Material to Others"; 00353 ot->idname= "OBJECT_OT_material_slot_copy"; 00354 ot->description="Copies materials to other selected objects"; 00355 00356 /* api callbacks */ 00357 ot->exec= material_slot_copy_exec; 00358 00359 /* flags */ 00360 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00361 } 00362 00363 /********************** new material operator *********************/ 00364 00365 static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) 00366 { 00367 Scene *scene= CTX_data_scene(C); 00368 Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data; 00369 PointerRNA ptr, idptr; 00370 PropertyRNA *prop; 00371 00372 /* add or copy material */ 00373 if(ma) { 00374 ma= copy_material(ma); 00375 } 00376 else { 00377 ma= add_material("Material"); 00378 00379 if(scene_use_new_shading_nodes(scene)) { 00380 ED_node_shader_default(scene, &ma->id); 00381 ma->use_nodes= 1; 00382 } 00383 } 00384 00385 /* hook into UI */ 00386 uiIDContextProperty(C, &ptr, &prop); 00387 00388 if(prop) { 00389 /* when creating new ID blocks, use is already 1, but RNA 00390 * pointer se also increases user, so this compensates it */ 00391 ma->id.us--; 00392 00393 RNA_id_pointer_create(&ma->id, &idptr); 00394 RNA_property_pointer_set(&ptr, prop, idptr); 00395 RNA_property_update(C, &ptr, prop); 00396 } 00397 00398 WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma); 00399 00400 return OPERATOR_FINISHED; 00401 } 00402 00403 void MATERIAL_OT_new(wmOperatorType *ot) 00404 { 00405 /* identifiers */ 00406 ot->name= "New Material"; 00407 ot->idname= "MATERIAL_OT_new"; 00408 ot->description="Add a new material"; 00409 00410 /* api callbacks */ 00411 ot->exec= new_material_exec; 00412 00413 /* flags */ 00414 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00415 } 00416 00417 /********************** new texture operator *********************/ 00418 00419 static int new_texture_exec(bContext *C, wmOperator *UNUSED(op)) 00420 { 00421 Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; 00422 PointerRNA ptr, idptr; 00423 PropertyRNA *prop; 00424 00425 /* add or copy texture */ 00426 if(tex) 00427 tex= copy_texture(tex); 00428 else 00429 tex= add_texture("Texture"); 00430 00431 /* hook into UI */ 00432 uiIDContextProperty(C, &ptr, &prop); 00433 00434 if(prop) { 00435 /* when creating new ID blocks, use is already 1, but RNA 00436 * pointer se also increases user, so this compensates it */ 00437 tex->id.us--; 00438 00439 RNA_id_pointer_create(&tex->id, &idptr); 00440 RNA_property_pointer_set(&ptr, prop, idptr); 00441 RNA_property_update(C, &ptr, prop); 00442 } 00443 00444 WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex); 00445 00446 return OPERATOR_FINISHED; 00447 } 00448 00449 void TEXTURE_OT_new(wmOperatorType *ot) 00450 { 00451 /* identifiers */ 00452 ot->name= "New Texture"; 00453 ot->idname= "TEXTURE_OT_new"; 00454 ot->description="Add a new texture"; 00455 00456 /* api callbacks */ 00457 ot->exec= new_texture_exec; 00458 00459 /* flags */ 00460 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00461 } 00462 00463 /********************** new world operator *********************/ 00464 00465 static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) 00466 { 00467 Scene *scene= CTX_data_scene(C); 00468 World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data; 00469 PointerRNA ptr, idptr; 00470 PropertyRNA *prop; 00471 00472 /* add or copy world */ 00473 if(wo) { 00474 wo= copy_world(wo); 00475 } 00476 else { 00477 wo= add_world("World"); 00478 00479 if(scene_use_new_shading_nodes(scene)) { 00480 ED_node_shader_default(scene, &wo->id); 00481 wo->use_nodes= 1; 00482 } 00483 } 00484 00485 /* hook into UI */ 00486 uiIDContextProperty(C, &ptr, &prop); 00487 00488 if(prop) { 00489 /* when creating new ID blocks, use is already 1, but RNA 00490 * pointer se also increases user, so this compensates it */ 00491 wo->id.us--; 00492 00493 RNA_id_pointer_create(&wo->id, &idptr); 00494 RNA_property_pointer_set(&ptr, prop, idptr); 00495 RNA_property_update(C, &ptr, prop); 00496 } 00497 00498 WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo); 00499 00500 return OPERATOR_FINISHED; 00501 } 00502 00503 void WORLD_OT_new(wmOperatorType *ot) 00504 { 00505 /* identifiers */ 00506 ot->name= "New World"; 00507 ot->idname= "WORLD_OT_new"; 00508 ot->description= "Add a new world"; 00509 00510 /* api callbacks */ 00511 ot->exec= new_world_exec; 00512 00513 /* flags */ 00514 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00515 } 00516 00517 /********************** render layer operators *********************/ 00518 00519 static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op)) 00520 { 00521 Scene *scene= CTX_data_scene(C); 00522 00523 scene_add_render_layer(scene, NULL); 00524 scene->r.actlay= BLI_countlist(&scene->r.layers) - 1; 00525 00526 WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene); 00527 00528 return OPERATOR_FINISHED; 00529 } 00530 00531 void SCENE_OT_render_layer_add(wmOperatorType *ot) 00532 { 00533 /* identifiers */ 00534 ot->name= "Add Render Layer"; 00535 ot->idname= "SCENE_OT_render_layer_add"; 00536 ot->description="Add a render layer"; 00537 00538 /* api callbacks */ 00539 ot->exec= render_layer_add_exec; 00540 00541 /* flags */ 00542 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00543 } 00544 00545 static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op)) 00546 { 00547 Scene *scene = CTX_data_scene(C); 00548 SceneRenderLayer *rl = BLI_findlink(&scene->r.layers, scene->r.actlay); 00549 00550 if(!scene_remove_render_layer(CTX_data_main(C), scene, rl)) 00551 return OPERATOR_CANCELLED; 00552 00553 WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene); 00554 00555 return OPERATOR_FINISHED; 00556 } 00557 00558 void SCENE_OT_render_layer_remove(wmOperatorType *ot) 00559 { 00560 /* identifiers */ 00561 ot->name= "Remove Render Layer"; 00562 ot->idname= "SCENE_OT_render_layer_remove"; 00563 ot->description="Remove the selected render layer"; 00564 00565 /* api callbacks */ 00566 ot->exec= render_layer_remove_exec; 00567 00568 /* flags */ 00569 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00570 } 00571 00572 static int texture_slot_move(bContext *C, wmOperator *op) 00573 { 00574 ID *id= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; 00575 00576 if(id) { 00577 MTex **mtex_ar, *mtexswap; 00578 short act; 00579 int type= RNA_enum_get(op->ptr, "type"); 00580 struct AnimData *adt= BKE_animdata_from_id(id); 00581 00582 give_active_mtex(id, &mtex_ar, &act); 00583 00584 if(type == -1) { /* Up */ 00585 if(act > 0) { 00586 mtexswap = mtex_ar[act]; 00587 mtex_ar[act] = mtex_ar[act-1]; 00588 mtex_ar[act-1] = mtexswap; 00589 00590 BKE_animdata_fix_paths_rename(id, adt, "texture_slots", NULL, NULL, act-1, -1, 0); 00591 BKE_animdata_fix_paths_rename(id, adt, "texture_slots", NULL, NULL, act, act-1, 0); 00592 BKE_animdata_fix_paths_rename(id, adt, "texture_slots", NULL, NULL, -1, act, 0); 00593 00594 if(GS(id->name)==ID_MA) { 00595 Material *ma= (Material *)id; 00596 int mtexuse = ma->septex & (1<<act); 00597 ma->septex &= ~(1<<act); 00598 ma->septex |= (ma->septex & (1<<(act-1))) << 1; 00599 ma->septex &= ~(1<<(act-1)); 00600 ma->septex |= mtexuse >> 1; 00601 } 00602 00603 set_active_mtex(id, act-1); 00604 } 00605 } 00606 else { /* Down */ 00607 if(act < MAX_MTEX-1) { 00608 mtexswap = mtex_ar[act]; 00609 mtex_ar[act] = mtex_ar[act+1]; 00610 mtex_ar[act+1] = mtexswap; 00611 00612 BKE_animdata_fix_paths_rename(id, adt, "texture_slots", NULL, NULL, act+1, -1, 0); 00613 BKE_animdata_fix_paths_rename(id, adt, "texture_slots", NULL, NULL, act, act+1, 0); 00614 BKE_animdata_fix_paths_rename(id, adt, "texture_slots", NULL, NULL, -1, act, 0); 00615 00616 if(GS(id->name)==ID_MA) { 00617 Material *ma= (Material *)id; 00618 int mtexuse = ma->septex & (1<<act); 00619 ma->septex &= ~(1<<act); 00620 ma->septex |= (ma->septex & (1<<(act+1))) >> 1; 00621 ma->septex &= ~(1<<(act+1)); 00622 ma->septex |= mtexuse << 1; 00623 } 00624 00625 set_active_mtex(id, act+1); 00626 } 00627 } 00628 00629 DAG_id_tag_update(id, 0); 00630 WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C)); 00631 } 00632 00633 return OPERATOR_FINISHED; 00634 } 00635 00636 void TEXTURE_OT_slot_move(wmOperatorType *ot) 00637 { 00638 static EnumPropertyItem slot_move[] = { 00639 {-1, "UP", 0, "Up", ""}, 00640 {1, "DOWN", 0, "Down", ""}, 00641 {0, NULL, 0, NULL, NULL} 00642 }; 00643 00644 /* identifiers */ 00645 ot->name= "Move Texture Slot"; 00646 ot->idname= "TEXTURE_OT_slot_move"; 00647 ot->description="Move texture slots up and down"; 00648 00649 /* api callbacks */ 00650 ot->exec= texture_slot_move; 00651 00652 /* flags */ 00653 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00654 00655 RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", ""); 00656 } 00657 00658 00659 00660 /********************** environment map operators *********************/ 00661 00662 static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, const char imtype) 00663 { 00664 float layout[12]; 00665 if ( RNA_struct_find_property(op->ptr, "layout") ) 00666 RNA_float_get_array(op->ptr, "layout",layout); 00667 else 00668 memcpy(layout, default_envmap_layout, sizeof(layout)); 00669 00670 if (RE_WriteEnvmapResult(op->reports, scene, env, path, imtype, layout)) { 00671 return OPERATOR_FINISHED; 00672 } 00673 else { 00674 return OPERATOR_CANCELLED; 00675 } 00676 00677 } 00678 00679 static int envmap_save_exec(bContext *C, wmOperator *op) 00680 { 00681 Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; 00682 Scene *scene = CTX_data_scene(C); 00683 //int imtype = RNA_enum_get(op->ptr, "file_type"); 00684 char imtype = scene->r.im_format.imtype; 00685 char path[FILE_MAX]; 00686 00687 RNA_string_get(op->ptr, "filepath", path); 00688 00689 if(scene->r.scemode & R_EXTENSION) { 00690 BKE_add_image_extension(path, imtype); 00691 } 00692 00693 WM_cursor_wait(1); 00694 00695 save_envmap(op, scene, tex->env, path, imtype); 00696 00697 WM_cursor_wait(0); 00698 00699 WM_event_add_notifier(C, NC_TEXTURE, tex); 00700 00701 return OPERATOR_FINISHED; 00702 } 00703 00704 static int envmap_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 00705 { 00706 //Scene *scene= CTX_data_scene(C); 00707 00708 if(RNA_struct_property_is_set(op->ptr, "filepath")) 00709 return envmap_save_exec(C, op); 00710 00711 //RNA_enum_set(op->ptr, "file_type", scene->r.im_format.imtype); 00712 RNA_string_set(op->ptr, "filepath", G.main->name); 00713 WM_event_add_fileselect(C, op); 00714 00715 return OPERATOR_RUNNING_MODAL; 00716 } 00717 00718 static int envmap_save_poll(bContext *C) 00719 { 00720 Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; 00721 00722 if (!tex) 00723 return 0; 00724 if (!tex->env || !tex->env->ok) 00725 return 0; 00726 if (tex->env->cube[1]==NULL) 00727 return 0; 00728 00729 return 1; 00730 } 00731 00732 void TEXTURE_OT_envmap_save(wmOperatorType *ot) 00733 { 00734 PropertyRNA *prop; 00735 /* identifiers */ 00736 ot->name= "Save Environment Map"; 00737 ot->idname= "TEXTURE_OT_envmap_save"; 00738 ot->description="Save the current generated Environment map to an image file"; 00739 00740 /* api callbacks */ 00741 ot->exec= envmap_save_exec; 00742 ot->invoke= envmap_save_invoke; 00743 ot->poll= envmap_save_poll; 00744 00745 /* flags */ 00746 ot->flag= OPTYPE_REGISTER; /* no undo since this doesnt modify the env-map */ 00747 00748 /* properties */ 00749 prop= RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] (use -1 to skip a face)", 0.0f, 0.0f); 00750 RNA_def_property_flag(prop, PROP_HIDDEN); 00751 00752 WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH); 00753 } 00754 00755 static int envmap_clear_exec(bContext *C, wmOperator *UNUSED(op)) 00756 { 00757 Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; 00758 00759 BKE_free_envmapdata(tex->env); 00760 00761 WM_event_add_notifier(C, NC_TEXTURE|NA_EDITED, tex); 00762 00763 return OPERATOR_FINISHED; 00764 } 00765 00766 static int envmap_clear_poll(bContext *C) 00767 { 00768 Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; 00769 00770 if (!tex) 00771 return 0; 00772 if (!tex->env || !tex->env->ok) 00773 return 0; 00774 if (tex->env->cube[1]==NULL) 00775 return 0; 00776 00777 return 1; 00778 } 00779 00780 void TEXTURE_OT_envmap_clear(wmOperatorType *ot) 00781 { 00782 /* identifiers */ 00783 ot->name= "Clear Environment Map"; 00784 ot->idname= "TEXTURE_OT_envmap_clear"; 00785 ot->description="Discard the environment map and free it from memory"; 00786 00787 /* api callbacks */ 00788 ot->exec= envmap_clear_exec; 00789 ot->poll= envmap_clear_poll; 00790 00791 /* flags */ 00792 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00793 } 00794 00795 static int envmap_clear_all_exec(bContext *C, wmOperator *UNUSED(op)) 00796 { 00797 Main *bmain = CTX_data_main(C); 00798 Tex *tex; 00799 00800 for (tex=bmain->tex.first; tex; tex=tex->id.next) 00801 if (tex->env) 00802 BKE_free_envmapdata(tex->env); 00803 00804 WM_event_add_notifier(C, NC_TEXTURE|NA_EDITED, tex); 00805 00806 return OPERATOR_FINISHED; 00807 } 00808 00809 void TEXTURE_OT_envmap_clear_all(wmOperatorType *ot) 00810 { 00811 /* identifiers */ 00812 ot->name= "Clear All Environment Maps"; 00813 ot->idname= "TEXTURE_OT_envmap_clear_all"; 00814 ot->description="Discard all environment maps in the .blend file and free them from memory"; 00815 00816 /* api callbacks */ 00817 ot->exec= envmap_clear_all_exec; 00818 ot->poll= envmap_clear_poll; 00819 00820 /* flags */ 00821 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00822 } 00823 00824 /********************** material operators *********************/ 00825 00826 /* material copy/paste */ 00827 static int copy_material_exec(bContext *C, wmOperator *UNUSED(op)) 00828 { 00829 Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data; 00830 00831 if(ma==NULL) 00832 return OPERATOR_CANCELLED; 00833 00834 copy_matcopybuf(ma); 00835 00836 return OPERATOR_FINISHED; 00837 } 00838 00839 void MATERIAL_OT_copy(wmOperatorType *ot) 00840 { 00841 /* identifiers */ 00842 ot->name= "Copy Material"; 00843 ot->idname= "MATERIAL_OT_copy"; 00844 ot->description="Copy the material settings and nodes"; 00845 00846 /* api callbacks */ 00847 ot->exec= copy_material_exec; 00848 00849 /* flags */ 00850 ot->flag= OPTYPE_REGISTER; /* no undo needed since no changes are made to the material */ 00851 } 00852 00853 static int paste_material_exec(bContext *C, wmOperator *UNUSED(op)) 00854 { 00855 Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data; 00856 00857 if(ma==NULL) 00858 return OPERATOR_CANCELLED; 00859 00860 paste_matcopybuf(ma); 00861 00862 WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING_DRAW, ma); 00863 00864 return OPERATOR_FINISHED; 00865 } 00866 00867 void MATERIAL_OT_paste(wmOperatorType *ot) 00868 { 00869 /* identifiers */ 00870 ot->name= "Paste Material"; 00871 ot->idname= "MATERIAL_OT_paste"; 00872 ot->description="Paste the material settings and nodes"; 00873 00874 /* api callbacks */ 00875 ot->exec= paste_material_exec; 00876 00877 /* flags */ 00878 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00879 } 00880 00881 00882 static short mtexcopied=0; /* must be reset on file load */ 00883 static MTex mtexcopybuf; 00884 00885 void ED_render_clear_mtex_copybuf(void) 00886 { /* use for file reload */ 00887 mtexcopied= 0; 00888 } 00889 00890 static void copy_mtex_copybuf(ID *id) 00891 { 00892 MTex **mtex= NULL; 00893 00894 switch(GS(id->name)) { 00895 case ID_MA: 00896 mtex= &(((Material *)id)->mtex[(int)((Material *)id)->texact]); 00897 break; 00898 case ID_LA: 00899 mtex= &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]); 00900 // la->mtex[(int)la->texact] // TODO 00901 break; 00902 case ID_WO: 00903 mtex= &(((World *)id)->mtex[(int)((World *)id)->texact]); 00904 // mtex= wrld->mtex[(int)wrld->texact]; // TODO 00905 break; 00906 case ID_PA: 00907 mtex= &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]); 00908 break; 00909 } 00910 00911 if(mtex && *mtex) { 00912 memcpy(&mtexcopybuf, *mtex, sizeof(MTex)); 00913 mtexcopied= 1; 00914 } 00915 else { 00916 mtexcopied= 0; 00917 } 00918 } 00919 00920 static void paste_mtex_copybuf(ID *id) 00921 { 00922 MTex **mtex= NULL; 00923 00924 if(mtexcopied == 0 || mtexcopybuf.tex==NULL) 00925 return; 00926 00927 switch(GS(id->name)) { 00928 case ID_MA: 00929 mtex= &(((Material *)id)->mtex[(int)((Material *)id)->texact]); 00930 break; 00931 case ID_LA: 00932 mtex= &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]); 00933 // la->mtex[(int)la->texact] // TODO 00934 break; 00935 case ID_WO: 00936 mtex= &(((World *)id)->mtex[(int)((World *)id)->texact]); 00937 // mtex= wrld->mtex[(int)wrld->texact]; // TODO 00938 break; 00939 case ID_PA: 00940 mtex= &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]); 00941 break; 00942 default: 00943 BLI_assert("invalid id type"); 00944 return; 00945 } 00946 00947 if(mtex) { 00948 if(*mtex==NULL) { 00949 *mtex= MEM_mallocN(sizeof(MTex), "mtex copy"); 00950 } 00951 else if((*mtex)->tex) { 00952 (*mtex)->tex->id.us--; 00953 } 00954 00955 memcpy(*mtex, &mtexcopybuf, sizeof(MTex)); 00956 00957 id_us_plus((ID *)mtexcopybuf.tex); 00958 } 00959 } 00960 00961 00962 static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op)) 00963 { 00964 ID *id= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; 00965 00966 if(id==NULL) { 00967 /* copying empty slot */ 00968 ED_render_clear_mtex_copybuf(); 00969 return OPERATOR_CANCELLED; 00970 } 00971 00972 copy_mtex_copybuf(id); 00973 00974 return OPERATOR_FINISHED; 00975 } 00976 00977 static int copy_mtex_poll(bContext *C) 00978 { 00979 ID *id= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; 00980 00981 return (id != NULL); 00982 } 00983 00984 void TEXTURE_OT_slot_copy(wmOperatorType *ot) 00985 { 00986 /* identifiers */ 00987 ot->name= "Copy Texture Slot Settings"; 00988 ot->idname= "TEXTURE_OT_slot_copy"; 00989 ot->description="Copy the material texture settings and nodes"; 00990 00991 /* api callbacks */ 00992 ot->exec= copy_mtex_exec; 00993 ot->poll= copy_mtex_poll; 00994 00995 /* flags */ 00996 ot->flag= OPTYPE_REGISTER; /* no undo needed since no changes are made to the mtex */ 00997 } 00998 00999 static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op)) 01000 { 01001 ID *id= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; 01002 01003 if(id==NULL) { 01004 Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data; 01005 Lamp *la= CTX_data_pointer_get_type(C, "lamp", &RNA_Lamp).data; 01006 World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data; 01007 ParticleSystem *psys= CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data; 01008 01009 if (ma) 01010 id = &ma->id; 01011 else if (la) 01012 id = &la->id; 01013 else if (wo) 01014 id = &wo->id; 01015 else if (psys) 01016 id = &psys->part->id; 01017 01018 if (id==NULL) 01019 return OPERATOR_CANCELLED; 01020 } 01021 01022 paste_mtex_copybuf(id); 01023 01024 WM_event_add_notifier(C, NC_TEXTURE|ND_SHADING_DRAW, NULL); 01025 01026 return OPERATOR_FINISHED; 01027 } 01028 01029 void TEXTURE_OT_slot_paste(wmOperatorType *ot) 01030 { 01031 /* identifiers */ 01032 ot->name= "Paste Texture Slot Settings"; 01033 ot->idname= "TEXTURE_OT_slot_paste"; 01034 ot->description="Copy the texture settings and nodes"; 01035 01036 /* api callbacks */ 01037 ot->exec= paste_mtex_exec; 01038 01039 /* flags */ 01040 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01041 } 01042