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; } }
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); }
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; } }
/** * \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; }
/** * 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); }
/* 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); }
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; } }
/* 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; }
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; }
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); }
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; }
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; }
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); }
void BKE_free_ocean_cache(struct OceanCache *och) { if (!och) return; MEM_freeN(och); }
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; }
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); }
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; } } }
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; }
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); } }
/* 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); } }
static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo) { numbytes -= cinfo->dest->free_in_buffer; MEM_freeN(cinfo->dest); }
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; }
static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo) { numbytes -= dinfo->src->bytes_in_buffer; MEM_freeN(dinfo->src); }
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); }
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; }
/* 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; }
void BKE_free_ocean(struct Ocean *oc) { if (!oc) return; MEM_freeN(oc); }
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; }
void wm_stereo3d_set_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); op->customdata = NULL; }