Dealing with the visibility maps (the seams)
Dumping the visibility map
The visibility map can be saved at any moment by calling the function:
LqrVMap* lqr_vmap_dump( | LqrCarver* carver); |
This function will return a pointer to a newly allocated LqrVMap object, or NULL in case of
failure. See also the section "The visibility map objects".
Storing the visibility maps
By default, the computed visibility maps are wasted. Instead of saving them individually, it is
possible to automatically dump them at the end of the carving process, attaching them to their
associated LqrCarver. In order to activate this feature, the following function has to be called:
void lqr_carver_set_dump_vmaps( | LqrCarver* carver); |
This will have the effect of dumping the visibility map each time
lqr_carver_resize is invoked, and storing it internally. When resizing along
both directions, two maps will be dumped, one for each direction.
In order to revert the effect of lqr_carver_set_dump_vmaps, thus stopping the
automatic dumping, use the function
void lqr_carver_set_no_dump_vmaps( | LqrCarver* carver); |
Alternatively, the internal storage mechanism can be called over the current visibility map at any
given moment by calling this function:
LqrRetVal lqr_vmap_internal_dump( | LqrCarver* carver); |
The dumped maps are stored inside LqrVMap objects, and these are attached to their corresponing
LqrCarver object through a linked list, whose type is LqrVMapList
Accessing the internally attached visibility maps
To access the maps attached to a carver one has first to obtain the pointer to the list, with the
function:
LqrVMapList* lqr_vmap_list_start( | LqrCarver* carver); |
Then, one can iterate through the attached maps by using these two functions:
LqrVMap* lqr_vmap_list_current( | LqrVMapList* list); |
LqrVMapList* lqr_vmap_list_next( | LqrVMapList* list); |
Here is a sample code usage:
Example 2.7. Accessing visibility maps #1
LqrVMap *vmap;
LqrVMapList *list;
list = lqr_vmap_list_start (carver);
while (list) {
vmap = lqr_vmap_list_current (list);
/* ... do something on vmap ... */
list = lqr_vmap_list_next (list);
}
The maps will always be accessed in the order in which they were dumped.
Alternatively, one can apply a function to all the elements of the list, through this function:
LqrRetVal lqr_vmap_list_foreach( | LqrVMapList* list, |
| | LqrVMapFunc func, |
| | gpointer data); |
To use this second method, you'll need to define a function first, as in this sample code:
Example 2.8. Accessing visibility maps #2
LqrRetVal my_func (LqrVMap vmap, gpointer data)
{
/* ... do something on vmap ... */
return LQR_OK;
}
LqrVMapList *list;
list = lqr_vmap_list_start (carver);
lqr_vmap_list_foreach (list, my_func, NULL);
In the above example, no data is actually passed on to the function.
Note
In actual code the call to lqr_vmap_list_foreach should be protected to
test its return value, which is LQR_OK if all my_func calls have been
successful, or it will hold the first non-successful return value from
my_func.
The visibility map objects
The LqrVMap objects contain an int buffer with the actual map data (plain array, ordered by row),
plus all the information needed to be able to recover it from scratch.
The information can be extracted with these functions:
gint* lqr_vmap_get_data (LqrVMap* vmap);
gint lqr_vmap_get_width (LqrVMap* vmap);
gint lqr_vmap_get_height (LqrVMap* vmap);
gint lqr_vmap_get_orientation (LqrVMap* vmap);
gint lqr_vmap_get_depth (LqrVMap* vmap);
The first one returns a pointer to the data buffer.
The orientation of the map is 0 if the map is to be used for horizontal rescaling, 1 otherwise.
The depth of the map is the maximum amount of rescaling possible with that map, either shrinking or
enlarging.
Example 2.9. Reading visibility maps data
If we have a LqrVMap pointer called vmap, we could access the
value at (x,y) by:
gint *buffer;
gint width;
gint vis;
buffer = lqr_vmap_get_data (vmap);
width = lqr_vmap_get_width (vmap);
vis = buffer[y * width + x];
Uninitialised points will yield vis = 0. For
initialised points, vis will store a positive value between
1 (least visible points, the first to be carved away or to be duplicated)
and (depth + 1) (most visible points, the last to be carved away
or to be duplicated).
If the orientation is 0, the map allows resizing in the whole range form (width
- depth) to (width + depth). If the
orientation is 1, the analogue formula holds with height in place of width.
Importing a visibility map in a carver
Having an LqrVMap object, one can load it in an LqrCarver simply by calling this function:
LqrRetVal lqr_vmap_load( | LqrCarver* carver, |
| | LqrVMap* vmap); |
The carver must not to be initialised, neither before nor after invoking this function.
Note
This implies that the map cannot be updated, and that it will only be possible to resize the
carver by an amount depth along the orientation given by
lqr_vmap_orientation. The enlargment step is also set to its maximum, 2.0.
Invoking lqr_carver_resize with an out-of-bounds argument results in a
fatal error (i.e. it returns LQR_ERROR).
Note
Do not attach other carvers after you have loaded a visibility map (see also the
Attaching extra images section).
Saving and loading visibility maps to/from files
The library does not include methods to load/save visibility maps to/from files. However, a way to
do so is shown in the demo program `liquidrescale' in the
`examples' directory.