Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <mail@jlucke.com>2018-09-24 13:21:05 +0300
committerJacques Lucke <mail@jlucke.com>2018-09-24 13:21:05 +0300
commit70177028974edb177fe7a4fa7096ee0e80ce7fb3 (patch)
tree19425dcac8b4f780ac4a4495de67648c9989c89c /io_mesh_uv_layout/export_uv_png.py
parentce871b0b50d0abc853c3a04002f32e620da01e2d (diff)
Export UV Layout: Rewrite Export UV Layout addon
Differential Revision: https://developer.blender.org/D3715 Reviewer: brecht
Diffstat (limited to 'io_mesh_uv_layout/export_uv_png.py')
-rw-r--r--io_mesh_uv_layout/export_uv_png.py291
1 files changed, 131 insertions, 160 deletions
diff --git a/io_mesh_uv_layout/export_uv_png.py b/io_mesh_uv_layout/export_uv_png.py
index be03ed0b..74b820b8 100644
--- a/io_mesh_uv_layout/export_uv_png.py
+++ b/io_mesh_uv_layout/export_uv_png.py
@@ -20,163 +20,134 @@
import bpy
-
-class Export_UV_PNG:
- def begin(self, fw, image_size, opacity):
- self.filepath = fw.__self__.name
- fw.__self__.close()
-
- self.scene = bpy.data.scenes.new("uv_temp")
-
- image_width = image_size[0]
- image_height = image_size[1]
-
- self.scene.render.resolution_x = image_width
- self.scene.render.resolution_y = image_height
- self.scene.render.resolution_percentage = 100
-
- self.scene.render.alpha_mode = 'TRANSPARENT'
-
- if image_width > image_height:
- self.scene.render.pixel_aspect_y = image_width / image_height
- elif image_width < image_height:
- self.scene.render.pixel_aspect_x = image_height / image_width
-
- self.base_material = bpy.data.materials.new("uv_temp_base")
- self.base_material.use_nodes = True
- self.base_material.node_tree.nodes.clear()
- output_node = self.base_material.node_tree.nodes.new(type="ShaderNodeOutputMaterial")
- emission_node = self.base_material.node_tree.nodes.new(type="ShaderNodeEmission")
- emission_node.inputs["Color"].default_value = (1.0, 1.0, 1.0, opacity)
- self.base_material.node_tree.links.new(
- output_node.inputs["Surface"],
- emission_node.outputs["Emission"])
-
- self.material_wire = self.base_material.copy()
- self.material_wire.name = "Wire"
- self.material_wire.node_tree.nodes['Emission'].inputs["Color"].default_value = (0.0, 0.0, 0.0, 1.0)
-
- self.base_material.blend_method = "BLEND"
-
- self.material_solids_list = [] # list of lists
- self.material_solids_list.append([self.base_material,
- self.material_wire])
-
- self.mesh_list = []
- self.obj_list = []
-
- def build(self, mesh_source, face_iter_func):
- material_solids = [self.base_material.copy() for i in range(max(1, len(mesh_source.materials)))]
-
- self.material_solids_list.append(material_solids)
-
- mesh = bpy.data.meshes.new("uv_temp")
- self.mesh_list.append(mesh)
-
- for mat_solid in material_solids:
- mesh.materials.append(mat_solid)
-
- # setup materials
- for i, mat_solid in enumerate(material_solids):
- if mesh_source.materials and mesh_source.materials[i]:
- mat_solid.node_tree.nodes['Emission'].\
- inputs["Color"].default_value[0:3]\
- = mesh_source.materials[i].diffuse_color
-
- # Add materials for wireframe modifier.
- for mat_solid in material_solids:
- mesh.materials.append(self.material_wire)
-
- polys_source = mesh_source.polygons
-
- # get unique UV's in case there are many overlapping
- # which slow down filling.
- face_hash = {(uvs, polys_source[i].material_index)
- for i, uvs in face_iter_func()}
-
- # now set the faces coords and locations
- # build mesh data
- mesh_new_vertices = []
- mesh_new_materials = []
- mesh_new_polys_startloop = []
- mesh_new_polys_totloop = []
- mesh_new_loops_vertices = []
-
- current_vert = 0
-
- for uvs, mat_idx in face_hash:
- num_verts = len(uvs)
- # dummy = (0.0,) * num_verts
- for uv in uvs:
- mesh_new_vertices += (uv[0], uv[1], 0.0)
- mesh_new_polys_startloop.append(current_vert)
- mesh_new_polys_totloop.append(num_verts)
- mesh_new_loops_vertices += range(current_vert,
- current_vert + num_verts)
- mesh_new_materials.append(mat_idx)
- current_vert += num_verts
-
- mesh.vertices.add(current_vert)
- mesh.loops.add(current_vert)
- mesh.polygons.add(len(mesh_new_polys_startloop))
-
- mesh.vertices.foreach_set("co", mesh_new_vertices)
- mesh.loops.foreach_set("vertex_index", mesh_new_loops_vertices)
- mesh.polygons.foreach_set("loop_start", mesh_new_polys_startloop)
- mesh.polygons.foreach_set("loop_total", mesh_new_polys_totloop)
- mesh.polygons.foreach_set("material_index", mesh_new_materials)
-
- mesh.update(calc_edges=True)
-
- obj_solid = bpy.data.objects.new("uv_temp_solid", mesh)
-
- wire_mod = obj_solid.modifiers.new("wire_mod", 'WIREFRAME')
- wire_mod.use_replace = False
- wire_mod.use_relative_offset = True
-
- wire_mod.material_offset = len(material_solids)
-
- self.obj_list.append(obj_solid)
- self.scene.collection.objects.link(obj_solid)
-
- def end(self):
- # setup the camera
- cam = bpy.data.cameras.new("uv_temp")
- cam.type = 'ORTHO'
- cam.ortho_scale = 1.0
- obj_cam = bpy.data.objects.new("uv_temp_cam", cam)
- obj_cam.location = 0.5, 0.5, 1.0
- self.scene.collection.objects.link(obj_cam)
- self.obj_list.append(obj_cam)
- self.scene.camera = obj_cam
-
- # scene render settings
- self.scene.render.alpha_mode = 'TRANSPARENT'
- self.scene.render.image_settings.color_mode = 'RGBA'
-
- self.scene.frame_start = 1
- self.scene.frame_end = 1
-
- self.scene.render.image_settings.file_format = 'PNG'
- self.scene.render.filepath = self.filepath
-
- self.scene.update()
-
- data_context = {"blend_data": bpy.context.blend_data,
- "scene": self.scene}
- bpy.ops.render.render(data_context, write_still=True)
-
- # cleanup
- bpy.data.scenes.remove(self.scene, do_unlink=True)
-
- for obj in self.obj_list:
- bpy.data.objects.remove(obj, do_unlink=True)
-
- bpy.data.cameras.remove(cam, do_unlink=True)
-
- for mesh in self.mesh_list:
- bpy.data.meshes.remove(mesh, do_unlink=True)
-
- for material_solids in self.material_solids_list:
- for mat_solid in material_solids:
- bpy.data.materials.remove(mat_solid, do_unlink=True)
+# maybe we could also just use the svg exporter, import it again
+# and render it. Unfortunately the svg importer does not work atm.
+def export(filepath, face_data, colors, width, height, opacity):
+ aspect = width / height
+
+ # curves for lines
+ lines = curve_from_uvs(face_data, aspect, 1 / min(width, height))
+ lines_object = bpy.data.objects.new("temp_lines_object", lines)
+ black_material = make_colored_material((0, 0, 0))
+ lines.materials.append(black_material)
+
+ # background mesh
+ background_mesh = background_mesh_from_uvs(face_data, colors, aspect, opacity)
+ background_object = bpy.data.objects.new("temp_background_object", background_mesh)
+ background_object.location = (0, 0, -1)
+
+ # camera
+ camera = bpy.data.cameras.new("temp_camera")
+ camera_object = bpy.data.objects.new("temp_camera_object", camera)
+ camera.type = "ORTHO"
+ camera.ortho_scale = max(1, aspect)
+ camera_object.location = (aspect / 2, 0.5, 1)
+ camera_object.rotation_euler = (0, 0, 0)
+
+ # scene
+ scene = bpy.data.scenes.new("temp_scene")
+ scene.render.engine = "BLENDER_EEVEE"
+ scene.render.resolution_x = width
+ scene.render.resolution_y = height
+ scene.render.image_settings.color_mode = "RGBA"
+ scene.render.alpha_mode = "TRANSPARENT"
+ scene.render.filepath = filepath
+
+ # Link everything to the scene
+ scene.collection.objects.link(lines_object)
+ scene.collection.objects.link(camera_object)
+ scene.collection.objects.link(background_object)
+ scene.camera = camera_object
+
+ # Render
+ override = {"scene" : scene}
+ bpy.ops.render.render(override, write_still=True)
+
+ # Cleanup
+ bpy.data.objects.remove(lines_object)
+ bpy.data.objects.remove(camera_object)
+ bpy.data.objects.remove(background_object)
+
+ for material in background_mesh.materials:
+ bpy.data.materials.remove(material)
+ bpy.data.meshes.remove(background_mesh)
+
+ bpy.data.cameras.remove(camera)
+ bpy.data.curves.remove(lines)
+ bpy.data.materials.remove(black_material)
+ bpy.data.scenes.remove(scene)
+
+def curve_from_uvs(face_data, aspect, thickness):
+ lines = bpy.data.curves.new("temp_curve", "CURVE")
+ lines.fill_mode = "BOTH"
+ lines.bevel_depth = thickness
+ lines.offset = -thickness / 2
+ lines.dimensions = "3D"
+
+ for uvs, _ in face_data:
+ for i in range(len(uvs)):
+ start = uvs[i]
+ end = uvs[(i+1) % len(uvs)]
+
+ spline = lines.splines.new("POLY")
+ # one point is already there
+ spline.points.add(count=1)
+ points = spline.points
+
+ points[0].co.x = start[0] * aspect
+ points[0].co.y = start[1]
+
+ points[1].co.x = end[0] * aspect
+ points[1].co.y = end[1]
+
+ return lines
+
+def background_mesh_from_uvs(face_data, colors, aspect, opacity):
+ mesh = bpy.data.meshes.new("temp_background")
+
+ vertices = []
+ polygons = []
+ for uvs, _ in face_data:
+ polygon = []
+ for uv in uvs:
+ polygon.append(len(vertices))
+ vertices.append((uv[0] * aspect, uv[1], 0))
+ polygons.append(tuple(polygon))
+
+ mesh.from_pydata(vertices, [], polygons)
+
+ materials, material_index_by_color = make_polygon_background_materials(colors, opacity)
+ for material in materials:
+ mesh.materials.append(material)
+
+ for generated_polygon, (_, color) in zip(mesh.polygons, face_data):
+ generated_polygon.material_index = material_index_by_color[color]
+
+ mesh.update()
+ mesh.validate()
+
+ return mesh
+
+def make_polygon_background_materials(colors, opacity=1):
+ materials = []
+ material_index_by_color = {}
+ for i, color in enumerate(colors):
+ material = make_colored_material(color, opacity)
+ materials.append(material)
+ material_index_by_color[color] = i
+ return materials, material_index_by_color
+
+def make_colored_material(color, opacity=1):
+ material = bpy.data.materials.new("temp_material")
+ material.use_nodes = True
+ material.blend_method = "BLEND"
+ tree = material.node_tree
+ tree.nodes.clear()
+
+ output_node = tree.nodes.new("ShaderNodeOutputMaterial")
+ emission_node = tree.nodes.new("ShaderNodeEmission")
+
+ emission_node.inputs["Color"].default_value = [color[0], color[1], color[2], opacity]
+ tree.links.new(emission_node.outputs["Emission"], output_node.inputs["Surface"])
+
+ return material