mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
470 lines
13 KiB
C++
470 lines
13 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: vtkSMSelectionLink.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 "vtkSMSelectionLink.h"
|
|
|
|
#include "vtkCollection.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkNew.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPVXMLElement.h"
|
|
#include "vtkSMMessage.h"
|
|
#include "vtkSMProxy.h"
|
|
#include "vtkSMProxyLocator.h"
|
|
#include "vtkSMProxyManager.h"
|
|
#include "vtkSMSessionProxyManager.h"
|
|
#include "vtkSMSourceProxy.h"
|
|
#include "vtkStdString.h"
|
|
#include "vtkWeakPointer.h"
|
|
|
|
#include <list>
|
|
|
|
vtkStandardNewMacro(vtkSMSelectionLink);
|
|
//-----------------------------------------------------------------------------
|
|
class vtkSMSelectionLinkObserver : public vtkCommand
|
|
{
|
|
public:
|
|
static vtkSMSelectionLinkObserver* New()
|
|
{
|
|
return new vtkSMSelectionLinkObserver;
|
|
}
|
|
vtkSMSelectionLinkObserver()
|
|
{
|
|
this->Link = 0;
|
|
this->InProgress = false;
|
|
}
|
|
~vtkSMSelectionLinkObserver()
|
|
{
|
|
this->Link = 0;
|
|
}
|
|
|
|
virtual void Execute(vtkObject *c, unsigned long event, void* port)
|
|
{
|
|
if (this->InProgress)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this->Link && !this->Link->GetEnabled())
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->InProgress = true;
|
|
vtkSMSourceProxy* caller = vtkSMSourceProxy::SafeDownCast(c);
|
|
if (this->Link && caller)
|
|
{
|
|
if (event == vtkCommand::SelectionChangedEvent)
|
|
{
|
|
this->Link->SelectionModified(caller, *((unsigned int *)port));
|
|
}
|
|
}
|
|
this->InProgress = false;
|
|
}
|
|
|
|
vtkSMSelectionLink* Link;
|
|
bool InProgress;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
class vtkSMSelectionLinkInternals
|
|
{
|
|
public:
|
|
struct LinkedSelection
|
|
{
|
|
public:
|
|
LinkedSelection(vtkSMProxy* proxy, int updateDir) :
|
|
Proxy(proxy), UpdateDirection(updateDir)
|
|
{
|
|
}
|
|
|
|
~LinkedSelection()
|
|
{
|
|
}
|
|
|
|
vtkWeakPointer<vtkSMSourceProxy> Proxy;
|
|
int UpdateDirection;
|
|
};
|
|
|
|
typedef std::list<LinkedSelection> LinkedSelectionType;
|
|
LinkedSelectionType LinkedSelections;
|
|
vtkSMSelectionLinkObserver* SelectionObserver;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkSMSelectionLink::vtkSMSelectionLink()
|
|
{
|
|
this->Internals = new vtkSMSelectionLinkInternals;
|
|
this->Internals->SelectionObserver = vtkSMSelectionLinkObserver::New();
|
|
this->Internals->SelectionObserver->Link = this;
|
|
this->ModifyingSelection = false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkSMSelectionLink::~vtkSMSelectionLink()
|
|
{
|
|
vtkSMSelectionLinkInternals::LinkedSelectionType::iterator iter =
|
|
this->Internals->LinkedSelections.begin();
|
|
for (; iter != this->Internals->LinkedSelections.end(); ++iter)
|
|
{
|
|
if (iter->Proxy.GetPointer() != NULL)
|
|
{
|
|
if (iter->UpdateDirection & INPUT)
|
|
{
|
|
iter->Proxy->RemoveObserver(this->Internals->SelectionObserver);
|
|
}
|
|
if (iter->UpdateDirection & OUTPUT)
|
|
{
|
|
for (unsigned int i = 0;
|
|
i< iter->Proxy->GetNumberOfAlgorithmOutputPorts(); i++)
|
|
{
|
|
this->Internals->SelectionObserver->InProgress = true;
|
|
iter->Proxy->CleanSelectionInputs(i);
|
|
this->Internals->SelectionObserver->InProgress = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this->Internals->SelectionObserver->Delete();
|
|
delete this->Internals;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkSMSelectionLink::AddLinkedSelection(vtkSMProxy* proxy, int updateDir)
|
|
{
|
|
vtkSMSourceProxy* sourceProxy = vtkSMSourceProxy::SafeDownCast(proxy);
|
|
if (sourceProxy != NULL)
|
|
{
|
|
int addToList = 1;
|
|
int addObserver = updateDir & INPUT;
|
|
|
|
vtkSMSelectionLinkInternals::LinkedSelectionType::iterator iter =
|
|
this->Internals->LinkedSelections.begin();
|
|
for (; iter != this->Internals->LinkedSelections.end(); ++iter)
|
|
{
|
|
if (iter->Proxy.GetPointer() == sourceProxy &&
|
|
iter->UpdateDirection == updateDir)
|
|
{
|
|
addObserver = 0;
|
|
addToList = 0;
|
|
}
|
|
}
|
|
|
|
if (addToList)
|
|
{
|
|
this->Internals->LinkedSelections.push_back(
|
|
vtkSMSelectionLinkInternals::LinkedSelection(sourceProxy, updateDir));
|
|
}
|
|
|
|
if (addObserver)
|
|
{
|
|
sourceProxy->AddObserver(vtkCommand::SelectionChangedEvent,
|
|
this->Internals->SelectionObserver);
|
|
|
|
for (unsigned int i = 0;
|
|
i< sourceProxy->GetNumberOfAlgorithmOutputPorts(); i++)
|
|
{
|
|
if (sourceProxy->GetSelectionInput(i) != NULL)
|
|
{
|
|
this->Internals->SelectionObserver->InProgress = true;
|
|
this->SelectionModified(sourceProxy, i);
|
|
this->Internals->SelectionObserver->InProgress = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->Modified();
|
|
|
|
// Update state and push it to share
|
|
this->UpdateState();
|
|
this->PushStateToSession();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkSMSelectionLink::RemoveAllLinks()
|
|
{
|
|
this->Internals->LinkedSelections.clear();
|
|
this->State->ClearExtension(LinkState::link);
|
|
this->Modified();
|
|
|
|
// Update state and push it to share
|
|
this->UpdateState();
|
|
this->PushStateToSession();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkSMSelectionLink::RemoveLinkedSelection(vtkSMProxy* proxy)
|
|
{
|
|
vtkSMSelectionLinkInternals::LinkedSelectionType::iterator iter =
|
|
this->Internals->LinkedSelections.begin();
|
|
for (; iter != this->Internals->LinkedSelections.end();)
|
|
{
|
|
if (iter->Proxy.Get() == proxy)
|
|
{
|
|
iter = this->Internals->LinkedSelections.erase(iter);
|
|
this->Modified();
|
|
|
|
// Update state and push it to share
|
|
this->UpdateState();
|
|
this->PushStateToSession();
|
|
}
|
|
else
|
|
{
|
|
++iter;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
unsigned int vtkSMSelectionLink::GetNumberOfLinkedObjects()
|
|
{
|
|
return static_cast<unsigned int>(this->Internals->LinkedSelections.size());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkSMProxy* vtkSMSelectionLink::GetLinkedProxy(int index)
|
|
{
|
|
vtkSMSelectionLinkInternals::LinkedSelectionType::iterator iter =
|
|
this->Internals->LinkedSelections.begin();
|
|
for (int i = 0;
|
|
i<index && iter != this->Internals->LinkedSelections.end();
|
|
i++)
|
|
{
|
|
iter++;
|
|
}
|
|
if (iter == this->Internals->LinkedSelections.end())
|
|
{
|
|
return NULL;
|
|
}
|
|
return iter->Proxy;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int vtkSMSelectionLink::GetLinkedObjectDirection(int index)
|
|
{
|
|
vtkSMSelectionLinkInternals::LinkedSelectionType::iterator iter =
|
|
this->Internals->LinkedSelections.begin();
|
|
for (int i = 0;
|
|
i<index && iter != this->Internals->LinkedSelections.end();
|
|
i++)
|
|
{
|
|
iter++;
|
|
}
|
|
if (iter == this->Internals->LinkedSelections.end())
|
|
{
|
|
return NONE;
|
|
}
|
|
return iter->UpdateDirection;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkSMSelectionLink::SaveXMLState(const char* linkname, vtkPVXMLElement* parent)
|
|
{
|
|
vtkPVXMLElement* root = vtkPVXMLElement::New();
|
|
root->SetName("SelectionLink");
|
|
root->AddAttribute("name", linkname);
|
|
vtkSMSelectionLinkInternals::LinkedSelectionType::iterator iter =
|
|
this->Internals->LinkedSelections.begin();
|
|
for (; iter != this->Internals->LinkedSelections.end(); ++iter)
|
|
{
|
|
vtkPVXMLElement* child = vtkPVXMLElement::New();
|
|
child->SetName("Selection");
|
|
child->AddAttribute("id",
|
|
static_cast<unsigned int>(iter->Proxy.GetPointer()->GetGlobalID()));
|
|
child->AddAttribute("direction", ((iter->UpdateDirection & INPUT)?
|
|
"input" : "output"));
|
|
root->AddNestedElement(child);
|
|
child->Delete();
|
|
}
|
|
parent->AddNestedElement(root);
|
|
root->Delete();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int vtkSMSelectionLink::LoadXMLState(vtkPVXMLElement* linkElement,
|
|
vtkSMProxyLocator* locator)
|
|
{
|
|
unsigned int numElems = linkElement->GetNumberOfNestedElements();
|
|
for (unsigned int cc = 0; cc < numElems; cc++)
|
|
{
|
|
vtkPVXMLElement* child = linkElement->GetNestedElement(cc);
|
|
if (!child->GetName() || strcmp(child->GetName(), "Selection") != 0)
|
|
{
|
|
vtkWarningMacro("Invalid element in link state. Ignoring.");
|
|
continue;
|
|
}
|
|
const char* direction = child->GetAttribute("direction");
|
|
if (!direction)
|
|
{
|
|
vtkErrorMacro("State missing required attribute direction.");
|
|
return 0;
|
|
}
|
|
int idirection;
|
|
if (strcmp(direction, "input") == 0)
|
|
{
|
|
idirection = INPUT;
|
|
}
|
|
else if (strcmp(direction, "output") == 0)
|
|
{
|
|
idirection = OUTPUT;
|
|
}
|
|
else
|
|
{
|
|
vtkErrorMacro("Invalid value for direction: " << direction);
|
|
return 0;
|
|
}
|
|
int id;
|
|
if (!child->GetScalarAttribute("id", &id))
|
|
{
|
|
vtkErrorMacro("State missing required attribute id.");
|
|
return 0;
|
|
}
|
|
vtkSMProxy* proxy = locator->LocateProxy(id);
|
|
if (!proxy)
|
|
{
|
|
vtkErrorMacro("Failed to locate proxy with ID: " << id);
|
|
return 0;
|
|
}
|
|
|
|
this->AddLinkedSelection(proxy, idirection);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkSMSelectionLink::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkSMSelectionLink::LoadState(const vtkSMMessage *msg,
|
|
vtkSMProxyLocator *locator)
|
|
{
|
|
this->Superclass::LoadState(msg, locator);
|
|
|
|
// Reset old state
|
|
this->Internals->LinkedSelections.clear();
|
|
|
|
// Load Selection Links
|
|
int numberOfLinks = msg->ExtensionSize(LinkState::link);
|
|
for(int i=0; i < numberOfLinks; i++)
|
|
{
|
|
const LinkState_LinkDescription* link = &msg->GetExtension(LinkState::link, i);
|
|
vtkSMProxy* proxy = locator->LocateProxy(link->proxy());
|
|
|
|
if(proxy)
|
|
{
|
|
switch(link->direction())
|
|
{
|
|
case LinkState_LinkDescription::NONE:
|
|
this->AddLinkedSelection(proxy, vtkSMLink::NONE);
|
|
break;
|
|
case LinkState_LinkDescription::INPUT:
|
|
this->AddLinkedSelection(proxy, vtkSMLink::INPUT);
|
|
break;
|
|
case LinkState_LinkDescription::OUTPUT:
|
|
this->AddLinkedSelection(proxy, vtkSMLink::OUTPUT);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkDebugMacro("Proxy not found with ID: " << link->proxy());
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkSMSelectionLink::UpdateState()
|
|
{
|
|
if(this->Session == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->State->ClearExtension(LinkState::link);
|
|
|
|
vtkSMSelectionLinkInternals::LinkedSelectionType::iterator iter =
|
|
this->Internals->LinkedSelections.begin();
|
|
for(; iter != this->Internals->LinkedSelections.end(); ++iter)
|
|
{
|
|
if (!iter->Proxy.GetPointer())
|
|
{
|
|
continue;
|
|
}
|
|
LinkState_LinkDescription* link = this->State->AddExtension(LinkState::link);
|
|
link->set_proxy(iter->Proxy.GetPointer()->GetGlobalID());
|
|
switch(iter->UpdateDirection)
|
|
{
|
|
case vtkSMLink::NONE:
|
|
link->set_direction(LinkState_LinkDescription::NONE);
|
|
break;
|
|
case vtkSMLink::INPUT:
|
|
link->set_direction(LinkState_LinkDescription::INPUT);
|
|
break;
|
|
case vtkSMLink::OUTPUT:
|
|
link->set_direction(LinkState_LinkDescription::OUTPUT);
|
|
break;
|
|
default:
|
|
vtkErrorMacro("Invalid Link direction");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkSMSelectionLink::SelectionModified(vtkSMSourceProxy* caller,
|
|
unsigned int portIndex)
|
|
{
|
|
vtkSMSourceProxy* selectionInput = NULL;
|
|
bool callerFound = false;
|
|
vtkSMSelectionLinkInternals::LinkedSelectionType::iterator iter;
|
|
for (iter = this->Internals->LinkedSelections.begin();
|
|
iter != this->Internals->LinkedSelections.end(); iter++)
|
|
{
|
|
if (caller == iter->Proxy.Get())
|
|
{
|
|
if (iter->UpdateDirection & INPUT)
|
|
{
|
|
selectionInput = caller->GetSelectionInput(portIndex);
|
|
callerFound = true;
|
|
}
|
|
}
|
|
}
|
|
if (selectionInput != NULL)
|
|
{
|
|
for (iter = this->Internals->LinkedSelections.begin();
|
|
iter != this->Internals->LinkedSelections.end(); iter++)
|
|
{
|
|
if (iter->UpdateDirection & OUTPUT && iter->Proxy != caller)
|
|
{
|
|
iter->Proxy->SetSelectionInput(portIndex, selectionInput, 0);
|
|
}
|
|
}
|
|
}
|
|
else if (callerFound)
|
|
{
|
|
for (iter = this->Internals->LinkedSelections.begin();
|
|
iter != this->Internals->LinkedSelections.end(); iter++)
|
|
{
|
|
if (iter->UpdateDirection & OUTPUT && iter->Proxy != caller)
|
|
{
|
|
iter->Proxy->CleanSelectionInputs(portIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|