Export ply supports texture
This commit is contained in:
parent
913583aeba
commit
556054cd9e
|
@ -8,6 +8,3 @@ Ka 0.5 0.5 0.
|
||||||
Kd 0.9 0.9 0.9
|
Kd 0.9 0.9 0.9
|
||||||
Ks 0.0 0.0 0.0
|
Ks 0.0 0.0 0.0
|
||||||
map_Kd cube.png
|
map_Kd cube.png
|
||||||
|
|
||||||
newmtl fuckyou
|
|
||||||
Ka 1 1 1
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ class ModelParser:
|
||||||
self.normals = []
|
self.normals = []
|
||||||
self.tex_coords = []
|
self.tex_coords = []
|
||||||
self.parts = []
|
self.parts = []
|
||||||
|
self.materials = []
|
||||||
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
|
||||||
|
@ -252,6 +253,13 @@ class ModelParser:
|
||||||
face.b.normal = index
|
face.b.normal = index
|
||||||
face.c.normal = index
|
face.c.normal = index
|
||||||
|
|
||||||
|
def get_material_index(self, material):
|
||||||
|
"""Finds the index of the given material
|
||||||
|
|
||||||
|
:param material: Material you want the index of
|
||||||
|
"""
|
||||||
|
return [i for (i,m) in enumerate(self.materials) if m.name == material.name][0]
|
||||||
|
|
||||||
class TextModelParser(ModelParser):
|
class TextModelParser(ModelParser):
|
||||||
def parse_file(self, path):
|
def parse_file(self, path):
|
||||||
"""Sets the path of the model and parse each line
|
"""Sets the path of the model and parse each line
|
||||||
|
|
|
@ -42,7 +42,7 @@ class OBJParser(TextModelParser):
|
||||||
self.mtl = MTLParser(self)
|
self.mtl = MTLParser(self)
|
||||||
self.mtl.parse_file(path)
|
self.mtl.parse_file(path)
|
||||||
else:
|
else:
|
||||||
print('Warning : ' + path + 'not found ', file=sys.stderr)
|
print('Warning : ' + path + ' not found ', file=sys.stderr)
|
||||||
elif first == 'v':
|
elif first == 'v':
|
||||||
self.add_vertex(Vertex().from_array(split))
|
self.add_vertex(Vertex().from_array(split))
|
||||||
elif first == 'vn':
|
elif first == 'vn':
|
||||||
|
@ -55,7 +55,11 @@ class OBJParser(TextModelParser):
|
||||||
for i in range(len(splits)):
|
for i in range(len(splits)):
|
||||||
for j in range(len(splits[i])):
|
for j in range(len(splits[i])):
|
||||||
if splits[i][j] is not '':
|
if splits[i][j] is not '':
|
||||||
splits[i][j] = int(splits[i][j]) - 1
|
splits[i][j] = int(splits[i][j])
|
||||||
|
if splits[i][j] > 0:
|
||||||
|
splits[i][j] -= 1
|
||||||
|
else:
|
||||||
|
splits[i][j] = len(self.vertices) + splits[i][j]
|
||||||
|
|
||||||
# if Face3
|
# if Face3
|
||||||
if len(split) == 3:
|
if len(split) == 3:
|
||||||
|
@ -83,7 +87,6 @@ class MTLParser:
|
||||||
:param parent: the OBJParser this MTLParser refers to
|
:param parent: the OBJParser this MTLParser refers to
|
||||||
"""
|
"""
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.materials = []
|
|
||||||
self.current_mtl = None
|
self.current_mtl = None
|
||||||
|
|
||||||
def parse_line(self, string):
|
def parse_line(self, string):
|
||||||
|
@ -101,7 +104,7 @@ class MTLParser:
|
||||||
|
|
||||||
if first == 'newmtl':
|
if first == 'newmtl':
|
||||||
self.current_mtl = Material(split[0])
|
self.current_mtl = Material(split[0])
|
||||||
self.materials.append(self.current_mtl)
|
self.parent.materials.append(self.current_mtl)
|
||||||
elif first == 'Ka':
|
elif first == 'Ka':
|
||||||
self.current_mtl.Ka = Vertex().from_array(split)
|
self.current_mtl.Ka = Vertex().from_array(split)
|
||||||
elif first == 'Kd':
|
elif first == 'Kd':
|
||||||
|
@ -109,11 +112,8 @@ class MTLParser:
|
||||||
elif first == 'Ks':
|
elif first == 'Ks':
|
||||||
self.current_mtl.Ks = Vertex().from_array(split)
|
self.current_mtl.Ks = Vertex().from_array(split)
|
||||||
elif first == 'map_Kd':
|
elif first == 'map_Kd':
|
||||||
try:
|
self.current_mtl.relative_path_to_texture = split[0]
|
||||||
import PIL.Image
|
self.current_mtl.absolute_path_to_texture = os.path.join(os.path.dirname(self.parent.path), split[0])
|
||||||
self.current_mtl.map_Kd = PIL.Image.open(os.path.join(os.path.dirname(self.parent.path), split[0]))
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def parse_file(self, path):
|
def parse_file(self, path):
|
||||||
|
@ -123,7 +123,7 @@ class MTLParser:
|
||||||
self.parse_line(line)
|
self.parse_line(line)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
for material in self.materials:
|
for material in self.parent.materials:
|
||||||
if material.name == key:
|
if material.name == key:
|
||||||
return material
|
return material
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ def _ply_type_size(type):
|
||||||
"""Returns the size of a ply property
|
"""Returns the size of a ply property
|
||||||
|
|
||||||
:param type: a string that is in a ply element
|
:param type: a string that is in a ply element
|
||||||
""""
|
"""
|
||||||
if type == 'char' or type == 'uchar':
|
if type == 'char' or type == 'uchar':
|
||||||
return 1
|
return 1
|
||||||
elif type == 'short' or type == 'ushort':
|
elif type == 'short' or type == 'ushort':
|
||||||
|
@ -86,7 +86,6 @@ class PLYParser(ModelParser):
|
||||||
super().__init__(up_conversion)
|
super().__init__(up_conversion)
|
||||||
self.counter = 0
|
self.counter = 0
|
||||||
self.elements = []
|
self.elements = []
|
||||||
self.materials = []
|
|
||||||
self.inner_parser = PLYHeaderParser(self)
|
self.inner_parser = PLYHeaderParser(self)
|
||||||
self.beginning_of_line = ''
|
self.beginning_of_line = ''
|
||||||
self.header_finished = False
|
self.header_finished = False
|
||||||
|
@ -156,11 +155,8 @@ class PLYHeaderParser:
|
||||||
elif split[0] == 'comment' and split[1] == 'TextureFile':
|
elif split[0] == 'comment' and split[1] == 'TextureFile':
|
||||||
material = Material('mat' + str(len(self.parent.materials)))
|
material = Material('mat' + str(len(self.parent.materials)))
|
||||||
self.parent.materials.append(material)
|
self.parent.materials.append(material)
|
||||||
|
material.relative_path_to_texture = split[2]
|
||||||
try:
|
material.absolute_path_to_texture = os.path.join(os.path.dirname(self.parent.path), split[2])
|
||||||
material.map_Kd = PIL.Image.open(os.path.join(os.path.dirname(self.parent.path), split[2]))
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class PLYElement:
|
class PLYElement:
|
||||||
def __init__(self, name, number):
|
def __init__(self, name, number):
|
||||||
|
@ -258,6 +254,7 @@ class PLY_ASCII_ContentParser:
|
||||||
|
|
||||||
elif property[0] == 'texnumber':
|
elif property[0] == 'texnumber':
|
||||||
current_material = self.parent.materials[int(split[offset])]
|
current_material = self.parent.materials[int(split[offset])]
|
||||||
|
offset += 1
|
||||||
|
|
||||||
face = Face(*faceVertexArray)
|
face = Face(*faceVertexArray)
|
||||||
face.material = current_material
|
face.material = current_material
|
||||||
|
@ -454,13 +451,20 @@ class PLYExporter(Exporter):
|
||||||
# Header
|
# Header
|
||||||
string = "ply\nformat ascii 1.0\ncomment Automatically gnerated by model-converter\n"
|
string = "ply\nformat ascii 1.0\ncomment Automatically gnerated by model-converter\n"
|
||||||
|
|
||||||
|
for material in self.model.materials:
|
||||||
|
string += "comment TextureFile " + material.relative_path_to_texture + "\n"
|
||||||
|
|
||||||
# Types : vertices
|
# Types : vertices
|
||||||
string += "element vertex " + str(len(self.model.vertices)) +"\n"
|
string += "element vertex " + str(len(self.model.vertices)) +"\n"
|
||||||
string += "property float x\nproperty float y\nproperty float z\n"
|
string += "property float x\nproperty float y\nproperty float z\n"
|
||||||
|
|
||||||
# Types : faces
|
# Types : faces
|
||||||
string += "element face " + str(len(faces)) + "\n"
|
string += "element face " + str(len(faces)) + "\n"
|
||||||
string += "property list uint8 int32 vertex_indices\n"
|
string += "property list uchar int vertex_indices\n"
|
||||||
|
|
||||||
|
if len(self.model.tex_coords) > 0:
|
||||||
|
string += "property list uchar float texcoord\n"
|
||||||
|
string += "property int texnumber\n"
|
||||||
|
|
||||||
# End header
|
# End header
|
||||||
string += "end_header\n"
|
string += "end_header\n"
|
||||||
|
@ -470,7 +474,19 @@ class PLYExporter(Exporter):
|
||||||
string += str(vertex.x) + " " + str(vertex.y) + " " + str(vertex.z) + "\n"
|
string += str(vertex.x) + " " + str(vertex.y) + " " + str(vertex.z) + "\n"
|
||||||
|
|
||||||
for face in faces:
|
for face in faces:
|
||||||
string += "3 " + str(face.a.vertex) + " " + str(face.b.vertex) + " " + str(face.c.vertex) + "\n"
|
string += "3 " + str(face.a.vertex) + " " + str(face.b.vertex) + " " + str(face.c.vertex)
|
||||||
|
|
||||||
|
if len(self.model.tex_coords) > 0:
|
||||||
|
string += " 6 " \
|
||||||
|
+ str(self.model.tex_coords[face.a.tex_coord].x) + " " \
|
||||||
|
+ str(self.model.tex_coords[face.a.tex_coord].y) + " " \
|
||||||
|
+ str(self.model.tex_coords[face.b.tex_coord].x) + " " \
|
||||||
|
+ str(self.model.tex_coords[face.b.tex_coord].y) + " " \
|
||||||
|
+ str(self.model.tex_coords[face.c.tex_coord].x) + " " \
|
||||||
|
+ str(self.model.tex_coords[face.c.tex_coord].y) + " " \
|
||||||
|
+ str(self.model.get_material_index(face.material))
|
||||||
|
|
||||||
|
string += "\n"
|
||||||
|
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@ class Material:
|
||||||
self.Ka = None
|
self.Ka = None
|
||||||
self.Kd = None
|
self.Kd = None
|
||||||
self.Ks = None
|
self.Ks = None
|
||||||
self.map_Kd = None
|
self.relative_path_to_texture = None
|
||||||
|
self.absolute_path_to_texture = None
|
||||||
|
self.im = None
|
||||||
self.id = None
|
self.id = None
|
||||||
|
|
||||||
def init_texture(self):
|
def init_texture(self):
|
||||||
|
@ -28,13 +30,21 @@ class Material:
|
||||||
return
|
return
|
||||||
|
|
||||||
# If no map_Kd, nothing to do
|
# If no map_Kd, nothing to do
|
||||||
if self.map_Kd is None:
|
if self.im is None:
|
||||||
return
|
|
||||||
|
if self.absolute_path_to_texture is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
import PIL.Image
|
||||||
|
self.im = PIL.Image.open(self.absolute_path_to_texture)
|
||||||
|
except ImportError:
|
||||||
|
return
|
||||||
|
|
||||||
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.im.size[0], self.im.size[1], self.im.tobytes("raw", "RGBA", 0, -1)
|
||||||
except:
|
except:
|
||||||
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.im.size[0], self.im.size[1], self.im.tobytes("raw", "RGBX", 0, -1)
|
||||||
|
|
||||||
self.id = gl.glGenTextures(1)
|
self.id = gl.glGenTextures(1)
|
||||||
|
|
||||||
|
@ -73,7 +83,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.im = PIL.Image.new("RGBA", (1,1), "white")
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue