我们看一个非常简单的定义sources的代码:
# 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)
我们可以看到,它直接就调用了sources模块,然后其下的一个类,然后直接建立。可是并没有找到sources模块。这要怎么去找呢?
经过试验我发现,在paraview4.2my/lib/site-package/simple.py在我们正常操控Paraview的时候根本用不到,只有当调用Paraview中的python shell的时候才会用到。也就是在QT写的这个界面之后的业务逻辑根本不是那些python文件操控,那么是什么呢?
而且还有一个事情,就是我们在修改了那里面的python文件之后,需要重新启动Paraview才能起作用。
在对数据进行追踪的时候,我发现在运行:
dafengply = PLYReader(FileName='/root/data/G1/dafeng.ply')
这条代码时,它创建了一个group为sources,name为plyreader的代理对象。所以我们先去看看是怎么创建的:
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;
}
pxm是一个服务器代理管理对象。在它的里面创建新的代理:
vtkSMProxy* vtkSMSessionProxyManager::NewProxy(
const char* groupName, const char* proxyName, const char* subProxyName)
{
if (!groupName || !proxyName)
{
return 0;
}
// Find the XML element from which the proxy can be instantiated and
// initialized
vtkPVXMLElement* element = this->GetProxyElement( groupName, proxyName,
subProxyName);
if (element)
{
return this->NewProxy(element, groupName, proxyName, subProxyName);
}
return 0;
}
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;
}
非常简单,对于每个renderer,他可能都创建了一个plyreader对象。通过实验,发现确实产生了3个plyreader。
下一步,或许,我们需要按照上次发现的那个代理类进行测试。
经过我使用两台机器并行实验测试,发现对于ply文件,它只是在头结点把所有的数据都读入第一个进程。并且在每个节点上,他们都进行了渲染操作。但是具体他们渲染的数据是不是平分的,或者数据是怎么划分的,还是最坏的情况,两个都渲染了完整的,这个还需要进一步的实验测试,初步的想法,就是数据好像是在处理后传给了vtkMapper,再给vtkRenderer,所以通过这里我们来看看他们的数据是什么情况。
在vtkMapper的相关的polydata的vtkOpenGLPolyDataMapper中发现并没运行到,而且在后面的并行中也对polydata的那个并行数据提取的也没有运行到,难道plyreader产生的数据并不是polydata?还是那个函数没用?
vtkRenderer中对数据并没有直接操控,还是要到vtkMapper上。但是在里面写数据的提取发现会报错,数据格式不知道,提取不出来。所以这个方法目前也停止了。
下面的一个想法,就是去/VTK/Filter/Parallel中去找相关的类试试,看能不能找到数据分发的地方。
今天在/ParaViewCore/ClientServerCore/Rendering/中找到一个文件vtkMPIMoveData,这个文件是用来在各个进程中转移和重新划分数据的。这其中有对Paraview的几种运行方式分别执行一些代码。我们现在的运行方式应该是其中的第二种:
if (this->MoveMode == vtkMPIMoveData::PASS_THROUGH &&
this->MPIMToNSocketConnection == 0)
{
if (input)
{
output->ShallowCopy(input);
}
return 1;
}
只是把input浅复制到output中。是最简单的一种,对我们的进展没有什么影响。这种模式应该就是我们我们的dataserver就直接作为了renderserver,所以直接就把input复制到output里就行了。所以这一步是数据处理好了之后进行的。
今天又做了一些实验,发现当运行D3Filter,也就是vtkDistributeDataFilter.cxx文件,我在MPIRedistribute中加了一个输出,并且在文件vtkMPICommunicator::SendVoidArray和vtkMPICommunicator::SendData下加上了输出标记,在执行MPIRedistribute之后,确实运行了这两个方法,并且在我使用D3Filter之前它也运行了这两个函数。但是在我不用这个Filter时,这两个函数并不会运行。这两个函数是进行数据的发送的,为什么会不运行呢?
并且我在vtkTranmitPolyDataPiece.cxx的RequestData中也加了输出标记,但是也没有运行。但是在vtkPolyDataMapper中却运行了,说明最后的数据应该还是PolyData。但是这个没有用到。
ClientServerCore/vtkMPIMToNSocketConnection是用于数据服务器和渲染服务器分开来的状况。M to N
vtkClientServerMoveData这个类是用于把数据从服务器传给客户端的。我在这里面加了输出标记,结果也没有运行到。
还有在VTKExtension/Rendering/下的vtkRedistributePolyData在这里面加了输出标记,发现也没有运行到。
同样的在VTKExtension/Rendering/下的vtkWeightedRedistributePolyData类也没有运行
同样的在VTKExtension/Rendering/下的vtkAllToNRedistributePolyData类也没有运行
同样的在VTKExtension/Rendering/下的vtkAllToNRedistributeCompusitePolyData类也没有运行