/** * \returns is_valid. */ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata, CustomData *ldata, CustomData *pdata, const bool check_meshmask, const bool do_verbose, const bool do_fixes, bool *r_change) { bool is_valid = true; bool is_change_v, is_change_e, is_change_l, is_change_p; int tot_texpoly, tot_uvloop; CustomDataMask mask = check_meshmask ? CD_MASK_MESH : 0; is_valid &= mesh_validate_customdata(vdata, mask, do_verbose, do_fixes, &is_change_v); is_valid &= mesh_validate_customdata(edata, mask, do_verbose, do_fixes, &is_change_e); is_valid &= mesh_validate_customdata(ldata, mask, do_verbose, do_fixes, &is_change_l); is_valid &= mesh_validate_customdata(pdata, mask, do_verbose, do_fixes, &is_change_p); tot_texpoly = CustomData_number_of_layers(pdata, CD_MTEXPOLY); tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV); if (tot_texpoly != tot_uvloop) { PRINT_ERR("\tCustomDataLayer mismatch, tot_texpoly(%d), tot_uvloop(%d)\n", tot_texpoly, tot_uvloop); } *r_change = (is_change_v || is_change_e || is_change_l || is_change_p); return is_valid; }
int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me) { EditMesh *em; int layernum; if(me->edit_mesh) { em= me->edit_mesh; layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE); if(layernum >= MAX_MTFACE) return OPERATOR_CANCELLED; EM_add_data_layer(em, &em->fdata, CD_MTFACE); CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum); } else { layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE); if(layernum >= MAX_MTFACE) return OPERATOR_CANCELLED; if(me->mtface) CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface); else CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface); CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum); mesh_update_customdata_pointers(me); } DAG_id_flush_update(&me->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return 1; }
void RE_set_customdata_names(ObjectRen *obr, CustomData *data) { /* CustomData layer names are stored per object here, because the * DerivedMesh which stores the layers is freed */ CustomDataLayer *layer; int numtf = 0, numcol = 0, i, mtfn, mcn; if (CustomData_has_layer(data, CD_MTFACE)) { numtf= CustomData_number_of_layers(data, CD_MTFACE); obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numtf, "mtfacenames"); } if (CustomData_has_layer(data, CD_MCOL)) { numcol= CustomData_number_of_layers(data, CD_MCOL); obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numcol, "mcolnames"); } for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) { layer= &data->layers[i]; if (layer->type == CD_MTFACE) { BLI_strncpy(obr->mtface[mtfn++], layer->name, sizeof(layer->name)); obr->actmtface= CLAMPIS(layer->active_rnd, 0, numtf); obr->bakemtface= layer->active; } else if (layer->type == CD_MCOL) { BLI_strncpy(obr->mcol[mcn++], layer->name, sizeof(layer->name)); obr->actmcol= CLAMPIS(layer->active_rnd, 0, numcol); } } }
static void mesh_ensure_tessellation_customdata(Mesh *me) { if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) { /* Pass, otherwise this function clears 'mface' before * versioning 'mface -> mpoly' code kicks in [#30583] * * Callers could also check but safer to do here - campbell */ } else { const int tottex_original = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE); const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL); if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) { BKE_mesh_tessface_clear(me); CustomData_from_bmeshpoly(&me->fdata, &me->pdata, &me->ldata, me->totface); /* TODO - add some --debug-mesh option */ if (G.debug & G_DEBUG) { /* note: this warning may be un-called for if we are initializing the mesh for the * first time from bmesh, rather then giving a warning about this we could be smarter * and check if there was any data to begin with, for now just print the warning with * some info to help troubleshoot whats going on - campbell */ printf("%s: warning! Tessellation uvs or vcol data got out of sync, " "had to reset!\n CD_MTFACE: %d != CD_MTEXPOLY: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n", __func__, tottex_tessface, tottex_original, totcol_tessface, totcol_original); } } } }
/** * Currently this is only used for Python scripts * which may fail to keep matching UV/TexFace layers. * * \note This should only perform any changes in exceptional cases, * if we need this to be faster we could inline #BM_data_layer_add and only * call #update_data_blocks once at the end. */ void BM_mesh_cd_validate(BMesh *bm) { int totlayer_mtex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); int totlayer_uv = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV); if (LIKELY(totlayer_mtex == totlayer_uv)) { /* pass */ } else if (totlayer_mtex < totlayer_uv) { const int uv_index_first = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV); do { const char *from_name = bm->ldata.layers[uv_index_first + totlayer_mtex].name; BM_data_layer_add_named(bm, &bm->pdata, CD_MTEXPOLY, from_name); CustomData_set_layer_unique_name(&bm->pdata, totlayer_mtex); } while (totlayer_uv != ++totlayer_mtex); } else if (totlayer_uv < totlayer_mtex) { const int mtex_index_first = CustomData_get_layer_index(&bm->pdata, CD_MTEXPOLY); do { const char *from_name = bm->pdata.layers[mtex_index_first + totlayer_uv].name; BM_data_layer_add_named(bm, &bm->ldata, CD_MLOOPUV, from_name); CustomData_set_layer_unique_name(&bm->ldata, totlayer_uv); } while (totlayer_mtex != ++totlayer_uv); } BLI_assert(totlayer_mtex == totlayer_uv); }
/** * \returns is_valid. */ bool BKE_mesh_validate_all_customdata( CustomData *vdata, CustomData *edata, CustomData *ldata, CustomData *pdata, const bool check_meshmask, const bool do_verbose, const bool do_fixes, bool *r_change) { bool is_valid = true; bool is_change_v, is_change_e, is_change_l, is_change_p; int tot_texpoly, tot_uvloop, tot_vcolloop; CustomDataMask mask = check_meshmask ? CD_MASK_MESH : 0; is_valid &= mesh_validate_customdata(vdata, mask, do_verbose, do_fixes, &is_change_v); is_valid &= mesh_validate_customdata(edata, mask, do_verbose, do_fixes, &is_change_e); is_valid &= mesh_validate_customdata(ldata, mask, do_verbose, do_fixes, &is_change_l); is_valid &= mesh_validate_customdata(pdata, mask, do_verbose, do_fixes, &is_change_p); tot_texpoly = CustomData_number_of_layers(pdata, CD_MTEXPOLY); tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV); tot_vcolloop = CustomData_number_of_layers(ldata, CD_MLOOPCOL); if (tot_texpoly != tot_uvloop) { PRINT_ERR("\tCustomDataLayer mismatch, tot_texpoly(%d), tot_uvloop(%d)\n", tot_texpoly, tot_uvloop); } if (tot_texpoly > MAX_MTFACE) { PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", MAX_MTFACE, tot_texpoly - MAX_MTFACE); } if (tot_uvloop > MAX_MTFACE) { PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", MAX_MTFACE, tot_uvloop - MAX_MTFACE); } if (tot_vcolloop > MAX_MCOL) { PRINT_ERR("\tMore VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", MAX_MCOL, tot_vcolloop - MAX_MCOL); } /* check indices of clone/stencil */ if (do_fixes && CustomData_get_clone_layer(pdata, CD_MTEXPOLY) >= tot_texpoly) { CustomData_set_layer_clone(pdata, CD_MTEXPOLY, 0); is_change_p = true; } if (do_fixes && CustomData_get_clone_layer(ldata, CD_MLOOPUV) >= tot_uvloop) { CustomData_set_layer_clone(ldata, CD_MLOOPUV, 0); is_change_l = true; } if (do_fixes && CustomData_get_stencil_layer(pdata, CD_MTEXPOLY) >= tot_texpoly) { CustomData_set_layer_stencil(pdata, CD_MTEXPOLY, 0); is_change_p = true; } if (do_fixes && CustomData_get_stencil_layer(ldata, CD_MLOOPUV) >= tot_uvloop) { CustomData_set_layer_stencil(ldata, CD_MLOOPUV, 0); is_change_l = true; } *r_change = (is_change_v || is_change_e || is_change_l || is_change_p); return is_valid; }
static void bmo_subd_init_shape_info(BMesh *bm, SubDParams *params) { const int skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1; params->shape_info.tmpkey = skey; params->shape_info.cd_vert_shape_offset = CustomData_get_offset(&bm->vdata, CD_SHAPEKEY); params->shape_info.cd_vert_shape_offset_tmp = CustomData_get_n_offset(&bm->vdata, CD_SHAPEKEY, skey); params->shape_info.totlayer = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY); }
/** * Duplicate of BM_mesh_cd_validate() for Mesh data. */ void BKE_mesh_cd_validate(Mesh *me) { int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY); int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV); int i; /* XXX For now, do not delete those, just warn they are not really usable. */ if (UNLIKELY(totlayer_mtex > MAX_MTFACE)) { printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", MAX_MTFACE, totlayer_mtex - MAX_MTFACE); } if (UNLIKELY(totlayer_uv > MAX_MTFACE)) { printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", MAX_MTFACE, totlayer_uv - MAX_MTFACE); } if (UNLIKELY(totlayer_mcol > MAX_MCOL)) { printf("WARNING! More VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", MAX_MCOL, totlayer_mcol - MAX_MCOL); } if (LIKELY(totlayer_mtex == totlayer_uv)) { /* pass */ } else if (totlayer_mtex < totlayer_uv) { do { const char *from_name = me->ldata.layers[uv_index + totlayer_mtex].name; CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, from_name); CustomData_set_layer_unique_name(&me->pdata, totlayer_mtex); } while (totlayer_uv != ++totlayer_mtex); mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY); } else if (totlayer_uv < totlayer_mtex) { do { const char *from_name = me->pdata.layers[mtex_index + totlayer_uv].name; CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, from_name); CustomData_set_layer_unique_name(&me->ldata, totlayer_uv); } while (totlayer_mtex != ++totlayer_uv); uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV); } BLI_assert(totlayer_mtex == totlayer_uv); /* Check uv/tex names match as well!!! */ for (i = 0; i < totlayer_mtex; i++, mtex_index++, uv_index++) { const char *name_src = me->pdata.layers[mtex_index].name; const char *name_dst = me->ldata.layers[uv_index].name; if (!STREQ(name_src, name_dst)) { BKE_mesh_uv_cdlayer_rename_index(me, mtex_index, uv_index, -1, name_src, false); } } }
static PyObject *bpy_bmlayercollection_items(BPy_BMLayerCollection *self) { PyObject *ret; PyObject *item; int index; CustomData *data; BPY_BM_CHECK_OBJ(self); data = bpy_bm_customdata_get(self->bm, self->htype); index = CustomData_get_layer_index(data, self->type); ret = PyList_New(0); if (index != -1) { int tot = CustomData_number_of_layers(data, self->type); for ( ; tot-- > 0; index++) { item = BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); PyList_Append(ret, item); Py_DECREF(item); } } return ret; }
static PyObject *bpy_bmlayercollection_values(BPy_BMLayerCollection *self) { PyObject *ret; PyObject *item; int index; CustomData *data; BPY_BM_CHECK_OBJ(self); data = bpy_bm_customdata_get(self->bm, self->htype); index = CustomData_get_layer_index(data, self->type); ret = PyList_New(0); if (index != -1) { int tot = CustomData_number_of_layers(data, self->type); for ( ; tot-- > 0; index++) { item = PyTuple_New(2); PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(data->layers[index].name)); PyTuple_SET_ITEM(item, 1, BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index)); PyList_Append(ret, item); Py_DECREF(item); } } return ret; }
static PyObject *bpy_bmlayercollection_keys(BPy_BMLayerCollection *self) { PyObject *ret; PyObject *item; int index; CustomData *data; BPY_BM_CHECK_OBJ(self); data = bpy_bm_customdata_get(self->bm, self->htype); index = CustomData_get_layer_index(data, self->type); /* absolute, but no need to make relative */ ret = PyList_New(0); if (index != -1) { int tot = CustomData_number_of_layers(data, self->type); for ( ; tot-- > 0; index++) { item = PyUnicode_FromString(data->layers[index].name); PyList_Append(ret, item); Py_DECREF(item); } } return ret; }
/* This is a Mesh-based copy of the same function in DerivedMesh.c */ static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int actshape_uid) { KeyBlock *kb; int i, j, tot; if (!mesh_dst->key) { return; } tot = CustomData_number_of_layers(&mesh_src->vdata, CD_SHAPEKEY); for (i = 0; i < tot; i++) { CustomDataLayer *layer = &mesh_src->vdata.layers[CustomData_get_layer_index_n(&mesh_src->vdata, CD_SHAPEKEY, i)]; float(*cos)[3], (*kbcos)[3]; for (kb = mesh_dst->key->block.first; kb; kb = kb->next) { if (kb->uid == layer->uid) { break; } } if (!kb) { kb = BKE_keyblock_add(mesh_dst->key, layer->name); kb->uid = layer->uid; } if (kb->data) { MEM_freeN(kb->data); } cos = CustomData_get_layer_n(&mesh_src->vdata, CD_SHAPEKEY, i); kb->totelem = mesh_src->totvert; kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, 3 * sizeof(float), __func__); if (kb->uid == actshape_uid) { MVert *mvert = mesh_src->mvert; for (j = 0; j < mesh_src->totvert; j++, kbcos++, mvert++) { copy_v3_v3(*kbcos, mvert->co); } } else { for (j = 0; j < kb->totelem; j++, cos++, kbcos++) { copy_v3_v3(*kbcos, *cos); } } } for (kb = mesh_dst->key->block.first; kb; kb = kb->next) { if (kb->totelem != mesh_src->totvert) { if (kb->data) { MEM_freeN(kb->data); } kb->totelem = mesh_src->totvert; kb->data = MEM_calloc_arrayN(kb->totelem, 3 * sizeof(float), __func__); CLOG_ERROR(&LOG, "lost a shapekey layer: '%s'! (bmesh internal error)", kb->name); } } }
static PyObject *bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject *args) { const char *name = NULL; int index; CustomData *data; BPY_BM_CHECK_OBJ(self); if (!PyArg_ParseTuple(args, "|s:new", &name)) { return NULL; } data = bpy_bm_customdata_get(self->bm, self->htype); if (CustomData_layertype_is_singleton(self->type) && CustomData_has_layer(data, self->type)) { PyErr_SetString(PyExc_ValueError, "layers.new(): is a singleton, use verify() instead"); return NULL; } if (name) { BM_data_layer_add_named(self->bm, data, self->type, name); } else { BM_data_layer_add(self->bm, data, self->type); } index = CustomData_number_of_layers(data, self->type) - 1; BLI_assert(index >= 0); return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); }
static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd) { DerivedMesh *result; GenerateOceanGeometryData gogd; int num_verts; int num_polys; const bool use_threading = omd->resolution > 4; gogd.rx = omd->resolution * omd->resolution; gogd.ry = omd->resolution * omd->resolution; gogd.res_x = gogd.rx * omd->repeat_x; gogd.res_y = gogd.ry * omd->repeat_y; num_verts = (gogd.res_x + 1) * (gogd.res_y + 1); num_polys = gogd.res_x * gogd.res_y; gogd.sx = omd->size * omd->spatial_size; gogd.sy = omd->size * omd->spatial_size; gogd.ox = -gogd.sx / 2.0f; gogd.oy = -gogd.sy / 2.0f; gogd.sx /= gogd.rx; gogd.sy /= gogd.ry; result = CDDM_new(num_verts, 0, 0, num_polys * 4, num_polys); gogd.mverts = CDDM_get_verts(result); gogd.mpolys = CDDM_get_polys(result); gogd.mloops = CDDM_get_loops(result); gogd.origindex = CustomData_get_layer(&result->polyData, CD_ORIGINDEX); /* create vertices */ BLI_task_parallel_range(0, gogd.res_y + 1, &gogd, generate_ocean_geometry_vertices, use_threading); /* create faces */ BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_polygons, use_threading); CDDM_calc_edges(result); /* add uvs */ if (CustomData_number_of_layers(&result->loopData, CD_MLOOPUV) < MAX_MTFACE) { gogd.mloopuvs = CustomData_add_layer(&result->loopData, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4); CustomData_add_layer(&result->polyData, CD_MTEXPOLY, CD_CALLOC, NULL, num_polys); if (gogd.mloopuvs) { /* unlikely to fail */ gogd.ix = 1.0 / gogd.rx; gogd.iy = 1.0 / gogd.ry; BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_uvs, use_threading); } } result->dirty |= DM_DIRTY_NORMALS; return result; }
static PyObject *bpy_bmlayercollection_items(BPy_BMLayerCollection *self) { PyObject *ret; PyObject *item; int index; CustomData *data; int tot, i; BPY_BM_CHECK_OBJ(self); data = bpy_bm_customdata_get(self->bm, self->htype); index = CustomData_get_layer_index(data, self->type); tot = (index != -1) ? CustomData_number_of_layers(data, self->type) : 0; ret = PyList_New(tot); for (i = 0; tot-- > 0; index++) { item = PyTuple_New(2); PyTuple_SET_ITEMS(item, PyUnicode_FromString(data->layers[index].name), BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, i)); PyList_SET_ITEM(ret, i++, item); } return ret; }
void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only) { for (int a = 0; a < ob->totcol; a++) { Material *ma = give_current_material(ob, a + 1); COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList(); if (ma) { std::string matid(get_material_id(ma)); matid = translate_id(matid); std::ostringstream ostr; ostr << matid; COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); // create <bind_vertex_input> for each uv map Mesh *me = (Mesh *)ob->data; int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); int map_index = 0; int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) -1; for (int b = 0; b < totlayer; b++) { if (!active_uv_only || b == active_uv_index) { char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); } } iml.push_back(im); } } }
/* Create new external mesh */ static void exporter_InitGeomArrays(ExportMeshData *export_data, int num_verts, int num_edges, int num_loops, int num_polys) { DerivedMesh *dm = CDDM_new(num_verts, num_edges, 0, num_loops, num_polys); DerivedMesh *dm_left = export_data->dm_left, *dm_right = export_data->dm_right; /* Mask for custom data layers to be merged from operands. */ CustomDataMask merge_mask = CD_MASK_DERIVEDMESH & ~CD_MASK_ORIGINDEX; export_data->dm = dm; export_data->mvert = dm->getVertArray(dm); export_data->medge = dm->getEdgeArray(dm); export_data->mloop = dm->getLoopArray(dm); export_data->mpoly = dm->getPolyArray(dm); /* Allocate layers for UV layers and vertex colors. * Without this interpolation of those data will not happen. */ allocate_custom_layers(&dm->loopData, CD_MLOOPCOL, num_loops, CustomData_number_of_layers(&dm_left->loopData, CD_MLOOPCOL)); allocate_custom_layers(&dm->loopData, CD_MLOOPUV, num_loops, CustomData_number_of_layers(&dm_left->loopData, CD_MLOOPUV)); allocate_custom_layers(&dm->loopData, CD_MLOOPCOL, num_loops, CustomData_number_of_layers(&dm_right->loopData, CD_MLOOPCOL)); allocate_custom_layers(&dm->loopData, CD_MLOOPUV, num_loops, CustomData_number_of_layers(&dm_right->loopData, CD_MLOOPUV)); /* Merge custom data layers from operands. * * Will only create custom data layers for all the layers which appears in * the operand. Data for those layers will not be allocated or initialized. */ CustomData_merge(&dm_left->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys); CustomData_merge(&dm_right->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys); CustomData_merge(&dm_left->edgeData, &dm->edgeData, merge_mask, CD_DEFAULT, num_edges); CustomData_merge(&dm_right->edgeData, &dm->edgeData, merge_mask, CD_DEFAULT, num_edges); export_data->vert_origindex = dm->getVertDataArray(dm, CD_ORIGINDEX); export_data->edge_origindex = dm->getEdgeDataArray(dm, CD_ORIGINDEX); export_data->poly_origindex = dm->getPolyDataArray(dm, CD_ORIGINDEX); export_data->loop_origindex = dm->getLoopDataArray(dm, CD_ORIGINDEX); }
int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mesh *me, const char *name, int active_set) { EditMesh *em; MCol *mcol; int layernum; if(me->edit_mesh) { em= me->edit_mesh; layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL); if(layernum >= MAX_MCOL) return 0; EM_add_data_layer(em, &em->fdata, CD_MCOL, name); if(layernum) /* copy data from active vertex color layer */ copy_editface_active_customdata(em, CD_MCOL, layernum); if(active_set || layernum==0) CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum); } else { layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL); if(layernum >= MAX_MCOL) return 0; mcol= me->mcol; if(me->mcol) CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name); else CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface, name); if(active_set || layernum==0) CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum); mesh_update_customdata_pointers(me); } DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return 1; }
//creates <source> for texcoords void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) { #if 0 int totfaces = dm->getNumFaces(dm); MFace *mfaces = dm->getFaceArray(dm); #endif int totfaces = me->totface; MFace *mfaces = me->mface; int totuv = 0; int i; // count totuv for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; if (f->v4 == 0) { totuv+=3; } else { totuv+=4; } } int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); // write <source> for each layer // each <source> will get id like meshName + "map-channel-1" for (int a = 0; a < num_layers; a++) { MTFace *tface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a); COLLADASW::FloatSourceF source(mSW); std::string layer_id = makeTexcoordSourceId(geom_id, a); source.setId(layer_id); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); source.setAccessorCount(totuv); source.setAccessorStride(2); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("S"); param.push_back("T"); source.prepareToAppendValues(); for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { source.appendValues(tface[i].uv[j][0], tface[i].uv[j][1]); } } source.finish(); } }
// OB_MESH is assumed static std::string getActiveUVLayerName(Object *ob) { Mesh *me = (Mesh *)ob->data; int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); if (num_layers) return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE)); return ""; }
static Py_ssize_t bpy_bmlayercollection_length(BPy_BMLayerCollection *self) { CustomData *data; BPY_BM_CHECK_INT(self); data = bpy_bm_customdata_get(self->bm, self->htype); return CustomData_number_of_layers(data, self->type); }
int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_set) { EditMesh *em; int layernum; if(me->edit_mesh) { em= me->edit_mesh; layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE); if(layernum >= MAX_MTFACE) return 0; EM_add_data_layer(em, &em->fdata, CD_MTFACE, name); if(layernum) /* copy data from active UV */ copy_editface_active_customdata(em, CD_MTFACE, layernum); if(active_set || layernum==0) CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum); } else { layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE); if(layernum >= MAX_MTFACE) return 0; if(me->mtface) CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name); else CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name); if(active_set || layernum==0) CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum); mesh_update_customdata_pointers(me); } DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return 1; }
int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me) { EditMesh *em; MCol *mcol; int layernum; if(me->edit_mesh) { em= me->edit_mesh; layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL); if(layernum >= MAX_MCOL) return 0; EM_add_data_layer(em, &em->fdata, CD_MCOL); CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum); } else { layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL); if(layernum >= MAX_MCOL) return 0; mcol= me->mcol; if(me->mcol) CustomData_add_layer(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface); else CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface); CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum); mesh_update_customdata_pointers(me); if(!mcol) shadeMeshMCol(scene, ob, me); } DAG_id_flush_update(&me->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return 1; }
/** * Duplicate of BM_mesh_cd_validate() for Mesh data. */ void BKE_mesh_cd_validate(Mesh *me) { int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY); int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV); int i; if (LIKELY(totlayer_mtex == totlayer_uv)) { /* pass */ } else if (totlayer_mtex < totlayer_uv) { do { const char *from_name = me->ldata.layers[uv_index + totlayer_mtex].name; CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, from_name); CustomData_set_layer_unique_name(&me->pdata, totlayer_mtex); } while (totlayer_uv != ++totlayer_mtex); mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY); } else if (totlayer_uv < totlayer_mtex) { do { const char *from_name = me->pdata.layers[mtex_index + totlayer_uv].name; CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, from_name); CustomData_set_layer_unique_name(&me->ldata, totlayer_uv); } while (totlayer_mtex != ++totlayer_uv); uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV); } BLI_assert(totlayer_mtex == totlayer_uv); /* Check uv/tex names match as well!!! */ for (i = 0; i < totlayer_mtex; i++, mtex_index++, uv_index++) { const char *name_src = me->pdata.layers[mtex_index].name; const char *name_dst = me->ldata.layers[uv_index].name; if (!STREQ(name_src, name_dst)) { BKE_mesh_uv_cdlayer_rename_index(me, mtex_index, uv_index, -1, name_src, false); } } }
static bool mesh_validate_customdata( CustomData *data, CustomDataMask mask, const bool do_verbose, const bool do_fixes, bool *r_change) { bool is_valid = true; bool has_fixes = false; int i = 0; PRINT_MSG("%s: Checking %d CD layers...\n", __func__, data->totlayer); while (i < data->totlayer) { CustomDataLayer *layer = &data->layers[i]; bool ok = true; if (CustomData_layertype_is_singleton(layer->type)) { const int layer_tot = CustomData_number_of_layers(data, layer->type); if (layer_tot > 1) { PRINT_ERR("\tCustomDataLayer type %d is a singleton, found %d in Mesh structure\n", layer->type, layer_tot); ok = false; } } if (mask != 0) { CustomDataMask layer_typemask = CD_TYPE_AS_MASK(layer->type); if ((layer_typemask & mask) == 0) { PRINT_ERR("\tCustomDataLayer type %d which isn't in the mask\n", layer->type); ok = false; } } if (ok == false) { if (do_fixes) { CustomData_free_layer(data, layer->type, 0, i); has_fixes = true; } } if (ok) i++; } PRINT_MSG("%s: Finished (is_valid=%d)\n\n", __func__, (int)!has_fixes); *r_change = has_fixes; return is_valid; }
void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) { /* Find number of vertex color layers */ int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); if (totlayer_mcol == 0) return; int map_index = 0; for (int a = 0; a < totlayer_mcol; a++) { map_index++; MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, a); COLLADASW::FloatSourceF source(mSW); char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); std::string layer_id = makeVertexColorSourceId(geom_id, layer_name); source.setId(layer_id); source.setNodeName(layer_name); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); source.setAccessorCount(me->totloop); source.setAccessorStride(3); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("R"); param.push_back("G"); param.push_back("B"); source.prepareToAppendValues(); MPoly *mpoly; int i; for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) { MLoopCol *mlc = mloopcol + mpoly->loopstart; for (int j = 0; j < mpoly->totloop; j++, mlc++) { source.appendValues( mlc->r / 255.0f, mlc->g / 255.0f, mlc->b / 255.0f ); } } source.finish(); } }
//creates <source> for texcoords void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) { int totpoly = me->totpoly; int totuv = me->totloop; MPoly *mpolys = me->mpoly; int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); // write <source> for each layer // each <source> will get id like meshName + "map-channel-1" int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); for (int a = 0; a < num_layers; a++) { if (!this->export_settings->active_uv_only || a == active_uv_index) { MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); COLLADASW::FloatSourceF source(mSW); std::string layer_id = makeTexcoordSourceId(geom_id, a, this->export_settings->active_uv_only); source.setId(layer_id); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); source.setAccessorCount(totuv); source.setAccessorStride(2); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("S"); param.push_back("T"); source.prepareToAppendValues(); for (int index = 0; index < totpoly; index++) { MPoly *mpoly = mpolys+index; MLoopUV *mloop = mloops+mpoly->loopstart; for (int j = 0; j < mpoly->totloop; j++) { source.appendValues(mloop[j].uv[0], mloop[j].uv[1]); } } source.finish(); } } }
static PyObject *bpy_bmlayercollection_values(BPy_BMLayerCollection *self) { PyObject *ret; PyObject *item; int index; CustomData *data; int tot, i; BPY_BM_CHECK_OBJ(self); data = bpy_bm_customdata_get(self->bm, self->htype); index = CustomData_get_layer_index(data, self->type); tot = (index != -1) ? CustomData_number_of_layers(data, self->type) : 0; ret = PyList_New(tot); for (i = 0; tot-- > 0; index++) { item = BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, i); PyList_SET_ITEM(ret, i++, item); } return ret; }
bool ImagesExporter::hasImages(Scene *sce) { LinkNode *node; for (node = this->export_settings->export_set; node; node = node->next) { Object *ob = (Object *)node->link; int a; for (a = 0; a < ob->totcol; a++) { Material *ma = give_current_material(ob, a + 1); // no material, but check all of the slots if (!ma) continue; int b; for (b = 0; b < MAX_MTEX; b++) { MTex *mtex = ma->mtex[b]; if (mtex && mtex->tex && mtex->tex->ima) return true; } } if (ob->type == OB_MESH) { Mesh *me = (Mesh *) ob->data; BKE_mesh_tessface_ensure(me); bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE); if (has_uvs) { int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); for (int a = 0; a < num_layers; a++) { MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); Image *img = tface->tpage; if (img) return true; } } } } return false; }
static DerivedMesh *cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) { DerivedMesh *splitdm; MFace *mf = NULL, *df1 = NULL; MFace *mface = dm->getTessFaceArray(dm); MVert *dupve, *mv; EdgeHash *edgehash; EdgeHashIterator *ehi; int totvert = dm->getNumVerts(dm); int totface = dm->getNumTessFaces(dm); int *facesplit = MEM_callocN(sizeof(int) * totface, "explode_facesplit"); int *vertpa = MEM_callocN(sizeof(int) * totvert, "explode_vertpa2"); int *facepa = emd->facepa; int *fs, totesplit = 0, totfsplit = 0, curdupface = 0; int i, v1, v2, v3, v4, esplit, v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */ uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */ int numlayer; unsigned int ed_v1, ed_v2; edgehash = BLI_edgehash_new(__func__); /* recreate vertpa from facepa calculation */ for (i = 0, mf = mface; i < totface; i++, mf++) { vertpa[mf->v1] = facepa[i]; vertpa[mf->v2] = facepa[i]; vertpa[mf->v3] = facepa[i]; if (mf->v4) vertpa[mf->v4] = facepa[i]; } /* mark edges for splitting and how to split faces */ for (i = 0, mf = mface, fs = facesplit; i < totface; i++, mf++, fs++) { v1 = vertpa[mf->v1]; v2 = vertpa[mf->v2]; v3 = vertpa[mf->v3]; if (v1 != v2) { BLI_edgehash_reinsert(edgehash, mf->v1, mf->v2, NULL); (*fs) |= 1; } if (v2 != v3) { BLI_edgehash_reinsert(edgehash, mf->v2, mf->v3, NULL); (*fs) |= 2; } if (mf->v4) { v4 = vertpa[mf->v4]; if (v3 != v4) { BLI_edgehash_reinsert(edgehash, mf->v3, mf->v4, NULL); (*fs) |= 4; } if (v1 != v4) { BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL); (*fs) |= 8; } /* mark center vertex as a fake edge split */ if (*fs == 15) BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); } else { (*fs) |= 16; /* mark face as tri */ if (v1 != v3) { BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); (*fs) |= 4; } } } /* count splits & create indexes for new verts */ ehi = BLI_edgehashIterator_new(edgehash); totesplit = totvert; for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totesplit)); totesplit++; } BLI_edgehashIterator_free(ehi); /* count new faces due to splitting */ for (i = 0, fs = facesplit; i < totface; i++, fs++) totfsplit += add_faces[*fs]; splitdm = CDDM_from_template(dm, totesplit, 0, totface + totfsplit, 0, 0); numlayer = CustomData_number_of_layers(&splitdm->faceData, CD_MTFACE); /* copy new faces & verts (is it really this painful with custom data??) */ for (i = 0; i < totvert; i++) { MVert source; MVert *dest; dm->getVert(dm, i, &source); dest = CDDM_get_vert(splitdm, i); DM_copy_vert_data(dm, splitdm, i, i, 1); *dest = source; } /* override original facepa (original pointer is saved in caller function) */ /* BMESH_TODO, (totfsplit * 2) over allocation is used since the quads are * later interpreted as tri's, for this to work right I think we probably * have to stop using tessface - campbell */ facepa = MEM_callocN(sizeof(int) * (totface + (totfsplit * 2)), "explode_facepa"); //memcpy(facepa, emd->facepa, totface*sizeof(int)); emd->facepa = facepa; /* create new verts */ ehi = BLI_edgehashIterator_new(edgehash); for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); esplit = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); mv = CDDM_get_vert(splitdm, ed_v2); dupve = CDDM_get_vert(splitdm, esplit); DM_copy_vert_data(splitdm, splitdm, ed_v2, esplit, 1); *dupve = *mv; mv = CDDM_get_vert(splitdm, ed_v1); mid_v3_v3v3(dupve->co, dupve->co, mv->co); } BLI_edgehashIterator_free(ehi); /* create new faces */ curdupface = 0; //=totface; //curdupin=totesplit; for (i = 0, fs = facesplit; i < totface; i++, fs++) { mf = dm->getTessFaceData(dm, i, CD_MFACE); switch (*fs) { case 3: case 10: case 11: case 15: SET_VERTS(1, 2, 3, 4); break; case 5: case 6: case 7: SET_VERTS(2, 3, 4, 1); break; case 9: case 13: SET_VERTS(4, 1, 2, 3); break; case 12: case 14: SET_VERTS(3, 4, 1, 2); break; case 21: case 23: SET_VERTS(1, 2, 3, 4); break; case 19: SET_VERTS(2, 3, 1, 4); break; case 22: SET_VERTS(3, 1, 2, 4); break; } switch (*fs) { case 3: case 6: case 9: case 12: remap_faces_3_6_9_12(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); if (numlayer) remap_uvs_3_6_9_12(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); break; case 5: case 10: remap_faces_5_10(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); if (numlayer) remap_uvs_5_10(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); break; case 15: remap_faces_15(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); if (numlayer) remap_uvs_15(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); break; case 7: case 11: case 13: case 14: remap_faces_7_11_13_14(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); if (numlayer) remap_uvs_7_11_13_14(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); break; case 19: case 21: case 22: remap_faces_19_21_22(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); if (numlayer) remap_uvs_19_21_22(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]); break; case 23: remap_faces_23(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); if (numlayer) remap_uvs_23(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]); break; case 0: case 16: df1 = get_dface(dm, splitdm, curdupface, i, mf); facepa[curdupface] = vertpa[mf->v1]; if (df1->v4) df1->flag |= ME_FACE_SEL; else df1->flag &= ~ME_FACE_SEL; break; } curdupface += add_faces[*fs] + 1; } for (i = 0; i < curdupface; i++) { mf = CDDM_get_tessface(splitdm, i); test_index_face(mf, &splitdm->faceData, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3)); } BLI_edgehash_free(edgehash, NULL); MEM_freeN(facesplit); MEM_freeN(vertpa); CDDM_calc_edges_tessface(splitdm); CDDM_tessfaces_to_faces(splitdm); /*builds ngon faces from tess (mface) faces*/ return splitdm; }