Example #1
0
static void fcm_generator_evaluate(FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime)
{
	FMod_Generator *data = (FMod_Generator *)fcm->data;
	
	/* behavior depends on mode 
	 * NOTE: the data in its default state is fine too
	 */
	switch (data->mode) {
		case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */
		{
			/* we overwrite cvalue with the sum of the polynomial */
			float *powers = MEM_callocN(sizeof(float) * data->arraysize, "Poly Powers");
			float value = 0.0f;
			unsigned int i;
			
			/* for each x^n, precalculate value based on previous one first... this should be 
			 * faster that calling pow() for each entry
			 */
			for (i = 0; i < data->arraysize; i++) {
				/* first entry is x^0 = 1, otherwise, calculate based on previous */
				if (i)
					powers[i] = powers[i - 1] * evaltime;
				else
					powers[0] = 1;
			}
			
			/* for each coefficient, add to value, which we'll write to *cvalue in one go */
			for (i = 0; i < data->arraysize; i++)
				value += data->coefficients[i] * powers[i];
			
			/* only if something changed, write *cvalue in one go */
			if (data->poly_order) {
				if (data->flag & FCM_GENERATOR_ADDITIVE)
					*cvalue += value;
				else
					*cvalue = value;
			}
				
			/* cleanup */
			if (powers) 
				MEM_freeN(powers);
		}
		break;
			
		case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial */
		{
			float value = 1.0f, *cp = NULL;
			unsigned int i;
			
			/* for each coefficient pair, solve for that bracket before accumulating in value by multiplying */
			for (cp = data->coefficients, i = 0; (cp) && (i < (unsigned int)data->poly_order); cp += 2, i++)
				value *= (cp[0] * evaltime + cp[1]);
				
			/* only if something changed, write *cvalue in one go */
			if (data->poly_order) {
				if (data->flag & FCM_GENERATOR_ADDITIVE)
					*cvalue += value;
				else
					*cvalue = value;
			}
		}
		break;
	}
}
Example #2
0
static bool python_script_exec(
        bContext *C, const char *fn, struct Text *text,
        struct ReportList *reports, const bool do_jump)
{
	Main *bmain_old = CTX_data_main(C);
	PyObject *main_mod = NULL;
	PyObject *py_dict = NULL, *py_result = NULL;
	PyGILState_STATE gilstate;

	BLI_assert(fn || text);

	if (fn == NULL && text == NULL) {
		return 0;
	}

	bpy_context_set(C, &gilstate);

	PyC_MainModule_Backup(&main_mod);

	if (text) {
		char fn_dummy[FILE_MAXDIR];
		bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);

		if (text->compiled == NULL) {   /* if it wasn't already compiled, do it now */
			char *buf;
			PyObject *fn_dummy_py;

			fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);

			buf = txt_to_buf(text);
			text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
			MEM_freeN(buf);

			Py_DECREF(fn_dummy_py);

			if (PyErr_Occurred()) {
				if (do_jump) {
					python_script_error_jump_text(text);
				}
				BPY_text_free_code(text);
			}
		}

		if (text->compiled) {
			py_dict = PyC_DefaultNameSpace(fn_dummy);
			py_result =  PyEval_EvalCode(text->compiled, py_dict, py_dict);
		}

	}
	else {
		FILE *fp = BLI_fopen(fn, "r");

		if (fp) {
			py_dict = PyC_DefaultNameSpace(fn);

#ifdef _WIN32
			/* Previously we used PyRun_File to run directly the code on a FILE
			 * object, but as written in the Python/C API Ref Manual, chapter 2,
			 * 'FILE structs for different C libraries can be different and
			 * incompatible'.
			 * So now we load the script file data to a buffer */
			{
				const char *pystring =
				        "ns = globals().copy()\n"
				        "with open(__file__, 'rb') as f: exec(compile(f.read(), __file__, 'exec'), ns)";

				fclose(fp);

				py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict);
			}
#else
			py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
			fclose(fp);
#endif
		}
		else {
			PyErr_Format(PyExc_IOError,
			             "Python file \"%s\" could not be opened: %s",
			             fn, strerror(errno));
			py_result = NULL;
		}
	}

	if (!py_result) {
		if (text) {
			if (do_jump) {
				/* ensure text is valid before use, the script may have freed its self */
				Main *bmain_new = CTX_data_main(C);
				if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->text, text) != -1)) {
					python_script_error_jump_text(text);
				}
			}
		}
		BPy_errors_to_report(reports);
	}
	else {
		Py_DECREF(py_result);
	}

	if (py_dict) {
#ifdef PYMODULE_CLEAR_WORKAROUND
		PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__");
		PyObject *dict_back = mmod->md_dict;
		/* freeing the module will clear the namespace,
		 * gives problems running classes defined in this namespace being used later. */
		mmod->md_dict = NULL;
		Py_DECREF(dict_back);
#endif

#undef PYMODULE_CLEAR_WORKAROUND
	}

	PyC_MainModule_Restore(main_mod);

	bpy_context_clear(C, &gilstate);

	return (py_result != NULL);
}
Example #3
0
static void buildchar(Main *bmain, Curve *cu, unsigned long character, CharInfo *info,
                      float ofsx, float ofsy, float rot, int charidx)
{
	BezTriple *bezt1, *bezt2;
	Nurb *nu1 = NULL, *nu2 = NULL;
	float *fp, fsize, shear, x, si, co;
	VFontData *vfd = NULL;
	VChar *che = NULL;
	int i;

	vfd = vfont_get_data(bmain, which_vfont(cu, info));
	if (!vfd) return;

#if 0
	if (cu->selend < cu->selstart) {
		if ((charidx >= (cu->selend)) && (charidx <= (cu->selstart - 2)))
			sel = 1;
	}
	else {
		if ((charidx >= (cu->selstart - 1)) && (charidx <= (cu->selend - 1)))
			sel = 1;
	}
#endif

	/* make a copy at distance ofsx, ofsy with shear */
	fsize = cu->fsize;
	shear = cu->shear;
	si = sinf(rot);
	co = cosf(rot);

	che = find_vfont_char(vfd, character);
	
	/* Select the glyph data */
	if (che)
		nu1 = che->nurbsbase.first;

	/* Create the character */
	while (nu1) {
		bezt1 = nu1->bezt;
		if (bezt1) {
			nu2 = (Nurb *) MEM_mallocN(sizeof(Nurb), "duplichar_nurb");
			if (nu2 == NULL) break;
			memcpy(nu2, nu1, sizeof(struct Nurb));
			nu2->resolu = cu->resolu;
			nu2->bp = NULL;
			nu2->knotsu = nu2->knotsv = NULL;
			nu2->flag = CU_SMOOTH;
			nu2->charidx = charidx;
			if (info->mat_nr > 0) {
				nu2->mat_nr = info->mat_nr - 1;
			}
			else {
				nu2->mat_nr = 0;
			}
			/* nu2->trim.first = 0; */
			/* nu2->trim.last = 0; */
			i = nu2->pntsu;

			bezt2 = (BezTriple *)MEM_mallocN(i * sizeof(BezTriple), "duplichar_bezt2");
			if (bezt2 == NULL) {
				MEM_freeN(nu2);
				break;
			}
			memcpy(bezt2, bezt1, i * sizeof(struct BezTriple));
			nu2->bezt = bezt2;
			
			if (shear != 0.0f) {
				bezt2 = nu2->bezt;
				
				for (i = nu2->pntsu; i > 0; i--) {
					bezt2->vec[0][0] += shear * bezt2->vec[0][1];
					bezt2->vec[1][0] += shear * bezt2->vec[1][1];
					bezt2->vec[2][0] += shear * bezt2->vec[2][1];
					bezt2++;
				}
			}
			if (rot != 0.0f) {
				bezt2 = nu2->bezt;
				for (i = nu2->pntsu; i > 0; i--) {
					fp = bezt2->vec[0];

					x = fp[0];
					fp[0] = co * x + si * fp[1];
					fp[1] = -si * x + co * fp[1];
					x = fp[3];
					fp[3] = co * x + si * fp[4];
					fp[4] = -si * x + co * fp[4];
					x = fp[6];
					fp[6] = co * x + si * fp[7];
					fp[7] = -si * x + co * fp[7];

					bezt2++;
				}
			}
			bezt2 = nu2->bezt;

			if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) {
				const float sca = cu->smallcaps_scale;
				for (i = nu2->pntsu; i > 0; i--) {
					fp = bezt2->vec[0];
					fp[0] *= sca;
					fp[1] *= sca;
					fp[3] *= sca;
					fp[4] *= sca;
					fp[6] *= sca;
					fp[7] *= sca;
					bezt2++;
				}
			}
			bezt2 = nu2->bezt;

			for (i = nu2->pntsu; i > 0; i--) {
				fp = bezt2->vec[0];
				fp[0] = (fp[0] + ofsx) * fsize;
				fp[1] = (fp[1] + ofsy) * fsize;
				fp[3] = (fp[3] + ofsx) * fsize;
				fp[4] = (fp[4] + ofsy) * fsize;
				fp[6] = (fp[6] + ofsx) * fsize;
				fp[7] = (fp[7] + ofsy) * fsize;
				bezt2++;
			}
			
			BLI_addtail(&(cu->nurb), nu2);
		}
		
		nu1 = nu1->next;
	}
}
Example #4
0
/**
 * \see #wm_homefile_write_exec wraps #BLO_write_file in a similar way.
 */
int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *reports)
{
	Library *li;
	int len;
	int *thumb = NULL;
	ImBuf *ibuf_thumb = NULL;

	len = strlen(filepath);
	
	if (len == 0) {
		BKE_report(reports, RPT_ERROR, "Path is empty, cannot save");
		return -1;
	}

	if (len >= FILE_MAX) {
		BKE_report(reports, RPT_ERROR, "Path too long, cannot save");
		return -1;
	}
	
	/* Check if file write permission is ok */
	if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) {
		BKE_reportf(reports, RPT_ERROR, "Cannot save blend file, path '%s' is not writable", filepath);
		return -1;
	}
 
	/* note: used to replace the file extension (to ensure '.blend'),
	 * no need to now because the operator ensures,
	 * its handy for scripts to save to a predefined name without blender editing it */
	
	/* send the OnSave event */
	for (li = G.main->library.first; li; li = li->id.next) {
		if (BLI_path_cmp(li->filepath, filepath) == 0) {
			BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath);
			return -1;
		}
	}

	/* blend file thumbnail */
	/* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */
	if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) {
		ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb);
	}

	BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE);

	/* operator now handles overwrite checks */

	if (G.fileflags & G_AUTOPACK) {
		packAll(G.main, reports, false);
	}

	/* don't forget not to return without! */
	WM_cursor_wait(1);
	
	ED_editors_flush_edits(C, false);

	fileflags |= G_FILE_HISTORY; /* write file history */

	/* first time saving */
	/* XXX temp solution to solve bug, real fix coming (ton) */
	if ((G.main->name[0] == '\0') && !(fileflags & G_FILE_SAVE_COPY)) {
		BLI_strncpy(G.main->name, filepath, sizeof(G.main->name));
	}

	/* XXX temp solution to solve bug, real fix coming (ton) */
	G.main->recovered = 0;
	
	if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) {
		if (!(fileflags & G_FILE_SAVE_COPY)) {
			G.relbase_valid = 1;
			BLI_strncpy(G.main->name, filepath, sizeof(G.main->name));  /* is guaranteed current file */
	
			G.save_over = 1; /* disable untitled.blend convention */
		}

		BKE_BIT_TEST_SET(G.fileflags, fileflags & G_FILE_COMPRESS, G_FILE_COMPRESS);
		BKE_BIT_TEST_SET(G.fileflags, fileflags & G_FILE_AUTOPLAY, G_FILE_AUTOPLAY);

		/* prevent background mode scripts from clobbering history */
		if (!G.background) {
			write_history();
		}

		BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST);

		/* run this function after because the file cant be written before the blend is */
		if (ibuf_thumb) {
			IMB_thumb_delete(filepath, THB_FAIL); /* without this a failed thumb overrides */
			ibuf_thumb = IMB_thumb_create(filepath, THB_LARGE, THB_SOURCE_BLEND, ibuf_thumb);
			IMB_freeImBuf(ibuf_thumb);
		}

		if (thumb) MEM_freeN(thumb);
	}
	else {
		if (ibuf_thumb) IMB_freeImBuf(ibuf_thumb);
		if (thumb) MEM_freeN(thumb);
		
		WM_cursor_wait(0);
		return -1;
	}

	WM_cursor_wait(0);
	
	return 0;
}
Example #5
0
/**
 * Scans the directory named *dirname and appends entries for its contents to files.
 */
static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
{
	struct ListBase dirbase = {NULL, NULL};
	int newnum = 0;
	DIR *dir;

	if ((dir = opendir(dirname)) != NULL) {
		const struct dirent *fname;
		while ((fname = readdir(dir)) != NULL) {
			struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
			if (dlink != NULL) {
				dlink->name = BLI_strdup(fname->d_name);
				BLI_addhead(&dirbase, dlink);
				newnum++;
			}
		}

		if (newnum) {
			if (dir_ctx->files) {
				void * const tmp = MEM_reallocN(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
				if (tmp) {
					dir_ctx->files = (struct direntry *)tmp;
				}
				else { /* realloc fail */
					MEM_freeN(dir_ctx->files);
					dir_ctx->files = NULL;
				}
			}
			
			if (dir_ctx->files == NULL)
				dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(struct direntry), __func__);

			if (dir_ctx->files) {
				struct dirlink * dlink = (struct dirlink *) dirbase.first;
				struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles];
				while (dlink) {
					char fullname[PATH_MAX];
					memset(file, 0, sizeof(struct direntry));
					file->relname = dlink->name;
					file->path = BLI_strdupcat(dirname, dlink->name);
					BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name);
					if (BLI_stat(fullname, &file->s) != -1) {
						file->type = file->s.st_mode;
					}
					file->flags = 0;
					dir_ctx->nrfiles++;
					file++;
					dlink = dlink->next;
				}
			}
			else {
				printf("Couldn't get memory for dir\n");
				exit(1);
			}

			BLI_freelist(&dirbase);
			if (dir_ctx->files) {
				qsort(dir_ctx->files, dir_ctx->nrfiles, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
			}
		}
		else {
			printf("%s empty directory\n", dirname);
		}

		closedir(dir);
	}
	else {
		printf("%s non-existent directory\n", dirname);
	}
}
/**
 * The main function for copying DerivedMesh data into BMesh.
 *
 * \note The mesh may already have geometry. see 'is_init'
 */
void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm, const bool calc_face_normal)
{
	MVert *mv, *mvert;
	MEdge *me, *medge;
	MPoly /* *mpoly, */ /* UNUSED */ *mp;
	MLoop *mloop;
	BMVert *v, **vtable;
	BMEdge *e, **etable;
	float (*face_normals)[3];
	BMFace *f;
	int i, j, totvert, totedge /* , totface */ /* UNUSED */ ;
	bool is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0);
	bool is_cddm = (dm->type == DM_TYPE_CDDM);  /* duplicate the arrays for non cddm */
	char has_orig_htype = 0;

	int cd_vert_bweight_offset;
	int cd_edge_bweight_offset;
	int cd_edge_crease_offset;

	if (is_init == false) {
		/* check if we have an origflag */
		has_orig_htype |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0;
		has_orig_htype |= CustomData_has_layer(&bm->edata, CD_ORIGINDEX) ? BM_EDGE : 0;
		has_orig_htype |= CustomData_has_layer(&bm->pdata, CD_ORIGINDEX) ? BM_FACE : 0;
	}

	/*merge custom data layout*/
	CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT);
	CustomData_bmesh_merge(&dm->edgeData, &bm->edata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_EDGE);
	CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_LOOP);
	CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_FACE);

	if (is_init) {
		BM_mesh_cd_flag_apply(bm, dm->cd_flag);
	}

	cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
	cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
	cd_edge_crease_offset  = CustomData_get_offset(&bm->edata, CD_CREASE);

	totvert = dm->getNumVerts(dm);
	totedge = dm->getNumEdges(dm);
	/* totface = dm->getNumPolys(dm); */ /* UNUSED */

	vtable = MEM_mallocN(sizeof(*vtable) * totvert, __func__);
	etable = MEM_mallocN(sizeof(*etable) * totedge, __func__);

	/*do verts*/
	mv = mvert = is_cddm ? dm->getVertArray(dm) : dm->dupVertArray(dm);
	for (i = 0; i < totvert; i++, mv++) {
		v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD);
		normal_short_to_float_v3(v->no, mv->no);
		v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
		BM_elem_index_set(v, i); /* set_inline */

		CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data, true);
		vtable[i] = v;

		/* add bevel weight */
		if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mv->bweight / 255.0f);

		if (UNLIKELY(has_orig_htype & BM_VERT)) {
			int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX);
			*orig_index = ORIGINDEX_NONE;
		}
	}
	if (!is_cddm) MEM_freeN(mvert);
	if (is_init) bm->elem_index_dirty &= ~BM_VERT;

	/*do edges*/
	me = medge = is_cddm ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm);
	for (i = 0; i < totedge; i++, me++) {
		//BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL);
		e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD);

		e->head.hflag = BM_edge_flag_from_mflag(me->flag);
		BM_elem_index_set(e, i); /* set_inline */

		CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true);
		etable[i] = e;

		if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)me->bweight / 255.0f);
		if (cd_edge_crease_offset  != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset,  (float)me->crease  / 255.0f);

		if (UNLIKELY(has_orig_htype & BM_EDGE)) {
			int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX);
			*orig_index = ORIGINDEX_NONE;
		}
	}
	if (!is_cddm) MEM_freeN(medge);
	if (is_init) bm->elem_index_dirty &= ~BM_EDGE;

	/* do faces */
	/* note: i_alt is aligned with bmesh faces which may not always align with mpolys */
	mp = dm->getPolyArray(dm);
	mloop = dm->getLoopArray(dm);
	face_normals = (dm->dirty & DM_DIRTY_NORMALS) ? NULL : CustomData_get_layer(&dm->polyData, CD_NORMAL);
	for (i = 0; i < dm->numPolyData; i++, mp++) {
		BMLoop *l_iter;
		BMLoop *l_first;

		f = bm_face_create_from_mpoly(mp, mloop + mp->loopstart,
		                              bm, vtable, etable);

		if (UNLIKELY(f == NULL)) {
			continue;
		}

		f->head.hflag = BM_face_flag_from_mflag(mp->flag);
		BM_elem_index_set(f, bm->totface - 1); /* set_inline */
		f->mat_nr = mp->mat_nr;

		j = mp->loopstart;
		l_iter = l_first = BM_FACE_FIRST_LOOP(f);
		do {
			/* Save index of correspsonding MLoop */
			CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, j, &l_iter->head.data, true);
			BM_elem_index_set(l_iter, j++); /* set_inline */
		} while ((l_iter = l_iter->next) != l_first);

		CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true);

		if (calc_face_normal) {
			if (face_normals) {
				copy_v3_v3(f->no, face_normals[i]);
			}
			else {
				BM_face_normal_update(f);
			}
		}

		if (UNLIKELY(has_orig_htype & BM_FACE)) {
			int *orig_index = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_ORIGINDEX);
			*orig_index = ORIGINDEX_NONE;
		}
	}
	if (is_init) bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);

	MEM_freeN(vtable);
	MEM_freeN(etable);
}
Example #7
0
/* do not free scene itself */
void BKE_scene_free(Scene *sce)
{
	Base *base;
	SceneRenderLayer *srl;

	/* check all sequences */
	BKE_sequencer_clear_scene_in_allseqs(G.main, sce);

	base = sce->base.first;
	while (base) {
		base->object->id.us--;
		base = base->next;
	}
	/* do not free objects! */
	
	if (sce->gpd) {
#if 0   /* removed since this can be invalid memory when freeing everything */
		/* since the grease pencil data is freed before the scene.
		 * since grease pencil data is not (yet?), shared between objects
		 * its probably safe not to do this, some save and reload will free this. */
		sce->gpd->id.us--;
#endif
		sce->gpd = NULL;
	}

	BLI_freelistN(&sce->base);
	BKE_sequencer_editing_free(sce);

	BKE_free_animdata((ID *)sce);
	BKE_keyingsets_free(&sce->keyingsets);
	
	if (sce->rigidbody_world)
		BKE_rigidbody_free_world(sce->rigidbody_world);
	
	if (sce->r.avicodecdata) {
		free_avicodecdata(sce->r.avicodecdata);
		MEM_freeN(sce->r.avicodecdata);
		sce->r.avicodecdata = NULL;
	}
	if (sce->r.qtcodecdata) {
		free_qtcodecdata(sce->r.qtcodecdata);
		MEM_freeN(sce->r.qtcodecdata);
		sce->r.qtcodecdata = NULL;
	}
	if (sce->r.ffcodecdata.properties) {
		IDP_FreeProperty(sce->r.ffcodecdata.properties);
		MEM_freeN(sce->r.ffcodecdata.properties);
		sce->r.ffcodecdata.properties = NULL;
	}
	
	for (srl = sce->r.layers.first; srl; srl = srl->next) {
		BKE_freestyle_config_free(&srl->freestyleConfig);
	}
	
	BLI_freelistN(&sce->markers);
	BLI_freelistN(&sce->transform_spaces);
	BLI_freelistN(&sce->r.layers);
	
	if (sce->toolsettings) {
		if (sce->toolsettings->vpaint) {
			BKE_paint_free(&sce->toolsettings->vpaint->paint);
			MEM_freeN(sce->toolsettings->vpaint);
		}
		if (sce->toolsettings->wpaint) {
			BKE_paint_free(&sce->toolsettings->wpaint->paint);
			MEM_freeN(sce->toolsettings->wpaint);
		}
		if (sce->toolsettings->sculpt) {
			BKE_paint_free(&sce->toolsettings->sculpt->paint);
			MEM_freeN(sce->toolsettings->sculpt);
		}
		if (sce->toolsettings->uvsculpt) {
			BKE_paint_free(&sce->toolsettings->uvsculpt->paint);
			MEM_freeN(sce->toolsettings->uvsculpt);
		}
		BKE_paint_free(&sce->toolsettings->imapaint.paint);

		MEM_freeN(sce->toolsettings);
		sce->toolsettings = NULL;
	}
	
	DAG_scene_free(sce);
	
	if (sce->nodetree) {
		ntreeFreeTree(sce->nodetree);
		MEM_freeN(sce->nodetree);
	}

	if (sce->stats)
		MEM_freeN(sce->stats);
	if (sce->fps_info)
		MEM_freeN(sce->fps_info);

	sound_destroy_scene(sce);

	BKE_color_managed_view_settings_free(&sce->view_settings);
}
Example #8
0
void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset, int slope)
{
	if(cuma->curve)
		MEM_freeN(cuma->curve);

	switch(preset) {
		case CURVE_PRESET_LINE: cuma->totpoint= 2; break;
		case CURVE_PRESET_SHARP: cuma->totpoint= 4; break;
		case CURVE_PRESET_SMOOTH: cuma->totpoint= 4; break;
		case CURVE_PRESET_MAX: cuma->totpoint= 2; break;
		case CURVE_PRESET_MID9: cuma->totpoint= 9; break;
		case CURVE_PRESET_ROUND: cuma->totpoint= 4; break;
		case CURVE_PRESET_ROOT: cuma->totpoint= 4; break;
	}

	cuma->curve= MEM_callocN(cuma->totpoint*sizeof(CurveMapPoint), "curve points");

	switch(preset) {
		case CURVE_PRESET_LINE:
			cuma->curve[0].x= clipr->xmin;
			cuma->curve[0].y= clipr->ymax;
			cuma->curve[0].flag= 0;
			cuma->curve[1].x= clipr->xmax;
			cuma->curve[1].y= clipr->ymin;
			cuma->curve[1].flag= 0;
			break;
		case CURVE_PRESET_SHARP:
			cuma->curve[0].x= 0;
			cuma->curve[0].y= 1;
			cuma->curve[1].x= 0.25;
			cuma->curve[1].y= 0.50;
			cuma->curve[2].x= 0.75;
			cuma->curve[2].y= 0.04;
			cuma->curve[3].x= 1;
			cuma->curve[3].y= 0;
			break;
		case CURVE_PRESET_SMOOTH:
			cuma->curve[0].x= 0;
			cuma->curve[0].y= 1;
			cuma->curve[1].x= 0.25;
			cuma->curve[1].y= 0.94;
			cuma->curve[2].x= 0.75;
			cuma->curve[2].y= 0.06;
			cuma->curve[3].x= 1;
			cuma->curve[3].y= 0;
			break;
		case CURVE_PRESET_MAX:
			cuma->curve[0].x= 0;
			cuma->curve[0].y= 1;
			cuma->curve[1].x= 1;
			cuma->curve[1].y= 1;
			break;
		case CURVE_PRESET_MID9:
			{
				int i;
				for (i=0; i < cuma->totpoint; i++)
				{
					cuma->curve[i].x= i / ((float)cuma->totpoint-1);
					cuma->curve[i].y= 0.5;
				}
			}
			break;
		case CURVE_PRESET_ROUND:
			cuma->curve[0].x= 0;
			cuma->curve[0].y= 1;
			cuma->curve[1].x= 0.5;
			cuma->curve[1].y= 0.90;
			cuma->curve[2].x= 0.86;
			cuma->curve[2].y= 0.5;
			cuma->curve[3].x= 1;
			cuma->curve[3].y= 0;
			break;
		case CURVE_PRESET_ROOT:
			cuma->curve[0].x= 0;
			cuma->curve[0].y= 1;
			cuma->curve[1].x= 0.25;
			cuma->curve[1].y= 0.95;
			cuma->curve[2].x= 0.75;
			cuma->curve[2].y= 0.44;
			cuma->curve[3].x= 1;
			cuma->curve[3].y= 0;
			break;
	}

	/* mirror curve in x direction to have positive slope
	 * rather than default negative slope */
	if (slope == CURVEMAP_SLOPE_POSITIVE) {
		int i, last=cuma->totpoint-1;
		CurveMapPoint *newpoints= MEM_dupallocN(cuma->curve);
		
		for (i=0; i<cuma->totpoint; i++) {
			newpoints[i].y = cuma->curve[last-i].y;
		}
		
		MEM_freeN(cuma->curve);
		cuma->curve = newpoints;
	}
	
	if(cuma->table) {
		MEM_freeN(cuma->table);
		cuma->table= NULL;
	}
}
Example #9
0
/* only creates a table for a single channel in CurveMapping */
static void curvemap_make_table(CurveMap *cuma, rctf *clipr)
{
	CurveMapPoint *cmp= cuma->curve;
	BezTriple *bezt;
	float *fp, *allpoints, *lastpoint, curf, range;
	int a, totpoint;
	
	if(cuma->curve==NULL) return;
	
	/* default rect also is table range */
	cuma->mintable= clipr->xmin;
	cuma->maxtable= clipr->xmax;
	
	/* hrmf... we now rely on blender ipo beziers, these are more advanced */
	bezt= MEM_callocN(cuma->totpoint*sizeof(BezTriple), "beztarr");
	
	for(a=0; a<cuma->totpoint; a++) {
		cuma->mintable= MIN2(cuma->mintable, cmp[a].x);
		cuma->maxtable= MAX2(cuma->maxtable, cmp[a].x);
		bezt[a].vec[1][0]= cmp[a].x;
		bezt[a].vec[1][1]= cmp[a].y;
		if(cmp[a].flag & CUMA_VECTOR)
			bezt[a].h1= bezt[a].h2= HD_VECT;
		else
			bezt[a].h1= bezt[a].h2= HD_AUTO;
	}
	
	for(a=0; a<cuma->totpoint; a++) {
		if(a==0)
			calchandle_curvemap(bezt, NULL, bezt+1, 0);
		else if(a==cuma->totpoint-1)
			calchandle_curvemap(bezt+a, bezt+a-1, NULL, 0);
		else
			calchandle_curvemap(bezt+a, bezt+a-1, bezt+a+1, 0);
	}
	
	/* first and last handle need correction, instead of pointing to center of next/prev, 
		we let it point to the closest handle */
	if(cuma->totpoint>2) {
		float hlen, nlen, vec[3];
		
		if(bezt[0].h2==HD_AUTO) {
			
			hlen= len_v3v3(bezt[0].vec[1], bezt[0].vec[2]);	/* original handle length */
			/* clip handle point */
			VECCOPY(vec, bezt[1].vec[0]);
			if(vec[0] < bezt[0].vec[1][0])
				vec[0]= bezt[0].vec[1][0];
			
			sub_v3_v3(vec, bezt[0].vec[1]);
			nlen= len_v3(vec);
			if(nlen>FLT_EPSILON) {
				mul_v3_fl(vec, hlen/nlen);
				add_v3_v3v3(bezt[0].vec[2], vec, bezt[0].vec[1]);
				sub_v3_v3v3(bezt[0].vec[0], bezt[0].vec[1], vec);
			}
		}
		a= cuma->totpoint-1;
		if(bezt[a].h2==HD_AUTO) {
			
			hlen= len_v3v3(bezt[a].vec[1], bezt[a].vec[0]);	/* original handle length */
			/* clip handle point */
			VECCOPY(vec, bezt[a-1].vec[2]);
			if(vec[0] > bezt[a].vec[1][0])
				vec[0]= bezt[a].vec[1][0];
			
			sub_v3_v3(vec, bezt[a].vec[1]);
			nlen= len_v3(vec);
			if(nlen>FLT_EPSILON) {
				mul_v3_fl(vec, hlen/nlen);
				add_v3_v3v3(bezt[a].vec[0], vec, bezt[a].vec[1]);
				sub_v3_v3v3(bezt[a].vec[2], bezt[a].vec[1], vec);
			}
		}
	}	
	/* make the bezier curve */
	if(cuma->table)
		MEM_freeN(cuma->table);
	totpoint= (cuma->totpoint-1)*CM_RESOL;
	fp= allpoints= MEM_callocN(totpoint*2*sizeof(float), "table");
	
	for(a=0; a<cuma->totpoint-1; a++, fp += 2*CM_RESOL) {
		correct_bezpart(bezt[a].vec[1], bezt[a].vec[2], bezt[a+1].vec[0], bezt[a+1].vec[1]);
		forward_diff_bezier(bezt[a].vec[1][0], bezt[a].vec[2][0], bezt[a+1].vec[0][0], bezt[a+1].vec[1][0], fp, CM_RESOL-1, 2*sizeof(float));	
		forward_diff_bezier(bezt[a].vec[1][1], bezt[a].vec[2][1], bezt[a+1].vec[0][1], bezt[a+1].vec[1][1], fp+1, CM_RESOL-1, 2*sizeof(float));
	}
	
	/* store first and last handle for extrapolation, unit length */
	cuma->ext_in[0]= bezt[0].vec[0][0] - bezt[0].vec[1][0];
	cuma->ext_in[1]= bezt[0].vec[0][1] - bezt[0].vec[1][1];
	range= sqrt(cuma->ext_in[0]*cuma->ext_in[0] + cuma->ext_in[1]*cuma->ext_in[1]);
	cuma->ext_in[0]/= range;
	cuma->ext_in[1]/= range;
	
	a= cuma->totpoint-1;
	cuma->ext_out[0]= bezt[a].vec[1][0] - bezt[a].vec[2][0];
	cuma->ext_out[1]= bezt[a].vec[1][1] - bezt[a].vec[2][1];
	range= sqrt(cuma->ext_out[0]*cuma->ext_out[0] + cuma->ext_out[1]*cuma->ext_out[1]);
	cuma->ext_out[0]/= range;
	cuma->ext_out[1]/= range;
	
	/* cleanup */
	MEM_freeN(bezt);

	range= CM_TABLEDIV*(cuma->maxtable - cuma->mintable);
	cuma->range= 1.0f/range;
	
	/* now make a table with CM_TABLE equal x distances */
	fp= allpoints;
	lastpoint= allpoints + 2*(totpoint-1);
	cmp= MEM_callocN((CM_TABLE+1)*sizeof(CurveMapPoint), "dist table");
	
	for(a=0; a<=CM_TABLE; a++) {
		curf= cuma->mintable + range*(float)a;
		cmp[a].x= curf;
		
		/* get the first x coordinate larger than curf */
		while(curf >= fp[0] && fp!=lastpoint) {
			fp+=2;
		}
		if(fp==allpoints || (curf >= fp[0] && fp==lastpoint))
			cmp[a].y= curvemap_calc_extend(cuma, curf, allpoints, lastpoint);
		else {
			float fac1= fp[0] - fp[-2];
			float fac2= fp[0] - curf;
			if(fac1 > FLT_EPSILON)
				fac1= fac2/fac1;
			else
				fac1= 0.0f;
			cmp[a].y= fac1*fp[-1] + (1.0f-fac1)*fp[1];
		}
	}
	
	MEM_freeN(allpoints);
	cuma->table= cmp;
}
Example #10
0
static int convert_include(const char *filename)
{
	/* read include file, skip structs with a '#' before it.
	 * store all data in temporal arrays.
	 */
	int filelen, count, slen, type, name, strct;
	short *structpoin, *sp;
	char *maindata, *mainend, *md, *md1;
	bool skip_struct;

	md = maindata = read_file_data(filename, &filelen);
	if (filelen == -1) {
		fprintf(stderr, "Can't read file %s\n", filename);
		return 1;
	}

	filelen = preprocess_include(maindata, filelen);
	mainend = maindata + filelen - 1;

	/* we look for '{' and then back to 'struct' */
	count = 0;
	skip_struct = false;
	while (count < filelen) {

		/* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */
		if (md[0] == '#' && md[1] == ' ' && md[2] == '#') {
			skip_struct = true;
		}

		if (md[0] == '{') {
			md[0] = 0;
			if (skip_struct) {
				skip_struct = false;
			}
			else {
				if (md[-1] == ' ') md[-1] = 0;
				md1 = md - 2;
				while (*md1 != 32) md1--;       /* to beginning of word */
				md1++;

				/* we've got a struct name when... */
				if (strncmp(md1 - 7, "struct", 6) == 0) {

					strct = add_type(md1, 0);
					if (strct == -1) {
						fprintf(stderr, "File '%s' contains struct we cant parse \"%s\"\n", filename, md1);
						return 1;
					}

					structpoin = add_struct(strct);
					sp = structpoin + 2;

					if (debugSDNA > 1) printf("\t|\t|-- detected struct %s\n", types[strct]);

					/* first lets make it all nice strings */
					md1 = md + 1;
					while (*md1 != '}') {
						if (md1 > mainend) break;

						if (*md1 == ',' || *md1 == ' ') *md1 = 0;
						md1++;
					}

					/* read types and names until first character that is not '}' */
					md1 = md + 1;
					while (*md1 != '}') {
						if (md1 > mainend) break;

						/* skip when it says 'struct' or 'unsigned' or 'const' */
						if (*md1) {
							if (strncmp(md1, "struct", 6) == 0) md1 += 7;
							if (strncmp(md1, "unsigned", 8) == 0) md1 += 9;
							if (strncmp(md1, "const", 5) == 0) md1 += 6;

							/* we've got a type! */
							type = add_type(md1, 0);
							if (type == -1) {
								fprintf(stderr, "File '%s' contains struct we can't parse \"%s\"\n", filename, md1);
								return 1;
							}

							if (debugSDNA > 1) printf("\t|\t|\tfound type %s (", md1);

							md1 += strlen(md1);


							/* read until ';' */
							while (*md1 != ';') {
								if (md1 > mainend) break;

								if (*md1) {
									/* We've got a name. slen needs
									 * correction for function
									 * pointers! */
									slen = (int) strlen(md1);
									if (md1[slen - 1] == ';') {
										md1[slen - 1] = 0;


										name = add_name(md1);
										slen += additional_slen_offset;
										sp[0] = type;
										sp[1] = name;

										if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s |", names[name]);

										structpoin[1]++;
										sp += 2;

										md1 += slen;
										break;
									}


									name = add_name(md1);
									slen += additional_slen_offset;

									sp[0] = type;
									sp[1] = name;
									if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s ||", names[name]);

									structpoin[1]++;
									sp += 2;

									md1 += slen;
								}
								md1++;
							}

							if (debugSDNA > 1) printf(")\n");

						}
						md1++;
					}
				}
			}
		}
		count++;
		md++;
	}

	MEM_freeN(maindata);

	return 0;
}
Example #11
0
static int make_structDNA(const char *baseDirectory, FILE *file, FILE *file_offsets)
{
	int len, i;
	const short *sp;
	/* str contains filenames. Since we now include paths, I stretched       */
	/* it a bit. Hope this is enough :) -nzc-                                */
	char str[SDNA_MAX_FILENAME_LENGTH], *cp;
	int firststruct;

	if (debugSDNA > 0) {
		fflush(stdout);
		printf("Running makesdna at debug level %d\n", debugSDNA);
	}

	/* the longest known struct is 50k, so we assume 100k is sufficient! */
	namedata = MEM_callocN(maxdata, "namedata");
	typedata = MEM_callocN(maxdata, "typedata");
	structdata = MEM_callocN(maxdata, "structdata");

	/* a maximum of 5000 variables, must be sufficient? */
	names = MEM_callocN(sizeof(char *) * maxnr, "names");
	types = MEM_callocN(sizeof(char *) * maxnr, "types");
	typelens_native = MEM_callocN(sizeof(short) * maxnr, "typelens_native");
	typelens_32 = MEM_callocN(sizeof(short) * maxnr, "typelens_32");
	typelens_64 = MEM_callocN(sizeof(short) * maxnr, "typelens_64");
	structs = MEM_callocN(sizeof(short *) * maxnr, "structs");

	/**
	 * Insertion of all known types.
	 *
	 * \warning Order of function calls here must be aligned with #eSDNA_Type.
	 * \warning uint is not allowed! use in structs an unsigned int.
	 * \warning sizes must match #DNA_elem_type_size().
	 */
	add_type("char", 1);     /* SDNA_TYPE_CHAR */
	add_type("uchar", 1);    /* SDNA_TYPE_UCHAR */
	add_type("short", 2);    /* SDNA_TYPE_SHORT */
	add_type("ushort", 2);   /* SDNA_TYPE_USHORT */
	add_type("int", 4);      /* SDNA_TYPE_INT */

	/* note, long isn't supported,
	 * these are place-holders to maintain alignment with eSDNA_Type*/
	add_type("long", 4);     /* SDNA_TYPE_LONG */
	add_type("ulong", 4);    /* SDNA_TYPE_ULONG */

	add_type("float", 4);    /* SDNA_TYPE_FLOAT */
	add_type("double", 8);   /* SDNA_TYPE_DOUBLE */
	add_type("int64_t", 8);  /* SDNA_TYPE_INT64 */
	add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */
	add_type("void", 0);     /* SDNA_TYPE_VOID */

	/* the defines above shouldn't be output in the padding file... */
	firststruct = nr_types;

	/* add all include files defined in the global array                     */
	/* Since the internal file+path name buffer has limited length, I do a   */
	/* little test first...                                                  */
	/* Mind the breaking condition here!                                     */
	if (debugSDNA) printf("\tStart of header scan:\n");
	for (i = 0; *(includefiles[i]) != '\0'; i++) {
		sprintf(str, "%s%s", baseDirectory, includefiles[i]);
		if (debugSDNA) printf("\t|-- Converting %s\n", str);
		if (convert_include(str)) {
			return (1);
		}
	}
	if (debugSDNA) printf("\tFinished scanning %d headers.\n", i);

	if (calculate_structlens(firststruct)) {
		/* error */
		return(1);
	}

	/* FOR DEBUG */
	if (debugSDNA > 1) {
		int a, b;
		/* short *elem; */
		short num_types;

		printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs);
		for (a = 0; a < nr_names; a++) {
			printf(" %s\n", names[a]);
		}
		printf("\n");

		sp = typelens_native;
		for (a = 0; a < nr_types; a++, sp++) {
			printf(" %s %d\n", types[a], *sp);
		}
		printf("\n");

		for (a = 0; a < nr_structs; a++) {
			sp = structs[a];
			printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], typelens_native[sp[0]]);
			num_types  = sp[1];
			sp += 2;
			/* ? num_types was elem? */
			for (b = 0; b < num_types; b++, sp += 2) {
				printf("   %s %s\n", types[sp[0]], names[sp[1]]);
			}
		}
	}

	/* file writing */

	if (debugSDNA > 0) printf("Writing file ... ");

	if (nr_names == 0 || nr_structs == 0) {
		/* pass */
	}
	else {
		dna_write(file, "SDNA", 4);

		/* write names */
		dna_write(file, "NAME", 4);
		len = nr_names;
		dna_write(file, &len, 4);

		/* calculate size of datablock with strings */
		cp = names[nr_names - 1];
		cp += strlen(names[nr_names - 1]) + 1;         /* +1: null-terminator */
		len = (intptr_t) (cp - (char *) names[0]);
		len = (len + 3) & ~3;
		dna_write(file, names[0], len);

		/* write TYPES */
		dna_write(file, "TYPE", 4);
		len = nr_types;
		dna_write(file, &len, 4);

		/* calculate datablock size */
		cp = types[nr_types - 1];
		cp += strlen(types[nr_types - 1]) + 1;     /* +1: null-terminator */
		len = (intptr_t) (cp - (char *) types[0]);
		len = (len + 3) & ~3;

		dna_write(file, types[0], len);

		/* WRITE TYPELENGTHS */
		dna_write(file, "TLEN", 4);

		len = 2 * nr_types;
		if (nr_types & 1) len += 2;
		dna_write(file, typelens_native, len);

		/* WRITE STRUCTS */
		dna_write(file, "STRC", 4);
		len = nr_structs;
		dna_write(file, &len, 4);

		/* calc datablock size */
		sp = structs[nr_structs - 1];
		sp += 2 + 2 * (sp[1]);
		len = (intptr_t) ((char *) sp - (char *) structs[0]);
		len = (len + 3) & ~3;

		dna_write(file, structs[0], len);

		/* a simple dna padding test */
		if (0) {
			FILE *fp;
			int a;

			fp = fopen("padding.c", "w");
			if (fp == NULL) {
				/* pass */
			}
			else {

				/* add all include files defined in the global array */
				for (i = 0; *(includefiles[i]) != '\0'; i++) {
					fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]);
				}

				fprintf(fp, "main() {\n");
				sp = typelens_native;
				sp += firststruct;
				for (a = firststruct; a < nr_types; a++, sp++) {
					if (*sp) {
						fprintf(fp, "\tif (sizeof(struct %s) - %d) printf(\"ALIGN ERROR:", types[a], *sp);
						fprintf(fp, "%%d %s %d ", types[a], *sp);
						fprintf(fp, "\\n\",  sizeof(struct %s) - %d);\n", types[a], *sp);
					}
				}
				fprintf(fp, "}\n");
				fclose(fp);
			}
		}
		/*	end end padding test */
	}

	/* write a simple enum with all structs offsets,
	 * should only be accessed via SDNA_TYPE_FROM_STRUCT macro */
	{
		fprintf(file_offsets, "#define SDNA_TYPE_FROM_STRUCT(id) _SDNA_TYPE_##id\n");
		fprintf(file_offsets, "enum {\n");
		for (i = 0; i < nr_structs; i++) {
			const short *structpoin = structs[i];
			const int    structtype = structpoin[0];
			fprintf(file_offsets, "\t_SDNA_TYPE_%s = %d,\n", types[structtype], i);
		}
		fprintf(file_offsets, "\tSDNA_TYPE_MAX = %d,\n", nr_structs);
		fprintf(file_offsets, "};\n");
	}

	MEM_freeN(namedata);
	MEM_freeN(typedata);
	MEM_freeN(structdata);
	MEM_freeN(names);
	MEM_freeN(types);
	MEM_freeN(typelens_native);
	MEM_freeN(typelens_32);
	MEM_freeN(typelens_64);
	MEM_freeN(structs);

	if (debugSDNA > 0) printf("done.\n");

	return(0);
}
Example #12
0
static int preprocess_include(char *maindata, int len)
{
	int a, newlen, comment = 0;
	char *cp, *temp, *md;

	/* note: len + 1, last character is a dummy to prevent
	 * comparisons using uninitialized memory */
	temp = MEM_mallocN(len + 1, "preprocess_include");
	temp[len] = ' ';

	memcpy(temp, maindata, len);

	/* remove all c++ comments */
	/* replace all enters/tabs/etc with spaces */
	cp = temp;
	a = len;
	comment = 0;
	while (a--) {
		if (cp[0] == '/' && cp[1] == '/') {
			comment = 1;
		}
		else if (*cp == '\n') {
			comment = 0;
		}
		if (comment || *cp < 32 || *cp > 128) *cp = 32;
		cp++;
	}


	/* data from temp copy to maindata, remove comments and double spaces */
	cp = temp;
	md = maindata;
	newlen = 0;
	comment = 0;
	a = len;
	while (a--) {

		if (cp[0] == '/' && cp[1] == '*') {
			comment = 1;
			cp[0] = cp[1] = 32;
		}
		if (cp[0] == '*' && cp[1] == '/') {
			comment = 0;
			cp[0] = cp[1] = 32;
		}

		/* do not copy when: */
		if (comment) {
			/* pass */
		}
		else if (cp[0] == ' ' && cp[1] == ' ') {
			/* pass */
		}
		else if (cp[-1] == '*' && cp[0] == ' ') {
			/* pointers with a space */
		}	/* skip special keywords */
		else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) {
			/* single values are skipped already, so decrement 1 less */
			a -= 13;
			cp += 13;
		}
		else {
			md[0] = cp[0];
			md++;
			newlen++;
		}
		cp++;
	}

	MEM_freeN(temp);
	return newlen;
}
Example #13
0
static int find_nearest_diff_point(const bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather,
                                   MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r,
                                   float *u_r, float tangent[2],
                                   const short use_deform)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);

	MaskLayer *masklay, *point_masklay;
	MaskSpline *point_spline;
	MaskSplinePoint *point = NULL;
	float dist = FLT_MAX, co[2];
	int width, height;
	float u;
	float scalex, scaley;

	ED_mask_get_size(sa, &width, &height);
	ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);

	co[0] = normal_co[0] * scalex;
	co[1] = normal_co[1] * scaley;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			int i;
			MaskSplinePoint *cur_point;

			for (i = 0, cur_point = use_deform ? spline->points_deform : spline->points;
			     i < spline->tot_point;
			     i++, cur_point++)
			{
				float *diff_points;
				unsigned int tot_diff_point;

				diff_points = BKE_mask_point_segment_diff_with_resolution(spline, cur_point, width, height,
				                                                          &tot_diff_point);

				if (diff_points) {
					int j, tot_point;
					unsigned int tot_feather_point;
					float *feather_points = NULL, *points;

					if (feather) {
						feather_points = BKE_mask_point_segment_feather_diff_with_resolution(spline, cur_point,
						                                                                     width, height,
						                                                                     &tot_feather_point);

						points = feather_points;
						tot_point = tot_feather_point;
					}
					else {
						points = diff_points;
						tot_point = tot_diff_point;
					}

					for (j = 0; j < tot_point - 1; j++) {
						float cur_dist, a[2], b[2];

						a[0] = points[2 * j] * scalex;
						a[1] = points[2 * j + 1] * scaley;

						b[0] = points[2 * j + 2] * scalex;
						b[1] = points[2 * j + 3] * scaley;

						cur_dist = dist_to_line_segment_v2(co, a, b);

						if (cur_dist < dist) {
							if (tangent)
								sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]);

							point_masklay = masklay;
							point_spline = spline;
							point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point;
							dist = cur_dist;
							u = (float)j / tot_point;

						}
					}

					if (feather_points)
						MEM_freeN(feather_points);

					MEM_freeN(diff_points);
				}
			}
		}
	}

	if (point && dist < threshold) {
		if (masklay_r)
			*masklay_r = point_masklay;

		if (spline_r)
			*spline_r = point_spline;

		if (point_r)
			*point_r = point;

		if (u_r) {
			u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY);

			*u_r = u;
		}

		return TRUE;
	}

	if (masklay_r)
		*masklay_r = NULL;

	if (spline_r)
		*spline_r = NULL;

	if (point_r)
		*point_r = NULL;

	return FALSE;
}
Example #14
0
void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track)
{
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingStabilization *stab = &tracking->stabilization;
	MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
	MovieTrackingPlaneTrack *plane_track, *next_plane_track;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
	bool has_bundle = false, update_stab = false;
	char track_name_escaped[MAX_NAME], prefix[MAX_NAME * 2];

	if (track == act_track)
		tracking->act_track = NULL;

	if (track == stab->rot_track) {
		stab->rot_track = NULL;

		update_stab = true;
	}

	/* handle reconstruction display in 3d viewport */
	if (track->flag & TRACK_HAS_BUNDLE)
		has_bundle = true;

	/* Make sure no plane will use freed track */
	for (plane_track = plane_tracks_base->first;
	     plane_track;
	     plane_track = next_plane_track)
	{
		bool found = false;
		int i;

		next_plane_track = plane_track->next;

		for (i = 0; i < plane_track->point_tracksnr; i++) {
			if (plane_track->point_tracks[i] == track) {
				found = true;
				break;
			}
		}

		if (!found) {
			continue;
		}

		if (plane_track->point_tracksnr > 4) {
			int track_index;
			MovieTrackingTrack **new_point_tracks;

			new_point_tracks = MEM_mallocN(sizeof(*new_point_tracks) * plane_track->point_tracksnr,
			                               "new point tracks array");

			for (i = 0, track_index = 0; i < plane_track->point_tracksnr; i++) {
				if (plane_track->point_tracks[i] != track) {
					new_point_tracks[track_index++] = plane_track->point_tracks[i];
				}
			}

			MEM_freeN(plane_track->point_tracks);
			plane_track->point_tracks = new_point_tracks;
			plane_track->point_tracksnr--;
		}
		else {
			/* Delete planes with less than 3 point tracks in it. */
			BKE_tracking_plane_track_free(plane_track);
			BLI_freelinkN(plane_tracks_base, plane_track);
		}
	}

	/* Delete f-curves associated with the track (such as weight, i.e.) */
	BLI_strescape(track_name_escaped, track->name, sizeof(track_name_escaped));
	BLI_snprintf(prefix, sizeof(prefix), "tracks[\"%s\"]", track_name_escaped);
	BKE_animdata_fix_paths_remove(&clip->id, prefix);

	BKE_tracking_track_free(track);
	BLI_freelinkN(tracksbase, track);

	WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);

	if (update_stab) {
		tracking->stabilization.ok = false;
		WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip);
	}

	DAG_id_tag_update(&clip->id, 0);

	if (has_bundle)
		WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
Example #15
0
void BKE_free_ocean_cache(struct OceanCache *och)
{
	if (!och) return;

	MEM_freeN(och);
}
Example #16
0
void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
{
	int x, y, c;
	unsigned int n, nl;
	double div, divl;
	float *rf=NULL;
	unsigned char *rc=NULL;
	unsigned int *bin_r, *bin_g, *bin_b, *bin_lum;
	int savedlines, saveline;
	float rgb[3], ycc[3], luma;
	int ycc_mode=-1;
	const short is_float = (ibuf->rect_float != NULL);

	if (ibuf->rect==NULL && ibuf->rect_float==NULL) return;

	if (scopes->ok == 1 ) return;

	if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f;

	/* hmmmm */
	if (!(ELEM(ibuf->channels, 3, 4))) return;

	scopes->hist.channels = 3;
	scopes->hist.x_resolution = 256;

	switch (scopes->wavefrm_mode) {
		case SCOPES_WAVEFRM_RGB:
			ycc_mode = -1;
			break;
		case SCOPES_WAVEFRM_LUMA:
		case SCOPES_WAVEFRM_YCC_JPEG:
			ycc_mode = BLI_YCC_JFIF_0_255;
			break;
		case SCOPES_WAVEFRM_YCC_601:
			ycc_mode = BLI_YCC_ITU_BT601;
			break;
		case SCOPES_WAVEFRM_YCC_709:
			ycc_mode = BLI_YCC_ITU_BT709;
			break;
	}

	/* temp table to count pix value for histo */
	bin_r = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
	bin_g = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
	bin_b = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
	bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");

	/* convert to number of lines with logarithmic scale */
	scopes->sample_lines = (scopes->accuracy*0.01f) * (scopes->accuracy*0.01f) * ibuf->y;
	
	if (scopes->sample_full)
		scopes->sample_lines = ibuf->y;

	/* scan the image */
	savedlines=0;
	for (c=0; c<3; c++) {
		scopes->minmax[c][0]=25500.0f;
		scopes->minmax[c][1]=-25500.0f;
	}
	
	scopes->waveform_tot = ibuf->x*scopes->sample_lines;
	
	if (scopes->waveform_1)
		MEM_freeN(scopes->waveform_1);
	if (scopes->waveform_2)
		MEM_freeN(scopes->waveform_2);
	if (scopes->waveform_3)
		MEM_freeN(scopes->waveform_3);
	if (scopes->vecscope)
		MEM_freeN(scopes->vecscope);
	
	scopes->waveform_1= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 1");
	scopes->waveform_2= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 2");
	scopes->waveform_3= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3");
	scopes->vecscope= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel");
	
	if (is_float)
		rf = ibuf->rect_float;
	else
		rc = (unsigned char *)ibuf->rect;

	for (y = 0; y < ibuf->y; y++) {
		if (savedlines<scopes->sample_lines && y>=((savedlines)*ibuf->y)/(scopes->sample_lines+1)) {
			saveline=1;
		} else saveline=0;
		for (x = 0; x < ibuf->x; x++) {

			if (is_float) {
				if (use_color_management)
					linearrgb_to_srgb_v3_v3(rgb, rf);
				else
					copy_v3_v3(rgb, rf);
			}
			else {
				for (c=0; c<3; c++)
					rgb[c] = rc[c] * INV_255;
			}

			/* we still need luma for histogram */
			luma = 0.299f * rgb[0] + 0.587f * rgb[1] + 0.114f * rgb[2];

			/* check for min max */
			if(ycc_mode == -1 ) {
				for (c=0; c<3; c++) {
					if (rgb[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgb[c];
					if (rgb[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgb[c];
				}
			}
			else {
				rgb_to_ycc(rgb[0],rgb[1],rgb[2],&ycc[0],&ycc[1],&ycc[2], ycc_mode);
				for (c=0; c<3; c++) {
					ycc[c] *=INV_255;
					if (ycc[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = ycc[c];
					if (ycc[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = ycc[c];
				}
			}
			/* increment count for histo*/
			bin_r[ get_bin_float(rgb[0]) ] += 1;
			bin_g[ get_bin_float(rgb[1]) ] += 1;
			bin_b[ get_bin_float(rgb[2]) ] += 1;
			bin_lum[ get_bin_float(luma) ] += 1;

			/* save sample if needed */
			if(saveline) {
				const float fx = (float)x / (float)ibuf->x;
				const int idx = 2*(ibuf->x*savedlines+x);
				save_sample_line(scopes, idx, fx, rgb, ycc);
			}

			rf+= ibuf->channels;
			rc+= ibuf->channels;
		}
		if (saveline)
			savedlines +=1;
	}

	/* convert hist data to float (proportional to max count) */
	n=0;
	nl=0;
	for (x=0; x<256; x++) {
		if (bin_r[x] > n)
			n = bin_r[x];
		if (bin_g[x] > n)
			n = bin_g[x];
		if (bin_b[x] > n)
			n = bin_b[x];
		if (bin_lum[x] > nl)
			nl = bin_lum[x];
	}
	div = 1.0/(double)n;
	divl = 1.0/(double)nl;
	for (x=0; x<256; x++) {
		scopes->hist.data_r[x] = bin_r[x] * div;
		scopes->hist.data_g[x] = bin_g[x] * div;
		scopes->hist.data_b[x] = bin_b[x] * div;
		scopes->hist.data_luma[x] = bin_lum[x] * divl;
	}
	MEM_freeN(bin_r);
	MEM_freeN(bin_g);
	MEM_freeN(bin_b);
	MEM_freeN(bin_lum);

	scopes->ok = 1;
}
Example #17
0
void BKE_free_ocean_data(struct Ocean *oc)
{
	if (!oc) return;

	BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_WRITE);

	BLI_lock_thread(LOCK_FFTW);

	if (oc->_do_disp_y) {
		fftw_destroy_plan(oc->_disp_y_plan);
		MEM_freeN(oc->_disp_y);
	}

	if (oc->_do_normals) {
		MEM_freeN(oc->_fft_in_nx);
		MEM_freeN(oc->_fft_in_nz);
		fftw_destroy_plan(oc->_N_x_plan);
		fftw_destroy_plan(oc->_N_z_plan);
		MEM_freeN(oc->_N_x);
		/*fftwf_free(oc->_N_y); (MEM01)*/
		MEM_freeN(oc->_N_z);
	}

	if (oc->_do_chop) {
		MEM_freeN(oc->_fft_in_x);
		MEM_freeN(oc->_fft_in_z);
		fftw_destroy_plan(oc->_disp_x_plan);
		fftw_destroy_plan(oc->_disp_z_plan);
		MEM_freeN(oc->_disp_x);
		MEM_freeN(oc->_disp_z);
	}

	if (oc->_do_jacobian) {
		MEM_freeN(oc->_fft_in_jxx);
		MEM_freeN(oc->_fft_in_jzz);
		MEM_freeN(oc->_fft_in_jxz);
		fftw_destroy_plan(oc->_Jxx_plan);
		fftw_destroy_plan(oc->_Jzz_plan);
		fftw_destroy_plan(oc->_Jxz_plan);
		MEM_freeN(oc->_Jxx);
		MEM_freeN(oc->_Jzz);
		MEM_freeN(oc->_Jxz);
	}

	BLI_unlock_thread(LOCK_FFTW);

	if (oc->_fft_in)
		MEM_freeN(oc->_fft_in);

	/* check that ocean data has been initialized */
	if (oc->_htilda) {
		MEM_freeN(oc->_htilda);
		MEM_freeN(oc->_k);
		MEM_freeN(oc->_h0);
		MEM_freeN(oc->_h0_minus);
		MEM_freeN(oc->_kx);
		MEM_freeN(oc->_kz);
	}

	BLI_rw_mutex_unlock(&oc->oceanmutex);
}
Example #18
0
static void flyEvent(bContext *C, wmOperator *op, FlyInfo *fly, const wmEvent *event)
{
	if (event->type == TIMER && event->customdata == fly->timer) {
		fly->redraw = 1;
	}
	else if (event->type == MOUSEMOVE) {
		copy_v2_v2_int(fly->mval, event->mval);
	}
	else if (event->type == NDOF_MOTION) {
		/* do these automagically get delivered? yes. */
		// puts("ndof motion detected in fly mode!");
		// static const char *tag_name = "3D mouse position";

		const wmNDOFMotionData *incoming_ndof = event->customdata;
		switch (incoming_ndof->progress) {
			case P_STARTING:
				/* start keeping track of 3D mouse position */
#ifdef NDOF_FLY_DEBUG
				puts("start keeping track of 3D mouse position");
#endif
				/* fall-through */
			case P_IN_PROGRESS:
				/* update 3D mouse position */
#ifdef NDOF_FLY_DEBUG
				putchar('.'); fflush(stdout);
#endif
				if (fly->ndof == NULL) {
					// fly->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
					fly->ndof = MEM_dupallocN(incoming_ndof);
					// fly->ndof = malloc(sizeof(wmNDOFMotionData));
				}
				else {
					memcpy(fly->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
				}
				break;
			case P_FINISHING:
				/* stop keeping track of 3D mouse position */
#ifdef NDOF_FLY_DEBUG
				puts("stop keeping track of 3D mouse position");
#endif
				if (fly->ndof) {
					MEM_freeN(fly->ndof);
					// free(fly->ndof);
					fly->ndof = NULL;
				}
				/* update the time else the view will jump when 2D mouse/timer resume */
				fly->time_lastdraw = PIL_check_seconds_timer();
				break;
			default:
				break; /* should always be one of the above 3 */
		}
	}
	/* handle modal keymap first */
	else if (event->type == EVT_MODAL_MAP) {
		switch (event->val) {
			case FLY_MODAL_CANCEL:
				fly->state = FLY_CANCEL;
				break;
			case FLY_MODAL_CONFIRM:
				fly->state = FLY_CONFIRM;
				break;
				
			/* speed adjusting with mousepan (trackpad) */
			case FLY_MODAL_SPEED:
			{
				float fac = 0.02f * (event->prevy - event->y);
				
				/* allowing to brake immediate */
				if (fac > 0.0f && fly->speed < 0.0f)
					fly->speed = 0.0f;
				else if (fac < 0.0f && fly->speed > 0.0f)
					fly->speed = 0.0f;
				else
					fly->speed += fly->grid * fac;
				
				break;
			}
			case FLY_MODAL_ACCELERATE:
			{
				double time_currwheel;
				float time_wheel;

				/* not quite correct but avoids confusion WASD/arrow keys 'locking up' */
				if (fly->axis == -1) {
					fly->axis = 2;
					fly->speed = fabsf(fly->speed);
				}

				time_currwheel = PIL_check_seconds_timer();
				time_wheel = (float)(time_currwheel - fly->time_lastwheel);
				fly->time_lastwheel = time_currwheel;
				/* Mouse wheel delays range from (0.5 == slow) to (0.01 == fast) */
				time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */

				if (fly->speed < 0.0f) {
					fly->speed = 0.0f;
				}
				else {
					fly->speed += fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
				}
				break;
			}
			case FLY_MODAL_DECELERATE:
			{
				double time_currwheel;
				float time_wheel;

				/* not quite correct but avoids confusion WASD/arrow keys 'locking up' */
				if (fly->axis == -1) {
					fly->axis = 2;
					fly->speed = -fabsf(fly->speed);
				}

				time_currwheel = PIL_check_seconds_timer();
				time_wheel = (float)(time_currwheel - fly->time_lastwheel);
				fly->time_lastwheel = time_currwheel;
				time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */

				if (fly->speed > 0.0f) {
					fly->speed = 0;
				}
				else {
					fly->speed -= fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
				}
				break;
			}
			case FLY_MODAL_PAN_ENABLE:
				fly->pan_view = true;
				break;
			case FLY_MODAL_PAN_DISABLE:
				fly->pan_view = false;
				break;

			/* implement WASD keys,
			 * comments only for 'forward '*/
			case FLY_MODAL_DIR_FORWARD:
				if (fly->axis == 2 && fly->speed < 0.0f) { /* reverse direction stops, tap again to continue */
					fly->axis = -1;
				}
				else {
					/* flip speed rather than stopping, game like motion,
					 * else increase like mousewheel if were already moving in that direction */
					if (fly->speed < 0.0f)   fly->speed = -fly->speed;
					else if (fly->axis == 2) fly->speed += fly->grid;
					fly->axis = 2;
				}
				break;
			case FLY_MODAL_DIR_BACKWARD:
				if (fly->axis == 2 && fly->speed > 0.0f) {
					fly->axis = -1;
				}
				else {
					if (fly->speed > 0.0f)   fly->speed = -fly->speed;
					else if (fly->axis == 2) fly->speed -= fly->grid;

					fly->axis = 2;
				}
				break;
			case FLY_MODAL_DIR_LEFT:
				if (fly->axis == 0 && fly->speed < 0.0f) {
					fly->axis = -1;
				}
				else {
					if (fly->speed < 0.0f)   fly->speed = -fly->speed;
					else if (fly->axis == 0) fly->speed += fly->grid;

					fly->axis = 0;
				}
				break;
			case FLY_MODAL_DIR_RIGHT:
				if (fly->axis == 0 && fly->speed > 0.0f) {
					fly->axis = -1;
				}
				else {
					if (fly->speed > 0.0f)   fly->speed = -fly->speed;
					else if (fly->axis == 0) fly->speed -= fly->grid;

					fly->axis = 0;
				}
				break;
			case FLY_MODAL_DIR_DOWN:
				if (fly->axis == 1 && fly->speed < 0.0f) {
					fly->axis = -1;
				}
				else {
					if (fly->speed < 0.0f)   fly->speed = -fly->speed;
					else if (fly->axis == 1) fly->speed += fly->grid;
					fly->axis = 1;
				}
				break;
			case FLY_MODAL_DIR_UP:
				if (fly->axis == 1 && fly->speed > 0.0f) {
					fly->axis = -1;
				}
				else {
					if (fly->speed > 0.0f)   fly->speed = -fly->speed;
					else if (fly->axis == 1) fly->speed -= fly->grid;
					fly->axis = 1;
				}
				break;

			case FLY_MODAL_AXIS_LOCK_X:
				if (fly->xlock != FLY_AXISLOCK_STATE_OFF)
					fly->xlock = FLY_AXISLOCK_STATE_OFF;
				else {
					fly->xlock = FLY_AXISLOCK_STATE_ACTIVE;
					fly->xlock_momentum = 0.0;
				}
				fly_update_header(C, op, fly);
				break;
			case FLY_MODAL_AXIS_LOCK_Z:
				if (fly->zlock != FLY_AXISLOCK_STATE_OFF)
					fly->zlock = FLY_AXISLOCK_STATE_OFF;
				else {
					fly->zlock = FLY_AXISLOCK_STATE_ACTIVE;
					fly->zlock_momentum = 0.0;
				}
				fly_update_header(C, op, fly);
				break;

			case FLY_MODAL_PRECISION_ENABLE:
				fly->use_precision = true;
				break;
			case FLY_MODAL_PRECISION_DISABLE:
				fly->use_precision = false;
				break;

			case FLY_MODAL_FREELOOK_ENABLE:
				fly->use_freelook = true;
				break;
			case FLY_MODAL_FREELOOK_DISABLE:
				fly->use_freelook = false;
				break;
		}
	}
}
Example #19
0
Scene *BKE_scene_copy(Scene *sce, int type)
{
	Scene *scen;
	SceneRenderLayer *srl, *new_srl;
	ToolSettings *ts;
	Base *base, *obase;
	
	if (type == SCE_COPY_EMPTY) {
		ListBase lb;
		/* XXX. main should become an arg */
		scen = BKE_scene_add(G.main, sce->id.name + 2);
		
		lb = scen->r.layers;
		scen->r = sce->r;
		scen->r.layers = lb;
		scen->r.actlay = 0;
		scen->unit = sce->unit;
		scen->physics_settings = sce->physics_settings;
		scen->gm = sce->gm;
		scen->audio = sce->audio;

		if (sce->id.properties)
			scen->id.properties = IDP_CopyProperty(sce->id.properties);

		MEM_freeN(scen->toolsettings);
	}
	else {
		scen = BKE_libblock_copy(&sce->id);
		BLI_duplicatelist(&(scen->base), &(sce->base));
		
		clear_id_newpoins();
		
		id_us_plus((ID *)scen->world);
		id_us_plus((ID *)scen->set);
		id_us_plus((ID *)scen->gm.dome.warptext);

		scen->ed = NULL;
		scen->theDag = NULL;
		scen->obedit = NULL;
		scen->stats = NULL;
		scen->fps_info = NULL;

		if (sce->rigidbody_world)
			scen->rigidbody_world = BKE_rigidbody_world_copy(sce->rigidbody_world);

		BLI_duplicatelist(&(scen->markers), &(sce->markers));
		BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
		BLI_duplicatelist(&(scen->r.layers), &(sce->r.layers));
		BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));

		if (sce->nodetree) {
			/* ID's are managed on both copy and switch */
			scen->nodetree = ntreeCopyTree(sce->nodetree);
			ntreeSwitchID(scen->nodetree, &sce->id, &scen->id);
		}

		obase = sce->base.first;
		base = scen->base.first;
		while (base) {
			id_us_plus(&base->object->id);
			if (obase == sce->basact) scen->basact = base;
	
			obase = obase->next;
			base = base->next;
		}

		/* copy color management settings */
		BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings);
		BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings);
		BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings);

		BLI_strncpy(scen->sequencer_colorspace_settings.name, sce->sequencer_colorspace_settings.name,
		            sizeof(scen->sequencer_colorspace_settings.name));

		/* remove animation used by sequencer */
		if (type != SCE_COPY_FULL)
			remove_sequencer_fcurves(scen);

		/* copy Freestyle settings */
		new_srl = scen->r.layers.first;
		for (srl = sce->r.layers.first; srl; srl = srl->next) {
			BKE_freestyle_config_copy(&new_srl->freestyleConfig, &srl->freestyleConfig);
			new_srl = new_srl->next;
		}
	}

	/* tool settings */
	scen->toolsettings = MEM_dupallocN(sce->toolsettings);

	ts = scen->toolsettings;
	if (ts) {
		if (ts->vpaint) {
			ts->vpaint = MEM_dupallocN(ts->vpaint);
			ts->vpaint->paintcursor = NULL;
			ts->vpaint->vpaint_prev = NULL;
			ts->vpaint->wpaint_prev = NULL;
			BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint);
		}
		if (ts->wpaint) {
			ts->wpaint = MEM_dupallocN(ts->wpaint);
			ts->wpaint->paintcursor = NULL;
			ts->wpaint->vpaint_prev = NULL;
			ts->wpaint->wpaint_prev = NULL;
			BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint);
		}
		if (ts->sculpt) {
			ts->sculpt = MEM_dupallocN(ts->sculpt);
			BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint);
		}

		BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint);
		ts->imapaint.paintcursor = NULL;
		ts->particle.paintcursor = NULL;
	}
	
	/* make a private copy of the avicodecdata */
	if (sce->r.avicodecdata) {
		scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
		scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
		scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
	}
	
	/* make a private copy of the qtcodecdata */
	if (sce->r.qtcodecdata) {
		scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
		scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
	}
	
	if (sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */
		scen->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
	}

	/* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
	 * are done outside of blenkernel with ED_objects_single_users! */

	/*  camera */
	if (type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
		ID_NEW(scen->camera);
	}
	
	/* before scene copy */
	sound_create_scene(scen);

	/* world */
	if (type == SCE_COPY_FULL) {
		BKE_copy_animdata_id_action((ID *)scen);
		if (scen->world) {
			id_us_plus((ID *)scen->world);
			scen->world = BKE_world_copy(scen->world);
			BKE_copy_animdata_id_action((ID *)scen->world);
		}

		if (sce->ed) {
			scen->ed = MEM_callocN(sizeof(Editing), "addseq");
			scen->ed->seqbasep = &scen->ed->seqbase;
			BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
		}
	}

	return scen;
}
Example #20
0
void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow)
{
	RegionView3D *rv3d= ar->regiondata;

	float viewnormal[3];
	int i, j, n, good_index;
	float d, d0, dd, ds;
	float *points = NULL;
	int numpoints = 0;
	float cor[3] = {1.,1.,1.};
	int gl_depth = 0, gl_blend = 0;

	/* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, [email protected] */
	float cv[][3] = {
		{1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
		{1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}
	};

	// edges have the form edges[n][0][xyz] + t*edges[n][1][xyz]
	float edges[12][2][3] = {
		{{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}},
		{{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}},
		{{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}},
		{{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}},

		{{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}},
		{{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}},
		{{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}},
		{{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}},

		{{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}},
		{{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}},
		{{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}},
		{{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}
	};

	/* Fragment program to calculate the view3d of smoke */
	/* using 2 textures, density and shadow */
	const char *text = "!!ARBfp1.0\n"
					"PARAM dx = program.local[0];\n"
					"PARAM darkness = program.local[1];\n"
					"PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n"
					"TEMP temp, shadow, value;\n"
					"TEX temp, fragment.texcoord[0], texture[0], 3D;\n"
					"TEX shadow, fragment.texcoord[0], texture[1], 3D;\n"
					"MUL value, temp, darkness;\n"
					"MUL value, value, dx;\n"
					"MUL value, value, f;\n"
					"EX2 temp, -value.r;\n"
					"SUB temp.a, 1.0, temp.r;\n"
					"MUL temp.r, temp.r, shadow.r;\n"
					"MUL temp.g, temp.g, shadow.r;\n"
					"MUL temp.b, temp.b, shadow.r;\n"
					"MOV result.color, temp;\n"
					"END\n";
	GLuint prog;

	
	float size[3];

	if(!tex) {
		printf("Could not allocate 3D texture for 3D View smoke drawing.\n");
		return;
	}

	tstart();

	VECSUB(size, max, min);

	// maxx, maxy, maxz
	cv[0][0] = max[0];
	cv[0][1] = max[1];
	cv[0][2] = max[2];
	// minx, maxy, maxz
	cv[1][0] = min[0];
	cv[1][1] = max[1];
	cv[1][2] = max[2];
	// minx, miny, maxz
	cv[2][0] = min[0];
	cv[2][1] = min[1];
	cv[2][2] = max[2];
	// maxx, miny, maxz
	cv[3][0] = max[0];
	cv[3][1] = min[1];
	cv[3][2] = max[2];

	// maxx, maxy, minz
	cv[4][0] = max[0];
	cv[4][1] = max[1];
	cv[4][2] = min[2];
	// minx, maxy, minz
	cv[5][0] = min[0];
	cv[5][1] = max[1];
	cv[5][2] = min[2];
	// minx, miny, minz
	cv[6][0] = min[0];
	cv[6][1] = min[1];
	cv[6][2] = min[2];
	// maxx, miny, minz
	cv[7][0] = max[0];
	cv[7][1] = min[1];
	cv[7][2] = min[2];

	VECCOPY(edges[0][0], cv[4]); // maxx, maxy, minz
	VECCOPY(edges[1][0], cv[5]); // minx, maxy, minz
	VECCOPY(edges[2][0], cv[6]); // minx, miny, minz
	VECCOPY(edges[3][0], cv[7]); // maxx, miny, minz

	VECCOPY(edges[4][0], cv[3]); // maxx, miny, maxz
	VECCOPY(edges[5][0], cv[2]); // minx, miny, maxz
	VECCOPY(edges[6][0], cv[6]); // minx, miny, minz
	VECCOPY(edges[7][0], cv[7]); // maxx, miny, minz

	VECCOPY(edges[8][0], cv[1]); // minx, maxy, maxz
	VECCOPY(edges[9][0], cv[2]); // minx, miny, maxz
	VECCOPY(edges[10][0], cv[6]); // minx, miny, minz
	VECCOPY(edges[11][0], cv[5]); // minx, maxy, minz

	// printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]);
	// printf("min[2]: %f, max[2]: %f\n", min[2], max[2]);

	edges[0][1][2] = size[2];
	edges[1][1][2] = size[2];
	edges[2][1][2] = size[2];
	edges[3][1][2] = size[2];

	edges[4][1][1] = size[1];
	edges[5][1][1] = size[1];
	edges[6][1][1] = size[1];
	edges[7][1][1] = size[1];

	edges[8][1][0] = size[0];
	edges[9][1][0] = size[0];
	edges[10][1][0] = size[0];
	edges[11][1][0] = size[0];

	glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend);
	glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth);

	glLoadMatrixf(rv3d->viewmat);
	// glMultMatrixf(ob->obmat);	

	glDepthMask(GL_FALSE);
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	/*
	printf("Viewinv:\n");
	printf("%f, %f, %f\n", rv3d->viewinv[0][0], rv3d->viewinv[0][1], rv3d->viewinv[0][2]);
	printf("%f, %f, %f\n", rv3d->viewinv[1][0], rv3d->viewinv[1][1], rv3d->viewinv[1][2]);
	printf("%f, %f, %f\n", rv3d->viewinv[2][0], rv3d->viewinv[2][1], rv3d->viewinv[2][2]);
	*/

	// get view vector
	VECCOPY(viewnormal, rv3d->viewinv[2]);
	normalize_v3(viewnormal);

	// find cube vertex that is closest to the viewer
	for (i=0; i<8; i++) {
		float x,y,z;

		x = cv[i][0] - viewnormal[0];
		y = cv[i][1] - viewnormal[1];
		z = cv[i][2] - viewnormal[2];

		if ((x>=min[0])&&(x<=max[0])
			&&(y>=min[1])&&(y<=max[1])
			&&(z>=min[2])&&(z<=max[2])) {
			break;
		}
	}

	if(i >= 8) {
		/* fallback, avoid using buffer over-run */
		i= 0;
	}

	// printf("i: %d\n", i);
	// printf("point %f, %f, %f\n", cv[i][0], cv[i][1], cv[i][2]);

	if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program"))
	{
		glEnable(GL_FRAGMENT_PROGRAM_ARB);
		glGenProgramsARB(1, &prog);

		glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog);
		glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text);

		// cell spacing
		glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0);
		// custom parameter for smoke style (higher = thicker)
		glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0);
	}
	else
		printf("Your gfx card does not support 3D View smoke drawing.\n");

	GPU_texture_bind(tex, 0);
	if(tex_shadow)
		GPU_texture_bind(tex_shadow, 1);
	else
		printf("No volume shadow\n");

	if (!GPU_non_power_of_two_support()) {
		cor[0] = (float)res[0]/(float)larger_pow2(res[0]);
		cor[1] = (float)res[1]/(float)larger_pow2(res[1]);
		cor[2] = (float)res[2]/(float)larger_pow2(res[2]);
	}

	// our slices are defined by the plane equation a*x + b*y +c*z + d = 0
	// (a,b,c), the plane normal, are given by viewdir
	// d is the parameter along the view direction. the first d is given by
	// inserting previously found vertex into the plane equation
	d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]);
	ds = (ABS(viewnormal[0])*size[0] + ABS(viewnormal[1])*size[1] + ABS(viewnormal[2])*size[2]);
	dd = 0.05; // ds/512.0f;
	n = 0;
	good_index = i;

	// printf("d0: %f, dd: %f, ds: %f\n\n", d0, dd, ds);

	points = MEM_callocN(sizeof(float)*12*3, "smoke_points_preview");

	while(1) {
		float p0[3];
		float tmp_point[3], tmp_point2[3];

		if(dd*(float)n > ds)
			break;

		VECCOPY(tmp_point, viewnormal);
		mul_v3_fl(tmp_point, -dd*((ds/dd)-(float)n));
		VECADD(tmp_point2, cv[good_index], tmp_point);
		d = INPR(tmp_point2, viewnormal);

		// printf("my d: %f\n", d);

		// intersect_edges returns the intersection points of all cube edges with
		// the given plane that lie within the cube
		numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], -d, edges);

		// printf("points: %d\n", numpoints);

		if (numpoints > 2) {
			VECCOPY(p0, points);

			// sort points to get a convex polygon
			for(i = 1; i < numpoints - 1; i++)
			{
				for(j = i + 1; j < numpoints; j++)
				{
					if(!convex(p0, viewnormal, &points[j * 3], &points[i * 3]))
					{
						float tmp2[3];
						VECCOPY(tmp2, &points[j * 3]);
						VECCOPY(&points[j * 3], &points[i * 3]);
						VECCOPY(&points[i * 3], tmp2);
					}
				}
			}

			// printf("numpoints: %d\n", numpoints);
			glBegin(GL_POLYGON);
			glColor3f(1.0, 1.0, 1.0);
			for (i = 0; i < numpoints; i++) {
				glTexCoord3d((points[i * 3 + 0] - min[0] )*cor[0]/size[0], (points[i * 3 + 1] - min[1])*cor[1]/size[1], (points[i * 3 + 2] - min[2])*cor[2]/size[2]);
				glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]);
			}
			glEnd();
		}
		n++;
	}

	tend();
	// printf ( "Draw Time: %f\n",( float ) tval() );

	if(tex_shadow)
		GPU_texture_unbind(tex_shadow);
	GPU_texture_unbind(tex);

	if(GLEW_ARB_fragment_program)
	{
		glDisable(GL_FRAGMENT_PROGRAM_ARB);
		glDeleteProgramsARB(1, &prog);
	}


	MEM_freeN(points);

	if(!gl_blend)
		glDisable(GL_BLEND);
	if(gl_depth)
	{
		glEnable(GL_DEPTH_TEST);
		glDepthMask(GL_TRUE);	
	}
}
Example #21
0
/* NOTE: does *not* free *sh itself!  only the direct data! */
void BLI_smallhash_release(SmallHash *sh)
{
	if (sh->buckets != sh->buckets_stack) {
		MEM_freeN(sh->buckets);
	}
}
Example #22
0
static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo)
{
	numbytes -= cinfo->dest->free_in_buffer;

	MEM_freeN(cinfo->dest);
}
Example #23
0
size_t blf_font_width_to_rstrlen(FontBLF *font, const char *str, size_t len, float width, float *r_width)
{
	unsigned int c;
	GlyphBLF *g, *g_prev = NULL;
	FT_Vector delta;
	int pen_x = 0;
	size_t i = 0, i_prev;
	GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
	const int width_i = (int)width + 1;
	int width_new;

	bool is_malloc;
	int (*width_accum)[2];
	int width_accum_ofs = 0;

	BLF_KERNING_VARS(font, has_kerning, kern_mode);

	/* skip allocs in simple cases */
	len = BLI_strnlen(str, len);
	if (width_i <= 1 || len == 0) {
		if (r_width) {
			*r_width = 0.0f;
		}
		return len;
	}

	if (len < 2048) {
		width_accum = BLI_array_alloca(width_accum, len);
		is_malloc = false;
	}
	else {
		width_accum = MEM_mallocN(sizeof(*width_accum) * len, __func__);
		is_malloc = true;
	}

	blf_font_ensure_ascii_table(font);

	while ((i < len) && str[i]) {
		BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);

		if (c == BLI_UTF8_ERR)
			break;
		if (g == NULL)
			continue;
		if (has_kerning)
			BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);

		pen_x += (int)g->advance;

		width_accum[width_accum_ofs][0] = (int)i;
		width_accum[width_accum_ofs][1] = pen_x;
		width_accum_ofs++;

		g_prev = g;
	}

	if (pen_x > width_i && width_accum_ofs != 0) {
		const int min_x = pen_x - width_i;

		/* search backwards */
		width_new = pen_x;
		while (width_accum_ofs-- > 0) {
			if (min_x > width_accum[width_accum_ofs][1]) {
				break;
			}
		}
		width_accum_ofs++;
		width_new = pen_x - width_accum[width_accum_ofs][1];
		i_prev = (size_t)width_accum[width_accum_ofs][0];
	}
	else {
		width_new = pen_x;
		i_prev = 0;
	}

	if (is_malloc) {
		MEM_freeN(width_accum);
	}

	if (r_width) {
		*r_width = (float)width_new;
	}

	return i_prev;
}
Example #24
0
static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo)
{
	numbytes -= dinfo->src->bytes_in_buffer;
	
	MEM_freeN(dinfo->src);
}
Example #25
0
static void handleRadialSymmetry(BGraph *graph, BNode *root_node, int depth, float axis[3], float limit)
{
	RadialArc *ring = NULL;
	RadialArc *unit;
	int total = 0;
	int group;
	int first;
	int i;

	/* mark topological symmetry */
	root_node->symmetry_flag |= SYM_TOPOLOGICAL;

	/* total the number of arcs in the symmetry ring */
	for (i = 0; i < root_node->degree; i++) {
		BArc *connectedArc = root_node->arcs[i];
		
		/* depth is store as a negative in flag. symmetry level is positive */
		if (connectedArc->symmetry_level == -depth) {
			total++;
		}
	}

	ring = MEM_callocN(sizeof(RadialArc) * total, "radial symmetry ring");
	unit = ring;

	/* fill in the ring */
	for (unit = ring, i = 0; i < root_node->degree; i++) {
		BArc *connectedArc = root_node->arcs[i];
		
		/* depth is store as a negative in flag. symmetry level is positive */
		if (connectedArc->symmetry_level == -depth) {
			BNode *otherNode = BLI_otherNode(connectedArc, root_node);
			float vec[3];

			unit->arc = connectedArc;

			/* project the node to node vector on the symmetry plane */
			sub_v3_v3v3(unit->n, otherNode->p, root_node->p);
			project_v3_v3v3(vec, unit->n, axis);
			sub_v3_v3v3(unit->n, unit->n, vec);

			normalize_v3(unit->n);

			unit++;
		}
	}

	/* sort ring by arc length
	 * using a rather bogus insertion sort
	 * but rings will never get too big to matter
	 * */
	for (i = 0; i < total; i++) {
		int j;

		for (j = i - 1; j >= 0; j--) {
			BArc *arc1, *arc2;
			
			arc1 = ring[j].arc;
			arc2 = ring[j + 1].arc;
			
			if (arc1->length > arc2->length) {
				/* swap with smaller */
				RadialArc tmp;
				
				tmp = ring[j + 1];
				ring[j + 1] = ring[j];
				ring[j] = tmp;
			}
			else {
				break;
			}
		}
	}

	/* Dispatch to specific symmetry tests */
	first = 0;
	group = 0;
	
	for (i = 1; i < total; i++) {
		int dispatch = 0;
		int last = i - 1;
		
		if (fabsf(ring[first].arc->length - ring[i].arc->length) > limit) {
			dispatch = 1;
		}

		/* if not dispatching already and on last arc
		 * Dispatch using current arc as last
		 */
		if (dispatch == 0 && i == total - 1) {
			last = i;
			dispatch = 1;
		}
		
		if (dispatch) {
			int sub_total = last - first + 1; 

			group += 1;

			if (sub_total == 1) {
				group -= 1; /* not really a group so decrement */
				/* NOTHING TO DO */
			}
			else if (sub_total == 2) {
				BArc *arc1, *arc2;
				BNode *node1, *node2;
				
				arc1 = ring[first].arc;
				arc2 = ring[last].arc;
				
				node1 = BLI_otherNode(arc1, root_node);
				node2 = BLI_otherNode(arc2, root_node);
				
				testAxialSymmetry(graph, root_node, node1, node2, arc1, arc2, axis, limit, group);
			}
			else if (sub_total != total) /* allocate a new sub ring if needed */ {
				RadialArc *sub_ring = MEM_callocN(sizeof(RadialArc) * sub_total, "radial symmetry ring");
				int sub_i;
				
				/* fill in the sub ring */
				for (sub_i = 0; sub_i < sub_total; sub_i++) {
					sub_ring[sub_i] = ring[first + sub_i];
				}
				
				testRadialSymmetry(graph, root_node, sub_ring, sub_total, axis, limit, group);
			
				MEM_freeN(sub_ring);
			}
			else if (sub_total == total) {
				testRadialSymmetry(graph, root_node, ring, total, axis, limit, group);
			}
			
			first = i;
		}
	}


	MEM_freeN(ring);
}
Example #26
0
void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel),
                    void *update_cb_data)
{
	/* note: some of these values remain uninitialized unless certain options
	 * are enabled, take care that BKE_ocean_eval_ij() initializes a member
	 * before use - campbell */
	OceanResult ocr;

	ImageFormatData imf = {0};

	int f, i = 0, x, y, cancel = 0;
	float progress;

	ImBuf *ibuf_foam, *ibuf_disp, *ibuf_normal;
	float *prev_foam;
	int res_x = och->resolution_x;
	int res_y = och->resolution_y;
	char string[FILE_MAX];
	//RNG *rng;

	if (!o) return;

	if (o->_do_jacobian) prev_foam = MEM_callocN(res_x * res_y * sizeof(float), "previous frame foam bake data");
	else prev_foam = NULL;

	//rng = BLI_rng_new(0);

	/* setup image format */
	imf.imtype = R_IMF_IMTYPE_OPENEXR;
	imf.depth =  R_IMF_CHAN_DEPTH_16;
	imf.exr_codec = R_IMF_EXR_CODEC_ZIP;

	for (f = och->start, i = 0; f <= och->end; f++, i++) {

		/* create a new imbuf to store image for this frame */
		ibuf_foam = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
		ibuf_disp = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
		ibuf_normal = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);

		BKE_simulate_ocean(o, och->time[i], och->wave_scale, och->chop_amount);

		/* add new foam */
		for (y = 0; y < res_y; y++) {
			for (x = 0; x < res_x; x++) {

				BKE_ocean_eval_ij(o, &ocr, x, y);

				/* add to the image */
				rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp);

				if (o->_do_jacobian) {
					/* TODO, cleanup unused code - campbell */

					float /*r, */ /* UNUSED */ pr = 0.0f, foam_result;
					float neg_disp, neg_eplus;

					ocr.foam = BKE_ocean_jminus_to_foam(ocr.Jminus, och->foam_coverage);

					/* accumulate previous value for this cell */
					if (i > 0) {
						pr = prev_foam[res_x * y + x];
					}

					/* r = BLI_rng_get_float(rng); */ /* UNUSED */ /* randomly reduce foam */

					/* pr = pr * och->foam_fade; */		/* overall fade */

					/* remember ocean coord sys is Y up!
					 * break up the foam where height (Y) is low (wave valley), and X and Z displacement is greatest
					 */

#if 0
					vec[0] = ocr.disp[0];
					vec[1] = ocr.disp[2];
					hor_stretch = len_v2(vec);
					CLAMP(hor_stretch, 0.0, 1.0);
#endif

					neg_disp = ocr.disp[1] < 0.0f ? 1.0f + ocr.disp[1] : 1.0f;
					neg_disp = neg_disp < 0.0f ? 0.0f : neg_disp;

					/* foam, 'ocr.Eplus' only initialized with do_jacobian */
					neg_eplus = ocr.Eplus[2] < 0.0f ? 1.0f + ocr.Eplus[2] : 1.0f;
					neg_eplus = neg_eplus < 0.0f ? 0.0f : neg_eplus;

#if 0
					if (ocr.disp[1] < 0.0 || r > och->foam_fade)
						pr *= och->foam_fade;


					pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
					pr = pr * neg_disp * neg_eplus;
#endif

					if (pr < 1.0f)
						pr *= pr;

					pr *= och->foam_fade * (0.75f + neg_eplus * 0.25f);

					/* A full clamping should not be needed! */
					foam_result = min_ff(pr + ocr.foam, 1.0f);

					prev_foam[res_x * y + x] = foam_result;

					/*foam_result = min_ff(foam_result, 1.0f); */

					value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
				}

				if (o->_do_normals) {
					rgb_to_rgba_unit_alpha(&ibuf_normal->rect_float[4 * (res_x * y + x)], ocr.normal);
				}
			}
		}

		/* write the images */
		cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_DISPLACE);
		if (0 == BKE_imbuf_write(ibuf_disp, string, &imf))
			printf("Cannot save Displacement File Output to %s\n", string);

		if (o->_do_jacobian) {
			cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_FOAM);
			if (0 == BKE_imbuf_write(ibuf_foam, string, &imf))
				printf("Cannot save Foam File Output to %s\n", string);
		}

		if (o->_do_normals) {
			cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_NORMAL);
			if (0 == BKE_imbuf_write(ibuf_normal, string, &imf))
				printf("Cannot save Normal File Output to %s\n", string);
		}

		IMB_freeImBuf(ibuf_disp);
		IMB_freeImBuf(ibuf_foam);
		IMB_freeImBuf(ibuf_normal);

		progress = (f - och->start) / (float)och->duration;

		update_cb(update_cb_data, progress, &cancel);

		if (cancel) {
			if (prev_foam) MEM_freeN(prev_foam);
			//BLI_rng_free(rng);
			return;
		}
	}

	//BLI_rng_free(rng);
	if (prev_foam) MEM_freeN(prev_foam);
	och->baked = 1;
}
Example #27
0
/* render call to fill in strands */
int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache)
{
	ObjectRen *obr;
	ObjectInstanceRen *obi;
	ZSpan zspan;
	StrandRen *strand = NULL;
	StrandVert *svert;
	StrandBound *sbound;
	StrandPart spart;
	StrandSegment sseg;
	StrandSortSegment *sortsegments = NULL, *sortseg, *firstseg;
	MemArena *memarena;
	float z[4], bounds[4], obwinmat[4][4];
	int a, b, c, i, totsegment, clip[4];

	if (re->test_break(re->tbh))
		return 0;
	if (re->totstrand == 0)
		return 0;

	/* setup StrandPart */
	memset(&spart, 0, sizeof(spart));

	spart.re= re;
	spart.rectx= pa->rectx;
	spart.recty= pa->recty;
	spart.apixbuf= apixbuf;
	spart.zspan= &zspan;
	spart.rectdaps= pa->rectdaps;
	spart.rectz= pa->rectz;
	spart.rectmask= pa->rectmask;
	spart.cache= cache;
	spart.shadow= shadow;
	spart.jit= jit;
	spart.samples= samples;

	zbuf_alloc_span(&zspan, pa->rectx, pa->recty, clipcrop);

	/* needed for transform from hoco to zbuffer co */
	zspan.zmulx= ((float)winx)/2.0f;
	zspan.zmuly= ((float)winy)/2.0f;
	
	zspan.zofsx= -pa->disprect.xmin;
	zspan.zofsy= -pa->disprect.ymin;

	/* to center the sample position */
	if (!shadow) {
		zspan.zofsx -= 0.5f;
		zspan.zofsy -= 0.5f;
	}

	zspan.apsmbase= apsmbase;

	/* clipping setup */
	bounds[0]= (2*pa->disprect.xmin - winx-1)/(float)winx;
	bounds[1]= (2*pa->disprect.xmax - winx+1)/(float)winx;
	bounds[2]= (2*pa->disprect.ymin - winy-1)/(float)winy;
	bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy;

	memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand sort arena");
	firstseg= NULL;
	totsegment= 0;

	/* for all object instances */
	for (obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) {
		Material *ma;
		float widthx, widthy;

		obr= obi->obr;

		if (!obr->strandbuf || !(obr->strandbuf->lay & lay))
			continue;

		/* compute matrix and try clipping whole object */
		if (obi->flag & R_TRANSFORMED)
			mul_m4_m4m4(obwinmat, winmat, obi->mat);
		else
			copy_m4_m4(obwinmat, winmat);

		/* test if we should skip it */
		ma = obr->strandbuf->ma;

		if (shadow && !(ma->mode & MA_SHADBUF))
			continue;
		else if (!shadow && (ma->mode & MA_ONLYCAST))
			continue;

		if (clip_render_object(obi->obr->boundbox, bounds, obwinmat))
			continue;
		
		widthx= obr->strandbuf->maxwidth*obwinmat[0][0];
		widthy= obr->strandbuf->maxwidth*obwinmat[1][1];

		/* for each bounding box containing a number of strands */
		sbound= obr->strandbuf->bound;
		for (c=0; c<obr->strandbuf->totbound; c++, sbound++) {
			if (clip_render_object(sbound->boundbox, bounds, obwinmat))
				continue;

			/* for each strand in this bounding box */
			for (a=sbound->start; a<sbound->end; a++) {
				strand= RE_findOrAddStrand(obr, a);
				svert= strand->vert;

				/* keep clipping and z depth for 4 control points */
				clip[1]= strand_test_clip(obwinmat, &zspan, bounds, svert->co, &z[1], widthx, widthy);
				clip[2]= strand_test_clip(obwinmat, &zspan, bounds, (svert+1)->co, &z[2], widthx, widthy);
				clip[0]= clip[1]; z[0]= z[1];

				for (b=0; b<strand->totvert-1; b++, svert++) {
					/* compute 4th point clipping and z depth */
					if (b < strand->totvert-2) {
						clip[3]= strand_test_clip(obwinmat, &zspan, bounds, (svert+2)->co, &z[3], widthx, widthy);
					}
					else {
						clip[3]= clip[2]; z[3]= z[2];
					}

					/* check clipping and add to sortsegments buffer */
					if (!(clip[0] & clip[1] & clip[2] & clip[3])) {
						sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
						sortseg->obi= i;
						sortseg->strand= strand->index;
						sortseg->segment= b;

						sortseg->z= 0.5f*(z[1] + z[2]);

						sortseg->next= firstseg;
						firstseg= sortseg;
						totsegment++;
					}

					/* shift clipping and z depth */
					clip[0]= clip[1]; z[0]= z[1];
					clip[1]= clip[2]; z[1]= z[2];
					clip[2]= clip[3]; z[2]= z[3];
				}
			}
		}
	}

	if (!re->test_break(re->tbh)) {
		/* convert list to array and sort */
		sortsegments= MEM_mallocN(sizeof(StrandSortSegment)*totsegment, "StrandSortSegment");
		for (a=0, sortseg=firstseg; a<totsegment; a++, sortseg=sortseg->next)
			sortsegments[a]= *sortseg;
		qsort(sortsegments, totsegment, sizeof(StrandSortSegment), compare_strand_segment);
	}

	BLI_memarena_free(memarena);

	spart.totapixbuf= MEM_callocN(sizeof(int)*pa->rectx*pa->recty, "totapixbuf");

	if (!re->test_break(re->tbh)) {
		/* render segments in sorted order */
		sortseg= sortsegments;
		for (a=0; a<totsegment; a++, sortseg++) {
			if (re->test_break(re->tbh))
				break;

			obi= &re->objectinstance[sortseg->obi];
			obr= obi->obr;

			sseg.obi= obi;
			sseg.strand= RE_findOrAddStrand(obr, sortseg->strand);
			sseg.buffer= sseg.strand->buffer;
			sseg.sqadaptcos= sseg.buffer->adaptcos;
			sseg.sqadaptcos *= sseg.sqadaptcos;

			svert= sseg.strand->vert + sortseg->segment;
			sseg.v[0]= (sortseg->segment > 0)? (svert-1): svert;
			sseg.v[1]= svert;
			sseg.v[2]= svert+1;
			sseg.v[3]= (sortseg->segment < sseg.strand->totvert-2)? svert+2: svert+1;
			sseg.shaded= 0;

			spart.segment= &sseg;

			render_strand_segment(re, winmat, &spart, &zspan, 1, &sseg);
		}
	}

	if (sortsegments)
		MEM_freeN(sortsegments);
	MEM_freeN(spart.totapixbuf);
	
	zbuf_free_span(&zspan);

	return totsegment;
}
Example #28
0
void BKE_free_ocean(struct Ocean *oc)
{
	if (!oc) return;
	MEM_freeN(oc);
}
Example #29
0
struct CharTrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode)
{
	VFont *vfont, *oldvfont;
	VFontData *vfd = NULL;
	Curve *cu;
	CharInfo *info = NULL, *custrinfo;
	TextBox *tb;
	VChar *che;
	struct CharTrans *chartransdata = NULL, *ct;
	float *f, xof, yof, xtrax, linedist, *linedata, *linedata2, *linedata3, *linedata4;
	float twidth, maxlen = 0;
	int i, slen, j;
	int curbox;
	int selstart, selend;
	int utf8len;
	short cnr = 0, lnr = 0, wsnr = 0;
	wchar_t *mem, *tmp, ascii;

	/* remark: do calculations including the trailing '\0' of a string
	 * because the cursor can be at that location */

	if (ob->type != OB_FONT) return NULL;

	/* Set font data */
	cu = (Curve *) ob->data;
	vfont = cu->vfont;

	if (cu->str == NULL) return NULL;
	if (vfont == NULL) return NULL;

	/* Create unicode string */
	utf8len = BLI_strlen_utf8(cu->str);
	mem = MEM_mallocN(((utf8len + 1) * sizeof(wchar_t)), "convertedmem");

	BLI_strncpy_wchar_from_utf8(mem, cu->str, utf8len + 1);

	/* Count the wchar_t string length */
	slen = wcslen(mem);

	if (cu->ulheight == 0.0f)
		cu->ulheight = 0.05f;
	
	if (cu->strinfo == NULL) /* old file */
		cu->strinfo = MEM_callocN((slen + 4) * sizeof(CharInfo), "strinfo compat");
	
	custrinfo = cu->strinfo;
	if (cu->editfont)
		custrinfo = cu->editfont->textbufinfo;
	
	if (cu->tb == NULL)
		cu->tb = MEM_callocN(MAXTEXTBOX * sizeof(TextBox), "TextBox compat");

	vfd = vfont_get_data(bmain, vfont);

	/* The VFont Data can not be found */
	if (!vfd) {
		if (mem)
			MEM_freeN(mem);
		return NULL;
	}

	/* calc offset and rotation of each char */
	ct = chartransdata =
	         (struct CharTrans *)MEM_callocN((slen + 1) * sizeof(struct CharTrans), "buildtext");

	/* We assume the worst case: 1 character per line (is freed at end anyway) */

	linedata  = MEM_mallocN(sizeof(float) * (slen * 2 + 1), "buildtext2");
	linedata2 = MEM_mallocN(sizeof(float) * (slen * 2 + 1), "buildtext3");
	linedata3 = MEM_callocN(sizeof(float) * (slen * 2 + 1), "buildtext4");
	linedata4 = MEM_callocN(sizeof(float) * (slen * 2 + 1), "buildtext5");
	
	linedist = cu->linedist;
	
	xof = cu->xof + (cu->tb[0].x / cu->fsize);
	yof = cu->yof + (cu->tb[0].y / cu->fsize);

	xtrax = 0.5f * cu->spacing - 0.5f;

	oldvfont = NULL;

	for (i = 0; i < slen; i++) custrinfo[i].flag &= ~(CU_CHINFO_WRAP | CU_CHINFO_SMALLCAPS_CHECK);

	if (cu->selboxes) MEM_freeN(cu->selboxes);
	cu->selboxes = NULL;
	if (BKE_vfont_select_get(ob, &selstart, &selend))
		cu->selboxes = MEM_callocN((selend - selstart + 1) * sizeof(SelBox), "font selboxes");

	tb = &(cu->tb[0]);
	curbox = 0;
	for (i = 0; i <= slen; i++) {
makebreak:
		/* Characters in the list */
		info = &(custrinfo[i]);
		ascii = mem[i];
		if (info->flag & CU_CHINFO_SMALLCAPS) {
			ascii = towupper(ascii);
			if (mem[i] != ascii) {
				mem[i] = ascii;
				info->flag |= CU_CHINFO_SMALLCAPS_CHECK;
			}
		}

		vfont = which_vfont(cu, info);
		
		if (vfont == NULL) break;

		che = find_vfont_char(vfd, ascii);

		/*
		 * The character wasn't in the current curve base so load it
		 * But if the font is built-in then do not try loading since
		 * whole font is in the memory already
		 */
		if (che == NULL && BKE_vfont_is_builtin(vfont) == FALSE) {
			BLI_vfontchar_from_freetypefont(vfont, ascii);
		}

		/* Try getting the character again from the list */
		che = find_vfont_char(vfd, ascii);

		/* No VFont found */
		if (vfont == NULL) {
			if (mem)
				MEM_freeN(mem);
			MEM_freeN(chartransdata);
			return NULL;
		}

		if (vfont != oldvfont) {
			vfd = vfont_get_data(bmain, vfont);
			oldvfont = vfont;
		}

		/* VFont Data for VFont couldn't be found */
		if (!vfd) {
			if (mem)
				MEM_freeN(mem);
			MEM_freeN(chartransdata);
			return NULL;
		}

		twidth = char_width(cu, che, info);

		/* Calculate positions */
		if ((tb->w != 0.0f) &&
		    (ct->dobreak == 0) &&
		    (((xof - (tb->x / cu->fsize) + twidth) * cu->fsize) > tb->w + cu->xof * cu->fsize))
		{
			//		fprintf(stderr, "linewidth exceeded: %c%c%c...\n", mem[i], mem[i+1], mem[i+2]);
			for (j = i; j && (mem[j] != '\n') && (mem[j] != '\r') && (chartransdata[j].dobreak == 0); j--) {
				if (mem[j] == ' ' || mem[j] == '-') {
					ct -= (i - (j - 1));
					cnr -= (i - (j - 1));
					if (mem[j] == ' ') wsnr--;
					if (mem[j] == '-') wsnr++;
					i = j - 1;
					xof = ct->xof;
					ct[1].dobreak = 1;
					custrinfo[i + 1].flag |= CU_CHINFO_WRAP;
					goto makebreak;
				}
				if (chartransdata[j].dobreak) {
					//				fprintf(stderr, "word too long: %c%c%c...\n", mem[j], mem[j+1], mem[j+2]);
					ct->dobreak = 1;
					custrinfo[i + 1].flag |= CU_CHINFO_WRAP;
					ct -= 1;
					cnr -= 1;
					i--;
					xof = ct->xof;
					goto makebreak;
				}
			}
		}

		if (ascii == '\n' || ascii == '\r' || ascii == 0 || ct->dobreak) {
			ct->xof = xof;
			ct->yof = yof;
			ct->linenr = lnr;
			ct->charnr = cnr;

			yof -= linedist;

			maxlen = max_ff(maxlen, (xof - tb->x / cu->fsize));
			linedata[lnr] = xof - tb->x / cu->fsize;
			linedata2[lnr] = cnr;
			linedata3[lnr] = tb->w / cu->fsize;
			linedata4[lnr] = wsnr;
			
			if ((tb->h != 0.0f) &&
			    ((-(yof - (tb->y / cu->fsize))) > ((tb->h / cu->fsize) - (linedist * cu->fsize)) - cu->yof) &&
			    (cu->totbox > (curbox + 1)) )
			{
				maxlen = 0;
				tb++;
				curbox++;
				yof = cu->yof + tb->y / cu->fsize;
			}

			/* XXX, has been unused for years, need to check if this is useful, r4613 r5282 - campbell */
#if 0
			if (ascii == '\n' || ascii == '\r')
				xof = cu->xof;
			else
				xof = cu->xof + (tb->x / cu->fsize);
#else
			xof = cu->xof + (tb->x / cu->fsize);
#endif
			lnr++;
			cnr = 0;
			wsnr = 0;
		}
		else if (ascii == 9) {    /* TAB */
			float tabfac;
			
			ct->xof = xof;
			ct->yof = yof;
			ct->linenr = lnr;
			ct->charnr = cnr++;

			tabfac = (xof - cu->xof + 0.01f);
			tabfac = 2.0f * ceilf(tabfac / 2.0f);
			xof = cu->xof + tabfac;
		}
		else {
			SelBox *sb = NULL;
			float wsfac;

			ct->xof = xof;
			ct->yof = yof;
			ct->linenr = lnr;
			ct->charnr = cnr++;

			if (cu->selboxes && (i >= selstart) && (i <= selend)) {
				sb = &(cu->selboxes[i - selstart]);
				sb->y = yof * cu->fsize - linedist * cu->fsize * 0.1f;
				sb->h = linedist * cu->fsize;
				sb->w = xof * cu->fsize;
			}
	
			if (ascii == 32) {
				wsfac = cu->wordspace; 
				wsnr++;
			}
			else {
				wsfac = 1.0f;
			}
			
			/* Set the width of the character */
			twidth = char_width(cu, che, info);

			xof += (twidth * wsfac * (1.0f + (info->kern / 40.0f)) ) + xtrax;
			
			if (sb) {
				sb->w = (xof * cu->fsize) - sb->w;
			}
		}
		ct++;
	}
	
	cu->lines = 1;
	ct = chartransdata;
	tmp = mem;
	for (i = 0; i <= slen; i++, tmp++, ct++) {
		ascii = *tmp;
		if (ascii == '\n' || ascii == '\r' || ct->dobreak) cu->lines++;
	}

	/* linedata is now: width of line
	 * linedata2 is now: number of characters
	 * linedata3 is now: maxlen of that line
	 * linedata4 is now: number of whitespaces of line */

	if (cu->spacemode != CU_LEFT) {
		ct = chartransdata;

		if (cu->spacemode == CU_RIGHT) {
			for (i = 0; i < lnr; i++) linedata[i] = linedata3[i] - linedata[i];
			for (i = 0; i <= slen; i++) {
				ct->xof += linedata[ct->linenr];
				ct++;
			}
		}
		else if (cu->spacemode == CU_MIDDLE) {
			for (i = 0; i < lnr; i++) linedata[i] = (linedata3[i] - linedata[i]) / 2;
			for (i = 0; i <= slen; i++) {
				ct->xof += linedata[ct->linenr];
				ct++;
			}
		}
		else if ((cu->spacemode == CU_FLUSH) && (cu->tb[0].w != 0.0f)) {
			for (i = 0; i < lnr; i++)
				if (linedata2[i] > 1)
					linedata[i] = (linedata3[i] - linedata[i]) / (linedata2[i] - 1);
			for (i = 0; i <= slen; i++) {
				for (j = i; (!ELEM3(mem[j], '\0', '\n', '\r')) && (chartransdata[j].dobreak == 0) && (j < slen); j++) {
					/* do nothing */
				}

//				if ((mem[j] != '\r') && (mem[j] != '\n') && (mem[j])) {
				ct->xof += ct->charnr * linedata[ct->linenr];
//				}
				ct++;
			}
		}
		else if ((cu->spacemode == CU_JUSTIFY) && (cu->tb[0].w != 0.0f)) {
			float curofs = 0.0f;
			for (i = 0; i <= slen; i++) {
				for (j = i; (mem[j]) && (mem[j] != '\n') &&
				     (mem[j] != '\r') && (chartransdata[j].dobreak == 0) && (j < slen);
				     j++)
				{
					/* pass */
				}

				if ((mem[j] != '\r') && (mem[j] != '\n') &&
				    ((chartransdata[j].dobreak != 0)))
				{
					if (mem[i] == ' ') curofs += (linedata3[ct->linenr] - linedata[ct->linenr]) / linedata4[ct->linenr];
					ct->xof += curofs;
				}
				if (mem[i] == '\n' || mem[i] == '\r' || chartransdata[i].dobreak) curofs = 0;
				ct++;
			}
		}
	}
	
	/* TEXT ON CURVE */
	/* Note: Only OB_CURVE objects could have a path  */
	if (cu->textoncurve && cu->textoncurve->type == OB_CURVE) {
		Curve *cucu = cu->textoncurve->data;
		int oldflag = cucu->flag;
		
		cucu->flag |= (CU_PATH + CU_FOLLOW);
		
		if (cu->textoncurve->curve_cache == NULL || cu->textoncurve->curve_cache->path == NULL) {
			BKE_displist_make_curveTypes(scene, cu->textoncurve, 0);
		}
		if (cu->textoncurve->curve_cache->path) {
			float distfac, imat[4][4], imat3[3][3], cmat[3][3];
			float minx, maxx, miny, maxy;
			float timeofs, sizefac;
			
			invert_m4_m4(imat, ob->obmat);
			copy_m3_m4(imat3, imat);

			copy_m3_m4(cmat, cu->textoncurve->obmat);
			mul_m3_m3m3(cmat, cmat, imat3);
			sizefac = normalize_v3(cmat[0]) / cu->fsize;
			
			minx = miny = 1.0e20f;
			maxx = maxy = -1.0e20f;
			ct = chartransdata;
			for (i = 0; i <= slen; i++, ct++) {
				if (minx > ct->xof) minx = ct->xof;
				if (maxx < ct->xof) maxx = ct->xof;
				if (miny > ct->yof) miny = ct->yof;
				if (maxy < ct->yof) maxy = ct->yof;
			}
			
			/* we put the x-coordinaat exact at the curve, the y is rotated */
			
			/* length correction */
			distfac = sizefac * cu->textoncurve->curve_cache->path->totdist / (maxx - minx);
			timeofs = 0.0f;
			
			if (distfac > 1.0f) {
				/* path longer than text: spacemode involves */
				distfac = 1.0f / distfac;
				
				if (cu->spacemode == CU_RIGHT) {
					timeofs = 1.0f - distfac;
				}
				else if (cu->spacemode == CU_MIDDLE) {
					timeofs = (1.0f - distfac) / 2.0f;
				}
				else if (cu->spacemode == CU_FLUSH) {
					distfac = 1.0f;
				}
			}
			else {
				distfac = 1.0;
			}

			distfac /= (maxx - minx);
			
			timeofs += distfac * cu->xof;  /* not cyclic */
			
			ct = chartransdata;
			for (i = 0; i <= slen; i++, ct++) {
				float ctime, dtime, vec[4], tvec[4], rotvec[3];
				float si, co;
				
				/* rotate around center character */
				ascii = mem[i];

				che = find_vfont_char(vfd, ascii);
	
				twidth = char_width(cu, che, info);

				dtime = distfac * 0.5f * twidth;

				ctime = timeofs + distfac * (ct->xof - minx);
				CLAMP(ctime, 0.0f, 1.0f);

				/* calc the right loc AND the right rot separately */
				/* vec, tvec need 4 items */
				where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL, NULL);
				where_on_path(cu->textoncurve, ctime + dtime, tvec, rotvec, NULL, NULL, NULL);
				
				mul_v3_fl(vec, sizefac);
				
				ct->rot = (float)M_PI - atan2f(rotvec[1], rotvec[0]);

				si = sinf(ct->rot);
				co = cosf(ct->rot);

				yof = ct->yof;
				
				ct->xof = vec[0] + si * yof;
				ct->yof = vec[1] + co * yof;
				
			}
			cucu->flag = oldflag;
		}
	}

	if (cu->selboxes) {
		ct = chartransdata;
		for (i = 0; i <= selend; i++, ct++) {
			if (i >= selstart) {
				cu->selboxes[i - selstart].x = ct->xof * cu->fsize;
				cu->selboxes[i - selstart].y = ct->yof * cu->fsize;
			}
		}
	}

	if (mode == FO_CURSUP || mode == FO_CURSDOWN || mode == FO_PAGEUP || mode == FO_PAGEDOWN) {
		/* 2: curs up
		 * 3: curs down */
		ct = chartransdata + cu->pos;
		
		if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) {
			/* pass */
		}
		else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) {
			/* pass */
		}
		else {
			switch (mode) {
				case FO_CURSUP:     lnr = ct->linenr - 1; break;
				case FO_CURSDOWN:   lnr = ct->linenr + 1; break;
				case FO_PAGEUP:     lnr = ct->linenr - 10; break;
				case FO_PAGEDOWN:   lnr = ct->linenr + 10; break;
			}
			cnr = ct->charnr;
			/* seek for char with lnr en cnr */
			cu->pos = 0;
			ct = chartransdata;
			for (i = 0; i < slen; i++) {
				if (ct->linenr == lnr) {
					if ((ct->charnr == cnr) || ((ct + 1)->charnr == 0)) {
						break;
					}
				}
				else if (ct->linenr > lnr) {
					break;
				}
				cu->pos++;
				ct++;
			}
		}
	}
	
	/* cursor first */
	if (cu->editfont) {
		float si, co;
		
		ct = chartransdata + cu->pos;
		si = sinf(ct->rot);
		co = cosf(ct->rot);

		f = cu->editfont->textcurs[0];
		
		f[0] = cu->fsize * (-0.1f * co + ct->xof);
		f[1] = cu->fsize * ( 0.1f * si + ct->yof);
		
		f[2] = cu->fsize * ( 0.1f * co + ct->xof);
		f[3] = cu->fsize * (-0.1f * si + ct->yof);
		
		f[4] = cu->fsize * ( 0.1f * co + 0.8f * si + ct->xof);
		f[5] = cu->fsize * (-0.1f * si + 0.8f * co + ct->yof);
		
		f[6] = cu->fsize * (-0.1f * co + 0.8f * si + ct->xof);
		f[7] = cu->fsize * ( 0.1f * si + 0.8f * co + ct->yof);
		
	}

	MEM_freeN(linedata);
	MEM_freeN(linedata2);
	MEM_freeN(linedata3);
	MEM_freeN(linedata4);

	if (mode == FO_SELCHANGE) {
		MEM_freeN(chartransdata);
		MEM_freeN(mem);
		return NULL;
	}

	if (mode == FO_EDIT) {
		/* make nurbdata */
		BKE_nurbList_free(&cu->nurb);
		
		ct = chartransdata;
		if (cu->sepchar == 0) {
			for (i = 0; i < slen; i++) {
				unsigned long cha = (uintptr_t) mem[i];
				info = &(custrinfo[i]);
				if (info->mat_nr > (ob->totcol)) {
					/* printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr); */
					info->mat_nr = 0;
				}
				/* We do not want to see any character for \n or \r */
				if (cha != '\n' && cha != '\r')
					buildchar(bmain, cu, cha, info, ct->xof, ct->yof, ct->rot, i);
				
				if ((info->flag & CU_CHINFO_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) {
					float ulwidth, uloverlap = 0.0f;
					
					if ((i < (slen - 1)) && (mem[i + 1] != '\n') && (mem[i + 1] != '\r') &&
					    ((mem[i + 1] != ' ') || (custrinfo[i + 1].flag & CU_CHINFO_UNDERLINE)) &&
					    ((custrinfo[i + 1].flag & CU_CHINFO_WRAP) == 0))
					{
						uloverlap = xtrax + 0.1f;
					}
					/* Find the character, the characters has to be in the memory already
					 * since character checking has been done earlier already. */
					che = find_vfont_char(vfd, cha);

					twidth = char_width(cu, che, info);
					ulwidth = cu->fsize * ((twidth * (1.0f + (info->kern / 40.0f))) + uloverlap);
					build_underline(cu, ct->xof * cu->fsize, ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize,
					                ct->xof * cu->fsize + ulwidth,
					                ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize - cu->ulheight * cu->fsize,
					                i, info->mat_nr);
				}
				ct++;
			}
		}
		else {
			int outta = 0;
			for (i = 0; (i < slen) && (outta == 0); i++) {
				ascii = mem[i];
				info = &(custrinfo[i]);
				if (cu->sepchar == (i + 1)) {
					float vecyo[3];

					vecyo[0] = ct->xof;
					vecyo[1] = ct->yof;
					vecyo[2] = 0.0f;

					mem[0] = ascii;
					mem[1] = 0;
					custrinfo[0] = *info;
					cu->pos = 1;
					cu->len = 1;
					mul_v3_m4v3(ob->loc, ob->obmat, vecyo);
					outta = 1;
					cu->sepchar = 0;
				}
				ct++;
			}
		}
	}

	if (mode == FO_DUPLI) {
		MEM_freeN(mem);
		return chartransdata;
	}

	if (mem)
		MEM_freeN(mem);

	MEM_freeN(chartransdata);
	return NULL;
}
Example #30
0
void wm_stereo3d_set_cancel(bContext *UNUSED(C), wmOperator *op)
{
	MEM_freeN(op->customdata);
	op->customdata = NULL;
}