PyAPI Docs: Add default values for bmesh API

This diff improves the docs for bmesh by adding the default values to all methods. This is motivated by this issue https://github.com/nutti/fake-bpy-module/issues/118 in fake-bpy-module which generates a typed API for authoring Blender scripts and addons from the docs.

After this diff gets merged, the Blender docs get updated, and `fake-bpy-module` gets regenerated, the type signatures in `fake-bpy-module` will match the reality of Blender's API.

Here's a diff for the docs using the modified script:
https://gist.github.com/xixixao/1c83153adbcefbe0859f9cc9ba757d46

I "hardcoded" the defaults based on the types of the arguments, after some testing and consulting the Blender .c source for these APIs.

Here's a test script that verifies that the arguments with defaults added in this diff are indeed not required by Blender 3.3: https://gist.github.com/xixixao/adc4e5a076e80a63735bd60c7c9e7a0d

I made the minimum changes required to get this doc generation script fixed, but let me know if I should restructure this script more.

I also amended the comments of three args, 2 to align them with Python (NULL -> None) and one to mark it as optional (CurveProfile).

Reviewed By: Blendify

Differential Revision: https://developer.blender.org/D16400
This commit is contained in:
Michal Srb 2022-12-07 14:57:15 -06:00 committed by Aaron Carlisle
parent 3494ba3815
commit be5afe9987
2 changed files with 52 additions and 32 deletions

View File

@ -234,28 +234,7 @@ def main():
args_in_index[:] = [i for (i, a) in enumerate(args_in) if type(a) == tuple]
if args_out is not None:
args_out_index[:] = [i for (i, a) in enumerate(args_out) if type(a) == tuple]
fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index])))
# -- wash the comment
comment_washed = []
comment = [] if comment is None else comment
for i, l in enumerate(comment):
assert ((l.strip() == "") or
(l in {"/*", " *"}) or
(l.startswith(("/* ", " * "))))
l = l[3:]
if i == 0 and not l.strip():
continue
if l.strip():
l = " " + l
comment_washed.append(l)
fw("\n".join(comment_washed))
fw("\n")
# -- done
# get the args
def get_args_wash(args, args_index, is_ret):
args_wash = []
@ -296,26 +275,36 @@ def main():
if comment_next:
comment += ("\n" if comment_prev else "") + comment_next.strip()
default_value = None
if tp == BMO_OP_SLOT_FLT:
tp_str = "float"
default_value = '0'
elif tp == BMO_OP_SLOT_INT:
if tp_sub == BMO_OP_SLOT_SUBTYPE_INT_ENUM:
tp_str = "enum in " + enums + ", default " + enums.split(",", 1)[0].strip("[")
default_value = enums.split(",", 1)[0].strip("[")
tp_str = "enum in " + enums + ", default " + default_value
elif tp_sub == BMO_OP_SLOT_SUBTYPE_INT_FLAG:
tp_str = "set of flags from " + enums + ", default {}"
default_value = 'set()'
tp_str = "set of flags from " + enums + ", default " + default_value
else:
tp_str = "int"
default_value = '0'
elif tp == BMO_OP_SLOT_BOOL:
tp_str = "bool"
default_value = 'False'
elif tp == BMO_OP_SLOT_MAT:
tp_str = ":class:`mathutils.Matrix`"
default_value = 'mathutils.Matrix.Identity(4)'
elif tp == BMO_OP_SLOT_VEC:
tp_str = ":class:`mathutils.Vector`"
default_value = 'mathutils.Vector()'
if not is_ret:
tp_str += " or any sequence of 3 floats"
elif tp == BMO_OP_SLOT_PTR:
tp_str = "dict"
assert tp_sub is not None
if 'if None' in comment:
default_value = 'None'
if tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_BMESH:
tp_str = ":class:`bmesh.types.BMesh`"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_SCENE:
@ -348,13 +337,16 @@ def main():
tp_str = "/".join(ls)
else:
tp_str = ("list of (%s)" % ", ".join(ls))
default_value = '[]'
del ls
elif tp == BMO_OP_SLOT_MAPPING:
if tp_sub & BMO_OP_SLOT_SUBTYPE_MAP_EMPTY:
tp_str = "set of vert/edge/face type"
default_value = 'set()'
else:
tp_str = "dict mapping vert/edge/face types to "
default_value = '{}'
if tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_BOOL:
tp_str += "bool"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INT:
@ -372,18 +364,41 @@ def main():
print("Can't find", vars_dict_reverse[tp])
assert 0
args_wash.append((name, tp_str, comment))
args_wash.append((name, default_value, tp_str, comment))
return args_wash
# end get_args_wash
args_in_wash = get_args_wash(args_in, args_in_index, False)
fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([print_arg_in(arg) for arg in args_in_wash])))
# -- wash the comment
comment_washed = []
comment = [] if comment is None else comment
for i, l in enumerate(comment):
assert ((l.strip() == "") or
(l in {"/*", " *"}) or
(l.startswith(("/* ", " * "))))
l = l[3:]
if i == 0 and not l.strip():
continue
if l.strip():
l = " " + l
comment_washed.append(l)
fw("\n".join(comment_washed))
fw("\n")
# -- done
# all ops get this arg
fw(" :arg bm: The bmesh to operate on.\n")
fw(" :type bm: :class:`bmesh.types.BMesh`\n")
args_in_wash = get_args_wash(args_in, args_in_index, False)
args_out_wash = get_args_wash(args_out, args_out_index, True)
for (name, tp, comment) in args_in_wash:
for (name, _, tp, comment) in args_in_wash:
if comment == "":
comment = "Undocumented."
@ -393,7 +408,7 @@ def main():
if args_out_wash:
fw(" :return:\n\n")
for (name, tp, comment) in args_out_wash:
for (name, _, tp, comment) in args_out_wash:
assert name.endswith(".out")
name = name[:-4]
fw(" - ``%s``: %s\n\n" % (name, comment))
@ -408,6 +423,11 @@ def main():
del fout
print(OUT_RST)
def print_arg_in(arg):
(name, default_value, _, _) = arg
if default_value is None:
return name
return name + '=' + default_value
if __name__ == "__main__":
main()

View File

@ -1373,7 +1373,7 @@ static BMOpDefine bmo_duplicate_def = {
"duplicate",
/* slots_in */
{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
{"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}}, /* destination bmesh, if NULL will use current on */
{"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}}, /* destination bmesh, if None will use current on */
{"use_select_history", BMO_OP_SLOT_BOOL},
{"use_edge_flip_from_face", BMO_OP_SLOT_BOOL},
{{'\0'}},
@ -1405,7 +1405,7 @@ static BMOpDefine bmo_split_def = {
"split",
/* slots_in */
{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
{"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}}, /* destination bmesh, if NULL will use current one */
{"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}}, /* destination bmesh, if None will use current one */
{"use_only_faces", BMO_OP_SLOT_BOOL}, /* when enabled. don't duplicate loose verts/edges */
{{'\0'}},
},
@ -1780,7 +1780,7 @@ static BMOpDefine bmo_bevel_def = {
bmo_enum_bevel_miter_type}, /* outer miter kind */
{"spread", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
{"smoothresh", BMO_OP_SLOT_FLT}, /* for passing mesh's smoothresh, used in hardening */
{"custom_profile", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_STRUCT}}, /* CurveProfile */
{"custom_profile", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_STRUCT}}, /* CurveProfile, if None ignored */
{"vmesh_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
bmo_enum_bevel_vmesh_method}, /* The method to use to create meshes at intersections. */
{{'\0'}},