Exemplo n.º 1
0
void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
{
	/* CustomData layer names are stored per object here, because the
	 * DerivedMesh which stores the layers is freed */
	
	CustomDataLayer *layer;
	int numtf = 0, numcol = 0, i, mtfn, mcn;

	if (CustomData_has_layer(data, CD_MTFACE)) {
		numtf= CustomData_number_of_layers(data, CD_MTFACE);
		obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numtf, "mtfacenames");
	}

	if (CustomData_has_layer(data, CD_MCOL)) {
		numcol= CustomData_number_of_layers(data, CD_MCOL);
		obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numcol, "mcolnames");
	}

	for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) {
		layer= &data->layers[i];

		if (layer->type == CD_MTFACE) {
			BLI_strncpy(obr->mtface[mtfn++], layer->name, sizeof(layer->name));
			obr->actmtface= CLAMPIS(layer->active_rnd, 0, numtf);
			obr->bakemtface= layer->active;
		}
		else if (layer->type == CD_MCOL) {
			BLI_strncpy(obr->mcol[mcn++], layer->name, sizeof(layer->name));
			obr->actmcol= CLAMPIS(layer->active_rnd, 0, numcol);
		}
	}
}
Exemplo n.º 2
0
int console_char_pick(struct SpaceConsole *sc, ARegion *ar, const int mval[2])
{
	int pos_pick = 0;
	void *mouse_pick = NULL;
	int mval_clamp[2];

	mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - CONSOLE_DRAW_MARGIN);
	mval_clamp[1] = CLAMPIS(mval[1], CONSOLE_DRAW_MARGIN, ar->winy - CONSOLE_DRAW_MARGIN);

	console_textview_main__internal(sc, ar, 0, mval_clamp, &mouse_pick, &pos_pick);
	return pos_pick;
}
Exemplo n.º 3
0
void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	SetValueOperation *operation = new SetValueOperation();
	this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
	bNode *node = this->getbNode();

	/* stack order output: fac */
	float fac = 0.0f;
	const int framenumber = context->getFramenumber();

	if (framenumber < node->custom1) {
		fac = 0.0f;
	}
	else if (framenumber > node->custom2) {
		fac = 1.0f;
	}
	else if (node->custom1 < node->custom2) {
		fac = (context->getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
	}

	curvemapping_initialize((CurveMapping *)node->storage);
	fac = curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac);
	operation->setValue(CLAMPIS(fac, 0.0f, 1.0f));
	graph->addOperation(operation);
}
Exemplo n.º 4
0
/*
 * This calls the new bevel code (added since 2.64)
 */
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
  Mesh *result;
  BMesh *bm;
  BMIter iter;
  BMEdge *e;
  BMVert *v;
  float weight, weight2;
  int vgroup = -1;
  MDeformVert *dvert = NULL;
  BevelModifierData *bmd = (BevelModifierData *)md;
  const float threshold = cosf(bmd->bevel_angle + 0.000000175f);
  const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0;
  const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK);
  const int offset_type = bmd->val_flags;
  const float value = bmd->value;
  const int mat = CLAMPIS(bmd->mat, -1, ctx->object->totcol - 1);
  const bool loop_slide = (bmd->flags & MOD_BEVEL_EVEN_WIDTHS) == 0;
  const bool mark_seam = (bmd->edge_flags & MOD_BEVEL_MARK_SEAM);
  const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP);
  bool harden_normals = (bmd->flags & MOD_BEVEL_HARDEN_NORMALS);
  const int face_strength_mode = bmd->face_str_mode;
  const int miter_outer = bmd->miter_outer;
  const int miter_inner = bmd->miter_inner;
  const float spread = bmd->spread;

  bm = BKE_mesh_to_bmesh_ex(mesh,
                            &(struct BMeshCreateParams){0},
Exemplo n.º 5
0
static float do_clump_level(float result[3], const float co[3], const float par_co[3], float time,
                            float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve)
{
	float clump = 0.0f;
	
	if (clumpcurve) {
		clump = pa_clump * (1.0f - CLAMPIS(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
		
		interp_v3_v3v3(result, co, par_co, clump);
	}
	else if (clumpfac != 0.0f) {
		float cpow;

		if (clumppow < 0.0f)
			cpow = 1.0f + clumppow;
		else
			cpow = 1.0f + 9.0f * clumppow;

		if (clumpfac < 0.0f) /* clump roots instead of tips */
			clump = -clumpfac * pa_clump * (float)pow(1.0 - (double)time, (double)cpow);
		else
			clump = clumpfac * pa_clump * (float)pow((double)time, (double)cpow);

		interp_v3_v3v3(result, co, par_co, clump);
	}
	
	return clump;
}
Exemplo n.º 6
0
/* this makes sure we can extend for non-cyclic.
 *
 * returns OK: 1/0
 */
static bool where_on_path_deform(
    Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius)
{
  BevList *bl;
  float ctime1;
  int cycl = 0;

  /* test for cyclic */
  bl = ob->runtime.curve_cache->bev.first;
  if (!bl->nr) {
    return false;
  }
  if (bl->poly > -1) {
    cycl = 1;
  }

  if (cycl == 0) {
    ctime1 = CLAMPIS(ctime, 0.0f, 1.0f);
  }
  else {
    ctime1 = ctime;
  }

  /* vec needs 4 items */
  if (where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {

    if (cycl == 0) {
      Path *path = ob->runtime.curve_cache->path;
      float dvec[3];

      if (ctime < 0.0f) {
        sub_v3_v3v3(dvec, path->data[1].vec, path->data[0].vec);
        mul_v3_fl(dvec, ctime * (float)path->len);
        add_v3_v3(vec, dvec);
        if (quat) {
          copy_qt_qt(quat, path->data[0].quat);
        }
        if (radius) {
          *radius = path->data[0].radius;
        }
      }
      else if (ctime > 1.0f) {
        sub_v3_v3v3(dvec, path->data[path->len - 1].vec, path->data[path->len - 2].vec);
        mul_v3_fl(dvec, (ctime - 1.0f) * (float)path->len);
        add_v3_v3(vec, dvec);
        if (quat) {
          copy_qt_qt(quat, path->data[path->len - 1].quat);
        }
        if (radius) {
          *radius = path->data[path->len - 1].radius;
        }
        /* weight - not used but could be added */
      }
    }
    return true;
  }
  return false;
}
Exemplo n.º 7
0
void PaletteColor_color_set(PointerRNA *ptr, const float values[3])
{
	PaletteColor *data = (PaletteColor *)(ptr->data);
	unsigned int i;

	for (i = 0; i < 3; i++) {
		((float *)data->rgb)[i] = CLAMPIS(values[i], 0.0f, 1.0f);
	}
}
Exemplo n.º 8
0
void MovieClip_display_aspect_set(PointerRNA *ptr, const float values[2])
{
	MovieClip *data = (MovieClip *)(ptr->data);
	unsigned int i;

	for (i = 0; i < 2; i++) {
		(&data->aspx)[i] = CLAMPIS(values[i], 0.1000000015f, FLT_MAX);
	}
}
Exemplo n.º 9
0
static void rna_render_slots_active_set(PointerRNA *ptr, PointerRNA value)
{
	Image *image = (Image *)ptr->id.data;
	if (value.id.data == image) {
		RenderSlot *render_slot = (RenderSlot *)value.data;
		int index = render_slot - image->render_slots;
		image->render_slot = CLAMPIS(index, 0, IMA_MAX_RENDER_SLOT - 1);
	}
}
Exemplo n.º 10
0
/* clamp handles to defined size in pixel space */
static float draw_seq_handle_size_get_clamped(Sequence *seq, const float pixelx)
{
	const float minhandle = pixelx * SEQ_HANDLE_SIZE_MIN;
	const float maxhandle = pixelx * SEQ_HANDLE_SIZE_MAX;
	float size = CLAMPIS(seq->handsize, minhandle, maxhandle);

	/* ensure we're not greater than half width */
	return min_ff(size, ((float)(seq->enddisp - seq->startdisp) / 2.0f) / pixelx);
}
Exemplo n.º 11
0
// get visibility of a wind ray
static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, EffectorData *efd, EffectedPoint *point)
{
	const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT);
	ListBase *colls = colliders;
	ColliderCache *col;
	float norm[3], len = 0.0;
	float visibility = 1.0, absorption = 0.0;
	
	if (!(eff->pd->flag & PFIELD_VISIBILITY))
		return visibility;

	if (!colls)
		colls = get_collider_cache(eff->scene, eff->ob, NULL);

	if (!colls)
		return visibility;

	negate_v3_v3(norm, efd->vec_to_point);
	len = normalize_v3(norm);
	
	/* check all collision objects */
	for (col = colls->first; col; col = col->next) {
		CollisionModifierData *collmd = col->collmd;

		if (col->ob == eff->ob)
			continue;

		if (collmd->bvhtree) {
			BVHTreeRayHit hit;

			hit.index = -1;
			hit.dist = len + FLT_EPSILON;

			/* check if the way is blocked */
			if (BLI_bvhtree_ray_cast_ex(
			        collmd->bvhtree, point->loc, norm, 0.0f, &hit,
			        eff_tri_ray_hit, NULL, raycast_flag) != -1)
			{
				absorption= col->ob->pd->absorption;

				/* visibility is only between 0 and 1, calculated from 1-absorption */
				visibility *= CLAMPIS(1.0f-absorption, 0.0f, 1.0f);
				
				if (visibility <= 0.0f)
					break;
			}
		}
	}

	if (!colliders)
		free_collider_cache(&colls);
	
	return visibility;
}
Exemplo n.º 12
0
static void time_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread))
{
	/* stack order output: fac */
	float fac= 0.0f;
	
	if (node->custom1 < node->custom2)
		fac = (p->cfra - node->custom1)/(float)(node->custom2-node->custom1);
	
	fac = curvemapping_evaluateF(node->storage, 0, fac);
	out[0] = CLAMPIS(fac, 0.0f, 1.0f);
}
static void node_composit_exec_curves_time(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
{
	RenderData *rd= data;
	/* stack order output: fac */
	float fac= 0.0f;
	
	if (node->custom1 < node->custom2)
		fac= (rd->cfra - node->custom1)/(float)(node->custom2-node->custom1);
	
	fac= curvemapping_evaluateF(node->storage, 0, fac);
	out[0]->vec[0]= CLAMPIS(fac, 0.0f, 1.0f);
}
Exemplo n.º 14
0
bool MOD_meshcache_read_mdd_times(const char *filepath,
                                  float (*vertexCos)[3], const int verts_tot, const char interp,
                                  const float time, const float fps, const char time_mode,
                                  const char **err_str)
{
	float frame;

	FILE *fp = BLI_fopen(filepath, "rb");
	bool ok;

	if (fp == NULL) {
		*err_str = errno ? strerror(errno) : "Unknown error opening file";
		return false;
	}

	switch (time_mode) {
		case MOD_MESHCACHE_TIME_FRAME:
		{
			frame = time;
			break;
		}
		case MOD_MESHCACHE_TIME_SECONDS:
		{
			/* we need to find the closest time */
			if (meshcache_read_mdd_range_from_time(fp, verts_tot, time, fps, &frame, err_str) == false) {
				fclose(fp);
				return false;
			}
			rewind(fp);
			break;
		}
		case MOD_MESHCACHE_TIME_FACTOR:
		default:
		{
			MDDHead mdd_head;
			if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
				fclose(fp);
				return false;
			}

			frame = CLAMPIS(time, 0.0f, 1.0f) * (float)mdd_head.frame_tot;
			rewind(fp);
			break;
		}
	}

	ok = MOD_meshcache_read_mdd_frame(fp, vertexCos, verts_tot, interp, frame, err_str);

	fclose(fp);
	return ok;
}
static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, PyObject *value)
{
	if (PyIndex_Check(key)) {
		int i;

		i = PyNumber_AsSsize_t(key, PyExc_IndexError);
		if (i == -1 && PyErr_Occurred()) {
			return -1;
		}

		if (value) {
			/* dvert[group_index] = 0.5 */
			if (i < 0) {
				PyErr_SetString(PyExc_KeyError, "BMDeformVert[key] = x: "
				                "weight keys can't be negative");
				return -1;
			}
			else {
				MDeformWeight *dw = defvert_verify_index(self->data, i);
				const float f = PyFloat_AsDouble(value);
				if (f == -1 && PyErr_Occurred()) { // parsed key not a number
					PyErr_SetString(PyExc_TypeError,
					                "BMDeformVert[key] = x: "
					                "assigned value not a number");
					return -1;
				}

				dw->weight = CLAMPIS(f, 0.0f, 1.0f);
			}
		}
		else {
			/* del dvert[group_index] */
			MDeformWeight *dw = defvert_find_index(self->data, i);

			if (dw == NULL) {
				PyErr_SetString(PyExc_KeyError, "del BMDeformVert[key]: "
				                "key not found");
			}
			defvert_remove_group(self->data, dw);
		}

		return 0;

	}
	else {
		PyErr_Format(PyExc_TypeError,
		             "BMDeformVert keys must be integers, not %.200s",
		             Py_TYPE(key)->tp_name);
		return -1;
	}
}
Exemplo n.º 16
0
static PyObject *bpy_bm_utils_vert_collapse_faces(PyObject *UNUSED(self), PyObject *args)
{
	BPy_BMEdge *py_edge;
	BPy_BMVert *py_vert;

	float fac;
	int do_join_faces;

	BMesh *bm;
	BMEdge *e_new = NULL;

	if (!PyArg_ParseTuple(args, "O!O!fi:vert_collapse_faces",
	                      &BPy_BMVert_Type, &py_vert,
	                      &BPy_BMEdge_Type, &py_edge,
	                      &fac, &do_join_faces))
	{
		return NULL;
	}

	BPY_BM_CHECK_OBJ(py_edge);
	BPY_BM_CHECK_OBJ(py_vert);

	/* this doubles for checking that the verts are in the same mesh */
	if (!(py_edge->e->v1 == py_vert->v ||
	      py_edge->e->v2 == py_vert->v))
	{
		PyErr_SetString(PyExc_ValueError,
		                "vert_collapse_faces(vert, edge): the vertex is not found in the edge");
		return NULL;
	}

	if (BM_vert_edge_count(py_vert->v) > 2) {
		PyErr_SetString(PyExc_ValueError,
		                "vert_collapse_faces(vert, edge): vert has more then 2 connected edges");
		return NULL;
	}

	bm = py_edge->bm;

	e_new = BM_vert_collapse_faces(bm, py_edge->e, py_vert->v, CLAMPIS(fac, 0.0f, 1.0f), do_join_faces, TRUE);

	if (e_new) {
		return BPy_BMEdge_CreatePyObject(bm, e_new);
	}
	else {
		PyErr_SetString(PyExc_ValueError,
		                "vert_collapse_edge(vert, edge): no new edge created, internal error");
		return NULL;
	}
}
Exemplo n.º 17
0
static bool edbm_bevel_calc(wmOperator *op)
{
	BevelData *opdata = op->customdata;
	BMEditMesh *em = opdata->em;
	BMOperator bmop;
	const float offset = RNA_float_get(op->ptr, "offset");
	const int offset_type = RNA_enum_get(op->ptr, "offset_type");
	const int segments = RNA_int_get(op->ptr, "segments");
	const float profile = RNA_float_get(op->ptr, "profile");
	const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
	const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
	int material = RNA_int_get(op->ptr, "material");
	const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");

	/* revert to original mesh */
	if (opdata->is_modal) {
		EDBM_redo_state_restore(opdata->mesh_backup, em, false);
	}

	if (em->ob) {
		material = CLAMPIS(material, -1, em->ob->totcol - 1);
	}

	EDBM_op_init(em, &bmop, op,
	             "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b "
	             "material=%i loop_slide=%b",
	             BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile,
	             clamp_overlap, material, loop_slide);

	BMO_op_exec(em->bm, &bmop);

	if (offset != 0.0f) {
		/* not essential, but we may have some loose geometry that
		 * won't get bevel'd and better not leave it selected */
		EDBM_flag_disable_all(em, BM_ELEM_SELECT);
		BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
	}

	/* no need to de-select existing geometry */
	if (!EDBM_op_finish(em, &bmop, op, true)) {
		return false;
	}

	EDBM_mesh_normals_update(opdata->em);

	EDBM_update_generic(opdata->em, true, true);

	return true;
}
void GPU_simple_shader_colors(const float diffuse[3], const float specular[3],
	int shininess, float alpha)
{
	float gl_diffuse[4], gl_specular[4];

	copy_v3_v3(gl_diffuse, diffuse);
	gl_diffuse[3] = alpha;

	copy_v3_v3(gl_specular, specular);
	gl_specular[3] = 1.0f;

	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gl_diffuse);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gl_specular);
	glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(shininess, 1, 128));
}
Exemplo n.º 19
0
static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t *AFD)
{
	int xs, ys, clip = 0;
	float tc[4], xsd, ysd, cw = 0.f;
	const float ux = ibuf->x*AFD->dxt[0], uy = ibuf->y*AFD->dxt[1];
	const float vx = ibuf->x*AFD->dyt[0], vy = ibuf->y*AFD->dyt[1];
	int xsam = (int)(0.5f*sqrtf(ux*ux + uy*uy) + 0.5f);
	int ysam = (int)(0.5f*sqrtf(vx*vx + vy*vy) + 0.5f);
	const int minsam = AFD->intpol ? 2 : 4;
	xsam = CLAMPIS(xsam, minsam, ibuf->x*2);
	ysam = CLAMPIS(ysam, minsam, ibuf->y*2);
	xsd = 1.f / xsam;
	ysd = 1.f / ysam;
	texr->tr = texr->tg = texr->tb = texr->ta = 0.f;
	for (ys=0; ys<ysam; ++ys) {
		for (xs=0; xs<xsam; ++xs) {
			const float su = (xs + ((ys & 1) + 0.5f)*0.5f)*xsd - 0.5f;
			const float sv = (ys + ((xs & 1) + 0.5f)*0.5f)*ysd - 0.5f;
			const float pu = fx + su*AFD->dxt[0] + sv*AFD->dyt[0];
			const float pv = fy + su*AFD->dxt[1] + sv*AFD->dyt[1];
			const int out = ibuf_get_color_clip_bilerp(tc, ibuf, pu*ibuf->x, pv*ibuf->y, AFD->intpol, AFD->extflag);
			clip |= out;
			cw += out ? 0.f : 1.f;
			texr->tr += tc[0];
			texr->tg += tc[1];
			texr->tb += tc[2];
			texr->ta += texr->talpha ? tc[3] : 0.f;
		}
	}
	xsd *= ysd;
	texr->tr *= xsd;
	texr->tg *= xsd;
	texr->tb *= xsd;
	/* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
	texr->ta = texr->talpha ? texr->ta*xsd : (clip ? cw*xsd : 1.f);
}
Exemplo n.º 20
0
static PyObject *bpy_bm_utils_edge_split(PyObject *UNUSED(self), PyObject *args)
{
	BPy_BMEdge *py_edge;
	BPy_BMVert *py_vert;
	float fac;

	BMesh *bm;
	BMVert *v_new = NULL;
	BMEdge *e_new = NULL;

	if (!PyArg_ParseTuple(args, "O!O!f:edge_split",
	                      &BPy_BMEdge_Type, &py_edge,
	                      &BPy_BMVert_Type, &py_vert,
	                      &fac))
	{
		return NULL;
	}

	BPY_BM_CHECK_OBJ(py_edge);
	BPY_BM_CHECK_OBJ(py_vert);

	/* this doubles for checking that the verts are in the same mesh */
	if (!(py_edge->e->v1 == py_vert->v ||
	      py_edge->e->v2 == py_vert->v))
	{
		PyErr_SetString(PyExc_ValueError,
		                "edge_split(edge, vert): the vertex is not found in the edge");
		return NULL;
	}

	bm = py_edge->bm;

	v_new = BM_edge_split(bm, py_edge->e, py_vert->v, &e_new, CLAMPIS(fac, 0.0f, 1.0f));

	if (v_new && e_new) {
		PyObject *ret = PyTuple_New(2);
		PyTuple_SET_ITEMS(ret,
		        BPy_BMEdge_CreatePyObject(bm, e_new),
		        BPy_BMVert_CreatePyObject(bm, v_new));
		return ret;
	}
	else {
		PyErr_SetString(PyExc_ValueError,
		                "edge_split(edge, vert): couldn't split the edge, internal error");
		return NULL;
	}
}
Exemplo n.º 21
0
static int render_frame(int argc, const char **argv, void *data)
{
	bContext *C = data;
	Scene *scene = CTX_data_scene(C);
	if (scene) {
		Main *bmain = CTX_data_main(C);

		if (argc > 1) {
			Render *re = RE_NewRender(scene->id.name);
			int frame;
			ReportList reports;

			switch (*argv[1]) {
				case '+':
					frame = scene->r.sfra + atoi(argv[1] + 1);
					break;
				case '-':
					frame = (scene->r.efra - atoi(argv[1] + 1)) + 1;
					break;
				default:
					frame = atoi(argv[1]);
					break;
			}

			BLI_begin_threaded_malloc();
			BKE_reports_init(&reports, RPT_PRINT);

			frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);

			RE_SetReports(re, &reports);
			RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
			RE_SetReports(re, NULL);
			BLI_end_threaded_malloc();
			return 1;
		}
		else {
			printf("\nError: frame number must follow '-f / --render-frame'.\n");
			return 0;
		}
	}
	else {
		printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
		return 0;
	}
}
Exemplo n.º 22
0
static int set_end_frame(int argc, const char **argv, void *data)
{
	bContext *C = data;
	if (CTX_data_scene(C)) {
		Scene *scene= CTX_data_scene(C);
		if (argc > 1) {
			int frame = atoi(argv[1]);
			(scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
			return 1;
		} else {
			printf("\nError: frame number must follow '-e / --frame-end'.\n");
			return 0;
		}
	} else {
		printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
		return 0;
	}
}
Exemplo n.º 23
0
static int set_skip_frame(int argc, const char **argv, void *data)
{
	bContext *C = data;
	if (CTX_data_scene(C)) {
		Scene *scene= CTX_data_scene(C);
		if (argc > 1) {
			int frame = atoi(argv[1]);
			(scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
			return 1;
		} else {
			printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
			return 0;
		}
	} else {
		printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
		return 0;
	}
}
Exemplo n.º 24
0
/* this makes sure we can extend for non-cyclic. *vec needs 4 items! */
static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius)	/* returns OK */
{
	Curve *cu= ob->data;
	BevList *bl;
	float ctime1;
	int cycl=0;
	
	/* test for cyclic */
	bl= cu->bev.first;
	if (!bl->nr) return 0;
	if(bl && bl->poly> -1) cycl= 1;

	if(cycl==0) {
		ctime1= CLAMPIS(ctime, 0.0f, 1.0f);
	}
	else ctime1= ctime;
	
	/* vec needs 4 items */
	if(where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
		
		if(cycl==0) {
			Path *path= cu->path;
			float dvec[3];
			
			if(ctime < 0.0f) {
				sub_v3_v3v3(dvec, path->data[1].vec, path->data[0].vec);
				mul_v3_fl(dvec, ctime*(float)path->len);
				add_v3_v3(vec, dvec);
				if(quat) copy_qt_qt(quat, path->data[0].quat);
				if(radius) *radius= path->data[0].radius;
			}
			else if(ctime > 1.0f) {
				sub_v3_v3v3(dvec, path->data[path->len-1].vec, path->data[path->len-2].vec);
				mul_v3_fl(dvec, (ctime-1.0f)*(float)path->len);
				add_v3_v3(vec, dvec);
				if(quat) copy_qt_qt(quat, path->data[path->len-1].quat);
				if(radius) *radius= path->data[path->len-1].radius;
				/* weight - not used but could be added */
			}
		}
		return 1;
	}
	return 0;
}
Exemplo n.º 25
0
static void do_rough_curve(const float loc[3], float mat[4][4], float time, float fac, float size, CurveMapping *roughcurve, ParticleKey *state)
{
	float rough[3];
	float rco[3];
	
	if (!roughcurve)
		return;
	
	fac *= CLAMPIS(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
	
	copy_v3_v3(rco, loc);
	mul_v3_fl(rco, time);
	rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
	rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
	rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
	
	madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
	madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
	madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
}
Exemplo n.º 26
0
unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
{
	const float max_segment = 0.005;
	unsigned int resol = BKE_mask_spline_resolution(spline, width, height);
	float max_jump = 0.0f;
	int i;

	/* avoid checking the featrher if we already hit the maximum value */
	if (resol >= MASK_RESOL_MAX) {
		return MASK_RESOL_MAX;
	}

	for (i = 0; i < spline->tot_point; i++) {
		MaskSplinePoint *point = &spline->points[i];
		float prev_u, prev_w;
		int j;

		prev_u = 0.0f;
		prev_w = point->bezt.weight;

		for (j = 0; j < point->tot_uw; j++) {
			const float w_diff = (point->uw[j].w - prev_w);
			const float u_diff = (point->uw[j].u - prev_u);

			/* avoid divide by zero and very high values,
			 * though these get clamped eventually */
			if (u_diff > FLT_EPSILON) {
				float jump = fabsf(w_diff / u_diff);

				max_jump = max_ff(max_jump, jump);
			}

			prev_u = point->uw[j].u;
			prev_w = point->uw[j].w;
		}
	}

	resol += max_jump / max_segment;

	return CLAMPIS(resol, 1, MASK_RESOL_MAX);
}
Exemplo n.º 27
0
unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
{
	float max_segment = 0.01f;
	unsigned int i, resol = 1;

	if (width != 0 && height != 0) {
		max_segment = 1.0f / (float)max_ii(width, height);
	}

	for (i = 0; i < spline->tot_point; i++) {
		MaskSplinePoint *point = &spline->points[i];
		BezTriple *bezt_curr, *bezt_next;
		float a, b, c, len;
		unsigned int cur_resol;

		bezt_curr = &point->bezt;
		bezt_next = BKE_mask_spline_point_next_bezt(spline, spline->points, point);

		if (bezt_next == NULL) {
			break;
		}

		a = len_v3v3(bezt_curr->vec[1], bezt_curr->vec[2]);
		b = len_v3v3(bezt_curr->vec[2], bezt_next->vec[0]);
		c = len_v3v3(bezt_next->vec[0], bezt_next->vec[1]);

		len = a + b + c;
		cur_resol = len / max_segment;

		resol = MAX2(resol, cur_resol);

		if (resol >= MASK_RESOL_MAX) {
			break;
		}
	}

	return CLAMPIS(resol, 1, MASK_RESOL_MAX);
}
Exemplo n.º 28
0
static void rna_Lattice_points_w_set(PointerRNA *ptr, int value)
{
	Lattice *lt= (Lattice*)ptr->data;

	lt->opntsw= CLAMPIS(value, 1, 64);
}
Exemplo n.º 29
0
/* Evaluate spline IK for a given bone */
static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan,
                                   int index, float ctime)
{
	bSplineIKConstraint *ikData = tree->ikData;
	float poseHead[3], poseTail[3], poseMat[4][4];
	float splineVec[3], scaleFac, radius = 1.0f;

	/* firstly, calculate the bone matrix the standard way, since this is needed for roll control */
	BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1);

	copy_v3_v3(poseHead, pchan->pose_head);
	copy_v3_v3(poseTail, pchan->pose_tail);

	/* step 1: determine the positions for the endpoints of the bone */
	{
		float vec[4], dir[3], rad;
		float tailBlendFac = 1.0f;

		/* determine if the bone should still be affected by SplineIK */
		if (tree->points[index + 1] >= 1.0f) {
			/* spline doesn't affect the bone anymore, so done... */
			pchan->flag |= POSE_DONE;
			return;
		}
		else if ((tree->points[index] >= 1.0f) && (tree->points[index + 1] < 1.0f)) {
			/* blending factor depends on the amount of the bone still left on the chain */
			tailBlendFac = (1.0f - tree->points[index + 1]) / (tree->points[index] - tree->points[index + 1]);
		}

		/* tail endpoint */
		if (where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad, NULL)) {
			/* apply curve's object-mode transforms to the position
			 * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
			 */
			if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0)
				mul_m4_v3(ikData->tar->obmat, vec);

			/* convert the position to pose-space, then store it */
			mul_m4_v3(ob->imat, vec);
			interp_v3_v3v3(poseTail, pchan->pose_tail, vec, tailBlendFac);

			/* set the new radius */
			radius = rad;
		}

		/* head endpoint */
		if (where_on_path(ikData->tar, tree->points[index + 1], vec, dir, NULL, &rad, NULL)) {
			/* apply curve's object-mode transforms to the position
			 * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
			 */
			if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0)
				mul_m4_v3(ikData->tar->obmat, vec);

			/* store the position, and convert it to pose space */
			mul_m4_v3(ob->imat, vec);
			copy_v3_v3(poseHead, vec);

			/* set the new radius (it should be the average value) */
			radius = (radius + rad) / 2;
		}
	}

	/* step 2: determine the implied transform from these endpoints
	 *     - splineVec: the vector direction that the spline applies on the bone
	 *     - scaleFac: the factor that the bone length is scaled by to get the desired amount
	 */
	sub_v3_v3v3(splineVec, poseTail, poseHead);
	scaleFac = len_v3(splineVec) / pchan->bone->length;

	/* step 3: compute the shortest rotation needed to map from the bone rotation to the current axis
	 *      - this uses the same method as is used for the Damped Track Constraint (see the code there for details)
	 */
	{
		float dmat[3][3], rmat[3][3], tmat[3][3];
		float raxis[3], rangle;

		/* compute the raw rotation matrix from the bone's current matrix by extracting only the
		 * orientation-relevant axes, and normalizing them
		 */
		copy_v3_v3(rmat[0], pchan->pose_mat[0]);
		copy_v3_v3(rmat[1], pchan->pose_mat[1]);
		copy_v3_v3(rmat[2], pchan->pose_mat[2]);
		normalize_m3(rmat);

		/* also, normalize the orientation imposed by the bone, now that we've extracted the scale factor */
		normalize_v3(splineVec);

		/* calculate smallest axis-angle rotation necessary for getting from the
		 * current orientation of the bone, to the spline-imposed direction
		 */
		cross_v3_v3v3(raxis, rmat[1], splineVec);

		rangle = dot_v3v3(rmat[1], splineVec);
		CLAMP(rangle, -1.0f, 1.0f);
		rangle = acosf(rangle);

		/* multiply the magnitude of the angle by the influence of the constraint to
		 * control the influence of the SplineIK effect
		 */
		rangle *= tree->con->enforce;

		/* construct rotation matrix from the axis-angle rotation found above
		 *	- this call takes care to make sure that the axis provided is a unit vector first
		 */
		axis_angle_to_mat3(dmat, raxis, rangle);

		/* combine these rotations so that the y-axis of the bone is now aligned as the spline dictates,
		 * while still maintaining roll control from the existing bone animation
		 */
		mul_m3_m3m3(tmat, dmat, rmat); /* m1, m3, m2 */
		normalize_m3(tmat); /* attempt to reduce shearing, though I doubt this'll really help too much now... */
		copy_m4_m3(poseMat, tmat);
	}

	/* step 4: set the scaling factors for the axes */
	{
		/* only multiply the y-axis by the scaling factor to get nice volume-preservation */
		mul_v3_fl(poseMat[1], scaleFac);

		/* set the scaling factors of the x and z axes from... */
		switch (ikData->xzScaleMode) {
			case CONSTRAINT_SPLINEIK_XZS_ORIGINAL:
			{
				/* original scales get used */
				float scale;

				/* x-axis scale */
				scale = len_v3(pchan->pose_mat[0]);
				mul_v3_fl(poseMat[0], scale);
				/* z-axis scale */
				scale = len_v3(pchan->pose_mat[2]);
				mul_v3_fl(poseMat[2], scale);
				break;
			}
			case CONSTRAINT_SPLINEIK_XZS_INVERSE:
			{
				/* old 'volume preservation' method using the inverse scale */
				float scale;

				/* calculate volume preservation factor which is
				 * basically the inverse of the y-scaling factor
				 */
				if (fabsf(scaleFac) != 0.0f) {
					scale = 1.0f / fabsf(scaleFac);

					/* we need to clamp this within sensible values */
					/* NOTE: these should be fine for now, but should get sanitised in future */
					CLAMP(scale, 0.0001f, 100000.0f);
				}
				else
					scale = 1.0f;

				/* apply the scaling */
				mul_v3_fl(poseMat[0], scale);
				mul_v3_fl(poseMat[2], scale);
				break;
			}
			case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC:
			{
				/* improved volume preservation based on the Stretch To constraint */
				float final_scale;
				
				/* as the basis for volume preservation, we use the inverse scale factor... */
				if (fabsf(scaleFac) != 0.0f) {
					/* NOTE: The method here is taken wholesale from the Stretch To constraint */
					float bulge = powf(1.0f / fabsf(scaleFac), ikData->bulge);
					
					if (bulge > 1.0f) {
						if (ikData->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MAX) {
							float bulge_max = max_ff(ikData->bulge_max, 1.0f);
							float hard = min_ff(bulge, bulge_max);
							
							float range = bulge_max - 1.0f;
							float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
							float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (float)M_PI_2;
							
							bulge = interpf(soft, hard, ikData->bulge_smooth);
						}
					}
					if (bulge < 1.0f) {
						if (ikData->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MIN) {
							float bulge_min = CLAMPIS(ikData->bulge_min, 0.0f, 1.0f);
							float hard = max_ff(bulge, bulge_min);
							
							float range = 1.0f - bulge_min;
							float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
							float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (float)M_PI_2;
							
							bulge = interpf(soft, hard, ikData->bulge_smooth);
						}
					}
					
					/* compute scale factor for xz axes from this value */
					final_scale = sqrtf(bulge);
				}
				else {
					/* no scaling, so scale factor is simple */
					final_scale = 1.0f;
				}
				
				/* apply the scaling (assuming normalised scale) */
				mul_v3_fl(poseMat[0], final_scale);
				mul_v3_fl(poseMat[2], final_scale);
				break;
			}
		}

		/* finally, multiply the x and z scaling by the radius of the curve too,
		 * to allow automatic scales to get tweaked still
		 */
		if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) {
			mul_v3_fl(poseMat[0], radius);
			mul_v3_fl(poseMat[2], radius);
		}
	}

	/* step 5: set the location of the bone in the matrix */
	if (ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) {
		/* when the 'no-root' option is affected, the chain can retain
		 * the shape but be moved elsewhere
		 */
		copy_v3_v3(poseHead, pchan->pose_head);
	}
	else if (tree->con->enforce < 1.0f) {
		/* when the influence is too low
		 *	- blend the positions for the 'root' bone
		 *	- stick to the parent for any other
		 */
		if (pchan->parent) {
			copy_v3_v3(poseHead, pchan->pose_head);
		}
		else {
			/* FIXME: this introduces popping artifacts when we reach 0.0 */
			interp_v3_v3v3(poseHead, pchan->pose_head, poseHead, tree->con->enforce);
		}
	}
	copy_v3_v3(poseMat[3], poseHead);

	/* finally, store the new transform */
	copy_m4_m4(pchan->pose_mat, poseMat);
	copy_v3_v3(pchan->pose_head, poseHead);

	/* recalculate tail, as it's now outdated after the head gets adjusted above! */
	BKE_pose_where_is_bone_tail(pchan);

	/* done! */
	pchan->flag |= POSE_DONE;
}
Exemplo n.º 30
0
static void cloth_continuum_step(ClothModifierData *clmd, float dt)
{
	ClothSimSettings *parms = clmd->sim_parms;
	Cloth *cloth = clmd->clothObject;
	Implicit_Data *data = cloth->implicit;
	int mvert_num = cloth->mvert_num;
	ClothVertex *vert;
	
	const float fluid_factor = 0.95f; /* blend between PIC and FLIP methods */
	float smoothfac = parms->velocity_smooth;
	/* XXX FIXME arbitrary factor!!! this should be based on some intuitive value instead,
	 * like number of hairs per cell and time decay instead of "strength"
	 */
	float density_target = parms->density_target;
	float density_strength = parms->density_strength;
	float gmin[3], gmax[3];
	int i;
	
	/* clear grid info */
	zero_v3_int(clmd->hair_grid_res);
	zero_v3(clmd->hair_grid_min);
	zero_v3(clmd->hair_grid_max);
	clmd->hair_grid_cellsize = 0.0f;
	
	hair_get_boundbox(clmd, gmin, gmax);
	
	/* gather velocities & density */
	if (smoothfac > 0.0f || density_strength > 0.0f) {
		HairGrid *grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax);
		
		cloth_continuum_fill_grid(grid, cloth);
		
		/* main hair continuum solver */
		BPH_hair_volume_solve_divergence(grid, dt, density_target, density_strength);
		
		for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {
			float x[3], v[3], nv[3];
			
			/* calculate volumetric velocity influence */
			BPH_mass_spring_get_position(data, i, x);
			BPH_mass_spring_get_new_velocity(data, i, v);
			
			BPH_hair_volume_grid_velocity(grid, x, v, fluid_factor, nv);
			
			interp_v3_v3v3(nv, v, nv, smoothfac);
			
			/* apply on hair data */
			BPH_mass_spring_set_new_velocity(data, i, nv);
		}
		
		/* store basic grid info in the modifier data */
		BPH_hair_volume_grid_geometry(grid, &clmd->hair_grid_cellsize, clmd->hair_grid_res, clmd->hair_grid_min, clmd->hair_grid_max);
		
#if 0 /* DEBUG hair velocity vector field */
		{
			const int size = 64;
			int i, j;
			float offset[3], a[3], b[3];
			const int axis = 0;
			const float shift = 0.0f;
			
			copy_v3_v3(offset, clmd->hair_grid_min);
			zero_v3(a);
			zero_v3(b);
			
			offset[axis] = shift * clmd->hair_grid_cellsize;
			a[(axis+1) % 3] = clmd->hair_grid_max[(axis+1) % 3] - clmd->hair_grid_min[(axis+1) % 3];
			b[(axis+2) % 3] = clmd->hair_grid_max[(axis+2) % 3] - clmd->hair_grid_min[(axis+2) % 3];
			
			BKE_sim_debug_data_clear_category(clmd->debug_data, "grid velocity");
			for (j = 0; j < size; ++j) {
				for (i = 0; i < size; ++i) {
					float x[3], v[3], gvel[3], gvel_smooth[3], gdensity;
					
					madd_v3_v3v3fl(x, offset, a, (float)i / (float)(size-1));
					madd_v3_v3fl(x, b, (float)j / (float)(size-1));
					zero_v3(v);
					
					BPH_hair_volume_grid_interpolate(grid, x, &gdensity, gvel, gvel_smooth, NULL, NULL);
					
//					BKE_sim_debug_data_add_circle(clmd->debug_data, x, gdensity, 0.7, 0.3, 1, "grid density", i, j, 3111);
					if (!is_zero_v3(gvel) || !is_zero_v3(gvel_smooth)) {
						float dvel[3];
						sub_v3_v3v3(dvel, gvel_smooth, gvel);
//						BKE_sim_debug_data_add_vector(clmd->debug_data, x, gvel, 0.4, 0, 1, "grid velocity", i, j, 3112);
//						BKE_sim_debug_data_add_vector(clmd->debug_data, x, gvel_smooth, 0.6, 1, 1, "grid velocity", i, j, 3113);
						BKE_sim_debug_data_add_vector(clmd->debug_data, x, dvel, 0.4, 1, 0.7, "grid velocity", i, j, 3114);
#if 0
						if (gdensity > 0.0f) {
							float col0[3] = {0.0, 0.0, 0.0};
							float col1[3] = {0.0, 1.0, 0.0};
							float col[3];
							
							interp_v3_v3v3(col, col0, col1, CLAMPIS(gdensity * clmd->sim_parms->density_strength, 0.0, 1.0));
//							BKE_sim_debug_data_add_circle(clmd->debug_data, x, gdensity * clmd->sim_parms->density_strength, 0, 1, 0.4, "grid velocity", i, j, 3115);
//							BKE_sim_debug_data_add_dot(clmd->debug_data, x, col[0], col[1], col[2], "grid velocity", i, j, 3115);
							BKE_sim_debug_data_add_circle(clmd->debug_data, x, 0.01f, col[0], col[1], col[2], "grid velocity", i, j, 3115);
						}
#endif
					}
				}
			}
		}
#endif
		
		BPH_hair_volume_free_vertex_grid(grid);
	}
}