您的位置:首页 > 其它

Paraview与VTK学习笔记(三)

2015-03-22 10:50 127 查看
下面接着上一面继续,上面那个函数最后调用了

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这个对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: