This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/blenkernel/intern/CCGSubSurf.h

215 lines
8.3 KiB
C++
Raw Normal View History

2013-07-02 09:47:22 +00:00
/*
* 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.
*/
2011-10-10 09:38:02 +00:00
#pragma once
/** \file
* \ingroup bke
2011-02-27 20:40:57 +00:00
*/
2019-03-25 11:42:28 +11:00
typedef void *CCGMeshHDL;
typedef void *CCGVertHDL;
typedef void *CCGEdgeHDL;
typedef void *CCGFaceHDL;
typedef struct CCGEdge CCGEdge;
typedef struct CCGFace CCGFace;
typedef struct CCGSubSurf CCGSubSurf;
typedef struct CCGVert CCGVert;
- convert all DerivedMesh map functions to use index based mapping (instead of Edit{Vert,Edge,Face} pointers) - dropped convertToDispListMeshMapped (whew, glad of it too) - added DerivedMesh drawMappedFaces function - dropped EM suffix for DerivedMesh functions, it was neither particularly correct nor descriptive - converted test_index_mface to test_index_face that also corrects MCol and TFace. Good thing we had three versions of this routine, you never know when one might burn down. - removed flipnorm_mesh, not used anymore (and was incorrect to boot) - Getting face select to work with modifiers turned out to be much more complicated than expected. Reworked mapping architecture for modifiers - basically elements in a DispListMesh are now required to be stored in an order that corresponds exactly to original ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX that is set on each element that is set on the first derived element of each original element. I can't say the code to follow these requirements for subsurf is particularly transparent, but on the upside it is a reasonably consistent and simple system that is memory efficient and allows keeping the DispListMesh structure. - rewrote mirror modifier to be simpler/conform to new requirements for mapped DispListMesh structure. This also means that mirror interacts much better with incremental subsurf calculation (it used to recalc one entire side on any topology change, now it generally avoids that). - added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index functions to handle mapping indices back into appropriate EditMesh structures. - bug fix, make edges didn't recalc object data - bug fix, initial image assignment to TFace's didn't recalc object data - new feature, added circle select support for FACESELECT - bug fix, creating new faces in editmode duplicated the TFACE active flag - but there should only be one active tface - bug fix, possible crash when deleting all faces in faceselect mode on mesh with tfaces... Still todo: TFace edge drawing is still not always correct in face mode, in particular with a mirror modifier when mesh has edges (and no preceeding subsurf). Have not yet decided how to deal with this. Best solution is probably to do switch to meshes all having MEdge's, in which case I can get rid of TFace edge flags (and need to recalc modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
typedef struct CCGMeshIFC {
int vertUserSize, edgeUserSize, faceUserSize;
int numLayers;
int vertDataSize;
int simpleSubdiv;
} CCGMeshIFC;
/***/
2019-03-25 11:42:28 +11:00
typedef void *CCGAllocatorHDL;
typedef struct CCGAllocatorIFC {
void *(*alloc)(CCGAllocatorHDL a, int numBytes);
void *(*realloc)(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize);
void (*free)(CCGAllocatorHDL a, void *ptr);
void (*release)(CCGAllocatorHDL a);
} CCGAllocatorIFC;
/* private, so we can allocate on the stack */
typedef struct _EHashIterator {
struct _EHash *eh;
int curBucket;
struct _EHEntry *curEntry;
} EHashIterator;
/***/
typedef enum {
eCCGError_None = 0,
eCCGError_InvalidSyncState,
eCCGError_InvalidValue,
} CCGError;
/***/
/* TODO(sergey): This actually depends on subsurf level as well. */
#define CCG_TASK_LIMIT 16
/***/
CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc,
int subdivLevels,
CCGAllocatorIFC *allocatorIFC,
CCGAllocatorHDL allocator);
void ccgSubSurf_free(CCGSubSurf *ss);
CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss);
CCGError ccgSubSurf_initPartialSync(CCGSubSurf *ss);
OpenSubdiv: Commit of OpenSubdiv integration into Blender This commit contains all the remained parts needed for initial integration of OpenSubdiv into Blender's subdivision surface code. Includes both GPU and CPU backends which works in the following way: - When SubSurf modifier is the last in the modifiers stack then GPU pipeline of OpenSubdiv is used, making viewport performance as fast as possible. This also requires graphscard with GLSL 1.5 support. If this requirement is not met, then no GPU pipeline is used at all. - If SubSurf is not a last modifier or if DerivesMesh is being evaluated for rendering then CPU limit evaluation API from OpenSubdiv is used. This only replaces the legacy evaluation code from CCGSubSurf_legacy, but keeps CCG structures exactly the same as they used to be for ages now. This integration is fully covered with ifdef and not enabled by default because there are several TODOs to be solved first: - Face varying data interpolation is not really cleanly implemented for GPU in OpenSubdiv 3.0. It is also not implemented for limit evaluation API. This basically means we'll have really hard time supporting UVs. - Limit evaluation only works with adaptivly subdivided meshes so far, which basically means all the points of CCG are pushed to the limit. This gives different result from old code. - There are some serious optimizations possible on the topology refiner creation, which would speed up initial OpenSubdiv mesh creation. - There are some hardcoded asumptions in the GPU and DerivedMesh areas which could be generalized. That's something where Antony and Campbell can help, making it so the code is structured in a way which is reusable by all planned viewport projects. - There are also some workarounds in the dependency graph to make sure OpenGL buffers are only freed from the main thread. Those who'll be wanting to make experiments with this code should grab dev branch (NOT master) from https://github.com/Nazg-Gul/OpenSubdiv/tree/dev There are some patches applied in there which we're working on on getting into upstream.
2015-07-20 16:08:06 +02:00
#ifdef WITH_OPENSUBDIV
CCGError ccgSubSurf_initOpenSubdivSync(CCGSubSurf *ss);
OpenSubdiv: Commit of OpenSubdiv integration into Blender This commit contains all the remained parts needed for initial integration of OpenSubdiv into Blender's subdivision surface code. Includes both GPU and CPU backends which works in the following way: - When SubSurf modifier is the last in the modifiers stack then GPU pipeline of OpenSubdiv is used, making viewport performance as fast as possible. This also requires graphscard with GLSL 1.5 support. If this requirement is not met, then no GPU pipeline is used at all. - If SubSurf is not a last modifier or if DerivesMesh is being evaluated for rendering then CPU limit evaluation API from OpenSubdiv is used. This only replaces the legacy evaluation code from CCGSubSurf_legacy, but keeps CCG structures exactly the same as they used to be for ages now. This integration is fully covered with ifdef and not enabled by default because there are several TODOs to be solved first: - Face varying data interpolation is not really cleanly implemented for GPU in OpenSubdiv 3.0. It is also not implemented for limit evaluation API. This basically means we'll have really hard time supporting UVs. - Limit evaluation only works with adaptivly subdivided meshes so far, which basically means all the points of CCG are pushed to the limit. This gives different result from old code. - There are some serious optimizations possible on the topology refiner creation, which would speed up initial OpenSubdiv mesh creation. - There are some hardcoded asumptions in the GPU and DerivedMesh areas which could be generalized. That's something where Antony and Campbell can help, making it so the code is structured in a way which is reusable by all planned viewport projects. - There are also some workarounds in the dependency graph to make sure OpenGL buffers are only freed from the main thread. Those who'll be wanting to make experiments with this code should grab dev branch (NOT master) from https://github.com/Nazg-Gul/OpenSubdiv/tree/dev There are some patches applied in there which we're working on on getting into upstream.
2015-07-20 16:08:06 +02:00
#endif
CCGError ccgSubSurf_syncVert(
CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r);
CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss,
CCGEdgeHDL eHDL,
CCGVertHDL e_vHDL0,
CCGVertHDL e_vHDL1,
float crease,
CCGEdge **e_r);
CCGError ccgSubSurf_syncFace(
CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r);
CCGError ccgSubSurf_syncVertDel(CCGSubSurf *ss, CCGVertHDL vHDL);
CCGError ccgSubSurf_syncEdgeDel(CCGSubSurf *ss, CCGEdgeHDL eHDL);
CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL);
CCGError ccgSubSurf_processSync(CCGSubSurf *ss);
CCGError ccgSubSurf_updateFromFaces(CCGSubSurf *ss,
int lvl,
CCGFace **effectedF,
int numEffectedF);
CCGError ccgSubSurf_updateToFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF);
CCGError ccgSubSurf_updateNormals(CCGSubSurf *ss, CCGFace **effectedF, int numEffectedF);
CCGError ccgSubSurf_updateLevels(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF);
CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF);
CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels);
CCGError ccgSubSurf_setAllowEdgeCreation(CCGSubSurf *ss,
int allowEdgeCreation,
float defaultCreaseValue,
void *defaultUserData);
void ccgSubSurf_getAllowEdgeCreation(CCGSubSurf *ss,
int *allowEdgeCreation_r,
float *defaultCreaseValue_r,
void *defaultUserData_r);
void ccgSubSurf_getUseAgeCounts(CCGSubSurf *ss,
int *useAgeCounts_r,
int *vertUserOffset_r,
int *edgeUserOffset_r,
int *faceUserOffset_r);
CCGError ccgSubSurf_setUseAgeCounts(
CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset);
CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset);
void ccgSubSurf_setAllocMask(CCGSubSurf *ss, int allocMask, int maskOffset);
void ccgSubSurf_setNumLayers(CCGSubSurf *ss, int numLayers);
/***/
int ccgSubSurf_getNumVerts(const CCGSubSurf *ss);
int ccgSubSurf_getNumEdges(const CCGSubSurf *ss);
int ccgSubSurf_getNumFaces(const CCGSubSurf *ss);
int ccgSubSurf_getSubdivisionLevels(const CCGSubSurf *ss);
int ccgSubSurf_getEdgeSize(const CCGSubSurf *ss);
int ccgSubSurf_getEdgeLevelSize(const CCGSubSurf *ss, int level);
int ccgSubSurf_getGridSize(const CCGSubSurf *ss);
int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level);
int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss);
CCGVert *ccgSubSurf_getVert(CCGSubSurf *ss, CCGVertHDL v);
CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v);
int ccgSubSurf_getVertNumFaces(CCGVert *v);
CCGFace *ccgSubSurf_getVertFace(CCGVert *v, int index);
int ccgSubSurf_getVertNumEdges(CCGVert *v);
CCGEdge *ccgSubSurf_getVertEdge(CCGVert *v, int index);
int ccgSubSurf_getVertAge(CCGSubSurf *ss, CCGVert *v);
void *ccgSubSurf_getVertUserData(CCGSubSurf *ss, CCGVert *v);
void *ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v);
void *ccgSubSurf_getVertLevelData(CCGSubSurf *ss, CCGVert *v, int level);
CCGEdge *ccgSubSurf_getEdge(CCGSubSurf *ss, CCGEdgeHDL e);
CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle(CCGEdge *e);
int ccgSubSurf_getEdgeNumFaces(CCGEdge *e);
CCGFace *ccgSubSurf_getEdgeFace(CCGEdge *e, int index);
CCGVert *ccgSubSurf_getEdgeVert0(CCGEdge *e);
CCGVert *ccgSubSurf_getEdgeVert1(CCGEdge *e);
float ccgSubSurf_getEdgeCrease(CCGEdge *e);
int ccgSubSurf_getEdgeAge(CCGSubSurf *ss, CCGEdge *e);
void *ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e);
void *ccgSubSurf_getEdgeDataArray(CCGSubSurf *ss, CCGEdge *e);
void *ccgSubSurf_getEdgeData(CCGSubSurf *ss, CCGEdge *e, int x);
void *ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level);
CCGFace *ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f);
CCGFaceHDL ccgSubSurf_getFaceFaceHandle(CCGFace *f);
int ccgSubSurf_getFaceNumVerts(CCGFace *f);
CCGVert *ccgSubSurf_getFaceVert(CCGFace *f, int index);
CCGEdge *ccgSubSurf_getFaceEdge(CCGFace *f, int index);
int ccgSubSurf_getFaceEdgeIndex(CCGFace *f, CCGEdge *e);
int ccgSubSurf_getFaceAge(CCGSubSurf *ss, CCGFace *f);
void *ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f);
void *ccgSubSurf_getFaceCenterData(CCGFace *f);
void *ccgSubSurf_getFaceGridEdgeDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex);
void *ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x);
void *ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex);
void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y);
int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss);
int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss);
int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss);
/***/
typedef struct _EHashIterator CCGEdgeIterator;
typedef struct _EHashIterator CCGFaceIterator;
typedef struct _EHashIterator CCGVertIterator;
void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter);
void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter);
void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter);
CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi);
int ccgVertIterator_isStopped(CCGVertIterator *vi);
void ccgVertIterator_next(CCGVertIterator *vi);
CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *ei);
int ccgEdgeIterator_isStopped(CCGEdgeIterator *ei);
void ccgEdgeIterator_next(CCGEdgeIterator *ei);
CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *fi);
int ccgFaceIterator_isStopped(CCGFaceIterator *fi);
void ccgFaceIterator_next(CCGFaceIterator *fi);