Commit 9bb3d76e authored by T.J. Corona's avatar T.J. Corona

Introduce query API for resources and components

parent cd6eac8c
## Changes to SMTK Resource
* queryOperation now returns a functor that takes in a const smtk::resource::Component& instead of a const smtk::resource::ConstComponentPtr&
* Resources now have Query functors. Queries are functors designed to incrementally augment the API of a Resource at runtime via registration.
......@@ -18,7 +18,7 @@ namespace smtk
{
namespace detail
{
/// If T is in Tuple, return std::tuple<T>. Otherwise, return std::tuple<>.
/// If T is not in Tuple, return std::tuple<T>. Otherwise, return std::tuple<>.
///
/// Examples:
/// ```
......@@ -49,6 +49,52 @@ struct tuple_if_unique<T, std::tuple<T, Ts...> >
using type = std::tuple<>;
};
/// If T is not a base of any types in Tuple, return std::tuple<T>. Otherwise,
/// return std::tuple<>.
template <typename T, typename Tuple>
struct tuple_if_not_base;
/// @see tuple_if_not_base
template <typename T>
struct tuple_if_not_base<T, std::tuple<> >
{
using type = std::tuple<T>;
};
/// @see tuple_if_not_base
template <typename T, typename U, typename... Ts>
struct tuple_if_not_base<T, std::tuple<U, Ts...> >
{
using type = typename std::conditional<std::is_base_of<T, U>::value, std::tuple<>,
typename tuple_if_not_base<T, std::tuple<Ts...> >::type>::type;
};
/// Given a tuple, starting with the first parameter and moving to the last,
/// remove the parameter from the tuple if it is a base of any of the parameters
/// to the right.
template <typename T, typename... Args>
struct remove_bases_from_tuple_lr;
template <>
struct remove_bases_from_tuple_lr<std::tuple<> >
{
using type = std::tuple<>;
};
template <typename T>
struct remove_bases_from_tuple_lr<std::tuple<T> >
{
using type = std::tuple<T>;
};
template <typename T, typename... Args>
struct remove_bases_from_tuple_lr<std::tuple<T, Args...> >
{
using type = decltype(std::tuple_cat(
std::declval<typename detail::tuple_if_not_base<T, std::tuple<Args...> >::type>(),
std::declval<typename remove_bases_from_tuple_lr<std::tuple<Args...> >::type>()));
};
/// If T is a tuple containing a single type, return the type it contians.
/// Otherwise, return T.
///
......@@ -99,6 +145,14 @@ struct flatten_tuple<std::tuple<T, Args...> >
std::declval<typename flatten_tuple<std::tuple<Args...> >::type>()));
};
/// @see my_flatten_tuple
template <typename... TupleArgs, typename... Args>
struct flatten_tuple<std::tuple<std::tuple<TupleArgs...>, Args...> >
{
using type = decltype(std::tuple_cat(std::declval<std::tuple<TupleArgs...> >(),
std::declval<typename flatten_tuple<std::tuple<Args...> >::type>()));
};
/// Takes a tuple of potentially duplicate types and returns a tuple with the
/// duplicate types removed.
///
......@@ -133,6 +187,38 @@ struct unique_tuple<std::tuple<T, Args...> >
std::declval<typename unique_tuple<std::tuple<Args...> >::type>()));
};
/// Takes a tuple and reverses its arguments.
///
/// Examples:
/// ```
/// reverse_tuple<std::tuple<bool, int, float>>::type == std::tuple<float, int, bool>
/// ```
template <typename T>
struct reverse_tuple;
template <typename T>
struct reverse_tuple<std::tuple<T> >
{
using type = std::tuple<T>;
};
template <typename T, typename... Args>
struct reverse_tuple<std::tuple<T, Args...> >
{
using type = decltype(
std::tuple_cat(std::declval<typename reverse_tuple<std::tuple<Args...> >::type>(),
std::declval<std::tuple<T> >()));
};
/// Takes a tuple and removes any types that are bases of any other types in the
/// tuple.
template <typename T>
struct remove_bases_from_tuple
{
using type = typename detail::remove_bases_from_tuple_lr<typename reverse_tuple<typename detail::
remove_bases_from_tuple_lr<typename reverse_tuple<T>::type>::type>::type>::type;
};
/// Takes a type and a tuple of types and returns a tuple with all of the
/// original types sans the input type.
///
......
......@@ -6,7 +6,6 @@ set(classes
Registrar
VTKSelectionResponderGroup
vtkPVModelSources
vtkSMSMTKResourceRepresentationProxy
vtkSMSMTKWrapperProxy
vtkSMTKResource
......
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt 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 "smtk/extension/paraview/server/vtkPVModelSources.h"
#include "smtk/extension/vtk/source/vtkModelAuxiliaryGeometry.h"
#include "smtk/extension/vtk/source/vtkModelMultiBlockSource.h"
#include "smtk/extension/vtk/source/vtkResourceMultiBlockSource.h"
#include "vtkCompositeDataIterator.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkObjectFactory.h"
vtkPVModelSources* vtkPVModelSources::s_instance = nullptr;
static bool s_assuredDestruction = false;
void vtkPVModelSources::destroySingleton()
{
if (vtkPVModelSources::s_instance)
{
vtkPVModelSources::s_instance->Delete();
vtkPVModelSources::s_instance = nullptr;
s_assuredDestruction = false;
}
}
vtkPVModelSources* vtkPVModelSources::New()
{
vtkObject* ret = vtkObjectFactory::CreateInstance("vtkPVModelSources", false);
vtkPVModelSources* result = static_cast<vtkPVModelSources*>(ret);
if (!result)
{
result = new vtkPVModelSources;
}
result->InitializeObjectBase();
if (vtkPVModelSources::s_instance)
{
vtkPVModelSources::s_instance->Delete();
vtkPVModelSources::s_instance = nullptr;
}
vtkPVModelSources::s_instance = result;
result->Register(nullptr);
if (!s_assuredDestruction)
{
atexit(&vtkPVModelSources::destroySingleton);
}
return result;
}
vtkPVModelSources* vtkPVModelSources::GetInstance()
{
return vtkPVModelSources::s_instance;
}
class vtkPVModelSources::Internal
{
public:
std::set<vtkSmartPointer<vtkModelMultiBlockSource> > m_modelSources;
std::set<vtkSmartPointer<vtkResourceMultiBlockSource> > m_meshSources;
};
vtkPVModelSources::vtkPVModelSources()
{
m_p = new vtkPVModelSources::Internal;
}
vtkPVModelSources::~vtkPVModelSources()
{
delete m_p;
}
void vtkPVModelSources::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
/*
bool vtkPVModelSources::AddSource(vtkModelMultiBlockSource* ms)
{
return m_p.m_modelSources.insert(ms).second;
}
bool vtkPVModelSources::AddSource(vtkResourceMultiBlockSource* ms)
{
return m_p.m_meshSources.insert(ms).second;
}
bool vtkPVModelSources::RemoveSource(vtkModelMultiBlockSource* ms)
{
return m_p.m_modelSources.erase(ms) > 0;
}
bool vtkPVModelSources::RemoveSource(vtkResourceMultiBlockSource* ms)
{
return m_p.m_meshSources.erase(ms) > 0;
}
bool vtkPVModelSources::RemoveAllSources()
{
bool anythingToErase = !m_p.m_modelSources.empty() || !m_p.m_meshSources.empty();
m_p.m_modelSources.clear();
m_p.m_meshSources.clear();
return anythingToErase;
}
std::pair<vtkModelMultiBlockSource*, vtkIdType> vtkPVModelSources::findModelEntity(
const smtk::model::EntityRef& ent)
{
std::map<smtk::common::UUID, vtkIdType> blockMap;
for (auto src : m_p.m_modelSources)
{
src->GetUUID2BlockIdMap(blockMap);
if (blockMap.find(ent.entity()) != blockMap.end())
{
return std::make_pair(src, blockMap->second);
}
}
return std::pair<vtkModelMultiBlockSource*, vtkIdType>(nullptr, -1);
}
std::pair<vtkResourceMultiBlockSource*, vtkIdType> vtkPVModelSources::findMeshSet(
const smtk::mesh::MeshSet& mesh)
{
std::map<smtk::mesh::MeshSet, vtkIdType> blockMap;
for (auto src : m_p.m_meshSources)
{
src->GetMeshSet2BlockIdMap(blockMap);
if (blockMap.find(mesh) != blockMap.end())
{
return std::make_pair(src, blockMap->second);
}
}
return std::pair<vtkResourceMultiBlockSource*, vtkIdType>(nullptr, -1);
}
*/
std::pair<vtkMultiBlockDataSetAlgorithm*, vtkIdType> vtkPVModelSources::findModelEntitySource(
const smtk::model::EntityRef& ent)
{
vtkMultiBlockDataSetAlgorithm* source = nullptr;
vtkIdType blockId = -1;
vtkModelMultiBlockSource::visitInstances(
[ent, &source, &blockId](vtkModelMultiBlockSource* inst) {
std::map<smtk::common::UUID, vtkIdType> blockMap;
inst->GetUUID2BlockIdMap(blockMap);
std::map<smtk::common::UUID, vtkIdType>::const_iterator bit;
if ((bit = blockMap.find(ent.entity())) != blockMap.end())
{
source = inst;
blockId = bit->second;
return true;
}
return false;
});
if (!source)
{
std::string uid(ent.entity().toString());
vtkModelAuxiliaryGeometry::visitInstances(
[uid, &source, &blockId](vtkModelAuxiliaryGeometry* inst) {
if (uid == inst->GetAuxiliaryEntityID())
{
source = inst;
blockId = 0;
return true;
}
return false;
});
}
return std::make_pair(source, blockId);
}
/*
std::pair<vtkResourceMultiBlockSource*, vtkIdType> vtkPVModelSources::findMeshSetSource(
const smtk::mesh::MeshSet& mesh)
{
vtkResourceMultiBlockSource* source = nullptr;
vtkIdType blockId = -1;
vtkResourceMultiBlockSource::visitInstances([mesh, &source, &blockId](vtkResourceMultiBlockSource* inst) {
std::map<smtk::common::UUID, vtkIdType> blockMap;
inst->GetUUID2BlockIdMap(blockMap);
std::map<smtk::common::UUID, vtkIdType>::const_iterator bit;
if ((bit = blockMap.find(mesh.id())) != blockMap.end())
{
source = inst;
blockId = bit->second;
return true;
}
return false;
});
return std::make_pair(source, blockId);
}
*/
vtkDataObject* vtkPVModelSources::findModelEntity(const smtk::model::EntityRef& ent)
{
std::pair<vtkMultiBlockDataSetAlgorithm*, vtkIdType> result =
vtkPVModelSources::findModelEntitySource(ent);
if (!result.first)
{
return nullptr;
}
vtkDataObject* res = result.first->GetOutputDataObject(0);
if (result.second < 0)
{
return res;
}
vtkCompositeDataSet* mbds = vtkCompositeDataSet::SafeDownCast(res);
if (!mbds)
{
return nullptr;
}
auto iter = mbds->NewIterator();
for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
if (iter->GetCurrentFlatIndex() == result.second)
{
res = iter->GetCurrentDataObject();
iter->Delete();
return res;
}
}
iter->Delete();
return nullptr;
}
/*
vtkDataObject* vtkPVModelSources::findMeshSet(const smtk::mesh::MeshSet& mesh)
{
std::pair<vtkResourceMultiBlockSource*, vtkIdType> result =
vtkPVModelSources::findMeshSetSource(mesh);
if (!result.first)
{
return nullptr;
}
vtkDataObject* res = result.first->GetOutputDataObject(0);
if (result.second < 0)
{
return res;
}
vtkCompositeDataSet* mbds = vtkCompositeDataSet::SafeDownCast(res);
if (!mbds)
{
return nullptr;
}
auto iter = mbds->NewIterator();
for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
if (iter->GetCurrentFlatIndex() == result.second)
{
res = iter->GetCurrentDataObject();
iter->Delete();
return res;
}
}
iter->Delete();
return nullptr;
}
*/
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt 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.
//=========================================================================
#ifndef smtk_extension_paraview_server_vtkPVModelSources_h
#define smtk_extension_paraview_server_vtkPVModelSources_h
#include "smtk/extension/paraview/server/smtkPVServerExtModule.h"
#include "smtk/mesh/core/MeshSet.h"
#include "smtk/model/EntityRef.h"
#include "vtkObject.h"
class vtkDataObject;
class vtkMultiBlockDataSetAlgorithm;
class vtkModelMultiBlockSource;
class vtkResourceMultiBlockSource;
/**\brief Track instances of vtk{Model,Mesh}MultiBlockSource on the Paraview server.
*
* This object, exposed to ParaView (PV) by the smconfig.xml file in this directory,
* is intended to be constructed as a singleton on the server and informed by
* your PV-based application whenever a vtk{Model,Mesh}MultiBlockSource instance is
* constructed or destroyed.
*
* Server-side extensions can then ask this singleton for the multiblock holding
* graphics primitives for any model or mesh entity by UUID, making it possible
* to use VTK filters for queries on renderable entities.
*/
class SMTKPVSERVEREXT_EXPORT vtkPVModelSources : public vtkObject
{
public:
static vtkPVModelSources* New();
void PrintSelf(ostream& os, vtkIndent indent) override;
vtkTypeMacro(vtkPVModelSources, vtkObject);
static vtkPVModelSources* GetInstance();
/*
virtual bool AddSource(vtkModelMultiBlockSource*);
virtual bool AddSource(vtkResourceMultiBlockSource*);
virtual bool RemoveSource(vtkModelMultiBlockSource*);
virtual bool RemoveSource(vtkResourceMultiBlockSource*);
virtual bool RemoveAllSources();
*/
static std::pair<vtkMultiBlockDataSetAlgorithm*, vtkIdType> findModelEntitySource(
const smtk::model::EntityRef&);
/*
static std::pair<vtkResourceMultiBlockSource*, vtkIdType> findMeshSetSource(
const smtk::mesh::MeshSet&);
*/
static vtkDataObject* findModelEntity(const smtk::model::EntityRef&);
/*
static vtkDataObject* findMeshSet(const smtk::mesh::MeshSet&);
*/
protected:
vtkPVModelSources();
virtual ~vtkPVModelSources();
class Internal;
Internal* m_p;
static void destroySingleton();
static vtkPVModelSources* s_instance;
};
#endif
......@@ -9,8 +9,6 @@
//=========================================================================
#include "smtk/extension/paraview/server/vtkSMTKResourceCreator.h"
#include "smtk/extension/vtk/source/vtkModelAuxiliaryGeometry.h"
#include "smtk/extension/paraview/server/vtkSMTKWrapper.h"
#include "smtk/attribute/Attribute.h"
......
......@@ -3,6 +3,7 @@ set(module_files
"${CMAKE_CURRENT_SOURCE_DIR}/geometry/vtk.module"
"${CMAKE_CURRENT_SOURCE_DIR}/mesh/vtk.module"
"${CMAKE_CURRENT_SOURCE_DIR}/meshing/vtk.module"
"${CMAKE_CURRENT_SOURCE_DIR}/model/vtk.module"
"${CMAKE_CURRENT_SOURCE_DIR}/operators/vtk.module"
"${CMAKE_CURRENT_SOURCE_DIR}/reader/vtk.module"
"${CMAKE_CURRENT_SOURCE_DIR}/source/vtk.module"
......
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt 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 "smtk/extension/vtk/geometry/BoundingBox.h"
#include "smtk/extension/vtk/geometry/Backend.h"
#include "smtk/extension/vtk/geometry/Geometry.h"
#include "smtk/geometry/Geometry.h"
#include "smtk/geometry/Resource.h"
#include <vtkDataSet.h>
namespace smtk
{
namespace extension
{
namespace vtk
{
namespace geometry
{
std::array<double, 6> BoundingBox::operator()(
const smtk::resource::PersistentObjectPtr& object) const
{
std::array<double, 6> returnValue{ { 1., 0., 1., 0., 1., 0. } };
smtk::geometry::Resource::Ptr resource =
std::dynamic_pointer_cast<smtk::geometry::Resource>(object);
if (!resource)
{
if (smtk::resource::Component::Ptr component =
std::dynamic_pointer_cast<smtk::resource::Component>(object))
{
resource = std::dynamic_pointer_cast<smtk::geometry::Resource>(component->resource());
}
}
if (!resource)
{
return returnValue;
}
smtk::extension::vtk::geometry::Backend vtk;
const auto& geometry = resource->geometry(vtk);
if (geometry)
{
vtkDataSet* data = nullptr;
try
{
const auto& vtkGeometry =
dynamic_cast<const smtk::extension::vtk::geometry::Geometry&>(*geometry);
data = vtkDataSet::SafeDownCast(vtkGeometry.data(object));
}
catch (std::bad_cast&)
{
return returnValue;
}
if (data)
{
data->GetBounds(returnValue.data());
}
}
return returnValue;
}
};
}
}
}
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt 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.
//=========================================================================
#ifndef smtk_extension_vtk_geometry_BoundingBox_h