Commit d4874963 authored by T.J. Corona's avatar T.J. Corona Committed by Kitware Robot
Browse files

Merge topic 'mesh-displace-implicit'

8b8bbe2a

 Add functional input for mesh elevation; add testing.
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: David Thompson's avatarDavid Thompson <david.thompson@kitware.com>
Merge-request: !547
parents c5bb6818 8b8bbe2a
......@@ -91,7 +91,7 @@ namespace
{
smtk::mesh::PointLocator& m_locator;
std::vector<T>& m_zValues;
//represents the value to convert pointId's into m_zValues offsets
//represents the value to convert pointIds into m_zValues offsets
std::size_t m_pointIdOffset;
double m_radius;
bool m_useInvalid;
......@@ -268,8 +268,10 @@ public:
{
if (!extremaFound[0])
{
double x_ = m_data.m_origin[0] + i*m_data.m_spacing[0];
double y_ = m_data.m_origin[1] + jmin*m_data.m_spacing[1];
double x_ = m_data.m_origin[0] +
(i - m_data.m_extent[0])*m_data.m_spacing[0];
double y_ = m_data.m_origin[1] +
(jmin - m_data.m_extent[2])*m_data.m_spacing[1];
if (xStart <= x_ && x_ <= xEnd && yStart <= y_ && y_ <= yEnd)
{
......@@ -288,8 +290,10 @@ public:
if (!extremaFound[1])
{
double x_ = m_data.m_origin[0] + i*m_data.m_spacing[0];
double y_ = m_data.m_origin[1] + jmax*m_data.m_spacing[1];
double x_ = m_data.m_origin[0] +
(i - m_data.m_extent[0])*m_data.m_spacing[0];
double y_ = m_data.m_origin[1] +
(jmin - m_data.m_extent[2])*m_data.m_spacing[1];
if (xStart <= x_ && x_ <= xEnd && yStart <= y_ && y_ <= yEnd)
{
......@@ -383,6 +387,28 @@ public:
}
};
class ElevatePointForFunctionalInput : public smtk::mesh::PointForEach
{
const std::function<double(double,double)> m_data;
public:
ElevatePointForFunctionalInput(
const std::function<double(double,double)> data) : m_data(data) {}
void forPoints(const smtk::mesh::HandleRange& pointIds,
std::vector<double>& xyz,
bool& coordinatesModified)
{
typedef smtk::mesh::HandleRange::const_iterator c_it;
std::size_t offset = 0;
for(c_it i = pointIds.begin(); i != pointIds.end(); ++i, offset+=3)
{
xyz[offset+2] = m_data(xyz[offset], xyz[offset+1]);
}
coordinatesModified = true; //mark we are going to modify the points
}
};
namespace smtk {
namespace mesh {
......@@ -476,6 +502,47 @@ bool elevate( const smtk::mesh::ElevationStructuredData& data,
return elevate(data, ms.points(), radius, controls);
}
bool elevate( const std::function<double(double,double)>& data,
const smtk::mesh::PointSet& ps,
ElevationControls controls )
{
std::function<double(double,double)> clampedData;
if (controls.m_clampMin && controls.m_clampMax)
{
clamper<true,true,double> clamp;
clampedData = [=, &data](double x,double y)
{ return clamp(data(x,y), controls.m_minElev, controls.m_maxElev); };
}
else if (controls.m_clampMin)
{
clamper<true,false,double> clamp;
clampedData = [=, &data](double x,double y)
{ return clamp(data(x,y), controls.m_minElev, controls.m_maxElev); };
}
else if (controls.m_clampMax)
{
clamper<false,true,double> clamp;
clampedData = [=, &data](double x,double y)
{ return clamp(data(x,y), controls.m_minElev, controls.m_maxElev); };
}
else
{
clampedData = data;
}
ElevatePointForFunctionalInput functor(clampedData);
smtk::mesh::for_each(ps, functor);
return true;
}
bool elevate( const std::function<double(double,double)>& data,
const smtk::mesh::MeshSet& ms,
ElevationControls controls )
{
return elevate(data, ms.points(), controls);
}
namespace
{
class DisplacePoint : public smtk::mesh::PointForEach
......
......@@ -16,6 +16,8 @@
#include "smtk/mesh/MeshSet.h"
#include <functional>
namespace smtk {
namespace mesh {
......@@ -130,6 +132,16 @@ namespace smtk {
double radius,
ElevationControls controls = ElevationControls() );
SMTKCORE_EXPORT
bool elevate( const std::function<double(double,double)>& data,
const smtk::mesh::MeshSet& ms,
ElevationControls controls = ElevationControls() );
SMTKCORE_EXPORT
bool elevate( const std::function<double(double,double)>& data,
const smtk::mesh::PointSet& ps,
ElevationControls controls = ElevationControls() );
#endif
//displace a set of points, given a point cloud. Doesn't flatten like
......
......@@ -18,6 +18,7 @@
#include "smtk/mesh/testing/cxx/helpers.h"
#include <cmath>
#include <fstream>
#include <sstream>
......@@ -85,7 +86,7 @@ void verify_empty_elevate()
}
template<typename T>
void verify_elevate_self()
void verify_elevate_pointcloud()
{
smtk::mesh::ManagerPtr meshManager = smtk::mesh::Manager::create();
smtk::model::ManagerPtr modelManager = smtk::model::Manager::create();
......@@ -131,6 +132,112 @@ void verify_elevate_self()
}
}
//phony structured data with 300 x 300 data points, origin at (-15,15) and a
//spacing of (.1,-.1). The actual values returned are the sum of the x and y
//coordinates. For fun, we omit the data point at every 7th x coordinate and
//every 13th y coordinate.
class TestElevationStructuredData : public smtk::mesh::ElevationStructuredData
{
public:
TestElevationStructuredData()
{
m_extent[0] = m_extent[2] = -150;
m_extent[1] = m_extent[3] = 150;
m_origin[0] = -15.;
m_origin[1] = 15.;
m_spacing[0] = .1;
m_spacing[1] = -.1;
}
std::pair<double,double> coords(int ix, int iy) const
{
return std::make_pair(m_origin[0] + ix*m_spacing[0],
m_origin[1] + iy*m_spacing[1]);
}
double operator()(int ix, int iy) const
{
auto c = coords(ix, iy);
return c.first + c.second;
}
bool containsIndex(int ix, int iy) const
{
return (ix % 7 == 1 && iy % 13 == 1 ? false : true);
}
};
void verify_elevate_structuredgrid()
{
smtk::mesh::ManagerPtr meshManager = smtk::mesh::Manager::create();
smtk::model::ManagerPtr modelManager = smtk::model::Manager::create();
create_simple_mesh_model(modelManager);
smtk::io::ModelToMesh convert;
smtk::mesh::CollectionPtr collection = convert(meshManager,modelManager);
test( collection->isValid(), "collection should be valid");
smtk::mesh::MeshSet meshes = collection->meshes();
smtk::mesh::PointSet points = meshes.points();
{
TestElevationStructuredData testElevationStructuredData;
smtk::mesh::elevate(testElevationStructuredData, meshes, 2.0);
//verify that the elevate filter doesn't add any new points
//to the collection
test( collection->points().size() == points.size() );
} //verify the elevate can safely leave scope
//confirm all the points have the right z value
//point averaging over a grid does not yield a great resolution, so our
//epsilon is pretty high
static const double EPSILON = 1.e-2;
std::vector<double> pts;
points.get(pts);
for(std::size_t i=0; i < pts.size(); i+=3)
{
const double correct_z = pts[i] + pts[i+1];
test( std::abs(pts[i+2] - correct_z) < EPSILON );
}
}
void verify_elevate_functional()
{
smtk::mesh::ManagerPtr meshManager = smtk::mesh::Manager::create();
smtk::model::ManagerPtr modelManager = smtk::model::Manager::create();
create_simple_mesh_model(modelManager);
smtk::io::ModelToMesh convert;
smtk::mesh::CollectionPtr collection = convert(meshManager,modelManager);
test( collection->isValid(), "collection should be valid");
smtk::mesh::MeshSet meshes = collection->meshes();
smtk::mesh::PointSet points = meshes.points();
{
std::function<double(double x,double y)> f =
[](double x, double y){ return x - y; };
smtk::mesh::elevate(f, meshes);
//verify that the elevate filter doesn't add any new points
//to the collection
test( collection->points().size() == points.size() );
} //verify the elevate can safely leave scope
//confirm all the points have the right z value
static const double EPSILON = 1.e-10;
std::vector<double> pts;
points.get(pts);
for(std::size_t i=0; i < pts.size(); i+=3)
{
const double correct_z = pts[i] - pts[i+1];
test( std::abs(pts[i+2] - correct_z) < EPSILON );
}
}
}
int UnitTestElevate(int, char** const)
......@@ -139,8 +246,10 @@ int UnitTestElevate(int, char** const)
std::cout << "UnitTestElevate" << std::endl;
verify_empty_elevate( );
verify_elevate_self<double>( );
verify_elevate_self<float>( );
verify_elevate_pointcloud<double>( );
verify_elevate_pointcloud<float>( );
verify_elevate_structuredgrid( );
verify_elevate_functional( );
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment