Objekt auswählen und vervielfachen Blender

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
55john
User
Beiträge: 8
Registriert: Samstag 13. Mai 2017, 16:32

Hey liebe Mitglieder,

ich sitz' jetzt schon seit Stunden hier und überlege, wo mein Fehler liegt..
Im ersten Teil habe ich ein Haus "gebaut", welches dann mit der for-Schleife entlang der Y-Achse mit einem Abstand vervielfacht werden soll. Idee des Ganzen soll es sein, ein kleines Dorf zu bauen, aber Blender spuckt immer nur "Python script fail, look in the console for now..." aus, sobald ich die letzte Codezeile geschrieben habe. Hoffe mir kann jemand helfen!

Code: Alles auswählen

# Bibliothek mit Blender Funktionen
import bpy
import math
# einen Link auf die aktuelle Szene
Dorf = bpy.context.scene
def haus(kantenlaenge):
    #Punkte aus (x,y,z) erstellen   
    punkte = [(0,0,0),(0,2,0),(4,2,0),(4,0,0),(0,0,2),(0,2,2),(4,2,2),(4,0,2),(1,1,3),(3,1,3)]
    #Kanten aus Punktnummern erstellen
    kanten = [(0,1),(1,2),(2,3),(3,0),(0,4),(1,5),(2,6),(3,7),(4,5),(5,6),(6,7),(7,4),(4,8),(5,8),(8,9),(9,7),(9,6)]
    #Flächen aus Punktnummern erstellen z.B.: (Punkt Nummer 1,Punkt Nummer2,...)
    flaechen = [(1,5,4,0),(2,6,5,1),(3,7,6,2),(0,4,7,3),(8,4,5),(7,9,6),(7,4,8,9),(6,9,8,5)]
    #Netz erstellen
    pyramiden_netz = bpy.data.meshes.new("haus")
    pyramiden_netz.from_pydata(punkte, kanten, flaechen)
    #Objekt erstellen und benennen
    haus_objekt = bpy.data.objects.new("haus",pyramiden_netz)
    #Objekt in die Szene setzen
    Dorf.objects.link(haus_objekt)
#mit der neuen Funktion ein Objekt erstellen    
haus(1)
for i in range(1,5):
    haus(1)
    letztes_haus = bpy.context.object
    letzteshaus.location = (0,i*3,0)
BlackJack

@55john: Was wird denn in der Konsole ausgegeben? Und damit ist nicht die Python-Konsole gemeint, sondern die Konsole von der aus man Blender gestartet hat. Was also erfordert das man Blender aus einer Konsole heraus startet.
beertonic
User
Beiträge: 37
Registriert: Montag 8. Mai 2017, 15:26

Du übergibst kantenlaenge, aber du benutzt es nicht. Davon abgesehen versuch mal

Code: Alles auswählen

Dorf = bpy.context.scene
in zeile 18 zu verschieben.
55john
User
Beiträge: 8
Registriert: Samstag 13. Mai 2017, 16:32

[codebox=dos file=Unbenannt.bat]read blend: G:\Scripting\PyrAmide\neueshaus.blend
Traceback (most recent call last):
File "G:\Scripting\PyrAmide\neueshaus.blend\Text", line 25, in <module>
AttributeError: 'NoneType' object has no attribute 'location'[/code]

Anscheinen weiß der nicht mit der .location anzufangen :K
55john
User
Beiträge: 8
Registriert: Samstag 13. Mai 2017, 16:32

Kantenlänge habe ich jetzt wie folgt eingebaut:

Code: Alles auswählen

def haus(kantenlaenge):
    #Punkte aus (x,y,z) erstellen   
    punkte = [(0,0,0),(kantenlaenge,0,0),(kantenlaenge,kantenlaenge,0),(0,kantenlaenge,0),(0.5,0.5,kantenlaenge),(0,0,-1),(kantenlaenge,0,-1),(kantenlaenge,kantenlaenge,-1),(0,kantenlaenge,-1)]
    #Kanten aus Punktnummern erstellen
    kanten = [(0,1),(1,2),(2,3),(3,0),(0,4),(1,4),(2,4),(3,4),(0,5),(1,6),(2,7),(3,8),(5,6),(6,7),(7,8),(8,5)]
    #Flächen aus Punktnummern erstellen z.B.: (Punkt Nummer 1,Punkt Nummer2,...)
    flaechen = [(0,3,2,1),(0,1,4),(1,2,4),(2,3,4),(3,0,4),(5,8,7,6),(0,5,6,1),(6,1,2,7),(7,2,3,8),(3,0,5,8)]
    #Netz erstellen
    pyramiden_netz = bpy.data.meshes.new("haus")
    pyramiden_netz.from_pydata(punkte, kanten, flaechen)
    #Objekt erstellen und benennen
    haus_objekt = bpy.data.objects.new("haus",pyramiden_netz)
    #Objekt in die Szene setzen
    Dorf.objects.link(haus_objekt)
beertonic
User
Beiträge: 37
Registriert: Montag 8. Mai 2017, 15:26

Wie soll dein Haus überhaupt aussehen? Ein Würfelmit Spitzdach?
Dann müssten es 10 Punkte, 15 Kanten und 9 Flächen sein.

Mal am besten erstmal nur ein Haus wenn das funktioniert kannst du mehrere malen.
55john
User
Beiträge: 8
Registriert: Samstag 13. Mai 2017, 16:32

@beertonic Ja ich habe mich jetzt erstmal auf ein würfelförmiges Haus mit Spitzdach beschränkt. Aber das ist ja erst einmal nebensächlich. Warum bei letzteshaus.location (den Unterstrich aus Zeile 24 hab ich schon entfernt^^) rumgemeckert wird, ist mir noch ein Rätsel :?:
beertonic
User
Beiträge: 37
Registriert: Montag 8. Mai 2017, 15:26

Hast du mal

Code: Alles auswählen

Dorf = bpy.context.scene
in der haus funktion probiert?

Code: Alles auswählen

letztes_haus = bpy.context.object
funktioniert offensichtlich nicht deswegen kriegst du den AttributeError.
55john
User
Beiträge: 8
Registriert: Samstag 13. Mai 2017, 16:32

Wenn ich

Code: Alles auswählen

Dorf = bpy.context.scene
nach Zeile 18 verschiebe ändert sich nichts :(

Wie schaffe ich es, die Variabel "letztes_haus" dem letzt erstelltem Objekt zu zuweisen, so dass ich die location dann mit meiner Funktion (1, i*3,1)beschreiben kann?
beertonic
User
Beiträge: 37
Registriert: Montag 8. Mai 2017, 15:26

Code: Alles auswählen

bpy.context.object
ist eine Liste oder Dict. Versuch mal

Code: Alles auswählen

letztes_haus = bpy.context.object['haus']
55john
User
Beiträge: 8
Registriert: Samstag 13. Mai 2017, 16:32

@beertonic

Code: Alles auswählen

TypeError: 'NoneType' object is not subscriptable
Ohne Erfolg...
beertonic
User
Beiträge: 37
Registriert: Montag 8. Mai 2017, 15:26

Ist bpy.context.object leer?
gib mal

Code: Alles auswählen

print(bpy.context.object)
vor dem .loccation ein und poste was dann kommt
55john
User
Beiträge: 8
Registriert: Samstag 13. Mai 2017, 16:32

[codebox=dos file=Unbenannt.bat]None
Traceback (most recent call last):
File "G:\Scripting\PyrAmide\neueshaus.blend\Text", line 26, in <module>
AttributeError: 'NoneType' object has no attribute 'location'
Error: Python script fail, look in the console for now...[/code]
beertonic
User
Beiträge: 37
Registriert: Montag 8. Mai 2017, 15:26

Code: Alles auswählen

hauser = []
loca = Vector((0,0,0)) #startpunkt
vec =  Vector((0,10,0)) #abstand zwischen hauspunkten
def haus(name,kantenlaenge, loca):
    ...
    pyramiden_netz = bpy.data.meshes.new(name)
    haus_objekt = bpy.data.objects.new(name,pyramiden_netz)
    haus_objekt.location = loca
    dorf = bpy.context.scene
    dorf.objects.link(haus_objekt)
    dorf.objects.active = haus_objekt
    haus_objekt.select = True
    pyramiden_netz.from_pydata(punkte, kanten, flaechen)
    pyramiden_netz.update()
    return haus_objekt
    

for n in range(5):
	hauser.append(haus(('haus'+str(n)), kantenlaenge,loca)
	loca += vec
Das sollte funktionieren, guck dir mal den Link an:
https://wiki.blender.org/index.php/Dev: ... te_objects
55john
User
Beiträge: 8
Registriert: Samstag 13. Mai 2017, 16:32

Code: Alles auswählen

def haus(kantenlaenge):
    #Punkte aus (x,y,z) erstellen   
    punkte = [(0,0,0),(kantenlaenge,0,0),(kantenlaenge,kantenlaenge,0),(0,kantenlaenge,0),(0.5,0.5,kantenlaenge),(0,0,-1),(kantenlaenge,0,-1),(kantenlaenge,kantenlaenge,-1),(0,kantenlaenge,-1)]
    #Kanten aus Punktnummern erstellen
    kanten = [(0,1),(1,2),(2,3),(3,0),(0,4),(1,4),(2,4),(3,4),(0,5),(1,6),(2,7),(3,8),(5,6),(6,7),(7,8),(8,5)]
    #Flächen aus Punktnummern erstellen z.B.: (Punkt Nummer 1,Punkt Nummer2,...)
    flaechen = [(0,3,2,1),(0,1,4),(1,2,4),(2,3,4),(3,0,4),(5,8,7,6),(0,5,6,1),(6,1,2,7),(7,2,3,8),(3,0,5,8)]
    #Netz erstellen
    pyramiden_netz = bpy.data.meshes.new("haus")
    pyramiden_netz.from_pydata(punkte, kanten, flaechen)
    #Objekt erstellen und benennen
    haus_objekt = bpy.data.objects.new("haus",pyramiden_netz)
    #Objekt in die Szene setzen
    Dorf.objects.link(haus_objekt)
    Dorf.objects.active = haus_objekt
    haus_objekt.select = True
#mit der neuen Funktion ein Objekt erstellen    
for n in range(1,5):
    haus(1)
    haus = bpy.context.object
    haus.location = (1,n*3,0)
Habe meinem Lehrer per Email geschrieben und nachgefragt...
Zeile 15 & 16 sind dabei wichtig.
Danke dir/euch aber für das Opfern deiner Zeit für meine Probleme :)
beertonic
User
Beiträge: 37
Registriert: Montag 8. Mai 2017, 15:26

Wie unterscheidest du die Häuser wenn sie alle 'haus' heißen? Und wie greifst du auf ein bestimmtes Haus zu?
Antworten