def drawTravelTimeData(ax, data, t=None): """Draw first arrival traveltime data into mpl ax a. data of type pg.DataContainer must contain sensorIdx 's' and 'g' and thus being numbered internally [0..n) """ x = pg.x(data.sensorPositions()) # z = pg.z(data.sensorPositions()) shots = pg.unique(pg.sort(data('s'))) geoph = pg.unique(pg.sort(data('g'))) startOffsetIDX = 0 if min(min(shots), min(geoph)) == 1: startOffsetIDX = 1 tShow = data('t') if t is not None: tShow = t ax.set_xlim([min(x), max(x)]) ax.set_ylim([max(tShow), -0.002]) ax.figure.show() for shot in shots: gIdx = pg.find(data('s') == shot) sensorIdx = [int(i__ - startOffsetIDX) for i__ in data('g')[gIdx]] ax.plot(x[sensorIdx], tShow[gIdx], 'x-') yPixel = ax.transData.inverted().transform_point((1, 1))[1] - \ ax.transData.inverted().transform_point((0, 0))[1] xPixel = ax.transData.inverted().transform_point((1, 1))[0] - \ ax.transData.inverted().transform_point((0, 0))[0] # draw shot points ax.plot(x[[int(i__ - startOffsetIDX) for i__ in shots]], np.zeros(len(shots)) + 8. * yPixel, 'gv', markersize=8) # draw geophone points ax.plot(x[[int(i__ - startOffsetIDX) for i__ in geoph]], np.zeros(len(geoph)) + 3. * yPixel, 'r^', markersize=8) ax.grid() ax.set_ylim([max(tShow), +16. * yPixel]) ax.set_xlim([min(x) - 5. * xPixel, max(x) + 5. * xPixel]) ax.set_xlabel('x-Coordinate [m]') ax.set_ylabel('Traveltime [ms]')
def drawTravelTimeData(axes, data, t=None): """ Draw first arrival traveltime data into mpl axes a. data of type \ref DataContainer must contain sensorIdx 's' and 'g' and thus being numbered internally [0..n) """ x = pg.x(data.sensorPositions()) # z = pg.z(data.sensorPositions()) shots = pg.unique(pg.sort(data('s'))) geoph = pg.unique(pg.sort(data('g'))) startOffsetIDX = 0 if min(min(shots), min(geoph)) == 1: startOffsetIDX = 1 tShow = data('t') if t is not None: tShow = t axes.set_xlim([min(x), max(x)]) axes.set_ylim([max(tShow), -0.002]) axes.figure.show() for shot in shots: gIdx = pg.find(data('s') == shot) sensorIdx = [int(i__ - startOffsetIDX) for i__ in data('g')[gIdx]] axes.plot(x[sensorIdx], tShow[gIdx], 'x-') yPixel = axes.transData.inverted().transform_point((1, 1))[1] - \ axes.transData.inverted().transform_point((0, 0))[1] xPixel = axes.transData.inverted().transform_point((1, 1))[0] - \ axes.transData.inverted().transform_point((0, 0))[0] # draw shot points axes.plot(x[[int(i__ - startOffsetIDX) for i__ in shots]], np.zeros(len(shots)) + 8. * yPixel, 'gv', markersize=8) # draw geophone points axes.plot(x[[int(i__ - startOffsetIDX) for i__ in geoph]], np.zeros(len(geoph)) + 3. * yPixel, 'r^', markersize=8) axes.grid() axes.set_ylim([max(tShow), +16. * yPixel]) axes.set_xlim([min(x) - 5. * xPixel, max(x) + 5. * xPixel]) axes.set_xlabel('x-Coordinate [m]') axes.set_ylabel('Traveltime [ms]')
def test_face_in_face(self): """Test subface with different marker constructed with hole marker.""" w = mt.createCube(marker=1, boundaryMarker=1) b = w.boundary(2) pad = mt.createFacet( mt.createCircle(radius=0.2, segments=12, isHole=True)) b2 = pad.boundary(0) # rotate to match target norm and pos rot = pg.core.getRotation(b2.norm(), b.norm()) pad.transform(rot) pad.translate(b.center()) # create a boundary with new marker match the hole w.copyBoundary(b2) w.createBoundary(w.nodes( [w.createNode(n.pos()).id() for n in b2.nodes()]), marker=2) #print(w.boundaryMarkers()) mesh = mt.createMesh(w) #pg.show(mesh) # w.exportPLC('pad.poly') # mesh.exportBoundaryVTU('b.vtu') np.testing.assert_array_equal( pg.unique(pg.sort(mesh.boundaryMarkers())), [0, 1, 2]) # print(mesh) # mesh.exportBoundaryVTU('b.vtu') pg.show(mesh)
def setDefaultBackground(self): """ """ regionIds = self.regionManager().regionIdxs() pg.info("Found {} regions.".format(len(regionIds))) if len(regionIds) > 1: bk = pg.sort(regionIds)[0] pg.info("Region with smallest marker set to background (marker={0})".format(bk)) self.setRegionProperties(bk, background=True)
def test_appendTriangleBoundary(self): geom = mt.createWorld(start=[-10, 0], end=[10, -10], layers=[-5, -10]) mesh = mt.createMesh(geom, area=1) mesh2 = mt.appendTriangleBoundary(mesh, marker=0) # test if boundary markers are preserved np.testing.assert_array_equal( pg.unique(pg.sort(mesh2.boundaryMarkers())), [-2, -1, 0, 2, 7, 8])
def exportSTL(mesh, fileName, ascii=True): """Write :term:`STL` surface mesh and returns a :gimliapi:`GIMLI::Mesh`. Export a three dimensional boundary :gimliapi:`GIMLI::Mesh` into a :term:`STL` surface mesh. Boundaries with different marker will be separated into different STL solids. TODO: * ASCII=False, write binary STL * QuadrangleFace Boundaries * p2 Boundaries Parameters ---------- mesh : :gimliapi:`GIMLI::Mesh` Mesh to be exported. Only Boundaries of type TriangleFace will be exported. fileName : str name of the .stl file containing the STL surface mesh ascii : bool [True] STL Ascii format """ marker = pg.unique(pg.sort(mesh.boundaryMarkers())) if not '.stl' in fileName: fileName = fileName + '.stl' fi = open(fileName, 'w') for m in marker: me = mesh.extract(mesh.boundaries(mesh.boundaryMarkers() == m)) fi.write('solid ' + str(m) + '\n') for b in me.boundaries(): n = b.norm() fi.write('facet normal %f %f %f\n' % (n[0], n[1], n[2])) fi.write('\touter loop\n') fi.write( '\t\tvertex %f %f %f\n' % (b.node(0).pos()[0], b.node(0).pos()[1], b.node(0).pos()[2])) fi.write( '\t\tvertex %f %f %f\n' % (b.node(1).pos()[0], b.node(1).pos()[1], b.node(1).pos()[2])) fi.write( '\t\tvertex %f %f %f\n' % (b.node(2).pos()[0], b.node(2).pos()[1], b.node(2).pos()[2])) fi.write('\tendloop\n') fi.write('endfacet\n') fi.write('endsolid\n') fi.close()
def test_cubeBasics(self): plc = mt.createCube() for i, b in enumerate(plc.boundaries()): b.setMarker(i + 1) mesh = mt.createMesh(plc) for marker in pg.unique(pg.sort(plc.boundaryMarkers())): b1 = plc.boundaries(plc.boundaryMarkers() == marker)[0] b2 = mesh.boundaries(mesh.boundaryMarkers() == marker)[0] np.testing.assert_array_equal(b1.norm(), b2.norm())
def setDefaultBackground(self): """Set the default background behaviour.""" if self.complex(): self.regionManager().addRegion(3, self._baseMesh, 2) regionIds = self.regionManager().regionIdxs() pg.info("Found {} regions.".format(len(regionIds))) if len(regionIds) > 1: bk = pg.sort(regionIds)[0] pg.info("Region with smallest marker ({0}) " "set to background".format(bk)) self.setRegionProperties(bk, background=True)
def exportSTL(mesh, fileName, ascii=True): """Write :term:`STL` surface mesh and returns a :gimliapi:`GIMLI::Mesh`. Export a three dimensional boundary :gimliapi:`GIMLI::Mesh` into a :term:`STL` surface mesh. Boundaries with different marker will be separated into different STL solids. TODO: * ASCII=False, write binary STL * QuadrangleFace Boundaries * p2 Boundaries Parameters ---------- mesh : :gimliapi:`GIMLI::Mesh` Mesh to be exported. Only Boundaries of type TriangleFace will be exported. fileName : str name of the .stl file containing the STL surface mesh ascii : bool [True] STL Ascii format """ marker = pg.unique(pg.sort(mesh.boundaryMarkers())) if not '.stl' in fileName: fileName = fileName + '.stl' fi = open(fileName, 'w') for m in marker: me = mesh.extract(mesh.boundaries(mesh.boundaryMarkers() == m)) fi.write('solid ' + str(m) + '\n') for b in me.boundaries(): n = b.norm() fi.write('facet normal %f %f %f\n' %(n[0], n[1], n[2])) fi.write('\touter loop\n') fi.write('\t\tvertex %f %f %f\n' %(b.node(0).pos()[0], b.node(0).pos()[1], b.node(0).pos()[2])) fi.write('\t\tvertex %f %f %f\n' %(b.node(1).pos()[0], b.node(1).pos()[1], b.node(1).pos()[2])) fi.write('\t\tvertex %f %f %f\n' %(b.node(2).pos()[0], b.node(2).pos()[1], b.node(2).pos()[2])) fi.write('\tendloop\n') fi.write('endfacet\n') fi.write('endsolid\n') fi.close()
def test_io_STL(self): try: import tempfile as tmp except ImportError: return str = r"""solid name facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 6.100000e+002 -1.046773e+002 -2.818708e+003 vertex 6.100000e+002 -1.249950e+002 -2.814064e+003 vertex 6.100000e+002 -2.507565e+000 -2.930000e+003 endloop endfacet endsolid solid name facet normal -2.568735e-007 1.396183e-002 -9.999025e-001 outer loop vertex 1.350000e+002 3.839764e+001 -2.929429e+003 vertex 6.100000e+002 7.930283e+001 -2.928858e+003 vertex 6.100000e+002 -2.507565e+000 -2.930000e+003 endloop endfacet endsolid""" _, fileName = tmp.mkstemp(suffix='.stl') fi = open(fileName, 'w') fi.write(str) fi.close() mesh = pg.load(fileName, verbose=True) np.testing.assert_equal(mesh.cellCount(), 0) np.testing.assert_equal(mesh.nodeCount(), 5) np.testing.assert_equal(mesh.boundaryCount(), 2) np.testing.assert_equal( np.array(pg.unique(pg.sort(mesh.boundaryMarkers()))), [0, 1]) try: os.remove(fileName) except: print("can't remove:", fileName)
def test_io_STL(self): try: import tempfile as tmp except ImportError: return str = r"""solid name facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 6.100000e+002 -1.046773e+002 -2.818708e+003 vertex 6.100000e+002 -1.249950e+002 -2.814064e+003 vertex 6.100000e+002 -2.507565e+000 -2.930000e+003 endloop endfacet endsolid solid name facet normal -2.568735e-007 1.396183e-002 -9.999025e-001 outer loop vertex 1.350000e+002 3.839764e+001 -2.929429e+003 vertex 6.100000e+002 7.930283e+001 -2.928858e+003 vertex 6.100000e+002 -2.507565e+000 -2.930000e+003 endloop endfacet endsolid""" _, fileName = tmp.mkstemp(suffix='.stl') fi = open(fileName, 'w') fi.write(str) fi.close() mesh = pg.load(fileName, verbose=True) np.testing.assert_equal(mesh.cellCount(), 0) np.testing.assert_equal(mesh.nodeCount(), 5) np.testing.assert_equal(mesh.boundaryCount(), 2) np.testing.assert_equal(np.array(pg.unique(pg.sort(mesh.boundaryMarkers()))), [0, 1]) try: os.remove(fileName) except: print("can't remove:", fileName)
def drawPLC(ax, mesh, fillRegion=True, regionMarker=True, boundaryMarker=False, **kwargs): """Draw 2D PLC into the given ax. Parameters ---------- fillRegion: bool [True] Fill the regions with default colormap. regionMarker: bool [True] show region marker boundaryMarker: bool [False] show boundary marker **kwargs Examples -------- """ # eCircles = [] cols = [] if fillRegion and mesh.boundaryCount() > 0: tmpMesh = pg.meshtools.createMesh(mesh, quality=20, area=0) if tmpMesh.cellCount() == 0: pass else: drawModel(ax=ax, mesh=tmpMesh, data=tmpMesh.cellMarkers(), nLevs=len(pg.unique(pg.sort(tmpMesh.cellMarkers()))), levels=pg.utils.unique(tmpMesh.cellMarkers()), tri=True, alpha=0.5, linewidth=0.0, edgecolors='k', snap=True) for n in mesh.nodes(): col = (0.0, 0.0, 0.0, 0.5) if n.marker() == pg.MARKER_NODE_SENSOR: col = (0.0, 0.0, 0.0, 1.0) ms = kwargs.pop('markersize', 5) ax.plot(n.pos()[0], n.pos()[1], 'bo', markersize=ms, color=col) # eCircles.append(mpl.patches.Circle((n.pos()[0], n.pos()[1]))) # eCircles.append(mpl.patches.Circle((n.pos()[0], n.pos()[1]), 0.1)) cols.append(col) if boundaryMarker: for b in mesh.boundaries(): ax.text(b.center()[0], b.center()[1], str(b.marker()), color='red', verticalalignment='center', horizontalalignment='center') # 'white' # p = mpl.collections.PatchCollection(eCircles, color=cols) # ax.add_collection(p) if regionMarker: for reg in mesh.regionMarker(): ax.text(reg[0], reg[1], str(reg.marker()) + ": " + str(reg.area()), color='black', verticalalignment='center', horizontalalignment='left') # 'white' for hole in mesh.holeMarker(): ax.text(hole[0], hole[1], 'H', color='black') updateAxes_(ax)
def createWorld(start, end, marker=1, area=0., layers=None, worldMarker=True): """Create simple rectangular world. Create simple rectangular world with appropriate boundary conditions. Surface boundary is set do pg.MARKER_BOUND_HOMOGEN_NEUMANN, i.e, -1 and inner subsurface is set to pg.MARKER_BOUND_MIXED, i.e., -2 or Numbered in ascending order in left direction starting upper left if worldMarker is set to false. Parameters ---------- start : [x, y] Upper/Left Corner end : [x, y] Lower/Right Corner marker : int Marker for the resulting triangle cells after mesh generation. area : float | list Maximum cell size for resulting triangles after mesh generation. If area is a float set it global, if area is a list set it per layer. layers : [float] Add some layers to the world. worldMarker : [bool] Specify kind of preset boundary marker [-1, -2] or [1, 2, 3, 4 ..] Returns ------- poly : :gimliapi:`GIMLI::Mesh` The resulting polygon is a :gimliapi:`GIMLI::Mesh`. Examples -------- >>> from pygimli.meshtools import createWorld >>> from pygimli.mplviewer import drawMesh >>> import matplotlib.pyplot as plt >>> world = createWorld(start=[-5, 0], end=[5, -5], layers=[-1,-2,-3]) >>> >>> fig, ax = plt.subplots() >>> drawMesh(ax, world) >>> plt.show() """ z = [start[1]] if layers is not None: z = z + list(layers) z.append(end[1]) # ensure - decreasing order if layers are out of bounding box z = pg.sort(z)[::-1] poly = pg.Mesh(2) if isinstance(area, float) or isinstance(area, int): area = np.ones(len(z)) * float(area) for i, depth in enumerate(z): n = poly.createNode([start[0], depth]) if i > 0: if len(z) == 2: poly.addRegionMarker(n.pos() + [0.2, 0.2], marker=marker, area=area[0]) else: poly.addRegionMarker(n.pos() + [0.2, 0.2], marker=i, area=area[i-1]) for i, depth in enumerate(z[::-1]): poly.createNode([end[0], depth]) polyCreateDefaultEdges_(poly, boundaryMarker=range(1, poly.nodeCount() + 1)) if worldMarker: for b in poly.boundaries(): if b.norm()[1] == 1.0: b.setMarker(pg.MARKER_BOUND_HOMOGEN_NEUMANN) else: b.setMarker(pg.MARKER_BOUND_MIXED) if layers is not None: for i in range(len(layers)): poly.createEdge( poly.node(i + 1), poly.node(poly.nodeCount() - i - 2), poly.boundaryCount() + 1) # pg.warnNonEmptyArgs(kwargs) return poly
def drawBoundaryMarkers(ax, mesh, clipBoundaryMarkers=False, **kwargs): """Draw boundary markers for mesh.boundaries with marker != 0 Args ---- mesh: :gimliapi:`GIMLI::Mesh` Mesh that have the boundary markers. clipBoundaryMarkers: bool [False] Clip boundary marker to the axes limits if needed. Keyword Arguments ---------------- **kwargs Forwarded to plot Examples -------- >>> import pygimli as pg >>> import pygimli.meshtools as mt >>> c0 = mt.createCircle(pos=(0.0, 0.0), radius=1, segments=4) >>> l0 = mt.createPolygon([[-0.5, 0.0], [.5, 0.0]], boundaryMarker=2) >>> l1 = mt.createPolygon([[-0.25, -0.25], [0.0, -0.5], [0.25, -0.25]], ... interpolate='spline', addNodes=4, ... boundaryMarker=3) >>> l2 = mt.createPolygon([[-0.25, 0.25], [0.0, 0.5], [0.25, 0.25]], ... interpolate='spline', addNodes=4, ... isClosed=True, boundaryMarker=3) >>> mesh = mt.createMesh([c0, l0, l1, l2], area=0.01) >>> ax, _ = pg.show(mesh) >>> pg.viewer.mpl.drawBoundaryMarkers(ax, mesh) """ ms = pg.unique(pg.sort( mesh.boundaryMarkers()[mesh.boundaryMarkers() != 0])) # cMap = plt.cm.get_cmap("Set3", len(ms)) kwargs['lw'] = kwargs.pop('lw', 4) for i, m in enumerate(ms): bs = mesh.findBoundaryByMarker(m) paths = mesh.findPaths(bs) col = 'C' + str(i) for p in paths: xs = pg.x(mesh.nodes(p)) ys = pg.y(mesh.nodes(p)) path = np.array([xs, ys]).T ax.plot(xs, ys, color=col, **kwargs) center = pg.meshtools.interpolateAlongCurve( path, [pg.utils.cumDist(path)[-1] / 2])[0] x = center[0] y = center[1] bbox_props = dict(boxstyle="circle,pad=0.2", fc="w", ec=col) txt = ax.text(x, y, str(m), color=col, va="center", ha="center", zorder=20, bbox=bbox_props, fontsize=9, fontdict={'weight': 'bold'}) # clipping avoid visuablity outside axes. # Needed if the axes limits do not match mesh size. txt.set_clip_on(clipBoundaryMarkers) ax.plot(xs[0], ys[0], 'o', color='k') ax.plot(xs[-1], ys[-1], 'o', color='k')
def main( argv ): from optparse import OptionParser parser = OptionParser( "usage: %prog [options] mesh" ) parser.add_option("-v", "--verbose", dest="verbose", action="store_true" , help="be verbose", default=False ) parser.add_option("-o", "--output", dest="outFileName", help="filename for the resulting mesh", metavar="File" ) parser.add_option("-p", "--paramesh", dest="paraMesh", help="name for reference parameter mesh", metavar="File", default='' ) (options, args) = parser.parse_args() if options.verbose: print(options, args) if len( args ) == 0: parser.print_help() print("Please add a mesh or model name.") sys.exit( 2 ) else: meshname = args[ 0 ]; mesh = g.Mesh( meshname ) if options.verbose: print("input mesh:", mesh) print("nModel(input):", end=' ') for m in g.unique( g.sort( mesh.cellMarker() ) ): print(m) if len( options.paraMesh ) == 0: print("no reference mesh given") sys.exit(0) refParaIn = g.Mesh( options.paraMesh ) refPara = g.Mesh() refPara.createH2Mesh( refParaIn ) refModel = g.unique( g.sort( refPara.cellMarker() ) ) if options.verbose: print("reference mesh:", refPara) print("nModel(ref):", len( refModel ), refModel[ 0] , refModel[1], refModel[2], '...', refModel[-1]) swatch = g.Stopwatch( True ) lastTime = 0 for c in mesh.cells(): cell = refPara.findCell( c.center(), False ) if swatch.duration() - lastTime > 1: print("\r", c.id()) lastTime = swatch.duration() if cell is not None: c.setMarker( cell.marker() ) else: # set background c.setMarker( -1 ) newModel = g.unique( g.sort( mesh.cellMarker() ) ) if options.verbose: print("convert:", swatch.duration()) print("nModel(out):", len( newModel ), newModel[ 0 ], newModel[ 1 ], newModel[ 2 ], ' ... ' , newModel[ -1 ]) print("diff should be 1(background)", len( newModel ) -len( refModel )) missing = g.stdVectorI() missingMesh = g.Mesh() for i in refModel: if i-1 not in newModel: for c in refPara.findCellByMarker( i-1 ): missing.append( c.id() ) print(len( missing ), missing) missingMesh.createMeshByCellIdx( refPara, missing ); missingMesh.exportVTK( 'missing' ) if options.outFileName: mesh.save( options.outFileName ) if options.verbose: print("wrote: ", options.outFileName)
def drawPLC(axes, mesh, fillRegion=True, boundaryMarker=False, **kwargs): """ Draw 2D PLC into the given axes. Parameters ---------- fillRegion: bool [True] Fill the regions with default colormap. boundaryMarker: bool [False] show boundary marker **kwargs Examples -------- """ eCircles = [] cols = [] if fillRegion and mesh.boundaryCount() > 0: tmpMesh = pg.meshtools.createMesh(mesh, quality=20) if tmpMesh.cellCount() == 0: pass else: drawModel(axes=axes, mesh=tmpMesh, data=tmpMesh.cellMarkers(), nLevs=len(pg.unique(pg.sort(tmpMesh.cellMarkers()))), levels=pg.utils.unique(tmpMesh.cellMarkers()), tri=True, alpha=0.5, linewidth=0.0, edgecolors='k', snap=False) for n in mesh.nodes(): col = (0.0, 0.0, 0.0) if n.marker() == pg.MARKER_NODE_SENSOR: col = (1.0, 0.0, 0.0) # eCircles.append(mpl.patches.Circle((n.pos()[0], n.pos()[1]))) ms = kwargs.pop('markersize', 5) axes.plot(n.pos()[0], n.pos()[1], 'bo', markersize=ms, color='black') # eCircles.append(mpl.patches.Circle((n.pos()[0], n.pos()[1]), 0.1)) cols.append(col) if boundaryMarker: for b in mesh.boundaries(): axes.text(b.center()[0], b.center()[1], str(b.marker()), color='red', verticalalignment='center', horizontalalignment='center') # 'white' p = mpl.collections.PatchCollection(eCircles, color=cols) axes.add_collection(p) for reg in mesh.regionMarker(): axes.text(reg[0], reg[1], str(reg.marker()) + ": " + str(reg.area()), color='black', verticalalignment='center', horizontalalignment='left' ) # 'white' for hole in mesh.holeMarker(): axes.text(hole[0], hole[1], 'H', color='black') updateAxes_(axes)