Failed to build my self discrete data
I am using gmsh
to re-mesh my data. After learning gmsh/examples/aneurysm.py
, my current test code is:
import gmsh
import sys
import os
import math
import numpy as np
def GetPointFace():
idx, points, _ = gmsh.model.mesh.getNodes()
idx -= 1
idx = idx.tolist()
m = {}
for i, v in enumerate(idx):
m[v] = i
points = np.asarray(points).reshape(-1, 3)
elem_types, elem_tags, node_tags = gmsh.model.mesh.getElements()
idx = elem_types.tolist().index(2)
elem_type, elem_tag, node_tag = elem_types[idx], elem_tags[idx], node_tags[idx]
num_nodes_per_cell = gmsh.model.mesh.getElementProperties(elem_type)[3]
node_tags_reshaped = np.asarray(node_tag).reshape(-1, num_nodes_per_cell) - 1
node_tags_sorted = node_tags_reshaped[np.argsort(elem_tag)]
tris = []
for i, tri in enumerate(node_tags_sorted):
p0 = tri[0]
p1 = tri[1]
p2 = tri[2]
tris.append([m[p0], m[p1], m[p2]])
return points, tris
gmsh.initialize(sys.argv)
path = os.path.dirname(os.path.abspath(__file__))
gmsh.merge(os.path.join(path, 'aneurysm_data.stl'))
gmsh.model.mesh.classifySurfaces(math.pi, True, True)
gmsh.model.mesh.createGeometry()
gmsh.model.geo.synchronize()
gmsh.option.setNumber('Mesh.Algorithm', 1)
gmsh.option.setNumber('Mesh.MeshSizeMin', 1)
gmsh.option.setNumber('Mesh.MeshSizeMax', 1)
gmsh.option.setNumber('Mesh.MeshSizeFactor', 1)
gmsh.model.mesh.generate(2)
## display the result
points, faces = GetPointFace()
from vedo import *
mesh = Mesh([points, faces]).c('y').bc('c')
show(mesh)
The aneurysm_data.stl
is located in gmsh/examples/aneurysm_data.stl
, and the result is good.
However, my data is obtained by one calculation rather than a stl
data. Thus, I need to input the calculated points/faces to gmsh
. In the following code, I obtain the points/faces
from the stl
and then input to gmsh
. After learning the x2.py
, the code to input my data to gmsh
is:
## input points/faces to gmsh
nodes = list(range(1, len(points) + 1))
coords = []
for p in points:
coords.extend(p)
gmsh.model.addDiscreteEntity(2, 0, [])
gmsh.model.mesh.addNodes(2, 0, nodes, coords)
elementType = 2
elementTags = list(range(len(faces)))
nodeTags = []
for t in faces:
tt = [idx + 1 for idx in t]
nodeTags.extend(tt)
gmsh.model.mesh.addElementsByType(0, elementType, elementTags, nodeTags)
And the other re-mesh code is the same with the before one, but the result is:
There is a unexpected hole (red circle). But there is no unexpected hole if the data is read from stl
file.
The complete code to reproduce the result is:
import gmsh
import sys
import os
import math
import numpy as np
def GetPointFace():
idx, points, _ = gmsh.model.mesh.getNodes()
idx -= 1
idx = idx.tolist()
m = {}
for i, v in enumerate(idx):
m[v] = i
points = np.asarray(points).reshape(-1, 3)
elem_types, elem_tags, node_tags = gmsh.model.mesh.getElements()
idx = elem_types.tolist().index(2)
elem_type, elem_tag, node_tag = elem_types[idx], elem_tags[idx], node_tags[idx]
num_nodes_per_cell = gmsh.model.mesh.getElementProperties(elem_type)[3]
node_tags_reshaped = np.asarray(node_tag).reshape(-1, num_nodes_per_cell) - 1
node_tags_sorted = node_tags_reshaped[np.argsort(elem_tag)]
tris = []
for i, tri in enumerate(node_tags_sorted):
p0 = tri[0]
p1 = tri[1]
p2 = tri[2]
tris.append([m[p0], m[p1], m[p2]])
return points, tris
gmsh.initialize(sys.argv)
path = os.path.dirname(os.path.abspath(__file__))
gmsh.merge(os.path.join(path, 'aneurysm_data.stl'))
points, faces = GetPointFace() ## get the aneurysm data from stl, including points and the faces
gmsh.clear()
## input points/faces to gmsh
nodes = list(range(1, len(points) + 1))
coords = []
for p in points:
coords.extend(p)
gmsh.model.addDiscreteEntity(2, 0, [])
gmsh.model.mesh.addNodes(2, 0, nodes, coords)
elementType = 2
elementTags = list(range(len(faces)))
nodeTags = []
for t in faces:
tt = [idx + 1 for idx in t]
nodeTags.extend(tt)
gmsh.model.mesh.addElementsByType(0, elementType, elementTags, nodeTags)
gmsh.model.mesh.classifySurfaces(math.pi, True, True)
gmsh.model.mesh.createGeometry()
gmsh.model.geo.synchronize()
gmsh.option.setNumber('Mesh.Algorithm', 1)
gmsh.option.setNumber('Mesh.MeshSizeMin', 1)
gmsh.option.setNumber('Mesh.MeshSizeMax', 1)
gmsh.option.setNumber('Mesh.MeshSizeFactor', 1)
gmsh.model.mesh.generate(2)
## display the result
points, faces = GetPointFace()
from vedo import *
mesh = Mesh([points, faces]).c('y').bc('c')
show(mesh)
Is there anything wrong to input points/faces
into gmsh
? Ang suggestion is appreciated~~~