def process(self): n_id = node_id(self) nvBGL.callback_disable(n_id) if self.activate: if not self.inputs[0].other: return # parameter containers config = lambda: None geom = lambda: None palette = lambda: None palette.high_colour = (0.33, 0.33, 0.33, 1.0) palette.low_colour = (0.1, 0.1, 0.1, 1.0) scale = self.get_drawing_attributes() # some aliases w = self.graph_width h = self.graph_height dims = (w, h) loc = (0, 0) config.scale = scale grid_data = gridshader(dims, loc, palette, self.num_channels) # this is for drawing only. wave_data = self.get_wavedata(raw=False) wave_params = self.get_waveparams() wave_data_processed = self.generate_2d_drawing_data( wave_data, wave_params, dims, loc) scope_tick_data = self.generate_tick_data(wave_data, dims, loc) # GRAPH PART - Background config.background_shader = get_2d_smooth_color_shader() config.background_batch = batch_for_shader( config.background_shader, 'TRIS', { "pos": grid_data.background_coords, "color": grid_data.background_colors }, indices=grid_data.background_indices) if scope_tick_data.verts: params, kw_params = (('LINES', { "pos": scope_tick_data.verts }), { "indices": scope_tick_data.indices }) config.tick_shader = get_2d_uniform_color_shader() config.tick_batch = batch_for_shader(config.tick_shader, *params, **kw_params) # LINE PART coords = wave_data_processed.verts indices = wave_data_processed.indices config.line_shader = get_2d_uniform_color_shader() params, kw_params = (('LINES', { "pos": coords }), { "indices": indices }) if indices else (('LINE_STRIP', { "pos": coords }), {}) config.line_batch = batch_for_shader(config.line_shader, *params, **kw_params) # -------------- final draw data accumulation and pass to callback ------------------ draw_data = { 'mode': 'custom_function_context', 'tree_name': self.id_data.name[:], 'node_name': self.name[:], 'loc': get_offset_xy, 'custom_function': advanced_grid_xy, 'args': (geom, config) } nvBGL.callback_enable(self.n_id, draw_data)
def sv_free(self): nvBGL.callback_disable(node_id(self))
def free(self): nvBGL2.callback_disable(node_id(self))
def free(self): nvBGL2.callback_disable(node_id(self)) self.delete_texture()
def disable_time_graph(ng): nvBGL2.callback_disable(f"{ng.tree_id}_time_graph_overlay")
def disable_node_times(ng): nvBGL2.callback_disable(f"{ng.tree_id}_node_time_info")
def process(self): n_id = node_id(self) nvBGL.callback_disable(n_id) inputs = self.inputs # end early if not self.activate: return if self.mode == 'Number': if not inputs['Number'].is_linked: return numbers = inputs['Number'].sv_get(default=[[]]) elif self.mode == 'Curve': if not inputs['Curve'].is_linked: return curves = inputs['Curve'].sv_get(default=[[]]) else: if not inputs['Vecs'].is_linked: return vecs = inputs['Vecs'].sv_get(default=[[]]) edges = inputs['Edges'].sv_get(default=[[]]) polygons = inputs['Polygons'].sv_get(default=[[]]) vector_color = inputs['Vector Color'].sv_get(default=[[self.vector_color]]) edge_color = inputs['Edge Color'].sv_get(default=[[self.edge_color]]) poly_color = inputs['Polygon Color'].sv_get(default=[[self.polygon_color]]) seed_set(self.random_seed) config = self.create_config() config.vector_color = vector_color config.edge_color = edge_color config.poly_color = poly_color config.edges = edges if self.mode == 'Number': config.size = self.drawing_size geom = generate_number_geom(config, numbers) elif self.mode == 'Path': geom = generate_graph_geom(config, vecs) elif self.mode == 'Curve': paths = [] for curve in curves: t_min, t_max = curve.get_u_bounds() ts = np_linspace(t_min, t_max, num=self.curve_samples, dtype=np_float64) paths.append(curve.evaluate_array(ts).tolist()) geom = generate_graph_geom(config, paths) else: config.polygons = polygons if not inputs['Edges'].is_linked and self.edge_toggle: config.edges = polygons_to_edges(polygons, unique_edges=True) geom = generate_mesh_geom(config, vecs) draw_data = { 'mode': 'custom_function', 'tree_name': self.id_data.name[:], 'node_name': self.name[:], 'loc': get_drawing_location, 'custom_function': view_2d_geom, 'args': (geom, config) } nvBGL.callback_enable(n_id, draw_data)
def clear_exception_drawing_with_bgl(nodes): """ remove the previously drawn exception if needed """ ng = nodes.id_data ng_id = exception_nodetree_id(ng) nvBGL2.callback_disable(ng_id)
def process(self): inputs = self.inputs outputs = self.outputs # no inputs are connected ? => return if not any(s.is_linked for s in inputs): nvBGL.callback_disable(node_id(self)) # clear drawing return # no outputs are connected or statistics are not shown? => return if not self.show_statistics: if not any(s.is_linked for s in outputs): nvBGL.callback_disable(node_id(self)) # clear drawing return input_D = inputs["Data"].sv_get(default=[[]]) if len(input_D) == 0 or any([len(d) == 0 for d in input_D]): outputs[0].sv_set([[]]) outputs[1].sv_set([[]]) raise Exception("Input data contains empty lists") input_P = inputs["Percentage"].sv_get()[0] input_B = inputs["Bins"].sv_get()[0] input_S = inputs["Size"].sv_get()[0] # sanitize the inputs input_P = list(map(lambda x: max(0, min(1, x)), input_P)) input_B = list(map(lambda x: max(1, x), input_B)) if self.mode == "INT": input_P = list(map(lambda x: int(x), input_P)) # determine the list of functions to generate statistics for if self.function == "ALL_STATISTICS": function_names = list(functions.keys()) elif self.function == "SELECTED_STATISTICS": function_names = [] for i, f in enumerate(functions.keys()): if self["selected_quantities"][i]: function_names.append(f) else: # one statistical quantity function_names = [self.function] params = match_long_repeat([input_D, input_P, input_B, input_S]) all_names = [] all_values = [] for function_name in function_names: statistics_function = functions[function_name][ 2] # (0=index, 1=abbreviation, 2=function) quantity_list = [] for d, p, b, s in zip(*params): if function_name == "PERCENTILE": quantity = statistics_function(d, p) elif function_name == "HISTOGRAM": quantity = statistics_function(d, b, self.normalize, s) else: quantity = statistics_function(d) if function_name != "HISTOGRAM": if self.mode == "INT": quantity = int(quantity) quantity_list.append(quantity) if self.abreviate_names: name = functions[function_name][ 1] # (0=index, 1=abbreviation, 2=function) else: name = function_name.replace("_", " ").title() all_names.append(name) all_values.append(quantity_list) if outputs[0].is_linked: outputs[0].sv_set(all_names) if outputs[1].is_linked: outputs[1].sv_set(all_values) self.draw_statistics(all_names, all_values)
def draw_statistics(self, names, values): """ Draw the statistics in the node editor The statistics data can be either single or vectorized. * single: [ [sum], [avg], ... [[b1, b2, .. bN]] ] * vectorized: [ [sum1... sumM], [avg1... avgM], ... [[b11... b1N]... [bM1... bMN]] ] Q: how can we tell statistics are simple or vectorized? A: if the values[0] is a list with length > 1 then it's vectorized """ nvBGL.callback_disable(node_id(self)) # clear drawing if len(values) == 0: return if self.show_statistics: max_width = max(len(name) for name in names) # used for text alignment info = [] # for now let's treat single and vectorized separately (optimize later) is_vectorized = len(values[0]) > 1 if is_vectorized: for n, v in zip(names, values): if n in ["Histogram", "HIS"]: line_format = "{0:>{x}} : [{1}]" histogram_lines = [] for a in v: # for each histogram set if self.mode == "FLOAT": value_format = "{:.{p}f}" else: value_format = "{}" histogram_values = ", ".join([ value_format.format(aa, p=self.precision) for aa in a ]) histogram_lines.append( "[{}]".format(histogram_values)) line = line_format.format(n, ", ".join(histogram_lines), x=max_width) info.append(line) else: line_format = "{0:>{x}} : [{1}]" if n in ["Count", "CNT"]: value_format = "{}" else: if self.mode == "FLOAT": value_format = "{:.{p}f}" else: value_format = "{}" value_line = ", ".join([ value_format.format(vv, p=self.precision) for vv in v ]) line = line_format.format(n, value_line, x=max_width) info.append(line) else: # single values for n, v in zip(names, values): if n in ["Histogram", "HIS"]: # print("drawing histogram") line_format = "{0:>{x}} : [{1}]" if self.normalize: value_format = "{:.{p}f}" else: value_format = "{}" histogram_values = ", ".join([ value_format.format(a, p=self.precision) for a in v[0] ]) line = line_format.format(n, histogram_values, x=max_width) info.append(line) else: if n in ["Count", "CNT"]: line_format = "{0:>{x}} : {1}" else: if self.mode == "FLOAT": line_format = "{0:>{x}} : {1:.{p}f}" else: line_format = "{0:>{x}} : {1}" line = line_format.format(n, v[0], x=max_width, p=self.precision) info.append(line) draw_data = { 'tree_name': self.id_data.name[:], 'node_name': self.name[:], 'content': info, 'location': get_text_drawing_location, 'color': self.text_color[:], 'scale': self.text_scale * get_dpi_factor(), 'font_id': int(self.selected_font_id()) } nvBGL.callback_enable(node_id(self), draw_data)
def update_show_statistics(self, context): nvBGL.callback_disable(node_id(self)) # clear draw updateNode(self, context)