예제 #1
0
/* Random metaball selection */
static int select_random_metaelems_exec(bContext *C, wmOperator *op)
{
	Object *obedit = CTX_data_edit_object(C);
	MetaBall *mb = (MetaBall *)obedit->data;
	MetaElem *ml;
	const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
	const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
	const int seed = RNA_int_get(op->ptr, "seed");
	
	RNG *rng = BLI_rng_new_srandom(seed);

	for (ml = mb->editelems->first; ml; ml = ml->next) {
		if (BLI_rng_get_float(rng) < randfac) {
			if (select)
				ml->flag |= SELECT;
			else
				ml->flag &= ~SELECT;
		}
	}

	BLI_rng_free(rng);

	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);
	
	return OPERATOR_FINISHED;
}
예제 #2
0
static int lattice_select_random_exec(bContext *C, wmOperator *op)
{
	Object *obedit = CTX_data_edit_object(C);
	Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt;

	const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
	const int seed = RNA_int_get(op->ptr, "seed");
	const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);

	RNG *rng = BLI_rng_new_srandom(seed);

	int tot;
	BPoint *bp;

	tot = lt->pntsu * lt->pntsv * lt->pntsw;
	bp = lt->def;
	while (tot--) {
		if (!bp->hide) {
			if (BLI_rng_get_float(rng) < randfac) {
				bpoint_select_set(bp, select);
			}
		}
		bp++;
	}

	if (select == false) {
		lt->actbp = LT_ACTBP_NONE;
	}

	BLI_rng_free(rng);

	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);

	return OPERATOR_FINISHED;
}
예제 #3
0
static void curve_select_random(ListBase *editnurb, float randfac, int seed, bool select)
{
	Nurb *nu;
	BezTriple *bezt;
	BPoint *bp;
	int a;

	RNG *rng = BLI_rng_new_srandom(seed);

	for (nu = editnurb->first; nu; nu = nu->next) {
		if (nu->type == CU_BEZIER) {
			bezt = nu->bezt;
			a = nu->pntsu;
			while (a--) {
				if (!bezt->hide) {
					if (BLI_rng_get_float(rng) < randfac) {
						select_beztriple(bezt, select, SELECT, VISIBLE);
					}
				}
				bezt++;
			}
		}
		else {
			bp = nu->bp;
			a = nu->pntsu * nu->pntsv;

			while (a--) {
				if (!bp->hide) {
					if (BLI_rng_get_float(rng) < randfac) {
						select_bpoint(bp, select, SELECT, VISIBLE);
					}
				}
				bp++;
			}
		}
	}

	BLI_rng_free(rng);
}
예제 #4
0
/**
 * Maps distances to weights, with an optional "smoothing" mapping.
 */
static void do_map(Object *ob, float *weights, const int nidx, const float min_d, const float max_d, short mode)
{
	const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */
	unsigned int i = nidx;
	if (max_d == min_d) {
		while (i-- > 0) {
			weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
		}
	}
	else if (max_d > min_d) {
		while (i-- > 0) {
			if     (weights[i] >= max_d) weights[i] = 1.0f;  /* most likely case first */
			else if (weights[i] <= min_d) weights[i] = 0.0f;
			else weights[i] = (weights[i] - min_d) * range_inv;
		}
	}
	else {
		while (i-- > 0) {
			if     (weights[i] <= max_d) weights[i] = 1.0f;  /* most likely case first */
			else if (weights[i] >= min_d) weights[i] = 0.0f;
			else weights[i] = (weights[i] - min_d) * range_inv;
		}
	}

	if (!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) {
		RNG *rng = NULL;

		if (mode == MOD_WVG_MAPPING_RANDOM)
			rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2));

		weightvg_do_map(nidx, weights, mode, NULL, rng);

		if (rng)
			BLI_rng_free(rng);
	}
}
예제 #5
0
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);
}
예제 #6
0
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData,
                                  ModifierApplyFlag UNUSED(flag))
{
	WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
	DerivedMesh *dm = derivedData;
	MDeformVert *dvert = NULL;
	MDeformWeight **dw = NULL;
	float *org_w; /* Array original weights. */
	float *new_w; /* Array new weights. */
	int numVerts;
	int defgrp_index;
	int i;
	/* Flags. */
	int do_add  = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0;
	int do_rem  = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0;
	/* Only do weight-preview in Object, Sculpt and Pose modes! */
#if 0
	int do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview);
#endif

	/* Get number of verts. */
	numVerts = dm->getNumVerts(dm);

	/* Check if we can just return the original mesh.
	 * Must have verts and therefore verts assigned to vgroups to do anything useful!
	 */
	if ((numVerts == 0) || (ob->defbase.first == NULL))
		return dm;

	/* Get vgroup idx from its name. */
	defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
	if (defgrp_index == -1)
		return dm;

	dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
	/* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
	if (!dvert) {
		/* If this modifier is not allowed to add vertices, just return. */
		if (!do_add)
			return dm;
		/* Else, add a valid data layer! */
		dvert = CustomData_add_layer_named(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC,
		                                   NULL, numVerts, wmd->defgrp_name);
		/* Ultimate security check. */
		if (!dvert)
			return dm;
	}

	/* Get org weights, assuming 0.0 for vertices not in given vgroup. */
	org_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, org_w");
	new_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, new_w");
	dw = MEM_mallocN(sizeof(MDeformWeight *) * numVerts, "WeightVGEdit Modifier, dw");
	for (i = 0; i < numVerts; i++) {
		dw[i] = defvert_find_index(&dvert[i], defgrp_index);
		if (dw[i]) {
			org_w[i] = new_w[i] = dw[i]->weight;
		}
		else {
			org_w[i] = new_w[i] = wmd->default_weight;
		}
	}

	/* Do mapping. */
	if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) {
		RNG *rng = NULL;

		if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM)
			rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2));

		weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng);

		if (rng)
			BLI_rng_free(rng);
	}

	/* Do masking. */
	weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, dm, wmd->mask_constant,
	                 wmd->mask_defgrp_name, wmd->modifier.scene, wmd->mask_texture,
	                 wmd->mask_tex_use_channel, wmd->mask_tex_mapping,
	                 wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);

	/* Update/add/remove from vgroup. */
	weightvg_update_vg(dvert, defgrp_index, dw, numVerts, NULL, org_w, do_add, wmd->add_threshold,
	                   do_rem, wmd->rem_threshold);

	/* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
	if (do_prev)
		DM_update_weight_mcol(ob, dm, 0, org_w, 0, NULL);
#endif

	/* Freeing stuff. */
	MEM_freeN(org_w);
	MEM_freeN(new_w);
	MEM_freeN(dw);

	/* Return the vgroup-modified mesh. */
	return dm;
}