def execute(self, context):
        """Import a :code:`Colmap` model/workspace."""
        path = self.directory
        # Remove trailing slash
        path = os.path.dirname(path)
        log_report("INFO", "path: " + str(path), self)

        self.image_dp = self.get_default_image_path(path, self.image_dp)
        cameras, points, mesh_ifp = ColmapFileHandler.parse_colmap_folder(
            path,
            self.use_workspace_images,
            self.image_dp,
            self.image_fp_type,
            self.suppress_distortion_warnings,
            self,
        )

        log_report("INFO", "Number cameras: " + str(len(cameras)), self)
        log_report("INFO", "Number points: " + str(len(points)), self)
        log_report("INFO", "Mesh file path: " + str(mesh_ifp), self)

        reconstruction_collection = add_collection("Reconstruction Collection")
        self.import_photogrammetry_cameras(cameras, reconstruction_collection)
        self.import_photogrammetry_points(points, reconstruction_collection)
        self.import_photogrammetry_mesh(mesh_ifp, reconstruction_collection)
        self.apply_general_options()

        return {"FINISHED"}
    def execute(self, context):
        """Import an :code:`MVE` workspace."""
        path = self.directory
        # Remove trailing slash
        path = os.path.dirname(path)
        log_report("INFO", "path: " + str(path), self)

        cameras, points = MVEFileHandler.parse_mve_workspace(
            path,
            self.default_width,
            self.default_height,
            self.add_depth_maps_as_point_cloud,
            self.suppress_distortion_warnings,
            self,
        )

        log_report("INFO", "Number cameras: " + str(len(cameras)), self)
        log_report("INFO", "Number points: " + str(len(points)), self)

        reconstruction_collection = add_collection("Reconstruction Collection")
        self.import_photogrammetry_cameras(cameras, reconstruction_collection)
        self.import_photogrammetry_points(points, reconstruction_collection)
        self.apply_general_options()

        return {"FINISHED"}
Esempio n. 3
0
    def execute(self, context):
        """Import an :code:`OpenMVG` :code:`JSON` file."""
        path = os.path.join(self.directory, self.filepath)
        log_report("INFO", "path: " + str(path), self)

        self.image_dp = self.get_default_image_path(path, self.image_dp)
        log_report("INFO", "image_dp: " + str(self.image_dp), self)

        cameras, points = OpenMVGJSONFileHandler.parse_openmvg_file(
            path,
            self.image_dp,
            self.image_fp_type,
            self.suppress_distortion_warnings,
            self,
        )

        log_report("INFO", "Number cameras: " + str(len(cameras)), self)
        log_report("INFO", "Number points: " + str(len(points)), self)

        reconstruction_collection = add_collection("Reconstruction Collection")
        self.import_photogrammetry_cameras(cameras, reconstruction_collection)
        self.import_photogrammetry_points(points, reconstruction_collection)
        self.apply_general_options()

        return {"FINISHED"}
def add_points_as_object_with_particle_system(
    points,
    reconstruction_collection,
    mesh_type="CUBE",
    point_extent=0.01,
    add_particle_color_emission=True,
    particle_overwrite_color=None,
    op=None,
):
    """Add a point cloud as particle system."""
    log_report("INFO", "Adding Points as Particle System: ...", op)
    stop_watch = StopWatch()

    # The particle systems in Blender do not work for large particle numbers
    # (see https://developer.blender.org/T81103). Thus, we represent large
    # point clouds with multiple smaller particle systems.
    max_number_particles = 10000

    particle_system_collection = add_collection("Particle System",
                                                reconstruction_collection)

    point_cloud_obj_list = []
    for i in range(0, len(points), max_number_particles):

        particle_obj_name = f"Particle Shape {i}"
        particle_material_name = f"Point Cloud Material {i}"
        point_cloud_obj_name = f"Particle Point Cloud {i}"

        points_subset = points[i:i + max_number_particles]
        coords, colors = Point.split_points(points_subset,
                                            normalize_colors=True)

        particle_obj = _add_particle_obj(
            colors,
            particle_obj_name,
            particle_material_name,
            particle_overwrite_color,
            add_particle_color_emission,
            mesh_type,
            point_extent,
            particle_system_collection,
        )
        point_cloud_obj = _add_particle_system_obj(
            coords,
            particle_obj,
            point_cloud_obj_name,
            particle_system_collection,
        )
        point_cloud_obj_list.append(point_cloud_obj)

    bpy.context.view_layer.update()

    log_report("INFO", "Duration: " + str(stop_watch.get_elapsed_time()), op)
    log_report("INFO", "Adding Points as Particle System: Done", op)
    return point_cloud_obj_list
    def execute(self, context):
        """Import a file with point data (e.g. :code:`PLY`)."""
        path = os.path.join(self.directory, self.filepath)
        log_report("INFO", "path: " + str(path), self)

        points = PointDataFileHandler.parse_point_data_file(path, self)
        log_report("INFO", "Number points: " + str(len(points)), self)

        reconstruction_collection = add_collection("Reconstruction Collection")
        self.import_photogrammetry_points(points, reconstruction_collection)
        self.apply_general_options()

        return {"FINISHED"}
Esempio n. 6
0
    def execute(self, context):
        """Import a :code:`Meshroom` file/workspace."""
        path = os.path.join(self.directory, self.filepath)
        log_report("INFO", "path: " + str(path), self)

        self.image_dp = self.get_default_image_path(path, self.image_dp)
        (
            cameras,
            points,
            mesh_fp,
            image_dp,
        ) = MeshroomFileHandler.parse_meshroom_file(
            path,
            self.use_workspace_images,
            self.image_dp,
            self.image_fp_type,
            self.suppress_distortion_warnings,
            self.sfm_node_type,
            self.sfm_node_number,
            self.mesh_node_type,
            self.mesh_node_number,
            self.prepare_node_number,
            self,
        )
        self.image_dp = image_dp
        log_report("INFO", "image_dp: " + str(self.image_dp), self)

        log_report("INFO", "Number cameras: " + str(len(cameras)), self)
        log_report("INFO", "Number points: " + str(len(points)), self)

        reconstruction_collection = add_collection("Reconstruction Collection")
        self.import_photogrammetry_cameras(cameras, reconstruction_collection)
        self.import_photogrammetry_points(points, reconstruction_collection)
        self.import_photogrammetry_mesh(mesh_fp, reconstruction_collection)
        self.apply_general_options()

        return {"FINISHED"}
def add_cameras(
    cameras,
    parent_collection,
    add_background_images=False,
    add_image_planes=False,
    add_depth_maps_as_point_cloud=True,
    convert_camera_coordinate_system=True,
    camera_collection_name="Cameras",
    image_plane_collection_name="Image Planes",
    depth_map_collection_name="Depth Maps",
    camera_scale=1.0,
    image_plane_transparency=0.5,
    add_image_plane_emission=True,
    use_default_depth_map_color=False,
    depth_map_default_color=(1.0, 0.0, 0.0),
    depth_map_display_sparsity=10,
    depth_map_id_or_name_str="",
    op=None,
):
    """Add a set of reconstructed cameras to Blender's 3D view port."""
    log_report("INFO", "Adding Cameras: ...", op)
    stop_watch = StopWatch()
    camera_collection = add_collection(camera_collection_name,
                                       parent_collection)

    if add_image_planes:
        log_report("INFO", "Adding image planes: True", op)
        image_planes_collection = add_collection(image_plane_collection_name,
                                                 parent_collection)
        camera_image_plane_pair_collection = add_collection(
            "Camera Image Plane Pair Collection", parent_collection)
    else:
        log_report("INFO", "Adding image planes: False", op)

    if add_depth_maps_as_point_cloud:
        log_report("INFO", "Adding depth maps as point cloud: True", op)
        depth_map_collection = add_collection(depth_map_collection_name,
                                              parent_collection)
        camera_depth_map_pair_collection = add_collection(
            "Camera Depth Map Pair Collection", parent_collection)
    else:
        log_report("INFO", "Adding depth maps as point cloud: False", op)

    depth_map_id_or_name_str = depth_map_id_or_name_str.rstrip()
    if depth_map_id_or_name_str == "":
        depth_map_indices = None
    else:
        depth_map_indices = []
        cam_rel_fp_to_idx = {}
        for idx, camera in enumerate(cameras):
            rel_fp = camera.get_relative_fp()
            cam_rel_fp_to_idx[rel_fp] = idx
        for id_or_name in depth_map_id_or_name_str.split(" "):
            if is_int(id_or_name):
                depth_map_indices.append(int(id_or_name))
            else:
                if id_or_name in cam_rel_fp_to_idx:
                    depth_map_indices.append(cam_rel_fp_to_idx[id_or_name])
                else:
                    log_report(
                        "WARNING",
                        "Could not find depth map name " + id_or_name + ". " +
                        "Possible values are: " +
                        str(cam_rel_fp_to_idx.keys()),
                        op,
                    )

    # Adding cameras and image planes:
    for index, camera in enumerate(cameras):

        # camera_name = "Camera %d" % index     # original code
        # Replace the camera name so it matches the image name (without extension)
        blender_image_name_stem = _get_camera_obj_gui_str(camera)
        camera_name = blender_image_name_stem + "_cam"
        camera_object = add_camera_object(camera, camera_name,
                                          camera_collection)
        camera_object.scale *= camera_scale

        if not add_image_planes and not add_background_images:
            continue

        if camera.has_undistorted_absolute_fp():
            image_path = camera.get_undistorted_absolute_fp()
        else:
            image_path = camera.get_absolute_fp()

        if not os.path.isfile(image_path):
            log_report("WARNING", "Could not find image at " + str(image_path),
                       op)
            continue
        else:
            log_report("INFO", "Found image at " + str(image_path), op)

        blender_image = bpy.data.images.load(image_path)

        if add_background_images:
            camera_data = bpy.data.objects[camera_name].data
            camera_data.show_background_images = True
            background_image = camera_data.background_images.new()
            background_image.image = blender_image

        if add_image_planes and not camera.is_panoramic():
            # Group image plane and camera:
            camera_image_plane_pair_collection_current = add_collection(
                "Camera Image Plane Pair Collection %s" %
                blender_image_name_stem,
                camera_image_plane_pair_collection,
            )

            image_plane_name = blender_image_name_stem + "_image_plane"

            image_plane_obj = add_camera_image_plane(
                matrix_world,
                blender_image,
                camera=camera,
                name=image_plane_name,
                transparency=image_plane_transparency,
                add_image_plane_emission=add_image_plane_emission,
                image_planes_collection=image_planes_collection,
                op=op,
            )

            camera_image_plane_pair_collection_current.objects.link(
                camera_object)
            camera_image_plane_pair_collection_current.objects.link(
                image_plane_obj)

        if not add_depth_maps_as_point_cloud:
            continue

        if camera.get_depth_map_fp() is None:
            continue

        if depth_map_indices is not None:
            if index not in depth_map_indices:
                continue

        # Group image plane and camera:
        camera_depth_map_pair_collection_current = add_collection(
            "Camera Depth Map Pair Collection %s" %
            os.path.basename(camera.get_depth_map_fp()),
            camera_depth_map_pair_collection,
        )

        depth_map_world_coords = camera.convert_depth_map_to_world_coords(
            depth_map_display_sparsity=depth_map_display_sparsity)

        if use_default_depth_map_color:
            color = depth_map_default_color
        else:
            color = _color_from_value(val=index,
                                      min_val=0,
                                      max_val=len(cameras))

        depth_map_anchor_handle = draw_coords(
            depth_map_world_coords,
            # TODO Setting this to true causes an error message
            add_points_to_point_cloud_handle=False,
            reconstruction_collection=depth_map_collection,
            object_anchor_handle_name=_get_camera_obj_gui_str(camera) +
            "_depth_point_cloud",
            color=color,
            op=op,
        )

        camera_depth_map_pair_collection_current.objects.link(camera_object)
        camera_depth_map_pair_collection_current.objects.link(
            depth_map_anchor_handle)

    log_report("INFO", "Duration: " + str(stop_watch.get_elapsed_time()), op)
    log_report("INFO", "Adding Cameras: Done", op)