model-converter-python/conv3d/ply.py

108 lines
3.2 KiB
Python
Raw Normal View History

2016-11-21 14:59:03 +00:00
#!/usr/bin/env python3
2016-11-21 16:05:52 +00:00
from .model import ModelParser, Exporter, Vertex, Face, FaceVertex
2016-11-21 14:59:03 +00:00
2016-11-22 10:27:42 +00:00
def is_ply(filename):
return filename[-4:] == '.ply'
2016-11-21 14:59:03 +00:00
class PLYParser(ModelParser):
def __init__(self):
super().__init__()
self.counter = 0
self.elements = []
self.inner_parser = PLYHeaderParser(self)
def parse_line(self, string):
2016-11-21 15:18:49 +00:00
self.inner_parser.parse_line(string)
2016-11-21 14:59:03 +00:00
class PLYHeaderParser:
def __init__(self, parent):
self.current_element = None
self.parent = parent
def parse_line(self, string):
split = string.split(' ')
if string == 'ply':
return
elif split[0] == 'format':
if split[1] != 'ascii' or split[2] != '1.0':
print('Only ascii 1.0 format is supported', file=sys.stderr)
sys.exit(-1)
elif split[0] == 'element':
self.current_element = PLYElement(split[1], int(split[2]))
self.parent.elements.append(self.current_element)
elif split[0] == 'property':
self.current_element.add_property(split[2], split[1])
elif split[0] == 'end_header':
self.parent.inner_parser = PLYContentParser(self.parent)
class PLYElement:
def __init__(self, name, number):
self.name = name
self.number = number
self.properties = []
2016-11-21 15:18:49 +00:00
def add_property(self, name, type):
2016-11-21 14:59:03 +00:00
self.properties.append((name, type))
class PLYContentParser:
def __init__(self, parent):
self.parent = parent
self.element_index = 0
self.counter = 0
self.current_element = self.parent.elements[0]
def parse_line(self, string):
split = string.split(' ')
if self.current_element.name == 'vertex':
2016-11-21 15:18:49 +00:00
self.parent.add_vertex(Vertex().from_array(split))
2016-11-21 14:59:03 +00:00
elif self.current_element.name == 'face':
self.parent.add_face(Face(FaceVertex(int(split[1])), FaceVertex(int(split[2])), FaceVertex(int(split[3]))))
2016-11-21 14:59:03 +00:00
self.counter += 1
2016-11-21 15:18:49 +00:00
if self.counter == self.current_element.number:
self.next_element()
2016-11-21 14:59:03 +00:00
def next_element(self):
self.element_index += 1
2016-11-21 15:18:49 +00:00
if self.element_index < len(self.parent.elements):
self.current_element = self.parent.elements[self.element_index]
2016-11-21 14:59:03 +00:00
class PLYExporter(Exporter):
def __init__(self, model):
super().__init__(model)
def __str__(self):
# Header
string = "ply\nformat ascii 1.0\ncomment Automatically gnerated by model-converter\n"
# Types : vertices
string += "element vertex " + str(len(self.model.vertices)) +"\n"
string += "property float32 x\nproperty float32 y\nproperty float32 z\n"
# Types : faces
string += "element face " + str(len(self.model.faces)) + "\n"
string += "property list uint8 int32 vertex_indices\n"
# End header
string += "end_header\n"
# Content of the model
for vertex in self.model.vertices:
string += str(vertex.x) + " " + str(vertex.y) + " " + str(vertex.z) + "\n"
2016-11-21 14:59:03 +00:00
for face in self.model.faces:
string += "3 " + str(face.a.vertex) + " " + str(face.b.vertex) + " " + str(face.c.vertex) + "\n"
2016-11-21 14:59:03 +00:00
return string