Module mola.core_mesh
Expand source code
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = ['Benjamin Dillenburger','Demetris Shammas','Mathias Bernhard']
__copyright__ = 'Copyright 2019 / Digital Building Technologies DBT / ETH Zurich'
__license__ = 'MIT License'
__email__ = ['<dbt@arch.ethz.ch>']
import math
from mola.core_vertex import Vertex
from mola.core_face import Face
from mola.core_edge import Edge
from mola.core_box import Box
from mola import utils_face
class Mesh:
"""A mesh describes a 3D surface made of Vertices connected by Faces.
Attributes
----------
vertices : list
The list of `Vertex` objects in the mesh.
faces : list
The list of `Face` objects in the mesh.
edges : list
The list of edges in the mesh.
"""
def __init__(self):
self.vertices = []
self.faces = []
self.edges = []
def scale(self, sx, sy, sz):
"""
scales a mesh by adding multiplying
the position of its vertices by sx, sy and sz.
"""
#vs = Vertex(sx, sy, sz)
for v in self.vertices:
v.x *= sx
v.y *= sy
v.z *= sz
def translate(self, tx, ty, tz):
"""
translates a mesh by adding tx,ty and tz
to the position of the vertices.
"""
vt = Vertex(tx, ty, tz)
for v in self.vertices:
v.add(vt)
def bounding_box(self):
"""
returns the bounding box of this mesh as a Box() object
"""
box = Box()
for f in self.faces:
for v in f.vertices:
box.add_point(v.x,v.y,v.z)
return box
def center(self):
"""
Returns the center of the Mesh as a Vertex() object
Note: not the center of gravity, just the average of its vertices.
"""
return self.bounding_box().center()
def edge_adjacent_to_vertices(self, v1, v2):
for edge in v1.edges:
if edge.v2 == v2 or edge.v1 == v2:
return edge
return None
def face_adjacent_to_vertices(self, v1, v2):
edge = v1.edge_adjacent_to_vertex(v2)
if edge != None:
if edge.v1 == v1:
return edge.face1
else:
return edge.face2
return None
def add_vertex(self, x, y, z=0):
v = Vertex(x,y,z)
self.vertices.append(v)
return v
def add_face(self, vertices):
f = Face(vertices)
self.faces.append(f)
return f
def face_properties(self,face_analyse):
values=[]
for face in self.faces:
values.append(face_analyse(face))
return values
def weld_vertices(self):
weldedVertices = {}
self.vertices = []
for f in self.faces:
for i in range(len(f.vertices)):
v = f.vertices[i]
vtuple = (v.x, v.y, v.z)
if vtuple in weldedVertices:
f.vertices[i] = weldedVertices[vtuple]
else:
weldedVertices[vtuple] = v
self.vertices = [v for v in weldedVertices.values()]
def update_edges(self):
self.edges = []
for v in self.vertices:
v.edges = []
for f in self.faces:
v1 = f.vertices[-1]
for v2 in f.vertices:
edge = v1.edge_adjacent_to_vertex(v2)
if edge == None:
edge = Edge(v1,v2)
v1.edges.append(edge)
v2.edges.append(edge)
self.edges.append(edge)
if edge.v1 == v1:
edge.face1 = f
else:
edge.face2 = f
v1 = v2
def update_topology(self):
self.weld_vertices()
self.update_edges()
def copy(self):
meshcopy = Mesh()
# if mesh has no topolgy constructed
if len(self.edges) == 0:
for f in self.faces:
vs = [Vertex(v.x,v.y,v.z) for v in f.vertices]
for nv,ov in zip(vs, f.vertices):
nv.fix = ov.fix
nv.generation = ov.generation
nf = meshcopy.add_face(vs)
utils_face.face_copy_properties(f,nf)
else:
meshcopy.vertices = [Vertex(v.x,v.y,v.z) for v in self.vertices]
for nv,ov in zip(meshcopy.vertices, self.vertices):
nv.fix = ov.fix
nv.generation = ov.generation
for f in self.faces:
vs = [meshcopy.vertices[self.vertices.index(v)] for v in f.vertices]
nf = meshcopy.add_face(vs)
utils_face.face_copy_properties(f,nf)
for e in self.edges:
iv1 = self.vertices.index(e.v1)
iv2 = self.vertices.index(e.v1)
ie1 = self.faces.index(e.face1)
ie2 = self.faces.index(e.face2)
v1c = meshcopy.vertices[iv1]
v2c = meshcopy.vertices[iv2]
edge = Edge(v1c,v2c)
v1c.edges.append(edge)
v2c.edges.append(edge)
meshcopy.edges.append(edge)
edge.face1 = meshcopy.faces[ie1]
edge.face2 = meshcopy.faces[ie2]
return meshcopy
Classes
class Mesh
-
A mesh describes a 3D surface made of Vertices connected by Faces.
Attributes
vertices
:list
- The list of
Vertex
objects in the mesh. faces
:list
- The list of
Face
objects in the mesh. edges
:list
- The list of edges in the mesh.
Expand source code
class Mesh: """A mesh describes a 3D surface made of Vertices connected by Faces. Attributes ---------- vertices : list The list of `Vertex` objects in the mesh. faces : list The list of `Face` objects in the mesh. edges : list The list of edges in the mesh. """ def __init__(self): self.vertices = [] self.faces = [] self.edges = [] def scale(self, sx, sy, sz): """ scales a mesh by adding multiplying the position of its vertices by sx, sy and sz. """ #vs = Vertex(sx, sy, sz) for v in self.vertices: v.x *= sx v.y *= sy v.z *= sz def translate(self, tx, ty, tz): """ translates a mesh by adding tx,ty and tz to the position of the vertices. """ vt = Vertex(tx, ty, tz) for v in self.vertices: v.add(vt) def bounding_box(self): """ returns the bounding box of this mesh as a Box() object """ box = Box() for f in self.faces: for v in f.vertices: box.add_point(v.x,v.y,v.z) return box def center(self): """ Returns the center of the Mesh as a Vertex() object Note: not the center of gravity, just the average of its vertices. """ return self.bounding_box().center() def edge_adjacent_to_vertices(self, v1, v2): for edge in v1.edges: if edge.v2 == v2 or edge.v1 == v2: return edge return None def face_adjacent_to_vertices(self, v1, v2): edge = v1.edge_adjacent_to_vertex(v2) if edge != None: if edge.v1 == v1: return edge.face1 else: return edge.face2 return None def add_vertex(self, x, y, z=0): v = Vertex(x,y,z) self.vertices.append(v) return v def add_face(self, vertices): f = Face(vertices) self.faces.append(f) return f def face_properties(self,face_analyse): values=[] for face in self.faces: values.append(face_analyse(face)) return values def weld_vertices(self): weldedVertices = {} self.vertices = [] for f in self.faces: for i in range(len(f.vertices)): v = f.vertices[i] vtuple = (v.x, v.y, v.z) if vtuple in weldedVertices: f.vertices[i] = weldedVertices[vtuple] else: weldedVertices[vtuple] = v self.vertices = [v for v in weldedVertices.values()] def update_edges(self): self.edges = [] for v in self.vertices: v.edges = [] for f in self.faces: v1 = f.vertices[-1] for v2 in f.vertices: edge = v1.edge_adjacent_to_vertex(v2) if edge == None: edge = Edge(v1,v2) v1.edges.append(edge) v2.edges.append(edge) self.edges.append(edge) if edge.v1 == v1: edge.face1 = f else: edge.face2 = f v1 = v2 def update_topology(self): self.weld_vertices() self.update_edges() def copy(self): meshcopy = Mesh() # if mesh has no topolgy constructed if len(self.edges) == 0: for f in self.faces: vs = [Vertex(v.x,v.y,v.z) for v in f.vertices] for nv,ov in zip(vs, f.vertices): nv.fix = ov.fix nv.generation = ov.generation nf = meshcopy.add_face(vs) utils_face.face_copy_properties(f,nf) else: meshcopy.vertices = [Vertex(v.x,v.y,v.z) for v in self.vertices] for nv,ov in zip(meshcopy.vertices, self.vertices): nv.fix = ov.fix nv.generation = ov.generation for f in self.faces: vs = [meshcopy.vertices[self.vertices.index(v)] for v in f.vertices] nf = meshcopy.add_face(vs) utils_face.face_copy_properties(f,nf) for e in self.edges: iv1 = self.vertices.index(e.v1) iv2 = self.vertices.index(e.v1) ie1 = self.faces.index(e.face1) ie2 = self.faces.index(e.face2) v1c = meshcopy.vertices[iv1] v2c = meshcopy.vertices[iv2] edge = Edge(v1c,v2c) v1c.edges.append(edge) v2c.edges.append(edge) meshcopy.edges.append(edge) edge.face1 = meshcopy.faces[ie1] edge.face2 = meshcopy.faces[ie2] return meshcopy
Methods
def add_face(self, vertices)
-
Expand source code
def add_face(self, vertices): f = Face(vertices) self.faces.append(f) return f
def add_vertex(self, x, y, z=0)
-
Expand source code
def add_vertex(self, x, y, z=0): v = Vertex(x,y,z) self.vertices.append(v) return v
def bounding_box(self)
-
returns the bounding box of this mesh as a Box() object
Expand source code
def bounding_box(self): """ returns the bounding box of this mesh as a Box() object """ box = Box() for f in self.faces: for v in f.vertices: box.add_point(v.x,v.y,v.z) return box
def center(self)
-
Returns the center of the Mesh as a Vertex() object Note: not the center of gravity, just the average of its vertices.
Expand source code
def center(self): """ Returns the center of the Mesh as a Vertex() object Note: not the center of gravity, just the average of its vertices. """ return self.bounding_box().center()
def copy(self)
-
Expand source code
def copy(self): meshcopy = Mesh() # if mesh has no topolgy constructed if len(self.edges) == 0: for f in self.faces: vs = [Vertex(v.x,v.y,v.z) for v in f.vertices] for nv,ov in zip(vs, f.vertices): nv.fix = ov.fix nv.generation = ov.generation nf = meshcopy.add_face(vs) utils_face.face_copy_properties(f,nf) else: meshcopy.vertices = [Vertex(v.x,v.y,v.z) for v in self.vertices] for nv,ov in zip(meshcopy.vertices, self.vertices): nv.fix = ov.fix nv.generation = ov.generation for f in self.faces: vs = [meshcopy.vertices[self.vertices.index(v)] for v in f.vertices] nf = meshcopy.add_face(vs) utils_face.face_copy_properties(f,nf) for e in self.edges: iv1 = self.vertices.index(e.v1) iv2 = self.vertices.index(e.v1) ie1 = self.faces.index(e.face1) ie2 = self.faces.index(e.face2) v1c = meshcopy.vertices[iv1] v2c = meshcopy.vertices[iv2] edge = Edge(v1c,v2c) v1c.edges.append(edge) v2c.edges.append(edge) meshcopy.edges.append(edge) edge.face1 = meshcopy.faces[ie1] edge.face2 = meshcopy.faces[ie2] return meshcopy
def edge_adjacent_to_vertices(self, v1, v2)
-
Expand source code
def edge_adjacent_to_vertices(self, v1, v2): for edge in v1.edges: if edge.v2 == v2 or edge.v1 == v2: return edge return None
def face_adjacent_to_vertices(self, v1, v2)
-
Expand source code
def face_adjacent_to_vertices(self, v1, v2): edge = v1.edge_adjacent_to_vertex(v2) if edge != None: if edge.v1 == v1: return edge.face1 else: return edge.face2 return None
def face_properties(self, face_analyse)
-
Expand source code
def face_properties(self,face_analyse): values=[] for face in self.faces: values.append(face_analyse(face)) return values
def scale(self, sx, sy, sz)
-
scales a mesh by adding multiplying the position of its vertices by sx, sy and sz.
Expand source code
def scale(self, sx, sy, sz): """ scales a mesh by adding multiplying the position of its vertices by sx, sy and sz. """ #vs = Vertex(sx, sy, sz) for v in self.vertices: v.x *= sx v.y *= sy v.z *= sz
def translate(self, tx, ty, tz)
-
translates a mesh by adding tx,ty and tz to the position of the vertices.
Expand source code
def translate(self, tx, ty, tz): """ translates a mesh by adding tx,ty and tz to the position of the vertices. """ vt = Vertex(tx, ty, tz) for v in self.vertices: v.add(vt)
def update_edges(self)
-
Expand source code
def update_edges(self): self.edges = [] for v in self.vertices: v.edges = [] for f in self.faces: v1 = f.vertices[-1] for v2 in f.vertices: edge = v1.edge_adjacent_to_vertex(v2) if edge == None: edge = Edge(v1,v2) v1.edges.append(edge) v2.edges.append(edge) self.edges.append(edge) if edge.v1 == v1: edge.face1 = f else: edge.face2 = f v1 = v2
def update_topology(self)
-
Expand source code
def update_topology(self): self.weld_vertices() self.update_edges()
def weld_vertices(self)
-
Expand source code
def weld_vertices(self): weldedVertices = {} self.vertices = [] for f in self.faces: for i in range(len(f.vertices)): v = f.vertices[i] vtuple = (v.x, v.y, v.z) if vtuple in weldedVertices: f.vertices[i] = weldedVertices[vtuple] else: weldedVertices[vtuple] = v self.vertices = [v for v in weldedVertices.values()]