| | | CATIA V5 Grundkurs | Einsteiger - 5 Std. 15 Min | | | | KISTERS 3DViewStation: Effektiver Know-how-Schutz von sensiblen Produktdaten, eine Pressemitteilung
|
Autor
|
Thema: Rekursiv (4565 mal gelesen)
|
Erich Mitglied Senior Consultant selbstständig
Beiträge: 223 Registriert: 03.10.2000 i7-9850H RAM 32,0 GB Nvidia Quadro T2000 Windows 7 Professional 64Bit
|
erstellt am: 10. Mrz. 2007 20:38 <-- editieren / zitieren --> Unities abgeben:
Hallo zusammen ich benötige ein CATScript, welches alle Produkte und Parts findet und in eine Datei schreibt. Die Infos über einen rekursiven Programmteil habe ich gelesen, ich bekomme ihn im CATScript nicht gelöst. Kann jemand mir jemand dieses Thema in Form eines Beispiel detaillieren. Würde mir wirklich sehr helfen. Danke. ------------------ mfg Erich Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
listing_code Mitglied
Beiträge: 45 Registriert: 27.10.2003
|
erstellt am: 12. Mrz. 2007 10:40 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
|
okl Mitglied Wirtsch-Ing (Maschbau)
Beiträge: 157 Registriert: 21.04.2006 2x3,6 GHz, 2 GB RAM, NVIDIA Quadro FX 1800, Delmia V5R16 SP1, Win XP Prof SP2, Office, VS 2005, VB 6, Inventor (Test), VBExpress .NET 2005 Adminrechte
|
erstellt am: 12. Mrz. 2007 12:18 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
Hm, muss es denn CATScript sein oder darf es auch etwas angenehmeres sein? CATScript ist IMHO eine Skriptsprache, die nicht wirklich dafür gemacht worden ist, nicht sequenzielle Anweisungen zu bearbeiten. Noch etwas: rekursive Vorgänge können sehr speicherintensiv sein (und dem entsprechend langsam) und man muss sehr genau programmieren damit keine Enbdlosschleifen entstehen. Dennoch gelten sie zurecht als "hohe Schule" des Programmierens, wenn man sehr gut die Speicherauslastung begrenzt etc. Da jede rekursive Anweisung auch iterativ darstellbar ist, denk doch mal über eine solche Programmierung nach, da diese bei großen CAD-Teilen mit Sicherheit umfangreicher zu schreiben sein, aber schneller kaufen wird. Ich habe beide Versionen mal programmiert, muss die nur in meinem Datensumpf suchen. Wenn Interesse besteht, kann ich gerne ein paar Sniplets, sofern ich sie finde, posten. Grüße, Ole Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
tomtom1972 Mitglied dipl ing maschinenbau
Beiträge: 608 Registriert: 22.03.2005 NVidia Quadro K4000 Intel Xeon E5-1620, 64GB RAM Windows10 64bit R30 <= CATIA V5 > =R19
|
erstellt am: 13. Mrz. 2007 09:05 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
Hallo, wieso soll CATScript dafür nicht gemacht sein? Und wieso ist ein rekursiv aufgebautes Script speicherintensiver? Das halte ich alles für absoluten Unfug. Endlosschleifen sind das Resultat falscher Programmierung und nicht das Ergebnis rekursiver Vorgänge. Rekursiv heißt ja nicht, das eine Schleife beliebig oft aufgerufen wird. Bsp sei folgende Struktur: Product Product Part Product Part Part und folgendes Script: Sub CATMain() Set oRoot = Catia.ActiveDocument Set oProducts = oRoot.Product.Products SUB_ProdScan oProducts End Sub Sub SUB_ProdScan(oProducts) For i = 1 to oProducts.Count If oProducts.Item(i).Products.Count > 0 Then MsgBox oProducts.Item(i).Name, "64", "enthält Kinder" Set oProductsUebergabe = oProducts.Item(i).Products SUB_ProdScan oProductsUebergabe Else MsgBox oProducts.Item(i).Name, "64", "enthält keine Kinder" End If Next End Sub Das ist ein CATScript, es ist rekursiv aufgebaut, hat mit speicherintensiv gar nix zu tun, ist überdies nicht langsam und würde sich ansonsten für nicht definierte (also immer andere) Strukturen gar nicht programmieren lassen. Und unter "hoher Schule des Programmierens" verstehe ich auch was anderes. TomTom
------------------ tomtom1972 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
okl Mitglied Wirtsch-Ing (Maschbau)
Beiträge: 157 Registriert: 21.04.2006 2x3,6 GHz, 2 GB RAM, NVIDIA Quadro FX 1800, Delmia V5R16 SP1, Win XP Prof SP2, Office, VS 2005, VB 6, Inventor (Test), VBExpress .NET 2005 Adminrechte
|
erstellt am: 13. Mrz. 2007 09:38 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
Zitat: Und wieso ist ein rekursiv aufgebautes Script speicherintensiver
Prizipiell werden alle Zwischenresultate vorgehalten. Zitat: If oProducts.Item(i).Products.Count > 0 Then
Damit hast Du genau das gemacht, was ich als Speicherauslastung beschrieben habe. Du nimmst einfach nicht jedes Zwischenergebnis mit auf. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
tomtom1972 Mitglied dipl ing maschinenbau
Beiträge: 608 Registriert: 22.03.2005 NVidia Quadro K4000 Intel Xeon E5-1620, 64GB RAM Windows10 64bit R30 <= CATIA V5 > =R19
|
erstellt am: 13. Mrz. 2007 10:11 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
Hallo, das war jetzt aber nur meine Schreibfaulheit. Ich denke unter "Zwischenergebnis aufnehmen" verstehst du z.B. folgendes: Set oZwischenergebnis = oProduct.Item(i) und dann If oZwischenergebnis.Products.Count > 0 Then ..... Meine Meinung dazu ist folgende: Sofern oZwischenergebnis keine globale Variable ist (Public) - und das ist sie bei rekursiven Vorgängen normalerweise nie - wird der Variable in der nächsten Schleife ein neues Objekt zugewiesen. Das beinhaltet, das die alte Zuweisung vorher gelöscht wird. Da läuft gar nix voll im Arbeitsspeicher. Das habe ich mit Productstrukturen > 1000 Modellen in mehreren Zusammenhängen ausprobiert. Zudem kann man bei Bedarf die Zuweisungen gezielt löschen (auch für globale definierte Variablen, Set oIrgendwas = Nothing). Mit einem nicht rekursiv aufgebauten Script nimmst du im übrigen die Zwischenergebnisse genauso auf (oder eben nicht, wie in meinen Fall). Das hat aber mit rekursiv oder nicht rekursiv überhaupt gar nix zu tun. Ich habe also immer noch nicht verstanden, was hier speicherintensiver sein soll. Und wie gesagt: Bei nicht statischen Strukturen bleibt dir doch gar nichts anderes übrig als rekursiv vorzugehen. Oder hast du eine bessere Alternative? TomTom ------------------ tomtom1972 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
okl Mitglied Wirtsch-Ing (Maschbau)
Beiträge: 157 Registriert: 21.04.2006 2x3,6 GHz, 2 GB RAM, NVIDIA Quadro FX 1800, Delmia V5R16 SP1, Win XP Prof SP2, Office, VS 2005, VB 6, Inventor (Test), VBExpress .NET 2005 Adminrechte
|
erstellt am: 13. Mrz. 2007 12:36 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
Moin TomTom! Ich denke, wir reden über dasselbe, haben nur unterschiedliche Sichtweisen auf das eigentliche Problem. Schön erklärt: http://de.wikipedia.org/wiki/Rekursive_Programmierung Du brauchst einfach extrem viel Speicher, um Deine Prozeduren und Methoden in den Speicher zu laden. Meines Erachtens wird nicht bei jedem neuen Prozeduraufruf die Variable neu beschrieben und das alte Ergbnis verworfen, denn sonst hättest Du am Ende des Tages nicht alle zugehörigen Inhalte ausgelesen. Also muss eine neue Variable pro Prozeduraufruf deklariert und beschrieben werden. Und wenn Du jetzt noch die unterschiedlichen Anfangsspeichergrößen, die einfach nur für einen bestimmten Vartypen vorgehalten werden, addierst, dann kommst Du auf eine ziemlich hohe Speicherplatzbelegung. Sop jedenfalls habe ich es verstanden. Vielleicht liege ich auch völlig daneben. Ich lasse mich gerne berichtigen. Ansonsten hast Du natürlich recht, dass Du, wenn Du Strukturen wie die Part/Productstrukturen innerhalb von Catia auslesen möchtest, ein ähnlich aufgebautes Abfrage/Auslesetool brauchst. Und das geht natürlich gut mit rekursiver Programmierung. [Diese Nachricht wurde von okl am 13. Mrz. 2007 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
tomtom1972 Mitglied dipl ing maschinenbau
Beiträge: 608 Registriert: 22.03.2005 NVidia Quadro K4000 Intel Xeon E5-1620, 64GB RAM Windows10 64bit R30 <= CATIA V5 > =R19
|
erstellt am: 14. Mrz. 2007 07:42 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
Moin okl, führen wir unsere Diskussion weiter. Ich sehe das ein bischen anders. Ich will mich ja nicht zu weit aus dem Fenster lehnen, aber ich denke du interpretierst den Artikel auf Wiki nicht ganz richtig (das Beispiel dort ist auch unglücklich). Oder eben ich. Holen wir mal etwas weiter aus: Es gibt zwei Bereiche im RAM, die ein Script mit Arbeitsspeicher bedient: der Stack und der Heap. Wird z.B. eine Integer-Variable deklariert (Dim iTest As Integer, iTest = 1000), schreibt sich der 32-Bit-Wert der selbigen in den Stack. Der Stack findet sich wie gesagt im RAM, wird aber vom Prozessor durch einen so genannten Stack Pointer direkt unterstützt. Dieser kann auf dem Stack neuen Speicher reservieren und alten freigeben. Dieses Verfahren ist sehr effizient und schneller als das Allokieren von Speicher im Heap (für Referenztypen). Eine Referenz ist ein Verweis auf ein Objekt ( Set oTest = CATIA.ActiveDocument). Dieser Verweis wird im Heap gespeichert. Der Heap ist der Speicher im RAM, der allgemeinen Zwecken zur Verfügung steht. Es wird nur genau so viel Speicher allokiert, wie benötigt wird, d.h. der Compiler weiß zur Laufzeit eines Programms weder wie viel das ist noch wie lange die Allokierung aufrechterhalten bleibt. Das ist flexiebler, dauert aber auch länger. Dieses Thema findest du in einschlägiger Literatur in aller Ausführlichkeit behandelt, z.B. im Buch Visual Basic 2005 von Andreas Kühnel (ohne Werbung zu machen; ich habe weder mit dem Autor noch mit dem Verlag was zu tun.) Ein anderes Thema sind Schleifen (rekursive oder nicht). Ein VB-Programm (und auch ein CATScript) reserviert bei jedem Aufruf einer Routine (das ist eine Funktion, eine Sub oder was auch immer) Platz auf dem Stack für die Parameter und für die lokalen Variablen der Routine und gibt diese beim Verlassen der Routine automatisch wieder frei. Standardmäßig wird für jeden Stapel (das engl. Wort dafür ist „Stack“ ) 1 Megabyte reserviert. In einem VB6.0 Script kann man diese Zuweisung bis auf 250 KB begrenzen, in einem CATScript nicht. Um auf die rekursiven Schleifen zurück zu kommen: Wenn du also nun eine Routine immer wieder aufrufst ohne sie zu beenden, gibt sie den Speicher im Stack nicht mehr frei und dieser „läuft über“. Das heißt aber nicht, das er voll ist, sondern das für die nächste Routine nichts mehr reserviert werden kann. Das Script bricht ab und erzeugt eine Windows-Standard-Fehlermeldung (Err.Number 28) Das kannst du mit folgenden Script ausprobieren: Public j as Interger
Sub CATMain() j = 0 SUB_Rekursiv Msgbox "Err.Number " & Err.Number & ": " & Err.Description, 16, "In Schleife " & j & " ist folgender Fehler aufgetreten" End Sub Sub SUB_Rekursiv On Error Resume Next If j < 10000 Then If Err.Number = 0 Then j = j + 1 SUB_Rekursiv Else Exit Sub End if End if End Sub Hierbei wird kein einziges Zwischenergebnis gesichert (wie du es oben genannt hast). Das ist nämlich völlig unrelevant hinsichtlich der Auslastung. Problematisch ist die Reservierung für jede Routine. D.h. im Klartext: wenn du (bei mir sind es 1022) Routinen aufrufst, ohne sie zu beenden, dann läuft der Stack über (bezogen auf die Reservierung, nicht auf die Auslastung). Wenn du einen Blick in den Task-Manager wirfst wirst du sehen, das sich an der Auslastung gar nichts ändert hat.
Wenn du nun z.B. Produktstrukturen (wie in meinem Bsp. oben) rekursiv nach Parts abklapperst, benötigst du eine Struktur mit 1022 (bei meinem RAM) Verschachtelungstiefen, damit das passiert. Das ist mir (auch bei Strukturen mit 10000 Modellen) noch nicht untergekommen. Wenn eine Routine abgearbeitet ist (also verlassen wird), wird der reservierte Speicher wieder freigegeben. Allerspätestens jedoch wenn das Script beendet wird. Das Sichern von Zwischenergebnissen ist ein Witz (hinsichtlich der Auslastung) und wird nie zu einem Überlaufen führen, so wie man das aus CATIA kennt (wenn eine Struktur zu groß ist oder irgendwas im RAM „hängen bleibt“ ). Unten ein Script, um das “Sichern von Zwischenergebnissen” zu testen. Einfach ein leeres Part auf, läuft bei mir ca. 8 Sekunden, wenn iMax auf 1000 steht, also 1000000 mal das Catia.ActiveDocument erfasst wird. Public k as Integer Public iMax as Integer Sub CatMain() iMax = 1000 k = 0 For j = 1 to iMax Test Next Msgbox "Es wuden " & k & " Zwischenergebnisse gesichert", 64, "Info" End Sub Sub Test() Dim aTest() ReDim aTest(iMax) For i = 1 to iMax Set aTest(i) = Catia.ActiveDocument k = k + 1 Next End Sub Wenn du iMax auf 100000 stellst (also 1000000000000 mal das Catia.ActiveDocument erfasst wird) kannst du im Task sehen, wie die Auslastung ganz langsam steigt. Aber Überlaufen wird da gar nix (und das Script läuft jetzt mehrere Stunden). Jetzt habe ich meinen Senf ganz Ausführlich dazugegeben. Mehr weiß ich zu dem Thema nicht. Sind wir jetzt ein Stückchen weiter als vorher? Gruss TomTom
------------------ tomtom1972 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
okl Mitglied Wirtsch-Ing (Maschbau)
Beiträge: 157 Registriert: 21.04.2006 2x3,6 GHz, 2 GB RAM, NVIDIA Quadro FX 1800, Delmia V5R16 SP1, Win XP Prof SP2, Office, VS 2005, VB 6, Inventor (Test), VBExpress .NET 2005 Adminrechte
|
erstellt am: 14. Mrz. 2007 10:17 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
Moin TomTom, danke für die ausführliche Darstellung. Ich muss wohl meine Meinung darüber ein wenig modifizieren. Dennoch hatte ich durchaus Probleme mit meinem Speicher (der übergelaufen ist). Muss mal das alte Skript ausgraben und mir die Stelle suchen, an der es passiert ist. Bis dahin würde ich gerne die Diskussion "ruhen" lassen... Grüße, Ole Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
tomtom1972 Mitglied dipl ing maschinenbau
Beiträge: 608 Registriert: 22.03.2005 NVidia Quadro K4000 Intel Xeon E5-1620, 64GB RAM Windows10 64bit R30 <= CATIA V5 > =R19
|
erstellt am: 14. Mrz. 2007 11:48 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
|
Tom i2 Mitglied Konstrukteur
Beiträge: 24 Registriert: 24.11.2004
|
erstellt am: 21. Mrz. 2007 16:00 <-- editieren / zitieren --> Unities abgeben: Nur für Erich
Hallo Leute Muss erstmal sagen ich hab mir diesen Thread nicht ganz durchgelesen, aber wenns nur darum geht die BOM darzustellen dann geht das ja wohl auch mit "Speichern unter" -> "*.txt" Das gibt ein Textfile mit der ganzen Produktstruktur. Das Erscheinungsbild lässt sich auch sicher irgendwo beeinflussen. Aber das ist eine andere Geschichte. Gruß Tom.i2 ------------------ It's not the speed that kills you It's the sudden stop [Diese Nachricht wurde von Tom i2 am 21. Mrz. 2007 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|