mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
ParaView-5.0.1: Added the source-tree to ThirdParty-dev and patched as described in the README file
Resolves bug-report http://bugs.openfoam.org/view.php?id=2098
This commit is contained in:
@ -0,0 +1,550 @@
|
||||
/*=========================================================================
|
||||
|
||||
Program: ParaView
|
||||
Module: vtkPythonView.cxx
|
||||
|
||||
Copyright (c) Kitware, Inc.
|
||||
All rights reserved.
|
||||
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notice for more information.
|
||||
|
||||
=========================================================================*/
|
||||
#include "vtkPython.h" // must be the first thing that's included
|
||||
#include "vtkPythonView.h"
|
||||
|
||||
#include "vtkObjectFactory.h"
|
||||
|
||||
#include "vtkDataObject.h"
|
||||
#include "vtkInformationRequestKey.h"
|
||||
#include "vtkPVSynchronizedRenderWindows.h"
|
||||
#include "vtkPythonInterpreter.h"
|
||||
#include "vtkSmartPyObject.h"
|
||||
#include "vtkPythonRepresentation.h"
|
||||
#include "vtkRenderer.h"
|
||||
#include "vtkRendererCollection.h"
|
||||
#include "vtkRenderWindow.h"
|
||||
#include "vtkTexture.h"
|
||||
#include "vtkTimerLog.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
class vtkPythonView::vtkInternals
|
||||
{
|
||||
PyObject* CustomLocals;
|
||||
public:
|
||||
vtkInternals() : CustomLocals(0) {}
|
||||
~vtkInternals()
|
||||
{
|
||||
this->CleanupObjects();
|
||||
}
|
||||
|
||||
PyObject* GetCustomLocalsPyObject()
|
||||
{
|
||||
if (this->CustomLocals)
|
||||
{
|
||||
return this->CustomLocals;
|
||||
}
|
||||
|
||||
// Make sure the python interpreter is initialized
|
||||
vtkPythonInterpreter::Initialize(1);
|
||||
|
||||
{
|
||||
vtkPythonScopeGilEnsurer gilEnsurer;
|
||||
const char* code = "__vtkPythonViewLocals={'__builtins__':__builtins__}\n";
|
||||
PyRun_SimpleString(const_cast<char *>(code));
|
||||
|
||||
PyObject* main_module = PyImport_AddModule((char*)"__main__");
|
||||
PyObject* global_dict = PyModule_GetDict(main_module);
|
||||
this->CustomLocals = PyDict_GetItemString(global_dict, "__vtkPythonViewLocals");
|
||||
if (!this->CustomLocals)
|
||||
{
|
||||
vtkGenericWarningMacro("Failed to locate the __vtkPythonViewLocals object.");
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(this->CustomLocals);
|
||||
|
||||
PyRun_SimpleString(const_cast<char*>("del __vtkPythonViewLocals"));
|
||||
}
|
||||
|
||||
return this->CustomLocals;
|
||||
}
|
||||
|
||||
void CleanupObjects()
|
||||
{
|
||||
Py_XDECREF(this->CustomLocals);
|
||||
this->CustomLocals = NULL;
|
||||
if (vtkPythonInterpreter::IsInitialized())
|
||||
{
|
||||
const char* code = "import gc; gc.collect()\n";
|
||||
vtkPythonInterpreter::RunSimpleString(code);
|
||||
}
|
||||
}
|
||||
|
||||
void ResetCustomLocals()
|
||||
{
|
||||
this->CleanupObjects();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
vtkStandardNewMacro(vtkPythonView);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkPythonView::vtkPythonView()
|
||||
{
|
||||
this->Internals = new vtkPythonView::vtkInternals();
|
||||
this->RenderTexture = vtkSmartPointer<vtkTexture>::New();
|
||||
this->Renderer = vtkSmartPointer<vtkRenderer>::New();
|
||||
this->Renderer->SetBackgroundTexture(this->RenderTexture);
|
||||
this->RenderWindow.TakeReference(this->SynchronizedWindows->NewRenderWindow());
|
||||
this->RenderWindow->AddRenderer(this->Renderer);
|
||||
this->Magnification = 1;
|
||||
this->ImageData = NULL;
|
||||
|
||||
this->Script = NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkPythonView::~vtkPythonView()
|
||||
{
|
||||
// Clean up memory
|
||||
delete this->Internals;
|
||||
this->SetScript(NULL);
|
||||
this->SetImageData(NULL);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkInformationKeyMacro(vtkPythonView, REQUEST_DELIVER_DATA_TO_CLIENT, Request);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::Update()
|
||||
{
|
||||
vtkTimerLog::MarkStartEvent("vtkPythonView::Update");
|
||||
|
||||
this->Internals->ResetCustomLocals();
|
||||
|
||||
if (this->Script && strlen(this->Script) > 0)
|
||||
{
|
||||
|
||||
this->CallProcessViewRequest(vtkPVView::REQUEST_UPDATE(),
|
||||
this->RequestInformation,
|
||||
this->ReplyInformationVector);
|
||||
|
||||
// Define the view in Python by creating a new instance of the
|
||||
// Python vtkPythonView class from the pointer to the C++
|
||||
// vtkPythonView instance.
|
||||
char addressOfThis[1024];
|
||||
sprintf(addressOfThis, "%p", this);
|
||||
char *address = addressOfThis;
|
||||
if ((addressOfThis[0] == '0') &&
|
||||
((addressOfThis[1] == 'x') || (addressOfThis[1] == 'X')))
|
||||
{
|
||||
address += 2;
|
||||
}
|
||||
|
||||
// Import necessary items from ParaView
|
||||
std::ostringstream importStream;
|
||||
importStream << "import paraview" << endl
|
||||
<< "from vtkPVClientServerCoreRenderingPython import vtkPythonView" << endl
|
||||
<< "pythonView = vtkPythonView('" << addressOfThis << " ')" << endl;
|
||||
this->RunSimpleStringWithCustomLocals(importStream.str().c_str());
|
||||
|
||||
// Evaluate the user-defined script. It should define two functions,
|
||||
// setup_data(view) and render(view, figure) that each take a
|
||||
// vtkPythonView (the render function also takes a matplotlib.figure
|
||||
// as the second argument). If these functions are not defined in
|
||||
// this script, they must be defined in the global Python
|
||||
// interpreter by some other means (e.g. a script executed by
|
||||
// pvpython).
|
||||
this->RunSimpleStringWithCustomLocals(this->Script);
|
||||
|
||||
// Update the data array settings. Do this only on servers where local data is available
|
||||
if (this->IsLocalDataAvailable())
|
||||
{
|
||||
std::ostringstream setupDataCommandStream;
|
||||
setupDataCommandStream
|
||||
<< "from paraview import python_view\n"
|
||||
<< "try:\n"
|
||||
<< " python_view.call_setup_data(setup_data, pythonView)\n"
|
||||
<< "except:\n"
|
||||
<< " pass\n";
|
||||
this->RunSimpleStringWithCustomLocals(setupDataCommandStream.str().c_str());
|
||||
}
|
||||
|
||||
this->CallProcessViewRequest(vtkPythonView::REQUEST_DELIVER_DATA_TO_CLIENT(),
|
||||
this->RequestInformation,
|
||||
this->ReplyInformationVector);
|
||||
}
|
||||
|
||||
vtkTimerLog::MarkEndEvent("vtkPythonView::Update");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkRenderer* vtkPythonView::GetRenderer()
|
||||
{
|
||||
return this->Renderer;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::SetRenderer(vtkRenderer* renderer)
|
||||
{
|
||||
vtkRendererCollection* rens = this->RenderWindow->GetRenderers();
|
||||
vtkCollectionSimpleIterator cookie;
|
||||
rens->InitTraversal(cookie);
|
||||
while(vtkRenderer *ren = rens->GetNextRenderer(cookie))
|
||||
{
|
||||
ren->SetRenderWindow(NULL);
|
||||
this->RenderWindow->RemoveRenderer(ren);
|
||||
}
|
||||
|
||||
this->RenderWindow->AddRenderer(renderer);
|
||||
this->Renderer = renderer;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkRenderWindow* vtkPythonView::GetRenderWindow()
|
||||
{
|
||||
return this->RenderWindow;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::SetRenderWindow(vtkRenderWindow * renWin)
|
||||
{
|
||||
if (!renWin)
|
||||
{
|
||||
vtkErrorMacro(<< "SetRenderWindow called with a null window pointer."
|
||||
<< " That can't be right.");
|
||||
return;
|
||||
}
|
||||
|
||||
// move renderers to new window
|
||||
vtkRendererCollection* rens = this->RenderWindow->GetRenderers();
|
||||
while(rens->GetNumberOfItems())
|
||||
{
|
||||
vtkRenderer* ren = rens->GetFirstRenderer();
|
||||
ren->SetRenderWindow(NULL);
|
||||
renWin->AddRenderer(ren);
|
||||
this->RenderWindow->RemoveRenderer(ren);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int vtkPythonView::GetNumberOfVisibleDataObjects()
|
||||
{
|
||||
int numberOfVisibleRepresentations = 0;
|
||||
int numberOfRepresentations = this->GetNumberOfRepresentations();
|
||||
for (int i = 0; i < numberOfRepresentations; ++i)
|
||||
{
|
||||
vtkPVDataRepresentation* representation =
|
||||
vtkPVDataRepresentation::SafeDownCast(this->GetRepresentation(i));
|
||||
if (representation && representation->GetVisibility())
|
||||
{
|
||||
numberOfVisibleRepresentations++;
|
||||
}
|
||||
}
|
||||
|
||||
return numberOfVisibleRepresentations;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkPythonRepresentation* vtkPythonView::GetVisibleRepresentation(int visibleObjectIndex)
|
||||
{
|
||||
if (visibleObjectIndex < 0 || visibleObjectIndex >= this->GetNumberOfVisibleDataObjects())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int numberOfVisibleRepresentations = 0;
|
||||
int numberOfRepresentations = this->GetNumberOfRepresentations();
|
||||
for (int i = 0; i < numberOfRepresentations; ++i)
|
||||
{
|
||||
vtkPythonRepresentation* representation =
|
||||
vtkPythonRepresentation::SafeDownCast(this->GetRepresentation(i));
|
||||
if (representation && representation->GetVisibility())
|
||||
{
|
||||
if (visibleObjectIndex == numberOfVisibleRepresentations)
|
||||
{
|
||||
return representation;
|
||||
}
|
||||
numberOfVisibleRepresentations++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkDataObject* vtkPythonView::GetVisibleDataObjectForSetup(int visibleObjectIndex)
|
||||
{
|
||||
vtkPythonRepresentation* representation =
|
||||
this->GetVisibleRepresentation(visibleObjectIndex);
|
||||
if (!representation)
|
||||
{
|
||||
vtkErrorMacro(<< "No visible representation at index " << visibleObjectIndex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return representation->GetLocalInput();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkDataObject* vtkPythonView::GetVisibleDataObjectForRendering(int visibleObjectIndex)
|
||||
{
|
||||
vtkPythonRepresentation* representation =
|
||||
this->GetVisibleRepresentation(visibleObjectIndex);
|
||||
if (!representation)
|
||||
{
|
||||
vtkErrorMacro(<< "No visible representation at index " << visibleObjectIndex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return representation->GetClientDataObject();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int vtkPythonView::GetNumberOfAttributeArrays(int visibleObjectIndex, int attributeType)
|
||||
{
|
||||
// Forward to the visible representation
|
||||
vtkPythonRepresentation* representation =
|
||||
this->GetVisibleRepresentation(visibleObjectIndex);
|
||||
if (!representation)
|
||||
{
|
||||
vtkErrorMacro(<< "No visible representation at index " << visibleObjectIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return representation->GetNumberOfAttributeArrays(attributeType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* vtkPythonView::GetAttributeArrayName(int visibleObjectIndex,
|
||||
int attributeType,
|
||||
int arrayIndex)
|
||||
{
|
||||
// Forward to the visible representation
|
||||
vtkPythonRepresentation* representation =
|
||||
this->GetVisibleRepresentation(visibleObjectIndex);
|
||||
if (!representation)
|
||||
{
|
||||
vtkErrorMacro(<< "No visible representation at index " << visibleObjectIndex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return representation->GetAttributeArrayName(attributeType, arrayIndex);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::SetAttributeArrayStatus(int visibleObjectIndex,
|
||||
int attributeType,
|
||||
const char* name,
|
||||
int status)
|
||||
{
|
||||
// Forward to the visible representation
|
||||
vtkPythonRepresentation* representation =
|
||||
this->GetVisibleRepresentation(visibleObjectIndex);
|
||||
if (!representation)
|
||||
{
|
||||
vtkErrorMacro(<< "No visible representation at index " << visibleObjectIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
representation->SetAttributeArrayStatus(attributeType, name, status);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int vtkPythonView::GetAttributeArrayStatus(int visibleObjectIndex,
|
||||
int attributeType,
|
||||
const char* name)
|
||||
{
|
||||
// Forward to the visible representation
|
||||
vtkPythonRepresentation* representation =
|
||||
this->GetVisibleRepresentation(visibleObjectIndex);
|
||||
if (!representation)
|
||||
{
|
||||
vtkErrorMacro(<< "No visible representation at index " << visibleObjectIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return representation->GetAttributeArrayStatus(attributeType, name);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::EnableAllAttributeArrays()
|
||||
{
|
||||
int numRepresentations = this->GetNumberOfRepresentations();
|
||||
for (int i = 0; i < numRepresentations; ++i)
|
||||
{
|
||||
vtkPythonRepresentation* representation =
|
||||
vtkPythonRepresentation::SafeDownCast(this->GetRepresentation(i));
|
||||
if (representation)
|
||||
{
|
||||
representation->EnableAllAttributeArrays();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::DisableAllAttributeArrays()
|
||||
{
|
||||
int numRepresentations = this->GetNumberOfRepresentations();
|
||||
for (int i = 0; i < numRepresentations; ++i)
|
||||
{
|
||||
vtkPythonRepresentation* representation =
|
||||
vtkPythonRepresentation::SafeDownCast(this->GetRepresentation(i));
|
||||
if (representation)
|
||||
{
|
||||
representation->DisableAllAttributeArrays();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::StillRender()
|
||||
{
|
||||
// Render only on the client
|
||||
if (this->SynchronizedWindows->GetLocalProcessIsDriver())
|
||||
{
|
||||
this->SetImageData(NULL);
|
||||
|
||||
// Now draw the image
|
||||
int width = this->Size[0] * this->Magnification;
|
||||
int height = this->Size[1] * this->Magnification;
|
||||
|
||||
std::ostringstream renderCommandStream;
|
||||
renderCommandStream
|
||||
<< "from paraview import python_view\n"
|
||||
<< "try:\n"
|
||||
<< " python_view.call_render(render, pythonView, " << width << ", " << height << ")\n"
|
||||
<< "except:\n"
|
||||
<< " pass\n";
|
||||
this->RunSimpleStringWithCustomLocals(renderCommandStream.str().c_str());
|
||||
|
||||
// this->ImageData should be set by the call_render() function
|
||||
// invoked above.
|
||||
if (this->ImageData)
|
||||
{
|
||||
this->RenderTexture->SetInputData(this->ImageData);
|
||||
this->Renderer->TexturedBackgroundOn();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Renderer->TexturedBackgroundOff();
|
||||
}
|
||||
this->RenderWindow->Render();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::InteractiveRender()
|
||||
{
|
||||
this->StillRender();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool vtkPythonView::IsLocalDataAvailable()
|
||||
{
|
||||
// Check with the representations to see if they have local
|
||||
// input.
|
||||
bool available = false;
|
||||
for (int i = 0; i < this->GetNumberOfRepresentations(); ++i)
|
||||
{
|
||||
vtkPythonRepresentation* representation =
|
||||
vtkPythonRepresentation::SafeDownCast(this->GetRepresentation(i));
|
||||
if (!representation)
|
||||
{
|
||||
vtkErrorMacro(<< "Should only have vtkPythonRepresentations");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (representation->GetLocalInput())
|
||||
{
|
||||
available = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return available;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int vtkPythonView::RunSimpleStringWithCustomLocals(const char* code)
|
||||
{
|
||||
// The embedded python interpreter cannot handle DOS line-endings, see
|
||||
// http://sourceforge.net/tracker/?group_id=5470&atid=105470&func=detail&aid=1167922
|
||||
std::string buffer = code ? code : "";
|
||||
buffer.erase(std::remove(buffer.begin(), buffer.end(), '\r'), buffer.end());
|
||||
|
||||
PyObject* context = this->Internals->GetCustomLocalsPyObject();
|
||||
|
||||
vtkPythonScopeGilEnsurer gilEnsurer;
|
||||
vtkSmartPyObject result(PyRun_String(const_cast<char*>(buffer.c_str()),
|
||||
Py_file_input, context, context));
|
||||
|
||||
if (result)
|
||||
{
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = NULL;
|
||||
if (Py_FlushLine())
|
||||
{
|
||||
PyErr_Clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkPythonView::PrintSelf(ostream& os, vtkIndent indent)
|
||||
{
|
||||
this->Superclass::PrintSelf(os, indent);
|
||||
|
||||
os << indent << "RenderTexture: ";
|
||||
if (this->RenderTexture)
|
||||
{
|
||||
os << endl;
|
||||
this->RenderTexture->PrintSelf(os, indent.GetNextIndent());
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "(none)" << endl;
|
||||
}
|
||||
os << indent << "Renderer: ";
|
||||
if (this->Renderer)
|
||||
{
|
||||
os << endl;
|
||||
this->Renderer->PrintSelf(os, indent.GetNextIndent());
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "(none)" << endl;
|
||||
}
|
||||
os << indent << "RenderWindow: ";
|
||||
if (this->RenderWindow)
|
||||
{
|
||||
os << endl;
|
||||
this->RenderWindow->PrintSelf(os, indent.GetNextIndent());
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "(none)" << endl;
|
||||
}
|
||||
os << indent << "Magnification: " << this->Magnification << endl;
|
||||
os << indent << "Script: \n" << this->Script << endl;
|
||||
os << indent << "ImageData: ";
|
||||
if (this->ImageData)
|
||||
{
|
||||
os << endl;
|
||||
this->ImageData->PrintSelf(os, indent.GetNextIndent());
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "(none)" << endl;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user