message: Incoporates klee geometric operators into shaping query
diff: @@ -21,6 +21,61 @@ namespace axom
  {
  namespace quest
  {
  +namespace internal
  +{
  +/*!
  + * \brief Implementation of a GeometryOperatorVisitor for processing klee shape operators
  + *
  + * This class extracts the matrix form of supported operators and marks the operator as unvalid otherwise
  + * To use, check the \a isValid() function after visiting and then call the \a getMatrix() function.
  + */
  +class AffineMatrixVisitor : public klee::GeometryOperatorVisitor
  +{
  +public:
  + AffineMatrixVisitor() : m_matrix(4, 4) { }
  +
  + void visit(const klee::Translation& translation) override
  + {
  + m_matrix = translation.toMatrix();
  + m_isValid = true;
  + }
  + void visit(const klee::Rotation& rotation) override
  + {
  + m_matrix = rotation.toMatrix();
  + m_isValid = true;
  + }
  + void visit(const klee::Scale& scale) override
  + {
  + m_matrix = scale.toMatrix();
  + m_isValid = true;
  + }
  + void visit(const klee::UnitConverter& converter) override
  + {
  + m_matrix = converter.toMatrix();
  + m_isValid = true;
  + }
  +
  + void visit(const klee::CompositeOperator&) override
  + {
  + SLIC_WARNING("CompositeOperator not supported for Shaper query");
  + m_isValid = false;
  + }
  + void visit(const klee::SliceOperator&) override
  + {
  + SLIC_WARNING("SliceOperator not yet supported for Shaper query");
  + m_isValid = false;
  + }
  +
  + const numerics::Matrix<double>& getMatrix() const { return m_matrix; }
  + bool isValid() const { return m_isValid; }
  +
  +private:
  + bool m_isValid {false};
  + numerics::Matrix<double> m_matrix;
  +};
  +
  +} // end namespace internal
  +
  Shaper::Shaper(const klee::ShapeSet& shapeSet, sidre::MFEMSidreDataCollection* dc)
  : m_shapeSet(shapeSet)
  , m_dc(dc)
  @@ -97,8 +152,47 @@ void Shaper::loadShape(const klee::Shape& shape)
  void Shaper::applyTransforms(const klee::Shape& shape)
  {
  - // TODO: Implement this as a set of affine transforms to vertices of mesh
  - AXOM_UNUSED_VAR(shape);
  + auto& geometryOperator = shape.getGeometry().getGeometryOperator();
  + auto composite =
  + std::dynamic_pointer_cast<const klee::CompositeOperator>(geometryOperator);
  + if(composite)
  + {
  + // Get surface mesh coordinates
  + const int spaceDim = m_surfaceMesh->getDimension();
  + const int numSurfaceVertices = m_surfaceMesh->getNumberOfNodes();
  + double* x = m_surfaceMesh->getCoordinateArray(mint::X_COORDINATE);
  + double* y = m_surfaceMesh->getCoordinateArray(mint::Y_COORDINATE);
  + double* z = spaceDim > 2
  + ? m_surfaceMesh->getCoordinateArray(mint::Z_COORDINATE)
  + : nullptr;
  +
  + // Loop through operators and apply transformations to vertices
  + for(auto op : composite->getOperators())
  + {
  + // Use visitor pattern to extract the affine matrix from supported operators
  + internal::AffineMatrixVisitor visitor;
  + op->accept(visitor);
  + if(!visitor.isValid())
  + {
  + continue;
  + }
  + const auto& matrix = visitor.getMatrix();
  +
  + // Apply transformation to coordinates of each vertex in mesh
  + double xformed[4];
  + for(int i = 0; i < numSurfaceVertices; ++i)
  + {
  + double coords[4] = {x[i], y[i], (z == nullptr ? 0. : z[i]), 1.};
  + numerics::matrix_vector_multiply(matrix, coords, xformed);
  + x[i] = xformed[0];
  + y[i] = xformed[1];
  + if(z != nullptr)
  + {
  + z[i] = xformed[2];
  + }
  + }
  + }
  + }
  }
  // ----------------------------------------------------------------------------
  