ply ascii parser supports vertex colors

This commit is contained in:
Thomas FORGIONE 2017-01-18 10:27:34 +01:00
parent 5ee5d5c3f9
commit 1113c6d137
No known key found for this signature in database
GPG Key ID: 2A210FFC062E00C3
5 changed files with 78 additions and 12 deletions

View File

@ -1,4 +1,5 @@
varying vec3 fNormal; varying vec3 fNormal;
varying vec4 fFrontColor;
vec3 ambientLight = vec3(0.2,0.2,0.2); vec3 ambientLight = vec3(0.2,0.2,0.2);
vec3 directionnalLight = normalize(vec3(10,5,7)); vec3 directionnalLight = normalize(vec3(10,5,7));
@ -15,7 +16,7 @@ void main() {
vec4 color = texture2D(tex, gl_TexCoord[0].st); vec4 color = texture2D(tex, gl_TexCoord[0].st);
vec4 fragColor = noTexColor * color; vec4 fragColor = noTexColor * color;
gl_FragColor = fragColor; gl_FragColor = fragColor * fFrontColor;
} }

View File

@ -1,10 +1,12 @@
varying vec3 fNormal; varying vec3 fNormal;
varying vec4 fTexCoord; varying vec4 fTexCoord;
varying vec4 fFrontColor;
void main() { void main() {
fNormal = gl_Normal; fNormal = gl_Normal;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
fFrontColor = gl_Color;
} }

View File

@ -3,8 +3,9 @@ from ..geometry import Vector
from .mesh import Material, MeshPart from .mesh import Material, MeshPart
Vertex = Vector Vertex = Vector
Normal = Vertex
TexCoord = Vertex TexCoord = Vertex
Normal = Vertex
Color = Vertex
class FaceVertex: class FaceVertex:
"""Contains the information a vertex needs in a face """Contains the information a vertex needs in a face
@ -12,12 +13,13 @@ class FaceVertex:
In contains the index of the vertex, the index of the texture coordinate In contains the index of the vertex, the index of the texture coordinate
and the index of the normal. It is None if it is not available. and the index of the normal. It is None if it is not available.
""" """
def __init__(self, vertex = None, tex_coord = None, normal = None): def __init__(self, vertex = None, tex_coord = None, normal = None, color = None):
"""Initializes a FaceVertex from its indices """Initializes a FaceVertex from its indices
""" """
self.vertex = vertex self.vertex = vertex
self.tex_coord = tex_coord self.tex_coord = tex_coord
self.normal = normal self.normal = normal
self.color = color
def from_array(self, arr): def from_array(self, arr):
"""Initializes a FaceVertex from an array """Initializes a FaceVertex from an array
@ -38,6 +40,11 @@ class FaceVertex:
except: except:
self.normal = None self.normal = None
try:
self.color = int(arr[3]) if len(arr) > 3 else None
except:
self.color = None
return self return self
class Face: class Face:
@ -75,15 +82,13 @@ class ModelParser:
""" """
self.up_conversion = up_conversion self.up_conversion = up_conversion
self.vertices = [] self.vertices = []
self.colors = []
self.normals = [] self.normals = []
self.tex_coords = [] self.tex_coords = []
self.parts = [] self.parts = []
self.current_part = None self.current_part = None
self.bounding_box = BoundingBox() self.bounding_box = BoundingBox()
self.center_and_scale = True self.center_and_scale = True
self.vertex_vbo = None
self.tex_coord_vbo = None
self.normal_vbo = None
self.path = None self.path = None
def init_textures(self): def init_textures(self):
@ -121,6 +126,11 @@ class ModelParser:
""" """
self.normals.append(normal) self.normals.append(normal)
def add_color(self, color):
"""Adds a color element to the current model
"""
self.colors.append(color)
def add_face(self, face): def add_face(self, face):
"""Adds a face to the current model """Adds a face to the current model

View File

@ -2,7 +2,7 @@ import os
import sys import sys
import PIL import PIL
import struct import struct
from ..basemodel import ModelParser, TextModelParser, Exporter, Vertex, Face, FaceVertex, TexCoord, Material from ..basemodel import ModelParser, TextModelParser, Exporter, Vertex, Face, Color, FaceVertex, TexCoord, Material
class UnkownTypeError(Exception): class UnkownTypeError(Exception):
def __init__(self, message): def __init__(self, message):
@ -172,9 +172,42 @@ class PLY_ASCII_ContentParser:
self.current_element = self.parent.elements[0] self.current_element = self.parent.elements[0]
split = string.split() split = string.split()
color = None
if self.current_element.name == 'vertex': if self.current_element.name == 'vertex':
self.parent.add_vertex(Vertex().from_array(split))
vertex = Vertex()
red = None
blue = None
green = None
alpha = None
offset = 0
for property in self.current_element.properties:
if property[0] == 'x':
vertex.x = float(split[offset])
elif property[0] == 'y':
vertex.y = float(split[offset])
elif property[0] == 'z':
vertex.z = float(split[offset])
elif property[0] == 'red':
red = float(split[offset]) / 255
elif property[0] == 'green':
green = float(split[offset]) / 255
elif property[0] == 'blue':
blue = float(split[offset]) / 255
elif property[0] == 'alpha':
alpha = float(split[offset]) / 255
offset += 1
self.parent.add_vertex(vertex)
if red is not None:
color = Color(red, blue, green)
self.parent.add_color(color)
elif self.current_element.name == 'face': elif self.current_element.name == 'face':
faceVertexArray = [] faceVertexArray = []
@ -183,10 +216,12 @@ class PLY_ASCII_ContentParser:
# Analyse element # Analyse element
offset = 0 offset = 0
for property in self.current_element.properties: for property in self.current_element.properties:
if property[0] == 'vertex_indices': if property[0] == 'vertex_indices':
for i in range(int(split[offset])): for i in range(int(split[offset])):
faceVertexArray.append(FaceVertex(int(split[i+offset+1]))) faceVertexArray.append(FaceVertex(int(split[i+offset+1])))
offset += int(split[0]) + 1 offset += int(split[0]) + 1
elif property[0] == 'texcoord': elif property[0] == 'texcoord':
offset += 1 offset += 1
for i in range(3): for i in range(3):
@ -195,6 +230,7 @@ class PLY_ASCII_ContentParser:
offset += 2 offset += 2
self.parent.add_tex_coord(tex_coord) self.parent.add_tex_coord(tex_coord)
faceVertexArray[i].tex_coord = len(self.parent.tex_coords) - 1 faceVertexArray[i].tex_coord = len(self.parent.tex_coords) - 1
elif property[0] == 'texnumber': elif property[0] == 'texnumber':
current_material = self.parent.materials[int(split[offset])] current_material = self.parent.materials[int(split[offset])]
@ -314,8 +350,8 @@ class PLYLittleEndianContentParser:
elif property[0] == 'texnumber': elif property[0] == 'texnumber':
material = self.parent.materials[property_values[i]] material = self.parent.materials[property_values[i]]
for tex_coord in tex_coords: for tex_coord in tex_coords:
self.parent.add_tex_coord(tex_coord) self.parent.add_tex_coord(tex_coord)
face = Face(*list(map(lambda x: FaceVertex(x), vertex_indices))) face = Face(*list(map(lambda x: FaceVertex(x), vertex_indices)))

View File

@ -24,7 +24,6 @@ class Material:
try: try:
ix, iy, image = self.map_Kd.size[0], self.map_Kd.size[1], self.map_Kd.tobytes("raw", "RGBA", 0, -1) ix, iy, image = self.map_Kd.size[0], self.map_Kd.size[1], self.map_Kd.tobytes("raw", "RGBA", 0, -1)
except: except:
print('Humm')
ix, iy, image = self.map_Kd.size[0], self.map_Kd.size[1], self.map_Kd.tobytes("raw", "RGBX", 0, -1) ix, iy, image = self.map_Kd.size[0], self.map_Kd.size[1], self.map_Kd.tobytes("raw", "RGBX", 0, -1)
self.id = gl.glGenTextures(1) self.id = gl.glGenTextures(1)
@ -59,7 +58,7 @@ Material.DEFAULT_MATERIAL.Ks = 0.0
try: try:
import PIL.Image import PIL.Image
Material.DEFAULT_MATERIAL.map_Kd = PIL.Image.new("RGBA", (1,1), "white") Material.DEFAULT_MATERIAL.map_Kd = PIL.Image.new("RGBA", (1,1), "white")
except: except ImportError:
pass pass
class MeshPart: class MeshPart:
@ -69,6 +68,7 @@ class MeshPart:
self.vertex_vbo = None self.vertex_vbo = None
self.tex_coord_vbo = None self.tex_coord_vbo = None
self.normal_vbo = None self.normal_vbo = None
self.color_vbo = None
self.faces = [] self.faces = []
def init_texture(self): def init_texture(self):
@ -87,6 +87,7 @@ class MeshPart:
v = [] v = []
n = [] n = []
t = [] t = []
c = []
for face in self.faces: for face in self.faces:
v1 = self.parent.vertices[face.a.vertex] v1 = self.parent.vertices[face.a.vertex]
@ -106,6 +107,12 @@ class MeshPart:
t3 = self.parent.tex_coords[face.c.tex_coord] t3 = self.parent.tex_coords[face.c.tex_coord]
t += [[t1.x, t1.y], [t2.x, t2.y], [t3.x, t3.y]] t += [[t1.x, t1.y], [t2.x, t2.y], [t3.x, t3.y]]
if len(self.parent.colors) > 0: # face.a.color is not None:
c1 = self.parent.colors[face.a.vertex]
c2 = self.parent.colors[face.b.vertex]
c3 = self.parent.colors[face.c.vertex]
c += [[c1.x, c1.y, c1.z], [c2.x, c2.y, c2.z], [c3.x, c3.y, c3.z]]
self.vertex_vbo = vbo.VBO(array(v, 'f')) self.vertex_vbo = vbo.VBO(array(v, 'f'))
if len(n) > 0: if len(n) > 0:
@ -114,6 +121,9 @@ class MeshPart:
if len(t) > 0: if len(t) > 0:
self.tex_coord_vbo = vbo.VBO(array(t, 'f')) self.tex_coord_vbo = vbo.VBO(array(t, 'f'))
if len(c) > 0:
self.color_vbo = vbo.VBO(array(c, 'f'))
def draw(self): def draw(self):
if self.material is not None: if self.material is not None:
@ -152,11 +162,18 @@ class MeshPart:
gl.glTexCoordPointerf(self.tex_coord_vbo) gl.glTexCoordPointerf(self.tex_coord_vbo)
self.tex_coord_vbo.unbind() self.tex_coord_vbo.unbind()
if self.color_vbo is not None:
self.color_vbo.bind()
gl.glEnableClientState(gl.GL_COLOR_ARRAY)
gl.glColorPointerf(self.color_vbo)
self.color_vbo.unbind()
gl.glDrawArrays(gl.GL_TRIANGLES, 0, len(self.vertex_vbo.data) * 9) gl.glDrawArrays(gl.GL_TRIANGLES, 0, len(self.vertex_vbo.data) * 9)
gl.glDisableClientState(gl.GL_VERTEX_ARRAY) gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
gl.glDisableClientState(gl.GL_NORMAL_ARRAY) gl.glDisableClientState(gl.GL_NORMAL_ARRAY)
gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY) gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
gl.glDisableClientState(gl.GL_COLOR_ARRAY)
def draw_from_arrays(self): def draw_from_arrays(self):