diff options
Diffstat (limited to 'source/blender/blenkernel/intern/DerivedMesh.c')
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 175 |
1 files changed, 135 insertions, 40 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 81c03d8081b..0bfa3628967 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -73,13 +73,11 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm); #include "BLI_sys_types.h" /* for intptr_t support */ #include "GPU_buffers.h" -#include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_glew.h" -#include "GPU_material.h" /* very slow! enable for testing only! */ -// #define USE_MODIFIER_VALIDATE +//#define USE_MODIFIER_VALIDATE #ifdef USE_MODIFIER_VALIDATE # define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true))) @@ -394,9 +392,9 @@ void DM_ensure_normals(DerivedMesh *dm) BLI_assert((dm->dirty & DM_DIRTY_NORMALS) == 0); } -static void DM_calc_loop_normals(DerivedMesh *dm, float split_angle) +static void DM_calc_loop_normals(DerivedMesh *dm, const bool use_split_normals, float split_angle) { - dm->calcLoopNormals(dm, split_angle); + dm->calcLoopNormals(dm, use_split_normals, split_angle); dm->dirty |= DM_DIRTY_TESS_CDLAYERS; } @@ -533,13 +531,26 @@ MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr) return tf_base; } -void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) +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 */ Mesh tmp = *me; int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; int did_shapekeys = 0; - + int alloctype = CD_DUPLICATE; + + if (take_ownership && dm->type == DM_TYPE_CDDM && dm->needsFree) { + bool has_any_referenced_layers = + CustomData_has_referenced(&dm->vertData) || + CustomData_has_referenced(&dm->edgeData) || + CustomData_has_referenced(&dm->loopData) || + CustomData_has_referenced(&dm->faceData) || + CustomData_has_referenced(&dm->polyData); + if (!has_any_referenced_layers) { + alloctype = CD_ASSIGN; + } + } + CustomData_reset(&tmp.vdata); CustomData_reset(&tmp.edata); CustomData_reset(&tmp.fdata); @@ -554,10 +565,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) totpoly = tmp.totpoly = dm->getNumPolys(dm); tmp.totface = 0; - CustomData_copy(&dm->vertData, &tmp.vdata, mask, CD_DUPLICATE, totvert); - CustomData_copy(&dm->edgeData, &tmp.edata, mask, CD_DUPLICATE, totedge); - CustomData_copy(&dm->loopData, &tmp.ldata, mask, CD_DUPLICATE, totloop); - CustomData_copy(&dm->polyData, &tmp.pdata, mask, CD_DUPLICATE, totpoly); + CustomData_copy(&dm->vertData, &tmp.vdata, mask, alloctype, totvert); + CustomData_copy(&dm->edgeData, &tmp.edata, mask, alloctype, totedge); + CustomData_copy(&dm->loopData, &tmp.ldata, mask, alloctype, totloop); + CustomData_copy(&dm->polyData, &tmp.pdata, mask, alloctype, totpoly); tmp.cd_flag = dm->cd_flag; if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) { @@ -592,13 +603,19 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) /* not all DerivedMeshes store their verts/edges/faces in CustomData, so * we set them here in case they are missing */ - if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) - CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert); - if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) - CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge); + if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) { + CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, + (alloctype == CD_ASSIGN) ? dm->getVertArray(dm) : dm->dupVertArray(dm), + totvert); + } + if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) { + CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, + (alloctype == CD_ASSIGN) ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm), + totedge); + } if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) { - tmp.mloop = dm->dupLoopArray(dm); - tmp.mpoly = dm->dupPolyArray(dm); + tmp.mloop = (alloctype == CD_ASSIGN) ? dm->getLoopArray(dm) : dm->dupLoopArray(dm); + tmp.mpoly = (alloctype == CD_ASSIGN) ? dm->getPolyArray(dm) : dm->dupPolyArray(dm); CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop); CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly); @@ -609,7 +626,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) if (CustomData_has_layer(&me->ldata, CD_MDISPS)) { if (totloop == me->totloop) { MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); - CustomData_add_layer(&tmp.ldata, CD_MDISPS, CD_DUPLICATE, mdisps, totloop); + CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop); } } @@ -643,6 +660,16 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) /* skip the listbase */ MEMCPY_STRUCT_OFS(me, &tmp, id.prev); + + if (take_ownership) { + if (alloctype == CD_ASSIGN) { + CustomData_free_typemask(&dm->vertData, dm->numVertData, ~mask); + CustomData_free_typemask(&dm->edgeData, dm->numEdgeData, ~mask); + CustomData_free_typemask(&dm->loopData, dm->numLoopData, ~mask); + CustomData_free_typemask(&dm->polyData, dm->numPolyData, ~mask); + } + dm->release(dm); + } } void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb) @@ -914,7 +941,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL; if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr - 1))) { - BKE_key_convert_to_mesh(kb, me); + BKE_keyblock_convert_to_mesh(kb, me); } if (mti->type == eModifierTypeType_OnlyDeform) { @@ -1221,14 +1248,14 @@ static void calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const d unsigned int i; /* variables for multipaint */ - const int defbase_tot = BLI_countlist(&ob->defbase); + const int defbase_tot = BLI_listbase_count(&ob->defbase); const int defbase_act = ob->actdef - 1; int defbase_sel_tot = 0; bool *defbase_sel = NULL; if (draw_flag & CALC_WP_MULTIPAINT) { - defbase_sel = BKE_objdef_selected_get(ob, defbase_tot, &defbase_sel_tot); + defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_sel_tot); } for (i = numVerts; i != 0; i--, wc++, dv++) { @@ -1451,8 +1478,10 @@ static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob)) */ static void dm_ensure_display_normals(DerivedMesh *dm) { - /* this is for final output only, up until now this layer should be missing */ - BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false); + /* Note: dm *may* have a poly CD_NORMAL layer (generated by a modifier needing poly normals e.g.). + * We do not use it here, though. And it should be tagged as temp! + */ + /* BLI_assert((CustomData_has_layer(&dm->polyData, CD_NORMAL) == false)); */ if ((dm->type == DM_TYPE_CDDM) && ((dm->dirty & DM_DIRTY_NORMALS) || CustomData_has_layer(&dm->faceData, CD_NORMAL) == false)) @@ -1486,8 +1515,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); const bool has_multires = (mmd && mmd->sculptlvl != 0); bool multires_applied = false; - const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt; - const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm); + const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams; + const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams; const int draw_flag = dm_drawflag_calc(scene->toolsettings); /* Generic preview only in object mode! */ @@ -1500,7 +1529,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* XXX Same as above... For now, only weights preview in WPaint mode. */ const bool do_mod_wmcol = do_init_wmcol; - const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH); + const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH) != 0; const float loop_normals_split_angle = me->smoothresh; VirtualModifierData virtualModifierData; @@ -1906,7 +1935,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if (do_loop_normals) { /* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */ - DM_calc_loop_normals(finaldm, loop_normals_split_angle); + DM_calc_loop_normals(finaldm, do_loop_normals, loop_normals_split_angle); } { @@ -1977,10 +2006,10 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh * if (!modifier_isEnabled(scene, md, required_mode)) return 0; if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { modifier_setError(md, "Modifier requires original data, bad stack position"); - return 0; + return false; } - return 1; + return true; } static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r, @@ -2006,7 +2035,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D const bool do_mod_wmcol = do_init_wmcol; VirtualModifierData virtualModifierData; - const bool do_loop_normals = (((Mesh *)(ob->data))->flag & ME_AUTOSMOOTH); + const bool do_loop_normals = (((Mesh *)(ob->data))->flag & ME_AUTOSMOOTH) != 0; const float loop_normals_split_angle = ((Mesh *)(ob->data))->smoothresh; modifiers_clearErrors(ob); @@ -2222,9 +2251,9 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D if (do_loop_normals) { /* Compute loop normals */ - DM_calc_loop_normals(*final_r, loop_normals_split_angle); + DM_calc_loop_normals(*final_r, do_loop_normals, loop_normals_split_angle); if (cage_r && *cage_r && (*cage_r != *final_r)) { - DM_calc_loop_normals(*cage_r, loop_normals_split_angle); + DM_calc_loop_normals(*cage_r, do_loop_normals, loop_normals_split_angle); } } @@ -2511,7 +2540,9 @@ DerivedMesh *object_get_derived_final(Object *ob, const bool for_render) return ob->derivedFinal; } - if (em) { + /* only return the editmesh if its from this object because + * we don't a mesh from another object's modifier stack: T43122 */ + if (em && (em->ob == ob)) { DerivedMesh *dm = em->derivedFinal; return dm; } @@ -2960,7 +2991,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, a = attribs->tottface++; if (layer != -1) { - attribs->tface[a].array = tfdata->layers[layer].data; + attribs->tface[a].array = NULL; attribs->tface[a].em_offset = ldata->layers[layer].offset; } else { @@ -3007,7 +3038,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, a = attribs->totmcol++; if (layer != -1) { - attribs->mcol[a].array = tfdata->layers[layer].data; + attribs->mcol[a].array = NULL; /* odd, store the offset for a different layer type here, but editmode draw code expects it */ attribs->mcol[a].em_offset = ldata->layers[layer].offset; } @@ -3078,6 +3109,69 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, } } +/* Set vertex shader attribute inputs for a particular tessface vert + * + * a: tessface index + * index: vertex index + * vert: corner index (0, 1, 2, 3) + */ +void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert) +{ + const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + int b; + + /* orco texture coordinates */ + if (attribs->totorco) { + /*const*/ float (*array)[3] = attribs->orco.array; + const float *orco = (array) ? array[index] : zero; + + if (attribs->orco.gl_texco) + glTexCoord3fv(orco); + else + glVertexAttrib3fvARB(attribs->orco.gl_index, orco); + } + + /* uv texture coordinates */ + for (b = 0; b < attribs->tottface; b++) { + const float *uv; + + if (attribs->tface[b].array) { + MTFace *tf = &attribs->tface[b].array[a]; + uv = tf->uv[vert]; + } + else { + uv = zero; + } + + if (attribs->tface[b].gl_texco) + glTexCoord2fv(uv); + else + glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv); + } + + /* vertex colors */ + for (b = 0; b < attribs->totmcol; b++) { + 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; + } + else { + col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; + } + + glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col); + } + + /* tangent for normal mapping */ + if (attribs->tottang) { + /*const*/ float (*array)[4] = attribs->tang.array; + const float *tang = (array) ? array[a * 4 + vert] : zero; + glVertexAttrib4fvARB(attribs->tang.gl_index, tang); + } +} + /* Set object's bounding box based on DerivedMesh min/max data */ void DM_set_object_boundbox(Object *ob, DerivedMesh *dm) { @@ -3141,7 +3235,8 @@ static void navmesh_drawColored(DerivedMesh *dm) #endif glDisable(GL_LIGHTING); - /* if (GPU_buffer_legacy(dm) ) */ { /* TODO - VBO draw code, not high priority - campbell */ + /* if (GPU_buffer_legacy(dm) ) */ /* TODO - VBO draw code, not high priority - campbell */ + { DEBUG_VBO("Using legacy code. drawNavMeshColored\n"); //glShadeModel(GL_SMOOTH); glBegin(glmode = GL_QUADS); @@ -3325,7 +3420,7 @@ static void dm_debug_info_layers(DynStr *dynstr, DerivedMesh *dm, CustomData *cd CustomData_file_write_info(type, &structname, &structnum); BLI_dynstr_appendf(dynstr, " dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n", - name, structname, type, (void *)pt, size, pt_size); + name, structname, type, (const void *)pt, size, pt_size); } } } @@ -3389,7 +3484,7 @@ void DM_debug_print(DerivedMesh *dm) void DM_debug_print_cdlayers(CustomData *data) { int i; - CustomDataLayer *layer; + const CustomDataLayer *layer; printf("{\n"); @@ -3401,7 +3496,7 @@ void DM_debug_print_cdlayers(CustomData *data) int structnum; CustomData_file_write_info(layer->type, &structname, &structnum); printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n", - name, structname, layer->type, (void *)layer->data, size, (int)(MEM_allocN_len(layer->data) / size)); + name, structname, layer->type, (const void *)layer->data, size, (int)(MEM_allocN_len(layer->data) / size)); } printf("}\n"); @@ -3420,7 +3515,7 @@ bool DM_is_valid(DerivedMesh *dm) dm->getEdgeDataLayout(dm), dm->getLoopDataLayout(dm), dm->getPolyDataLayout(dm), - 0, /* setting mask here isn't useful, gives false positives */ + false, /* setting mask here isn't useful, gives false positives */ do_verbose, do_fixes, &changed); is_valid &= BKE_mesh_validate_arrays( |