def write_2_collada_falsecolour(occface_list, result_list, unit_str, dae_filepath, description_str=None, minval=None, maxval=None, other_occface_list=None, other_occedge_list=None): """ This function writes a falsecolour 3D model into a Collada file. Parameters ---------- occface_list : list of OCCfaces The geometries to be visualised with the results. The list of geometries must correspond to the list of results. Other OCCtopologies are also accepted, but the OCCtopology must contain OCCfaces. OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface. result_list : list of floats The results to be visualised. The list of results must correspond to the occface_list. unit_str : str The string of the unit to be displayed on the bar. dae_filepath : str The file path of the DAE (Collada) file. description_str : str, optional Description for the falsecolour bar, Default = None. minval : float, optional The minimum value of the falsecolour rgb, Default = None. If None the maximum value is equal to the maximum value from the results. maxval : float, optional The maximum value of the falsecolour rgb, Default = None. If None the maximum value is equal to the minimum value from the results. other_occface_list : list of OCCfaces, optional Other geometries to be visualised together with the results, Default = None. Other OCCtopologies are also accepted, but the OCCtopology must contain OCCfaces. OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface. other_occedge_list : list of OCCedges, optional Other OCCedges to be visualised together with the results, Default = None. Returns ------- None : None The geometries are written to a DAE file. """ if minval == None: minval = min(result_list) if maxval == None: maxval = max(result_list) #FOR CREATING THE FALSECOLOUR BAR AND LABELS topo_cmpd = construct.make_compound(occface_list) xmin, ymin, zmin, xmax, ymax, zmax = calculate.get_bounding_box(topo_cmpd) topo_centre_pt = calculate.get_centre_bbox(topo_cmpd) otopo_centre_pt = (topo_centre_pt[0], topo_centre_pt[1], zmin) topo_cmpd = modify.move(otopo_centre_pt, (0, 0, 0), topo_cmpd) xmin, ymin, zmin, xmax, ymax, zmax = calculate.get_bounding_box(topo_cmpd) x_extend = xmax - xmin y_extend = ymax - ymin topo_centre_pt = calculate.get_centre_bbox(topo_cmpd) topo_centre_pt = (topo_centre_pt[0], topo_centre_pt[1], zmin) loc_pt = modify.move_pt(topo_centre_pt, (1, 0, 0), x_extend / 1.5) grid_srfs, bar_colour, str_cmpd, str_colour_list, value_midpts = utility.generate_falsecolour_bar( minval, maxval, unit_str, y_extend, description_str=description_str, bar_pos=loc_pt) #DIVIDE THE RESULT INTO 10 DIVISION LIKE THE FALSECOLOUR BAR falsecolour_list = [] for result in result_list: if result >= maxval: falsecolour_list.append(bar_colour[-1]) elif result <= minval: falsecolour_list.append(bar_colour[0]) else: inc = (value_midpts[1] - value_midpts[0]) / 2.0 ur_cnt = 0 for midpt in value_midpts: if midpt - inc <= result <= midpt + inc: falsecolour_list.append(bar_colour[ur_cnt]) break ur_cnt += 1 #ARRANGE THE SURFACE AS ACCORDING TO ITS COLOUR colour_list = [] c_srf_list = [] for r_cnt in range(len(falsecolour_list)): fcolour = falsecolour_list[r_cnt] rf = occface_list[r_cnt] rf = modify.move(otopo_centre_pt, (0, 0, 0), rf) if fcolour not in colour_list: colour_list.append(fcolour) c_srf_list.append([rf]) elif fcolour in colour_list: c_index = colour_list.index(fcolour) c_srf_list[c_index].append(rf) cmpd_list = [] #SORT EACH SURFACE AS A COMPOUND for c_cnt in range(len(c_srf_list)): c_srfs = c_srf_list[c_cnt] compound = construct.make_compound(c_srfs) cmpd_list.append(compound) if other_occface_list != None: other_cmpd = construct.make_compound(other_occface_list) other_cmpd = modify.move(otopo_centre_pt, (0, 0, 0), other_cmpd) other_colour_list = [(1, 1, 1)] to_be_written_occface_list = cmpd_list + grid_srfs + [str_cmpd ] + [other_cmpd] to_be_written_colour_list = colour_list + bar_colour + str_colour_list + other_colour_list else: to_be_written_occface_list = cmpd_list + grid_srfs + [str_cmpd] to_be_written_colour_list = colour_list + bar_colour + str_colour_list if other_occedge_list != None: edge_cmpd = construct.make_compound(other_occedge_list) edge_cmpd = modify.move(otopo_centre_pt, (0, 0, 0), edge_cmpd) other_occedge_list = fetch.topo_explorer(edge_cmpd, "edge") mesh = occtopo_2_collada( dae_filepath, occface_list=to_be_written_occface_list, face_rgb_colour_list=to_be_written_colour_list, occedge_list=other_occedge_list) mesh.write(dae_filepath) else: mesh = occtopo_2_collada( dae_filepath, occface_list=to_be_written_occface_list, face_rgb_colour_list=to_be_written_colour_list) mesh.write(dae_filepath)
def write_2_collada(dae_filepath, occface_list=None, face_rgb_colour_list=None, occedge_list=None, text_string=None): """ This function writes a 3D model into a Collada file. Parameters ---------- dae_filepath : str The file path of the DAE (Collada) file. occface_list : list of OCCfaces, optional The geometries to be visualised with the results. The list of geometries must correspond to the list of results. Other OCCtopologies are also accepted, but the OCCtopology must contain OCCfaces. OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface. face_rgb_colour_list : list of tuple of floats, optional Each tuple is a r,g,b that is specifying the colour of the face,Default = None. The number of colours must correspond to the number of OCCfaces. occedge_list : list of OCCedges, optional OCCedges to be visualised together, Default = None. text_string : str, optional Description for the 3D model, Default = None. Returns ------- None : None The geometries are written to a DAE file. """ if text_string != None: if occface_list != None: overall_cmpd = construct.make_compound(occface_list) else: overall_cmpd = construct.make_compound(occedge_list) occface_list = [] xmin, ymin, zmin, xmax, ymax, zmax = calculate.get_bounding_box( overall_cmpd) xdim = xmax - xmin d_str = fetch.topo2topotype( construct.make_brep_text(text_string, xdim / 10)) xmin1, ymin1, zmin1, xmax1, ymax1, zmax1 = calculate.get_bounding_box( d_str) corner_pt = (xmin1, ymax1, zmin1) corner_pt2 = (xmin, ymin, zmin) moved_str = modify.move(corner_pt, corner_pt2, d_str) face_list = fetch.topo_explorer(moved_str, "face") meshed_list = [] for face in face_list: meshed_face_list = construct.simple_mesh(face) mface = construct.make_shell(meshed_face_list) face_mid_pt = calculate.face_midpt(face) str_mid_pt = calculate.get_centre_bbox(mface) moved_mface = modify.move(str_mid_pt, face_mid_pt, mface) meshed_list.append(moved_mface) meshed_str_cmpd = construct.make_compound(meshed_list) occface_list.append(meshed_str_cmpd) if face_rgb_colour_list != None: face_rgb_colour_list.append((0, 0, 0)) mesh = occtopo_2_collada(dae_filepath, occface_list=occface_list, face_rgb_colour_list=face_rgb_colour_list, occedge_list=occedge_list) mesh.write(dae_filepath)
def flatten_shell_z_value(occshell, z=0): #face_list = fetch.faces_frm_solid(occshell) xmin, ymin, zmin, xmax, ymax, zmax = calculate.get_bounding_box(occshell) boundary_pyptlist = [[xmin, ymin, zmin], [xmax, ymin, zmin], [xmax, ymax, zmin], [xmin, ymax, zmin]] boundary_face = construct.make_polygon(boundary_pyptlist) b_mid_pt = calculate.face_midpt(boundary_face) flatten_shell = fetch.shape2shapetype( uniform_scale(occshell, 1, 1, 0, b_mid_pt)) face_list = construct.simple_mesh(flatten_shell) #face_list = fetch.geom_explorer(flatten_shell,"face") nfaces = len(face_list) merged_faces = construct.merge_faces(face_list) dest_pt = [b_mid_pt[0], b_mid_pt[1], z] #depending on how complicated is the shell we decide which is the best way to flatten it #1.) if it is an open shell and when everything is flatten it fits nicely as a flat surface if len(merged_faces) == 1: flatten_face = fetch.shape2shapetype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face #2.) if it is a complex shell with less than 500 faces we fused and create a single surface if nfaces < 50: try: fused_shape = None fcnt = 0 for face in face_list: face_area = calculate.face_area(face) if not face_area < 0.001: if fcnt == 0: fused_shape = face else: #construct.visualise([[fused_shape], [face]], ['WHITE', 'RED']) fused_shape = construct.boolean_fuse(fused_shape, face) fcnt += 1 if fused_shape != None: fused_face_list = fetch.geom_explorer(fused_shape, "face") merged_faces = construct.merge_faces(fused_face_list) if len(merged_faces) == 1: flatten_face = fetch.shape2shapetype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: flatten_vertex = fetch.geom_explorer( flatten_shell, "vertex") flatten_pts = fetch.vertex_list_2_point_list( flatten_vertex) flatten_pypts = fetch.occptlist2pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.shape2shapetype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None except RuntimeError: flatten_vertex = fetch.geom_explorer(flatten_shell, "vertex") flatten_pts = fetch.vertex_list_2_point_list(flatten_vertex) flatten_pypts = fetch.occptlist2pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.shape2shapetype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None #3.) if it is a complex shell with more than 500 faces we get the vertexes and create a triangulated srf with delaunay #and merge all the faces to make a single surface if nfaces >= 50: flatten_vertex = fetch.geom_explorer(flatten_shell, "vertex") flatten_pts = fetch.vertex_list_2_point_list(flatten_vertex) flatten_pypts = fetch.occptlist2pyptlist(flatten_pts) #flatten_pypts = rmv_duplicated_pts_by_distance(flatten_pypts, tolerance = 1e-04) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.shape2shapetype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None
def flatten_shell_z_value(occshell, z=0): """ This function flatten the OCCshell to the Z-value specified. Parameters ---------- occshell : OCCshell The OCCshell to be flattened. z : float, optional The Z-value to flatten to. Default = 0. Returns ------- flatten shell : OCCshell The flatten OCCshell. """ face_list = fetch.faces_frm_solid(occshell) xmin, ymin, zmin, xmax, ymax, zmax = calculate.get_bounding_box(occshell) boundary_pyptlist = [[xmin, ymin, zmin], [xmax, ymin, zmin], [xmax, ymax, zmin], [xmin, ymax, zmin]] boundary_face = construct.make_polygon(boundary_pyptlist) b_mid_pt = calculate.face_midpt(boundary_face) #flatten_shell = fetch.topo2topotype(uniform_scale(occshell, 1, 1, 0, b_mid_pt)) face_list = construct.simple_mesh(occshell) f_face_list = [] for occface in face_list: f_face = flatten_face_z_value(occface, z=zmin) f_face_list.append(f_face) face_list = f_face_list flatten_shell = construct.make_compound(face_list) nfaces = len(face_list) merged_faces = construct.merge_faces(face_list) dest_pt = [b_mid_pt[0], b_mid_pt[1], z] #depending on how complicated is the shell we decide which is the best way to flatten it #1.) if it is an open shell and when everything is flatten it fits nicely as a flat surface if len(merged_faces) == 1: m_area = calculate.face_area(merged_faces[0]) if m_area > 1e-06: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face #2.) if it is a complex shell with less than 500 faces we fused and create a single surface if nfaces < 50: try: fused_shape = None fcnt = 0 for face in face_list: face_area = calculate.face_area(face) if not face_area < 0.001: if fcnt == 0: fused_shape = face else: #construct.visualise([[fused_shape], [face]], ['WHITE', 'RED']) fused_shape = construct.boolean_fuse(fused_shape, face) fcnt += 1 if fused_shape != None: fused_face_list = fetch.topo_explorer(fused_shape, "face") merged_faces = construct.merge_faces(fused_face_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: flatten_vertex = fetch.topo_explorer( flatten_shell, "vertex") flatten_pts = modify.occvertex_list_2_occpt_list( flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None except RuntimeError: flatten_vertex = fetch.topo_explorer(flatten_shell, "vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None #3.) if it is a complex shell with more than 500 faces we get the vertexes and create a triangulated srf with delaunay #and merge all the faces to make a single surface if nfaces >= 50: flatten_vertex = fetch.topo_explorer(flatten_shell, "vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) #flatten_pypts = rmv_duplicated_pts_by_distance(flatten_pypts, tolerance = 1e-04) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None
def flatten_shell_z_value(occshell, z=0): """ This function flatten the OCCshell to the Z-value specified. Parameters ---------- occshell : OCCshell The OCCshell to be flattened. z : float, optional The Z-value to flatten to. Default = 0. Returns ------- flatten shell : OCCshell The flatten OCCshell. """ face_list = fetch.faces_frm_solid(occshell) xmin,ymin,zmin,xmax,ymax,zmax = calculate.get_bounding_box(occshell) boundary_pyptlist = [[xmin,ymin,zmin], [xmax,ymin,zmin], [xmax,ymax,zmin], [xmin,ymax,zmin]] boundary_face = construct.make_polygon(boundary_pyptlist) b_mid_pt = calculate.face_midpt(boundary_face) #flatten_shell = fetch.topo2topotype(uniform_scale(occshell, 1, 1, 0, b_mid_pt)) face_list = construct.simple_mesh(occshell) f_face_list = [] for occface in face_list: f_face = flatten_face_z_value(occface, z=zmin) f_face_list.append(f_face) face_list = f_face_list flatten_shell = construct.make_compound(face_list) nfaces = len(face_list) merged_faces = construct.merge_faces(face_list) dest_pt = [b_mid_pt[0], b_mid_pt[1], z] #depending on how complicated is the shell we decide which is the best way to flatten it #1.) if it is an open shell and when everything is flatten it fits nicely as a flat surface if len(merged_faces) == 1: m_area = calculate.face_area(merged_faces[0]) if m_area > 1e-06: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face #2.) if it is a complex shell with less than 500 faces we fused and create a single surface if nfaces < 50: try: fused_shape = None fcnt = 0 for face in face_list: face_area = calculate.face_area(face) if not face_area < 0.001: if fcnt == 0: fused_shape = face else: #construct.visualise([[fused_shape], [face]], ['WHITE', 'RED']) fused_shape = construct.boolean_fuse(fused_shape, face) fcnt+=1 if fused_shape!=None: fused_face_list = fetch.topo_explorer(fused_shape, "face") merged_faces = construct.merge_faces(fused_face_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face else: flatten_vertex = fetch.topo_explorer(flatten_shell,"vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None except RuntimeError: flatten_vertex = fetch.topo_explorer(flatten_shell,"vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None #3.) if it is a complex shell with more than 500 faces we get the vertexes and create a triangulated srf with delaunay #and merge all the faces to make a single surface if nfaces >=50: flatten_vertex = fetch.topo_explorer(flatten_shell,"vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) #flatten_pypts = rmv_duplicated_pts_by_distance(flatten_pypts, tolerance = 1e-04) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None