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

View File

@ -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

View File

@ -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;

View File

@ -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<OpenSubdiv_TopologyRefinerImpl *>(topology_refiner_impl);
return topology_refiner;
}

View File

@ -20,7 +20,7 @@
# include <iso646.h>
#endif
#include "internal/topology/topology_refiner_factory.h"
#include "internal/topology/topology_refiner_impl.h"
#include <cassert>
#include <cstdio>
@ -40,6 +40,8 @@ struct TopologyRefinerData {
const OpenSubdiv_Converter *converter;
};
typedef OpenSubdiv::Far::TopologyRefinerFactory<TopologyRefinerData> 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<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
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<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

View File

@ -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_

View File

@ -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

View File

@ -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.
//