Discussion:
[Bf-python] BMesh API
Treyer Lukas
2013-04-23 12:32:55 UTC
Permalink
Dear bpy Dev's

I would highly appreciate it, if the bmesh module could be extended with "bmesh.types.BMFace.'myProperty'/'myFunction' = 'myProperty' or 'myFunction'

It would allow for cleaner python code when dealing with BMesh as geometry generation tool.
For instance: I would like to write a python definition "bmesh.types.BMFace.split(line)" or "bmesh.types.BMFaceSeq.remove_hidden_surface()" or a class "Surface" that is a subclass of BMFaceSeq.

Is there an easy way for this to be implemented? Or would it call for a GSoC? What are the implications of making BMFace not a final class?


Best, Lukas
Campbell Barton
2013-04-23 13:27:11 UTC
Permalink
Post by Treyer Lukas
Dear bpy Dev's
I would highly appreciate it, if the bmesh module could be extended with "bmesh.types.BMFace.'myProperty'/'myFunction' = 'myProperty' or 'myFunction'
It would allow for cleaner python code when dealing with BMesh as geometry generation tool.
For instance: I would like to write a python definition "bmesh.types.BMFace.split(line)" or "bmesh.types.BMFaceSeq.remove_hidden_surface()" or a class "Surface" that is a subclass of BMFaceSeq.
Is there an easy way for this to be implemented? Or would it call for a GSoC? What are the implications of making BMFace not a final class?
Best, Lukas
Hi Lukas,
Realistically I don't think this will be added, with mesh data we use
a C based API (see customdata.c), and any complicated data types
(Vertex Groups for eg), have to be added in C and manage their own
memory, comparison, interpolation etc.

This is really low level stuff - so python _could_ define some binary
blob thay fits into customdata, but it wouldn't be handled nicely for
subdivde. extrude etc.
and IMHO this is too low level for python to be used.

Suggest to use existing primitive data types to either store data (255
bytes), or an id (probably an int) which python can use to lookup a
dictionary to do whatever it likes.

Not sure how familier you are with the bmesh api but steps would be...
- add customdata int layer to faces with a name unique to your purpose.
- keep a store of data in python (can be stored anywhere - as an ID
property on the mesh for example).
- Map each faces int property to your data-store.
- Make some small python api so you can do: data = mydata_face_get(f),
mydata_face_set(f, data)
.... where data can be any python object.
Treyer Lukas
2013-04-23 16:23:00 UTC
Permalink
Well. Then I would probably prefer to write a wrapper for the wrapper? as proposed here
http://stackoverflow.com/questions/399022/why-cant-i-subclass-datetime-date

With normal bpy.types.MeshPolygon.customdata = bpy.props.IntProperty() I can add properties.
With Bmesh this is not possible. Why?
bmesh.types.BMFace.custom = bpy.props.StringProperty(name="my", default="String")
TypeError: can't set attributes of built-in/extension type 'BMFace'

What are the existing primitive data you mention? Are we talking about Python or C API of BMesh?
Assuming you're talking about C functions in your step by step instructions: I don't want to add anything in C. I want my python code to run with an official Blender release.
Treyer Lukas
2013-04-23 18:17:16 UTC
Permalink
Ah, it is me who should write the C code! Sorry for not getting it in the first place!? I have never written anything in C before. But am I getting it right? You want to reference python data in the C-type, right? But how is this possible then?:

bpy.types.MeshPolygon.custom = "custom"

would it be possible to extend the bmesh wrapper in a way that custom data assignment would be as simple as above? Possibly with some automatic translation to a pointer in C, if necessary?
Treyer Lukas
2013-04-24 09:57:58 UTC
Permalink
Dear mailing list readers

For some reason the only doc I found yesterday on google about custom layers was "blah blah" in the the BMesh API<http://www.blender.org/documentation/blender_python_api_2_63_5/bmesh.types.html#bmesh.types.BMVertSeq.layers>.
Now with the the help of CoDEmanX, I discovered custom layers in Bmesh.

Just for clarification for "dumb" readers like me (an extension to the BMesh API Doc<http://www.blender.org/documentation/blender_python_api_2_63_2/bmesh.html#customdata-access>):

bm.verts, bm.edges, bm.faces are not just a lists but they are of type
bmesh.types.BMVertSeq, bmesh.types.BMEdgeSeq, bmesh.types.BMFaceSeq

The access to custom data of a vert for instance is implemented in bmesh.types.BMVert
and bmesh.types.VertSeq together.

Let's say you want to store the coordinates of a bounding box of a BMFace.
What I wanted to do in the first place was:
bm.faces[0].b_rect = [vmax,vmin,hmax,hmin]

Now with layers it looks a bit different:
bm.faces[0][b_rect] = "we will come to the bounding box later"
Note that the following will not work:
bm.faces[0]['b_rect'] = "something"

The layer needs to be accessed with the key generated by the face sequence as follows:
key = bm.faces.layers.int.new("b_rect")
bm.faces[0][key] #read/write access

You can retrieve the key by typing:
key = bm.faces.layers.int['b_rect']

Now what Campbell suggested to my problem was storing my complex data in a list and adding the index of the data in that list to my face as an int layer:

MyData = []
MyData.append([vmax,vmin,hmax,hmin])
index = len(MyData)-1

bm.faces[0][b_rect] = index


I still hope that at some point I could extend the wrapper classes directly to store my data.


Best, Lukas
CoDEmanX
2013-04-24 10:25:49 UTC
Permalink
Couldn't you add 4 faces.layers.float (vmax, vmin,hmax, hmin) ?
Post by Treyer Lukas
Dear mailing list readers
For some reason the only doc I found yesterday on google about custom layers was "blah blah" in the the BMesh API<http://www.blender.org/documentation/blender_python_api_2_63_5/bmesh.types.html#bmesh.types.BMVertSeq.layers>.
Now with the the help of CoDEmanX, I discovered custom layers in Bmesh.
bm.verts, bm.edges, bm.faces are not just a lists but they are of type
bmesh.types.BMVertSeq, bmesh.types.BMEdgeSeq, bmesh.types.BMFaceSeq
The access to custom data of a vert for instance is implemented in bmesh.types.BMVert
and bmesh.types.VertSeq together.
Let's say you want to store the coordinates of a bounding box of a BMFace.
bm.faces[0].b_rect = [vmax,vmin,hmax,hmin]
bm.faces[0][b_rect] = "we will come to the bounding box later"
bm.faces[0]['b_rect'] = "something"
key = bm.faces.layers.int.new("b_rect")
bm.faces[0][key] #read/write access
key = bm.faces.layers.int['b_rect']
MyData = []
MyData.append([vmax,vmin,hmax,hmin])
index = len(MyData)-1
bm.faces[0][b_rect] = index
I still hope that at some point I could extend the wrapper classes directly to store my data.
Best, Lukas
_______________________________________________
Bf-python mailing list
Bf-python at blender.org
http://lists.blender.org/mailman/listinfo/bf-python
Treyer Lukas
2013-04-24 12:05:21 UTC
Permalink
I've think I want to store Vectors. I could pack them into a float

and store them in 4 layers, as suggested (maybe as int's). Instead

of max/min I would need the corners of the bounding rectangle.

TL,TR,BL,BR

Of course it would be much easier to write

face.calc_center_bounds()

which would store its bounds in face.bounds ;-)

Then also the precision of my coordniates would be 2^32 instead of 2^8?

Or would you suggest to store 12 layers??
Post by CoDEmanX
Couldn't you add 4 faces.layers.float (vmax, vmin,hmax, hmin) ?
Campbell Barton
2013-04-24 12:12:08 UTC
Permalink
Post by Treyer Lukas
I've think I want to store Vectors. I could pack them into a float
and store them in 4 layers, as suggested (maybe as int's). Instead
of max/min I would need the corners of the bounding rectangle.
TL,TR,BL,BR
Of course it would be much easier to write
face.calc_center_bounds()
which would store its bounds in face.bounds ;-)
Then also the precision of my coordniates would be 2^32 instead of 2^8?
Or would you suggest to store 12 layers??
Post by CoDEmanX
Couldn't you add 4 faces.layers.float (vmax, vmin,hmax, hmin) ?
If you want to put many floats in a layer you could use pythons script
module and pack/unpack them into bytes (string layer)
--
- Campbell
Loading...