diff options
-rw-r--r-- | release/scripts/ui/properties_material.py | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 106 | ||||
-rw-r--r-- | source/blender/editors/render/render_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/render/render_ops.c | 3 | ||||
-rw-r--r-- | source/blender/editors/render/render_shading.c | 59 |
6 files changed, 191 insertions, 1 deletions
diff --git a/release/scripts/ui/properties_material.py b/release/scripts/ui/properties_material.py index be5e98a362f..863e596d701 100644 --- a/release/scripts/ui/properties_material.py +++ b/release/scripts/ui/properties_material.py @@ -43,6 +43,17 @@ class MATERIAL_MT_sss_presets(bpy.types.Menu): draw = bpy.types.Menu.draw_preset +class MATERIAL_MT_specials(bpy.types.Menu): + bl_label = "Material Options" + + def draw(self, context): + layout = self.layout + + layout.operator("object.material_slot_copy", icon='COPY_ID') + layout.operator("material.copy", icon='COPYDOWN') + layout.operator("material.paste", icon='PASTEDOWN') + + class MaterialButtonsPanel(bpy.types.Panel): bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' @@ -92,7 +103,8 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel): col = row.column(align=True) col.operator("object.material_slot_add", icon='ZOOMIN', text="") col.operator("object.material_slot_remove", icon='ZOOMOUT', text="") - col.operator("object.material_slot_copy", icon='COPY_ID', text="") + + col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="") if ob.mode == 'EDIT': row = layout.row(align=True) @@ -914,6 +926,7 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel): col.prop(vol, "depth_cutoff") bpy.types.register(MATERIAL_MT_sss_presets) +bpy.types.register(MATERIAL_MT_specials) bpy.types.register(MATERIAL_PT_volume_density) bpy.types.register(MATERIAL_PT_volume_shading) diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 3ea7cae2c86..c8cbf21a093 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -77,6 +77,12 @@ int material_in_material(struct Material *parmat, struct Material *mat); void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col); +/* copy/paste */ +void clear_matcopybuf(void); +void free_matcopybuf(void); +void copy_matcopybuf(struct Material *ma); +void paste_matcopybuf(struct Material *ma); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 2d4ff857b2a..038ce6c5d25 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1240,4 +1240,110 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) } } +/* copy/paste buffer, if we had a propper py api that would be better */ +Material matcopybuf; +// MTex mtexcopybuf; +static short matcopied=0; +void clear_matcopybuf(void) +{ + memset(&matcopybuf, 0, sizeof(Material)); +} + +void free_matcopybuf(void) +{ +// extern MTex mtexcopybuf; /* buttons.c */ + int a; + + for(a=0; a<MAX_MTEX; a++) { + if(matcopybuf.mtex[a]) { + MEM_freeN(matcopybuf.mtex[a]); + matcopybuf.mtex[a]= NULL; + } + } + + if(matcopybuf.ramp_col) MEM_freeN(matcopybuf.ramp_col); + if(matcopybuf.ramp_spec) MEM_freeN(matcopybuf.ramp_spec); + + matcopybuf.ramp_col= NULL; + matcopybuf.ramp_spec= NULL; + + if(matcopybuf.nodetree) { + ntreeFreeTree(matcopybuf.nodetree); + MEM_freeN(matcopybuf.nodetree); + matcopybuf.nodetree= NULL; + } +// default_mtex(&mtexcopybuf); +} + +void copy_matcopybuf(Material *ma) +{ + int a; + MTex *mtex; + + if(matcopied) + free_matcopybuf(); + + memcpy(&matcopybuf, ma, sizeof(Material)); + if(matcopybuf.ramp_col) matcopybuf.ramp_col= MEM_dupallocN(matcopybuf.ramp_col); + if(matcopybuf.ramp_spec) matcopybuf.ramp_spec= MEM_dupallocN(matcopybuf.ramp_spec); + + for(a=0; a<MAX_MTEX; a++) { + mtex= matcopybuf.mtex[a]; + if(mtex) { + matcopybuf.mtex[a]= MEM_dupallocN(mtex); + } + } + matcopybuf.nodetree= ntreeCopyTree(ma->nodetree, 0); + matcopybuf.preview= NULL; + matcopybuf.gpumaterial.first= matcopybuf.gpumaterial.last= NULL; + matcopied= 1; +} + +void paste_matcopybuf(Material *ma) +{ + int a; + MTex *mtex; + ID id; + + if(matcopied==0) + return; + /* free current mat */ + if(ma->ramp_col) MEM_freeN(ma->ramp_col); + if(ma->ramp_spec) MEM_freeN(ma->ramp_spec); + for(a=0; a<MAX_MTEX; a++) { + mtex= ma->mtex[a]; + if(mtex && mtex->tex) mtex->tex->id.us--; + if(mtex) MEM_freeN(mtex); + } + + if(ma->nodetree) { + ntreeFreeTree(ma->nodetree); + MEM_freeN(ma->nodetree); + } + + GPU_materials_free(ma); + + id= (ma->id); + memcpy(ma, &matcopybuf, sizeof(Material)); + (ma->id)= id; + + if(matcopybuf.ramp_col) ma->ramp_col= MEM_dupallocN(matcopybuf.ramp_col); + if(matcopybuf.ramp_spec) ma->ramp_spec= MEM_dupallocN(matcopybuf.ramp_spec); + + for(a=0; a<MAX_MTEX; a++) { + mtex= ma->mtex[a]; + if(mtex) { + ma->mtex[a]= MEM_dupallocN(mtex); + if(mtex->tex) id_us_plus((ID *)mtex->tex); + } + } + + ma->nodetree= ntreeCopyTree(matcopybuf.nodetree, 0); + + /* + BIF_preview_changed(ID_MA); + BIF_undo_push("Paste material settings"); + scrarea_queue_winredraw(curarea); + */ +} diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index 7b4c0194c5d..846edd67736 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -43,6 +43,9 @@ void MATERIAL_OT_new(struct wmOperatorType *ot); void TEXTURE_OT_new(struct wmOperatorType *ot); void WORLD_OT_new(struct wmOperatorType *ot); +void MATERIAL_OT_copy(struct wmOperatorType *ot); +void MATERIAL_OT_paste(struct wmOperatorType *ot); + void SCENE_OT_render_layer_add(struct wmOperatorType *ot); void SCENE_OT_render_layer_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index 3e1643fab7b..0672709d364 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -52,6 +52,9 @@ void ED_operatortypes_render(void) WM_operatortype_append(MATERIAL_OT_new); WM_operatortype_append(TEXTURE_OT_new); WM_operatortype_append(WORLD_OT_new); + + WM_operatortype_append(MATERIAL_OT_copy); + WM_operatortype_append(MATERIAL_OT_paste); WM_operatortype_append(SCENE_OT_render_layer_add); WM_operatortype_append(SCENE_OT_render_layer_remove); diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 4be35a4a2c4..413d9889b5d 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -758,3 +758,62 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot) RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", ""); } + + + +/* material copy/paste */ +static int copy_material_exec(bContext *C, wmOperator *op) +{ + Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data; + + if(ma==NULL) + return; + + copy_matcopybuf(ma); + + WM_event_add_notifier(C, NC_MATERIAL, ma); + + return OPERATOR_FINISHED; +} + +void MATERIAL_OT_copy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Material"; + ot->idname= "MATERIAL_OT_copy"; + ot->description="Copy the material settings and nodes."; + + /* api callbacks */ + ot->exec= copy_material_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int paste_material_exec(bContext *C, wmOperator *op) +{ + Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data; + + if(ma==NULL) + return; + + paste_matcopybuf(ma); + + WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING_DRAW, ma); + + return OPERATOR_FINISHED; +} + +void MATERIAL_OT_paste(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Paste Material"; + ot->idname= "MATERIAL_OT_paste"; + ot->description="Copy the material settings and nodes."; + + /* api callbacks */ + ot->exec= paste_material_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} |