我用python和mayavi成功地使用spyder显示了模型的3D几何。
现在我面临一个问题,我想点击模型的点来显示有关场景中点的信息;不只是打印它。
有任何方法或任何功能吗?
以下是我所做的代码:
from mayavi import mlab
import meshio
import numpy
def ReadGmshNodes(file,nbcoord):
import scipy
f=open(file,'r')
i=0
goodline=0
nbnodes=0
for l in f:
s=l.split()
if (goodline==1):
if (nbnodes==0):
nbnodes=int(s[0])
nodes=scipy.zeros((nbnodes,nbcoord))
else:
if (i<nbnodes):
if nbcoord==3:
nodes[i,0]=float(s[1])
nodes[i,1]=float(s[2])
nodes[i,2]=float(s[3])
i=i+1
if nbcoord==2:
nodes[i,0]=float(s[1])
nodes[i,1]=float(s[2])
i=i+1
if ( s[0]=='$Nodes' ):
goodline=1
f.close()
return nodes
def ReadGmshDisplacements(file):
import scipy
f=open(file,'r')
i=0
goodline=0
nbnodes=0
j=0
for l in f:
s=l.split()
if (goodline==1):
j=j+1
if (j==8):
nbnodes=int(s[0])
displacements=scipy.zeros((nbnodes,3))
if (j>8):
if (i<nbnodes):
displacements[i,0]=float(s[1])
displacements[i,1]=float(s[2])
displacements[i,2]=float(s[3])
i=i+1
if ( s[0]=='$NodeData' ):
goodline=1
f.close()
return displacements
points, cells, point_data, cell_data, field_data = meshio.read("Wing.msh")
x=points[:,0]
y=points[:,1]
z=points[:,2]
s=numpy.zeros(z.size)+1
triangles=cells ['triangle']
InputFile='Wing-results.msh'
nodes=ReadGmshNodes(InputFile,3)
displacements=ReadGmshDisplacements(InputFile)
from traits.api import HasTraits, Range, Instance,Enum,Array, \
on_trait_change
from traitsui.api import View, Item, Group,CheckListEditor
from mayavi.core.api import PipelineBase,Source
from mayavi.core.ui.api import MayaviScene, SceneEditor, \
MlabSceneModel
def applyscalefactor(scalefactor):
t = displacements[:,2]*scalefactor
xdisp=x+displacements[:,0]
ydisp=y+displacements[:,1]
zdisp=z+t
return xdisp,ydisp,zdisp
class MyModel(HasTraits):
scalefactor = Range(0,100,0,)
minvalue = Range(-0.00483,0,-0.00483,)
maxvalue = Range(0,1.58*10**-3,0,)
coordinates = Array('d', (3,), labels=['x', 'y', 'z'], cols=3,
desc='the coordinate of the picked point')
scene = Instance(MlabSceneModel, ())
plot = Instance(PipelineBase)
figure = None;
colorbar = None;
dispCB = displacements[:,2]
clickpoint_glyphs = None ;
glyph_points = None ;
data_src3d = Instance(Source)
choose_axis = Enum('X', 'Y', 'Z')
@on_trait_change('minvalue,maxvalue,scene.activated')
def update_colorbar(self):
if self.colorbar is None:
self.colorbar =self.scene.mlab.colorbar(title='Wing',orientation='vertical', nb_labels=6)
else:
self.colorbar.data_range=[self.minvalue,self.maxvalue]
@on_trait_change('coordinates,scene.activated')
def picker_callback(self,objPicker):
print(objPicker)
@on_trait_change('scalefactor,scene.activated')
def update_plot(self):
x,y,z=applyscalefactor(self.scalefactor)
if self.plot is None:
self.figure=self.scene.mlab.gcf()
self.plot = self.scene.mlab.triangular_mesh(x,y,z,triangles,scalars=self.dispCB,representation='surface')
self.clickpoint_glyphs = self.scene.mlab.points3d(x,y,z,s,colormap="copper",scale_factor=0.001)
self.glyph_points =self.clickpoint_glyphs.glyph.glyph_source.glyph_source.output.points.to_array()
self.figure.on_mouse_pick(self.picker_callback,type='point')
else:
self.plot.mlab_source.set(x=x, y=y, z=z,scale_factor=0.001,scalars=self.dispCB)
self.update_colorbar()
view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
height=250, width=300, show_label=False),
Group(
'_', 'scalefactor','minvalue','maxvalue'
),
Group(Item('coordinates'),Item('choose_axis',
style='simple',
editor=CheckListEditor(values='XYZ')),
orientation='vertical'),
scrollable=True,
height=100,
resizable=True,
)
my_model = MyModel()
my_model.configure_traits()