Exemplo n.º 1
0
def sort_face_by_xy(occface_list):
    """
    This function sorts the faces in order of the xy direction.
 
    Parameters
    ----------        
    occface_list : list of OCCfaces
        The list of OCCfaces to be sorted.

    Returns
    -------
    sorted list of faces : list of OCCfaces
        The list of sorted OCCfaces in xy direction.
    """
    fdict = {}
    vlist = []
    for face in occface_list:
        cpt = calculate.face_midpt(face)
        v = construct.make_vertex(cpt)
        vlist.append(v)
        fdict[cpt] = face

    #import utility
    #utility.visualise([occface_list, vlist], ["WHITE", "BLUE"])
    fitems = fdict.items()
    fitems.sort(key=lambda x: [x[0][1], x[0][0]])

    flist = []
    for f in fitems:
        flist.append(f[1])

    return flist
Exemplo n.º 2
0
def sort_face_by_xy(occface_list):
    """
    This function sorts the faces in order of the xy direction.
 
    Parameters
    ----------        
    occface_list : list of OCCfaces
        The list of OCCfaces to be sorted.

    Returns
    -------
    sorted list of faces : list of OCCfaces
        The list of sorted OCCfaces in xy direction.
    """
    fdict = {}
    vlist =[]
    for face in occface_list:
        cpt = calculate.face_midpt(face)
        v = construct.make_vertex(cpt)
        vlist.append(v)
        fdict[cpt] = face
       
    #import utility
    #utility.visualise([occface_list, vlist], ["WHITE", "BLUE"])
    fitems = fdict.items()
    fitems.sort(key=lambda x: [x[0][1], x[0][0]])

    flist = []
    for f in fitems:
        flist.append(f[1])
        
    return flist
Exemplo n.º 3
0
def extrude(occface, pydir, height):
    orig_pt = calculate.face_midpt(occface)
    dest_pt = modify.move_pt(orig_pt, pydir, height)
    moved_face = modify.move(orig_pt, dest_pt, occface)
    loft = make_loft([occface, moved_face])
    face_list = fetch.geom_explorer(loft, "face")
    face_list.append(occface)
    face_list.append(moved_face)
    shell = make_shell_frm_faces(face_list)[0]
    solid = make_solid(shell)
    solid = modify.fix_close_solid(solid)
    return solid
Exemplo n.º 4
0
def generate_falsecolour_bar(minval, maxval, unit_str, bar_length, 
                             description_str = None, bar_pos = (0,0,0),
                             inverse = False):
    """
    This function constructs a falsecolour diagram.
 
    Parameters
    ----------
    minval : float
        The minimum value of the falsecolour bar.
        
    maxval : float
        The maximum value of the falsecolour bar.
        
    unit_str : str
        The string of the unit to be displayed on the bar.
        
    bar_length : float
        The length of the falsecolour bar.
        
    description_str : str, optional
        Description for the falsecolour bar, Default = None.
        
    bar_pos : tuple of floats, optional
        The position of the bar, Default = (0,0,0).
    
    inverse : bool
        False for red being max, True for blue being maximum.
        
    Returns
    -------
    falsecolour bar : list of OCCfaces
        The falsecolor bar which is a list of OCCfaces. 
        
    bar colour : list of tuple of floats
        Each tuple is a r,g,b that is specifying the colour of the bar.
        
    geometries of text: OCCcompound
        The geometries of the text.
        
    str_colour_list : list of tuple of floats
        Each tuple is a r,g,b that is specifying the colour of the string.
        
    value of each falsecolour : list of floats
        The value of each falsecolour.
    """
    import numpy
    interval = 10.0
    xdim = bar_length/interval
    ydim = bar_length
    rectangle = construct.make_rectangle(xdim, ydim)
    rec_mid_pt = calculate.face_midpt(rectangle)
    moved_rectangle = fetch.topo2topotype(modify.move(rec_mid_pt, bar_pos, rectangle))
    
    grid_srfs = construct.grid_face(moved_rectangle, xdim, xdim)

    #generate uniform results between max and min
    inc1 = (maxval-minval)/(interval)
    value_range = list(numpy.arange(minval, maxval+0.1, inc1))
    inc2 = inc1/2.0
    value_range_midpts = list(numpy.arange(minval+inc2, maxval, inc1))
    bar_colour = falsecolour(value_range_midpts, minval, maxval, inverse=inverse)
    grid_srfs2 = []
    moved_str_face_list = []
    srf_cnt = 0
    for srf in grid_srfs:
        reversed_srf = modify.reverse_face(srf)
        grid_srfs2.append(reversed_srf)
        res_label = round(value_range[srf_cnt],2)
        brep_str = fetch.topo2topotype(construct.make_brep_text(str(res_label), xdim/2))
        orig_pt = calculate.get_centre_bbox(brep_str)
        loc_pt = calculate.face_midpt(srf)
        loc_pt = modify.move_pt(loc_pt, (1,-0.3,0), xdim*1.2)
        moved_str = modify.move(orig_pt, loc_pt, brep_str)
        moved_str_face_list.append(moved_str)
        
        if srf_cnt == len(grid_srfs)-1:
            res_label = round(value_range[srf_cnt+1],2)
            brep_str = fetch.topo2topotype(construct.make_brep_text(str(res_label), xdim/2))
            orig_pt = calculate.get_centre_bbox(brep_str)
            loc_pt3 = modify.move_pt(loc_pt, (0,1,0), xdim)
            moved_str = modify.move(orig_pt, loc_pt3, brep_str)
            moved_str_face_list.append(moved_str)
        
            brep_str_unit = construct.make_brep_text(str(unit_str), xdim)
            orig_pt2 = calculate.get_centre_bbox(brep_str_unit)
            loc_pt2 = modify.move_pt(loc_pt, (0,1,0), xdim*2)
            moved_str = modify.move(orig_pt2, loc_pt2, brep_str_unit)
            moved_str_face_list.append(moved_str)
            
        if description_str !=None:    
            if srf_cnt == 0:
                d_str = fetch.topo2topotype(construct.make_brep_text(description_str, xdim/2))
                orig_pt2 = calculate.get_centre_bbox(d_str)
                loc_pt2 = modify.move_pt(loc_pt, (0,-1,0), xdim*5)
                moved_str = modify.move(orig_pt2, loc_pt2, d_str)
                moved_str_face_list.append(moved_str)
            

        srf_cnt+=1
        
    cmpd = construct.make_compound(moved_str_face_list)
    face_list = fetch.topo_explorer(cmpd, "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)
    str_colour_list = [(0,0,0)]
    return grid_srfs2, bar_colour, meshed_str_cmpd, str_colour_list, value_range_midpts
Exemplo n.º 5
0
def generate_falsecolour_bar(minval,
                             maxval,
                             unit_str,
                             bar_length,
                             description_str=None,
                             bar_pos=(0, 0, 0),
                             inverse=False):
    """
    This function constructs a falsecolour diagram.
 
    Parameters
    ----------
    minval : float
        The minimum value of the falsecolour bar.
        
    maxval : float
        The maximum value of the falsecolour bar.
        
    unit_str : str
        The string of the unit to be displayed on the bar.
        
    bar_length : float
        The length of the falsecolour bar.
        
    description_str : str, optional
        Description for the falsecolour bar, Default = None.
        
    bar_pos : tuple of floats, optional
        The position of the bar, Default = (0,0,0).
    
    inverse : bool
        False for red being max, True for blue being maximum.
        
    Returns
    -------
    falsecolour bar : list of OCCfaces
        The falsecolor bar which is a list of OCCfaces. 
        
    bar colour : list of tuple of floats
        Each tuple is a r,g,b that is specifying the colour of the bar.
        
    geometries of text: OCCcompound
        The geometries of the text.
        
    str_colour_list : list of tuple of floats
        Each tuple is a r,g,b that is specifying the colour of the string.
        
    value of each falsecolour : list of floats
        The value of each falsecolour.
    """
    import numpy
    interval = 10.0
    xdim = bar_length / interval
    ydim = bar_length
    rectangle = construct.make_rectangle(xdim, ydim)
    rec_mid_pt = calculate.face_midpt(rectangle)
    moved_rectangle = fetch.topo2topotype(
        modify.move(rec_mid_pt, bar_pos, rectangle))

    grid_srfs = construct.grid_face(moved_rectangle, xdim, xdim)

    #generate uniform results between max and min
    inc1 = (maxval - minval) / (interval)
    value_range = list(numpy.arange(minval, maxval + 0.1, inc1))
    inc2 = inc1 / 2.0
    value_range_midpts = list(numpy.arange(minval + inc2, maxval, inc1))
    bar_colour = falsecolour(value_range_midpts,
                             minval,
                             maxval,
                             inverse=inverse)
    grid_srfs2 = []
    moved_str_face_list = []
    srf_cnt = 0
    for srf in grid_srfs:
        reversed_srf = modify.reverse_face(srf)
        grid_srfs2.append(reversed_srf)
        res_label = round(value_range[srf_cnt], 2)
        brep_str = fetch.topo2topotype(
            construct.make_brep_text(str(res_label), xdim / 2))
        orig_pt = calculate.get_centre_bbox(brep_str)
        loc_pt = calculate.face_midpt(srf)
        loc_pt = modify.move_pt(loc_pt, (1, -0.3, 0), xdim * 1.2)
        moved_str = modify.move(orig_pt, loc_pt, brep_str)
        moved_str_face_list.append(moved_str)

        if srf_cnt == len(grid_srfs) - 1:
            res_label = round(value_range[srf_cnt + 1], 2)
            brep_str = fetch.topo2topotype(
                construct.make_brep_text(str(res_label), xdim / 2))
            orig_pt = calculate.get_centre_bbox(brep_str)
            loc_pt3 = modify.move_pt(loc_pt, (0, 1, 0), xdim)
            moved_str = modify.move(orig_pt, loc_pt3, brep_str)
            moved_str_face_list.append(moved_str)

            brep_str_unit = construct.make_brep_text(str(unit_str), xdim)
            orig_pt2 = calculate.get_centre_bbox(brep_str_unit)
            loc_pt2 = modify.move_pt(loc_pt, (0, 1, 0), xdim * 2)
            moved_str = modify.move(orig_pt2, loc_pt2, brep_str_unit)
            moved_str_face_list.append(moved_str)

        if description_str != None:
            if srf_cnt == 0:
                d_str = fetch.topo2topotype(
                    construct.make_brep_text(description_str, xdim / 2))
                orig_pt2 = calculate.get_centre_bbox(d_str)
                loc_pt2 = modify.move_pt(loc_pt, (0, -1, 0), xdim * 5)
                moved_str = modify.move(orig_pt2, loc_pt2, d_str)
                moved_str_face_list.append(moved_str)

        srf_cnt += 1

    cmpd = construct.make_compound(moved_str_face_list)
    face_list = fetch.topo_explorer(cmpd, "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)
    str_colour_list = [(0, 0, 0)]
    return grid_srfs2, bar_colour, meshed_str_cmpd, str_colour_list, value_range_midpts
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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