def autoCrop(dummy):
    margin = bpy.context.scene.automatic_render_border_margin
    sc = bpy.context.scene
    sc.render.use_border = True
    x, y = [], []
    objetos = [bpy.context.visible_objects[:] if len(
        bpy.context.selected_objects) == 0 else
        bpy.context.selected_objects[:]]
    for ob in objetos[0]:
        if ob.type in ["MESH", "FONT", "CURVE", "META"] and ob.is_visible(sc):
            nmesh = ob.to_mesh(sc, True, "RENDER")
            for vert in nmesh.vertices:
                gl = ob.matrix_world * vert.co
                cc = world_to_camera_view(sc, sc.camera, gl)
                x.append(cc[0])
                y.append(cc[1])
            bpy.data.meshes.remove(nmesh)
        if ob.dupli_type == "GROUP" and ob.type == "EMPTY":
            for iob in ob.dupli_group.objects:
                if iob.type == "MESH" and ob.is_visible(sc):
                    nmesh = iob.to_mesh(sc, True, "RENDER")
                    for vert in nmesh.vertices:
                        gl = ob.matrix_world * iob.matrix_world * vert.co
                        cc = world_to_camera_view(sc, sc.camera, gl)
                        x.append(cc[0])
                        y.append(cc[1])
                    bpy.data.meshes.remove(nmesh)
    x.sort()
    y.sort()
    sc.render.border_min_x = x[0] - margin
    sc.render.border_max_x = x[-1] + margin
    sc.render.border_min_y = y[0] - margin
    sc.render.border_max_y = y[-1] + margin
    del x
    del y
Ejemplo n.º 2
0
    def coords_within_image(self, coords):

        scene = bpy.context.scene
        scene.update()
        cs, ce = self.camera.data.clip_start, self.camera.data.clip_end

        object_names = [obj.name for obj in list(bpy.data.objects)]
        random_objects = []
        image_coords = []

        for name in object_names:

            if 'random' == name[:6]:
                obj = bpy.data.objects[name]
                mat_world = obj.matrix_world
                verts = (mat_world * vert.co for vert in obj.data.vertices)
                coords_2d = [
                    world_to_camera_view(scene, self.camera, coord)
                    for coord in verts
                ]
                image_coords.append(coords_2d)
                random_objects.append(obj)

        def random_object_is_blocking(obj_coords, limit_coord):

            for co in obj_coords:
                if np.abs(co.x - limit_coord.x) < 0.01 and np.abs(
                        co.y - limit_coord.y) < 0.01 and co.z < limit_coord.z:
                    return True
            return False

        for idx, coord in enumerate(coords):
            coord = mathutils.Vector(coord)
            co_ndc = world_to_camera_view(scene, self.camera, coord)

            if not ((0.0 < co_ndc.x < 1.0 and 0.0 < co_ndc.y < 1.0
                     and cs < co_ndc.z < ce)):

                return False

            update_objects = []
            update_image_coords = []
            for i in range(len(image_coords)):

                if random_object_is_blocking(image_coords[i], co_ndc):
                    obstacle = random_objects[i]
                    print('POP', obstacle.name)
                    bpy.data.objects.remove(obstacle)
                else:
                    update_objects.append(random_objects[i])
                    update_image_coords.append(image_coords[i])
            random_objects = update_objects
            image_coords = update_image_coords

        return True
Ejemplo n.º 3
0
def get_normal_from_points(sc, obj, p1, p2):
    '''Given two points, return their 2d normal vector in camera view.'''
    cam = sc.camera
    rp = sc.render.resolution_percentage / 100.0
    p1_cam = world_to_camera_view(sc, cam, p1)
    p2_cam = world_to_camera_view(sc, cam, p2)

    normal = (p2_cam - p1_cam).xy
    normal.x *= sc.render.resolution_x * rp
    normal.y *= sc.render.resolution_y * rp
    normal = normal.normalized()
    return normal
def compute_camera_size(context, center, fill_mode, aspect):
    """Determine how large an object needs to be to fit or fill the camera's field of view."""
    scene = context.scene
    camera = scene.camera
    view_frame = camera.data.view_frame(scene=scene)
    frame_size = \
        Vector([max(v[i] for v in view_frame) for i in range(3)]) - \
        Vector([min(v[i] for v in view_frame) for i in range(3)])
    camera_aspect = frame_size.x / frame_size.y

    # Convert the frame size to the correct sizing at a given distance
    if camera.type == 'ORTHO':
        frame_size = frame_size.xy
    else:
        # Perspective transform
        distance = world_to_camera_view(scene, camera, center).z
        frame_size = distance * frame_size.xy / (-view_frame[0].z)

    # Determine what axis to match to the camera
    match_axis = 0  # match the Y axis size
    match_aspect = aspect
    if (fill_mode == 'FILL' and aspect > camera_aspect) or \
            (fill_mode == 'FIT' and aspect < camera_aspect):
        match_axis = 1  # match the X axis size
        match_aspect = 1.0 / aspect

    # scale the other axis to the correct aspect
    frame_size[1 - match_axis] = frame_size[match_axis] / match_aspect

    return frame_size
Ejemplo n.º 5
0
def obj_bounding_rect(scene, cam, obj):
    # use generator expressions () or list comprehensions []
    # Had problem with negative y-coord - added obj.matrix_world from
    # https://www.reddit.com/r/blender/comments/4s8k3f/help_with_finding_whether_a_vertex_is_visible/

    obj_mat_world = obj.matrix_world
    verts = (obj_mat_world * vert.co for vert in obj.data.vertices)
    coords_2d = [world_to_camera_view(scene, cam, coord) for coord in verts]

    # 2d data printout:
    # rnd = lambda i: round(i)
    # for x, y, distance_to_lens in coords_2d:
    #     print("{},{}".format(rnd(res_x*x), rnd(res_y*y)))

    x0 = coords_2d[0].x
    y0 = coords_2d[0].y
    x1 = x0
    y1 = y0

    # print('x,y')
    for x, y, distance_to_lens in coords_2d:
        if (x < x0): x0 = x
        if (y < y0): y0 = y
        if (x > x1): x1 = x
        if (y > y1): y1 = y

    return x0, y0, x1, y1
def find_plane_corner(object_name, x, y, axis, camera=None, *args, **kwargs):
    """Find the location in camera space of a plane's corner"""
    if args or kwargs:
        # I've added args / kwargs as a compatibility measure with future versions
        warnings.warn("Unknown Parameters Passed to \"Images as Planes\".  Maybe you need to upgrade?")

    plane = bpy.data.objects[object_name]

    # Passing in camera doesn't work before 2.78, so we use the current one
    camera = camera or bpy.context.scene.camera

    # Hack to ensure compositor updates on future changes
    register_watched_object(camera)
    register_watched_object(plane)

    scale = plane.scale * 2.0
    v = plane.dimensions.copy()
    v.x *= x / scale.x
    v.y *= y / scale.y
    v = plane.matrix_world @ v

    camera_vertex = world_to_camera_view(
        bpy.context.scene, camera, v)

    return camera_vertex[axis]
Ejemplo n.º 7
0
def project_keypoints_onto_image(keypoints, scene, obj, camera):
    """Converts 3D keypoints of an object into their corresponding 2D coordinates on the image.

    This function takes a list of keypoints represented as 3D coordinates in object space, and then projects them
    onto the camera to get their corresponding 2D coordinates on the image. It uses the current location and
    orientation of the input Blender objects. Typical usage would be to call this function after
    `Frame.setup <starfish.Frame.setup>` and then store the 2D locations as metadata for that frame::

        frame.setup(scene, obj, camera, sun)
        frame.keypoints = project_keypoints_onto_image(keypoints, scene, obj, camera)
        with open('meta...', 'w') as f:
            f.write(frame.dumps())

    :param keypoints: a list of 3D coordinates corresponding to the locations of the keypoints in the object space, e.g.
        the output of `generate_keypoints <starfish.annotation.generate_keypoints>`
    :param scene: (BlendDataObject): the scene to use for aspect ratio calculations. Note that this should be the
        scene that you intend to perform the final render in, not necessarily the one that your objects exist in. If
        you render in a scene that has an output resolution with a different aspect ratio than the output
        resolution of this scene, then the results may be incorrect.
    :param obj: (BlendDataObject): the object to use
    :param camera: (BlendDataObject): the camera to use

    :return: a list of (y, x) coordinates in the same order as ``keypoints`` where (0, 0) is the top left corner of
        the image and (1, 1) is the bottom right
    """
    from bpy_extras.object_utils import world_to_camera_view
    results = []
    for keypoint in keypoints:
        camera_coord = world_to_camera_view(
            scene, camera, obj.matrix_world @ Vector(keypoint))
        results.append((1 - camera_coord.y, camera_coord.x))
    return results
Ejemplo n.º 8
0
 def visible_face_from_vertex(
         vertex: bpy.types.MeshVertex, scene: bpy.types.Scene,
         mesh_object: bpy.types.Object) -> bpy.types.MeshPolygon:
     """Convert the vertex's coordinates into camera space, and check
     whether its coordinates are within the frustum. Then cast a ray at it
     to see whether it's occluded."""
     cam = scene.camera
     cc = world_to_camera_view(scene, cam,
                               mesh_object.matrix_world @ vertex.co)
     cs = cam.data.clip_start
     ce = cam.data.clip_end
     # If the vertex's screen coordinates are within camera view
     if 0.0 < cc.x < 1.0 and 0.0 < cc.y < 1.0 and cs < cc.z < ce:
         # Convert the screen coordinates to a 3D vector
         frame = cam.data.view_frame(scene=scene)
         top_left = frame[3]
         pixel_vector = Vector((cc.x, cc.y, top_left[2]))
         pixel_vector.rotate(cam.matrix_world.to_quaternion())
         # Convert to target object space
         wmatrix_inv = mesh_object.matrix_world.inverted()
         origin = wmatrix_inv @ (pixel_vector +
                                 cam.matrix_world.translation)
         # Destination is the original vertex, in the same object space
         destination = wmatrix_inv @ vertex.co
         direction = (destination - origin).normalized()
         # Cast a ray from those screen coordinates to the vertex
         result, location, normal, index = mesh_object.ray_cast(
             origin, direction)
         if result and index > -1:
             # Return the face the vertex belongs to
             return mesh_object.data.polygons[index]
     return False
Ejemplo n.º 9
0
def make_flattened(bm_output, flattened_name):
    #remap to flat plane for oscistudio to see
    global cam
    global vamp_scale

    res_y = bpy.context.scene.render.resolution_y
    res_x = bpy.context.scene.render.resolution_x
    cam_x_scale = res_x / 500
    cam_y_scale = res_y / 500

    vamp_scale = bpy.context.scene.vamp_params.vamp_scale
    # determine location based on xy cam scale
    flat_loc = Vector(
        (-0.5 * cam_x_scale * vamp_scale, -0.5 * cam_y_scale * vamp_scale, 0))
    # first, make flatSliced
    flat_sliced = bpy.data.objects[flattened_name]
    mat_world = flat_sliced.matrix_world

    # use bm_output, remap vertices
    FlatVerts = []
    for v in bm_output.verts:
        co_ndc = world_to_camera_view(scene, cam, v.co)
        v.co.x = co_ndc[0] * cam_x_scale * vamp_scale
        v.co.y = co_ndc[1] * cam_y_scale * vamp_scale
        v.co.z = 0
    bm_output.to_mesh(flat_sliced.data)
    flat_sliced.location = flat_loc
    layer = bpy.context.view_layer
    layer.update()
    return {'FINISHED'}
Ejemplo n.º 10
0
def DefRenderOnlyInCamera():
    # crea grupos
    if "INCAMERA" not in bpy.data.groups:
        bpy.data.groups.new("INCAMERA")
    if "NOTINCAMERA" not in bpy.data.groups:
        bpy.data.groups.new("NOTINCAMERA")

    # limpio grupos
    for ob in bpy.data.objects:
        if ob.name in bpy.data.groups["INCAMERA"].objects:
            bpy.data.groups["INCAMERA"].objects.unlink(ob)
        if ob.name in bpy.data.groups["NOTINCAMERA"].objects:
            bpy.data.groups["NOTINCAMERA"].objects.unlink(ob)

    # ordeno grupos
    for ob in bpy.data.objects:
        obs = False
        if ob.type == "MESH":
            tm = ob.to_mesh(bpy.context.scene, True, "RENDER")
            for vert in tm.vertices:
                cam = world_to_camera_view(
                    bpy.context.scene,
                    bpy.context.scene.camera,
                    vert.co + ob.location)
                if cam[0] >= -0 and cam[0] <= 1 and cam[1] >= 0 and cam[1] <= 1:
                    obs = True
            del(tm)
        else:
            obs = True
        if obs:
            bpy.data.groups["INCAMERA"].objects.link(ob)
        else:
            bpy.data.groups["NOTINCAMERA"].objects.link(ob)
Ejemplo n.º 11
0
def getVisibleVertices(obj, cam, scene):
    # In world coordinates, get a bvh tree and vertices
    bvh, vertices = BVHTreeAndVerticesInWorldFromObj(obj)
    visible_vertices = []

    for i, v in enumerate(vertices):
        #print("vertex #")
        #print(i)
        # Get the 2D projection of the vertex
        co2D = world_to_camera_view(scene, cam, v)
        #print(co2D)
        #print("\n")

        # By default, deselect it
        obj.data.vertices[i].select = False

        # If inside the camera view
        if 0.0 <= co2D.x <= 1.0 and 0.0 <= co2D.y <= 1.0:
            #print(i,"this vertex is inside camera view")
            # Try a ray cast, in order to test the vertex visibility from the camera
            location, normal, index, distance = bvh.ray_cast(
                cam.location, (v - cam.location).normalized())
            #print("cam.location, (v - cam.location).normalized() , location, normal, index, distance")
            #print(cam.location, (v - cam.location).normalized() , location, normal, index, distance)
            # If the ray hits something and if this hit is close to the vertex, we assume this is the vertex
            if location and (v - location).length < limit:
                obj.data.vertices[i].select = True
                #print("selected vertex is:", i)
                #print(getCoords(obj.data.vertices[i]))
            visible_vertices.append([v.x, v.y, v.z])
        #print("\n\n")
    print("#verts:", NUMVERTS, " #visible vertices:", len(visible_vertices))
    del bvh
    print("visible vertices:", visible_vertices)
    return visible_vertices
Ejemplo n.º 12
0
 def get_render_location(self, context, coord):
     scene = context.scene
     co_2d = object_utils.world_to_camera_view(scene, scene.camera, coord)
     # Get pixel coords
     render_scale = scene.render.resolution_percentage / 100
     render_size = (int(scene.render.resolution_x * render_scale),
                    int(scene.render.resolution_y * render_scale))
     return [round(co_2d.x * render_size[0]), round(co_2d.y * render_size[1])]
Ejemplo n.º 13
0
def get_z(shape):
    global z_map
    global scene
    z = z_map.get(shape.id.first)
    if z == None:
        o = bpy.data.objects[shape.name]
        z = world_to_camera_view(scene, scene.camera, o.location)[2]
        z_map[shape.id.first] = z
    return z
Ejemplo n.º 14
0
def get_z(shape):
    global z_map
    global scene
    z = z_map.get(shape.id.first)
    if z == None:
        o = bpy.data.objects[shape.name]
        z = world_to_camera_view(scene, scene.camera, o.location)[2]
        z_map[shape.id.first] = z
    return z
Ejemplo n.º 15
0
 def get_z_curve(self, curve, func=GetShapeF1D()):
     shape = func(curve)[0]
     # get the shapes z-index
     z = self.z_map.get(shape.id.first)
     if z is None:
         o = bpy.data.objects[shape.name]
         z = world_to_camera_view(self.scene, self.scene.camera, o.location).z
         self.z_map[shape.id.first] = z
     return z
Ejemplo n.º 16
0
def get_render_location(mypoint):

    v1 = mathutils.Vector(mypoint)
    scene = bpy.context.scene
    co_2d = object_utils.world_to_camera_view(scene, scene.camera, v1)
    # Get pixel coords
    render_scale = scene.render.resolution_percentage / 100
    render_size = (int(scene.render.resolution_x * render_scale), int(scene.render.resolution_y * render_scale))

    return [round(co_2d.x * render_size[0]), round(co_2d.y * render_size[1])]
Ejemplo n.º 17
0
def helper_getBB2D(scene, cam, obj):
    bb3d = obj.bound_box
    bb3d_list = [mathutils.Vector(p) for p in bb3d]
    coords_2d = [
        object_utils.world_to_camera_view(scene, cam, obj.matrix_world @ p)
        for p in bb3d_list
    ]
    xx = [p.x for p in coords_2d]
    yy = [p.y for p in coords_2d]
    return (min(xx), min(yy), max(xx), max(yy))
Ejemplo n.º 18
0
def coordinate_within_image(coord):
    coord = mathutils.Vector(coord)
    scene = bpy.context.scene
    cam = bpy.data.objects['Camera']
    cs, ce = cam.data.clip_start, cam.data.clip_end
    co_ndc = world_to_camera_view(scene, cam, coord)
    within_image = False
    if (0.0 < co_ndc.x < 1.0 and
        0.0 < co_ndc.y < 1.0):
        within_image = True
    return within_image
Ejemplo n.º 19
0
def helper_mkJsonBB2D(scene, cam, obj):
    bb3d = obj.objectPtr.bound_box
    bb3d_list = [mathutils.Vector(p) for p in bb3d]
    coords_2d = [
        object_utils.world_to_camera_view(scene, cam,
                                          obj.objectPtr.matrix_world @ p)
        for p in bb3d_list
    ]
    xx = [p.x for p in coords_2d]
    yy = [p.y for p in coords_2d]
    jsonData = {"x1": min(xx), "y1": min(yy), "x2": max(xx), "y2": max(yy)}
    return jsonData
Ejemplo n.º 20
0
def animate_render_border(scene):
    
    scene = bpy.context.scene
    camera = scene.camera
    border = scene.animated_render_border
    
    if border.enable and camera.type == "CAMERA":
        #If object is chosen but consequently renamed, it can't be tracked.
        if border.type == "Object" and border.object != "" and border.object in bpy.data.objects or \
           border.type == "Group" and border.group != "" and border.group in bpy.data.groups: 
        
            objs = [] 
            if border.type == "Object":  
                objs = [border.object]
            elif border.type == "Group":
                objs = (object.name for object in bpy.data.groups[border.group].objects if object.type =="MESH")
            
            coords_2d = []
            for obj in objs:
                
                verts = []
                if border.use_bounding_box:
                    verts = (Vector(corner) for corner in bpy.data.objects[obj].bound_box)
                else:
                    verts = (vert.co for vert in bpy.data.objects[obj].data.vertices)
                        
                wm = bpy.data.objects[obj].matrix_world     #Vertices will be in local space unless multiplied by the world matrix
                for coord in verts:
                    coords_2d.append(world_to_camera_view(scene, camera, wm*coord))

            minX = 1
            maxX = 0
            minY = 1
            maxY = 0

            for x, y, distance_to_lens in coords_2d:
                
                if x<minX:
                    minX = x
                if x>maxX:
                    maxX = x
                if y<minY:
                    minY = y
                if y>maxY:
                    maxY = y                 
                    
            margin = border.margin
                
            scene.render.border_min_x = minX - (margin/100)
            scene.render.border_max_x = maxX + (margin/100)
            scene.render.border_min_y = minY - (margin/100)
            scene.render.border_max_y = maxY + (margin/100)
def location_in_camera_view(camera, location):
    scene = bpy.context.scene

    cs, ce = camera.data.clip_start, camera.data.clip_end

    in_view = False

    co_ndc = world_to_camera_view(scene, camera, location)
    in_view = (0.0 < co_ndc.x < 1.0 and 0.0 < co_ndc.y < 1.0 and cs < co_ndc.z <  ce)
    
    #print("Center view: " + str(in_view) + " with loc: " + str(obj.location) + " and camera rel position: " + str(Vector((co_ndc.x, co_ndc.y, co_ndc.z))))

    return in_view
Ejemplo n.º 22
0
def depth_to_camera(obj, camera):
    dg = bpy.context.evaluated_depsgraph_get()
    lq = obj.evaluated_get(dg)
    ng = bpy.context.evaluated_depsgraph_get()
    cq = camera.evaluated_get(ng)
    mat = lq.matrix_world
    min_z = 1000
    max_z = -1
    for v in lq.data.vertices:
        co_ndc = world_to_camera_view(bpy.context.scene, cq, mat @ v.co)
        max_z = max(max_z, co_ndc.z)
        min_z = min(min_z, co_ndc.z)
    return min_z, max_z
Ejemplo n.º 23
0
def export(context):
    '''Create export data and write to file.'''
    sc = context.scene
    cam = sc.camera
    hqz_params = context.scene.hqz_parameters
    rp = sc.render.resolution_percentage / 100.0

    if hqz_params.animation:
        start_frame = sc.frame_start
        frame_range = range(sc.frame_start, sc.frame_end + 1)
    else:
        start_frame = sc.frame_current
        frame_range = (start_frame,)

    if hqz_params.batch:
        write_batch_script(hqz_params, frame_range)

    for frame in frame_range:
        print('Exporting frame', frame)

        export_data = {}

        if hqz_params.animation:
            sc.frame_set(frame)

        export_data['resolution'] = [
            int(sc.render.resolution_x * rp),
            int(sc.render.resolution_y * rp)]
        export_data['viewport'] = [
            0, 0,
            sc.render.resolution_x * rp,
            sc.render.resolution_y * rp]
        export_data['exposure'] = hqz_params.exposure
        export_data['gamma'] = hqz_params.gamma
        export_data['rays'] = hqz_params.rays
        if hqz_params.time != 0.0:
            export_data['timelimit'] = hqz_params.time
        export_data['seed'] = hqz_params.seed

        # LIGHTS
        export_data['lights'] = []
        for lamp in sc.objects:
            if lamp.type == 'LAMP' and lamp.is_visible(sc):
                lamp_obstacle = False

                if not lamp_obstacle:
                    light = []
                    use_spectral = lamp.data.hqz_lamp.use_spectral_light
                    spectral_start = lamp.data.hqz_lamp.spectral_start
                    spectral_end = lamp.data.hqz_lamp.spectral_end
                    wav = color_to_wavelength(lamp.data.color)
                    lamp_loc = lamp.matrix_world.to_translation()
                    x, y, z = world_to_camera_view(
                        sc, cam,
                        lamp_loc)
                    x *= sc.render.resolution_x * rp
                    y *= sc.render.resolution_y * rp

                    # Check that lamp is not behind camera
                    if z > 0:
                        y = sc.render.resolution_y * rp - y
                        light.append(lamp.data.energy)
                        light.append(x)
                        light.append(y)
                        if lamp.data.type == 'SPOT':
                            lamp_angle = get_object_rot(sc, lamp)
                            lamp_size = degrees(lamp.data.spot_size) / 2.0
                            lamp_min = (lamp_angle - lamp_size)
                            lamp_max = (lamp_angle + lamp_size)
                            light.append([lamp_min, lamp_max])
                        else:
                            light.append([0, 360])
                        light_start = (
                            lamp.data.hqz_lamp.light_start
                            * (sc.render.resolution_y * rp))
                        light_end = (
                            lamp.data.hqz_lamp.light_end
                            * (sc.render.resolution_y * rp))
                        light.append([light_start,
                                      light_end])
                        if lamp.data.type == 'SPOT':
                            light.append([lamp_min, lamp_max])
                        else:
                            light.append([0, 360])
                        if use_spectral:
                            light.append([spectral_start, spectral_end])
                        else:
                            light.append(wav)
                    export_data['lights'].append(light)

        export_data['objects'] = []

        # get Blender edge list
        edge_list = []
        for obj in sc.objects:
            if obj.type == 'MESH' and obj.is_visible(sc):
                mesh = bpy.data.meshes.new_from_object(
                    sc, obj, apply_modifiers=True, settings='PREVIEW')
                for edge in mesh.edges:
                    if edge.use_freestyle_mark:
                        continue
                    edgev = {}
                    vertices = list(edge.vertices)
                    edgev["material"] = obj.hqz_material_id
                    v1 = obj.matrix_world * mesh.vertices[vertices[0]].co
                    v2 = obj.matrix_world * mesh.vertices[vertices[1]].co
                    v1_cam = world_to_camera_view(
                        sc, cam, v1)
                    v2_cam = world_to_camera_view(
                        sc, cam, v2)
                    edgev["v1"] = v1_cam
                    edgev["v2"] = v2_cam
                    if hqz_params.normals_export:
                        v1_normal_offset = (
                            v1 + obj.matrix_world
                            * mesh.vertices[vertices[0]].normal
                            )
                        v2_normal_offset = (
                            v2 + obj.matrix_world
                            * mesh.vertices[vertices[1]].normal
                            )
                        n1 = get_normal_from_points(sc, obj, v1, v1_normal_offset)
                        n1_angle = degrees(Vector((1.0, 0.0)).angle_signed(n1))
                        n2 = get_normal_from_points(sc, obj, v2, v2_normal_offset)
                        n2_angle = degrees(n1.angle_signed(n2))
                        if hqz_params.normals_invert:
                            n1_angle += 180
                            n2_angle += 180
                        edgev["n1"] = n1_angle
                        edgev["n2"] = n2_angle

                    edge_list.append(edgev)
                bpy.data.meshes.remove(mesh)

        # OBJECTS
        for edge in edge_list:
            # if check_inside(
            #         context,
            #         edge["v1"].x * sc.render.resolution_x * rp,
            #         edge["v1"].y * sc.render.resolution_y * rp
            #         ):
            edge_data = []
            # MATERIAL
            edge_data.append(edge["material"])
            # VERT1 XPOS
            edge_data.append(
                edge["v1"].x
                * sc.render.resolution_x * rp)
            # VERT1 YPOS
            edge_data.append(
                (1 - edge["v1"].y) * sc.render.resolution_y * rp)
            # VERT1 NORMAL
            if hqz_params.normals_export:
                edge_data.append(edge["n1"])
            # VERT2 DELTA XPOS
            edge_data.append(
                (edge["v2"].x - edge["v1"].x)
                * sc.render.resolution_x * rp
            )
            # VERT2 DELTA YPOS
            edge_data.append(
                (edge["v1"].y - edge["v2"].y)
                * sc.render.resolution_y * rp
            )
            # VERT2 NORMAL
            if hqz_params.normals_export:
                edge_data.append(edge["n2"])

            export_data['objects'].append(edge_data)

        # Materials
        export_data['materials'] = []
        for material in hqz_params.materials:
            mat_data = []
            mat_data.append([material.diffuse, "d"])
            mat_data.append([material.transmission, "t"])
            mat_data.append([material.specular, "r"])
            export_data['materials'].append(mat_data)

        save_path = hqz_params.directory + hqz_params.file + '_' + str(frame).zfill(4) + '.json'

        d = os.path.dirname(save_path)
        os.makedirs(d, exist_ok=True)

        file = open(save_path, 'w')
        file.write(json.dumps(
            export_data, indent=None if hqz_params.debug else 2, sort_keys=True))
        file.close()
Ejemplo n.º 24
0
def export(self, context):
    '''Create export data and write to file.'''
    sc = context.scene
    cam = sc.camera
    hqz_params = context.scene.hqz_parameters
    rp = sc.render.resolution_percentage / 100.0

    if not hqz_params.hqz_bin_path:
        self.report({'WARNING'}, 'Please select hqz binary.')
    if not hqz_params.export_filepath:
        self.report({'ERROR'}, 'Please choose export file name.')
        return {'CANCELLED'}
    if cam is None:
        self.report({'ERROR'}, 'No camera found in scene.')
        return {'CANCELLED'}

    if hqz_params.animation:
        start_frame = sc.frame_start
        frame_range = range(sc.frame_start, sc.frame_end + 1)
    else:
        start_frame = sc.frame_current
        frame_range = (start_frame,)

    export_dir = os.path.dirname(
        bpy.path.abspath(hqz_params.export_filepath)
    )

    os.makedirs(export_dir, exist_ok=True)

    if hqz_params.render_script_path:
        write_render_script(export_dir, hqz_params, frame_range)

    export_data = {}

    for frame in frame_range:
        print('Exporting frame', frame)

        if hqz_params.animation:
            sc.frame_set(frame)

        # SETTINGS
        export_data['resolution'] = [
            int(sc.render.resolution_x * rp),
            int(sc.render.resolution_y * rp)]
        export_data['viewport'] = [
            0, 0,
            sc.render.resolution_x * rp,
            sc.render.resolution_y * rp]
        export_data['exposure'] = hqz_params.exposure
        export_data['gamma'] = hqz_params.gamma
        export_data['rays'] = hqz_params.rays
        if hqz_params.time != 0.0:
            export_data['timelimit'] = hqz_params.time
        export_data['seed'] = hqz_params.seed

        # LIGHTS
        export_data['lights'] = []
        for lamp in sc.objects:
            if lamp.type == 'LAMP' and lamp.is_visible(sc):
                lamp_obstacle = False

                if not lamp_obstacle:
                    hqz_light = []
                    use_spectral = lamp.data.hqz_lamp.use_spectral_light
                    spectral_start = lamp.data.hqz_lamp.spectral_start
                    spectral_end = lamp.data.hqz_lamp.spectral_end
                    wav = color_to_wavelength(lamp.data.color)
                    lamp_loc = lamp.matrix_world.to_translation()
                    x, y, z = world_to_camera_view(
                        sc, cam,
                        lamp_loc)
                    x *= sc.render.resolution_x * rp
                    y *= sc.render.resolution_y * rp

                    if z > 0:  # Check that lamp is not behind camera
                        y = sc.render.resolution_y * rp - y
                        hqz_light.append(lamp.data.energy)
                        hqz_light.append(x)
                        hqz_light.append(y)
                        if lamp.data.type == 'SPOT':
                            lamp_angle = get_object_rot(sc, lamp)
                            lamp_size = degrees(lamp.data.spot_size) / 2.0
                            lamp_min = (lamp_angle - lamp_size)
                            lamp_max = (lamp_angle + lamp_size)
                            hqz_light.append([lamp_min, lamp_max])
                        else:
                            hqz_light.append([0, 360])
                        light_start = (
                            lamp.data.hqz_lamp.light_start
                            * (sc.render.resolution_y * rp))
                        light_end = (
                            lamp.data.hqz_lamp.light_end
                            * (sc.render.resolution_y * rp))
                        hqz_light.append([light_start,
                                          light_end])
                        if lamp.data.type == 'SPOT':
                            hqz_light.append([lamp_min, lamp_max])
                        else:
                            hqz_light.append([0, 360])
                        if use_spectral:
                            hqz_light.append([spectral_start, spectral_end])
                        else:
                            hqz_light.append(wav)
                    export_data['lights'].append(hqz_light)

        export_data['objects'] = []

        # OBJECTS
        for obj in sc.objects:
            if (
                    obj.type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}
                    and obj.is_visible(sc)
                    ):
                mesh = bpy.data.meshes.new_from_object(
                    sc, obj, apply_modifiers=True, settings='PREVIEW')
                for edge in mesh.edges:
                    if edge.use_freestyle_mark:
                        continue
                    edge_data = []
                    vertices = list(edge.vertices)
                    # MATERIAL
                    edge_data.append(obj.hqz_material_id)
                    v1 = obj.matrix_world * mesh.vertices[vertices[0]].co
                    v2 = obj.matrix_world * mesh.vertices[vertices[1]].co
                    v1_cam = world_to_camera_view(
                        sc, cam, v1)
                    v2_cam = world_to_camera_view(
                        sc, cam, v2)
                    # VERT1 XPOS
                    edge_data.append(
                        v1_cam.x * sc.render.resolution_x * rp)
                    # VERT1 YPOS
                    edge_data.append(
                        (1 - v1_cam.y) * sc.render.resolution_y * rp)
                    # VERT2 DELTA XPOS
                    edge_data.append(
                        (v2_cam.x - v1_cam.x)
                        * sc.render.resolution_x * rp
                    )
                    # VERT2 DELTA YPOS
                    edge_data.append(
                        (v1_cam.y - v2_cam.y)
                        * sc.render.resolution_y * rp
                    )
                    if hqz_params.normals_export:
                        v1_normal_offset = (
                            obj.matrix_world
                            * (mesh.vertices[vertices[0]].co
                               + mesh.vertices[vertices[0]].normal)
                            )
                        v2_normal_offset = (
                            obj.matrix_world
                            * (mesh.vertices[vertices[1]].co
                               + mesh.vertices[vertices[1]].normal)
                            )
                        n1 = get_normal_from_points(
                            sc, obj, v1, v1_normal_offset)
                        n2 = get_normal_from_points(
                            sc, obj, v2, v2_normal_offset)
                        if n1.length_squared and n2.length_squared:
                            # Do not export normals if parallel to camera axis
                            n1_angle = degrees(Vector((1.0, 0.0)).angle_signed(n1))
                            n2_angle = degrees(n1.angle_signed(n2))
                            if hqz_params.normals_invert:
                                n1_angle += 180
                            # VERT1 NORMAL
                            edge_data.insert(3, n1_angle)
                            # VERT2 NORMAL
                            edge_data.append(n2_angle)

                    export_data['objects'].append(edge_data)
                bpy.data.meshes.remove(mesh)

        # Materials
        export_data['materials'] = []
        for material in hqz_params.materials:
            mat_data = []
            mat_data.append([material.diffuse, "d"])
            mat_data.append([material.transmission, "t"])
            mat_data.append([material.specular, "r"])
            export_data['materials'].append(mat_data)

        save_path = (hqz_params.export_filepath
                     + '.' + str(frame).zfill(4)
                     + '.json')

        d = os.path.dirname(save_path)
        os.makedirs(d, exist_ok=True)

        file = open(save_path, 'w')
        file.write(json.dumps(
                              export_data,
                              indent=None if hqz_params.debug else 2,
                              sort_keys=True)
                   )
        file.close()
    return {'FINISHED'}
Ejemplo n.º 25
0
def animated_render_border(scene):
        
    scene = bpy.context.scene
    camera = scene.camera
    border = scene.animated_render_border
    
    cameraExists = False
    
    if camera:
        if camera.type == "CAMERA":
            cameraExists = True
    
    if border.enable and cameraExists:
        #If object is chosen but consequently renamed, it can't be tracked.
        if validObject() or validGroup(): 
        
            objs = [] 
            if border.type == "Object":  
                objs = [bpy.data.objects[border.object]]
            elif border.type == "Group":
                objs = (object for object in bpy.data.groups[border.group].objects if object.type in trackableObjectTypes) #Type of objects that can be tracked
            
            coords_2d = []
            for obj in objs:
                
                verts = []
                if border.use_bounding_box or obj.type in noVertexObjectTypes: #Objects that have no vertices
                    
                    #Lattices and Armatures can't use bounding box in pre 2.76 version of blender.
                    if bpy.app.version < (2, 76, 0) and obj.type in ["ARMATURE","LATTICE"]:
                    
                        if obj.type == "LATTICE":
                            
                            verts = (vert.co_deform for vert in obj.data.points)
                            
                        elif obj.type == "ARMATURE":
                            
                            if border.bone == "":
                        
                                verts = (chain.from_iterable((bone.head, bone.tail) for bone in obj.pose.bones))
                        
                            else:
                                
                                bone = bpy.data.objects[border.object].pose.bones[border.bone]
                                verts = [bone.head, bone.tail]                                                   
                        
                    else:
                        
                        verts = (Vector(corner) for corner in obj.bound_box)
                
                elif obj.type == "MESH":

                    verts = (vert.co for vert in obj.data.vertices)
                
                elif obj.type == "CURVE":
                    
                    verts = (vert.co for spline in obj.data.splines for vert in spline.bezier_points)
                
                elif obj.type == "SURFACE":
                    
                    verts = (vert.co for spline in obj.data.splines for vert in spline.points)
                    
                elif obj.type == "LATTICE":
                           
                    verts = (vert.co_deform for vert in obj.data.points)
                        
                elif obj.type == "ARMATURE":

                    if border.bone == "":
                        
                        verts = (chain.from_iterable((bone.head, bone.tail) for bone in obj.pose.bones))
                        
                    else:
                        
                        bone = bpy.data.objects[border.object].pose.bones[border.bone]
                        verts = [bone.head, bone.tail]
                        
                wm = obj.matrix_world     #Vertices will be in local space unless multiplied by the world matrix
                for coord in verts:
                    coords_2d.append(world_to_camera_view(scene, camera, wm*coord))
            
            #If a group is empty there will be no coordinates
            if len(coords_2d) > 0:
                
                minX = 1
                maxX = 0
                minY = 1
                maxY = 0
                
                for x, y, distance_to_lens in coords_2d:
                                    
                    #Points behind camera will have negative coordinates, this makes them positive                
                    if distance_to_lens<0:
                        y = y *-1
                        x = x *-1               
                    
                    if x<minX:
                        minX = x
                    if x>maxX:
                        maxX = x
                    if y<minY:
                        minY = y
                    if y>maxY:
                        maxY = y
                                            
                margin = border.margin/100
                
                #Haven't worked out why I'm multiplying 'shift_x' and 'shift_y' by 2
                if scene.render.resolution_x > scene.render.resolution_y:
                        
                    aspectRatio = 2 * (scene.render.resolution_x / scene.render.resolution_y) * (scene.render.pixel_aspect_x / scene.render.pixel_aspect_y) 
                    
                    cameraShiftX = scene.camera.data.shift_x * 2
                    cameraShiftY = scene.camera.data.shift_y * aspectRatio
                    
                else:
                    
                    aspectRatio = 2 * (scene.render.resolution_y / scene.render.resolution_x) * (scene.render.pixel_aspect_y / scene.render.pixel_aspect_x) 
                    
                    cameraShiftX = scene.camera.data.shift_x*aspectRatio
                    cameraShiftY = scene.camera.data.shift_y*2
                    
                
                scene.render.border_min_x = (minX - margin) - cameraShiftX
                scene.render.border_max_x = (maxX + margin) - cameraShiftX
                scene.render.border_min_y = (minY - margin) - cameraShiftY
                scene.render.border_max_y = (maxY + margin) - cameraShiftY
            
        elif border.type == "Keyframe":
            
            scene.render.border_min_x = border.border_min_x
            scene.render.border_max_x = border.border_max_x
            scene.render.border_min_y = border.border_min_y
            scene.render.border_max_y = border.border_max_y