void register_node_type_sh_group(void) { static bNodeType ntype; /* NB: cannot use sh_node_type_base for node group, because it would map the node type * to the shared NODE_GROUP integer type id. */ node_type_base_custom(&ntype, "ShaderNodeGroup", "Group", NODE_CLASS_GROUP, NODE_CONST_OUTPUT); ntype.type = NODE_GROUP; ntype.poll = sh_node_poll_default; ntype.poll_instance = node_group_poll_instance; ntype.update_internal_links = node_update_internal_links_default; ntype.ext.srna = RNA_struct_find("ShaderNodeGroup"); BLI_assert(ntype.ext.srna != NULL); RNA_struct_blender_type_set(ntype.ext.srna, &ntype); node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING); node_type_socket_templates(&ntype, NULL, NULL); node_type_size(&ntype, 140, 60, 400); node_type_label(&ntype, node_group_label); node_type_update(&ntype, NULL, node_group_verify); node_type_exec(&ntype, group_initexec, group_freeexec, group_execute); node_type_gpu(&ntype, gpu_group_execute); nodeRegisterType(&ntype); }
static bNodeSocketType *make_socket_type_virtual(void) { extern void ED_init_node_socket_type_virtual(bNodeSocketType *); const char *socket_idname = "NodeSocketVirtual"; bNodeSocketType *stype; StructRNA *srna; stype = MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname)); /* set the RNA type * uses the exact same identifier as the socket type idname */ srna = stype->ext_socket.srna = RNA_struct_find(socket_idname); BLI_assert(srna != NULL); /* associate the RNA type with the socket type */ RNA_struct_blender_type_set(srna, stype); /* extra type info for standard socket types */ stype->type = SOCK_CUSTOM; ED_init_node_socket_type_virtual(stype); return stype; }
static StructRNA *rna_UIList_register( Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { uiListType *ult, dummyult = {NULL}; uiList dummyuilist = {NULL}; PointerRNA dummyul_ptr; int have_function[3]; size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */ /* setup dummy menu & menu type to store static properties in */ dummyuilist.type = &dummyult; RNA_pointer_create(NULL, &RNA_UIList, &dummyuilist, &dummyul_ptr); /* validate the python class */ if (validate(&dummyul_ptr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummyult.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering uilist class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyult.idname)); return NULL; } /* check if we have registered this uilist type before, and remove it */ ult = WM_uilisttype_find(dummyult.idname, true); if (ult && ult->ext.srna) { rna_UIList_unregister(bmain, ult->ext.srna); } if (!RNA_struct_available_or_report(reports, dummyult.idname)) { return NULL; } if (!RNA_struct_bl_idname_ok_or_report(reports, dummyult.idname, "_UL_")) { return NULL; } /* create a new menu type */ ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist"); memcpy(ult, &dummyult, sizeof(dummyult)); ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList); ult->ext.data = data; ult->ext.call = call; ult->ext.free = free; RNA_struct_blender_type_set(ult->ext.srna, ult); ult->draw_item = (have_function[0]) ? uilist_draw_item : NULL; ult->draw_filter = (have_function[1]) ? uilist_draw_filter : NULL; ult->filter_items = (have_function[2]) ? uilist_filter_items : NULL; WM_uilisttype_add(ult); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); return ult->ext.srna; }
static StructRNA *rna_RenderEngine_register( Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { RenderEngineType *et, dummyet = {NULL}; RenderEngine dummyengine = {NULL}; PointerRNA dummyptr; int have_function[7]; /* setup dummy engine & engine type to store static properties in */ dummyengine.type = &dummyet; dummyet.flag |= RE_USE_SHADING_NODES_CUSTOM; RNA_pointer_create(NULL, &RNA_RenderEngine, &dummyengine, &dummyptr); /* validate the python class */ if (validate(&dummyptr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummyet.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering render engine class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyet.idname)); return NULL; } /* check if we have registered this engine type before, and remove it */ for (et = R_engines.first; et; et = et->next) { if (STREQ(et->idname, dummyet.idname)) { if (et->ext.srna) rna_RenderEngine_unregister(bmain, et->ext.srna); break; } } /* create a new engine type */ et = MEM_callocN(sizeof(RenderEngineType), "python render engine"); memcpy(et, &dummyet, sizeof(dummyet)); et->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, et->idname, &RNA_RenderEngine); et->ext.data = data; et->ext.call = call; et->ext.free = free; RNA_struct_blender_type_set(et->ext.srna, et); et->update = (have_function[0]) ? engine_update : NULL; et->render = (have_function[1]) ? engine_render : NULL; et->bake = (have_function[2]) ? engine_bake : NULL; et->view_update = (have_function[3]) ? engine_view_update : NULL; et->view_draw = (have_function[4]) ? engine_view_draw : NULL; et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL; et->update_render_passes = (have_function[6]) ? engine_update_render_passes : NULL; BLI_addtail(&R_engines, et); return et->ext.srna; }
static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { ARegionType *art; HeaderType *ht, dummyht = {NULL}; Header dummyheader = {NULL}; PointerRNA dummyhtr; int have_function[1]; /* setup dummy header & header type to store static properties in */ dummyheader.type = &dummyht; RNA_pointer_create(NULL, &RNA_Header, &dummyheader, &dummyhtr); /* validate the python class */ if (validate(&dummyhtr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummyht.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering header class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyht.idname)); return NULL; } if (!(art = region_type_find(reports, dummyht.space_type, RGN_TYPE_HEADER))) return NULL; /* check if we have registered this header type before, and remove it */ for (ht = art->headertypes.first; ht; ht = ht->next) { if (strcmp(ht->idname, dummyht.idname) == 0) { if (ht->ext.srna) rna_Header_unregister(bmain, ht->ext.srna); break; } } /* create a new header type */ ht = MEM_callocN(sizeof(HeaderType), "python buttons header"); memcpy(ht, &dummyht, sizeof(dummyht)); ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header); ht->ext.data = data; ht->ext.call = call; ht->ext.free = free; RNA_struct_blender_type_set(ht->ext.srna, ht); ht->draw = (have_function[0]) ? header_draw : NULL; BLI_addtail(&art->headertypes, ht); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); return ht->ext.srna; }
static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { KeyingSetInfo dummyksi = {NULL}; KeyingSetInfo *ksi; PointerRNA dummyptr = {{NULL}}; int have_function[3]; /* setup dummy type info to store static properties in */ /* TODO: perhaps we want to get users to register as if they're using 'KeyingSet' directly instead? */ RNA_pointer_create(NULL, &RNA_KeyingSetInfo, &dummyksi, &dummyptr); /* validate the python class */ if (validate(&dummyptr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummyksi.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering keying set info class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyksi.idname)); return NULL; } /* check if we have registered this info before, and remove it */ ksi = ANIM_keyingset_info_find_name(dummyksi.idname); if (ksi && ksi->ext.srna) rna_KeyingSetInfo_unregister(bmain, ksi->ext.srna); /* create a new KeyingSetInfo type */ ksi = MEM_callocN(sizeof(KeyingSetInfo), "python keying set info"); memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo)); /* set RNA-extensions info */ ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo); ksi->ext.data = data; ksi->ext.call = call; ksi->ext.free = free; RNA_struct_blender_type_set(ksi->ext.srna, ksi); /* set callbacks */ /* NOTE: we really should have all of these... */ ksi->poll = (have_function[0]) ? RKS_POLL_rna_internal : NULL; ksi->iter = (have_function[1]) ? RKS_ITER_rna_internal : NULL; ksi->generate = (have_function[2]) ? RKS_GEN_rna_internal : NULL; /* add and register with other info as needed */ ANIM_keyingset_info_register(ksi); WM_main_add_notifier(NC_WINDOW, NULL); /* return the struct-rna added */ return ksi->ext.srna; }
static bNodeSocketType *make_standard_socket_type(int type, int subtype) { extern void ED_init_standard_node_socket_type(bNodeSocketType *); const char *socket_idname = nodeStaticSocketType(type, subtype); const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype); bNodeSocketType *stype; StructRNA *srna; stype = MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname)); /* set the RNA type * uses the exact same identifier as the socket type idname */ srna = stype->ext_socket.srna = RNA_struct_find(socket_idname); BLI_assert(srna != NULL); /* associate the RNA type with the socket type */ RNA_struct_blender_type_set(srna, stype); /* set the interface RNA type */ srna = stype->ext_interface.srna = RNA_struct_find(interface_idname); BLI_assert(srna != NULL); /* associate the RNA type with the socket type */ RNA_struct_blender_type_set(srna, stype); /* extra type info for standard socket types */ stype->type = type; stype->subtype = subtype; /* XXX bad-level call! needed for setting draw callbacks */ ED_init_standard_node_socket_type(stype); stype->interface_init_socket = standard_node_socket_interface_init_socket; stype->interface_from_socket = standard_node_socket_interface_from_socket; stype->interface_verify_socket = standard_node_socket_interface_verify_socket; return stype; }
static void operator_properties_init(wmOperatorType *ot) { PyObject *py_class = ot->ext.data; RNA_struct_blender_type_set(ot->ext.srna, ot); /* only call this so pyrna_deferred_register_class gives a useful error * WM_operatortype_append_ptr will call RNA_def_struct_identifier * later */ RNA_def_struct_identifier(ot->srna, ot->idname); if (pyrna_deferred_register_class(ot->srna, py_class) != 0) { PyErr_Print(); /* failed to register operator props */ PyErr_Clear(); } }
static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { MenuType *mt, dummymt = {NULL}; Menu dummymenu= {NULL}; PointerRNA dummymtr; int have_function[2]; /* setup dummy menu & menu type to store static properties in */ dummymenu.type= &dummymt; RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr); /* validate the python class */ if(validate(&dummymtr, data, have_function) != 0) return NULL; if(strlen(identifier) >= sizeof(dummymt.idname)) { BKE_reportf(reports, RPT_ERROR, "registering menu class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummymt.idname)); return NULL; } /* check if we have registered this menu type before, and remove it */ mt= WM_menutype_find(dummymt.idname, TRUE); if(mt && mt->ext.srna) rna_Menu_unregister(bmain, mt->ext.srna); /* create a new menu type */ mt= MEM_callocN(sizeof(MenuType), "python buttons menu"); memcpy(mt, &dummymt, sizeof(dummymt)); mt->ext.srna= RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); mt->ext.data= data; mt->ext.call= call; mt->ext.free= free; RNA_struct_blender_type_set(mt->ext.srna, mt); RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES); mt->poll= (have_function[0])? menu_poll: NULL; mt->draw= (have_function[1])? menu_draw: NULL; WM_menutype_add(mt); /* update while blender is running */ WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL); return mt->ext.srna; }
void register_node_type_cmp_group(void) { static bNodeType ntype; /* NB: cannot use sh_node_type_base for node group, because it would map the node type * to the shared NODE_GROUP integer type id. */ node_type_base_custom(&ntype, "CompositorNodeGroup", "Group", NODE_CLASS_GROUP, NODE_OPTIONS | NODE_CONST_OUTPUT); ntype.type = NODE_GROUP; ntype.poll = cmp_node_poll_default; ntype.poll_instance = node_group_poll_instance; ntype.update_internal_links = node_update_internal_links_default; ntype.ext.srna = RNA_struct_find("CompositorNodeGroup"); BLI_assert(ntype.ext.srna != NULL); RNA_struct_blender_type_set(ntype.ext.srna, &ntype); node_type_socket_templates(&ntype, NULL, NULL); node_type_size(&ntype, 120, 60, 200); node_type_label(&ntype, node_group_label); node_type_update(&ntype, NULL, node_group_verify); nodeRegisterType(&ntype); }
static StructRNA *rna_Menu_register( Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { MenuType *mt, dummymt = {NULL}; Menu dummymenu = {NULL}; PointerRNA dummymtr; int have_function[2]; size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */ size_t description_size = 0; char _menu_descr[RNA_DYN_DESCR_MAX]; /* setup dummy menu & menu type to store static properties in */ dummymenu.type = &dummymt; _menu_descr[0] = '\0'; dummymenu.type->description = _menu_descr; RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr); /* We have to set default context! Else we get a void string... */ strcpy(dummymt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); /* validate the python class */ if (validate(&dummymtr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummymt.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering menu class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummymt.idname)); return NULL; } /* check if we have registered this menu type before, and remove it */ mt = WM_menutype_find(dummymt.idname, true); if (mt && mt->ext.srna) { rna_Menu_unregister(bmain, mt->ext.srna); } if (!RNA_struct_available_or_report(reports, dummymt.idname)) { return NULL; } if (!RNA_struct_bl_idname_ok_or_report(reports, dummymt.idname, "_MT_")) { return NULL; } /* create a new menu type */ if (_menu_descr[0]) { description_size = strlen(_menu_descr) + 1; over_alloc += description_size; } mt = MEM_callocN(sizeof(MenuType) + over_alloc, "python buttons menu"); memcpy(mt, &dummymt, sizeof(dummymt)); if (_menu_descr[0]) { char *buf = (char *)(mt + 1); memcpy(buf, _menu_descr, description_size); mt->description = buf; } else mt->description = ""; mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu); RNA_def_struct_translation_context(mt->ext.srna, mt->translation_context); mt->ext.data = data; mt->ext.call = call; mt->ext.free = free; RNA_struct_blender_type_set(mt->ext.srna, mt); RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES); mt->poll = (have_function[0]) ? menu_poll : NULL; mt->draw = (have_function[1]) ? menu_draw : NULL; WM_menutype_add(mt); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); return mt->ext.srna; }
static StructRNA *rna_Panel_register( Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { ARegionType *art; PanelType *pt, dummypt = {NULL}; Panel dummypanel = {NULL}; PointerRNA dummyptr; int have_function[3]; /* setup dummy panel & panel type to store static properties in */ dummypanel.type = &dummypt; RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr); /* We have to set default context! Else we get a void string... */ strcpy(dummypt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); /* validate the python class */ if (validate(&dummyptr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummypt.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering panel class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummypt.idname)); return NULL; } if ((dummypt.category[0] == '\0') && (dummypt.region_type == RGN_TYPE_TOOLS)) { /* Use a fallback, otherwise an empty value will draw the panel in every category. */ strcpy(dummypt.category, PNL_CATEGORY_FALLBACK); } if (!(art = region_type_find(reports, dummypt.space_type, dummypt.region_type))) return NULL; /* check if we have registered this panel type before, and remove it */ for (pt = art->paneltypes.first; pt; pt = pt->next) { if (STREQ(pt->idname, dummypt.idname)) { if (pt->ext.srna) rna_Panel_unregister(bmain, pt->ext.srna); else BLI_freelinkN(&art->paneltypes, pt); break; } } if (!RNA_struct_available_or_report(reports, dummypt.idname)) { return NULL; } if (!RNA_struct_bl_idname_ok_or_report(reports, dummypt.idname, "_PT_")) { return NULL; } /* create a new panel type */ pt = MEM_callocN(sizeof(PanelType), "python buttons panel"); memcpy(pt, &dummypt, sizeof(dummypt)); pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel); RNA_def_struct_translation_context(pt->ext.srna, pt->translation_context); pt->ext.data = data; pt->ext.call = call; pt->ext.free = free; RNA_struct_blender_type_set(pt->ext.srna, pt); RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES); pt->poll = (have_function[0]) ? panel_poll : NULL; pt->draw = (have_function[1]) ? panel_draw : NULL; pt->draw_header = (have_function[2]) ? panel_draw_header : NULL; /* XXX use "no header" flag for some ordering of panels until we have real panel ordering */ if (pt->flag & PNL_NO_HEADER) { PanelType *pth = art->paneltypes.first; while (pth && pth->flag & PNL_NO_HEADER) pth = pth->next; if (pth) BLI_insertlinkbefore(&art->paneltypes, pth, pt); else BLI_addtail(&art->paneltypes, pt); } else BLI_addtail(&art->paneltypes, pt); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); return pt->ext.srna; }
static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { ARegionType *art; PanelType *pt, dummypt = {NULL}; Panel dummypanel= {NULL}; PointerRNA dummyptr; int have_function[3]; /* setup dummy panel & panel type to store static properties in */ dummypanel.type= &dummypt; RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr); /* validate the python class */ if(validate(&dummyptr, data, have_function) != 0) return NULL; if(strlen(identifier) >= sizeof(dummypt.idname)) { BKE_reportf(reports, RPT_ERROR, "registering panel class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummypt.idname)); return NULL; } if(!(art=region_type_find(reports, dummypt.space_type, dummypt.region_type))) return NULL; /* check if we have registered this panel type before, and remove it */ for(pt=art->paneltypes.first; pt; pt=pt->next) { if(strcmp(pt->idname, dummypt.idname) == 0) { if(pt->ext.srna) rna_Panel_unregister(bmain, pt->ext.srna); else BLI_freelinkN(&art->paneltypes, pt); break; } } /* create a new panel type */ pt= MEM_callocN(sizeof(PanelType), "python buttons panel"); memcpy(pt, &dummypt, sizeof(dummypt)); pt->ext.srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); pt->ext.data= data; pt->ext.call= call; pt->ext.free= free; RNA_struct_blender_type_set(pt->ext.srna, pt); RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES); pt->poll= (have_function[0])? panel_poll: NULL; pt->draw= (have_function[1])? panel_draw: NULL; pt->draw_header= (have_function[2])? panel_draw_header: NULL; /* XXX use "no header" flag for some ordering of panels until we have real panel ordering */ if(pt->flag & PNL_NO_HEADER) { PanelType *pth = art->paneltypes.first; while(pth && pth->flag & PNL_NO_HEADER) pth=pth->next; if(pth) BLI_insertlinkbefore(&art->paneltypes, pth, pt); else BLI_addtail(&art->paneltypes, pt); } else BLI_addtail(&art->paneltypes, pt); /* update while blender is running */ WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL); return pt->ext.srna; }