Example #1
0
class Book:
    def __init__(self, cover_height, cover_thickness, cover_depth, page_height,
                 page_depth, page_thickness, spine_curl, hinge_inset,
                 hinge_width, book_width, lean, lean_angle, subsurf, material):
        self.height = cover_height
        self.width = page_thickness + 2 * cover_thickness
        self.depth = cover_depth
        self.lean_angle = lean_angle
        self.lean = lean
        self.page_thickness = page_thickness
        self.page_height = page_height
        self.page_depth = page_depth
        self.cover_depth = cover_depth
        self.cover_height = cover_height
        self.cover_thickness = cover_thickness
        self.hinge_inset = hinge_inset
        self.hinge_width = hinge_width
        self.spine_curl = spine_curl
        self.subsurf = subsurf
        self.material = material
        self.location = Vector([0, 0, 0])
        self.rotation = Vector([0, 0, 0])

        self.verts = get_verts(page_thickness, page_height, cover_depth,
                               cover_height, cover_thickness, page_depth,
                               hinge_inset, hinge_width, spine_curl)
        self.faces = get_faces()

    def to_object(self):
        def index_to_vert(face):
            lst = []
            for i in face:
                lst.append(vert_ob[i])
            return tuple(lst)

        mesh = bpy.data.meshes.new("book")

        self.creases = get_creases()
        self.uvs = get_uvs(self.page_thickness, self.page_height,
                           self.cover_depth, self.cover_height,
                           self.cover_thickness, self.page_depth,
                           self.hinge_inset, self.hinge_width, self.spine_curl)

        self.obj = bpy.data.objects.new("book", mesh)

        bm = bmesh.new()
        bm.from_mesh(mesh)
        vert_ob = []
        for vert in self.verts:
            vert_ob.append(bm.verts.new(vert))

        bm.verts.index_update()
        bm.verts.ensure_lookup_table()

        cl = bm.edges.layers.crease.verify()
        for c in self.creases:
            e = bm.edges.new((bm.verts[c[0]], bm.verts[c[1]]))
            e[cl] = 1.0

        for face in self.faces:
            f = bm.faces.new(index_to_vert(face))
            f.smooth = True

        bm.faces.index_update()
        bm.edges.ensure_lookup_table()

        uv_layer = bm.loops.layers.uv.verify()
        for (f, uvs) in zip(bm.faces, self.uvs):
            for (l, uv) in zip(f.loops, uvs):
                loop_uv = l[uv_layer]
                loop_uv.uv.x = uv[0]
                loop_uv.uv.y = uv[1]

        bm.normal_update()
        bm.to_mesh(mesh)
        bm.free()

        # calculate auto smooth angle based on spine
        center = self.verts[-1]
        side = self.verts[-5]
        curl = abs(center[1] - side[1])
        width = abs(center[0] - side[0])
        spine_angle = atan(width / curl) * 2
        normal_angle = radians(180) - spine_angle + radians(
            1)  # add 1 deg to account for fp
        mesh.use_auto_smooth = True
        mesh.auto_smooth_angle = normal_angle

        if (self.subsurf):
            self.obj.modifiers.new("subd", type='SUBSURF')
            self.obj.modifiers['subd'].levels = 1

        if (self.material):
            if self.obj.data.materials:
                self.obj.data.materials[0] = self.material
            else:
                self.obj.data.materials.append(self.material)

        self.obj.matrix_world = Matrix.Translation(
            self.location) @ self.rotation.to_4x4()

        return self.obj

    def get_geometry(self):
        transformed_verts = map(
            lambda v: self.rotation @ Vector(v) + self.location, self.verts)
        return transformed_verts, self.faces
Example #2
0
class Book:
    """
    This stores information about a single book. It can export the book as blender object
    or return the raw geometry for previz.
    """

    def __init__(
        self,
        cover_height,
        cover_thickness,
        cover_depth,
        page_height,
        page_depth,
        page_thickness,
        spine_curl,
        hinge_inset,
        hinge_width,
        lean=0,
        lean_angle=0,
        subsurf=False,
        cover_material=None,
        page_material=None
    ):
        self.height = cover_height
        self.width = page_thickness + 2 * cover_thickness
        self.depth = cover_depth
        self.lean_angle = lean_angle
        self.lean = lean
        self.page_thickness = page_thickness
        self.page_height = page_height
        self.page_depth = page_depth
        self.cover_depth = cover_depth
        self.cover_height = cover_height
        self.cover_thickness = cover_thickness
        self.hinge_inset = hinge_inset
        self.hinge_width = hinge_width
        self.spine_curl = spine_curl
        self.subsurf = subsurf
        self.cover_material = cover_material
        self.page_material = page_material
        self.location = Vector([0, 0, 0])
        self.rotation = Vector([0, 0, 0])

        self.obj = None

        self.vertices = get_vertices(
            page_thickness,
            page_height,
            cover_depth,
            cover_height,
            cover_thickness,
            page_depth,
            hinge_inset,
            hinge_width,
            spine_curl)
        self.faces = get_faces()

    def to_object(self, with_uvs=False):
        """
        Exports the book as a blender object
        """
        def index_to_vert(face):
            lst = []
            for i in face:
                lst.append(vert_ob[i])
            return tuple(lst)

        mesh = bpy.data.meshes.new("book")

        creases = get_creases()

        if with_uvs:
            uvs = get_uvs(
                self.page_thickness,
                self.page_height,
                self.cover_depth,
                self.cover_height,
                self.cover_thickness,
                self.page_depth,
                self.hinge_inset,
                self.hinge_width,
                self.spine_curl)

        self.obj = bpy.data.objects.new("book", mesh)

        bm = bmesh.new()
        bm.from_mesh(mesh)
        vert_ob = []
        for vert in self.vertices:
            vert_ob.append(bm.verts.new(vert))

        bm.verts.index_update()
        bm.verts.ensure_lookup_table()

        crease_layer = bm.edges.layers.crease.verify()
        for crease in creases:
            edge = bm.edges.new((bm.verts[crease[0]], bm.verts[crease[1]]))
            edge[crease_layer] = 1.0

        for face_index in self.faces:
            face = bm.faces.new(index_to_vert(face_index))
            face.smooth = True

        bm.faces.index_update()
        bm.edges.ensure_lookup_table()

        if with_uvs:
            uv_layer = bm.loops.layers.uv.verify()
            for (face, face_uvs) in zip(bm.faces, uvs):
                for (loop, uv) in zip(face.loops, face_uvs):
                    loop_uv = loop[uv_layer]
                    loop_uv.uv.x = uv[0]
                    loop_uv.uv.y = uv[1]

        bm.normal_update()

        # calculate auto smooth angle based on spine
        center = self.vertices[-1]
        side = self.vertices[-5]
        curl = abs(center[1] - side[1])
        width = abs(center[0] - side[0])
        spine_angle = atan(width / curl) * 2
        normal_angle = radians(180) - spine_angle + radians(1)  # add 1 deg to account for fp
        mesh.use_auto_smooth = True
        mesh.auto_smooth_angle = normal_angle

        if self.subsurf:
            self.obj.modifiers.new("Subdivision Surface", type='SUBSURF')
            self.obj.modifiers['Subdivision Surface'].levels = 1

        if self.cover_material:
            if self.obj.data.materials:
                self.obj.data.materials[0] = self.cover_material
            else:
                self.obj.data.materials.append(self.cover_material)

        if self.page_material:
            self.obj.data.materials.append(self.page_material)
            bm.faces.ensure_lookup_table()
            bm.faces[0].material_index = 1
            bm.faces[1].material_index = 1
            bm.faces[2].material_index = 1
            bm.faces[3].material_index = 1

        self.obj.matrix_world = Matrix.Translation(self.location) @ self.rotation.to_4x4()

        bm.to_mesh(mesh)
        bm.free()

        return self.obj

    def get_geometry(self):
        """
        Returns the raw geometry of a book
        """
        transformed_verts = map(lambda v: self.rotation @ Vector(v) + self.location, self.vertices)
        return transformed_verts, self.faces