static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
	float vi[2];
	if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line_2d",
	                      &vector_Type, &line_a1,
	                      &vector_Type, &line_a2,
	                      &vector_Type, &line_b1,
	                      &vector_Type, &line_b2))
	{
		return NULL;
	}
	
	if (BaseMath_ReadCallback(line_a1) == -1 ||
	    BaseMath_ReadCallback(line_a2) == -1 ||
	    BaseMath_ReadCallback(line_b1) == -1 ||
	    BaseMath_ReadCallback(line_b2) == -1)
	{
		return NULL;
	}

	if (isect_seg_seg_v2_point(line_a1->vec, line_a2->vec, line_b1->vec, line_b2->vec, vi) == 1) {
		return Vector_CreatePyObject(vi, 2, Py_NEW, NULL);
	}
	else {
		Py_RETURN_NONE;
	}
}
Exemple #2
0
static bool testVoronoiEdge(const float site[2], const float point[2], const VoronoiEdge *edge)
{
  float p[2];

  if (isect_seg_seg_v2_point(site, point, edge->start, edge->end, p) == 1) {
    if (len_squared_v2v2(p, edge->start) > VORONOI_EPS &&
        len_squared_v2v2(p, edge->end) > VORONOI_EPS) {
      return false;
    }
  }

  return true;
}
Exemple #3
0
static void voronoi_clampEdgeVertex(int width, int height, float *coord, float *other_coord)
{
  const float corners[4][2] = {
      {0.0f, 0.0f}, {width - 1, 0.0f}, {width - 1, height - 1}, {0.0f, height - 1}};
  int i;

  if (IN_RANGE_INCL(coord[0], 0, width - 1) && IN_RANGE_INCL(coord[1], 0, height - 1)) {
    return;
  }

  for (i = 0; i < 4; i++) {
    float v1[2], v2[2];
    float p[2];

    copy_v2_v2(v1, corners[i]);

    if (i == 3) {
      copy_v2_v2(v2, corners[0]);
    }
    else {
      copy_v2_v2(v2, corners[i + 1]);
    }

    if (isect_seg_seg_v2_point(v1, v2, coord, other_coord, p) == 1) {
      if (i == 0 && coord[1] > p[1]) {
        continue;
      }
      if (i == 1 && coord[0] < p[0]) {
        continue;
      }
      if (i == 2 && coord[1] < p[1]) {
        continue;
      }
      if (i == 3 && coord[0] > p[0]) {
        continue;
      }

      copy_v2_v2(coord, p);
    }
  }
}
Exemple #4
0
static void feather_bucket_check_intersect(
        float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
        int cur_a, int cur_b)
{
	int i;

	const float *v1 = (float *) feather_points[cur_a];
	const float *v2 = (float *) feather_points[cur_b];

	for (i = 0; i < bucket->tot_segment; i++) {
		int check_a = bucket->segments[i][0];
		int check_b = bucket->segments[i][1];

		const float *v3 = (float *) feather_points[check_a];
		const float *v4 = (float *) feather_points[check_b];

		if (check_a >= cur_a - 1 || cur_b == check_a)
			continue;

		if (isect_seg_seg_v2_simple(v1, v2, v3, v4)) {
			int k;
			float p[2];
			float min_a[2], max_a[2];
			float min_b[2], max_b[2];

			isect_seg_seg_v2_point(v1, v2, v3, v4, p);

			INIT_MINMAX2(min_a, max_a);
			INIT_MINMAX2(min_b, max_b);

			/* collapse loop with smaller AABB */
			for (k = 0; k < tot_feather_point; k++) {
				if (k >= check_b && k <= cur_a) {
					minmax_v2v2_v2(min_a, max_a, feather_points[k]);
				}
				else {
					minmax_v2v2_v2(min_b, max_b, feather_points[k]);
				}
			}

			if (max_a[0] - min_a[0] < max_b[0] - min_b[0] ||
			    max_a[1] - min_a[1] < max_b[1] - min_b[1])
			{
				for (k = check_b; k <= cur_a; k++) {
					copy_v2_v2(feather_points[k], p);
				}
			}
			else {
				for (k = 0; k <= check_a; k++) {
					copy_v2_v2(feather_points[k], p);
				}

				if (cur_b != 0) {
					for (k = cur_b; k < tot_feather_point; k++) {
						copy_v2_v2(feather_points[k], p);
					}
				}
			}
		}
	}
}
static bool scanfill_preprocess_self_isect(
        ScanFillContext *sf_ctx,
        PolyInfo *poly_info,
        const unsigned short poly_nr,
        ListBase *filledgebase)
{
	PolyInfo *pi = &poly_info[poly_nr];
	GHash *isect_hash = NULL;
	ListBase isect_lb = {NULL};

	/* warning, O(n2) check here, should use spatial lookup */
	{
		ScanFillEdge *eed;

		for (eed = pi->edge_first;
		     eed;
		     eed = (eed == pi->edge_last) ? NULL : eed->next)
		{
			ScanFillEdge *eed_other;

			for (eed_other = eed->next;
			     eed_other;
			     eed_other = (eed_other == pi->edge_last) ? NULL : eed_other->next)
			{
				if (!ELEM(eed->v1, eed_other->v1, eed_other->v2) &&
				    !ELEM(eed->v2, eed_other->v1, eed_other->v2) &&
				    (eed != eed_other))
				{
					/* check isect */
					float pt[2];
					BLI_assert(eed != eed_other);

					if (isect_seg_seg_v2_point(eed->v1->co, eed->v2->co,
					                           eed_other->v1->co, eed_other->v2->co,
					                           pt) == 1)
					{
						ScanFillIsect *isect;

						if (UNLIKELY(isect_hash == NULL)) {
							isect_hash = BLI_ghash_ptr_new(__func__);
						}

						isect = MEM_mallocN(sizeof(ScanFillIsect), __func__);

						BLI_addtail(&isect_lb, isect);

						copy_v2_v2(isect->co, pt);
						isect->co[2] = eed->v1->co[2];
						isect->v = BLI_scanfill_vert_add(sf_ctx, isect->co);
						isect->v->poly_nr = eed->v1->poly_nr;  /* NOTE: vert may belong to 2 polys now */
						VFLAG_SET(isect->v, V_ISISECT);
						edge_isect_ls_add(isect_hash, eed, isect);
						edge_isect_ls_add(isect_hash, eed_other, isect);
					}
				}
			}
		}
	}

	if (isect_hash == NULL) {
		return false;
	}

	/* now subdiv the edges */
	{
		ScanFillEdge *eed;

		for (eed = pi->edge_first;
		     eed;
		     eed = (eed == pi->edge_last) ? NULL : eed->next)
		{
			if (eed->user_flag & E_ISISECT) {
				ListBase *e_ls = BLI_ghash_lookup(isect_hash, eed);

				LinkData *isect_link;

				/* maintain coorect terminating edge */
				if (pi->edge_last == eed) {
					pi->edge_last = NULL;
				}

				if (BLI_listbase_is_single(e_ls) == false) {
					BLI_sortlist_r(e_ls, eed->v2->co, edge_isect_ls_sort_cb);
				}

				/* move original edge to filledgebase and add replacement
				 * (which gets subdivided next) */
				{
					ScanFillEdge *eed_tmp;
					eed_tmp = BLI_scanfill_edge_add(sf_ctx, eed->v1, eed->v2);
					BLI_remlink(&sf_ctx->filledgebase, eed_tmp);
					BLI_insertlinkafter(&sf_ctx->filledgebase, eed, eed_tmp);
					BLI_remlink(&sf_ctx->filledgebase, eed);
					BLI_addtail(filledgebase, eed);
					if (pi->edge_first == eed) {
						pi->edge_first = eed_tmp;
					}
					eed = eed_tmp;
				}

				for (isect_link = e_ls->first; isect_link; isect_link = isect_link->next) {
					ScanFillIsect *isect = isect_link->data;
					ScanFillEdge *eed_subd;

					eed_subd = BLI_scanfill_edge_add(sf_ctx, isect->v, eed->v2);
					eed_subd->poly_nr = poly_nr;
					eed->v2 = isect->v;

					BLI_remlink(&sf_ctx->filledgebase, eed_subd);
					BLI_insertlinkafter(&sf_ctx->filledgebase, eed, eed_subd);

					/* step to the next edge and continue dividing */
					eed = eed_subd;
				}

				BLI_freelistN(e_ls);
				MEM_freeN(e_ls);

				if (pi->edge_last == NULL) {
					pi->edge_last = eed;
				}
			}
		}
	}

	BLI_freelistN(&isect_lb);
	BLI_ghash_free(isect_hash, NULL, NULL);

	{
		ScanFillEdge *e_init;
		ScanFillEdge *e_curr;
		ScanFillEdge *e_next;

		ScanFillVert *v_prev;
		ScanFillVert *v_curr;

		int inside = false;

		/* first vert */
#if 0
		e_init = pi->edge_last;
		e_curr = e_init;
		e_next = pi->edge_first;

		v_prev = e_curr->v1;
		v_curr = e_curr->v2;
#else

		/* find outside vertex */
		{
			ScanFillEdge *eed;
			ScanFillEdge *eed_prev;
			float min_x = FLT_MAX;

			e_curr = pi->edge_last;
			e_next = pi->edge_first;

			eed_prev = pi->edge_last;
			for (eed = pi->edge_first;
			     eed;
			     eed = (eed == pi->edge_last) ? NULL : eed->next)
			{
				if (eed->v2->co[0] < min_x) {
					min_x = eed->v2->co[0];
					e_curr = eed_prev;
					e_next = eed;

				}
				eed_prev = eed;
			}

			e_init = e_curr;
			v_prev = e_curr->v1;
			v_curr = e_curr->v2;
		}
#endif

		BLI_assert(e_curr->poly_nr == poly_nr);
		BLI_assert(pi->edge_last->poly_nr == poly_nr);

		do {
			ScanFillVert *v_next;

			v_next = (e_next->v1 == v_curr) ? e_next->v2 : e_next->v1;
			BLI_assert(ELEM(v_curr, e_next->v1, e_next->v2));

			/* track intersections */
			if (inside) {
				EFLAG_SET(e_next, E_ISDELETE);
			}
			if (v_next->user_flag & V_ISISECT) {
				inside = !inside;
			}
			/* now step... */

			v_prev = v_curr;
			v_curr = v_next;
			e_curr = e_next;

			e_next = edge_step(poly_info, poly_nr, v_prev, v_curr, e_curr);

		} while (e_curr != e_init);
	}

	return true;
}