Skip to content

Add support for basic mesh types. #5

@robertmaynard

Description

@robertmaynard

Remus isn't the place to build, modify, or query a mesh, what it is designed to do is send a mesh to another process/computer/thread. Because of this the mesh class(es) in Remus can have a well defined structure that is easy for any library/program to copy into, or specify where the allocated data already is.

Now for an initial implementation of this I don't want to be super fancy and allow arbitrary mappings of any pre-existing, instead I want to use a very simple model of a mesh with the following rules:

  • A mesh can only have a single collection of points
  • Points can be either 2 or 3 dimensional
  • Points can be either float or doubles
  • The layout of the point coordinates are in a linear array with the following order: x1,y1,z1,x2,y2,z2,...
  • A mesh can have any number of Cell Collections
  • A Cell Collection can only contain a single cell type
  • We support the following cell types
    • vertex
    • line
    • triangle
    • tetrahedron
    • hexahedron
  • Cell Connection values can either be int32 or int64

So a simple schema for a mesh of triangles and lines could look like:

{
"points" : { "dims" : 3, "num_elements": "300", 
                 "data_type": "float", "data" : [ x1, y1, z1, x2, y2, z2, .... ] 
               }
"cells" : [
             { "cell_type" : "triangle", "num_cells": 400, 
                "data_type": "int32", "data" : [ a1, a2, a3, b1, b2, b3, c1, c2, c3, ...] 
             },
             { "cell_type" : "line",  "num_cells": 50,
               "data_type": "int32", "data" : [ a1, a2, b1, b2, c1, c2, ...] 
             }
             ]
}

This will allow us to be easily able to serialize and deserialize the data as a little endian encoded binary blob.

Now that we understand the schema of the mesh classes lets see how this
would look how we could write the interface with a couple simple C++ classes that can reference pre-existing allocated memory, or be easily copied into. Note that none of these classes show how to serialize to and from them, as those would be similar to how remus::proto::JobContent and remus::proto::JobRequirements.

namespace remus { namespace mesh {
class Points
{ 
public:
  enum DataType { FLOAT=4, DOUBLE=8 };
  enum Dimensionality { Dim2D, Dim3D };

  //Use existing memory, we don't deallocate passed in memory
  //Pointer must be valid as long as this class exists
  Points(double* existing_coordinates, std::size_t numPoints, Dimensionality dim);

  //Use existing memory, we don't deallocate passed in memory
  //Pointer must be valid as long as this class exists
  Points(float* existing_coordinates, std::size_t numPoints, Dimensionality dim);

  //Pass in arbitrary iterators and copy the data into memory that we will allocate.
  //Iterators must support std::iterator_traits, and have a value_type
  //of either float or double
  //Iterators only have to be valid for the initial construction of the object.  
  template<typename T>
  Points(T begin, T end, std::size_t numPoints, Dimensionality dim);

  //returns the current dimension of the points
  Dimensionality dims() const;

  //returns true if the type of the points is float
  bool isFloat() const;

  //returns true if the type of the points is double
  bool isDouble() const;

  //returns the data type of the points, note that the DataType enum value is also the sizeof of the datatype.
  DataType dataType();

  //returns the number of points 
  std::size_t numPoints() const;

  //returns a pointer initialized to the first element of the data
  const char* begin() const;

  //returns a pointer initialized to first element past the end of the data.
  const char* end() const;

private:
  class InternalImpl;
  boost::shared_ptr<InternalImpl> Implementation;
};

class Cells
{ 
public:
  enum DataType { Int32=4, Int64=8 };
  enum Types { Vertex,Line,Triangle,Tetrahedron,Hexahedron };

  //Use existing memory, we don't deallocate passed in memory
  //Pointer must be valid as long as this class exists
  Cells(std::int32_t* existing_cells, std::size_t numCells, Types type);

  //Use existing memory, we don't deallocate passed in memory
  //Pointer must be valid as long as this class exists
  Cells(std::int64_t* existing_cells, std::size_t numCells, Types type);

  //Pass in arbitrary iterators and copy the data into memory that we will allocate.
  //Iterators must support std::iterator_traits, and have a value_type
  //of either int32 or int64
  //Iterators only have to be valid for the initial construction of the object.  
  template<typename T>
  Cells(T begin, T end, std::size_t numCells, Types type); 

  //returns the cell type we are holding
  Types cellType() const;

  //returns true if the type is int32
  bool isInt32() const;

  //returns true if the type is int64
  bool isInt64() const;

  //returns the data type of the points, note that the DataType enum value is also the sizeof of the datatype.
  DataType dataType();

  //returns the number of cells 
  std::size_t numCells() const;

  //returns a pointer initialized to the first element of the data
  const char* begin() const;

  //returns a pointer initialized to first element past the end of the data.
  const char* end() const;
private:
  class InternalImpl;
  boost::shared_ptr<InternalImpl> Implementation;
};

class Mesh
{ 
  typedef  std::vector<Cells>::const_iterator const_iterator;
public:
  Mesh(Points p, Cells c):
    PointData(p),
    CellsCollection(1,c)
  {
  }

  Mesh(Points p, std::vector<Cells> c):
    PointData(p),
    CellsCollection(c)
  {
  }

  //returns a read only reference to the underlying points object.
  const Points& points( ) const;

  //returns the number of cells
  std::size_t numCellCollections() const;

  //total sum of cells in all the collections
  std::size_t totalNumCells() const;

  //return a read only reference of the cells at a given index inside the collection
  const Cells& cells( std::size_t index) const;

  //returns an iterator initialized to the first element of the cells collection
  const_iterator begin() const;

  //returns an iterator initialized to first element past the end of the cells collection.
  const_iterator end() const;
private:
  Points PointData;
  std::vector<Cells> CellsCollection;
};

} }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions