Ejemplo n.º 1
0
def cart3d_to_stl(cart3d, stl_filename=None, is_binary=False, log=None, debug=False):
    """
    Converts a Cart3D object to STL format.

    Parameters
    ----------
    cart3d : Cart3D()
        a Cart3D object
    stl_filename : str; default=None
        path to the output STL file (or None to skip)
    log : log
        a logger object (or None)
    debug : bool; default=False
        True/False (used if log is not defined)

    Returns
    -------
    stl : STL()
        an STL object
    """
    #normals = cart3d.get_normals()
    stl = STL(log=log, debug=debug)
    stl.nodes = cart3d.nodes - 1
    stl.elements = cart3d.elements - 1
    if stl_filename:
        stl.write_stl(stl_filename, is_binary=is_binary)
    return stl
Ejemplo n.º 2
0
def nastran_to_stl(bdf_filename, stl_filename, is_binary=False, log=None):
    """
    Converts a Nastran model to an STL

    Parameters
    ----------
    bdf_filename : varies
        str : the path to a BDF input file
        BDF() : a BDF() model object
    stl_filename : str
        the output STL path
    is_binary : bool; default=False
        should the output file be binary
    """
    if isinstance(bdf_filename, str):
        model = read_bdf(bdf_filename, log=None)
    else:
        model = bdf_filename

    #log.info('card_count = %s' % model.card_count)

    nnodes = len(model.nodes)
    nodes = zeros((nnodes, 3), dtype='float64')
    elements = []

    i = 0
    nodeid_to_i_map = {}
    for node_id, node in sorted(iteritems(model.nodes)):
        xyz = node.get_position()
        nodes[i, :] = xyz
        nodeid_to_i_map[node_id] = i
        i += 1

    assert len(model.nodes) == i, 'model.nodes=%s i=%s' % (len(model.nodes), i)
    for eid, element in sorted(iteritems(model.elements)):
        if element.type in ['CQUADR']:
            continue
        elif element.type in ['CBAR', 'CBEAM', 'CONM2', 'RBE2', 'RBE3',
                              'CBUSH', 'CBUSH1D', 'CBUSH2D',
                              'CONROD', 'CROD',
                              'CELAS1', 'CELAS2', 'CELAS3', 'CELAS4',
                              'CDAMP1', 'CDAMP2', 'CDAMP3', 'CDAMP4',]:
            continue
        elif element.type in ['CQUAD4']:
            n1, n2, n3, n4 = element.node_ids
            i1, i2, i3, i4 = nodeid_to_i_map[n1], nodeid_to_i_map[n2], nodeid_to_i_map[n3], nodeid_to_i_map[n4]
            elements.append([i1, i2, i3])
            elements.append([i3, i4, i1])
        elif element.type in ['CTRIA3', 'CTRIAR']:
            n1, n2, n3 = element.node_ids
            i1, i2, i3 = nodeid_to_i_map[n1], nodeid_to_i_map[n2], nodeid_to_i_map[n3]
            elements.append([i1, i2, i3])
        else:
            print(element.type)
    elements = array(elements, dtype='int32')
    stl = STL()
    stl.nodes = nodes
    stl.elements = elements
    stl.write_stl(stl_filename, is_binary=is_binary)
    return stl
Ejemplo n.º 3
0
def cart3d_to_stl(cart3d,
                  stl_filename=None,
                  is_binary=False,
                  log=None,
                  debug=False):
    """
    Converts a Cart3D object to STL format.

    Parameters
    ----------
    cart3d : Cart3D()
        a Cart3D object
    stl_filename : str; default=None
        path to the output STL file (or None to skip)
    log : log
        a logger object (or None)
    debug : bool; default=False
        True/False (used if log is not defined)

    Returns
    -------
    stl : STL()
        an STL object

    .. todo:: this seems to be broken...
    """
    #normals = cart3d.get_normals()
    stl = STL(log=log, debug=debug)
    stl.nodes = cart3d.nodes  #- 1
    stl.elements = cart3d.elements  #- 1
    assert stl.elements.min() == 0, stl.elements.min()
    if stl_filename:
        stl.write_stl(stl_filename, is_binary=is_binary)
    return stl
Ejemplo n.º 4
0
def merge_stl_files(stl_filenames, stl_out_filename=None, remove_bad_elements=False,
                    is_binary=True, float_fmt='%6.12f'):
    """
    Combines multiple STLs into a single file

    Parameters
    ----------
    stl_filenames : List[str, str, ...]
        list of stl filenames or a string filename
        (useful for removing bad elements)
    remove_bad_elements : bool; default=False
        should elements with invalid normals be removed?
    stl_out_filename : str; default=None -> no writing
        string of stl output filename
    is_binary : bool; default=True
        should the output file be binary
    float_fmt : str; default='%6.12f'
        the ascii float format

    Returns
    -------
    stl : STL()
        the stl object
    """
    if isinstance(stl_filenames, str):
        stl_filenames = [stl_filenames]
    assert isinstance(stl_filenames, (list, tuple)), type(stl_filenames)
    assert len(stl_filenames) > 0, stl_filenames

    if len(stl_filenames) == 1:
        model = STL()
        model.read_stl(stl_filenames[0])
        if remove_bad_elements:
            model.remove_elements_with_bad_normals(model.elements, nodes=model.nodes)
        if stl_out_filename is not None:
            model.write_stl(stl_out_filename, is_binary=is_binary)
        return model

    nodes = []
    elements = []

    n0 = 0
    for fname in stl_filenames:
        model = STL()  # TODO: you shouldn't need to to reinstantiate the STL
        model.read_stl(fname)
        nnodes = model.nodes.shape[0]
        nodes.append(model.nodes)
        elements.append(model.elements + n0)
        n0 += nnodes

    model.nodes = vstack(nodes)
    model.elements = vstack(elements)

    if remove_bad_elements:
        model.remove_elements_with_bad_normals(model.elements, nodes=model.nodes)

    if stl_out_filename is not None:
        model.write_stl(stl_out_filename, is_binary=is_binary, float_fmt=float_fmt)
    return model
Ejemplo n.º 5
0
def merge_stl_files(stl_filenames, stl_out_filename=None, remove_bad_elements=False,
                    is_binary=True, float_fmt='%6.12f'):
    """
    Combines multiple STLs into a single file

    Parameters
    ----------
    stl_filenames : List[str, str, ...]
        list of stl filenames or a string filename
        (useful for removing bad elements)
    remove_bad_elements : bool; default=False
        should elements with invalid normals be removed?
    stl_out_filename : str; default=None -> no writing
        string of stl output filename
    is_binary : bool; default=True
        should the output file be binary
    float_fmt : str; default='%6.12f'
        the ascii float format

    Returns
    -------
    stl : STL()
        the stl object
    """
    if isinstance(stl_filenames, str):
        stl_filenames = [stl_filenames]
    assert isinstance(stl_filenames, (list, tuple)), type(stl_filenames)
    assert len(stl_filenames) > 0, stl_filenames

    if len(stl_filenames) == 1:
        model = STL()
        model.read_stl(stl_filenames[0])
        if remove_bad_elements:
            model.remove_elements_with_bad_normals(model.elements, nodes=model.nodes)
        if stl_out_filename is not None:
            model.write_stl(stl_out_filename, is_binary=is_binary)
        return model

    nodes = []
    elements = []

    n0 = 0
    for fname in stl_filenames:
        model = STL()  # TODO: you shouldn't need to to reinstantiate the STL
        model.read_stl(fname)
        nnodes = model.nodes.shape[0]
        nodes.append(model.nodes)
        elements.append(model.elements + n0)
        n0 += nnodes

    model.nodes = vstack(nodes)
    model.elements = vstack(elements)

    if remove_bad_elements:
        model.remove_elements_with_bad_normals(model.elements, nodes=model.nodes)

    if stl_out_filename is not None:
        model.write_stl(stl_out_filename, is_binary=is_binary, float_fmt=float_fmt)
    return model
Ejemplo n.º 6
0
def nastran_to_stl(model, stl_filename, is_binary=False):
    #log.info('card_count = %s' % model.card_count)

    nnodes = len(model.nodes)
    nodes = zeros((nnodes, 3), dtype='float64')
    elements = []

    i = 0
    nodeid_to_i_map = {}
    for node_id, node in sorted(iteritems(model.nodes)):
        xyz = node.get_position()
        nodes[i, :] = xyz
        nodeid_to_i_map[node_id] = i
        i += 1

    assert len(model.nodes) == i, 'model.nodes=%s i=%s' % (len(model.nodes), i)
    for eid, element in sorted(iteritems(model.elements)):
        if element.type in ['CQUADR']:
            continue
        elif element.type in ['CBAR', 'CBEAM', 'CONM2', 'RBE2', 'RBE3',
                              'CBUSH', 'CBUSH1D', 'CBUSH2D',
                              'CONROD', 'CROD',
                              'CELAS1', 'CELAS2', 'CELAS3', 'CELAS4',
                              'CDAMP1', 'CDAMP2', 'CDAMP3', 'CDAMP4',]:
            continue
        elif element.type in ['CQUAD4']:
            n1, n2, n3, n4 = element.node_ids
            i1, i2, i3, i4 = nodeid_to_i_map[n1], nodeid_to_i_map[n2], nodeid_to_i_map[n3], nodeid_to_i_map[n4]
            elements.append([i1, i2, i3])
            elements.append([i3, i4, i1])
        elif element.type in ['CTRIA3', 'CTRIAR']:
            n1, n2, n3 = element.node_ids
            i1, i2, i3 = nodeid_to_i_map[n1], nodeid_to_i_map[n2], nodeid_to_i_map[n3]
            elements.append([i1, i2, i3])
        else:
            print(element.type)
    elements = array(elements, dtype='int32')
    stl = STL()
    stl.nodes = nodes
    stl.elements = elements
    stl.write_stl(stl_filename, is_binary=is_binary)
    return stl
Ejemplo n.º 7
0
def main():  # pragma: no cover
    import os

    #base = 'gear'
    #read_tetgen(base, dimension_flag=2)
    #return

    from pyNastran.converters.stl.stl import STL
    m1 = STL()
    m1.read_stl('tetgen_test.stl')
    m1.flip_normals()
    m1.write_stl('tetgen_test_flipped.stl')
    del m1

    os.system('tetgen.exe -pqcvVqY tetgen_test_flipped.stl')

    m = Tetgen()
    base = 'tetgen_test_flipped.1'
    m.read_tetgen(base + '.node', base + '.smesh', base + '.ele', dimension_flag=3)
    m.write_nastran(base + '.bdf')
Ejemplo n.º 8
0
def nastran_to_stl(bdf_filename,
                   stl_filename,
                   is_binary=False,
                   log=None,
                   stop_on_failure=False):
    """
    Converts a Nastran model to an STL

    Parameters
    ----------
    bdf_filename : varies
        str : the path to a BDF input file
        BDF() : a BDF() model object
    stl_filename : str
        the output STL path
    is_binary : bool; default=False
        should the output file be binary
    log : Logger()
        a Python logging object
    stop_on_failure : bool; default=False
        should the code stop if an error is encountered
    """
    if isinstance(bdf_filename, str):
        model = read_bdf(bdf_filename, log=log)
    else:
        model = bdf_filename

    #log.info('card_count = %s' % model.card_count)

    nnodes = len(model.nodes)
    nodes = np.zeros((nnodes, 3), dtype='float64')
    elements = []

    i = 0
    nodeid_to_i_map = {}
    offset = False
    if offset:
        nid = list(model.nodes.keys())[0]
        xyz0 = model.nodes[nid].get_position()
    else:
        xyz0 = np.zeros(3, dtype='float64')
    for node_id, node in sorted(model.nodes.items()):
        xyz = node.get_position()
        nodes[i, :] = xyz - xyz0
        nodeid_to_i_map[node_id] = i
        i += 1
    assert len(model.nodes) == i, 'model.nodes=%s i=%s' % (len(model.nodes), i)
    for unused_eid, element in sorted(model.elements.items()):
        if element.type in ['CQUADR']:
            continue
        elif element.type in [
                'CBAR',
                'CBEAM',
                'CONM2',
                'RBE2',
                'RBE3',
                'CBUSH',
                'CBUSH1D',
                'CBUSH2D',
                'CONROD',
                'CROD',
                'CELAS1',
                'CELAS2',
                'CELAS3',
                'CELAS4',
                'CDAMP1',
                'CDAMP2',
                'CDAMP3',
                'CDAMP4',
        ]:
            continue
        elif element.type in ['CQUAD4']:
            n1, n2, n3, n4 = element.node_ids
            i1, i2, i3, i4 = (nodeid_to_i_map[n1], nodeid_to_i_map[n2],
                              nodeid_to_i_map[n3], nodeid_to_i_map[n4])
            elements.append([i1, i2, i3])
            elements.append([i3, i4, i1])
        elif element.type in ['CTRIA3', 'CTRIAR']:
            nids = element.node_ids
            unids = np.unique(nids)
            if len(unids) == 2:
                continue
            n1, n2, n3 = nids
            i1, i2, i3 = nodeid_to_i_map[n1], nodeid_to_i_map[
                n2], nodeid_to_i_map[n3]
            elements.append([i1, i2, i3])
        else:
            model.log.warning('skipping %s' % element.type)
    elements = np.array(elements, dtype='int32')
    stl = STL(log=model.log)
    stl.nodes = nodes
    #stl.nodes -= nodes[0, :]
    stl.elements = elements
    stl.write_stl(stl_filename,
                  is_binary=is_binary,
                  stop_on_failure=stop_on_failure)
    return stl
Ejemplo n.º 9
0
def nastran_to_stl(bdf_filename, stl_filename, is_binary=False, log=None):
    """
    Converts a Nastran model to an STL

    Parameters
    ----------
    bdf_filename : varies
        str : the path to a BDF input file
        BDF() : a BDF() model object
    stl_filename : str
        the output STL path
    is_binary : bool; default=False
        should the output file be binary
    log : Logger()
        a Python logging object
    """
    if isinstance(bdf_filename, str):
        model = read_bdf(bdf_filename, log=log)
    else:
        model = bdf_filename

    #log.info('card_count = %s' % model.card_count)

    nnodes = len(model.nodes)
    nodes = zeros((nnodes, 3), dtype='float64')
    elements = []

    i = 0
    nodeid_to_i_map = {}
    for node_id, node in sorted(iteritems(model.nodes)):
        xyz = node.get_position()
        nodes[i, :] = xyz
        nodeid_to_i_map[node_id] = i
        i += 1

    assert len(model.nodes) == i, 'model.nodes=%s i=%s' % (len(model.nodes), i)
    for eid, element in sorted(iteritems(model.elements)):
        if element.type in ['CQUADR']:
            continue
        elif element.type in [
                'CBAR',
                'CBEAM',
                'CONM2',
                'RBE2',
                'RBE3',
                'CBUSH',
                'CBUSH1D',
                'CBUSH2D',
                'CONROD',
                'CROD',
                'CELAS1',
                'CELAS2',
                'CELAS3',
                'CELAS4',
                'CDAMP1',
                'CDAMP2',
                'CDAMP3',
                'CDAMP4',
        ]:
            continue
        elif element.type in ['CQUAD4']:
            n1, n2, n3, n4 = element.node_ids
            i1, i2, i3, i4 = nodeid_to_i_map[n1], nodeid_to_i_map[
                n2], nodeid_to_i_map[n3], nodeid_to_i_map[n4]
            elements.append([i1, i2, i3])
            elements.append([i3, i4, i1])
        elif element.type in ['CTRIA3', 'CTRIAR']:
            n1, n2, n3 = element.node_ids
            i1, i2, i3 = nodeid_to_i_map[n1], nodeid_to_i_map[
                n2], nodeid_to_i_map[n3]
            elements.append([i1, i2, i3])
        else:
            print(element.type)
    elements = array(elements, dtype='int32')
    stl = STL(log=model.log)
    stl.nodes = nodes
    stl.elements = elements
    stl.write_stl(stl_filename, is_binary=is_binary)
    return stl
Ejemplo n.º 10
0
def stl_reshape(data):
    if '--xy' not in data:
        data['--xy'] = False
    if '--yz' not in data:
        data['--yz'] = False
    if '--xz' not in data:
        data['--xz'] = False
    if '--scale' not in data:
        data['--scale'] = None

    if '--xscale' not in data:
        data['--xscale'] = None
    if '--yscale' not in data:
        data['--yscale'] = None
    if '--zscale' not in data:
        data['--zscale'] = None

    if '<xshift>' not in data:
        data['<xshift>'] = None
    if '<yshift>' not in data:
        data['<yshift>'] = None
    if '<zshift>' not in data:
        data['<zshift>'] = None

    if '--stats' not in data:
        data['--stats'] = None
    if '--mirror' not in data:
        data['--mirror'] = None
    if '--flip_normals' not in data:
        data['--flip_normals'] = None

    in_stl_filename = data['<in_stl_filename>']
    out_stl_filename = data['<out_stl_filename>']
    assert in_stl_filename != out_stl_filename

    stl = STL()
    stl.read_stl(in_stl_filename)

    if data['<fmt>'] in ['False', False]:
        is_binary = True
        fmt = None
    else:
        fmt = data['<fmt>']
        is_binary = False
    print('is_binary=%s' % is_binary)

    if data['--xy'] or data['--yz'] or data['--xz']:
        scale = 1.
        if data['--scale'] is not None:
            scale = float(data['--scale'])

        if data['--xy']:
            assert data['--yz'] is False
            assert data['--xz'] is False
            axes = 'xy'
        elif data['--yz']:
            assert data['--xy'] is False
            assert data['--xz'] is False
            axes = 'yz'
        elif data['--xz']:
            assert data['--xy'] is False
            assert data['--yz'] is False
            axes = 'xz'
        #print('flip_axes = %r' % axes)
        #print(data)
        stl.flip_axes(axes, scale)

    elif data['--xscale'] or data['--yscale'] or data['--zscale']:
        xscale = 1.
        yscale = 1.
        zscale = 1.
        if data['--xscale'] is not None:
            xscale = float(data['--xscale'].strip("'"))
        if data['--yscale'] is not None:
            yscale = float(data['--yscale'].strip("'"))
        if data['--zscale'] is not None:
            zscale = float(data['--zscale'].strip("'"))
        x = deepcopy(stl.nodes[:, 0])
        y = deepcopy(stl.nodes[:, 1])
        z = deepcopy(stl.nodes[:, 2])
        stl.nodes[:, 0] = x * xscale
        stl.nodes[:, 1] = y * yscale
        stl.nodes[:, 2] = z * zscale
    elif data['<xshift>'] or data['<yshift>'] or data['<zshift>']:
        xshift = 1.
        yshift = 1.
        zshift = 1.
        if data['<xshift>'] is not None:
            if isinstance(xshift, basestring):
                xshift = float(data['<xshift>'].strip("'"))
            else:
                xshift = float(data['<xshift>'])

        if data['<yshift>'] is not None:
            if isinstance(xshift, basestring):
                yshift = float(data['<yshift>'].strip("'"))
            else:
                yshift = float(data['<yshift>'])

        if data['<zshift>'] is not None:
            if isinstance(xshift, basestring):
                zshift = float(data['<zshift>'].strip("'"))
            else:
                zshift = float(data['<zshift>'])

        print('delta = (%s, %s, %s)' % (xshift, yshift, zshift))
        stl.nodes[:, 0] += xshift
        stl.nodes[:, 1] += yshift
        stl.nodes[:, 2] += zshift
    elif data['--scale']:
        scale = float(data['--scale'])
        stl.nodes *= scale
    elif data['--stats']:
        xmax, ymax, zmax = stl.nodes.max(axis=0)
        xmin, ymin, zmin = stl.nodes.min(axis=0)
        print('xyz_max = (%g, %g, %g)' % (xmax, ymax, zmax))
        print('xyz_min = (%g, %g, %g)' % (xmin, ymin, zmin))
        return
    elif data['--mirror']:
        #plane = data['plane']
        #assert plane in ['xy', 'yz', 'xz'], 'plane=%r' % plane
        xyz = data['<xyz>']
        tol = float(data['<tol>'])
        stl.create_mirror_model(xyz, tol)
    elif data['--flip_normals']:
        stl.flip_normals()
    else:
        raise RuntimeError('unsupported reshape...data=%s' % data)

    stl.write_stl(out_stl_filename, is_binary=is_binary, float_fmt=fmt)
Ejemplo n.º 11
0
def stl_reshape(data):
    if '--xy' not in data:
        data['--xy'] = False
    if '--yz' not in data:
        data['--yz'] = False
    if '--xz' not in data:
        data['--xz'] = False
    if '--scale' not in data:
        data['--scale'] = None

    if '--xscale' not in data:
        data['--xscale'] = None
    if '--yscale' not in data:
        data['--yscale'] = None
    if '--zscale' not in data:
        data['--zscale'] = None

    if '<xshift>' not in data:
        data['<xshift>'] = None
    if '<yshift>' not in data:
        data['<yshift>'] = None
    if '<zshift>' not in data:
        data['<zshift>'] = None

    if '--stats' not in data:
        data['--stats'] = None
    if '--mirror' not in data:
        data['--mirror'] = None
    if '--flip_normals' not in data:
        data['--flip_normals'] = None

    in_stl_filename = data['<in_stl_filename>']
    out_stl_filename = data['<out_stl_filename>']
    assert in_stl_filename != out_stl_filename

    stl = STL()
    stl.read_stl(in_stl_filename)

    if data['<fmt>'] in ['False', False]:
        is_binary = True
        fmt = None
    else:
        fmt = data['<fmt>']
        is_binary = False
    print('is_binary=%s' % is_binary)

    if data['--xy'] or data['--yz'] or data['--xz']:
        scale = 1.
        if data['--scale'] is not None:
            scale = float(data['--scale'])

        if data['--xy']:
            assert data['--yz'] is False
            assert data['--xz'] is False
            axes = 'xy'
        elif data['--yz']:
            assert data['--xy'] is False
            assert data['--xz'] is False
            axes = 'yz'
        elif data['--xz']:
            assert data['--xy'] is False
            assert data['--yz'] is False
            axes = 'xz'
        #print('flip_axes = %r' % axes)
        #print(data)
        stl.flip_axes(axes, scale)

    elif data['--xscale'] or data['--yscale'] or data['--zscale']:
        xscale = 1.
        yscale = 1.
        zscale = 1.
        if data['--xscale'] is not None:
            xscale = float(data['--xscale'].strip("'"))
        if data['--yscale'] is not None:
            yscale = float(data['--yscale'].strip("'"))
        if data['--zscale'] is not None:
            zscale = float(data['--zscale'].strip("'"))
        x = deepcopy(stl.nodes[:, 0])
        y = deepcopy(stl.nodes[:, 1])
        z = deepcopy(stl.nodes[:, 2])
        stl.nodes[:, 0] = x * xscale
        stl.nodes[:, 1] = y * yscale
        stl.nodes[:, 2] = z * zscale
    elif data['<xshift>'] or data['<yshift>'] or data['<zshift>']:
        xshift = 1.
        yshift = 1.
        zshift = 1.
        if data['<xshift>'] is not None:
            if isinstance(xshift, basestring):
                xshift = float(data['<xshift>'].strip("'"))
            else:
                xshift = float(data['<xshift>'])

        if data['<yshift>'] is not None:
            if isinstance(xshift, basestring):
                yshift = float(data['<yshift>'].strip("'"))
            else:
                yshift = float(data['<yshift>'])

        if data['<zshift>'] is not None:
            if isinstance(xshift, basestring):
                zshift = float(data['<zshift>'].strip("'"))
            else:
                zshift = float(data['<zshift>'])

        print('delta = (%s, %s, %s)' % (xshift, yshift, zshift))
        stl.nodes[:, 0] += xshift
        stl.nodes[:, 1] += yshift
        stl.nodes[:, 2] += zshift
    elif data['--scale'] :
        scale = float(data['--scale'])
        stl.nodes *= scale
    elif data['--stats'] :
        xmax, ymax, zmax = stl.nodes.max(axis=0)
        xmin, ymin, zmin = stl.nodes.min(axis=0)
        print('xyz_max = (%g, %g, %g)' % (xmax, ymax, zmax))
        print('xyz_min = (%g, %g, %g)' % (xmin, ymin, zmin))
        return
    elif data['--mirror']:
        #plane = data['plane']
        #assert plane in ['xy', 'yz', 'xz'], 'plane=%r' % plane
        xyz = data['<xyz>']
        tol = float(data['<tol>'])
        stl.create_mirror_model(xyz, tol)
    elif data['--flip_normals']:
        stl.flip_normals()
    else:
        raise RuntimeError('unsupported reshape...data=%s' % data)

    stl.write_stl(out_stl_filename, is_binary=is_binary, float_fmt=fmt)