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".
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.
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
.
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.3. 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.4. 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.
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 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
); gintlqr_vmap_get_width
(LqrVMap
*vmap
); gintlqr_vmap_get_height
(LqrVMap
*vmap
); gintlqr_vmap_get_orientation
(LqrVMap
*vmap
); gintlqr_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.5. 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];
Uninitialized points will yield
vis = 0
.
For initialized points, vis will store a
positive value between 1
(least visible points,
the first to be carved away or to be duplicated) and
(
(most visible points, the last to be carved away or to
be duplicated).
depth
+ 1)
If the orientation is 0, the map allows resizing in the
whole range form (
to width
- depth
)(
.
If the orientation is 1, the analogue formula holds
with width
+ depth
)height
in place of width
.
Having an LqrVMap
object, one can load it in a LqrCarver
simply by calling this function:
LqrRetVal lqr_vmap_load( | LqrCarver* | carver, |
LqrVMap* | vmap) ; |
The carver must not to be initialized.
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
.
Invoking lqr_carver_resize
with an
out-of-bounds argument results in a fatal error
(i.e. it returns LQR_ERROR
)
Do not attach other carvers after you have loaded a visibility map (see also the Attaching extra images section).