bmesh docs:

- add examples for custom-data access
- group BMesh types logically in docs
- added missing docstrings

needed to add grouping functionality to sphinx for this.
This commit is contained in:
Campbell Barton
2012-03-21 05:33:37 +00:00
parent 1d5922fbaf
commit 9773f87891
9 changed files with 215 additions and 50 deletions

View File

@@ -30,10 +30,19 @@ For an overview of BMesh data types and how they reference each other see:
*Campbell Barton, 13, March 2012*
.. todo::
.. warning::
TODO Items Are
* add access to BMesh **walkers**
* add a way to re-tessellate an editmode bmesh.
* add deform vert custom-data access.
Example Script
--------------
.. literalinclude:: ../../../release/scripts/templates/bmesh_simple.py
Stand-Alone Module
@@ -66,6 +75,35 @@ its good practice to call :class:`bmesh.types.BMesh.free` which will remove all
further access.
CustomData Access
-----------------
BMesh has a unified way to access mesh attributes such as UV's vertex colors, shape keys, edge crease etc.
This works by having a **layers** property on bmesh data sequences to access the custom data layers which can then be
used to access the actual data on each vert/edge/face/loop.
Here are some examples ...
.. code-block:: python
uv_lay = bm.loops.layers.uv.active
for face in bm.faces:
for loop in f.loops:
uv = loop[uv_lay]
print("Loop UV: %f, %f" % (uv.x, uv.y))
.. code-block:: python
shape_lay = bm.verts.layers.shape["Key.001"]
for vert in bm.verts:
shape = vert[shape_lay]
print("Vert Shape: %f, %f, %f" % (shape.x, shape.y, shape.z))
Keeping a Correct State
-----------------------
@@ -92,11 +130,5 @@ As mentioned above, it is possible to create an invalid selection state
flush the selection after performing a series of edits. this validates the selection state.
Example Script
--------------
.. literalinclude:: ../../../release/scripts/templates/bmesh_simple.py
Module Functions
----------------

View File

@@ -312,6 +312,36 @@ RNA_BLACKLIST = {
"UserPreferencesSystem": {"language", }
}
MODULE_GROUPING = {
"bmesh.types": (
("Base Mesh Type", '-'),
"BMesh",
("Mesh Elements", '-'),
"BMVert",
"BMEdge",
"BMFace",
"BMLoop",
("Sequence Accessors", '-'),
"BMElemSeq",
"BMVertSeq",
"BMEdgeSeq",
"BMFaceSeq",
"BMLoopSeq",
"BMIter",
("Selection History", '-'),
"BMEditSelSeq",
"BMEditSelIter",
("Custom-Data Layer Access", '-'),
"BMLayerAccessVert",
"BMLayerAccessEdge",
"BMLayerAccessFace",
"BMLayerAccessLoop",
"BMLayerCollection",
"BMLayerItem",
("Custom-Data Layer Types", '-'),
"BMLoopUV"
)
}
# --------------------configure compile time options----------------------------
@@ -656,6 +686,29 @@ def pymodule2sphinx(basepath, module_name, module, title):
if module_all:
module_dir = module_all
# TODO - currently only used for classes
# grouping support
module_grouping = MODULE_GROUPING.get(module_name)
def module_grouping_index(name):
if module_grouping is not None:
try:
return module_grouping.index(name)
except ValueError:
pass
return -1
def module_grouping_heading(name):
if module_grouping is not None:
i = module_grouping_index(name) - 1
if i >= 0 and type(module_grouping[i]) == tuple:
return module_grouping[i]
return None, None
def module_grouping_sort_key(name):
return module_grouping_index(name)
# done grouping support
file = open(filepath, "w", encoding="utf-8")
fw = file.write
@@ -805,8 +858,17 @@ def pymodule2sphinx(basepath, module_name, module, title):
fw("\n")
'''
if module_grouping is not None:
classes.sort(key=lambda pair: module_grouping_sort_key(pair[0]))
# write collected classes now
for (type_name, value) in classes:
if module_grouping is not None:
heading, heading_char = module_grouping_heading(type_name)
if heading:
fw(title_string(heading, heading_char))
# May need to be its own function
fw(".. class:: %s\n\n" % type_name)
if value.__doc__:
@@ -1412,7 +1474,7 @@ def write_rst_contents(basepath):
fw(".. toctree::\n")
fw(" :maxdepth: 1\n\n")
app_modules = [
app_modules = (
"bpy.context", # note: not actually a module
"bpy.data", # note: not actually a module
"bpy.ops",
@@ -1425,8 +1487,9 @@ def write_rst_contents(basepath):
"bpy.app.handlers",
# C modules
"bpy.props"
]
"bpy.props",
)
for mod in app_modules:
if mod not in EXCLUDE_MODULES:
fw(" %s\n\n" % mod)
@@ -1435,14 +1498,15 @@ def write_rst_contents(basepath):
fw(".. toctree::\n")
fw(" :maxdepth: 1\n\n")
standalone_modules = [
standalone_modules = (
# mathutils
"mathutils", "mathutils.geometry", "mathutils.noise",
# misc
"bgl", "blf", "gpu", "aud", "bpy_extras",
# bmesh
"bmesh", "bmesh.types", "bmesh.utils"
]
"bmesh", "bmesh.types", "bmesh.utils",
)
for mod in standalone_modules:
if mod not in EXCLUDE_MODULES:
fw(" %s\n\n" % mod)

View File

@@ -523,7 +523,7 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float
int i;
int numFaces= mesh->getNumTessFaces(mesh);
/* BMESH spesific check that we have tessfaces,
/* BMESH specific check that we have tessfaces,
* we _could_ tessellate here but rather not - campbell
*
* this assert checks we have tessfaces,

View File

@@ -2785,7 +2785,7 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Preview", "When rendering animations, save JPG preview images in same directory");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
/* format spesific */
/* format specific */
#ifdef WITH_OPENEXR
/* OpenEXR */

View File

@@ -180,7 +180,7 @@ static int bpy_bm_elem_index_set(BPy_BMElem *self, PyObject *value, void *UNUSED
}
}
/* type spesific get/sets
/* type specific get/sets
* ---------------------- */

View File

@@ -72,6 +72,39 @@ static CustomDataLayer *bpy_bmlayeritem_get(BPy_BMLayerItem *self)
/* getseters
* ========= */
/* used for many different types */
PyDoc_STRVAR(bpy_bmlayeraccess_collection__float_doc,
"Generic float custom-data layer.\n\ntype: :class:`BMLayerCollection`"
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__int_doc,
"Generic int custom-data layer.\n\ntype: :class:`BMLayerCollection`"
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__string_doc,
"Generic string custom-data layer (exposed as bytes, 255 max length).\n\ntype: :class:`BMLayerCollection`"
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__deform_doc,
"Vertex deform weight :class:`BMDeformVert` (TODO).\n\ntype: :class:`BMLayerCollection`" // TYPE DOESN'T EXIST YET
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__shape_doc,
"Vertex shapekey absolute location (as a 3D Vector).\n\n:type: :class:`BMLayerCollection`"
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__bevel_weight_doc,
"Bevel weight float in [0 - 1].\n\n:type: :class:`BMLayerCollection`"
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__crease_doc,
"Edge crease for subsurf - float in [0 - 1].\n\n:type: :class:`BMLayerCollection`"
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__tex_doc,
"Accessor for :class:`BMTexPoly` layer (TODO).\n\ntype: :class:`BMLayerCollection`" // TYPE DOESN'T EXIST YET
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__uv_doc,
"Accessor for :class:`BMLoopUV` UV (as a 2D Vector).\n\ntype: :class:`BMLayerCollection`"
);
PyDoc_STRVAR(bpy_bmlayeraccess_collection__color_doc,
"Accessor for vertex color layer.\n\ntype: :class:`BMLayerCollection`"
);
static PyObject *bpy_bmlayeraccess_collection_get(BPy_BMLayerAccess *self, void *flag)
{
const int type = (int)GET_INT_FROM_POINTER(flag);
@@ -81,6 +114,10 @@ static PyObject *bpy_bmlayeraccess_collection_get(BPy_BMLayerAccess *self, void
return BPy_BMLayerCollection_CreatePyObject(self->bm, self->htype, type);
}
PyDoc_STRVAR(bpy_bmlayercollection_active_doc,
"This meshes vert sequence (read-only).\n\n:type: :class:`BMVertSeq`"
);
static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *UNUSED(flag))
{
CustomData *data;
@@ -99,6 +136,9 @@ static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *U
}
}
PyDoc_STRVAR(bpy_bmlayercollection_name_doc,
"The layers unique name (read-only).\n\n:type: string"
);
static PyObject *bpy_bmlayeritem_name_get(BPy_BMLayerItem *self, void *UNUSED(flag))
{
CustomDataLayer *layer;
@@ -110,46 +150,46 @@ static PyObject *bpy_bmlayeritem_name_get(BPy_BMLayerItem *self, void *UNUSED(fl
}
static PyGetSetDef bpy_bmlayeraccess_vert_getseters[] = {
{(char *)"deform", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_MDEFORMVERT},
{(char *)"deform", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__deform_doc, (void *)CD_MDEFORMVERT},
{(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_FLT},
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_STR},
{(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__float_doc, (void *)CD_PROP_FLT},
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__int_doc, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__string_doc, (void *)CD_PROP_STR},
{(char *)"shape", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_SHAPEKEY},
{(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_BWEIGHT},
{(char *)"shape", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__shape_doc, (void *)CD_SHAPEKEY},
{(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__bevel_weight_doc, (void *)CD_BWEIGHT},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef bpy_bmlayeraccess_edge_getseters[] = {
{(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_FLT},
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_STR},
{(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__float_doc, (void *)CD_PROP_FLT},
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__int_doc, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__string_doc, (void *)CD_PROP_STR},
{(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_BWEIGHT},
{(char *)"crease", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_CREASE},
{(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__bevel_weight_doc, (void *)CD_BWEIGHT},
{(char *)"crease", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__crease_doc, (void *)CD_CREASE},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef bpy_bmlayeraccess_face_getseters[] = {
{(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_FLT},
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_STR},
{(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__float_doc, (void *)CD_PROP_FLT},
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__int_doc, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__string_doc, (void *)CD_PROP_STR},
{(char *)"tex", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_MTEXPOLY},
{(char *)"tex", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__tex_doc, (void *)CD_MTEXPOLY},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef bpy_bmlayeraccess_loop_getseters[] = {
{(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_FLT},
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_STR},
{(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__float_doc, (void *)CD_PROP_FLT},
{(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__int_doc, (void *)CD_PROP_INT},
{(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__string_doc, (void *)CD_PROP_STR},
{(char *)"uv", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_MLOOPUV},
{(char *)"color", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_MLOOPCOL},
{(char *)"uv", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__uv_doc, (void *)CD_MLOOPUV},
{(char *)"color", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__color_doc, (void *)CD_MLOOPCOL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -157,14 +197,14 @@ static PyGetSetDef bpy_bmlayeraccess_loop_getseters[] = {
static PyGetSetDef bpy_bmlayercollection_getseters[] = {
/* BMESH_TODO, make writeable */
{(char *)"active", (getter)bpy_bmlayercollection_active_get, (setter)NULL, (char *)NULL, NULL},
{(char *)"active", (getter)bpy_bmlayercollection_active_get, (setter)NULL, (char *)bpy_bmlayercollection_active_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef bpy_bmlayeritem_getseters[] = {
/* BMESH_TODO, make writeable */
{(char *)"name", (getter)bpy_bmlayeritem_name_get, (setter)NULL, (char *)NULL, NULL},
{(char *)"name", (getter)bpy_bmlayeritem_name_get, (setter)NULL, (char *)bpy_bmlayercollection_name_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -527,6 +567,21 @@ static PyObject *bpy_bmlayercollection_iter(BPy_BMLayerCollection *self)
return iter;
}
PyDoc_STRVAR(bpy_bmlayeraccess_type_doc,
"Exposes custom-data layer attributes."
);
PyDoc_STRVAR(bpy_bmlayercollection_type_doc,
"Gives access to a collection of custom-data layers of the same type and behaves like python dictionaries, "
"except for the ability to do list like index access."
);
PyDoc_STRVAR(bpy_bmlayeritem_type_doc,
"Exposes a single custom data layer, "
"their main purpose is for use as item accessors to custom-data when used with vert/edge/face/loop data."
);
PyTypeObject BPy_BMLayerAccessVert_Type = {{{0}}}; /* bm.verts.layers */
PyTypeObject BPy_BMLayerAccessEdge_Type = {{{0}}}; /* bm.edges.layers */
PyTypeObject BPy_BMLayerAccessFace_Type = {{{0}}}; /* bm.faces.layers */
@@ -596,12 +651,12 @@ void BPy_BM_init_types_customdata(void)
BPy_BMLayerItem_Type.tp_name = "BMLayerItem";
/* todo */
BPy_BMLayerAccessVert_Type.tp_doc = NULL;
BPy_BMLayerAccessEdge_Type.tp_doc = NULL;
BPy_BMLayerAccessFace_Type.tp_doc = NULL;
BPy_BMLayerAccessLoop_Type.tp_doc = NULL;
BPy_BMLayerCollection_Type.tp_doc = NULL;
BPy_BMLayerItem_Type.tp_doc = NULL;
BPy_BMLayerAccessVert_Type.tp_doc = bpy_bmlayeraccess_type_doc;
BPy_BMLayerAccessEdge_Type.tp_doc = bpy_bmlayeraccess_type_doc;
BPy_BMLayerAccessFace_Type.tp_doc = bpy_bmlayeraccess_type_doc;
BPy_BMLayerAccessLoop_Type.tp_doc = bpy_bmlayeraccess_type_doc;
BPy_BMLayerCollection_Type.tp_doc = bpy_bmlayercollection_type_doc;
BPy_BMLayerItem_Type.tp_doc = bpy_bmlayeritem_type_doc;
BPy_BMLayerAccessVert_Type.tp_repr = (reprfunc)NULL;
BPy_BMLayerAccessEdge_Type.tp_repr = (reprfunc)NULL;

View File

@@ -58,7 +58,7 @@ typedef struct BPy_BMLayerCollection {
int type; /* customdata type - CD_XXX */
} BPy_BMLayerCollection;
/* access a spesific layer directly */
/* access a specific layer directly */
typedef struct BPy_BMLayerItem {
PyObject_VAR_HEAD
struct BMesh *bm; /* keep first */

View File

@@ -49,6 +49,9 @@ typedef struct BPy_BMLoopUV {
MLoopUV *data;
} BPy_BMLoopUV;
PyDoc_STRVAR(bpy_bmloopuv_uv_doc,
"Loops UV (as a 2D Vector).\n\n:type: :class:`mathutils.Vector`"
);
static PyObject *bpy_bmloopuv_uv_get(BPy_BMLoopUV *self, void *UNUSED(closure))
{
return Vector_CreatePyObject(self->data->uv, 2, Py_WRAP, NULL);
@@ -66,6 +69,17 @@ static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED
}
}
PyDoc_STRVAR(bpy_bmloopuv_flag__pin_uv_doc,
"UV pin state.\n\n:type: boolean"
);
PyDoc_STRVAR(bpy_bmloopuv_flag__select_doc,
"UV select state.\n\n:type: boolean"
);
PyDoc_STRVAR(bpy_bmloopuv_flag__select_edge_doc,
"UV edge select state.\n\n:type: boolean"
);
static PyObject *bpy_bmloopuv_flag_get(BPy_BMLoopUV *self, void *flag_p)
{
const int flag = GET_INT_FROM_POINTER(flag_p);
@@ -92,10 +106,10 @@ static int bpy_bmloopuv_flag_set(BPy_BMLoopUV *self, PyObject *value, void *flag
static PyGetSetDef bpy_bmloopuv_getseters[] = {
/* attributes match rna_def_mloopuv */
{(char *)"uv", (getter)bpy_bmloopuv_uv_get, (setter)bpy_bmloopuv_uv_set, (char *)NULL, NULL},
{(char *)"pin_uv", (getter)bpy_bmloopuv_flag_get, (setter)bpy_bmloopuv_flag_set, (char *)NULL, (void *)MLOOPUV_PINNED},
{(char *)"select", (getter)bpy_bmloopuv_flag_get, (setter)bpy_bmloopuv_flag_set, (char *)NULL, (void *)MLOOPUV_VERTSEL},
{(char *)"select_edge", (getter)bpy_bmloopuv_flag_get, (setter)bpy_bmloopuv_flag_set, (char *)NULL, (void *)MLOOPUV_EDGESEL},
{(char *)"uv", (getter)bpy_bmloopuv_uv_get, (setter)bpy_bmloopuv_uv_set, (char *)bpy_bmloopuv_uv_doc, NULL},
{(char *)"pin_uv", (getter)bpy_bmloopuv_flag_get, (setter)bpy_bmloopuv_flag_set, (char *)bpy_bmloopuv_flag__pin_uv_doc, (void *)MLOOPUV_PINNED},
{(char *)"select", (getter)bpy_bmloopuv_flag_get, (setter)bpy_bmloopuv_flag_set, (char *)bpy_bmloopuv_flag__select_doc, (void *)MLOOPUV_VERTSEL},
{(char *)"select_edge", (getter)bpy_bmloopuv_flag_get, (setter)bpy_bmloopuv_flag_set, (char *)bpy_bmloopuv_flag__select_edge_doc, (void *)MLOOPUV_EDGESEL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};

View File

@@ -230,7 +230,7 @@ set(BLENDER_TEXT_FILES
# -----------------------------------------------------------------------------
# Platform Spesific Var: TARGETDIR_VER
# Platform Specific Var: TARGETDIR_VER
if(UNIX AND NOT APPLE)
if(WITH_INSTALL_PORTABLE)