Changeset View
Changeset View
Standalone View
Standalone View
doc/python_api/rst_from_bmesh_opdefines.py
| Show All 25 Lines | |||||
| # that each arg has its own line, that comments above or directly after will be __doc__ etc... | # that each arg has its own line, that comments above or directly after will be __doc__ etc... | ||||
| # | # | ||||
| # We may want to replace this script with something else one day but for now its good enough. | # We may want to replace this script with something else one day but for now its good enough. | ||||
| # if it needs large updates it may be better to rewrite using a real parser or | # if it needs large updates it may be better to rewrite using a real parser or | ||||
| # add introspection into bmesh.ops. | # add introspection into bmesh.ops. | ||||
| # - campbell | # - campbell | ||||
| import os | import os | ||||
| import re | |||||
| CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) | CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) | ||||
| SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(CURRENT_DIR, "..", "..")))) | SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(CURRENT_DIR, "..", "..")))) | ||||
| FILE_OP_DEFINES_C = os.path.join(SOURCE_DIR, "source", "blender", "bmesh", "intern", "bmesh_opdefines.c") | FILE_OP_DEFINES_C = os.path.join(SOURCE_DIR, "source", "blender", "bmesh", "intern", "bmesh_opdefines.c") | ||||
| OUT_RST = os.path.join(CURRENT_DIR, "rst", "bmesh.ops.rst") | OUT_RST = os.path.join(CURRENT_DIR, "rst", "bmesh.ops.rst") | ||||
| HEADER = r""" | HEADER = r""" | ||||
| BMesh Operators (bmesh.ops) | BMesh Operators (bmesh.ops) | ||||
| Show All 28 Lines | def main(): | ||||
| is_comment = False # /* global comments only */ | is_comment = False # /* global comments only */ | ||||
| comment_ctx = None | comment_ctx = None | ||||
| block_ctx = None | block_ctx = None | ||||
| for l in fsrc: | for l in fsrc: | ||||
| l = l[:-1] | l = l[:-1] | ||||
| # weak but ok | # weak but ok | ||||
| if ("BMOpDefine" in l and l.split()[1] == "BMOpDefine") and "bmo_opdefines[]" not in l: | if ((("BMOpDefine" in l and l.split()[1] == "BMOpDefine") and "bmo_opdefines[]" not in l) or | ||||
| ("static BMO_FlagSet " in l)): | |||||
| is_block = True | is_block = True | ||||
| block_ctx = [] | block_ctx = [] | ||||
| blocks.append((comment_ctx, block_ctx)) | blocks.append((comment_ctx, block_ctx)) | ||||
| elif l.strip().startswith("/*"): | elif l.strip().startswith("/*"): | ||||
| is_comment = True | is_comment = True | ||||
| comment_ctx = [] | comment_ctx = [] | ||||
| if is_block: | if is_block: | ||||
| if l.strip().startswith("//"): | if l.strip().startswith("//"): | ||||
| pass | pass | ||||
| else: | else: | ||||
| # remove c++ comment if we have one | # remove c++ comment if we have one | ||||
| cpp_comment = l.find("//") | cpp_comment = l.find("//") | ||||
| if cpp_comment != -1: | if cpp_comment != -1: | ||||
| l = l[:cpp_comment] | l = l[:cpp_comment] | ||||
| # remove sentinel from enums | |||||
| l = l.replace("{0, NULL}", "") | |||||
| block_ctx.append(l) | block_ctx.append(l) | ||||
| if l.strip() == "};": | if l.strip().endswith("};"): | ||||
| is_block = False | is_block = False | ||||
| comment_ctx = None | comment_ctx = None | ||||
| if is_comment: | if is_comment: | ||||
| c_comment_start = l.find("/*") | c_comment_start = l.find("/*") | ||||
| if c_comment_start != -1: | if c_comment_start != -1: | ||||
| l = l[c_comment_start + 2:] | l = l[c_comment_start + 2:] | ||||
| Show All 25 Lines | vars = ( | ||||
| "BMO_OP_SLOT_SUBTYPE_MAP_EMPTY", | "BMO_OP_SLOT_SUBTYPE_MAP_EMPTY", | ||||
| "BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL", | "BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL", | ||||
| "BMO_OP_SLOT_SUBTYPE_PTR_SCENE", | "BMO_OP_SLOT_SUBTYPE_PTR_SCENE", | ||||
| "BMO_OP_SLOT_SUBTYPE_PTR_OBJECT", | "BMO_OP_SLOT_SUBTYPE_PTR_OBJECT", | ||||
| "BMO_OP_SLOT_SUBTYPE_PTR_MESH", | "BMO_OP_SLOT_SUBTYPE_PTR_MESH", | ||||
| "BMO_OP_SLOT_SUBTYPE_PTR_BMESH", | "BMO_OP_SLOT_SUBTYPE_PTR_BMESH", | ||||
| "BMO_OP_SLOT_SUBTYPE_INT_ENUM", | |||||
| "BMO_OP_SLOT_SUBTYPE_INT_FLAG", | |||||
| "BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE", | "BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE", | ||||
| "BM_VERT", | "BM_VERT", | ||||
| "BM_EDGE", | "BM_EDGE", | ||||
| "BM_FACE", | "BM_FACE", | ||||
| "BMO_OPTYPE_FLAG_NORMALS_CALC", | "BMO_OPTYPE_FLAG_NORMALS_CALC", | ||||
| "BMO_OPTYPE_FLAG_UNTAN_MULTIRES", | "BMO_OPTYPE_FLAG_UNTAN_MULTIRES", | ||||
| "BMO_OPTYPE_FLAG_SELECT_FLUSH", | "BMO_OPTYPE_FLAG_SELECT_FLUSH", | ||||
| "BMO_OPTYPE_FLAG_SELECT_VALIDATE", | "BMO_OPTYPE_FLAG_SELECT_VALIDATE", | ||||
| "BMO_OPTYPE_FLAG_NOP", | "BMO_OPTYPE_FLAG_NOP", | ||||
| ) | ) | ||||
| vars_dict = {} | vars_dict = {} | ||||
| for i, v in enumerate(vars): | for i, v in enumerate(vars): | ||||
| vars_dict[v] = (1 << i) | vars_dict[v] = (1 << i) | ||||
| globals().update(vars_dict) | globals().update(vars_dict) | ||||
| # reverse lookup | # reverse lookup | ||||
| vars_dict_reverse = {v: k for k, v in vars_dict.items()} | vars_dict_reverse = {v: k for k, v in vars_dict.items()} | ||||
| # end namespace hack | # end namespace hack | ||||
| blocks_py = [] | blocks_py = [] | ||||
| for comment, b in blocks: | for comment, b in blocks: | ||||
| # magic, translate into python | # magic, translate into python | ||||
| b[0] = b[0].replace("static BMOpDefine ", "") | b[0] = b[0].replace("static BMOpDefine ", "") | ||||
| is_enum = False | |||||
| for i, l in enumerate(b): | for i, l in enumerate(b): | ||||
| l = l.strip() | l = l.strip() | ||||
| # casts | # casts | ||||
| l = l.replace("(int)", "") | l = l.replace("(int)", "") | ||||
| l = l.replace("{", "(") | l = l.replace("{", "(") | ||||
| l = l.replace("}", ")") | l = l.replace("}", ")") | ||||
| if l.startswith("/*"): | if l.startswith("/*"): | ||||
| l = l.replace("/*", "'''own <") | l = l.replace("/*", "'''own <") | ||||
| else: | else: | ||||
| l = l.replace("/*", "'''inline <") | l = l.replace("/*", "'''inline <") | ||||
| l = l.replace("*/", ">''',") | l = l.replace("*/", ">''',") | ||||
| # exec func. eg: bmo_rotate_edges_exec, | # exec func. eg: bmo_rotate_edges_exec, | ||||
| if l.startswith("bmo_") and l.endswith("_exec,"): | if l.startswith("bmo_") and l.endswith("_exec,"): | ||||
| l = "None," | l = "None," | ||||
| # enums | |||||
| if l.startswith("static BMO_FlagSet "): | |||||
| is_enum = True | |||||
| b[i] = l | b[i] = l | ||||
| # for l in b: | # for l in b: | ||||
| # print(l) | # print(l) | ||||
| if is_enum: | |||||
| text = "".join(b) | |||||
| text = text.replace("static BMO_FlagSet ", "") | |||||
| text = text.replace("[]", "") | |||||
| text = text.strip(";") | |||||
| text = text.replace("(", "[").replace(")", "]") | |||||
| text = text.replace("\"", "'") | |||||
| k, v = text.split("=", 1) | |||||
| v = repr(re.findall(r"'([^']*)'", v)) | |||||
| k = k.strip() | |||||
| v = v.strip() | |||||
| vars_dict[k] = v | |||||
| continue | |||||
| text = "\n".join(b) | text = "\n".join(b) | ||||
| global_namespace = { | global_namespace = { | ||||
| "__file__": "generated", | "__file__": "generated", | ||||
| "__name__": "__main__", | "__name__": "__main__", | ||||
| } | } | ||||
| global_namespace.update(vars_dict) | global_namespace.update(vars_dict) | ||||
| Show All 26 Lines | for comment, b in blocks_py: | ||||
| args_in_index[:] = [i for (i, a) in enumerate(args_in) if type(a) == tuple] | args_in_index[:] = [i for (i, a) in enumerate(args_in) if type(a) == tuple] | ||||
| if args_out is not None: | if args_out is not None: | ||||
| args_out_index[:] = [i for (i, a) in enumerate(args_out) if type(a) == tuple] | 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]))) | fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index]))) | ||||
| # -- wash the comment | # -- wash the comment | ||||
| comment_washed = [] | comment_washed = [] | ||||
| comment = [] if comment is None else comment | |||||
| for i, l in enumerate(comment): | for i, l in enumerate(comment): | ||||
| assert((l.strip() == "") or | assert((l.strip() == "") or | ||||
| (l in {"/*", " *"}) or | (l in {"/*", " *"}) or | ||||
| (l.startswith(("/* ", " * ")))) | (l.startswith(("/* ", " * ")))) | ||||
| l = l[3:] | l = l[3:] | ||||
| if i == 0 and not l.strip(): | if i == 0 and not l.strip(): | ||||
| continue | continue | ||||
| if l.strip(): | if l.strip(): | ||||
| l = " " + l | l = " " + l | ||||
| comment_washed.append(l) | comment_washed.append(l) | ||||
| fw("\n".join(comment_washed)) | fw("\n".join(comment_washed)) | ||||
| fw("\n") | fw("\n") | ||||
| # -- done | # -- done | ||||
| # get the args | # get the args | ||||
| def get_args_wash(args, args_index, is_ret): | def get_args_wash(args, args_index, is_ret): | ||||
| args_wash = [] | args_wash = [] | ||||
| for i in args_index: | for i in args_index: | ||||
| arg = args[i] | arg = args[i] | ||||
| if len(arg) == 3: | if len(arg) == 4: | ||||
| name, tp, tp_sub, enums = arg | |||||
| elif len(arg) == 3: | |||||
| name, tp, tp_sub = arg | name, tp, tp_sub = arg | ||||
| elif len(arg) == 2: | elif len(arg) == 2: | ||||
| name, tp = arg | name, tp = arg | ||||
| tp_sub = None | tp_sub = None | ||||
| else: | else: | ||||
| print(arg) | print(arg) | ||||
| assert(0) | assert(0) | ||||
| Show All 19 Lines | for comment, b in blocks_py: | ||||
| if comment_prev: | if comment_prev: | ||||
| comment += comment_prev.strip() | comment += comment_prev.strip() | ||||
| if comment_next: | if comment_next: | ||||
| comment += ("\n" if comment_prev else "") + comment_next.strip() | comment += ("\n" if comment_prev else "") + comment_next.strip() | ||||
| if tp == BMO_OP_SLOT_FLT: | if tp == BMO_OP_SLOT_FLT: | ||||
| tp_str = "float" | tp_str = "float" | ||||
| elif tp == BMO_OP_SLOT_INT: | 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("[") | |||||
| elif tp_sub == BMO_OP_SLOT_SUBTYPE_INT_FLAG: | |||||
| tp_str = "set of flags from " + enums + ", default {}" | |||||
| else: | |||||
| tp_str = "int" | tp_str = "int" | ||||
| elif tp == BMO_OP_SLOT_BOOL: | elif tp == BMO_OP_SLOT_BOOL: | ||||
| tp_str = "bool" | tp_str = "bool" | ||||
| elif tp == BMO_OP_SLOT_MAT: | elif tp == BMO_OP_SLOT_MAT: | ||||
| tp_str = ":class:`mathutils.Matrix`" | tp_str = ":class:`mathutils.Matrix`" | ||||
| elif tp == BMO_OP_SLOT_VEC: | elif tp == BMO_OP_SLOT_VEC: | ||||
| tp_str = ":class:`mathutils.Vector`" | tp_str = ":class:`mathutils.Vector`" | ||||
| if not is_ret: | if not is_ret: | ||||
| tp_str += " or any sequence of 3 floats" | tp_str += " or any sequence of 3 floats" | ||||
| ▲ Show 20 Lines • Show All 94 Lines • Show Last 20 Lines | |||||