material copy/paste
authorCampbell Barton <ideasman42@gmail.com>
Thu, 28 Jan 2010 17:31:11 +0000 (17:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 28 Jan 2010 17:31:11 +0000 (17:31 +0000)
not enough room for the buttons so adding a menu, icon is ugly probably needs a new icon?.

release/scripts/ui/properties_material.py
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/intern/material.c
source/blender/editors/render/render_intern.h
source/blender/editors/render/render_ops.c
source/blender/editors/render/render_shading.c

index be5e98a..863e596 100644 (file)
@@ -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)
index 3ea7cae..c8cbf21 100644 (file)
@@ -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
index 2d4ff85..038ce6c 100644 (file)
@@ -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);
+       */
+}
index 7b4c019..846edd6 100644 (file)
@@ -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);
 
index 3e1643f..0672709 100644 (file)
@@ -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);
index 4be35a4..413d988 100644 (file)
@@ -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;
+}