Beispiel #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
Beispiel #2
0
def stl_to_plot3d_filename(stl_filename, p3d_filename, log=None, ascii=True):
    model = STL(log=log)
    model.read_stl(stl_filename)

    #nodal_normals = model.get_normals_at_nodes(model.elements)

    with open(p3d_filename, 'wb') as p3d:
        nblocks = len(model.elements)
        #nblocks = 10
        p3d.write('%i\n' % nblocks)
        for iblock in range(nblocks):
            p3d.write('2 2 1\n')

        nodes = model.nodes
        elements = model.elements
        if 0:
            for i in [0, 1, 2]:
                for iblock in range(nblocks):
                    (n1, n2, n3) = elements[iblock]
                    p1 = nodes[n1, :]
                    p2 = nodes[n2, :]
                    p3 = nodes[n3, :]
                    p4 = p3
                    xi = [[p1[i], p2[i], p3[i], p4[i]]]
                    savetxt(p3d, xi, fmt='%f')
        else:
            for iblock in range(nblocks):
                for i in [0, 1, 2]:
                    (n1, n2, n3) = elements[iblock]
                    p1 = nodes[n1, :]
                    p2 = nodes[n2, :]
                    p3 = nodes[n3, :]
                    p4 = p3
                    xi = [[p1[i], p2[i], p3[i], p4[i]]]
                    savetxt(p3d, xi, fmt='%f')
Beispiel #3
0
    def test_stl_io_01(self):
        lines = (
            'solid	testsphere\n'
            '    facet normal -0.13 -0.13 -0.98\n'
            '        outer loop\n'
            '            vertex 1.50000 1.50000 0.00000\n'
            '            vertex 1.50000 1.11177 0.05111\n'
            '            vertex 1.11177 1.50000 0.05111\n'
            '        endloop\n'
            '    endfacet\n'
            '    facet normal  0.13  0.13 -0.98\n'
            '        outer loop\n'
            '            vertex 1.50000 1.50000 0.00000\n'
            '            vertex 1.50000 1.88823 0.05111\n'
            '            vertex 1.88823 1.50000 0.05111\n'
            '        endloop\n'
            '    endfacet\n'
            'endsolid\n'
        )
        stl_filename = os.path.join(test_path, 'tris.stl')
        with open(stl_filename, 'w') as f:
            f.write(lines)

        stl = STL(log=None, debug=False)
        stl.read_stl(stl_filename)
        assert len(stl.nodes) == 6, 'nodes=%s' % len(stl.nodes)
        assert len(stl.elements) == 2, 'nelements=%s' % len(stl.elements)
        os.remove(stl_filename)
Beispiel #4
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
Beispiel #5
0
def stl_to_plot3d_filename(stl_filename, p3d_filename, log=None, ascii=True):
    model = STL(log=log)
    model.read_stl(stl_filename)

    # nodal_normals = model.get_normals_at_nodes(model.elements)

    with open(p3d_filename, "wb") as p3d:
        nblocks = len(model.elements)
        # nblocks = 10
        p3d.write("%i\n" % nblocks)
        for iblock in range(nblocks):
            p3d.write("2 2 1\n")

        nodes = model.nodes
        elements = model.elements
        if 0:
            for i in [0, 1, 2]:
                for iblock in range(nblocks):
                    (n1, n2, n3) = elements[iblock]
                    p1 = nodes[n1, :]
                    p2 = nodes[n2, :]
                    p3 = nodes[n3, :]
                    p4 = p3
                    xi = [[p1[i], p2[i], p3[i], p4[i]]]
                    savetxt(p3d, xi, fmt="%f")
        else:
            for iblock in range(nblocks):
                for i in [0, 1, 2]:
                    (n1, n2, n3) = elements[iblock]
                    p1 = nodes[n1, :]
                    p2 = nodes[n2, :]
                    p3 = nodes[n3, :]
                    p4 = p3
                    xi = [[p1[i], p2[i], p3[i], p4[i]]]
                    savetxt(p3d, xi, fmt="%f")
def stl_to_nastran_filename(stl_filename, bdf_filename,
                            nnodes_offset=0, nelements_offset=0,
                            pid=100, mid=200,
                            size=8, is_double=False,
                            log=None):
    model = STL(log=log)
    model.read_stl(stl_filename)

    nid = nnodes_offset + 1
    cid = None
    load_id = 10

    nodal_normals = model.get_normals_at_nodes(model.elements)

    bdf = open(bdf_filename, 'wb')
    bdf.write('CEND\n')
    #bdf.write('LOAD = %s\n' % load_id)
    bdf.write('BEGIN BULK\n')
    nid2 = 1
    magnitude = 100.

    if size == 8:
        print_card = print_card_8
    elif size == 16:
        if is_double:
            print_card = print_card_16
        else:
            print_card = print_card_double

    for x, y, z in model.nodes:
        card = ['GRID', nid, cid, x, y, z]
        bdf.write(print_card_16(card))

        #nx, ny, nz = nodal_normals[nid2 - 1]
        #card = ['FORCE', load_id, nid, cid, magnitude, nx, ny, nz]
        #bdf.write(print_card_8(card))
        nid += 1
        nid2 += 1

    eid = nelements_offset + 1
    for (n1, n2, n3) in (model.elements + (nnodes_offset + 1)):
        card = ['CTRIA3', eid, pid, n1, n2, n3]
        bdf.write(print_card_8(card))
        eid += 1

    t = 0.1
    card = ['PSHELL', pid, mid, t]
    bdf.write(print_card_8(card))

    E = 1e7
    G = None
    nu = 0.3
    card = ['MAT1', mid, E, G, nu]
    bdf.write(print_card_8(card))

    bdf.write('ENDDATA\n')
    bdf.close()
def stl_to_plot3d_filename(stl_filename, p3d_filename, log=None, ascii=True):
    model = STL(log=log)
    model.read_stl(stl_filename)

    #nodal_normals = model.get_normals_at_nodes(model.elements)

    p3d = open(p3d_filename, 'wb')
    nblocks = len(model.elements)
    #nblocks = 10
    p3d.write('%i\n' % nblocks)
    for iblock in range(nblocks):
        p3d.write('2 2 1\n')

    nodes = model.nodes
    elements = model.elements
    if 0:
        for i in [0, 1, 2]:
            for iblock in range(nblocks):
                (n1, n2, n3) = elements[iblock]
                p1 = nodes[n1, :]
                p2 = nodes[n2, :]
                p3 = nodes[n3, :]
                p4 = p3
                xi = [[p1[i], p2[i], p3[i], p4[i]]]
                savetxt(p3d, xi, fmt='%f')
    else:
        for iblock in range(nblocks):
            for i in [0, 1, 2]:
                (n1, n2, n3) = elements[iblock]
                p1 = nodes[n1, :]
                p2 = nodes[n2, :]
                p3 = nodes[n3, :]
                p4 = p3
                xi = [[p1[i], p2[i], p3[i], p4[i]]]
                savetxt(p3d, xi, fmt='%f')

            #p3d.write("----\n")
            #x = [[p1[0], p2[0], p3[0], p4[0]]]
            #y = [[p1[1], p2[1], p3[1], p4[1]]]
            #z = [[p1[2], p2[2], p3[2], p4[2]]]

            #savetxt(p3d, x, fmt='%f')
            #savetxt(p3d, y, fmt='%f')
            #savetxt(p3d, z, fmt='%f')

        #p3d.write('\n')
        #p3d.write(' '.join(x) + '\n')
        #p3d.write(' '.join(y) + '\n')
        #p3d.write(' '.join(z) + '\n')
        #xxxz
        #yyyz
        #zzzz
    p3d.close()
Beispiel #8
0
def main():  # pragma: no cover
    bdf_filename = 'bay.bdf'
    bc_file = 'bc'

    bdf_filename2 = 'bay2.bdf'
    cart3d_filename = 'bay.i.tri'
    stl_filename = 'bay.stl'
    #in_format = 'nastran'
    flip_normals = True

    volume_bdfname = 'bay.vol.bdf'

    module = __import__(bc_file)
    pid_map = module.__dict__['pid_map']
    boundary_conditions = module.__dict__['boundary_conditions']

    #print(dir(module))
    #e = execfile(bc_file, globals(), locals())
    #print(globals())
    #print(dir(e))

    pid_map
    boundary_conditions
    assert isinstance(pid_map, dict)
    assert isinstance(boundary_conditions, dict)

    get_bcs(bdf_filename, pid_map, boundary_conditions, log=None)
    #if flip_normals:
    #bdf = BDF(debug=False)
    #bdf.read_bdf(bdf_filename, xref=False)
    #bdf.flip_normals()
    #bdf.write_bdf(bdf_filename2)
    #del bdf
    #else:
    #bdf_filename2 = bdf_filename

    if 0:
        nastran_to_cart3d_filename(bdf_filename, cart3d_filename, log=log)
        cart3d_to_stl_filename(cart3d_filename, stl_filename, log=log)
    else:
        nastran_to_stl_filename(bdf_filename, stl_filename, log=log)
        stl_to_nastran_filename(stl_filename, bdf_filename2, log=log)
    print('----------')
    #nastran_to_cart3d(bdf_filename2, cart3d_filename)
    #cart3d = Cart3d()
    #cart3d.read_cart3d(cart3d_filename)

    stl = STL()
    stl.read_stl(stl_filename)

    if flip_normals:
        stl.flip_normals()
    stl.project_boundary_layer(stl.nodes, stl.elements, volume_bdfname)
Beispiel #9
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
Beispiel #10
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
def main():
    bdf_filename = 'bay.bdf'
    bc_file = 'bc'

    bdf_filename2 = 'bay2.bdf'
    cart3d_filename = 'bay.i.tri'
    stl_filename = 'bay.stl'
    #in_format = 'nastran'
    flip_normals = True

    volume_bdfname = 'bay.vol.bdf'

    module = __import__(bc_file)
    pid_map = module.__dict__['pid_map']
    boundary_conditions = module.__dict__['boundary_conditions']

    #print(dir(module))
    #e = execfile(bc_file, globals(), locals())
    #print(globals())
    #print(dir(e))

    pid_map
    boundary_conditions
    assert isinstance(pid_map, dict)
    assert isinstance(boundary_conditions, dict)

    get_bcs(bdf_filename, pid_map, boundary_conditions, log=None)
    #if flip_normals:
       #bdf = BDF()
       #bdf.read_bdf(bdf_filename, xref=False)
       #bdf.flip_normals()
       #bdf.write_bdf(bdf_filename2)
       #del bdf
    #else:
    #bdf_filename2 = bdf_filename

    if 0:
        nastran_to_cart3d_filename(bdf_filename, cart3d_filename, log=log)
        cart3d_to_stl_filename(cart3d_filename, stl_filename, log=log)
    else:
        nastran_to_stl_filename(bdf_filename, stl_filename, log=log)
        stl_to_nastran_filename(stl_filename, bdf_filename2, log=log)
    print("----------")
    #nastran_to_cart3d(bdf_filename2, cart3d_filename)
    #cart3d = Cart3d()
    #cart3d.read_cart3d(cart3d_filename)

    stl = STL()
    stl.read_stl(stl_filename)

    if flip_normals:
        stl.flip_normals()
    stl.project_boundary_layer(stl.nodes, stl.elements, volume_bdfname)
Beispiel #12
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')
Beispiel #13
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
Beispiel #14
0
def merge_stl_files(stl_filenames,
                    stl_out_filename=None,
                    remove_bad_elements=False,
                    is_binary=True,
                    float_fmt='%6.12f',
                    log=None):
    """
    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

    log = get_logger2(log=log, debug=False, encoding='utf-8')
    if len(stl_filenames) == 1:
        model = STL(log=log)
        model.read_stl(stl_filenames[0])
        if remove_bad_elements:
            model.remove_elements_with_bad_normals()
        if stl_out_filename is not None:
            model.write_stl(stl_out_filename, is_binary=is_binary)
        return model

    nodes = []
    elements = []

    n0 = 0
    for i, fname in enumerate(stl_filenames):
        log.debug(f'reading file {i}: {fname}')
        model = STL(
            log=log)  # 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()

    if stl_out_filename is not None:
        model.write_stl(stl_out_filename,
                        is_binary=is_binary,
                        float_fmt=float_fmt)
    return model
Beispiel #15
0
    def load_stl_geometry(self, stl_filename, dirname, name='main', plot=True):
        #print("load_stl_geometry...")
        skip_reading = self._remove_old_geometry(stl_filename)
        if skip_reading:
            return

        model = STL(log=self.log, debug=False)
        #self.model_type = model.model_type
        model.read_stl(stl_filename)
        nodes = model.nodes
        elements = model.elements

        normals = model.get_normals(elements, stop_on_failure=False)
        areas = model.get_area(elements, stop_on_failure=False)
        #nnormals = model.get_normals_at_nodes(elements)
        self.nNodes = nodes.shape[0]
        self.nElements = elements.shape[0]

        self.log.info('nnodes=%s nelements=%s' % (self.nNodes, self.nElements))
        self.grid.Allocate(self.nElements, 1000)
        #self.gridResult.SetNumberOfComponents(self.nElements)

        points = vtk.vtkPoints()
        points.SetNumberOfPoints(self.nNodes)
        #self.gridResult.Allocate(self.nNodes, 1000)
        #vectorReselt.SetNumberOfComponents(3)
        self.nid_map = {}
        #elem.SetNumberOfPoints(nNodes)
        if 0:
            fraction = 1. / self.nNodes  # so you can color the nodes by ID
            for nid, node in sorted(iteritems(nodes)):
                points.InsertPoint(nid - 1, *node)
                self.gridResult.InsertNextValue(nid * fraction)
                #print str(element)

                #elem = vtk.vtkVertex()
                #elem.GetPointIds().SetId(0, i)
                #self.aQuadGrid.InsertNextCell(elem.GetCellType(), elem.GetPointIds())
                #vectorResult.InsertTuple3(0, 0.0, 0.0, 1.0)

        assert nodes is not None
        nnodes = nodes.shape[0]
        xmax, ymax, zmax = nodes.max(axis=0)
        xmin, ymin, zmin = nodes.min(axis=0)
        self.log.info('xmax=%s xmin=%s' % (xmax, xmin))
        self.log.info('ymax=%s ymin=%s' % (ymax, ymin))
        self.log.info('zmax=%s zmin=%s' % (zmax, zmin))
        dim_max = max(xmax - xmin, ymax - ymin, zmax - zmin)
        self.create_global_axes(dim_max)

        nid = 0
        #print("nnodes=%s" % nnodes)
        for i in range(nnodes):
            points.InsertPoint(nid, nodes[i, :])
            nid += 1

        nelements = elements.shape[0]
        #elements -= 1
        for eid in range(nelements):
            elem = vtkTriangle()
            node_ids = elements[eid, :]
            elem.GetPointIds().SetId(0, node_ids[0])
            elem.GetPointIds().SetId(1, node_ids[1])
            elem.GetPointIds().SetId(2, node_ids[2])
            self.grid.InsertNextCell(
                5, elem.GetPointIds())  #elem.GetCellType() = 5  # vtkTriangle

        self.grid.SetPoints(points)
        self.grid.Modified()
        if hasattr(self.grid, 'Update'):
            self.grid.Update()
            self.log_info("updated grid")

        # loadSTLResults - regions/loads
        self.turn_text_on()
        self.scalarBar.VisibilityOff()
        self.scalarBar.Modified()

        cases = {}
        self.iSubcaseNameMap = {}
        ID = 1

        form, cases = self._fill_stl_case(cases, ID, elements, nodes, normals,
                                          areas)
        self._finish_results_io2(form, cases)
Beispiel #16
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
Beispiel #17
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)
Beispiel #18
0
def stl_to_nastran(stl_filename,
                   bdf_filename,
                   nnodes_offset=0,
                   nelements_offset=0,
                   pid=100,
                   mid=200,
                   size=8,
                   is_double=False,
                   log=None):
    if isinstance(stl_filename, string_types):
        model = STL(log=log)
        model.read_stl(stl_filename)
    elif isinstance(stl_filename, STL):
        model = stl_filename
    else:
        raise TypeError('stl_filename must be a string or STL; type=%s' %
                        type(stl_filename))

    nid = nnodes_offset + 1
    cid = None
    load_id = 10

    nodal_normals = model.get_normals_at_nodes(model.elements)

    if size == 8:
        print_card = print_card_8
    elif size == 16:
        if is_double:
            print_card = print_card_16
        else:
            print_card = print_card_double
    else:
        raise RuntimeError('size=%r' % size)

    with open(bdf_filename, 'w') as bdf:
        bdf.write('CEND\n')
        #bdf.write('LOAD = %s\n' % load_id)
        bdf.write('BEGIN BULK\n')
        nid2 = 1
        magnitude = 100.

        for x, y, z in model.nodes:
            card = ['GRID', nid, cid, x, y, z]
            bdf.write(print_card_16(card))

            #nx, ny, nz = nodal_normals[nid2 - 1]
            #card = ['FORCE', load_id, nid, cid, magnitude, nx, ny, nz]
            #bdf.write(print_card_8(card))
            nid += 1
            nid2 += 1

        eid = nelements_offset + 1
        for (n1, n2, n3) in (model.elements + (nnodes_offset + 1)):
            card = ['CTRIA3', eid, pid, n1, n2, n3]
            bdf.write(print_card_8(card))
            eid += 1

        t = 0.1
        card = ['PSHELL', pid, mid, t]
        bdf.write(print_card_8(card))

        E = 1e7
        G = None
        nu = 0.3
        card = ['MAT1', mid, E, G, nu]
        bdf.write(print_card_8(card))
        bdf.write('ENDDATA\n')
    return bdf
Beispiel #19
0
    def load_stl_geometry(self, stl_filename, dirname, name='main', plot=True):
        print("load_stl_geometry...")
        skip_reading = self.removeOldGeometry(stl_filename)
        if skip_reading:
            return

        model = STL(log=self.log, debug=False)
        #self.model_type = model.model_type
        model.read_stl(stl_filename)
        nodes = model.nodes
        elements = model.elements

        normals = model.get_normals(elements)
        areas = model.get_area(elements)
        #nnormals = model.get_normals_at_nodes(elements)
        self.nNodes = nodes.shape[0]
        self.nElements = elements.shape[0]

        print("nnodes = %s" % self.nNodes)
        print("nelements = %s" % self.nElements)

        self.grid.Allocate(self.nElements, 1000)
        #self.gridResult.SetNumberOfComponents(self.nElements)

        points = vtk.vtkPoints()
        points.SetNumberOfPoints(self.nNodes)
        #self.gridResult.Allocate(self.nNodes, 1000)
        #vectorReselt.SetNumberOfComponents(3)
        self.nid_map = {}
        #elem.SetNumberOfPoints(nNodes)
        if 0:
            fraction = 1. / self.nNodes  # so you can color the nodes by ID
            for nid, node in sorted(iteritems(nodes)):
                points.InsertPoint(nid - 1, *node)
                self.gridResult.InsertNextValue(nid * fraction)
                #print str(element)

                #elem = vtk.vtkVertex()
                #elem.GetPointIds().SetId(0, i)
                #self.aQuadGrid.InsertNextCell(elem.GetCellType(), elem.GetPointIds())
                #vectorResult.InsertTuple3(0, 0.0, 0.0, 1.0)

        assert nodes is not None
        nnodes = nodes.shape[0]
        xmax, ymax, zmax = nodes.max(axis=0)
        xmin, ymin, zmin = nodes.min(axis=0)
        self.log.info('xmax=%s xmin=%s' % (xmax, xmin))
        self.log.info('ymax=%s ymin=%s' % (ymax, ymin))
        self.log.info('zmax=%s zmin=%s' % (zmax, zmin))
        dim_max = max(xmax-xmin, ymax-ymin, zmax-zmin)
        self.create_global_axes(dim_max)


        nid = 0
        print("nnodes=%s" % nnodes)
        for i in range(nnodes):
            points.InsertPoint(nid, nodes[i, :])
            nid += 1

        nelements = elements.shape[0]
        #elements -= 1
        for eid in range(nelements):
            elem = vtkTriangle()
            node_ids = elements[eid, :]
            elem.GetPointIds().SetId(0, node_ids[0])
            elem.GetPointIds().SetId(1, node_ids[1])
            elem.GetPointIds().SetId(2, node_ids[2])
            self.grid.InsertNextCell(5, elem.GetPointIds())  #elem.GetCellType() = 5  # vtkTriangle

        self.grid.SetPoints(points)
        self.grid.Modified()
        if hasattr(self.grid, 'Update'):
            self.grid.Update()
            print("updated grid")

        # loadSTLResults - regions/loads
        self. turn_text_on()
        self.scalarBar.VisibilityOff()
        self.scalarBar.Modified()

        cases = {}
        self.iSubcaseNameMap = {}
        ID = 1

        form, cases = self._fill_stl_case(cases, ID, elements, nodes, normals, areas)
        self._finish_results_io2(form, cases)
Beispiel #20
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
Beispiel #21
0
def stl_to_nastran(stl_filename, bdf_filename,
                   nnodes_offset=0, nelements_offset=0,
                   pid=100, mid=200,
                   size=8, is_double=False,
                   log=None):
    if isinstance(stl_filename, string_types):
        model = STL(log=log)
        model.read_stl(stl_filename)
    elif isinstance(stl_filename, STL):
        model = stl_filename
    else:
        raise TypeError('stl_filename must be a string or STL; type=%s' % type(stl_filename))

    nid = nnodes_offset + 1
    cid = None
    load_id = 10

    nodal_normals = model.get_normals_at_nodes(model.elements)

    if size == 8:
        print_card = print_card_8
    elif size == 16:
        if is_double:
            print_card = print_card_16
        else:
            print_card = print_card_double
    else:
        raise RuntimeError('size=%r' % size)

    with open(bdf_filename, 'w') as bdf:
        bdf.write('CEND\n')
        #bdf.write('LOAD = %s\n' % load_id)
        bdf.write('BEGIN BULK\n')
        nid2 = 1
        magnitude = 100.

        for x, y, z in model.nodes:
            card = ['GRID', nid, cid, x, y, z]
            bdf.write(print_card_16(card))

            #nx, ny, nz = nodal_normals[nid2 - 1]
            #card = ['FORCE', load_id, nid, cid, magnitude, nx, ny, nz]
            #bdf.write(print_card_8(card))
            nid += 1
            nid2 += 1

        eid = nelements_offset + 1
        for (n1, n2, n3) in (model.elements + (nnodes_offset + 1)):
            card = ['CTRIA3', eid, pid, n1, n2, n3]
            bdf.write(print_card_8(card))
            eid += 1

        t = 0.1
        card = ['PSHELL', pid, mid, t]
        bdf.write(print_card_8(card))

        E = 1e7
        G = None
        nu = 0.3
        card = ['MAT1', mid, E, G, nu]
        bdf.write(print_card_8(card))
        bdf.write('ENDDATA\n')
    return bdf
Beispiel #22
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)