def test_on_demand_getter(self): # check if standard properties are requested on demand, # i.e. if it doesn't crash it works mesh = self.one_triangle() mesh.normal(openmesh.VertexHandle(0)) mesh = self.one_triangle() mesh.normal(openmesh.HalfedgeHandle(0)) mesh = self.one_triangle() mesh.normal(openmesh.FaceHandle(0)) mesh = self.one_triangle() mesh.color(openmesh.VertexHandle(0)) mesh = self.one_triangle() mesh.color(openmesh.HalfedgeHandle(0)) mesh = self.one_triangle() mesh.color(openmesh.EdgeHandle(0)) mesh = self.one_triangle() mesh.color(openmesh.FaceHandle(0)) mesh = self.one_triangle() mesh.color(openmesh.VertexHandle(0)) mesh = self.one_triangle() mesh.texcoord1D(openmesh.VertexHandle(0)) mesh = self.one_triangle() mesh.texcoord1D(openmesh.HalfedgeHandle(0)) mesh = self.one_triangle() mesh.texcoord2D(openmesh.VertexHandle(0)) mesh = self.one_triangle() mesh.texcoord2D(openmesh.HalfedgeHandle(0)) mesh = self.one_triangle() mesh.texcoord3D(openmesh.VertexHandle(0)) mesh = self.one_triangle() mesh.texcoord3D(openmesh.HalfedgeHandle(0))
def test_on_demand_delete(self): # check if standard properties are requested on demand, # i.e. if it doesn't crash it works mesh = self.one_triangle() mesh.delete_vertex(openmesh.VertexHandle(0)) mesh.garbage_collection() mesh = self.one_triangle() mesh.delete_edge(openmesh.EdgeHandle(0)) mesh.garbage_collection() mesh = self.one_triangle() mesh.delete_face(openmesh.FaceHandle(0)) mesh.garbage_collection()
def test_on_demand_update(self): # check if standard properties are requested on demand, # i.e. if it doesn't crash it works mesh = self.one_triangle() mesh.update_normal(openmesh.FaceHandle(0)) mesh = self.one_triangle() mesh.update_face_normals() mesh = self.one_triangle() mesh.update_normal(openmesh.HalfedgeHandle(0)) mesh = self.one_triangle() mesh.update_halfedge_normals() mesh = self.one_triangle() mesh.update_normal(openmesh.VertexHandle(0)) mesh = self.one_triangle() mesh.update_vertex_normals() mesh = self.one_triangle() mesh.update_normals()
def find_largest_failing_triangle(omesh): def is_domain_corner(omesh, sv0, sv1, sv2): if not sv0.edges_with_p is None: if len(sv0.edges_with_p) == 2: return True if not sv1.edges_with_p is None: if len(sv1.edges_with_p) == 2: return True if not sv2.edges_with_p is None: if len(sv2.edges_with_p) == 2: return True return False def skip_to_avoid_ping_pong_encroachment(omesh, fh): def in_danger_of_encroachment(omesh, hh0, hh1): assert hh1 == omesh.next_halfedge_handle(hh0) eh0 = omesh.edge_handle(hh0) eh1 = omesh.edge_handle(hh1) if omesh.is_boundary(eh0) and omesh.is_boundary(eh1): p0 = omesh.point(omesh.from_vertex_handle(hh0)) p1 = omesh.point(omesh.to_vertex_handle(hh0)) p2 = omesh.point(omesh.to_vertex_handle(hh1)) angle = calculate_angle_between_vectors( normalize(p0 - p1), normalize(p2 - p1)) return angle < PPE_THRESHOLD return False hh0 = omesh.halfedge_handle(fh) hh1 = omesh.next_halfedge_handle(hh0) hh2 = omesh.next_halfedge_handle(hh1) if in_danger_of_encroachment(omesh, hh0, hh1) or\ in_danger_of_encroachment(omesh, hh1, hh2) or\ in_danger_of_encroachment(omesh, hh2, hh0): return True return False def shape_test(sv0, sv1, sv2): p0 = sv0.XYZ_vec3() p1 = sv1.XYZ_vec3() p2 = sv2.XYZ_vec3() alpha = calculate_angle_in_corner(p0, p1, p2) beta = calculate_angle_in_corner(p1, p2, p0) gamma = calculate_angle_in_corner(p2, p0, p1) return min(alpha, beta, gamma) > SMALLEST_ANGLE def size_test(sv0, sv1, sv2): def approximation_distance(sv0, sv1, sv2): # center-of-gravity distance sv_cog = SuperVertex.compute_surface_center_of_gravity( sv0, sv1, sv2) cog_surface = sv_cog.XYZ_vec3() cog_3d = (sv0.XYZ_vec3() + sv1.XYZ_vec3() + sv2.XYZ_vec3()) / 3 cog_distance = np.linalg.norm(cog_surface - cog_3d) distance = cog_distance if APPROX_DIST_MULTI_SAMPLING: # halfway-point distances hw0_surface = SuperVertex.compute_halfway(sv0, sv1).XYZ_vec3() hw1_surface = SuperVertex.compute_halfway(sv1, sv2).XYZ_vec3() hw2_surface = SuperVertex.compute_halfway(sv2, sv0).XYZ_vec3() hw0_3d = sv0.XYZ_vec3() + ( (sv1.XYZ_vec3() - sv0.XYZ_vec3()) / 2) hw1_3d = sv1.XYZ_vec3() + ( (sv2.XYZ_vec3() - sv1.XYZ_vec3()) / 2) hw2_3d = sv2.XYZ_vec3() + ( (sv0.XYZ_vec3() - sv2.XYZ_vec3()) / 2) hw0_distance = np.linalg.norm(hw0_surface - hw0_3d) hw1_distance = np.linalg.norm(hw1_surface - hw1_3d) hw2_distance = np.linalg.norm(hw2_surface - hw2_3d) distance = (distance + hw0_distance + hw1_distance + hw2_distance) / 4 if APPROX_DIST_AREA_WRIGHTED: area = calculate_area(sv0.XYZ_vec3(), sv1.XYZ_vec3(), sv2.XYZ_vec3()) distance /= area**0.5 return distance**2 t_distance = approximation_distance(sv0, sv1, sv2) if USE_SIZE_TEST: return t_distance < DISTANCE_THRESHOLD, t_distance else: return True, t_distance delta = om.FaceHandle(-1) delta_size = float('-inf') for fh in omesh.faces(): sv0, sv1, sv2 = collect_triangle_supervertices(omesh, fh) p0 = sv0.XYZ_vec3() p1 = sv1.XYZ_vec3() p2 = sv2.XYZ_vec3() if SKIP_ALL_DOMAIN_CORNERS and is_domain_corner(omesh, sv0, sv1, sv2): continue if SKIP_PPE_DOMAIN_CORNERS and skip_to_avoid_ping_pong_encroachment( omesh, fh): continue well_shaped = shape_test(sv0, sv1, sv2) well_sized, t_distance = size_test(sv0, sv1, sv2) if well_shaped and well_sized: continue if PRIORITY_FACTOR == PRIORITIZE_AREA: t_size = calculate_area(p0, p1, p2) elif PRIORITY_FACTOR == PRIORITIZE_CIRCUMRADIUS: t_size = calculate_circumradius_v2(p0, p1, p2) elif PRIORITY_FACTOR == PRIORITIZE_DISTANCE: t_size = t_distance else: raise Exception('PRIORITY_FACTOR unknown') if t_size > delta_size: delta_size = t_size delta = fh return delta