395 lines
15 KiB
C
395 lines
15 KiB
C
/*
|
|
* 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) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#ifndef __BKE_DERIVEDMESH_H__
|
|
#define __BKE_DERIVEDMESH_H__
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*
|
|
* Basic design of the DerivedMesh system:
|
|
*
|
|
* DerivedMesh is a common set of interfaces for mesh systems.
|
|
*
|
|
* There are three main mesh data structures in Blender:
|
|
* #Mesh, #CDDerivedMesh and #BMesh.
|
|
*
|
|
* These, and a few others, all implement DerivedMesh interfaces,
|
|
* which contains unified drawing interfaces, a few utility interfaces,
|
|
* and a bunch of read-only interfaces intended mostly for conversion from
|
|
* one format to another.
|
|
*
|
|
* All Mesh structures in blender make use of CustomData, which is used to store
|
|
* per-element attributes and interpolate them (e.g. uvs, vcols, vgroups, etc).
|
|
*
|
|
* Mesh is the "serialized" structure, used for storing object-mode mesh data
|
|
* and also for saving stuff to disk. It's interfaces are also what DerivedMesh
|
|
* uses to communicate with.
|
|
*
|
|
* CDDM is a little mesh library, that uses Mesh data structures in the backend.
|
|
* It's mostly used for modifiers, and has the advantages of not taking much
|
|
* resources.
|
|
*
|
|
* BMesh is a full-on brep, used for editmode, some modifiers, etc. It's much
|
|
* more capable (if memory-intensive) then CDDM.
|
|
*
|
|
* DerivedMesh is somewhat hackish. Many places assumes that a DerivedMesh is
|
|
* a CDDM (most of the time by simply copying it and converting it to one).
|
|
* CDDM is the original structure for modifiers, but has since been superseded
|
|
* by BMesh, at least for the foreseeable future.
|
|
*/
|
|
|
|
/*
|
|
* Note: This structure is read-only, for all practical purposes.
|
|
* At some point in the future, we may want to consider
|
|
* creating a replacement structure that implements a proper
|
|
* abstract mesh kernel interface. Or, we can leave this
|
|
* as it is and stick with using BMesh and CDDM.
|
|
*/
|
|
|
|
#include "DNA_customdata_types.h"
|
|
#include "DNA_defs.h"
|
|
#include "DNA_meshdata_types.h"
|
|
|
|
#include "BLI_compiler_attrs.h"
|
|
|
|
#include "BKE_bvhutils.h"
|
|
#include "BKE_customdata.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct BMEditMesh;
|
|
struct CCGElem;
|
|
struct CCGKey;
|
|
struct CustomData_MeshMasks;
|
|
struct Depsgraph;
|
|
struct MEdge;
|
|
struct MFace;
|
|
struct MVert;
|
|
struct Mesh;
|
|
struct ModifierData;
|
|
struct Object;
|
|
struct Scene;
|
|
|
|
/*
|
|
* Note: all mface interfaces now officially operate on tessellated data.
|
|
* Also, the mface origindex layer indexes mpolys, not mfaces.
|
|
*/
|
|
|
|
/* keep in sync with MFace/MPoly types */
|
|
typedef struct DMFlagMat {
|
|
short mat_nr;
|
|
char flag;
|
|
} DMFlagMat;
|
|
|
|
typedef enum DerivedMeshType {
|
|
DM_TYPE_CDDM,
|
|
DM_TYPE_CCGDM,
|
|
} DerivedMeshType;
|
|
|
|
typedef enum DMDirtyFlag {
|
|
/* dm has valid tessellated faces, but tessellated CDDATA need to be updated. */
|
|
DM_DIRTY_TESS_CDLAYERS = 1 << 0,
|
|
|
|
/* check this with modifier dependsOnNormals callback to see if normals need recalculation */
|
|
DM_DIRTY_NORMALS = 1 << 1,
|
|
} DMDirtyFlag;
|
|
|
|
typedef struct DerivedMesh DerivedMesh;
|
|
struct DerivedMesh {
|
|
/** Private DerivedMesh data, only for internal DerivedMesh use */
|
|
CustomData vertData, edgeData, faceData, loopData, polyData;
|
|
int numVertData, numEdgeData, numTessFaceData, numLoopData, numPolyData;
|
|
int needsFree; /* checked on ->release, is set to 0 for cached results */
|
|
int deformedOnly; /* set by modifier stack if only deformed from original */
|
|
DerivedMeshType type;
|
|
DMDirtyFlag dirty;
|
|
|
|
/**
|
|
* \warning Typical access is done via #getLoopTriArray, #getNumLoopTri.
|
|
*/
|
|
struct {
|
|
/* WARNING! swapping between array (ready-to-be-used data) and array_wip
|
|
* (where data is actually computed) shall always be protected by same
|
|
* lock as one used for looptris computing. */
|
|
struct MLoopTri *array, *array_wip;
|
|
int num;
|
|
int num_alloc;
|
|
} looptris;
|
|
|
|
/* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
|
|
char cd_flag;
|
|
|
|
short tangent_mask; /* which tangent layers are calculated */
|
|
|
|
/** Calculate vert and face normals */
|
|
void (*calcNormals)(DerivedMesh *dm);
|
|
|
|
/** Loop tessellation cache (WARNING! Only call inside threading-protected code!) */
|
|
void (*recalcLoopTri)(DerivedMesh *dm);
|
|
/** accessor functions */
|
|
const struct MLoopTri *(*getLoopTriArray)(DerivedMesh *dm);
|
|
int (*getNumLoopTri)(DerivedMesh *dm);
|
|
|
|
/* Misc. Queries */
|
|
|
|
/* Also called in Editmode */
|
|
int (*getNumVerts)(DerivedMesh *dm);
|
|
int (*getNumEdges)(DerivedMesh *dm);
|
|
int (*getNumTessFaces)(DerivedMesh *dm);
|
|
int (*getNumLoops)(DerivedMesh *dm);
|
|
int (*getNumPolys)(DerivedMesh *dm);
|
|
|
|
/** Copy a single vert/edge/tessellated face from the derived mesh into
|
|
* ``*r_{vert/edge/face}``. note that the current implementation
|
|
* of this function can be quite slow, iterating over all
|
|
* elements (editmesh)
|
|
*/
|
|
void (*getVert)(DerivedMesh *dm, int index, struct MVert *r_vert);
|
|
void (*getEdge)(DerivedMesh *dm, int index, struct MEdge *r_edge);
|
|
void (*getTessFace)(DerivedMesh *dm, int index, struct MFace *r_face);
|
|
|
|
/** Return a pointer to the entire array of verts/edges/face from the
|
|
* derived mesh. if such an array does not exist yet, it will be created,
|
|
* and freed on the next ->release(). consider using getVert/Edge/Face if
|
|
* you are only interested in a few verts/edges/faces.
|
|
*/
|
|
struct MVert *(*getVertArray)(DerivedMesh *dm);
|
|
struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
|
|
struct MFace *(*getTessFaceArray)(DerivedMesh *dm);
|
|
struct MLoop *(*getLoopArray)(DerivedMesh *dm);
|
|
struct MPoly *(*getPolyArray)(DerivedMesh *dm);
|
|
|
|
/** Copy all verts/edges/faces from the derived mesh into
|
|
* *{vert/edge/face}_r (must point to a buffer large enough)
|
|
*/
|
|
void (*copyVertArray)(DerivedMesh *dm, struct MVert *r_vert);
|
|
void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge);
|
|
void (*copyTessFaceArray)(DerivedMesh *dm, struct MFace *r_face);
|
|
void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop);
|
|
void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly);
|
|
|
|
/** Return a copy of all verts/edges/faces from the derived mesh
|
|
* it is the caller's responsibility to free the returned pointer
|
|
*/
|
|
struct MVert *(*dupVertArray)(DerivedMesh *dm);
|
|
struct MEdge *(*dupEdgeArray)(DerivedMesh *dm);
|
|
struct MFace *(*dupTessFaceArray)(DerivedMesh *dm);
|
|
struct MLoop *(*dupLoopArray)(DerivedMesh *dm);
|
|
struct MPoly *(*dupPolyArray)(DerivedMesh *dm);
|
|
|
|
/** Return a pointer to a single element of vert/edge/face custom data
|
|
* from the derived mesh (this gives a pointer to the actual data, not
|
|
* a copy)
|
|
*/
|
|
void *(*getVertData)(DerivedMesh *dm, int index, int type);
|
|
void *(*getEdgeData)(DerivedMesh *dm, int index, int type);
|
|
void *(*getTessFaceData)(DerivedMesh *dm, int index, int type);
|
|
void *(*getPolyData)(DerivedMesh *dm, int index, int type);
|
|
|
|
/** Return a pointer to the entire array of vert/edge/face custom data
|
|
* from the derived mesh (this gives a pointer to the actual data, not
|
|
* a copy)
|
|
*/
|
|
void *(*getVertDataArray)(DerivedMesh *dm, int type);
|
|
void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
|
|
void *(*getTessFaceDataArray)(DerivedMesh *dm, int type);
|
|
void *(*getLoopDataArray)(DerivedMesh *dm, int type);
|
|
void *(*getPolyDataArray)(DerivedMesh *dm, int type);
|
|
|
|
/** Retrieves the base CustomData structures for
|
|
* verts/edges/tessfaces/loops/facdes*/
|
|
CustomData *(*getVertDataLayout)(DerivedMesh *dm);
|
|
CustomData *(*getEdgeDataLayout)(DerivedMesh *dm);
|
|
CustomData *(*getTessFaceDataLayout)(DerivedMesh *dm);
|
|
CustomData *(*getLoopDataLayout)(DerivedMesh *dm);
|
|
CustomData *(*getPolyDataLayout)(DerivedMesh *dm);
|
|
|
|
/** Optional grid access for subsurf */
|
|
int (*getNumGrids)(DerivedMesh *dm);
|
|
int (*getGridSize)(DerivedMesh *dm);
|
|
struct CCGElem **(*getGridData)(DerivedMesh *dm);
|
|
int *(*getGridOffset)(DerivedMesh *dm);
|
|
void (*getGridKey)(DerivedMesh *dm, struct CCGKey *key);
|
|
DMFlagMat *(*getGridFlagMats)(DerivedMesh *dm);
|
|
unsigned int **(*getGridHidden)(DerivedMesh *dm);
|
|
|
|
/** Direct Access Operations
|
|
* - Can be undefined
|
|
* - Must be defined for modifiers that only deform however */
|
|
|
|
/** Get vertex location, undefined if index is not valid */
|
|
void (*getVertCo)(DerivedMesh *dm, int index, float r_co[3]);
|
|
|
|
/** Get smooth vertex normal, undefined if index is not valid */
|
|
void (*getVertNo)(DerivedMesh *dm, int index, float r_no[3]);
|
|
void (*getPolyNo)(DerivedMesh *dm, int index, float r_no[3]);
|
|
|
|
/** Get a map of vertices to faces
|
|
*/
|
|
const struct MeshElemMap *(*getPolyMap)(struct Object *ob, DerivedMesh *dm);
|
|
|
|
/** Release reference to the DerivedMesh. This function decides internally
|
|
* if the DerivedMesh will be freed, or cached for later use. */
|
|
void (*release)(DerivedMesh *dm);
|
|
};
|
|
|
|
void DM_init_funcs(DerivedMesh *dm);
|
|
|
|
void DM_init(DerivedMesh *dm,
|
|
DerivedMeshType type,
|
|
int numVerts,
|
|
int numEdges,
|
|
int numFaces,
|
|
int numLoops,
|
|
int numPolys);
|
|
|
|
void DM_from_template_ex(DerivedMesh *dm,
|
|
DerivedMesh *source,
|
|
DerivedMeshType type,
|
|
int numVerts,
|
|
int numEdges,
|
|
int numTessFaces,
|
|
int numLoops,
|
|
int numPolys,
|
|
const struct CustomData_MeshMasks *mask);
|
|
void DM_from_template(DerivedMesh *dm,
|
|
DerivedMesh *source,
|
|
DerivedMeshType type,
|
|
int numVerts,
|
|
int numEdges,
|
|
int numFaces,
|
|
int numLoops,
|
|
int numPolys);
|
|
|
|
/**
|
|
* Utility function to release a DerivedMesh's layers
|
|
* returns 1 if DerivedMesh has to be released by the backend, 0 otherwise.
|
|
*/
|
|
int DM_release(DerivedMesh *dm);
|
|
|
|
void DM_set_only_copy(DerivedMesh *dm, const struct CustomData_MeshMasks *mask);
|
|
|
|
/* adds a vertex/edge/face custom data layer to a DerivedMesh, optionally
|
|
* backed by an external data array
|
|
* alloctype defines how the layer is allocated or copied, and how it is
|
|
* freed, see BKE_customdata.h for the different options
|
|
*/
|
|
void DM_add_vert_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
|
|
void DM_add_edge_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
|
|
void DM_add_tessface_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
|
|
void DM_add_loop_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
|
|
void DM_add_poly_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer);
|
|
|
|
/* custom data access functions
|
|
* return pointer to data from first layer which matches type
|
|
* if they return NULL for valid indices, data doesn't exist
|
|
* note these return pointers - any change modifies the internals of the mesh
|
|
*/
|
|
void *DM_get_vert_data(struct DerivedMesh *dm, int index, int type);
|
|
void *DM_get_edge_data(struct DerivedMesh *dm, int index, int type);
|
|
void *DM_get_tessface_data(struct DerivedMesh *dm, int index, int type);
|
|
void *DM_get_poly_data(struct DerivedMesh *dm, int index, int type);
|
|
|
|
/* custom data layer access functions
|
|
* return pointer to first data layer which matches type (a flat array)
|
|
* if they return NULL, data doesn't exist
|
|
* note these return pointers - any change modifies the internals of the mesh
|
|
*/
|
|
void *DM_get_vert_data_layer(struct DerivedMesh *dm, int type);
|
|
void *DM_get_edge_data_layer(struct DerivedMesh *dm, int type);
|
|
void *DM_get_tessface_data_layer(struct DerivedMesh *dm, int type);
|
|
void *DM_get_poly_data_layer(struct DerivedMesh *dm, int type);
|
|
void *DM_get_loop_data_layer(struct DerivedMesh *dm, int type);
|
|
|
|
/* custom data copy functions
|
|
* copy count elements from source_index in source to dest_index in dest
|
|
* these copy all layers for which the CD_FLAG_NOCOPY flag is not set
|
|
*/
|
|
void DM_copy_vert_data(struct DerivedMesh *source,
|
|
struct DerivedMesh *dest,
|
|
int source_index,
|
|
int dest_index,
|
|
int count);
|
|
|
|
/*sets up mpolys for a DM based on face iterators in source*/
|
|
void DM_DupPolys(DerivedMesh *source, DerivedMesh *target);
|
|
|
|
void DM_ensure_normals(DerivedMesh *dm);
|
|
|
|
void DM_ensure_looptri_data(DerivedMesh *dm);
|
|
|
|
void DM_interp_vert_data(struct DerivedMesh *source,
|
|
struct DerivedMesh *dest,
|
|
int *src_indices,
|
|
float *weights,
|
|
int count,
|
|
int dest_index);
|
|
|
|
void mesh_get_mapped_verts_coords(struct Mesh *me_eval, float (*r_cos)[3], const int totcos);
|
|
|
|
/* same as above but wont use render settings */
|
|
struct Mesh *editbmesh_get_eval_cage(struct Depsgraph *depsgraph,
|
|
struct Scene *scene,
|
|
struct Object *,
|
|
struct BMEditMesh *em,
|
|
const struct CustomData_MeshMasks *dataMask);
|
|
struct Mesh *editbmesh_get_eval_cage_from_orig(struct Depsgraph *depsgraph,
|
|
struct Scene *scene,
|
|
struct Object *object,
|
|
const struct CustomData_MeshMasks *dataMask);
|
|
struct Mesh *editbmesh_get_eval_cage_and_final(struct Depsgraph *depsgraph,
|
|
struct Scene *scene,
|
|
struct Object *,
|
|
struct BMEditMesh *em,
|
|
const struct CustomData_MeshMasks *dataMask,
|
|
struct Mesh **r_final);
|
|
|
|
float (*editbmesh_vert_coords_alloc(struct BMEditMesh *em, int *r_vert_len))[3];
|
|
bool editbmesh_modifier_is_enabled(struct Scene *scene,
|
|
struct ModifierData *md,
|
|
bool has_prev_mesh);
|
|
void makeDerivedMesh(struct Depsgraph *depsgraph,
|
|
struct Scene *scene,
|
|
struct Object *ob,
|
|
struct BMEditMesh *em,
|
|
const struct CustomData_MeshMasks *dataMask);
|
|
|
|
void DM_calc_loop_tangents(DerivedMesh *dm,
|
|
bool calc_active_tangent,
|
|
const char (*tangent_names)[MAX_NAME],
|
|
int tangent_names_count);
|
|
|
|
/* debug only */
|
|
#ifndef NDEBUG
|
|
char *DM_debug_info(DerivedMesh *dm);
|
|
void DM_debug_print(DerivedMesh *dm);
|
|
void DM_debug_print_cdlayers(CustomData *cdata);
|
|
|
|
bool DM_is_valid(DerivedMesh *dm);
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __BKE_DERIVEDMESH_H__ */
|