Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/DerivedMesh.c
| Show First 20 Lines • Show All 358 Lines • ▼ Show 20 Lines | if (dm->needsFree) { | ||||
| CustomData_free(&dm->polyData, dm->numPolyData); | CustomData_free(&dm->polyData, dm->numPolyData); | ||||
| if (dm->mat) { | if (dm->mat) { | ||||
| MEM_freeN(dm->mat); | MEM_freeN(dm->mat); | ||||
| dm->mat = NULL; | dm->mat = NULL; | ||||
| dm->totmat = 0; | dm->totmat = 0; | ||||
| } | } | ||||
| MEM_SAFE_FREE(dm->looptris.array); | |||||
| dm->looptris.num = 0; | |||||
| dm->looptris.num_alloc = 0; | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| else { | else { | ||||
| CustomData_free_temporary(&dm->vertData, dm->numVertData); | CustomData_free_temporary(&dm->vertData, dm->numVertData); | ||||
| CustomData_free_temporary(&dm->edgeData, dm->numEdgeData); | CustomData_free_temporary(&dm->edgeData, dm->numEdgeData); | ||||
| CustomData_free_temporary(&dm->faceData, dm->numTessFaceData); | CustomData_free_temporary(&dm->faceData, dm->numTessFaceData); | ||||
| CustomData_free_temporary(&dm->loopData, dm->numLoopData); | CustomData_free_temporary(&dm->loopData, dm->numLoopData); | ||||
| CustomData_free_temporary(&dm->polyData, dm->numPolyData); | CustomData_free_temporary(&dm->polyData, dm->numPolyData); | ||||
| ▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | void DM_ensure_tessface(DerivedMesh *dm) | ||||
| } | } | ||||
| else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) { | else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) { | ||||
| BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX) || numTessFaces == 0); | BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX) || numTessFaces == 0); | ||||
| DM_update_tessface_data(dm); | DM_update_tessface_data(dm); | ||||
| } | } | ||||
| dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS; | dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS; | ||||
| /* -------------------------------------------------------------------- */ | |||||
| /* ---------------------- WATCH IT! THIS IS ONLY HERE FOR TESTING ----- */ | |||||
| /* -------------------------------------------------------------------- */ | |||||
| DM_ensure_looptri(dm); | |||||
| } | |||||
| /* 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; | |||||
| } | |||||
| } | |||||
| 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. */ | /* Update tessface CD data from loop/poly ones. Needed when not retessellating after modstack evaluation. */ | ||||
| /* NOTE: Assumes dm has valid tessellated data! */ | /* NOTE: Assumes dm has valid tessellated data! */ | ||||
| void DM_update_tessface_data(DerivedMesh *dm) | void DM_update_tessface_data(DerivedMesh *dm) | ||||
| { | { | ||||
| MFace *mf, *mface = dm->getTessFaceArray(dm); | MFace *mf, *mface = dm->getTessFaceArray(dm); | ||||
| MPoly *mp = dm->getPolyArray(dm); | MPoly *mp = dm->getPolyArray(dm); | ||||
| ▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr) | ||||
| } | } | ||||
| else { | else { | ||||
| tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE); | tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE); | ||||
| } | } | ||||
| return tf_base; | 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) | 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 */ | /* dm might depend on me, so we need to do everything with a local copy */ | ||||
| Mesh tmp = *me; | Mesh tmp = *me; | ||||
| int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; | int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; | ||||
| int did_shapekeys = 0; | int did_shapekeys = 0; | ||||
| int alloctype = CD_DUPLICATE; | int alloctype = CD_DUPLICATE; | ||||
| ▲ Show 20 Lines • Show All 2,598 Lines • ▼ Show 20 Lines | if (gattribs->layer[b].type == CD_MTFACE) { | ||||
| attribs->tface[a].array = NULL; | attribs->tface[a].array = NULL; | ||||
| attribs->tface[a].em_offset = -1; | attribs->tface[a].em_offset = -1; | ||||
| } | } | ||||
| attribs->tface[a].gl_index = gattribs->layer[b].glindex; | attribs->tface[a].gl_index = gattribs->layer[b].glindex; | ||||
| attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; | attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; | ||||
| } | } | ||||
| else { | else { | ||||
| /* exception .. */ | |||||
| CustomData *ldata = dm->getLoopDataLayout(dm); | |||||
| if (gattribs->layer[b].name[0]) | 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); | gattribs->layer[b].name); | ||||
| else | else | ||||
| layer = CustomData_get_active_layer_index(tfdata, CD_MTFACE); | layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV); | ||||
| a = attribs->tottface++; | a = attribs->tottface++; | ||||
| if (layer != -1) { | if (layer != -1) { | ||||
| attribs->tface[a].array = tfdata->layers[layer].data; | attribs->tface[a].array = ldata->layers[layer].data; | ||||
| attribs->tface[a].em_offset = tfdata->layers[layer].offset; | attribs->tface[a].em_offset = ldata->layers[layer].offset; | ||||
| } | } | ||||
| else { | else { | ||||
| attribs->tface[a].array = NULL; | attribs->tface[a].array = NULL; | ||||
| attribs->tface[a].em_offset = -1; | attribs->tface[a].em_offset = -1; | ||||
| } | } | ||||
| attribs->tface[a].gl_index = gattribs->layer[b].glindex; | attribs->tface[a].gl_index = gattribs->layer[b].glindex; | ||||
| attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; | attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; | ||||
| Show All 20 Lines | else if (gattribs->layer[b].type == CD_MCOL) { | ||||
| else { | else { | ||||
| attribs->mcol[a].array = NULL; | attribs->mcol[a].array = NULL; | ||||
| attribs->mcol[a].em_offset = -1; | attribs->mcol[a].em_offset = -1; | ||||
| } | } | ||||
| attribs->mcol[a].gl_index = gattribs->layer[b].glindex; | attribs->mcol[a].gl_index = gattribs->layer[b].glindex; | ||||
| } | } | ||||
| else { | else { | ||||
| /* exception .. */ | |||||
| CustomData *ldata = dm->getLoopDataLayout(dm); | |||||
| /* vertex colors */ | /* vertex colors */ | ||||
| if (gattribs->layer[b].name[0]) | 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); | gattribs->layer[b].name); | ||||
| else | else | ||||
| layer = CustomData_get_active_layer_index(tfdata, CD_MCOL); | layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL); | ||||
| a = attribs->totmcol++; | a = attribs->totmcol++; | ||||
| if (layer != -1) { | 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 */ | /* 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 { | else { | ||||
| attribs->mcol[a].array = NULL; | attribs->mcol[a].array = NULL; | ||||
| attribs->mcol[a].em_offset = -1; | attribs->mcol[a].em_offset = -1; | ||||
| } | } | ||||
| attribs->mcol[a].gl_index = gattribs->layer[b].glindex; | attribs->mcol[a].gl_index = gattribs->layer[b].glindex; | ||||
| } | } | ||||
| Show All 30 Lines | else if (gattribs->layer[b].type == CD_ORCO) { | ||||
| } | } | ||||
| attribs->orco.gl_index = gattribs->layer[b].glindex; | attribs->orco.gl_index = gattribs->layer[b].glindex; | ||||
| attribs->orco.gl_texco = gattribs->layer[b].gltexco; | attribs->orco.gl_texco = gattribs->layer[b].gltexco; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Set vertex shader attribute inputs for a particular tessface vert | /** | ||||
| * Set vertex shader attribute inputs for a particular tessface vert | |||||
| * | * | ||||
| * a: tessface index | * \param a: tessface index | ||||
| * index: vertex index | * \param index: vertex index | ||||
| * vert: corner index (0, 1, 2, 3) | * \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}; | const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | ||||
| int b; | int b; | ||||
| /* orco texture coordinates */ | /* orco texture coordinates */ | ||||
| if (attribs->totorco) { | if (attribs->totorco) { | ||||
| /*const*/ float (*array)[3] = attribs->orco.array; | /*const*/ float (*array)[3] = attribs->orco.array; | ||||
| const float *orco = (array) ? array[index] : zero; | const float *orco = (array) ? array[index] : zero; | ||||
| if (attribs->orco.gl_texco) | if (attribs->orco.gl_texco) | ||||
| glTexCoord3fv(orco); | glTexCoord3fv(orco); | ||||
| else | else | ||||
| glVertexAttrib3fvARB(attribs->orco.gl_index, orco); | glVertexAttrib3fvARB(attribs->orco.gl_index, orco); | ||||
| } | } | ||||
| /* uv texture coordinates */ | /* uv texture coordinates */ | ||||
| for (b = 0; b < attribs->tottface; b++) { | for (b = 0; b < attribs->tottface; b++) { | ||||
| const float *uv; | const float *uv; | ||||
| if (attribs->tface[b].array) { | if (attribs->tface[b].array) { | ||||
| MTFace *tf = &attribs->tface[b].array[a]; | MLoopUV *mloopuv = &attribs->tface[b].array[loop]; | ||||
| uv = tf->uv[vert]; | uv = mloopuv->uv; | ||||
| } | } | ||||
| else { | else { | ||||
| uv = zero; | uv = zero; | ||||
| } | } | ||||
| if (attribs->tface[b].gl_texco) | if (attribs->tface[b].gl_texco) | ||||
| glTexCoord2fv(uv); | glTexCoord2fv(uv); | ||||
| else | else | ||||
| glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv); | glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv); | ||||
| } | } | ||||
| /* vertex colors */ | /* vertex colors */ | ||||
| for (b = 0; b < attribs->totmcol; b++) { | for (b = 0; b < attribs->totmcol; b++) { | ||||
| GLubyte col[4]; | GLubyte col[4]; | ||||
| if (attribs->mcol[b].array) { | if (attribs->mcol[b].array) { | ||||
| MCol *cp = &attribs->mcol[b].array[a * 4 + vert]; | MLoopCol *cp = &attribs->mcol[b].array[loop]; | ||||
| col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; | col[0] = cp->r; col[1] = cp->g; col[2] = cp->b; col[3] = cp->a; | ||||
| } | } | ||||
| else { | else { | ||||
| col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; | col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; | ||||
| } | } | ||||
| glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col); | glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 452 Lines • Show Last 20 Lines | |||||