Since I am familar with the blockMesh utility and GIS, I decided to try another approach. Using ArcGIS I converted the point cloud first to a TIN and then a DEM. A DEM is essentially a regular matrix of elevations and which makes it very easy to work with as opposed to a randomly spaced point cloud. I then exported the DEM to an ASCII DEM. Finally I wrote a PYTHON script to read the ASCII DEM and write out the blockMeshDict file. The script can be found below. Currently the script requires to user to specify the number of rows and columns as well as the cell size however these could also be read from the ASCII DEM header. The script is nice in that it is easy to make modifications to extract subsets. For example I have a version used to extract a 2D slice of the bed.
There is one issue with the code to be aware of. The code treats each centroid of the DEM as a vertex in the blockMesh which is not quite correct. This may or may not be an issue depending on your problem, but can be corrected. If I get around to correcting this I will post the code.
Here is an image of the mesh I was able to generate for my point cloud:
'''
Created on May 10, 2013
@author: Patrick Grover
'''
from numpy import *
# note that matrix starts at 1,1 and goes up to numrows,numcols
def getvertex(row, col, numrows):
index = numrows*(col-1) + row
return index
def getBlock(row, col, numrows,numcols, blockSettings):
retval = "\thex ("
retval = retval + str(getvertex(row,col,numrows)-1) + " "
retval = retval + str(getvertex(row+1,col,numrows)-1) + " "
retval = retval + str(getvertex(row+1,col+1,numrows)-1) + " "
retval = retval + str(getvertex(row,col+1,numrows)-1) + " "
numvertices = numrows*numcols
retval = retval + str(getvertex(row,col,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row+1,col,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row+1,col+1,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row,col+1,numrows) + numvertices-1) + ") "
retval = retval + blockSettings
return retval
def getTopWall(row, col, numrows,numcols):
numvertices = numrows*numcols
retval = "(" + str(getvertex(row,col,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row,col+1,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row+1,col+1,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row+1,col,numrows) + numvertices-1) + ") "
return retval
def getBottomWall(row, col, numrows,numcols):
retval = "(" + str(getvertex(row,col,numrows) -1) + " "
retval = retval + str(getvertex(row+1,col,numrows) -1) + " "
retval = retval + str(getvertex(row+1,col+1,numrows)-1 ) + " "
retval = retval + str(getvertex(row,col+1,numrows)-1 ) + ") "
return retval
def getInlet(row, col, numrows,numcols):
numvertices = numrows*numcols
retval = "(" + str(getvertex(row,col,numrows)-1) + " "
retval = retval + str(getvertex(row,col,numrows)+ numvertices-1) + " "
retval = retval + str(getvertex(row+1,col,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row+1,col,numrows) -1)
retval = retval + ") "
return retval
def getOutlet(row, col, numrows,numcols):
numvertices = numrows*numcols
retval = "(" + str(getvertex(row,col,numrows)-1) + " "
retval = retval + str(getvertex(row+1,col,numrows) -1) + " "
retval = retval + str(getvertex(row+1,col,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row,col,numrows) + numvertices-1)
retval = retval + ") "
return retval
def getLeftWall(row, col, numrows,numcols):
numvertices = numrows*numcols
retval = "(" + str(getvertex(row,col,numrows)-1) + " "
retval = retval + str(getvertex(row,col+1,numrows)-1) + " "
retval = retval + str(getvertex(row,col+1,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row,col,numrows) + numvertices-1)
retval = retval + ") "
return retval
def getRightWall(row, col, numrows,numcols):
numvertices = numrows*numcols
retval = "(" + str(getvertex(row,col,numrows)-1) + " "
retval = retval + str(getvertex(row,col,numrows)+ numvertices-1) + " "
retval = retval + str(getvertex(row,col+1,numrows) + numvertices-1) + " "
retval = retval + str(getvertex(row,col+1,numrows)-1)
retval = retval + ") "
return retval
#--------------------------------------------------------------------------------
# BlockMesh Parameters
# Manually set these. Could read these from the ASCII header.
depth = 2.0
numrows = 67
numcols = 1000
cellsize = 0.03
# Meshing details - describes the mesh
blockSettings = "(2 1 20) simpleGrading (1 1 10)\n"
# Input ASCII DEM
asciiFilePath = '/home/geeko/working/GIS/dunes_3cm_67x1000.asc' # Path to the blockMeshDict
blockMeshPath = "/home/geeko/working/BlockMesh/TestMesh2/constant/polyMesh/blockMeshDict"
# Read in ASCII file
data = genfromtxt(asciiFilePath,delimiter=' ',skiprows=6,unpack=True, filling_values=-9999)
print data
fo= open(blockMeshPath,'w')
fo.write("FoamFile\n{version\t2.0;\n\tformat\tascii;\n\tclass\tdictionary;\n\tobject\tblockMeshDict;\n}\n\n")
fo.write("convertToMeters 1.0;\n\n")
# Write out vertices
fo.write("vertices\n")
fo.write("(\n")
for y in range(0,numcols):
for x in range(0,numrows):
#print "x= " + str(x) + "y= " + str(y)
if data[y,x]==-9999:
print "!!!!!!!!!!!!!!!! Error!!!!!!!!!!!!!!!!!!!!!"
#fo.write("( " + str(x*cellsize) + " " + str(y*cellsize) + " " + str(data[numrows-y-1,x]) + ")\n")
fo.write("( " + str(x*cellsize) + " " + str(y*cellsize) + " " + str(data[y-1,x]) + ")\n")
for y in range(0,numcols):
for x in range(0,numrows):
fo.write("( " + str(x*cellsize) + " " + str(y*cellsize) + " " + str(depth) + ")\n")
fo.write(");\n")
# Write out blocks
fo.write("blocks\n")
fo.write("(\n")
for row in range (1,numrows):
for col in range(1,numcols):
fo.write(getBlock(row, col, numrows,numcols, blockSettings))
fo.write(");\n")
fo.close
#edges
fo.write("edges\n")
fo.write("(\n")
fo.write(");\n");
# Boundaries
fo.write("boundary\n")
fo.write("(\n")
# Top Wall
fo.write("\ttopWall\n")
fo.write("\t{\n")
fo.write("\ttype symmetryPlane;\n")
fo.write("\tfaces\n")
fo.write("\t(\n")
for row in range (1,numrows):
for col in range(1,numcols):
fo.write("\t\t" + getTopWall(row, col, numrows,numcols) + "\n")
fo.write("\t);\n")
fo.write("\t}\n")
# getBottomWall
fo.write("\tbottomWall\n")
fo.write("\t{\n")
fo.write("\ttype wall;\n")
fo.write("\tfaces\n")
fo.write("\t(\n")
for row in range (1,numrows):
for col in range(1,numcols):
fo.write("\t\t" + getBottomWall(row, col, numrows,numcols) + "\n")
fo.write("\t);\n")
fo.write("\t}\n")
# Inlet
fo.write("\tinlet\n")
fo.write("\t{\n")
fo.write("\ttype patch;\n")
#fo.write("\ttype cyclic;\n")
#fo.write("\tneighbourPatch outlet;\n")
fo.write("\tfaces\n")
fo.write("\t(\n")
for row in range(1,numrows):
fo.write("\t\t" + getInlet(row, 1, numrows,numcols) + "\n")
fo.write("\t);\n")
fo.write("\t}\n")
# Outlet
fo.write("\toutlet\n")
fo.write("\t{\n")
fo.write("\ttype patch;\n")
#fo.write("\ttype cyclic;\n")
#fo.write("\tneighbourPatch inlet;\n")
fo.write("\tfaces\n")
fo.write("\t(\n")
for row in range(1,numrows):
fo.write("\t\t" + getOutlet(row, numcols, numrows,numcols) + "\n")
fo.write("\t);\n")
fo.write("\t}\n")
# Front and Back
fo.write("\tfrontAndBack\n")
fo.write("\t{\n")
fo.write("\ttype empty;\n")
fo.write("\tfaces\n")
fo.write("\t(\n")
fo.write("\t// Left side\n")
for col in range (1,numcols):
fo.write("\t\t" + getLeftWall(1, col, numrows,numcols) + "\n")
fo.write("\t// Right side\n")
for col in range (1,numcols):
fo.write("\t\t" + getRightWall(numrows, col, numrows,numcols) + "\n")
fo.write("\t);\n")
fo.write("\t}\n")
fo.write(");\n")
#mergePatchPairs
fo.write("mergePatchPairs\n")
fo.write("(\n")
fo.write(");\n");
print "Done!"

Thanks. I have problems in the generation of .xyz file or ASCII file. It will be very grateful if you can further explain details of ArcMap.
ReplyDelete