Add tessellation data to DerivedMesh (LoopTri)
This stores loop indices into the loop array giving easier acess to data such as vertex-colors and UV's, removing the need to store an MFace duplicate of custom-data. This doesn't yet move all internal code from MFace to LoopTri just yet. Only applies to: - opengl drawing - sculpting (pbvh) - vertex/weight paint Thanks to @psy-fi for review, fixes and improvements to drawing!
This commit is contained in:
parent
c8f6313487
commit
595a491e63
|
@ -185,6 +185,15 @@ struct DerivedMesh {
|
|||
int totmat; /* total materials. Will be valid only before object drawing. */
|
||||
struct Material **mat; /* material array. Will be valid only before object drawing */
|
||||
|
||||
/**
|
||||
* \warning Typical access is done via #getLoopTriArray, #getNumLoopTri.
|
||||
*/
|
||||
struct {
|
||||
struct MLoopTri *array;
|
||||
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;
|
||||
|
||||
|
@ -201,6 +210,12 @@ struct DerivedMesh {
|
|||
/** Recalculates mesh tessellation */
|
||||
void (*recalcTessellation)(DerivedMesh *dm);
|
||||
|
||||
/** Loop tessellation cache */
|
||||
void (*recalcLoopTri)(DerivedMesh *dm);
|
||||
/** accessor functions */
|
||||
const struct MLoopTri *(*getLoopTriArray)(DerivedMesh * dm);
|
||||
int (*getNumLoopTri)(DerivedMesh *dm);
|
||||
|
||||
/* Misc. Queries */
|
||||
|
||||
/* Also called in Editmode */
|
||||
|
@ -594,10 +609,14 @@ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target);
|
|||
void DM_ensure_normals(DerivedMesh *dm);
|
||||
void DM_ensure_tessface(DerivedMesh *dm);
|
||||
|
||||
void DM_ensure_looptri_data(DerivedMesh *dm);
|
||||
void DM_ensure_looptri(DerivedMesh *dm);
|
||||
|
||||
void DM_update_tessface_data(DerivedMesh *dm);
|
||||
|
||||
void DM_update_materials(DerivedMesh *dm, struct Object *ob);
|
||||
struct MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr);
|
||||
struct MLoopUV *DM_paint_uvlayer_active_get_mloopuv(DerivedMesh *dm, int mat_nr);
|
||||
|
||||
void DM_interp_vert_data(
|
||||
struct DerivedMesh *source, struct DerivedMesh *dest,
|
||||
|
@ -721,12 +740,12 @@ void DM_update_weight_mcol(
|
|||
* the DerivedMesh, with both a pointer for arrays and an offset for editmesh */
|
||||
typedef struct DMVertexAttribs {
|
||||
struct {
|
||||
struct MTFace *array;
|
||||
struct MLoopUV *array;
|
||||
int em_offset, gl_index, gl_texco;
|
||||
} tface[MAX_MTFACE];
|
||||
|
||||
struct {
|
||||
struct MCol *array;
|
||||
struct MLoopCol *array;
|
||||
int em_offset, gl_index;
|
||||
} mcol[MAX_MCOL];
|
||||
|
||||
|
@ -747,7 +766,7 @@ void DM_vertex_attributes_from_gpu(
|
|||
DerivedMesh *dm,
|
||||
struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs);
|
||||
|
||||
void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert);
|
||||
void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, int loop);
|
||||
|
||||
void DM_add_tangent_layer(DerivedMesh *dm);
|
||||
void DM_calc_auto_bump_scale(DerivedMesh *dm);
|
||||
|
|
|
@ -125,6 +125,8 @@ void CDDM_calc_edges(struct DerivedMesh *dm);
|
|||
void CDDM_recalc_tessellation(struct DerivedMesh *dm);
|
||||
void CDDM_recalc_tessellation_ex(struct DerivedMesh *dm, const bool do_face_nor_cpy);
|
||||
|
||||
void CDDM_recalc_looptri(struct DerivedMesh *dm);
|
||||
|
||||
/* lowers the number of vertices/edges/faces in a CDDerivedMesh
|
||||
* the layer data stays the same size
|
||||
*/
|
||||
|
|
|
@ -39,6 +39,7 @@ struct LinkNode;
|
|||
struct BLI_Stack;
|
||||
struct MemArena;
|
||||
struct BMesh;
|
||||
struct MLoopTri;
|
||||
struct Main;
|
||||
struct Mesh;
|
||||
struct MPoly;
|
||||
|
@ -178,6 +179,11 @@ void BKE_mesh_calc_normals_tessface(
|
|||
struct MVert *mverts, int numVerts,
|
||||
const struct MFace *mfaces, int numFaces,
|
||||
float (*r_faceNors)[3]);
|
||||
void BKE_mesh_calc_normals_looptri(
|
||||
struct MVert *mverts, int numVerts,
|
||||
const struct MLoop *mloop,
|
||||
const struct MLoopTri *looptri, int looptri_num,
|
||||
float (*r_tri_nors)[3]);
|
||||
void BKE_mesh_loop_tangents_ex(
|
||||
const struct MVert *mverts, const int numVerts, const struct MLoop *mloops,
|
||||
float (*r_looptangent)[4], float (*loopnors)[3], const struct MLoopUV *loopuv,
|
||||
|
@ -285,6 +291,11 @@ int BKE_mesh_recalc_tessellation(
|
|||
struct MVert *mvert,
|
||||
int totface, int totloop, int totpoly,
|
||||
const bool do_face_nor_copy);
|
||||
void BKE_mesh_recalc_looptri(
|
||||
const struct MLoop *mloop, const struct MPoly *mpoly,
|
||||
const struct MVert *mvert,
|
||||
int totloop, int totpoly,
|
||||
struct MLoopTri *mlooptri);
|
||||
int BKE_mesh_mpoly_to_mface(
|
||||
struct CustomData *fdata, struct CustomData *ldata,
|
||||
struct CustomData *pdata, int totface, int totloop, int totpoly);
|
||||
|
|
|
@ -40,6 +40,8 @@ struct CurveMapping;
|
|||
struct MeshElemMap;
|
||||
struct GridPaintMask;
|
||||
struct Main;
|
||||
struct MLoop;
|
||||
struct MLoopTri;
|
||||
struct MFace;
|
||||
struct MVert;
|
||||
struct Object;
|
||||
|
@ -133,7 +135,7 @@ bool BKE_paint_select_vert_test(struct Object *ob);
|
|||
bool BKE_paint_select_elem_test(struct Object *ob);
|
||||
|
||||
/* partial visibility */
|
||||
bool paint_is_face_hidden(const struct MFace *f, const struct MVert *mvert);
|
||||
bool paint_is_face_hidden(const struct MLoopTri *lt, const struct MVert *mvert, const struct MLoop *mloop);
|
||||
bool paint_is_grid_face_hidden(const unsigned int *grid_hidden,
|
||||
int gridsize, int x, int y);
|
||||
bool paint_is_bmesh_face_hidden(struct BMFace *f);
|
||||
|
|
|
@ -34,7 +34,9 @@ struct CCGElem;
|
|||
struct CCGKey;
|
||||
struct CustomData;
|
||||
struct DMFlagMat;
|
||||
struct MFace;
|
||||
struct MPoly;
|
||||
struct MLoop;
|
||||
struct MLoopTri;
|
||||
struct MVert;
|
||||
struct PBVH;
|
||||
struct PBVHNode;
|
||||
|
@ -60,8 +62,10 @@ typedef void (*BKE_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *
|
|||
|
||||
PBVH *BKE_pbvh_new(void);
|
||||
void BKE_pbvh_build_mesh(
|
||||
PBVH *bvh, const struct MFace *faces, struct MVert *verts,
|
||||
int totface, int totvert, struct CustomData *vdata);
|
||||
PBVH *bvh,
|
||||
const struct MPoly *mpoly, const struct MLoop *mloop,
|
||||
struct MVert *verts, int totvert, struct CustomData *vdata,
|
||||
const struct MLoopTri *looptri, int looptri_num);
|
||||
void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
|
||||
int totgrid,
|
||||
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
|
||||
|
|
|
@ -220,6 +220,11 @@ static MPoly *dm_dupPolyArray(DerivedMesh *dm)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
static int dm_getNumLoopTri(DerivedMesh *dm)
|
||||
{
|
||||
return dm->looptris.num;
|
||||
}
|
||||
|
||||
static CustomData *dm_getVertCData(DerivedMesh *dm)
|
||||
{
|
||||
return &dm->vertData;
|
||||
|
@ -263,6 +268,9 @@ void DM_init_funcs(DerivedMesh *dm)
|
|||
dm->dupLoopArray = dm_dupLoopArray;
|
||||
dm->dupPolyArray = dm_dupPolyArray;
|
||||
|
||||
/* subtypes handle getting actual data */
|
||||
dm->getNumLoopTri = dm_getNumLoopTri;
|
||||
|
||||
dm->getVertDataLayout = dm_getVertCData;
|
||||
dm->getEdgeDataLayout = dm_getEdgeCData;
|
||||
dm->getTessFaceDataLayout = dm_getTessFaceCData;
|
||||
|
@ -364,6 +372,10 @@ int DM_release(DerivedMesh *dm)
|
|||
dm->totmat = 0;
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(dm->looptris.array);
|
||||
dm->looptris.num = 0;
|
||||
dm->looptris.num_alloc = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
|
@ -440,6 +452,47 @@ void DM_ensure_tessface(DerivedMesh *dm)
|
|||
dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the array is large enough
|
||||
*/
|
||||
void DM_ensure_looptri_data(DerivedMesh *dm)
|
||||
{
|
||||
const unsigned int totpoly = dm->numPolyData;
|
||||
const unsigned int totloop = dm->numLoopData;
|
||||
const int looptris_num = poly_to_tri_count(totpoly, totloop);
|
||||
|
||||
if ((looptris_num > dm->looptris.num_alloc) ||
|
||||
(looptris_num < dm->looptris.num_alloc * 2) ||
|
||||
(totpoly == 0))
|
||||
{
|
||||
MEM_SAFE_FREE(dm->looptris.array);
|
||||
dm->looptris.num_alloc = 0;
|
||||
dm->looptris.num = 0;
|
||||
}
|
||||
|
||||
if (totpoly) {
|
||||
if (dm->looptris.array == NULL) {
|
||||
dm->looptris.array = MEM_mallocN(sizeof(*dm->looptris.array) * looptris_num, __func__);
|
||||
dm->looptris.num_alloc = looptris_num;
|
||||
}
|
||||
|
||||
dm->looptris.num = looptris_num;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The purpose of this function is that we can call:
|
||||
* `dm->getLoopTriArray(dm)` and get the array returned.
|
||||
*/
|
||||
void DM_ensure_looptri(DerivedMesh *dm)
|
||||
{
|
||||
const int numPolys = dm->getNumPolys(dm);
|
||||
|
||||
if ((dm->looptris.num == 0) && (numPolys != 0)) {
|
||||
dm->recalcLoopTri(dm);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update tessface CD data from loop/poly ones. Needed when not retessellating after modstack evaluation. */
|
||||
/* NOTE: Assumes dm has valid tessellated data! */
|
||||
void DM_update_tessface_data(DerivedMesh *dm)
|
||||
|
@ -546,6 +599,29 @@ MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr)
|
|||
return tf_base;
|
||||
}
|
||||
|
||||
MLoopUV *DM_paint_uvlayer_active_get_mloopuv(DerivedMesh *dm, int mat_nr)
|
||||
{
|
||||
MLoopUV *uv_base;
|
||||
|
||||
BLI_assert(mat_nr < dm->totmat);
|
||||
|
||||
if (dm->mat[mat_nr] && dm->mat[mat_nr]->texpaintslot &&
|
||||
dm->mat[mat_nr]->texpaintslot[dm->mat[mat_nr]->paint_active_slot].uvname)
|
||||
{
|
||||
uv_base = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV,
|
||||
dm->mat[mat_nr]->texpaintslot[dm->mat[mat_nr]->paint_active_slot].uvname);
|
||||
/* This can fail if we have changed the name in the UV layer list and have assigned the old name in the material
|
||||
* texture slot.*/
|
||||
if (!uv_base)
|
||||
uv_base = CustomData_get_layer(&dm->loopData, CD_MLOOPUV);
|
||||
}
|
||||
else {
|
||||
uv_base = CustomData_get_layer(&dm->loopData, CD_MLOOPUV);
|
||||
}
|
||||
|
||||
return uv_base;
|
||||
}
|
||||
|
||||
void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask, bool take_ownership)
|
||||
{
|
||||
/* dm might depend on me, so we need to do everything with a local copy */
|
||||
|
@ -2031,7 +2107,12 @@ static void mesh_calc_modifiers(
|
|||
}
|
||||
|
||||
if (sculpt_dyntopo == false) {
|
||||
/* watch this! after 2.75a we move to from tessface to looptri (by default) */
|
||||
#if 0
|
||||
DM_ensure_tessface(finaldm);
|
||||
#else
|
||||
DM_ensure_looptri(finaldm);
|
||||
#endif
|
||||
|
||||
/* without this, drawing ngon tri's faces will show ugly tessellated face
|
||||
* normals and will also have to calculate normals on the fly, try avoid
|
||||
|
@ -3160,17 +3241,20 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
|
|||
attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
|
||||
}
|
||||
else {
|
||||
/* exception .. */
|
||||
CustomData *ldata = dm->getLoopDataLayout(dm);
|
||||
|
||||
if (gattribs->layer[b].name[0])
|
||||
layer = CustomData_get_named_layer_index(tfdata, CD_MTFACE,
|
||||
layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV,
|
||||
gattribs->layer[b].name);
|
||||
else
|
||||
layer = CustomData_get_active_layer_index(tfdata, CD_MTFACE);
|
||||
layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
|
||||
|
||||
a = attribs->tottface++;
|
||||
|
||||
if (layer != -1) {
|
||||
attribs->tface[a].array = tfdata->layers[layer].data;
|
||||
attribs->tface[a].em_offset = tfdata->layers[layer].offset;
|
||||
attribs->tface[a].array = ldata->layers[layer].data;
|
||||
attribs->tface[a].em_offset = ldata->layers[layer].offset;
|
||||
}
|
||||
else {
|
||||
attribs->tface[a].array = NULL;
|
||||
|
@ -3207,19 +3291,22 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
|
|||
attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
|
||||
}
|
||||
else {
|
||||
/* exception .. */
|
||||
CustomData *ldata = dm->getLoopDataLayout(dm);
|
||||
|
||||
/* vertex colors */
|
||||
if (gattribs->layer[b].name[0])
|
||||
layer = CustomData_get_named_layer_index(tfdata, CD_MCOL,
|
||||
layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL,
|
||||
gattribs->layer[b].name);
|
||||
else
|
||||
layer = CustomData_get_active_layer_index(tfdata, CD_MCOL);
|
||||
layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL);
|
||||
|
||||
a = attribs->totmcol++;
|
||||
|
||||
if (layer != -1) {
|
||||
attribs->mcol[a].array = tfdata->layers[layer].data;
|
||||
attribs->mcol[a].array = ldata->layers[layer].data;
|
||||
/* odd, store the offset for a different layer type here, but editmode draw code expects it */
|
||||
attribs->mcol[a].em_offset = tfdata->layers[layer].offset;
|
||||
attribs->mcol[a].em_offset = ldata->layers[layer].offset;
|
||||
}
|
||||
else {
|
||||
attribs->mcol[a].array = NULL;
|
||||
|
@ -3266,13 +3353,15 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
|
|||
}
|
||||
}
|
||||
|
||||
/* Set vertex shader attribute inputs for a particular tessface vert
|
||||
/**
|
||||
* Set vertex shader attribute inputs for a particular tessface vert
|
||||
*
|
||||
* a: tessface index
|
||||
* index: vertex index
|
||||
* vert: corner index (0, 1, 2, 3)
|
||||
* \param a: tessface index
|
||||
* \param index: vertex index
|
||||
* \param vert: corner index (0, 1, 2, 3)
|
||||
* \param loop: absolute loop corner index
|
||||
*/
|
||||
void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert)
|
||||
void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, int loop)
|
||||
{
|
||||
const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
int b;
|
||||
|
@ -3293,8 +3382,8 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert)
|
|||
const float *uv;
|
||||
|
||||
if (attribs->tface[b].array) {
|
||||
MTFace *tf = &attribs->tface[b].array[a];
|
||||
uv = tf->uv[vert];
|
||||
const MLoopUV *mloopuv = &attribs->tface[b].array[loop];
|
||||
uv = mloopuv->uv;
|
||||
}
|
||||
else {
|
||||
uv = zero;
|
||||
|
@ -3311,8 +3400,8 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert)
|
|||
GLubyte col[4];
|
||||
|
||||
if (attribs->mcol[b].array) {
|
||||
MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
|
||||
col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
|
||||
const MLoopCol *cp = &attribs->mcol[b].array[loop];
|
||||
copy_v4_v4_char((char *)col, &cp->r);
|
||||
}
|
||||
else {
|
||||
col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -242,6 +242,47 @@ static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
|
|||
/* do nothing */
|
||||
}
|
||||
|
||||
static void emDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
|
||||
{
|
||||
/* Nothing to do: emDM tessellation is known,
|
||||
* allocate and fill in with emDM_getLoopTriArray */
|
||||
}
|
||||
|
||||
static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
|
||||
{
|
||||
if (dm->looptris.array) {
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
}
|
||||
else {
|
||||
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
|
||||
BMLoop *(*looptris)[3] = bmdm->em->looptris;
|
||||
MLoopTri *mlooptri;
|
||||
const int tottri = bmdm->em->tottri;
|
||||
int i;
|
||||
|
||||
DM_ensure_looptri_data(dm);
|
||||
mlooptri = dm->looptris.array;
|
||||
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
BLI_assert(tottri == dm->looptris.num);
|
||||
|
||||
BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
|
||||
|
||||
for (i = 0; i < tottri; i++) {
|
||||
BMLoop **ltri = looptris[i];
|
||||
MLoopTri *lt = &mlooptri[i];
|
||||
|
||||
ARRAY_SET_ITEMS(
|
||||
lt->tri,
|
||||
BM_elem_index_get(ltri[0]),
|
||||
BM_elem_index_get(ltri[1]),
|
||||
BM_elem_index_get(ltri[2]));
|
||||
lt->poly = BM_elem_index_get(ltri[0]->f);
|
||||
}
|
||||
}
|
||||
return dm->looptris.array;
|
||||
}
|
||||
|
||||
static void emDM_foreachMappedVert(
|
||||
DerivedMesh *dm,
|
||||
void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
|
||||
|
@ -1794,6 +1835,8 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
|
|||
bmdm->dm.getNumLoops = emDM_getNumLoops;
|
||||
bmdm->dm.getNumPolys = emDM_getNumPolys;
|
||||
|
||||
bmdm->dm.getLoopTriArray = emDM_getLoopTriArray;
|
||||
|
||||
bmdm->dm.getVert = emDM_getVert;
|
||||
bmdm->dm.getVertCo = emDM_getVertCo;
|
||||
bmdm->dm.getVertNo = emDM_getVertNo;
|
||||
|
@ -1812,6 +1855,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
|
|||
bmdm->dm.calcLoopNormals = emDM_calcLoopNormals;
|
||||
bmdm->dm.calcLoopNormalsSpaceArray = emDM_calcLoopNormalsSpaceArray;
|
||||
bmdm->dm.recalcTessellation = emDM_recalcTessellation;
|
||||
bmdm->dm.recalcLoopTri = emDM_recalcLoopTri;
|
||||
|
||||
bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
|
||||
bmdm->dm.foreachMappedLoop = emDM_foreachMappedLoop;
|
||||
|
|
|
@ -328,6 +328,52 @@ void BKE_mesh_calc_normals_tessface(
|
|||
MEM_freeN(fnors);
|
||||
}
|
||||
|
||||
void BKE_mesh_calc_normals_looptri(
|
||||
MVert *mverts, int numVerts,
|
||||
const MLoop *mloop,
|
||||
const MLoopTri *looptri, int looptri_num,
|
||||
float (*r_tri_nors)[3])
|
||||
{
|
||||
float (*tnorms)[3] = MEM_callocN(sizeof(*tnorms) * (size_t)numVerts, "tnorms");
|
||||
float (*fnors)[3] = (r_tri_nors) ? r_tri_nors : MEM_callocN(sizeof(*fnors) * (size_t)looptri_num, "meshnormals");
|
||||
int i;
|
||||
|
||||
for (i = 0; i < looptri_num; i++) {
|
||||
const MLoopTri *lt = &looptri[i];
|
||||
float *f_no = fnors[i];
|
||||
const unsigned int vtri[3] = {
|
||||
mloop[lt->tri[0]].v,
|
||||
mloop[lt->tri[1]].v,
|
||||
mloop[lt->tri[2]].v,
|
||||
};
|
||||
|
||||
normal_tri_v3(
|
||||
f_no,
|
||||
mverts[vtri[0]].co, mverts[vtri[1]].co, mverts[vtri[2]].co);
|
||||
|
||||
accumulate_vertex_normals_tri(
|
||||
tnorms[vtri[0]], tnorms[vtri[1]], tnorms[vtri[2]],
|
||||
f_no, mverts[vtri[0]].co, mverts[vtri[1]].co, mverts[vtri[2]].co);
|
||||
}
|
||||
|
||||
/* following Mesh convention; we use vertex coordinate itself for normal in this case */
|
||||
for (i = 0; i < numVerts; i++) {
|
||||
MVert *mv = &mverts[i];
|
||||
float *no = tnorms[i];
|
||||
|
||||
if (UNLIKELY(normalize_v3(no) == 0.0f)) {
|
||||
normalize_v3_v3(no, mv->co);
|
||||
}
|
||||
|
||||
normal_float_to_short_v3(mv->no, no);
|
||||
}
|
||||
|
||||
MEM_freeN(tnorms);
|
||||
|
||||
if (fnors != r_tri_nors)
|
||||
MEM_freeN(fnors);
|
||||
}
|
||||
|
||||
void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops)
|
||||
{
|
||||
if (!(lnors_spacearr->lspacearr && lnors_spacearr->loops_pool)) {
|
||||
|
@ -2541,6 +2587,136 @@ int BKE_mesh_recalc_tessellation(
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate tessellation into #MLoopTri which exist only for this purpose.
|
||||
*/
|
||||
void BKE_mesh_recalc_looptri(
|
||||
const MLoop *mloop, const MPoly *mpoly,
|
||||
const MVert *mvert,
|
||||
int totloop, int totpoly,
|
||||
MLoopTri *mlooptri)
|
||||
{
|
||||
/* use this to avoid locking pthread for _every_ polygon
|
||||
* and calling the fill function */
|
||||
|
||||
#define USE_TESSFACE_SPEEDUP
|
||||
|
||||
const MPoly *mp;
|
||||
const MLoop *ml;
|
||||
MLoopTri *mlt;
|
||||
MemArena *arena = NULL;
|
||||
int poly_index, mlooptri_index;
|
||||
unsigned int j;
|
||||
|
||||
mlooptri_index = 0;
|
||||
mp = mpoly;
|
||||
for (poly_index = 0; poly_index < totpoly; poly_index++, mp++) {
|
||||
const unsigned int mp_loopstart = (unsigned int)mp->loopstart;
|
||||
const unsigned int mp_totloop = (unsigned int)mp->totloop;
|
||||
unsigned int l1, l2, l3;
|
||||
if (mp_totloop < 3) {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
#ifdef USE_TESSFACE_SPEEDUP
|
||||
|
||||
#define ML_TO_MLT(i1, i2, i3) { \
|
||||
mlt = &mlooptri[mlooptri_index]; \
|
||||
l1 = mp_loopstart + i1; \
|
||||
l2 = mp_loopstart + i2; \
|
||||
l3 = mp_loopstart + i3; \
|
||||
ARRAY_SET_ITEMS(mlt->tri, l1, l2, l3); \
|
||||
mlt->poly = (unsigned int)poly_index; \
|
||||
} ((void)0)
|
||||
|
||||
else if (mp_totloop == 3) {
|
||||
ML_TO_MLT(0, 1, 2);
|
||||
mlooptri_index++;
|
||||
}
|
||||
else if (mp_totloop == 4) {
|
||||
ML_TO_MLT(0, 1, 2);
|
||||
mlooptri_index++;
|
||||
ML_TO_MLT(0, 2, 3);
|
||||
mlooptri_index++;
|
||||
}
|
||||
#endif /* USE_TESSFACE_SPEEDUP */
|
||||
else {
|
||||
const float *co_curr, *co_prev;
|
||||
|
||||
float normal[3];
|
||||
|
||||
float axis_mat[3][3];
|
||||
float (*projverts)[2];
|
||||
unsigned int (*tris)[3];
|
||||
|
||||
const unsigned int totfilltri = mp_totloop - 2;
|
||||
|
||||
if (UNLIKELY(arena == NULL)) {
|
||||
arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
|
||||
}
|
||||
|
||||
tris = BLI_memarena_alloc(arena, sizeof(*tris) * (size_t)totfilltri);
|
||||
projverts = BLI_memarena_alloc(arena, sizeof(*projverts) * (size_t)mp_totloop);
|
||||
|
||||
zero_v3(normal);
|
||||
|
||||
/* calc normal, flipped: to get a positive 2d cross product */
|
||||
ml = mloop + mp_loopstart;
|
||||
co_prev = mvert[ml[mp_totloop - 1].v].co;
|
||||
for (j = 0; j < mp_totloop; j++, ml++) {
|
||||
co_curr = mvert[ml->v].co;
|
||||
add_newell_cross_v3_v3v3(normal, co_prev, co_curr);
|
||||
co_prev = co_curr;
|
||||
}
|
||||
if (UNLIKELY(normalize_v3(normal) == 0.0f)) {
|
||||
normal[2] = 1.0f;
|
||||
}
|
||||
|
||||
/* project verts to 2d */
|
||||
axis_dominant_v3_to_m3_negate(axis_mat, normal);
|
||||
|
||||
ml = mloop + mp_loopstart;
|
||||
for (j = 0; j < mp_totloop; j++, ml++) {
|
||||
mul_v2_m3v3(projverts[j], axis_mat, mvert[ml->v].co);
|
||||
}
|
||||
|
||||
BLI_polyfill_calc_arena((const float (*)[2])projverts, mp_totloop, 1, tris, arena);
|
||||
|
||||
/* apply fill */
|
||||
for (j = 0; j < totfilltri; j++) {
|
||||
unsigned int *tri = tris[j];
|
||||
|
||||
mlt = &mlooptri[mlooptri_index];
|
||||
|
||||
/* set loop indices, transformed to vert indices later */
|
||||
l1 = mp_loopstart + tri[0];
|
||||
l2 = mp_loopstart + tri[1];
|
||||
l3 = mp_loopstart + tri[2];
|
||||
|
||||
ARRAY_SET_ITEMS(mlt->tri, l1, l2, l3);
|
||||
mlt->poly = (unsigned int)poly_index;
|
||||
|
||||
mlooptri_index++;
|
||||
}
|
||||
|
||||
BLI_memarena_clear(arena);
|
||||
}
|
||||
}
|
||||
|
||||
if (arena) {
|
||||
BLI_memarena_free(arena);
|
||||
arena = NULL;
|
||||
}
|
||||
|
||||
BLI_assert(mlooptri_index == poly_to_tri_count(totpoly, totloop));
|
||||
|
||||
#undef USE_TESSFACE_SPEEDUP
|
||||
#undef ML_TO_MLT
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifdef USE_BMESH_SAVE_AS_COMPAT
|
||||
|
||||
/**
|
||||
|
|
|
@ -470,12 +470,11 @@ void BKE_paint_stroke_get_average(Scene *scene, Object *ob, float stroke[3])
|
|||
|
||||
/* returns non-zero if any of the face's vertices
|
||||
* are hidden, zero otherwise */
|
||||
bool paint_is_face_hidden(const MFace *f, const MVert *mvert)
|
||||
bool paint_is_face_hidden(const MLoopTri *lt, const MVert *mvert, const MLoop *mloop)
|
||||
{
|
||||
return ((mvert[f->v1].flag & ME_HIDE) ||
|
||||
(mvert[f->v2].flag & ME_HIDE) ||
|
||||
(mvert[f->v3].flag & ME_HIDE) ||
|
||||
(f->v4 && (mvert[f->v4].flag & ME_HIDE)));
|
||||
return ((mvert[mloop[lt->tri[0]].v].flag & ME_HIDE) ||
|
||||
(mvert[mloop[lt->tri[1]].v].flag & ME_HIDE) ||
|
||||
(mvert[mloop[lt->tri[2]].v].flag & ME_HIDE));
|
||||
}
|
||||
|
||||
/* returns non-zero if any of the corners of the grid
|
||||
|
|
|
@ -168,7 +168,7 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node)
|
|||
// BB_expand(&node->vb, co);
|
||||
//}
|
||||
|
||||
static int face_materials_match(const MFace *f1, const MFace *f2)
|
||||
static int face_materials_match(const MPoly *f1, const MPoly *f2)
|
||||
{
|
||||
return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
|
||||
(f1->mat_nr == f2->mat_nr));
|
||||
|
@ -201,21 +201,22 @@ static int partition_indices(int *prim_indices, int lo, int hi, int axis,
|
|||
/* Returns the index of the first element on the right of the partition */
|
||||
static int partition_indices_material(PBVH *bvh, int lo, int hi)
|
||||
{
|
||||
const MFace *faces = bvh->faces;
|
||||
const MPoly *mpoly = bvh->mpoly;
|
||||
const MLoopTri *looptri = bvh->looptri;
|
||||
const DMFlagMat *flagmats = bvh->grid_flag_mats;
|
||||
const int *indices = bvh->prim_indices;
|
||||
const void *first;
|
||||
int i = lo, j = hi;
|
||||
|
||||
if (bvh->faces)
|
||||
first = &faces[bvh->prim_indices[lo]];
|
||||
if (bvh->looptri)
|
||||
first = &looptri[bvh->prim_indices[lo]];
|
||||
else
|
||||
first = &flagmats[bvh->prim_indices[lo]];
|
||||
|
||||
for (;; ) {
|
||||
if (bvh->faces) {
|
||||
for (; face_materials_match(first, &faces[indices[i]]); i++) ;
|
||||
for (; !face_materials_match(first, &faces[indices[j]]); j--) ;
|
||||
if (bvh->looptri) {
|
||||
for (; face_materials_match(first, &mpoly[looptri[indices[i]].poly]); i++) ;
|
||||
for (; !face_materials_match(first, &mpoly[looptri[indices[j]].poly]); j--) ;
|
||||
}
|
||||
else {
|
||||
for (; grid_materials_match(first, &flagmats[indices[i]]); i++) ;
|
||||
|
@ -295,17 +296,18 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
|||
node->face_vert_indices = (const int (*)[4])face_vert_indices;
|
||||
|
||||
for (i = 0; i < totface; ++i) {
|
||||
const MFace *f = &bvh->faces[node->prim_indices[i]];
|
||||
int sides = f->v4 ? 4 : 3;
|
||||
const MLoopTri *lt = &bvh->looptri[node->prim_indices[i]];
|
||||
const int sides = 3;
|
||||
|
||||
for (j = 0; j < sides; ++j) {
|
||||
face_vert_indices[i][j] =
|
||||
map_insert_vert(bvh, map, &node->face_verts,
|
||||
&node->uniq_verts, (&f->v1)[j]);
|
||||
&node->uniq_verts, bvh->mloop[lt->tri[j]].v);
|
||||
}
|
||||
|
||||
if (!paint_is_face_hidden(f, bvh->verts))
|
||||
if (!paint_is_face_hidden(lt, bvh->verts, bvh->mloop)) {
|
||||
has_visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
vert_indices = MEM_callocN(sizeof(int) *
|
||||
|
@ -326,9 +328,8 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
|||
}
|
||||
|
||||
for (i = 0; i < totface; ++i) {
|
||||
const MFace *f = &bvh->faces[node->prim_indices[i]];
|
||||
int sides = f->v4 ? 4 : 3;
|
||||
|
||||
const int sides = 3;
|
||||
|
||||
for (j = 0; j < sides; ++j) {
|
||||
if (face_vert_indices[i][j] < 0)
|
||||
face_vert_indices[i][j] =
|
||||
|
@ -406,7 +407,7 @@ static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc,
|
|||
/* Still need vb for searches */
|
||||
update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
|
||||
|
||||
if (bvh->faces)
|
||||
if (bvh->looptri)
|
||||
build_mesh_leaf_node(bvh, bvh->nodes + node_index);
|
||||
else {
|
||||
build_grid_leaf_node(bvh, bvh->nodes + node_index);
|
||||
|
@ -417,25 +418,28 @@ static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc,
|
|||
* same material (including flat/smooth shading), non-zero otherwise */
|
||||
static int leaf_needs_material_split(PBVH *bvh, int offset, int count)
|
||||
{
|
||||
int i, prim;
|
||||
int i;
|
||||
|
||||
if (count <= 1)
|
||||
return 0;
|
||||
|
||||
if (bvh->faces) {
|
||||
const MFace *first = &bvh->faces[bvh->prim_indices[offset]];
|
||||
if (bvh->looptri) {
|
||||
const MLoopTri *first = &bvh->looptri[bvh->prim_indices[offset]];
|
||||
const MPoly *mp = &bvh->mpoly[first->poly];
|
||||
|
||||
for (i = offset + count - 1; i > offset; --i) {
|
||||
prim = bvh->prim_indices[i];
|
||||
if (!face_materials_match(first, &bvh->faces[prim]))
|
||||
int prim = bvh->prim_indices[i];
|
||||
const MPoly *mp_other = &bvh->mpoly[bvh->looptri[prim].poly];
|
||||
if (!face_materials_match(mp, mp_other)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const DMFlagMat *first = &bvh->grid_flag_mats[bvh->prim_indices[offset]];
|
||||
|
||||
for (i = offset + count - 1; i > offset; --i) {
|
||||
prim = bvh->prim_indices[i];
|
||||
int prim = bvh->prim_indices[i];
|
||||
if (!grid_materials_match(first, &bvh->grid_flag_mats[prim]))
|
||||
return 1;
|
||||
}
|
||||
|
@ -534,15 +538,18 @@ static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
|
|||
|
||||
/* Do a full rebuild with on Mesh data structure */
|
||||
void BKE_pbvh_build_mesh(
|
||||
PBVH *bvh, const MFace *faces, MVert *verts,
|
||||
int totface, int totvert, struct CustomData *vdata)
|
||||
PBVH *bvh, const MPoly *mpoly, const MLoop *mloop, MVert *verts,
|
||||
int totvert, struct CustomData *vdata,
|
||||
const MLoopTri *looptri, int looptri_num)
|
||||
{
|
||||
BBC *prim_bbc = NULL;
|
||||
BB cb;
|
||||
int i, j;
|
||||
|
||||
bvh->type = PBVH_FACES;
|
||||
bvh->faces = faces;
|
||||
bvh->mpoly = mpoly;
|
||||
bvh->mloop = mloop;
|
||||
bvh->looptri = looptri;
|
||||
bvh->verts = verts;
|
||||
bvh->vert_bitmap = BLI_BITMAP_NEW(totvert, "bvh->vert_bitmap");
|
||||
bvh->totvert = totvert;
|
||||
|
@ -552,25 +559,25 @@ void BKE_pbvh_build_mesh(
|
|||
BB_reset(&cb);
|
||||
|
||||
/* For each face, store the AABB and the AABB centroid */
|
||||
prim_bbc = MEM_mallocN(sizeof(BBC) * totface, "prim_bbc");
|
||||
prim_bbc = MEM_mallocN(sizeof(BBC) * looptri_num, "prim_bbc");
|
||||
|
||||
for (i = 0; i < totface; ++i) {
|
||||
const MFace *f = &faces[i];
|
||||
const int sides = f->v4 ? 4 : 3;
|
||||
for (i = 0; i < looptri_num; ++i) {
|
||||
const MLoopTri *lt = &looptri[i];
|
||||
const int sides = 3;
|
||||
BBC *bbc = prim_bbc + i;
|
||||
|
||||
BB_reset((BB *)bbc);
|
||||
|
||||
for (j = 0; j < sides; ++j)
|
||||
BB_expand((BB *)bbc, verts[(&f->v1)[j]].co);
|
||||
BB_expand((BB *)bbc, verts[bvh->mloop[lt->tri[j]].v].co);
|
||||
|
||||
BBC_update_centroid(bbc);
|
||||
|
||||
BB_expand(&cb, bbc->bcentroid);
|
||||
}
|
||||
|
||||
if (totface)
|
||||
pbvh_build(bvh, &cb, prim_bbc, totface);
|
||||
if (looptri_num)
|
||||
pbvh_build(bvh, &cb, prim_bbc, looptri_num);
|
||||
|
||||
MEM_freeN(prim_bbc);
|
||||
MEM_freeN(bvh->vert_bitmap);
|
||||
|
@ -657,12 +664,13 @@ void BKE_pbvh_free(PBVH *bvh)
|
|||
/* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
|
||||
|
||||
MEM_freeN((void *)bvh->verts);
|
||||
if (bvh->faces) {
|
||||
MEM_freeN((void *)bvh->faces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bvh->looptri) {
|
||||
MEM_freeN((void *)bvh->looptri);
|
||||
}
|
||||
|
||||
if (bvh->nodes)
|
||||
MEM_freeN(bvh->nodes);
|
||||
|
||||
|
@ -983,20 +991,23 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||
totface = node->totprim;
|
||||
|
||||
for (i = 0; i < totface; ++i) {
|
||||
const MFace *f = &bvh->faces[faces[i]];
|
||||
const MLoopTri *lt = &bvh->looptri[faces[i]];
|
||||
const unsigned int vtri[3] = {
|
||||
bvh->mloop[lt->tri[0]].v,
|
||||
bvh->mloop[lt->tri[1]].v,
|
||||
bvh->mloop[lt->tri[2]].v,
|
||||
};
|
||||
float fn[3];
|
||||
const unsigned int *fv = &f->v1;
|
||||
int sides = (f->v4) ? 4 : 3;
|
||||
const int sides = 3;
|
||||
|
||||
if (f->v4)
|
||||
normal_quad_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
|
||||
bvh->verts[f->v3].co, bvh->verts[f->v4].co);
|
||||
else
|
||||
normal_tri_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
|
||||
bvh->verts[f->v3].co);
|
||||
normal_tri_v3(
|
||||
fn,
|
||||
bvh->verts[vtri[0]].co,
|
||||
bvh->verts[vtri[1]].co,
|
||||
bvh->verts[vtri[2]].co);
|
||||
|
||||
for (j = 0; j < sides; ++j) {
|
||||
int v = fv[j];
|
||||
int v = vtri[j];
|
||||
|
||||
if (bvh->verts[v].flag & ME_VERT_PBVH_UPDATE) {
|
||||
/* this seems like it could be very slow but profile
|
||||
|
@ -1010,8 +1021,9 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||
}
|
||||
}
|
||||
|
||||
if (face_nors)
|
||||
copy_v3_v3(face_nors[faces[i]], fn);
|
||||
if (face_nors) {
|
||||
copy_v3_v3(face_nors[lt->poly], fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1093,7 +1105,8 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
|||
case PBVH_FACES:
|
||||
node->draw_buffers =
|
||||
GPU_build_mesh_pbvh_buffers(node->face_vert_indices,
|
||||
bvh->faces, bvh->verts,
|
||||
bvh->mpoly, bvh->mloop, bvh->looptri,
|
||||
bvh->verts,
|
||||
node->prim_indices,
|
||||
node->totprim);
|
||||
break;
|
||||
|
@ -1515,15 +1528,16 @@ static bool pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
|
|||
const float ray_normal[3], float *dist)
|
||||
{
|
||||
const MVert *vert = bvh->verts;
|
||||
const MLoop *mloop = bvh->mloop;
|
||||
const int *faces = node->prim_indices;
|
||||
int i, totface = node->totprim;
|
||||
bool hit = false;
|
||||
|
||||
for (i = 0; i < totface; ++i) {
|
||||
const MFace *f = bvh->faces + faces[i];
|
||||
const MLoopTri *lt = &bvh->looptri[faces[i]];
|
||||
const int *face_verts = node->face_vert_indices[i];
|
||||
|
||||
if (paint_is_face_hidden(f, vert))
|
||||
if (paint_is_face_hidden(lt, vert, mloop))
|
||||
continue;
|
||||
|
||||
if (origco) {
|
||||
|
@ -1532,16 +1546,16 @@ static bool pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
|
|||
origco[face_verts[0]],
|
||||
origco[face_verts[1]],
|
||||
origco[face_verts[2]],
|
||||
f->v4 ? origco[face_verts[3]] : NULL,
|
||||
NULL,
|
||||
dist);
|
||||
}
|
||||
else {
|
||||
/* intersect with current coordinates */
|
||||
hit |= ray_face_intersection(ray_start, ray_normal,
|
||||
vert[f->v1].co,
|
||||
vert[f->v2].co,
|
||||
vert[f->v3].co,
|
||||
f->v4 ? vert[f->v4].co : NULL,
|
||||
vert[mloop[lt->tri[0]].v].co,
|
||||
vert[mloop[lt->tri[1]].v].co,
|
||||
vert[mloop[lt->tri[2]].v].co,
|
||||
NULL,
|
||||
dist);
|
||||
}
|
||||
}
|
||||
|
@ -1874,8 +1888,8 @@ void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
|
|||
/* original data and applying new coords to this arrays would lead to */
|
||||
/* unneeded deformation -- duplicate verts/faces to avoid this */
|
||||
|
||||
pbvh->verts = MEM_dupallocN(pbvh->verts);
|
||||
pbvh->faces = MEM_dupallocN(pbvh->faces);
|
||||
pbvh->verts = MEM_dupallocN(pbvh->verts);
|
||||
pbvh->looptri = MEM_dupallocN(pbvh->looptri);
|
||||
|
||||
pbvh->deformed = 1;
|
||||
}
|
||||
|
@ -1890,7 +1904,11 @@ void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
|
|||
}
|
||||
|
||||
/* coordinates are new -- normals should also be updated */
|
||||
BKE_mesh_calc_normals_tessface(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
|
||||
BKE_mesh_calc_normals_looptri(
|
||||
pbvh->verts, pbvh->totvert,
|
||||
pbvh->mloop,
|
||||
pbvh->looptri, pbvh->totprim,
|
||||
NULL);
|
||||
|
||||
for (a = 0; a < pbvh->totnode; ++a)
|
||||
BKE_pbvh_node_mark_update(&pbvh->nodes[a]);
|
||||
|
|
|
@ -133,7 +133,9 @@ struct PBVH {
|
|||
|
||||
/* Mesh data */
|
||||
MVert *verts;
|
||||
const MFace *faces;
|
||||
const MPoly *mpoly;
|
||||
const MLoop *mloop;
|
||||
const MLoopTri *looptri;
|
||||
CustomData *vdata;
|
||||
|
||||
/* Grid Data */
|
||||
|
|
|
@ -1769,7 +1769,7 @@ static void ccgDM_buffer_copy_normal(
|
|||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGKey key;
|
||||
const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
|
||||
const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
|
||||
int gridSize = ccgSubSurf_getGridSize(ss);
|
||||
int gridFaces = gridSize - 1;
|
||||
DMFlagMat *faceFlags = ccgdm->faceFlags;
|
||||
|
@ -1784,7 +1784,7 @@ static void ccgDM_buffer_copy_normal(
|
|||
CCGFace *f = ccgdm->faceMap[i].face;
|
||||
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
|
||||
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
|
||||
const short (*ln)[3] = NULL;
|
||||
const float (*ln)[3] = NULL;
|
||||
|
||||
if (faceFlags) {
|
||||
shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
|
||||
|
@ -1794,8 +1794,8 @@ static void ccgDM_buffer_copy_normal(
|
|||
}
|
||||
|
||||
if (lnors) {
|
||||
ln = *lnors;
|
||||
lnors += gridFaces * gridFaces * numVerts;
|
||||
ln = lnors;
|
||||
lnors += gridFaces * gridFaces * numVerts * 4;
|
||||
}
|
||||
|
||||
for (S = 0; S < numVerts; S++) {
|
||||
|
@ -1805,10 +1805,10 @@ static void ccgDM_buffer_copy_normal(
|
|||
/* Can't use quad strips here... */
|
||||
for (y = 0; y < gridFaces; y ++) {
|
||||
for (x = 0; x < gridFaces; x ++) {
|
||||
copy_v3_v3_short(&varray[start], ln[0]);
|
||||
copy_v3_v3_short(&varray[start + 4], ln[3]);
|
||||
copy_v3_v3_short(&varray[start + 8], ln[2]);
|
||||
copy_v3_v3_short(&varray[start + 12], ln[1]);
|
||||
normal_float_to_short_v3(&varray[start + 0], ln[0]);
|
||||
normal_float_to_short_v3(&varray[start + 4], ln[3]);
|
||||
normal_float_to_short_v3(&varray[start + 8], ln[2]);
|
||||
normal_float_to_short_v3(&varray[start + 12], ln[1]);
|
||||
|
||||
start += 16;
|
||||
ln += 4;
|
||||
|
@ -1953,13 +1953,6 @@ static void ccgDM_buffer_copy_vertex(
|
|||
}
|
||||
}
|
||||
|
||||
static void copy_mcol_uc3(unsigned char *v, const unsigned char *col)
|
||||
{
|
||||
v[0] = col[3];
|
||||
v[1] = col[2];
|
||||
v[2] = col[1];
|
||||
}
|
||||
|
||||
/* Only used by non-editmesh types */
|
||||
static void ccgDM_buffer_copy_color(
|
||||
DerivedMesh *dm, unsigned char *varray,
|
||||
|
@ -1968,7 +1961,7 @@ static void ccgDM_buffer_copy_color(
|
|||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGKey key;
|
||||
const unsigned char *mcol = user_data;
|
||||
const char *mloopcol = user_data;
|
||||
int gridSize = ccgSubSurf_getGridSize(ss);
|
||||
int gridFaces = gridSize - 1;
|
||||
int i, totface = ccgSubSurf_getNumFaces(ss);
|
||||
|
@ -1985,10 +1978,10 @@ static void ccgDM_buffer_copy_color(
|
|||
for (S = 0; S < numVerts; S++) {
|
||||
for (y = 0; y < gridFaces; y++) {
|
||||
for (x = 0; x < gridFaces; x++) {
|
||||
copy_mcol_uc3(&varray[start], &mcol[iface * 16]);
|
||||
copy_mcol_uc3(&varray[start + 3], &mcol[iface * 16 + 12]);
|
||||
copy_mcol_uc3(&varray[start + 6], &mcol[iface * 16 + 8]);
|
||||
copy_mcol_uc3(&varray[start + 9], &mcol[iface * 16 + 4]);
|
||||
copy_v3_v3_char((char *)&varray[start + 0], &mloopcol[iface * 16 + 0]);
|
||||
copy_v3_v3_char((char *)&varray[start + 3], &mloopcol[iface * 16 + 12]);
|
||||
copy_v3_v3_char((char *)&varray[start + 6], &mloopcol[iface * 16 + 8]);
|
||||
copy_v3_v3_char((char *)&varray[start + 9], &mloopcol[iface * 16 + 4]);
|
||||
|
||||
start += 12;
|
||||
iface++;
|
||||
|
@ -2005,7 +1998,7 @@ static void ccgDM_buffer_copy_uv(
|
|||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGKey key;
|
||||
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
MLoopUV *mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV);
|
||||
int gridSize = ccgSubSurf_getGridSize(ss);
|
||||
int gridFaces = gridSize - 1;
|
||||
int i, totface = ccgSubSurf_getNumFaces(ss);
|
||||
|
@ -2020,12 +2013,12 @@ static void ccgDM_buffer_copy_uv(
|
|||
for (S = 0; S < numVerts; S++) {
|
||||
for (y = 0; y < gridFaces; y++) {
|
||||
for (x = 0; x < gridFaces; x++) {
|
||||
copy_v2_v2(&varray[start], tf->uv[0]);
|
||||
copy_v2_v2(&varray[start + 2], tf->uv[3]);
|
||||
copy_v2_v2(&varray[start + 4], tf->uv[2]);
|
||||
copy_v2_v2(&varray[start + 6], tf->uv[1]);
|
||||
copy_v2_v2(&varray[start + 0], mloopuv[0].uv);
|
||||
copy_v2_v2(&varray[start + 2], mloopuv[3].uv);
|
||||
copy_v2_v2(&varray[start + 4], mloopuv[2].uv);
|
||||
copy_v2_v2(&varray[start + 6], mloopuv[1].uv);
|
||||
|
||||
tf++;
|
||||
mloopuv += 4;
|
||||
start += 8;
|
||||
}
|
||||
}
|
||||
|
@ -2045,22 +2038,22 @@ static void ccgDM_buffer_copy_uv_texpaint(
|
|||
int start = 0;
|
||||
DMFlagMat *faceFlags = ccgdm->faceFlags;
|
||||
int totmaterial = dm->totmat;
|
||||
MTFace **mtface_base;
|
||||
MTFace *stencil_base;
|
||||
MLoopUV **mloopuv_base;
|
||||
MLoopUV *stencil_base;
|
||||
int stencil;
|
||||
|
||||
CCG_key_top_level(&key, ss);
|
||||
|
||||
/* should have been checked for before, reassert */
|
||||
BLI_assert(DM_get_tessface_data_layer(dm, CD_MTFACE));
|
||||
mtface_base = MEM_mallocN(totmaterial * sizeof(*mtface_base), "texslots");
|
||||
BLI_assert(DM_get_loop_data_layer(dm, CD_MLOOPUV));
|
||||
mloopuv_base = MEM_mallocN(totmaterial * sizeof(*mloopuv_base), "texslots");
|
||||
|
||||
for (i = 0; i < totmaterial; i++) {
|
||||
mtface_base[i] = DM_paint_uvlayer_active_get(dm, i);
|
||||
mloopuv_base[i] = DM_paint_uvlayer_active_get_mloopuv(dm, i);
|
||||
}
|
||||
|
||||
stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
|
||||
stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
|
||||
stencil = CustomData_get_stencil_layer(&dm->loopData, CD_MLOOPUV);
|
||||
stencil_base = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, stencil);
|
||||
|
||||
start = 0;
|
||||
|
||||
|
@ -2080,23 +2073,23 @@ static void ccgDM_buffer_copy_uv_texpaint(
|
|||
for (S = 0; S < numVerts; S++) {
|
||||
for (y = 0; y < gridFaces; y++) {
|
||||
for (x = 0; x < gridFaces; x++) {
|
||||
/* divide by 16, gives us current tface */
|
||||
unsigned int i_tf = start / 16;
|
||||
copy_v2_v2(&varray[start], mtface_base[matnr][i_tf].uv[0]);
|
||||
copy_v2_v2(&varray[start + 2], stencil_base[i_tf].uv[0]);
|
||||
copy_v2_v2(&varray[start + 4], mtface_base[matnr][i_tf].uv[3]);
|
||||
copy_v2_v2(&varray[start + 6], stencil_base[i_tf].uv[3]);
|
||||
copy_v2_v2(&varray[start + 8], mtface_base[matnr][i_tf].uv[2]);
|
||||
copy_v2_v2(&varray[start + 10], stencil_base[i_tf].uv[2]);
|
||||
copy_v2_v2(&varray[start + 12], mtface_base[matnr][i_tf].uv[1]);
|
||||
copy_v2_v2(&varray[start + 14], stencil_base[i_tf].uv[1]);
|
||||
/* divide by 4, gives us current loop-index */
|
||||
unsigned int i_ml = start / 4;
|
||||
copy_v2_v2(&varray[start + 0], mloopuv_base[matnr][i_ml + 0].uv);
|
||||
copy_v2_v2(&varray[start + 2], stencil_base[i_ml + 0].uv);
|
||||
copy_v2_v2(&varray[start + 4], mloopuv_base[matnr][i_ml + 3].uv);
|
||||
copy_v2_v2(&varray[start + 6], stencil_base[i_ml + 3].uv);
|
||||
copy_v2_v2(&varray[start + 8], mloopuv_base[matnr][i_ml + 2].uv);
|
||||
copy_v2_v2(&varray[start + 10], stencil_base[i_ml + 2].uv);
|
||||
copy_v2_v2(&varray[start + 12], mloopuv_base[matnr][i_ml + 1].uv);
|
||||
copy_v2_v2(&varray[start + 14], stencil_base[i_ml + 1].uv);
|
||||
start += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(mtface_base);
|
||||
MEM_freeN(mloopuv_base);
|
||||
}
|
||||
|
||||
static void ccgDM_copy_gpu_data(
|
||||
|
@ -2301,7 +2294,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
|
|||
index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
|
||||
else \
|
||||
index = 0; \
|
||||
DM_draw_attrib_vertex(&attribs, a, index, vert); \
|
||||
DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \
|
||||
} (void)0
|
||||
|
||||
totface = ccgSubSurf_getNumFaces(ss);
|
||||
|
@ -2472,7 +2465,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
|
|||
index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
|
||||
else \
|
||||
index = 0; \
|
||||
DM_draw_attrib_vertex(&attribs, a, index, vert); \
|
||||
DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \
|
||||
} (void)0
|
||||
|
||||
totface = ccgSubSurf_getNumFaces(ss);
|
||||
|
@ -2621,8 +2614,8 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
|||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGKey key;
|
||||
int colType = CD_TEXTURE_MCOL;
|
||||
MCol *mcol = dm->getTessFaceDataArray(dm, colType);
|
||||
int colType;
|
||||
const MLoopCol *mloopcol;
|
||||
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
DMFlagMat *faceFlags = ccgdm->faceFlags;
|
||||
DMDrawOption draw_option;
|
||||
|
@ -2637,13 +2630,15 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
|||
CCG_key_top_level(&key, ss);
|
||||
ccgdm_pbvh_update(ccgdm);
|
||||
|
||||
if (!mcol) {
|
||||
colType = CD_TEXTURE_MLOOPCOL;
|
||||
mloopcol = dm->getLoopDataArray(dm, colType);
|
||||
if (!mloopcol) {
|
||||
colType = CD_PREVIEW_MCOL;
|
||||
mcol = dm->getTessFaceDataArray(dm, colType);
|
||||
mloopcol = dm->getLoopDataArray(dm, colType);
|
||||
}
|
||||
if (!mcol) {
|
||||
colType = CD_MCOL;
|
||||
mcol = dm->getTessFaceDataArray(dm, colType);
|
||||
if (!mloopcol) {
|
||||
colType = CD_MLOOPCOL;
|
||||
mloopcol = dm->getLoopDataArray(dm, colType);
|
||||
}
|
||||
|
||||
GPU_vertex_setup(dm);
|
||||
|
@ -2653,7 +2648,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
|||
GPU_texpaint_uv_setup(dm);
|
||||
else
|
||||
GPU_uv_setup(dm);
|
||||
if (mcol) {
|
||||
if (mloopcol) {
|
||||
GPU_color_setup(dm, colType);
|
||||
}
|
||||
|
||||
|
@ -2695,10 +2690,11 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
|||
if (drawParams) {
|
||||
MTexPoly tpoly;
|
||||
if (tf) {
|
||||
memset(&tpoly, 0, sizeof(tpoly));
|
||||
ME_MTEXFACE_CPY(&tpoly, tf + actualFace);
|
||||
}
|
||||
|
||||
draw_option = drawParams((use_tface && tf) ? &tpoly : NULL, (mcol != NULL), mat_nr);
|
||||
draw_option = drawParams((use_tface && tf) ? &tpoly : NULL, (mloopcol != NULL), mat_nr);
|
||||
}
|
||||
else if (index != ORIGINDEX_NONE)
|
||||
draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL;
|
||||
|
@ -2721,7 +2717,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
|||
tot_drawn += facequads * 6;
|
||||
|
||||
if (tot_drawn) {
|
||||
if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
|
||||
if (mloopcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
|
||||
GPU_color_switch(1);
|
||||
else
|
||||
GPU_color_switch(0);
|
||||
|
@ -2801,7 +2797,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
|
|||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGKey key;
|
||||
MCol *mcol = NULL;
|
||||
MLoopCol *mloopcol = NULL;
|
||||
short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
|
||||
int i, gridSize = ccgSubSurf_getGridSize(ss);
|
||||
DMFlagMat *faceFlags = ccgdm->faceFlags;
|
||||
|
@ -2815,9 +2811,9 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
|
|||
(void)compareDrawOptions;
|
||||
|
||||
if (useColors) {
|
||||
mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
|
||||
if (!mcol)
|
||||
mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
|
||||
mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL);
|
||||
if (!mloopcol)
|
||||
mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL);
|
||||
}
|
||||
|
||||
totface = ccgSubSurf_getNumFaces(ss);
|
||||
|
@ -2835,9 +2831,9 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
|
|||
else if (faceFlags) drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH));
|
||||
else drawSmooth = 1;
|
||||
|
||||
if (mcol) {
|
||||
cp = (unsigned char *)mcol;
|
||||
mcol += gridFaces * gridFaces * numVerts * 4;
|
||||
if (mloopcol) {
|
||||
cp = (unsigned char *)mloopcol;
|
||||
mloopcol += gridFaces * gridFaces * numVerts * 4;
|
||||
}
|
||||
|
||||
if (lnors) {
|
||||
|
@ -2881,16 +2877,16 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
|
|||
float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
|
||||
float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
|
||||
|
||||
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
|
||||
if (cp) glColor3ubv(&cp[4]);
|
||||
glNormal3sv(ln[0][1]);
|
||||
glVertex3fv(d);
|
||||
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
|
||||
if (cp) glColor3ubv(&cp[8]);
|
||||
glNormal3sv(ln[0][2]);
|
||||
glVertex3fv(c);
|
||||
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
|
||||
if (cp) glColor3ubv(&cp[12]);
|
||||
glNormal3sv(ln[0][3]);
|
||||
glVertex3fv(b);
|
||||
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
|
||||
if (cp) glColor3ubv(&cp[0]);
|
||||
glNormal3sv(ln[0][0]);
|
||||
glVertex3fv(a);
|
||||
|
||||
|
@ -2908,10 +2904,10 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
|
|||
a = CCG_grid_elem(&key, faceGridData, x, y + 0);
|
||||
b = CCG_grid_elem(&key, faceGridData, x, y + 1);
|
||||
|
||||
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
|
||||
if (cp) glColor3ubv(&cp[0]);
|
||||
glNormal3fv(CCG_elem_no(&key, a));
|
||||
glVertex3fv(CCG_elem_co(&key, a));
|
||||
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
|
||||
if (cp) glColor3ubv(&cp[4]);
|
||||
glNormal3fv(CCG_elem_no(&key, b));
|
||||
glVertex3fv(CCG_elem_co(&key, b));
|
||||
|
||||
|
@ -2923,10 +2919,10 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
|
|||
a = CCG_grid_elem(&key, faceGridData, x, y + 0);
|
||||
b = CCG_grid_elem(&key, faceGridData, x, y + 1);
|
||||
|
||||
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
|
||||
if (cp) glColor3ubv(&cp[12]);
|
||||
glNormal3fv(CCG_elem_no(&key, a));
|
||||
glVertex3fv(CCG_elem_co(&key, a));
|
||||
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
|
||||
if (cp) glColor3ubv(&cp[8]);
|
||||
glNormal3fv(CCG_elem_no(&key, b));
|
||||
glVertex3fv(CCG_elem_co(&key, b));
|
||||
|
||||
|
@ -2946,13 +2942,13 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
|
|||
|
||||
ccgDM_glNormalFast(a, b, c, d);
|
||||
|
||||
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
|
||||
if (cp) glColor3ubv(&cp[4]);
|
||||
glVertex3fv(d);
|
||||
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
|
||||
if (cp) glColor3ubv(&cp[8]);
|
||||
glVertex3fv(c);
|
||||
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
|
||||
if (cp) glColor3ubv(&cp[12]);
|
||||
glVertex3fv(b);
|
||||
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
|
||||
if (cp) glColor3ubv(&cp[0]);
|
||||
glVertex3fv(a);
|
||||
|
||||
if (cp) cp += 16;
|
||||
|
@ -3568,10 +3564,15 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
|
|||
}
|
||||
else if (ob->type == OB_MESH) {
|
||||
Mesh *me = ob->data;
|
||||
const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
|
||||
MLoopTri *looptri;
|
||||
|
||||
looptri = MEM_mallocN(sizeof(*looptri) * looptris_num, __func__);
|
||||
|
||||
ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
|
||||
BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH ONLY complain if mpoly is valid but not mface */
|
||||
BKE_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
|
||||
me->totface, me->totvert, &me->vdata);
|
||||
BKE_pbvh_build_mesh(ccgdm->pbvh, me->mpoly, me->mloop, me->mvert, me->totvert, &me->vdata,
|
||||
looptri, looptris_num);
|
||||
}
|
||||
|
||||
if (ccgdm->pbvh)
|
||||
|
@ -3585,6 +3586,47 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
|
|||
/* Nothing to do: CCG handles creating its own tessfaces */
|
||||
}
|
||||
|
||||
static void ccgDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
|
||||
{
|
||||
/* Nothing to do: CCG tessellation is known,
|
||||
* allocate and fill in with ccgDM_getLoopTriArray */
|
||||
}
|
||||
|
||||
static const MLoopTri *ccgDM_getLoopTriArray(DerivedMesh *dm)
|
||||
{
|
||||
if (dm->looptris.array) {
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
}
|
||||
else {
|
||||
MLoopTri *mlooptri;
|
||||
const int tottri = dm->numTessFaceData * 2;
|
||||
int i, poly_index;
|
||||
|
||||
DM_ensure_looptri_data(dm);
|
||||
mlooptri = dm->looptris.array;
|
||||
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
BLI_assert(tottri == dm->looptris.num);
|
||||
|
||||
for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
|
||||
MLoopTri *lt;
|
||||
lt = &mlooptri[i];
|
||||
/* quad is (0, 3, 2, 1) */
|
||||
lt->tri[0] = (poly_index * 4) + 0;
|
||||
lt->tri[1] = (poly_index * 4) + 3;
|
||||
lt->tri[2] = (poly_index * 4) + 2;
|
||||
lt->poly = poly_index;
|
||||
|
||||
lt = &mlooptri[i + 1];
|
||||
lt->tri[0] = (poly_index * 4) + 0;
|
||||
lt->tri[1] = (poly_index * 4) + 2;
|
||||
lt->tri[2] = (poly_index * 4) + 1;
|
||||
lt->poly = poly_index;
|
||||
}
|
||||
}
|
||||
return dm->looptris.array;
|
||||
}
|
||||
|
||||
static void ccgDM_calcNormals(DerivedMesh *dm)
|
||||
{
|
||||
/* Nothing to do: CCG calculates normals during drawing */
|
||||
|
@ -3667,6 +3709,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
|
|||
/* reuse of ccgDM_getNumTessFaces is intentional here: subsurf polys are just created from tessfaces */
|
||||
ccgdm->dm.getNumPolys = ccgDM_getNumTessFaces;
|
||||
|
||||
ccgdm->dm.getLoopTriArray = ccgDM_getLoopTriArray;
|
||||
|
||||
ccgdm->dm.getVert = ccgDM_getFinalVert;
|
||||
ccgdm->dm.getEdge = ccgDM_getFinalEdge;
|
||||
ccgdm->dm.getTessFace = ccgDM_getFinalFace;
|
||||
|
@ -3702,6 +3746,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
|
|||
ccgdm->dm.calcLoopNormals = CDDM_calc_loop_normals;
|
||||
ccgdm->dm.calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
|
||||
ccgdm->dm.recalcTessellation = ccgDM_recalcTessellation;
|
||||
ccgdm->dm.recalcLoopTri = ccgDM_recalcLoopTri;
|
||||
|
||||
ccgdm->dm.getVertCos = ccgdm_getVertCos;
|
||||
ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
|
||||
|
|
|
@ -300,6 +300,11 @@ void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f
|
|||
|
||||
/********************************** Normals **********************************/
|
||||
|
||||
void accumulate_vertex_normals_tri(
|
||||
float n1[3], float n2[3], float n3[3],
|
||||
const float f_no[3],
|
||||
const float co1[3], const float co2[3], const float co3[3]);
|
||||
|
||||
void accumulate_vertex_normals(
|
||||
float n1[3], float n2[3], float n3[3], float n4[3],
|
||||
const float f_no[3],
|
||||
|
|
|
@ -3549,6 +3549,40 @@ void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f
|
|||
|
||||
/********************************* Normals **********************************/
|
||||
|
||||
void accumulate_vertex_normals_tri(
|
||||
float n1[3], float n2[3], float n3[3],
|
||||
const float f_no[3],
|
||||
const float co1[3], const float co2[3], const float co3[3])
|
||||
{
|
||||
float vdiffs[3][3];
|
||||
const int nverts = 3;
|
||||
|
||||
/* compute normalized edge vectors */
|
||||
sub_v3_v3v3(vdiffs[0], co2, co1);
|
||||
sub_v3_v3v3(vdiffs[1], co3, co2);
|
||||
sub_v3_v3v3(vdiffs[2], co1, co3);
|
||||
|
||||
normalize_v3(vdiffs[0]);
|
||||
normalize_v3(vdiffs[1]);
|
||||
normalize_v3(vdiffs[2]);
|
||||
|
||||
/* accumulate angle weighted face normal */
|
||||
{
|
||||
float *vn[] = {n1, n2, n3};
|
||||
const float *prev_edge = vdiffs[nverts - 1];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nverts; i++) {
|
||||
const float *cur_edge = vdiffs[i];
|
||||
const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
|
||||
|
||||
/* accumulate */
|
||||
madd_v3_v3fl(vn[i], f_no, fac);
|
||||
prev_edge = cur_edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void accumulate_vertex_normals(
|
||||
float n1[3], float n2[3], float n3[3], float n4[3],
|
||||
const float f_no[3],
|
||||
|
|
|
@ -62,9 +62,8 @@ void paintface_flush_flags(Object *ob)
|
|||
Mesh *me = BKE_mesh_from_object(ob);
|
||||
DerivedMesh *dm = ob->derivedFinal;
|
||||
MPoly *polys, *mp_orig;
|
||||
MFace *faces;
|
||||
const int *index_array = NULL;
|
||||
int totface, totpoly;
|
||||
int totpoly;
|
||||
int i;
|
||||
|
||||
if (me == NULL)
|
||||
|
@ -79,26 +78,7 @@ void paintface_flush_flags(Object *ob)
|
|||
if (dm == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Try to push updated mesh poly flags to three other data sets:
|
||||
* - Mesh polys => Mesh tess faces
|
||||
* - Mesh polys => Final derived polys
|
||||
* - Final derived polys => Final derived tessfaces
|
||||
*/
|
||||
|
||||
if ((index_array = CustomData_get_layer(&me->fdata, CD_ORIGINDEX))) {
|
||||
faces = me->mface;
|
||||
totface = me->totface;
|
||||
|
||||
/* loop over tessfaces */
|
||||
for (i = 0; i < totface; i++) {
|
||||
if (index_array[i] != ORIGINDEX_NONE) {
|
||||
/* Copy flags onto the original tessface from its original poly */
|
||||
mp_orig = me->mpoly + index_array[i];
|
||||
faces[i].flag = mp_orig->flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Mesh polys => Final derived polys */
|
||||
|
||||
if ((index_array = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX))) {
|
||||
polys = dm->getPolyArray(dm);
|
||||
|
@ -113,21 +93,6 @@ void paintface_flush_flags(Object *ob)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((index_array = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))) {
|
||||
polys = dm->getPolyArray(dm);
|
||||
faces = dm->getTessFaceArray(dm);
|
||||
totface = dm->getNumTessFaces(dm);
|
||||
|
||||
/* loop over tessfaces */
|
||||
for (i = 0; i < totface; i++) {
|
||||
if (index_array[i] != ORIGINDEX_NONE) {
|
||||
/* Copy flags onto the final tessface from its final poly */
|
||||
mp_orig = polys + index_array[i];
|
||||
faces[i].flag = mp_orig->flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void paintface_hide(Object *ob, const bool unselected)
|
||||
|
|
|
@ -91,45 +91,6 @@ static bool vertex_paint_use_fast_update_check(Object *ob)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* if the polygons from the mesh and the 'derivedFinal' match
|
||||
* we can assume that no modifiers are applied and that its worth adding tessellated faces
|
||||
* so 'vertex_paint_use_fast_update_check()' returns true */
|
||||
static bool vertex_paint_use_tessface_check(Object *ob, Mesh *me)
|
||||
{
|
||||
DerivedMesh *dm = ob->derivedFinal;
|
||||
|
||||
if (me && dm) {
|
||||
return (me->mpoly == CustomData_get_layer(&dm->polyData, CD_MPOLY));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void update_tessface_data(Object *ob, Mesh *me)
|
||||
{
|
||||
if (vertex_paint_use_tessface_check(ob, me)) {
|
||||
/* assume if these exist, that they are up to date & valid */
|
||||
if (!me->mcol || !me->mface) {
|
||||
/* should always be true */
|
||||
/* XXX Why this clearing? tessface_calc will reset it anyway! */
|
||||
#if 0
|
||||
if (me->mcol) {
|
||||
memset(me->mcol, 255, 4 * sizeof(MCol) * me->totface);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* create tessfaces because they will be used for drawing & fast updates */
|
||||
BKE_mesh_tessface_calc(me); /* does own call to update pointers */
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (me->totface) {
|
||||
/* this wont be used, theres no need to keep it */
|
||||
BKE_mesh_tessface_clear(me);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* polling - retrieve whether cursor should be set or operator should be done */
|
||||
|
||||
/* Returns true if vertex paint mode is active */
|
||||
|
@ -205,80 +166,7 @@ unsigned int vpaint_get_current_col(Scene *scene, VPaint *vp)
|
|||
return *(unsigned int *)col;
|
||||
}
|
||||
|
||||
static void do_shared_vertex_tesscol(Mesh *me, bool *mfacetag)
|
||||
{
|
||||
/* if no mcol: do not do */
|
||||
/* if tface: only the involved faces, otherwise all */
|
||||
const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
|
||||
MFace *mface;
|
||||
int a;
|
||||
short *scolmain, *scol;
|
||||
char *mcol;
|
||||
const bool *mftag;
|
||||
|
||||
if (me->mcol == NULL || me->totvert == 0 || me->totface == 0) return;
|
||||
|
||||
scolmain = MEM_callocN(4 * sizeof(short) * me->totvert, "colmain");
|
||||
|
||||
mface = me->mface;
|
||||
mcol = (char *)me->mcol;
|
||||
for (a = me->totface; a > 0; a--, mface++, mcol += 16) {
|
||||
if ((use_face_sel == false) || (mface->flag & ME_FACE_SEL)) {
|
||||
scol = scolmain + 4 * mface->v1;
|
||||
scol[0]++; scol[1] += mcol[1]; scol[2] += mcol[2]; scol[3] += mcol[3];
|
||||
scol = scolmain + 4 * mface->v2;
|
||||
scol[0]++; scol[1] += mcol[5]; scol[2] += mcol[6]; scol[3] += mcol[7];
|
||||
scol = scolmain + 4 * mface->v3;
|
||||
scol[0]++; scol[1] += mcol[9]; scol[2] += mcol[10]; scol[3] += mcol[11];
|
||||
if (mface->v4) {
|
||||
scol = scolmain + 4 * mface->v4;
|
||||
scol[0]++; scol[1] += mcol[13]; scol[2] += mcol[14]; scol[3] += mcol[15];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a = me->totvert;
|
||||
scol = scolmain;
|
||||
while (a--) {
|
||||
if (scol[0] > 1) {
|
||||
scol[1] = divide_round_i(scol[1], scol[0]);
|
||||
scol[2] = divide_round_i(scol[2], scol[0]);
|
||||
scol[3] = divide_round_i(scol[3], scol[0]);
|
||||
}
|
||||
scol += 4;
|
||||
}
|
||||
|
||||
mface = me->mface;
|
||||
mcol = (char *)me->mcol;
|
||||
mftag = mfacetag;
|
||||
for (a = me->totface; a > 0; a--, mface++, mcol += 16, mftag += 4) {
|
||||
if ((use_face_sel == false) || (mface->flag & ME_FACE_SEL)) {
|
||||
if (mftag[0]) {
|
||||
scol = scolmain + 4 * mface->v1;
|
||||
mcol[1] = scol[1]; mcol[2] = scol[2]; mcol[3] = scol[3];
|
||||
}
|
||||
|
||||
if (mftag[1]) {
|
||||
scol = scolmain + 4 * mface->v2;
|
||||
mcol[5] = scol[1]; mcol[6] = scol[2]; mcol[7] = scol[3];
|
||||
}
|
||||
|
||||
if (mftag[2]) {
|
||||
scol = scolmain + 4 * mface->v3;
|
||||
mcol[9] = scol[1]; mcol[10] = scol[2]; mcol[11] = scol[3];
|
||||
}
|
||||
|
||||
if (mface->v4 && mftag[3]) {
|
||||
scol = scolmain + 4 * mface->v4;
|
||||
mcol[13] = scol[1]; mcol[14] = scol[2]; mcol[15] = scol[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(scolmain);
|
||||
}
|
||||
|
||||
static void do_shared_vertexcol(Mesh *me, bool *mlooptag, bool *mfacetag, const bool do_tessface)
|
||||
static void do_shared_vertexcol(Mesh *me, bool *mlooptag)
|
||||
{
|
||||
const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
|
||||
MPoly *mp;
|
||||
|
@ -332,10 +220,6 @@ static void do_shared_vertexcol(Mesh *me, bool *mlooptag, bool *mfacetag, const
|
|||
}
|
||||
|
||||
MEM_freeN(scol);
|
||||
|
||||
if (has_shared && do_tessface) {
|
||||
do_shared_vertex_tesscol(me, mfacetag);
|
||||
}
|
||||
}
|
||||
|
||||
static bool make_vertexcol(Object *ob) /* single ob */
|
||||
|
@ -352,17 +236,12 @@ static bool make_vertexcol(Object *ob) /* single ob */
|
|||
|
||||
/* copies from shadedisplist to mcol */
|
||||
if (!me->mloopcol && me->totloop) {
|
||||
if (!me->mcol) {
|
||||
CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
|
||||
}
|
||||
if (!me->mloopcol) {
|
||||
CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop);
|
||||
}
|
||||
BKE_mesh_update_customdata_pointers(me, true);
|
||||
}
|
||||
|
||||
update_tessface_data(ob, me);
|
||||
|
||||
DAG_id_tag_update(&me->id, 0);
|
||||
|
||||
return (me->mloopcol != NULL);
|
||||
|
@ -593,7 +472,7 @@ bool ED_vpaint_smooth(Object *ob)
|
|||
/* remove stale me->mcol, will be added later */
|
||||
BKE_mesh_tessface_clear(me);
|
||||
|
||||
do_shared_vertexcol(me, mlooptag, NULL, false);
|
||||
do_shared_vertexcol(me, mlooptag);
|
||||
|
||||
MEM_freeN(mlooptag);
|
||||
|
||||
|
@ -2753,35 +2632,13 @@ typedef struct VPaintData {
|
|||
* array, otherwise we need to refresh the modifier stack */
|
||||
bool use_fast_update;
|
||||
|
||||
/* mpoly -> mface mapping */
|
||||
MeshElemMap *polyfacemap;
|
||||
void *polyfacemap_mem;
|
||||
|
||||
/* loops tagged as having been painted, to apply shared vertex color
|
||||
* blending only to modified loops */
|
||||
bool *mlooptag;
|
||||
bool *mfacetag;
|
||||
|
||||
bool is_texbrush;
|
||||
} VPaintData;
|
||||
|
||||
static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
|
||||
{
|
||||
const int *tessface_origindex;
|
||||
|
||||
vd->polyfacemap = NULL;
|
||||
vd->polyfacemap_mem = NULL;
|
||||
|
||||
tessface_origindex = CustomData_get_layer(&me->fdata, CD_ORIGINDEX);
|
||||
|
||||
if (!tessface_origindex)
|
||||
return;
|
||||
|
||||
BKE_mesh_origindex_map_create(&vd->polyfacemap, (int **)&vd->polyfacemap_mem,
|
||||
me->totpoly,
|
||||
tessface_origindex, me->totface);
|
||||
}
|
||||
|
||||
static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const float UNUSED(mouse[2]))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
@ -2804,11 +2661,6 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
|
|||
if (me->mloopcol == NULL)
|
||||
return false;
|
||||
|
||||
/* Update tessface data if needed
|
||||
* Added here too because e.g. switching to/from edit mode would remove tessface data,
|
||||
* yet "fast_update" could still be used! */
|
||||
update_tessface_data(ob, me);
|
||||
|
||||
/* make mode data storage */
|
||||
vpd = MEM_callocN(sizeof(struct VPaintData), "VPaintData");
|
||||
paint_stroke_set_mode_data(stroke, vpd);
|
||||
|
@ -2825,7 +2677,6 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
|
|||
/* are we painting onto a modified mesh?,
|
||||
* if not we can skip face map trickyness */
|
||||
if (vertex_paint_use_fast_update_check(ob)) {
|
||||
vpaint_build_poly_facemap(vpd, me);
|
||||
vpd->use_fast_update = true;
|
||||
/* printf("Fast update!\n");*/
|
||||
}
|
||||
|
@ -2837,8 +2688,6 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
|
|||
/* to keep tracked of modified loops for shared vertex color blending */
|
||||
if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
|
||||
vpd->mlooptag = MEM_mallocN(sizeof(bool) * me->totloop, "VPaintData mlooptag");
|
||||
if (vpd->use_fast_update)
|
||||
vpd->mfacetag = MEM_mallocN(sizeof(bool) * me->totface * 4, "VPaintData mfacetag");
|
||||
}
|
||||
|
||||
/* for filtering */
|
||||
|
@ -2859,14 +2708,10 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
|
|||
ViewContext *vc = &vpd->vc;
|
||||
Brush *brush = BKE_paint_brush(&vp->paint);
|
||||
MPoly *mpoly = &me->mpoly[index];
|
||||
MFace *mf;
|
||||
MCol *mc;
|
||||
MLoop *ml;
|
||||
MLoopCol *mlc;
|
||||
unsigned int *lcol = ((unsigned int *)me->mloopcol) + mpoly->loopstart;
|
||||
unsigned int *lcolorig = ((unsigned int *)vp->vpaint_prev) + mpoly->loopstart;
|
||||
bool *mlooptag = (vpd->mlooptag) ? vpd->mlooptag + mpoly->loopstart : NULL;
|
||||
bool *mftag;
|
||||
float alpha;
|
||||
int i, j;
|
||||
int totloop = mpoly->totloop;
|
||||
|
@ -2923,35 +2768,6 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
|
|||
if (mlooptag) mlooptag[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (vpd->use_fast_update) {
|
||||
const MeshElemMap *map = &vpd->polyfacemap[index];
|
||||
|
||||
/* update vertex colors for tessellations incrementally,
|
||||
* rather then regenerating the tessellation altogether */
|
||||
for (i = 0; i < map->count; i++) {
|
||||
const int index_tessface = map->indices[i];
|
||||
|
||||
mf = &me->mface[index_tessface];
|
||||
mc = &me->mcol[index_tessface * 4];
|
||||
mftag = &vpd->mfacetag[index_tessface * 4];
|
||||
|
||||
ml = me->mloop + mpoly->loopstart;
|
||||
mlc = me->mloopcol + mpoly->loopstart;
|
||||
|
||||
for (j = 0; j < totloop; j++, ml++, mlc++) {
|
||||
/* search for the loop vertex within the tessface */
|
||||
const int fidx = BKE_MESH_TESSFACE_VINDEX_ORDER(mf, ml->v);
|
||||
if (fidx != -1) {
|
||||
MESH_MLOOPCOL_TO_MCOL(mlc, mc + fidx);
|
||||
if (mlooptag) {
|
||||
mftag[fidx] = mlooptag[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
|
||||
|
@ -3003,8 +2819,6 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
|
|||
/* clear modified tag for blur tool */
|
||||
if (vpd->mlooptag)
|
||||
memset(vpd->mlooptag, 0, sizeof(bool) * me->totloop);
|
||||
if (vpd->mfacetag)
|
||||
memset(vpd->mfacetag, 0, sizeof(bool) * me->totface * 4);
|
||||
|
||||
for (index = 0; index < totindex; index++) {
|
||||
if (indexar[index] && indexar[index] <= me->totpoly) {
|
||||
|
@ -3016,8 +2830,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
|
|||
|
||||
/* was disabled because it is slow, but necessary for blur */
|
||||
if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
|
||||
int do_tessface = vpd->use_fast_update;
|
||||
do_shared_vertexcol(me, vpd->mlooptag, vpd->mfacetag, do_tessface);
|
||||
do_shared_vertexcol(me, vpd->mlooptag);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(vc->ar);
|
||||
|
@ -3046,20 +2859,9 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
|
|||
/* frees prev buffer */
|
||||
copy_vpaint_prev(ts->vpaint, NULL, 0);
|
||||
|
||||
if (vpd->polyfacemap) {
|
||||
MEM_freeN(vpd->polyfacemap);
|
||||
}
|
||||
|
||||
if (vpd->polyfacemap_mem) {
|
||||
MEM_freeN(vpd->polyfacemap_mem);
|
||||
}
|
||||
|
||||
if (vpd->mlooptag)
|
||||
MEM_freeN(vpd->mlooptag);
|
||||
|
||||
if (vpd->mfacetag)
|
||||
MEM_freeN(vpd->mfacetag);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
|
||||
|
||||
MEM_freeN(vpd);
|
||||
|
|
|
@ -80,14 +80,14 @@ typedef struct drawEMTFMapped_userData {
|
|||
BMEditMesh *em;
|
||||
bool has_mcol;
|
||||
int cd_poly_tex_offset;
|
||||
MFace *mf;
|
||||
MTFace *tf;
|
||||
const MPoly *mpoly;
|
||||
const MTexPoly *mtexpoly;
|
||||
} drawEMTFMapped_userData;
|
||||
|
||||
typedef struct drawTFace_userData {
|
||||
Mesh *me;
|
||||
MFace *mf;
|
||||
MTFace *tf;
|
||||
const Mesh *me;
|
||||
const MPoly *mpoly;
|
||||
const MTexPoly *mtexpoly;
|
||||
} drawTFace_userData;
|
||||
|
||||
/**************************** Face Select Mode *******************************/
|
||||
|
@ -590,11 +590,12 @@ static DMDrawOption draw_tface__set_draw(MTexPoly *mtexpoly, const bool UNUSED(h
|
|||
|
||||
static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol)
|
||||
{
|
||||
const MPoly *mp = dm->getPolyArray(dm);
|
||||
const int mpoly_num = dm->getNumPolys(dm);
|
||||
MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
|
||||
MFace *mface = dm->getTessFaceArray(dm);
|
||||
MCol *finalCol;
|
||||
MLoopCol *finalCol;
|
||||
int i, j;
|
||||
MCol *mcol = NULL;
|
||||
MLoopCol *mloopcol = NULL;
|
||||
|
||||
/* cache material values to avoid a lot of lookups */
|
||||
Material *ma = NULL;
|
||||
|
@ -606,108 +607,94 @@ static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol)
|
|||
} copy_mode = COPY_CALC;
|
||||
|
||||
if (use_mcol) {
|
||||
mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
|
||||
if (!mcol)
|
||||
mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
|
||||
mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL);
|
||||
if (!mloopcol)
|
||||
mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL);
|
||||
}
|
||||
|
||||
if (CustomData_has_layer(&dm->faceData, CD_TEXTURE_MCOL)) {
|
||||
finalCol = CustomData_get_layer(&dm->faceData, CD_TEXTURE_MCOL);
|
||||
if (CustomData_has_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL)) {
|
||||
finalCol = CustomData_get_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL);
|
||||
}
|
||||
else {
|
||||
finalCol = MEM_mallocN(sizeof(MCol) * 4 * dm->getNumTessFaces(dm), "add_tface_color_layer");
|
||||
|
||||
CustomData_add_layer(&dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numTessFaceData);
|
||||
finalCol = MEM_mallocN(sizeof(MLoopCol) * dm->numLoopData, "add_tface_color_layer");
|
||||
CustomData_add_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL, CD_ASSIGN, finalCol, dm->numLoopData);
|
||||
}
|
||||
|
||||
for (i = 0; i < dm->getNumTessFaces(dm); i++) {
|
||||
const short mat_nr = mface[i].mat_nr;
|
||||
for (i = mpoly_num; i--; mp++) {
|
||||
const short mat_nr = mp->mat_nr;
|
||||
|
||||
if (UNLIKELY(mat_nr_prev != mat_nr)) {
|
||||
ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1);
|
||||
ma = give_current_material(Gtexdraw.ob, mat_nr + 1);
|
||||
copy_mode = COPY_CALC;
|
||||
mat_nr_prev = mat_nr;
|
||||
}
|
||||
|
||||
/* avoid lookups */
|
||||
if (copy_mode == COPY_ORIG) {
|
||||
memcpy(&finalCol[i * 4], &mcol[i * 4], sizeof(MCol) * 4);
|
||||
memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
|
||||
}
|
||||
else if (copy_mode == COPY_PREV) {
|
||||
memcpy(&finalCol[i * 4], &finalCol[(i - 1) * 4], sizeof(MCol) * 4);
|
||||
int loop_index = mp->loopstart;
|
||||
const MLoopCol *lcol_prev = &finalCol[(mp - 1)->loopstart];
|
||||
for (j = 0; j < mp->totloop; j++, loop_index++) {
|
||||
finalCol[loop_index] = *lcol_prev;
|
||||
}
|
||||
}
|
||||
|
||||
/* (copy_mode == COPY_CALC) */
|
||||
else if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
|
||||
if (mcol) {
|
||||
memcpy(&finalCol[i * 4], &mcol[i * 4], sizeof(MCol) * 4);
|
||||
if (mloopcol) {
|
||||
memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
|
||||
copy_mode = COPY_ORIG;
|
||||
}
|
||||
else {
|
||||
for (j = 0; j < 4; j++) {
|
||||
finalCol[i * 4 + j].b = 255;
|
||||
finalCol[i * 4 + j].g = 255;
|
||||
finalCol[i * 4 + j].r = 255;
|
||||
}
|
||||
memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
|
||||
copy_mode = COPY_PREV;
|
||||
}
|
||||
}
|
||||
else if (mtexpoly && set_draw_settings_cached(0, mtexpoly, ma, Gtexdraw)) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
finalCol[i * 4 + j].b = 255;
|
||||
finalCol[i * 4 + j].g = 0;
|
||||
finalCol[i * 4 + j].r = 255;
|
||||
int loop_index = mp->loopstart;
|
||||
for (j = 0; j < mp->totloop; j++, loop_index++) {
|
||||
finalCol[loop_index].r = 255;
|
||||
finalCol[loop_index].g = 0;
|
||||
finalCol[loop_index].b = 255;
|
||||
}
|
||||
copy_mode = COPY_PREV;
|
||||
}
|
||||
else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
finalCol[i * 4 + j].b = Gtexdraw.obcol[0];
|
||||
finalCol[i * 4 + j].g = Gtexdraw.obcol[1];
|
||||
finalCol[i * 4 + j].r = Gtexdraw.obcol[2];
|
||||
int loop_index = mp->loopstart;;
|
||||
for (j = 0; j < mp->totloop; j++, loop_index++) {
|
||||
copy_v3_v3_char(&finalCol[loop_index].r, (char *)Gtexdraw.obcol);
|
||||
}
|
||||
copy_mode = COPY_PREV;
|
||||
}
|
||||
else {
|
||||
if (mcol) {
|
||||
memcpy(&finalCol[i * 4], &mcol[i * 4], sizeof(MCol) * 4);
|
||||
if (mloopcol) {
|
||||
memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop);
|
||||
copy_mode = COPY_ORIG;
|
||||
}
|
||||
else if (mtexpoly) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
finalCol[i * 4 + j].b = 255;
|
||||
finalCol[i * 4 + j].g = 255;
|
||||
finalCol[i * 4 + j].r = 255;
|
||||
}
|
||||
memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
|
||||
copy_mode = COPY_PREV;
|
||||
}
|
||||
else {
|
||||
float col[3];
|
||||
|
||||
if (ma) {
|
||||
float col[3];
|
||||
MCol tcol;
|
||||
int loop_index = mp->loopstart;
|
||||
MLoopCol lcol;
|
||||
|
||||
if (Gtexdraw.color_profile) {
|
||||
linearrgb_to_srgb_v3_v3(col, &ma->r);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(col, &ma->r);
|
||||
}
|
||||
|
||||
tcol.b = FTOCHAR(col[0]);
|
||||
tcol.g = FTOCHAR(col[1]);
|
||||
tcol.r = FTOCHAR(col[2]);
|
||||
tcol.a = 255;
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
finalCol[i * 4 + j] = tcol;
|
||||
if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
|
||||
else copy_v3_v3(col, &ma->r);
|
||||
rgb_float_to_uchar((unsigned char *)&lcol.r, col);
|
||||
lcol.a = 255;
|
||||
|
||||
for (j = 0; j < mp->totloop; j++, loop_index++) {
|
||||
finalCol[loop_index] = lcol;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (j = 0; j < 4; j++) {
|
||||
finalCol[i * 4 + j].b = 255;
|
||||
finalCol[i * 4 + j].g = 255;
|
||||
finalCol[i * 4 + j].r = 255;
|
||||
}
|
||||
memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop);
|
||||
}
|
||||
copy_mode = COPY_PREV;
|
||||
}
|
||||
|
@ -717,7 +704,7 @@ static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol)
|
|||
|
||||
static DMDrawOption draw_tface_mapped__set_draw(void *userData, int origindex, int UNUSED(mat_nr))
|
||||
{
|
||||
Mesh *me = ((drawTFace_userData *)userData)->me;
|
||||
const Mesh *me = ((drawTFace_userData *)userData)->me;
|
||||
|
||||
/* array checked for NULL before calling */
|
||||
MPoly *mpoly = &me->mpoly[origindex];
|
||||
|
@ -915,10 +902,10 @@ static int compareDrawOptions(void *userData, int cur_index, int next_index)
|
|||
{
|
||||
drawTFace_userData *data = userData;
|
||||
|
||||
if (data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
|
||||
if (data->mpoly && data->mpoly[cur_index].mat_nr != data->mpoly[next_index].mat_nr)
|
||||
return 0;
|
||||
|
||||
if (data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
|
||||
if (data->mtexpoly && data->mtexpoly[cur_index].tpage != data->mtexpoly[next_index].tpage)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
@ -929,10 +916,10 @@ static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
|
|||
{
|
||||
drawEMTFMapped_userData *data = userData;
|
||||
|
||||
if (data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
|
||||
if (data->mpoly && data->mpoly[cur_index].mat_nr != data->mpoly[next_index].mat_nr)
|
||||
return 0;
|
||||
|
||||
if (data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
|
||||
if (data->mtexpoly && data->mtexpoly[cur_index].tpage != data->mtexpoly[next_index].tpage)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
@ -964,8 +951,8 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
|
|||
data.has_mcol = CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
|
||||
data.cd_poly_tex_offset = CustomData_get_offset(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
|
||||
|
||||
data.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
|
||||
data.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
data.mpoly = DM_get_poly_data_layer(dm, CD_MPOLY);
|
||||
data.mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
|
||||
|
||||
dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data, 0);
|
||||
}
|
||||
|
@ -976,8 +963,8 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
|
|||
else {
|
||||
drawTFace_userData userData;
|
||||
|
||||
userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
|
||||
userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
userData.mpoly = DM_get_poly_data_layer(dm, CD_MPOLY);
|
||||
userData.mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
|
||||
userData.me = me;
|
||||
dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData, uvflag);
|
||||
}
|
||||
|
@ -987,8 +974,8 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
|
|||
|
||||
update_tface_color_layer(dm, !(ob->mode & OB_MODE_TEXTURE_PAINT));
|
||||
|
||||
userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
|
||||
userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
userData.mpoly = DM_get_poly_data_layer(dm, CD_MPOLY);
|
||||
userData.mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
|
||||
userData.me = NULL;
|
||||
|
||||
dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag);
|
||||
|
|
|
@ -212,9 +212,12 @@ void GPU_interleaved_attrib_unbind(void);
|
|||
typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
|
||||
|
||||
/* build */
|
||||
GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(const int (*face_vert_indices)[4],
|
||||
const struct MFace *mface, const struct MVert *mvert,
|
||||
const int *face_indices, int totface);
|
||||
GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
|
||||
const int (*face_vert_indices)[4],
|
||||
const struct MPoly *mpoly, const struct MLoop *mloop, const struct MLoopTri *looptri,
|
||||
const struct MVert *verts,
|
||||
const int *face_indices,
|
||||
const int face_indices_len);
|
||||
|
||||
GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
|
||||
unsigned int **grid_hidden, int gridsize, const struct CCGKey *key);
|
||||
|
|
|
@ -644,11 +644,11 @@ static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type)
|
|||
|
||||
/* special handling for MCol and UV buffers */
|
||||
if (type == GPU_BUFFER_COLOR) {
|
||||
if (!(user_data = DM_get_tessface_data_layer(dm, dm->drawObject->colType)))
|
||||
if (!(user_data = DM_get_loop_data_layer(dm, dm->drawObject->colType)))
|
||||
return NULL;
|
||||
}
|
||||
else if (ELEM(type, GPU_BUFFER_UV, GPU_BUFFER_UV_TEXPAINT)) {
|
||||
if (!DM_get_tessface_data_layer(dm, CD_MTFACE))
|
||||
if (!DM_get_loop_data_layer(dm, CD_MLOOPUV))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1090,10 +1090,13 @@ struct GPU_PBVH_Buffers {
|
|||
GLenum index_type;
|
||||
|
||||
/* mesh pointers in case buffer allocation fails */
|
||||
const MFace *mface;
|
||||
const MPoly *mpoly;
|
||||
const MLoop *mloop;
|
||||
const MLoopTri *looptri;
|
||||
const MVert *mvert;
|
||||
|
||||
const int *face_indices;
|
||||
int totface;
|
||||
int face_indices_len;
|
||||
const float *vmask;
|
||||
|
||||
/* grid pointers */
|
||||
|
@ -1177,7 +1180,7 @@ void GPU_update_mesh_pbvh_buffers(
|
|||
const int (*face_vert_indices)[4], bool show_diffuse_color)
|
||||
{
|
||||
VertexBufferFormat *vert_data;
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
|
||||
buffers->vmask = vmask;
|
||||
buffers->show_diffuse_color = show_diffuse_color;
|
||||
|
@ -1190,9 +1193,10 @@ void GPU_update_mesh_pbvh_buffers(
|
|||
if (buffers->use_matcaps)
|
||||
diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
|
||||
else if (show_diffuse_color) {
|
||||
const MFace *f = buffers->mface + buffers->face_indices[0];
|
||||
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
|
||||
const MPoly *mp = &buffers->mpoly[lt->poly];
|
||||
|
||||
GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
|
||||
GPU_material_diffuse_get(mp->mat_nr + 1, diffuse_color);
|
||||
}
|
||||
|
||||
copy_v4_v4(buffers->diffuse_color, diffuse_color);
|
||||
|
@ -1225,72 +1229,61 @@ void GPU_update_mesh_pbvh_buffers(
|
|||
rgb_float_to_uchar(out->color, diffuse_color); \
|
||||
} (void)0
|
||||
|
||||
for (i = 0; i < buffers->totface; i++) {
|
||||
const MFace *f = buffers->mface + buffers->face_indices[i];
|
||||
for (i = 0; i < buffers->face_indices_len; i++) {
|
||||
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
|
||||
const unsigned int vtri[3] = {
|
||||
buffers->mloop[lt->tri[0]].v,
|
||||
buffers->mloop[lt->tri[1]].v,
|
||||
buffers->mloop[lt->tri[2]].v,
|
||||
};
|
||||
|
||||
UPDATE_VERTEX(i, f->v1, 0, diffuse_color);
|
||||
UPDATE_VERTEX(i, f->v2, 1, diffuse_color);
|
||||
UPDATE_VERTEX(i, f->v3, 2, diffuse_color);
|
||||
if (f->v4)
|
||||
UPDATE_VERTEX(i, f->v4, 3, diffuse_color);
|
||||
UPDATE_VERTEX(i, vtri[0], 0, diffuse_color);
|
||||
UPDATE_VERTEX(i, vtri[1], 1, diffuse_color);
|
||||
UPDATE_VERTEX(i, vtri[2], 2, diffuse_color);
|
||||
}
|
||||
#undef UPDATE_VERTEX
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < buffers->totface; ++i) {
|
||||
const MFace *f = &buffers->mface[buffers->face_indices[i]];
|
||||
const unsigned int *fv = &f->v1;
|
||||
const int vi[2][3] = {{0, 1, 2}, {3, 0, 2}};
|
||||
for (i = 0; i < buffers->face_indices_len; ++i) {
|
||||
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
|
||||
const unsigned int vtri[3] = {
|
||||
buffers->mloop[lt->tri[0]].v,
|
||||
buffers->mloop[lt->tri[1]].v,
|
||||
buffers->mloop[lt->tri[2]].v,
|
||||
};
|
||||
float fno[3];
|
||||
short no[3];
|
||||
|
||||
float fmask;
|
||||
|
||||
if (paint_is_face_hidden(f, mvert))
|
||||
if (paint_is_face_hidden(lt, mvert, buffers->mloop))
|
||||
continue;
|
||||
|
||||
/* Face normal and mask */
|
||||
if (f->v4) {
|
||||
normal_quad_v3(fno,
|
||||
mvert[fv[0]].co,
|
||||
mvert[fv[1]].co,
|
||||
mvert[fv[2]].co,
|
||||
mvert[fv[3]].co);
|
||||
if (vmask) {
|
||||
fmask = (vmask[fv[0]] +
|
||||
vmask[fv[1]] +
|
||||
vmask[fv[2]] +
|
||||
vmask[fv[3]]) * 0.25f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
normal_tri_v3(fno,
|
||||
mvert[fv[0]].co,
|
||||
mvert[fv[1]].co,
|
||||
mvert[fv[2]].co);
|
||||
if (vmask) {
|
||||
fmask = (vmask[fv[0]] +
|
||||
vmask[fv[1]] +
|
||||
vmask[fv[2]]) / 3.0f;
|
||||
}
|
||||
normal_tri_v3(fno,
|
||||
mvert[vtri[0]].co,
|
||||
mvert[vtri[1]].co,
|
||||
mvert[vtri[2]].co);
|
||||
if (vmask) {
|
||||
fmask = (vmask[vtri[0]] +
|
||||
vmask[vtri[1]] +
|
||||
vmask[vtri[2]]) / 3.0f;
|
||||
}
|
||||
normal_float_to_short_v3(no, fno);
|
||||
|
||||
for (j = 0; j < (f->v4 ? 2 : 1); j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
const MVert *v = &mvert[fv[vi[j][k]]];
|
||||
VertexBufferFormat *out = vert_data;
|
||||
for (j = 0; j < 3; j++) {
|
||||
const MVert *v = &mvert[vtri[j]];
|
||||
VertexBufferFormat *out = vert_data;
|
||||
|
||||
copy_v3_v3(out->co, v->co);
|
||||
memcpy(out->no, no, sizeof(short) * 3);
|
||||
copy_v3_v3(out->co, v->co);
|
||||
copy_v3_v3_short(out->no, no);
|
||||
|
||||
if (vmask)
|
||||
gpu_color_from_mask_copy(fmask, diffuse_color, out->color);
|
||||
else
|
||||
rgb_float_to_uchar(out->color, diffuse_color);
|
||||
if (vmask)
|
||||
gpu_color_from_mask_copy(fmask, diffuse_color, out->color);
|
||||
else
|
||||
rgb_float_to_uchar(out->color, diffuse_color);
|
||||
|
||||
vert_data++;
|
||||
}
|
||||
vert_data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1308,35 +1301,39 @@ void GPU_update_mesh_pbvh_buffers(
|
|||
buffers->mvert = mvert;
|
||||
}
|
||||
|
||||
GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(const int (*face_vert_indices)[4],
|
||||
const MFace *mface, const MVert *mvert,
|
||||
GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
|
||||
const int (*face_vert_indices)[4],
|
||||
const MPoly *mpoly, const MLoop *mloop, const MLoopTri *looptri,
|
||||
const MVert *mvert,
|
||||
const int *face_indices,
|
||||
int totface)
|
||||
const int face_indices_len)
|
||||
{
|
||||
GPU_PBVH_Buffers *buffers;
|
||||
unsigned short *tri_data;
|
||||
int i, j, k, tottri;
|
||||
int i, j, tottri;
|
||||
|
||||
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
|
||||
buffers->index_type = GL_UNSIGNED_SHORT;
|
||||
buffers->smooth = mface[face_indices[0]].flag & ME_SMOOTH;
|
||||
buffers->smooth = mpoly[face_indices[0]].flag & ME_SMOOTH;
|
||||
|
||||
buffers->show_diffuse_color = false;
|
||||
buffers->use_matcaps = false;
|
||||
|
||||
/* Count the number of visible triangles */
|
||||
for (i = 0, tottri = 0; i < totface; ++i) {
|
||||
const MFace *f = &mface[face_indices[i]];
|
||||
if (!paint_is_face_hidden(f, mvert))
|
||||
tottri += f->v4 ? 2 : 1;
|
||||
for (i = 0, tottri = 0; i < face_indices_len; ++i) {
|
||||
const MLoopTri *lt = &looptri[face_indices[i]];
|
||||
if (!paint_is_face_hidden(lt, mvert, mloop))
|
||||
tottri++;
|
||||
}
|
||||
|
||||
if (tottri == 0) {
|
||||
buffers->tot_tri = 0;
|
||||
|
||||
buffers->mface = mface;
|
||||
buffers->mpoly = mpoly;
|
||||
buffers->mloop = mloop;
|
||||
buffers->looptri = looptri;
|
||||
buffers->face_indices = face_indices;
|
||||
buffers->totface = 0;
|
||||
buffers->face_indices_len = 0;
|
||||
|
||||
return buffers;
|
||||
}
|
||||
|
@ -1351,26 +1348,16 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(const int (*face_vert_indices)[4],
|
|||
/* Fill the triangle buffer */
|
||||
tri_data = GPU_buffer_lock(buffers->index_buf, GPU_BINDING_INDEX);
|
||||
if (tri_data) {
|
||||
for (i = 0; i < totface; ++i) {
|
||||
const MFace *f = mface + face_indices[i];
|
||||
int v[3];
|
||||
for (i = 0; i < face_indices_len; ++i) {
|
||||
const MLoopTri *lt = &looptri[face_indices[i]];
|
||||
|
||||
/* Skip hidden faces */
|
||||
if (paint_is_face_hidden(f, mvert))
|
||||
if (paint_is_face_hidden(lt, mvert, mloop))
|
||||
continue;
|
||||
|
||||
v[0] = 0;
|
||||
v[1] = 1;
|
||||
v[2] = 2;
|
||||
|
||||
for (j = 0; j < (f->v4 ? 2 : 1); ++j) {
|
||||
for (k = 0; k < 3; ++k) {
|
||||
*tri_data = face_vert_indices[i][v[k]];
|
||||
tri_data++;
|
||||
}
|
||||
v[0] = 3;
|
||||
v[1] = 0;
|
||||
v[2] = 2;
|
||||
for (j = 0; j < 3; ++j) {
|
||||
*tri_data = face_vert_indices[i][j];
|
||||
tri_data++;
|
||||
}
|
||||
}
|
||||
GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
|
||||
|
@ -1385,9 +1372,12 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(const int (*face_vert_indices)[4],
|
|||
|
||||
buffers->tot_tri = tottri;
|
||||
|
||||
buffers->mface = mface;
|
||||
buffers->mpoly = mpoly;
|
||||
buffers->mloop = mloop;
|
||||
buffers->looptri = looptri;
|
||||
|
||||
buffers->face_indices = face_indices;
|
||||
buffers->totface = totface;
|
||||
buffers->face_indices_len = face_indices_len;
|
||||
|
||||
return buffers;
|
||||
}
|
||||
|
@ -1946,9 +1936,10 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
|
|||
/* sets material from the first face, to solve properly face would need to
|
||||
* be sorted in buckets by materials */
|
||||
if (setMaterial) {
|
||||
if (buffers->totface) {
|
||||
const MFace *f = &buffers->mface[buffers->face_indices[0]];
|
||||
if (!setMaterial(f->mat_nr + 1, NULL))
|
||||
if (buffers->face_indices_len) {
|
||||
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
|
||||
const MPoly *mp = &buffers->mpoly[lt->poly];
|
||||
if (!setMaterial(mp->mat_nr + 1, NULL))
|
||||
return;
|
||||
}
|
||||
else if (buffers->totgrid) {
|
||||
|
@ -1962,7 +1953,7 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
|
|||
}
|
||||
}
|
||||
|
||||
glShadeModel((buffers->smooth || buffers->totface) ? GL_SMOOTH : GL_FLAT);
|
||||
glShadeModel((buffers->smooth || buffers->face_indices_len) ? GL_SMOOTH : GL_FLAT);
|
||||
|
||||
if (buffers->vert_buf) {
|
||||
char *base = NULL;
|
||||
|
@ -2056,10 +2047,11 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces,
|
|||
if ((buffers->show_diffuse_color == false) || use_matcaps)
|
||||
return false;
|
||||
|
||||
if (buffers->mface) {
|
||||
const MFace *f = &buffers->mface[buffers->face_indices[0]];
|
||||
if (buffers->looptri) {
|
||||
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
|
||||
const MPoly *mp = &buffers->mpoly[lt->poly];
|
||||
|
||||
GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
|
||||
GPU_material_diffuse_get(mp->mat_nr + 1, diffuse_color);
|
||||
}
|
||||
else if (buffers->use_bmesh) {
|
||||
/* due to dynamic nature of dyntopo, only get first material */
|
||||
|
|
|
@ -99,7 +99,7 @@ typedef enum CustomDataType {
|
|||
CD_MDISPS = 19,
|
||||
CD_PREVIEW_MCOL = 20, /* for displaying weightpaint colors */
|
||||
/* CD_ID_MCOL = 21, */
|
||||
CD_TEXTURE_MCOL = 22,
|
||||
CD_TEXTURE_MLOOPCOL = 22,
|
||||
CD_CLOTH_ORCO = 23,
|
||||
CD_RECAST = 24,
|
||||
|
||||
|
|
|
@ -89,6 +89,14 @@ typedef struct MLoop {
|
|||
unsigned int e; /* edge index */
|
||||
} MLoop;
|
||||
|
||||
/* runtime only */
|
||||
#
|
||||
#
|
||||
typedef struct MLoopTri {
|
||||
unsigned int tri[3];
|
||||
unsigned int poly;
|
||||
} MLoopTri;
|
||||
|
||||
typedef struct MTexPoly {
|
||||
struct Image *tpage;
|
||||
char flag, transp;
|
||||
|
@ -345,6 +353,9 @@ enum {
|
|||
#define ME_POLY_LOOP_PREV(mloop, mp, i) (&(mloop)[(mp)->loopstart + (((i) + (mp)->totloop - 1) % (mp)->totloop)])
|
||||
#define ME_POLY_LOOP_NEXT(mloop, mp, i) (&(mloop)[(mp)->loopstart + (((i) + 1) % (mp)->totloop)])
|
||||
|
||||
/* number of tri's that make up this polygon once tessellated */
|
||||
#define ME_POLY_TRI_TOT(mp) ((mp)->totloop - 2)
|
||||
|
||||
/* mselect->type */
|
||||
enum {
|
||||
ME_VSEL = 0,
|
||||
|
|
Loading…
Reference in New Issue