Commit 8bd735ba authored by Robert Maynard's avatar Robert Maynard

Introducing smtk::mesh::PointSet.

We now have very basic interface to get the physical coordinates of meshes.
Next we need an efficient interface to extract that information.
parent 9408b80f
# set up sources to build
set(meshSrcs
# Cells.cxx
CellSet.cxx
CellTypes.cxx
Collection.cxx
Manager.cxx
# Mesh.cxx
MeshSet.cxx
PointConnectivity.cxx
# Points.cxx
# PointSet.cxx
PointSet.cxx
TypeSet.cxx
moab/Allocator.cxx
moab/CellTypeToType.cxx
......@@ -20,7 +17,6 @@ set(meshSrcs
)
set(meshHeaders
# Cells.h
CellSet.h
CellTraits.h
CellTypes.h
......@@ -29,11 +25,9 @@ set(meshHeaders
Handle.h
Interface.h
Manager.h
# Mesh.h
MeshSet.h
PointConnectivity.h
# Points.h
# PointSet.h
PointSet.h
QueryTypes.h
TypeSet.h
......
......@@ -96,17 +96,22 @@ smtk::mesh::TypeSet CellSet::types() const
//----------------------------------------------------------------------------
smtk::mesh::Points CellSet::points( ) const
smtk::mesh::PointSet CellSet::points( ) const
{
//need to pass the range and parents I expect
return smtk::mesh::Points();
const smtk::mesh::InterfacePtr& iface = this->m_parent->interface();
smtk::mesh::HandleRange range = iface->getPoints( this->m_range );
return smtk::mesh::PointSet(this->m_parent, range );
}
//----------------------------------------------------------------------------
smtk::mesh::Points CellSet::points( std::size_t ) const
smtk::mesh::PointSet CellSet::points( std::size_t position ) const
{
//need to pass the range and parents I expect
return smtk::mesh::Points();
smtk::mesh::HandleRange singleIndex;
singleIndex.insert(this->m_range[position]);
const smtk::mesh::InterfacePtr& iface = this->m_parent->interface();
smtk::mesh::HandleRange range = iface->getPoints( singleIndex );
return smtk::mesh::PointSet(this->m_parent, range );
}
//----------------------------------------------------------------------------
......
......@@ -14,10 +14,11 @@
#include "smtk/CoreExports.h"
#include "smtk/PublicPointerDefs.h"
#include "smtk/mesh/PointConnectivity.h"
#include "smtk/mesh/DimensionTypes.h"
#include "smtk/mesh/Handle.h"
#include "smtk/mesh/PointConnectivity.h"
#include "smtk/mesh/PointSet.h"
#include "smtk/mesh/QueryTypes.h"
#include "smtk/mesh/DimensionTypes.h"
#include "smtk/mesh/TypeSet.h"
namespace smtk {
......@@ -67,11 +68,11 @@ public:
std::size_t size() const;
smtk::mesh::TypeSet types() const;
smtk::mesh::Points points() const; //all points of the cellset
smtk::mesh::PointSet points() const; //all points of the cellset
smtk::mesh::PointConnectivity pointConnectivity( ) const; //all connectivity info for all cells
//get the points for a single cell
smtk::mesh::Points points( std::size_t ) const;
smtk::mesh::PointSet points( std::size_t ) const;
//get the connectivity for a single cell
smtk::mesh::PointConnectivity pointConnectivity( std::size_t ) const;
......
......@@ -191,9 +191,11 @@ smtk::mesh::CellSet Collection::cells( )
}
//----------------------------------------------------------------------------
smtk::mesh::Points Collection::points( )
smtk::mesh::PointSet Collection::points( )
{
return smtk::mesh::Points( );
smtk::mesh::MeshSet ms(this->shared_from_this(),
this->m_internals->mesh_root_handle());
return ms.points( );
}
//----------------------------------------------------------------------------
......
......@@ -77,7 +77,7 @@ public:
smtk::mesh::TypeSet types() const;
smtk::mesh::MeshSet meshes( ); //all meshes
smtk::mesh::CellSet cells( ); //all cells
smtk::mesh::Points points( ); //all points
smtk::mesh::PointSet points( ); //all points
//todo:
//find all cells of a given dimension that are attached to ?
......
......@@ -163,6 +163,10 @@ public:
virtual smtk::mesh::HandleRange getCells(const smtk::mesh::HandleRange& meshsets,
smtk::mesh::DimensionType dim) const = 0;
//----------------------------------------------------------------------------
//get all points held by this range of handle of a given dimension
virtual smtk::mesh::HandleRange getPoints(const smtk::mesh::HandleRange& cells) const = 0;
//----------------------------------------------------------------------------
virtual std::vector< std::string > computeNames(const smtk::mesh::HandleRange& meshsets) const = 0;
......
......@@ -195,9 +195,12 @@ smtk::mesh::CellSet MeshSet::cells( ) const
}
//----------------------------------------------------------------------------
smtk::mesh::Points MeshSet::points( ) const
smtk::mesh::PointSet MeshSet::points( ) const
{
return smtk::mesh::Points();
const smtk::mesh::InterfacePtr& iface = this->m_parent->interface();
smtk::mesh::HandleRange cells = iface->getCells( this->m_range );
smtk::mesh::HandleRange range = iface->getPoints( cells );
return smtk::mesh::PointSet(this->m_parent, range);
}
//----------------------------------------------------------------------------
......
......@@ -16,6 +16,7 @@
#include "smtk/mesh/CellSet.h"
#include "smtk/mesh/Handle.h"
#include "smtk/mesh/PointSet.h"
#include "smtk/mesh/QueryTypes.h"
#include "smtk/mesh/TypeSet.h"
......@@ -84,7 +85,7 @@ public:
smtk::mesh::TypeSet types() const;
smtk::mesh::CellSet cells() const; //all cells of the meshset
smtk::mesh::Points points() const; //all points of the meshset
smtk::mesh::PointSet points() const; //all points of the meshset
smtk::mesh::PointConnectivity pointConnectivity( ) const; //all point connectivity info for all cells
//we should be able to extract the points or cells of the meshes.
......
//=========================================================================
// 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/mesh/PointSet.h"
#include "smtk/mesh/Collection.h"
#include "smtk/mesh/Interface.h"
namespace smtk {
namespace mesh {
//----------------------------------------------------------------------------
PointSet::PointSet(const smtk::mesh::CollectionPtr& parent,
const smtk::mesh::HandleRange& points):
m_parent(parent),
m_points(points)
{
}
//----------------------------------------------------------------------------
PointSet::PointSet(const smtk::mesh::PointSet& other):
m_parent(other.m_parent),
m_points(other.m_points)
{
}
//----------------------------------------------------------------------------
PointSet::~PointSet()
{
}
//----------------------------------------------------------------------------
PointSet& PointSet::operator=(const PointSet& other)
{
this->m_parent = other.m_parent;
this->m_points = other.m_points;
return *this;
}
//----------------------------------------------------------------------------
bool PointSet::operator==(const PointSet& other) const
{
return this->m_parent == other.m_parent && this->m_points == other.m_points;
}
//----------------------------------------------------------------------------
bool PointSet::operator!=(const PointSet& other) const
{
return !(*this == other);
}
//----------------------------------------------------------------------------
bool PointSet::is_empty( ) const
{
return this->m_points.empty();
}
//----------------------------------------------------------------------------
std::size_t PointSet::size( ) const
{
return this->m_points.size();
}
//----------------------------------------------------------------------------
std::size_t PointSet::numberOfPointSet( ) const
{
return this->m_points.size();
}
//----------------------------------------------------------------------------
bool PointSet::contains( const smtk::mesh::Handle& pointId ) const
{
return this->m_points.find( pointId ) != this->m_points.end();
}
//----------------------------------------------------------------------------
std::size_t PointSet::find( const smtk::mesh::Handle& pointId ) const
{
//yes index() method returns an int
int index = this->m_points.index(pointId);
if (index >= 0 )
{
return static_cast< std::size_t > (index);
}
return this->m_points.size();
}
// //----------------------------------------------------------------------------
// void PointSet::get(std::size_t index, double& x, double& y, double& z) const
// {
// }
// //----------------------------------------------------------------------------
// void PointSet::get(std::size_t startIndex, std::size_t endIndex, std::vector<double>& xyz) const
// {
// }
// //----------------------------------------------------------------------------
// void PointSet::get(std::size_t startIndex, std::size_t endIndex, const double* xyz) const
// {
// }
// //----------------------------------------------------------------------------
// void PointSet::set(std::size_t index, double& x, double& y, double& z)
// {
// }
// //----------------------------------------------------------------------------
// void PointSet::set(std::size_t startIndex, std::size_t endIndex, const std::vector<double>& xyz)
// {
// }
// //----------------------------------------------------------------------------
// void PointSet::set(std::size_t startIndex, std::size_t endIndex, const double* const xyz)
// {
// }
// //Floats are not how we store the coordinates internally, so asking for
// //the coordinates in such a manner could cause data inaccuracies to appear
// //so generally this is only used if you fully understand the input domain
// //----------------------------------------------------------------------------
// void PointSet::getAsFloats(std::size_t startIndex, std::size_t endIndex, std::vector<float>& xyz) const
// {
// }
// //----------------------------------------------------------------------------
// void PointSet::getAsFloats(std::size_t startIndex, std::size_t endIndex, const float* xyz) const
// {
// }
// //----------------------------------------------------------------------------
// void PointSet::setFromFloats(std::size_t startIndex, std::size_t endIndex, const std::vector<float>& xyz)
// {
// }
// //----------------------------------------------------------------------------
// void PointSet::setFromFloats(std::size_t startIndex, std::size_t endIndex, const float* const xyz)
// {
// }
//----------------------------------------------------------------------------
PointSet set_intersect( const PointSet& a, const PointSet& b )
{
if( a.m_parent != b.m_parent )
{ //return an empty PointSet if the collections don't match
return smtk::mesh::PointSet(a.m_parent,
smtk::mesh::HandleRange());
}
const smtk::mesh::InterfacePtr& iface = a.m_parent->interface();
smtk::mesh::HandleRange result = iface->rangeIntersect(a.m_points, b.m_points);
return smtk::mesh::PointSet(a.m_parent, result);
}
//----------------------------------------------------------------------------
PointSet set_difference( const PointSet& a, const PointSet& b )
{
if( a.m_parent != b.m_parent )
{ //return an empty PointSet if the collections don't match
return smtk::mesh::PointSet(a.m_parent,
smtk::mesh::HandleRange());
}
const smtk::mesh::InterfacePtr& iface = a.m_parent->interface();
smtk::mesh::HandleRange result = iface->rangeDifference(a.m_points, b.m_points);
return smtk::mesh::PointSet(a.m_parent, result);
}
//----------------------------------------------------------------------------
PointSet set_union( const PointSet& a, const PointSet& b )
{
if( a.m_parent != b.m_parent )
{ //return an empty PointSet if the collections don't match
return smtk::mesh::PointSet(a.m_parent, smtk::mesh::HandleRange());
}
const smtk::mesh::InterfacePtr& iface = a.m_parent->interface();
smtk::mesh::HandleRange result = iface->rangeUnion(a.m_points, b.m_points);
return smtk::mesh::PointSet(a.m_parent, result);
}
//----------------------------------------------------------------------------
void for_each( const PointSet& a, PointForEach& filter )
{
const smtk::mesh::InterfacePtr& iface = a.m_parent->interface();
filter.m_collection=a.m_parent;
iface->pointForEach(a.m_points, filter);
}
}
}
//=========================================================================
// 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_mesh_PointSet_h
#define __smtk_mesh_PointSet_h
#include "smtk/CoreExports.h"
#include "smtk/PublicPointerDefs.h"
#include "smtk/mesh/Handle.h"
#include "smtk/mesh/QueryTypes.h"
namespace smtk {
namespace mesh {
class SMTKCORE_EXPORT PointSet
{
friend PointSet set_intersect( const PointSet& a, const PointSet& b);
friend PointSet set_difference( const PointSet& a, const PointSet& b);
friend PointSet set_union( const PointSet& a, const PointSet& b );
friend void for_each( const PointSet& a, PointForEach& filter);
public:
PointSet(const smtk::mesh::CollectionPtr& parent,
const smtk::mesh::HandleRange& points);
//Copy Constructor required for rule of 3
PointSet(const PointSet& other);
//required to be in the cpp file as we hold a HandleRange
~PointSet();
//Copy assignment operator required for rule of 3
PointSet& operator= (const PointSet& other);
bool operator==( const PointSet& other ) const;
bool operator!=( const PointSet& other ) const;
bool is_empty() const;
std::size_t size() const;
//Get the number of points in the array
std::size_t numberOfPointSet() const;
//returns true if the point set contains a given point id
bool contains( const smtk::mesh::Handle& pointId ) const;
//returns the index in this point set for the given point id
std::size_t find( const smtk::mesh::Handle& pointId ) const;
// //Get/Set a point coordinate. This interface is offered for when
// //you need
// void get(std::size_t index, double& x, double& y, double& z) const;
// void get(std::size_t startIndex, std::size_t endIndex, std::vector<double>& xyz) const;
// void get(std::size_t startIndex, std::size_t endIndex, const double* xyz) const;
// void set(std::size_t index, double& x, double& y, double& z);
// void set(std::size_t startIndex, std::size_t endIndex, const std::vector<double>& xyz);
// void set(std::size_t startIndex, std::size_t endIndex, const double* const xyz);
// //Floats are not how we store the coordinates internally, so asking for
// //the coordinates in such a manner could cause data inaccuracies to appear
// //so generally this is only used if you fully understand the input domain
// void getAsFloats(std::size_t startIndex, std::size_t endIndex, std::vector<float>& xyz);
// void getAsFloats(std::size_t startIndex, std::size_t endIndex, const float* xyz);
// void setFromFloats(std::size_t startIndex, std::size_t endIndex, const std::vector<float>& xyz);
// void setFromFloats(std::size_t startIndex, std::size_t endIndex, const float* const xyz);
private:
smtk::mesh::CollectionPtr m_parent;
smtk::mesh::HandleRange m_points;
};
//intersect two set of points, placing the results in the return points object.
//This uses a point id based comparison, so points that have duplicate
//coordinates but different id's are considered to not intersect
//Note: If the points come from different collections the result will
//always be empty
SMTKCORE_EXPORT PointSet set_intersect( const PointSet& a, const PointSet& b);
//subtract points b from a, placing the results in the return points object.
//This uses a point id based comparison, so points that have duplicate
//coordinates but different id's are considered to not intersect
//Note: If the points come from different collections the result will
//always be empty
SMTKCORE_EXPORT PointSet set_difference( const PointSet& a, const PointSet& b);
//union two set of points, placing the results in the return points object.
//This uses a point id based comparison, so points that have duplicate
//coordinates but different id's are considered to not intersect
//Note: If the points come from different collections the result will
//always be empty
SMTKCORE_EXPORT PointSet set_union( const PointSet& a, const PointSet& b );
//apply a for_each point operator on each point in a container.
SMTKCORE_EXPORT void for_each( const PointSet& a, PointForEach& filter);
}
}
#endif
\ No newline at end of file
......@@ -25,8 +25,6 @@
namespace smtk {
namespace mesh {
typedef int Points;
//forward declare of CellSet and MeshSet
class CellSet;
class MeshSet;
......
......@@ -537,6 +537,16 @@ smtk::mesh::HandleRange Interface::getCells(const smtk::mesh::HandleRange& meshs
return entitiesCells;
}
//----------------------------------------------------------------------------
//get all cells held by this range handle of a given dimension
smtk::mesh::HandleRange Interface::getPoints(const smtk::mesh::HandleRange& cells) const
{
smtk::mesh::HandleRange pointIds;
m_iface->get_connectivity(cells, pointIds);
return pointIds;
}
//----------------------------------------------------------------------------
std::vector< std::string > Interface::computeNames(const smtk::mesh::HandleRange& meshsets) const
{
......@@ -921,24 +931,60 @@ smtk::mesh::HandleRange Interface::pointDifference(const smtk::mesh::HandleRange
}
//----------------------------------------------------------------------------
void Interface::pointForEach(const smtk::mesh::HandleRange &points,
smtk::mesh::MeshForEach& filter) const
void Interface::pointForEach(const HandleRange &points,
smtk::mesh::PointForEach& filter) const
{
if(!points.empty())
{
//fetch a collection of points
std::vector<double> coords;
coords.reserve(3);
typedef smtk::mesh::HandleRange::const_iterator cit;
for(cit i = points.begin(); i!= points.end(); ++i)
//determine the number of points. Break that into manageable chunks, we dont
//want to allocate an array for hundreds of millions of points, instead
//we would want to fetch a subset of points at a time.
const std::size_t numPoints = points.size();
const std::size_t numPointsPerLoop =524288;
const std::size_t numLoops = numPoints / 524288;
coords.reserve(numPointsPerLoop*3);
smtk::mesh::HandleRange::const_iterator start = points.begin();
for(std::size_t i=0; i < numLoops; ++i)
{
//grab the coordinates for a single point
smtk::mesh::HandleRange singlHandle(*i,*i);
m_iface->get_coords(singlHandle, &coords[0]);
//determine where the end iterator should be
smtk::mesh::HandleRange::const_iterator end = start + numPointsPerLoop;
//call the custom filter
filter(*i,&coords[0]);
//needs to be insert so we use iterator insert, since we don't want
//all points between start and end values, but only those that are
//in the range. Think not 0 to N, but 0 - 10, 14 - N.
::moab::Range subset;
subset.insert(start,end);
//fetch all the coordinates for the start, end range
m_iface->get_coords( subset, &coords[0] );
//call the filter for each point
for(std::size_t offset = 0; start != end; offset+=3, ++start)
{
filter( *start, &coords[offset] );
}
}
std::size_t difference = numPoints - (numPointsPerLoop * numLoops);
smtk::mesh::HandleRange::const_iterator end = start + difference;
::moab::Range subset;
subset.insert(start,end);
//fetch all the coordinates for the start, end range
m_iface->get_coords( subset, &coords[0] );
//call the filter for each point
for(std::size_t offset = 0; start != end; offset+=3, ++start)
{
filter( *start, &coords[offset] );
}
}
return;
......
......@@ -132,6 +132,10 @@ public:
smtk::mesh::HandleRange getCells(const smtk::mesh::HandleRange& meshsets,
smtk::mesh::DimensionType dim) const;
//----------------------------------------------------------------------------
//get all points held by this range of handle of a given dimension
virtual smtk::mesh::HandleRange getPoints(const smtk::mesh::HandleRange& cells) const;
//----------------------------------------------------------------------------
std::vector< std::string > computeNames(const smtk::mesh::HandleRange& meshsets) const;
......@@ -208,7 +212,7 @@ public:
smtk::mesh::PointForEach& filter) const;
//----------------------------------------------------------------------------
void cellForEach( smtk::mesh::PointConnectivity& a,
void cellForEach( smtk::mesh::PointConnectivity& pc,
smtk::mesh::CellForEach& filter) const;
//----------------------------------------------------------------------------
......
......@@ -25,6 +25,7 @@ set(unit_tests_which_require_data
UnitTestCreateMesh.cxx
UnitTestLoadMesh.cxx
UnitTestPointConnectivity.cxx
UnitTestPointSet.cxx
UnitTestMeshSet.cxx
UnitTestRemoveMeshes.cxx
UnitTestTypeSetFromData.cxx
......
//=========================================================================
// 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/mesh/Collection.h"
#include "smtk/mesh/Manager.h"
#include "smtk/io/ImportMesh.h"
#include "smtk/mesh/testing/cxx/helpers.h"
namespace
{
//SMTK_DATA_DIR is a define setup by cmake
std::string data_root = SMTK_DATA_DIR;
//----------------------------------------------------------------------------
smtk::mesh::CollectionPtr load_mesh(smtk::mesh::ManagerPtr mngr)
{
std::string file_path(data_root);
file_path += "/mesh/twoassm_out.h5m";
smtk::mesh::CollectionPtr c = smtk::io::ImportMesh::entireFile(file_path, mngr);
test( c->isValid(), "collection should be valid");
return c;
}
//----------------------------------------------------------------------------
void verify_constructors(const smtk::mesh::CollectionPtr& c)
{
std::vector< std::string > mesh_names = c->meshNames();
smtk::mesh::MeshSet ms = c->meshes( mesh_names[0] );
smtk::mesh::PointSet ps = ms.points();
smtk::mesh::PointSet ps2(ps);
smtk::mesh::PointSet ps3 = c->meshes( "bad_name" ).points();
test( ps3.is_empty() == true );
test( ps3.size() == 0 );
test( ps.size() == ps2.size());
test( ps.size() != ps3.size());
ps3 = ps; //test assignment operator
test( ps.size() == ps3.size());
test( ps.is_empty() == false );
test( ps2.is_empty() == false );
test( ps3.is_empty() == false );
}
//----------------------------------------------------------------------------
void verify_comparisons(const smtk::mesh::CollectionPtr& c)
{
std::vector< std::string > mesh_names = c->meshNames();
smtk::mesh::PointSet one = c->meshes( mesh_names[0] ).points();
smtk::mesh::PointSet two = c->meshes( mesh_names[1] ).points();
test(one == one);
test( !(one != one) );
test(two != one);
test( !(two == one) );
smtk::mesh::PointSet one_a(one);
test(one_a == one);
smtk::mesh::PointSet two_b = one_a;
two_b = two; //test assignment operator
test(two_b == two);
test(one_a != two_b);
}
//----------------------------------------------------------------------------
void verify_contains(const smtk::mesh::CollectionPtr& c)
{
//need to verify that point_set contains actually works
//I think we should grab the point connectivity from a cell set and
//verify that each point id in the point connectivity returns true
smtk::mesh::CellSet hexs = c->cells( smtk::mesh::Hexahedron );
smtk::mesh::PointSet hexPoints = hexs.points();
smtk::mesh::PointConnectivity hexConn = hexs.pointConnectivity();
smtk::mesh::CellType cellType;
int size=0;
const smtk::mesh::Handle* points;
for(hexConn.initCellTraversal();
hexConn.fetchNextCell(cellType, size, points);)
{
for(int i=0; i < size; ++i)
{
const bool contains = hexPoints.contains(points[i]);
test( contains );
}
}
}
//----------------------------------------------------------------------------
void verify_find(const smtk::mesh::CollectionPtr& c)
{
//need to verify that point_set contains actually works
//I think we should grab the point connectivity from a cell set and
//verify that each point id find return a value between 0 and (size()-1)
smtk::mesh::CellSet hexs = c->cells( smtk::mesh::Hexahedron );
smtk::mesh::PointSet hexPoints = hexs.points();
smtk::mesh::PointConnectivity hexConn = hexs.pointConnectivity();