Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/render/render_shading.c
| Show First 20 Lines • Show All 375 Lines • ▼ Show 20 Lines | void OBJECT_OT_material_slot_copy(wmOperatorType *ot) | ||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->exec = material_slot_copy_exec; | ot->exec = material_slot_copy_exec; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; | ||||
| } | } | ||||
| static int material_slot_move_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Object *ob = ED_object_context(C); | |||||
| unsigned int *slotremap; | |||||
| int dir = RNA_enum_get(op->ptr, "direction"); | |||||
| if (!ob || ob->totcol ==0) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| slotremap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, "Temp remap array BKE_material_id_remap"); | |||||
campbellbarton: dont need to calloc if its filled right after | |||||
| for (int index = 0; index < ob->totcol; index++) | |||||
| slotremap[index] = index; | |||||
| /* up */ | |||||
| if (dir == 1 && ob->actcol > 1) { | |||||
| slotremap[ob->actcol - 2] = ob->actcol - 1; | |||||
| slotremap[ob->actcol - 1] = ob->actcol - 2; | |||||
| ob->actcol--; | |||||
| } | |||||
| /* down */ | |||||
| else if (dir == -1 && ob->actcol < ob->totcol) { | |||||
| slotremap[ob->actcol - 1] = ob->actcol - 0; | |||||
| slotremap[ob->actcol - 0] = ob->actcol - 1; | |||||
| ob->actcol++; | |||||
| } | |||||
| else { | |||||
| MEM_freeN(slotremap); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| BKE_material_id_remap(ob, slotremap); | |||||
| MEM_freeN(slotremap); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_DRAW | ND_DATA, ob); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| void OBJECT_OT_material_slot_move(wmOperatorType *ot) | |||||
| { | |||||
| static EnumPropertyItem material_slot_move[] = { | |||||
| {1, "UP", 0, "Up", ""}, | |||||
| {-1, "DOWN", 0, "Down", ""}, | |||||
| {0, NULL, 0, NULL, NULL} | |||||
| }; | |||||
| /* identifiers */ | |||||
| ot->name = "Move Material"; | |||||
| ot->idname = "OBJECT_OT_material_slot_move"; | |||||
| ot->description = "Move the active material up/down in the list"; | |||||
| /* api callbacks */ | |||||
| ot->exec = material_slot_move_exec; | |||||
Not Done Inline ActionsNULL checks here seem a bit redundant caller can check if state is sane. campbellbarton: NULL checks here seem a bit redundant caller can check if state is sane. | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| RNA_def_enum(ot->srna, "direction", material_slot_move, 0, "Direction", "Direction to move, UP or DOWN"); | |||||
| } | |||||
| /********************** new material operator *********************/ | /********************** new material operator *********************/ | ||||
| static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) | static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; | Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| PointerRNA ptr, idptr; | PointerRNA ptr, idptr; | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| /* add or copy material */ | /* add or copy material */ | ||||
| if (ma) { | if (ma) { | ||||
| ma = BKE_material_copy(ma); | ma = BKE_material_copy(ma); | ||||
| } | } | ||||
| else { | else { | ||||
| ma = BKE_material_add(bmain, DATA_("Material")); | ma = BKE_material_add(bmain, DATA_("Material")); | ||||
| if (BKE_scene_use_new_shading_nodes(scene)) { | if (BKE_scene_use_new_shading_nodes(scene)) { | ||||
| ED_node_shader_default(C, &ma->id); | ED_node_shader_default(C, &ma->id); | ||||
| ma->use_nodes = true; | ma->use_nodes = true; | ||||
| } | } | ||||
| } | } | ||||
| /* hook into UI */ | /* hook into UI */ | ||||
| UI_context_active_but_prop_get_templateID(C, &ptr, &prop); | UI_context_active_but_prop_get_templateID(C, &ptr, &prop); | ||||
| if (prop) { | if (prop) { | ||||
| /* when creating new ID blocks, use is already 1, but RNA | /* when creating new ID blocks, use is already 1, but RNA | ||||
| * pointer se also increases user, so this compensates it */ | * pointer se also increases user, so this compensates it */ | ||||
| ma->id.us--; | ma->id.us--; | ||||
| RNA_id_pointer_create(&ma->id, &idptr); | RNA_id_pointer_create(&ma->id, &idptr); | ||||
| RNA_property_pointer_set(&ptr, prop, idptr); | RNA_property_pointer_set(&ptr, prop, idptr); | ||||
Not Done Inline ActionsThink this could be made into a generic API function & moved to material.c BKE_material_id_remap() or BKE_material_id_permutate() It can take an array of shorts and just do bounds check, then, efa->mat_nr = remap[efa->mat_nr]; This means we can more easily sort materials/reverse... etc. However implementing this, we would also want to have a similar function for object mode, handling ob->matbits, this complicates a little more, but think its still worth doing. Once this is done, most of this logic should be in BKE, and the operators can just create & free the remap arrays. campbellbarton: Think this could be made into a generic API function & moved to `material.c`… | |||||
| RNA_property_update(C, &ptr, prop); | RNA_property_update(C, &ptr, prop); | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma); | WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,427 Lines • Show Last 20 Lines | |||||
dont need to calloc if its filled right after