rakson23 Napisano 1 Luty 2011 Napisano 1 Luty 2011 Po sesji jako ze rozpoczynam ostatni semestr napisanie skryptu do mayki jest jedna z czesci pracy magisterskiej i tak sie zastanawiam czy ma ktos jakies informacje na temat pozycji książkowych o l-systemach oprocz algorytmic beauty of plants. Jeśli tak to z góry dzieki z pomoc
rakson23 Napisano 15 Maj 2011 Autor Napisano 15 Maj 2011 Jak już mówiłem, pracuje nad skryptem tworzącym roślinność przy pomocy l-systemów dla maya i teraz mam prośbe czy ktoś mógłby odpalić ten skrypt taki jak go wklejam i powiedziec czy sie nie wywalił? import pymel.core as pm import random poczatek=[0,0,0] alf=['F','[',']','+','-','V','^'] pozycjaX=0 pozycjaY=0 pozycjaZ=0 lista=[] class ParametryLSystemu: def __init__(self,prze,ka,oprze,oka): self.przesuniecie=prze self.katobrotu=ka self.odchyleniePrzesuniecia=oprze self.odchylenieKata=oka class GeneratorLSystemu: def __init__(self,iteracje,aksjomat,regula): if (iteracje>5): self.iter=5 else: self.iter=iteracje self.aks=aksjomat self.reg=regula def GenerujLString(self): lString="" while (self.iter>0): drzewo="" for i in range (len(self.aks)): if self.aks[i]=='F': drzewo=drzewo+self.reg else: drzewo=drzewo+self.aks[i] self.aks=drzewo self.iter=self.iter-1 return self.aks class InterpretatorLSystemu: def __init__(self,napis): self.ciag=napis def wypisz(self): print len(self.ciag) def sprawdzDlugosc(self): return len(self.ciag) def dodajKrzywa(self,indeks,dlugosc,odchyld): randomizacja=float(random.randint(-odchyld,odchyld)) dlugosc=float(dlugosc+(dlugosc*randomizacja/100)) #print dlugosc pm.curve (d=1,p=[(0, 0, 0),(0,dlugosc,0)], n='konar'+str(indeks)) def obroc(self,ostatni,kat,odchylk,znak): randomizacja=float(random.randint(-odchylk,odchylk)) kat=float(kat+(kat*randomizacja/100)) if (znak=='+'): pm.rotate (ostatni,[kat,0,0]) elif (znak=='-'): pm.rotate (ostatni,[-kat,0,0]) elif (znak=='^'): pm.rotate (ostatni,[0,0,kat]) elif (znak=='V'): pm.rotate (ostatni,[0,0,-kat]) def ustawRelacje(self,dziecko,rodzic): pm.parent (dziecko,rodzic, relative=True) def sprawdzZnak(self,indeks): znak=self.ciag[indeks] return znak def sprawdzPozycje(self,nazwa): infoNode=pm.pointOnCurve (nazwa,ch=True,pr=1) pozycjaX= pm.getAttr(infoNode+".positionX") pozycjaY= pm.getAttr(infoNode+".positionY") pozycjaZ= pm.getAttr(infoNode+".positionZ") return pozycjaX,pozycjaY,pozycjaZ def odlozNaStos(self,ostat): lista.append(ostat) def pobierzZeStosu(self): ost=lista.pop() return ost def interpretujLString(self,przes,obr,odchp,odchk): igalezi=0 i=0 pozycjaX=0 pozycjaY=0 pozycjaZ=0 pm.createNode('transform', n='korzen') ostatni='korzen' przedostatni='' dlugoscLString=self.sprawdzDlugosc() przesuniecie=przes katobr=obr odchylk=odchk odchylprze=odchp while(i aktualnyZnak=self.sprawdzZnak(i) print 'znak nr: ',i+1,' z: ',dlugoscLString if (aktualnyZnak=='F'): self.dodajKrzywa(igalezi,przesuniecie,odchylprze) przedostatni=ostatni ostatni='konar'+str(igalezi) self.ustawRelacje(ostatni,przedostatni) pozycja=self.sprawdzPozycje('konar'+str(igalezi)) pozycjaX=pozycja[0] pozycjaY=pozycja[1] pozycjaZ=pozycja[2] igalezi=igalezi+1 pm.createNode('transform', n='wezel'+str(i)) przedostatni=ostatni ostatni='wezel'+str(i) self.ustawRelacje(ostatni,przedostatni) pm.move (ostatni,pozycjaX,pozycjaY,pozycjaZ) elif (aktualnyZnak=='+' or aktualnyZnak=='-' or aktualnyZnak=='^' or aktualnyZnak=='V'): self.obroc(ostatni,katobr,odchylk,aktualnyZnak) elif (aktualnyZnak=='['): pm.createNode ('transform', n='wezel'+str(i)) self.odlozNaStos(ostatni) przedostatni=ostatni ostatni='wezel'+str(i) self.ustawRelacje(ostatni,przedostatni) elif (aktualnyZnak==']'): print przedostatni, ostatni ostatni=self.pobierzZeStosu() i=i+1 drzewo=GeneratorLSystemu(8,"F","F+F−F−F+F") string=drzewo.GenerujLString() parametry=ParametryLSystemu(10,90,0,0) interpretacja=InterpretatorLSystemu(string) interpretacja.interpretujLString(parametry.przesuniecie,parametry.katobrotu,parametry.odchyleniePrzesuniecia,parametry.odchylenieKata)
rakson23 Napisano 16 Maj 2011 Autor Napisano 16 Maj 2011 ok, juz po problemie. ot to taka przypadlosc windows 7 ze jak maya nie odpowiada przy wykonaniu skryptu to ja wywala:P sposob prosty sub-process i wszystko smiga:)
rakson23 Napisano 16 Maj 2011 Autor Napisano 16 Maj 2011 Niestety, na L-systemy dla mayki przyjdzie troche poczekac, ze wzgledu na potrzebe przepisania kodu z pymel(jak sie okazalo wolny diabelnie) do mrv(szybszy wiec moze 70tys iteracji zadziala)
bareja Napisano 29 Czerwiec 2011 Napisano 29 Czerwiec 2011 zerknij na implementacje l-systemow w Houdinim. Moze one Cie jakos naprowadzą.
rakson23 Napisano 14 Lipiec 2011 Autor Napisano 14 Lipiec 2011 Po drobnej przerwie wracam do skryptu. Właściwie to przepisałem dużą część od początku, oprócz krawędziowego przepisywania reguł dodałem węzłowe, raczej nie ma już problemu z wywalaniem się skryptu(chociaż nie próbowałem z jakimiś ogromnymi długościami L-Stringa). Generator w chwili obecnej zamiast liści i kwiatów wstawia w ich miejscu plane więc spokojnie z reguł można wyrzucić litery L i K jeśli jakieś są. Oprócz tego nie ma jeszcze GUI, ale to dlatego, że to będzie napisane jako ostatnie. W chwili obecnej zajmuje się implementacją parametrycznych L-Systemów w skrypcie i na tych chyba zakończę pracę nad tą wersją skryptu. A tym czasem zapraszam do testowania. import pymel.core as pm import random alf=['F','[',']','+','-','V','^',''] lista=[] class ParametryLSystemu: def __init__(self,przes,kat,oprzes,okat): self.przesuniecie=przes self.katobrotu=kat self.odchyleniePrzesuniecia=oprzes self.odchylenieKata=okat class obiektStos: def __init__(self,pozycjaX,pozycjaY,pozycjaZ,rotacjaX,rotacjaY,rotacjaZ): self.pozX=pozycjaX self.pozY=pozycjaY self.pozZ=pozycjaZ self.rotX=rotacjaX self.rotY=rotacjaY self.rotZ=rotacjaZ class GeneratorLSystemuE: def __init__(self,iteracje,aksjomat,reguly): if (iteracje>7): self.iter=7 else: self.iter=iteracje self.aks=aksjomat self.reg=reguly def GenerujLStringE(self): lString="" while (self.iter>0): drzewo="" aktualna=random.randint(0,len(self.reg)-1) for i in range (len(self.aks)): if self.aks[i]=='F': drzewo=drzewo+self.reg[aktualna] else: drzewo=drzewo+self.aks[i] self.aks=drzewo self.iter=self.iter-1 return self.aks class GeneratorLSystemuN: def __init__(self,iteracje,aksjomat,reguly): if (iteracje>7): self.iter=7 else: self.iter=iteracje self.aks=aksjomat self.reg=reguly def GenerujLStringN(self): lString="" while (self.iter>0): drzewo="" for i in range (len(self.aks)): if self.aks[i]=='F': drzewo=drzewo+self.reg[0] elif self.aks[i]=='Z': drzewo=drzewo+self.reg[1] elif self.aks[i]=='X': drzewo=drzewo+self.reg[2] elif self.aks[i]=='C': drzewo=drzewo+self.reg[3] elif self.aks[i]=='V': drzewo=drzewo+self.reg[4] elif self.aks[i]=='B': drzewo=drzewo+self.reg[5] elif self.aks[i]=='N': drzewo=drzewo+self.reg[6] elif self.aks[i]=='M': drzewo=drzewo+self.reg[7] else: drzewo=drzewo+self.aks[i] self.aks=drzewo self.iter=self.iter-1 return self.aks class InterpretatorLSystemu: def __init__(self,napis): self.ciag=napis def wypisz(self): print len(self.ciag) def sprawdzDlugosc(self): return len(self.ciag) def dodajKrzywa(self,indeks,dlugosc): pm.curve (d=1,p=[(0, 0, 0),(0,dlugosc,0)], n='konar'+str(indeks)) def dodajCylinder (self,indeks,dlugosc): pm.polyCylinder(n='konar'+str(indeks),h=dlugosc,r=0.25) pm.move('konar'+str(indeks),0,dlugosc/2.0,0) pm.polyDelFacet('konar'+str(indeks)+'.f[20]','konar'+str(indeks)+'.f[21]') pm.makeIdentity('konar'+str(indeks),apply=True, t=1) def randomdlugosci(self,dlugosc,odchyld): randomizacja=float(random.randint(-odchyld,odchyld)) dlugosc=float(dlugosc+(dlugosc*randomizacja/100)) return dlugosc def randomKata(self,kat,odchylk): randomizacja=float(random.randint(-odchylk,odchylk)) kat=float(kat+(kat*randomizacja/100.0)) return kat def dodajLisc(self,indeks): pm.polyPlane(n='lisc'+str(indeks),sw=1,sh=1) def dodajKwiat(self,indeks): pm.polyPlane(n='kwiat'+str(indeks),sw=1,sh=1) def dodajGeometrie(self,indeks,dlugosc,rodzaj): if (rodzaj=='krzywa'): self.dodajKrzywa(indeks,dlugosc) elif (rodzaj=='cylinder'): self.dodajCylinder(indeks,dlugosc) def obroc(self,kat,odchylk,znak): randomizacja=float(random.randint(-odchylk,odchylk)) kat=float(kat+(kat*randomizacja/100)) print kat if (znak=='+'): pm.rotate ('pomocnik',[kat,0,0],relative=True,objectSpace=True) elif (znak=='-'): pm.rotate ('pomocnik',[-kat,0,0],relative=True,objectSpace=True) elif (znak=='^'): pm.rotate ('pomocnik',[0,0,kat],relative=True,objectSpace=True) elif (znak=='&'): pm.rotate ('pomocnik',[0,0,-kat],relative=True,objectSpace=True) elif (znak==' pm.rotate ('pomocnik',[0,kat,0],relative=True,objectSpace=True) elif (znak=='>'): pm.rotate ('pomocnik',[0,-kat,0],relative=True,objectSpace=True) def sprawdzZnak(self,indeks): znak=self.ciag[indeks] return znak def odlozNaStos(self,ostat): lista.append(ostat) def pobierzZeStosu(self): ost=lista.pop() return ost.pozX,ost.pozY,ost.pozZ,ost.rotX,ost.rotY,ost.rotZ def interpretujLString(self,przes,obr,odchp,odchk): igalezi=0 iliscia=0 ikwiata=0 i=0 dlugoscLString=self.sprawdzDlugosc() przesuniecie=przes katobr=obr odchylk=odchk odchylprze=odchp dlug=0 pm.spaceLocator(n='pomocnik') while(i aktualnyZnak=self.sprawdzZnak(i) dlug=self.randomdlugosci(przesuniecie,odchylprze) if (aktualnyZnak=='F'): self.dodajCylinder(igalezi,dlug) pm.parent('konar'+str(igalezi),'pomocnik',relative=True) pm.parent('konar'+str(igalezi),world=True) pm.delete('pomocnik') pm.spaceLocator(n='pomocnik') pm.parent('pomocnik','konar'+str(igalezi),relative=True) pm.move('pomocnik',0,dlug,0,objectSpace=True) pm.parent('pomocnik', world=True) igalezi=igalezi+1 print 'KONAR' elif (aktualnyZnak=='+' or aktualnyZnak=='-' or aktualnyZnak=='^' or aktualnyZnak=='&' or aktualnyZnak=='>' or aktualnyZnak==' self.obroc(katobr,odchylk,aktualnyZnak) elif(aktualnyZnak=='['): pX=pm.getAttr('pomocnik.translateX') pY=pm.getAttr('pomocnik.translateY') pZ=pm.getAttr('pomocnik.translateZ') rX=pm.getAttr('pomocnik.rotateX') rY=pm.getAttr('pomocnik.rotateY') rZ=pm.getAttr('pomocnik.rotateZ') doOdlozenia=obiektStos(pX,pY,pZ,rX,rY,rZ) self.odlozNaStos(doOdlozenia) elif(aktualnyZnak==']'): zdjety=self.pobierzZeStosu() pm.setAttr('pomocnik.translateX',zdjety[0]) pm.setAttr('pomocnik.translateY',zdjety[1]) pm.setAttr('pomocnik.translateZ',zdjety[2]) pm.setAttr('pomocnik.rotateX',zdjety[3]) pm.setAttr('pomocnik.rotateY',zdjety[4]) pm.setAttr('pomocnik.rotateZ',zdjety[5]) elif(aktualnyZnak=='L'): self.dodajLisc(iliscia) pm.parent('lisc'+str(iliscia),'pomocnik',relative=True) pm.parent('lisc'+str(iliscia),world=True) iliscia=iliscia+1 print 'LISC' elif(aktualnyZnak=='K'): self.dodajKwiat(ikwiata) pm.parent('kwiat'+str(ikwiata),'pomocnik',relative=True) pm.parent('kwiat'+str(ikwiata),world=True) ikwiata=ikwiata+1 print 'KWIAT' else: print 'INNY ZNAK' i=i+1 regulyE=["F[+F]F[-F]F"] regulyN=["XdrzewoE=GeneratorLSystemuE(3,"F",regulyE) stringE=drzewoE.GenerujLStringE() drzewoN=GeneratorLSystemuN(7,"Z",regulyN) stringN=drzewoN.GenerujLStringN() parametry=ParametryLSystemu(5,20.5,50,75) interpretacja=InterpretatorLSystemu(stringN) interpretacja.interpretujLString(parametry.przesuniecie,parametry.katobrotu,parametry.odchyleniePrzesuniecia,parametry.odchylenieKata) 1
goat91 Napisano 15 Lipiec 2011 Napisano 15 Lipiec 2011 a tak z czystej ciekawosci mozesz pokazac jak taka roslinka wygenerowana przez twoj skrypt wyglada? Sam nie mam Majki.,..
rakson23 Napisano 21 Lipiec 2011 Autor Napisano 21 Lipiec 2011 Jak będą wyglądały wygenerowane drzewa pokaże jak skończe skrypt, pewnie po obronie wrzuce go na forum ku miejmy nadzieje uciesze gawiedzi, ale teraz mam drobny problem. Po poczytaniu porad i zastosowaniu sie do nich w houdinim odnalazlem cos takiego: $(x,y,z) - Rotates the turtle so the up vector is (0,1,0). Points the turtle in the direction of the point (x,y,z). Default behavior is only to orient and not to change the direction. Wie ktos jak uzyskać cos takiego w pymel ewentualnie python?
CgBartosz Napisano 13 Sierpień 2011 Napisano 13 Sierpień 2011 (edytowane) Przepisalem sobie to na maxscript bo nie mam majki i cos tam sie generuje. Ciekawszy wydaje sie GeneratorLSystemuN. Bardzo fajne !! Uwagi mam tylko do kodu ale rozumiem, ze nie jest skonczony ,wiec sie z nimi wstrzymam :) Mozesz zoptymalizowac na przyklad klase ObiektStos poprzez uzycie __slots__ pythonowych. Znajdziesz opisy w sieci. Trzymam w ObiektStos tylko macierz transformacji przez co zniknelo ze 20 linijek kodu Edytowane 13 Sierpień 2011 przez CgBartosz
CgBartosz Napisano 13 Sierpień 2011 Napisano 13 Sierpień 2011 (edytowane) moje 3 grosze :) zamiast tego: if self.aks[i]=='F': drzewo=drzewo+self.reg[0] elif self.aks[i]=='Z': drzewo=drzewo+self.reg[1] elif self.aks[i]=='X': drzewo=drzewo+self.reg[2] elif self.aks[i]=='C': drzewo=drzewo+self.reg[3] elif self.aks[i]=='V': drzewo=drzewo+self.reg[4] elif self.aks[i]=='B': drzewo=drzewo+self.reg[5] elif self.aks[i]=='N': drzewo=drzewo+self.reg[6] elif self.aks[i]=='M': drzewo=drzewo+self.reg[7] ... mozesz zastosowac taki sposob: _dict = {'F':0,'Z':1,'X':2,'C':3,'V':4,'B':5,...} _index = self._dict[self.aks[i]] drzewo=drzewo+self.reg[_index] _dict moze byc atrybutem klasy. Troche to poprawi czytelnosc kodu. unikaj dodawania stringow w ten sposob: drzewo = drzewo+ jakisstring Szczegolnie w petlach moze byc wolo. Szybciej jest tak: strinsArr = [str(i) for i in xrange(0,1000)] #list comprehension drzewo = ''.join(strinsArr) ...takze xrange jest szybsze od range. tu zamiast tak: if (znak=='+'): pm.rotate ('pomocnik',[kat,0,0],relative=True,objectSpace=True) elif (znak=='-'): pm.rotate ('pomocnik',[-kat,0,0],relative=True,objectSpace=True) elif (znak=='^'): pm.rotate ('pomocnik',[0,0,kat],relative=True,objectSpace=True) elif (znak=='&'): pm.rotate ('pomocnik',[0,0,-kat],relative=True,objectSpace=True) elif (znak==' pm.rotate ('pomocnik',[0,kat,0],relative=True,objectSpace=True) elif (znak=='>'): pm.rotate ('pomocnik',[0,-kat,0],relative=True,objectSpace=True) mozna chyba tak: def GetVector(_key,_angle): _dict = {'+':[_angle,0,0],'-':[-_angle,0,0], '^':[0,0,_angle],'&':[0,0,-_angle], '':[0,-_angle,0]} return _dict[_key] def RotateNode(_nodeName, _key, _angle, relative=True, objectSpace=True ): pm.rotate(_nodeName,GetVector(_key,_angle),relative=relative,objectSpace=objectSpace) i wywolujesz: RotateNode('pomocnik', _key, _angle ) Nie moglem sie powstrzymac :D Mam nadzieje, ze to tez troche pomoze w Twojej pracy magisterskiej :) Edytowane 13 Sierpień 2011 przez CgBartosz
CgBartosz Napisano 14 Sierpień 2011 Napisano 14 Sierpień 2011 Na moim kompie takie cos: maxscript i obiekty jako referencje = time:28.808 s 8 iteracji GeneratorLSystemuN.
rakson23 Napisano 14 Sierpień 2011 Autor Napisano 14 Sierpień 2011 Na moim kompie takie cos: maxscript i obiekty jako referencje = time:28.808 s 8 iteracji GeneratorLSystemuN. predkosc juz rozwiazana;) zajmuje okolo 20 sekund w zaleznosci od reguly, teraz robie szlify do mgr i pisze prace, po obronie bedzie dalszy development, dodana bedzie filotaksja itd. teraz same drzewa bedzie generowac pozniej dowolne rosliny.
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się