3D-s számítógépes geometria és alakzatrekonstrukció Tesztkörnyezet II http://cg.iit.bme.hu/portal/node/312 https://portal.vik.bme.hu/kepzes/targyak/viiima01 Dr. Várady Tamás, Dr. Salvi Péter BME, Villamosmérnöki és Informatikai Kar Irányítástechnika és Informatika Tanszék
Tartalom Poligonhálók reprezentációja Fájlformátumok Fél-él adatstruktúra OpenMesh könyvtár Osztály definiálása Iterátorok, cirkulátorok libqglviewer/opengl Kamera használata Megjelenítési módok (wireframe / solid)
Második fázis Mit tud? Háromszöghálók beolvasása STL és PLY fájlformátum Megjelenítés W: wireframe ON/OFF S: solid ON/OFF Ehhez: Qt [menü, fájlnyitás-dialógus] OpenGL [megjelenítés] OpenMesh Hatékony háromszögháló implementáció Standard fájlformátumok kezelése
Poligonhálók reprezentációja Hogyan érdemes tárolni......fájlokban? [a méret a lényeg]...a memóriában? [a használhatóság a lényeg] Triviális megoldás (háromszögekre): T1Ax, T1Ay, T1Az, T1Bx, T1By, T1Bz, T1Cx, T1Cy, T1Cz T2Ax, T2Ay, T2Az, T2Bx, T2By, T2Bz, T2Cx, T2Cy, T2Cz... TnAx, TnAy, TnAz, TnBx, TnBy, TnBz, TnCx, TnCy, TnCz Pl. STL formátum Mi ezzel a probléma? Nincs topológiai információ Ugyanaz a vertex többször szerepel
Ügyesebb reprezentáció Minden vertexet egyszer tárol Hivatkozás indexekkel Például (PLY formátum): [...header...] P1x P1y P1z P2x P2y P2z... Pmx Pmy Pmz 3 T1A T1B T1C 3 T2A T2B T2C... 3 TnA TnB TnC Obj, VTK formátumok hasonló elven Fájlban tárolásra jó, de kevés topológiai információ
Milyen a jó adatstruktúra? Hatékony műveletek nagy háromszöghálókra Lekérdezések Topológiai (szomszédsági információk) Geometriai (koordináták, szögek, élhosszak) Átstrukturáló operációk (pl. éltörlés) Egyéb műveletek Normális- és görbületbecslés Adott sugáron belüli pontok kigyűjtése Univerzális n-oldalú lapok Külső és belső hurkok (lyukak)
Fél-él adatstruktúra Irányított élpárok, orientált felületek Az anyag a baloldalon Csúcs: Egy (tetszőleges) fél-él Koordináták stb. Fél-él: Kezdőpont Pár ( twin, mindig létezik) Lap (ha van) Előző és/vagy következő fél-él Lap: egy fél-él minden hurokhoz
Ujjgyakorlat Hol vannak az alábbi háromszöghálón a fél-élek? (satírozás lyuk)
Ujjgyakorlat Hol vannak az alábbi háromszöghálón a fél-élek? (satírozás lyuk)
Fejgyakorlat Egy fél-él adatstruktúra alapján... Hogyan gyűjtjük össze egy csúcs körüli szomszédos csúcsokat? Hogyan gyűjtjük össze egy csúcs körüli szomszédos lapokat? Hogyan találjuk meg, és hogyan megyünk végig a mesh határán? (ha nincsenek lyukak)
Fejgyakorlat Egy fél-él adatstruktúra alapján... Hogyan gyűjtjük össze egy csúcs körüli szomszédos csúcsokat? első csúcs: a félél párjának kezdőpontja köv. félél: a pár rákövetkező félélje köv. csúcs: az új félélből hasonlóan... Hogyan gyűjtjük össze egy csúcs körüli szomszédos lapokat? Ugyanaz, kezdőpont helyett lap Hogyan találjuk meg, és hogyan megyünk végig a mesh határán? (ha nincsenek lyukak) első félél: ahol nincs lap köv. félél: a rákövetkező (!)
OpenMesh Honlap: http://www.openmesh.org/ RWTH Aachen egyetem (Leif Kobbelt) Általános és hatékony reprezentáció Poligonhálók Fél-él struktúra Alapvető algoritmusok Pl. normálbecslés, decimálás, simítás Fontosabb fájlformátumok támogatása STL, PLY, OBJ, IGES stb. Lightweight (vö. CGAL, OpenCascade) Dokumentáció: szűkszavú, de van sok példa
Az OpenMesh használata Mesh = TriMesh/PolyMesh + Kernel + Traits Kernel: belső tárolás (pl. ArrayKernel) Traits: testreszabás Koordináták, pontok típusai Plusz információk hozzárendelése Példa:
Egyéb hasznos funkciók Bejárás [bővebben később] Iterátorok (csúcsok, (fél)élek, lapok) Cirkulátorok (pl. VertexFaceIter) Fájlbeolvasás OpenMesh::IO::read_mesh(mesh, filename) Fájlformátumot automatikusan felismeri Normálisok hozzárendelése (lap/csúcs) request_face_normals / request_vertex_normals Csak lefoglalja a helyet update_face_normals / update_vertex_normals Ez végzi el a tényleges számolást
MyWindow.cpp: Fájlnyitás GUI
MyViewer.h: Fájlnyitás Geometria MyViewer.cpp:
Megjelenítés Feladatok: Kamera ráirányítása az objektumra Befoglaló doboz (bounding box) Megjelenítési módok Tárolás, rajzolás megfelelő módosítása Billentyű-lenyomásra váltás Háromszögek kirajzolása Ehhez: iterátor (lapokon), cirkulátor (csúcsokon) STL-jellegű Iterátor: MyMesh::[Const]FaceIter stb. Range objektum: mesh.faces() / mesh.vertices() stb. Cirkulátor: MyMesh::[Const]FaceVertexIter stb. Range objektum: mesh.fv_range(), mesh.vih_range() stb. A range-ek indexeken (...Handle) mennek végig
MyViewer.cpp Kamera-beállítás: Kirajzolás:
MyViewer.h: Megjelenítési módok MyViewer.cpp:
glpolygonmode Wireframe vs. Solid Csak wireframe GL_FRONT_AND_BACK, GL_LINE Különben GL_FRONT_AND_BACK, GL_FILL Solid + wireframe problémás Kétszer kell kirajzolni Egyszer a kitöltött, fehér, árnyalt háromszögeket Egyszer csak a fekete körvonalakat A másodiknál ki kell kapcsolni a világítást Meg kell akadályozni, hogy egymásba essenek glenable(gl_polygon_offset_fill) glpolygonoffset(1, 1)
A teljes draw()