Exemple #1
0
/**
 * Triangulates the given (convex or concave) simple polygon to a list of triangle vertices.
 * \param vertices pairs describing vertices of the polygon, in either clockwise or counterclockwise order.
 * \return triples of triangle indices in clockwise order.
 *         Note the returned array is reused for later calls to the same method.
 */
void BLI_polyfill_calc_ex(
        const float (*coords)[2],
        const unsigned int coords_tot,
        unsigned int (*r_tris)[3],

        unsigned int *r_indices, eSign *r_coords_sign)
{
	PolyFill pf;

	/* localize */
	unsigned int *indices = r_indices;
	eSign *coords_sign = r_coords_sign;

	unsigned int i;

	/* assign all polyfill members here */
	pf.indices = r_indices;
	pf.coords = coords;
	pf.coords_tot = coords_tot;
	pf.coords_sign = r_coords_sign;
#ifdef USE_CONVEX_SKIP
	pf.coords_tot_concave = 0;
#endif
	pf.tris = r_tris;
	pf.tris_tot = 0;

	if ((coords_tot < 3) ||
	    cross_poly_v2((int)coords_tot, (float(*)[2])coords) > 0.0f)
	{
		for (i = 0; i < coords_tot; i++) {
			indices[i] = i;
		}
	}
	else {
		/* reversed */
		unsigned int n = coords_tot - 1;
		for (i = 0; i < coords_tot; i++) {
			indices[i] = (n - i);
		}
	}

	for (i = 0; i < coords_tot; i++) {
		coords_sign[i] = pf_coord_sign_calc(&pf, i);
#ifdef USE_CONVEX_SKIP
		if (coords_sign[i] != CONVEX) {
			pf.coords_tot_concave += 1;
		}
#endif
	}

	pf_triangulate(&pf);
}
Exemple #2
0
UvVertMap *BKE_mesh_uv_vert_map_create(
        struct MPoly *mpoly, struct MLoop *mloop, struct MLoopUV *mloopuv,
        unsigned int totpoly, unsigned int totvert,
        const float limit[2], const bool selected, const bool use_winding)
{
	UvVertMap *vmap;
	UvMapVert *buf;
	MPoly *mp;
	unsigned int a;
	int i, totuv, nverts;

	bool *winding = NULL;
	BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, 32);

	totuv = 0;

	/* generate UvMapVert array */
	mp = mpoly;
	for (a = 0; a < totpoly; a++, mp++)
		if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL)))
			totuv += mp->totloop;

	if (totuv == 0)
		return NULL;

	vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap");
	buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * (size_t)totuv, "UvMapVert");
	vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totvert, "UvMapVert*");
	if (use_winding) {
		winding = MEM_callocN(sizeof(*winding) * totpoly, "winding");
	}

	if (!vmap->vert || !vmap->buf) {
		BKE_mesh_uv_vert_map_free(vmap);
		return NULL;
	}

	mp = mpoly;
	for (a = 0; a < totpoly; a++, mp++) {
		if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL))) {
			float (*tf_uv)[2] = NULL;

			if (use_winding) {
				tf_uv = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, (size_t)mp->totloop);
			}

			nverts = mp->totloop;

			for (i = 0; i < nverts; i++) {
				buf->tfindex = (unsigned char)i;
				buf->f = a;
				buf->separate = 0;
				buf->next = vmap->vert[mloop[mp->loopstart + i].v];
				vmap->vert[mloop[mp->loopstart + i].v] = buf;

				if (use_winding) {
					copy_v2_v2(tf_uv[i], mloopuv[mpoly[a].loopstart + i].uv);
				}

				buf++;
			}

			if (use_winding) {
				winding[a] = cross_poly_v2((const float (*)[2])tf_uv, (unsigned int)nverts) > 0;
			}
		}
	}

	/* sort individual uvs for each vert */
	for (a = 0; a < totvert; a++) {
		UvMapVert *newvlist = NULL, *vlist = vmap->vert[a];
		UvMapVert *iterv, *v, *lastv, *next;
		float *uv, *uv2, uvdiff[2];

		while (vlist) {
			v = vlist;
			vlist = vlist->next;
			v->next = newvlist;
			newvlist = v;

			uv = mloopuv[mpoly[v->f].loopstart + v->tfindex].uv;
			lastv = NULL;
			iterv = vlist;

			while (iterv) {
				next = iterv->next;

				uv2 = mloopuv[mpoly[iterv->f].loopstart + iterv->tfindex].uv;
				sub_v2_v2v2(uvdiff, uv2, uv);


				if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] &&
				    (!use_winding || winding[iterv->f] == winding[v->f]))
				{
					if (lastv) lastv->next = next;
					else vlist = next;
					iterv->next = newvlist;
					newvlist = iterv;
				}
				else
					lastv = iterv;

				iterv = next;
			}

			newvlist->separate = 1;
		}

		vmap->vert[a] = newvlist;
	}

	if (use_winding)  {
		MEM_freeN(winding);
	}

	BLI_buffer_free(&tf_uv_buf);

	return vmap;
}
Exemple #3
0
/**
 * Triangulates the given (convex or concave) simple polygon to a list of triangle vertices.
 *
 * \param coords pairs describing vertices of the polygon, in either clockwise or counterclockwise order.
 * \return triples of triangle indices in clockwise order.
 *         Note the returned array is reused for later calls to the same method.
 */
static void polyfill_prepare(
        PolyFill *pf,
        const float (*coords)[2],
        const unsigned int coords_tot,
        int coords_sign,
        unsigned int (*r_tris)[3],
        PolyIndex *r_indices)
{
	/* localize */
	PolyIndex *indices = r_indices;

	unsigned int i;

	/* assign all polyfill members here */
	pf->indices = r_indices;
	pf->coords = coords;
	pf->coords_tot = coords_tot;
#ifdef USE_CONVEX_SKIP
	pf->coords_tot_concave = 0;
#endif
	pf->tris = r_tris;
	pf->tris_tot = 0;

	if (coords_sign == 0) {
		coords_sign = (cross_poly_v2(coords, coords_tot) >= 0.0f) ? 1 : -1;
	}
	else {
		/* chech we're passing in correcty args */
#ifndef NDEBUG
		if (coords_sign == 1) {
			BLI_assert(cross_poly_v2(coords, coords_tot) >= 0.0f);
		}
		else {
			BLI_assert(cross_poly_v2(coords, coords_tot) <= 0.0f);
		}
#endif
	}

	if (coords_sign == 1) {
		for (i = 0; i < coords_tot; i++) {
			indices[i].next = &indices[i + 1];
			indices[i].prev = &indices[i - 1];
			indices[i].index = i;
		}
	}
	else {
		/* reversed */
		unsigned int n = coords_tot - 1;
		for (i = 0; i < coords_tot; i++) {
			indices[i].next = &indices[i + 1];
			indices[i].prev = &indices[i - 1];
			indices[i].index = (n - i);
		}
	}
	indices[0].prev = &indices[coords_tot - 1];
	indices[coords_tot - 1].next = &indices[0];

	for (i = 0; i < coords_tot; i++) {
		PolyIndex *pi = &indices[i];
		pf_coord_sign_calc(pf, pi);
#ifdef USE_CONVEX_SKIP
		if (pi->sign != CONVEX) {
			pf->coords_tot_concave += 1;
		}
#endif
	}
}