Skip to content

basic guide for developers

copyme edited this page Apr 26, 2014 · 26 revisions

This guide shows few steps which you need to implement a curvature flow.

Right now we will focus on some building blocks and after that we will come back to implementation of flow.

Vertex get_vertex ( unsigned int index ) const;

This method will return instance of class Vertex which implement read only access to vertices. The main method of this class is range operator. More information you can find in mesh.h.

float operator[] ( unsigned int index ) const;

To perform some write like operations on vertex you have to transform it to class Point defined in point.h. Remember Point is working always on a copy of data and there is no way to modify mesh directly.

A next useful method of the Mesh is normal getter. These normals are defined for faces not for vertices like in standard approach.

//! \param index - index of face
Vector < float > get_normal ( unsigned int index ) const;

Each normal is an instance of class Vector which implements standard vector operation and has a support to work with Vertex and Point.

The last important method is getter of all edges adjacent to given vertex. Also these edges starts in this vertex.

//! \param vertex - index of vertex
std::pair< StarConstIter, StarConstIter > get_start ( unsigned int vertex ) const;

This method returns a pair which contains iterators where first is a begging of range and second its end. These iterators allows you to access class Edge see mesh.h. This class allows you to get information about two vertices which belongs this edge by:

//! \return index of vertex
 unsigned int begin() const;
//! \return index of vertex
 unsigned int end() const;

Also you can access all faces which contains given edge.

//! \return - A pair of indices of faces. -1 on on given position if face not assigned.
std::pair < int, int > const & get_faces() const;

Right now we are read to implement a new flow. In the file flowfilter.h you can find an abstract class which provide an interface which you should implement, because other classes used a pointer to this interface. We will talk about this later in this place.

class FlowFilter 
{
public:
    //! \param mesh which will be under flow. This mesh will be unchanged
    virtual void input ( Mesh const * mesh ) = 0;
    virtual Mesh const * get_input () const = 0;
    //! \param mesh where filter will store new mesh parameters after flowing 
    virtual void set_output ( Mesh * mesh ) = 0;
    virtual float get_time() const = 0;
    virtual void set_time ( float value ) = 0;
    //! Implementation should throw exception if at least one of meshes is not set.
    virtual void execute() = 0;
    //! For access to curvature vectors of vertices
    virtual void set_debug( std::vector < float > * vectors ) = 0;
};

Your main goal is to focus on execute(), all other methods are used for communication with other classes and you can just copy their implementations from meanflowfilter.h also is good to start by taking a look on this class and its implementation. You just have to read vertices from input mesh apply curvature vector to them and add a new vertices to output mesh by using:

void add_vertexs_coord ( float coord );

are components should by added in a good order. When your class is implemented or you are ready to tests, you just have to go to the flowfactory.cpp and add new else if statement e.g:

std::shared_ptr< FlowFilter > FlowFactory::get_flow ( const char * name, const char * params )
{
  if ( strcmp ( "MEAN", name ) == 0 )
  {
    return std::shared_ptr< FlowFilter > ( new MeanFlowFilter() );
  }
  else if ( strcmp ( "POWER_MEAN", name ) == 0 )
  {
    if ( strcmp ( "null", params ) != 0 )
    {
      int param = std::atoi ( params );
      return std::shared_ptr< FlowFilter > ( new PowerMeanFlowFilter( param ) );
    }
    else
    {
      std::cerr << "Warrning: PowerMeanFlowFilter created with standard power - 2." << std::endl;
      return std::shared_ptr< FlowFilter > (  new PowerMeanFlowFilter( 2 ) );
    }
  }
  // Your code here
  else
    throw std::runtime_error ( "FlowFactory: Non registered flow!" );
}

After that you are done. FlowRunner will send other parameters like time and output mesh to your class and will run it on a new thread(we do not want to block drawing on screen during execution).

If you need to send to you class more input than one param like for e.g. PowerFlowFilter. You can use CSVExtractor delivered with FlowER. This class can extract all parameters from string of structure like:

"param1,param2,param3"

More information can be found in the file flowfactory.cpp

Clone this wiki locally