[Bf-funboard] per vertex properties and property sets: second proposal

Gregor Mückl bf-funboard@blender.org
Sun, 24 Aug 2003 18:23:49 +0200

Content-Type: text/plain;
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


Although I've started with implementing global property sets I'm posting a 
massively updated version of the original proposal. The majority of the 
changes aims at easier implementation and easier reuse of global property 
sets in other situations (like object properties).

See the appendix for details.

I'm posting this to funboard as well as to the developers because I belive 
that this is interesting to everyone, although more than half of the document 
is on the technical side of things.


Content-Type: text/plain;
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="pvpdesign.txt"


This document discusses some of the design ideas and implementation issues with
this feature.

It also reflects the current state of the implementation.


The idea is to extend the current property mechanism in a way that allows the
assignment of properties to various objects including vertices.

The implementation has two parts: global property sets and their usage in assigning
properties to individual vertices.

Global property sets are named lists of properties that behave just like object
properties. A new property type will be introduced to reference global property
sets. This property type will *not* be available in global property sets to avoid
circular references from the ground up.

Global property sets can be shared between as many local sets as you like. Indeed
they are introduced to make the mass-assigning of long lists of properties easier
for the user. At the same time it is possible to override properties from the
global sets using local properties of the same name.


[Note that this is a completely arbitrary example - there are other more likely
use cases :-)]

Create a property set named "basicarmour"
Add a property named "armour", type integer, value 1000
Add a property named "shiny", type integer, value 0

Create a propety set named "shinyarmour"
Add a property named "shiny", type integer, value 1
Add a property named "reflective", type integer, value 1

Create a sphere and select a vertex.

Assign the property set "basicarmour" to the vertex

This means that the vertex will in effect have the following properties and

- "armour", type integer, value 1000
- "shiny", type integer, value 0

Add a property named "armour", type integer, value 10 to the vertex

Then the visible property values for the vertex look like this:
- "armour", type integer, value 10
- "shiny", type integer, value 0

Note that the property set "basicarmour" is unchanged

Assign the property set "shinyarmour" to the top of the stack for this

Then the visible property values would look like this:
- "armour", type integer, value 10
- "shiny", type integer, value 1
- "reflective", type integer, value 1


Already implemented:

Added two buttons to the top-left corner of the real time buttons (moved actuator buttons
down). These show a tab-like behaviour that switches between the properties buttons and the
rest of the realtime buttons. The properties buttons have been moved to this tab.

To do:

Implement second "property stack" on the right of the property tab below a drop down button
that allows to manage and edit the global property sets.

Make the (now) object-specific property list more context-aware.


Already implemented:

struct bPropertySet {
  ID id;
  ListBase *props; /* properties are stored in a linked list */

Added to struct Main:
  ListBase properties;

Allocated new ID:
#define ID_PSET         MAKE_ID2('P', 'R')

[TODO: sDNA code for saving and loading]

Still pending implementation:

struct bVertexProperties {
  struct bVertexProperties *prev, *next;
  int vert; /* index of vertex this struct is assigned to */
  ListBase *local; /* properties that are assigned only to this vertex*/

NOTE: Is it a good idea to refer to a vertex like that? How else could it be
done? Adding a pointer to the MVert struct seems a bit too heavy to me.


in the Mesh struct:
  ListBase vertexprop; /* pointer to the list of bVertexProperties */

[TODO: add the reference to global property set as new property type]


Functions needing changes:

in blenkernel/intern/property.c:

	bProperty *get_property(Object *ob, char *name);

needs to be changed to:

	bProperty *get_property(ListBase *lb, char *name);

Reason: This way this function can be applied to global property sets as well.
        It will also be changed to correctly follow links to global property sets.

Functions that are partially implemented:

struct bPropertySet *pset_addpset(void);
void pset_freepset(struct bPropertySet *pset);
void pset_appendproperty(struct bPropertySet *pset, struct bProperty *prop);

Functions that are entirely missing:

void pset_removeproperty(struct bPropertySet *pset, struct bProperty *prop);

/* Functions for manipulating vertex properties */
/* TODO: choose other names that appear more consistent with existing blender code */
bVertexProperties *VPropCreate(Mesh *mesh, MVert *mvert);
void VPropDestroy(Mesh *mesh, bVertexProperties *props);
void VPropAddProp(bVertexProperties *vertexprops, bProperty *prop);
void VPropRemoveProp(bVertexProperties *vertexprops, bProperty *prop);

A couple of additional functions could be needed. But this list should cover the
basic functionality.

TODO: What about Python interface?


All code that looks for values of named properties should not traverse the properties
itself but use the get_property() function instead as it will follow links to global
property sets correctly and in the correct order.

[NOTE: I never looked whether there really is dodgy code that omits get_property()]

When entering edit mode the vertex and face arrays are converted to linked lists
to simplify reordering. During this step the per-vertex properties must be converted
so that they point to the proper vertices in the linked list. When leaving edit mode
these pointers must be converted to the correct vertex indices again.