forked from dbt-ethz/mola
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils_face.py
155 lines (135 loc) · 4.32 KB
/
utils_face.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/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__ = ['<[email protected]>']
import math
from mola.core_vertex import Vertex
from mola import utils_math
from mola import utils_vertex
def face_area(face):
"""
Returns the area of a face, for quads that of two triangles.
Arguments:
----------
face : mola.Face
The face to be measured
"""
if(len(face.vertices) == 3):
return utils_vertex.triangle_area(face.vertices[0], face.vertices[1], face.vertices[2])
else:
return utils_vertex.triangle_area(face.vertices[0], face.vertices[1], face.vertices[2]) + utils_vertex.triangle_area(face.vertices[2], face.vertices[3], face.vertices[0])
def face_perimeter(face):
"""
Returns the perimeter of a face as the sum of all the edges' lengths.
Arguments:
----------
face : mola.Face
The face to be measured
"""
sum = 0
for i in range(len(face.vertices)):
v1 = face.vertices[i]
v2 = face.vertices[(i + 1) % len(face.vertices)]
sum += utils_vertex.vertex_distance(v1,v2)
return sum
def face_compactness(face):
"""
Returns the compactness of a face as the ratio between area and perimeter.
Arguments:
----------
face : mola.Face
The face to be measured
"""
return face_area(face) / face_perimeter(face)
def face_angle_horizontal(face):
"""
Returns the azimuth, the orientation of the face around the z-axis in the XY-plane
Arguments:
----------
face : mola.Face
The face to be measured
"""
n = face_normal(face)
return math.atan2(n.y, n.x)
def face_angle_vertical(f):
"""
Returns the altitude, 0 if the face is vertical, -Pi/2 if it faces downwards, +Pi/2 if it faces upwards.
Arguments:
----------
face : mola.Face
The face to be measured
"""
n = face_normal(f)
#nXY = Vertex(n.x, n.y, 0.0)
#return vecUtils.angle(n, nXY)
# alternative, probably less computationally intense:
return math.asin(n.z)
def face_curvature(face):
"""
Returns the local curvature of a mesh face, by measuring the angle to the neighbour faces.
Arguments:
----------
face : mola.Face
The face to be measured
"""
facenormal = face_normal(face)
sumD = 0
vPrev = face.vertices[-1]
num_faces = 1
for v in face.vertices:
edge = v.edge_adjacent_to_vertex(vPrev)
if edge != None:
nbFace = edge.face1
if edge.face1 == face:
nbFace = edge.face2
if nbFace != None:
num_faces += 1
nbNormal = face_normal(nbFace)
sumD += utils_vertex.vertex_distance(nbNormal,facenormal)
vPrev = v
return sumD / num_faces
def face_center(face):
"""
Returns the center point (type Vertex) of a face.
Note: not the center of gravity, just the average of its vertices.
Arguments:
----------
face : mola.Face
The face to be measured
"""
return utils_vertex.vertices_list_center(face.vertices)
def face_normal(face):
"""
Returns the normal of a face, a vector of length 1 perpendicular to the plane of the triangle.
Arguments:
----------
face : mola.Face
the face to get the normal from
"""
return utils_vertex.triangle_normal(face.vertices[0], face.vertices[1], face.vertices[2])
def face_copy_properties(faceParent,faceChild):
"""
Copies the properties (color,group,...) of faceParent to faceChild.
Arguments:
----------
faceParent : mola.Face
The face to copy the properties From.
faceChild : mola.Face
The face to copy the properties To.
"""
faceChild.group = faceParent.group
faceChild.color = faceParent.color
def face_scale(face, factor=1.0, origin=None):
if origin is None:
for v in face.vertices:
v.scale(factor)
else:
for v in face.vertices:
delta = v - origin
delta.scale(factor)
v.x = origin.x + delta.x
v.y = origin.y + delta.y
v.z = origin.z + delta.z
return face