def create_face_geom( coord_vals: SoCoordValsListType, face_indices: SoIndicesListType, face_color: SoVectorType, transparency: float, translation: SoVectorType = None, quaternion: SoQuaternionType = None ) -> ThreeJSSceneGraphObjectListType: """ Returns a pythreejs `Mesh` object that consists of the faces given by face_indices and the coord_vals. Additionally the attributes `Mesh.default_material` and `Mesh.geometry.default_color` will be set before returning the Mesh. Those attributes contain references to the default colors and materials that are set in this function to restore later changes. """ vertices = np.asarray(coord_vals, dtype='float32') faces = np.asarray(face_indices, dtype='uint16') normals = compute_normals(faces, vertices) faces = faces.ravel() vertexcolors = np.asarray([face_color] * len(coord_vals), dtype='float32') face_geometry = BufferGeometry( attributes=dict(position=BufferAttribute(vertices, normalized=False), index=BufferAttribute(faces, normalized=False), normal=BufferAttribute(normals, normalized=False), color=BufferAttribute(vertexcolors, normalized=False))) # this is used for returning to original state after highlighting face_geometry.default_color = vertexcolors # BUG: This is a bug in pythreejs and currently does not work #faceGeometry.exec_three_obj_method('computeFaceNormals') #faceGeometry.exec_three_obj_method('computeVertexNormals') col = so_col_to_hex(face_color) material = MeshPhongMaterial(color=col, transparency=transparency, depthTest=True, depthWrite=True, metalness=0) object_mesh = Mesh( geometry=face_geometry, material=material, position=[0, 0, 0] # Center the cube ) object_mesh.default_material = material if quaternion: object_mesh.quaternion = quaternion if translation: object_mesh.position = translation return [object_mesh]
def _get_cylinder_from_vec(v0, v1, d_args=None): """Draw the cylinder given the two endpoints. Args: v0 (list): one endpoint of line v1 (list): other endpoint of line d_args (dict): properties of the line (line_width and color) Returns: Mesh: Pythreejs object that displays the cylinders """ obj_args = update_object_args(d_args, "Cylinders", ['radius', 'color']) v0 = np.array(v0) v1 = np.array(v1) vec = v1 - v0 mid_point = (v0 + v1) / 2.0 rot_vec = np.cross([0, 1, 0], vec) rot_vec_len = np.linalg.norm(rot_vec) rot_vec = rot_vec / rot_vec_len rot_arg = np.arccos(np.dot([0, 1, 0], vec) / np.linalg.norm(vec)) new_bond = Mesh( geometry=CylinderBufferGeometry( radiusTop=obj_args['radius'], radiusBottom=obj_args['radius'], height=np.linalg.norm(v1 - v0), radialSegments=12, heightSegments=10, ), material=MeshLambertMaterial(color=obj_args['color']), position=tuple(mid_point), ) rot = R.from_rotvec(rot_arg * rot_vec) quat = tuple(rot.as_quat()) if any(isnan(itr_q) for itr_q in quat): new_bond.quaternion = (0, 0, 0, 0) else: new_bond.quaternion = quat return new_bond
def _get_cylinder_from_vec(v0, v1, radius=0.15, color="#FFFFFF"): v0 = np.array(v0) v1 = np.array(v1) vec = v1 - v0 mid_point = (v0 + v1) / 2. rot_vec = np.cross([0, 1, 0], vec) rot_vec_len = np.linalg.norm(rot_vec) rot_vec = rot_vec / rot_vec_len rot_arg = np.arccos(np.dot([0, 1, 0], vec) / np.linalg.norm(vec)) new_bond = Mesh(geometry=CylinderBufferGeometry(radiusTop=radius, radiusBottom=radius, height=np.linalg.norm(v1 - v0), radialSegments=12, heightSegments=10), material=MeshLambertMaterial(color=color), position=tuple(mid_point)) rot = R.from_rotvec(rot_arg * rot_vec) new_bond.quaternion = tuple(rot.as_quat()) return new_bond