hölzli Geschrieben 19. November 2020 Teilen Geschrieben 19. November 2020 Ich möchte gerne ein Marionette Node erstellen, welches "dynamisch" die Werte aus einer Tabelle zur Auswahl stellt und die entsprechenden Werte aus den jeweiligen Spalten wiedergibt. Die Auswahl funktioniert soweit, dass im Popup die richtigen Werte stehen. Beim Ausführen erhalte ich jedoch eine Meldung, dass ein Name nicht definiert ist - genau der Name, welcher jedoch für die Auswahl ja zu funktionieren scheint Wie kann ich ein Script so ausführen lassen, dass die Namen sowohl in der Nodedefinition wie auch in der Ausführung verfügbar sind? Inhalt des Nodes: #gim2020-11-19 #Modified April 2017 #Script zur Auswahl der Tabelle und der Werte tabname = 'Spot Standard' #Name der Tabelle tab = vs.GetObject(tabname) #Handle zur Tabelle (numRows, numColumns) = vs.GetWSRowColumnCount(tab) #Zählt die Anzahl Zeilen und Spalten def frange(x, y, jump): #x entspricht der Startzeile in der Tabelle, y der letzten Zeile, jump ist die Schrittgrösse while x - y <= .000001: yield x x += jump list = [] list = [n for n in frange(2, numRows, 1)] #erstellt eine Liste, welche Zeilen aus der Tabelle ausgewählt werden sollen Artikelbeschriebe = [] Artikelnummern = [] for i in range(len(list)): Artikelbeschriebe.append(vs.GetWSCellFormulaN(tab, list[i], 1)) #Die Beschriebe sind in der ersten Spalte Artikelnummern.append(vs.GetWSCellFormulaN(tab, list[i], 2)) #Die Nummern sind in der zweiten Spalte @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'Popup' ) this.SetDescription('This node demonstrates the use of a Popup OIP control. The values returned by this node will be integers based on your selection starting with 0 for the first option and increasing by 1 for consecutive options.') #Input Ports #OIP Controls input = Marionette.OIPControl( 'Popup', Marionette.WidgetType.Popup, 0, Artikelbeschriebe) input.SetDescription('an OIP control representing the options designated within the script editor') #Output Ports outputs = Marionette.PortOut('sArtikel') outputs.SetDescription('Artikelbeschrieb') outputn = Marionette.PortOut('nArtikel') outputn.SetDescription('Artikelnummer') #BEHAVIOR def RunNode(self): #inputs pass input = self.Params.input.value #Integer der Auswahl Artb = self.Params.Artikelbeschriebe.value Artn = self.Params.Artikelnummern.value #script outputs = Artb[input] outputn = Artn[input] #outputs self.Params.outputs.value = outputs self.Params.outputn.value = outputn Die Tabelle sowie das Popup im OIP: und die ernüchternde Fehlermeldung: Popup mit Werten aus Tabelle_2020-11-19.vwx 1 Vectorworks 2022 interiorcad | Windows11 Link zu diesem Kommentar
Manuel Roth Geschrieben 19. November 2020 Teilen Geschrieben 19. November 2020 Wow, habe gar nicht gewusst, dass vor @Marioette.NodeDefiniton noch Code eingefügt werden kann. Habe noch nie einen solchen Node gesehen und weiss ehrlich gesagt auch nicht, was das mit der Funktion des Nodes macht und ob es überhaupt legal ist. Ich habe auch schon versucht, ein PopUp dynamisch mit einem Input von der Marionette zu füllen. Dieses Vorhaben funktioniert allerdings nicht. Bei dir ist die Situation allerdings leicht anders, da die Werte nicht nur während der Laufzeit des Scripts verfügbar sind, sondern die ganze Zeit fix in der Tabelle stehen. Ich erwähne, dies nur, damit du gewarnt bist, dass dein Vorhaben eventuell nicht funktionieren könnte. Da mich der Vorabcode gestört hat, habe ich ihn direkt unter der Klasse Params eingebaut. Die Fehlermeldung hat sich daraufhin geändert, und nach dem Weglassen von .value beim Wertimport von RunScript gibt dir der Node schon einmal den gewählten String aus. Was allerdings noch nicht funktioniert, ist das Update der OIP. Das ist aber ein Thema, bei dem Marionette allgemein Mühe hat. Egal mit was für Methoden ich den Node resete, das Update der OIP funktionert nicht richtig. Am Besten funktioniert noch das Bearbeiten des Codes. Dann ist durchnittlich nach dem dritten Klick auf OK die OIP aktualisiert. Dieses Problem besteht allerdings auch bei deinem Originalcode und ist eher auf das Tool, als auf den Code zurückzuführen. Vielleicht findest du eine Möglichkeit zur zuverlässigen Aktualisierung. Dein Node wird sich allerdings nicht ohne einen Kick von selbst aktualisieren. Du müsstest einen Weg finden, eine Änderung der Tabelle abzufangen und den Node erst dann zu aktualisieren. Ich habe allerdings noch nie einen Ereignisslistener in Marionette gesehen. Es gibt aber allem anschein nach noch eine Menge, was ich noch nie gesehen habe. Und die Tatsache, dass es diese Listener für PIOs gibt, macht Hoffnung, dass es eventuell auch in Marionette möglich ist. @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE tabname = 'Spot Standard' #Name der Tabelle tab = vs.GetObject(tabname) #Handle zur Tabelle (numRows, numColumns) = vs.GetWSRowColumnCount(tab) #Zählt die Anzahl Zeilen und Spalten def frange(x, y, jump): #x entspricht der Startzeile in der Tabelle, y der letzten Zeile, jump ist die Schrittgrösse while x - y <= .000001: yield x x += jump list = [] list = [n for n in frange(2, numRows, 1)] #erstellt eine Liste, welche Zeilen aus der Tabelle ausgewählt werden sollen Artikelbeschriebe = [] Artikelnummern = [] for i in range(len(list)): Artikelbeschriebe.append(vs.GetWSCellFormulaN(tab, list[i], 1)) #Die Beschriebe sind in der ersten Spalte Artikelnummern.append(vs.GetWSCellFormulaN(tab, list[i], 2)) #Die Nummern sind in der zweiten Spalte #Name this = Marionette.Node( 'Popup' ) this.SetDescription('This node demonstrates the use of a Popup OIP control. The values returned by this node will be integers based on your selection starting with 0 for the first option and increasing by 1 for consecutive options.') #Input Ports #OIP Controls input = Marionette.OIPControl( 'Popup', Marionette.WidgetType.Popup, 0, Artikelbeschriebe) input.SetDescription('an OIP control representing the options designated within the script editor') #Output Ports outputs = Marionette.PortOut('sArtikel') outputs.SetDescription('Artikelbeschrieb') outputn = Marionette.PortOut('nArtikel') outputn.SetDescription('Artikelnummer') #BEHAVIOR def RunNode(self): #inputs input = self.Params.input.value #Integer der Auswahl Artb = self.Params.Artikelbeschriebe #script outputs = Artb[input] #outputs self.Params.outputs.value = outputs self.Params.outputn.value = 0 @Dominique Corpataux, was meinst du zu diesem Vorhaben? 1 Freundliche Grüsse Manuel Roth _________________________________________________ Vectorworks 2022 SP3 | Architektur | Windows 10 Link zu diesem Kommentar
Nicolas Goutte Geschrieben 20. November 2020 Teilen Geschrieben 20. November 2020 vor 10 Stunden schrieb hölzli: Inhalt des Nodes: #gim2020-11-19 #Modified April 2017 #Script zur Auswahl der Tabelle und der Werte tabname = 'Spot Standard' #Name der Tabelle tab = vs.GetObject(tabname) #Handle zur Tabelle (numRows, numColumns) = vs.GetWSRowColumnCount(tab) #Zählt die Anzahl Zeilen und Spalten def frange(x, y, jump): #x entspricht der Startzeile in der Tabelle, y der letzten Zeile, jump ist die Schrittgrösse while x - y <= .000001: yield x x += jump list = [] list = [n for n in frange(2, numRows, 1)] #erstellt eine Liste, welche Zeilen aus der Tabelle ausgewählt werden sollen Artikelbeschriebe = [] Artikelnummern = [] for i in range(len(list)): Artikelbeschriebe.append(vs.GetWSCellFormulaN(tab, list[i], 1)) #Die Beschriebe sind in der ersten Spalte Artikelnummern.append(vs.GetWSCellFormulaN(tab, list[i], 2)) #Die Nummern sind in der zweiten Spalte @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( 'Popup' ) this.SetDescription('This node demonstrates the use of a Popup OIP control. The values returned by this node will be integers based on your selection starting with 0 for the first option and increasing by 1 for consecutive options.') #Input Ports #OIP Controls input = Marionette.OIPControl( 'Popup', Marionette.WidgetType.Popup, 0, Artikelbeschriebe) input.SetDescription('an OIP control representing the options designated within the script editor') #Output Ports outputs = Marionette.PortOut('sArtikel') outputs.SetDescription('Artikelbeschrieb') outputn = Marionette.PortOut('nArtikel') outputn.SetDescription('Artikelnummer') #BEHAVIOR def RunNode(self): #inputs pass input = self.Params.input.value #Integer der Auswahl Artb = self.Params.Artikelbeschriebe.value Artn = self.Params.Artikelnummern.value #script outputs = Artb[input] outputn = Artn[input] #outputs self.Params.outputs.value = outputs self.Params.outputn.value = outputn Ich kann da nichts Konkretes besteuern, aber ich sehe, dass bei SetDescription 'Artikelbeschrieb' genutzt wird, aber beim Variablen auslesen Artb = self.Params.Artikelbeschriebe . Da scheint mir eine Diskrepanz um ein "e" zu sein. 1 Software-Entwickler extragroup GmbH https://www.extragroup.de Link zu diesem Kommentar
hölzli Geschrieben 20. November 2020 Autor Teilen Geschrieben 20. November 2020 vor 21 Minuten schrieb Nicolas Goutte: Ich kann da nichts Konkretes besteuern, aber ich sehe, dass bei SetDescription 'Artikelbeschrieb' genutzt wird, aber beim Variablen auslesen Artb = self.Params.Artikelbeschriebe . Da scheint mir eine Diskrepanz um ein "e" zu sein. Nach meinem Verständnis ist ja SetDescription lediglich für die Beschreibung relevant, also ist der "Wert" dort der anzuzeigende Text, beim Klicken auf "Beschreibung. 1 Vectorworks 2022 interiorcad | Windows11 Link zu diesem Kommentar
Manuel Roth Geschrieben 20. November 2020 Teilen Geschrieben 20. November 2020 Genau, der Wert bei SetDescription kann irgend ein String sein, der unter Beschreibung angezeigt wird. Hat ansonsten keine Relaevanz auf das Script. Eigentlich könnte die Zeile sogar weggelassen werden, wenn dir keine intelligente Beschriebung einfällt. (Damit habe ich oftmals mehr Probleme als mit dem Script selbst. ) 1 Freundliche Grüsse Manuel Roth _________________________________________________ Vectorworks 2022 SP3 | Architektur | Windows 10 Link zu diesem Kommentar
hölzli Geschrieben 20. November 2020 Autor Teilen Geschrieben 20. November 2020 vor 21 Stunden schrieb Manuel Roth: Wow, habe gar nicht gewusst, dass vor @Marioette.NodeDefiniton noch Code eingefügt werden kann. Habe noch nie einen solchen Node gesehen und weiss ehrlich gesagt auch nicht, was das mit der Funktion des Nodes macht und ob es überhaupt legal ist. Haha, "...dann kam einer, der wusste das nicht und hat es gemacht" Dein Script funktioniert soweit ja wunderbar. Das Weglassen vom .value war mein Fehler, weshalb ich durch" try and error" auf den Versuch mit dem Einfügen VOR @Marionette.NodeDefinition kam und dachte, eine Lösung gefunden zu haben. vor 21 Stunden schrieb Manuel Roth: Dein Node wird sich allerdings nicht ohne einen Kick von selbst aktualisieren. Du müsstest einen Weg finden, eine Änderung der Tabelle abzufangen und den Node erst dann zu aktualisieren. Es scheint, dass der Code in Class Params nur beim Einfügen eines Nodes oder der Bearbeitung aktualisiert wird. 1 Vectorworks 2022 interiorcad | Windows11 Link zu diesem Kommentar
hölzli Geschrieben 20. November 2020 Autor Teilen Geschrieben 20. November 2020 (bearbeitet) Werden die Daten, welche ausgewertet werden innerhalb der Klasse möglicherweise im "pycache" zwischengespeichert? C:\Users\USERNAME\AppData\Roaming\Nemetschek\Vectorworks\2020\Plug-Ins\Marionette\__pycache__ Falls ja, weiss jemand, ob es möglich ist, die entsprechende Instanz dieses Nodes mit dem Ausgeführten Skript zu unterdrücken oder zu löschen, damit wieder neu berechnet werden muss? Im Prinzip ja absolut ineffizient was die Geschwindigkeit angeht, aber für gewisse Situationen könnte dies ja durchaus hilfreich sein Auf jeden Fall werden die Daten ja berechnet und müssen dann auch gespeichert werden. Wenn man den Ort kennt, gibt es vielleicht ja auch eine Möglichkeit, dies zu ändern? Interessanterweise wird eine Änderung in der Tabelle zwar im Popup nicht angezeigt, ein neuer Wert wird jedoch im Output ausgegeben. Das Skript wird also sehr wohl ausgeführt, jedoch ohne Einfluss auf die Liste, welche für das Dropdown verwendet wird. Bearbeitet 20. November 2020 von hölzli 1 Vectorworks 2022 interiorcad | Windows11 Link zu diesem Kommentar
Holzzukunft Geschrieben 18. November 2021 Teilen Geschrieben 18. November 2021 Hallo hölzli Dein Knoten könnte für mich Interessant sein. Konntest du diesen vollenden? Vielen Dank für deine Rückmeldung. 1 Link zu diesem Kommentar
kingchaos Geschrieben 18. November 2021 Teilen Geschrieben 18. November 2021 weiter so ^^ verstehe ich das jetzt richtig, dass man damit den Node-Namen manipulieren kann? Den rest habe ich nicht ganz verstanden, kann es jemand fuer einen python-nub wie mich erklaeren bitte? HP Z6 G4 Intel(R) Xeon(R) W-3223 CPU @ 3.50 GHz - NVIDIA Quadro RTX 4000 VWX IC 2023 SP7-F7 R1 Windows 10 64 GB 64 bit Link zu diesem Kommentar
hölzli Geschrieben 19. November 2021 Autor Teilen Geschrieben 19. November 2021 Salut zusammen @HolzzukunftIch hab zu diesem Thema leider keine Lösung gefunden und hab dieses Thema folglich auch nicht mehr weiter verfolgt. Ich wäre aber ebenfalls sehr interessiert daran, falls dies doch klappen sollte. @kingchaos Ja eigentlich würde dies funktionieren, falls mein eigentlicher Wunsch überhaupt laufen würde: Nämlich dass der Inhalt des Nodes bei jeder Ausführung neu ausgewertet wird. Ich hab dies aber leider nicht hinbekommen, daüfür reichen meine Programmierkenntnisse um Welten zu wenig weit :-) Vectorworks 2022 interiorcad | Windows11 Link zu diesem Kommentar
Empfohlene Beiträge
Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren
Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde Dich hier an.
Jetzt anmelden