diff --git a/kibot/out_base.py b/kibot/out_base.py index 10215d80..837548a4 100644 --- a/kibot/out_base.py +++ b/kibot/out_base.py @@ -830,6 +830,52 @@ class VariantOptions(BaseOptions): for f in glob(board_name.replace('.kicad_pcb', '.*')): os.remove(f) + def solve_kf_filters(self, components): + """ Solves references to KiBot filters in the list of components to show. + They are not yet expanded, just solved to filter objects """ + new_list = [] + for c in components: + c_s = c.strip() + if c_s.startswith('_kf('): + # A reference to a KiBot filter + if c_s[-1] != ')': + raise KiPlotConfigurationError('Missing `)` in KiBot filter reference: `{}`'.format(c)) + filter_name = c_s[4:-1].strip().split(';') + logger.debug('Expanding KiBot filter in list of components: `{}`'.format(filter_name)) + filter = BaseFilter.solve_filter(filter_name, 'show_components') + if not filter: + raise KiPlotConfigurationError('Unknown filter in: `{}`'.format(c)) + new_list.append(filter) + self._filters_to_expand = True + else: + new_list.append(c) + return new_list + + def expand_kf_components(self, components): + """ Expands references to filters in show_components """ + if not components or not self._filters_to_expand: + return components + new_list = [] + if self._comps: + all_comps = self._comps + else: + load_sch() + all_comps = GS.sch.get_components() + get_board_comps_data(all_comps) + # Scan the list to show + for c in components: + if isinstance(c, str): + # A reference, just add it + new_list.append(c) + continue + # A filter, add its results + ext_list = [] + for ac in all_comps: + if c.filter(ac): + ext_list.append(ac.ref) + new_list += ext_list + return new_list + def run(self, output_dir): """ Makes the list of components available """ if not self.dnf_filter and not self.variant and not self.pre_transform: diff --git a/kibot/out_pcbdraw.py b/kibot/out_pcbdraw.py index 08761c97..36915b34 100644 --- a/kibot/out_pcbdraw.py +++ b/kibot/out_pcbdraw.py @@ -24,7 +24,6 @@ import subprocess from tempfile import NamedTemporaryFile # Here we import the whole module to make monkeypatch work from .error import KiPlotConfigurationError -from .fil_base import BaseFilter from .kiplot import load_sch, get_board_comps_data from .misc import (PCBDRAW_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, W_PCBDRAW) from .gs import GS @@ -293,7 +292,7 @@ class PcbDrawOptions(VariantOptions): if isinstance(self.highlight, type): self.highlight = None else: - self.highlight = self.solve_filters(self.highlight) + self.highlight = self.solve_kf_filters(self.highlight) # Margin if isinstance(self.margin, type): self.margin = (0, 0, 0, 0) @@ -344,27 +343,6 @@ class PcbDrawOptions(VariantOptions): self._expand_id = 'bottom' if self.bottom else 'top' self._expand_ext = self.format - def solve_filters(self, components): - """ Solves references to KiBot filters in the list of components to show. - They are not yet expanded, just solved to filter objects """ - new_list = [] - for c in components: - c_s = c.strip() - if c_s.startswith('_kf('): - # A reference to a KiBot filter - if c_s[-1] != ')': - raise KiPlotConfigurationError('Missing `)` in KiBot filter reference: `{}`'.format(c)) - filter_name = c_s[4:-1].strip().split(';') - logger.debug('Expanding KiBot filter in list of components: `{}`'.format(filter_name)) - filter = BaseFilter.solve_filter(filter_name, 'show_components') - if not filter: - raise KiPlotConfigurationError('Unknown filter in: `{}`'.format(c)) - new_list.append(filter) - self._filters_to_expand = True - else: - new_list.append(c) - return new_list - def expand_filtered_components(self, components): """ Expands references to filters in show_components """ if not components or not self._filters_to_expand: diff --git a/kibot/out_render_3d.py b/kibot/out_render_3d.py index 89c6c422..6dcdff28 100644 --- a/kibot/out_render_3d.py +++ b/kibot/out_render_3d.py @@ -141,6 +141,7 @@ class Render3DOptions(Base3DOptions): self._expand_ext = 'png' def config(self, parent): + self._filters_to_expand = False # Apply global defaults if GS.global_pcb_material is not None: material = GS.global_pcb_material.lower() @@ -186,18 +187,18 @@ class Render3DOptions(Base3DOptions): if isinstance(self.show_components, str): if self.show_components == 'all': self._show_all_components = True - self.show_components = set() + self.show_components = [] elif isinstance(self.show_components, type): # Default is all self._show_all_components = True else: # a list - self.show_components = set(self.show_components) + self.show_components = self.solve_kf_filters(self.show_components) self._expand_id += '_'+self._rviews.get(self.view) # highlight if isinstance(self.highlight, type): - self.highlight = set() + self.highlight = None else: - self.highlight = set(self.highlight) + self.highlight = self.solve_kf_filters(self.highlight) def add_step(self, cmd, steps, ops): if steps: @@ -256,9 +257,20 @@ class Render3DOptions(Base3DOptions): self._comps = GS.sch.get_components() get_board_comps_data(self._comps) # If the component isn't listed by the user make it DNF + show_components = set(self.expand_kf_components(self.show_components)) + self.undo_show = set() for c in self._comps: - if c.ref not in self.show_components: + if c.ref not in show_components and c.fitted: c.fitted = False + self.undo_show.add(c.ref) + + def undo_show_components(self): + if self._show_all_components: + # Don't change anything + return + for c in self._comps: + if c.ref in self.undo_show: + c.fitted = True def run(self, output): super().run(output) @@ -276,7 +288,8 @@ class Render3DOptions(Base3DOptions): self.add_options(cmd) # The board self.apply_show_components() - board_name = self.filter_components(highlight=self.highlight) + board_name = self.filter_components(highlight=set(self.expand_kf_components(self.highlight))) + self.undo_show_components() cmd.extend([board_name, os.path.dirname(output)]) cmd, video_remove = add_extra_options(cmd) # Execute it