def embed_label(model, face, side, label, glyph): # transform face to shape (into which we will embed the label) transform = MtxMath.conv_to_euclid(VecMath.rotate_fromto_matrix(face._norm, np.array([0., 0., 1.]))) vertices = [transform * euclid.Point3(v[0], v[1], v[2]) for v in face._vertices] target_path = svg.Path.from_shape(svg.Shape([np.array([v[0], v[1]]) for v in vertices])) # render label into path label_path = svg.Path.combine([(glyph[int(c)], np.array([1., 0.])) for c in label]) # move/scale label to fit into target triangle p, s, r = fit_rect_in_triangle(vertices, side, label_path._bbox) label_path.scale(s[0], s[1]) pivot = label_path._bbox._center+np.array([0, label_path._bbox._size[1]*-.5]) label_path.rotate(r, anchor=pivot) label_path.translate(p-pivot) # embed the label embedded_model = target_path.embed([label_path.triangulate(z=vertices[0].z)], group_name='svg', z=vertices[0].z) embedded_model.transform(transform.inverse()) # (optional) extrude the label embedded_model.get_group('svg')._material._diffuse = [1., 0., 0.] embedded_model.extrude(-.5, faces=embedded_model.get_group('svg')._faces) # replace initial face with new 'labeled face' model.remove_face(face) model.merge(embedded_model) return embedded_model
def get_path_from_face(face): transform = MtxMath.conv_to_euclid( VecMath.rotate_fromto_matrix(face._norm, np.array([0., 0., 1.]))) vertices = [ transform * euclid.Point3(v[0], v[1], v[2]) for v in face._vertices ] path = svg.Path.from_shape( svg.Shape([np.array([v[0], v[1]]) for v in vertices])) return path, transform
def test_get_rotation_mtx_equal_vecs(self): """ edge case: would normaly break rot mtx. use identity mtx instead """ a = np.array([1., 0., 0.]) b = np.array([1., 0., 0.]) rot = VecMath.rotate_fromto_matrix(a, b) self.assertIsNotNone(rot) a2 = rot.__matmul__(a) self.assertEqual(VecMath.angle_between(a2, b), 0.0)
def test_get_rotation_mtx(self): a = np.array([1., 0., 0.]) b = np.array([0., 1., 0.]) rot = VecMath.rotate_fromto_matrix(a, b) self.assertIsNotNone(rot) a2 = rot.__matmul__(a) self.assertNotEqual(VecMath.angle_between(a, b), 0.0) self.assertEqual(VecMath.angle_between(a2, b), 0.0)
def write(model, filename, orientation_vec=None): """Rotate and center object to lay flat on the heat-bead""" model._update() if orientation_vec is None: transform = euclid.Matrix4.new_translate(-model._center[0], -model._center[1], -model._center[2]) else: transform = MtxMath.conv_to_euclid( VecMath.rotate_fromto_matrix(orientation_vec, np.array([0., 0., -1.]))) n = transform * euclid.Point3(-model._center[0], -model._center[1], -model._center[2]) transform = euclid.Matrix4.new_translate(n.x, n.y, n.z) * transform write_obj(model, filename, transform=transform)
model.merge(embedded_model) return embedded_model if __name__ == "__main__": radius = 100. sphere = primitives.Sphere(radius) obj_model = sphere.triangulate(recursion_level=2) for iter in range(0,4): print(f'noise iteration({iter})') for idx, vertex in enumerate(obj_model._vertices): l = min([edge.length for edge in obj_model.get_edges_with_vertex(idx)]) * .1 rnd_d = get_random_norm() dir = VecMath.unit_vector(vertex) transf = MtxMath.conv_to_euclid(VecMath.rotate_fromto_matrix(np.array([0., 0., 1.]), dir)) tv = transf * (rnd_d*euclid.Vector3(l,l,10)) vertex += tv # sphere_model.triangulate() ObjExporter.write(obj_model, f'./export/_sphere_noise.obj') print(f'Faces: {len(obj_model._faces)}') print(f'Vertices: {len(obj_model._vertices)}') bbox_size = obj_model._size print(f'Boundingbox: [{bbox_size[0]}, {bbox_size[1]}, {bbox_size[2]}]') target_lid_size = 100. #mm^2 faceted_model = Model() facets = []
d = euclid.Vector3(random.uniform(0, 1), random.uniform(0, 1), 0.).normalize() # d = euclid.Vector3(0., 0., 0.) # d.x = random.uniform(-1, 1) # d.y = random.uniform(-1, 1) # d.z = random.uniform(-.1, .1) # d.z = 1. return d if __name__ == "__main__": radius = 100. sphere = primitives.Sphere(radius) sphere_model = sphere.triangulate(recursion_level=2) for iter in range(0, 4): print(f'noise iteration({iter})') for idx, vertex in enumerate(sphere_model._vertices): l = min([ edge.length for edge in sphere_model.get_edges_with_vertex(idx) ]) * .1 rnd_d = get_random_norm() dir = vm.unit_vector(vertex) transf = MtxMath.conv_to_euclid( vm.rotate_fromto_matrix(np.array([0., 0., 1.]), dir)) tv = transf * (rnd_d * euclid.Vector3(l, l, 10)) vertex += tv # sphere_model.triangulate() ObjExporter.write(sphere_model, f'./export/_sphere_noise.obj')