diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt index 0bf3bbcb2b9..f4bfaf52df1 100644 --- a/intern/opensubdiv/CMakeLists.txt +++ b/intern/opensubdiv/CMakeLists.txt @@ -68,7 +68,6 @@ if(WITH_OPENSUBDIV) # Topology. internal/topology/topology_refiner_capi.cc internal/topology/topology_refiner_factory.cc - internal/topology/topology_refiner_factory.h internal/topology/topology_refiner_impl.cc internal/topology/topology_refiner_impl.h diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc index e5b9654c5d9..a9960a9b027 100644 --- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc @@ -751,7 +751,7 @@ OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal( OpenSubdiv_TopologyRefiner *topology_refiner) { using blender::opensubdiv::vector; - TopologyRefiner *refiner = topology_refiner->impl->osd_topology_refiner; + TopologyRefiner *refiner = topology_refiner->impl->topology_refiner; if (refiner == NULL) { // Happens on bad topology. return NULL; diff --git a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc index 5014d24a52b..56d90b84632 100644 --- a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc +++ b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc @@ -23,7 +23,6 @@ #include "internal/opensubdiv_edge_map.h" #include "internal/opensubdiv_internal.h" #include "internal/opensubdiv_util.h" -#include "internal/topology/topology_refiner_factory.h" #include "internal/topology/topology_refiner_impl.h" using blender::opensubdiv::vector; @@ -33,7 +32,7 @@ namespace { const OpenSubdiv::Far::TopologyRefiner *getOSDTopologyRefiner( const OpenSubdiv_TopologyRefiner *topology_refiner) { - return topology_refiner->impl->osd_topology_refiner; + return topology_refiner->impl->topology_refiner; } const OpenSubdiv::Far::TopologyLevel *getOSDTopologyBaseLevel( @@ -230,7 +229,6 @@ void assignFunctionPointers(OpenSubdiv_TopologyRefiner *topology_refiner) OpenSubdiv_TopologyRefiner *allocateTopologyRefiner() { OpenSubdiv_TopologyRefiner *topology_refiner = OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefiner); - topology_refiner->impl = new OpenSubdiv_TopologyRefinerImpl(); assignFunctionPointers(topology_refiner); return topology_refiner; } @@ -240,17 +238,17 @@ OpenSubdiv_TopologyRefiner *allocateTopologyRefiner() OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter( OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings) { - OpenSubdiv::Far::TopologyRefiner *osd_topology_refiner = - blender::opensubdiv::createOSDTopologyRefinerFromConverter(converter); - if (osd_topology_refiner == NULL) { - // Happens on empty or bad topology. - return NULL; + using blender::opensubdiv::TopologyRefinerImpl; + + TopologyRefinerImpl *topology_refiner_impl = TopologyRefinerImpl::createFromConverter(converter, + *settings); + if (topology_refiner_impl == nullptr) { + return nullptr; } + OpenSubdiv_TopologyRefiner *topology_refiner = allocateTopologyRefiner(); - topology_refiner->impl->osd_topology_refiner = osd_topology_refiner; - // Store setting which we want to keep track of and which can not be stored - // in OpenSubdiv's descriptor yet. - topology_refiner->impl->settings = *settings; + topology_refiner->impl = static_cast(topology_refiner_impl); + return topology_refiner; } diff --git a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc index 1f69025782d..2e86a39fb51 100644 --- a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc +++ b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc @@ -20,7 +20,7 @@ # include #endif -#include "internal/topology/topology_refiner_factory.h" +#include "internal/topology/topology_refiner_impl.h" #include #include @@ -40,6 +40,8 @@ struct TopologyRefinerData { const OpenSubdiv_Converter *converter; }; +typedef OpenSubdiv::Far::TopologyRefinerFactory TopologyRefinerFactoryType; + namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { namespace Far { @@ -254,6 +256,7 @@ OpenSubdiv::Sdc::Options::VtxBoundaryInterpolation getVtxBoundaryInterpolationFr OpenSubdiv_VtxBoundaryInterpolation boundary_interpolation) { using OpenSubdiv::Sdc::Options; + switch (boundary_interpolation) { case OSD_VTX_BOUNDARY_NONE: return Options::VTX_BOUNDARY_NONE; @@ -266,30 +269,62 @@ OpenSubdiv::Sdc::Options::VtxBoundaryInterpolation getVtxBoundaryInterpolationFr return Options::VTX_BOUNDARY_EDGE_ONLY; } -} // namespace - -OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter( - OpenSubdiv_Converter *converter) +OpenSubdiv::Sdc::Options getSDCOptions(OpenSubdiv_Converter *converter) { - using OpenSubdiv::Far::TopologyRefinerFactory; using OpenSubdiv::Sdc::Options; - const OpenSubdiv::Sdc::SchemeType scheme_type = getSchemeTypeFromCAPI( - converter->getSchemeType(converter)); + const Options::FVarLinearInterpolation linear_interpolation = getFVarLinearInterpolationFromCAPI( converter->getFVarLinearInterpolation(converter)); + Options options; options.SetVtxBoundaryInterpolation( getVtxBoundaryInterpolationFromCAPI(converter->getVtxBoundaryInterpolation(converter))); options.SetCreasingMethod(Options::CREASE_UNIFORM); options.SetFVarLinearInterpolation(linear_interpolation); - TopologyRefinerFactory::Options topology_options(scheme_type, options); + return options; +} + +TopologyRefinerFactoryType::Options getTopologyRefinerOptions(OpenSubdiv_Converter *converter) +{ + using OpenSubdiv::Sdc::SchemeType; + + OpenSubdiv::Sdc::Options sdc_options = getSDCOptions(converter); + + const SchemeType scheme_type = getSchemeTypeFromCAPI(converter->getSchemeType(converter)); + TopologyRefinerFactoryType::Options topology_options(scheme_type, sdc_options); #ifdef OPENSUBDIV_VALIDATE_TOPOLOGY topology_options.validateFullTopology = true; #endif + + return topology_options; +} + +} // namespace + +TopologyRefinerImpl *TopologyRefinerImpl::createFromConverter( + OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings &settings) +{ + using OpenSubdiv::Far::TopologyRefiner; + TopologyRefinerData cb_data; cb_data.converter = converter; - return TopologyRefinerFactory::Create(cb_data, topology_options); + + // Create OpenSubdiv descriptor for the topology refiner. + TopologyRefinerFactoryType::Options topology_refiner_options = getTopologyRefinerOptions( + converter); + TopologyRefiner *topology_refiner = TopologyRefinerFactoryType::Create(cb_data, + topology_refiner_options); + if (topology_refiner == nullptr) { + return nullptr; + } + + // Create Blender-side object holding all necessary data for the topology refiner. + TopologyRefinerImpl *topology_refiner_impl = new TopologyRefinerImpl(); + topology_refiner_impl->topology_refiner = topology_refiner; + topology_refiner_impl->settings = settings; + + return topology_refiner_impl; } } // namespace opensubdiv diff --git a/intern/opensubdiv/internal/topology/topology_refiner_factory.h b/intern/opensubdiv/internal/topology/topology_refiner_factory.h deleted file mode 100644 index 4333292f3d1..00000000000 --- a/intern/opensubdiv/internal/topology/topology_refiner_factory.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2015 Blender Foundation. All rights reserved. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// Author: Sergey Sharybin - -#ifndef OPENSUBDIV_TOPOLOGY_REFINER_FACTORY_H_ -#define OPENSUBDIV_TOPOLOGY_REFINER_FACTORY_H_ - -#ifdef _MSC_VER -# include -#endif - -#include - -struct OpenSubdiv_Converter; - -namespace blender { -namespace opensubdiv { - -OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter( - struct OpenSubdiv_Converter *converter); - -} // namespace opensubdiv -} // namespace blender - -#endif // OPENSUBDIV_TOPOLOGY_REFINER_FACTORY_H_ diff --git a/intern/opensubdiv/internal/topology/topology_refiner_impl.cc b/intern/opensubdiv/internal/topology/topology_refiner_impl.cc index 7d2ae2a6304..fe14d42ac33 100644 --- a/intern/opensubdiv/internal/topology/topology_refiner_impl.cc +++ b/intern/opensubdiv/internal/topology/topology_refiner_impl.cc @@ -21,13 +21,13 @@ namespace blender { namespace opensubdiv { -TopologyRefinerImpl::TopologyRefinerImpl() : osd_topology_refiner(nullptr) +TopologyRefinerImpl::TopologyRefinerImpl() : topology_refiner(nullptr) { } TopologyRefinerImpl::~TopologyRefinerImpl() { - delete osd_topology_refiner; + delete topology_refiner; } } // namespace opensubdiv diff --git a/intern/opensubdiv/internal/topology/topology_refiner_impl.h b/intern/opensubdiv/internal/topology/topology_refiner_impl.h index 5c7b81c2540..5232e97b24b 100644 --- a/intern/opensubdiv/internal/topology/topology_refiner_impl.h +++ b/intern/opensubdiv/internal/topology/topology_refiner_impl.h @@ -28,15 +28,22 @@ #include "internal/base/memory.h" #include "opensubdiv_topology_refiner_capi.h" +struct OpenSubdiv_Converter; + namespace blender { namespace opensubdiv { class TopologyRefinerImpl { public: + // NOTE: Will return nullptr if topology refiner can not be created (for example, when topology + // is detected to be corrupted or invalid). + static TopologyRefinerImpl *createFromConverter( + OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings &settings); + TopologyRefinerImpl(); ~TopologyRefinerImpl(); - OpenSubdiv::Far::TopologyRefiner *osd_topology_refiner; + OpenSubdiv::Far::TopologyRefiner *topology_refiner; // Subdivision settingsa this refiner is created for. //