Пример #1
0
static void occ_face(const OccFace *face, float co[3], float normal[3], float *area)
{
	ObjectInstanceRen *obi;
	VlakRen *vlr;
	float v1[3], v2[3], v3[3], v4[3];

	obi = &R.objectinstance[face->obi];
	vlr = RE_findOrAddVlak(obi->obr, face->facenr);
	
	if (co) {
		if (vlr->v4)
			mid_v3_v3v3(co, vlr->v1->co, vlr->v3->co);
		else
			cent_tri_v3(co, vlr->v1->co, vlr->v2->co, vlr->v3->co);

		if (obi->flag & R_TRANSFORMED)
			mul_m4_v3(obi->mat, co);
	}
	
	if (normal) {
		normal[0] = -vlr->n[0];
		normal[1] = -vlr->n[1];
		normal[2] = -vlr->n[2];

		if (obi->flag & R_TRANSFORMED)
			mul_m3_v3(obi->nmat, normal);
	}

	if (area) {
		copy_v3_v3(v1, vlr->v1->co);
		copy_v3_v3(v2, vlr->v2->co);
		copy_v3_v3(v3, vlr->v3->co);
		if (vlr->v4) copy_v3_v3(v4, vlr->v4->co);

		if (obi->flag & R_TRANSFORMED) {
			mul_m4_v3(obi->mat, v1);
			mul_m4_v3(obi->mat, v2);
			mul_m4_v3(obi->mat, v3);
			if (vlr->v4) mul_m4_v3(obi->mat, v4);
		}

		/* todo: correct area for instances */
		if (vlr->v4)
			*area = area_quad_v3(v1, v2, v3, v4);
		else
			*area = area_tri_v3(v1, v2, v3);
	}
}
Пример #2
0
static void init_laplacian_matrix(LaplacianSystem *sys)
{
	float *v1, *v2, *v3, *v4;
	float w1, w2, w3, w4;
	float areaf;
	int i, j;
	unsigned int idv1, idv2, idv3, idv4, idv[4];
	bool has_4_vert;
	for (i = 0; i < sys->numEdges; i++) {
		idv1 = sys->medges[i].v1;
		idv2 = sys->medges[i].v2;

		v1 = sys->vertexCos[idv1];
		v2 = sys->vertexCos[idv2];

		sys->numNeEd[idv1] = sys->numNeEd[idv1] + 1;
		sys->numNeEd[idv2] = sys->numNeEd[idv2] + 1;
		w1 = len_v3v3(v1, v2);
		if (w1 < sys->min_area) {
			sys->zerola[idv1] = 1;
			sys->zerola[idv2] = 1;
		}
		else {
			w1 = 1.0f / w1;
		}

		sys->eweights[i] = w1;
	}
	for (i = 0; i < sys->numFaces; i++) {
		has_4_vert = ((&sys->mfaces[i])->v4) ? 1 : 0;

		idv1 = sys->mfaces[i].v1;
		idv2 = sys->mfaces[i].v2;
		idv3 = sys->mfaces[i].v3;
		idv4 = has_4_vert ? sys->mfaces[i].v4 : 0;

		sys->numNeFa[idv1] += 1;
		sys->numNeFa[idv2] += 1;
		sys->numNeFa[idv3] += 1;
		if (has_4_vert) sys->numNeFa[idv4] += 1;

		v1 = sys->vertexCos[idv1];
		v2 = sys->vertexCos[idv2];
		v3 = sys->vertexCos[idv3];
		v4 = has_4_vert ? sys->vertexCos[idv4] : NULL;

		if (has_4_vert) {
			areaf = area_quad_v3(v1, v2, v3, sys->vertexCos[sys->mfaces[i].v4]);
		}
		else {
			areaf = area_tri_v3(v1, v2, v3);
		}
		if (fabsf(areaf) < sys->min_area) {
			sys->zerola[idv1] = 1;
			sys->zerola[idv2] = 1;
			sys->zerola[idv3] = 1;
			if (has_4_vert) sys->zerola[idv4] = 1;
		}

		if (has_4_vert) {
			sys->ring_areas[idv1] += average_area_quad_v3(v1, v2, v3, v4);
			sys->ring_areas[idv2] += average_area_quad_v3(v2, v3, v4, v1);
			sys->ring_areas[idv3] += average_area_quad_v3(v3, v4, v1, v2);
			sys->ring_areas[idv4] += average_area_quad_v3(v4, v1, v2, v3);
		}
		else {
			sys->ring_areas[idv1] += areaf;
			sys->ring_areas[idv2] += areaf;
			sys->ring_areas[idv3] += areaf;
		}

		if (has_4_vert) {

			idv[0] = idv1;
			idv[1] = idv2;
			idv[2] = idv3;
			idv[3] = idv4;

			for (j = 0; j < 4; j++) {
				idv1 = idv[j];
				idv2 = idv[(j + 1) % 4];
				idv3 = idv[(j + 2) % 4];
				idv4 = idv[(j + 3) % 4];

				v1 = sys->vertexCos[idv1];
				v2 = sys->vertexCos[idv2];
				v3 = sys->vertexCos[idv3];
				v4 = sys->vertexCos[idv4];

				w2 = cotangent_tri_weight_v3(v4, v1, v2) + cotangent_tri_weight_v3(v3, v1, v2);
				w3 = cotangent_tri_weight_v3(v2, v3, v1) + cotangent_tri_weight_v3(v4, v1, v3);
				w4 = cotangent_tri_weight_v3(v2, v4, v1) + cotangent_tri_weight_v3(v3, v4, v1);

				sys->vweights[idv1] += (w2 + w3 + w4) / 4.0f;
			}
		}
		else {
			w1 = cotangent_tri_weight_v3(v1, v2, v3) / 2.0f;
			w2 = cotangent_tri_weight_v3(v2, v3, v1) / 2.0f;
			w3 = cotangent_tri_weight_v3(v3, v1, v2) / 2.0f;

			sys->fweights[i][0] = sys->fweights[i][0] + w1;
			sys->fweights[i][1] = sys->fweights[i][1] + w2;
			sys->fweights[i][2] = sys->fweights[i][2] + w3;

			sys->vweights[idv1] = sys->vweights[idv1] + w2 + w3;
			sys->vweights[idv2] = sys->vweights[idv2] + w1 + w3;
			sys->vweights[idv3] = sys->vweights[idv3] + w1 + w2;
		}
	}
	for (i = 0; i < sys->numEdges; i++) {
		idv1 = sys->medges[i].v1;
		idv2 = sys->medges[i].v2;
		/* if is boundary, apply scale-dependent umbrella operator only with neighboors in boundary */
		if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2]) {
			sys->vlengths[idv1] += sys->eweights[i];
			sys->vlengths[idv2] += sys->eweights[i];
		}
	}

}