示例#1
0
/* mode = 0: interpolate normals,
 * mode = 1: interpolate coord */
static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
{
	int x0, x1, y0, y1;
	float u, v;
	float data[4][3];

	x0 = (int) crn_x;
	x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1);

	y0 = (int) crn_y;
	y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1);

	u = crn_x - x0;
	v = crn_y - y0;

	if (mode == 0) {
		copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0));
		copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0));
		copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1));
		copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1));
	}
	else {
		copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0));
		copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0));
		copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1));
		copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1));
	}

	interp_bilinear_quad_v3(data, u, v, res);
}
示例#2
0
BLI_INLINE void multires_reshape_propagate_init_patch_corners(
    MultiresPropagateData *data,
    CCGElem *delta_grid,
    const int patch_x,
    const int patch_y,
    MultiresPropagateCornerData r_corners[4])
{
  CCGKey *delta_level_key = &data->top_level_key;
  const int orig_grid_size = data->reshape_grid_size;
  const int top_grid_size = data->top_grid_size;
  const int skip = (top_grid_size - 1) / (orig_grid_size - 1);
  const int x = patch_x * skip;
  const int y = patch_y * skip;
  /* Store coordinate deltas. */
  copy_v3_v3(r_corners[0].coord_delta, CCG_grid_elem_co(delta_level_key, delta_grid, x, y));
  copy_v3_v3(r_corners[1].coord_delta, CCG_grid_elem_co(delta_level_key, delta_grid, x + skip, y));
  copy_v3_v3(r_corners[2].coord_delta, CCG_grid_elem_co(delta_level_key, delta_grid, x, y + skip));
  copy_v3_v3(r_corners[3].coord_delta,
             CCG_grid_elem_co(delta_level_key, delta_grid, x + skip, y + skip));
  if (delta_level_key->has_mask) {
    r_corners[0].mask_delta = *CCG_grid_elem_mask(delta_level_key, delta_grid, x, y);
    r_corners[1].mask_delta = *CCG_grid_elem_mask(delta_level_key, delta_grid, x + skip, y);
    r_corners[2].mask_delta = *CCG_grid_elem_mask(delta_level_key, delta_grid, x, y + skip);
    r_corners[3].mask_delta = *CCG_grid_elem_mask(delta_level_key, delta_grid, x + skip, y + skip);
  }
}
示例#3
0
/* Apply smoothed deltas on the actual data layers. */
static void multires_reshape_propagate_apply_delta(MultiresPropagateData *data,
                                                   CCGElem **delta_grids_data)
{
  const int num_grids = data->num_grids;
  /* At this point those custom data layers has updated data for the
   * level we are propagating from. */
  MDisps *mdisps = data->mdisps;
  GridPaintMask *grid_paint_mask = data->grid_paint_mask;
  CCGKey *orig_key = &data->reshape_level_key;
  CCGKey *delta_level_key = &data->top_level_key;
  CCGElem **orig_grids_data = data->orig_grids_data;
  const int orig_grid_size = data->reshape_grid_size;
  const int top_grid_size = data->top_grid_size;
  const int skip = (top_grid_size - 1) / (orig_grid_size - 1);
  /* Restore grid values at the reshape level. Those values are to be changed
   * to the accommodate for the smooth delta. */
  for (int grid_index = 0; grid_index < num_grids; grid_index++) {
    CCGElem *orig_grid = orig_grids_data[grid_index];
    for (int y = 0; y < orig_grid_size; y++) {
      const int top_y = y * skip;
      for (int x = 0; x < orig_grid_size; x++) {
        const int top_x = x * skip;
        const int top_index = top_y * top_grid_size + top_x;
        copy_v3_v3(mdisps[grid_index].disps[top_index],
                   CCG_grid_elem_co(orig_key, orig_grid, x, y));
        if (grid_paint_mask != NULL) {
          grid_paint_mask[grid_index].data[top_index] = *CCG_grid_elem_mask(
              orig_key, orig_grid, x, y);
        }
      }
    }
  }
  /* Add smoothed delta to all the levels. */
  for (int grid_index = 0; grid_index < num_grids; grid_index++) {
    CCGElem *delta_grid = delta_grids_data[grid_index];
    for (int y = 0; y < top_grid_size; y++) {
      for (int x = 0; x < top_grid_size; x++) {
        const int top_index = y * top_grid_size + x;
        add_v3_v3(mdisps[grid_index].disps[top_index],
                  CCG_grid_elem_co(delta_level_key, delta_grid, x, y));
        if (delta_level_key->has_mask) {
          grid_paint_mask[grid_index].data[top_index] += *CCG_grid_elem_mask(
              delta_level_key, delta_grid, x, y);
        }
      }
    }
  }
}
示例#4
0
BLI_INLINE void multires_reshape_propagate_and_smooth_delta_grid_patch(MultiresPropagateData *data,
                                                                       CCGElem *delta_grid,
                                                                       const int patch_x,
                                                                       const int patch_y)
{
  CCGKey *delta_level_key = &data->top_level_key;
  const int orig_grid_size = data->reshape_grid_size;
  const int top_grid_size = data->top_grid_size;
  const int skip = (top_grid_size - 1) / (orig_grid_size - 1);
  const float skip_inv = 1.0f / (float)skip;
  MultiresPropagateCornerData corners[4];
  multires_reshape_propagate_init_patch_corners(data, delta_grid, patch_x, patch_y, corners);
  const int start_x = patch_x * skip;
  const int start_y = patch_y * skip;
  for (int y = 0; y <= skip; y++) {
    const float v = (float)y * skip_inv;
    const int final_y = start_y + y;
    for (int x = 0; x <= skip; x++) {
      const float u = (float)x * skip_inv;
      const int final_x = start_x + x;
      const float linear_weights[4] = {
          (1.0f - u) * (1.0f - v), u * (1.0f - v), (1.0f - u) * v, u * v};
      multires_reshape_propagate_interpolate_coord(
          CCG_grid_elem_co(delta_level_key, delta_grid, final_x, final_y),
          corners,
          linear_weights);
      if (delta_level_key->has_mask) {
        float *mask = CCG_grid_elem_mask(delta_level_key, delta_grid, final_x, final_y);
        *mask = multires_reshape_propagate_interpolate_mask(corners, linear_weights);
      }
    }
  }
}
示例#5
0
static void multires_reshape_store_original_grids(MultiresPropagateData *data)
{
  const int num_grids = data->num_grids;
  /* Original data to be backed up. */
  const MDisps *mdisps = data->mdisps;
  const GridPaintMask *grid_paint_mask = data->grid_paint_mask;
  /* Allocate grids for backup. */
  CCGKey *orig_key = &data->reshape_level_key;
  CCGElem **orig_grids_data = allocate_grids(orig_key, num_grids);
  /* Fill in grids. */
  const int orig_grid_size = data->reshape_grid_size;
  const int top_grid_size = data->top_grid_size;
  const int skip = (top_grid_size - 1) / (orig_grid_size - 1);
  for (int grid_index = 0; grid_index < num_grids; grid_index++) {
    CCGElem *orig_grid = orig_grids_data[grid_index];
    for (int y = 0; y < orig_grid_size; y++) {
      const int top_y = y * skip;
      for (int x = 0; x < orig_grid_size; x++) {
        const int top_x = x * skip;
        const int top_index = top_y * top_grid_size + top_x;
        memcpy(CCG_grid_elem_co(orig_key, orig_grid, x, y),
               mdisps[grid_index].disps[top_index],
               sizeof(float) * 3);
        if (orig_key->has_mask) {
          *CCG_grid_elem_mask(
              orig_key, orig_grid, x, y) = grid_paint_mask[grid_index].data[top_index];
        }
      }
    }
  }
  /* Store in the context. */
  data->orig_grids_data = orig_grids_data;
}
示例#6
0
static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
{
	DerivedMesh *hidm = bkr->hires_dm;
	RayObject *raytree;
	RayFace *face;
	CCGElem **grid_data;
	CCGKey key;
	int num_grids, grid_size /*, face_side */, num_faces;
	int i;

	num_grids = hidm->getNumGrids(hidm);
	grid_size = hidm->getGridSize(hidm);
	grid_data = hidm->getGridData(hidm);
	hidm->getGridKey(hidm, &key);

	/* face_side = (grid_size << 1) - 1; */  /* UNUSED */
	num_faces = num_grids * (grid_size - 1) * (grid_size - 1);

	raytree = ao_data->raytree = RE_rayobject_create(bkr->raytrace_structure, num_faces, bkr->octree_resolution);
	face = ao_data->rayfaces = (RayFace *) MEM_callocN(num_faces * sizeof(RayFace), "ObjectRen faces");

	for (i = 0; i < num_grids; i++) {
		int x, y;
		for (x = 0; x < grid_size - 1; x++) {
			for (y = 0; y < grid_size - 1; y++) {
				float co[4][3];

				copy_v3_v3(co[0], CCG_grid_elem_co(&key, grid_data[i], x, y));
				copy_v3_v3(co[1], CCG_grid_elem_co(&key, grid_data[i], x, y + 1));
				copy_v3_v3(co[2], CCG_grid_elem_co(&key, grid_data[i], x + 1, y + 1));
				copy_v3_v3(co[3], CCG_grid_elem_co(&key, grid_data[i], x + 1, y));

				RE_rayface_from_coords(face, ao_data, face, co[0], co[1], co[2], co[3]);
				RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face));

				face++;
			}
		}
	}

	RE_rayobject_done(raytree);
}
示例#7
0
/* Calculate delta of changed reshape level data layers. Delta goes to a
 * grids at top level (meaning, the result grids are only partially filled
 * in). */
static void multires_reshape_calculate_delta(MultiresPropagateData *data,
                                             CCGElem **delta_grids_data)
{
  const int num_grids = data->num_grids;
  /* At this point those custom data layers has updated data for the
   * level we are propagating from. */
  const MDisps *mdisps = data->mdisps;
  const GridPaintMask *grid_paint_mask = data->grid_paint_mask;
  CCGKey *reshape_key = &data->reshape_level_key;
  CCGKey *delta_level_key = &data->top_level_key;
  /* Calculate delta. */
  const int top_grid_size = data->top_grid_size;
  const int reshape_grid_size = data->reshape_grid_size;
  const int delta_grid_size = data->top_grid_size;
  const int skip = (top_grid_size - 1) / (reshape_grid_size - 1);
  for (int grid_index = 0; grid_index < num_grids; grid_index++) {
    /*const*/ CCGElem *orig_grid = data->orig_grids_data[grid_index];
    CCGElem *delta_grid = delta_grids_data[grid_index];
    for (int y = 0; y < reshape_grid_size; y++) {
      const int top_y = y * skip;
      for (int x = 0; x < reshape_grid_size; x++) {
        const int top_x = x * skip;
        const int top_index = top_y * delta_grid_size + top_x;
        sub_v3_v3v3(CCG_grid_elem_co(delta_level_key, delta_grid, top_x, top_y),
                    mdisps[grid_index].disps[top_index],
                    CCG_grid_elem_co(reshape_key, orig_grid, x, y));
        if (delta_level_key->has_mask) {
          const float old_mask_value = *CCG_grid_elem_mask(reshape_key, orig_grid, x, y);
          const float new_mask_value = grid_paint_mask[grid_index].data[top_index];
          *CCG_grid_elem_mask(delta_level_key, delta_grid, top_x, top_y) = new_mask_value -
                                                                           old_mask_value;
        }
      }
    }
  }
}