Пример #1
0
    def test_mtg():
        g = MTG()
        cs = mtg_to_cscene(g)
        assert cs == {}
        g.add_property('geometry')
        cs = mtg_to_cscene(g)
        assert cs == {}
        geom = g.property('geometry')
        geom[0] = pgl.Sphere()
        cs = mtg_to_cscene(g)
        assert len(cs) == 1
        assert len(cs.values()[0][0]) == 3
        assert len(cs.values()[0][0][0]) == 3

        return cs
    def test_mtg():
        g = MTG()
        cs = mtg_to_cscene(g)
        assert cs == {}
        g.add_property('geometry')
        cs = mtg_to_cscene(g)
        assert cs == {}
        geom = g.property('geometry')
        geom[0] = pgl.Sphere()
        cs = mtg_to_cscene(g)
        assert len(cs) == 1
        assert len(cs.values()[0][0]) == 3
        assert len(cs.values()[0][0][0]) == 3

        return cs
Пример #3
0
    def __init__(self, scene=None, light=None, pattern=None, opt=None,
                 soil_reflectance=None, soil_mesh=None, z_soil=None,
                 scene_unit='m'):
        """ Initialise a CaribuScene

        Args:
            scene (dict): a {primitive_id: [triangles,]} dict.A triangle is a
                    list of 3-tuples points coordinates
                    Alternatively, scene can be a *.can file or a mtg with
                    'geometry' property or a plantGL scene.
                    For the later case, shape.id are used as primitive_id.
            light (list): a list of (Energy, (vx, vy, vz)) tuples defining light
                    sources
                    Alternatively,  a *.light file
                    If None (default), a unit energy vertical light is used.
                    Energy unit should be given per square-meter (m-2)
            pattern (tuple): 2D Coordinates of the domain bounding the scene for
                    its replication.
                     (xmin, ymin, xmax, ymax) scene is not bounded along z axis.
                     Alternatively a *.8 file.
                     if None (default), scene is not repeated
            opt (dict): a {band_name: {primitive_id: material}} dict of dict
                        or a {band_name: material} dict of tuples.
                        In the second form the material is used for all primitives.
                    A material is a 1-, 2- or 4-tuple depending on its optical behavior.
                    A 1-tuple encode an opaque material characterised by its reflectance
                    A 2-tuple encode a symmetric translucent material defined
                    by a reflectance and a transmittance
                    A 4-tuple encode an asymmetric translucent material defined
                    the reflectance and transmittance
                    of the upper and lower side respectively
                    Alternatively, a list of band_name.opt files (require scene
                    to be given as a *.can file)
                    If None (default), all primitive are associated to the
                    default material of the class.
            soil_reflectance (dict): a {band_name: reflectance} dict.
                    If None (default) class default soil reflectance is used for all bands
                    If *.opt files are provided, the values in opt files are used in priority
            soil_mesh (int): a flag triggering for the creation of a soil mesh
            in the scene during computations
                    If None (default) or -1, no soil is added
                    If an int (n), a soil is added to the scene, with n subdivisions
            z_soil (float): the altitude of the soil.
                    If None (default), the soil is placed at the bottom of
                    the scene bounding box
            scene_unit (str): the unit of length used for scene coordinate
            and for pattern (should be one of class.units default)
                    By default, scene_unit is considered to be 'm' (meter).

        Returns:
            A CaribuScene instance

        Note:
            File format specifications (*.can, *.light, *.8, *.opt) can be found in data/CanestraDoc.pdf
        """

        if scene_unit not in self.units:
            raise ValueError('unrecognised scene unit: ' + scene_unit)
        self.conv_unit = self.units[scene_unit]

        self.scene = None
        if scene is not None:
            if isinstance(scene, dict):
                elt = scene[scene.keys()[0]]
                try:
                    assert isinstance(elt, list)
                    assert isinstance(elt[0], list)
                    assert isinstance(elt[0][0], tuple)
                except:
                    raise ValueError('Unrecognised scene format')
                self.scene = scene
            elif isinstance(scene, str):
                self.scene = read_can(scene)
            elif isinstance(scene, MTG):
                self.scene = mtg_to_cscene(scene)
            elif isinstance(scene, pglScene):
                self.scene = scene_to_cscene(scene)
            else:
                raise ValueError('Unrecognised scene format')

        self.light = [self.default_light]
        if light is not None:
            if isinstance(light, list):
                elt = light[0]
                try:
                    assert isinstance(elt, tuple)
                    assert isinstance(elt[1], tuple)
                except:
                    raise ValueError('Unrecognised light format')
                self.light = light
            elif isinstance(light, str):
                self.light = read_light(light)
            else:
                raise ValueError('Unrecognised light format')

        self.pattern = None
        if pattern is not None:
            if isinstance(pattern, tuple):
                if len(pattern) == 2:
                    pattern = sum(pattern, ())
                if len(pattern) != 4:
                    raise ValueError('Unrecognised pattern format')
                self.pattern = pattern
            elif isinstance(pattern, str):
                self.pattern = read_pattern(pattern)
            else:
                raise ValueError('Unrecognised pattern format')

        self.material = None
        if opt is None:
            if soil_reflectance is None:
                self.soil_reflectance = {
                    self.default_band: self.default_soil_reflectance}
                bands = [self.default_band]
            else:
                self.soil_reflectance = soil_reflectance
                bands = soil_reflectance.keys()
            if self.scene is not None:
                self.material = {}
                for band in bands:
                    self.material[band] = {pid: self.default_material for pid in
                                           self.scene}
        else:
            if isinstance(opt, list):
                if not isinstance(opt[0], str):
                    raise ValueError('Unrecognised opt format')
                if not isinstance(scene, str):
                    raise ValueError(
                        'un-compatible inputs types: opt file and scene not a can file')
                if self.scene is not None:
                    self.material = {}
                    self.soil_reflectance = {}
                    for path in opt:
                        band = os.path.basename(path).split('.')[0]
                        n, ro_soil, po = read_opt(path)
                        self.material[band] = build_materials(self.scene.keys(),
                                                              po, ro_soil)
                        self.soil_reflectance[band] = ro_soil
            elif isinstance(opt, dict):
                elt = opt[opt.keys()[0]]
                if not isinstance(elt, dict):
                    if isinstance(elt, tuple):
                        self.material = {}
                        if self.scene is not None:
                            for band in opt:
                                self.material[band] = {pid: opt[band] for pid in
                                                       self.scene}
                    else:
                        raise ValueError('Unrecognised opt format')
                else:
                    self.material = opt
                if soil_reflectance is None:
                    self.soil_reflectance = {band: self.default_soil_reflectance
                                             for band in self.material}
                else:
                    if isinstance(soil_reflectance, dict):
                        if not len(soil_reflectance) == len(opt):
                            raise ValueError(
                                'the number of bands for optical properties and soil reflectance should match')
                        self.soil_reflectance = soil_reflectance
                    else:
                        raise ValueError('Unrecognised soil_reflectance format')
            else:
                raise ValueError('Unrecognised opt format')

        self.soil = None
        if soil_mesh is not None:
            if soil_mesh != -1:
                if self.pattern is None:
                    raise ValueError(
                        'Adding a soil needs the scene domain to be defined')
                if z_soil is None:
                    if self.scene is None:
                        z_soil = 0
                    else:
                        triangles = reduce(lambda x, y: x + y,
                                           self.scene.values())
                        z = (pt[2] for tri in triangles for pt in tri)
                        z_soil = min(z)
                self.soil = domain_mesh(self.pattern, z_soil, soil_mesh)
Пример #4
0
    def __init__(self,
                 scene=None,
                 light=None,
                 pattern=None,
                 opt=None,
                 soil_reflectance=None,
                 soil_mesh=None,
                 z_soil=None,
                 scene_unit='m',
                 debug=False,
                 filecache=True):
        """ Initialise a CaribuScene

        Args:
            scene (dict): a {primitive_id: [triangles,]} dict.A triangle is a
                    list of 3-tuples points coordinates
                    Alternatively, scene can be a *.can file or a mtg with
                    'geometry' property or a plantGL scene.
                    For the later case, shape.id are used as primitive_id.
            light (list): a list of (Energy, (vx, vy, vz)) tuples defining light
                    sources
                    Alternatively,  a *.light file
                    If None (default), a unit energy vertical light is used.
                    Energy unit should be given per square-meter (m-2)
            pattern (tuple): 2D Coordinates of the domain bounding the scene for
                    its replication.
                     (xmin, ymin, xmax, ymax) scene is not bounded along z axis.
                     Alternatively a *.8 file.
                     if None (default), scene is not repeated
            opt (dict): a {band_name: {primitive_id: material}} dict of dict
                        or a {band_name: material} dict of tuples.
                        In the second form the material is used for all primitives.
                    A material is a 1-, 2- or 4-tuple depending on its optical behavior.
                    A 1-tuple encode an opaque material characterised by its reflectance
                    A 2-tuple encode a symmetric translucent material defined
                    by a reflectance and a transmittance
                    A 4-tuple encode an asymmetric translucent material defined
                    the reflectance and transmittance
                    of the upper and lower side respectively
                    Alternatively, a list of band_name.opt files (require scene
                    to be given as a *.can file)
                    If None (default), all primitive are associated to the
                    default material of the class.
            soil_reflectance (dict): a {band_name: reflectance} dict.
                    If None (default) class default soil reflectance is used for all bands
                    If *.opt files are provided, the values in opt files are used in priority
            soil_mesh (int): a flag triggering for the creation of a soil mesh
            in the scene during computations
                    If None (default) or -1, no soil is added
                    If an int (n), a soil is added to the scene, with n subdivisions
            z_soil (float): the altitude of the soil.
                    If None (default), the soil is placed at the bottom of
                    the scene bounding box
            scene_unit (str): the unit of length used for scene coordinate
            and for pattern (should be one of class.units default)
                    By default, scene_unit is considered to be 'm' (meter).

        Returns:
            A CaribuScene instance

        Note:
            File format specifications (*.can, *.light, *.8, *.opt) can be found in data/CanestraDoc.pdf
        """

        self.debug = debug

        if scene_unit not in self.units:
            raise ValueError('unrecognised scene unit: ' + scene_unit)
        self.conv_unit = self.units[scene_unit]

        self.scene = None
        if scene is not None:
            if isinstance(scene, dict):
                elt = scene[list(scene.keys())[0]]
                try:
                    assert isinstance(elt, list)
                    assert isinstance(elt[0], list)
                    assert isinstance(elt[0][0], tuple)
                except:
                    raise ValueError('Unrecognised scene format')
                self.scene = CaribuTriangleSet(scene)
            elif isinstance(scene, str):
                self.scene = CaribuTriangleSet(read_can(scene))
            elif isinstance(scene, MTG):
                self.scene = CaribuTriangleSet(mtg_to_cscene(scene))
            elif isinstance(scene, pglScene):
                self.scene = CaribuTriangleSet(scene_to_cscene(scene))
            elif isinstance(scene, AbstractCaribuTriangleSet):
                self.scene = scene
            else:
                raise ValueError('Unrecognised scene format')

        self.light = [self.default_light]
        if light is not None:
            self.setLight(light)

        self.pattern = None
        if pattern is not None:
            if isinstance(pattern, tuple):
                if len(pattern) == 2:
                    pattern = sum(pattern, ())
                if len(pattern) != 4:
                    raise ValueError('Unrecognised pattern format')
                self.pattern = pattern
            elif isinstance(pattern, str):
                self.pattern = read_pattern(pattern)
            else:
                raise ValueError('Unrecognised pattern format')

        self.material = None
        if opt is None:
            if soil_reflectance is None:
                self.soil_reflectance = {
                    self.default_band: self.default_soil_reflectance
                }
                bands = [self.default_band]
            else:
                self.soil_reflectance = soil_reflectance
                bands = list(soil_reflectance.keys())
            if self.scene is not None:
                self.material = {}
                for band in bands:
                    self.material[band] = {
                        pid: self.default_material
                        for pid in self.scene.keys()
                    }
        else:
            if isinstance(opt, list):
                if not isinstance(opt[0], str):
                    raise ValueError('Unrecognised opt format')
                if not isinstance(scene, str):
                    raise ValueError(
                        'un-compatible inputs types: opt file and scene not a can file'
                    )
                if self.scene is not None:
                    self.material = {}
                    self.soil_reflectance = {}
                    for path in opt:
                        band = os.path.basename(path).split('.')[0]
                        n, ro_soil, po = read_opt(path)
                        self.material[band] = build_materials(
                            list(self.scene.keys()), po, ro_soil)
                        self.soil_reflectance[band] = ro_soil
            elif isinstance(opt, dict):
                elt = opt[list(opt.keys())[0]]
                if not isinstance(elt, dict):
                    if isinstance(elt, tuple):
                        self.material = {}
                        if self.scene is not None:
                            for band in opt:
                                self.material[band] = {
                                    pid: opt[band]
                                    for pid in self.scene.keys()
                                }
                    else:
                        raise ValueError('Unrecognised opt format')
                else:
                    self.material = opt
                if soil_reflectance is None:
                    self.soil_reflectance = {
                        band: self.default_soil_reflectance
                        for band in self.material
                    }
                else:
                    if isinstance(soil_reflectance, dict):
                        if not len(soil_reflectance) == len(opt):
                            raise ValueError(
                                'the number of bands for optical properties and soil reflectance should match'
                            )
                        self.soil_reflectance = soil_reflectance
                    else:
                        raise ValueError(
                            'Unrecognised soil_reflectance format')
            else:
                raise ValueError('Unrecognised opt format')

        self.soil = None
        if soil_mesh is not None:
            if soil_mesh != -1:
                if self.pattern is None:
                    raise ValueError(
                        'Adding a soil needs the scene domain to be defined')
                if z_soil is None:
                    if self.scene is None:
                        z_soil = 0
                    else:
                        z_soil = self.scene.getZmin()
                self.soil = domain_mesh(self.pattern, z_soil, soil_mesh)

        self.tempdir = None
        if filecache:
            self.tempdir = tempfile.mkdtemp(
            ) if not debug else './caribuscene_' + str(id(self))
        self.canfile = None
        self.optfile = None