Paraview与vtk学习笔记(二)

上一节,我们讲到最后:不知道它是否属于,这里的xml_name为RenderView

rendering.__dict__[xmlName]
然而我在Paraview的源代码中找到这样一个类,它叫做vtkSMRenderViewProxy,它的父类为vtkSMViewProxy,这个类在ParaviewCore/Servermanager/Rendering/文件夹下。在它的父类中有这个方法StillRender()。它的代码如下

头文件中:

  // Renders the view using full resolution.
  virtual void StillRender();
可以看到这个方法是采用全分辨率渲染view

源文件中:

void vtkSMViewProxy::StillRender()
{
  // bug 0013947
  // on Mac OSX don't render into invalid drawable, all subsequent
  // OpenGL calls fail with invalid framebuffer operation.
  if (this->IsContextReadyForRendering() == false)//判断当前window是否可画
    {
    return;
    }

  int interactive = 0;
  this->InvokeEvent(vtkCommand::StartEvent, &interactive);
  this->GetSession()->PrepareProgress();
  // We call update separately from the render. This is done so that we don't//我们单独调用render的更新。这样做之后,我们不会得到GUI的任何同步的信息,这归咎
  // get any synchronization issues with GUI responding to the data-updated于数>//据更新事件,它是由一些数据信息请求而实现的。如果这些发生时,在服务器端正在
  // event by making some data information requests(for example). If those执行StillRender或者InteractiveRender,则将会造成死锁。
  // happen while StillRender/InteractiveRender is being executed on the server
  // side then we get deadlocks.
  this->Update();

  vtkTypeUInt32 render_location = this->PreRender(interactive==1);

  if (this->ObjectsCreated)
    {
    vtkClientServerStream stream;
    stream << vtkClientServerStream::Invoke
           << VTKOBJECT(this)
           << "StillRender"
           << vtkClientServerStream::End;
    this->ExecuteStream(stream, false, render_location);
    }

  this->PostRender(interactive==1);
  this->GetSession()->CleanupPendingProgress();
  this->InvokeEvent(vtkCommand::EndEvent, &interactive);
}
接下来执行this->Update,在vtkSMRenderViewProxy这个类中,它是这样的:

void vtkSMRenderViewProxy::Update()
{
  this->NeedsUpdateLOD |= this->NeedsUpdate;
  this->Superclass::Update();
}
在vtkSMViewProxy中为:

void vtkSMViewProxy::Update()
{
  if (this->ObjectsCreated && this->NeedsUpdate)
    {
    vtkClientServerStream stream;

    // To avoid race conditions in multi-client modes, we are taking a peculiar
    // approach. Any ivar that affect parallel communication are overridden任何影响并行传输交流的ivar都通过使用客户端在相同执行流的值重载了
    // using the client-side values in the same ExecuteStream() call. That
    // ensures that two clients cannot enter race condition. This results in minor保证两个clients不会进入竞争状态
    // increase in the size of the messages sent, but overall the benefits are
    // greater.
    vtkPVView* pvview = vtkPVView::SafeDownCast(this->GetClientSideObject());
    if (pvview)
      {
      int use_cache =  pvview->GetUseCache()? 1 : 0;
      stream << vtkClientServerStream::Invoke
             << VTKOBJECT(this)
             << "SetUseCache" << use_cache
             << vtkClientServerStream::End;
      }
    stream << vtkClientServerStream::Invoke
           << VTKOBJECT(this)
           << "Update"
           << vtkClientServerStream::End;
    this->GetSession()->PrepareProgress();
    this->ExecuteStream(stream);
    this->GetSession()->CleanupPendingProgress();

    unsigned int numProducers = this->GetNumberOfProducers();
    for (unsigned int i=0; iGetProducerProxy(i));
      if (repr)
        {
        repr->ViewUpdated(this);
        }
      else
        {
        //this->GetProducerProxy(i)->PostUpdateData();
        }
      }

    this->PostUpdateData();
    }
}
下面就是要搞清楚:
 if (this->ObjectsCreated)
    {
    vtkClientServerStream stream;
    stream << vtkClientServerStream::Invoke
           << VTKOBJECT(this)
           << "StillRender"
           << vtkClientServerStream::End;
    this->ExecuteStream(stream, false, render_location);
    }
这段代码啥意思,大致理解为把stream赋值成这个,通过以前的经验,感觉应该stream是把里面的内容当做字节流赋值进去,然后执行这段stream程序:

 this->ExecuteStream(stream, false, render_location);
vtkTypeUInt32 render_location = this->PreRender(interactive==1);render_location由这个函数赋值。
在子类vtkSMRenderViewProxy中,对PreRender这个方法进行了重载:

vtkTypeUInt32 vtkSMRenderViewProxy::PreRender(bool interactive)
{
  this->Superclass::PreRender(interactive);

  vtkPVRenderView* rv = vtkPVRenderView::SafeDownCast(
    this->GetClientSideObject());
  assert(rv != NULL);

  if (interactive && rv->GetUseLODForInteractiveRender())
    {
    // for interactive renders, we need to determine if we are going to use LOD.
    // If so, we may need to update the LOD geometries.
    this->UpdateLOD();
    }
  this->DeliveryManager->Deliver(interactive);
  return interactive? rv->GetInteractiveRenderProcesses():
    rv->GetStillRenderProcesses();
}
这里传过去的bool interactive明显为false。则返回的是

rv->GetStillRenderProcesses();这个函数在vtkPVRenderView中     vtkGetMacro(StillRenderProcesses, vtkTypeUInt32);获得这个类的一个变量StillRenderProcesses

显然是获得执行StillRender的进程。这个rv为vtkPVRenderView的类的一个实例,这个类是在/ParaviewCore/ClientServerCore/Rendering。可以推测,这个类是用于后台服务器端渲染的。所以这就从客户端转到了服务器端。

this->ExecuteStream(stream, false, render_location);
所以很显然,接下来在执行StillRender()的进程执行这段stream程序。我们来看ExecuteStream这个函数:这个函数是继承自vtkSMViewProxy的父类vtkSMProxy的。void vtkSMProxy::ExecuteStream(const vtkClientServerStream& stream,
  bool ignore_errors/*=false*/, vtkTypeUInt32 location/*=0*/)
{
  if (location == 0)
    {
    location = this->Location;
    }
  if (location == 0 || stream.GetNumberOfMessages() == 0)
    {
    return;
    }

  if (this->GetSession())
    {
    this->GetSession()->ExecuteStream(location, stream, ignore_errors);//可以看出它又调用了vtkPVSessionBase类下的ExecuteStream方法。
    }
  // if no session, nothing to do.
}
vtkPVSessionBase在/ParaviewCore/ServerImplementation/core下

void vtkPVSessionBase::ExecuteStream(//在所给的进程上执行该命令。当这个命令执行之后,使用GetLastResult()获得之后的结果。如果设置为true则,忽  vtkTypeUInt32 location, const vtkClientServerStream& stream//视任何打断进程的错误
{
  this->Activate();

  // This class does not handle remote sessions, so all messages are directly//这个类不控制远程sessions,所有的信息都直接本地执行
  // processes locally.
  this->SessionCore->ExecuteStream(location, stream, ignore_errors);//这个类可以看出又调用了下面的一个类vtkPVSessionCore的该方法

  this->DeActivate();
}
vtkPVSessionCore在/ParaviewCore/ServerImplementation/core下

void vtkPVSessionCore::ExecuteStream( vtkTypeUInt32 location,
                                      const vtkClientServerStream& stream,
                                      bool ignore_errors/*=false*/)
{
  if (stream.GetNumberOfMessages() == 0)
    {
    return;
    }

  // This can only be called on the root node.
  assert( this->ParallelController == NULL ||
          this->ParallelController->GetLocalProcessId() == 0 ||
          this->SymmetricMPIMode );

  if ( (location & vtkProcessModule::SERVERS) != 0 &&
       !this->SymmetricMPIMode)
    {
    // send message to satellites and then start processing.

    if ( this->ParallelController &&
         this->ParallelController->GetNumberOfProcesses() > 1 &&
         this->ParallelController->GetLocalProcessId() == 0 )//当前为头结点
      {
      // Forward the message to the satellites if the object is expected to exist//传输到其他卫星进程
      // on the satellites.
      size_t byte_size;
      const unsigned char *raw_data;
      stream.GetData(&raw_data, &byte_size);//获取数据

      // FIXME: There's one flaw in this logic. If a object is to be created on//这里有一个缺陷,如果一个对象是在DATA_SERVER_ROOT创建的,但是在所有      
	// DATA_SERVER_ROOT, but on all RENDER_SERVER nodes, then in render-serverRENDER_SERVER//节点上运行,在render-server配置,信息将也会结束为被传输     
// configuration, the message will end up being send to all data-server//到所有的数据服务器节点      // nodes as well. Although we never do that presently, it's a possibility
      // and we should fix this.
      unsigned char type = EXECUTE_STREAM;
      this->ParallelController->TriggerRMIOnAllChildren(&type, 1,//TriggerRMI在所有的子节点
        ROOT_SATELLITE_RMI_TAG);
      int size[2];
      size[0] = static_cast(byte_size);
      size[1] = (ignore_errors? 1 : 0);
      this->ParallelController->Broadcast(size, 2, 0);
      this->ParallelController->Broadcast(
        const_cast(raw_data), size[0], 0);
      }
    }

  this->ExecuteStreamInternal(stream, ignore_errors);
}

 


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