Beispiel #1
0
    def __get_normalize_transform(self, active_view):
        centroid = active_view.center
        scale = active_view.scale

        normalize_transform = Transform.scale(Vector(scale, scale, scale)) *\
                Transform.translate(Vector(*(-1 * centroid)))
        return normalize_transform
Beispiel #2
0
    def __add_cone(self, shape):
        y_dir = np.array([0.0, 1.0, 0.0])
        v = shape.end_points[1] - shape.end_points[0]
        center = 0.5 * (shape.end_points[0] + shape.end_points[1])
        height = norm(v)
        scale = Transform.scale(Vector(shape.radius, height, shape.radius))
        axis = np.cross(y_dir, v)
        axis_len = norm(axis)
        angle = degrees(atan2(axis_len, np.dot(y_dir, v)))

        if (axis_len > 1e-6):
            axis /= axis_len
            rotate = Transform.rotate(Vector(*axis), angle)
        else:
            axis = np.array([1.0, 0.0, 0.0])
            rotate = Transform.rotate(Vector(*axis), angle)
        translate = Transform.translate(Vector(*center))

        cone_file = self.file_resolver.resolve("cone.ply")
        cone_transform = translate * rotate * scale
        setting = {
            "type": "ply",
            "filename": cone_file,
            "toWorld": cone_transform
        }
        return setting
Beispiel #3
0
    def __add_floor(self):
        rotate_transform = Transform.rotate(Vector(-1, 0, 0), 90)
        scale_transform = Transform.scale(Vector(100, 100, 100))
        translate_transform = Transform.translate(
            Vector(0.0, self.floor_height, 0.0))
        total_transform = translate_transform * scale_transform\
                * rotate_transform

        if self.scene.active_view.background == "d":
            reflectance = Spectrum(0.05)
        elif self.scene.active_view.background == "l":
            reflectance = Spectrum(0.5)
        else:
            reflectance = Spectrum(0.0)

        floor = self.plgr.create({
            "type": "rectangle",
            "toWorld": total_transform,
            "bsdf": {
                "type": "roughdiffuse",
                "diffuseReflectance": reflectance,
                "alpha": 0.5
            }
        })
        self.mitsuba_scene.addChild(floor)
Beispiel #4
0
            def transform_lookAt(self, origin, target, up, scale=None):
                # Blender is Z up but Mitsuba is Y up, convert the lookAt
                transform = Transform.lookAt(
                    Point(origin[0], origin[2], -origin[1]),
                    Point(target[0], target[2], -target[1]),
                    Vector(up[0], up[2], -up[1]))

                if scale is not None:
                    transform *= Transform.scale(Vector(scale, scale, 1))

                return transform
Beispiel #5
0
def axis_unit_vector(axis: str):
    """
    Create a unit vector along the given axis
    :param axis: 3D axis x, y, or z
    :return: A Vector of length one along the specified axis
    """
    if axis == 'x':
        return Vector(1, 0, 0)
    elif axis == 'y':
        return Vector(0, 1, 0)
    elif axis == 'z':
        return Vector(0, 0, 1)
    else:
        raise ValueError("Choose between x, y, and z")
Beispiel #6
0
 def getCameraAltitudeHeight(self, main_scene_xml_file_prifix, pos_x,
                             pos_z):
     currdir = os.path.split(os.path.realpath(__file__))[0]
     sys.path.append(currdir + '/bin/rt/' + current_rt_program +
                     '/python/2.7/')
     os.environ[
         'PATH'] = currdir + '/bin/rt/' + current_rt_program + os.pathsep + os.environ[
             'PATH']
     import mitsuba
     from mitsuba.core import Vector, Point, Ray, Thread
     from mitsuba.render import SceneHandler
     import platform
     scenepath = session.get_scenefile_path()
     fileResolver = Thread.getThread().getFileResolver()
     logger = Thread.getThread().getLogger()
     logger.clearAppenders()
     scenepath = scenepath.encode('utf-8')
     fileResolver.appendPath(scenepath)
     filepath = os.path.join(session.get_scenefile_path(),
                             main_scene_xml_file_prifix +
                             terr_scene_file).encode("utf-8")
     scene = SceneHandler.loadScene(fileResolver.resolve(filepath))
     scene.configure()
     scene.initialize()
     ray = Ray()
     ray.setOrigin(Point(pos_x, 999999999, pos_z))
     ray.setDirection(Vector(0, -1, 0))
     its = scene.rayIntersect(ray)
     if not its is None:
         return its.p[1]
     else:
         print("Camera is outside of the scene, do not use relative height")
         return 0
Beispiel #7
0
 def rayIntersect(self, o, xyz):
     origin = Point(self.X(o[0]), o[2], self.Y(o[1]))
     vector = Vector(-xyz[0], xyz[2], -xyz[1])
     ray = Ray()
     ray.setOrigin(origin)
     ray.setDirection(vector)
     its = self.scene.rayIntersect(ray)
     if its is None:
         return None
     else:
         itsp = its.p
         return self.X(itsp[0]), self.Y(itsp[2]), itsp[1]
Beispiel #8
0
    def __add_active_camera(self):
        active_view = self.scene.active_view
        camera = self.scene.active_camera
        if active_view.transparent_bg:
            pixel_format = "rgba"
        else:
            pixel_format = "rgb"

        crop_bbox = np.array(camera.crop_bbox)
        if np.amax(crop_bbox) <= 1.0:
            # bbox is relative.
            crop_bbox[:, 0] *= self.image_width
            crop_bbox[:, 1] *= self.image_height

        assert (np.all(crop_bbox >= 0))
        assert (np.all(crop_bbox[:, 0] <= self.image_width))
        assert (np.all(crop_bbox[:, 1] <= self.image_height))

        mitsuba_camera = self.plgr.create({
            "type":
            "perspective",
            "fov":
            float(camera.fovy),
            "fovAxis":
            "y",
            "toWorld":
            Transform.lookAt(Point(*camera.location),
                             Point(*camera.look_at_point),
                             Vector(*camera.up_direction)),
            "film": {
                "type": "ldrfilm",
                "width": self.image_width,
                "height": self.image_height,
                "cropOffsetX": int(crop_bbox[0, 0]),
                "cropOffsetY": int(crop_bbox[0, 1]),
                "cropWidth": int(crop_bbox[1, 0] - crop_bbox[0, 0]),
                "cropHeight": int(crop_bbox[1, 1] - crop_bbox[0, 1]),
                "banner": False,
                "pixelFormat": pixel_format,
                "rfilter": {
                    "type": "gaussian"
                }
            },
            "sampler": {
                "type": "halton",
                "sampleCount": 4,
            }
        })
        self.mitsuba_scene.addChild(mitsuba_camera)
Beispiel #9
0
def makeScene():

    scene = Scene()

    pmgr = PluginManager.getInstance()

    # make shapes
    for i in range(100):
        shapeProps = Properties("sphere")
        shapeProps["center"] = Point(i, i, i)
        shapeProps["radius"] = 0.1
        shape = pmgr.createObject(shapeProps)
        shape.configure()

        scene.addChild(shape)

    # make perspective sensor
    sensorProps = Properties("perspective")
    sensorProps["toWorld"] = Transform.lookAt(Point(0, 0, 10), Point(0, 0, 0),
                                              Vector(0, 1, 0))
    sensorProps["fov"] = 45.0

    sensor = pmgr.createObject(sensorProps)

    # make film
    filmProps = Properties("ldrfilm")
    filmProps["width"] = 640
    filmProps["height"] = 480

    film = pmgr.createObject(filmProps)
    film.configure()

    sensor.addChild("film", film)
    sensor.configure()

    scene.addChild(sensor)
    scene.configure()

    return scene
Beispiel #10
0
    def forest_generate_according_tree_pos_file_for3d(config_file_path):
        import mitsuba
        from mitsuba.core import Vector, Point, Ray, Thread
        from mitsuba.render import SceneHandler
        from mitsuba.render import RenderQueue, RenderJob
        from mitsuba.render import Scene
        from mitsuba.render import Intersection

        f = open(config_file_path, 'r')
        cfg = json.load(f)
        tree_pos = combine_file_path(session.get_input_dir(),
                                     cfg["scene"]["forest"]["tree_pos_file"])
        if cfg["scene"]["forest"]["tree_pos_file"] == "" or (
                not os.path.exists(tree_pos)):
            return

        # 读取地形数据 计算每个树的高程
        if cfg["scene"]["terrain"]["terrain_type"] != "PLANE" and cfg["scene"][
                "terrain"]["terrain_type"] == "RASTER":
            demfile = combine_file_path(session.get_input_dir(),
                                        cfg["scene"]["terrain"]["terr_file"])
            img_w, img_h, dem_arr = RasterHelper.read_dem_as_array(demfile)
            dem_arr = dem_arr - dem_arr.min()

        scenepath = session.get_scenefile_path()
        if "Windows" in platform.system():
            scenepath = str(scenepath.replace('\\', '\\\\'))
        # 得到高程信息 通过光线跟踪的方法精确得到高程信息
        fileResolver = Thread.getThread().getFileResolver()
        logger = Thread.getThread().getLogger()
        logger.clearAppenders()
        fileResolver.appendPath(scenepath)
        # 由于batch模式不会改变地形几何结构,因此在用地形打点计算树木的高程时,用第一个terrain文件即可,所以加上了_0_

        scene = SceneHandler.loadScene(
            fileResolver.resolve(str(terr_scene_file)))
        scene.configure()
        scene.initialize()
        tf = open(tree_pos)

        objectPosFile = open(
            os.path.join(session.get_input_dir(), "object_pos_3dView.txt"),
            'w')

        # 创建一个虚拟根节点,最后再删除
        for line in tf:
            arr = line.replace("\n", "").split(" ")
            objectName = arr[0]
            x = float(arr[1])
            y = float(arr[2])
            xScale = cfg["scene"]["terrain"]["extent_width"]
            zScale = cfg["scene"]["terrain"]["extent_height"]
            treeX = 0.5 * xScale - x
            treeZ = 0.5 * zScale - y
            if cfg["scene"]["terrain"]["terrain_type"] != "PLANE":
                ray = Ray()
                ray.setOrigin(Point(treeX, 9999, treeZ))
                ray.setDirection(Vector(0, -1, 0))
                its = scene.rayIntersect(ray)
                if not its is None:
                    linestr = objectName + " " + str(treeX) + " " + str(
                        its.p[1]) + " " + str(treeZ) + "\n"
                else:
                    # log("warning: precise height not found.")
                    if cfg["scene"]["terrain"]["terrain_type"] == "RASTER":
                        im_r = int((y / float(zScale)) * img_h)
                        im_c = int((x / float(xScale)) * img_w)
                        if im_r >= img_h:
                            im_r = img_h - 1
                        if im_c >= img_w:
                            im_c = img_w - 1
                        linestr = objectName + " " + str(treeX) + " " + str(
                            dem_arr[im_r][im_c]) + " " + str(treeZ) + "\n"
                    else:
                        linestr = objectName + " " + str(treeX) + " " + str(
                            0) + " " + str(treeZ) + "\n"
            else:
                linestr = objectName + " " + str(treeX) + " " + str(
                    0) + " " + str(treeZ) + "\n"
            objectPosFile.write(linestr)
        objectPosFile.close()
Beispiel #11
0
    def __add_quarter(self):
        scale = self.scene.active_view.scale
        radius = 12.13 * scale
        thickness = 0.875 * scale
        face_scale = Transform.scale(Vector(radius))
        tail_offset = Transform.translate(Vector(0, 0, thickness))
        head_offset = Transform.translate(Vector(0, 0, -thickness)) *\
                Transform.scale(Vector(1.0, 1.0, -1.0))

        bbox_diag = 0.5 * norm(self.transformed_bbox_max -
                               self.transformed_bbox_min)
        custom_transform = Transform.translate(
            Vector(0.5, self.floor_height + radius + 0.01, -bbox_diag - 0.01))

        head_texture = self.file_resolver.resolve("head.png")
        tail_texture = self.file_resolver.resolve("tail.png")
        side_texture = self.file_resolver.resolve("side.png")

        quarter_ring = self.plgr.create({
            "type": "cylinder",
            "p0": Point(0.0, 0.0, thickness),
            "p1": Point(0.0, 0.0, -thickness),
            "radius": radius,
            "toWorld": custom_transform,
            "bsdf": {
                "type": "bumpmap",
                "texture": {
                    "type": "scale",
                    "scale": 0.01,
                    "texture": {
                        "type": "bitmap",
                        "filename": side_texture,
                        "gamma": 1.0,
                        "uscale": 100.0,
                    },
                },
                "bsdf": {
                    "type": "roughconductor",
                    "distribution": "ggx",
                    "alpha": 0.5,
                    "material": "Ni_palik"
                    #"diffuseReflectance": Spectrum(0.5)
                }
            }
        })
        head = self.plgr.create({
            "type": "disk",
            "toWorld": custom_transform * head_offset * face_scale,
            "bsdf": {
                "type": "diffuse",
                "reflectance": {
                    "type": "bitmap",
                    "filename": head_texture
                }
            }
        })
        tail = self.plgr.create({
            "type": "disk",
            "toWorld": custom_transform * tail_offset * face_scale,
            "bsdf": {
                "type": "diffuse",
                "reflectance": {
                    "type": "bitmap",
                    "filename": tail_texture
                }
            }
        })

        self.mitsuba_scene.addChild(quarter_ring)
        self.mitsuba_scene.addChild(head)
        self.mitsuba_scene.addChild(tail)
Beispiel #12
0
    def forest_generate_according_tree_pos_file(config_file_path,
                                                forest_file_name,
                                                linestart,
                                                lineend,
                                                forest_prifix=""):
        import mitsuba
        from mitsuba.core import Vector, Point, Ray, Thread
        from mitsuba.render import SceneHandler
        from mitsuba.render import RenderQueue, RenderJob
        from mitsuba.render import Scene
        from mitsuba.render import Intersection

        f = open(config_file_path, 'r')
        cfg = json.load(f)
        tree_pos = combine_file_path(session.get_input_dir(),
                                     cfg["scene"]["forest"]["tree_pos_file"])
        if cfg["scene"]["forest"]["tree_pos_file"] == "" or (
                not os.path.exists(tree_pos)):
            return
        # 保存场景中树的位置 forest*.xml
        # f = open(os.path.join(session.get_scenefile_path(),forest_file_name),'w')
        f = codecs.open(
            os.path.join(session.get_scenefile_path(), forest_file_name), "w",
            "utf-8-sig")
        doc = minidom.Document()
        root = doc.createElement("scene")
        doc.appendChild(root)
        root.setAttribute("version", "0.5.0")

        #读取地形数据 计算每个树的高程
        if cfg["scene"]["terrain"]["terrain_type"] != "PLANE" and cfg["scene"][
                "terrain"]["terrain_type"] == "RASTER":
            demfile = combine_file_path(session.get_input_dir(),
                                        cfg["scene"]["terrain"]["terr_file"])
            img_w, img_h, dem_arr = RasterHelper.read_dem_as_array(demfile)
            dem_arr = dem_arr - dem_arr.min()

        #读取object boundingbox 数据
        bound_path = os.path.join(session.get_input_dir(),
                                  obj_bounding_box_file)
        if os.path.exists(bound_path):
            fobj = open(bound_path)
            bound_dict = dict()
            for line in fobj:
                arr = line.split(":")
                objName = arr[0]
                arr = list(map(lambda x: float(x), arr[1].split(" ")))
                bound_dict[objName] = [
                    arr[3] - arr[0], arr[4] - arr[1], arr[5] - arr[2]
                ]

        scenepath = session.get_scenefile_path()
        # if "Windows" in platform.system():
        #     scenepath = str(scenepath.replace('\\', '\\\\'))
        #得到高程信息 通过光线跟踪的方法精确得到高程信息
        fileResolver = Thread.getThread().getFileResolver()
        logger = Thread.getThread().getLogger()
        logger.clearAppenders()
        fileResolver.appendPath(str(scenepath))
        # 由于batch模式不会改变地形几何结构,因此在用地形打点计算树木的高程时,用第一个terrain文件即可,所以加上了_0_
        # if(forest_prifix != ""):
        #     forest_prifix = forest_prifix[0:len(forest_prifix)-1] +"_0_"
        scene = SceneHandler.loadScene(
            fileResolver.resolve(str(forest_prifix + terr_scene_file)))
        # scene = SceneHandler.loadScene(fileResolver.resolve(r"E:\Research\20-LESS\RealScene\SimProj\calLAI\Parameters\_scenefile\terrain1.xml"))
        scene.configure()
        scene.initialize()
        tf = open(tree_pos)

        hidden_objects = SceneGenerate.get_hidded_objects()

        #创建一个虚拟根节点,最后再删除
        treeIdx = 0
        for line in tf:
            if treeIdx >= linestart and treeIdx <= lineend:
                arr = line.replace("\n", "").strip().split(" ")
                objectName = arr[0]
                if objectName in hidden_objects:
                    continue

                shapenode = doc.createElement("shape")
                root.appendChild(shapenode)
                shapenode.setAttribute("type", "instance")
                refnode = doc.createElement("ref")
                shapenode.appendChild(refnode)
                refnode.setAttribute("id", objectName)
                trnode = doc.createElement("transform")
                shapenode.appendChild(trnode)
                trnode.setAttribute("name", "toWorld")
                if len(arr) == 6:  # fit with
                    scale_node = doc.createElement("scale")
                    trnode.appendChild(scale_node)
                    scale_node.setAttribute(
                        "x", str(float(arr[4]) / bound_dict[objectName][0]))
                    scale_node.setAttribute(
                        "z", str(float(arr[4]) / bound_dict[objectName][0]))
                    scale_node.setAttribute(
                        "y", str(float(arr[5]) / bound_dict[objectName][1]))

                if len(arr) == 5:  # for rotation of the tree
                    angle = arr[len(arr) - 1]
                    rotatenode = doc.createElement("rotate")
                    trnode.appendChild(rotatenode)
                    rotatenode.setAttribute("y", '1')
                    rotatenode.setAttribute("angle", angle)
                translatenode = doc.createElement("translate")
                trnode.appendChild(translatenode)
                x = float(arr[1])
                y = float(arr[2])
                z = float(arr[3])
                xScale = cfg["scene"]["terrain"]["extent_width"]
                zScale = cfg["scene"]["terrain"]["extent_height"]
                # treeX = xScale - x * (2 * xScale) / float(img_w)
                # treeZ = zScale - y * (2 * zScale) / float(img_h)
                treeX = 0.5 * xScale - x
                treeZ = 0.5 * zScale - y
                translatenode.setAttribute("x", str(treeX))
                translatenode.setAttribute("z", str(treeZ))
                if cfg["scene"]["terrain"]["terrain_type"] != "PLANE":
                    ray = Ray()
                    ray.setOrigin(Point(treeX, 9999, treeZ))
                    ray.setDirection(Vector(0, -1, 0))
                    its = scene.rayIntersect(ray)
                    if not its is None:
                        translatenode.setAttribute("y", str(its.p[1] + z))
                        # translatenode.setAttribute("y", str(z))
                    else:
                        # log("warning: precise height not found.")
                        if cfg["scene"]["terrain"]["terrain_type"] == "RASTER":
                            im_r = int((y / float(zScale)) * img_h)
                            im_c = int((x / float(xScale)) * img_w)
                            if im_r >= img_h:
                                im_r = img_h - 1
                            if im_c >= img_w:
                                im_c = img_w - 1

                            translatenode.setAttribute(
                                "y", str(dem_arr[im_r][im_c] + z))
                        else:
                            translatenode.setAttribute("y", str(z))
                else:
                    translatenode.setAttribute("y", str(z))

            treeIdx += 1

        xm = doc.toprettyxml()
        # xm = xm.replace('<?xml version="1.0" ?>', '')
        f.write(xm)
        f.close()

        log("INFO: Objects and positions generated.")
Beispiel #13
0
def do_simulation_multiangle_seq(seqname):
    currdir = os.path.split(os.path.realpath(__file__))[0]
    sys.path.append(currdir + '/bin/rt/' + current_rt_program + '/python/2.7/')
    os.environ['PATH'] = currdir + '/bin/rt/' + current_rt_program + os.pathsep + os.environ['PATH']
    import mitsuba
    from mitsuba.core import Vector, Point, Ray, Thread, Scheduler, LocalWorker, PluginManager, Transform
    from mitsuba.render import SceneHandler
    from mitsuba.render import RenderQueue, RenderJob
    from mitsuba.render import Scene
    import multiprocessing

    scheduler = Scheduler.getInstance()
    for i in range(0, multiprocessing.cpu_count()):
        scheduler.registerWorker(LocalWorker(i, 'wrk%i' % i))
    scheduler.start()


    scene_path = session.get_scenefile_path()
    fileResolver = Thread.getThread().getFileResolver()
    fileResolver.appendPath(str(scene_path))
    scene = SceneHandler.loadScene(fileResolver.resolve(
        str(os.path.join(session.get_scenefile_path(), main_scene_xml_file))))
    scene.configure()
    scene.initialize()
    queue = RenderQueue()
    sceneResID = scheduler.registerResource(scene)
    bsphere = scene.getKDTree().getAABB().getBSphere()
    radius = bsphere.radius
    targetx, targety, targetz = bsphere.center[0], bsphere.center[1], bsphere.center[2]
    f = open(seqname + ".conf", 'r')
    params = json.load(f)
    obs_azimuth = params['seq1']['obs_azimuth']
    obs_zenith = params['seq2']['obs_zenith']
    cfgfile = session.get_config_file()
    f = open(cfgfile, 'r')
    cfg = json.load(f)
    viewR = cfg["sensor"]["obs_R"]
    mode = cfg["sensor"]["film_type"]
    azi_arr = map(lambda x: float(x), obs_azimuth.strip().split(":")[1].split(","))
    zeni_arr = map(lambda x: float(x), obs_zenith.strip().split(":")[1].split(","))
    seq_header = multi_file_prefix + "_" + seqname
    index = 0
    for azi in azi_arr:
        for zeni in zeni_arr:
            distFile = os.path.join(session.get_output_dir(),
                                    seq_header + ("_VA_%.2f" % azi).replace(".", "_") + ("_VZ_%.2f" % zeni).replace(".", "_"))
            newScene = Scene(scene)
            pmgr = PluginManager.getInstance()
            newSensor = pmgr.createObject(scene.getSensor().getProperties())
            theta = zeni / 180.0 * math.pi
            phi = (azi - 90) / 180.0 * math.pi
            scale_x = radius
            scale_z = radius
            toWorld = Transform.lookAt(
                Point(targetx - viewR * math.sin(theta) * math.cos(phi), targety + viewR * math.cos(theta),
                      targetz - viewR * math.sin(theta) * math.sin(phi)),  # original
                Point(targetx, targety, targetz),  # target
                Vector(0, 0, 1)  # up
            ) * Transform.scale(
                Vector(scale_x, scale_z, 1)  # 视场大小
            )
            newSensor.setWorldTransform(toWorld)
            newFilm = pmgr.createObject(scene.getFilm().getProperties())
            newFilm.configure()
            newSensor.addChild(newFilm)
            newSensor.configure()
            newScene.addSensor(newSensor)
            newScene.setSensor(newSensor)
            newScene.setSampler(scene.getSampler())
            newScene.setDestinationFile(str(distFile))
            job = RenderJob('Simulation Job' + "VA_"+str(azi)+"_VZ_"+str(zeni), newScene, queue, sceneResID)
            job.start()
        queue.waitLeft(0)
        queue.join()
    # handle npy
    if mode == "spectrum" and (output_format not in ("npy", "NPY")):
        for azi in azi_arr:
            for zeni in zeni_arr:
                distFile = os.path.join(session.get_output_dir(),
                                        seq_header + ("_VA_%.2f" % azi).replace(".", "_") + ("_VZ_%.2f" % zeni).replace(
                                            ".", "_"))
                data = np.load(distFile + ".npy")
                bandlist = cfg["sensor"]["bands"].split(",")
                RasterHelper.saveToHdr_no_transform(data, distFile, bandlist, output_format)
                os.remove(distFile + ".npy")
Beispiel #14
0
 def vector(self, x, y, z):
     # Blender is Z up but Mitsuba is Y up, convert the vector
     return Vector(x, z, -y)