This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/blenkernel/BKE_subdiv.h
Sergey Sharybin 3fbdcefa17 Subdiv: Initial implementation of CCG
Attempts to substitude CCGDM with an OpenSubdiv based structure
which has less abstraction levels. The missing part in this
substitude is a face pointers which old CCGDM/multires code was
using to stitch faces (averaging boundaries).

Another curial bit missing: "reshaping" of multires CD_MDISPS
to the state of new PBVH grids.

The new code is only available when OpenSubdiv modifier is
enabled (WITH_OPENSUBDIV_MODIFIER=ON) and with debug value of
128. This is so this WIP code is not interfering with current
production machines in the studio.

Reviewers: brecht

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D3685
2018-09-11 16:37:02 +02:00

202 lines
6.8 KiB
C++

/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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.
*
* The Original Code is Copyright (C) 2018 by Blender Foundation.
* All rights reserved.
*
* Contributor(s): Sergey Sharybin.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file BKE_subdiv.h
* \ingroup bke
* \since July 2018
* \author Sergey Sharybin
*/
#ifndef __BKE_SUBDIV_H__
#define __BKE_SUBDIV_H__
#include "BLI_sys_types.h"
struct Mesh;
struct MultiresModifierData;
struct Object;
struct OpenSubdiv_Converter;
struct OpenSubdiv_Evaluator;
struct OpenSubdiv_TopologyRefiner;
struct Subdiv;
struct SubdivToMeshSettings;
typedef enum {
SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE,
SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY,
SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS,
SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_JUNCTIONS_AND_CONCAVE,
SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES,
SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL,
} eSubdivFVarLinearInterpolation;
typedef struct SubdivSettings {
bool is_simple;
bool is_adaptive;
int level;
eSubdivFVarLinearInterpolation fvar_linear_interpolation;
} SubdivSettings;
/* NOTE: Order of enumerators MUST match order of values in SubdivStats. */
typedef enum eSubdivStatsValue {
SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME = 0,
SUBDIV_STATS_SUBDIV_TO_MESH,
SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY,
SUBDIV_STATS_EVALUATOR_CREATE,
SUBDIV_STATS_EVALUATOR_REFINE,
SUBDIV_STATS_SUBDIV_TO_CCG,
SUBDIV_STATS_SUBDIV_TO_CCG_ELEMENTS,
NUM_SUBDIV_STATS_VALUES,
} eSubdivStatsValue;
typedef struct SubdivStats {
union {
struct {
/* Time spend on creating topology refiner, which includes time
* spend on conversion from Blender data to OpenSubdiv data, and
* time spend on topology orientation on OpenSubdiv C-API side.
*/
double topology_refiner_creation_time;
/* Total time spent in BKE_subdiv_to_mesh(). */
double subdiv_to_mesh_time;
/* Geometry (MVert and co) creation time during SUBDIV_TYO_MESH. */
double subdiv_to_mesh_geometry_time;
/* Time spent on evaluator creation from topology refiner. */
double evaluator_creation_time;
/* Time spent on evaluator->refine(). */
double evaluator_refine_time;
/* Total time spent on whole CCG creation. */
double subdiv_to_ccg_time;
/* Time spent on CCG elements evaluation/initialization. */
double subdiv_to_ccg_elements_time;
};
double values_[NUM_SUBDIV_STATS_VALUES];
};
/* Per-value timestamp on when corresponding BKE_subdiv_stats_begin() was
* called.
*/
double begin_timestamp_[NUM_SUBDIV_STATS_VALUES];
} SubdivStats;
/* Functor which evaluates dispalcement at a given (u, v) of given ptex face. */
typedef struct SubdivDisplacement {
/* Return displacement which is to be added to the original coordinate.
*
* NOTE: This function is supposed to return "continuous" displacement for
* each pf PTex faces created for special (non-quad) polygon. This means,
* if displacement is stored on per-corner manner (like MDisps for multires)
* this is up the displacement implementation to average boundaries of the
* displacement grids if needed.
*
* Averaging of displacement for vertices created for over coarse vertices
* and edges is done by subdiv code.
*/
void (*eval_displacement)(struct SubdivDisplacement *displacement,
const int ptex_face_index,
const float u, const float v,
const float dPdu[3], const float dPdv[3],
float r_D[3]);
/* Free the data, not the evaluator itself. */
void (*free)(struct SubdivDisplacement *displacement);
void *user_data;
} SubdivDisplacement;
/* This structure contains everything needed to construct subdivided surface.
* It does not specify storage, memory layout or anything else.
* It is possible to create different storages (like, grid based CPU side
* buffers, GPU subdivision mesh, CPU side fully qualified mesh) from the same
* Subdiv structure.
*/
typedef struct Subdiv {
/* Settings this subdivision surface is created for.
*
* It is read-only after assignment in BKE_subdiv_new_from_FOO().
*/
SubdivSettings settings;
/* Topology refiner includes all the glue logic to feed Blender side
* topology to OpenSubdiv. It can be shared by both evaluator and GL mesh
* drawer.
*/
struct OpenSubdiv_TopologyRefiner *topology_refiner;
/* CPU side evaluator. */
struct OpenSubdiv_Evaluator *evaluator;
/* Optional displacement evaluator. */
struct SubdivDisplacement *displacement_evaluator;
/* Statistics for debugging. */
SubdivStats stats;
/* Cached values, are not supposed to be accessed directly. */
struct {
/* Indexed by base face index, element indicates total number of ptex
*faces created for preceding base faces.
*/
int *face_ptex_offset;
} cache_;
} Subdiv;
/* ================================ HELPERS ================================= */
/* NOTE: uv_smooth is eSubsurfUVSmooth. */
eSubdivFVarLinearInterpolation
BKE_subdiv_fvar_interpolation_from_uv_smooth(int uv_smooth);
/* =============================== STATISTICS =============================== */
void BKE_subdiv_stats_init(SubdivStats *stats);
void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value);
void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value);
void BKE_subdiv_stats_print(const SubdivStats *stats);
/* ============================== CONSTRUCTION ============================== */
Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
struct OpenSubdiv_Converter *converter);
Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings,
struct Mesh *mesh);
void BKE_subdiv_free(Subdiv *subdiv);
/* ============================ DISPLACEMENT API ============================ */
void BKE_subdiv_displacement_attach_from_multires(
Subdiv *subdiv,
const struct Mesh *mesh,
const struct MultiresModifierData *mmd);
void BKE_subdiv_displacement_detach(Subdiv *subdiv);
/* ============================ TOPOLOGY HELPERS ============================ */
int *BKE_subdiv_face_ptex_offset_get(Subdiv *subdiv);
#endif /* __BKE_SUBDIV_H__ */