OpenSubdiv: Refactor creation of topology refiner

Consolidate it inside of the topology refiner implementation class,
which would allow to store extra data acquired during construction
of the OpenSubdiv's object.
This commit is contained in:
Sergey Sharybin 2020-05-19 10:13:16 +02:00
parent 57aae2a355
commit 4ab36c4393
7 changed files with 66 additions and 66 deletions

@ -68,7 +68,6 @@ if(WITH_OPENSUBDIV)
# Topology. # Topology.
internal/topology/topology_refiner_capi.cc internal/topology/topology_refiner_capi.cc
internal/topology/topology_refiner_factory.cc internal/topology/topology_refiner_factory.cc
internal/topology/topology_refiner_factory.h
internal/topology/topology_refiner_impl.cc internal/topology/topology_refiner_impl.cc
internal/topology/topology_refiner_impl.h internal/topology/topology_refiner_impl.h

@ -751,7 +751,7 @@ OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal(
OpenSubdiv_TopologyRefiner *topology_refiner) OpenSubdiv_TopologyRefiner *topology_refiner)
{ {
using blender::opensubdiv::vector; using blender::opensubdiv::vector;
TopologyRefiner *refiner = topology_refiner->impl->osd_topology_refiner; TopologyRefiner *refiner = topology_refiner->impl->topology_refiner;
if (refiner == NULL) { if (refiner == NULL) {
// Happens on bad topology. // Happens on bad topology.
return NULL; return NULL;

@ -23,7 +23,6 @@
#include "internal/opensubdiv_edge_map.h" #include "internal/opensubdiv_edge_map.h"
#include "internal/opensubdiv_internal.h" #include "internal/opensubdiv_internal.h"
#include "internal/opensubdiv_util.h" #include "internal/opensubdiv_util.h"
#include "internal/topology/topology_refiner_factory.h"
#include "internal/topology/topology_refiner_impl.h" #include "internal/topology/topology_refiner_impl.h"
using blender::opensubdiv::vector; using blender::opensubdiv::vector;
@ -33,7 +32,7 @@ namespace {
const OpenSubdiv::Far::TopologyRefiner *getOSDTopologyRefiner( const OpenSubdiv::Far::TopologyRefiner *getOSDTopologyRefiner(
const OpenSubdiv_TopologyRefiner *topology_refiner) const OpenSubdiv_TopologyRefiner *topology_refiner)
{ {
return topology_refiner->impl->osd_topology_refiner; return topology_refiner->impl->topology_refiner;
} }
const OpenSubdiv::Far::TopologyLevel *getOSDTopologyBaseLevel( const OpenSubdiv::Far::TopologyLevel *getOSDTopologyBaseLevel(
@ -230,7 +229,6 @@ void assignFunctionPointers(OpenSubdiv_TopologyRefiner *topology_refiner)
OpenSubdiv_TopologyRefiner *allocateTopologyRefiner() OpenSubdiv_TopologyRefiner *allocateTopologyRefiner()
{ {
OpenSubdiv_TopologyRefiner *topology_refiner = OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefiner); OpenSubdiv_TopologyRefiner *topology_refiner = OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefiner);
topology_refiner->impl = new OpenSubdiv_TopologyRefinerImpl();
assignFunctionPointers(topology_refiner); assignFunctionPointers(topology_refiner);
return topology_refiner; return topology_refiner;
} }
@ -240,17 +238,17 @@ OpenSubdiv_TopologyRefiner *allocateTopologyRefiner()
OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter( OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter(
OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings) OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings)
{ {
OpenSubdiv::Far::TopologyRefiner *osd_topology_refiner = using blender::opensubdiv::TopologyRefinerImpl;
blender::opensubdiv::createOSDTopologyRefinerFromConverter(converter);
if (osd_topology_refiner == NULL) { TopologyRefinerImpl *topology_refiner_impl = TopologyRefinerImpl::createFromConverter(converter,
// Happens on empty or bad topology. *settings);
return NULL; if (topology_refiner_impl == nullptr) {
return nullptr;
} }
OpenSubdiv_TopologyRefiner *topology_refiner = allocateTopologyRefiner(); OpenSubdiv_TopologyRefiner *topology_refiner = allocateTopologyRefiner();
topology_refiner->impl->osd_topology_refiner = osd_topology_refiner; topology_refiner->impl = static_cast<OpenSubdiv_TopologyRefinerImpl *>(topology_refiner_impl);
// 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;
return topology_refiner; return topology_refiner;
} }

@ -20,7 +20,7 @@
# include <iso646.h> # include <iso646.h>
#endif #endif
#include "internal/topology/topology_refiner_factory.h" #include "internal/topology/topology_refiner_impl.h"
#include <cassert> #include <cassert>
#include <cstdio> #include <cstdio>
@ -40,6 +40,8 @@ struct TopologyRefinerData {
const OpenSubdiv_Converter *converter; const OpenSubdiv_Converter *converter;
}; };
typedef OpenSubdiv::Far::TopologyRefinerFactory<TopologyRefinerData> TopologyRefinerFactoryType;
namespace OpenSubdiv { namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION { namespace OPENSUBDIV_VERSION {
namespace Far { namespace Far {
@ -254,6 +256,7 @@ OpenSubdiv::Sdc::Options::VtxBoundaryInterpolation getVtxBoundaryInterpolationFr
OpenSubdiv_VtxBoundaryInterpolation boundary_interpolation) OpenSubdiv_VtxBoundaryInterpolation boundary_interpolation)
{ {
using OpenSubdiv::Sdc::Options; using OpenSubdiv::Sdc::Options;
switch (boundary_interpolation) { switch (boundary_interpolation) {
case OSD_VTX_BOUNDARY_NONE: case OSD_VTX_BOUNDARY_NONE:
return Options::VTX_BOUNDARY_NONE; return Options::VTX_BOUNDARY_NONE;
@ -266,30 +269,62 @@ OpenSubdiv::Sdc::Options::VtxBoundaryInterpolation getVtxBoundaryInterpolationFr
return Options::VTX_BOUNDARY_EDGE_ONLY; return Options::VTX_BOUNDARY_EDGE_ONLY;
} }
} // namespace OpenSubdiv::Sdc::Options getSDCOptions(OpenSubdiv_Converter *converter)
OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter(
OpenSubdiv_Converter *converter)
{ {
using OpenSubdiv::Far::TopologyRefinerFactory;
using OpenSubdiv::Sdc::Options; using OpenSubdiv::Sdc::Options;
const OpenSubdiv::Sdc::SchemeType scheme_type = getSchemeTypeFromCAPI(
converter->getSchemeType(converter));
const Options::FVarLinearInterpolation linear_interpolation = getFVarLinearInterpolationFromCAPI( const Options::FVarLinearInterpolation linear_interpolation = getFVarLinearInterpolationFromCAPI(
converter->getFVarLinearInterpolation(converter)); converter->getFVarLinearInterpolation(converter));
Options options; Options options;
options.SetVtxBoundaryInterpolation( options.SetVtxBoundaryInterpolation(
getVtxBoundaryInterpolationFromCAPI(converter->getVtxBoundaryInterpolation(converter))); getVtxBoundaryInterpolationFromCAPI(converter->getVtxBoundaryInterpolation(converter)));
options.SetCreasingMethod(Options::CREASE_UNIFORM); options.SetCreasingMethod(Options::CREASE_UNIFORM);
options.SetFVarLinearInterpolation(linear_interpolation); options.SetFVarLinearInterpolation(linear_interpolation);
TopologyRefinerFactory<TopologyRefinerData>::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 #ifdef OPENSUBDIV_VALIDATE_TOPOLOGY
topology_options.validateFullTopology = true; topology_options.validateFullTopology = true;
#endif #endif
return topology_options;
}
} // namespace
TopologyRefinerImpl *TopologyRefinerImpl::createFromConverter(
OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings &settings)
{
using OpenSubdiv::Far::TopologyRefiner;
TopologyRefinerData cb_data; TopologyRefinerData cb_data;
cb_data.converter = converter; cb_data.converter = converter;
return TopologyRefinerFactory<TopologyRefinerData>::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 } // namespace opensubdiv

@ -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 <iso646.h>
#endif
#include <opensubdiv/far/topologyRefiner.h>
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_

@ -21,13 +21,13 @@
namespace blender { namespace blender {
namespace opensubdiv { namespace opensubdiv {
TopologyRefinerImpl::TopologyRefinerImpl() : osd_topology_refiner(nullptr) TopologyRefinerImpl::TopologyRefinerImpl() : topology_refiner(nullptr)
{ {
} }
TopologyRefinerImpl::~TopologyRefinerImpl() TopologyRefinerImpl::~TopologyRefinerImpl()
{ {
delete osd_topology_refiner; delete topology_refiner;
} }
} // namespace opensubdiv } // namespace opensubdiv

@ -28,15 +28,22 @@
#include "internal/base/memory.h" #include "internal/base/memory.h"
#include "opensubdiv_topology_refiner_capi.h" #include "opensubdiv_topology_refiner_capi.h"
struct OpenSubdiv_Converter;
namespace blender { namespace blender {
namespace opensubdiv { namespace opensubdiv {
class TopologyRefinerImpl { class TopologyRefinerImpl {
public: 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();
~TopologyRefinerImpl(); ~TopologyRefinerImpl();
OpenSubdiv::Far::TopologyRefiner *osd_topology_refiner; OpenSubdiv::Far::TopologyRefiner *topology_refiner;
// Subdivision settingsa this refiner is created for. // Subdivision settingsa this refiner is created for.
// //