def generateCubeMesh(): mesh_info = MeshInfo() mesh_info.set_points([ (0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0), (0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1), ]) mesh_info.set_facets([ [0, 1, 2, 3], [4, 5, 6, 7], [0, 4, 5, 1], [1, 5, 6, 2], [2, 6, 7, 3], [3, 7, 4, 0], ]) mesh = build(mesh_info) cellList = [] vertexList = [] mupifMesh = Mesh.UnstructuredMesh() print("Mesh Points:") for i, p in enumerate(mesh.points): print(i, p) vertexList.extend([Vertex.Vertex(i, i, p)]) print("Point numbers in tetrahedra:") for i, t in enumerate(mesh.elements): print(i, t) cellList.extend([Cell.Tetrahedron_3d_lin(mupifMesh, i, i, t)]) mupifMesh.setup(vertexList, cellList) return(mupifMesh)
def create_beam(vol): # build using MeshPy from meshpy.tet import MeshInfo,build mesh_info = MeshInfo() mesh_info.set_points([ (0,0,0), (0,1,0), (0,1,1), (0,0,1), (5,0,0), (5,1,0), (5,1,1), (5,0,1), ]) mesh_info.set_facets([ [0,1,2,3], [4,5,6,7], [0,1,5,4], [1,2,6,5], [0,3,7,4], [3,2,6,7], ]) mesh = build(mesh_info,max_volume=vol) return fmsh.MeshPyTet(mesh)
def PlotTets(): # Get the mesh from meshpy.tet import MeshInfo, build mesh_info = MeshInfo() mesh_info.set_points([(-1, -1, -1), (1, -1, -1), (-1, 1, -1), (-1, -1, 1)]) mesh_info.set_facets([[0, 2, 1], [0, 1, 3], [0, 3, 2], [2, 1, 3]]) mesh = build(mesh_info, max_volume=0.0002) points = np.asarray(mesh.points) elements = np.asarray(mesh.elements) faces = np.asarray(mesh.faces) # mesh.save_faces('/home/roman/Desktop/test.dat') C = 2 nsize = int((C + 2) * (C + 3) * (C + 4) / 6.) Bases = np.zeros((points.shape[0], nsize)) for i in range(0, points.shape[0]): Bases[i, :] = Tet.hpBases(C, points[i, 0], points[i, 1], points[i, 2])[0] mydict = { 'points': points, 'elements': elements, 'faces': faces, 'Bases': Bases } io.savemat( '/home/roman/Desktop/orthopoly/bases_tet_p' + str(C + 1) + '.mat', mydict)
def test_tetgen(): from meshpy.tet import MeshInfo, build mesh_info = MeshInfo() mesh_info.set_points([ (0, 0, 0), (2, 0, 0), (2, 2, 0), (0, 2, 0), (0, 0, 12), (2, 0, 12), (2, 2, 12), (0, 2, 12), ]) mesh_info.set_facets([ [0, 1, 2, 3], [4, 5, 6, 7], [0, 4, 5, 1], [1, 5, 6, 2], [2, 6, 7, 3], [3, 7, 4, 0], ]) build(mesh_info)
def generate_Preview(): bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False) config = bpy.context.scene.CONFIG_MeshPy vertList = [] faceList = [] meshPoints = [] meshFacets = [] split_faceList = [] split_vertList = [] ob = bpy.context.active_object obname = ob.name #compute mesh compute_vertices(ob, meshPoints) compute_polygones(ob, meshFacets) if config.make_subdivision == False: arg = "Y" else: arg = "" mesh_info = MeshInfo() mesh_info.set_points(meshPoints) mesh_info.set_facets(meshFacets) print(meshPoints) print(meshFacets) #args = ("pq" + str(config.ratio_quality) + "a" + str(config.ratio_maxsize) + str(arg)) '''
def create_beam(vol): # build using MeshPy from meshpy.tet import MeshInfo, build mesh_info = MeshInfo() mesh_info.set_points([ (0, 0, 0), (0, 1, 0), (0, 1, 1), (0, 0, 1), (5, 0, 0), (5, 1, 0), (5, 1, 1), (5, 0, 1), ]) mesh_info.set_facets([ [0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [0, 3, 7, 4], [3, 2, 6, 7], ]) mesh = build(mesh_info, max_volume=vol) return fmsh.MeshPyTet(mesh)
def tets_from_vertices_faces(vertices, faces, volume=None): """ Generate tetrahedron points and elements with MeshPy (TetGen). Parameters ---------- vertices : list List of lists of vertex co-ordinates for the input surface mesh. faces : list List of lists of face indices for the input surface mesh. volume : float Volume constraint for each tetrahedron element. Returns ------- list Points of the tetrahedrons. list Indices of points for each tetrahedron element. """ try: info = MeshInfo() info.set_points(vertices) info.set_facets(faces) tets = build(info, max_volume=volume) points = [list(i) for i in list(tets.points)] elements = [list(i) for i in list(tets.elements)] return points, elements except: print('***** MeshPy failed *****')
def main(): mesh_info = MeshInfo() mesh_info.set_points([ (0,0,0), (2,0,0), (2,2,0), (0,2,0), (0,0,12), (2,0,12), (2,2,12), (0,2,12), ]) mesh_info.set_facets([ [0,1,2,3], [4,5,6,7], [0,4,5,1], [1,5,6,2], [2,6,7,3], [3,7,4,0], ]) mesh_info.save_nodes("bar") mesh_info.save_poly("bar") mesh = build(mesh_info) mesh.save_nodes("barout") mesh.save_elements("barout") mesh.save_faces("barout") mesh.write_vtk("test.vtk")
def main(): mesh_info = MeshInfo() mesh_info.set_points([ (0, 0, 0), (2, 0, 0), (2, 2, 0), (0, 2, 0), (0, 0, 12), (2, 0, 12), (2, 2, 12), (0, 2, 12), ]) mesh_info.set_facets([ [0, 1, 2, 3], [4, 5, 6, 7], [0, 4, 5, 1], [1, 5, 6, 2], [2, 6, 7, 3], [3, 7, 4, 0], ]) mesh_info.save_nodes("bar") mesh_info.save_poly("bar") mesh = build(mesh_info) mesh.save_nodes("barout") mesh.save_elements("barout") mesh.save_faces("barout") mesh.write_vtk("test.vtk")
def brep2lar(larBrep): V,FV = larBrep mesh_info = MeshInfo() mesh_info.set_points(V) mesh_info.set_facets(FV) mesh = build(mesh_info) W = [v for h,v in enumerate(mesh.points)] CW = [tet for k,tet in enumerate(mesh.elements)] FW = sorted(set(AA(tuple)(CAT(AA(faces)(CW))))) EW = sorted(set(AA(tuple)(CAT(AA(edges)(FW))))) return W,CW,FW,EW
def brep2lar(larBrep): V, FV = larBrep mesh_info = MeshInfo() mesh_info.set_points(V) mesh_info.set_facets(FV) mesh = build(mesh_info) W = [v for h, v in enumerate(mesh.points)] CW = [tet for k, tet in enumerate(mesh.elements)] FW = sorted(set(AA(tuple)(CAT(AA(faces)(CW))))) EW = sorted(set(AA(tuple)(CAT(AA(edges)(FW))))) return W, CW, FW, EW
def make_tetgen_mesh(vert_list, face_list): # Make the tetgen mesh mesh_info = MeshInfo() # Points mesh_info.set_points(vert_list) # Faces mesh_info.set_facets(face_list) # --- TEMP --- ''' # Make an object from the surface we are planning to tetrahedronalize mesh_new = bpy.data.meshes.new("pre_tet_mesh") mesh_new.from_pydata(vert_list,[],face_list) mesh_new.validate(verbose=False) # Important! and i dont know why mesh_new.update() obj_new = bpy.data.objects.new("pre_tet",mesh_new) context.scene.objects.link(obj_new) # return ''' # --- FIN TEMP --- # Tetrahedralize # Options: # neighout = Write out neighbors # facesout = Write out faces # edgesout = Write out edges # regionattrib = Write out element_attributes = unique id for every tet in a distinct volume # nobisect = Dont alter surface print("> Starting TetGen") opts = Options(switches='pq', neighout = True, facesout = True, edgesout = True, regionattrib = True, verbose = True, docheck = True) mesh_built = build(mesh_info, options=opts) print("> Finished TetGen successfully") return mesh_built
def unstructure_mesh(h): mesh_info = MeshInfo() # Set the vertices of the domain [0, 1]^3 mesh_info.set_points([ (0,0,0), (1,0,0), (1,1,0), (0,1,0), (0,0,1), (1,0,1), (1,1,1), (0,1,1), ]) # Set the facets of the domain [0, 1]^3 mesh_info.set_facets([ [0,1,2,3], [4,5,6,7], [0,4,5,1], [1,5,6,2], [2,6,7,3], [3,7,4,0], ]) # Generate the tet mesh mesh = build(mesh_info, max_volume=(h)**3) point = np.array(mesh.points, dtype=np.float) cell = np.array(mesh.elements, dtype=np.int) return TetrahedronMesh(point, cell)
''' Created on Jul 10, 2014 @author: BOIRUM ''' from meshpy.tet import MeshInfo, build mesh_info = MeshInfo() mesh_info.set_points([ (0,0,0), (2,0,0), (2,2,0), (0,2,0), (0,0,12), (2,0,12), (2,2,12), (0,2,12), ]) mesh_info.set_facets([ [0,1,2,3], [4,5,6,7], [0,4,5,1], [1,5,6,2], [2,6,7,3], [3,7,4,0], ]) mesh = build(mesh_info) print "Mesh Points:" for i, p in enumerate(mesh.points): print i, p print "Point numbers in tetrahedra:" for i, t in enumerate(mesh.elements): print i, t mesh.write_vtk("test.vtk")
def save_mesh(filepath, mesh, boundary_condition, use_graphics, fem_dimensions, mass_density, poisson_ratio, young_modulus, meshpy ): """Write mesh data out to ply file If graphics are checked to be exported, it will prep any UVs and normals it can and prepare a full list of faces FEM3D meshes have their mesh run through MeshPy which is a Python interface for TetGen """ file = open(filepath, "w", encoding="utf8", newline="\n") fwrite = file.write verts = [] faces = [] elements = [] uvcoords = {} normals = {} has_uv = bool(mesh.uv_textures) and mesh.uv_textures.active if has_uv and use_graphics: mesh.calc_tessface() uv_data = mesh.tessface_uv_textures.active.data for i, polygon in enumerate(mesh.polygons): uv = uv_data[i].uv1, uv_data[i].uv2, uv_data[i].uv3, uv_data[i].uv4 for j, vert in enumerate(polygon.vertices): uvcoord = uv[j][0], uv[j][1] normal = mesh.vertices[vert].normal[:] vertcoord = mesh.vertices[vert].co[:] if vertcoord not in uvcoords: uvcoords[vertcoord] = uvcoord if vertcoord not in normals: normals[vertcoord] = normal if fem_dimensions == '3': from meshpy.tet import MeshInfo, build, Options bpy.ops.object.mode_set(mode='OBJECT', toggle=False) bpy.context.scene.update() # get list of verts and faces direct from mesh mesh_verts = [] for vert in mesh.vertices: mesh_verts.append(vert.co[:]) mesh_faces = [] for face in mesh.polygons: mesh_faces.append(face.vertices[:]) args = meshpy mesh_info = MeshInfo() mesh_info.set_points(mesh_verts) mesh_info.set_facets(mesh_faces) tets = build(mesh_info, Options(args), verbose=True, attributes=False, volume_constraints=False, max_volume=None, diagnose=False, insert_points=None) # Ply prep by creating updated vert list and face list using tets.points and tets.elements for point in tets.points: verts.append((point[0], point[1], point[2])) for tet in tets.elements: elements.append((tet[0], tet[1], tet[2], tet[3])) for face in tets.faces: faces.append((face[2], face[1], face[0])) else: for vert in mesh.vertices: verts.append((vert.co[0], vert.co[1], vert.co[2])) for face in mesh.polygons: if len(face.vertices) == 3: faces.append((face.vertices[0], face.vertices[1], face.vertices[2])) else: faces.append((face.vertices[0], face.vertices[1], face.vertices[2])) faces.append((face.vertices[0], face.vertices[2], face.vertices[3])) fwrite("ply\n") fwrite("format ascii 1.0\n") fwrite("comment Created by OpenSurgSim FEM exporter for Blender\n") fwrite("comment MeshPy options '%s'\n" % meshpy) fwrite("element vertex %d\n" % len(verts)) fwrite("property double x\n" "property double y\n" "property double z\n") if use_graphics: if fem_dimensions != '1': if normals: fwrite("property double nx\n" "property double ny\n" "property double nz\n") if has_uv: fwrite("property double s\n" "property double t\n") fwrite("element face %d\n" % len(faces)) fwrite("property list uint uint vertex_indices\n") if fem_dimensions == '1': fwrite("element 1d_element %d\n" % len(mesh.vertices)-1) fwrite("property list uint uint vertex_indices\n") elif fem_dimensions == '2': fwrite("element 2d_element %d\n" % len(faces)) fwrite("property list uint uint vertex_indices\n") elif fem_dimensions == '3': fwrite("element 3d_element %d\n" % len(elements)) fwrite("property list uint uint vertex_indices\n") fwrite("element material 1\n") fwrite("property double mass_density\n") fwrite("property double poisson_ratio\n") fwrite("property double young_modulus\n") if boundary_condition is not None: fwrite("element boundary_condition %d\n" % len(boundary_condition)) fwrite("property uint vertex_index\n") fwrite("end_header\n") if fem_dimensions != '1': if use_graphics: for vert in verts: fwrite("%.6f %.6f %.6f" % vert[:]) if vert in normals: fwrite(" %.6f %.6f %.6f" % normals[vert][:]) if has_uv and vert in uvcoords: fwrite(" %.6f %.6f" % uvcoords[vert][:]) fwrite("\n") for face in faces: fwrite("3 %d %d %d\n" % face[:]) else: for vert in verts: fwrite("%.6f %.6f %.6f\n" % vert[:]) else: for vert in mesh.vertices: fwrite("%.6f %.6f %.6f\n" % vert.co[:]) if fem_dimensions is '1': for i in len(mesh.vertices)-1: fwrite("2 %d %d\n" % list(i, i+1)) elif fem_dimensions is '2': for face in faces: fwrite("3 %d %d %d\n" % face[:]) elif fem_dimensions is '3': for tet in elements: fwrite("4 %d %d %d %d\n" % tet[:]) fwrite("%s %s %s\n" % (mass_density, poisson_ratio, young_modulus)) if boundary_condition is not None: for index in boundary_condition: fwrite("%d\n" % index) file.close() print("writing %r done" % filepath) return {'FINISHED'}
def make_box_mesh(a=(0, 0, 0), b=(1, 1, 1), max_volume=None, periodicity=None, boundary_tagger=(lambda fvi, el, fn, all_v: []), return_meshpy_mesh=False): """Return a mesh for a brick from the origin to `dimensions`. *max_volume* specifies the maximum volume for each tetrahedron. *periodicity* is either None, or a triple of bools, indicating whether periodic BCs are to be applied along that axis. See :func:`make_conformal_mesh` for the meaning of *boundary_tagger*. A few stock boundary tags are provided for easy application of boundary conditions, namely plus_[xyz] and minus_[xyz] tag the appropriate faces of the brick. """ def count(iterable): result = 0 for i in iterable: result += 1 return result from meshpy.tet import MeshInfo, build from meshpy.geometry import make_box points, facets, _, facet_markers = make_box(a, b) mesh_info = MeshInfo() mesh_info.set_points(points) mesh_info.set_facets(facets, facet_markers) if periodicity is None: periodicity = (False, False, False) axes = ["x", "y", "z"] per_count = count(p for p in periodicity if p) marker_to_tag = {} mesh_periodicity = [] periodic_tags = set() if per_count: mesh_info.pbc_groups.resize(per_count) pbc_group_number = 0 for axis, axis_per in enumerate(periodicity): minus_marker = 1+2*axis plus_marker = 2+2*axis minus_tag = "minus_"+axes[axis] plus_tag = "plus_"+axes[axis] marker_to_tag[minus_marker] = minus_tag marker_to_tag[plus_marker] = plus_tag if axis_per: pbcg = mesh_info.pbc_groups[pbc_group_number] pbc_group_number += 1 pbcg.facet_marker_1 = minus_marker pbcg.facet_marker_2 = plus_marker translation = [0, 0, 0] translation[axis] = b[axis]-a[axis] pbcg.set_transform(translation=translation) mesh_periodicity.append((minus_tag, plus_tag)) periodic_tags.add(minus_tag) periodic_tags.add(plus_tag) else: mesh_periodicity.append(None) generated_mesh = build(mesh_info, max_volume=max_volume) fvi2fm = generated_mesh.face_vertex_indices_to_face_marker def wrapped_boundary_tagger(fvi, el, fn, all_v): face_tag = marker_to_tag[fvi2fm[frozenset(fvi)]] if face_tag in periodic_tags: return [face_tag] else: return [face_tag] + boundary_tagger(fvi, el, fn, all_v) from hedge.mesh import make_conformal_mesh_ext from hedge.mesh.element import Tetrahedron vertices = numpy.asarray(generated_mesh.points, dtype=float, order="C") result = make_conformal_mesh_ext( vertices, [Tetrahedron(i, el_idx, vertices) for i, el_idx in enumerate(generated_mesh.elements)], wrapped_boundary_tagger, periodicity=mesh_periodicity) if return_meshpy_mesh: return result, generated_mesh else: return result
def ProcessGlobalAction(ActionType, GlobalAction, NumberedPoints, Elements, Points): ExtendedData = {'ElementPropertyIndex' : {}} if ActionType == 'SpecialEntities': Filters = json.loads(GlobalAction['Filters']) if not 'SpecialEntities' in ExtendedData: ExtendedData['SpecialEntities'] = [] for Element in Elements: if Element and Element['filter'] in Filters: ExtendedData['SpecialEntities'].append(Element) return ExtendedData, False if ActionType == 'Nonlinear': Output = {} #for key in GlobalAction: # if 'ElementPropertyMaxIndex' in ExtendedData: # ExtendedData['ElementPropertyMaxIndex'] += 1 # else: # ExtendedData['ElementPropertyMaxIndex'] = 1 # propertyindex = ExtendedData['ElementPropertyMaxIndex'] # ExtendedData['ElementPropertyIndex'][key] = propertyindex # ExtendedData['NonlinearPropertyIndex'][key] = nonlinearindex # # # ExtendedData['ElementPropertyIndex'][key] = workingindex #In this same notation we can get the index when writing elements # Output[index] = "" return ExtendedData, Output #Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'ElementProperties': Output = {} for key in GlobalAction: if 'ElementPropertyMaxIndex' in ExtendedData: ExtendedData['ElementPropertyMaxIndex'] += 1 else: ExtendedData['ElementPropertyMaxIndex'] = 1 workingindex = ExtendedData['ElementPropertyMaxIndex'] ExtendedData['ElementPropertyIndex'][key] = workingindex #In this same notation we can get the index when writing elements Output[workingindex] = GlobalAction[key] return ExtendedData, Output #Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'Orphans': Output = [] for Number, Point in NumberedPoints['points'].iteritems(): ElementAmount = len(Point['elementnumbers']) if ElementAmount < 2: print "Orphan node {}!".format(Number) Output.append({'element_type': 'POINT', 'position': Point['point'], 'layer': 'Errors', 'nodenumber': Number}) return {'information':'addObjects'}, Output#Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'Meshing': EntityModelData = json.loads(GlobalAction['EntityModelData']) if 'EntityModelData' in GlobalAction else {} ExtendedModelData = json.loads(GlobalAction['ExtendedModelData']) if 'ExtendedModelData' in GlobalAction else {} Semantic = json.loads(GlobalAction['Semantic']) if 'Semantic' in GlobalAction else {} if 'exclude filters' in Semantic: if not 'ExcludeFilters' in ExtendedData: ExtendedData['ExcludeFilters'] = [] ExtendedData['ExcludeFilters'] = ExtendedData['ExcludeFilters'] + Semantic['exclude filters'] Boundaries = [] Output = [] Geometry = json.loads(GlobalAction['Geometry']) if 'Geometry' in GlobalAction else {} Parameters = json.loads(GlobalAction['Parameters']) if 'Parameters' in GlobalAction else {} AdditionalPointsFilters = Geometry['points'] if 'points' in Geometry else [] for Filter in Geometry['boundaries']: print "Using filter {} as finite element domain boundary.".format(Filter) for Element in Elements: if Element and Element['filter'] == Filter and Element['elementclass'] in ['FACE_3NODES', 'FACE_4NODES', 'POLYLINE', 'PLINE_5NODES']: Boundaries.append(Element) AdditionalPoints = [] for Filter in AdditionalPointsFilters: print "Using filter {} as additional points container.".format(Filter) for Element in Elements: if Element and Element['filter'] == Filter and Element['elementclass'] in ['FACE_3NODES', 'FACE_4NODES', 'POLYLINE', 'LINE_2NODES']: AdditionalPoints.extend( Element['points'] ) print "Assembling FE domain" mesh_info = MeshInfo() #additional_points = MeshInfo() #additional_points.set_points(list(set(AdditionalPoints))) MeshPoints = [] MeshFacets = [] MeshPointsIndex = {} PointIndex = 0 for BoundaryElement in Boundaries: ElementPoints = BoundaryElement['points'] MeshFacet = [] if Parameters['type'] == 'divide_4p_faces': for point in [ElementPoints[0],ElementPoints[1],ElementPoints[2]]: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 MeshFacet.append(MeshPointsIndex[point]) MeshFacets.append(MeshFacet) MeshFacet = [] if ElementPoints[2] != ElementPoints[3]: for point in [ElementPoints[0],ElementPoints[2],ElementPoints[3]]: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 MeshFacet.append(MeshPointsIndex[point]) MeshFacets.append(MeshFacet) else: for point in ElementPoints: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 if not MeshPointsIndex[point] in MeshFacet: MeshFacet.append(MeshPointsIndex[point]) else: print "Mesh error or 3-point 3DFACE." MeshFacets.append(MeshFacet) MeshFacet = [] for point in list(set(AdditionalPoints)): if not point in MeshPointsIndex: #See whether the point is already indexed by its native number MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 saveobject(MeshFacets, r'MeshFacets') saveobject(MeshPoints, r'MeshPoints') mesh_info.set_facets(MeshFacets) mesh_info.set_points(MeshPoints) #insertaddpoints #points = np.array([list(x) for x in MeshPoints]) #qhull = scipy.spatial.Delaunay(points) #mesh_info.Options(switches='pq') #mesh_info.set_points([ # (0,0,0), (12,0,0), (12,12,0), (0,12,0), # (0,0,12), (12,0,12), (12,12,12), (0,12,12), # ]) #mesh_info.set_facets([ # [0,1,2,3], # [4,5,6,7], # [0,4,5,1], # [1,5,6,2], # [2,6,7,3], # [3,7,4,0], # ]) #opts = Options(switches='pq') #opts.maxvolume = 0.0001 #opts.parse_switches() mesh_info.regions.resize(1) mesh_info.regions[0] = [ MeshPoints[0][0], MeshPoints[0][1], MeshPoints[0][2], # point in volume -> first box 0, # region tag (user-defined number) Parameters['maxvolume'], # max tet volume in region ] mesh = build(mesh_info, options=Options(switches="pqT", epsilon=Parameters['tolerance']), volume_constraints=True) print "Created mesh with {} points, {} faces and {} elements.".format(len(mesh.points), len(mesh.faces), len(mesh.elements)) #mesh = build(mesh_info, options=Options(switches="pTi", epsilon=Parameters['tolerance'], insertaddpoints=True), volume_constraints=True, insert_points=additional_points) #mesh.write_vtk("test.vtk") #mesh.points #mesh.elements #mesh.faces filename = "test" #mesh.save_elements(filename) #mesh.save_nodes(filename) #mesh.save_elements(filename) #mesh.save_faces(filename) #mesh.save_edges(filename) #mesh.save_neighbors(filename) #mesh.save_poly(filename) #for element in qhull.simplices: # Position = [list(qhull.points[x]) for x in element] # Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Elements'}) #NumberedPoints['points'][compoundObject['points'][0]]['point'] if not Boundaries: return False, False Precision = int(GlobalAction['Precision']) if 'Precision' in GlobalAction else 4 if Semantic['output'].lower() == 'graphics': for face in mesh.faces: Position = [mesh.points[x] for x in face] Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Faces'}) for element in mesh.elements: Position = [mesh.points[x] for x in element] Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Elements'}) return {'information':'addObjects'}, Output elif Semantic['output'].lower() == 'fea': Points = {} for NumberedPoint in NumberedPoints['points']: Points[NumberedPoints['points'][NumberedPoint]['point']] = NumberedPoint NodeNumber = NumberedPoints['maximumNode'] for element in mesh.elements: Position = [mesh.points[x] for x in element] for i, point in enumerate(Position): Position[i] = [round(x, Precision) for x in point] #else: # if tuple([round(x, PrepPrecision) for x in Coords]) in [(4.95,-17.69,58.9), (4.96,-17.69,58.9)]: # pass # object['points'][i] = tuple([round(x, PrepPrecision) for x in Coords]) # if not object['points'][i] in GlobalPointIndex: # GlobalPointIndex.append(object['points'][i]) ElementPoints = [] ElementNumber = len(Elements) for point in Position: #Update NumberedPoints and construct all necessary data for Elements point = NeighborhoodRaw(tuple(point), Precision, Points) if not tuple(point) in Points: NodeNumber += 1 Points[tuple(point)] = NodeNumber #PointsNumbered.append(None) NumberedPoints['points'][NodeNumber] = {'point': tuple(point), 'elementnumbers': []} NumberedPoints['maximumNode'] = NodeNumber CurrentPointNumber = Points[tuple(point)] ElementPoints.append(CurrentPointNumber) NumberedPoints['points'][CurrentPointNumber]['elementnumbers'].append(ElementNumber) #Update Points if possible #Update Elements Element = { 'points' : ElementPoints, 'elementclass' : 'SOLID_4NODES', 'elementnum': ElementNumber, #??? 'filter': Semantic['filter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = Element return ExtendedData, False if ActionType == 'AddShells': ExtendedData = {} EntityModelData = json.loads(GlobalAction['EntityModelData']) if 'EntityModelData' in GlobalAction else {} ExtendedModelData = json.loads(GlobalAction['ExtendedModelData']) if 'ExtendedModelData' in GlobalAction else {} Filters = json.loads(GlobalAction['Filters']) if 'Filters' in GlobalAction else {} for Element in Elements: if not Element or not Element['filter'] in Filters: continue if Element['generation_order'] == 0 and Element['entity_model_data']['layer'] != "Concrete bases crown": ElementPoints = [Element['points'][0], Element['points'][1], Element['points'][2]] ElementNumber = len(Elements) NewElement = { 'points' : ElementPoints, 'elementclass' : 'FACE_3NODES', 'elementnum': ElementNumber, #??? 'filter': GlobalAction['AssignedFilter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = NewElement if Element['elementclass'] == 'SOLID_8NODES': ElementPoints = [Element['points'][0], Element['points'][2], Element['points'][3]] ElementNumber = len(Elements) NewElement = { 'points' : ElementPoints, 'elementclass' : 'FACE_3NODES', 'elementnum': ElementNumber, #??? 'filter': GlobalAction['AssignedFilter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = NewElement if Element['elementclass'] == 'SOLID_10NODES': pass pass return {}, {} return False
box_without_minus_z = [ [4, 5, 6, 7], [0, 4, 5, 1], [1, 5, 6, 2], [2, 6, 7, 3], [3, 7, 4, 0], ] def add_to_all_vertex_indices(facets, increment): return [[pt + increment for pt in facet] for facet in facets] mesh_info.set_facets( [[0, 1, 2, 3]] # base + box_without_minus_z # first box + add_to_all_vertex_indices(box_without_minus_z, 4) # second box ) # set the volume properties -- this is where the tet size constraints are mesh_info.regions.resize(2) mesh_info.regions[0] = [ 0, 0, 2, # point in volume -> first box 0, # region tag (user-defined number) 1e-1, # max tet volume in region ] mesh_info.regions[1] = [ 0, 0,
def generate_TetMesh(): bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False) bpy.context.scene.update() print("Scene Updated!") config = bpy.context.scene.CONFIG_MeshPy tetIndex = 0 vertList = [] faceList = [] meshPoints = [] meshFacets = [] split_faceList = [] split_vertList = [] ob = bpy.context.active_object obname = ob.name #convert all faces to triangles for testing ### that did not help with the crash problem:( ''' for vert in ob.data.vertices: vert.select = True bpy.ops.object.mode_set(mode = 'EDIT', toggle = False) bpy.ops.mesh.quads_convert_to_tris() bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False) ''' #compute mesh compute_vertices(ob, meshPoints) compute_faces(ob, meshFacets) if config.make_subdivision == False: arg = "Y" else: arg = "" mesh_info = MeshInfo() mesh_info.set_points(meshPoints) mesh_info.set_facets(meshFacets) debugArg = "" args = (debugArg + "pq" + str(config.ratio_quality) + "a" + str(config.ratio_maxsize) + str(arg)) #args = ("o2" + str(arg)) tetmesh = build(mesh_info, Options(args), verbose = True, attributes = False, volume_constraints = False, max_volume = None, diagnose = False, insert_points = None) compute_mesh(tetmesh, vertList, faceList) ##all this should only be executed when preview is disabled if config.make_split == True: ##add counter to iterate to iterate the loop through all tetras #print(len(tetmesh.elements)) while tetIndex < len(tetmesh.elements): compute_mesh_split(tetmesh, split_faceList, split_vertList, vertList) #print("split_faceList ", tetIndex, ": ", split_faceList[tetIndex]) #print("split_vertList ", tetIndex, ": ", split_vertList[tetIndex]) #put this in a separate loop maybe bring some speed up #create mesh tetname = obname + "Tet" tet = create_mesh(tetname, split_vertList[tetIndex], split_faceList[tetIndex]) #run configs enable_game(config, tet) enable_physics(config, tet, tetname) #bpy.ops.group.create(name='test') world_correction(config, ob, tet) tetIndex = tetIndex + 1 else: #create mesh tetname = obname + "Tet" tetMesh = create_mesh(tetname, vertList, faceList) #run configs enable_game(config, tetMesh) enable_physics(config, tetMesh, tetname) world_correction(config, ob, tetMesh)
# Show the plot to the screen #pyplot.show() points = [] for _tri in stl_mesh.vectors: points = points + [tuple(x) for x in [_tri[0],_tri[1],_tri[2]]] uniques = np.unique(points, axis=0) #This needs significant speedup panels = [] for _tri in stl_mesh.vectors: _tripnt = [] for _index in range(len(uniques)): if list(uniques[_index]) in list(list(x) for x in _tri): _tripnt.append(_index) panels.append(tuple(_tripnt)) mesh_info = MeshInfo() mesh_info.set_points(points) mesh_info.set_facets(panels) ### Plotting points = np.array(mesh_info.points) from plotting import scatter3d scatter3d(points) ## mesh = build(mesh_info, options=Options("")) #mesh = build(mesh_info, options=Options("pq")) mesh.write_vtk("test.vtk")
def ProcessGlobalAction(ActionType, GlobalAction, NumberedPoints, Elements, Points): ExtendedData = {'ElementPropertyIndex' : {}} if ActionType == 'SpecialEntities': Filters = json.loads(GlobalAction['Filters']) if not 'SpecialEntities' in ExtendedData: ExtendedData['SpecialEntities'] = [] for Element in Elements: if Element and Element['filter'] in Filters: ExtendedData['SpecialEntities'].append(Element) return ExtendedData, False if ActionType == 'Nonlinear': Output = {} #for key in GlobalAction: # if 'ElementPropertyMaxIndex' in ExtendedData: # ExtendedData['ElementPropertyMaxIndex'] += 1 # else: # ExtendedData['ElementPropertyMaxIndex'] = 1 # propertyindex = ExtendedData['ElementPropertyMaxIndex'] # ExtendedData['ElementPropertyIndex'][key] = propertyindex # ExtendedData['NonlinearPropertyIndex'][key] = nonlinearindex # # # ExtendedData['ElementPropertyIndex'][key] = workingindex #In this same notation we can get the index when writing elements # Output[index] = "" return ExtendedData, Output #Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'ElementProperties': Output = {} for key in GlobalAction: if 'ElementPropertyMaxIndex' in ExtendedData: ExtendedData['ElementPropertyMaxIndex'] += 1 else: ExtendedData['ElementPropertyMaxIndex'] = 1 workingindex = ExtendedData['ElementPropertyMaxIndex'] ExtendedData['ElementPropertyIndex'][key] = workingindex #In this same notation we can get the index when writing elements Output[workingindex] = GlobalAction[key] return ExtendedData, Output #Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'Orphans': Output = [] for Number, Point in NumberedPoints['points'].iteritems(): ElementAmount = len(Point['elementnumbers']) if ElementAmount < 2: print "Orphan node {}!".format(Number) Output.append({'element_type': 'POINT', 'position': Point['point'], 'layer': 'Errors', 'nodenumber': Number}) return {'information':'addObjects'}, Output#Here we have Output ready to be printed and ExtendedData, a mapper to Output if ActionType == 'Meshing': EntityModelData = json.loads(GlobalAction['EntityModelData']) if 'EntityModelData' in GlobalAction else {} ExtendedModelData = json.loads(GlobalAction['ExtendedModelData']) if 'ExtendedModelData' in GlobalAction else {} Semantic = json.loads(GlobalAction['Semantic']) if 'Semantic' in GlobalAction else {} if 'exclude filters' in Semantic: if not 'ExcludeFilters' in ExtendedData: ExtendedData['ExcludeFilters'] = [] ExtendedData['ExcludeFilters'] = ExtendedData['ExcludeFilters'] + Semantic['exclude filters'] Boundaries = [] Output = [] Geometry = json.loads(GlobalAction['Geometry']) if 'Geometry' in GlobalAction else {} Parameters = json.loads(GlobalAction['Parameters']) if 'Parameters' in GlobalAction else {} AdditionalPointsFilters = Geometry['points'] if 'points' in Geometry else [] for Filter in Geometry['boundaries']: print "Using filter {} as finite element domain boundary.".format(Filter) for Element in Elements: if Element and Element['filter'] == Filter and Element['elementclass'] in ['FACE_3NODES', 'FACE_4NODES', 'POLYLINE', 'PLINE_5NODES']: Boundaries.append(Element) AdditionalPoints = [] for Filter in AdditionalPointsFilters: print "Using filter {} as additional points container.".format(Filter) for Element in Elements: if Element and Element['filter'] == Filter and Element['elementclass'] in ['FACE_3NODES', 'FACE_4NODES', 'POLYLINE', 'LINE_2NODES']: AdditionalPoints.extend( Element['points'] ) print "Assembling FE domain" mesh_info = MeshInfo() #additional_points = MeshInfo() #additional_points.set_points(list(set(AdditionalPoints))) MeshPoints = [] MeshFacets = [] MeshPointsIndex = {} PointIndex = 0 for BoundaryElement in Boundaries: ElementPoints = BoundaryElement['points'] MeshFacet = [] if Parameters['type'] == 'divide_4p_faces': for point in [ElementPoints[0],ElementPoints[1],ElementPoints[2]]: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 MeshFacet.append(MeshPointsIndex[point]) MeshFacets.append(MeshFacet) MeshFacet = [] if ElementPoints[2] != ElementPoints[3]: for point in [ElementPoints[0],ElementPoints[2],ElementPoints[3]]: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 MeshFacet.append(MeshPointsIndex[point]) MeshFacets.append(MeshFacet) else: for point in ElementPoints: if not point in MeshPointsIndex: MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 if not MeshPointsIndex[point] in MeshFacet: MeshFacet.append(MeshPointsIndex[point]) else: print "Mesh error or 3-point 3DFACE." MeshFacets.append(MeshFacet) MeshFacet = [] for point in list(set(AdditionalPoints)): if not point in MeshPointsIndex: #See whether the point is already indexed by its native number MeshPointsIndex[point] = PointIndex MeshPoints.append(False) MeshPoints[PointIndex] = NumberedPoints['points'][point]['point'] PointIndex += 1 saveobject(MeshFacets, r'MeshFacets') saveobject(MeshPoints, r'MeshPoints') mesh_info.set_facets(MeshFacets) mesh_info.set_points(MeshPoints) #insertaddpoints #points = np.array([list(x) for x in MeshPoints]) #qhull = scipy.spatial.Delaunay(points) #mesh_info.Options(switches='pq') #mesh_info.set_points([ # (0,0,0), (12,0,0), (12,12,0), (0,12,0), # (0,0,12), (12,0,12), (12,12,12), (0,12,12), # ]) #mesh_info.set_facets([ # [0,1,2,3], # [4,5,6,7], # [0,4,5,1], # [1,5,6,2], # [2,6,7,3], # [3,7,4,0], # ]) #opts = Options(switches='pq') #opts.maxvolume = 0.0001 #opts.parse_switches() mesh_info.regions.resize(1) mesh_info.regions[0] = [ MeshPoints[0][0], MeshPoints[0][1], MeshPoints[0][2], # point in volume -> first box 0, # region tag (user-defined number) Parameters['maxvolume'], # max tet volume in region ] mesh = build(mesh_info, options=Options(switches="pqT", epsilon=Parameters['tolerance']), volume_constraints=True) print "Created mesh with {} points, {} faces and {} elements.".format(len(mesh.points), len(mesh.faces), len(mesh.elements)) #mesh = build(mesh_info, options=Options(switches="pTi", epsilon=Parameters['tolerance'], insertaddpoints=True), volume_constraints=True, insert_points=additional_points) #mesh.write_vtk("test.vtk") #mesh.points #mesh.elements #mesh.faces filename = "test" #mesh.save_elements(filename) #mesh.save_nodes(filename) #mesh.save_elements(filename) #mesh.save_faces(filename) #mesh.save_edges(filename) #mesh.save_neighbors(filename) #mesh.save_poly(filename) #for element in qhull.simplices: # Position = [list(qhull.points[x]) for x in element] # Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Elements'}) #NumberedPoints['points'][compoundObject['points'][0]]['point'] if not Boundaries: return False, False Precision = int(GlobalAction['Precision']) if 'Precision' in GlobalAction else 4 if not 'output' in Semantic or Semantic['output'].lower() == 'graphics': for face in mesh.faces: Position = [mesh.points[x] for x in face] Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Faces'}) for element in mesh.elements: Position = [mesh.points[x] for x in element] Output.append({'element_type': '3DFACE', 'position': Position, 'layer': 'Elements'}) return {'information':'addObjects'}, Output elif Semantic['output'].lower() == 'fea': Points = {} for NumberedPoint in NumberedPoints['points']: Points[NumberedPoints['points'][NumberedPoint]['point']] = NumberedPoint NodeNumber = NumberedPoints['maximumNode'] for element in mesh.elements: Position = [mesh.points[x] for x in element] for i, point in enumerate(Position): Position[i] = [round(x, Precision) for x in point] #else: # if tuple([round(x, PrepPrecision) for x in Coords]) in [(4.95,-17.69,58.9), (4.96,-17.69,58.9)]: # pass # object['points'][i] = tuple([round(x, PrepPrecision) for x in Coords]) # if not object['points'][i] in GlobalPointIndex: # GlobalPointIndex.append(object['points'][i]) ElementPoints = [] ElementNumber = len(Elements) for point in Position: #Update NumberedPoints and construct all necessary data for Elements point = NeighborhoodRaw(tuple(point), Precision, Points) if not tuple(point) in Points: NodeNumber += 1 Points[tuple(point)] = NodeNumber #PointsNumbered.append(None) NumberedPoints['points'][NodeNumber] = {'point': tuple(point), 'elementnumbers': []} NumberedPoints['maximumNode'] = NodeNumber CurrentPointNumber = Points[tuple(point)] ElementPoints.append(CurrentPointNumber) NumberedPoints['points'][CurrentPointNumber]['elementnumbers'].append(ElementNumber) #Update Points if possible #Update Elements Element = { 'points' : ElementPoints, 'elementclass' : 'SOLID_4NODES', 'elementnum': ElementNumber, #??? 'filter': Semantic['filter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = Element return ExtendedData, False if ActionType == 'AddShells': ExtendedData = {} EntityModelData = json.loads(GlobalAction['EntityModelData']) if 'EntityModelData' in GlobalAction else {} ExtendedModelData = json.loads(GlobalAction['ExtendedModelData']) if 'ExtendedModelData' in GlobalAction else {} Filters = json.loads(GlobalAction['Filters']) if 'Filters' in GlobalAction else {} for Element in Elements: if not Element or not Element['filter'] in Filters: continue if Element['generation_order'] == 0 and Element['entity_model_data']['layer'] != "Concrete bases crown": ElementPoints = [Element['points'][0], Element['points'][1], Element['points'][2]] ElementNumber = len(Elements) NewElement = { 'points' : ElementPoints, 'elementclass' : 'FACE_3NODES', 'elementnum': ElementNumber, #??? 'filter': GlobalAction['AssignedFilter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = NewElement if Element['elementclass'] == 'SOLID_8NODES': ElementPoints = [Element['points'][0], Element['points'][2], Element['points'][3]] ElementNumber = len(Elements) NewElement = { 'points' : ElementPoints, 'elementclass' : 'FACE_3NODES', 'elementnum': ElementNumber, #??? 'filter': GlobalAction['AssignedFilter'], 'entity_model_data': EntityModelData, 'extended_model_data': ExtendedModelData, 'generation_order': None, } Elements.append(None) Elements[ElementNumber] = NewElement if Element['elementclass'] == 'SOLID_10NODES': pass pass return {}, {} return False
# mesh_info.set_facets([ # [0,1,2], # [0,1,3], # [1,2,3], # [3,2,0] # ]) #Cubic entire cubic voronoi cell.... a = 0.5; b = -0.5 mesh_info.set_points([ (b,b,b), (b,b,a), (b,a,a),(b,a,b),(a,b,b), (a,b,a), (a,a,a),(a,a,b) ]) mesh_info.set_facets([ [0,1,2,3], [0,1,5,4], [0,4,7,3], [6,2,1,5], [6,2,3,7], [6,7,4,5]]) addpoints = [(0.0,0.0,0.0), (0.375,0.375,0.375)] # addpoints = [array([0.0,0.0,0.0]), array(0.375,0.375,0.375)] opts = Options("VO9pa0.04") # Overriding 'pq' mesh = build(mesh_info,options=opts, insert_points = addpoints) # mesh = build(mesh_info,max_volume = 0.1) vols = [] tets = [] points = [] print "Mesh Points:"
from meshpy.tet import MeshInfo, build mesh_info = MeshInfo() mesh_info.set_points([ (0,0,0), (2,0,0), (2,2,0), (0,2,0), (0,0,12), (2,0,12), (2,2,12), (0,2,12), ]) mesh_info.set_facets([ [0,1,2,3], [4,5,6,7], [0,4,5,1], [1,5,6,2], [2,6,7,3], [3,7,4,0], ]) mesh = build(mesh_info) print "Mesh Points:" for i, p in enumerate(mesh.points): print i, p print "Point numbers in tetrahedra:" for i, t in enumerate(mesh.elements): print i, t mesh.write_vtk("test.vtk")
def coarse_gen(cd,bdim,bmin,file_name): # INPUT: voxel cube side length (fl), box dimensions (fl), box minimum values (fl), name of file to create for mesh output (str) # This function generates a coarse mesh given info from NEURON sections. # Returns this mesh as a STEPS tuple, of which entry 0 is a steps.geom.Tetmesh object, # also saves STEPS format files for the Tetmesh to current directory under given file name (xml & ASCII file formats). ## CALCULATE BOX INFO ## box_w = bdim[0] box_l = bdim[1] box_h = bdim[2] min_x = bmin[0] min_y = bmin[1] min_z = bmin[2] cl = cd if not (box_w % cl == box_l % cl == box_h % cl == 0): print 'ERRROR: voxel cube side length not a common factor of all box dimensions' sys.exit() wpoints = 1+(box_w)/cl lpoints = 1+(box_l)/cl hpoints = 1+(box_h)/cl print "cube side length: ", cl print "box w,l,h: ", box_w,box_l,box_h print "w,l,h # points: ", wpoints,lpoints,hpoints cpoints = [] hfacets = [] vfacets = [] ## GENERATE POINTS AND FACETS ## for hp in range(int(hpoints)): for lp in range(int(lpoints)): for wp in range(int(wpoints)): cpoints.append((min_x+wp*cl,min_y+lp*cl,min_z+hp*cl)) pindex = (hp*lpoints*wpoints)+(lp*wpoints)+wp # horizontal facets if (wp < int(wpoints)-1 and lp < int(lpoints)-1): hfacets.append([int(pindex), int(pindex+1), int(pindex+1+wpoints), int(pindex+wpoints)]) # vertical facets if (hp > 0): if (wp > 0): vfacets.append([int(pindex),int(pindex-1),int(pindex-1-lpoints*wpoints),int(pindex-lpoints*wpoints)]) if (lp > 0): vfacets.append([int(pindex),int(pindex-wpoints),int(pindex-wpoints-lpoints*wpoints),int(pindex-lpoints*wpoints)]) all_facets = hfacets+vfacets ## PASS MESH TO STEPS ## mesh_info = MeshInfo() mesh_info.set_points(cpoints) mesh_info.set_facets(all_facets) m = build(mesh_info) # write mesh proxies nodeproxy = smeshio.ElementProxy('node',3) for i, p in enumerate(m.points): nodeproxy.insert(i,p) tetproxy = smeshio.ElementProxy('tet',4) newtet = [0,0,0,0] for i, t in enumerate(m.elements): newtet[0] = nodeproxy.getSTEPSID(int(t[0])) newtet[1] = nodeproxy.getSTEPSID(int(t[1])) newtet[2] = nodeproxy.getSTEPSID(int(t[2])) newtet[3] = nodeproxy.getSTEPSID(int(t[3])) tetproxy.insert(i, newtet) # build mesh from proxies and save in STEPS format (xml & ASCII) nodedata = nodeproxy.getAllData() tetdata = tetproxy.getAllData() newmesh = steps.geom.Tetmesh(nodedata, tetdata) smeshio.saveMesh(file_name,newmesh) # Load mesh into STEPS steps_mesh = smeshio.loadMesh(file_name) print "STEPS loaded Tetmesh successfully." print "# Vertices: ", steps_mesh[0].countVertices() print "# Tets: ", steps_mesh[0].countTets() print "# Faces/Tris: ", steps_mesh[0].countTris() return steps_mesh
# vertex indices for a box missing the -z face box_without_minus_z = [ [4,5,6,7], [0,4,5,1], [1,5,6,2], [2,6,7,3], [3,7,4,0], ] def add_to_all_vertex_indices(facets, increment): return [[pt+increment for pt in facet] for facet in facets] mesh_info.set_facets( [[0,1,2,3]] # base +box_without_minus_z # first box +add_to_all_vertex_indices(box_without_minus_z, 4) # second box ) # set the volume properties -- this is where the tet size constraints are mesh_info.regions.resize(2) mesh_info.regions[0] = [0,0,2, # point in volume -> first box 0, # region tag (user-defined number) 1e-1, # max tet volume in region ] mesh_info.regions[1] = [0,0,7, # point in volume -> second box 0, # region tag (user-defined number, arbitrary) 1e-2, # max tet volume in region ] mesh = build(mesh_info, volume_constraints=True)
def make_tetgen_mesh(): global mn_section_dict global face_marker_plane_dict # Make single volume vert_stack = [] face_stack = [] face_marker_stack = [] face_marker_brdr = 1 # are positive face_marker_surf = -1 # are negative # Make sure we don't double count any planes # Sides ids to face marker plane_sides_ids_done = {} # Go through all the sections for sec_id in mn_section_dict.keys(): sec = mn_section_dict[sec_id] # Check that there are any borders if len(sec.planes_sc_brdrs[0]) == 0 and len(sec.planes_sc_brdrs[1]) == 0 and sec.plane_surf == -1: print("Error! No bounding planes for this section!") # Add the surface plane... if not sec.plane_surf.sides_ids in plane_sides_ids_done: vert_stack += [sec.plane_surf.vert_list] face_stack += [sec.plane_surf.face_list] face_marker_stack += [len(sec.plane_surf.face_list)*[face_marker_surf]] face_marker_plane_dict[face_marker_surf] = sec.plane_surf sec.face_marker_dict[face_marker_surf] = -1 plane_sides_ids_done[sec.plane_surf.sides_ids] = face_marker_surf face_marker_surf -= 1 else: # Do this for EVERY section sec.face_marker_dict[plane_sides_ids_done[sec.plane_surf.sides_ids]] = -1 # And the borders... for i,brdr in enumerate(sec.planes_sc_brdrs): for j,plane in enumerate(brdr): if not plane.sides_ids in plane_sides_ids_done: vert_stack += [plane.vert_list] face_stack += [plane.face_list] # Face marker face_marker_stack += [len(plane.face_list)*[face_marker_brdr]] face_marker_plane_dict[face_marker_brdr] = plane sec.face_marker_dict[face_marker_brdr] = (i,j) ''' if mn_sec.sc_id == (1,3): global shared_3_27 PLANE_SHARED = True for v in shared_3_27: if not v in plane.vert_list: PLANE_SHARED = False break if PLANE_SHARED: print("THIS IS THE SHARED PLANE: marker: " + str(face_marker_brdr)) if triplet[0] in shared_3_27 and triplet[1] in shared_3_27 and triplet[2] in shared_3_27: print("Trip: " + str(triplet) + " is shared; has face marker: " + str(face_marker)) ''' plane_sides_ids_done[plane.sides_ids] = face_marker_brdr face_marker_brdr += 1 else: # Do this for EVERY section sec.face_marker_dict[plane_sides_ids_done[plane.sides_ids]] = (i,j) # Create a correctly indexed closed volume vert_list, face_list, face_marker_list = stack_lists(vert_stack,face_stack,face_marker_stack=face_marker_stack) # Make the tetgen mesh mesh_info = MeshInfo() # Points mesh_info.set_points(vert_list) # Faces mesh_info.set_facets(face_list, markers = face_marker_list) # --- TEMP --- ''' # Make an object from the surface we are planning to tetrahedronalize mesh_new = bpy.data.meshes.new("pre_tet_mesh") mesh_new.from_pydata(vert_list,[],face_list) mesh_new.validate(verbose=False) # Important! and i dont know why mesh_new.update() obj_new = bpy.data.objects.new("pre_tet",mesh_new) context.scene.objects.link(obj_new) # return ''' # --- FIN TEMP --- # Tetrahedralize # Options: # neighout = Write out neighbors # facesout = Write out faces # edgesout = Write out edges # regionattrib = Write out element_attributes = unique id for every tet in a distinct volume # nobisect = Dont alter surface print("> Starting TetGen") opts = Options(switches='pq', neighout = True, facesout = True, edgesout = True, regionattrib = True, verbose = True, docheck = True) mesh_built = build(mesh_info, options=opts) print("> Finished TetGen successfully") return mesh_built
[3,7,4,0], ] def add_to_all_vertex_indices(facets, increment): return [[pt+increment for pt in facet] for facet in facets] facets = [[0,1,2,3]] + box_without_minus_z # first box facets += add_to_all_vertex_indices(box_without_minus_z, 4)# second box facets += add_to_all_vertex_indices(box_without_minus_z, 8)# third box facet_mrks = [] for f in facets: facet_mrks.append(-(int(f == max(facets)))) # Finding the surface boundary facet and labeling negative mesh_info.set_facets(facets, facet_mrks # Surface boundary conditions ) # figuring out what each of the volume constraints should be # the edge length here is divided by four to make sure there are at least 3 nodes per layer vc = lambda x: (x/4)**3/6 # set the volume properties -- this is where the tet size constraints are mesh_info.regions.resize(3) mesh_info.regions[0] = [0,0,1-delta_con/2,# point in volume -> first box 10, # region tag (user-defined number) vc(delta_con), # max tet volume in region ] mesh_info.regions[1] = [0,0,((1-delta_con)-delta_base/2), # point in volume -> second box