From 659cad5de81cdb7a3490fb37c8b1a5a21e5fc0cd Mon Sep 17 00:00:00 2001
From: "Olivier J.N. Bertrand" <olivier.bertrand@uni-bielefeld.de>
Date: Wed, 30 May 2018 14:42:31 +0200
Subject: [PATCH] Create config file for BlenderRender This feature will be
 useful for easy trajectory rendering

---
 navipy/resources/configs/BlenderRender.yaml | 24 ++++---
 navipy/sensors/renderer.py                  | 77 +++++++++++++++++++--
 setup.py                                    |  8 ++-
 3 files changed, 88 insertions(+), 21 deletions(-)

diff --git a/navipy/resources/configs/BlenderRender.yaml b/navipy/resources/configs/BlenderRender.yaml
index bc2090a..fca41dc 100644
--- a/navipy/resources/configs/BlenderRender.yaml
+++ b/navipy/resources/configs/BlenderRender.yaml
@@ -3,15 +3,17 @@
 #
 
 BlenderRender:
+  # field of view of the camera
+  # elevation, two numbers [min, max]
+  # azimuth, two numbers [min, max]
   fov:
-  - min_elevation: -90
-  - max_elevation: 90
-  - min_azimuth: -180
-  - max_azimuth: 180
-  resolution:
-  - nbpx_azimtuh: 360
-  - nbpx_elevation: 180
-  gaussian:
-  - gaussian_width: 1.5
-  cycle:
-  - samples: 30
\ No newline at end of file
+    elevation: [-90,90]
+    azimuth: [-180, 180]
+  # Number of pixel along the azimuth, and elevation
+  resolution: [360, 180]
+  # Filter width for each pixel
+  gaussian_width: 1.5
+  # Number of rays (samples) used for redering
+  # Higher number give better results, but
+  # require more computation time. 
+  samples: 30
\ No newline at end of file
diff --git a/navipy/sensors/renderer.py b/navipy/sensors/renderer.py
index f1cb8b9..c480dc1 100644
--- a/navipy/sensors/renderer.py
+++ b/navipy/sensors/renderer.py
@@ -12,6 +12,8 @@ import numpy as np
 import tempfile
 import os
 import pandas as pd
+import yaml  # Used to load config files
+import pkg_resources
 from navipy.maths.homogeneous_transformations import compose_matrix
 import navipy.maths.constants as constants
 
@@ -34,6 +36,7 @@ class BlenderRender():
         # Rendering engine needs to be Cycles to support panoramic
         # equirectangular camera
         bpy.context.scene.render.engine = 'CYCLES'
+        # To get the distances we need to pass the z-buffer
         bpy.context.scene.render.layers["RenderLayer"].use_pass_z = True
         # Look for object camera
         camera_found = False
@@ -46,15 +49,11 @@ class BlenderRender():
         # The bee eye is panoramic, and with equirectangular projection
         self.camera.data.type = 'PANO'
         self.camera.data.cycles.panorama_type = 'EQUIRECTANGULAR'
-        # Filtering props
-        bpy.context.scene.cycles.filter_type = 'GAUSSIAN'
-        # Call all set function with default values
-        self.camera_fov = [[-90, 90], [-180, 180]]
-        self.camera_gaussian_width = 1.5
-        self.camera_resolution = [360, 180]
-        self.cycle_samples = 30
         # switch on nodes
         # Create render link to OutputFile with Image and Z buffer
+        # so that we can read the image from somewhere.
+        # This is a hack, because we did not manage to
+        # directly blender buffer...
         bpy.context.scene.use_nodes = True
         scene = bpy.context.scene
         nodes = scene.node_tree.nodes
@@ -75,6 +74,7 @@ class BlenderRender():
             render_layers.outputs['Image'],
             output_file.inputs['Image']
         )
+        # Z buffer has been renamed in Depth in newer versionW
         if bpy.app.version < (2, 79, 0):
             scene.node_tree.links.new(
                 render_layers.outputs['Z'],
@@ -87,6 +87,69 @@ class BlenderRender():
             )
         self.tmp_fileoutput = tmp_fileoutput
 
+        # Filtering props
+        bpy.context.scene.cycles.filter_type = 'GAUSSIAN'
+        self.config_file = pkg_resources.resource_filename(
+            'navipy', 'resources/configs/BlenderRender.yaml')
+
+    @property
+    def config_file(self):
+        return self.__config_file
+
+    @config_file.setter
+    def config_file(self, config_file):
+        if not isinstance(config_file, str):
+            raise TypeError('Config file should be a file path')
+        try:
+            with open(config_file, 'r') as stream:
+                try:
+                    config = yaml.load(stream)
+                except yaml.YAMLError as exc:
+                    print(exc)
+        except IOError:
+            print("The file could not be read")
+        if 'BlenderRender' not in config.keys():
+            raise KeyError(
+                'BlenderRender should be a section in the yaml config file')
+        blendconfig = config['BlenderRender']
+        # Loading the field of view in the camera
+        print(blendconfig)
+        print(blendconfig.keys())
+        if 'fov' in blendconfig.keys():
+            fov = np.zeros((2, 2))
+            if 'elevation' in blendconfig['fov'].keys():
+                fov[0, 0] = min(blendconfig['fov']['elevation'])
+                fov[0, 1] = max(blendconfig['fov']['elevation'])
+            else:
+                raise KeyError(
+                    'Yaml config file should contain fov/elevation key')
+            if 'azimuth' in blendconfig['fov'].keys():
+                fov[1, 0] = min(blendconfig['fov']['azimuth'])
+                fov[1, 1] = max(blendconfig['fov']['azimuth'])
+            else:
+                raise KeyError(
+                    'Yaml config file should contain fov/azimuth key')
+            self.camera_fov = fov
+        else:
+            raise KeyError('Yaml config file should contain fov')
+        # Loading the resolution ie number of pixel of the camera
+        if 'resolution' in blendconfig.keys():
+            self.camera_resolution = blendconfig['resolution']
+        else:
+            raise KeyError('Yaml config file should contain resolution')
+        # Load the filter of rendering
+        if 'gaussian_width' in blendconfig.keys():
+            self.camera_gaussian_width = blendconfig['gaussian_width']
+        else:
+            raise KeyError(
+                    'Yaml config file should contain gaussian_width')
+        # Load cycle for rendering
+        if 'samples' in blendconfig.keys():
+            self.camera_samples = blendconfig['samples']
+        else:
+            raise KeyError(
+                'Yaml config file should contain samples')
+
     @property
     def cycle_samples(self):
         """get the samples for rendering with cycle
diff --git a/setup.py b/setup.py
index ef697e0..46e6e66 100644
--- a/setup.py
+++ b/setup.py
@@ -33,7 +33,8 @@ setup_dict = {'name': 'navipy',
                            'matplotlib',
                            'scipy',
                            'networkx',
-                           'ipython'],
+                           'ipython',
+                           'yaml'],
               'install_requires': ["numpy",
                                    'pandas',
                                    'matplotlib',
@@ -43,11 +44,12 @@ setup_dict = {'name': 'navipy',
                                    'sphinx-argparse',
                                    'ipython',
                                    'flake8',
-                                   'tox'],
+                                   'tox',
+                                   'pyyaml'],
               'package_data': {'navipy':
                                ['resources/*.db',
                                 'resources/*.blend',
-                                'resources/confgis/*.yaml']},
+                                'resources/configs/*.yaml']},
               'include_package_data': True,
               'entry_points': {
                   'console_scripts': [
-- 
GitLab