0
$\begingroup$

Reading here and I saw that there is no possibility of having a custom property based on a selected face, but in blender I think you can do "Hackerate" and fly over this problem. I think for example, creating a FaceMap,or a temporary vertex group and to base the properties on these objects bpy.types, I am probably wrong, but I would like to have an opinion from some fan of these experiments. I would create different problems with these methods I believe, has anyone got to try it?

Have float property registered in a class like:

class MY_PT_Panel(bpy.types.Panel):

bl_label = "blah"
bl_idname = "blah"
bl_space_type = "blah"
bl_region_type = "blah"
bl_category = "blah"


def draw(self, context):
    ob = bpy.context.active_object
    ###how to get property ?
    layout = self.layout               
    row = layout.row()
    row.prop(##??##, 'my_float', text="")

class Myproperty(bpy.types.PropertyGroup):
    my_float: FloatProperty(default=0)

def register():
    from bpy.types import ##best type##
    ##best type##.faceproperty = bpy.props.PointerProperty(type=Myproperty)

I read about bmesh method but not understand if that information they are right for me : https://docs.blender.org/api/blender_python_api_2_78_release/bmesh.html

I have also seen looked at among the bpy.types. in the python console there is also bpy.types.SelectedUvElement and bpy.types.UVLoopLayers Assuming there is a uv, would I have the ability to customize the face property based on an uv layer?

Edit: I would like to clarify that the use of the selected face is clearly useful in edit mode and on the use of a FloatProperty slider, so I would like the values on each face to remain recorded once interacted

To make me understand better, I would like to get this property as you would with a bpy.types.Object

like to in register:

from bpy.types import Object

Object.example_property = bpy.props.PointerProperty(type=Myproperty)
$\endgroup$
1
$\begingroup$

Mesh data layers

Mesh components, faces, edges and vertices, can have custom data layers. A float can be assigned to each face in a mesh with custom face float layer

In object mode the index of the active face is me.polygons.active and in bmesh the active face is bm.faces.active, which will be None if no face is active.

Here is a simple test script. Run in object mode. Adds a custom float layer, and sets the value of the active face to 5. Switches to edit mode, prints the layer float value of the active face.

import bpy
import bmesh

context = bpy.context
ob = context.object
me = ob.data

# add a float layer to faces
float_layer = me.polygon_layers_float.new(name="float_layer")

# set the value of the active face to 5.0

float_layer.data[me.polygons.active].value = 5
bpy.ops.object.mode_set(mode='EDIT')

bm = bmesh.from_edit_mesh(me)
# get the float layer
float_layer = bm.faces.layers.float.get(float_layer.name)

af = bm.faces.active
if af:
    print(af[float_layer])

UV is also a mesh layer, associated with face loops (each uv face has its own set of 2d coordinate verts, whereas mesh faces, if connected, share verts with other faces at edges) For an example see Text Editor > Templates > Python > Operator Mesh UV

Property and Panel

Since the property attains to a mesh, possibly a good idea to make it a bpy.types.Mesh property.

Have made an edit mode bmesh property on the panel. The poll method will set it, and clear it when in object mode. The mesh needs a "float_layer" as explained above. Run the code above to add a face float layer to the active mesh object

The poll method is required to attach a live edit bmesh to the panel when the object enters edit mode (polls).

enter image description here

import bpy
import bmesh

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Mesh properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "data"
    ebm = dict()

    @classmethod
    def poll(cls, context):
        if context.mode == 'EDIT_MESH':
            me = context.edit_object.data
            fl = me.polygon_layers_float.get("float_layer")

            if fl:
                cls.ebm.setdefault(me.name, bmesh.from_edit_mesh(me))
                return True

        cls.ebm.clear()
        return False

    def draw(self, context):
        layout = self.layout
        me = context.edit_object.data
        layout.prop(me, "float_value")

def set_float(self, value):

    bm = HelloWorldPanel.ebm.setdefault(self.name, bmesh.from_edit_mesh(self))

    # get the float layer
    float_layer = bm.faces.layers.float.get("float_layer")

    af = bm.faces.active
    if af:
        af[float_layer] = value
        bmesh.update_edit_mesh(self)


def get_float(self):        
    bm = HelloWorldPanel.ebm.setdefault(self.name, bmesh.from_edit_mesh(self))

    # get the float layer
    float_layer = bm.faces.layers.float.get("float_layer")

    af = bm.faces.active
    if af:
        return(af[float_layer])
    #bm.free()

def register():
    bpy.utils.register_class(HelloWorldPanel)
    bpy.types.Mesh.float_value = bpy.props.FloatProperty(get=get_float, set=set_float)

def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)


if __name__ == "__main__":
    register()

enter image description here
Script designed for 2.8 can confirm also runs in 2.79

$\endgroup$
  • $\begingroup$ Ty batFINGER,so thanks to you I realized that you can do it but i not understand how to register floatproperty in classs with bpy.types in register, and how put in ui panel row.prop(##your_example.faceproperty##,'my_float', text='Ty bat') like to edit mode, if i understand well only bmesh in edit mode? $\endgroup$ – Pastrokkio Jul 3 at 14:22
  • $\begingroup$ I edited the question, because my problem is also how to handle this with a ui panel and a float slider, I have no experience on the faces and I am completely unable to get the necessary information correctly. $\endgroup$ – Pastrokkio Jul 3 at 17:30
  • $\begingroup$ So I thank you for this interest, I didn't think it was so complex and I understand very little (I have no confidence with this method at all) I already have a panel that must always be visible, so I suppose I'll have to change something, but I know that in blender 2.8 this doesn't work and in blender 2.79 it reports an error that I can't identify (im poor knowledge of the method) error Text in line 17, 52 and 44 $\endgroup$ – Pastrokkio Jul 4 at 1:13
  • 1
    $\begingroup$ No, needs the poll. There was a cut-n-paste error on line 17. Can confirm (via gif) working on both 2.79 and 2.8 Polls in edit mode. Could be modified to also work in object mode. $\endgroup$ – batFINGER Jul 4 at 1:35
  • 1
    $\begingroup$ I can open a new file in either 2.79 or 2.8, with the cube active, run the two scripts above (either order) and it works as expected (as displayed above) . I have no idea what you mean re q marks and classes being recorded. $\endgroup$ – batFINGER Jul 4 at 3:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.