Added stl support

This commit is contained in:
Thomas FORGIONE 2016-11-30 14:57:58 +01:00
parent ae3476d719
commit dfcd2eef41
No known key found for this signature in database
GPG Key ID: 2A210FFC062E00C3
4 changed files with 106 additions and 2 deletions

View File

@ -117,7 +117,7 @@ class ModelParser:
If the face has a different material than the current material, it will
create a new mesh part and update the current material.
"""
if self.current_part is None or face.material != self.current_part.material:
if self.current_part is None or (face.material != self.current_part.material and face.material is not None):
self.current_part = MeshPart(self)
self.current_part.material = face.material if face.material is not None else Material.DEFAULT_MATERIAL
self.parts.append(self.current_part)

View File

@ -122,7 +122,7 @@ class OBJExporter(Exporter):
faces = sum(map(lambda x: x.faces, self.model.parts), [])
for face in faces:
if face.material.name != current_material:
if face.material is not None and face.material.name != current_material:
current_material = face.material.name
string += "usemtl " + current_material + "\n"
string += "f "

99
d3/model/stl.py Normal file
View File

@ -0,0 +1,99 @@
#!/usr/bin/env python
from .basemodel import ModelParser, Exporter, Vertex, FaceVertex, Face
from .mesh import MeshPart
import os.path
def is_stl(filename):
return filename[-4:] == '.stl'
class STLParser(ModelParser):
def __init__(self):
super().__init__()
self.parsing_solid = False
self.parsing_face = False
self.parsing_loop = False
self.current_face = None
self.face_vertices = None
def parse_line(self, string):
if string == '':
return
split = string.split()
if split[0] == 'solid':
self.parsing_solid = True
return
if split[0] == 'endsolid':
self.parsing_solid = False
return
if self.parsing_solid:
if split[0] == 'facet' and split[1] == 'normal':
self.parsing_face = True
self.face_vertices = [FaceVertex(), FaceVertex(), FaceVertex()]
self.current_face = Face(*self.face_vertices)
return
if self.parsing_face:
if split[0] == 'outer' and split[1] == 'loop':
self.parsing_loop = True
return
if split[0] == 'endloop':
self.parsing_loop = False
return
if self.parsing_loop:
if split[0] == 'vertex':
current_vertex = Vertex().from_array(split[1:])
self.add_vertex(current_vertex)
self.face_vertices[0].vertex = len(self.vertices) - 1
self.face_vertices.pop(0)
return
if split[0] == 'endfacet':
self.parsing_face = False
self.add_face(self.current_face)
self.current_face = None
self.face_vertices = None
class STLExporter(Exporter):
def __init__(self, model):
super().__init__(model)
def __str__(self):
string = 'solid {}\n'.format(os.path.basename(self.model.path[:-4]))
self.model.generate_face_normals()
faces = sum(map(lambda x: x.faces, self.model.parts), [])
for face in faces:
n = self.model.normals[face.a.normal]
v1 = self.model.vertices[face.a.vertex]
v2 = self.model.vertices[face.b.vertex]
v3 = self.model.vertices[face.c.vertex]
string += "facet normal {} {} {}\n".format(n.x, n.y, n.z)
string += "\touter loop\n"
string += "\t\tvertex {} {} {}\n".format(v1.x, v1.y, v1.z)
string += "\t\tvertex {} {} {}\n".format(v2.x, v2.y, v2.z)
string += "\t\tvertex {} {} {}\n".format(v3.x, v3.y, v3.z)
string += "\tendloop\n"
string += "endfacet\n"
string += 'endsolid {}'.format(os.path.basename(self.model.path[:-4]))
return string

View File

@ -2,6 +2,7 @@
from .obj import is_obj, OBJParser, OBJExporter
from .ply import is_ply, PLYParser, PLYExporter
from .stl import is_stl, STLParser, STLExporter
from .basemodel import ModelParser, Exporter
def load_model(path):
@ -11,6 +12,8 @@ def load_model(path):
parser = OBJParser()
elif is_ply(path):
parser = PLYParser()
elif is_stl(path):
parser = STLParser()
else:
raise Exception("File format not supported")
@ -25,6 +28,8 @@ def export_model(model, path):
exporter = OBJExporter(model)
elif is_ply(path):
exporter = PLYExporter(model)
elif is_stl(path):
exporter = STLExporter(model)
else:
raise Exception("File format not supported")