Paraview与VTK学习笔记(三)
2015-03-22 10:50
127 查看
下面接着上一面继续,上面那个函数最后调用了
上面最后执行的四个函数,很显然又调用了vtkClientServerInterpreter类的实例Interpreter。
第一个函数,调用的是vtkClientServerInterpreter类的父类的函数,这个函数就是返回一个GetGlobalWarningDisplay量。让其等于temp
第二个函数,也是继承自父类vtkObject的函数,使其值为0或1。
第三个函数,ProcessStream(stream),调用的就是vtkClientServerInterpreter类的方法:
Now that id_values have been expanded, we do not need the last // result. Reset the result to empty before processing the message.
我们先来看ExpandMessage(css,midx,0,msg)这个函数,css即之前那条stream,midx为这条stream中的第几条信息,0为起始参数位置,out为建立的一个msg,下面这个函数应该就是要把stream扩展到这个out里,也可以说是对于一些特定参数需要解析添加
我们来看这个函数:
这个this很显然是vtkSMRenderViewProxy这个对象。
vtkPVSessionCore::ExecuteStreamInternal
void vtkPVSessionCore::ExecuteStreamInternal(const vtkClientServerStream& stream, bool ignore_errors) { LOG( << "----------------------------------------------------------------\n" << "ExecuteStream\n" << stream.StreamToString() << "----------------------------------------------------------------\n"); this->Interpreter->ClearLastResult();//最后结果重置 int temp = this->Interpreter->GetGlobalWarningDisplay(); this->Interpreter->SetGlobalWarningDisplay(ignore_errors ? 0 : 1); this->Interpreter->ProcessStream(stream);//Interpreter是vtkClientServerInterpreter this->Interpreter->SetGlobalWarningDisplay(temp); }
上面最后执行的四个函数,很显然又调用了vtkClientServerInterpreter类的实例Interpreter。
第一个函数,调用的是vtkClientServerInterpreter类的父类的函数,这个函数就是返回一个GetGlobalWarningDisplay量。让其等于temp
第二个函数,也是继承自父类vtkObject的函数,使其值为0或1。
第三个函数,ProcessStream(stream),调用的就是vtkClientServerInterpreter类的方法:
int vtkClientServerInterpreter::ProcessStream(const vtkClientServerStream& css) { for(int i=0; i < css.GetNumberOfMessages(); ++i) { if(!this->ProcessOneMessage(css, i)) { return 0; } } return 1; }我们再来回顾一下这条css的内容:
stream << vtkClientServerStream::Invoke << VTKOBJECT(this) << "StillRender" << vtkClientServerStream::End;然后我们再看this->ProcessOneMessage这个函数:
vtkClientServerInterpreter::ProcessOneMessage(const vtkClientServerStream& css, int message) { // Log the message. if(this->LogStream) { *this->LogStream << "---------------------------------------" << "---------------------------------------\n"; *this->LogStream << "Processing "; css.PrintMessage(*this->LogStream, message); this->LogStream->flush(); } // Look for known commands in the message. int result = 0; vtkClientServerStream::Commands cmd = css.GetCommand(message);//在这里获得cmd为Invoke命令,这里的message为第几条信息,为上一个函数的i switch(cmd) { case vtkClientServerStream::New: result = this->ProcessCommandNew(css, message); break; case vtkClientServerStream::Invoke: result = this->ProcessCommandInvoke(css, message); break;//执行 case vtkClientServerStream::Delete: result = this->ProcessCommandDelete(css, message); break; case vtkClientServerStream::Assign: result = this->ProcessCommandAssign(css, message); break; default: { // Command is not known. vtksys_ios::ostringstream error; error << "Message with type " << vtkClientServerStream::GetStringFromCommand(cmd) << " cannot be executed." << ends; this->LastResultMessage->Reset(); *this->LastResultMessage << vtkClientServerStream::Error << error.str().c_str() << vtkClientServerStream::End; } break; } // Log the result of the message. if(this->LogStream) { if(this->LastResultMessage->GetNumberOfMessages() > 0) { *this->LogStream << "Result "; this->LastResultMessage->Print(*this->LogStream); } else { *this->LogStream << "Empty Result\n"; } this->LogStream->flush(); } // If the command failed with an error message, invoke the error // event so observers can handle the error. if(!result) { this->InvokeEvent(vtkCommand::UserEvent, &info); } return result; }可以看到,这个函数最终调用了
result = this->ProcessCommandInvoke(css, message)其具体代码如下:
int vtkClientServerInterpreter ::ProcessCommandInvoke(const vtkClientServerStream& css, int midx)//midx为<pre name="code" class="cpp">就为第几条信息,上一个函数的i{ // Create a message with all known id_value arguments expanded. vtkClientServerStream msg; if(!this->ExpandMessage(css, midx, 0, msg))//把这个信息膨胀 { // ExpandMessage left an error in the LastResultMessage for us. return 0; } //
Now that id_values have been expanded, we do not need the last // result. Reset the result to empty before processing the message.
我们先来看ExpandMessage(css,midx,0,msg)这个函数,css即之前那条stream,midx为这条stream中的第几条信息,0为起始参数位置,out为建立的一个msg,下面这个函数应该就是要把stream扩展到这个out里,也可以说是对于一些特定参数需要解析添加
int vtkClientServerInterpreter::ExpandMessage(const vtkClientServerStream& in, int inIndex, int startArgument, vtkClientServerStream& out) { // Reset the output and make sure we have input. out.Reset(); if(inIndex < 0 || inIndex >= in.GetNumberOfMessages()) { vtksys_ios::ostringstream error; error << "ExpandMessage called to expand message index " << inIndex << " in a stream with " << in.GetNumberOfMessages() << " messages." << ends; this->LastResultMessage->Reset(); *this->LastResultMessage << vtkClientServerStream::Error << error.str().c_str() << vtkClientServerStream::End; return 0; } // Copy the command. out << in.GetCommand(inIndex);//把这条命令复制到out中 // Just copy the first arguments. int a; for(a=0; a < startArgument && a < in.GetNumberOfArguments(inIndex); ++a) { out << in.GetArgument(inIndex, a);//把第一个参数存到out中,这里应该不执行,因为startArgument为0 } // Expand id_value for remaining arguments. for(a=startArgument; a < in.GetNumberOfArguments(inIndex); ++a)//对于当前stream的当前信息获取其参数个数,每个参数进行for循环执行下面 { if(in.GetArgumentType(inIndex, a) == vtkClientServerStream::id_value)//如果当前参数的参数类型为id_value { vtkClientServerID id; in.GetArgument(inIndex, a, &id);//在stream中获取一个指向类型/值的指针 // If the ID is in the map, expand it. Otherwise, leave it.如果ID在map,则扩展它,否则舍弃它 if(const vtkClientServerStream* tmp = this->GetMessageFromID(id)) { for(int b=0; b < tmp->GetNumberOfArguments(0); ++b) { out << tmp->GetArgument(0, b); } } else { out << in.GetArgument(inIndex, a); } } else if(in.GetArgumentType(inIndex, a) == vtkClientServerStream::LastResult)//如果当前参数的类型是<span style="font-family:Arial, Helvetica, sans-serif;">LastResult,则把之前的result的值(参数)传进out</span> { // Insert the last result value. for(int b=0; b < this->LastResultMessage->GetNumberOfArguments(0); ++b) { out << this->LastResultMessage->GetArgument(0, b); } } else if (in.GetArgumentType(inIndex, a) == vtkClientServerStream::stream_value)//如果当前参数的类型是stream_value { // Evaluate the expression and insert the result. vtkClientServerStream *lastResult = this->LastResultMessage; this->LastResultMessage = new vtkClientServerStream(); vtkClientServerStream substream; in.GetArgument(inIndex, a, &substream); if (this->ProcessStream(substream)) { // Insert the last result value. for(int b=0; b < this->LastResultMessage->GetNumberOfArguments(0); ++b) { out << this->LastResultMessage->GetArgument(0, b);//也把<span style="font-family: Arial, Helvetica, sans-serif;">之前的result的值(参数)传进out</span> } } // restore last-result delete this->LastResultMessage; this->LastResultMessage = lastResult; } else { // Just copy the argument. out << in.GetArgument(inIndex, a);//其他则只把这个参数复制进out } } // End the message. out << vtkClientServerStream::End;//从而得到一个完整的out return 1; }回顾一下这条stream:
stream << vtkClientServerStream::Invoke << VTKOBJECT(this) << "StillRender" << vtkClientServerStream::End;接下来我们看:
this->LastResultMessage->Reset();//重置 // Get the object and method to be invoked. vtkObjectBase* obj; const char* method; if(msg.GetNumberOfArguments(0) >= 2 &&//第一条信息如果除了开始的command和最后的end,如果还有大于等于2条的信息 msg.GetArgument(0, 0, &obj) && msg.GetArgument(0, 1, &method))//第二条如果过是一个对象,并且第三个是一个方法。并且创建相应指针 {<pre name="code" class="cpp"> // Log the expanded form of the message. if(this->LogStream) { *this->LogStream << "Invoking "; msg.Print(*this->LogStream); this->LogStream->flush(); } // Find the command function for this object's type. if(obj && this->HasCommandFunction(obj->GetClassName()))//如果由这个对象,并且这个对象由这个方法,应该是利用xml去查 { if (this->CallCommandFunction(obj->GetClassName(), obj, method, msg,//执行这个对象的这个方法 *this->LastResultMessage)) { return 1; } } else { // Command function was not found for the class. vtksys_ios::ostringstream error; const char* cname = obj? obj->GetClassName():"(vtk object is NULL)";
error << "Wrapper function not found for class \"" << cname << "\"." << ends; *this->LastResultMessage << vtkClientServerStream::Error << error.str().c_str() << vtkClientServerStream::End; } } else { *this->LastResultMessage << vtkClientServerStream::Error << "Invalid arguments to vtkClientServerStream::Invoke. " "There must be at least two arguments. The first must be an object " "and the second a string." << vtkClientServerStream::End; } return 0; }
我们来看这个函数:
this->CallCommandFunction(obj->GetClassName(), obj, method, msg,//执行这个对象的这个方法 *this->LastResultMessage)
int vtkClientServerInterpreter::CallCommandFunction(const char* cname, vtkObjectBase* ptr, const char* method, const vtkClientServerStream& msg, vtkClientServerStream& result) { vtkClientServerInterpreterInternals::ClassToFunctionMapType::const_iterator f = this->Internal->ClassToFunctionMap.find(cname); if (f == this->Internal->ClassToFunctionMap.end()) { vtkErrorMacro("Cannot find command function for \"" << cname << "\"."); return 1; } const vtkClientServerInterpreterInternals::CommandFunction* n = f->second; vtkClientServerCommandFunction function = n->Function; void* ctx = n->Context ? n->Context->Context : 0; return function(this, ptr, method, msg, result, ctx); }这个看不明白,应该就是调用这个函数了。但是在vtkObject中并没有函数StillRender。这里有什么问题呢,我们看看VTKOBJECT(this)是什么。
这个this很显然是vtkSMRenderViewProxy这个对象。
相关文章推荐
- Paraview与VTK学习笔记(四)
- Paraview与VTK学习笔记(六)//representation篇
- Paraview与VTK学习笔记(五)
- Paraview和vtk的学习笔记(一)
- Paraview与vtk学习笔记(二)
- Paraview与VTK学习笔记(七)sources篇
- VTK学习笔记-2-TIFF图像数据的重切片
- VTK学习笔记1—VTK安装及源码编译(Winxp + VS2010 + CMake2.8.6 + VTK5.8)
- VTK学习笔记(1)
- VTK 学习笔记 - 天行健
- VTK学习笔记-1
- VTK学习笔记:可视化模型
- VTK学习笔记:使用VTK交互功能
- VTK学习笔记:数据集之非结构化网格集
- VTK学习笔记之图像处理
- VTK学习笔记:数据集和单元集合介绍
- VTK学习笔记之使用vtkMarchingCubes
- VTk学习笔记--vtkInteractorStyleRubberBand2D
- VTK学习笔记:数据集之结构化点集
- VTK学习笔记:数据集之多边形数据集