def make_bmesh_geometry(node, context, geometry, idx, layers): scene = context.scene meshes = bpy.data.meshes objects = bpy.data.objects verts, edges, matrix, _, _ = geometry name = node.basemesh_name + '.' + str("%04d" % idx) # remove object if name in objects: obj = objects[name] # assign the object an empty mesh, this allows the current mesh # to be uncoupled and removed from bpy.data.meshes obj.data = assign_empty_mesh(idx) # remove uncoupled mesh, and add it straight back. if name in meshes: meshes.remove(meshes[name]) mesh = meshes.new(name) obj.data = mesh else: # this is only executed once, upon the first run. mesh = meshes.new(name) obj = objects.new(name, mesh) scene.objects.link(obj) # at this point the mesh is always fresh and empty obj['idx'] = idx obj['basename'] = node.basemesh_name data_layers = None if node.distance_doubles > 0.0: bm = bmesh_from_pydata(verts, edges, []) verts, edges, faces, d1, d2 = shrink_geometry(bm, node.distance_doubles, layers) data_layers = d1, d2 force_pydata(obj.data, verts, edges) obj.update_tag(refresh={'OBJECT', 'DATA'}) if node.live_updates: if 'sv_skin' in obj.modifiers: sk = obj.modifiers['sv_skin'] obj.modifiers.remove(sk) if 'sv_subsurf' in obj.modifiers: sd = obj.modifiers['sv_subsurf'] obj.modifiers.remove(sd) _ = obj.modifiers.new(type='SKIN', name='sv_skin') b = obj.modifiers.new(type='SUBSURF', name='sv_subsurf') b.levels = node.levels b.render_levels = node.render_levels if matrix: matrix = matrix_sanitizer(matrix) obj.matrix_local = matrix else: obj.matrix_local = Matrix.Identity(4) return obj, data_layers
def make_text_object(node, idx, context, data): scene = context.scene curves = bpy.data.curves objects = bpy.data.objects txt, matrix = data name = node.basemesh_name + "_" + str(idx) # CURVES if not (name in curves): f = curves.new(name, 'FONT') else: f = curves[name] # CONTAINER OBJECTS if name in objects: sv_object = objects[name] else: sv_object = objects.new(name, f) scene.objects.link(sv_object) default = bpy.data.fonts.get('Bfont') f.body = txt # misc f.size = node.fsize f.font = bpy.data.fonts.get(node.fontname, default) # space f.space_character = node.space_character f.space_word = node.space_word f.space_line = node.space_line f.offset_x = node.xoffset f.offset_y = node.yoffset # modifications f.offset = node.offset f.extrude = node.extrude # bevel f.bevel_depth = node.bevel_depth f.bevel_resolution = node.bevel_resolution f.align = node.align # artifical restriction l/r/c sv_object['idx'] = idx sv_object['madeby'] = node.name sv_object['basename'] = node.basemesh_name sv_object.hide_select = False if matrix: matrix = matrix_sanitizer(matrix) sv_object.matrix_local = matrix else: sv_object.matrix_local = Matrix.Identity(4)
def make_curve_geometry(node, context, name, verts, matrix, close): sv_object = live_curve(node, name, verts, close) sv_object.hide_select = False if matrix: matrix = matrix_sanitizer(matrix) sv_object.matrix_local = matrix else: sv_object.matrix_local = Matrix.Identity(4)
def make_bmesh_geometry(node, idx, context, verts, *topology): scene = context.scene meshes = bpy.data.meshes objects = bpy.data.objects edges, faces, matrix = topology name = node.basemesh_name + "_" + str(idx) if name in objects: sv_object = objects[name] else: temp_mesh = default_mesh(name) sv_object = objects.new(name, temp_mesh) scene.objects.link(sv_object) # book-keeping via ID-props!? even this is can be broken by renames sv_object['idx'] = idx sv_object['madeby'] = node.name sv_object['basename'] = node.basemesh_name mesh = sv_object.data current_count = len(mesh.vertices) propose_count = len(verts) difference = (propose_count - current_count) ''' With this mode you make a massive assumption about the constant state of geometry. Assumes the count of verts edges/faces stays the same, and only updates the locations node.fixed_verts is not suitable for initial object creation but if over time you find that the only change is going to be vertices, this mode can be switched to to increase efficiency ''' if node.fixed_verts and difference == 0: f_v = list(itertools.chain.from_iterable(verts)) mesh.vertices.foreach_set('co', f_v) mesh.update() else: ''' get bmesh, write bmesh to obj, free bmesh''' bm = bmesh_from_pydata(verts, edges, faces, normal_update=node.calc_normals) bm.to_mesh(sv_object.data) bm.free() sv_object.hide_select = False if matrix: matrix = matrix_sanitizer(matrix) if node.extended_matrix: sv_object.data.transform(matrix) sv_object.matrix_local = Matrix.Identity(4) else: sv_object.matrix_local = matrix else: sv_object.matrix_local = Matrix.Identity(4)
def make_bmesh_geometry(node, idx, context, verts, *topology): scene = context.scene meshes = bpy.data.meshes objects = bpy.data.objects edges, faces, matrix = topology name = node.basemesh_name + "_" + str(idx) if name in objects: sv_object = objects[name] else: temp_mesh = default_mesh(name) sv_object = objects.new(name, temp_mesh) scene.objects.link(sv_object) # book-keeping via ID-props!? even this is can be broken by renames sv_object['idx'] = idx sv_object['madeby'] = node.name sv_object['basename'] = node.basemesh_name mesh = sv_object.data current_count = len(mesh.vertices) propose_count = len(verts) difference = (propose_count - current_count) ''' With this mode you make a massive assumption about the constant state of geometry. Assumes the count of verts edges/faces stays the same, and only updates the locations node.fixed_verts is not suitable for initial object creation but if over time you find that the only change is going to be vertices, this mode can be switched to to increase efficiency ''' if node.fixed_verts and difference == 0: f_v = list(itertools.chain.from_iterable(verts)) mesh.vertices.foreach_set('co', f_v) mesh.update() else: ''' get bmesh, write bmesh to obj, free bmesh''' bm = bmesh_from_pydata(verts, edges, faces) bm.to_mesh(sv_object.data) bm.free() sv_object.hide_select = False if matrix: matrix = matrix_sanitizer(matrix) if node.extended_matrix: sv_object.data.transform(matrix) sv_object.matrix_local = Matrix.Identity(4) else: sv_object.matrix_local = matrix else: sv_object.matrix_local = Matrix.Identity(4)
def make_curve_geometry(obj_index, node, verts, matrix, radii, twist): sv_object = live_curve(obj_index, node, verts, radii, twist) sv_object.hide_select = False if matrix: matrix = matrix_sanitizer(matrix) sv_object.matrix_local = matrix else: sv_object.matrix_local = Matrix.Identity(4) return sv_object
def make_bmesh_geometry_merged(node, idx, context, yielder_object): scene = context.scene meshes = bpy.data.meshes objects = bpy.data.objects name = node.basemesh_name + "_" + str(idx) if name in objects: sv_object = objects[name] else: temp_mesh = default_mesh(name) sv_object = objects.new(name, temp_mesh) scene.objects.link(sv_object) # book-keeping via ID-props! sv_object['idx'] = idx sv_object['madeby'] = node.name sv_object['basename'] = node.basemesh_name vert_count = 0 big_verts = [] big_edges = [] big_faces = [] for result in yielder_object: verts, topology = result edges, faces, matrix = topology if matrix: matrix = matrix_sanitizer(matrix) verts = [matrix * Vector(v) for v in verts] big_verts.extend(verts) big_edges.extend([[a + vert_count, b + vert_count] for a, b in edges]) big_faces.extend([[j + vert_count for j in f] for f in faces]) vert_count += len(verts) if node.fixed_verts and len(sv_object.data.vertices) == len(big_verts): mesh = sv_object.data f_v = list(itertools.chain.from_iterable(big_verts)) mesh.vertices.foreach_set('co', f_v) mesh.update() else: ''' get bmesh, write bmesh to obj, free bmesh''' bm = bmesh_from_pydata(big_verts, big_edges, big_faces, normal_update=node.calc_normals) bm.to_mesh(sv_object.data) bm.free() sv_object.hide_select = False sv_object.matrix_local = Matrix.Identity(4)
def make_curve_geometry(node, context, name, verts, *topology): edges, matrix = topology sv_object = live_curve(name, verts, edges, matrix, node) sv_object.hide_select = False if matrix: matrix = matrix_sanitizer(matrix) sv_object.matrix_local = matrix else: sv_object.matrix_local = Matrix.Identity(4)
def process(self): #objectsP = self.inputs['parent'].sv_get(default=None) objectsC = self.inputs['child'].sv_get() transforms = self.inputs['matr/vert'].sv_get() objects = bpy.data.objects #if any([x.name == self.name_node_generated_parent for x in objects]): ob = objects.get(self.name_node_generated_parent) #self.name_node_generated_parent = ob.name if ob: wipe_object(ob) # minimum requirements. if (not transforms) and (not objectsC): if ob: ob.dupli_type = 'NONE' return if not ob: name = self.name_node_generated_parent mesh = bpy.data.meshes.new(name + '_mesh') ob = bpy.data.objects.new(name, mesh) bpy.context.scene.objects.link(ob) # at this point there's a reference to an ob, and the mesh is empty. child = self.inputs['child'].sv_get()[0] #print('checking',child) if transforms and transforms[0]: sin, cos = math.sin, math.cos theta = 2 * math.pi / 3 thetb = theta * 2 ofs = 0.5 * math.pi + theta A = Vector((cos(0 + ofs), sin(0 + ofs), 0)) B = Vector((cos(theta + ofs), sin(theta + ofs), 0)) C = Vector((cos(thetb + ofs), sin(thetb + ofs), 0)) verts = [] add_verts = verts.extend num_matrices = len(transforms) for m in transforms: M = matrix_sanitizer(m) add_verts([(M * A)[:], (M * B)[:], (M * C)[:]]) strides = range(0, num_matrices * 3, 3) faces = [[i, i + 1, i + 2] for i in strides] ob.data.from_pydata(verts, [], faces) ob.dupli_type = self.mode ob.use_dupli_faces_scale = self.scale child.parent = ob
def make_bmesh_geometry_merged(node, idx, context, yielder_object): scene = context.scene meshes = bpy.data.meshes objects = bpy.data.objects name = node.basemesh_name + "_" + str(idx) if name in objects: sv_object = objects[name] else: temp_mesh = default_mesh(name) sv_object = objects.new(name, temp_mesh) scene.objects.link(sv_object) # book-keeping via ID-props! sv_object['idx'] = idx sv_object['madeby'] = node.name sv_object['basename'] = node.basemesh_name vert_count = 0 big_verts = [] big_edges = [] big_faces = [] while (True): result = next(yielder_object) if result == 'FINAL': break verts, topology = result edges, faces, matrix = topology if matrix: matrix = matrix_sanitizer(matrix) verts = [matrix * Vector(v) for v in verts] big_verts.extend(verts) big_edges.extend([[a+vert_count, b+vert_count] for a, b in edges]) big_faces.extend([[j+vert_count for j in f] for f in faces]) vert_count += len(verts) ''' get bmesh, write bmesh to obj, free bmesh''' bm = bmesh_from_pydata(big_verts, big_edges, big_faces) bm.to_mesh(sv_object.data) bm.free() sv_object.hide_select = False sv_object.matrix_local = Matrix.Identity(4)
def make_bmesh_geometry_merged(node, idx, context, yielder_object): scene = context.scene meshes = bpy.data.meshes objects = bpy.data.objects name = node.basemesh_name + "_" + str(idx) if name in objects: sv_object = objects[name] else: temp_mesh = default_mesh(name) sv_object = objects.new(name, temp_mesh) scene.objects.link(sv_object) # book-keeping via ID-props! sv_object['idx'] = idx sv_object['madeby'] = node.name sv_object['basename'] = node.basemesh_name vert_count = 0 big_verts = [] big_edges = [] big_faces = [] while (True): result = next(yielder_object) if result == 'FINAL': break verts, topology = result edges, faces, matrix = topology if matrix: matrix = matrix_sanitizer(matrix) verts = [matrix * Vector(v) for v in verts] big_verts.extend(verts) big_edges.extend([[a + vert_count, b + vert_count] for a, b in edges]) big_faces.extend([[j + vert_count for j in f] for f in faces]) vert_count += len(verts) ''' get bmesh, write bmesh to obj, free bmesh''' bm = bmesh_from_pydata(big_verts, big_edges, big_faces) bm.to_mesh(sv_object.data) bm.free() sv_object.hide_select = False sv_object.matrix_local = Matrix.Identity(4)
def make_duplicates_live_curve(node, curve_name, verts, edges, matrices): curves = bpy.data.curves objects = bpy.data.objects scene = bpy.context.scene # if curve data exists, pick it up else make new curve # this curve is then used as a data.curve for all objects. # objects still have slow creation time, but storage is very good due to # reuse of curve data and applying matrices to objects instead. cu = curves.get(curve_name) if not cu: cu = curves.new(name=curve_name, type='CURVE') cu.bevel_depth = node.depth cu.bevel_resolution = node.resolution cu.dimensions = '3D' cu.fill_mode = 'FULL' # wipe! if cu.splines: cu.splines.clear() # rebuild! for edge in edges: v0, v1 = verts[edge[0]], verts[edge[1]] full_flat = [v0[0], v0[1], v0[2], 0.0, v1[0], v1[1], v1[2], 0.0] # each spline has a default first coordinate but we need two. segment = cu.splines.new('POLY') segment.points.add(1) segment.points.foreach_set('co', full_flat) # to proceed we need to add or update objects. obj_base_name = curve_name[:-1] # if object reference exists, pick it up else make a new one # assign the same curve to all Objects. for idx, matrix in enumerate(matrices): m = matrix_sanitizer(matrix) obj_name = obj_base_name + str(idx) obj = objects.get(obj_name) if not obj: obj = objects.new(obj_name, cu) scene.objects.link(obj) obj.matrix_local = m
def make_bmesh_geometry(node, context, name, verts, *topology): scene = context.scene meshes = bpy.data.meshes objects = bpy.data.objects edges, faces, matrix = topology if name in objects: sv_object = objects[name] else: temp_mesh = default_mesh(name) sv_object = objects.new(name, temp_mesh) scene.objects.link(sv_object) ''' There is overalapping code here for testing! ''' mesh = sv_object.data current_count = len(mesh.vertices) propose_count = len(verts) difference = (propose_count - current_count) ''' With this mode you make a massive assumption about the constant state of geometry. Assumes the count of verts edges/faces stays the same, and only updates the locations node.fixed_verts is not suitable for initial object creation but if over time you find that the only change is going to be vertices, this mode can be switched to to increase efficiency ''' if node.fixed_verts and difference == 0: f_v = list(itertools.chain.from_iterable(verts)) mesh.vertices.foreach_set('co', f_v) mesh.update() else: ''' get bmesh, write bmesh to obj, free bmesh''' bm = bmesh_from_pydata(verts, edges, faces) bm.to_mesh(sv_object.data) bm.free() sv_object.hide_select = False if matrix: matrix = matrix_sanitizer(matrix) sv_object.matrix_local = matrix else: sv_object.matrix_local = Matrix.Identity(4)
def make_merged_live_curve(node, curve_name, verts, edges, matrices): curves = bpy.data.curves objects = bpy.data.objects scene = bpy.context.scene # if curve data exists, pick it up else make new curve cu = curves.get(curve_name) if not cu: cu = curves.new(name=curve_name, type='CURVE') # if object reference exists, pick it up else make a new one obj = objects.get(curve_name) if not obj: obj = objects.new(curve_name, cu) scene.objects.link(obj) # break down existing splines entirely. if cu.splines: cu.splines.clear() cu.bevel_depth = node.depth cu.bevel_resolution = node.resolution cu.dimensions = '3D' cu.fill_mode = 'FULL' for matrix in matrices: m = matrix_sanitizer(matrix) # and rebuild for edge in edges: v0, v1 = m * Vector(verts[edge[0]]), m * Vector(verts[edge[1]]) full_flat = [v0[0], v0[1], v0[2], 0.0, v1[0], v1[1], v1[2], 0.0] # each spline has a default first coordinate but we need two. segment = cu.splines.new('POLY') segment.points.add(1) segment.points.foreach_set('co', full_flat)
def process(self): #objectsP = self.inputs['parent'].sv_get(default=None) objectsC = self.inputs['child'].sv_get() transforms = self.inputs['matr/vert'].sv_get() objects = bpy.data.objects #if any([x.name == self.name_node_generated_parent for x in objects]): ob = objects.get(self.name_node_generated_parent) #self.name_node_generated_parent = ob.name if ob: wipe_object(ob) # minimum requirements. if (not transforms) and (not objectsC): if ob: ob.dupli_type = 'NONE' return if not ob: name = self.name_node_generated_parent mesh = bpy.data.meshes.new(name + '_mesh') ob = bpy.data.objects.new(name, mesh) bpy.context.scene.objects.link(ob) # at this point there's a reference to an ob, and the mesh is empty. child = self.inputs['child'].sv_get()[0] #print('проверка',child) if transforms and transforms[0]: # -- this mode will face duplicate -- # i expect this can be done faster using numpy # please view this only as exploratory if self.inputs['matr/vert'].links[ 0].from_socket.bl_idname == 'VerticesSocket': transforms = transforms[0] # -- this mode will vertex duplicate -- ob.data.from_pydata(transforms, [], []) ob.dupli_type = 'VERTS' child.parent = ob elif self.inputs['matr/vert'].links[ 0].from_socket.bl_idname == 'MatrixSocket': sin, cos = math.sin, math.cos theta = 2 * math.pi / 3 thetb = theta * 2 ofs = 0.5 * math.pi + theta A = Vector((cos(0 + ofs), sin(0 + ofs), 0)) B = Vector((cos(theta + ofs), sin(theta + ofs), 0)) C = Vector((cos(thetb + ofs), sin(thetb + ofs), 0)) verts = [] add_verts = verts.extend num_matrices = len(transforms) for m in transforms: M = matrix_sanitizer(m) add_verts([(M * A)[:], (M * B)[:], (M * C)[:]]) strides = range(0, num_matrices * 3, 3) faces = [[i, i + 1, i + 2] for i in strides] ob.data.from_pydata(verts, [], faces) ob.dupli_type = 'FACES' ob.use_dupli_faces_scale = self.scale child.parent = ob
def process(self): locations = self.inputs['Locations'].sv_get(default=None) transforms = self.inputs['Transforms'].sv_get(default=None) objects = bpy.data.objects ob = objects.get(self.name_node_generated_parent) if ob: wipe_object(ob) # minimum requirements. if (not any([locations, transforms])) or (not self.name_child): if ob: ob.dupli_type = 'NONE' return if not ob: name = self.name_node_generated_parent mesh = bpy.data.meshes.new(name + '_mesh') ob = bpy.data.objects.new(name, mesh) bpy.context.scene.objects.link(ob) # at this point there's a reference to an ob, and the mesh is empty. child = objects.get(self.name_child) if locations and locations[0] and (not transforms): locations = locations[0] # -- this mode will vertex duplicate -- ob.data.from_pydata(locations, [], []) ob.dupli_type = 'VERTS' child.parent = ob elif transforms: # -- this mode will face duplicate -- # i expect this can be done faster using numpy # please view this only as exploratory sin, cos = math.sin, math.cos theta = 2 * math.pi / 3 thetb = theta * 2 ofs = 0.5 * math.pi + theta A = Vector((cos(0 + ofs), sin(0 + ofs), 0)) B = Vector((cos(theta + ofs), sin(theta + ofs), 0)) C = Vector((cos(thetb + ofs), sin(thetb + ofs), 0)) verts = [] add_verts = verts.extend num_matrices = len(transforms) for m in transforms: M = matrix_sanitizer(m) add_verts([(M * A)[:], (M * B)[:], (M * C)[:]]) strides = range(0, num_matrices * 3, 3) faces = [[i, i + 1, i + 2] for i in strides] ob.data.from_pydata(verts, [], faces) ob.dupli_type = 'FACES' ob.use_dupli_faces_scale = True child.parent = ob
def process(self): #objectsP = self.inputs['parent'].sv_get(default=None) objectsC = self.inputs['child'].sv_get() transforms = self.inputs['matr/vert'].sv_get() objects = bpy.data.objects #if any([x.name == self.name_node_generated_parent for x in objects]): ob = objects.get(self.name_node_generated_parent) #self.name_node_generated_parent = ob.name if ob: wipe_object(ob) # minimum requirements. if (not transforms) and (not objectsC): if ob: ob.dupli_type = 'NONE' return if not ob: name = self.name_node_generated_parent mesh = bpy.data.meshes.new(name + '_mesh') ob = bpy.data.objects.new(name, mesh) bpy.context.scene.objects.link(ob) # at this point there's a reference to an ob, and the mesh is empty. child = self.inputs['child'].sv_get()[0] #print('проверка',child) if transforms and transforms[0]: # -- this mode will face duplicate -- # i expect this can be done faster using numpy # please view this only as exploratory if self.inputs['matr/vert'].links[0].from_socket.bl_idname == 'VerticesSocket': transforms = transforms[0] # -- this mode will vertex duplicate -- ob.data.from_pydata(transforms, [], []) ob.dupli_type = 'VERTS' child.parent = ob elif self.inputs['matr/vert'].links[0].from_socket.bl_idname == 'MatrixSocket': sin, cos = math.sin, math.cos theta = 2 * math.pi / 3 thetb = theta * 2 ofs = 0.5 * math.pi + theta A = Vector((cos(0 + ofs), sin(0 + ofs), 0)) B = Vector((cos(theta + ofs), sin(theta + ofs), 0)) C = Vector((cos(thetb + ofs), sin(thetb + ofs), 0)) verts = [] add_verts = verts.extend num_matrices = len(transforms) for m in transforms: M = matrix_sanitizer(m) add_verts([(M * A)[:], (M * B)[:], (M * C)[:]]) strides = range(0, num_matrices * 3, 3) faces = [[i, i + 1, i + 2] for i in strides] ob.data.from_pydata(verts, [], faces) ob.dupli_type = 'FACES' ob.use_dupli_faces_scale = self.scale child.parent = ob