Esempio n. 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);
}
Esempio n. 2
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
	}
}
Esempio n. 3
0
static void pf_triangulate(PolyFill *pf)
{
	/* localize */
	PolyIndex *pi_ear;

#ifdef USE_CLIP_EVEN
	PolyIndex *pi_ear_init = pf->indices;
#endif
#ifdef USE_CLIP_SWEEP
	bool reverse = false;
#endif

	while (pf->coords_tot > 3) {
		PolyIndex *pi_prev, *pi_next;
		eSign sign_orig_prev, sign_orig_next;

		pi_ear = pf_ear_tip_find(
		        pf
#ifdef USE_CLIP_EVEN
		        , pi_ear_init
#endif
#ifdef USE_CLIP_SWEEP
		        , reverse
#endif
		        );

#ifdef USE_CLIP_SWEEP
#ifdef USE_CLIP_EVEN
		if (pi_ear != pi_ear_init) {
			reverse = !reverse;
		}
#else
		if (pi_ear != pf->indices) {
			reverse = !reverse;
		}
#endif
#endif

#ifdef USE_CONVEX_SKIP
		if (pi_ear->sign != CONVEX) {
			pf->coords_tot_concave -= 1;
		}
#endif

		pi_prev = pi_ear->prev;
		pi_next = pi_ear->next;

		pf_ear_tip_cut(pf, pi_ear);

		/* The type of the two vertices adjacent to the clipped vertex may have changed. */
		sign_orig_prev = pi_prev->sign;
		sign_orig_next = pi_next->sign;

		/* check if any verts became convex the (else if)
		 * case is highly unlikely but may happen with degenerate polygons */
		if (sign_orig_prev != CONVEX) {
			pf_coord_sign_calc(pf, pi_prev);
#ifdef USE_CONVEX_SKIP
			if (pi_prev->sign == CONVEX) {
				pf->coords_tot_concave -= 1;
#ifdef USE_KDTREE
				kdtree2d_node_remove(&pf->kdtree, pi_prev->index);
#endif
			}
#endif
		}
		if (sign_orig_next != CONVEX) {
			pf_coord_sign_calc(pf, pi_next);
#ifdef USE_CONVEX_SKIP
			if (pi_next->sign == CONVEX) {
				pf->coords_tot_concave -= 1;
#ifdef USE_KDTREE
				kdtree2d_node_remove(&pf->kdtree, pi_next->index);
#endif
			}
#endif
		}

#ifdef USE_CLIP_EVEN
#ifdef USE_CLIP_SWEEP
		pi_ear_init = reverse ? pi_next->next : pi_prev->prev;
#else
		pi_ear_init = pi_next->next;
#endif
#endif

	}

	if (pf->coords_tot == 3) {
		unsigned int *tri = pf_tri_add(pf);
		pi_ear = pf->indices;
		tri[0] = pi_ear->index; pi_ear = pi_ear->next;
		tri[1] = pi_ear->index; pi_ear = pi_ear->next;
		tri[2] = pi_ear->index;
	}
}
Esempio n. 4
0
static void pf_triangulate(PolyFill *pf)
{
	/* localize */
	eSign *coords_sign = pf->coords_sign;

	unsigned int index_ear_tip = 0;


	while (pf->coords_tot > 3) {
		unsigned int i_prev, i_next;

#ifdef USE_CONVEX_SKIP
		eSign sign_orig_prev, sign_orig_next;
#endif


#ifdef USE_CLIP_EVEN
		index_ear_tip = pf_ear_tip_find(pf, index_ear_tip);
#else
		index_ear_tip = pf_ear_tip_find(pf);
#endif

#ifdef USE_CONVEX_SKIP
		if (coords_sign[index_ear_tip] != CONVEX) {
			pf->coords_tot_concave -= 1;
		}
#endif

		pf_ear_tip_cut(pf, index_ear_tip);

		/* The type of the two vertices adjacent to the clipped vertex may have changed. */
		i_prev = pf_index_prev(pf, index_ear_tip);
		i_next = (index_ear_tip == pf->coords_tot) ? 0 : index_ear_tip;

#ifdef USE_CONVEX_SKIP
		sign_orig_prev = coords_sign[i_prev];
		sign_orig_next = coords_sign[i_next];
#endif

		coords_sign[i_prev] = pf_coord_sign_calc(pf, i_prev);
		coords_sign[i_next] = pf_coord_sign_calc(pf, i_next);

#ifdef USE_CONVEX_SKIP
		/* check if any verts became convex the (else if)
		 * case is highly unlikely but may happen with degenerate polygons */
		if               ((sign_orig_prev != CONVEX) && (coords_sign[i_prev] == CONVEX))  pf->coords_tot_concave -= 1;
		else if (UNLIKELY((sign_orig_prev == CONVEX) && (coords_sign[i_prev] != CONVEX))) pf->coords_tot_concave += 1;

		if               ((sign_orig_next != CONVEX) && (coords_sign[i_next] == CONVEX))  pf->coords_tot_concave -= 1;
		else if (UNLIKELY((sign_orig_next == CONVEX) && (coords_sign[i_next] != CONVEX))) pf->coords_tot_concave += 1;
#endif

#ifdef USE_CLIP_EVEN
		index_ear_tip = i_prev;
#endif
	}

	if (pf->coords_tot == 3) {
		unsigned int *tri = pf_tri_add(pf);
		tri[0] = pf->indices[0];
		tri[1] = pf->indices[1];
		tri[2] = pf->indices[2];
	}
}