Let’s Import Meshes!
Computer Graphics
Marco Tarini
Università dell’Insubria Corso di Laurea in Informatica Anno Accademico 2014/15
Mesh import Piano:
1. procurarsi alcune mesh, in formati standard
• .OBJ, .PLY, .OFF, …
2. convertirle in qualcosa di facile da imporare
• useremo il programma opensource MeshLab 3. importarle nel nostro programma
• (come oggetti di “tipo” CpuMesh ) 4. caricarle in GPU
• (cioè convertirli in oggetti di “tipo” GpuMesh ) 5. disegnarle
• nella scena
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Fu nz io ni e si st en ti (n on c am bi a nu lla ) in system
memory
in video memory
1. Procurarsi alcune mesh
• Molto facile, in rete
– es: cercando su google: <qualcosa> 3D model
• Se ne trovano di tutti i tipi – a pagamento / gratuite
– complete di una o più tessiture, o no
– con attributi di tutti i tipi, o no (colore, uvmap, normali, etc) – complete di materiali, o no
– hi-res, o low-poly – di triangoli, o quad
– animate, o statiche (in questo corso, ci siamo occupati solo delle statiche) – di molti formati possibili: .obj, .3ds, .dae, .ply, …
• Esempio: prendiamo il famoso Stanford Bunny ( ) da:
http://graphics.stanford.edu/data/3Dscanrep/
– fornito dall’Univ. di Stanford
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Guardiamo dentro la nostra mesh con un plain text editor
• Alcuni formati per mesh sono scritti in ASCII – Si possono leggere con un editore di testo!
• Spesso, si riconosce la struttura mesh indicizzata – ma dipende dal formato, ovviamente
• Esempio:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
bun_zipper.ply ply
< … >
element vertex 35947
< … >
element face 69451
< … >
-0.0378297 0.12794 0.00447467 0.850855 0.5 -0.0447794 0.128887 0.00190497 0.900159 0.5 -0.0680095 0.151244 0.0371953 0.398443 0.5
< … altre ~35mila righe così … >
3 21216 21215 20399 3 9186 9280 14838 3 16020 13433 5187
< … altre ~70mila righe così … >
Guardiamo dentro la nostra mesh con un plain text editor
• Molti formati per mesh sono scritti in ASCII – Si possono leggere con un editore di testo!
• Spesso, si riconosce la struttura mesh indicizzata – ma dipende dal formato, ovviamente
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
bun_zipper.ply ply
< … >
element vertex 35947
< … >
element face 69451
< … >
-0.0378297 0.12794 0.00447467 0.850855 0.5 -0.0447794 0.128887 0.00190497 0.900159 0.5 -0.0680095 0.151244 0.0371953 0.398443 0.5
< … altre ~35mila righe così … >
3 21216 21215 20399 3 9186 9280 14838 3 16020 13433 5187
< … altre ~70mila righe così … >
numero vertici numero facce X,Y,Z
(in spazio oggetto) del 1mo vertice
… e del 3zo vertice
… indici dei 3 vertici della prima faccia
attributi?
(1mo vertice)
Next task:
Come importare questi dati in una struttura JavaScript?
(la nostra CpuMesh )
• soluz 1: usare una libreria esterna (es: three.js, SpiderGL …), per importare mesh, poi convertire la sua classe “mesh” nella nostra (o adottare la sua e abbandonare la nostra).
• soluz 2: scrivere un nuovo importer in JavaScript “a mano” per uno specifico file format (es il .ply) – come metodo di CpuMesh
• soluz 3: un trucco semplice e veloce ! (vediamo…)
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
ostacolo ulteriore: la lettura di file locali da browser (in JavaScript) è resa complicata da evidenti questioni di sicurezza .
Vedere libro di testo per alcune soluzioni.
Strumento: MeshLab
• Mesh processing toolbox
• OpenSource, free
• by:
Visual Computing Lab ( ISTI / CNR )
• Scaricare da:
http://meshlab.sourceforge.net/
e installare
– disponibile per tutte le piattaforme comuni – latest version: 1.3.3
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
1. [ File ] [ New Empty Project ] 2. [ File ] [ Import Mesh… ]
e selezionare la mesh (molti formati file possibili!) 3. [ File ] [ Export Mesh as… ]
Da meshlab:
convertire la mesh in formato JSON
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
JavaScript JSON ( *.json)
Da meshlab:
convertire la mesh in formato JSON 4. Selezionare gli attributi (per vertice)
da salvare
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Attributi per vertice:
noi usiamo solo normali (deselez tutto il resto)
Deselezionati (non usiamo attributi per Faccia, per Wedge)
Il file .json prodotto
• E’ un oggetto JSON (JavaScript Object Notation)
• Cioè un object literal in JavaScript!
• Aprirlo in un text-editor
• Aggiungere un nome di una var:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
bunny.json
{
"version" : "0.1.0",
"comment" : "Generated by MeshLab JSON Exporter",
"id" : 1,
"name" : "mesh",
"vertices" : [
{
"name" : "position_buffer",
"size" : 3,
"type" : "float32",
"normalized" : false,
"values" : [
-0.0378297, 0.12794, 0.00447467, …
varbunny_json =
<head>
<script src="js/three.min.js" type="text/javascript" ></script>
<script src="mesh.js" type="text/javascript" ></script>
<script type="text/javascript" >
</script>
</head>
file:index.html
Includerlo l’oggetto JSON nel progetto
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
<script src="bunny.json"
type="text/javascript" ></script>// da qui possiamo ora usare la variabile bunny_json
(
type="text/javascript"si può sempre omettere – è il default)
Brevi note su oggetti in JavaScript (JSON)
con le {} , oggetti:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var
docente = {
nome : "Marco Tarini", eta: 21,
oppure "nome" } con gli apici (non fa differenza)
"nome"
{}
docente.eta ; // 21
con le {} , array:
var"Jan", "Feb", "Mar" , mesi = [ ]
[]
mesi[ 2 ]; // "Mar"
// (si parte da [0])
combinabili:
vardocente = {
nome : "Marco Tarini",
esami: [ "CG" , "GameDev" , "Linguaggi" ] }
docente.esami[ 1 ] ; // "GameDev"
Brevi note su oggetti in JavaScript (JSON)
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
combinabili:
varnome docente : "Marco Tarini", = { esami: [
{ name: "CG" , CFU: 6 } , { name: "Linguaggi" , CFU: 3 } , ],
}
docente.esami[ 0 ].CFU ; // 6
var
docente = { nome : "Marco Tarini", esami: [
{
name: "GameDev" , CFU: 6 , years: [ 2014, 2016 ], } ,
{ name: "Linguaggi" , CFU: 3 } , ],
}
docente.esami[ 0 ].years[ 1 ] ; // 2016
La nostra
mesh in JSON:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var
bunny_json = {
… /* altri campi */
"vertices" : [
{
…
"values": [
x0,y0,z0, x1,y1,z1,… ],
… },
{
…
"values": [ x0,y0,z0,
x1,y1,z1,… ],
… }, ],
"connectivity" : [
{
…
"indices": [ a0,b0,c0,
a1,b1,c1, … ]},
] }
come prototta da MeshLAB Esercizio:
quale espressione restituisce la Y del 32-esimo vertice?
posiz
vertice 0 posiz vertice 1
normale
vertice 0 normale vertice 1
indici
faccia 0 indici faccia 1
Reminder
• Se abbiamo, per ogni vertice:
– X,Y,Z geometria
– R,G,B attributo colore (o normale, etc)
• Vari modi per formattare dati:
– in un array interleaved:
[ X 0 ,Y 0 ,Z 0 ,R 0 ,G 0 ,B 0 , X 1 ,Y 1 ,Z 1 ,R 1 ,G 1 ,B 1 ,… ] – in array separati:
[ X 0 ,Y 0 ,Z 0 , X 1 ,Y 1 ,Z 1 , … ], . [ R 0 ,G 0 ,B 0 , R 1 ,G 1 ,B 1 , … ] – …
• Dovremmo convertire!
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
usato nella nostra Mesh
usato nel JSON
Conversione:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a varCpuMesh= {
…
importFromMeshlabJson: function( orig) { varnverts= (orig.vertices[0].values.length)/3;
this.tris= new Uint16Array( orig.connectivity[0].indices );
this.verts= new Float32Array( nverts* 6 );
for (vari=0; i<nverts; i++ ) { this.setVert( i,
orig.vertices[0].values[ i*3+0 ], orig.vertices[0].values[ i*3+1 ], orig.vertices[0].values[ i*3+2 ] );
this.setNorm( i,
orig.vertices[1].values[ i*3+0 ], orig.vertices[1].values[ i*3+1 ], orig.vertices[1].values[ i*3+2 ] );
} }, }
Sarà per es bunny_json
Noi usiamo (per ora) 6 floats x vert.
Per i dettagli,
vedere l’implementazione sul sito (come al solito):
lez 23B
Provare con altre mesh, e a combinarle in una scena.
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a