Esempio n. 1
0
/**
 * \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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
		}
	}
}
Esempio n. 4
0
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);
			}
		}
	}
}
Esempio n. 5
0
/**
 * 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);
}
Esempio n. 6
0
/**
 * \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;
}
Esempio n. 7
0
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);

}
Esempio n. 8
0
/**
 * 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;
}
Esempio n. 12
0
/* 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);
    }
  }
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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);
}
Esempio n. 18
0
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;
}
Esempio n. 19
0
//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 &param = 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();
	}
}
Esempio n. 20
0
// 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 "";
}
Esempio n. 21
0
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);
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
/**
 * 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);
		}
	}
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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 &param = 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();
	}
}
Esempio n. 27
0
//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 &param = 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();
		}
	}
}
Esempio n. 28
0
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;
}
Esempio n. 29
0
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;
}
Esempio n. 30
0
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;
}