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 vec4 fFrontColor;
vec3 ambientLight = vec3(0.2,0.2,0.2);
vec3 directionnalLight = normalize(vec3(10,5,7));
@ -15,7 +16,7 @@ void main() {
vec4 color = texture2D(tex, gl_TexCoord[0].st);
vec4 fragColor = noTexColor * color;
gl_FragColor = fragColor;
gl_FragColor = fragColor * fFrontColor;
}

View File

@ -1,10 +1,12 @@
varying vec3 fNormal;
varying vec4 fTexCoord;
varying vec4 fFrontColor;
void main() {
fNormal = gl_Normal;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
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
Vertex = Vector
Normal = Vertex
TexCoord = Vertex
Normal = Vertex
Color = Vertex
class FaceVertex:
"""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
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
"""
self.vertex = vertex
self.tex_coord = tex_coord
self.normal = normal
self.color = color
def from_array(self, arr):
"""Initializes a FaceVertex from an array
@ -38,6 +40,11 @@ class FaceVertex:
except:
self.normal = None
try:
self.color = int(arr[3]) if len(arr) > 3 else None
except:
self.color = None
return self
class Face:
@ -75,15 +82,13 @@ class ModelParser:
"""
self.up_conversion = up_conversion
self.vertices = []
self.colors = []
self.normals = []
self.tex_coords = []
self.parts = []
self.current_part = None
self.bounding_box = BoundingBox()
self.center_and_scale = True
self.vertex_vbo = None
self.tex_coord_vbo = None
self.normal_vbo = None
self.path = None
def init_textures(self):
@ -121,6 +126,11 @@ class ModelParser:
"""
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):
"""Adds a face to the current model

View File

@ -2,7 +2,7 @@ import os
import sys
import PIL
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):
def __init__(self, message):
@ -172,9 +172,42 @@ class PLY_ASCII_ContentParser:
self.current_element = self.parent.elements[0]
split = string.split()
color = None
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':
faceVertexArray = []
@ -183,10 +216,12 @@ class PLY_ASCII_ContentParser:
# Analyse element
offset = 0
for property in self.current_element.properties:
if property[0] == 'vertex_indices':
for i in range(int(split[offset])):
faceVertexArray.append(FaceVertex(int(split[i+offset+1])))
offset += int(split[0]) + 1
elif property[0] == 'texcoord':
offset += 1
for i in range(3):
@ -195,6 +230,7 @@ class PLY_ASCII_ContentParser:
offset += 2
self.parent.add_tex_coord(tex_coord)
faceVertexArray[i].tex_coord = len(self.parent.tex_coords) - 1
elif property[0] == 'texnumber':
current_material = self.parent.materials[int(split[offset])]
@ -314,8 +350,8 @@ class PLYLittleEndianContentParser:
elif property[0] == 'texnumber':
material = self.parent.materials[property_values[i]]
for tex_coord in tex_coords:
self.parent.add_tex_coord(tex_coord)
for tex_coord in tex_coords:
self.parent.add_tex_coord(tex_coord)
face = Face(*list(map(lambda x: FaceVertex(x), vertex_indices)))

View File

@ -24,7 +24,6 @@ class Material:
try:
ix, iy, image = self.map_Kd.size[0], self.map_Kd.size[1], self.map_Kd.tobytes("raw", "RGBA", 0, -1)
except:
print('Humm')
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)
@ -59,7 +58,7 @@ Material.DEFAULT_MATERIAL.Ks = 0.0
try:
import PIL.Image
Material.DEFAULT_MATERIAL.map_Kd = PIL.Image.new("RGBA", (1,1), "white")
except:
except ImportError:
pass
class MeshPart:
@ -69,6 +68,7 @@ class MeshPart:
self.vertex_vbo = None
self.tex_coord_vbo = None
self.normal_vbo = None
self.color_vbo = None
self.faces = []
def init_texture(self):
@ -87,6 +87,7 @@ class MeshPart:
v = []
n = []
t = []
c = []
for face in self.faces:
v1 = self.parent.vertices[face.a.vertex]
@ -106,6 +107,12 @@ class MeshPart:
t3 = self.parent.tex_coords[face.c.tex_coord]
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'))
if len(n) > 0:
@ -114,6 +121,9 @@ class MeshPart:
if len(t) > 0:
self.tex_coord_vbo = vbo.VBO(array(t, 'f'))
if len(c) > 0:
self.color_vbo = vbo.VBO(array(c, 'f'))
def draw(self):
if self.material is not None:
@ -152,11 +162,18 @@ class MeshPart:
gl.glTexCoordPointerf(self.tex_coord_vbo)
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.glDisableClientState(gl.GL_VERTEX_ARRAY)
gl.glDisableClientState(gl.GL_NORMAL_ARRAY)
gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
gl.glDisableClientState(gl.GL_COLOR_ARRAY)
def draw_from_arrays(self):