Show crease value for selected edge with Python

Hello,

how can I get crease and bevel weight value for selected edge via Python?
What I need exist in N panel Item tab
Edge Data
but there is no tool-tip with python code.

Asked here but seems they have no clue what I’m talking about (I need to see value, not to change).
Yes, that script was useful, currently it look like this:
CaB
For some reason it can’t set Crease and Weight value on new object edge/s. Only after I manually add Crease mark on some edge it start to change values on all other edges, the same for Bevel Weight.

It seem, when I manually add mark, it add some data to the object and after then I only can modify it with this script

To the point.
I need something like this:
CaB todo

Code
    import bpy, bmesh
    from bpy.types import Panel, Operator, Menu

    # Add-on info
    bl_info = {
        "name": "Crease and Bevel",
        "author": "TLousky",
        "version": (0, 0, 1),
        "blender": (2, 83, 3),
        "location": "View3D > Properties > CaB",
        "description": "Shortcut UI panel for Mesh edge crease and vertex bevel weight properties", 
        "doc_url": "",
        "tracker_url": "",      
        "category": "3D View"
    }

    ###########################################################################################
    ################################### Functions #############################################
    ###########################################################################################

    #https://blender.stackexchange.com/questions/44787/python-code-for-edge-data-bevel-and-crease-weight/187853#187853
    class creaseAndBevelPG(bpy.types.PropertyGroup):
        ## Update functions
        def update_bevelWeight( self, context ):
            ''' Update function for bevelWeight property '''

            o  = bpy.context.object
            d  = o.data
            bm = bmesh.from_edit_mesh( d )

            bevelWeightLayer = bm.edges.layers.bevel_weight['BevelWeight']

            if self.whoToInfluence == 'Selected Elements':
                selectedVerts = [ v for v in bm.edges if v.select ]
                for v in selectedVerts: v[ bevelWeightLayer ] = self.bevelWeight
            else:
                for v in bm.edges: v[ bevelWeightLayer ] = self.bevelWeight

            bmesh.update_edit_mesh( d )

        def update_edgeCrease( self, context ):
            ''' Update function for edgeCrease property '''

            o  = bpy.context.object
            d  = o.data
            bm = bmesh.from_edit_mesh( d )

            creaseLayer = bm.edges.layers.crease['SubSurfCrease']

            if self.whoToInfluence == 'Selected Elements':
                selectedEdges = [ e for e in bm.edges if e.select ]
                for e in selectedEdges: e[ creaseLayer ] = self.edgeCrease
            else:
                for e in bm.edges: e[ creaseLayer ] = self.edgeCrease

            bmesh.update_edit_mesh( d )

        ## Properties
        items = [
            ('All', 'All', ''),
            ('Selected Elements', 'Selected Elements', '')
        ]

        whoToInfluence = bpy.props.EnumProperty( # Material distribution method
            description = "Influence all / selection",
            name        = "whoToInfluence",
            items       = items,
            default     = 'Selected Elements'
        )

        bevelWeight = bpy.props.FloatProperty(
            description = "Bevel Weight",
            name        = "Set bevel Weight",
            min         = 0.0,
            max         = 1.0,
            step        = 0.01,
            default     = 0,
            update      = update_bevelWeight
        )

        edgeCrease = bpy.props.FloatProperty(
            description = "Edge Crease",
            name        = "Set edge Crease",
            min         = 0.0,
            max         = 1.0,
            step        = 0.01,
            default     = 0,
            update      = update_edgeCrease
        )    

    ###########################################################################################
    ###################################### UI #################################################
    ###########################################################################################

    class creaseAndBevelPanel(Panel):
        bl_label = "Crease and Bevel"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
        bl_category = 'CaB'
     
        def draw( self, context ):
                layout = self.layout
                props  = context.scene.creaseAndBevelPG # Create reference to property group
                            
                #box = layout.box()                    # Draw a box
                #col = box.column( align = True )      # Create a column
    #            col = layout.column( align = True )
    #            if (context.active_object is not None) and (context.active_object.mode == 'OBJECT'):
    #                col.enabled = False
    #            col.operator("select.edge_crease_value", icon = 'SORTBYEXT')
                #col.prop( props, "whoToInfluence"  )  # Add properites to panel
                col = layout.column( align = True )
                if (context.active_object is not None) and (context.active_object.mode == 'OBJECT'):
                    col.enabled = False
                col.prop( props, "bevelWeight"     )
                col.prop( props, "edgeCrease"      )      
                                  
    ###########################################################################################
    ##################################### Register ############################################
    ########################################################################################### 
     
    classes = (
                creaseAndBevelPG,
                creaseAndBevelPanel,
    )

    def register():
        from bpy.utils import register_class
        for cls in classes:
            register_class(cls)
        
        bpy.types.Scene.creaseAndBevelPG = bpy.props.PointerProperty( type = creaseAndBevelPG )
        
    def unregister():
        from bpy.utils import unregister_class
        for cls in reversed(classes):
            unregister_class(cls)
            
    if __name__ == "__main__":
        register()

Try getting the crease layer like the following instead:

    # creaseLayer = bm.edges.layers.crease['SubSurfCrease']
    creaseLayer = bm.edges.layers.crease.verify()

    ...

verify method

1 Like

Yes, thank you! Now it changes values on new object.
It remains only to understand how to show values on selected edge/s.

e[creaseLayer] will return the actual value. What is preventing you from displaying that value?

For example, I set a 0.25 and a 0.5 crease value on 2 sides of a plane and selected them:

>>> selectedEdges = [ e for e in bm.edges if e.select ]
>>> for e in selectedEdges: print(e[ creaseLayer ])
... 
0.5
0.25
1 Like

My knowledge is very basic…
so I defined this two functions

    def get_crease_selected():
        o  = bpy.context.object
        d  = o.data
        bm = bmesh.from_edit_mesh( d )

        creaseLayer = bm.edges.layers.crease.verify()

        selectedEdges = ""
        for e in bm.edges:
            if e.select:
                selectedEdges += (str(e[ creaseLayer ]) + ' ')
        return selectedEdges

    def get_bevelWeight_selected():
        o  = bpy.context.object
        d  = o.data
        bm = bmesh.from_edit_mesh( d )

        bevelWeightLayer = bm.edges.layers.bevel_weight.verify()

        selectedVerts = ""
        for v in bm.edges:
            if v.select:
                selectedVerts += (str(v[ bevelWeightLayer ]) + ' ')
        return selectedVerts

and added them in UI section

    col.label(text='Weight value: ' + get_bevelWeight_selected())
    col.label(text='Crese value: ' + get_crease_selected()

Got this
CaB done
but there is some strange behavior with values after switch to Object and back in Edit mode.
Example, if I set edge crease value to 0.25 then switch to Object and back in Edit mode and select that edge, the value show 0.247…54
Why so?

Whole Addon code
    import bpy, bmesh
    from bpy.types import PropertyGroup, Panel, Operator, Menu

    # Add-on info
    bl_info = {
        "name": "Crease and Bevel",
        "author": "TLousky",
        "version": (0, 0, 1),
        "blender": (2, 83, 3),
        "location": "View3D > Properties > CaB",
        "description": "Shortcut UI panel for Mesh edge crease and vertex bevel weight properties", 
        "doc_url": "",
        "tracker_url": "",      
        "category": "3D View"
    }

    ###########################################################################################
    ################################### Functions #############################################
    ###########################################################################################

    #https://blender.stackexchange.com/questions/44787/python-code-for-edge-data-bevel-and-crease-weight/187853#187853
    class creaseAndBevelPG(PropertyGroup):
        ## Update functions
        def update_bevelWeight( self, context ):
            ''' Update function for bevelWeight property '''

            o  = bpy.context.object
            d  = o.data
            bm = bmesh.from_edit_mesh( d )

            #bevelWeightLayer = bm.edges.layers.bevel_weight['BevelWeight']
            bevelWeightLayer = bm.edges.layers.bevel_weight.verify()

            if self.whoToInfluence == 'Selected Elements':
                selectedVerts = [ v for v in bm.edges if v.select ]
                for v in selectedVerts: v[ bevelWeightLayer ] = self.bevelWeight
            else:
                for v in bm.edges: v[ bevelWeightLayer ] = self.bevelWeight

            bmesh.update_edit_mesh( d )

        def update_edgeCrease( self, context ):
            ''' Update function for edgeCrease property '''

            o  = bpy.context.object
            d  = o.data
            bm = bmesh.from_edit_mesh( d )

            #creaseLayer = bm.edges.layers.crease['SubSurfCrease']
            creaseLayer = bm.edges.layers.crease.verify()

            if self.whoToInfluence == 'Selected Elements':
                selectedEdges = [ e for e in bm.edges if e.select ]
                for e in selectedEdges: e[ creaseLayer ] = self.edgeCrease
            else:
                for e in bm.edges: e[ creaseLayer ] = self.edgeCrease

            bmesh.update_edit_mesh( d )
            
    #        selectedEdges = [ e for e in bm.edges if e.select ]
    #        for e in selectedEdges: print(e[ creaseLayer ])

        ## Properties
        items = [
            ('All', 'All', ''),
            ('Selected Elements', 'Selected Elements', '')
        ]

        whoToInfluence = bpy.props.EnumProperty( # Material distribution method
            description = "Influence all / selection",
            name        = "whoToInfluence",
            items       = items,
            default     = 'Selected Elements'
        )

        bevelWeight = bpy.props.FloatProperty(
            description = "Bevel Weight",
            name        = "Set bevel Weight",
            min         = 0.0,
            max         = 1.0,
            step        = 0.01,
            default     = 0,
            update      = update_bevelWeight
        )

        edgeCrease = bpy.props.FloatProperty(
            description = "Edge Crease",
            name        = "Set edge Crease",
            min         = 0.0,
            max         = 1.0,
            step        = 0.01,
            default     = 0,
            update      = update_edgeCrease
        )    

    def get_crease_selected():
        o  = bpy.context.object
        d  = o.data
        bm = bmesh.from_edit_mesh( d )

        creaseLayer = bm.edges.layers.crease.verify()

        selectedEdges = ""
        for e in bm.edges:
            if e.select:
                selectedEdges += (str(e[ creaseLayer ]) + ' ')
        return selectedEdges

    def get_bevelWeight_selected():
        o  = bpy.context.object
        d  = o.data
        bm = bmesh.from_edit_mesh( d )

        bevelWeightLayer = bm.edges.layers.bevel_weight.verify()

        selectedVerts = ""
        for v in bm.edges:
            if v.select:
                selectedVerts += (str(v[ bevelWeightLayer ]) + ' ')
        return selectedVerts
    ###########################################################################################
    ###################################### UI #################################################
    ###########################################################################################

    class creaseAndBevelPanel(Panel):
        bl_label = "Crease and Bevel"
        bl_space_type = 'VIEW_3D'
        bl_region_type = 'UI'
        bl_category = 'CaB'

    #    @classmethod
    #    def poll( self, context ):
    #        ''' Only show panel if there is an active mesh object '''
    #        return context.object and context.object.type == 'MESH'
     
        def draw( self, context ):
                layout = self.layout
                props  = context.scene.creaseAndBevelPG # Create reference to property group
                            
                #box = layout.box()                    # Draw a box
                #col = box.column( align = True )      # Create a column
    #            col = layout.column( align = True )
    #            if (context.active_object is not None) and (context.active_object.mode == 'OBJECT'):
    #                col.enabled = False
    #            col.operator("select.edge_crease_value", icon = 'SORTBYEXT')
    #            col.prop( props, "whoToInfluence"  )  # Add properites to panel            
                col = layout.column( align = True )
                if context.active_object.mode == 'EDIT':
                    col.label(text='Weight value: ' + get_bevelWeight_selected())
                    col.label(text='Crese value: ' + get_crease_selected())
                if (context.active_object is not None) and (context.active_object.mode == 'OBJECT'):
                    col.enabled = False
                col.prop( props, "bevelWeight"     )
                col.prop( props, "edgeCrease"      )      
                                  
    ###########################################################################################
    ##################################### Register ############################################
    ########################################################################################### 
     
    classes = (
                creaseAndBevelPG,
                creaseAndBevelPanel,
    )

    def register():
        from bpy.utils import register_class
        for cls in classes:
            register_class(cls)
        
        bpy.types.Scene.creaseAndBevelPG = bpy.props.PointerProperty( type = creaseAndBevelPG )
        
    def unregister():
        from bpy.utils import unregister_class
        for cls in reversed(classes):
            unregister_class(cls)
            
    if __name__ == "__main__":
        register()

Anyway it’s exactly what I needed.
Thank you!

I changed

selectedEdges += (str(e[ creaseLayer ]) + ' ')

to

selectedEdges += (str(round(e[ creaseLayer ], 2)) + ' ')

and value rounded to 0.25
but why it change when switching from Object to Edit mode I can’t understand…

Seems like we still can’t select freestyle Edges/Layer in BMESH… or says not supported basically in the console.

So I had to use / grab from the mesh data, but then that doesn’t update while in bmesh/edit mode, that I can tell. So I had to toggle object/edit mode at the end of my script to refresh/get the final freestyle marked edges…

Unless I can refresh a better way maybe?