## visu_pairs

visu_pairs — V_Sim can draw link between nodes. This part defines a pair object and interface to draw pairs.

## Synopsis

    #define             VISU_PAIR_DISTANCE_MIN
    #define             VISU_PAIR_DISTANCE_MAX
                        VisuPairData;
    void                (*VisuPairStartEndFunc)             (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             VisuPairData *data);
    void                (*VisuPairDrawFunc)                 (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             VisuPairData *data,
                                                             VisuOpenGLView *view,
                                                             double x1,
                                                             double y1,
                                                             double z1,
                                                             double x2,
                                                             double y2,
                                                             double z2,
                                                             float d2,
                                                             float alpha);
                        VisuPairExtension;
                        VisuPair;
                        VisuPairDistribution;
    VisuPairExtension*  visu_pair_extension_new             (const char *name,
                                                             const char *printName,
                                                             const char *description,
                                                             gboolean sensitive,
                                                             VisuPairStartEndFunc start,
                                                             VisuPairStartEndFunc end,
                                                             VisuPairDrawFunc draw);
    void                visu_pair_extension_free            (VisuPairExtension *extension);
    void                visu_pair_extension_add             (VisuPairExtension *extension);
    gboolean            visu_pair_extension_setDefault      (VisuPairExtension *extension);
    GList*              visu_pair_extension_getAllMethods   ();
    VisuPairExtension*  visu_pair_extension_getDefault      ();
    gboolean            visu_pair_build                     (VisuData *dataObj);
    gboolean            visu_pair_setStatus                 (gboolean onOff);
    void                visu_pair_setOutOfDate              ();
    gboolean            visu_pair_getStatus                 ();
    VisuPair*           visu_pair_getPair                   (VisuElement *ele1,
                                                             VisuElement *ele2);
    void                visu_pair_setProperty               (VisuPair *pair,
                                                             const gchar *key,
                                                             gpointer value,
                                                             GDestroyNotify freeFunc);
    gpointer            visu_pair_getProperty               (VisuPair *pair,
                                                             const gchar *key);
    VisuPairDistribution* visu_pair_getDistanceDistribution (VisuPair *pair,
                                                             VisuData *dataObj,
                                                             float step,
                                                             float min,
                                                             float max);
    gboolean            visu_pair_distribution_getNextPick  (VisuPairDistribution *dd,
                                                             guint startStopId[2],
                                                             guint *integral,
                                                             guint *max,
                                                             guint *posMax);
    GList*              visu_pair_getAllPairData            (VisuElement *ele1,
                                                             VisuElement *ele2);
    VisuPairData*       visu_pair_getPairData               (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             float minMax[2]);
    VisuPairData*       visu_pair_getPairDataFromId         (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             guint pos);
    gboolean            visu_pair_removePairData            (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             VisuPairData *data);
    gboolean            visu_pair_data_setDrawn             (VisuPairData *data,
                                                             gboolean drawn);
    gboolean            visu_pair_data_getDrawn             (VisuPairData *data);
    gboolean            visu_pair_data_setDistance          (VisuPairData *data,
                                                             float val,
                                                             int minOrMax);
    gboolean            visu_pair_data_setColor             (VisuPairData *data,
                                                             ToolColor *destColor);
    ToolColor*          visu_pair_data_getColor             (VisuPairData *data);
    gboolean            visu_pair_data_setPrintLength       (VisuPairData *data,
                                                             gboolean status);
    gboolean            visu_pair_data_setDrawMethod        (VisuPairData *data,
                                                             VisuPairExtension *ext);
    void                visu_pair_data_setProperty          (VisuPairData *data,
                                                             const gchar *key,
                                                             gpointer value);
    float               visu_pair_data_getDistance          (VisuPairData *data,
                                                             int minOrMax);
    gboolean            visu_pair_data_getPrintLength       (VisuPairData *data);
    gpointer            visu_pair_data_getProperty          (VisuPairData *data,
                                                             const gchar *key);
    VisuPairExtension*  visu_pair_data_getDrawMethod        (VisuPairData *data);
    void                (*VisuPairForeachFunc)              (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             VisuPairData *data,
                                                             gpointer userData);
    void                visu_pair_foreach                   (VisuPairForeachFunc whatToDo,
                                                             gpointer userData);
    gboolean            visu_pair_readLinkFromTokens        (gchar **tokens,
                                                             int *index,
                                                             VisuPairData **data,
                                                             int position,
                                                             GError **error);
    int                 initPairsModule                     ();

## Description

The visu_pairs.c defines only general methods to draw pairs. It introduces a new object called VisuPairData. This stores some characteristics on links between two VisuElement. The main characteristic is that pairs are drawn only if the length between two nodes is in a specific range. Use `visu_pair_data_setDistance()` and `visu_pair_data_getDistance()` to tune this range.

This file does not draw any pairs. But it gives some interface to create rendering capabilities. To create a new pair rendering module, called VisuPairExtension, use `visu_pair_extension_new()`. Basically, a VisuPairExtension is characterized by it drawing method. But it can have other methods that are called in different cases. See `VisuPairDrawFunc()` and `VisuPairStartEndFunc()` prototypes to have more informations.

## Details

### VISU_PAIR_DISTANCE_MIN

    #define VISU_PAIR_DISTANCE_MIN 0

Flag used to define the minimum length to draw pair. This is useful with the `visu_pair_data_getDistance()` and the `visu_pair_data_setDistance()` methods.

### VISU_PAIR_DISTANCE_MAX

    #define VISU_PAIR_DISTANCE_MAX 1

Flag used to define the maximum length to draw pair. This is useful with the `visu_pair_data_getDistance()` and the `visu_pair_data_setDistance()` methods.

### VisuPairData

    typedef struct {
      float minMax[2];
      gboolean drawn;
      gboolean printLength;

      VisuPairExtension *method;

      GHashTable *properties;
    } VisuPairData;

This structure is used to describe a link between two elements. A link is drawn only its length is between the minimum and the maximum value stored in the minMax array.

float `minMax`[2]; | storage for the length bounds for drawn pairs ;
gboolean `drawn`; | a boolean to say if the pair is drawn or not ;
gboolean `printLength`; | a boolean to say if length of pairs are drawn near them ;
VisuPairExtension *`method`; | the rendering method for this link.
GHashTable *`properties`; | some key:value association for this link.

### VisuPairStartEndFunc ()

    void                (*VisuPairStartEndFunc)             (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             VisuPairData *data);

Prototype of functions called at the beginning and the end of drawing of each pairs types. `ele1` and `ele2` arguments are the two elements between the pair defined by `data` is drawn. This is useful to set some OpenGL definition specific to each pair, such as the color for example.

`ele1` : | a VisuElement object ;
`ele2` : | a VisuElement object ;
`data` : | a VisuPairData object.

### VisuPairDrawFunc ()

    void                (*VisuPairDrawFunc)                 (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             VisuPairData *data,
                                                             VisuOpenGLView *view,
                                                             double x1,
                                                             double y1,
                                                             double z1,
                                                             double x2,
                                                             double y2,
                                                             double z2,
                                                             float d2,
                                                             float alpha);

Prototype of function to draw a pair. Such function are called each time a pair is drawn between the two points (`x1`, `y1`, `z1`) and (`x2`, `y2`, `z2`). The `d2` argument is the square distance between the two points. The `alpha` argument is a proposed alpha colour from the main program, its value is in [0;1].

`ele1` : | a VisuElement object ;
`ele2` : | a VisuElement object ;
`data` : | a VisuPairData object ;
`view` : | a VisuOpenGLView object, giving some constants describing the OpenGL scene ;
`x1` : | a floating point value ;
`y1` : | a floating point value ;
`z1` : | a floating point value ;
`x2` : | a floating point value ;
`y2` : | a floating point value ;
`z2` : | a floating point value ;
`d2` : | a floating point value ;
`alpha` : | a floating point value.

### VisuPairExtension

    typedef struct {
      /* Some variable to describe this OpenGL extension.
         The attribute name is mandatory since it is
         used to identify the method. */
      char* name;
      char* printName;
      char* description;

      gboolean sensitiveToFacette;

      VisuPairStartEndFunc beginDrawingPairs;
      VisuPairStartEndFunc endDrawingPairs;
      VisuPairDrawFunc drawPairs;
    } VisuPairExtension;

Structure to store pairs extensions. All fields are private and should not be accessed directly. This structure will not be public in near future, do not use it.

char *`name`; | an internal name ;
char *`printName`; | the UTF-8 name, used for the GUI ;
char *`description`; | an UTF-8 short description of the pairs method.
gboolean `sensitiveToFacette`; | if TRUE, the OpenGL list of the pairs is recompute each time the number of facette changes ;
VisuPairStartEndFunc `beginDrawingPairs`; | method called a startup of drawing pairs ;
VisuPairStartEndFunc `endDrawingPairs`; | method called a ending of drawing pairs ;
VisuPairDrawFunc `drawPairs`; | the drawing method for each pair.

### VisuPair

    typedef struct _VisuPair VisuPair;

An opaque structure to define links (i.e. several VisuPairData) between elements.

### VisuPairDistribution

    typedef struct {
      VisuElement *ele1, *ele2;
      guint *histo;
      guint nValues;
      float initValue, stepValue;
      guint nNodesEle1, nNodesEle2;
    } VisuPairDistribution;

This structure stores for a given pair, the distance distribution on a given range [`initValue`;`nValues` * `stepValue`[.

VisuElement *`ele1`; | one VisuElement.
VisuElement *`ele2`; | one VisuElement.
guint *`histo`; | an array containing the distribution ;
guint `nValues`; | the size of the array ;
float `initValue`; | the initial distance value (usualy 0) ;
float `stepValue`; | the step increase in distance at each value ;
guint `nNodesEle1`; | the number of nodes used during the computation ;
guint `nNodesEle2`; | idem for VisuElement 2.

### visu_pair_extension_new ()

    VisuPairExtension*  visu_pair_extension_new             (const char *name,
                                                             const char *printName,
                                                             const char *description,
                                                             gboolean sensitive,
                                                             VisuPairStartEndFunc start,
                                                             VisuPairStartEndFunc end,
                                                             VisuPairDrawFunc draw);

This creates a new pairs extension. Such an extension describes how to draw links (called pairs) between elements. The `sensitive` argument is to inform if pairs must be redrawn when the OpenGL engine sends the OpenGLFacetteChanged signal.

`name` : | name of the extension (must be non null) ;
`printName` : | a string to label the method that can be safely translated ;
`description` : | a brief description of the extension (can be null) ;
`sensitive` : | a boolean 0 or 1 ;
`start` : | a `VisuPairStartEndFunc()` method or NULL ;
`end` : | a `VisuPairStartEndFunc()` method or NULL ;
`draw` : | a `VisuPairDrawFunc()` method (not NULL).
Returns : | the new VisuPairExtension or null if something wrong happens.

### visu_pair_extension_free ()

    void                visu_pair_extension_free            (VisuPairExtension *extension);

Free all the allocated attributes of the specified method.

`extension` : | the extension to delete.

### visu_pair_extension_add ()

    void                visu_pair_extension_add             (VisuPairExtension *extension);

A method used by user to registered a new extension.

`extension` : | an extension.

### visu_pair_extension_setDefault ()

    gboolean            visu_pair_extension_setDefault      (VisuPairExtension *extension);

Choose the method used to draw pairs. If necessary, `visu_pair_build()` are called.

`extension` : | a VisuPairExtension object.
Returns : | TRUE if the OpenGLAskForReDraw signal show be emitted or not.

### visu_pair_extension_getAllMethods ()

    GList*              visu_pair_extension_getAllMethods   ();

Useful to know all VisuPairExtension.

Returns : | a list of all the known VisuPairExtension. This list should be considered read-only.

### visu_pair_extension_getDefault ()

    VisuPairExtension*  visu_pair_extension_getDefault      ();

If some process need to know the current VisuPairExtension. Such extension has been set with `setPairsMethod()`.

Returns : | the current VisuPairExtension, NULL if none has been set.

### visu_pair_build ()

    gboolean            visu_pair_build                     (VisuData *dataObj);

This methods recreates the OpenGL list of the VisuExtension associated to the pairs. Thus it is the heart of the pairs drawing. When called, if a valid VisuPairExtension has been set with `setPairsMethod()`, it takes all the nodes and compute all the distances between two different nodes. If this distance is compatible with the distance of drawn pairs for the two elements it calls the `VisuPairDrawFunc()` for these two nodes. WARNING! this method is very expensive in computing cost.

`dataObj` : | the VisuData object to create pairs for.
Returns : | TRUE if the OpenGLAskForReDraw signal show be emitted or not.

### visu_pair_setStatus ()

    gboolean            visu_pair_setStatus                 (gboolean onOff);

Turn on or off the pairs.

`onOff` : | a boolean 0 or 1.
Returns : | TRUE if `visu_pair_build()` should be called and then the 'OpenGLAskForReDraw' signal be emitted.

### visu_pair_setOutOfDate ()

    void                visu_pair_setOutOfDate              ();

Use this method to change the internal flag that pairs should be rebuilt. It is useful when an extension of pairs has one of its parameters that has changed.

### visu_pair_getStatus ()

    gboolean            visu_pair_getStatus                 ();

Get the status of pairs, drawn or not.

Returns : | TRUE if pairs are drawn.

### visu_pair_getPair ()

    VisuPair*           visu_pair_getPair                   (VisuElement *ele1,
                                                             VisuElement *ele2);

The object VisuPair is used to characterized links between two elements.

`ele1` : | a VisuElement object ;
`ele2` : | a VisuElement object.
Returns : | the VisuPair object associated to the given two elements. If none exists it is created. The returned value should not be freed.

### visu_pair_setProperty ()

    void                visu_pair_setProperty               (VisuPair *pair,
                                                             const gchar *key,
                                                             gpointer value,
                                                             GDestroyNotify freeFunc);

Each element/element can have associated data.

`pair` : | a VisuPair object ;
`key` : | a static string ;
`value` : | a pointer to some allocated data ;
`freeFunc` : | a destroying method (can be NULL).

### visu_pair_getProperty ()

    gpointer            visu_pair_getProperty               (VisuPair *pair,
                                                             const gchar *key);

Retrieve the property associated to the `key` or NULL if none exist.

`pair` : | a VisuPair object ;
`key` : | a string.
Returns : | the associated data.

### visu_pair_getDistanceDistribution ()

    VisuPairDistribution* visu_pair_getDistanceDistribution (VisuPair *pair,
                                                             VisuData *dataObj,
                                                             float step,
                                                             float min,
                                                             float max);

This will compute the distnace distribution of nodes for the given `pair`.

`pair` : | a VisuPair ;
`dataObj` : | a VisuData ;
`step` : | a float for the distance mesh (negative value to use built-in default) ;
`min` : | a float for the minimum scanning value (negative value to use built-in default).
`max` : | a float for the maximum scanning value (negative value to use built-in default).
Returns : | a structure defining the distance distribution. This structure is private and should not be freed.

### visu_pair_distribution_getNextPick ()

    gboolean            visu_pair_distribution_getNextPick  (VisuPairDistribution *dd,
                                                             guint startStopId[2],
                                                             guint *integral,
                                                             guint *max,
                                                             guint *posMax);

Try to find the next pick in the distribution. A pick is a group of consecutive non-null values, with a significant integral. On enter, `startStopId` contains the span to look into for the pick, and on output, it contains the span of the pick itself.

`dd` : | a VisuPairDistribution object.
`startStopId` : | two ids.
`integral` : | a location for a guint value, can be NULL.
Returns : | TRUE if a pick is found.

Since 3.6

### visu_pair_getAllPairData ()

    GList*              visu_pair_getAllPairData            (VisuElement *ele1,
                                                             VisuElement *ele2);

There can be one or several links between elements, retrieve them with this routine.

`ele1` : | a VisuElement object ;
`ele2` : | a VisuElement object.
Returns : | a list of VisuPairData. The list is owned by V_Sim and should not be freed.

### visu_pair_getPairData ()

    VisuPairData*       visu_pair_getPairData               (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             float minMax[2]);

A link between two elements is characterized by its boundary distances.

`ele1` : | a VisuElement object ;
`ele2` : | a VisuElement object ;
`minMax` : | the two min and max distances.
Returns : | the VisuPairData object associated to the given two elements and distances. If none exists it is created. The returned value should not be freed.

### visu_pair_getPairDataFromId ()

    VisuPairData*       visu_pair_getPairDataFromId         (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             guint pos);

A link can also be retrieved by its position.

`ele1` : | a VisuElement object ;
`ele2` : | a VisuElement object ;
`pos` : | the position in the list of links.
Returns : | the VisuPairData object associated to the given two elements and distances. If none exists NULL is returned.

### visu_pair_removePairData ()

    gboolean            visu_pair_removePairData            (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             VisuPairData *data);

Delete the given link.

`ele1` : | a VisuElement object ;
`ele2` : | a VisuElement object ;
`data` : | a link object.
Returns : | TRUE if the link exists and has been successfully removed.

### visu_pair_data_setDrawn ()

    gboolean            visu_pair_data_setDrawn             (VisuPairData *data,
                                                             gboolean drawn);

A pair can or cannot be drawn, use this method to tune it.

`data` : | a VisuPairData object ;
`drawn` : | a boolean.
Returns : | TRUE if `visu_pair_build()` should be called.

### visu_pair_data_getDrawn ()

    gboolean            visu_pair_data_getDrawn             (VisuPairData *data);

A pair can or cannot be drawn, use this method to retrieve its state.

`data` : | a VisuPairData object ;
Returns : | TRUE if pairs can be drawn.

### visu_pair_data_setDistance ()

    gboolean            visu_pair_data_setDistance          (VisuPairData *data,
                                                             float val,
                                                             int minOrMax);

Set the minimum or the maximum length for the given pair.

`val` : | a floating point value ;
`data` : | a VisuPairData object ;
`minOrMax` : | VISU_PAIR_DISTANCE_MAX or VISU_PAIR_DISTANCE_MIN.
Returns : | TRUE if `visu_pair_build()` should be called or not.

### visu_pair_data_setColor ()

    gboolean            visu_pair_data_setColor             (VisuPairData *data,
                                                             ToolColor *destColor);

Set the color of the given pair.

`data` : | a VisuPairData object ;
`destColor` : | a ToolColor object.
Returns : | TRUE if `visu_pair_build()` should be called or not.

### visu_pair_data_getColor ()

    ToolColor*          visu_pair_data_getColor             (VisuPairData *data);

Look for the properties of the pair `data` to find if a colour has been defined. If none, the default colour is returned instead.

`data` : | a VisuPairData object.
Returns : | a colour (don't free it).

### visu_pair_data_setPrintLength ()

    gboolean            visu_pair_data_setPrintLength       (VisuPairData *data,
                                                             gboolean status);

Set the attribute that controls if the length of pairs are drawn near pairs.

`data` : | a VisuPairData object ;
`status` : | TRUE to print length near pairs.
Returns : | TRUE if `visu_pair_build()` should be called or not.

### visu_pair_data_setDrawMethod ()

    gboolean            visu_pair_data_setDrawMethod        (VisuPairData *data,
                                                             VisuPairExtension *ext);

Set the drawing method of a pair.

`data` : | a VisuPairData object.
`ext` : | a VisuPairExtension object.
Returns : | TRUE if drawing method is changed.

Since 3.6

### visu_pair_data_setProperty ()

    void                visu_pair_data_setProperty          (VisuPairData *data,
                                                             const gchar *key,
                                                             gpointer value);

Each pair can store some informations that can be retrieve by a string key. This method is used to registered a new value associated to the key `key`.

`data` : | a VisuPairData object ;
`key` : | a static string ;
`value` : | a pointer to some allocated data.

### visu_pair_data_getDistance ()

    float               visu_pair_data_getDistance          (VisuPairData *data,
                                                             int minOrMax);

A pair between `ele1` and `ele2` is drawn only if its length is between a minimum and a maximum value. This method can get these values.

`data` : | a VisuPairData object ;
`minOrMax` : | VISU_PAIR_DISTANCE_MIN or VISU_PAIR_DISTANCE_MAX.
Returns : | the minimum or the maximum value for the pair between `ele1` and `ele2`.

### visu_pair_data_getPrintLength ()

    gboolean            visu_pair_data_getPrintLength       (VisuPairData *data);

Get the print length parameter of a pair. This parameter is used to tell if length should be drawn near pairs of this kind.

`data` : | a VisuPairData object.
Returns : | TRUE if length are printed.

### visu_pair_data_getProperty ()

    gpointer            visu_pair_data_getProperty          (VisuPairData *data,
                                                             const gchar *key);

Each pair can store some informations that can be retrieve by a string key. This method is used to retrieve a stored value associated to the key `key`.

`data` : | a VisuPairData object ;
`key` : | a static string.
Returns : | a found value, or NULL if nothing is associated to the `key`. If something is returned it should not be freed.

### visu_pair_data_getDrawMethod ()

    VisuPairExtension*  visu_pair_data_getDrawMethod        (VisuPairData *data);

Get the drawing method of a pair.

`data` : | a VisuPairData object.
Returns : | a drawing method.

Since 3.6

### VisuPairForeachFunc ()

    void                (*VisuPairForeachFunc)              (VisuElement *ele1,
                                                             VisuElement *ele2,
                                                             VisuPairData *data,
                                                             gpointer userData);

Prototype of functions called with the foreach method apply to each pairs.

`ele1` : | a VisuElement object ;
`ele2` : | a VisuElement object ;
`data` : | a VisuPairData object ;
`userData` : | some user defined data.

### visu_pair_foreach ()

    void                visu_pair_foreach                   (VisuPairForeachFunc whatToDo,
                                                             gpointer userData);

The way VisuPairData are stored in V_Sim is private and could changed between version. This method is used to apply some method each pairs.

`whatToDo` : | a `VisuPairForeachFunc()` method ;
`userData` : | some user defined data.

### visu_pair_readLinkFromTokens ()

    gboolean            visu_pair_readLinkFromTokens        (gchar **tokens,
                                                             int *index,
                                                             VisuPairData **data,
                                                             int position,
                                                             GError **error);

This routine is used to read the resource file. Given `tokens`, it associate a link object by reading the two elements and the two distances that characterised this link.

`tokens` : | array of tokens resulting from a call to `g_strsplit()` with " " as separator ;
`index` : | IN, the position of the beginning in `tokens` ; OUT, one token after the last read ;
`data` : | a pointer to return an allocated link object ;
`position` : | the number of the line of the config file which the `line` argument is taken from ;
`error` : | a location to store a possible reading error.
Returns : | TRUE if succeed.

### initPairsModule ()

    int                 initPairsModule                     ();

Initialise all the variable of this part. It calls all the elements in listInitPairsFunc (that stores the init function of the pairs extensions). If these elements return valid VisuPairExtension, they are registered through a call to `visu_pair_extension_add()`. This method is called by the main program at the initialisation stage and should not be called in others circonstempses.

Returns : | 1 if everything goes allright during the initialisation.