def readTetgen(fn): """Read and draw a tetgen file. This is an experimental function for the geometry import menu. """ res = {} base, ext = os.path.splitext(fn) if ext == '.node': nodes = readNodeFile(fn)[0] res['tetgen' + ext] = nodes elif ext in ['.ele', '.face']: nodes, nodenrs = readNodeFile(utils.changeExt(fn, '.node'))[:2] if ext == '.ele': elems = readEleFile(fn)[0] elif ext == '.face': elems = readFaceFile(fn)[0] if nodenrs.min() == 1 and nodenrs.max() == nodenrs.size: elems = elems - 1 M = Mesh(nodes, elems, eltype=elems.eltype) res['tetgen' + ext] = M elif ext == '.smesh': nodes, elems = readSmeshFile(fn) ML = [Mesh(nodes, elems[e]) for e in elems] res = dict([('Mesh-%s' % M.nplex(), M) for M in ML]) elif ext == '.poly': nodes, elems = readPolyFile(fn) ML = [Mesh(nodes, elems[e]) for e in elems] res = dict([('Mesh-%s' % M.nplex(), M) for M in ML]) return res
def test_convert_mesh_units(self): init = _tri_prism_mesh_map(5) actual = convert_units.mm_mesh_to_inch_mesh(Mesh(init)) def scale_point(point, factor): return tuple(val * factor for val in point) mm_to_inch = 1 / 25.4 scaled = Mesh( { scale_point(k, mm_to_inch): { scale_point(v, mm_to_inch) for v in init[k] } for k in init } ) self.assertEqual(len(scaled), len(actual)) # Sort keys and check for almost equal # Sort corresponding values and check for almost equal exp_keys = sorted(scaled.keys()) actual_keys = sorted(actual.keys()) for i in range(len(actual)): self.assertAlmostEqual(exp_keys[i], actual_keys[i]) self.assertEqual(len(scaled[exp_keys[i]]), len(actual[actual_keys[i]])) exp_vals = sorted(scaled[exp_keys[i]]) actual_vals = sorted(actual[actual_keys[i]]) for j in range(len(exp_vals)): self.assertAlmostEqual(exp_vals[j], actual_vals[j])
def createAnimatedModel(self, f11): wld = self.wld_container.wld_file_obj f10 = wld.getFragment(f11.fragRef) if f10.type != 0x10: print 'Model::createAnimatedModel() ERROR expected 0x10 fragment but got:', f10.type return # Lets initially try to only read all the mesh pieces and assemble the basic # model. Once that is working we can start looking into animation # Loop over the parts of the model/skeleton: the entries list in the f10 fragment # define these root_mesh = None for i in range(0, f10.size1): if i > 0: f2d = wld.getFragment( f10.entries[i][3]) # entry[3] -> fragRef2 # f2d.dump() f36 = wld.getFragment(f2d.fragRef) # f36.dump() m = Mesh(self.name + '_mesh_' + str(i)) m.buildFromFragment(f36, self.wld_container, False) m.root.reparentTo(root_mesh.root) else: # the root node (index 0) does not have a mesh m = Mesh(self.name + '_mesh_' + str(i)) # empty dummy mesh root_mesh = m self.meshes.append(m) # get model part orientation data from 0x10->0x13->0x12 ref chain f13 = wld.getFragment(f10.entries[i][2]) # entry[2] -> fragRef1 f12 = wld.getFragment(f13.fragRef) denom = float(f12.rotDenom) if denom != 0.0: rotx = f12.rotx / denom roty = f12.roty / denom rotz = f12.rotz / denom m.root.setHpr(rotx / 512.0 * 360.0, roty / 512.0 * 360.0, rotz / 512.0 * 360.0) denom = float(f12.shiftDenom) if denom != 0.0: shiftx = float(f12.shiftx) / denom shifty = float(f12.shifty) / denom shiftz = float(f12.shiftz) / denom # print shiftx, shifty, shiftz m.root.setPos(shiftx, shifty, shiftz) self.loaded = 1
def show(self, ids): #TODO '''ids: list of ids to play ''' if max(ids) >= self.N: raise ValueError('id: out of bounds') mesh = Mesh(v=self.vertices_train[ids[0]], f=self.reference_mesh.f) time.sleep(0.5) # pause 0.5 seconds viewer = mesh.show() for i in range(len(ids) - 1): viewer.dynamic_meshes = [ Mesh(v=self.vertices_train[ids[i + 1]], f=self.reference_mesh.f) ] time.sleep(0.5) # pause 0.5 seconds return 0
def get_normalized_meshes(self, mesh_paths): #TODO meshes = [] for mesh_path in mesh_paths: mesh = Mesh(filename=mesh_path) mesh_v = (mesh.v - self.mean) / self.std meshes.append(mesh_v) return np.array(meshes)
def save_meshes(self, filename, meshes): #TODO for i in range(meshes.shape[0]): vertices = meshes[i].reshape( (self.n_vertex, 3)) * self.std + self.mean mesh = Mesh(v=vertices, f=self.reference_mesh.f) mesh.write_obj(filename + '-' + str(i).zfill(3) + '.obj') return 0
def read_mesh(fname, name=None): """ Defines mesh based on data provided in COO and MEM tabs """ if name is None: name = fname[:-5] # strip 'xlsx' from end of filename and use as name # Define new mesh object mesh_obj = Mesh(name=name) # Read in node data from Excel file COO_df = read_COO(fname) # Define nodes and append to mesh mesh_obj.define_nodes(df=COO_df) del COO_df # Read in member data from Excel file MEM_df = read_MEM(fname) # Define elements and append to mesh mesh_obj.define_line_elements(df=MEM_df) del MEM_df return mesh_obj
def __init__(self, nVal, train_file, test_file, reference_mesh_file, pca_n_comp=8, fitpca=False): self.nVal = nVal self.train_file = train_file self.test_file = test_file self.vertices_train = None self.vertices_val = None self.vertices_test = None self.N = None self.n_vertex = None self.fitpca = fitpca self.mean = None self.std = None self.load() self.reference_mesh = Mesh(filename=reference_mesh_file) #TODO # self.mean = np.mean(self.vertices_train, axis=0) # self.std = np.std(self.vertices_train, axis=0) self.pca = PCA(n_components=pca_n_comp) self.pcaMatrix = None self.normalize()
def Gen1Dmesh(Lx, nx=None, dx=None, vtag=-100, ctag=-1): """ Generate 1D Mesh/Grid ===================== INPUT: Lx : length of bar nx : number of points/nodes [optional] dx : increments [optional] vtag : default tag for all vertices ctag : default tag for all cells RETURNS: a Mesh object ---- Notes: 1) One or another among nx or dx must be specified 2) By default, the first vertex is tagged with -101 and the last one with -102 """ if dx==None: dx = Lx/float(nx-1) else: nx = int(Lx/dx) dx = Lx/float(nx-1) V = [[i, vtag, i * dx ] for i in range(nx)] C = [[i, ctag, [i, i+1]] for i in range(nx-1)] V[0 ][1] = -101 V[nx-1][1] = -102 return Mesh(V, C)
def create_mesh(self, part, road_width): self.write('#MESH\n') part_name = part.get_part_name() #makes global seed half of the road width globalSeed = road_width / 2 #creating mesh object mesh = Mesh(part, globalSeed) part.create_mesh(mesh) self.write(part_name + '.seedPart(size=' + str(globalSeed) + ', deviationFactor=0.1, minSizeFactor=0.1)\n') #self.write(part_name + '.seedEdgeBySize(edges=substrate_edges, size=' + str(localSeed) + ', deviationFactor=0.1, minSizeFactor=0.1, constraint=FINER)\n') self.write('e = ' + part_name + '.edges\n') self.write(part_name + '.generateMesh()\n') self.write( 'elemType1 = mesh.ElemType(elemCode=DC3D8, elemLibrary=STANDARD)\n' ) #heat transfer element type self.write( 'elemType2 = mesh.ElemType(elemCode=DC3D6, elemLibrary=STANDARD)\n' ) self.write( 'elemType3 = mesh.ElemType(elemCode=DC3D4, elemLibrary=STANDARD)\n' ) self.write('c = ' + part_name + '.cells\n') self.write('region = ' + part_name + '.Set(cells = c, name = "part")\n') part_set = Set(part, 'part') part.add_set(part_set) self.write( part_name + '.setElementType(regions=region, elemTypes=(elemType1,elemType2,elemType3))\n' ) self.seperate_sec()
def test02(): """ Spatially varying anisotropy """ print('Test 2:') grid = Grid(box=[0, 20, 0, 20], resolution=(100, 100)) mesh = Mesh(grid=grid) element = QuadFE(2, 'Q1') system = System(mesh, element) alph = 2 kppa = 1 # Symmetric tensor gma T + bta* vv^T gma = 0.1 bta = 25 v2 = lambda x, y: -0.75 * np.cos(np.pi * x / 10) v1 = lambda x, y: 0.25 * np.sin(np.pi * y / 10) h11 = lambda x, y: gma + v1(x, y) * v1(x, y) h12 = lambda x, y: v1(x, y) * v2(x, y) h22 = lambda x, y: v2(x, y) * v2(x, y) X = Gmrf.from_matern_pde(alph, kppa, mesh, element, tau=(h11, h12, h22)) x = X.sample(1).ravel() fig, ax = plt.subplots() plot = Plot() ax = plot.contour(ax, fig, x, mesh, element, resolution=(200, 200)) plt.show()
def polygon(nb_sides): """Create a regular polygonal 2D mesh """ #create mesh m = Mesh() #create points pids = [] for i in range(nb_sides): pid = m.add_dart(0) vec = (cos(2 * pi * i / nb_sides), sin(2 * pi * i / nb_sides)) m.set_position(pid, vec) pids.append(pid) #create segments eids = [] for i in range(nb_sides): eid = m.add_dart(1) m.link(eid, pids[i]) m.link(eid, pids[(i + 1) % nb_sides]) eids.append(eid) #create face fid = m.add_dart(2) for eid in eids: m.link(fid, eid) #return return m
def __init__(self, heightfield): mesh = Mesh() size = 32 factor = 1.0 vertices = [] for z in xrange(size): z = float(z) / float(size - 1) for x in xrange(size): x = float(x) / float(size - 1) y = heightfield[x, z] vertices.append(mesh.vertex(x, y, z)) for y in xrange(size - 1): for x in xrange(size - 1): v0 = vertices[(x + 1) + (y + 1) * size] v1 = vertices[(x + 1) + (y + 0) * size] v2 = vertices[(x + 0) + (y + 0) * size] v3 = vertices[(x + 0) + (y + 1) * size] mesh.face(v0, v1, v2) mesh.face(v3, v0, v2) splits = Splits(mesh, heightfield) while len(mesh.verts) < 21840: #while len(mesh.verts) < 3000: print len(mesh.faces), len(mesh.verts) splits.perform() mesh.save('mesh.bin') self.vbo = mesh.serialize()
def test_funspace_2(): '''Test of FunctionSpace.int_phi_phi made up of linear elements, basic integration ''' ox, dx, nx = 0., 1., 1 mesh = Mesh(type='uniform', lx=dx, nx=nx, block='B1') V = FunctionSpace(mesh, {'B1': Element(type='link2')}) # basic properties assert V.num_dof == (nx + 1) assert V.size == nx X = np.linspace(ox, dx, nx+1) assert allclose(V.X, X) # Integrate[N(x) N(x) {x, 0, 1}] fun = lambda x: x f = lambda i, j: integrate(fun(x) * N[i] * N[j], (x, ox, dx)) ans = V.int_phi_phi(fun=fun, derivative=(False, False)) exact = Matrix(2, 2, lambda i, j: f(i,j)) assert areclose(exact, ans) # Trivial check with coefficient fun = lambda x: 1. a1 = V.int_phi_phi() a2 = V.int_phi_phi(fun=fun) assert areclose(a1, a2)
def remesh(self, edgelen=None): """Remesh a TriSurface. edgelen is the suggested edge length """ if edgelen is None: self.getElemEdges() E = Mesh(self.coords, self.edges, eltype='line2') edgelen = E.lengths().mean() tmp = utils.tempFile(suffix='.stl').name tmp1 = utils.tempFile(suffix='.stl').name pf.message("Writing temp file %s" % tmp) self.write(tmp, 'stl') pf.message("Remeshing using VMTK (edge length = %s)" % edgelen) cmd = "vmtk vmtksurfaceremeshing -ifile %s -ofile %s -edgelength %s" % ( tmp, tmp1, edgelen) sta, out = utils.runCommand(cmd) os.remove(tmp) if sta: pf.message("An error occurred during the remeshing.") pf.message(out) return None S = TriSurface.read(tmp1) os.remove(tmp1) return S
def crop(self, x_0, x_1, y_0, y_1, with_normals=False): """ This function generates another mesh (not depthMesh) by cropping the organized set of veftices (a depth ROI) """ w, h = self.depth.shape[1], self.depth.shape[0] if x_0 < 0 or y_0 < 0 or x_1 >= w or y_1 >= h or x_1 <=x_0 or y_1 <= y_0: return None mesh = Mesh() vcs_aux = self.vcs.reshape(self.depth.shape[0], self.depth.shape[1], 3) # Vertices mesh.vcs = vcs_aux[y_0:y_1, x_0:x_1, :].reshape(-1, 3) mesh.vcs_q = mesh.vcs.shape[0] # Normals if with_normals: vnorms_aux = self.vnorms.reshape(self.depth.shape[0], self.depth.shape[1], 3) mesh.vnorms = vnorms_aux[y_0:y_1, x_0:x_1, :].reshape(-1, 3) # Facets mesh.faces = DepthMesh.genFacets(x_1 - x_0, y_1 - y_0) mesh.faces_q = mesh.faces.shape[0] # texture mapping txcoord_aux = self.txcoord.reshape(self.depth.shape[0], self.depth.shape[1], 2) mesh.txcoord = txcoord_aux[y_0:y_1, x_0:x_1, :].reshape(-1, 2) mesh.texture = self.texture mesh.txwidth, mesh.txheight = self.txwidth, self.txheight return mesh
def generate_transform_matrices(mesh, factors): #TODO """Generates len(factors) meshes, each of them is scaled by factors[i] and computes the transformations between them. Returns: M: a set of meshes downsampled from mesh by a factor specified in factors. A: Adjacency matrix for each of the meshes D: Downsampling transforms between each of the meshes U: Upsampling transforms between each of the meshes """ factors = map(lambda x: 1.0 / x, factors) M, A, D, U = [], [], [], [] #A.append(get_vert_connectivity(mesh)) A.append(mesh) M.append(mesh) for factor in factors: ds_f, ds_D = qslim_decimator_transformer(M[-1], factor=factor) D.append(ds_D) new_mesh_v = ds_D.dot(M[-1].v) new_mesh = Mesh(v=new_mesh_v, f=ds_f) M.append(new_mesh) #A.append(get_vert_connectivity(new_mesh)) A.append(new_mesh) U.append(setup_deformation_transfer(M[-1], M[-2])) return M, A, D, U
def insert(self, path, name): self.inputimage = name if isinstance(path, basestring): self.image = Image.open(path) else: self.image = path self.background = ImageTk.PhotoImage(self.image) self.width = self.background.width() self.height = self.background.height() self.canvas.configure(width=self.width, height=self.height) self.canvas.create_image(0, 0, image=self.background, anchor=NW) self.color = Color(np.array(self.image), 0.5, 0.5) self.selectedFace = None # Mesh self.mesh = Mesh(self) # Selection self.selected = None # Mouse Event self.mouseEventHandled = False self.faceState = NORMAL
def __init__(self, window_name='Spherical Harmonics Viewer', window_size=(640, 640)): super(SphericalHarmonicsViewer, self).__init__(window_name, window_size) self.camera = Camera() self.origin = np.array([0, 0, 0]) self.mesh = Mesh(os.path.join("..", "models", "cube.obj")) self.mesh_samples = [] self.compute_mesh_samples(500) self.n_frequencies = 10 self.sh_coeffs = np.zeros(self.n_frequencies * self.n_frequencies) self.compute_sh_coeffs() self.print_coeffs() self.sh = SphericalHarmonicsMesh(coeffs=self.sh_coeffs) self.camera_speed = 1 / 100. self.initialize() self.action = "" self.prev_x = 0 self.prev_y = 0 glutMainLoop()
def main(): """ create window, add shaders & scene objects, then run rendering loop """ width = 640 height = 480 camera = Camera(vec(0, 0, -5), 60, height / width, .3, 1000) scene = Scene(camera, light=vec(-.57735026919, -.57735026919, .57735026919) * .5) pyramidMesh = Mesh(vertices=np.array( ((0, .5, 0), (.5, -.5, 0), (-.5, -.5, 0)), 'f'), normals=np.array( ((0, 0, -1), (0.70710678118, 0, -0.70710678118), (-0.70710678118, 0, -0.70710678118)), 'f'), perVertexColor=np.array( ((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)), 'f'), indexes=np.array((0, 1, 2), 'u4')) suzanne = Mesh.LoadMeshes("models/suzanne.obj")[0] scene.Add3DObject( Object3D(0, translate(-1.5, 0, 1) @ rotate(vec(0.0, 1.0, 0.0), -200), suzanne, Material("shaders/rainbow_shaded.frag"))) scene.Add3DObject( Object3D(1, translate(1.5, 0, 1) @ rotate(vec(0.0, 1.0, 0.0), 200), suzanne, Material("shaders/shaded.frag"))) renderer = Renderer(scene) renderer.Run()
def Gen1Dlayered(H, N=11): """ Generate 1D layred mesh ======================= INPUT: H : a list with the thickness of each layer N : the number of division within each layer. Can be a list with the number of divisions of each layer RETURNS: an instance of Mesh """ nlay = len(H) # number of layers if isinstance(N, int): N = N * ones(nlay) # same division for all layers V = [[0, -101, 0.]] # first vertex C = [] # cells for i in range(nlay): x0 = sum(H[:i]) # left x1 = x0 + H[i] # right L = linspace(x0, x1, N[i]) # divide layer for l in L[1:]: V.append([len(V), 0, l]) C.append([len(C), -(i+1), [len(V)-2,len(V)-1]]) V[-1][1] = -102 # tag last vertex return Mesh(V, C)
def addFeResult(DB, step, time, result): """Add an FeResult for a time step to the result DB This is currently 2D only """ print("Storing result for step %s, time %s" % (step, time)) DB.Increment(step, 0) DB.R['TIME'] = time if 'displ' in result: DB.datasize['U'] = result['displ'].shape[1] DB.R['U'] = result['displ'] if 'stres' in result: try: stress = result['stres'] # CALCULIX HAS NO 2D: keep only half of GP's ngp = stress.shape[1] / 2 stress = stress[:, :ngp, :] print("Reduced stresses: %s" % str(stress.shape)) mesh = Mesh(DB.nodes, DB.elems[0], eltype='quad4') gprule = [2, 2] stress = computeAveragedNodalStresses(mesh, stress, gprule) DB.datasize['S'] = result['stres'].shape[1] DB.R['S'] = stress except: print("Error importing stresses") return DB
def GenColumn(nc, w, h): """ Generate column =============== """ dy = h / float(nc) l, c, r, L, R = column_nodes(nc, True) nn = R[-2] + 1 V = [] for n in range(nn): V.append([n, 0, 0.0, 0.0]) y = 0.0 for i in range(len(L)): V[L[i]][3], V[R[i]][3], V[R[i]][2] = y, y, w y += dy/2.0 y = 0.0 for n in c: V[n][3], V[n][2] = y, w/2.0 y += dy C = [] for i in range(nc): con = [l[i],r[i],r[i+1],l[i+1],c[i],R[i*2+1],c[i+1],L[i*2+1]] btg = {1:-11, 3:-13} if i == 0: btg = {0:-10, 1:-11, 3:-13} if i == nc-1: btg = {1:-11, 2:-12, 3:-13} C.append([i, -1, con, btg, 0]) return Mesh(V, C)
def createMesh(self): """...import... """ #! must be replaced by importcode # create points and safe in list # point0 = vertex(0.0, 0.0, 0.0) # self.points.append(self.point0) # point1 = vertex(8.0, 0.0, 0.0) # self.points.append(self.point1) # point2 = vertex(0.0, 8.0, 0.0) # self.points.append(self.point2) # point3 = vertex(0.0, 0.0, 8.0) # self.points.append(self.point3) # for point in self.points: # point.printXYZ() # create triangles and safe in list # tri0 = Triangle(0, 1, 3) # self.tris.append(self.tri0) # tri1 = Triangle(1, 2, 3) # self.tris.append(self.tri1) # tri2 = Triangle(2, 0, 3) # self.tris.append(self.tri2) # tri3 = Triangle(2, 1, 0) # self.tris.append(self.tri3) # for tri in self.tris: # tri.printIV() self.mesh = Mesh(self.points, self.tris)
def compute_field_direction(filename, n=1, s=1., field_type=None): if filename.split(".")[1] != "off": raise Exception("must input a file of type .off") which_file = filename.split(".")[0] mesh = Mesh(*parse_off('../data/' + which_file + '.off')) # mesh = trimesh.Trimesh() # mesh.vertices, mesh.faces = parse_off('../data/'+which_file+'.off') u, X, scale, singularities = direction_field(mesh, s, n, field_type=field_type) if len(singularities) == 0: write_to_file(mesh, u, n, X, write_angle=True, filename='../data/' + which_file + ".txt") else: write_to_file(mesh, u, n, X, write_angle=True, singularities=None, filename='../data/' + which_file + ".txt")
def visualize(model, self_intersection_ids, default_model, vertices, faces): radius = 0.01 from psbody.mesh.meshviewer import MeshViewer # from mesh.mesh.meshviewer import MeshViewer mv = MeshViewer(window_width=800, window_height=800) mesh = Mesh(v=default_model.r, f=default_model.f) mesh.f = [] if self_intersection_ids == []: return mv.set_static_meshes([mesh, meanSphere], blocking=True) else: m = Mesh(v=model.v, f=model.f, vc='SeaGreen') m.vc[m.f[faces][self_intersection_ids].flatten()] = ones(1) mv.set_static_meshes([m], blocking=True) raw_input('Press Enter to exit')
def test_make_invalid_different_keys_values(self): different = { (1, 0): {(0, 1), (4, -1)}, (0, 1): {(-1, 0), (1, 0)}, (-1, 0): {(0, -1), (0, 1)}, (0, -1): {(-1, 0), (1, 0)}, } self.assertRaises(ValueError, lambda: Mesh(different))
def test_make_invalid_directed(self): digraph = { (1, 0): {(0, 1), (0, -1)}, (0, 1): {(-1, 0)}, (-1, 0): {(0, -1)}, (0, -1): {(1, 0)}, } self.assertRaises(ValueError, lambda: Mesh(digraph))
def stl_to_abaqus(fn): print("Converting %s to Abaqus .INP format" % fn) tetgen.runTetgen(fn) fb = os.path.splitext(fn)[0] nodes = tetgen.readNodes(fb + '.1.node') elems = tetgen.readElems(fb + '.1.ele') faces = tetgen.readSurface(fb + '.1.smesh') print("Exporting surface model") smesh = Mesh(nodes, faces, eltype='S3') fe_abq.exportMesh( fb + '-surface.inp', smesh, "Abaqus model generated by tetgen from surface in STL file %s" % fn) print("Exporting volume model") vmesh = Mesh(nodes, elems, eltype='C3D%d' % elems.shape[1]) abq_export( fb + '-volume.inp', vmesh, "Abaqus model generated by tetgen from surface in STL file %s" % fn)
def toMesh(self): """Convert the element type to a Mesh. Returns a Mesh with a single element of natural size. """ from mesh import Mesh x = self.vertices e = self.getElement() return Mesh(x, e, eltype=e.eltype)