236 lines
8.5 KiB
C++
236 lines
8.5 KiB
C++
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#pragma once
|
|
|
|
/** \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, vertex-colors, vertex-groups, etc).
|
|
*
|
|
* Mesh is the "serialized" structure, used for storing object-mode mesh data
|
|
* and also for saving stuff to disk. Its 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 edit-mode, 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 "BLI_compiler_attrs.h"
|
|
#include "BLI_math_vector_types.hh"
|
|
#include "BLI_span.hh"
|
|
|
|
#include "DNA_customdata_types.h"
|
|
|
|
struct BMEditMesh;
|
|
struct CCGElem;
|
|
struct CCGKey;
|
|
struct CustomData_MeshMasks;
|
|
struct Depsgraph;
|
|
struct Mesh;
|
|
struct ModifierData;
|
|
struct Object;
|
|
struct Scene;
|
|
|
|
enum DerivedMeshType {
|
|
DM_TYPE_CDDM,
|
|
DM_TYPE_CCGDM,
|
|
};
|
|
|
|
struct DerivedMesh {
|
|
/** Private DerivedMesh data, only for internal DerivedMesh use */
|
|
CustomData vertData, edgeData, faceData, loopData, polyData;
|
|
int numVertData, numEdgeData, numTessFaceData, numLoopData, numPolyData;
|
|
DerivedMeshType type;
|
|
/* Always owned by this object. */
|
|
int *face_offsets;
|
|
|
|
short tangent_mask; /* which tangent layers are calculated */
|
|
|
|
/* Misc. Queries */
|
|
|
|
/* Also called in Editmode */
|
|
int (*getNumVerts)(DerivedMesh *dm);
|
|
int (*getNumEdges)(DerivedMesh *dm);
|
|
int (*getNumLoops)(DerivedMesh *dm);
|
|
int (*getNumPolys)(DerivedMesh *dm);
|
|
|
|
/** 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.
|
|
*/
|
|
/**
|
|
* \warning The real return type is `float(*)[3]`.
|
|
*/
|
|
float *(*getVertArray)(DerivedMesh *dm);
|
|
blender::int2 *(*getEdgeArray)(DerivedMesh *dm);
|
|
int *(*getCornerVertArray)(DerivedMesh *dm);
|
|
int *(*getCornerEdgeArray)(DerivedMesh *dm);
|
|
int *(*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, float (*r_positions)[3]);
|
|
void (*copyEdgeArray)(DerivedMesh *dm, blender::int2 *r_edge);
|
|
void (*copyCornerVertArray)(DerivedMesh *dm, int *r_corner_verts);
|
|
void (*copyCornerEdgeArray)(DerivedMesh *dm, int *r_corner_edges);
|
|
void (*copyPolyArray)(DerivedMesh *dm, int *r_face_offsets);
|
|
|
|
/** 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, eCustomDataType type);
|
|
void *(*getEdgeDataArray)(DerivedMesh *dm, eCustomDataType type);
|
|
void *(*getLoopDataArray)(DerivedMesh *dm, eCustomDataType type);
|
|
void *(*getPolyDataArray)(DerivedMesh *dm, eCustomDataType type);
|
|
|
|
/** Optional grid access for subsurf */
|
|
int (*getNumGrids)(DerivedMesh *dm);
|
|
int (*getGridSize)(DerivedMesh *dm);
|
|
CCGElem **(*getGridData)(DerivedMesh *dm);
|
|
int *(*getGridOffset)(DerivedMesh *dm);
|
|
void (*getGridKey)(DerivedMesh *dm, CCGKey *key);
|
|
|
|
/* Direct Access Operations
|
|
* - Can be undefined
|
|
* - Must be defined for modifiers that only deform however. */
|
|
|
|
/** Release reference to the DerivedMesh. This function decides internally
|
|
* if the DerivedMesh will be freed, or cached for later use. */
|
|
void (*release)(DerivedMesh *dm);
|
|
};
|
|
|
|
/**
|
|
* Utility function to initialize a #DerivedMesh's function pointers to
|
|
* the default implementation (for those functions which have a default).
|
|
*/
|
|
void DM_init_funcs(DerivedMesh *dm);
|
|
|
|
/**
|
|
* Utility function to initialize a #DerivedMesh for the desired number
|
|
* of vertices, edges and faces (doesn't allocate memory for them, just
|
|
* sets up the custom data layers)>
|
|
*/
|
|
void DM_init(DerivedMesh *dm,
|
|
DerivedMeshType type,
|
|
int numVerts,
|
|
int numEdges,
|
|
int numTessFaces,
|
|
int numLoops,
|
|
int numPolys);
|
|
|
|
/**
|
|
* Utility function to initialize a DerivedMesh for the desired number
|
|
* of vertices, edges and faces, with a layer setup copied from source
|
|
*/
|
|
void DM_from_template(DerivedMesh *dm,
|
|
DerivedMesh *source,
|
|
DerivedMeshType type,
|
|
int numVerts,
|
|
int numEdges,
|
|
int numTessFaces,
|
|
int numLoops,
|
|
int numPolys);
|
|
|
|
void DM_release(DerivedMesh *dm);
|
|
|
|
/**
|
|
* set the #CD_FLAG_NOCOPY flag in custom data layers where the mask is
|
|
* zero for the layer type, so only layer types specified by the mask
|
|
* will be copied
|
|
*/
|
|
void DM_set_only_copy(DerivedMesh *dm, const CustomData_MeshMasks *mask);
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name 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(DerivedMesh *dm, eCustomDataType type);
|
|
void *DM_get_edge_data_layer(DerivedMesh *dm, eCustomDataType type);
|
|
void *DM_get_poly_data_layer(DerivedMesh *dm, eCustomDataType type);
|
|
void *DM_get_loop_data_layer(DerivedMesh *dm, eCustomDataType 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(
|
|
const DerivedMesh *source, DerivedMesh *dest, int source_index, int dest_index, int count);
|
|
|
|
/**
|
|
* Interpolates vertex data from the vertices indexed by `src_indices` in the
|
|
* source mesh using the given weights and stores the result in the vertex
|
|
* indexed by `dest_index` in the `dest` mesh.
|
|
*/
|
|
void DM_interp_vert_data(const DerivedMesh *source,
|
|
DerivedMesh *dest,
|
|
int *src_indices,
|
|
float *weights,
|
|
int count,
|
|
int dest_index);
|
|
|
|
void mesh_get_mapped_verts_coords(Mesh *mesh_eval, blender::MutableSpan<blender::float3> r_cos);
|
|
|
|
/**
|
|
* Same as above but won't use render settings.
|
|
*/
|
|
Mesh *editbmesh_get_eval_cage(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *obedit,
|
|
BMEditMesh *em,
|
|
const CustomData_MeshMasks *dataMask);
|
|
Mesh *editbmesh_get_eval_cage_from_orig(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *obedit,
|
|
const CustomData_MeshMasks *dataMask);
|
|
|
|
bool editbmesh_modifier_is_enabled(const Scene *scene,
|
|
const Object *ob,
|
|
ModifierData *md,
|
|
bool has_prev_mesh);
|
|
void makeDerivedMesh(Depsgraph *depsgraph,
|
|
const Scene *scene,
|
|
Object *ob,
|
|
const CustomData_MeshMasks *dataMask);
|