Paraview与VTK学习笔记(四)

上一节我们讲到最后我们要考虑VTKOBJECT(this)是什么意思,经过查找,我们发现。它是当这个stream在interpret(解释器)中时,让他调用vtkClassName::MethodName()。其中vtkClassName是其中的代理对象代表的的类的类名,方法就是后面这个方法。所以我们这里就是调用vtkPVRenderView这个类的

我们来解析之前那段代码:

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);
}
这段代码中,f是一个迭代器,从这个类到方法的map的方法中找到cname对应的方法f,然后n赋值为f的f的第二项,可以假设f是key,n是value,n是命令方法(是在解释器中的),然后根据它解析出它代表的方法执行。经过试验,这里的cname其实已经是vtkPVRenderView了,所以这里很好理解,根据类名找到对应的解释器,然后根据解释器找到对应的命令方法,再根据这个类对应的命令 方法,解析出在服务器上执行的命令方法,然后以命令方法的形式执行vtkPVRenderView下的StillRender方法。

所以下面我们来看:

void vtkPVRenderView::StillRender()//高分辨率的render
{
  vtkTimerLog::MarkStartEvent("Still Render");
  this->GetRenderWindow()->SetDesiredUpdateRate(0.002);
  this->Internals->PreRender(this->RenderView);
  this->Render(false, false);
  vtkTimerLog::MarkEndEvent("Still Render");
}
非常简单,就是设置里几个参数,然后执行Render:

void vtkPVRenderView::Render(bool interactive, bool skip_rendering)
{
  if (this->SynchronizedWindows->GetMode() !=
    vtkPVSynchronizedRenderWindows::CLIENT ||
    (!interactive && this->UseDistributedRenderingForStillRender) ||
    (interactive && this->UseDistributedRenderingForInteractiveRender))
    {
通过这段代码,我们可以看到Paraview渲染的三种模式,第一种是客户端直接渲染,第二种是采用分布式渲染的StillRender模式,第三种是采用分布式渲染的交互渲染模式。

不论哪种模式其实都要与客户端相配合,去完成update。

 // Although Selection do trigger a Render on the server side and in such
    // case we MUST NOT execute that collaboration synchronization
    if(!this->MakingSelection)
      {
      this->SynchronizeForCollaboration();
      }
    }
我们不需要做执行协作同步

 // BUG #13534. Reset the clip planes on every render. Since this does not
  // involve any communication, doing this on every render is not a big deal.
  this->ResetCameraClippingRange();
  bool in_tile_display_mode = this->InTileDisplayMode();
  bool in_cave_mode = this->SynchronizedWindows->GetIsInCave();
  if (in_cave_mode && !this->RemoteRenderingAvailable)
    {
    static bool warned_once = false;
    if (!warned_once)
      {
      vtkErrorMacro(
        "In Cave mode and Display cannot be opened on server-side! "
        "Ensure the environment is set correctly in the pvx file.");
      in_cave_mode = false;
      }
    }
重置每个render上的夹面,这不包括任何通讯,在每个render上做这个不是一个大问题。获得是否使用tile_display或者cave的模式,在cave模式下,如果不允许远程渲染,那么报错:检查是否在pvx文件中设置了环境参数。

// Use loss-less image compression for client-server for full-res renders.
  this->SynchronizedRenderers->SetLossLessCompression(!interactive);
  bool use_lod_rendering = interactive? this->GetUseLODForInteractiveRender() : false;
  if (use_lod_rendering)
    {
    this->RequestInformation->Set(USE_LOD(), 1);
    }

对客户端服务器的所有的render采用无损图像压缩的方式。这种方式是针对StillRender模式的。

// cout << "Using remote rendering: " << use_distributed_rendering << endl;

  // Decide if we are doing remote rendering or local rendering.
  bool use_distributed_rendering = interactive?
    this->GetUseDistributedRenderingForInteractiveRender():
    this->GetUseDistributedRenderingForStillRender();

  bool use_ordered_compositing = this->GetUseOrderedCompositing();
  if (use_ordered_compositing)
    {
    this->Internals->DeliveryManager->RedistributeDataForOrderedCompositing(
      use_lod_rendering);
    this->SynchronizedRenderers->SetKdTree(
      this->Internals->DeliveryManager->GetKdTree());
    }
  else
    {
    this->SynchronizedRenderers->SetKdTree(NULL);
    }
决定是采用远程渲染还是本地渲染。第一个参数是采用哪种分布式渲染模式,是StillRender还是InteractiveRender模式。

// enable render empty images if it was requested
  this->SynchronizedRenderers->SetRenderEmptyImages(this->GetRenderEmptyImages());
如果需要,使可以渲染空图片。

 // Render each representation with available geometry.
  // This is the pass where representations get an opportunity to get the
  // currently "available" represented data and try to render it.
  this->CallProcessViewRequest(vtkPVView::REQUEST_RENDER(),
    this->RequestInformation, this->ReplyInformationVector);
通过合适的几何形状渲染每一个representation。这是通过:representations获得机会去得到现在的“available”,这应该代表现在的数据是这个representation的。然后去渲染它。

// set the image reduction factor.
  this->SynchronizedRenderers->SetImageReductionFactor(
    (interactive?
     this->InteractiveRenderImageReductionFactor :
     this->StillRenderImageReductionFactor));

  this->UsedLODForLastRender = use_lod_rendering;

  if (skip_rendering)
    {
    // essential to restore state.
    return;
    }

设置图片折减系数。

 // When in tile-display mode, we are always doing shared rendering. However
  // when use_distributed_rendering we tell IceT that geometry is duplicated on
  // all processes.
  this->SynchronizedWindows->SetEnabled(
    use_distributed_rendering || in_tile_display_mode || in_cave_mode);
  this->SynchronizedRenderers->SetEnabled(
    use_distributed_rendering || in_tile_display_mode || in_cave_mode);
  this->SynchronizedRenderers->SetDataReplicatedOnAllProcesses(
    in_cave_mode ||
    (!use_distributed_rendering && in_tile_display_mode));

  if (this->ShowAnnotation)
    {
    std::ostringstream stream;
    stream
      << "Mode: " << (interactive? "interactive" : "still") << "\n"
      << "Level-of-detail: " << (use_lod_rendering? "yes" : "no") << "\n"
      << "Remote/parallel rendering (if applicable): " << (use_distributed_rendering? "yes" : "no") << "\n";
    this->Annotation->SetText(stream.str().c_str());
    }

当采用tile-display的的模式的时候,我们需要执行shared rendering(共享渲染)。但是当我们采用分布式渲染,我们需要告诉IceT,几何模型赋值到所有的进程中。但是我根据代码读到的应该是,一共三种模式:cave,tile_display,分布式渲染,当采用分布式渲染的时候,是不需要把数据复制到所有的进程的,采用tile_display反而是需要。

// When in batch mode, we are using the same render window for all views. That
  // makes it impossible for vtkPVSynchronizedRenderWindows to identify which
  // view is being rendered. We explicitly mark the view being rendered using
  // this HACK.
  this->SynchronizedWindows->BeginRender(this->GetIdentifier());

当是采用批量的模式,我们对于所有的views采用相同的render window。这样使得vtkPVSynchronizedRenderWindows可以判定那个view正在被渲染。我们明确的标记这个正在被渲染的view

  // Call Render() on local render window only if
  // 1: Local process is the driver OR
  // 2: RenderEventPropagation is Off and we are doing distributed rendering.
  // 3: In tile-display mode or cave-mode.
  // Note, ParaView no longer has RenderEventPropagation ON. It's set to off
  // always.
  if (
    (this->SynchronizedWindows->GetLocalProcessIsDriver() ||
     (!this->SynchronizedWindows->GetRenderEventPropagation() && use_distributed_rendering) ||
     in_tile_display_mode || in_cave_mode) &&
    vtkProcessModule::GetProcessType() != vtkProcessModule::PROCESS_DATA_SERVER)
    {
    this->GetRenderWindow()->Render();
    }

  if (!this->MakingSelection)
    {
    // If we are making selection, then it's a multi-step render process and we
    // need to leave the SynchronizedWindows/SynchronizedRenderers enabled for
    // that entire process.
    this->SynchronizedWindows->SetEnabled(false);
    this->SynchronizedRenderers->SetEnabled(false);
    }
}
只有当:

1.本地的进程是driver

2.我们是使用分布式渲染,但是我们不使用渲染事件传播

3.是tile-display模式或者cave模式

4.并且当前进程的类型不是dataserver

这三种情况时才调用本地的渲染窗口进行渲染。

注意,Paraview不再默认设置RenderEventPropagation为on,默认是off
如果我们做了决定,他是一个多步的渲染进程,我们需要给整个进程舍弃同步window和同步渲染














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