Beispiel #1
0
static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject* args)
{
	VectorObject *vec1, *vec2, *vec3;

	if(!PyArg_ParseTuple(args, "O!O!O!:area_tri", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3)) {
		return NULL;
	}

	if(vec1->size != vec2->size || vec1->size != vec3->size) {
		PyErr_SetString(PyExc_ValueError,
		                "vectors must be of the same size");
		return NULL;
	}

	if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1)
		return NULL;

	if (vec1->size == 3) {
		return PyFloat_FromDouble(area_tri_v3(vec1->vec, vec2->vec, vec3->vec));
	}
	else if (vec1->size == 2) {
		return PyFloat_FromDouble(area_tri_v2(vec1->vec, vec2->vec, vec3->vec));
	}
	else {
		PyErr_SetString(PyExc_ValueError,
		                "only 2D,3D vectors are supported");
		return NULL;
	}
}
Beispiel #2
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);
	}
}
static void laplacian_triangle_area(LaplacianSystem *sys, int i1, int i2, int i3)
{
	float t1, t2, t3, len1, len2, len3, area;
	float *varea = sys->varea, *v1, *v2, *v3;
	int obtuse = 0;

	v1 = sys->verts[i1];
	v2 = sys->verts[i2];
	v3 = sys->verts[i3];

	t1 = cotangent_tri_weight_v3(v1, v2, v3);
	t2 = cotangent_tri_weight_v3(v2, v3, v1);
	t3 = cotangent_tri_weight_v3(v3, v1, v2);

	if      (angle_v3v3v3(v2, v1, v3) > DEG2RADF(90.0f)) obtuse = 1;
	else if (angle_v3v3v3(v1, v2, v3) > DEG2RADF(90.0f)) obtuse = 2;
	else if (angle_v3v3v3(v1, v3, v2) > DEG2RADF(90.0f)) obtuse = 3;

	if (obtuse > 0) {
		area = area_tri_v3(v1, v2, v3);

		varea[i1] += (obtuse == 1) ? area : area * 0.5f;
		varea[i2] += (obtuse == 2) ? area : area * 0.5f;
		varea[i3] += (obtuse == 3) ? area : area * 0.5f;
	}
	else {
		len1 = len_v3v3(v2, v3);
		len2 = len_v3v3(v1, v3);
		len3 = len_v3v3(v1, v2);

		t1 *= len1 * len1;
		t2 *= len2 * len2;
		t3 *= len3 * len3;

		varea[i1] += (t2 + t3) * 0.25f;
		varea[i2] += (t1 + t3) * 0.25f;
		varea[i3] += (t1 + t2) * 0.25f;
	}
}
// With A, B and P indicating the three vertices of a given triangle, returns:
// 1 if points A and B are in the same position in the 3D space;
// 2 if the distance between point P and line segment AB is zero; and
// zero otherwise.
int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3[3])
{
	const float eps = 1.0e-6;
	const float eps_sq = eps * eps;

#if 0
	float area = area_tri_v3(v1, v2, v3);
	bool verbose = (area < 1.0e-6);
#endif

	if (equals_v3v3(v1, v2) || equals_v3v3(v2, v3) || equals_v3v3(v1, v3)) {
#if 0
		if (verbose && G.debug & G_DEBUG_FREESTYLE) {
			printf("BlenderFileLoader::testDegenerateTriangle = 1\n");
		}
#endif
		return 1;
	}
	if (dist_squared_to_line_segment_v3(v1, v2, v3) < eps_sq ||
	    dist_squared_to_line_segment_v3(v2, v1, v3) < eps_sq ||
	    dist_squared_to_line_segment_v3(v3, v1, v2) < eps_sq)
	{
#if 0
		if (verbose && G.debug & G_DEBUG_FREESTYLE) {
			printf("BlenderFileLoader::testDegenerateTriangle = 2\n");
		}
#endif
		return 2;
	}
#if 0
	if (verbose && G.debug & G_DEBUG_FREESTYLE) {
		printf("BlenderFileLoader::testDegenerateTriangle = 0\n");
	}
#endif
	return 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];
		}
	}

}
static float average_area_quad_v3(float *v1, float *v2, float *v3, float *v4)
{
	float areaq;
	areaq = area_tri_v3(v1, v2, v3) + area_tri_v3(v1, v2, v4) + area_tri_v3(v1, v3, v4);
	return areaq / 2.0f;
}
Beispiel #7
0
static void init_laplacian_matrix(LaplacianSystem *sys)
{
	float *v1, *v2;
	float w1, w2, w3;
	float areaf;
	int i;
	unsigned int idv1, idv2;

	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->numPolys; i++) {
		const MPoly *mp = &sys->mpoly[i];
		const MLoop *l_next = &sys->mloop[mp->loopstart];
		const MLoop *l_term = l_next + mp->totloop;
		const MLoop *l_prev = l_term - 2;
		const MLoop *l_curr = l_term - 1;

		for (;
		     l_next != l_term;
		     l_prev = l_curr, l_curr = l_next, l_next++)
		{
			const float *v_prev = sys->vertexCos[l_prev->v];
			const float *v_curr = sys->vertexCos[l_curr->v];
			const float *v_next = sys->vertexCos[l_next->v];
			const unsigned int l_curr_index = l_curr - sys->mloop;

			sys->numNeFa[l_curr->v] += 1;

			areaf = area_tri_v3(v_prev, v_curr, v_next);

			if (areaf < sys->min_area) {
				sys->zerola[l_curr->v] = 1;
			}

			sys->ring_areas[l_prev->v] += areaf;
			sys->ring_areas[l_curr->v] += areaf;
			sys->ring_areas[l_next->v] += areaf;

			w1 = cotangent_tri_weight_v3(v_curr, v_next, v_prev) / 2.0f;
			w2 = cotangent_tri_weight_v3(v_next, v_prev, v_curr) / 2.0f;
			w3 = cotangent_tri_weight_v3(v_prev, v_curr, v_next) / 2.0f;

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

			sys->vweights[l_curr->v] += w2 + w3;
			sys->vweights[l_next->v] += w1 + w3;
			sys->vweights[l_prev->v] += 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];
		}
	}

}