#include <glib.h>
+/**
+ * \defgroup P2trMeshAction P2trMeshAction - Mesh Action Recording
+ * Action recording state objects for mesh objects. These may be
+ * inspected by code outside of the library, but objects of this type
+ * should not be created or manipulated by external code!
+ * @{
+ */
+
+/**
+ * The type of the geometric primitive affected by a mesh action
+ */
typedef enum
{
P2TR_MESH_ACTION_POINT,
P2TR_MESH_ACTION_TRIANGLE
} P2trMeshActionType;
-typedef struct P2trMeshActionPoint_
-{
- P2trPoint *point;
-} P2trMeshActionPoint;
-
-typedef struct P2trMeshActionEdge_
-{
- P2trVEdge *vedge;
- gboolean constrained;
-} P2trMeshActionEdge;
-
-typedef struct P2trMeshActionTriangle_
-{
- P2trVTriangle *vtri;
-} P2trMeshActionTriangle;
-
+/**
+ * A struct representing any single action on a mesh. A single atomic
+ * action may be the insertion/removal of a point/edge/triangle.
+ *
+ * Note that such an action only treats the direct geometric operation
+ * related to the specific geometric primitve, without any of its
+ * dependencies.
+ *
+ * For example, if removing a point requires the removal of several
+ * edges and triangles, then the removal of each one of those should be
+ * recorded in its own action object.
+ */
typedef struct P2trMeshAction_
{
+ /** The type of geometric primitive affected by the action */
P2trMeshActionType type;
+ /** A flag specifying whether the primitive was added or removed */
gboolean added;
+ /** A reference count to the action object */
gint refcount;
+ /** Specific additional information which is needed for each type
+ * of action */
union {
- P2trMeshActionPoint action_point;
- P2trMeshActionEdge action_edge;
- P2trMeshActionTriangle action_tri;
- } action;
+ /** Information required to undo a point action */
+ struct {
+ /** The point that was added/deleted */
+ P2trPoint *point;
+ } action_point;
+
+ /** Information required to undo an edge action */
+ struct {
+ /** A virtual edge representing the added/deleted edge */
+ P2trVEdge *vedge;
+ /** A flag specifying whether the edge is constrained */
+ gboolean constrained;
+ } action_edge;
+
+ /** Information required to undo a triangle action */
+ struct {
+ /** A virtual triangle representing the added/deleted triangle */
+ P2trVTriangle *vtri;
+ } action_tri;
+ } action;
} P2trMeshAction;
+/**
+ * Create a new mesh action describing the addition of a new point
+ * @param point The point that is added to the mesh
+ * @return An object representing the point addition action
+ */
P2trMeshAction* p2tr_mesh_action_new_point (P2trPoint *point);
+
+/**
+ * Create a new mesh action describing the deletion of an existing point
+ * @param point The point that is deleted from the mesh
+ * @return An object representing the point deletion action
+ */
P2trMeshAction* p2tr_mesh_action_del_point (P2trPoint *point);
+
+/**
+ * Create a new mesh action describing the addition of a new edge
+ * @param edge The edge that is added to the mesh
+ * @return An object representing the edge addition action
+ */
P2trMeshAction* p2tr_mesh_action_new_edge (P2trEdge *edge);
+
+/**
+ * Create a new mesh action describing the deletion of an existing edge
+ * @param edge The edge that is deleted from the mesh
+ * @return An object representing the edge deletion action
+ */
P2trMeshAction* p2tr_mesh_action_del_edge (P2trEdge *edge);
+
+/**
+ * Create a new mesh action describing the addition of a triangle
+ * @param tri The triangle that is added to the mesh
+ * @return An object representing the triangle addition action
+ */
P2trMeshAction* p2tr_mesh_action_new_triangle (P2trTriangle *tri);
+
+/**
+ * Create a new mesh action describing the deletion of an existing
+ * triangle
+ * @param tri The triangle that is deleted from the mesh
+ * @return An object representing the triangle deletion action
+ */
P2trMeshAction* p2tr_mesh_action_del_triangle (P2trTriangle *tri);
+/**
+ * Increase the reference count to this mesh action by 1
+ * @param self The mesh action whose reference count should be increased
+ */
P2trMeshAction* p2tr_mesh_action_ref (P2trMeshAction *self);
+
+/**
+ * Decrease the reference count to this mesh action by 1
+ * @param self The mesh action whose reference count should be decreased
+ */
void p2tr_mesh_action_unref (P2trMeshAction *self);
+
+/**
+ * Free the memory used by a mesh action data structure
+ * @param self The mesh action whose memory should be freed
+ */
void p2tr_mesh_action_free (P2trMeshAction *self);
+
+/**
+ * Undo the action described by the given mesh action object
+ * @param self The mesh action to undo
+ * @param mesh The mesh on which this action was applied
+ */
void p2tr_mesh_action_undo (P2trMeshAction *self,
P2trMesh *mesh);
#include "utils.h"
#include "triangulation.h"
+/**
+ * \defgroup P2trMesh P2trMesh - Triangular Meshes
+ * The library is designed to handle triangular meshes which are made
+ * of one continuous region, potentially with holes
+ * @{
+ */
struct P2trMesh_
{
P2trHashSet *triangles;
guint refcount;
};
+/**
+ * Create a new empty mesh
+ * @return The newly created mesh
+ */
P2trMesh* p2tr_mesh_new (void);
/**
P2trPoint* p2tr_mesh_add_point (P2trMesh *self,
P2trPoint *point);
+/**
+ * Create a new point and add it to the given mesh
+ * @param mesh The mesh to add the point to
+ * @param c The coordinates of the point to create
+ * @return The newly created point
+ */
P2trPoint* p2tr_mesh_new_point (P2trMesh *mesh,
const P2trVector2 *c);
+/**
+ * Create a new point and add it to the given mesh
+ * @param mesh The mesh to add the point to
+ * @param x The X coordinate of the point to create
+ * @param y The Y coordinate of the point to create
+ * @return The newly created point
+ */
P2trPoint* p2tr_mesh_new_point2 (P2trMesh *mesh,
gdouble x,
gdouble y);
P2trEdge* p2tr_mesh_add_edge (P2trMesh *self,
P2trEdge *point);
+/**
+ * Create a new edge and add it to the given mesh
+ * @param mesh The mesh to add the edge to
+ * @param start The starting point of the edge
+ * @param end The ending point of the edge
+ * @param constrained Specify whether this edge is constrained or not
+ * @return Thew newly created edge
+ */
P2trEdge* p2tr_mesh_new_edge (P2trMesh *mesh,
P2trPoint *start,
P2trPoint *end,
gboolean constrained);
/**
- * Return a new edge between the two points if an edge doesn't exist, or
- * return an existing edge between the two points if there is such one.
- * THE RETURNED EDGE MUST BE UNREFFED, NO MATTER IF IT'S A NEW EDGE OR
- * AN EXISTING EDGE!
+ * This function checks if an edge between two points exists, and if
+ * not it creates it. In both cases the returned edge will be returned
+ * with an extra reference, so it must be unreffed later.
+ * @param self The mesh of the returned edge
+ * @param start The starting point of the returned edge
+ * @param end The ending point of the returned edge
+ * @param constrained Specify whether this edge should be constrained
+ * or not (in case a new edge is created)
+ * @return An edge between the two points
*/
P2trEdge* p2tr_mesh_new_or_existing_edge (P2trMesh *self,
P2trPoint *start,
P2trTriangle* p2tr_mesh_add_triangle (P2trMesh *self,
P2trTriangle *tri);
+/**
+ * Create a new triangle and add it to the given mesh
+ * @param mesh The mesh to add the triangle to
+ * @param AB An edge from the first point of the triangle to the second
+ * @param BC An edge from the second point of the triangle to the third
+ * @param CA An edge from the third point of the triangle to the first
+ */
P2trTriangle* p2tr_mesh_new_triangle (P2trMesh *mesh,
P2trEdge *AB,
P2trEdge *BC,
P2trEdge *CA);
+/** \internal
+ * This function should be called just before a point is removed from
+ * the mesh. It is used internally to update the mesh and it should not
+ * be called by any code outside of this library.
+ * @param mesh The mesh from which the point is going to be removed
+ * @param point The point which is going to be removed
+*/
void p2tr_mesh_on_point_removed (P2trMesh *mesh,
P2trPoint *point);
+/** \internal
+ * This function should be called just before an edge is removed from
+ * the mesh. It is used internally to update the mesh and it should not
+ * be called by any code outside of this library.
+ * @param mesh The mesh from which the edge is going to be removed
+ * @param edge The edge which is going to be removed
+*/
void p2tr_mesh_on_edge_removed (P2trMesh *mesh,
P2trEdge *edge);
+/** \internal
+ * This function should be called just before a triangle is removed from
+ * the mesh. It is used internally to update the mesh and it should not
+ * be called by any code outside of this library.
+ * @param mesh The mesh from which the triangle is going to be removed
+ * @param triangle The triangle which is going to be removed
+*/
void p2tr_mesh_on_triangle_removed (P2trMesh *mesh,
P2trTriangle *triangle);
+/**
+ * Begin recording all action performed on a mesh. Recording the
+ * actions performed on a mesh allows choosing later whether to commit
+ * those actions or whether they should be undone.
+ * \warning This function must not be called when recording is already
+ * taking place!
+ * @param self The mesh whose actions should be recorded
+ */
void p2tr_mesh_action_group_begin (P2trMesh *self);
+
+/**
+ * Terminate the current session of recording mesh actions by
+ * committing all the actions to the mesh
+ * \warning This function must not be called unless recording of
+ * actions is already taking place!
+ * @param self The mesh whose actions were recorded
+ */
void p2tr_mesh_action_group_commit (P2trMesh *self);
+
+/**
+ * Terminate the current session of recording mesh actions by
+ * undoing all the actions done to the mesh.
+ * \warning This function must not be called unless recording of
+ * actions is already taking place!
+ * \warning A call to this function may invalidate all references to
+ * any non virtual geometric primitives! If you plan on using
+ * this function, consider using virtual data structures!
+ * @param self The mesh whose actions were recorded
+ */
void p2tr_mesh_action_group_undo (P2trMesh *self);
+/**
+ * Remove all triangles, edges and points from a mesh
+ * @param mesh The mesh to clear
+ */
void p2tr_mesh_clear (P2trMesh *mesh);
-void p2tr_mesh_destroy (P2trMesh *mesh);
+/**
+ * Clear and then free the memory used by a mesh data structure
+ * @param mesh The mesh whose memory should be freed
+ */
+void p2tr_mesh_free (P2trMesh *mesh);
+/**
+ * Decrease the reference count to this mesh by 1
+ * @param mesh The mesh whose reference count should be decreased
+ */
void p2tr_mesh_unref (P2trMesh *mesh);
+/**
+ * Increase the reference count to this mesh by 1
+ * @param mesh The mesh whose reference count should be increased
+ */
P2trMesh* p2tr_mesh_ref (P2trMesh *mesh);
+/**
+ * Find a triangle of the mesh, containing the point at the given
+ * location
+ * @param self The mesh whose triangles should be checked
+ * @param pt The location of the point to test
+ * @return The triangle containing the given point, or NULL if the
+ * point is outside the triangulation domain
+ */
P2trTriangle* p2tr_mesh_find_point (P2trMesh *self,
const P2trVector2 *pt);
+/**
+ * Exactly like \ref p2tr_mesh_find_point, except for the fact that
+ * this variant also returns the UV coordinates of the point inside the
+ * triangle
+ * @param[in] self The mesh whose triangles should be checked
+ * @param[in] pt The location of the point to test
+ * @param[out] u The U coordinate of the point inside the triangle
+ * @param[out] v The V coordinate of the point inside the triangle
+ * @return The triangle containing the given point, or NULL if the
+ * point is outside the triangulation domain
+ */
P2trTriangle* p2tr_mesh_find_point2 (P2trMesh *self,
const P2trVector2 *pt,
gdouble *u,
gdouble *v);
-/** This function assumes the mesh is composed entirely of one
- * continuous region. The region may have holes, but eventually every
- * triangle should be accessible from any other triangle by going
- * through a chain of neigbor triangles
- * @param[in] self The mesh to search
- * @param[in] pt The point to find
- * @param[in] initial_guess An initial guess for which triangle contains
- * the point or is at least near it
- * @return The triangle containing the point, or NULL if it's outside
- * the triangulation domain
+/**
+ * Another variant of \ref p2tr_mesh_find_point taking an initial
+ * triangle that the search should begin from its area. The search is
+ * performed first on triangles close to the given triangle, and it
+ * gradually tests farther and farther triangles until it finds the one
+ * containing the given point.
+ *
+ * This way of search should be fast when the approximate area of the
+ * point to find is known, but it will be slower if initial triangle
+ * is not near.
+ *
+ * Note that in this function, triangles are considered near depending
+ * on the length of the chain of neighbor triangles needed to go from
+ * one to the other.
+ *
+ * \warning This function may use memory which is at least linear in
+ * the amount of triangles to test. Therefor, do not use it
+ * on large mesh objects unless the initial guess is supposed
+ * to be good!
+ * @param self The mesh whose triangles should be checked
+ * @param pt The location of the point to test
+ * @param initial_guess An initial guess for which triangle contains
+ * the point, or is at least near the triangle containing it
+ * @return The triangle containing the given point, or NULL if the
+ * point is outside the triangulation domain
*/
P2trTriangle* p2tr_mesh_find_point_local (P2trMesh *self,
const P2trVector2 *pt,
P2trTriangle *initial_guess);
-/** Same as @ref p2tr_mesh_find_point_local but also returns the u and v
- * coordinates of the given point inside the triangle
- * @param[in] self The mesh to search
- * @param[in] pt The point to find
- * @param[in] initial_guess An initial guess for which triangle contains
- * the point or is at least near it
- * @param[out] u The u coordinate of the point inside the returned triangle
- * @param[out] v The v coordinate of the point inside the returned triangle
- * @return The triangle containing the point, or NULL if it's outside
- * the triangulation domain
+/**
+ * Exactly like \ref p2tr_mesh_find_point_local, except for the fact
+ * that this variant also returns the UV coordinates of the point
+ * inside the triangle
+ * @param[in] self The mesh whose triangles should be checked
+ * @param[in] pt The location of the point to test
+ * @param[in] initial_guess An initial guess for which triangle
+ * contains the point, or is at least near the triangle
+ * containing it
+ * @param[out] u The U coordinate of the point inside the triangle
+ * @param[out] v The V coordinate of the point inside the triangle
+ * @return The triangle containing the given point, or NULL if the
+ * point is outside the triangulation domain
*/
P2trTriangle* p2tr_mesh_find_point_local2 (P2trMesh *self,
const P2trVector2 *pt,
gdouble *u,
gdouble *v);
+/** @} */
#endif