static int PyKDTree__tp_init(PyKDTree *self, PyObject *args, PyObject *kwargs)
{
	unsigned int maxsize;
	const char *keywords[] = {"size", NULL};

	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "I:KDTree", (char **)keywords, &maxsize)) {
		return -1;
	}

	if (UINT_IS_NEG(maxsize)) {
		PyErr_SetString(PyExc_ValueError, "negative 'size' given");
		return -1;
	}

	self->obj = BLI_kdtree_new(maxsize);
	self->maxsize = maxsize;
	self->count = 0;
	self->count_balance = 0;

	return 0;
}
void KX_Terrain::RebuildTree()
{
	// Suppression de l'ancien arbre.
	if (m_tree) {
		BLI_kdtree_free(m_tree);
	}
	// Instancation d'un nouvelle arbre.
	m_tree = BLI_kdtree_new(m_cells.size());

	for (unsigned int i = 0, size = m_cells.size(); i < size; ++i) {
		KX_Cell *cell = m_cells[i];
		/* Insertion des cellules dans l'arbre en fonction de leur indice 
		 * dans la liste des cellules.
		 */
		BLI_kdtree_insert(m_tree, i, cell->GetPosition().getValue());
	}

	/* Organisation des noeuds (= position cellule) dans l'arbre pour optimiser
	 * la recherche.
	 */
	BLI_kdtree_balance(m_tree);
}
static void createFacepa(ExplodeModifierData *emd,
                         ParticleSystemModifierData *psmd,
                         DerivedMesh *dm)
{
	ParticleSystem *psys = psmd->psys;
	MFace *fa = NULL, *mface = NULL;
	MVert *mvert = NULL;
	ParticleData *pa;
	KDTree *tree;
	RNG *rng;
	float center[3], co[3];
	int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0;
	int i, p, v1, v2, v3, v4 = 0;

	mvert = dm->getVertArray(dm);
	mface = dm->getTessFaceArray(dm);
	totface = dm->getNumTessFaces(dm);
	totvert = dm->getNumVerts(dm);
	totpart = psmd->psys->totpart;

	rng = BLI_rng_new_srandom(psys->seed);

	if (emd->facepa)
		MEM_freeN(emd->facepa);

	facepa = emd->facepa = MEM_callocN(sizeof(int) * totface, "explode_facepa");

	vertpa = MEM_callocN(sizeof(int) * totvert, "explode_vertpa");

	/* initialize all faces & verts to no particle */
	for (i = 0; i < totface; i++)
		facepa[i] = totpart;

	for (i = 0; i < totvert; i++)
		vertpa[i] = totpart;

	/* set protected verts */
	if (emd->vgroup) {
		MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
		if (dvert) {
			const int defgrp_index = emd->vgroup - 1;
			for (i = 0; i < totvert; i++, dvert++) {
				float val = BLI_rng_get_float(rng);
				val = (1.0f - emd->protect) * val + emd->protect * 0.5f;
				if (val < defvert_find_weight(dvert, defgrp_index))
					vertpa[i] = -1;
			}
		}
	}

	/* make tree of emitter locations */
	tree = BLI_kdtree_new(totpart);
	for (p = 0, pa = psys->particles; p < totpart; p++, pa++) {
		psys_particle_on_emitter(psmd, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, NULL, NULL, NULL, NULL, NULL);
		BLI_kdtree_insert(tree, p, co);
	}
	BLI_kdtree_balance(tree);

	/* set face-particle-indexes to nearest particle to face center */
	for (i = 0, fa = mface; i < totface; i++, fa++) {
		add_v3_v3v3(center, mvert[fa->v1].co, mvert[fa->v2].co);
		add_v3_v3(center, mvert[fa->v3].co);
		if (fa->v4) {
			add_v3_v3(center, mvert[fa->v4].co);
			mul_v3_fl(center, 0.25);
		}
		else
			mul_v3_fl(center, 1.0f / 3.0f);

		p = BLI_kdtree_find_nearest(tree, center, NULL);

		v1 = vertpa[fa->v1];
		v2 = vertpa[fa->v2];
		v3 = vertpa[fa->v3];
		if (fa->v4)
			v4 = vertpa[fa->v4];

		if (v1 >= 0 && v2 >= 0 && v3 >= 0 && (fa->v4 == 0 || v4 >= 0))
			facepa[i] = p;

		if (v1 >= 0) vertpa[fa->v1] = p;
		if (v2 >= 0) vertpa[fa->v2] = p;
		if (v3 >= 0) vertpa[fa->v3] = p;
		if (fa->v4 && v4 >= 0) vertpa[fa->v4] = p;
	}

	if (vertpa) MEM_freeN(vertpa);
	BLI_kdtree_free(tree);

	BLI_rng_free(rng);
}