Subsurf: Cleanup, remove unused mappings and topology queries

This commit is contained in:
2018-08-01 15:21:14 +02:00
parent ec4ba68730
commit 63058490a3

View File

@@ -45,31 +45,15 @@
# include "opensubdiv_converter_capi.h"
#endif
/* Use mesh element mapping structures during conversion.
* Uses more memory but is much faster than naive algorithm.
*/
#define USE_MESH_ELEMENT_MAPPING
#ifdef WITH_OPENSUBDIV
typedef struct ConverterStorage {
SubdivSettings settings;
const Mesh *mesh;
#ifdef USE_MESH_ELEMENT_MAPPING
MeshElemMap *vert_edge_map;
MeshElemMap *vert_poly_map;
MeshElemMap *edge_poly_map;
int *vert_edge_mem;
int *vert_poly_mem;
int *edge_poly_mem;
#endif
/* Indexed by loop index, value denotes index of face-varying vertex
* which corresponds to the UV coordinate.
*/
int *loop_uv_indices;
int num_uv_coordinates;
/* Indexed by coarse mesh elements, gives index of corresponding element
* with ignoring all non-manifold entities.
*
@@ -78,7 +62,6 @@ typedef struct ConverterStorage {
* or vertices in the mesh.
*/
int *manifold_vertex_index;
int *manifold_edge_index;
/* Indexed by vertex index from mesh, corresponds to whether this vertex has
* infinite sharpness due to non-manifol topology.
*/
@@ -154,19 +137,6 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter,
}
}
static void get_face_edges(const OpenSubdiv_Converter *converter,
int manifold_face_index,
int *manifold_face_edges)
{
ConverterStorage *storage = converter->user_data;
const MPoly *poly = &storage->mesh->mpoly[manifold_face_index];
const MLoop *mloop = storage->mesh->mloop;
for (int corner = 0; corner < poly->totloop; corner++) {
manifold_face_edges[corner] =
storage->manifold_edge_index[mloop[poly->loopstart + corner].e];
}
}
static void get_edge_vertices(const OpenSubdiv_Converter *converter,
int manifold_edge_index,
int *manifold_edge_vertices)
@@ -179,68 +149,6 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter,
manifold_edge_vertices[1] = storage->manifold_vertex_index[edge->v2];
}
static int get_num_edge_faces(const OpenSubdiv_Converter *converter,
int manifold_edge_index)
{
ConverterStorage *storage = converter->user_data;
const int edge_index =
storage->manifold_edge_index_reverse[manifold_edge_index];
#ifdef USE_MESH_ELEMENT_MAPPING
return storage->edge_poly_map[edge_index].count;
#else
const Mesh *mesh = storage->mesh;
const MPoly *mpoly = mesh->mpoly;
const MLoop *mloop = mesh->mloop;
int num = 0;
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly *poly = &mpoly[poly_index];
for (int corner = 0; corner < poly->totloop; corner++) {
const MLoop *loop = &mloop[poly->loopstart + corner];
if (storage->manifold_edge_index[loop->e] == -1) {
continue;
}
if (loop->e == edge_index) {
++num;
break;
}
}
}
return num;
#endif
}
static void get_edge_faces(const OpenSubdiv_Converter *converter,
int manifold_edge_index,
int *manifold_edge_faces)
{
ConverterStorage *storage = converter->user_data;
const int edge_index =
storage->manifold_edge_index_reverse[manifold_edge_index];
#ifdef USE_MESH_ELEMENT_MAPPING
memcpy(manifold_edge_faces,
storage->edge_poly_map[edge_index].indices,
sizeof(int) * storage->edge_poly_map[edge_index].count);
#else
const Mesh *mesh = storage->mesh;
const MPoly *mpoly = mesh->mpoly;
const MLoop *mloop = mesh->mloop;
int num = 0;
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly *poly = &mpoly[poly_index];
for (int corner = 0; corner < mpoly->totloop; corner++) {
const MLoop *loop = &mloop[poly->loopstart + corner];
if (storage->manifold_edge_index[loop->e] == -1) {
continue;
}
if (loop->e == edge_index) {
manifold_edge_faces[num++] = poly_index;
break;
}
}
}
#endif
}
static float get_edge_sharpness(const OpenSubdiv_Converter *converter,
int manifold_edge_index)
{
@@ -252,134 +160,6 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter,
return edge_crease * storage->settings.level;
}
static int get_num_vertex_edges(const OpenSubdiv_Converter *converter,
int manifold_vertex_index)
{
ConverterStorage *storage = converter->user_data;
const int vertex_index =
storage->manifold_vertex_index_reverse[manifold_vertex_index];
#ifdef USE_MESH_ELEMENT_MAPPING
const int num_vertex_edges = storage->vert_edge_map[vertex_index].count;
int num_manifold_vertex_edges = 0;
for (int i = 0; i < num_vertex_edges; i++) {
const int edge_index = storage->vert_edge_map[vertex_index].indices[i];
const int manifold_edge_index =
storage->manifold_edge_index[edge_index];
if (manifold_edge_index == -1) {
continue;
}
num_manifold_vertex_edges++;
}
return num_manifold_vertex_edges;
#else
const Mesh *mesh = storage->mesh;
const MEdge *medge = mesh->medge;
int num = 0;
for (int edge_index = 0; edge_index < mesh->totedge; edge_index++) {
const MEdge *edge = &medge[edge_index];
if (storage->manifold_edge_index[edge_index] == -1) {
continue;
}
if (edge->v1 == vertex_index || edge->v2 == vertex_index) {
++num;
}
}
return num;
#endif
}
static void get_vertex_edges(const OpenSubdiv_Converter *converter,
int manifold_vertex_index,
int *manifold_vertex_edges)
{
ConverterStorage *storage = converter->user_data;
const int vertex_index =
storage->manifold_vertex_index_reverse[manifold_vertex_index];
#ifdef USE_MESH_ELEMENT_MAPPING
const int num_vertex_edges = storage->vert_edge_map[vertex_index].count;
int num_manifold_vertex_edges = 0;
for (int i = 0; i < num_vertex_edges; i++) {
const int edge_index = storage->vert_edge_map[vertex_index].indices[i];
const int manifold_edge_index =
storage->manifold_edge_index[edge_index];
if (manifold_edge_index == -1) {
continue;
}
manifold_vertex_edges[num_manifold_vertex_edges] = manifold_edge_index;
num_manifold_vertex_edges++;
}
#else
const Mesh *mesh = storage->mesh;
const MEdge *medge = mesh->medge;
int num = 0;
for (int edge_index = 0; edge_index < mesh->totedge; edge_index++) {
const MEdge *edge = &medge[edge_index];
if (storage->manifold_edge_index[edge_index] == -1) {
continue;
}
if (edge->v1 == vertex_index || edge->v2 == vertex_index) {
manifold_vertex_edges[num++] =
storage->manifold_edge_index[edge_index];
}
}
#endif
}
static int get_num_vertex_faces(const OpenSubdiv_Converter *converter,
int manifold_vertex_index)
{
ConverterStorage *storage = converter->user_data;
const int vertex_index =
storage->manifold_vertex_index_reverse[manifold_vertex_index];
#ifdef USE_MESH_ELEMENT_MAPPING
return storage->vert_poly_map[vertex_index].count;
#else
const Mesh *mesh = storage->mesh;
const MPoly *mpoly = mesh->mpoly;
const MLoop *mloop = mesh->mloop;
int num = 0;
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly *poly = &mpoly[poly_index];
for (int corner = 0; corner < mpoly->totloop; corner++) {
const MLoop *loop = &mloop[poly->loopstart + corner];
if (loop->v == vertex_index) {
++num;
break;
}
}
}
return num;
#endif
}
static void get_vertex_faces(const OpenSubdiv_Converter *converter,
int manifold_vertex_index,
int *manifold_vertex_faces)
{
ConverterStorage *storage = converter->user_data;
const int vertex_index =
storage->manifold_vertex_index_reverse[manifold_vertex_index];
#ifdef USE_MESH_ELEMENT_MAPPING
memcpy(manifold_vertex_faces,
storage->vert_poly_map[vertex_index].indices,
sizeof(int) * storage->vert_poly_map[vertex_index].count);
#else
const Mesh *mesh = storage->mesh;
const MPoly *mpoly = mesh->mpoly;
const MLoop *mloop = mesh->mloop;
int num = 0;
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly *poly = &mpoly[poly_index];
for (int corner = 0; corner < mpoly->totloop; corner++) {
const MLoop *loop = &mloop[poly->loopstart + corner];
if (loop->v == vertex_index) {
manifold_vertex_faces[num++] = poly_index;
break;
}
}
}
#endif
}
static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter,
int manifold_vertex_index)
@@ -467,16 +247,7 @@ static void free_user_data(const OpenSubdiv_Converter *converter)
{
ConverterStorage *user_data = converter->user_data;
MEM_SAFE_FREE(user_data->loop_uv_indices);
#ifdef USE_MESH_ELEMENT_MAPPING
MEM_freeN(user_data->vert_edge_map);
MEM_freeN(user_data->vert_edge_mem);
MEM_freeN(user_data->vert_poly_map);
MEM_freeN(user_data->vert_poly_mem);
MEM_freeN(user_data->edge_poly_map);
MEM_freeN(user_data->edge_poly_mem);
#endif
MEM_freeN(user_data->manifold_vertex_index);
MEM_freeN(user_data->manifold_edge_index);
MEM_freeN(user_data->infinite_sharp_vertices_map);
MEM_freeN(user_data->manifold_vertex_index_reverse);
MEM_freeN(user_data->manifold_edge_index_reverse);
@@ -495,17 +266,17 @@ static void init_functions(OpenSubdiv_Converter *converter)
converter->getNumFaceVertices = get_num_face_vertices;
converter->getFaceVertices = get_face_vertices;
converter->getFaceEdges = get_face_edges;
converter->getFaceEdges = NULL;
converter->getEdgeVertices = get_edge_vertices;
converter->getNumEdgeFaces = get_num_edge_faces;
converter->getEdgeFaces = get_edge_faces;
converter->getNumEdgeFaces = NULL;
converter->getEdgeFaces = NULL;
converter->getEdgeSharpness = get_edge_sharpness;
converter->getNumVertexEdges = get_num_vertex_edges;
converter->getVertexEdges = get_vertex_edges;
converter->getNumVertexFaces = get_num_vertex_faces;
converter->getVertexFaces = get_vertex_faces;
converter->getNumVertexEdges = NULL;
converter->getVertexEdges = NULL;
converter->getNumVertexFaces = NULL;
converter->getVertexFaces = NULL;
converter->isInfiniteSharpVertex = is_infinite_sharp_vertex;
converter->getNumUVLayers = get_num_uv_layers;
@@ -517,55 +288,45 @@ static void init_functions(OpenSubdiv_Converter *converter)
converter->freeUserData = free_user_data;
}
static void create_element_maps_if_needed(ConverterStorage *storage)
{
#ifdef USE_MESH_ELEMENT_MAPPING
const Mesh *mesh = storage->mesh;
BKE_mesh_vert_edge_map_create(&storage->vert_edge_map,
&storage->vert_edge_mem,
mesh->medge,
mesh->totvert,
mesh->totedge);
BKE_mesh_vert_poly_map_create(&storage->vert_poly_map,
&storage->vert_poly_mem,
mesh->mpoly,
mesh->mloop,
mesh->totvert,
mesh->totpoly,
mesh->totloop);
BKE_mesh_edge_poly_map_create(&storage->edge_poly_map,
&storage->edge_poly_mem,
mesh->medge, mesh->totedge,
mesh->mpoly, mesh->totpoly,
mesh->mloop, mesh->totloop);
#else
(void) storage; /* Ignored. */
#endif
}
static void initialize_manifold_index_array(const BLI_bitmap *used_map,
const int num_elements,
int **indices_r,
int **indices_reverse_r,
int *num_manifold_elements_r)
{
int *indices = MEM_malloc_arrayN(
int *indices = NULL;
if (indices_r != NULL) {
indices = MEM_malloc_arrayN(
num_elements, sizeof(int), "manifold indices");
int *indices_reverse = MEM_malloc_arrayN(
}
int *indices_reverse = NULL;
if (indices_reverse_r != NULL) {
indices_reverse = MEM_malloc_arrayN(
num_elements, sizeof(int), "manifold indices reverse");
}
int offset = 0;
for (int i = 0; i < num_elements; i++) {
if (BLI_BITMAP_TEST_BOOL(used_map, i)) {
indices[i] = i - offset;
indices_reverse[i - offset] = i;
if (indices != NULL) {
indices[i] = i - offset;
}
if (indices_reverse != NULL) {
indices_reverse[i - offset] = i;
}
}
else {
indices[i] = -1;
if (indices != NULL) {
indices[i] = -1;
}
offset++;
}
}
*indices_r = indices;
*indices_reverse_r = indices_reverse;
if (indices_r != NULL) {
*indices_r = indices;
}
if (indices_reverse_r != NULL) {
*indices_reverse_r = indices_reverse;
}
*num_manifold_elements_r = num_elements - offset;
}
@@ -593,7 +354,7 @@ static void initialize_manifold_indices(ConverterStorage *storage)
&storage->num_manifold_vertices);
initialize_manifold_index_array(edge_used_map,
mesh->totedge,
&storage->manifold_edge_index,
NULL,
&storage->manifold_edge_index_reverse,
&storage->num_manifold_edges);
/* Initialize infinite sharp mapping. */
@@ -620,7 +381,6 @@ static void init_user_data(OpenSubdiv_Converter *converter,
user_data->settings = *settings;
user_data->mesh = mesh;
user_data->loop_uv_indices = NULL;
create_element_maps_if_needed(user_data);
initialize_manifold_indices(user_data);
converter->user_data = user_data;
}