got nonbinary partitioning working yippie
This commit is contained in:
parent
6b5bcff1a4
commit
330755591b
6 changed files with 170 additions and 57 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "dims.h"
|
#include "dims.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
struct ct_dims *new_dims(int x, int y, int width, int height) {
|
struct ct_dims *new_dims(int x, int y, int width, int height) {
|
||||||
struct ct_dims *dims;
|
struct ct_dims *dims;
|
||||||
|
|
@ -42,19 +43,17 @@ static struct ct_bounds *__bounds(const enum ct_boundtype type, const int wmin,
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void clamp(int *const val, const int min, const int max,
|
static inline void __clamp(int *const val, const int min, const int max,
|
||||||
const int do_ceiling) {
|
const int do_ceiling) {
|
||||||
if (*val == __BOUND_UNLIMITED)
|
if (*val == __BOUND_UNLIMITED)
|
||||||
*val = do_ceiling ? max : min;
|
*val = do_ceiling ? max : min;
|
||||||
else if (*val > max)
|
else
|
||||||
*val = max;
|
*val = clampi(*val, min, max);
|
||||||
else if (*val < min)
|
|
||||||
*val = min;
|
|
||||||
}
|
}
|
||||||
#define CLAMP_ABS(val, is_max) \
|
#define CLAMP_ABS(val, is_max) \
|
||||||
(clamp(&val, __BOUND_ABS_MIN, __BOUND_ABS_MAX, is_max))
|
(__clamp(&val, __BOUND_ABS_MIN, __BOUND_ABS_MAX, is_max))
|
||||||
#define CLAMP_REL(val, is_max) \
|
#define CLAMP_REL(val, is_max) \
|
||||||
(clamp(&val, __BOUND_REL_MIN, __BOUND_REL_MAX, is_max))
|
(__clamp(&val, __BOUND_REL_MIN, __BOUND_REL_MAX, is_max))
|
||||||
|
|
||||||
struct ct_bounds *bounds_none(void) {
|
struct ct_bounds *bounds_none(void) {
|
||||||
return __bounds(BOUND_NONE, __BOUND_ABS_MIN, __BOUND_ABS_MAX, __BOUND_ABS_MIN,
|
return __bounds(BOUND_NONE, __BOUND_ABS_MIN, __BOUND_ABS_MAX, __BOUND_ABS_MIN,
|
||||||
|
|
|
||||||
163
cursetree/node.c
163
cursetree/node.c
|
|
@ -7,6 +7,7 @@
|
||||||
#include "dims.h"
|
#include "dims.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "surface.h"
|
#include "surface.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
/* Internal allocator method for ct_node structures.
|
/* Internal allocator method for ct_node structures.
|
||||||
*/
|
*/
|
||||||
|
|
@ -74,9 +75,12 @@ void satisfy_node(struct ct_node *const node, struct ct_dims *const dims) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ct_whdims {
|
/* Surface Partition Dimensions */
|
||||||
|
/* TODO: can I use unsigned short instead of int? */
|
||||||
|
struct ct_spdims {
|
||||||
// Main Axis & Orthogonal Axis Sizes
|
// Main Axis & Orthogonal Axis Sizes
|
||||||
int axm_size, axo_size;
|
int axm_size;
|
||||||
|
// int axo_size;
|
||||||
bool fixed;
|
bool fixed;
|
||||||
int min, max;
|
int min, max;
|
||||||
};
|
};
|
||||||
|
|
@ -98,75 +102,136 @@ int resize_node(struct ct_node *const node, struct ct_dims *const dims) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ct_whdims cwhdims[node->cindex];
|
int axm_size, axm_free;
|
||||||
struct ct_whdims *const parts[node->cindex];
|
// int axo_size;
|
||||||
int cunfixedn = node->cindex; // number of non-fixed children
|
size_t bounds_axm_min_offset, bounds_axm_max_offset;
|
||||||
memset(cwhdims, 0, sizeof(struct ct_whdims) * node->cindex);
|
size_t dims_axm_pos_offset, dims_axm_size_offset;
|
||||||
|
// size_t dims_axo_pos_offset, dims_axo_size_offset;
|
||||||
int axm_size, axm_free, axo_size;
|
|
||||||
size_t axm_min_offset, axm_max_offset;
|
|
||||||
if (node->axis == AXIS_X) {
|
if (node->axis == AXIS_X) {
|
||||||
axm_free = dims->width;
|
axm_free = dims->width;
|
||||||
axm_size = dims->width;
|
axm_size = dims->width;
|
||||||
axo_size = dims->height;
|
// axo_size = dims->height;
|
||||||
|
|
||||||
axm_min_offset = offsetof(struct ct_bounds, wmin);
|
bounds_axm_min_offset = offsetof(struct ct_bounds, wmin);
|
||||||
axm_max_offset = offsetof(struct ct_bounds, wmax);
|
bounds_axm_max_offset = offsetof(struct ct_bounds, wmax);
|
||||||
|
|
||||||
|
dims_axm_pos_offset = offsetof(struct ct_dims, x);
|
||||||
|
// dims_axo_pos_offset = offsetof(struct ct_dims, y);
|
||||||
|
dims_axm_size_offset = offsetof(struct ct_dims, width);
|
||||||
|
// dims_axo_size_offset = offsetof(struct ct_dims, height);
|
||||||
} else {
|
} else {
|
||||||
assert(node->axis == AXIS_Y);
|
assert(node->axis == AXIS_Y);
|
||||||
axm_free = dims->height;
|
axm_free = dims->height;
|
||||||
axm_size = dims->height;
|
axm_size = dims->height;
|
||||||
axo_size = dims->width;
|
// axo_size = dims->width;
|
||||||
|
|
||||||
axm_min_offset = offsetof(struct ct_bounds, hmin);
|
bounds_axm_min_offset = offsetof(struct ct_bounds, hmin);
|
||||||
axm_max_offset = offsetof(struct ct_bounds, hmax);
|
bounds_axm_max_offset = offsetof(struct ct_bounds, hmax);
|
||||||
|
|
||||||
|
dims_axm_pos_offset = offsetof(struct ct_dims, y);
|
||||||
|
// dims_axo_pos_offset = offsetof(struct ct_dims, x);
|
||||||
|
dims_axm_size_offset = offsetof(struct ct_dims, height);
|
||||||
|
// dims_axo_size_offset = offsetof(struct ct_dims, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
int split = axm_free / node->cindex;
|
struct ct_spdims cspdims[node->cindex];
|
||||||
for (int j = 0; j < node->cindex; j++) {
|
// struct ct_spdims *parts[node->cindex];
|
||||||
cwhdims[j].min = *(int*)(node->child[j]->surface->bounds + axm_min_offset);
|
cindex parts_n = node->cindex;
|
||||||
cwhdims[j].max = *(int*)(node->child[j]->surface->bounds + axm_max_offset);
|
memset(cspdims, 0, sizeof(struct ct_spdims) * node->cindex);
|
||||||
if (node->child[j]->surface->bounds->type == BOUND_RELATIVE) {
|
for (int i = 0; i < node->cindex; i++) {
|
||||||
cwhdims[j].min *= axm_size;
|
cspdims[i].min = *(int *)(node->child[i]->surface->bounds + bounds_axm_min_offset);
|
||||||
cwhdims[j].max *= axm_size;
|
cspdims[i].max = *(int *)(node->child[i]->surface->bounds + bounds_axm_max_offset);
|
||||||
|
if (node->child[i]->surface->bounds->type == BOUND_RELATIVE) {
|
||||||
|
cspdims[i].min *= axm_size;
|
||||||
|
cspdims[i].max *= axm_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
cwhdims[j].axm_size = fmax(fmin(split, cwhdims[j].max), cwhdims[j].min);
|
cspdims[i].axm_size = 0;
|
||||||
cwhdims[j].axo_size = axo_size;
|
// cspdims[i].axo_size = axo_size;
|
||||||
|
|
||||||
axm_free -= cwhdims[j].axm_size;
|
// parts[i] = &cspdims[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int delta;
|
int split, new_size;
|
||||||
while (axm_free) {
|
while (parts_n) {
|
||||||
if (axm_free < cunfixedn) {
|
split = axm_free / parts_n;
|
||||||
int progress = 0;
|
for (int i = 0; i < node->cindex; i++) {
|
||||||
for (int j = 0; j < node->cindex; j++) {
|
if (cspdims[i].fixed)
|
||||||
if (cwhdims[j].fixed)
|
|
||||||
continue;
|
|
||||||
cwhdims[j].axm_size--;
|
|
||||||
axm_free--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// split is guaranteed to be >0
|
|
||||||
split = axm_free / node->cindex;
|
|
||||||
for (int j = 0; j < node->cindex; j++) {
|
|
||||||
if (cwhdims[j].fixed)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
delta = cwhdims[j].axm_size - fmax(cwhdims[j].axm_size - split, bounds->wmin);
|
new_size =
|
||||||
if (delta == 0) {
|
clampi(cspdims[i].axm_size + split, cspdims[i].min, cspdims[i].max);
|
||||||
cwhdims[j].fixed = true;
|
if (new_size == cspdims[i].axm_size) {
|
||||||
cunfixedn++;
|
cspdims[i].fixed = true;
|
||||||
|
parts_n--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cwhdims[j].axm_size -= delta;
|
axm_free -= (new_size - cspdims[i].axm_size);
|
||||||
axm_free -= delta;
|
cspdims[i].axm_size = new_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: using axo_size this way means cspdims doesn't need an axo field!! */
|
||||||
|
struct ct_dims * cdims = dup_dims(dims);
|
||||||
|
/* NOTE: the statements below are done implicitly by dup_dims */
|
||||||
|
// *(int*)(cdims + dims_axm_pos_offset) = *(int*)(dims + dims_axm_pos_offset);
|
||||||
|
// *(int*)(cdims + dims_axo_pos_offset) = *(int*)(dims + dims_axo_pos_offset);
|
||||||
|
// *(int*)(cdims + dims_axo_size_offset) = axo_size;
|
||||||
|
for (int i = 0; i < node->cindex; i++) {
|
||||||
|
*(int*)(cdims + dims_axm_size_offset) = cspdims[i].axm_size;
|
||||||
|
resize_node(node->child[i], dup_dims(cdims));
|
||||||
|
*(int*)(cdims + dims_axm_pos_offset) += cspdims[i].axm_size;
|
||||||
|
}
|
||||||
|
free(cdims);
|
||||||
|
|
||||||
|
// int split = axm_free / node->cindex;
|
||||||
|
// for (int j = 0; j < node->cindex; j++) {
|
||||||
|
// cwhdims[j].min = *(int*)(node->child[j]->surface->bounds +
|
||||||
|
// axm_min_offset); cwhdims[j].max = *(int*)(node->child[j]->surface->bounds
|
||||||
|
// + axm_max_offset); if (node->child[j]->surface->bounds->type ==
|
||||||
|
// BOUND_RELATIVE) {
|
||||||
|
// cwhdims[j].min *= axm_size;
|
||||||
|
// cwhdims[j].max *= axm_size;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cwhdims[j].axm_size = fmax(fmin(split, cwhdims[j].max), cwhdims[j].min);
|
||||||
|
// cwhdims[j].axo_size = axo_size;
|
||||||
|
|
||||||
|
// axm_free -= cwhdims[j].axm_size;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// int delta;
|
||||||
|
// while (axm_free) {
|
||||||
|
// if (axm_free < cunfixedn) {
|
||||||
|
// int progress = 0;
|
||||||
|
// for (int j = 0; j < node->cindex; j++) {
|
||||||
|
// if (cwhdims[j].fixed)
|
||||||
|
// continue;
|
||||||
|
// cwhdims[j].axm_size--;
|
||||||
|
// axm_free--;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // split is guaranteed to be >0
|
||||||
|
// split = axm_free / node->cindex;
|
||||||
|
// for (int j = 0; j < node->cindex; j++) {
|
||||||
|
// if (cwhdims[j].fixed)
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// delta = cwhdims[j].axm_size - fmax(cwhdims[j].axm_size - split,
|
||||||
|
// bounds->wmin); if (delta == 0) {
|
||||||
|
// cwhdims[j].fixed = true;
|
||||||
|
// cunfixedn++;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cwhdims[j].axm_size -= delta;
|
||||||
|
// axm_free -= delta;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// bifurcate_dims(dims, node->axis, node->ratio, &dims0, &dims1);
|
// bifurcate_dims(dims, node->axis, node->ratio, &dims0, &dims1);
|
||||||
|
|
||||||
// resize_node(node->child[0], dims0);
|
// resize_node(node->child[0], dims0);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ struct ct_node *new_node(struct ct_dims *const dims,
|
||||||
struct ct_bounds *const bounds,
|
struct ct_bounds *const bounds,
|
||||||
struct ct_node *const parent);
|
struct ct_node *const parent);
|
||||||
void destroy_node(struct ct_node *const node);
|
void destroy_node(struct ct_node *const node);
|
||||||
void resize_node(struct ct_node *const node, struct ct_dims *const new_dims);
|
int resize_node(struct ct_node *const node, struct ct_dims *const new_dims);
|
||||||
|
|
||||||
void collapse_node(struct ct_node **const node, const int i,
|
void collapse_node(struct ct_node **const node, const int i,
|
||||||
const bool preserve_bounds);
|
const bool preserve_bounds);
|
||||||
|
|
|
||||||
11
cursetree/nsparted.c
Normal file
11
cursetree/nsparted.c
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "nsparted.h"
|
||||||
|
|
||||||
|
struct ct_nsparted init_nsparted(struct ct_node *const node,
|
||||||
|
struct ct_dims *const dims) {
|
||||||
|
struct ct_nsparted nsparted = (struct ct_nsparted) {
|
||||||
|
.node = node,
|
||||||
|
.dims = dims,
|
||||||
|
.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
26
cursetree/nsparted.h
Normal file
26
cursetree/nsparted.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef CURSETREE_NSPARTED_H
|
||||||
|
#define CURSETREE_NSPARTED_H
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
/* Surface Partition Dimensions */
|
||||||
|
struct ct_spdims {
|
||||||
|
// Main Axis & Orthogonal Axis Sizes
|
||||||
|
int axm_size, axo_size;
|
||||||
|
bool fixed;
|
||||||
|
int min, max;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Node Surface Partitioner */
|
||||||
|
struct ct_nsparted {
|
||||||
|
struct ct_node *const node;
|
||||||
|
struct ct_dims *const dims;
|
||||||
|
|
||||||
|
/* Child Surface Partition Dimensions */
|
||||||
|
struct ct_spdims *const cspdims;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ct_nsparted *init_nsparted(struct ct_node *const node,
|
||||||
|
struct ct_dims *const dims);
|
||||||
|
|
||||||
|
#endif /* CURSETREE_NSPARTED_H */
|
||||||
12
cursetree/util.h
Normal file
12
cursetree/util.h
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef CURSETREE_UTIL_H
|
||||||
|
#define CURSETREE_UTIL_H
|
||||||
|
|
||||||
|
static inline int clampi(int val, int min, int max) {
|
||||||
|
if (val > max)
|
||||||
|
return max;
|
||||||
|
else if (val < min)
|
||||||
|
return min;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CURSETREE_UTIL_H */
|
||||||
Loading…
Add table
Add a link
Reference in a new issue