Fenster unauffindbar
-
Das Elementinformationenfenster war unauffindbar. Das Umschalten im Menü von Haken auf Strich ging wie von anderen Werkzeug-/Einstellfenstern bekannt. Aber nichts zu machen, es blieb verschwunden. Ein Aufräumbefehl fehlt hier ggf.
Gestern hatte ich einen Projektor zusätzlich angeschlossen. Mir kam der Verdacht, das gesuchte Fenster könnte in dem Bereich liegen, den der beamer abdeckte.
Und tatsächlich. Beamer nochmals angeschlossen, und das Elementinformationenfenster kam wieder zum Vorscheinen. Ich konnte das unsichtbare Fenster in den Anzeigebereich des Hauptbildschirms verschieben.
Hoffentlich verliert nicht wieder jemand soviel Zeit bei solcher Suche.
…
Im Elementinformationenfenster können Objekte mit Namen ausgestattet werden. Und: nach diesen Namen kann per Ruby-Skript gefahndet werden:
Folgender Skript bringt eine Liste der Objektnamen:Sketchup.active_model.entities.each { |e| puts e.name if e.kind_of?(Sketchup;;Group) or e.kind_of?(Sketchup;;ComponentInstance) }
Unbenannte Objekte bringen Leerzeilen, in Komponenten enthaltene Objektnamen werden nicht ermittelt.
…
Nächste Aufgabe wäre, für einen Objektnamen die Anordnung/Position im Achsenkreuz zu erfragen. Weiß dazu jemand etwas? -
Hilft das weiter?: Group und ComponentInstance erben von Drawingelement. Darum haben sie alle die Methode Drawingelement#bounds, die als Rückgabewert ein BoundingBox-Objekt liefert. Bei diesem sind die Methoden BoundingBox#center, BoundingBox#max und BoundingBox#min interessant, die allesamt ein Point3d-Objekt liefern. Und dies wiederum kann man nach seinen Werten (x, y, z) abfragen.
azuby
-
@azuby said:
Hilft das weiter?…
Das hilft sehr weiter? Nur, wie taste ich mich nun zur »boundingbox«-Abfrage heran?
Die Beispielskript »« oder »« können nicht geladen werden. Ich sehe allerdings, daß sie auf meiner Festplatte im Ruby-Ordner schon vorhanden sind.Wenn mein Objekt »Stein« heißt, wie lautet dann das Ruby-Skript, mit dem für »Stein« die boundingbox-Werte abgefragt werden?
-
Ich sehe gerade diesen Thread - das ganze Zeug um die BoundingBox ginge zwar auch, aber warum kompliziert, wenn es auch einfach geht.
def zoom_to_object object_name Sketchup.active_model.entities.each do |entity| if entity.name == object_name Sketchup.active_model.active_view.zoom entity break # ist zwar dreckig, bin heute aber mal faul end end end # aufzurufen dann mit z. B. zoom_to_object "Stein"
azuby
-
Ich werde jetzt aber nicht raten, was du getan oder nicht getan hast, um es zum Laufen zu bringen und welche Rückmeldung oder auch nicht du bekommen hast
azuby
-
@azuby said:
Ich sehe gerade diesen Thread - das ganze Zeug um die BoundingBox ginge zwar auch, aber warum kompliziert, wenn es auch einfach geht.
def zoom_to_object object_name > Sketchup.active_model.entities.each do |entity| > if entity.name == object_name > Sketchup.active_model.active_view.zoom entity > break # ist zwar dreckig, bin heute aber mal faul > end > end > end > > # aufzurufen dann mit z. B. zoom_to_object "Stein"
azuby
RickW schrieb:
model = Sketchup.active_model sel = model.selection # have something selected model.active_view.zoom sel.first
… funktioniert (auch, wenn ».first« fehlt).
Ein ausgewählter Teil der Sketchup-Zeichnung wird groß in der Mitte des Bildschirms dargestellt.Azubis Skript kriege ich dagegen nicht zum Laufen, obwohl dieser Skript mir einen Wunsch erfüllen würde (… ich könnte ein Objekt nach Namen auswählen lassen). Das »aufzurufen dann mit z. B. zoom_to_object "Stein"« bekomme ich nicht eingebaut.
-
Sketchup.active_model.entities.each do |entity| if entity.name == "Stein" Sketchup.active_model.active_view.zoom entity break # ist zwar dreckig, bin heute aber mal faul end end
Fehlermeldung in der Ruby-Konsole:
Error: #<NoMethodError: undefined methodname' for #<Sketchup::Text:0x1b8748c4>> (eval):203 (eval):202:in
each'
(eval):202Tippe ich alle Zeilen von azuby ein, dann sind die Fehlermeldungen mehr und unübersichtlicher, weil mehrmals die eigenen Zeilen wiederholt werden.
Puh, ich bin einfach zu sehr Anfänger.Meine Frage bleibt: Wie wählt Ruby für mich ein Objekt nach Name aus?
-
Ah OK, ich sehe den Fehler: Nicht alle Elemente in Sketchup haben jeweils einen Namen. Text-Objekte haben zum Beispiel keinen Namen. Gruppen und Komponenteninstanzen haben aber jeweils Namen, also muss die Prüfung des gerade iterierten Elements erweitert werden:
def zoom_to_object object_name Sketchup.active_model.entities.each do |entity| if entity.kind_of?(Sketchup;;Group) or entity.kind_of?(Sketchup;;ComponentInstance) if entity.name == object_name Sketchup.active_model.active_view.zoom entity break # ist zwar dreckig, bin heute aber mal faul end end end end # aufzurufen dann mit z. B. zoom_to_object "Stein"
Dazu muss noch gesagt werden, dass, wenn sich mehrere Objekte mit dem Namen "Stein" im Modell befinden, das Objekt angesprungen wird, welches zuerst gezeichnet/erstellt wurde.
azuby
-
@azuby said:
…
def zoom_to_object object_name > … > # aufzurufen dann mit z. B. zoom_to_object "Stein"
Aus den beiden Zeilen oben machte ich (unwissend) folgende Zeile:
def "Stein" object_name …
Und ich füge also azubys Zeilen mit meiner »Anpassung« in die Ruby-Konsole. Dort werden Zeile für Zeile Fehlermeldungen zurückgegeben.
Da habe ich wohl etwas vollkommen falsch verstanden. Soll ich erst eine Ruby-Datei daraus machen?
Ich stehe auf dem Schlauch.
Würde es helfen, die Fehlermeldungen hier aufzuführen?@unknownuser said:
def "Stein" object_name
^>
(eval):209Sketchup.active_model.entities.each do |entity|
Error: #<SyntaxError: (eval):209: compile error
(eval):209: parse error
Sketchup.active_model.entities.each do |entity|
^>
(eval):209
if entity.kind_of?(Sketchup::Group) or entity.kind_of?(Sketchup::ComponentInstance)
Error: #<SyntaxError: (eval):209: compile error
(eval):209: parse error, expectingkTHEN' or
':'' or'\n'' or
';''
if entity.kind_of?(Sketchup::Group) or entity.kind_of?(Sketchup::ComponentInstance)
^>
(eval):209
if entity.name == object_name
Error: #<SyntaxError: (eval):209: compile error
(eval):209: parse error, expectingkTHEN' or
':'' or'\n'' or
';''
if entity.name == object_name
^>
(eval):209
Sketchup.active_model.active_view.zoom entity
Error: #<NameError: undefined local variable or method `entity' for main:Object>
(eval):209
break
Error: #<LocalJumpError: (eval):209: unexpected break>
(eval):209
end
Error: #<SyntaxError: (eval):209: compile error
(eval):209: parse error
end
^>
(eval):209
end
Error: #<SyntaxError: (eval):209: compile error
(eval):209: parse error
end
^>
(eval):209
end
Error: #<SyntaxError: (eval):209: compile error
(eval):209: parse error
end
^>
(eval):209
end
Error: #<SyntaxError: (eval):209: compile error
(eval):209: parse error>
(eval):209 -
Ich habe keine Ahnung, warum du das machst - in zwei Beiträgen steht doch eindeutig:
# aufzurufen dann mit z. B. zoom_to_object "Stein"
azuby
-
Ich nochmal: Ich habe die Vermutung, du kommst mit dem Programmier-Konstrukt der -> Methoden noch nicht klar. Mal ein einfaches Beispiel, warum Methoden gut sind und wie man sie gebraucht (in Ruby wird eine Methode eingeleitet mit "def MEHTODENNAME ARGUMENT(E) ... end"):
Aufgabe: Verschiedene Flüssigkeiten sollen aus verschiedenen Behältern in verschiedene Gefäße gegossen werden. Man kann das folgendermaßen lösen, wie das auch die meisten Leute tun, wenn sie anfangen zu programmieren:
"Aufgabe: Gieße Kaffee aus einer Kanne in eine Tasse
Vorgehen: Nimm die Kaffeekanne, halte sie über den Rand der Tasse, schräge sie an, prüfe fortwährend die Füllhöhe in der Tasse, ...""Aufgabe: Gieße Putzwasser aus einem Eimer ins Klo
Vorgehen: Nimm den Eimer, halte ihn über den Rand ...""Aufgabe: Gieße Motoröl aus der Flasche in den Trabi-Benzintank
Vorgehen: Nimm die Flasche, halte sie über ..."Abstrakt ergibt sich
"Aufgabe: Gieße a aus b in c
Vorgehen: Nimm b, halte es über den Rand von c, ..."Das Abstrakte ist im Prinzip die Methode. Die muss man ja irgendwie ansprechen können, also kriegt sie einen Namen, z. B. "gieße" Man sagt über den Programmcode also: "Achtung, jetzt definiere ich eine Methode, die man danach verwenden kann, indem man sie über ihren Namen aufruft und ihr einige Argumente mitgibt"
Und für die o. g. drei Beispiele ergibt sich:
"Aufgabe: Gieße Kaffee (a) aus einer Kanne (b) in eine Tasse (c)
Vorgehen: gieße a, b, c"Für die Problematik hier im Thread bedeutet das, es gibt eine Methode zoom_to_object, deren Aufgabe es ist, zu einem Objekt zu zoomen. Der Methode ist egal, wie das Objekt konkret heißt oder ob es grün ist. Sie fordert nur, DASS es einen Namen hat und dass sie diesen Namen als Argument bekommt (klar, damit sie weiß, welches konkrete Objekt gemeint ist).
edit: Die Vorteile habe ich vergessen. Eine Methode stellt ein quasi standardisiertes Vorgehen dar, dass sich immer und immer wieder verwenden lässt. Man muss also den Algorithmus nicht für jede Zoom-Aktion neu notieren, sondern greift auf eine (hoffentliche funktionierende) Notation zurück. Das vereinfacht auch die Wartung. Wenn ich alles ständig "neu" schreiben muss - die meisten kopieren nur und ersetzen dann an einigen Stellen -, dann muss ich viel mehr tun, wenn doch irgendwo ein Fehler lauert. Stell dir vor, du hast 500 Zoom-Vorgänge und musstest den Algorithmus 500 Mal kopieren und anpassen. Dann musst du, sollte der Algorithmus doch fehlerhaft sein, an 500 Stellen eine Änderung machen. Bei Methodennutzung musst du das nur an einer Stelle - nämlich im Methoden-Rumpf.
azuby
-
@azuby said:
Ich habe keine Ahnung, warum du das machst - in zwei Beiträgen steht doch eindeutig:
# aufzurufen dann mit z. B. > zoom_to_object "Stein"
azuby
Ich lasse also in die Ruby-Konsole tippen:
def zoom_to_object "Stein" Sketchup.active_model.entities.each do |entity| if entity.kind_of?(Sketchup;;Group) or entity.kind_of?(Sketchup;;ComponentInstance) if entity.name == object_name Sketchup.active_model.active_view.zoom entity break end end end end
Und dann kommt folgende Ruby-Konsolen-Erfolgs-/Fehlermeldung:
@unknownuser said:
def zoom_to_object "Stein"
Sketchup.active_model.entities.each do |entity|
if entity.kind_of?(Sketchup::Group) or entity.kind_of?(Sketchup::ComponentInstance)
if entity.name == object_name
Sketchup.active_model.active_view.zoom entity
break
end
end
end
end
Error: #<SyntaxError: (eval):209: compile error
(eval):209: parse error, expecting'\n'' or
';''
def zoom_to_object "Stein"
Sketchup.active_model.entities.each do |entity|
if entity.kind_of?(Sketchup::Group) or entity.kind_of?(Sketchup::ComponentInstance)
if entity.name == object_name
Sketchup.active_model.active_view.zoom entity
break
end
end
end
end
^
(eval):209: parse error, expecting `$'
def zoom_to_object "Stein"
Sketchup.active_model.entities.each do |entity|
if entity.kind_of?(Sketchup::Group) or entity.kind_of?(Sketchup::ComponentInstance)
if entity.name == object_name
Sketchup.active_model.active_view.zoom entity
break
end
end
end
end
^>
(eval):209… und mein Stein ist nicht ausgewählt/markiert/mittig großgestellt. In meiner geöffneten SketchUp-Datei ist nichts passiert. Deshalb fing ich an herumzuhühnern.
Was muß ich denn nun richtiger machen?
Übrigens möchte ich mich noch sehr bedanken für Deine Bereitschaft, mir hier Grundlagen zu vermitteln. (Ich wußte ja noch nicht, daß eine Methode eingeklammert ist durch def … end.)4mal (eval):209, 2mal parse error, einmal SyntaxError, einmal compile error, 2mal expecting …
-
Du müsstest alle Zeilen, jeweils mit Semikolon getrennt, in eine Zeile schreiben. Ich hatte damals schon Zweifel angemeldet, Sketchup in der Art fernzusteuern, dass man quasi "auf der Oberfläche" "programmiert", so wie du das durch Nutzung von AppleScript tust. Die Ruby-Konsole ist nicht dazu geeignet, zu programmieren, sondern nur, um auszuführen, weil sie nur einzeilige Statement annehmen kann (ja, ich hatte natürlich mit d/Code einen entsprechenden Gegenvorschlag programmiert). Mir ist natürlich klar, dass es für die Mac-Version von Sketchup (noch) keine andere Möglichkeit gibt, unter der Oberfläche zu kommunizieren. Für die Windows-Version gibt es eine - ich glaube von TBD - programmierte EXE, die eine Schnittstelle nach außen ermöglicht und somit auch das "Einimpfen"/Aufrufen von Ruby-Code.
Sinnvoll wäre zu überlegen, den Code (ohne den "Auswähl-Schnipsel" (nach "z. B.")) in eine .rb-Datei auszulagern, die automatisch von Sketchup dann geladen wird, wenn man es startet. Dann muss nur noch der "Auswähl-Schnipsel" in die Konsole eingegeben werden.
Ich hatte dir zur Wiederverwendbarkeit gerade eben auch was geschrieben. Wenn du den gesamten Code bei jedem Aufruf aus FileMaker heraus in Sketchup eingibst, dann läuft das dem Prinzip der Wiederverwendbarkeit strikt entgegen aus Sicht von Sketchup. Denn jedes Mal (re-)definierst du die Methode aus Sketchup-Sicht neu. Sie sollte aber nur ein einziges Mal in Sketchup eingebracht und danach lediglich benutzt=aufgerufen werden. Oder anders: Die Funktionalität gehört NICHT zu (und in) FileMaker, sondern sie gehört zu Sketchup.
azuby
-
Vielleicht gehst du einfach mal die Lektionen von RubyKids durch, um dich mit der Sprache vertraut zu machen. Bitte nicht in Sketchup lernen, sondern in der Konsole / im Terminal (na wie auch immer das aufm Mac heißt). Mit der Eingabe "ruby -v" kannst du dort ermitteln, ob a) Ruby installiert ist und b) welche Version von Ruby installiert ist. Da die Lektionen für Windows sind, musst du etwas kreativer sein, was Pfade und Programme angeht. Beispielsweise lädt die Eingabe "nano" einen kleinen Editor, "nano meinedatei.txt" lädt den Editor und die im aktuellen Verzeichnis liegende Datei meinedatei.txt
azuby
-
Denk, denk. Dann muß ich eben über das Terminal gehen. Könnte noch systematischer werden. Ich stutze über die Mehrzeiler. Ist es wirklich so, daß die Ruby-Eingabezeile in SketchUp keine Mehrzahler vertragen kann? Ein ausgewähltes Objekt zu zoomen, ging doch schon mehrzeilig.
model = Sketchup.active_model sel = model.selection # have something selected model.active_view.zoom sel.first
Diese 3 Zeilen laufen einwandfrei.
So, dann muß ich jetzt Ruby für Kinder lernen …
-
Dein 3-Zeilen-Beispiel funktioniert nur deswegen in der Konsole, weil es drei voneinander unabhängige Zeilen sind, die jeweils von Sketchup-Ruby abgearbeitet werden. Eine Methode besteht aber aus folgenden Teilen:
def METHODENNAME ARGUMENTELISTE METHODENRUMPF end
Die Ruby-Konsole in Sketchup ist im Grunde äußerst doof. Sie kann nicht erkennen, dass, wenn du "def bla blubb" eingibst, es sich um den Anfang einer Methode handelt und die nächsten Zeilen dazu gehören, sodass sie mit der Ausführung der Zeilen noch warten muss. Sie nimmt einfach die Zeile und führt sie aus. "def bla blubb" ist aber kein valider Ruby-Code, wohingegen jede deiner 3 Zeilen valide ist. Auch d/Code ist so clever nicht, aber z. B. die IRB (Interaktive Ruby) kann das erkennen. Dazu gibst du in der Konsole / dem Terminal (also nicht in Sketchup) einfach mal: irb ein. Um dann damit aber weiterspielen zu können, musst du Ruby kennen.
Das heißt nur "RubyKids", es ist durchaus für alle Menschen nutzbar. Ansonsten kannst du dir natürlich auch ein Ruby-Buch kaufen bzw hier gucken.
azuby
-
@azuby said:
…
Sinnvoll wäre zu überlegen, den Code (ohne den "Auswähl-Schnipsel" (nach "z. B.")) in eine .rb-Datei auszulagern, die automatisch von Sketchup dann geladen wird, wenn man es startet. Dann muss nur noch der "Auswähl-Schnipsel" in die Konsole eingegeben werden.
…Meine .rb-Datei heißt Aar_zoom_to_object.rb und liegt im Plugins-Ordner neben zum Beispiel extentions.rb. In meiner .rb-Datei steht drin:
@unknownuser said:
azuby 2008-07
def zoom_to_object object_name
Sketchup.active_model.entities.each do |entity|
if entity.name == object_name
Sketchup.active_model.active_view.zoom entity
break # ist zwar dreckig, bin heute aber mal faul
end
end
endIch darf unterstellen, daß also diese Methode zoom_to_object beim SketchUp-Programmstart mitgeladen wird.
Tippe ich nun in die Ruby-Konsole in meiner SketchUp-Datei (die das Objekt "Stein" enthält):
zoom_to_object "Stein"
dann passiert leider nichts, außer folgende Meldung/Fehlermeldung:
@unknownuser said:
zoom_to_object "Stein"
Error: #<NoMethodError: undefined method `zoom_to_object' for main:Object>
(eval):209 -
@azuby said:
…
im Terminal
…
Eingabe "ruby -v"
…
gibt Rückmeldung:@unknownuser said:
ruby 1.8.2 (2004-12-25) [powerpc-darwin8.0]
RubyKids kann also losgehen. Danke bis hierhin.
-
@azuby said:
…
Da die Lektionen für Windows sind, musst du etwas kreativer sein, was Pfade und Programme angeht.
…Ja, require 'jcode! und require 'WIN32API' werden auf Mac naturgemäß nicht aufgelöst. Hm …
-
Ich kann nicht nachvollziehen, warum bei dir ein NoMethodError auftritt - habe es (unter Windows) mittlerweile zum dritten Mal probiert mit einer separaten Datei und es klappt. In deiner Datei steht darüber hinaus noch der etwas ältere Code ohne Objekttypenprüfung.
Gib mal, bevor du zoom_to_object "Stein" eingibst, vorher ein:
load "Aar_zoom_to_object.rb"
Nebenbei: require "jcode" sollte auch aufm Mac laufen, hatte vor einem Jahr auf dem System und mit dieser Bibliothek programmiert.
azuby
Advertisement