On to the question.
My SMD footprints for passive compontents are the same for resistor, capacitor and inductor. The 3D models are included for the 3 components in 1 footprint. Now instead of selecting manually which model to show, I’m writing a little script to select the correct one automatically. This is what I have now:
def select_correct_3d_model(footprint) -> None:
reference = footprint.GetReference()
show = ""
if reference[0] == "R":
show = "Resistor"
elif reference[0] == "C":
show = "Capacitor"
elif reference[0] == "L":
show = "Inductor"
else:
print(f"{reference}: untouched, has {len(footprint.Models())} 3d models")
return
for model in footprint.Models():
if show in model.m_Filename:
model.m_Show = True
print(f"{reference}: selected {model.m_Filename}")
else:
model.m_Show = False
My problem:
I can’t seem to set model.m_Show to False. How to do this? Where can I find the setters for this attribute?
I always try to appreciate people who help me online, as they forfait some of their free time.
Anyways, I did some more testing, as I had a feeling it might be that footprint.Models() gives copies of the models and no references to the models.
I acknowledged it by this snippet (added some print statements):
def select_correct_3d_model(footprint) -> None:
reference = footprint.GetReference()
show = ""
if reference[0] == "R":
show = "Resistor"
elif reference[0] == "C":
show = "Capacitor"
elif reference[0] == "L":
show = "Inductor"
else:
print(f"{reference} - {footprint.GetValue()}: untouched, has {len(footprint.Models())} 3d models")
return
for model in footprint.Models():
if show in model.m_Filename:
model.m_Show = True
print(f"{reference} - {footprint.GetValue()}: selected {model.m_Filename}")
else:
model.m_Show = False
print(model.m_Show)
print(f"{[model.m_Show for model in footprint.Models()]}")
print("")
I can’t even reach the models on nightly. Models() returns a non-iterable swig wrapper of std::vector (if I remember correctly; I don’t have v6.99 open ATM). I don’t know enough of the details to say what it does.
@eelik 's code snippet works in v6.00. Also I don’t need to call pcbnew.Refresh() to get the changes in pcbnew.
models = footprint.Models()
for i in range(len(models)):
if show in models[i].m_Filename:
models[i].m_Show = True
print(f"{reference} - {footprint.GetValue()}: selected {Path(models[i].m_Filename).name}")
else:
models[i].m_Show = False
@qu1ck that i was thinking. The link doesn’t seem to work (discord loads, but not the message, maybe due to work laptop, I’ll recheck when I get huome).
I was confused for a while because a loop didn’t work when I tried. But it really looks like iterating with for over the Models() result dirctly is the culprit. Your latest loop version works.
Don’t confuse changing loop variable itself and changing variable’s field. If you change the loop variable value you are just changing local variable that at that moment has nothing to do with array contents.
When you change a field of a class that you got from the array both the array element and your loop variable point to the same instance. Changing a field will reflect in the array.
The issue with models is most likely deeper, I haven’t confirmed this definitively but I think this is what’s happening on technical level (copy of my discord messages):
I’m still skeptical about this explanation because it wouldn’t make sense that swig makes a deep copy which would be needed to explain model visibility not updating sometimes but there may be 3d viewer caching involved too, obfuscating the issue (in original problem dev was trying to show models, not hide them like in this thread).