Cleanup: Use C++ arrays to store subdiv ccg data
Decrease the amount of manual memory management and pointer arithmetic.
This commit is contained in:
@@ -216,12 +216,11 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh);
|
||||
* Do a full rebuild with on Grids data structure.
|
||||
*/
|
||||
void BKE_pbvh_build_grids(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
int totgrid,
|
||||
blender::Span<CCGElem *> grids,
|
||||
CCGKey *key,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
unsigned int **grid_hidden,
|
||||
blender::Span<DMFlagMat> flagmats,
|
||||
blender::Span<BLI_bitmap *> grid_hidden,
|
||||
Mesh *me,
|
||||
SubdivCCG *subdiv_ccg);
|
||||
/**
|
||||
@@ -333,14 +332,14 @@ void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3]);
|
||||
/**
|
||||
* Multi-res hidden data, only valid for type == PBVH_GRIDS.
|
||||
*/
|
||||
unsigned int **BKE_pbvh_grid_hidden(const PBVH *pbvh);
|
||||
blender::Span<const BLI_bitmap *> BKE_pbvh_get_grid_visibility(const PBVH *pbvh);
|
||||
|
||||
void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *me);
|
||||
|
||||
/**
|
||||
* Returns the number of visible quads in the nodes' grids.
|
||||
*/
|
||||
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
|
||||
int BKE_pbvh_count_grid_quads(blender::Span<const BLI_bitmap *> grid_hidden,
|
||||
const int *grid_indices,
|
||||
int totgrid,
|
||||
int gridsize,
|
||||
@@ -351,8 +350,7 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
|
||||
*/
|
||||
const CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh);
|
||||
|
||||
CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh);
|
||||
BLI_bitmap **BKE_pbvh_get_grid_visibility(const PBVH *pbvh);
|
||||
blender::Span<CCGElem *> BKE_pbvh_get_grids(const PBVH *pbvh);
|
||||
int BKE_pbvh_get_grid_num_verts(const PBVH *pbvh);
|
||||
int BKE_pbvh_get_grid_num_faces(const PBVH *pbvh);
|
||||
|
||||
@@ -405,7 +403,7 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh,
|
||||
int *totgrid,
|
||||
int *maxgrid,
|
||||
int *gridsize,
|
||||
CCGElem ***r_griddata);
|
||||
CCGElem *const **r_griddata);
|
||||
void BKE_pbvh_node_num_verts(const PBVH *pbvh,
|
||||
const PBVHNode *node,
|
||||
int *r_uniquevert,
|
||||
@@ -463,10 +461,10 @@ blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
|
||||
blender::Span<const PBVHNode *> nodes,
|
||||
blender::IndexMaskMemory &memory);
|
||||
void BKE_pbvh_grids_update(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
blender::Span<CCGElem *> grids,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
unsigned int **grid_hidden,
|
||||
blender::Span<DMFlagMat> flagmats,
|
||||
blender::Span<BLI_bitmap *> grid_hidden,
|
||||
CCGKey *key);
|
||||
void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, SubdivCCG *subdiv_ccg);
|
||||
|
||||
@@ -505,9 +503,9 @@ struct PBVHVertexIter {
|
||||
|
||||
/* grid */
|
||||
CCGKey key;
|
||||
CCGElem **grids;
|
||||
CCGElem *const *grids;
|
||||
CCGElem *grid;
|
||||
BLI_bitmap **grid_hidden, *gh;
|
||||
BLI_bitmap *const *grid_hidden, *gh;
|
||||
const int *grid_indices;
|
||||
int totgrid;
|
||||
int gridsize;
|
||||
|
||||
@@ -132,10 +132,9 @@ struct SubdivCCG {
|
||||
*/
|
||||
/* Indexed by a grid index, points to a grid data which is stored in
|
||||
* grids_storage. */
|
||||
CCGElem **grids = nullptr;
|
||||
blender::Array<CCGElem *> grids;
|
||||
/* Flat array of all grids' data. */
|
||||
unsigned char *grids_storage = nullptr;
|
||||
int num_grids = -1;
|
||||
blender::Array<uchar> grids_storage;
|
||||
/* Loose edges, each array element contains grid_size elements
|
||||
* corresponding to vertices created by subdividing coarse edges. */
|
||||
CCGElem **edges = nullptr;
|
||||
@@ -157,25 +156,22 @@ struct SubdivCCG {
|
||||
int mask_offset = -1;
|
||||
|
||||
/* Faces from which grids are emitted. */
|
||||
int num_faces = -1;
|
||||
SubdivCCGFace *faces = nullptr;
|
||||
blender::Array<SubdivCCGFace> faces;
|
||||
/* Indexed by grid index, points to corresponding face from `faces`. */
|
||||
blender::Array<int> grid_to_face_map;
|
||||
|
||||
/* Edges which are adjacent to faces.
|
||||
* Used for faster grid stitching, in the cost of extra memory.
|
||||
*/
|
||||
int num_adjacent_edges = -1;
|
||||
SubdivCCGAdjacentEdge *adjacent_edges = nullptr;
|
||||
blender::Array<SubdivCCGAdjacentEdge> adjacent_edges;
|
||||
|
||||
/* Vertices which are adjacent to faces
|
||||
* Used for faster grid stitching, in the cost of extra memory.
|
||||
*/
|
||||
int num_adjacent_vertices = -1;
|
||||
SubdivCCGAdjacentVertex *adjacent_vertices = nullptr;
|
||||
blender::Array<SubdivCCGAdjacentVertex> adjacent_verts;
|
||||
|
||||
DMFlagMat *grid_flag_mats = nullptr;
|
||||
BLI_bitmap **grid_hidden = nullptr;
|
||||
blender::Array<DMFlagMat> grid_flag_mats;
|
||||
blender::Array<BLI_bitmap *> grid_hidden;
|
||||
|
||||
/* TODO(sergey): Consider adding some accessors to a "decoded" geometry,
|
||||
* to make integration with draw manager and such easy.
|
||||
@@ -198,7 +194,7 @@ struct SubdivCCG {
|
||||
/* Cached values, are not supposed to be accessed directly. */
|
||||
struct {
|
||||
/* Indexed by face, indicates index of the first grid which corresponds to the face. */
|
||||
int *start_face_grid_index = nullptr;
|
||||
blender::Array<int> start_face_grid_index;
|
||||
} cache_;
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ bool multires_reshape_assign_final_coords_from_ccg(const MultiresReshapeContext
|
||||
const int reshape_grid_size = reshape_context->reshape.grid_size;
|
||||
const float reshape_grid_size_1_inv = 1.0f / (float(reshape_grid_size) - 1.0f);
|
||||
|
||||
int num_grids = subdiv_ccg->num_grids;
|
||||
int num_grids = subdiv_ccg->grids.size();
|
||||
for (int grid_index = 0; grid_index < num_grids; ++grid_index) {
|
||||
CCGElem *ccg_grid = subdiv_ccg->grids[grid_index];
|
||||
for (int y = 0; y < reshape_grid_size; ++y) {
|
||||
|
||||
@@ -2150,7 +2150,7 @@ void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
|
||||
/* Nothing is hidden, so we can just remove all visibility bitmaps. */
|
||||
for (const int i : IndexRange(subdiv_ccg->num_grids)) {
|
||||
for (const int i : subdiv_ccg->grid_hidden.index_range()) {
|
||||
BKE_subdiv_ccg_grid_hidden_free(*subdiv_ccg, i);
|
||||
}
|
||||
return;
|
||||
@@ -2217,7 +2217,6 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
|
||||
|
||||
BKE_pbvh_build_grids(pbvh,
|
||||
subdiv_ccg->grids,
|
||||
subdiv_ccg->num_grids,
|
||||
&key,
|
||||
subdiv_ccg->grid_to_face_map,
|
||||
subdiv_ccg->grid_flag_mats,
|
||||
|
||||
@@ -254,7 +254,7 @@ static int partition_indices_material(
|
||||
PBVH *pbvh, const int *material_indices, const bool *sharp_faces, int lo, int hi)
|
||||
{
|
||||
const Span<int> looptri_faces = pbvh->looptri_faces;
|
||||
const DMFlagMat *flagmats = pbvh->grid_flag_mats;
|
||||
const Span<DMFlagMat> flagmats = pbvh->grid_flag_mats;
|
||||
MutableSpan<int> indices = pbvh->prim_indices;
|
||||
int i = lo, j = hi;
|
||||
|
||||
@@ -374,7 +374,7 @@ static void update_vb(PBVH *pbvh, PBVHNode *node, const Span<BBC> prim_bbc, int
|
||||
node->orig_vb = node->vb;
|
||||
}
|
||||
|
||||
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
|
||||
int BKE_pbvh_count_grid_quads(const Span<const BLI_bitmap *> grid_hidden,
|
||||
const int *grid_indices,
|
||||
int totgrid,
|
||||
int gridsize,
|
||||
@@ -661,7 +661,6 @@ static void pbvh_draw_args_init(const Mesh &mesh, PBVH *pbvh, PBVH_GPU_Args *arg
|
||||
memset((void *)args, 0, sizeof(*args));
|
||||
|
||||
args->pbvh_type = pbvh->header.type;
|
||||
args->mesh_grids_num = pbvh->totgrid;
|
||||
args->node = node;
|
||||
|
||||
args->grid_hidden = pbvh->grid_hidden;
|
||||
@@ -707,7 +706,6 @@ static void pbvh_draw_args_init(const Mesh &mesh, PBVH *pbvh, PBVH_GPU_Args *arg
|
||||
args->subdiv_ccg = pbvh->subdiv_ccg;
|
||||
args->faces = pbvh->faces;
|
||||
|
||||
args->mesh_grids_num = pbvh->totgrid;
|
||||
args->grids = pbvh->grids;
|
||||
args->grid_flag_mats = pbvh->grid_flag_mats;
|
||||
args->vert_normals = pbvh->vert_normals;
|
||||
@@ -900,12 +898,11 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh)
|
||||
}
|
||||
|
||||
void BKE_pbvh_build_grids(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
int totgrid,
|
||||
const Span<CCGElem *> grids,
|
||||
CCGKey *key,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
BLI_bitmap **grid_hidden,
|
||||
const Span<int> grid_to_face_map,
|
||||
const Span<DMFlagMat> flagmats,
|
||||
const Span<BLI_bitmap *> grid_hidden,
|
||||
Mesh *me,
|
||||
SubdivCCG *subdiv_ccg)
|
||||
{
|
||||
@@ -915,7 +912,6 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
||||
pbvh->grids = grids;
|
||||
pbvh->grid_to_face_map = grid_to_face_map;
|
||||
pbvh->grid_flag_mats = flagmats;
|
||||
pbvh->totgrid = totgrid;
|
||||
pbvh->gridkey = *key;
|
||||
pbvh->grid_hidden = grid_hidden;
|
||||
pbvh->subdiv_ccg = subdiv_ccg;
|
||||
@@ -946,11 +942,11 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
||||
pbvh->mesh = me;
|
||||
|
||||
/* For each grid, store the AABB and the AABB centroid */
|
||||
blender::Array<BBC> prim_bbc(totgrid);
|
||||
blender::Array<BBC> prim_bbc(grids.size());
|
||||
BB cb;
|
||||
BB_reset(&cb);
|
||||
cb = blender::threading::parallel_reduce(
|
||||
blender::IndexRange(totgrid),
|
||||
grids.index_range(),
|
||||
1024,
|
||||
cb,
|
||||
[&](const blender::IndexRange range, const BB &init) {
|
||||
@@ -973,12 +969,12 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
||||
return current;
|
||||
});
|
||||
|
||||
if (totgrid) {
|
||||
if (!grids.is_empty()) {
|
||||
const int *material_indices = static_cast<const int *>(
|
||||
CustomData_get_layer_named(&me->face_data, CD_PROP_INT32, "material_index"));
|
||||
const bool *sharp_faces = (const bool *)CustomData_get_layer_named(
|
||||
&me->face_data, CD_PROP_BOOL, "sharp_face");
|
||||
pbvh_build(pbvh, material_indices, sharp_faces, &cb, prim_bbc, totgrid);
|
||||
pbvh_build(pbvh, material_indices, sharp_faces, &cb, prim_bbc, grids.size());
|
||||
|
||||
#ifdef TEST_PBVH_FACE_SPLIT
|
||||
test_face_boundaries(pbvh);
|
||||
@@ -1602,18 +1598,17 @@ static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node)
|
||||
|
||||
static void pbvh_grids_node_visibility_update(PBVH *pbvh, PBVHNode *node)
|
||||
{
|
||||
CCGElem **grids;
|
||||
BLI_bitmap **grid_hidden;
|
||||
CCGElem *const *grids;
|
||||
const int *grid_indices;
|
||||
int totgrid, i;
|
||||
|
||||
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids);
|
||||
grid_hidden = BKE_pbvh_grid_hidden(pbvh);
|
||||
const Span<const BLI_bitmap *> grid_hidden = BKE_pbvh_get_grid_visibility(pbvh);
|
||||
CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
|
||||
|
||||
for (i = 0; i < totgrid; i++) {
|
||||
int g = grid_indices[i], x, y;
|
||||
BLI_bitmap *gh = grid_hidden[g];
|
||||
const BLI_bitmap *gh = grid_hidden[g];
|
||||
|
||||
if (!gh) {
|
||||
BKE_pbvh_node_fully_hidden_set(node, false);
|
||||
@@ -1755,7 +1750,7 @@ void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3])
|
||||
copy_v3_v3(max, bb->bmax);
|
||||
}
|
||||
|
||||
BLI_bitmap **BKE_pbvh_grid_hidden(const PBVH *pbvh)
|
||||
Span<const BLI_bitmap *> BKE_pbvh_get_grid_visibility(const PBVH *pbvh)
|
||||
{
|
||||
BLI_assert(pbvh->header.type == PBVH_GRIDS);
|
||||
return pbvh->grid_hidden;
|
||||
@@ -1767,28 +1762,22 @@ const CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh)
|
||||
return &pbvh->gridkey;
|
||||
}
|
||||
|
||||
CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh)
|
||||
Span<CCGElem *> BKE_pbvh_get_grids(const PBVH *pbvh)
|
||||
{
|
||||
BLI_assert(pbvh->header.type == PBVH_GRIDS);
|
||||
return pbvh->grids;
|
||||
}
|
||||
|
||||
BLI_bitmap **BKE_pbvh_get_grid_visibility(const PBVH *pbvh)
|
||||
{
|
||||
BLI_assert(pbvh->header.type == PBVH_GRIDS);
|
||||
return pbvh->grid_hidden;
|
||||
}
|
||||
|
||||
int BKE_pbvh_get_grid_num_verts(const PBVH *pbvh)
|
||||
{
|
||||
BLI_assert(pbvh->header.type == PBVH_GRIDS);
|
||||
return pbvh->totgrid * pbvh->gridkey.grid_area;
|
||||
return pbvh->grids.size() * pbvh->gridkey.grid_area;
|
||||
}
|
||||
|
||||
int BKE_pbvh_get_grid_num_faces(const PBVH *pbvh)
|
||||
{
|
||||
BLI_assert(pbvh->header.type == PBVH_GRIDS);
|
||||
return pbvh->totgrid * (pbvh->gridkey.grid_size - 1) * (pbvh->gridkey.grid_size - 1);
|
||||
return pbvh->grids.size() * (pbvh->gridkey.grid_size - 1) * (pbvh->gridkey.grid_size - 1);
|
||||
}
|
||||
|
||||
/***************************** Node Access ***********************************/
|
||||
@@ -2034,7 +2023,7 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh,
|
||||
int *r_totgrid,
|
||||
int *r_maxgrid,
|
||||
int *r_gridsize,
|
||||
CCGElem ***r_griddata)
|
||||
CCGElem *const **r_griddata)
|
||||
{
|
||||
switch (pbvh->header.type) {
|
||||
case PBVH_GRIDS:
|
||||
@@ -2045,13 +2034,13 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh,
|
||||
*r_totgrid = node->prim_indices.size();
|
||||
}
|
||||
if (r_maxgrid) {
|
||||
*r_maxgrid = pbvh->totgrid;
|
||||
*r_maxgrid = pbvh->grids.size();
|
||||
}
|
||||
if (r_gridsize) {
|
||||
*r_gridsize = pbvh->gridkey.grid_size;
|
||||
}
|
||||
if (r_griddata) {
|
||||
*r_griddata = pbvh->grids;
|
||||
*r_griddata = pbvh->grids.data();
|
||||
}
|
||||
break;
|
||||
case PBVH_FACES:
|
||||
@@ -2961,17 +2950,19 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
|
||||
}
|
||||
|
||||
void BKE_pbvh_grids_update(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
BLI_bitmap **grid_hidden,
|
||||
const blender::Span<CCGElem *> grids,
|
||||
const blender::Span<int> grid_to_face_map,
|
||||
const blender::Span<DMFlagMat> flagmats,
|
||||
const blender::Span<BLI_bitmap *> grid_hidden,
|
||||
CCGKey *key)
|
||||
{
|
||||
pbvh->gridkey = *key;
|
||||
pbvh->grids = grids;
|
||||
pbvh->grid_to_face_map = grid_to_face_map;
|
||||
|
||||
if (flagmats != pbvh->grid_flag_mats || pbvh->grid_hidden != grid_hidden) {
|
||||
if (flagmats.data() != pbvh->grid_flag_mats.data() ||
|
||||
pbvh->grid_hidden.data() != grid_hidden.data())
|
||||
{
|
||||
pbvh->grid_flag_mats = flagmats;
|
||||
pbvh->grid_hidden = grid_hidden;
|
||||
|
||||
@@ -3076,7 +3067,7 @@ void BKE_pbvh_node_color_buffer_free(PBVH *pbvh)
|
||||
|
||||
void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode)
|
||||
{
|
||||
CCGElem **grids;
|
||||
CCGElem *const *grids;
|
||||
const int *grid_indices;
|
||||
int totgrid, gridsize, uniq_verts, totvert;
|
||||
|
||||
@@ -3117,7 +3108,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
|
||||
|
||||
vi->gh = nullptr;
|
||||
if (vi->grids && mode == PBVH_ITER_UNIQUE) {
|
||||
vi->grid_hidden = pbvh->grid_hidden;
|
||||
vi->grid_hidden = pbvh->grid_hidden.data();
|
||||
}
|
||||
|
||||
vi->mask = 0.0f;
|
||||
|
||||
@@ -178,11 +178,10 @@ struct PBVH {
|
||||
|
||||
/* Grid Data */
|
||||
CCGKey gridkey;
|
||||
CCGElem **grids;
|
||||
blender::Span<CCGElem *> grids;
|
||||
blender::Span<int> grid_to_face_map;
|
||||
const DMFlagMat *grid_flag_mats;
|
||||
int totgrid;
|
||||
BLI_bitmap **grid_hidden;
|
||||
blender::Span<DMFlagMat> grid_flag_mats;
|
||||
blender::Span<BLI_bitmap *> grid_hidden;
|
||||
|
||||
/* Used during BVH build and later to mark that a vertex needs to update
|
||||
* (its normal must be recalculated). */
|
||||
|
||||
@@ -129,40 +129,28 @@ static int topology_refiner_count_face_corners(OpenSubdiv_TopologyRefiner *topol
|
||||
static void subdiv_ccg_alloc_elements(SubdivCCG &subdiv_ccg, Subdiv &subdiv)
|
||||
{
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv.topology_refiner;
|
||||
const int element_size = element_size_bytes_get(subdiv_ccg);
|
||||
const int64_t element_size = element_size_bytes_get(subdiv_ccg);
|
||||
/* Allocate memory for surface grids. */
|
||||
const int num_faces = topology_refiner->getNumFaces(topology_refiner);
|
||||
const int num_grids = topology_refiner_count_face_corners(topology_refiner);
|
||||
const int grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg.level);
|
||||
const int grid_area = grid_size * grid_size;
|
||||
const int64_t num_faces = topology_refiner->getNumFaces(topology_refiner);
|
||||
const int64_t num_grids = topology_refiner_count_face_corners(topology_refiner);
|
||||
const int64_t grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg.level);
|
||||
const int64_t grid_area = grid_size * grid_size;
|
||||
subdiv_ccg.grid_element_size = element_size;
|
||||
subdiv_ccg.num_grids = num_grids;
|
||||
subdiv_ccg.grids = static_cast<CCGElem **>(
|
||||
MEM_calloc_arrayN(num_grids, sizeof(CCGElem *), "subdiv ccg grids"));
|
||||
subdiv_ccg.grids_storage = static_cast<uchar *>(
|
||||
MEM_calloc_arrayN(num_grids, size_t(grid_area) * element_size, "subdiv ccg grids storage"));
|
||||
subdiv_ccg.grids.reinitialize(num_grids);
|
||||
subdiv_ccg.grids_storage.reinitialize(num_grids * grid_area * element_size);
|
||||
const size_t grid_size_in_bytes = size_t(grid_area) * element_size;
|
||||
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
|
||||
const size_t grid_offset = grid_size_in_bytes * grid_index;
|
||||
subdiv_ccg.grids[grid_index] = (CCGElem *)&subdiv_ccg.grids_storage[grid_offset];
|
||||
}
|
||||
/* Grid material flags. */
|
||||
subdiv_ccg.grid_flag_mats = static_cast<DMFlagMat *>(
|
||||
MEM_calloc_arrayN(num_grids, sizeof(DMFlagMat), "ccg grid material flags"));
|
||||
/* Grid hidden flags. */
|
||||
subdiv_ccg.grid_hidden = static_cast<BLI_bitmap **>(
|
||||
MEM_calloc_arrayN(num_grids, sizeof(BLI_bitmap *), "ccg grid material flags"));
|
||||
subdiv_ccg.grid_flag_mats.reinitialize(num_grids);
|
||||
subdiv_ccg.grid_hidden.reinitialize(num_grids);
|
||||
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
|
||||
subdiv_ccg.grid_hidden[grid_index] = BLI_BITMAP_NEW(grid_area, "ccg grid hidden");
|
||||
}
|
||||
/* TODO(sergey): Allocate memory for loose elements. */
|
||||
/* Allocate memory for faces. */
|
||||
subdiv_ccg.num_faces = num_faces;
|
||||
if (num_faces) {
|
||||
subdiv_ccg.faces = static_cast<SubdivCCGFace *>(
|
||||
MEM_calloc_arrayN(num_faces, sizeof(SubdivCCGFace), "Subdiv CCG faces"));
|
||||
subdiv_ccg.grid_to_face_map.reinitialize(num_grids);
|
||||
}
|
||||
subdiv_ccg.faces.reinitialize(num_faces);
|
||||
subdiv_ccg.grid_to_face_map.reinitialize(num_grids);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -236,9 +224,8 @@ static void subdiv_ccg_eval_regular_grid(Subdiv &subdiv,
|
||||
const int grid_size = subdiv_ccg.grid_size;
|
||||
const float grid_size_1_inv = 1.0f / (grid_size - 1);
|
||||
const int element_size = element_size_bytes_get(subdiv_ccg);
|
||||
const SubdivCCGFace *faces = subdiv_ccg.faces;
|
||||
blender::MutableSpan<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
|
||||
const SubdivCCGFace &face = faces[face_index];
|
||||
const SubdivCCGFace &face = subdiv_ccg.faces[face_index];
|
||||
for (int corner = 0; corner < face.num_grids; corner++) {
|
||||
const int grid_index = face.start_grid_index + corner;
|
||||
uchar *grid = (uchar *)subdiv_ccg.grids[grid_index];
|
||||
@@ -272,9 +259,8 @@ static void subdiv_ccg_eval_special_grid(Subdiv &subdiv,
|
||||
const int grid_size = subdiv_ccg.grid_size;
|
||||
const float grid_size_1_inv = 1.0f / (grid_size - 1);
|
||||
const int element_size = element_size_bytes_get(subdiv_ccg);
|
||||
const SubdivCCGFace *faces = subdiv_ccg.faces;
|
||||
blender::MutableSpan<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
|
||||
const SubdivCCGFace &face = faces[face_index];
|
||||
const SubdivCCGFace &face = subdiv_ccg.faces[face_index];
|
||||
for (int corner = 0; corner < face.num_grids; corner++) {
|
||||
const int grid_index = face.start_grid_index + corner;
|
||||
const int ptex_face_index = face_ptex_offset[face_index] + corner;
|
||||
@@ -305,7 +291,8 @@ static bool subdiv_ccg_evaluate_grids(SubdivCCG &subdiv_ccg,
|
||||
using namespace blender;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv.topology_refiner;
|
||||
const int num_faces = topology_refiner->getNumFaces(topology_refiner);
|
||||
const Span<int> face_ptex_offset(BKE_subdiv_face_ptex_offset_get(&subdiv), subdiv_ccg.num_faces);
|
||||
const Span<int> face_ptex_offset(BKE_subdiv_face_ptex_offset_get(&subdiv),
|
||||
subdiv_ccg.faces.size());
|
||||
threading::parallel_for(IndexRange(num_faces), 1024, [&](const IndexRange range) {
|
||||
for (const int face_index : range) {
|
||||
if (subdiv_ccg.faces[face_index].num_grids == 4) {
|
||||
@@ -340,7 +327,7 @@ static void subdiv_ccg_init_faces(SubdivCCG &subdiv_ccg)
|
||||
{
|
||||
Subdiv *subdiv = subdiv_ccg.subdiv;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
const int num_faces = subdiv_ccg.num_faces;
|
||||
const int num_faces = subdiv_ccg.faces.size();
|
||||
int corner_index = 0;
|
||||
for (int face_index = 0; face_index < num_faces; face_index++) {
|
||||
const int num_corners = topology_refiner->getNumFaceVertices(topology_refiner, face_index);
|
||||
@@ -352,9 +339,7 @@ static void subdiv_ccg_init_faces(SubdivCCG &subdiv_ccg)
|
||||
|
||||
static void subdiv_ccg_allocate_adjacent_edges(SubdivCCG &subdiv_ccg, const int num_edges)
|
||||
{
|
||||
subdiv_ccg.num_adjacent_edges = num_edges;
|
||||
subdiv_ccg.adjacent_edges = static_cast<SubdivCCGAdjacentEdge *>(MEM_calloc_arrayN(
|
||||
subdiv_ccg.num_adjacent_edges, sizeof(*subdiv_ccg.adjacent_edges), "ccg adjacent edges"));
|
||||
subdiv_ccg.adjacent_edges = Array<SubdivCCGAdjacentEdge>(num_edges, SubdivCCGAdjacentEdge{});
|
||||
}
|
||||
|
||||
static SubdivCCGCoord subdiv_ccg_coord(int grid_index, int x, int y)
|
||||
@@ -392,7 +377,7 @@ static SubdivCCGCoord *subdiv_ccg_adjacent_edge_add_face(SubdivCCG &subdiv_ccg,
|
||||
static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG &subdiv_ccg)
|
||||
{
|
||||
Subdiv *subdiv = subdiv_ccg.subdiv;
|
||||
const SubdivCCGFace *faces = subdiv_ccg.faces;
|
||||
const Span<SubdivCCGFace> faces = subdiv_ccg.faces;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
const int num_edges = topology_refiner->getNumEdges(topology_refiner);
|
||||
const int grid_size = subdiv_ccg.grid_size;
|
||||
@@ -405,8 +390,7 @@ static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG &subdiv_ccg)
|
||||
Vector<int, 64> face_vertices;
|
||||
Vector<int, 64> face_edges;
|
||||
/* Store adjacency for all faces. */
|
||||
const int num_faces = subdiv_ccg.num_faces;
|
||||
for (int face_index = 0; face_index < num_faces; face_index++) {
|
||||
for (const int face_index : faces.index_range()) {
|
||||
const SubdivCCGFace &face = faces[face_index];
|
||||
const int num_face_grids = face.num_grids;
|
||||
face_vertices.reinitialize(num_face_grids);
|
||||
@@ -458,11 +442,8 @@ static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG &subdiv_ccg)
|
||||
|
||||
static void subdiv_ccg_allocate_adjacent_vertices(SubdivCCG &subdiv_ccg, const int num_vertices)
|
||||
{
|
||||
subdiv_ccg.num_adjacent_vertices = num_vertices;
|
||||
subdiv_ccg.adjacent_vertices = static_cast<SubdivCCGAdjacentVertex *>(
|
||||
MEM_calloc_arrayN(subdiv_ccg.num_adjacent_vertices,
|
||||
sizeof(*subdiv_ccg.adjacent_vertices),
|
||||
"ccg adjacent vertices"));
|
||||
subdiv_ccg.adjacent_verts = Array<SubdivCCGAdjacentVertex>(num_vertices,
|
||||
SubdivCCGAdjacentVertex{});
|
||||
}
|
||||
|
||||
/* Returns storage where corner elements are to be stored. This is a pointer
|
||||
@@ -482,7 +463,7 @@ static SubdivCCGCoord *subdiv_ccg_adjacent_vertex_add_face(
|
||||
static void subdiv_ccg_init_faces_vertex_neighborhood(SubdivCCG &subdiv_ccg)
|
||||
{
|
||||
Subdiv *subdiv = subdiv_ccg.subdiv;
|
||||
const SubdivCCGFace *faces = subdiv_ccg.faces;
|
||||
const Span<SubdivCCGFace> faces = subdiv_ccg.faces;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
const int num_vertices = topology_refiner->getNumVertices(topology_refiner);
|
||||
const int grid_size = subdiv_ccg.grid_size;
|
||||
@@ -496,8 +477,7 @@ static void subdiv_ccg_init_faces_vertex_neighborhood(SubdivCCG &subdiv_ccg)
|
||||
CCGKey key;
|
||||
BKE_subdiv_ccg_key_top_level(key, subdiv_ccg);
|
||||
/* Store adjacency for all faces. */
|
||||
const int num_faces = subdiv_ccg.num_faces;
|
||||
for (int face_index = 0; face_index < num_faces; face_index++) {
|
||||
for (const int face_index : faces.index_range()) {
|
||||
const SubdivCCGFace &face = faces[face_index];
|
||||
const int num_face_grids = face.num_grids;
|
||||
face_vertices.reinitialize(num_face_grids);
|
||||
@@ -507,7 +487,7 @@ static void subdiv_ccg_init_faces_vertex_neighborhood(SubdivCCG &subdiv_ccg)
|
||||
/* Grid which is adjacent to the current corner. */
|
||||
const int grid_index = face.start_grid_index + corner;
|
||||
/* Add new face to the adjacent edge. */
|
||||
SubdivCCGAdjacentVertex &adjacent_vertex = subdiv_ccg.adjacent_vertices[vertex_index];
|
||||
SubdivCCGAdjacentVertex &adjacent_vertex = subdiv_ccg.adjacent_verts[vertex_index];
|
||||
SubdivCCGCoord *corner_coord = subdiv_ccg_adjacent_vertex_add_face(adjacent_vertex);
|
||||
*corner_coord = subdiv_ccg_coord(grid_index, grid_size - 1, grid_size - 1);
|
||||
}
|
||||
@@ -583,38 +563,27 @@ Mesh *BKE_subdiv_to_ccg_mesh(Subdiv &subdiv,
|
||||
|
||||
void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
|
||||
{
|
||||
const int num_grids = subdiv_ccg->num_grids;
|
||||
MEM_SAFE_FREE(subdiv_ccg->grids);
|
||||
MEM_SAFE_FREE(subdiv_ccg->grids_storage);
|
||||
MEM_SAFE_FREE(subdiv_ccg->edges);
|
||||
MEM_SAFE_FREE(subdiv_ccg->vertices);
|
||||
MEM_SAFE_FREE(subdiv_ccg->grid_flag_mats);
|
||||
if (subdiv_ccg->grid_hidden != nullptr) {
|
||||
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
|
||||
MEM_SAFE_FREE(subdiv_ccg->grid_hidden[grid_index]);
|
||||
}
|
||||
MEM_SAFE_FREE(subdiv_ccg->grid_hidden);
|
||||
for (const int grid_index : subdiv_ccg->grid_hidden.index_range()) {
|
||||
MEM_SAFE_FREE(subdiv_ccg->grid_hidden[grid_index]);
|
||||
}
|
||||
|
||||
if (subdiv_ccg->subdiv != nullptr) {
|
||||
BKE_subdiv_free(subdiv_ccg->subdiv);
|
||||
}
|
||||
MEM_SAFE_FREE(subdiv_ccg->faces);
|
||||
/* Free map of adjacent edges. */
|
||||
for (int i = 0; i < subdiv_ccg->num_adjacent_edges; i++) {
|
||||
|
||||
for (const int i : subdiv_ccg->adjacent_edges.index_range()) {
|
||||
SubdivCCGAdjacentEdge *adjacent_edge = &subdiv_ccg->adjacent_edges[i];
|
||||
for (int face_index = 0; face_index < adjacent_edge->num_adjacent_faces; face_index++) {
|
||||
MEM_SAFE_FREE(adjacent_edge->boundary_coords[face_index]);
|
||||
}
|
||||
MEM_SAFE_FREE(adjacent_edge->boundary_coords);
|
||||
}
|
||||
MEM_SAFE_FREE(subdiv_ccg->adjacent_edges);
|
||||
/* Free map of adjacent vertices. */
|
||||
for (int i = 0; i < subdiv_ccg->num_adjacent_vertices; i++) {
|
||||
SubdivCCGAdjacentVertex *adjacent_vertex = &subdiv_ccg->adjacent_vertices[i];
|
||||
|
||||
for (const int i : subdiv_ccg->adjacent_verts.index_range()) {
|
||||
SubdivCCGAdjacentVertex *adjacent_vertex = &subdiv_ccg->adjacent_verts[i];
|
||||
MEM_SAFE_FREE(adjacent_vertex->corner_coords);
|
||||
}
|
||||
MEM_SAFE_FREE(subdiv_ccg->adjacent_vertices);
|
||||
MEM_SAFE_FREE(subdiv_ccg->cache_.start_face_grid_index);
|
||||
|
||||
MEM_delete(subdiv_ccg);
|
||||
}
|
||||
|
||||
@@ -727,7 +696,7 @@ static void subdiv_ccg_recalc_inner_grid_normals(SubdivCCG &subdiv_ccg, const In
|
||||
threading::EnumerableThreadSpecific<Array<float3>> face_normals_tls(
|
||||
Array<float3>(grid_size_1 * grid_size_1));
|
||||
|
||||
const SubdivCCGFace *faces = subdiv_ccg.faces;
|
||||
const Span<SubdivCCGFace> faces = subdiv_ccg.faces;
|
||||
face_mask.foreach_segment(GrainSize(512), [&](const IndexMaskSegment segment) {
|
||||
MutableSpan<float3> face_normals = face_normals_tls.local();
|
||||
for (const int face_index : segment) {
|
||||
@@ -747,7 +716,7 @@ void BKE_subdiv_ccg_recalc_normals(SubdivCCG &subdiv_ccg)
|
||||
/* Grids don't have normals, can do early output. */
|
||||
return;
|
||||
}
|
||||
subdiv_ccg_recalc_inner_grid_normals(subdiv_ccg, IndexMask(subdiv_ccg.num_faces));
|
||||
subdiv_ccg_recalc_inner_grid_normals(subdiv_ccg, subdiv_ccg.faces.index_range());
|
||||
BKE_subdiv_ccg_average_grids(subdiv_ccg);
|
||||
}
|
||||
|
||||
@@ -854,7 +823,7 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG &subdiv_ccg,
|
||||
CCGKey &key,
|
||||
const SubdivCCGFace &face)
|
||||
{
|
||||
CCGElem **grids = subdiv_ccg.grids;
|
||||
const Span<CCGElem *> grids = subdiv_ccg.grids;
|
||||
const int num_face_grids = face.num_grids;
|
||||
const int grid_size = subdiv_ccg.grid_size;
|
||||
CCGElem *prev_grid = grids[face.start_grid_index + num_face_grids - 1];
|
||||
@@ -923,7 +892,7 @@ struct AverageGridsCornerData {
|
||||
SubdivCCG *subdiv_ccg;
|
||||
CCGKey *key;
|
||||
|
||||
/* Optional lookup table. Maps task range index to index in `subdiv_ccg.adjacent_vertices`. */
|
||||
/* Optional lookup table. Maps task range index to index in `subdiv_ccg.adjacent_verts`. */
|
||||
const int *adjacent_vert_index_map;
|
||||
};
|
||||
|
||||
@@ -975,7 +944,7 @@ static void subdiv_ccg_average_corners(SubdivCCG &subdiv_ccg,
|
||||
{
|
||||
using namespace blender;
|
||||
adjacent_vert_mask.foreach_index(GrainSize(1024), [&](const int i) {
|
||||
SubdivCCGAdjacentVertex &adjacent_vert = subdiv_ccg.adjacent_vertices[i];
|
||||
SubdivCCGAdjacentVertex &adjacent_vert = subdiv_ccg.adjacent_verts[i];
|
||||
subdiv_ccg_average_grids_corners(subdiv_ccg, key, adjacent_vert);
|
||||
});
|
||||
}
|
||||
@@ -987,9 +956,9 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG &subdiv_ccg)
|
||||
BKE_subdiv_ccg_key_top_level(key, subdiv_ccg);
|
||||
/* Average inner boundaries of grids (within one face), across faces
|
||||
* from different face-corners. */
|
||||
BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, IndexRange(subdiv_ccg.num_faces));
|
||||
subdiv_ccg_average_boundaries(subdiv_ccg, key, IndexMask(subdiv_ccg.num_adjacent_edges));
|
||||
subdiv_ccg_average_corners(subdiv_ccg, key, IndexMask(subdiv_ccg.num_adjacent_vertices));
|
||||
BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, subdiv_ccg.faces.index_range());
|
||||
subdiv_ccg_average_boundaries(subdiv_ccg, key, subdiv_ccg.adjacent_edges.index_range());
|
||||
subdiv_ccg_average_corners(subdiv_ccg, key, subdiv_ccg.adjacent_verts.index_range());
|
||||
}
|
||||
|
||||
static void subdiv_ccg_affected_face_adjacency(SubdivCCG &subdiv_ccg,
|
||||
@@ -1041,8 +1010,8 @@ void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG &subdiv_ccg, const IndexMask
|
||||
});
|
||||
/* TODO(sergey): Only average elements which are adjacent to modified
|
||||
* faces. */
|
||||
subdiv_ccg_average_boundaries(subdiv_ccg, key, IndexMask(subdiv_ccg.num_adjacent_edges));
|
||||
subdiv_ccg_average_corners(subdiv_ccg, key, IndexMask(subdiv_ccg.num_adjacent_vertices));
|
||||
subdiv_ccg_average_boundaries(subdiv_ccg, key, subdiv_ccg.adjacent_edges.index_range());
|
||||
subdiv_ccg_average_corners(subdiv_ccg, key, subdiv_ccg.adjacent_verts.index_range());
|
||||
}
|
||||
|
||||
void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg,
|
||||
@@ -1051,7 +1020,7 @@ void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg,
|
||||
int &r_num_faces,
|
||||
int &r_num_loops)
|
||||
{
|
||||
const int num_grids = subdiv_ccg.num_grids;
|
||||
const int num_grids = subdiv_ccg.grids.size();
|
||||
const int grid_size = subdiv_ccg.grid_size;
|
||||
const int grid_area = grid_size * grid_size;
|
||||
const int num_edges_per_grid = 2 * (grid_size * (grid_size - 1));
|
||||
@@ -1074,7 +1043,7 @@ void BKE_subdiv_ccg_print_coord(const char *message, const SubdivCCGCoord &coord
|
||||
|
||||
bool BKE_subdiv_ccg_check_coord_valid(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord)
|
||||
{
|
||||
if (coord.grid_index < 0 || coord.grid_index >= subdiv_ccg.num_grids) {
|
||||
if (coord.grid_index < 0 || coord.grid_index >= subdiv_ccg.grids.size()) {
|
||||
return false;
|
||||
}
|
||||
const int grid_size = subdiv_ccg.grid_size;
|
||||
@@ -1244,15 +1213,15 @@ static void neighbor_coords_corner_center_get(const SubdivCCG &subdiv_ccg,
|
||||
}
|
||||
}
|
||||
|
||||
/* Get index within adjacent_vertices array for the given CCG coordinate. */
|
||||
/* Get index within adjacent_verts array for the given CCG coordinate. */
|
||||
static int adjacent_vertex_index_from_coord(const SubdivCCG &subdiv_ccg,
|
||||
const SubdivCCGCoord &coord)
|
||||
{
|
||||
Subdiv *subdiv = subdiv_ccg.subdiv;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
|
||||
const SubdivCCGFace &face = subdiv_ccg.faces[subdiv_ccg.grid_to_face_map[coord.grid_index]];
|
||||
const int face_index = &face - subdiv_ccg.faces;
|
||||
const int face_index = subdiv_ccg.grid_to_face_map[coord.grid_index];
|
||||
const SubdivCCGFace &face = subdiv_ccg.faces[face_index];
|
||||
const int face_grid_index = coord.grid_index - face.start_grid_index;
|
||||
const int num_face_grids = face.num_grids;
|
||||
|
||||
@@ -1278,8 +1247,8 @@ static void neighbor_coords_corner_vertex_get(const SubdivCCG &subdiv_ccg,
|
||||
const int num_vertex_edges = topology_refiner->getNumVertexEdges(topology_refiner,
|
||||
adjacent_vertex_index);
|
||||
|
||||
SubdivCCGAdjacentVertex &adjacent_vertex = subdiv_ccg.adjacent_vertices[adjacent_vertex_index];
|
||||
const int num_adjacent_faces = adjacent_vertex.num_adjacent_faces;
|
||||
const SubdivCCGAdjacentVertex &adjacent_vert = subdiv_ccg.adjacent_verts[adjacent_vertex_index];
|
||||
const int num_adjacent_faces = adjacent_vert.num_adjacent_faces;
|
||||
|
||||
subdiv_ccg_neighbors_init(
|
||||
r_neighbors, num_vertex_edges, (include_duplicates) ? num_adjacent_faces - 1 : 0);
|
||||
@@ -1309,14 +1278,14 @@ static void neighbor_coords_corner_vertex_get(const SubdivCCG &subdiv_ccg,
|
||||
edge_point_index = duplicate_edge_point_index - 1;
|
||||
}
|
||||
|
||||
SubdivCCGAdjacentEdge &adjacent_edge = subdiv_ccg.adjacent_edges[edge_index];
|
||||
const SubdivCCGAdjacentEdge &adjacent_edge = subdiv_ccg.adjacent_edges[edge_index];
|
||||
r_neighbors.coords[i] = adjacent_edge.boundary_coords[edge_face_index][edge_point_index];
|
||||
}
|
||||
|
||||
if (include_duplicates) {
|
||||
/* Add duplicates of the current grid vertex in adjacent faces if requested. */
|
||||
for (int i = 0, duplicate_i = num_vertex_edges; i < num_adjacent_faces; i++) {
|
||||
SubdivCCGCoord neighbor_coord = adjacent_vertex.corner_coords[i];
|
||||
SubdivCCGCoord neighbor_coord = adjacent_vert.corner_coords[i];
|
||||
if (neighbor_coord.grid_index != coord.grid_index) {
|
||||
r_neighbors.coords[duplicate_i++] = neighbor_coord;
|
||||
}
|
||||
@@ -1328,10 +1297,10 @@ static int adjacent_edge_index_from_coord(const SubdivCCG &subdiv_ccg, const Sub
|
||||
{
|
||||
Subdiv *subdiv = subdiv_ccg.subdiv;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
const SubdivCCGFace &face = subdiv_ccg.faces[subdiv_ccg.grid_to_face_map[coord.grid_index]];
|
||||
|
||||
const int face_index = subdiv_ccg.grid_to_face_map[coord.grid_index];
|
||||
const SubdivCCGFace &face = subdiv_ccg.faces[face_index];
|
||||
const int face_grid_index = coord.grid_index - face.start_grid_index;
|
||||
const int face_index = &face - subdiv_ccg.faces;
|
||||
const int num_face_edges = topology_refiner->getNumFaceEdges(topology_refiner, face_index);
|
||||
|
||||
Array<int, 64> face_edges(num_face_edges);
|
||||
@@ -1626,7 +1595,7 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG &subdiv_ccg, const int gri
|
||||
|
||||
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg)
|
||||
{
|
||||
if (subdiv_ccg.cache_.start_face_grid_index == nullptr) {
|
||||
if (subdiv_ccg.cache_.start_face_grid_index.is_empty()) {
|
||||
const Subdiv *subdiv = subdiv_ccg.subdiv;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
if (topology_refiner == nullptr) {
|
||||
@@ -1635,8 +1604,7 @@ const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg)
|
||||
|
||||
const int num_coarse_faces = topology_refiner->getNumFaces(topology_refiner);
|
||||
|
||||
subdiv_ccg.cache_.start_face_grid_index = static_cast<int *>(
|
||||
MEM_malloc_arrayN(num_coarse_faces, sizeof(int), "start_face_grid_index"));
|
||||
subdiv_ccg.cache_.start_face_grid_index.reinitialize(num_coarse_faces);
|
||||
|
||||
int start_grid_index = 0;
|
||||
for (int face_index = 0; face_index < num_coarse_faces; face_index++) {
|
||||
@@ -1647,12 +1615,12 @@ const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg)
|
||||
}
|
||||
}
|
||||
|
||||
return subdiv_ccg.cache_.start_face_grid_index;
|
||||
return subdiv_ccg.cache_.start_face_grid_index.data();
|
||||
}
|
||||
|
||||
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG &subdiv_ccg)
|
||||
{
|
||||
return subdiv_ccg.cache_.start_face_grid_index;
|
||||
return subdiv_ccg.cache_.start_face_grid_index.data();
|
||||
}
|
||||
|
||||
static void adjacent_vertices_index_from_adjacent_edge(const SubdivCCG &subdiv_ccg,
|
||||
@@ -1745,7 +1713,7 @@ static void subdiv_ccg_coord_to_ptex_coord(const SubdivCCG &subdiv_ccg,
|
||||
const float grid_v = coord.y * grid_size_1_inv;
|
||||
|
||||
const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, coord.grid_index);
|
||||
const SubdivCCGFace *faces = subdiv_ccg.faces;
|
||||
const Span<SubdivCCGFace> faces = subdiv_ccg.faces;
|
||||
const SubdivCCGFace &face = faces[face_index];
|
||||
const int *face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv);
|
||||
*r_ptex_face_index = face_ptex_offset[face_index];
|
||||
|
||||
@@ -41,7 +41,6 @@ struct PBVH_GPU_Args {
|
||||
blender::OffsetIndices<int> faces;
|
||||
blender::Span<int> corner_verts;
|
||||
blender::Span<int> corner_edges;
|
||||
int mesh_grids_num;
|
||||
const CustomData *vert_data;
|
||||
const CustomData *loop_data;
|
||||
const CustomData *face_data;
|
||||
@@ -54,11 +53,11 @@ struct PBVH_GPU_Args {
|
||||
int face_sets_color_seed, face_sets_color_default;
|
||||
|
||||
SubdivCCG *subdiv_ccg;
|
||||
const DMFlagMat *grid_flag_mats;
|
||||
blender::Span<DMFlagMat> grid_flag_mats;
|
||||
blender::Span<int> grid_indices;
|
||||
CCGKey ccg_key;
|
||||
CCGElem **grids;
|
||||
BLI_bitmap **grid_hidden;
|
||||
blender::Span<CCGElem *> grids;
|
||||
blender::Span<const BLI_bitmap *> grid_hidden;
|
||||
|
||||
blender::Span<int> prim_indices;
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ struct PBVHBatches {
|
||||
break;
|
||||
}
|
||||
case PBVH_GRIDS: {
|
||||
count = BKE_pbvh_count_grid_quads((BLI_bitmap **)args.grid_hidden,
|
||||
count = BKE_pbvh_count_grid_quads(args.grid_hidden,
|
||||
args.grid_indices.data(),
|
||||
args.grid_indices.size(),
|
||||
args.ccg_key.grid_size,
|
||||
@@ -1170,7 +1170,7 @@ struct PBVHBatches {
|
||||
|
||||
for (const int grid_index : args.grid_indices) {
|
||||
bool smooth = !args.grid_flag_mats[grid_index].sharp;
|
||||
BLI_bitmap *gh = args.grid_hidden[grid_index];
|
||||
const BLI_bitmap *gh = args.grid_hidden[grid_index];
|
||||
|
||||
for (int y = 0; y < gridsize - 1; y += skip) {
|
||||
for (int x = 0; x < gridsize - 1; x += skip) {
|
||||
@@ -1194,11 +1194,8 @@ struct PBVHBatches {
|
||||
|
||||
const CCGKey *key = &args.ccg_key;
|
||||
|
||||
uint visible_quad_len = BKE_pbvh_count_grid_quads((BLI_bitmap **)args.grid_hidden,
|
||||
args.grid_indices.data(),
|
||||
totgrid,
|
||||
key->grid_size,
|
||||
display_gridsize);
|
||||
uint visible_quad_len = BKE_pbvh_count_grid_quads(
|
||||
args.grid_hidden, args.grid_indices.data(), totgrid, key->grid_size, display_gridsize);
|
||||
|
||||
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX);
|
||||
GPU_indexbuf_init(&elb_lines,
|
||||
@@ -1213,7 +1210,7 @@ struct PBVHBatches {
|
||||
uint v0, v1, v2, v3;
|
||||
bool grid_visible = false;
|
||||
|
||||
BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
|
||||
const BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
|
||||
|
||||
for (int j = 0; j < gridsize - skip; j += skip) {
|
||||
for (int k = 0; k < gridsize - skip; k += skip) {
|
||||
@@ -1251,7 +1248,7 @@ struct PBVHBatches {
|
||||
|
||||
for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
|
||||
bool grid_visible = false;
|
||||
BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
|
||||
const BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
|
||||
|
||||
uint v0, v1, v2, v3;
|
||||
for (int j = 0; j < gridsize - skip; j += skip) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "BKE_multires.hh"
|
||||
#include "BKE_paint.hh"
|
||||
#include "BKE_pbvh_api.hh"
|
||||
#include "BKE_subdiv_ccg.hh"
|
||||
#include "BKE_subsurf.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
@@ -120,15 +121,17 @@ static void partialvis_update_grids(Depsgraph *depsgraph,
|
||||
PartialVisArea area,
|
||||
float planes[4][4])
|
||||
{
|
||||
CCGElem **grids;
|
||||
BLI_bitmap **grid_hidden;
|
||||
CCGElem *const *grids;
|
||||
const int *grid_indices;
|
||||
int totgrid;
|
||||
bool any_changed = false, any_visible = false;
|
||||
|
||||
/* Get PBVH data. */
|
||||
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids);
|
||||
grid_hidden = BKE_pbvh_grid_hidden(pbvh);
|
||||
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
|
||||
blender::MutableSpan<BLI_bitmap *> grid_hidden = subdiv_ccg->grid_hidden;
|
||||
CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
|
||||
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
|
||||
|
||||
@@ -415,8 +415,8 @@ bool SCULPT_vertex_visible_get(const SculptSession *ss, PBVHVertRef vertex)
|
||||
const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
|
||||
const int grid_index = vertex.i / key->grid_area;
|
||||
const int vertex_index = vertex.i - grid_index * key->grid_area;
|
||||
BLI_bitmap **grid_hidden = BKE_pbvh_get_grid_visibility(ss->pbvh);
|
||||
if (grid_hidden && grid_hidden[grid_index]) {
|
||||
const blender::Span<const BLI_bitmap *> grid_hidden = BKE_pbvh_get_grid_visibility(ss->pbvh);
|
||||
if (grid_hidden[grid_index]) {
|
||||
return !BLI_BITMAP_TEST(grid_hidden[grid_index], vertex_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt
|
||||
CCGKey key;
|
||||
int gridsize;
|
||||
|
||||
grids = subdiv_ccg->grids;
|
||||
grids = subdiv_ccg->grids.data();
|
||||
gridsize = subdiv_ccg->grid_size;
|
||||
BKE_subdiv_ccg_key_top_level(key, *subdiv_ccg);
|
||||
|
||||
@@ -511,7 +511,7 @@ static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool
|
||||
}
|
||||
}
|
||||
else if (unode->maxgrid && subdiv_ccg != nullptr) {
|
||||
BLI_bitmap **grid_hidden = subdiv_ccg->grid_hidden;
|
||||
blender::MutableSpan<BLI_bitmap *> grid_hidden = subdiv_ccg->grid_hidden;
|
||||
|
||||
for (int i = 0; i < unode->totgrid; i++) {
|
||||
SWAP(BLI_bitmap *, unode->grid_hidden[i], grid_hidden[unode->grids[i]]);
|
||||
@@ -588,7 +588,7 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *m
|
||||
CCGKey key;
|
||||
int gridsize;
|
||||
|
||||
grids = subdiv_ccg->grids;
|
||||
grids = subdiv_ccg->grids.data();
|
||||
gridsize = subdiv_ccg->grid_size;
|
||||
BKE_subdiv_ccg_key_top_level(key, *subdiv_ccg);
|
||||
|
||||
@@ -927,8 +927,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
|
||||
}
|
||||
}
|
||||
else if (unode->maxgrid && subdiv_ccg != nullptr) {
|
||||
if ((subdiv_ccg->num_grids != unode->maxgrid) || (subdiv_ccg->grid_size != unode->gridsize))
|
||||
{
|
||||
if ((subdiv_ccg->grids.size() != unode->maxgrid) ||
|
||||
(subdiv_ccg->grid_size != unode->gridsize)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1166,7 +1166,7 @@ SculptUndoNode *SCULPT_undo_get_first_node()
|
||||
static size_t sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *unode)
|
||||
{
|
||||
PBVHNode *node = static_cast<PBVHNode *>(unode->node);
|
||||
BLI_bitmap **grid_hidden = BKE_pbvh_grid_hidden(pbvh);
|
||||
const blender::Span<const BLI_bitmap *> grid_hidden = BKE_pbvh_get_grid_visibility(pbvh);
|
||||
|
||||
const int *grid_indices;
|
||||
int totgrid;
|
||||
|
||||
@@ -262,19 +262,3 @@ extern "C" bool IMB_saveiff(struct ImBuf * /*ibuf*/, const char * /*filepath*/,
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Stubs of BKE_pbvh.hh
|
||||
* \{ */
|
||||
|
||||
int BKE_pbvh_count_grid_quads(BLI_bitmap ** /*grid_hidden*/,
|
||||
const int * /*grid_indices*/,
|
||||
int /*totgrid*/,
|
||||
int /*gridsize*/,
|
||||
int /*display_gridsize*/)
|
||||
{
|
||||
BLI_assert_unreachable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
Reference in New Issue
Block a user