diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc index a4ac0e3e767..96e9f2008f9 100644 --- a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc +++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc @@ -433,8 +433,8 @@ OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal( const bool has_varying_data = false; const int num_face_varying_channels = refiner->GetNumFVarChannels(); const bool has_face_varying_data = (num_face_varying_channels != 0); - const int level = topology_refiner->getSubdivisionLevel(topology_refiner); - const bool is_adaptive = topology_refiner->getIsAdaptive(topology_refiner); + const int level = topology_refiner->getSubdivisionLevel(); + const bool is_adaptive = topology_refiner->getIsAdaptive(); // Common settings for stencils and patches. const bool stencil_generate_intermediate_levels = is_adaptive; const bool stencil_generate_offsets = true; diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.h b/intern/opensubdiv/internal/evaluator/evaluator_impl.h index 632456fef19..2f06a8c85d3 100644 --- a/intern/opensubdiv/internal/evaluator/evaluator_impl.h +++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.h @@ -22,7 +22,7 @@ struct OpenSubdiv_Buffer; struct OpenSubdiv_EvaluatorCacheImpl; struct OpenSubdiv_EvaluatorSettings; struct OpenSubdiv_PatchCoord; -struct OpenSubdiv_TopologyRefiner; +class OpenSubdiv_TopologyRefiner; namespace blender::opensubdiv { @@ -197,7 +197,7 @@ struct OpenSubdiv_EvaluatorImpl { }; OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal( - struct OpenSubdiv_TopologyRefiner *topology_refiner, + OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type, OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr); diff --git a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc index 5b5c3151213..e7d2e34f13b 100644 --- a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc +++ b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc @@ -22,32 +22,32 @@ static const OpenSubdiv::Far::TopologyLevel &getOSDTopologyBaseLevel( return getOSDTopologyRefiner(topology_refiner)->GetLevel(0); } -static int getSubdivisionLevel(const OpenSubdiv_TopologyRefiner *topology_refiner) +int OpenSubdiv_TopologyRefiner::getSubdivisionLevel() const { - return topology_refiner->impl->settings.level; + return this->impl->settings.level; } -static bool getIsAdaptive(const OpenSubdiv_TopologyRefiner *topology_refiner) +bool OpenSubdiv_TopologyRefiner::getIsAdaptive() const { - return topology_refiner->impl->settings.is_adaptive; + return this->impl->settings.is_adaptive; } //////////////////////////////////////////////////////////////////////////////// // Query basic topology information from base level. -static int getNumVertices(const OpenSubdiv_TopologyRefiner *topology_refiner) +int OpenSubdiv_TopologyRefiner::getNumVertices() const { - return getOSDTopologyBaseLevel(topology_refiner).GetNumVertices(); + return getOSDTopologyBaseLevel(this).GetNumVertices(); } -static int getNumEdges(const OpenSubdiv_TopologyRefiner *topology_refiner) +int OpenSubdiv_TopologyRefiner::getNumEdges() const { - return getOSDTopologyBaseLevel(topology_refiner).GetNumEdges(); + return getOSDTopologyBaseLevel(this).GetNumEdges(); } -static int getNumFaces(const OpenSubdiv_TopologyRefiner *topology_refiner) +int OpenSubdiv_TopologyRefiner::getNumFaces() const { - return getOSDTopologyBaseLevel(topology_refiner).GetNumFaces(); + return getOSDTopologyBaseLevel(this).GetNumFaces(); } //////////////////////////////////////////////////////////////////////////////// @@ -60,164 +60,117 @@ static void convertArrayToRaw(const OpenSubdiv::Far::ConstIndexArray &array, int } } -static int getNumFaceVertices(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index) +int OpenSubdiv_TopologyRefiner::getNumFaceVertices(const int face_index) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); return base_level.GetFaceVertices(face_index).size(); } -static void getFaceVertices(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index, - int *face_vertices_indices) +void OpenSubdiv_TopologyRefiner::getFaceVertices(const int face_index, + int *face_vertices_indices) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); OpenSubdiv::Far::ConstIndexArray array = base_level.GetFaceVertices(face_index); convertArrayToRaw(array, face_vertices_indices); } -static int getNumFaceEdges(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index) +int OpenSubdiv_TopologyRefiner::getNumFaceEdges(const int face_index) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); return base_level.GetFaceEdges(face_index).size(); } -static void getFaceEdges(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index, - int *face_edges_indices) +void OpenSubdiv_TopologyRefiner::getFaceEdges(const int face_index, int *face_edges_indices) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); OpenSubdiv::Far::ConstIndexArray array = base_level.GetFaceEdges(face_index); convertArrayToRaw(array, face_edges_indices); } -static void getEdgeVertices(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int edge_index, - int edge_vertices_indices[2]) +void OpenSubdiv_TopologyRefiner::getEdgeVertices(const int edge_index, + int edge_vertices_indices[2]) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); OpenSubdiv::Far::ConstIndexArray array = base_level.GetEdgeVertices(edge_index); assert(array.size() == 2); edge_vertices_indices[0] = array[0]; edge_vertices_indices[1] = array[1]; } -static int getNumVertexEdges(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int vertex_index) +int OpenSubdiv_TopologyRefiner::getNumVertexEdges(const int vertex_index) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); return base_level.GetVertexEdges(vertex_index).size(); } -static void getVertexEdges(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int vertex_index, - int *vertex_edges_indices) +void OpenSubdiv_TopologyRefiner::getVertexEdges(const int vertex_index, + int *vertex_edges_indices) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); OpenSubdiv::Far::ConstIndexArray array = base_level.GetVertexEdges(vertex_index); convertArrayToRaw(array, vertex_edges_indices); } -static int getNumFacePtexFaces(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index) +int OpenSubdiv_TopologyRefiner::getNumFacePtexFaces(const int face_index) const { - const int num_face_vertices = topology_refiner->getNumFaceVertices(topology_refiner, face_index); + const int num_face_vertices = this->getNumFaceVertices(face_index); if (num_face_vertices == 4) { return 1; } return num_face_vertices; } -static int getNumPtexFaces(const OpenSubdiv_TopologyRefiner *topology_refiner) +int OpenSubdiv_TopologyRefiner::getNumPtexFaces() const { - const int num_faces = topology_refiner->getNumFaces(topology_refiner); + const int num_faces = this->getNumFaces(); int num_ptex_faces = 0; for (int face_index = 0; face_index < num_faces; ++face_index) { - num_ptex_faces += topology_refiner->getNumFacePtexFaces(topology_refiner, face_index); + num_ptex_faces += this->getNumFacePtexFaces(face_index); } return num_ptex_faces; } -static void fillFacePtexIndexOffset(const OpenSubdiv_TopologyRefiner *topology_refiner, - int *face_ptex_index_offset) +void OpenSubdiv_TopologyRefiner::fillFacePtexIndexOffset(int *face_ptex_index_offset) const { - const int num_faces = topology_refiner->getNumFaces(topology_refiner); + const int num_faces = this->getNumFaces(); int num_ptex_faces = 0; for (int face_index = 0; face_index < num_faces; ++face_index) { face_ptex_index_offset[face_index] = num_ptex_faces; - num_ptex_faces += topology_refiner->getNumFacePtexFaces(topology_refiner, face_index); + num_ptex_faces += this->getNumFacePtexFaces(face_index); } } //////////////////////////////////////////////////////////////////////////////// // Face-varying data. -static int getNumFVarChannels(const struct OpenSubdiv_TopologyRefiner *topology_refiner) +int OpenSubdiv_TopologyRefiner::getNumFVarChannels() const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); return base_level.GetNumFVarChannels(); } -static OpenSubdiv_FVarLinearInterpolation getFVarLinearInterpolation( - const struct OpenSubdiv_TopologyRefiner *topology_refiner) +OpenSubdiv_FVarLinearInterpolation OpenSubdiv_TopologyRefiner::getFVarLinearInterpolation() const { return blender::opensubdiv::getCAPIFVarLinearInterpolationFromOSD( - getOSDTopologyRefiner(topology_refiner)->GetFVarLinearInterpolation()); + getOSDTopologyRefiner(this)->GetFVarLinearInterpolation()); } -static int getNumFVarValues(const struct OpenSubdiv_TopologyRefiner *topology_refiner, - const int channel) +int OpenSubdiv_TopologyRefiner::getNumFVarValues(const int channel) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); return base_level.GetNumFVarValues(channel); } -static const int *getFaceFVarValueIndices( - const struct OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index, - const int channel) +const int *OpenSubdiv_TopologyRefiner::getFaceFVarValueIndices(const int face_index, + const int channel) const { - const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner); + const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(this); return &base_level.GetFaceFVarValues(face_index, channel)[0]; } //////////////////////////////////////////////////////////////////////////////// // Internal helpers. -static void assignFunctionPointers(OpenSubdiv_TopologyRefiner *topology_refiner) -{ - topology_refiner->getSubdivisionLevel = getSubdivisionLevel; - topology_refiner->getIsAdaptive = getIsAdaptive; - // Basic topology information. - topology_refiner->getNumVertices = getNumVertices; - topology_refiner->getNumEdges = getNumEdges; - topology_refiner->getNumFaces = getNumFaces; - topology_refiner->getNumFaceVertices = getNumFaceVertices; - topology_refiner->getFaceVertices = getFaceVertices; - topology_refiner->getNumFaceEdges = getNumFaceEdges; - topology_refiner->getFaceEdges = getFaceEdges; - topology_refiner->getEdgeVertices = getEdgeVertices; - topology_refiner->getNumVertexEdges = getNumVertexEdges; - topology_refiner->getVertexEdges = getVertexEdges; - // PTex face geometry. - topology_refiner->getNumFacePtexFaces = getNumFacePtexFaces; - topology_refiner->getNumPtexFaces = getNumPtexFaces; - topology_refiner->fillFacePtexIndexOffset = fillFacePtexIndexOffset; - // Face-varying data. - topology_refiner->getNumFVarChannels = getNumFVarChannels; - topology_refiner->getFVarLinearInterpolation = getFVarLinearInterpolation; - topology_refiner->getNumFVarValues = getNumFVarValues; - topology_refiner->getFaceFVarValueIndices = getFaceFVarValueIndices; -} - -static OpenSubdiv_TopologyRefiner *allocateTopologyRefiner() -{ - OpenSubdiv_TopologyRefiner *topology_refiner = MEM_new(__func__); - assignFunctionPointers(topology_refiner); - return topology_refiner; -} - OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter( OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings) { @@ -229,7 +182,7 @@ OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter( return nullptr; } - OpenSubdiv_TopologyRefiner *topology_refiner = allocateTopologyRefiner(); + OpenSubdiv_TopologyRefiner *topology_refiner = MEM_new(__func__); topology_refiner->impl = static_cast(topology_refiner_impl); return topology_refiner; diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.hh b/intern/opensubdiv/opensubdiv_evaluator_capi.hh index 4098b66387d..d25f6126e03 100644 --- a/intern/opensubdiv/opensubdiv_evaluator_capi.hh +++ b/intern/opensubdiv/opensubdiv_evaluator_capi.hh @@ -12,7 +12,7 @@ struct OpenSubdiv_EvaluatorCacheImpl; struct OpenSubdiv_EvaluatorImpl; struct OpenSubdiv_EvaluatorInternal; struct OpenSubdiv_PatchCoord; -struct OpenSubdiv_TopologyRefiner; +class OpenSubdiv_TopologyRefiner; struct OpenSubdiv_EvaluatorSettings { // Number of smoothly interpolated vertex data channels. diff --git a/intern/opensubdiv/opensubdiv_topology_refiner_capi.hh b/intern/opensubdiv/opensubdiv_topology_refiner_capi.hh index 169607c51e6..f2214698a7b 100644 --- a/intern/opensubdiv/opensubdiv_topology_refiner_capi.hh +++ b/intern/opensubdiv/opensubdiv_topology_refiner_capi.hh @@ -25,10 +25,11 @@ struct OpenSubdiv_TopologyRefinerSettings { // // The only purpose is to allow C-only code to access C++ implementation of the // topology refiner. -struct OpenSubdiv_TopologyRefiner { +class OpenSubdiv_TopologyRefiner { + public: // Query subdivision level the refiner is created for. - int (*getSubdivisionLevel)(const OpenSubdiv_TopologyRefiner *topology_refiner); - bool (*getIsAdaptive)(const OpenSubdiv_TopologyRefiner *topology_refiner); + int getSubdivisionLevel() const; + bool getIsAdaptive() const; // NOTE: All queries are querying base level. // @@ -40,29 +41,19 @@ struct OpenSubdiv_TopologyRefiner { ////////////////////////////////////////////////////////////////////////////// // Query basic topology information from base level. - int (*getNumVertices)(const OpenSubdiv_TopologyRefiner *topology_refiner); - int (*getNumEdges)(const OpenSubdiv_TopologyRefiner *topology_refiner); - int (*getNumFaces)(const OpenSubdiv_TopologyRefiner *topology_refiner); + int getNumVertices() const; + int getNumEdges() const; + int getNumFaces() const; - int (*getNumFaceVertices)(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index); - void (*getFaceVertices)(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index, - int *face_vertices_indices); + int getNumFaceVertices(int face_index) const; + void getFaceVertices(int face_index, int *face_vertices_indices) const; - int (*getNumFaceEdges)(const OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index); - void (*getFaceEdges)(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index, - int *face_edges_indices); - void (*getEdgeVertices)(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int edge_index, - int edge_vertices_indices[2]); + int getNumFaceEdges(int face_index) const; + void getFaceEdges(int face_index, int *face_edges_indices) const; + void getEdgeVertices(int edge_index, int edge_vertices_indices[2]) const; - int (*getNumVertexEdges)(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int vertex_index); - void (*getVertexEdges)(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int vertex_index, - int *vertex_edges_indices); + int getNumVertexEdges(int vertex_index) const; + void getVertexEdges(int vertex_index, int *vertex_edges_indices) const; ////////////////////////////////////////////////////////////////////////////// // PTex face geometry queries. @@ -74,9 +65,8 @@ struct OpenSubdiv_TopologyRefiner { // - Quad face consists of a single ptex face. // - N-gons (similar to triangle) consists of N ptex faces, ordered same // way as for triangle. - int (*getNumFacePtexFaces)(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index); - int (*getNumPtexFaces)(const OpenSubdiv_TopologyRefiner *topology_refiner); + int getNumFacePtexFaces(int face_index) const; + int getNumPtexFaces() const; // Initialize a per-base-face offset measured in ptex face indices. // @@ -84,26 +74,22 @@ struct OpenSubdiv_TopologyRefiner { // faces created for bases faces [0 .. base_face_index - 1]. // // The array must contain at least total number of ptex faces elements. - void (*fillFacePtexIndexOffset)(const OpenSubdiv_TopologyRefiner *topology_refiner, - int *face_ptex_index_offset); + void fillFacePtexIndexOffset(int *face_ptex_index_offset) const; ////////////////////////////////////////////////////////////////////////////// // Face-varying data. // Number of face-varying channels (or how they are called in Blender layers). - int (*getNumFVarChannels)(const OpenSubdiv_TopologyRefiner *topology_refiner); + int getNumFVarChannels() const; // Get face-varying interpolation type. - OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)( - const OpenSubdiv_TopologyRefiner *topology_refiner); + OpenSubdiv_FVarLinearInterpolation getFVarLinearInterpolation() const; // Get total number of face-varying values in a particular channel. - int (*getNumFVarValues)(const OpenSubdiv_TopologyRefiner *topology_refiner, const int channel); + int getNumFVarValues(int channel) const; // Get face-varying value indices associated with a particular face. // // This is an array of indices inside of face-varying array, array elements // are aligned with face corners (or loops in Blender terminology). - const int *(*getFaceFVarValueIndices)(const OpenSubdiv_TopologyRefiner *topology_refiner, - const int face_index, - const int channel); + const int *getFaceFVarValueIndices(int face_index, int channel) const; ////////////////////////////////////////////////////////////////////////////// // Internal use. diff --git a/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc b/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc index 641f8016e0a..01867c1f548 100644 --- a/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc +++ b/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc @@ -9,7 +9,7 @@ #include OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner( - struct OpenSubdiv_TopologyRefiner * /*topology_refiner*/, + OpenSubdiv_TopologyRefiner * /*topology_refiner*/, eOpenSubdivEvaluator /*evaluator_type*/, OpenSubdiv_EvaluatorCache * /*evaluator_cache*/) { diff --git a/source/blender/blenkernel/BKE_subdiv.hh b/source/blender/blenkernel/BKE_subdiv.hh index b298117df20..0ee0fdd1229 100644 --- a/source/blender/blenkernel/BKE_subdiv.hh +++ b/source/blender/blenkernel/BKE_subdiv.hh @@ -15,7 +15,7 @@ struct Mesh; struct MultiresModifierData; struct OpenSubdiv_Converter; struct OpenSubdiv_Evaluator; -struct OpenSubdiv_TopologyRefiner; +class OpenSubdiv_TopologyRefiner; namespace blender::bke::subdiv { diff --git a/source/blender/blenkernel/intern/subdiv.cc b/source/blender/blenkernel/intern/subdiv.cc index 1b55b63cb0e..a8fd4d51ef4 100644 --- a/source/blender/blenkernel/intern/subdiv.cc +++ b/source/blender/blenkernel/intern/subdiv.cc @@ -205,24 +205,29 @@ void free(Subdiv *subdiv) int *face_ptex_offset_get(Subdiv *subdiv) { +#ifdef WITH_OPENSUBDIV if (subdiv->cache_.face_ptex_offset != nullptr) { return subdiv->cache_.face_ptex_offset; } - OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; + const OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; if (topology_refiner == nullptr) { return nullptr; } - const int num_coarse_faces = topology_refiner->getNumFaces(topology_refiner); + const int num_coarse_faces = topology_refiner->getNumFaces(); subdiv->cache_.face_ptex_offset = static_cast( MEM_malloc_arrayN(num_coarse_faces + 1, sizeof(int), __func__)); int ptex_offset = 0; for (int face_index = 0; face_index < num_coarse_faces; face_index++) { - const int num_ptex_faces = topology_refiner->getNumFacePtexFaces(topology_refiner, face_index); + const int num_ptex_faces = topology_refiner->getNumFacePtexFaces(face_index); subdiv->cache_.face_ptex_offset[face_index] = ptex_offset; ptex_offset += num_ptex_faces; } subdiv->cache_.face_ptex_offset[num_coarse_faces] = ptex_offset; return subdiv->cache_.face_ptex_offset; +#else + UNUSED_VARS(subdiv); + return nullptr; +#endif } } // namespace blender::bke::subdiv diff --git a/source/blender/blenkernel/intern/subdiv_ccg.cc b/source/blender/blenkernel/intern/subdiv_ccg.cc index a20153693eb..c45cf0e8811 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.cc +++ b/source/blender/blenkernel/intern/subdiv_ccg.cc @@ -44,6 +44,8 @@ using namespace blender::bke::subdiv; /** \name Various forward declarations * \{ */ +#ifdef WITH_OPENSUBDIV + static void subdiv_ccg_average_inner_face_grids(SubdivCCG &subdiv_ccg, const CCGKey &key, const IndexRange face); @@ -116,10 +118,10 @@ static void subdiv_ccg_init_layers(SubdivCCG &subdiv_ccg, const SubdivToCCGSetti /* TODO(sergey): Make it more accessible function. */ static int topology_refiner_count_face_corners(OpenSubdiv_TopologyRefiner *topology_refiner) { - const int num_faces = topology_refiner->getNumFaces(topology_refiner); + const int num_faces = topology_refiner->getNumFaces(); int num_corners = 0; for (int face_index = 0; face_index < num_faces; face_index++) { - num_corners += topology_refiner->getNumFaceVertices(topology_refiner, face_index); + num_corners += topology_refiner->getNumFaceVertices(face_index); } return num_corners; } @@ -267,7 +269,7 @@ 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 int num_faces = topology_refiner->getNumFaces(); const Span face_ptex_offset(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) { @@ -331,7 +333,7 @@ static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG &subdiv_ccg) Subdiv *subdiv = subdiv_ccg.subdiv; const OffsetIndices faces = subdiv_ccg.faces; OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; - const int num_edges = topology_refiner->getNumEdges(topology_refiner); + const int num_edges = topology_refiner->getNumEdges(); const int grid_size = subdiv_ccg.grid_size; if (num_edges == 0) { /* Early output, nothing to do in this case. */ @@ -346,17 +348,17 @@ static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG &subdiv_ccg) const IndexRange face = faces[face_index]; const int num_face_grids = face.size(); face_vertices.reinitialize(num_face_grids); - topology_refiner->getFaceVertices(topology_refiner, face_index, face_vertices.data()); + topology_refiner->getFaceVertices(face_index, face_vertices.data()); /* Note that order of edges is same as order of MLoops, which also * means it's the same as order of grids. */ face_edges.reinitialize(num_face_grids); - topology_refiner->getFaceEdges(topology_refiner, face_index, face_edges.data()); + topology_refiner->getFaceEdges(face_index, face_edges.data()); /* Store grids adjacency for this edge. */ for (int corner = 0; corner < num_face_grids; corner++) { const int vertex_index = face_vertices[corner]; const int edge_index = face_edges[corner]; int edge_vertices[2]; - topology_refiner->getEdgeVertices(topology_refiner, edge_index, edge_vertices); + topology_refiner->getEdgeVertices(edge_index, edge_vertices); const bool is_edge_flipped = (edge_vertices[0] != vertex_index); /* Grid which is adjacent to the current corner. */ const int current_grid_index = face.start() + corner; @@ -417,7 +419,7 @@ static void subdiv_ccg_init_faces_vertex_neighborhood(SubdivCCG &subdiv_ccg) Subdiv *subdiv = subdiv_ccg.subdiv; const OffsetIndices faces = subdiv_ccg.faces; OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; - const int num_vertices = topology_refiner->getNumVertices(topology_refiner); + const int num_vertices = topology_refiner->getNumVertices(); const int grid_size = subdiv_ccg.grid_size; if (num_vertices == 0) { /* Early output, nothing to do in this case. */ @@ -430,7 +432,7 @@ static void subdiv_ccg_init_faces_vertex_neighborhood(SubdivCCG &subdiv_ccg) const IndexRange face = faces[face_index]; const int num_face_grids = face.size(); face_vertices.reinitialize(num_face_grids); - topology_refiner->getFaceVertices(topology_refiner, face_index, face_vertices.data()); + topology_refiner->getFaceVertices(face_index, face_vertices.data()); for (int corner = 0; corner < num_face_grids; corner++) { const int vertex_index = face_vertices[corner]; /* Grid which is adjacent to the current corner. */ @@ -449,6 +451,8 @@ static void subdiv_ccg_init_faces_neighborhood(SubdivCCG &subdiv_ccg) subdiv_ccg_init_faces_vertex_neighborhood(subdiv_ccg); } +#endif + /** \} */ /* -------------------------------------------------------------------- */ @@ -460,6 +464,7 @@ std::unique_ptr BKE_subdiv_to_ccg(Subdiv &subdiv, const Mesh &coarse_mesh, SubdivCCGMaskEvaluator *mask_evaluator) { +#ifdef WITH_OPENSUBDIV stats_begin(&subdiv.stats, SUBDIV_STATS_SUBDIV_TO_CCG); std::unique_ptr subdiv_ccg = std::make_unique(); subdiv_ccg->subdiv = &subdiv; @@ -476,6 +481,10 @@ std::unique_ptr BKE_subdiv_to_ccg(Subdiv &subdiv, } stats_end(&subdiv.stats, SUBDIV_STATS_SUBDIV_TO_CCG); return subdiv_ccg; +#else + UNUSED_VARS(subdiv, settings, coarse_mesh, mask_evaluator); + return {}; +#endif } Mesh *BKE_subdiv_to_ccg_mesh(Subdiv &subdiv, @@ -527,6 +536,7 @@ SubdivCCG::~SubdivCCG() CCGKey BKE_subdiv_ccg_key(const SubdivCCG &subdiv_ccg, int level) { +#ifdef WITH_OPENSUBDIV CCGKey key; key.level = level; key.elem_size = element_size_bytes_get(subdiv_ccg); @@ -540,6 +550,10 @@ CCGKey BKE_subdiv_ccg_key(const SubdivCCG &subdiv_ccg, int level) key.has_normals = subdiv_ccg.has_normal; key.has_mask = subdiv_ccg.has_mask; return key; +#else + UNUSED_VARS(subdiv_ccg, level); + return {}; +#endif } CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg) @@ -553,6 +567,8 @@ CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg) /** \name Normals * \{ */ +#ifdef WITH_OPENSUBDIV + /* Evaluate high-res face normals, for faces which corresponds to grid elements * * {(x, y), {x + 1, y}, {x + 1, y + 1}, {x, y + 1}} @@ -649,18 +665,25 @@ static void subdiv_ccg_recalc_inner_grid_normals(SubdivCCG &subdiv_ccg, const In }); } +#endif + void BKE_subdiv_ccg_recalc_normals(SubdivCCG &subdiv_ccg) { +#ifdef WITH_OPENSUBDIV if (!subdiv_ccg.has_normal) { /* Grids don't have normals, can do early output. */ return; } subdiv_ccg_recalc_inner_grid_normals(subdiv_ccg, subdiv_ccg.faces.index_range()); BKE_subdiv_ccg_average_grids(subdiv_ccg); +#else + UNUSED_VARS(subdiv_ccg); +#endif } void BKE_subdiv_ccg_update_normals(SubdivCCG &subdiv_ccg, const IndexMask &face_mask) { +#ifdef WITH_OPENSUBDIV if (!subdiv_ccg.has_normal) { /* Grids don't have normals, can do early output. */ return; @@ -673,6 +696,9 @@ void BKE_subdiv_ccg_update_normals(SubdivCCG &subdiv_ccg, const IndexMask &face_ const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); subdiv_ccg_average_faces_boundaries_and_corners(subdiv_ccg, key, face_mask); +#else + UNUSED_VARS(subdiv_ccg, face_mask); +#endif } /** \} */ @@ -681,6 +707,8 @@ void BKE_subdiv_ccg_update_normals(SubdivCCG &subdiv_ccg, const IndexMask &face_ /** \name Boundary averaging/stitching * \{ */ +#ifdef WITH_OPENSUBDIV + static void average_grid_element_value_v3(float a[3], float b[3]) { add_v3_v3(a, b); @@ -886,8 +914,11 @@ static void subdiv_ccg_average_corners(SubdivCCG &subdiv_ccg, }); } +#endif + void BKE_subdiv_ccg_average_grids(SubdivCCG &subdiv_ccg) { +#ifdef WITH_OPENSUBDIV using namespace blender; const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); /* Average inner boundaries of grids (within one face), across faces @@ -895,8 +926,13 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG &subdiv_ccg) 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()); +#else + UNUSED_VARS(subdiv_ccg); +#endif } +#ifdef WITH_OPENSUBDIV + static void subdiv_ccg_affected_face_adjacency(SubdivCCG &subdiv_ccg, const IndexMask &face_mask, blender::Set &adjacent_verts, @@ -911,11 +947,11 @@ static void subdiv_ccg_affected_face_adjacency(SubdivCCG &subdiv_ccg, face_mask.foreach_index([&](const int face_index) { const int num_face_grids = subdiv_ccg.faces[face_index].size(); face_vertices.reinitialize(num_face_grids); - topology_refiner->getFaceVertices(topology_refiner, face_index, face_vertices.data()); + topology_refiner->getFaceVertices(face_index, face_vertices.data()); adjacent_verts.add_multiple(face_vertices); face_edges.reinitialize(num_face_grids); - topology_refiner->getFaceEdges(topology_refiner, face_index, face_edges.data()); + topology_refiner->getFaceEdges(face_index, face_edges.data()); adjacent_edges.add_multiple(face_edges); }); } @@ -942,8 +978,11 @@ void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG &subdiv_ccg, subdiv_ccg, key, IndexMask::from_indices(adjacent_verts.as_span(), memory)); } +#endif + void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG &subdiv_ccg, const IndexMask &face_mask) { +#ifdef WITH_OPENSUBDIV using namespace blender; const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); face_mask.foreach_index(GrainSize(512), [&](const int face_index) { @@ -953,6 +992,9 @@ void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG &subdiv_ccg, const IndexMask * faces. */ 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()); +#else + UNUSED_VARS(subdiv_ccg, face_mask); +#endif } void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg, @@ -1072,6 +1114,8 @@ BLI_INLINE SubdivCCGCoord coord_at_next_col(const SubdivCCG &subdiv_ccg, return result; } +#ifdef WITH_OPENSUBDIV + /* For the input coordinate which is at the boundary of the grid do one step inside. */ static SubdivCCGCoord coord_step_inside_from_boundary(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord) @@ -1160,7 +1204,7 @@ static int adjacent_vertex_index_from_coord(const SubdivCCG &subdiv_ccg, const int num_face_grids = face.size(); Array face_vertices(num_face_grids); - topology_refiner->getFaceVertices(topology_refiner, face_index, face_vertices.data()); + topology_refiner->getFaceVertices(face_index, face_vertices.data()); const int adjacent_vertex_index = face_vertices[face_grid_index]; return adjacent_vertex_index; @@ -1176,8 +1220,7 @@ static void neighbor_coords_corner_vertex_get(const SubdivCCG &subdiv_ccg, OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; const int adjacent_vertex_index = adjacent_vertex_index_from_coord(subdiv_ccg, coord); - const int num_vertex_edges = topology_refiner->getNumVertexEdges(topology_refiner, - adjacent_vertex_index); + const int num_vertex_edges = topology_refiner->getNumVertexEdges(adjacent_vertex_index); const SubdivCCGAdjacentVertex &adjacent_vert = subdiv_ccg.adjacent_verts[adjacent_vertex_index]; const int num_adjacent_faces = adjacent_vert.num_adjacent_faces; @@ -1186,7 +1229,7 @@ static void neighbor_coords_corner_vertex_get(const SubdivCCG &subdiv_ccg, r_neighbors, num_vertex_edges, (include_duplicates) ? num_adjacent_faces - 1 : 0); Array vertex_edges(num_vertex_edges); - topology_refiner->getVertexEdges(topology_refiner, adjacent_vertex_index, vertex_edges.data()); + topology_refiner->getVertexEdges(adjacent_vertex_index, vertex_edges.data()); for (int i = 0; i < num_vertex_edges; ++i) { const int edge_index = vertex_edges[i]; @@ -1196,7 +1239,7 @@ static void neighbor_coords_corner_vertex_get(const SubdivCCG &subdiv_ccg, /* Depending edge orientation we use first (zero-based) or previous-to-last point. */ int edge_vertices_indices[2]; - topology_refiner->getEdgeVertices(topology_refiner, edge_index, edge_vertices_indices); + topology_refiner->getEdgeVertices(edge_index, edge_vertices_indices); int edge_point_index, duplicate_edge_point_index; if (edge_vertices_indices[0] == adjacent_vertex_index) { duplicate_edge_point_index = 0; @@ -1233,10 +1276,10 @@ static int adjacent_edge_index_from_coord(const SubdivCCG &subdiv_ccg, const Sub const int face_index = subdiv_ccg.grid_to_face_map[coord.grid_index]; const IndexRange face = subdiv_ccg.faces[face_index]; const int face_grid_index = coord.grid_index - face.start(); - const int num_face_edges = topology_refiner->getNumFaceEdges(topology_refiner, face_index); + const int num_face_edges = topology_refiner->getNumFaceEdges(face_index); Array face_edges(num_face_edges); - topology_refiner->getFaceEdges(topology_refiner, face_index, face_edges.data()); + topology_refiner->getFaceEdges(face_index, face_edges.data()); const int grid_size_1 = subdiv_ccg.grid_size - 1; int adjacent_edge_index = -1; @@ -1260,7 +1303,7 @@ static int adjacent_edge_point_index_from_coord(const SubdivCCG &subdiv_ccg, const int adjacent_vertex_index = adjacent_vertex_index_from_coord(subdiv_ccg, coord); int edge_vertices_indices[2]; - topology_refiner->getEdgeVertices(topology_refiner, adjacent_edge_index, edge_vertices_indices); + topology_refiner->getEdgeVertices(adjacent_edge_index, edge_vertices_indices); /* Vertex index of an edge which is used to see whether edge points in the right direction. * Tricky part here is that depending whether input coordinate is are maximum X or Y coordinate @@ -1488,11 +1531,14 @@ static void neighbor_coords_inner_get(const SubdivCCG &subdiv_ccg, r_neighbors.coords[3] = coord_at_next_col(subdiv_ccg, coord); } +#endif + void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, const bool include_duplicates, SubdivCCGNeighbors &r_neighbors) { +#ifdef WITH_OPENSUBDIV BLI_assert(coord.grid_index >= 0); BLI_assert(coord.grid_index < subdiv_ccg.grids.size()); BLI_assert(coord.x >= 0); @@ -1510,15 +1556,19 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg, neighbor_coords_inner_get(subdiv_ccg, coord, r_neighbors); } -#ifndef NDEBUG +# ifndef NDEBUG for (const int i : r_neighbors.coords.index_range()) { BLI_assert(BKE_subdiv_ccg_check_coord_valid(subdiv_ccg, r_neighbors.coords[i])); } +# endif +#else + UNUSED_VARS(subdiv_ccg, coord, include_duplicates, r_neighbors); #endif } const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg) { +#ifdef WITH_OPENSUBDIV if (subdiv_ccg.cache_.start_face_grid_index.is_empty()) { const Subdiv *subdiv = subdiv_ccg.subdiv; OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; @@ -1526,18 +1576,18 @@ const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg) return nullptr; } - const int num_coarse_faces = topology_refiner->getNumFaces(topology_refiner); + const int num_coarse_faces = topology_refiner->getNumFaces(); 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++) { - const int num_face_grids = topology_refiner->getNumFaceVertices(topology_refiner, - face_index); + const int num_face_grids = topology_refiner->getNumFaceVertices(face_index); subdiv_ccg.cache_.start_face_grid_index[face_index] = start_grid_index; start_grid_index += num_face_grids; } } +#endif return subdiv_ccg.cache_.start_face_grid_index.data(); } diff --git a/source/blender/blenkernel/intern/subdiv_eval.cc b/source/blender/blenkernel/intern/subdiv_eval.cc index 6d2f5ba1efe..e1a1238972e 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.cc +++ b/source/blender/blenkernel/intern/subdiv_eval.cc @@ -76,6 +76,8 @@ bool eval_begin(Subdiv *subdiv, return true; } +#ifdef WITH_OPENSUBDIV + static void set_coarse_positions(Subdiv *subdiv, const Span positions, const bke::LooseVertCache &verts_no_face) @@ -124,9 +126,8 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata, /* TODO(sergey): OpenSubdiv's C-API converter can change winding of * loops of a face, need to watch for that, to prevent wrong UVs assigned. */ - const int num_face_vertices = topology_refiner->getNumFaceVertices(topology_refiner, face_index); - const int *uv_indices = topology_refiner->getFaceFVarValueIndices( - topology_refiner, face_index, layer_index); + const int num_face_vertices = topology_refiner->getNumFaceVertices(face_index); + const int *uv_indices = topology_refiner->getFaceFVarValueIndices(face_index, layer_index); for (int vertex_index = 0; vertex_index < num_face_vertices; vertex_index++, mluv++) { copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], *mluv); } @@ -139,10 +140,10 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv, { OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; - const int num_faces = topology_refiner->getNumFaces(topology_refiner); + const int num_faces = topology_refiner->getNumFaces(); const float(*mluv)[2] = mloopuv; - const int num_fvar_values = topology_refiner->getNumFVarValues(topology_refiner, layer_index); + const int num_fvar_values = topology_refiner->getNumFVarValues(layer_index); /* Use a temporary buffer so we do not upload UVs one at a time to the GPU. */ float(*buffer)[2] = static_cast( MEM_mallocN(sizeof(float[2]) * num_fvar_values, __func__)); @@ -175,9 +176,9 @@ static void set_vertex_data_from_orco(Subdiv *subdiv, const Mesh *mesh) CustomData_get_layer(&mesh->vert_data, CD_CLOTH_ORCO)); if (orco || cloth_orco) { - OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; + const OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; - const int num_verts = topology_refiner->getNumVertices(topology_refiner); + const int num_verts = topology_refiner->getNumVertices(); if (orco && cloth_orco) { /* Set one by one if have both. */ @@ -206,22 +207,30 @@ static void get_mesh_evaluator_settings(OpenSubdiv_EvaluatorSettings *settings, (CustomData_has_layer(&mesh->vert_data, CD_CLOTH_ORCO) ? 3 : 0); } +#endif + bool eval_begin_from_mesh(Subdiv *subdiv, const Mesh *mesh, const float (*coarse_vertex_cos)[3], eSubdivEvaluatorType evaluator_type, OpenSubdiv_EvaluatorCache *evaluator_cache) { +#ifdef WITH_OPENSUBDIV OpenSubdiv_EvaluatorSettings settings = {0}; get_mesh_evaluator_settings(&settings, mesh); if (!eval_begin(subdiv, evaluator_type, evaluator_cache, &settings)) { return false; } return eval_refine_from_mesh(subdiv, mesh, coarse_vertex_cos); +#else + UNUSED_VARS(subdiv, mesh, coarse_vertex_cos, evaluator_type, evaluator_cache); + return false; +#endif } bool eval_refine_from_mesh(Subdiv *subdiv, const Mesh *mesh, const float (*coarse_vertex_cos)[3]) { +#ifdef WITH_OPENSUBDIV if (subdiv->evaluator == nullptr) { /* NOTE: This situation is supposed to be handled by begin(). */ BLI_assert_msg(0, "Is not supposed to happen"); @@ -249,6 +258,10 @@ bool eval_refine_from_mesh(Subdiv *subdiv, const Mesh *mesh, const float (*coars subdiv->evaluator->refine(subdiv->evaluator); stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE); return true; +#else + UNUSED_VARS(subdiv, mesh, coarse_vertex_cos); + return false; +#endif } void eval_init_displacement(Subdiv *subdiv) diff --git a/source/blender/blenkernel/intern/subdiv_topology.cc b/source/blender/blenkernel/intern/subdiv_topology.cc index 053695742cd..a8d54de7785 100644 --- a/source/blender/blenkernel/intern/subdiv_topology.cc +++ b/source/blender/blenkernel/intern/subdiv_topology.cc @@ -16,8 +16,12 @@ namespace blender::bke::subdiv { int topology_num_fvar_layers_get(const Subdiv *subdiv) { +#ifdef WITH_OPENSUBDIV OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; - return topology_refiner->getNumFVarChannels(topology_refiner); + return topology_refiner->getNumFVarChannels(); +#else + return 0; +#endif } } // namespace blender::bke::subdiv