Made the 3D model selection more versatile
- Now you can choose between using the variant name or the variant specific mechanism. - Works for all variants and both mechanism are simple.
This commit is contained in:
parent
de469577d1
commit
ebf529fa0b
15
README.md
15
README.md
|
|
@ -714,18 +714,25 @@ Here are both variants:
|
|||
|
||||

|
||||
|
||||
If you preffer to use the variant specific matching mechanism you can use the following syntax:
|
||||
|
||||
```
|
||||
$TEXT_TO_MATCH:SLOT1,SLOT2,SLOTN$
|
||||
```
|
||||
|
||||
In this case the variant will be applied to the `TEXT_TO_MATCH`, if it matches (equivalent to a component fitted) the `SLOT` will be used.
|
||||
|
||||
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 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%`.
|
||||
- If you are using variants and a lot of them select the same slots you can add a 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%`.
|
||||
avoid relying on any variant specific mechanism. But you can use the alternative syntax if you preffer the variant
|
||||
specific matching system.
|
||||
|
||||
#### DNF and DNC internal keys
|
||||
|
||||
|
|
|
|||
|
|
@ -449,18 +449,25 @@ Here are both variants:
|
|||
|
||||

|
||||
|
||||
If you preffer to use the variant specific matching mechanism you can use the following syntax:
|
||||
|
||||
```
|
||||
$TEXT_TO_MATCH:SLOT1,SLOT2,SLOTN$
|
||||
```
|
||||
|
||||
In this case the variant will be applied to the `TEXT_TO_MATCH`, if it matches (equivalent to a component fitted) the `SLOT` will be used.
|
||||
|
||||
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 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%`.
|
||||
- If you are using variants and a lot of them select the same slots you can add a 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%`.
|
||||
avoid relying on any variant specific mechanism. But you can use the alternative syntax if you preffer the variant
|
||||
specific matching system.
|
||||
|
||||
#### DNF and DNC internal keys
|
||||
|
||||
|
|
|
|||
|
|
@ -205,15 +205,13 @@ class Base3DOptions(VariantOptions):
|
|||
""" 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'\%([^:]+):(.*)\%')
|
||||
field_regex = re.compile(r'\%([^:]+):(.*)\%') # Generic (by name)
|
||||
field_regex_sp = re.compile(r'\$([^:]*):(.*)\$') # Variant specific
|
||||
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'))
|
||||
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())
|
||||
|
|
@ -230,10 +228,7 @@ class Base3DOptions(VariantOptions):
|
|||
var = match.group(1)
|
||||
slots = match.group(2).split(',') if match.group(2) else []
|
||||
# Do the match
|
||||
if var.startswith('_kicost.'):
|
||||
# KiCost specific matching system
|
||||
matched = var_re and var_re.match(var[8:])
|
||||
elif var == '_default_':
|
||||
if var == '_default_':
|
||||
default = slots
|
||||
if self.extra_debug:
|
||||
logger.debug('- Found defaults: {}'.format(slots))
|
||||
|
|
@ -242,6 +237,17 @@ class Base3DOptions(VariantOptions):
|
|||
if matched:
|
||||
self.apply_list_of_models(enable, slots, m, var)
|
||||
break
|
||||
else:
|
||||
# Try with the variant specific pattern
|
||||
match = field_regex_sp.match(text)
|
||||
if match:
|
||||
var = match.group(1)
|
||||
slots = match.group(2).split(',') if match.group(2) else []
|
||||
# Do the match
|
||||
matched = self.variant.matches_variant(var)
|
||||
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_')
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ class BaseVariant(RegVariant):
|
|||
""" Returns the name of the field used to determine if the component belongs to the variant """
|
||||
return None
|
||||
|
||||
def matches_variant(self, text):
|
||||
""" This is a generic match mechanism used by variants that doesn't really have a matching mechanism """
|
||||
return self.name.lower() == text.lower()
|
||||
|
||||
def filter(self, comps):
|
||||
# Apply all the filters
|
||||
comps = apply_pre_transform(comps, self.pre_transform)
|
||||
|
|
|
|||
|
|
@ -68,12 +68,11 @@ class KiBoM(BaseVariant): # noqa: F821
|
|||
# Config field must be lowercase
|
||||
self.config_field = self.config_field.lower()
|
||||
|
||||
def _variant_comp_is_fitted(self, config):
|
||||
def matches_variant(self, config):
|
||||
""" Apply the variants to determine if this component will be fitted.
|
||||
value: component value (lowercase).
|
||||
config: content of the 'Config' field (lowercase). """
|
||||
config: content of the 'Config' field. """
|
||||
# Variants logic
|
||||
opts = config.split(",")
|
||||
opts = config.lower().split(",")
|
||||
# Exclude components that match a -VARIANT
|
||||
for opt in opts:
|
||||
opt = opt.strip()
|
||||
|
|
@ -99,8 +98,8 @@ class KiBoM(BaseVariant): # noqa: F821
|
|||
if not (c.fitted and c.included):
|
||||
# Don't check if we already discarded it
|
||||
continue
|
||||
config = c.get_field_value(self.config_field).lower()
|
||||
c.fitted = self._variant_comp_is_fitted(config)
|
||||
config = c.get_field_value(self.config_field)
|
||||
c.fitted = self.matches_variant(config)
|
||||
if not c.fitted and GS.debug_level > 2:
|
||||
logger.debug('ref: {} config: {} variant: {} -> False'.
|
||||
format(c.ref, config, self.variant))
|
||||
|
|
|
|||
|
|
@ -53,32 +53,38 @@ class KiCost(BaseVariant): # noqa: F821
|
|||
self.separators = ' '
|
||||
else:
|
||||
self.separators = '['+self.separators+']'
|
||||
if self.variant_field and self.variant:
|
||||
self._var_re = re.compile(self.variant, flags=re.IGNORECASE)
|
||||
else:
|
||||
self._var_re = None
|
||||
|
||||
def matches_variant(self, variants):
|
||||
if self._var_re is None or not variants:
|
||||
return True
|
||||
# The component belongs to one or more variant
|
||||
for v in re.split(self.separators, variants):
|
||||
if self._var_re.match(v):
|
||||
# Matched, remains
|
||||
return True
|
||||
# None of the variants matched
|
||||
return False
|
||||
|
||||
def filter(self, comps):
|
||||
GS.variant = [self.variant]
|
||||
comps = super().filter(comps)
|
||||
logger.debug("Applying KiCost style variant `{}`".format(self.name))
|
||||
if not self.variant_field or not self.variant:
|
||||
if self._var_re is None:
|
||||
# No variant field or not variant regex
|
||||
# Just skip the process
|
||||
return comps
|
||||
# Apply to all the components
|
||||
var_re = re.compile(self.variant, flags=re.IGNORECASE)
|
||||
for c in comps:
|
||||
logger.debug("{} {} {}".format(c.ref, c.fitted, c.included))
|
||||
if not (c.fitted and c.included):
|
||||
# Don't check if we already discarded it
|
||||
continue
|
||||
variants = c.get_field_value(self.variant_field)
|
||||
if variants:
|
||||
# The component belong to one or more variant
|
||||
for v in re.split(self.separators, variants):
|
||||
if var_re.match(v):
|
||||
# Matched, remains
|
||||
break
|
||||
else:
|
||||
# None of the variants matched
|
||||
c.fitted = False
|
||||
if GS.debug_level > 2:
|
||||
logger.debug('ref: {} value: {} -> False'.format(c.ref, c.value))
|
||||
c.fitted = self.matches_variant(variants)
|
||||
if not c.fitted and GS.debug_level > 2:
|
||||
logger.debug('ref: {} value: {} variants: {} -> False'.format(c.ref, c.value, variants))
|
||||
return comps
|
||||
|
|
|
|||
Loading…
Reference in New Issue