def process(self): inputs = self.inputs n_id = node_id(self) # end early nvBGL.callback_disable(n_id) if self.activate and inputs[0].is_linked: try: with sv_preferences() as prefs: scale = prefs.stethoscope_view_scale location_theta = prefs.stethoscope_view_xy_multiplier except: # print('did not find preferences - you need to save user preferences') scale = 1.0 location_theta = 1.0 # gather vertices from input data = inputs[0].sv_get(deepcopy=False) self.num_elements = len(data) if self.selected_mode == 'text-based': props = lambda: None props.line_width = self.line_width props.compact = self.compact props.depth = self.depth or None processed_data = nvBGL.parse_socket( inputs[0], self.rounding, self.element_index, self.view_by_element, props ) else: # # implement another nvBGL parses for gfx processed_data = data node_width = (self.width_hidden + 30.0) if self.hide else self.width # adjust proposed text location in case node is framed. # take into consideration the hidden state _x, _y = recursive_framed_location_finder(self, self.location[:]) _x, _y = Vector((_x, _y)) + Vector((node_width + 20, 0)) # this alters location based on DPI/Scale settings. location = adjust_location(_x, _y, location_theta) draw_data = { 'tree_name': self.id_data.name[:], 'content': processed_data, 'location': location, 'color': self.text_color[:], 'scale' : float(scale), 'mode': self.selected_mode[:], 'font_id': int(self.font_id) } nvBGL.callback_enable(n_id, draw_data)
def process(self): inputs = self.inputs n_id = node_id(self) # end early nvBGL.callback_disable(n_id) if self.activate and inputs[0].is_linked: try: with sv_preferences() as prefs: scale = prefs.stethoscope_view_scale location_theta = prefs.render_location_xy_multiplier except: # print('did not find preferences - you need to save user preferences') scale = 1.0 location_theta = 1.0 # gather vertices from input data = inputs[0].sv_get(deepcopy=False) self.num_elements = len(data) if self.selected_mode == 'text-based': props = lambda: None props.line_width = self.line_width props.compact = self.compact props.depth = self.depth or None processed_data = nvBGL.parse_socket( inputs[0], self.rounding, self.element_index, self.view_by_element, props ) else: # # implement another nvBGL parses for gfx processed_data = data node_width = (self.width_hidden + 30.0) if self.hide else self.width # adjust proposed text location in case node is framed. # take into consideration the hidden state _x, _y = recursive_framed_location_finder(self, self.location[:]) _x, _y = Vector((_x, _y)) + Vector((node_width + 20, 0)) # this alters location based on DPI/Scale settings. location = adjust_location(_x, _y, location_theta) draw_data = { 'tree_name': self.id_data.name[:], 'content': processed_data, 'location': location, 'color': self.text_color[:], 'scale' : float(scale), 'mode': self.selected_mode[:], 'font_id': int(self.font_id) } nvBGL.callback_enable(n_id, draw_data)
def absolute_location(self): """ When a node is inside a frame (and parented to it) then node.location is relative to its parent's location. This function returns the location in absolute screen terms whether the node is framed or not. The return type is a tuple (x, y) (not a Vector) """ return recursive_framed_location_finder(self, self.location[:])
def get_superficial_props(node_dict, node): node_dict['height'] = node.height node_dict['width'] = node.width node_dict['label'] = node.label node_dict['hide'] = node.hide _x, _y = recursive_framed_location_finder(node, node.location[:]) node_dict['location'] = _x, _y if node.use_custom_color: node_dict['color'] = node.color[:] node_dict['use_custom_color'] = True
def _add_mandatory_attributes(self, node: SverchCustomTreeNode): """It adds attributes which all nodes have""" self._structure['bl_idname'] = node.bl_idname self._structure['height'] = node.height self._structure['width'] = node.width self._structure['label'] = node.label self._structure['hide'] = node.hide self._structure['location'] = recursive_framed_location_finder( node, node.location[:]) if node.use_custom_color: self._structure['color'] = node.color[:] self._structure['use_custom_color'] = True
def export(self, node, factories: StructFactory, dependencies) -> dict: # add_mandatory_attributes self._struct['bl_idname'] = node.bl_idname self._struct["attributes"]['location'] = recursive_framed_location_finder(node, node.location[:]) _set_optional(self._struct["attributes"], 'height', node.height, node.height != 100.0) _set_optional(self._struct["attributes"], 'width', node.width, node.width != 140.0) _set_optional(self._struct["attributes"], "label", node.label) _set_optional(self._struct["attributes"], "hide", node.hide) _set_optional(self._struct["attributes"], "use_custom_color", node.use_custom_color) _set_optional(self._struct["attributes"], "color", node.color[:], node.use_custom_color) if node.parent: # the node is inside of a frame node prop = BPYProperty(node, "parent") raw_struct = factories.prop("parent", self.logger).export(prop, factories, dependencies) self._struct["attributes"]["parent"] = raw_struct else: del self._struct["attributes"]["parent"] # add non default node properties for prop_name in node.keys(): prop = BPYProperty(node, prop_name) if prop.is_valid and prop.is_to_save: raw_struct = factories.prop(prop.name, self.logger).export(prop, factories, dependencies) if raw_struct is not None: self._struct["properties"][prop.name] = raw_struct _set_optional(self._struct, "properties", self._struct["properties"]) # all sockets should be kept in a file because it's possible to create UI # where sockets would be defined by pressing buttons for example like in the node group interface. # there is no sense of exporting information about sockets of group input and output nodes # they are totally controlled by Blender update system. if node.bl_idname not in ['NodeGroupInput', 'NodeGroupOutput']: for socket in node.inputs: raw_struct = factories.sock(socket.identifier, self.logger).export(socket, factories, dependencies) self._struct["inputs"][socket.identifier] = raw_struct for socket in node.outputs: raw_struct = factories.sock(socket.identifier, self.logger).export(socket, factories, dependencies) self._struct["outputs"][socket.identifier] = raw_struct _set_optional(self._struct, "inputs", self._struct["inputs"]) _set_optional(self._struct, "outputs", self._struct["outputs"]) if hasattr(node, 'save_to_json'): node.save_to_json(self._struct["advanced_properties"]) _set_optional(self._struct, "advanced_properties", self._struct["advanced_properties"]) return self._struct
def execute(self, context): tree = context.space_data.edit_tree nodes, links = tree.nodes, tree.links caller_node = nodes.get(self.origin) new_node = nodes.new(self.new_node_idname) new_node.location[0] = caller_node.location[0] + self.new_node_offsetx new_node.location[1] = caller_node.location[1] + self.new_node_offsety links.new(new_node.outputs[0], caller_node.inputs[self.socket_index]) if caller_node.parent: new_node.parent = caller_node.parent loc_xy = new_node.location[:] locx, locy = recursive_framed_location_finder(new_node, loc_xy) new_node.location = locx, locy return {'FINISHED'}
def absolute_location(self): return recursive_framed_location_finder(self, self.location[:])
def absolute_location(self): """ It can be useful in case if a node is in a frame node does not return a vactor, it returns a: tuple(x, y) """ return recursive_framed_location_finder(self, self.location[:])
def absolute_location(self): """ does not return a vactor, it returns a: tuple(x, y) """ return recursive_framed_location_finder(self, self.location[:])
def register(): bpy.utils.register_class(SverchCustomTree) bpy.types.NodeReroute.absolute_location = property( lambda self: recursive_framed_location_finder(self, self.location[:]))