Napisano 1 Luty 201114 l 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
Napisano 15 Maj 201113 l Autor 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)
Napisano 16 Maj 201113 l Autor 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:)
Napisano 16 Maj 201113 l Autor 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)
Napisano 29 Czerwiec 201113 l zerknij na implementacje l-systemow w Houdinim. Moze one Cie jakos naprowadzą.
Napisano 14 Lipiec 201113 l Autor 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)
Napisano 15 Lipiec 201113 l a tak z czystej ciekawosci mozesz pokazac jak taka roslinka wygenerowana przez twoj skrypt wyglada? Sam nie mam Majki.,..
Napisano 21 Lipiec 201113 l Autor 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?
Napisano 13 Sierpień 201113 l 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ń 201113 l przez CgBartosz
Napisano 13 Sierpień 201113 l 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ń 201113 l przez CgBartosz
Napisano 14 Sierpień 201113 l Na moim kompie takie cos: maxscript i obiekty jako referencje = time:28.808 s 8 iteracji GeneratorLSystemuN.
Napisano 14 Sierpień 201113 l Autor 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.
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto