vtkObject:
这个类位于/ParaView-v4.2.0-source/VTK/Common/Core/下
这个类是大部分vtk类的基类。vtkObject提供方法去追踪修改时间,debugging,打印,和事件回调,大部分基于vtk框架实现的类都是这个类的子类,或者其子类的子类。只有少数小的help类或者是某些多继承的类例外。vtkObject也提供引用计数。只要另一个类使用它,那么这个类的就被引用计数。当最后一个引用被移除,那么这个类将会被销毁。
在VTK对象中,创建都要使用New方法,删除使用Delete方法。VTK对象不能被分配进栈,因为构造函数是projected 方法。
首先我们来讲讲方法:PrintSelf的使用:
<span style="font-size:14px;"> vtkIndent indent(3);
this->PrintSelf(std::cout,indent);</span>
只要在你需要输出的地方加上这个就可以使用了,但是需要注意的是,不是所有类都对自己的PrintSelf进行了详细的书写,有些可能没有我们需要的信息。其中indent代表缩进。indent(3)即实例化缩进为3.
下面来看看我一直无法理解的方法:
<span style="font-size:14px;"> int InvokeEvent(unsigned long event, void *callData);
int InvokeEvent(const char *event, void *callData);
//ETX
int InvokeEvent(unsigned long event) { return this->InvokeEvent(event, NULL); };
int InvokeEvent(const char *event) { return this->InvokeEvent(event, NULL); };</span>
这个方法调用一个event并且返回这个事件是被放弃了还是没有。如果被放弃了,则返回1,没有则0.<span style="font-size:14px;">int vtkObject::InvokeEvent(unsigned long event, void *callData)
{
if (this->SubjectHelper)
{
return this->SubjectHelper->InvokeEvent(event,callData, this);
}
return 0;
}
</span>
我们可以看到,它调用了这个类中的一个辅助类SubjectHelper的这个方法:
这个类中的这个方法比较复杂,在这我们简单的讲一下:
当我们调用一个事件的时候,observer将会增加或者溢出observers。为了保证这些observers的迭代数理,我们需要通过ListModified ivar确保list的改变。但是一个observer也可能会做一些导致另一个事件在这个对象中调用的事。这意味着这个方法将会被递归调用,这意味着我们将要删除第一个调用所依赖的 ListModified flag 。为了面对这种情况,我们需要把之前的ListModified值存在栈里,并且在离开之前从新拿出来。
我们也需要存储我们已经在栈上调用了的observers(免得他在事件调用中被覆盖)。也保证我们不调用任何新的observers,这只会在被其他的observers调用时才会增加。
如果一个有比最大的maxTag还大的tag被找到,这意味着他在IvokeEvent被调用之后就已经被添加了进来,这个元素将会被丢弃并且不会执行元素命令。
循环调用两到三次。关注被动的observers和holders。
0.被动observers循环:
循环所有的Observers并且执行那些被动的observers。这些observers不会影响系统的状态,并且不允许去丢去event。
1.focus循环:
如果有focus holder,循环所有的observers并且执行所有与之相关的observers。设置focusHandled表明一个focus holder操控这个事件
2.Remainder(剩余) loop:
如果还没有focus holder操控这个事件。循环所有剩余observers。这个循环将会在没有focus holder时执行。
还有一个:
<span style="font-size:14px;">int vtkObject::InvokeEvent(const char *event, void *callData)
{
return this->InvokeEvent(vtkCommand::GetEventIdFromString(event), callData);
}
</span>
只是把事件这个事件的Id返回即可。没怎么看懂这个函数的意义,但是可以确定的是流水线应该不是根据这个走的,它可能起一个监督其中各个步骤不是不都没有abort,如果abort则抛弃中断?
感觉就是在一个类销毁之后,所以给这个类加了观察者模式的类就要知道,这个类被销毁了,要对数据进行更新,刚刚那个类已经不能调用了,可能要用之前的?就像abort?然后载入last?
vtkKdTreeManager:
这个类在:/ParaView-v4.2.0-source/ParaViewCore/VTKExtensions/Rendering/下:
这个类主要就是用来在结构化或者非结构化数据上产生KdTree。当使用ordered compositing时,Paraview需要构建KdTree。当使用结构化数据时,Kdtree通过使用所有的流水线中的数据或者使用由结构化数据范围变换器所提供的部分数据而构建树。这个类是在这个过程中管理逻辑的。当使用结构化数据变换范围的数据时,它只使用vtkKdTreeGenerator,否则,他还要用vtkPkdTree来建立最理想的数据划分。
首先我们来看这个类中的一个重要的函数:
void vtkKdTreeManager::GenerateKdTree():
首先把KdTree中的数据集全部移出,然后检测是否初始化了,没有则初始化: this->KdTree->BuildLocator();这个函数在并行应用程序中将会被所有进程调用。
然后把所有的数据加入到这个KdTree中:this->AddDataObjectToKdTree(iter->GetPointer());
如果是变换范围的数据:那么vtkPKdTree需要一个数据集去计算体的边界。通过正确的边界信息去创建一个outline source。然后把它加入Kd树中。然后创建 vtkKdTreeGenerator* generator = vtkKdTreeGenerator::New();使其给这个kd 树产生cut。:
generator->BuildTree(this->ExtentTranslator, this->WholeExtent,
this->Origin, this->Spacing);
如果不是,则直接执行:
this->KdTree->SetCuts(0);
this->KdTree->AssignRegionsContiguous();分配连续空间
最后执行:this->KdTree->BuildLocator();完成kdtree的建立。