From e00841c92135823d70e8ba99c747fbca3a919668 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Wed, 20 Apr 2022 10:39:19 -0300 Subject: [PATCH] Added two special syntaxis to the 3D model variants - %_kicost.TEXT:SLOTS% matches using the KiCost variant regex - %_default_:SLOTS% matches if no other text matched Related to #191 --- README.md | 7 ++++- docs/README.in | 7 ++++- kibot/out_base_3d.py | 66 +++++++++++++++++++++++++++++--------------- 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 9a607e55..83fb7793 100644 --- a/README.md +++ b/README.md @@ -652,11 +652,16 @@ Here are both variants: Some important notes: - If you want to control what models are used when no variant is used you'll need to create a `default` variant. - This what the above example does. In this case the `default` variant shows all the connectors, but no display. + This is what the above example does. In this case the `default` variant shows all the connectors, but no display. + Note that changing the 3D model needs the variants infrastructure. +- If you are using variants and a lot of them select the same slots you can add special text: `%_default_:SLOTS%`. + This will be used if none %VARIANT_NAME:SLOT%` matched. - If you want to disable a model and avoid any kind of warning add `_Disabled_by_KiBot` to the 3D model path. This could be needed if you want to remove some model and you don't want to adjust the slot numbers. - This mechanism can be used with any of the available variants. For this reason we use the `VARIANT_NAME` and we avoid relying on any variant specific mechanism. +- If you are using KiCost variants and you want to match the regex against the text you can use the following syntax: + `%_kicost.TEXT:SLOTS%`. #### DNF and DNC internal keys diff --git a/docs/README.in b/docs/README.in index 85a35a1a..9b5943e2 100644 --- a/docs/README.in +++ b/docs/README.in @@ -445,11 +445,16 @@ Here are both variants: Some important notes: - If you want to control what models are used when no variant is used you'll need to create a `default` variant. - This what the above example does. In this case the `default` variant shows all the connectors, but no display. + This is what the above example does. In this case the `default` variant shows all the connectors, but no display. + Note that changing the 3D model needs the variants infrastructure. +- If you are using variants and a lot of them select the same slots you can add special text: `%_default_:SLOTS%`. + This will be used if none %VARIANT_NAME:SLOT%` matched. - If you want to disable a model and avoid any kind of warning add `_Disabled_by_KiBot` to the 3D model path. This could be needed if you want to remove some model and you don't want to adjust the slot numbers. - This mechanism can be used with any of the available variants. For this reason we use the `VARIANT_NAME` and we avoid relying on any variant specific mechanism. +- If you are using KiCost variants and you want to match the regex against the text you can use the following syntax: + `%_kicost.TEXT:SLOTS%`. #### DNF and DNC internal keys diff --git a/kibot/out_base_3d.py b/kibot/out_base_3d.py index 7464c016..ff16a1f6 100644 --- a/kibot/out_base_3d.py +++ b/kibot/out_base_3d.py @@ -180,18 +180,45 @@ class Base3DOptions(VariantOptions): models.add(full_name) return list(models) + def apply_list_of_models(self, enable, slots, m, var): + # Disable the unused models adding bogus text to the end + slots = [int(v) for v in slots] + models = m.Models() + m_objs = [] + # Extract the models, we get a copy + while not models.empty(): + m_objs.insert(0, models.pop()) + for i, m3d in enumerate(m_objs): + if self.extra_debug: + logger.debug('- {} {} {} {}'.format(var, i+1, i+1 in slots, m3d.m_Filename)) + if i+1 not in slots: + if enable: + # Revert the added text + m3d.m_Filename = m3d.m_Filename[:-self.len_disable] + else: + # Not used, add text to make their name invalid + m3d.m_Filename += DISABLE_TEXT + # Push it back to the module + models.push_back(m3d) + def apply_variant_aspect(self, enable=False): """ Disable/Enable the 3D models that aren't for this variant. This mechanism uses the MTEXT attributes. """ # The magic text is %variant:slot1,slot2...% field_regex = re.compile(r'\%([^:]+):(.*)\%') - extra_debug = GS.debug_level > 3 + self.extra_debug = extra_debug = GS.debug_level > 3 if extra_debug: logger.debug("{} 3D models that aren't for this variant".format('Enable' if enable else 'Disable')) - len_disable = len(DISABLE_TEXT) + self.len_disable = len(DISABLE_TEXT) + variant_name = self.variant.name + var_re = None + if self.variant.type == 'kicost' and self.variant.variant: + var_re = re.compile(self.variant.variant, flags=re.IGNORECASE) for m in GS.get_modules(): if extra_debug: logger.debug("Processing module " + m.GetReference()) + default = None + matched = False # Look for text objects for gi in m.GraphicalItems(): if gi.GetClass() == 'MTEXT': @@ -202,26 +229,21 @@ class Base3DOptions(VariantOptions): # Check if this is for the current variant var = match.group(1) slots = match.group(2).split(',') if match.group(2) else [] - if var == self.variant.name: - # Disable the unused models adding bogus text to the end - slots = [int(v) for v in slots] - models = m.Models() - m_objs = [] - # Extract the models, we get a copy - while not models.empty(): - m_objs.insert(0, models.pop()) - for i, m3d in enumerate(m_objs): - if extra_debug: - logger.debug('- {} {} {}'.format(i+1, i+1 in slots, m3d.m_Filename)) - if i+1 not in slots: - if enable: - # Revert the added text - m3d.m_Filename = m3d.m_Filename[:-len_disable] - else: - # Not used, add text to make their name invalid - m3d.m_Filename += DISABLE_TEXT - # Push it back to the module - models.push_back(m3d) + # Do the match + if var.startswith('_kicost.'): + # KiCost specific matching system + matched = var_re and var_re.match(var[8:]) + elif var == '_default_': + default = slots + if self.extra_debug: + logger.debug('- Found defaults: {}'.format(slots)) + else: + matched = var == variant_name + if matched: + self.apply_list_of_models(enable, slots, m, var) + break + if not matched and default is not None: + self.apply_list_of_models(enable, slots, m, '_default_') def filter_components(self): self.undo_3d_models_rep = {}