Пример #1
0
/* returns a derived mesh if dm == NULL, for deforming modifiers that need it */
DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm,
                    float (*vertexCos)[3], bool use_normals, bool use_orco)
{
	if (dm) {
		/* pass */
	}
	else if (ob->type == OB_MESH) {
		if (em) dm = CDDM_from_editbmesh(em, false, false);
		else dm = CDDM_from_mesh((struct Mesh *)(ob->data));

		if (vertexCos) {
			CDDM_apply_vert_coords(dm, vertexCos);
			dm->dirty |= DM_DIRTY_NORMALS;
		}
		
		if (use_orco) {
			DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob));
		}
	}
	else if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
		dm = CDDM_from_curve(ob);
	}

	if (use_normals) {
		if (LIKELY(dm)) {
			DM_ensure_normals(dm);
		}
	}

	return dm;
}
Пример #2
0
void modwrap_deformVertsEM(
        ModifierData *md, Object *ob,
        struct BMEditMesh *em, DerivedMesh *dm,
        float (*vertexCos)[3], int numVerts)
{
	ModifierTypeInfo *mti = modifierType_getInfo(md->type);
	BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);

	if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
		DM_ensure_normals(dm);
	}
	mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts);
}
Пример #3
0
struct DerivedMesh *modwrap_applyModifier(
        ModifierData *md, Object *ob,
        struct DerivedMesh *dm,
        ModifierApplyFlag flag)
{
	ModifierTypeInfo *mti = modifierType_getInfo(md->type);
	BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);

	if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
		DM_ensure_normals(dm);
	}
	return mti->applyModifier(md, ob, dm, flag);
}
Пример #4
0
void modwrap_deformVerts(
        ModifierData *md, Object *ob,
        DerivedMesh *dm,
        float (*vertexCos)[3], int numVerts,
        ModifierApplyFlag flag)
{
	const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
	BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);

	if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
		DM_ensure_normals(dm);
	}
	mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag);
}
Пример #5
0
/* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */
DerivedMesh *get_cddm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], bool use_normals)
{
	if (dm) {
		if (dm->type != DM_TYPE_CDDM) {
			dm = CDDM_copy(dm);
			CDDM_apply_vert_coords(dm, vertexCos);
		}

		if (use_normals) {
			DM_ensure_normals(dm);
		}
	}
	else {
		dm = get_dm(ob, em, dm, vertexCos, use_normals, false);
	}

	return dm;
}
Пример #6
0
/**
 * This function populates an array of verts for the triangles of a mesh
 * Tangent and Normals are also stored
 */
static void mesh_calc_tri_tessface(
        TriTessFace *triangles, Mesh *me, bool tangent, DerivedMesh *dm)
{
	int i;
	MVert *mvert;
	TSpace *tspace;
	float *precomputed_normals = NULL;
	bool calculate_normal;
	const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
	MLoopTri *looptri;
	/* calculate normal for each polygon only once */
	unsigned int mpoly_prev = UINT_MAX;
	float no[3];

	mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
	looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);

	if (tangent) {
		DM_ensure_normals(dm);
		DM_calc_loop_tangents(dm);

		precomputed_normals = dm->getPolyDataArray(dm, CD_NORMAL);
		calculate_normal = precomputed_normals ? false : true;

		tspace = dm->getLoopDataArray(dm, CD_TANGENT);
		BLI_assert(tspace);
	}

	BKE_mesh_recalc_looptri(
	            me->mloop, me->mpoly,
	            me->mvert,
	            me->totloop, me->totpoly,
	            looptri);

	for (i = 0; i < tottri; i++) {
		MLoopTri *lt = &looptri[i];
		MPoly *mp = &me->mpoly[lt->poly];

		triangles[i].mverts[0] = &mvert[me->mloop[lt->tri[0]].v];
		triangles[i].mverts[1] = &mvert[me->mloop[lt->tri[1]].v];
		triangles[i].mverts[2] = &mvert[me->mloop[lt->tri[2]].v];
		triangles[i].is_smooth = (mp->flag & ME_SMOOTH) != 0;

		if (tangent) {
			triangles[i].tspace[0] = &tspace[lt->tri[0]];
			triangles[i].tspace[1] = &tspace[lt->tri[1]];
			triangles[i].tspace[2] = &tspace[lt->tri[2]];

			if (calculate_normal) {
				if (lt->poly != mpoly_prev) {
					const MPoly *mp = &me->mpoly[lt->poly];
					BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, no);
					mpoly_prev = lt->poly;
				}
				copy_v3_v3(triangles[i].normal, no);
			}
			else {
				copy_v3_v3(triangles[i].normal, &precomputed_normals[lt->poly]);
			}
		}
	}

	MEM_freeN(looptri);
}
Пример #7
0
static DerivedMesh *doOcean(ModifierData *md, Object *ob,
                            DerivedMesh *derivedData,
                            int UNUSED(useRenderParams))
{
	OceanModifierData *omd = (OceanModifierData *) md;

	DerivedMesh *dm = NULL;
	OceanResult ocr;

	MVert *mverts, *mv;
	MLoop *mloops;

	int i, j;

	int num_verts;
	int num_faces;

	int cfra;

	/* use cached & inverted value for speed
	 * expanded this would read...
	 *
	 * (axis / (omd->size * omd->spatial_size)) + 0.5f) */
#define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f)

	const float size_co_inv = 1.0f / (omd->size * omd->spatial_size);

	/* can happen in when size is small, avoid bad array lookups later and quit now */
	if (!finite(size_co_inv)) {
		return derivedData;
	}

	/* update modifier */
	if (omd->refresh & MOD_OCEAN_REFRESH_ADD)
		omd->ocean = BKE_ocean_add();
	if (omd->refresh & MOD_OCEAN_REFRESH_RESET)
		init_ocean_modifier(omd);
	if (omd->refresh & MOD_OCEAN_REFRESH_CLEAR_CACHE)
		clear_cache_data(omd);

	omd->refresh = 0;

	/* do ocean simulation */
	if (omd->cached == true) {
		if (!omd->oceancache) init_cache_data(ob, omd);
		BKE_ocean_simulate_cache(omd->oceancache, md->scene->r.cfra);
	}
	else {
		simulate_ocean_modifier(omd);
	}

	if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) {
		dm = generate_ocean_geometry(omd);
		DM_ensure_normals(dm);
	}
	else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
		dm = CDDM_copy(derivedData);
	}

	cfra = md->scene->r.cfra;
	CLAMP(cfra, omd->bakestart, omd->bakeend);
	cfra -= omd->bakestart; /* shift to 0 based */

	num_verts = dm->getNumVerts(dm);
	num_faces = dm->getNumPolys(dm);

	mverts = dm->getVertArray(dm);
	mloops = dm->getLoopArray(dm);

	/* add vcols before displacement - allows lookup based on position */

	if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
		int cdlayer = CustomData_number_of_layers(&dm->loopData, CD_MLOOPCOL);

		if (cdlayer < MAX_MCOL) {
			MLoopCol *mloopcols = CustomData_add_layer_named(&dm->loopData, CD_MLOOPCOL, CD_CALLOC, NULL,
			                                                 num_faces * 4, omd->foamlayername);

			if (mloopcols) { /* unlikely to fail */
				MLoopCol *mlcol;
				MPoly *mpolys = dm->getPolyArray(dm);
				MPoly *mp;

				float foam;

				for (i = 0, mp = mpolys; i < num_faces; i++, mp++) {
					j = mp->totloop - 1;

					/* highly unlikely */
					if (j <= 0) continue;

					do {
						const float *co = mverts[mloops[mp->loopstart + j].v].co;
						const float u = OCEAN_CO(size_co_inv, co[0]);
						const float v = OCEAN_CO(size_co_inv, co[1]);

						if (omd->oceancache && omd->cached == true) {
							BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
							foam = ocr.foam;
							CLAMP(foam, 0.0f, 1.0f);
						}
						else {
							BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
							foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage);
						}

						mlcol = &mloopcols[mp->loopstart + j];
						mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255);
						/* This needs to be set (render engine uses) */
						mlcol->a = 255;
					} while (j--);
				}
			}
		}
	}


	/* displace the geometry */

	/* #pragma omp parallel for private(i, ocr) if (omd->resolution > OMP_MIN_RES) */
	for (i = 0, mv = mverts; i < num_verts; i++, mv++) {
		const float u = OCEAN_CO(size_co_inv, mv->co[0]);
		const float v = OCEAN_CO(size_co_inv, mv->co[1]);

		if (omd->oceancache && omd->cached == true)
			BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
		else
			BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);

		mv->co[2] += ocr.disp[1];

		if (omd->chop_amount > 0.0f) {
			mv->co[0] += ocr.disp[0];
			mv->co[1] += ocr.disp[2];
		}
	}

#undef OCEAN_CO

	return dm;
}
Пример #8
0
/**
 * This function populates an array of verts for the triangles of a mesh
 * Tangent and Normals are also stored
 */
static void mesh_calc_tri_tessface(
        TriTessFace *triangles, Mesh *me, bool tangent, DerivedMesh *dm)
{
	int i;
	int p_id;
	MFace *mface;
	MVert *mvert;
	TSpace *tspace;
	float *precomputed_normals = NULL;
	bool calculate_normal;

	mface = CustomData_get_layer(&me->fdata, CD_MFACE);
	mvert = CustomData_get_layer(&me->vdata, CD_MVERT);

	if (tangent) {
		DM_ensure_normals(dm);
		DM_add_tangent_layer(dm);

		precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL);
		calculate_normal = precomputed_normals ? false : true;

		//mface = dm->getTessFaceArray(dm);
		//mvert = dm->getVertArray(dm);

		tspace = dm->getTessFaceDataArray(dm, CD_TANGENT);
		BLI_assert(tspace);
	}

	p_id = -1;
	for (i = 0; i < me->totface; i++) {
		MFace *mf = &mface[i];
		TSpace *ts = tangent ? &tspace[i * 4] : NULL;

		p_id++;

		triangles[p_id].mverts[0] = &mvert[mf->v1];
		triangles[p_id].mverts[1] = &mvert[mf->v2];
		triangles[p_id].mverts[2] = &mvert[mf->v3];
		triangles[p_id].is_smooth = (mf->flag & ME_SMOOTH) != 0;

		if (tangent) {
			triangles[p_id].tspace[0] = &ts[0];
			triangles[p_id].tspace[1] = &ts[1];
			triangles[p_id].tspace[2] = &ts[2];

			if (calculate_normal) {
				if (mf->v4 != 0) {
					normal_quad_v3(triangles[p_id].normal,
					               mvert[mf->v1].co,
					               mvert[mf->v2].co,
					               mvert[mf->v3].co,
					               mvert[mf->v4].co);
				}
				else {
					normal_tri_v3(triangles[p_id].normal,
					              triangles[p_id].mverts[0]->co,
					              triangles[p_id].mverts[1]->co,
					              triangles[p_id].mverts[2]->co);
				}
			}
			else {
				copy_v3_v3(triangles[p_id].normal, &precomputed_normals[3 * i]);
			}
		}

		/* 4 vertices in the face */
		if (mf->v4 != 0) {
			p_id++;

			triangles[p_id].mverts[0] = &mvert[mf->v1];
			triangles[p_id].mverts[1] = &mvert[mf->v3];
			triangles[p_id].mverts[2] = &mvert[mf->v4];
			triangles[p_id].is_smooth = (mf->flag & ME_SMOOTH) != 0;

			if (tangent) {
				triangles[p_id].tspace[0] = &ts[0];
				triangles[p_id].tspace[1] = &ts[2];
				triangles[p_id].tspace[2] = &ts[3];

				/* same normal as the other "triangle" */
				copy_v3_v3(triangles[p_id].normal, triangles[p_id - 1].normal);
			}
		}
	}

	BLI_assert(p_id < me->totface * 2);
}