Paraview和vtk的学习笔记(一)

在Paraview中,simple.py承接着与外界用户接口的任务,一个最基本的使用Paraview例子就是:

 from paraview.simple import *

  # Create a new sphere proxy on the active connection and register it
  # in the sources group.
  sphere = Sphere(ThetaResolution=16, PhiResolution=32)

  # Apply a shrink filter
  shrink = Shrink(sphere)

  # Turn the visiblity of the shrink object on.
  Show(shrink)

  # Render the scene
  Render()


可以看到,其实第一个函数,就是创建一个source,第二个函数是一个filter。接下来的Show函数其实就是:

def Show(proxy=None, view=None, **params):
    """Turns the visibility of a given pipeline object on in the given view.
    If pipeline object and/or view are not specified, active objects are used."""
    if proxy == None:
        proxy = GetActiveSource()
    if proxy == None:
        raise RuntimeError, "Show() needs a proxy argument or that an active source is set."
    if not view:
        # it here's now active view, controller.Show() will create a new preferred view.
        # if possible.
        view = active_objects.view
    controller = servermanager.ParaViewPipelineController()
    rep = controller.Show(proxy, proxy.Port, view)
    if rep == None:
        raise RuntimeError, "Could not create a representation object for proxy %s" % proxy.GetXMLLabel()
    for param in params.keys():
        setattr(rep, param, params[param])
    return rep

这个方法其中有一行

        raise RuntimeError, "Could not create a representation object for proxy %s" % proxy.GetXMLLabel()

告诉我们,其实rep就是一个representation。所以它就是把这个filter处理后的source绑定到当前的view和代理上。产生一个representation。

最后是Render函数:

def Render(view=None):
    """Renders the given view (default value is active view)"""
    if not view:
        view = active_objects.view
    view.StillRender()
    if _funcs_internals.first_render:
        # Not all views have a ResetCamera method
        try:
            view.ResetCamera()
            view.StillRender()
        except AttributeError: pass
        _funcs_internals.first_render = False
    return view
其实就是开始渲染,调用了
 view.StillRender()
进行渲染。

这其实与servermanager.py中的基本例子是一样的。simple.py通过调用servermanager中的函数完成渲染,用servermanager中的函数我们也可以做到,具体是:

 from paraview.servermanager import *

  # Creates a new built-in session and makes it the active session.
  Connect()

  # Creates a new render view on the active session.
  renModule = CreateRenderView()

  # Create a new sphere proxy on the active session and register it
  # in the sources group.
  sphere = sources.SphereSource(registrationGroup="sources", ThetaResolution=16, PhiResolution=32)

  # Create a representation for the sphere proxy and adds it to the render
  # module.
  display = CreateRepresentation(sphere, renModule)

  renModule.StillRender()
下面我们根据这一段Python代码来分析,当数据已经处理完成之后的渲染的一个过程。

Connect建立服务器连接,这个不用赘述。

renModule = CreateRenderView()
这个函数是:
def CreateRenderView(session=None, **extraArgs):
    """Creates a render window on the particular session. If session
    is not specified, then the active session is used, if available.

    This method can also be used to initialize properties by passing
    keyword arguments where the key is the name of the property. In addition
    registrationGroup and registrationName (optional) can be specified (as
    keyword arguments) to automatically register the proxy with the proxy
    manager."""
    return _create_view("RenderView", session, **extraArgs)
可以看到它直接调用了内部函数_create_view("RenderView", session, **extraArgs)

def _create_view(view_xml_name, session=None, **extraArgs):
    """Creates a view on the particular session. If session
    is not specified, then the active session is used, if available.
    This method can also be used to initialize properties by passing
    keyword arguments where the key is the name of the property."""
    if not session:
        session = ActiveConnection.Session
    if not session:
        raise RuntimeError, "Cannot create view without session."
    pxm = ProxyManager()
    view_module = None
    if view_xml_name:
        view_module = CreateProxy("views", view_xml_name, session)
    if not view_module:
        return None
    return _getPyProxy(view_module)
在这个函数中,session如果过没有会自动查找当前连接的活动session,前面没有,所以就是当前的ActiveConnection.Session。

pxm = ProxyManager()
这一句我们需要注意:

ProxyManager是一个类,它是对后台c++中的vtkSMProxyManager类的一个python封装。它大多数的方法都是使用的这个c++类的。且这是一个单例类。它的实例化方法就是获得当前 self.SMProxyManager = session.GetSessionProxyManager()的代理管理对象。所以这里的pxm就是一个全局的代理管理对象。这是在客户端的,通过它对所有的代理进行管理,在前端进行增删改查,后台就要做出相应的update()。在这里写下这个函数,应该是确认已初始化建立。

我们可以看到,这个函数,返回的是

return _getPyProxy(view_module)
在这之中的,view_module是由
CreateProxy("views", view_xml_name, session)
这个函数:

def CreateProxy(xml_group, xml_name, session=None):
    """Creates a proxy. If session is set, the proxy's session is
    set accordingly. If session is None, the current Session is used, if
    present. You should not have to use method normally. Instantiate the
    appropriate class from the appropriate module, for example:
    sph = servermanager.sources.SphereSource()"""
    global ActiveConnection
    if not session:
        session = ActiveConnection.Session
    if not session:
        raise RuntimeError, "Cannot create objects without a session."
    pxm = ProxyManager(session)
    return pxm.NewProxy(xml_group, xml_name)
可以看到,“views”是xml_group的一个,xml_group一共有:“source”,“filters”,“representation”,“views”四种。这里根据前面的传值xml_name为:“RenderView”。
这个函数的返回是一个代理对象,通过pxm根据xml_group和xml_name创建的一个代理

def NewProxy(self, group, name):
        """Creates a new proxy of given group and name and returns an SMProxy.
        Note that this is a server manager object. You should normally create
        proxies using the class objects. For example:
        obj = servermanager.sources.SphereSource()"""
        if not self.SMProxyManager:
            return None
        aProxy = self.SMProxyManager.NewProxy(group, name)
        if not aProxy:
            return None
        aProxy.UnRegister(None)
        return aProxy

显然这个可以看到,它调用了后台c++ vtkSMProxyManager类中的NewProxy方法。

vtkSMProxy* vtkSMProxyManager::NewProxy(const char* groupName,
  const char* proxyName, const char* subProxyName)
{
  if (vtkSMSessionProxyManager* pxm = this->GetActiveSessionProxyManager())
    {
    return pxm->NewProxy(groupName, proxyName, subProxyName);
    }
  vtkErrorMacro("No active session found.");
  return NULL;
}
可以看到这个函数返回的是vtkSMSessionProxyManager* pxm = this->GetActiveSessionProxyManager(),GetActiveSessionProxyManager()也就是当前session的代理管理对象。赋值到vtkSMSessionProxyManager类的pxm上。

然后根据其:

pxm->NewProxy(groupName, proxyName, subProxyName);
方法去建立相应的代理对象:
vtkSMProxy* vtkSMSessionProxyManager::NewProxy(vtkPVXMLElement* pelement,
                                        const char* groupname,
                                        const char* proxyname,
                                        const char* subProxyName)
{
  vtkObject* object = 0;
  vtksys_ios::ostringstream cname;
  cname << "vtkSM" << pelement->GetName() << ends;
  object = vtkPVInstantiator::CreateInstance(cname.str().c_str());

  vtkSMProxy* proxy = vtkSMProxy::SafeDownCast(object);
  if (proxy)
    {
    // XMLName/XMLGroup should be set before ReadXMLAttributes so sub proxy
    // can be found based on their names when sent to the PM Side
    proxy->SetXMLGroup(groupname);
    proxy->SetXMLName(proxyname);
    proxy->SetXMLSubProxyName(subProxyName);
    proxy->SetSession(this->GetSession());
    proxy->ReadXMLAttributes(this, pelement);
  else
    {
    vtkWarningMacro("Creation of new proxy " << cname.str() << " failed ("
                    << groupname << ", " << proxyname << ").");
    }
  return proxy;
}
在这个函数之前还有一个检测这个代理是否能够被建立的函数,去代理定义,xml文件中查找的一个函数,这里就不赘述,这个函数返回的是一个vtkSMProxy类的一个对象。并且设置了这个proxy的一些属性。
所以view_module其实就是建立的一个叫做“RenderView”,type为“views”的类为vtkSMProxy类的一个代理对象。

下面我们看

return _getPyProxy(view_module)
def _getPyProxy(smproxy, outputPort=0):
    """Returns a python wrapper for a server manager proxy. This method
    first checks if there is already such an object by looking in the
    _pyproxies group and returns it if found. Otherwise, it creates a
    new one. Proxies register themselves in _pyproxies upon creation."""
    if not smproxy:
        return None
    try:
        # is argument is already a Proxy instance, this takes care of it.
        return _getPyProxy(smproxy.SMProxy, outputPort)
    except AttributeError:
        pass
    if (smproxy, outputPort) in _pyproxies:
        return _pyproxies[(smproxy, outputPort)]()

    xmlName = smproxy.GetXMLName()
    if paraview.compatibility.GetVersion() >= 3.5:
        if smproxy.GetXMLLabel():
            xmlName = smproxy.GetXMLLabel()
    classForProxy = _findClassForProxy(_make_name_valid(xmlName), smproxy.GetXMLGroup())
    if classForProxy:
        retVal = classForProxy(proxy=smproxy, port=outputPort)
    else:
        retVal = Proxy(proxy=smproxy, port=outputPort)
    return retVal
 这个函数也就是说,如果这个代理对象实例化了,那么对它子代理对象再进行实例化,没有,则实例化它。_pyproxies是一个代理集合,如果存在直接返回这个代理,没有则继续并且把这个代理对象注册到_pyproxies中。然后把这个新创建的proxy实例化并且返回。其实返回的还是就是这个代理对象。 
  


所以我推测renMoudle其实就是一个“views”类的“RenderView"的代理对象

最后进行渲染,调用

renModule.StillRender()
但是找遍了整个servermanager.py文件,也没找到这个函数,所以去找vtkSMProxy类,但是在这个函数中也没有找到。
classForProxy = _findClassForProxy(_make_name_valid(xmlName), smproxy.GetXMLGroup())
 所以我们看看这个函数: 
  
def _findClassForProxy(xmlName, xmlGroup):
    """Given the xmlName for a proxy, returns a Proxy class. Note
    that if there are duplicates, the first one is returned."""
    global sources, filters, writers, rendering, animation, implicit_functions,\
           piecewise_functions, extended_sources, misc
    if not xmlName:
        return None
    if xmlGroup == "sources":
        return sources.__dict__[xmlName]
    elif xmlGroup == "filters":
        return filters.__dict__[xmlName]
    elif xmlGroup == "implicit_functions":
        return implicit_functions.__dict__[xmlName]
    elif xmlGroup == "piecewise_functions":
        return piecewise_functions.__dict__[xmlName]
    elif xmlGroup == "writers":
        return writers.__dict__[xmlName]
    elif xmlGroup == "extended_sources":
        return extended_sources.__dict__[xmlName]
    elif xmlName in rendering.__dict__:
        return rendering.__dict__[xmlName]
   elif xmlName in animation.__dict__:
        return animation.__dict__[xmlName]
    elif xmlName in misc.__dict__:
        return misc.__dict__[xmlName]
    else:
        return None
不知道它是否属于,这里的xml_name为RenderView
rendering.__dict__:

所以,这里也不知道返回了啥。

如果找不到,则调用

 retVal = Proxy(proxy=smproxy, port=outputPort)
Proxy是一个python类。它在这种情况下创建一个代理对象,它的self.SMProxy是view_module。

剩下的这两个方向都断了线

你可能感兴趣的:(Paraview和vtk的学习笔记(一))