Exemplo n.º 1
0
/* 
 * convert slicing tree into actual floorplan
 * returns the number of dead blocks compacted
 */
int tree_to_flp(tree_node_t *root, flp_t *flp, int compact_dead, 
				double compact_ratio)
{
	/* for now, only choose the floorplan with
	 * the minimum area regardless of the overall
	 * aspect ratio
	 */
	int pos = min_area_pos(root->curve);
	#if VERBOSE > 1									  
	double compacted_area = 0.0;
	#endif								  
	int dead_count = recursive_sizing(root, pos, 0.0, 0.0, 0, 
					 				  compact_dead, compact_ratio,
	#if VERBOSE > 1									  
									  &compacted_area,
	#endif								  
									  flp);
					 
	int compacted = (flp->n_units - 1) / 2 - dead_count;
	flp->n_units -= compacted;
	#if VERBOSE > 1
	fprintf(stdout, "%d dead blocks, %.2f%% of the core compacted\n", compacted, 
			compacted_area / (get_total_area(flp)-compacted_area) * 100);
	#endif
	return compacted;
}
Exemplo n.º 2
0
/* 
 * recursive sizing - given the slicing tree containing
 * the added up shape curves. 'pos' denotes the current
 * added up orientation. 'leftx' & 'bottomy' denote the
 * left and bottom ends of the current bounding rectangle
 */
int recursive_sizing (tree_node_t *node, int pos, 
					   double leftx, double bottomy,
					   int dead_count, int compact_dead,
					   double compact_ratio,
#if VERBOSE > 1					   
					   double *compacted_area, 
#endif					   
					   flp_t *flp)
{
	/* leaf node. fill the placeholder	*/
	if (node->label.unit >= 0) {
		flp->units[node->label.unit].width = node->curve->x[pos];
		flp->units[node->label.unit].height = node->curve->y[pos];
		flp->units[node->label.unit].leftx = leftx;
		flp->units[node->label.unit].bottomy = bottomy;
	} else {
		/* shortcuts */
		int idx;
		double x1, x2, y1, y2;

		/* location of the first dead block	+ offset */
		idx = (flp->n_units + 1) / 2 + dead_count;

		x1 = node->left->curve->x[node->curve->left_pos[pos]];
		x2 = node->right->curve->x[node->curve->right_pos[pos]];
		y1 = node->left->curve->y[node->curve->left_pos[pos]];
		y2 = node->right->curve->y[node->curve->right_pos[pos]];

		/* add a dead block - possibly of zero area	*/
		if (node->label.unit == CUT_VERTICAL) {
			flp->units[idx].width = (y2 >= y1) ? x1 : x2;
			flp->units[idx].height = fabs(y2 - y1);
			flp->units[idx].leftx = leftx + ((y2 >= y1) ? 0 : x1);
			flp->units[idx].bottomy = bottomy + MIN(y1, y2);
			/* 
			 * ignore dead blocks smaller than compact_ratio times the area
			 * of the smaller of the constituent rectangles. instead, increase
			 * the size of the rectangle by that amount
			 */
			if (compact_dead && fabs(y2-y1) / MIN(y1, y2) < compact_ratio) {
				#if VERBOSE > 1
				*compacted_area += (flp->units[idx].width * flp->units[idx].height);
				#endif
				if (y2 >= y1) 
					node->left->curve->y[node->curve->left_pos[pos]] = y2;
				else
					node->right->curve->y[node->curve->right_pos[pos]] = y1;
			} else {
				dead_count++;
			}

			/* left and bottom don't change for the left child	*/
			dead_count = recursive_sizing(node->left, node->curve->left_pos[pos],
										 leftx, bottomy, dead_count, compact_dead, 
										 compact_ratio,
			#if VERBOSE > 1
										 compacted_area,
			#endif
										 flp);
			dead_count = recursive_sizing(node->right, node->curve->right_pos[pos],
										 leftx + node->curve->median[pos], bottomy, 
										 dead_count, compact_dead, compact_ratio,
			#if VERBOSE > 1
										 compacted_area,
			#endif
										 flp);
		} else {
			flp->units[idx].width = fabs(x2 - x1);
			flp->units[idx].height = (x2 >= x1) ? y1 : y2;
			flp->units[idx].leftx = leftx + MIN(x1, x2);
			flp->units[idx].bottomy = bottomy + ((x2 >= x1) ? 0 : y1);
			if (compact_dead && fabs(x2-x1) / MIN(x1, x2) < compact_ratio) {
				#if VERBOSE > 1
				*compacted_area += (flp->units[idx].width * flp->units[idx].height);
				#endif
				if (x2 >= x1) 
					node->left->curve->x[node->curve->left_pos[pos]] = x2;
				else
					node->right->curve->x[node->curve->right_pos[pos]] = x1;
			} else {
				dead_count++;
			}

			/* left and bottom don't change for the bottom child	*/
			dead_count = recursive_sizing(node->left, node->curve->left_pos[pos],
										 leftx, bottomy, dead_count, compact_dead, 
										 compact_ratio,
			#if VERBOSE > 1
										 compacted_area,
			#endif
										 flp);
			dead_count = recursive_sizing(node->right, node->curve->right_pos[pos],
							 			 leftx, bottomy + node->curve->median[pos], 
										 dead_count, compact_dead, compact_ratio,
			#if VERBOSE > 1
										 compacted_area,
			#endif
										 flp);
		}
	}
	return dead_count;
}
Exemplo n.º 3
0
Arquivo: shape.c Projeto: bugamn/esesc
/* 
 * recursive sizing - given the slicing tree containing
 * the added up shape curves. 'pos' denotes the current
 * added up orientation. 'leftx' & 'bottomy' denote the
 * left and bottom ends of the current bounding rectangle
 */
int recursive_sizing (tree_node_t *node, int pos, 
					   double leftx, double bottomy,
					   int dead_count, int compact_dead,
					   double compact_ratio,
#if VERBOSE > 1					   
					   double *compacted_area, 
#endif					   
					   flp_t *flp)
{
	/* shortcut	*/
	shape_t *self = node->curve;

	/* leaf node. fill the placeholder	*/
	if (node->label.unit >= 0) {
		flp->units[node->label.unit].width = self->x[pos];
		flp->units[node->label.unit].height = self->y[pos];
		flp->units[node->label.unit].leftx = leftx;
		flp->units[node->label.unit].bottomy = bottomy;
	} else {
		/* shortcuts */
		int idx;
		double x1, x2, y1, y2;
		shape_t *left = node->left->curve;
		shape_t *right = node->right->curve;

		/* location of the first dead block	+ offset */
		idx = (flp->n_units + 1) / 2 + dead_count;

		x1 = left->x[self->left_pos[pos]];
		x2 = right->x[self->right_pos[pos]];
		y1 = left->y[self->left_pos[pos]];
		y2 = right->y[self->right_pos[pos]];

		/* add a dead block - possibly of zero area	*/
		if (node->label.unit == CUT_VERTICAL) {
			/* 
			 * if a dead block has been previously compacted away from this
			 * bounding rectangle, absorb that area into the child also
			 */
			if(self->y[pos] > MAX(y1, y2)) {
				left->y[self->left_pos[pos]] += (self->y[pos] - MAX(y1, y2));
				right->y[self->right_pos[pos]] += (self->y[pos] - MAX(y1, y2));
				y1 = left->y[self->left_pos[pos]];
				y2 = right->y[self->right_pos[pos]];
			}	
			if(self->x[pos] > (x1+x2)) {
				right->x[self->right_pos[pos]] += self->x[pos]-(x1+x2);
				x2 = right->x[self->right_pos[pos]];
			}	

			flp->units[idx].width = (y2 >= y1) ? x1 : x2;
			flp->units[idx].height = fabs(y2 - y1);
			flp->units[idx].leftx = leftx + ((y2 >= y1) ? 0 : x1);
			flp->units[idx].bottomy = bottomy + MIN(y1, y2);

			/* 
			 * ignore dead blocks smaller than compact_ratio times the area
			 * of the smaller of the constituent rectangles. instead, increase
			 * the size of the rectangle by that amount
			 */
			if (compact_dead && fabs(y2-y1) / MIN(y1, y2) <= compact_ratio) {
				#if VERBOSE > 1
				*compacted_area += (flp->units[idx].width * flp->units[idx].height);
				#endif
				if (y2 >= y1) 
					left->y[self->left_pos[pos]] = y2;
				else
					right->y[self->right_pos[pos]] = y1;
			} else {
				dead_count++;
			}

			/* left and bottom don't change for the left child	*/
			dead_count = recursive_sizing(node->left, self->left_pos[pos],
										 leftx, bottomy, dead_count, compact_dead, 
										 compact_ratio,
			#if VERBOSE > 1
										 compacted_area,
			#endif
										 flp);
			dead_count = recursive_sizing(node->right, self->right_pos[pos],
										 leftx + self->median[pos], bottomy, 
										 dead_count, compact_dead, compact_ratio,
			#if VERBOSE > 1
										 compacted_area,
			#endif
										 flp);
		} else {
			if(self->x[pos] > MAX(x1, x2)) {
				left->x[self->left_pos[pos]] += (self->x[pos] - MAX(x1, x2));
				right->x[self->right_pos[pos]] += (self->x[pos] - MAX(x1, x2));
				x1 = left->x[self->left_pos[pos]];
				x2 = right->x[self->right_pos[pos]];
			}	
			if(self->y[pos] > (y1+y2)) {
				right->y[self->right_pos[pos]] += self->y[pos]-(y1+y2);
				y2 = right->y[self->right_pos[pos]];
			}	

			flp->units[idx].width = fabs(x2 - x1);
			flp->units[idx].height = (x2 >= x1) ? y1 : y2;
			flp->units[idx].leftx = leftx + MIN(x1, x2);
			flp->units[idx].bottomy = bottomy + ((x2 >= x1) ? 0 : y1);

			if (compact_dead && fabs(x2-x1) / MIN(x1, x2) <= compact_ratio) {
				#if VERBOSE > 1
				*compacted_area += (flp->units[idx].width * flp->units[idx].height);
				#endif
				if (x2 >= x1) 
					left->x[self->left_pos[pos]] = x2;
				else
					right->x[self->right_pos[pos]] = x1;
			} else {
				dead_count++;
			}

			/* left and bottom don't change for the left child	*/
			dead_count = recursive_sizing(node->left, self->left_pos[pos],
										 leftx, bottomy, dead_count, compact_dead, 
										 compact_ratio,
			#if VERBOSE > 1
										 compacted_area,
			#endif
										 flp);
			dead_count = recursive_sizing(node->right, self->right_pos[pos],
							 			 leftx, bottomy + self->median[pos], 
										 dead_count, compact_dead, compact_ratio,
			#if VERBOSE > 1
										 compacted_area,
			#endif
										 flp);
		}
	}
	return dead_count;
}