diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f2cc1a9..486648f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `cache_3d_resistors` to avoid generating them all the time. - `resources_dir` to specify fonts and colors to install (CI/CD) - 3D: colored 3D models for THT resistors +- Blender export: + - Better default light + - More light options - Datasheet download: now the warnings mention which reference failed. - Plot related outputs and PCB_Print: - `individual_page_scaling`: to control if the center of the page is computed diff --git a/README.md b/README.md index 7e0e0cb0..763b490c 100644 --- a/README.md +++ b/README.md @@ -1661,17 +1661,19 @@ Notes: If none specified KiBot will create a suitable camera. If no position is specified for the camera KiBot will look for a suitable position. * Valid keys: - - `name`: [string=''] Name for the light. + - `name`: [string=''] Name for the camera. - `pos_x`: [number|string] X position [m]. You can use `width`, `height` and `size` for PCB dimensions. - `pos_y`: [number|string] Y position [m]. You can use `width`, `height` and `size` for PCB dimensions. - `pos_z`: [number|string] Z position [m]. You can use `width`, `height` and `size` for PCB dimensions. - `type`: [string='perspective'] [perspective,orthographic,panoramic] Type of camera. - `light`: [dict|list(dict)] Options for the light/s. * Valid keys: + - `energy`: [number=0] How powerful is the light. Using 0 for POINT and SUN KiBot will try to use something useful. - `name`: [string=''] Name for the light. - `pos_x`: [number|string] X position [m]. You can use `width`, `height` and `size` for PCB dimensions. - `pos_y`: [number|string] Y position [m]. You can use `width`, `height` and `size` for PCB dimensions. - `pos_z`: [number|string] Z position [m]. You can use `width`, `height` and `size` for PCB dimensions. + - `type`: [string='POINT'] [POINT, SUN, SPOT, HEMI, AREA] Type of light. SUN lights will illuminate more evenly. - `outputs`: [dict|list(dict)] Outputs to generate in the same run. * Valid keys: - **`type`**: [string='render'] [fbx,obj,x3d,gltf,stl,ply,blender,render] The format for the output. diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index 8a8f896c..c3439910 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -113,7 +113,7 @@ outputs: # If none specified KiBot will create a suitable camera. # If no position is specified for the camera KiBot will look for a suitable position camera: - # [string=''] Name for the light + # [string=''] Name for the camera name: '' # [number|string] X position [m]. You can use `width`, `height` and `size` for PCB dimensions pos_x: 0 @@ -125,14 +125,18 @@ outputs: type: 'perspective' # [dict|list(dict)] Options for the light/s light: - # [string=''] Name for the light - - name: '' + # [number=0] How powerful is the light. Using 0 for POINT and SUN KiBot will try to use something useful + - energy: 0 + # [string=''] Name for the light + name: '' # [number|string] X position [m]. You can use `width`, `height` and `size` for PCB dimensions pos_x: 0 # [number|string] Y position [m]. You can use `width`, `height` and `size` for PCB dimensions pos_y: 0 # [number|string] Z position [m]. You can use `width`, `height` and `size` for PCB dimensions pos_z: 0 + # [string='POINT'] [POINT, SUN, SPOT, HEMI, AREA] Type of light. SUN lights will illuminate more evenly + type: 'POINT' # [dict|list(dict)] Outputs to generate in the same run outputs: # [string='%f-%i%I%v.%x'] Name for the generated file (%i='3D_blender_$VIEW' %x=VARIABLE). diff --git a/kibot/optionable.py b/kibot/optionable.py index 30683e8d..5bbb3dc1 100644 --- a/kibot/optionable.py +++ b/kibot/optionable.py @@ -107,9 +107,9 @@ class Optionable(object): help, _, _ = self.get_doc(name) return help and help[0] == '*' - def add_to_doc(self, name, text): + def add_to_doc(self, name, text, with_nl=True): doc = getattr(self, '_help_'+name).strip() - setattr(self, '_help_'+name, doc+'.\n'+text) + setattr(self, '_help_'+name, doc+('.\n' if with_nl else '')+text) def set_doc(self, name, text): setattr(self, '_help_'+name, text) diff --git a/kibot/out_blender_export.py b/kibot/out_blender_export.py index 3e9aa3bd..7f0326db 100644 --- a/kibot/out_blender_export.py +++ b/kibot/out_blender_export.py @@ -82,13 +82,13 @@ class BlenderOutputOptions(Optionable): self._unknown_is_error = True -class BlenderLightOptions(Optionable): - """ A light in the scene. Currently also for the camera """ +class BlenderObjOptions(Optionable): + """ A light/camera in the scene. """ def __init__(self): super().__init__() with document: self.name = "" - """ Name for the light """ + """ Name for the """ self.pos_x = 0 """ [number|string] X position [m]. You can use `width`, `height` and `size` for PCB dimensions """ self.pos_y = 0 @@ -115,7 +115,38 @@ class BlenderLightOptions(Optionable): self.pos_z = self.solve('pos_z') -class BlenderCameraOptions(BlenderLightOptions): +class BlenderLightOptions(BlenderObjOptions): + """ A light in the scene. """ + def __init__(self): + super().__init__() + with document: + self.type = "POINT" + """ [POINT, SUN, SPOT, HEMI, AREA] Type of light. SUN lights will illuminate more evenly """ + self.energy = 0 + """ How powerful is the light. Using 0 for POINT and SUN KiBot will try to use something useful """ + self.add_to_doc('name', ' light', with_nl=False) + + def adjust(self): + self._width, self._height, self._size = get_board_size() + if not self.get_user_defined('pos_x') and not self.get_user_defined('pos_y') and not self.get_user_defined('pos_z'): + self.pos_x = -self._size*3.33 + self.pos_y = self._size*3.33 + self.pos_z = self._size*5.0 + if self.energy == 0: + if self.type == "POINT": + # 10 W is the default, works for 5 cm board, we make it grow cudratically + self.energy = 10.0*((self._size/0.05)**2) + elif self.type == "SUN": + # This is power by area + self.energy = 2 + + def config(self, parent): + super().config(parent) + self.adjust() + + +class BlenderCameraOptions(BlenderObjOptions): + """ A camera in the scene. """ CAM_TYPE = {'perspective': 'PERSP', 'orthographic': 'ORTHO', 'panoramic': 'PANO'} def __init__(self): @@ -123,6 +154,7 @@ class BlenderCameraOptions(BlenderLightOptions): with document: self.type = "perspective" """ [perspective,orthographic,panoramic] Type of camera """ + self.add_to_doc('name', ' camera', with_nl=False) def config(self, parent): super().config(parent) @@ -305,10 +337,7 @@ class Blender_ExportOptions(BaseOptions): # Create one light = BlenderLightOptions() light.name = 'kibot_light' - _, _, size = get_board_size() - light.pos_x = -size*3.33 - light.pos_y = size*3.33 - light.pos_z = size*5.0 + light.adjust() self.light = [light] else: # The dark ... @@ -489,7 +518,10 @@ class Blender_ExportOptions(BaseOptions): with NamedTemporaryFile(mode='w', suffix='.json') as f: scene = {} if self.light: - lights = [{'name': light.name, 'position': (light.pos_x, light.pos_y, light.pos_z)} for light in self.light] + lights = [{'name': light.name, + 'position': (light.pos_x, light.pos_y, light.pos_z), + 'type': light.type, + 'energy': light.energy} for light in self.light] scene['lights'] = lights if self.camera: ca = self.camera