1
$\begingroup$

I work on a script that reduces the vertex number of a Mesh meeting certain criteria.

To get it work, I need my own subclasses for Mesh, bpy_types.MeshEdge and bpy.types.MeshVertex to store some custom data. 'Mesh' is ok, but if I do something like:

class CustomVertex(bpy.types.MeshVertex):
    def __init__(self, inMesh, inVertex):
        pass

I get an error message:

TypeError: bpy_struct.__new__(type): expected a single argument

Blender, for some reason, doesn't like changing __init__()'s number of arguments, and also cannot be tricked with packaging multiple variables into a tuple or a list.

But, if I cannot pass in the mesh owning MeshVertex without passing it as a variable is there any function like bpy.types.MeshEdge.owner() or anything similar to refer to the Mesh in which the MeshEdge or the MeshVertex is in?

$\endgroup$
1
$\begingroup$

In theory you could add default values - like inMesh=None, inVertex=[], to be compatible with python code that doesn't add the extra arguments. In reality that may still fail as blender uses mostly C/C++ code for internal data like vertices, and it only provides a thin python wrapper to access that data, so some areas will not work well with custom python classes.

The good news is that you don't have to do any subclassing as blender supports adding custom properties to many existing classes. While the vertex and edge classes aren't in that list you can add properties to the Mesh class.

A collection allows you to create a property that is a list of custom classes, this would allow you to have a list that holds as many extra properties as you want for each vertex.

A slightly adjusted version of the example in the api docs -

import bpy

class CustomVertex(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name="Test Prop", default="Unknown")
    value = bpy.props.IntProperty(name="Test Prop", default=22)

bpy.utils.register_class(CustomVertex)

bpy.types.Mesh.my_vertdata = bpy.props.CollectionProperty(type=CustomVertex)

objdata = bpy.context.object.data

new_item = objdata.my_vertdata.add()
new_item.name = "Spam"
new_item.value = 1000

new_item = objdata.my_vertdata.add()
new_item.name = "Eggs"
new_item.value = 30
$\endgroup$
  • $\begingroup$ Two remarks: 1. Have you added two my_vertdata to the same vertex (objdata)? 2. Must be such a custom data added to a vertex an instance of Blender's internal property objects, like PropertyGroup, IntProperty etc? Does it have to be such a data to have an add() function to bind it tho, say, a vertex? $\endgroup$ – Gyula Sámuel Karli Mar 5 '17 at 11:47
  • $\begingroup$ The example only shows defining and adding some data, it is part of the mesh data block and has no links to individual vertices, you can think of a way to do that. $\endgroup$ – sambler Mar 6 '17 at 5:28
  • $\begingroup$ Some questions. 1. It seems that I have no occasion to run an __init__() for the ProperyGroup, am I right? I have to calculate many things for my stuff (edge lengths etc) that I would normally put to the __init__(), should I calculate them out of everything, in main code? 2. It's not clear what the objdata line does, does it simply get say, the selected Mesh? $\endgroup$ – Gyula Sámuel Karli Mar 18 '17 at 21:49
  • $\begingroup$ The objdata line only gets the data that is then used multiple times. The object.data is the property that holds the mesh data. True __init__() for propertygroups doesn't seem to work, I would make a method that sets all the initial values. You can add a method to the propertygroup so you can do something like new_item.setup("Eggs", 30) $\endgroup$ – sambler Mar 19 '17 at 4:11
  • $\begingroup$ Back to the start: it's nice that I have a data structure in Blender's favored format, but how can I bind it to my data (with the objdata.my_vertdata.add() function?) and, most importantly, how can I refer the owner object (in this example, objdata) from within the CustomVertex object? Is there an elegant solution or do I have to refer it explcitly (like new_item.ref = objdata, is this legal?) Cause this is the root problem: I cannot reach the owner object ('s other data) from the contained object. For example, I cannot reach Edge data from Edge's endpoint (a Vertex). $\endgroup$ – Gyula Sámuel Karli Mar 19 '17 at 8:42

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.