static int screenshot_exec(bContext *C, wmOperator *op) { ScreenshotData *scd = op->customdata; if (scd == NULL) { /* when running exec directly */ screenshot_data_create(C, op); scd = op->customdata; } if (scd) { if (scd->dumprect) { ImBuf *ibuf; char path[FILE_MAX]; RNA_string_get(op->ptr, "filepath", path); BLI_path_abs(path, G.main->name); /* operator ensures the extension */ ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0); ibuf->rect = scd->dumprect; /* crop to show only single editor */ if (!RNA_boolean_get(op->ptr, "full")) screenshot_crop(ibuf, scd->crop); if (scd->im_format.planes == R_IMF_PLANES_BW) { /* bw screenshot? - users will notice if it fails! */ IMB_color_to_bw(ibuf); } BKE_imbuf_write(ibuf, path, &scd->im_format); IMB_freeImBuf(ibuf); } } screenshot_data_free(op); return OPERATOR_FINISHED; }
ImBuf *get_brush_icon(Brush *brush) { static const int flags = IB_rect | IB_multilayer | IB_metadata; char path[FILE_MAX]; char *folder; if (!(brush->icon_imbuf)) { if (brush->flag & BRUSH_CUSTOM_ICON) { if (brush->icon_filepath[0]) { // first use the path directly to try and load the file BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath)); BLI_path_abs(path, G.main->name); brush->icon_imbuf = IMB_loadiffname(path, flags); // otherwise lets try to find it in other directories if (!(brush->icon_imbuf)) { folder = BLI_get_folder(BLENDER_DATAFILES, "brushicons"); BLI_make_file_string(G.main->name, path, folder, brush->icon_filepath); if (path[0]) brush->icon_imbuf = IMB_loadiffname(path, flags); } if (brush->icon_imbuf) BKE_icon_changed(BKE_icon_getid(&brush->id)); } } } if (!(brush->icon_imbuf)) brush->id.icon_id = 0; return brush->icon_imbuf; }
/* Get the output filename-- similar to the other output formats */ void filepath_ffmpeg(char* string, RenderData* rd) { char autosplit[20]; const char ** exts = get_file_extensions(rd->ffcodecdata.type); const char ** fe = exts; if (!string || !exts) return; strcpy(string, rd->pic); BLI_path_abs(string, G.main->name); BLI_make_existing_file(string); autosplit[0] = 0; if ((rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT) != 0) { sprintf(autosplit, "_%03d", ffmpeg_autosplit_count); } while (*fe) { if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), *fe) == 0) { break; } fe++; } if (!*fe) { strcat(string, autosplit); BLI_path_frame_range(string, rd->sfra, rd->efra, 4); strcat(string, *exts); } else { *(string + strlen(string) - strlen(*fe)) = 0; strcat(string, autosplit); strcat(string, *fe); } }
void BKE_library_filepath_set(Library *lib, const char *filepath) { /* in some cases this is used to update the absolute path from the * relative */ if (lib->name != filepath) { BLI_strncpy(lib->name, filepath, sizeof(lib->name)); } BLI_strncpy(lib->filepath, filepath, sizeof(lib->filepath)); /* not essential but set filepath is an absolute copy of value which * is more useful if its kept in sync */ if (BLI_path_is_rel(lib->filepath)) { /* note that the file may be unsaved, in this case, setting the * filepath on an indirectly linked path is not allowed from the * outliner, and its not really supported but allow from here for now * since making local could cause this to be directly linked - campbell */ const char *basepath = lib->parent ? lib->parent->filepath : G.main->name; BLI_path_abs(lib->filepath, basepath); } }
static void file_expand_directory(bContext *C) { SpaceFile *sfile = CTX_wm_space_file(C); if (sfile->params) { /* TODO, what about // when relbase isn't valid? */ if (G.relbase_valid && BLI_path_is_rel(sfile->params->dir)) { BLI_path_abs(sfile->params->dir, G.main->name); } else if (sfile->params->dir[0] == '~') { char tmpstr[sizeof(sfile->params->dir) - 1]; BLI_strncpy(tmpstr, sfile->params->dir + 1, sizeof(tmpstr)); BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr); } else if (sfile->params->dir[0] == '\0') #ifndef WIN32 { sfile->params->dir[0] = '/'; sfile->params->dir[1] = '\0'; } #else { get_default_root(sfile->params->dir); } /* change "C:" --> "C:\", [#28102] */ else if ((isalpha(sfile->params->dir[0]) && (sfile->params->dir[1] == ':')) && (sfile->params->dir[2] == '\0')) { sfile->params->dir[2] = '\\'; sfile->params->dir[3] = '\0'; } else if (BLI_path_is_unc(sfile->params->dir)) { BLI_cleanup_unc(sfile->params->dir, FILE_MAX_LIBEXTRA); } #endif }
static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) { static const char *kwlist[] = {"filepath", "link", "relative", NULL}; BPy_Library *ret; const char* filename = NULL; int is_rel = 0, is_link = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ii:load", (char **)kwlist, &filename, &is_link, &is_rel)) return NULL; ret = PyObject_New(BPy_Library, &bpy_lib_Type); BLI_strncpy(ret->relpath, filename, sizeof(ret->relpath)); BLI_strncpy(ret->abspath, filename, sizeof(ret->abspath)); BLI_path_abs(ret->abspath, G.main->name); ret->blo_handle = NULL; ret->flag= (is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0); ret->dict = PyDict_New(); return (PyObject *)ret; }
/* supposed to work with sequences only */ static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistorted, int framenr, char *name) { int size = rendersize_to_number(proxy_render_size); char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX]; BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX); if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) { BLI_strncpy(dir, clip->proxy.dir, sizeof(dir)); } else { BLI_snprintf(dir, FILE_MAX, "%s/BL_proxy", clipdir); } if (undistorted) BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, framenr); else BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, framenr); BLI_path_abs(name, G.main->name); BLI_path_frame(name, 1, 0); strcat(name, ".jpg"); }
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ struct wmWindow *win= CTX_wm_window(C); struct Scene *startscene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); RAS_Rect area_rect; area_rect.SetLeft(cam_frame->xmin); area_rect.SetBottom(cam_frame->ymin); area_rect.SetRight(cam_frame->xmax); area_rect.SetTop(cam_frame->ymax); int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; Main* blenderdata = maggie1; char* startscenename = startscene->id.name+2; char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; BlendFileData *bfd= NULL; BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); BLI_strncpy(oldsce, G.main->name, sizeof(oldsce)); #ifdef WITH_PYTHON resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path setGamePythonPath(G.main->name); // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */ #endif bgl::InitExtensions(true); // VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable int disableVBO = (U.gameflags & USER_DISABLE_VBO); U.gameflags |= USER_DISABLE_VBO; // Globals to be carried on over blender files GlobalSettings gs; gs.matmode= startscene->gm.matmode; gs.glslflag= startscene->gm.flag; do { View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); #ifdef WITH_PYTHON bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0); #endif bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0); bool mouse_state = startscene->gm.flag & GAME_SHOW_MOUSE; bool restrictAnimFPS = startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES; if(animation_record) usefixed= true; /* override since you's always want fixed time for sim recording */ // create the canvas, rasterizer and rendertools RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar); // default mouse state set on render panel if (mouse_state) canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); else canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); RAS_IRenderTools* rendertools = new KX_BlenderRenderTools(); RAS_IRasterizer* rasterizer = NULL; if(displaylists) { if (GLEW_VERSION_1_1 && !novertexarrays) rasterizer = new RAS_ListRasterizer(canvas, true, true); else rasterizer = new RAS_ListRasterizer(canvas); } else if (GLEW_VERSION_1_1 && !novertexarrays) rasterizer = new RAS_VAOpenGLRasterizer(canvas, false); else rasterizer = new RAS_OpenGLRasterizer(canvas); // create the inputdevices KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); // create a networkdevice NG_NetworkDeviceInterface* networkdevice = new NG_LoopBackNetworkDeviceInterface(); // // create a ketsji/blendersystem (only needed for timing and stuff) KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); // create the ketsjiengine KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); // set the devices ketsjiengine->SetKeyboardDevice(keyboarddevice); ketsjiengine->SetMouseDevice(mousedevice); ketsjiengine->SetNetworkDevice(networkdevice); ketsjiengine->SetCanvas(canvas); ketsjiengine->SetRenderTools(rendertools); ketsjiengine->SetRasterizer(rasterizer); ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #endif //lock frame and camera enabled - storing global values int tmp_lay= startscene->lay; Object *tmp_camera = startscene->camera; if (v3d->scenelock==0){ startscene->lay= v3d->lay; startscene->camera= v3d->camera; } // some blender stuff float camzoom; int draw_letterbox = 0; if(rv3d->persp==RV3D_CAMOB) { if(startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */ camzoom = 1.0f; draw_letterbox = 1; } else { camzoom = 1.0 / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); } } else { camzoom = 2.0; } ketsjiengine->SetDrawType(v3d->drawtype); ketsjiengine->SetCameraZoom(camzoom); // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) { exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) BLO_blendfiledata_free(bfd); char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory if (exitstring != "") strcpy(basedpath, exitstring.Ptr()); // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in // blend files should be relative to that file, not some other file // that happened to be loaded first BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); // if it wasn't loaded, try it forced relative if (!bfd) { // just add "//" in front of it char temppath[242]; strcpy(temppath, "//"); strcat(temppath, basedpath); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } // if we got a loaded blendfile, proceed if (bfd) { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; if(blenderdata) { BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name)); BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); #ifdef WITH_PYTHON setGamePythonPath(G.main->name); #endif } } // else forget it, we can't find it else { exitrequested = KX_EXIT_REQUEST_QUIT_GAME; } } Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); if (scene) { int startFrame = scene->r.cfra; ketsjiengine->SetAnimRecordMode(animation_record, startFrame); // Quad buffered needs a special window. if(scene->gm.stereoflag == STEREO_ENABLED){ if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode); rasterizer->SetEyeSeparation(scene->gm.eyeseparation); } rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f); } if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { if (rv3d->persp != RV3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat)); ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat)); if(rv3d->persp == RV3D_ORTHO) { ketsjiengine->SetCameraOverrideClipping(-v3d->far, v3d->far); } else { ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); } ketsjiengine->SetCameraOverrideLens(v3d->lens); } // create a scene converter, create and convert the startingscene KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); ketsjiengine->SetSceneConverter(sceneconverter); sceneconverter->addInitFromFrame=false; if (always_use_expand_framing) sceneconverter->SetAlwaysUseExpandFraming(true); bool usemat = false, useglslmat = false; if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; if(GPU_glsl_support()) useglslmat = true; else if(gs.matmode == GAME_MAT_GLSL) usemat = false; if(usemat && (gs.matmode != GAME_MAT_TEXFACE)) sceneconverter->SetMaterials(true); if(useglslmat && (gs.matmode == GAME_MAT_GLSL)) sceneconverter->SetGLSLMaterials(true); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, networkdevice, startscenename, scene, canvas); #ifdef WITH_PYTHON // some python things PyObject *gameLogic, *gameLogic_keys; setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL); #endif // WITH_PYTHON //initialize Dome Settings if(scene->gm.stereoflag == STEREO_DOME) ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext); // initialize 3D Audio Settings AUD_I3DDevice* dev = AUD_get3DDevice(); if(dev) { dev->setSpeedOfSound(scene->audio.speed_of_sound); dev->setDopplerFactor(scene->audio.doppler_factor); dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model)); } // from see blender.c: // FIXME: this version patching should really be part of the file-reading code, // but we still get too many unrelated data-corruption crashes otherwise... if (blenderdata->versionfile < 250) do_versions_ipos_to_animato(blenderdata); if (sceneconverter) { // convert and add scene sceneconverter->ConvertScene( startscene, rendertools, canvas); ketsjiengine->AddScene(startscene); // init the rasterizer rasterizer->Init(); // start the engine ketsjiengine->StartEngine(true); // Set the animation playback rate for ipo's and actions // the framerate below should patch with FPS macro defined in blendef.h // Could be in StartEngine set the framerate, we need the scene to do this ketsjiengine->SetAnimFrameRate(FPS); // the mainloop printf("\nBlender Game Engine Started\n"); while (!exitrequested) { // first check if we want to exit exitrequested = ketsjiengine->GetExitCode(); // kick the engine bool render = ketsjiengine->NextFrame(); if (render) { if(draw_letterbox) { // Clear screen to border color // We do this here since we set the canvas to be within the frames. This means the engine // itself is unaware of the extra space, so we clear the whole region for it. glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f); glViewport(ar->winrct.xmin, ar->winrct.ymin, ar->winrct.xmax - ar->winrct.xmin, ar->winrct.ymax - ar->winrct.ymin); glClear(GL_COLOR_BUFFER_BIT); } // render the frame ketsjiengine->Render(); } wm_window_process_events_nosleep(); // test for the ESC key //XXX while (qtest()) while(wmEvent *event= (wmEvent *)win->queue.first) { short val = 0; //unsigned short event = 0; //XXX extern_qread(&val); if (keyboarddevice->ConvertBlenderEvent(event->type,event->val)) exitrequested = KX_EXIT_REQUEST_BLENDER_ESC; /* Coordinate conversion... where * should this really be? */ if (event->type==MOUSEMOVE) { /* Note, not nice! XXX 2.5 event hack */ val = event->x - ar->winrct.xmin; mousedevice->ConvertBlenderEvent(MOUSEX, val); val = ar->winy - (event->y - ar->winrct.ymin) - 1; mousedevice->ConvertBlenderEvent(MOUSEY, val); } else { mousedevice->ConvertBlenderEvent(event->type,event->val); } BLI_remlink(&win->queue, event); wm_event_free(event); } if(win != CTX_wm_window(C)) { exitrequested= KX_EXIT_REQUEST_OUTSIDE; /* window closed while bge runs */ } } printf("Blender Game Engine Finished\n"); exitstring = ketsjiengine->GetExitString(); gs = *(ketsjiengine->GetGlobalSettings()); // when exiting the mainloop #ifdef WITH_PYTHON // Clears the dictionary by hand: // This prevents, extra references to global variables // inside the GameLogic dictionary when the python interpreter is finalized. // which allows the scene to safely delete them :) // see: (space.c)->start_game //PyDict_Clear(PyModule_GetDict(gameLogic)); // Keep original items, means python plugins will autocomplete members PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic)); const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new); Py_ssize_t listIndex; for (listIndex=0; listIndex < numitems; listIndex++) { PyObject* item = PyList_GET_ITEM(gameLogic_keys_new, listIndex); if (!PySequence_Contains(gameLogic_keys, item)) { PyDict_DelItem( PyModule_GetDict(gameLogic), item); } } Py_DECREF(gameLogic_keys_new); gameLogic_keys_new = NULL; #endif ketsjiengine->StopEngine(); #ifdef WITH_PYTHON exitGamePythonScripting(); #endif networkdevice->Disconnect(); } if (sceneconverter) { delete sceneconverter; sceneconverter = NULL; } #ifdef WITH_PYTHON Py_DECREF(gameLogic_keys); gameLogic_keys = NULL; #endif } //lock frame and camera enabled - restoring global values if (v3d->scenelock==0){ startscene->lay= tmp_lay; startscene->camera= tmp_camera; } if(exitrequested != KX_EXIT_REQUEST_OUTSIDE) { // set the cursor back to normal canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); } // clean up some stuff if (ketsjiengine) { delete ketsjiengine; ketsjiengine = NULL; } if (kxsystem) { delete kxsystem; kxsystem = NULL; } if (networkdevice) { delete networkdevice; networkdevice = NULL; } if (keyboarddevice) { delete keyboarddevice; keyboarddevice = NULL; } if (mousedevice) { delete mousedevice; mousedevice = NULL; } if (rasterizer) { delete rasterizer; rasterizer = NULL; } if (rendertools) { delete rendertools; rendertools = NULL; } if (canvas) { delete canvas; canvas = NULL; } // stop all remaining playing sounds AUD_getDevice()->stopAll(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (!disableVBO) U.gameflags &= ~USER_DISABLE_VBO; if (bfd) BLO_blendfiledata_free(bfd); BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name)); #ifdef WITH_PYTHON Py_DECREF(pyGlobalDict); // Release Python's GIL PyGILState_Release(gilstate); #endif }
static void meshcache_do( MeshCacheModifierData *mcmd, Object *ob, DerivedMesh *UNUSED(dm), float (*vertexCos_Real)[3], int numVerts) { const bool use_factor = mcmd->factor < 1.0f; float (*vertexCos_Store)[3] = (use_factor || (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ? MEM_mallocN(sizeof(*vertexCos_Store) * numVerts, __func__) : NULL; float (*vertexCos)[3] = vertexCos_Store ? vertexCos_Store : vertexCos_Real; Scene *scene = mcmd->modifier.scene; const float fps = FPS; char filepath[FILE_MAX]; const char *err_str = NULL; bool ok; float time; /* -------------------------------------------------------------------- */ /* Interpret Time (the reading functions also do some of this ) */ if (mcmd->play_mode == MOD_MESHCACHE_PLAY_CFEA) { const float cfra = BKE_scene_frame_get(scene); switch (mcmd->time_mode) { case MOD_MESHCACHE_TIME_FRAME: { time = cfra; break; } case MOD_MESHCACHE_TIME_SECONDS: { time = cfra / fps; break; } case MOD_MESHCACHE_TIME_FACTOR: default: { time = cfra / fps; break; } } /* apply offset and scale */ time = (mcmd->frame_scale * time) - mcmd->frame_start; } else { /* if (mcmd->play_mode == MOD_MESHCACHE_PLAY_EVAL) { */ switch (mcmd->time_mode) { case MOD_MESHCACHE_TIME_FRAME: { time = mcmd->eval_frame; break; } case MOD_MESHCACHE_TIME_SECONDS: { time = mcmd->eval_time; break; } case MOD_MESHCACHE_TIME_FACTOR: default: { time = mcmd->eval_factor; break; } } } /* -------------------------------------------------------------------- */ /* Read the File (or error out when the file is bad) */ /* would be nice if we could avoid doing this _every_ frame */ BLI_strncpy(filepath, mcmd->filepath, sizeof(filepath)); BLI_path_abs(filepath, ID_BLEND_PATH(G.main, (ID *)ob)); switch (mcmd->type) { case MOD_MESHCACHE_TYPE_MDD: ok = MOD_meshcache_read_mdd_times(filepath, vertexCos, numVerts, mcmd->interp, time, fps, mcmd->time_mode, &err_str); break; case MOD_MESHCACHE_TYPE_PC2: ok = MOD_meshcache_read_pc2_times(filepath, vertexCos, numVerts, mcmd->interp, time, fps, mcmd->time_mode, &err_str); break; default: ok = false; break; } /* -------------------------------------------------------------------- */ /* tricky shape key integration (slow!) */ if (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE) { Mesh *me = ob->data; /* we could support any object type */ if (UNLIKELY(ob->type != OB_MESH)) { modifier_setError(&mcmd->modifier, "'Integrate' only valid for Mesh objects"); } else if (UNLIKELY(me->totvert != numVerts)) { modifier_setError(&mcmd->modifier, "'Integrate' original mesh vertex mismatch"); } else if (UNLIKELY(me->totpoly == 0)) { modifier_setError(&mcmd->modifier, "'Integrate' requires faces"); } else { /* the moons align! */ int i; float (*vertexCos_Source)[3] = MEM_mallocN(sizeof(*vertexCos_Source) * numVerts, __func__); float (*vertexCos_New)[3] = MEM_mallocN(sizeof(*vertexCos_New) * numVerts, __func__); MVert *mv = me->mvert; for (i = 0; i < numVerts; i++, mv++) { copy_v3_v3(vertexCos_Source[i], mv->co); } BKE_mesh_calc_relative_deform( me->mpoly, me->totpoly, me->mloop, me->totvert, (const float (*)[3])vertexCos_Source, /* from the original Mesh*/ (const float (*)[3])vertexCos_Real, /* the input we've been given (shape keys!) */ (const float (*)[3])vertexCos, /* the result of this modifier */ vertexCos_New /* the result of this function */ ); /* write the corrected locations back into the result */ memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * numVerts); MEM_freeN(vertexCos_Source); MEM_freeN(vertexCos_New); } } /* -------------------------------------------------------------------- */ /* Apply the transformation matrix (if needed) */ if (UNLIKELY(err_str)) { modifier_setError(&mcmd->modifier, "%s", err_str); } else if (ok) { bool use_matrix = false; float mat[3][3]; unit_m3(mat); if (mat3_from_axis_conversion(mcmd->forward_axis, mcmd->up_axis, 1, 2, mat)) { use_matrix = true; } if (mcmd->flip_axis) { float tmat[3][3]; unit_m3(tmat); if (mcmd->flip_axis & (1 << 0)) tmat[0][0] = -1.0f; if (mcmd->flip_axis & (1 << 1)) tmat[1][1] = -1.0f; if (mcmd->flip_axis & (1 << 2)) tmat[2][2] = -1.0f; mul_m3_m3m3(mat, tmat, mat); use_matrix = true; } if (use_matrix) { int i; for (i = 0; i < numVerts; i++) { mul_m3_v3(mat, vertexCos[i]); } } } if (vertexCos_Store) { if (ok) { if (use_factor) { interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3); } else { memcpy(vertexCos_Real, vertexCos_Store, sizeof(*vertexCos_Store) * numVerts); } } MEM_freeN(vertexCos_Store); } }
/** * Produce image export path. * * Returns: * 0 if image filename is empty or if destination path * matches image path (i.e. both are the same file). * 2 if source is identical to destination. * 1 if rebase was successful * ------------------------------------------------------------- * Hint: Trailing slash in dest_dir is optional. * * Logic: * * - if an image is "below" current .blend file directory: * rebuild the same dir structure in dest_dir * * Example: * src : //textures/foo/bar.png * dest: [dest_dir]/textures/foo/bar.png. * * - if an image is not "below" current .blend file directory, * disregard it's path and copy it into the destination * directory. * * Example: * src : //../foo/bar.png becomes * dest: [dest_dir]/bar.png. * * This logic ensures that all image paths are relative and * that a user gets his images in one place. It'll also provide * consistent behavior across exporters. * IMPORTANT NOTE: If base_dir contains an empty string, then * this function returns wrong results! * XXX: test on empty base_dir and return an error ? */ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const char *base_dir, const char *src_dir, const char *dest_dir) { char path[FILE_MAX]; char dir[FILE_MAX]; char base[FILE_MAX]; char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */ char dest_path[FILE_MAX]; char rel_dir[FILE_MAX]; int len; if (abs) abs[0] = 0; if (rel) rel[0] = 0; BLI_split_dir_part(base_dir, blend_dir, sizeof(blend_dir)); if (src_dir[0] == '\0') return BLI_REBASE_NO_SRCDIR; BLI_strncpy(path, src_dir, sizeof(path)); /* expand "//" in filename and get absolute path */ BLI_path_abs(path, base_dir); /* get the directory part */ BLI_split_dirfile(path, dir, base, sizeof(dir), sizeof(base)); len = strlen(blend_dir); rel_dir[0] = 0; /* if image is "below" current .blend file directory */ if (!BLI_path_ncmp(path, blend_dir, len)) { /* if image is _in_ current .blend file directory */ if (BLI_path_cmp(dir, blend_dir) == 0) { BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base); } /* "below" */ else { /* rel = image_path_dir - blend_dir */ BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir)); BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir); BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base); } } /* image is out of current directory */ else { BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base); } if (abs) BLI_strncpy(abs, dest_path, abs_len); if (rel) { strncat(rel, rel_dir, rel_len); strncat(rel, base, rel_len); } /* return 2 if (src == dest) */ if (BLI_path_cmp(path, dest_path) == 0) { // if (G.debug & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path); return BLI_REBASE_IDENTITY; } return BLI_REBASE_OK; }
/** * \note RNA_struct_property_is_set_ex is used here because we want * the previously used settings to be used here rather then overriding them */ short ED_fileselect_set_params(SpaceFile *sfile) { FileSelectParams *params; wmOperator *op = sfile->op; /* create new parameters if necessary */ if (!sfile->params) { sfile->params = MEM_callocN(sizeof(FileSelectParams), "fileselparams"); /* set path to most recently opened .blend */ BLI_split_dirfile(G.main->name, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file)); sfile->params->filter_glob[0] = '\0'; /* set the default thumbnails size */ sfile->params->thumbnail_size = 128; } params = sfile->params; /* set the parameters from the operator, if it exists */ if (op) { PropertyRNA *prop; const bool is_files = (RNA_struct_find_property(op->ptr, "files") != NULL); const bool is_filepath = (RNA_struct_find_property(op->ptr, "filepath") != NULL); const bool is_filename = (RNA_struct_find_property(op->ptr, "filename") != NULL); const bool is_directory = (RNA_struct_find_property(op->ptr, "directory") != NULL); const bool is_relative_path = (RNA_struct_find_property(op->ptr, "relative_path") != NULL); BLI_strncpy_utf8(params->title, RNA_struct_ui_name(op->type->srna), sizeof(params->title)); if ((prop = RNA_struct_find_property(op->ptr, "filemode"))) { params->type = RNA_property_int_get(op->ptr, prop); } else { params->type = FILE_SPECIAL; } if (is_filepath && RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) { char name[FILE_MAX]; RNA_string_get(op->ptr, "filepath", name); if (params->type == FILE_LOADLIB) { BLI_strncpy(params->dir, name, sizeof(params->dir)); sfile->params->file[0] = '\0'; } else { BLI_split_dirfile(name, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file)); } } else { if (is_directory && RNA_struct_property_is_set_ex(op->ptr, "directory", false)) { RNA_string_get(op->ptr, "directory", params->dir); sfile->params->file[0] = '\0'; } if (is_filename && RNA_struct_property_is_set_ex(op->ptr, "filename", false)) { RNA_string_get(op->ptr, "filename", params->file); } } if (params->dir[0]) { BLI_cleanup_dir(G.main->name, params->dir); BLI_path_abs(params->dir, G.main->name); } if (is_directory == true && is_filename == false && is_filepath == false && is_files == false) { params->flag |= FILE_DIRSEL_ONLY; } else { params->flag &= ~FILE_DIRSEL_ONLY; } params->filter = 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_blender"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_backup"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER_BACKUP : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_image"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_IMAGE : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_movie"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_MOVIE : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_python"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_PYSCRIPT : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_font"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_FTFONT : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_sound"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_SOUND : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_text"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_TEXT : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_folder"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_FOLDER : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_btx"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BTX : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_collada"))) params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_COLLADA : 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_glob"))) { RNA_property_string_get(op->ptr, prop, params->filter_glob); params->filter |= (FILE_TYPE_OPERATOR | FILE_TYPE_FOLDER); } else { params->filter_glob[0] = '\0'; } if (params->filter != 0) { if (U.uiflag & USER_FILTERFILEEXTS) { params->flag |= FILE_FILTER; } else { params->flag &= ~FILE_FILTER; } } if (U.uiflag & USER_HIDE_DOT) { params->flag |= FILE_HIDE_DOT; } else { params->flag &= ~FILE_HIDE_DOT; } if (params->type == FILE_LOADLIB) { params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0; params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0; params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0; } if ((prop = RNA_struct_find_property(op->ptr, "display_type"))) { params->display = RNA_property_enum_get(op->ptr, prop); } if (params->display == FILE_DEFAULTDISPLAY) { if (U.uiflag & USER_SHOW_THUMBNAILS) { if (params->filter & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE)) params->display = FILE_IMGDISPLAY; else params->display = FILE_SHORTDISPLAY; } else { params->display = FILE_SHORTDISPLAY; } } if (is_relative_path) { if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) { if (!RNA_property_is_set_ex(op->ptr, prop, false)) { RNA_property_boolean_set(op->ptr, prop, (U.flag & USER_RELPATHS) != 0); } } } } else { /* default values, if no operator */ params->type = FILE_UNIX; params->flag |= FILE_HIDE_DOT; params->flag &= ~FILE_DIRSEL_ONLY; params->display = FILE_SHORTDISPLAY; params->filter = 0; params->filter_glob[0] = '\0'; } /* operator has no setting for this */ params->sort = FILE_SORT_ALPHA; params->active_file = -1; /* initialize the list with previous folders */ if (!sfile->folders_prev) sfile->folders_prev = folderlist_new(); if (!sfile->params->dir[0]) { if (G.main->name[0]) { BLI_split_dir_part(G.main->name, sfile->params->dir, sizeof(sfile->params->dir)); } else { const char *doc_path = BKE_appdir_folder_default(); if (doc_path) { BLI_strncpy(sfile->params->dir, doc_path, sizeof(sfile->params->dir)); } } } folderlist_pushdir(sfile->folders_prev, sfile->params->dir); /* switching thumbnails needs to recalc layout [#28809] */ if (sfile->layout) { sfile->layout->dirty = true; } return 1; }
static DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifierData *fluidmd, int framenr, int useRenderParams) { int displaymode = 0; int curFrame = framenr - 1 /*scene->r.sfra*/; /* start with 0 at start frame */ char targetFile[FILE_MAX]; FluidsimSettings *fss = fluidmd->fss; DerivedMesh *dm = NULL; MPoly *mpoly; MPoly mp_example = {0}; if (!useRenderParams) { displaymode = fss->guiDisplayMode; } else { displaymode = fss->renderDisplayMode; } switch (displaymode) { case 1: /* just display original object */ return NULL; case 2: /* use preview mesh */ BLI_join_dirfile(targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_PREVIEW_OBJ_FNAME); break; default: /* 3 */ /* 3. use final mesh */ BLI_join_dirfile(targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME); break; } /* offset baked frame */ curFrame += fss->frameOffset; BLI_path_abs(targetFile, modifier_path_relbase(ob)); BLI_path_frame(targetFile, curFrame, 0); // fixed #frame-no // assign material + flags to new dm // if there's no faces in original dm, keep materials and flags unchanged mpoly = orgdm->getPolyArray(orgdm); if (mpoly) { mp_example = *mpoly; } /* else leave NULL'd */ dm = fluidsim_read_obj(targetFile, &mp_example); if (!dm) { // switch, abort background rendering when fluidsim mesh is missing const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp if (G.background == 1) { if (getenv(strEnvName2)) { int elevel = atoi(getenv(strEnvName2)); if (elevel > 0) { printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n", strEnvName2, targetFile); exit(1); } } } // display org. object upon failure which is in dm return NULL; } // load vertex velocities, if they exist... // TODO? use generate flag as loading flag as well? // warning, needs original .bobj.gz mesh loading filename if (displaymode == 3) { fluidsim_read_vel_cache(fluidmd, dm, targetFile); } else { if (fss->meshVelocities) MEM_freeN(fss->meshVelocities); fss->meshVelocities = NULL; } return dm; }
/* Get the output filename-- similar to the other output formats */ static void ffmpeg_filepath_get(FFMpegContext *context, char *string, RenderData *rd, bool preview, const char *suffix) { char autosplit[20]; const char **exts = get_file_extensions(rd->ffcodecdata.type); const char **fe = exts; int sfra, efra; if (!string || !exts) return; if (preview) { sfra = rd->psfra; efra = rd->pefra; } else { sfra = rd->sfra; efra = rd->efra; } strcpy(string, rd->pic); BLI_path_abs(string, G.main->name); BLI_make_existing_file(string); autosplit[0] = 0; if ((rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT) != 0) { if (context) { sprintf(autosplit, "_%03d", context->ffmpeg_autosplit_count); } } if (rd->scemode & R_EXTENSION) { while (*fe) { if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), *fe) == 0) { break; } fe++; } if (*fe == NULL) { strcat(string, autosplit); BLI_path_frame_range(string, sfra, efra, 4); strcat(string, *exts); } else { *(string + strlen(string) - strlen(*fe)) = 0; strcat(string, autosplit); strcat(string, *fe); } } else { if (BLI_path_frame_check_chars(string)) { BLI_path_frame_range(string, sfra, efra, 4); } strcat(string, autosplit); } BLI_path_suffix(string, FILE_MAX, suffix, ""); }
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ static void get_material_startjob(void *customdata, short *stop, short *do_update, float *progress) { Main *bmain; bContext *C; bNodeTree *ntree; MatItem *items; uint32_t buf_size; GetMaterialJob *mj = customdata; mj->stop = stop; mj->do_update = do_update; mj->progress = progress; ntree = mj->ntree; bmain = mj->bmain; C = mj->C; *progress = 0.1f; items = mat_livedb_get_material(mj->address, mj->mat_id, &buf_size); *progress = 0.9f; if(items) { bNode *node, *next; MatItem *cur_item = items; bNode *node_to; bNodeSocket *sock_to; char file_path[FILE_MAX]; float cur_y_pos = 0; /* Remove all existing nodes */ ED_preview_kill_jobs(CTX_wm_manager(C), bmain); for (node = ntree->nodes.first; node; node = next) { next = node->next; /* check id user here, nodeFreeNode is called for free dbase too */ if (node->id) node->id->us--; nodeFreeNode(ntree, node); } ntreeUpdateTree(bmain, ntree); node_to = nodeAddNode(C, ntree, "ShaderNodeOutputMaterial"); node_to->locx = 0; node_to->locy = 0; for (sock_to = node_to->inputs.first; sock_to; sock_to = sock_to->next) { if(!sock_to || strcmp(sock_to->name, "Surface")) continue; break; } /* create file path */ if(!strlen(G.main->name)) { char *cur_path = (char*)BKE_appdir_folder_id_create(BLENDER_USER_DATAFILES, 0); strcpy(file_path, cur_path); strcat(file_path, "/livedb/"); } else { BLI_strncpy(file_path, "//livedb/", sizeof(file_path)); BLI_path_abs(file_path, G.main->name); } strcat(file_path, mj->address); strcat(file_path, "/textures/"); BLI_path_native_slash(file_path); BLI_dir_create_recursive(file_path); mat_livedb_add_mat_element(bmain, C, ntree, node_to, sock_to, &cur_item, file_path, 0, &cur_y_pos); ED_node_tree_update(C); ED_node_tag_update_nodetree(bmain, ntree, 0); MEM_freeN(items); } *do_update = 1; *stop = 0; *progress = 1.0f; return; } /* get_material_job() */
static int file_browse_exec(bContext *C, wmOperator *op) { FileBrowseOp *fbo = op->customdata; ID *id; char *str, path[FILE_MAX]; const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; if (RNA_struct_property_is_set(op->ptr, path_prop) == 0 || fbo == NULL) return OPERATOR_CANCELLED; str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0); /* add slash for directories, important for some properties */ if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) { const bool is_relative = RNA_boolean_get(op->ptr, "relative_path"); id = fbo->ptr.id.data; BLI_strncpy(path, str, FILE_MAX); BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name); if (BLI_is_dir(path)) { /* do this first so '//' isnt converted to '//\' on windows */ BLI_add_slash(path); if (is_relative) { BLI_strncpy(path, str, FILE_MAX); BLI_path_rel(path, G.main->name); str = MEM_reallocN(str, strlen(path) + 2); BLI_strncpy(str, path, FILE_MAX); } else { str = MEM_reallocN(str, strlen(str) + 2); } } else { char * const lslash = (char *)BLI_last_slash(str); if (lslash) lslash[1] = '\0'; } } RNA_property_string_set(&fbo->ptr, fbo->prop, str); RNA_property_update(C, &fbo->ptr, fbo->prop); MEM_freeN(str); if (fbo->is_undo) { const char *undostr = RNA_property_identifier(fbo->prop); ED_undo_push(C, undostr); } /* special, annoying exception, filesel on redo panel [#26618] */ { wmOperator *redo_op = WM_operator_last_redo(C); if (redo_op) { if (fbo->ptr.data == redo_op->ptr->data) { ED_undo_operator_repeat(C, redo_op); } } } MEM_freeN(op->customdata); return OPERATOR_FINISHED; }
static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetFile, char *debugStrBuffer) { FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim); FluidsimSettings *domainSettings= fluidmd->fss; FILE *fileCfg; int dirExist = 0; char newSurfdataPath[FILE_MAX]; /* modified output settings */ const char *suffixConfigTmp = FLUID_SUFFIX_CONFIG_TMP; int outStringsChanged = 0; /* prepare names... */ const char *relbase= modifier_path_relbase(fsDomain); BLI_strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR); BLI_strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR); /* if 0'd out below, this value is never used! */ BLI_path_abs(targetDir, relbase); /* fixed #frame-no */ /* .tmp: don't overwrite/delete original file */ BLI_join_dirfile(targetFile, FILE_MAX, targetDir, suffixConfigTmp); // make sure all directories exist // as the bobjs use the same dir, this only needs to be checked // for the cfg output BLI_make_existing_file(targetFile); // check selected directory // simply try to open cfg file for writing to test validity of settings fileCfg = BLI_fopen(targetFile, "w"); if (fileCfg) { dirExist = 1; fclose(fileCfg); // remove cfg dummy from directory test BLI_delete(targetFile, false, false); } if (targetDir[0] == '\0' || (!dirExist)) { char blendFile[FILE_MAX]; // invalid dir, reset to current/previous BLI_split_file_part(G.main->name, blendFile, sizeof(blendFile)); BLI_replace_extension(blendFile, FILE_MAX, ""); /* strip .blend */ BLI_snprintf(newSurfdataPath, FILE_MAX, "//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name); BLI_snprintf(debugStrBuffer, 256, "fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath); elbeemDebugOut(debugStrBuffer); outStringsChanged=1; } /* check if modified output dir is ok */ #if 0 if (outStringsChanged) { char dispmsg[FILE_MAX+256]; int selection=0; BLI_strncpy(dispmsg, "Output settings set to: '", sizeof(dispmsg)); strcat(dispmsg, newSurfdataPath); strcat(dispmsg, "'%t|Continue with changed settings %x1|Discard and abort %x0"); /* ask user if thats what he/she wants... */ selection = pupmenu(dispmsg); if (selection < 1) return 0; /* 0 from menu, or -1 aborted */ BLI_strncpy(targetDir, newSurfdataPath, sizeof(targetDir)); strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR); BLI_path_abs(targetDir, G.main->name); /* fixed #frame-no */ } #endif return outStringsChanged; }
int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, int guimode) { int file, number; int ret_value = RET_OK; bool remove_tmp = false; char name[FILE_MAX]; char tempname[FILE_MAX]; /* void *data; */ if (guimode) {} //XXX waitcursor(1); BLI_strncpy(name, filename, sizeof(name)); BLI_path_abs(name, G.main->name); if (BLI_exists(name)) { for (number = 1; number <= 999; number++) { BLI_snprintf(tempname, sizeof(tempname), "%s.%03d_", name, number); if (!BLI_exists(tempname)) { if (BLI_copy(name, tempname) == RET_OK) { remove_tmp = true; } break; } } } /* make sure the path to the file exists... */ BLI_make_existing_file(name); file = BLI_open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666); if (file == -1) { BKE_reportf(reports, RPT_ERROR, "Error creating file '%s'", name); ret_value = RET_ERROR; } else { if (write(file, pf->data, pf->size) != pf->size) { BKE_reportf(reports, RPT_ERROR, "Error writing file '%s'", name); ret_value = RET_ERROR; } else { BKE_reportf(reports, RPT_INFO, "Saved packed file to: %s", name); } close(file); } if (remove_tmp) { if (ret_value == RET_ERROR) { if (BLI_rename(tempname, name) != 0) { BKE_reportf(reports, RPT_ERROR, "Error restoring temp file (check files '%s' '%s')", tempname, name); } } else { if (BLI_delete(tempname, false, false) != 0) { BKE_reportf(reports, RPT_ERROR, "Error deleting '%s' (ignored)", tempname); } } } if (guimode) {} //XXX waitcursor(0); return (ret_value); }
int main(int argc, char** argv) { int i; int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */ bool error = false; SYS_SystemHandle syshandle = SYS_GetSystem(); bool fullScreen = false; bool fullScreenParFound = false; bool windowParFound = false; #ifdef WIN32 bool closeConsole = true; #endif RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO; bool stereoWindow = false; bool stereoParFound = false; int stereoFlag = STEREO_NOSTEREO; int domeFov = -1; int domeTilt = -200; int domeMode = 0; char* domeWarp = NULL; Text *domeText = NULL; int windowLeft = 100; int windowTop = 100; int windowWidth = 640; int windowHeight = 480; GHOST_TUns32 fullScreenWidth = 0; GHOST_TUns32 fullScreenHeight= 0; int fullScreenBpp = 32; int fullScreenFrequency = 60; GHOST_TEmbedderWindowID parentWindow = 0; bool isBlenderPlayer = false; //true when lauching from blender or command line. false for bundled player int validArguments=0; bool samplesParFound = false; GHOST_TUns16 aasamples = 0; #ifdef __linux__ #ifdef __alpha__ signal (SIGFPE, SIG_IGN); #endif /* __alpha__ */ #endif /* __linux__ */ #ifdef WITH_SDL_DYNLOAD sdlewInit(); #endif BKE_appdir_program_path_init(argv[0]); BKE_tempdir_init(NULL); // We don't use threads directly in the BGE, but we need to call this so things like // freeing up GPU_Textures works correctly. BLI_threadapi_init(); RNA_init(); init_nodesystem(); initglobals(); U.gameflags |= USER_DISABLE_VBO; // We load our own G.main, so free the one that initglobals() gives us BKE_main_free(G.main); G.main = NULL; MEM_CacheLimiter_set_disabled(true); IMB_init(); BKE_images_init(); BKE_modifier_init(); DAG_init(); #ifdef WITH_FFMPEG IMB_ffmpeg_init(); #endif // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c) BLF_init(11, U.dpi); BLF_lang_init(); BLF_lang_set(""); BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size); if (blf_mono_font == -1) blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char*)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size); // Parse command line options #if defined(DEBUG) printf("argv[0] = '%s'\n", argv[0]); #endif #ifdef WIN32 if (scr_saver_init(argc, argv)) { switch (scr_saver_mode) { case SCREEN_SAVER_MODE_CONFIGURATION: MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK); break; case SCREEN_SAVER_MODE_PASSWORD: /* This is W95 only, which we currently do not support. * Fall-back to normal screen saver behavior in that case... */ case SCREEN_SAVER_MODE_SAVER: fullScreen = true; fullScreenParFound = true; break; case SCREEN_SAVER_MODE_PREVIEW: /* This will actually be handled somewhere below... */ break; } } #endif // XXX add the ability to change this values to the command line parsing. U.mixbufsize = 2048; U.audiodevice = 2; U.audiorate = 44100; U.audioformat = 0x24; U.audiochannels = 2; // XXX this one too U.anisotropic_filter = 2; // enable fast mipmap generation U.use_gpu_mipmap = 1; sound_init_once(); set_free_windowmanager_cb(wm_free); /* if running blenderplayer the last argument can't be parsed since it has to be the filename. else it is bundled */ isBlenderPlayer = !BLO_is_a_runtime(argv[0]); if (isBlenderPlayer) validArguments = argc - 1; else validArguments = argc; /* Parsing command line arguments (can be set from WM_OT_blenderplayer_start) */ #if defined(DEBUG) printf("Parsing command line arguments...\n"); printf("Num of arguments is: %i\n", validArguments-1); //-1 because i starts at 1 #endif for (i = 1; (i < validArguments) && !error #ifdef WIN32 && scr_saver_mode == SCREEN_SAVER_MODE_NONE #endif ;) { #if defined(DEBUG) printf("argv[%d] = '%s'\n", i, argv[i]); #endif if (argv[i][0] == '-') { /* ignore all args after " - ", allow python to have own args */ if (argv[i][1]=='\0') { argc_py_clamped= i; break; } switch (argv[i][1]) { case 'g': //game engine options (show_framerate, fixedtime, etc) { i++; if (i <= validArguments) { char* paramname = argv[i]; // Check for single value versus assignment if (i+1 <= validArguments && (*(argv[i+1]) == '=')) { i++; if (i + 1 <= validArguments) { i++; // Assignment SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i])); SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i])); SYS_WriteCommandLineString(syshandle, paramname, argv[i]); #if defined(DEBUG) printf("%s = '%s'\n", paramname, argv[i]); #endif i++; } else { error = true; printf("error: argument assignment %s without value.\n", paramname); } } else { // SYS_WriteCommandLineInt(syshandle, argv[i++], 1); } } break; } case 'd': //debug on { i++; G.debug |= G_DEBUG; MEM_set_memory_debug(); #ifdef DEBUG BLI_mempool_set_memory_debug(); #endif break; } case 'f': //fullscreen mode { i++; fullScreen = true; fullScreenParFound = true; if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { fullScreenWidth = atoi(argv[i++]); fullScreenHeight = atoi(argv[i++]); if ((i + 1) <= validArguments && argv[i][0] != '-') { fullScreenBpp = atoi(argv[i++]); if ((i + 1) <= validArguments && argv[i][0] != '-') fullScreenFrequency = atoi(argv[i++]); } } else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { error = true; printf("error: to define fullscreen width or height, both options must be used.\n"); } break; } case 'w': //display in a window { i++; fullScreen = false; windowParFound = true; // Parse window position and size options if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { windowWidth = atoi(argv[i++]); windowHeight = atoi(argv[i++]); if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { windowLeft = atoi(argv[i++]); windowTop = atoi(argv[i++]); } else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { error = true; printf("error: to define the window left or right coordinates, both options must be used.\n"); } } else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { error = true; printf("error: to define the window's width or height, both options must be used.\n"); } break; } case 'h': //display help { usage(argv[0], isBlenderPlayer); return 0; break; } case 'i': //parent window ID { i++; if ( (i + 1) <= validArguments ) parentWindow = atoi(argv[i++]); else { error = true; printf("error: too few options for parent window argument.\n"); } #if defined(DEBUG) printf("XWindows ID = %d\n", parentWindow); #endif // defined(DEBUG) break; } case 'm': //maximum anti-aliasing (eg. 2,4,8,16) { i++; samplesParFound = true; if ((i+1) <= validArguments ) aasamples = atoi(argv[i++]); else { error = true; printf("error: No argument supplied for -m"); } break; } case 'c': //keep console (windows only) { i++; #ifdef WIN32 closeConsole = false; #endif break; } case 's': //stereo mode { i++; if ((i + 1) <= validArguments) { stereoParFound = true; stereoFlag = STEREO_ENABLED; if (!strcmp(argv[i], "nostereo")) // may not be redundant if the file has different setting { stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO; stereoFlag = STEREO_NOSTEREO; } // only the hardware pageflip method needs a stereo window else if (!strcmp(argv[i], "hwpageflip")) { stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED; stereoWindow = true; } else if (!strcmp(argv[i], "syncdoubling")) stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW; else if (!strcmp(argv[i], "3dtvtopbottom")) stereomode = RAS_IRasterizer::RAS_STEREO_3DTVTOPBOTTOM; else if (!strcmp(argv[i], "anaglyph")) stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH; else if (!strcmp(argv[i], "sidebyside")) stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE; else if (!strcmp(argv[i], "interlace")) stereomode = RAS_IRasterizer::RAS_STEREO_INTERLACED; else if (!strcmp(argv[i], "vinterlace")) stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE; #if 0 // // future stuff // else if (!strcmp(argv[i], "stencil") // stereomode = RAS_STEREO_STENCIL; #endif else { error = true; printf("error: stereomode '%s' unrecognized.\n", argv[i]); } i++; } else { error = true; printf("error: too few options for stereo argument.\n"); } break; } case 'D': //dome mode { stereoFlag = STEREO_DOME; stereomode = RAS_IRasterizer::RAS_STEREO_DOME; i++; if ((i + 1) <= validArguments) { if (!strcmp(argv[i], "angle")) { i++; domeFov = atoi(argv[i++]); } if (!strcmp(argv[i], "tilt")) { i++; domeTilt = atoi(argv[i++]); } if (!strcmp(argv[i], "warpdata")) { i++; domeWarp = argv[i++]; } if (!strcmp(argv[i], "mode")) { i++; if (!strcmp(argv[i], "fisheye")) domeMode = DOME_FISHEYE; else if (!strcmp(argv[i], "truncatedfront")) domeMode = DOME_TRUNCATED_FRONT; else if (!strcmp(argv[i], "truncatedrear")) domeMode = DOME_TRUNCATED_REAR; else if (!strcmp(argv[i], "cubemap")) domeMode = DOME_ENVMAP; else if (!strcmp(argv[i], "sphericalpanoramic")) domeMode = DOME_PANORAM_SPH; else printf("error: %s is not a valid dome mode.\n", argv[i]); } i++; } break; } default: //not recognized { printf("Unknown argument: %s\n", argv[i++]); break; } } } else { i++; } } if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight)) { error = true; printf("error: window size too small.\n"); } if (error ) { usage(argv[0], isBlenderPlayer); return 0; } #ifdef WIN32 if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION) #endif { // Create the system if (GHOST_ISystem::createSystem() == GHOST_kSuccess) { GHOST_ISystem* system = GHOST_ISystem::getSystem(); assertd(system); if (!fullScreenWidth || !fullScreenHeight) system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight); // process first batch of events. If the user // drops a file on top off the blenderplayer icon, we // receive an event with the filename system->processEvents(0); // this bracket is needed for app (see below) to get out // of scope before GHOST_ISystem::disposeSystem() is called. { int exitcode = KX_EXIT_REQUEST_NO_REQUEST; STR_String exitstring = ""; GPG_Application app(system); bool firstTimeRunning = true; char filename[FILE_MAX]; char pathname[FILE_MAX]; char *titlename; get_filename(argc_py_clamped, argv, filename); if (filename[0]) BLI_path_cwd(filename); // fill the GlobalSettings with the first scene files // those may change during the game and persist after using Game Actuator GlobalSettings gs; do { // Read the Blender file BlendFileData *bfd; // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME) { char basedpath[FILE_MAX]; // base the actuator filename relative to the last file BLI_strncpy(basedpath, exitstring.Ptr(), sizeof(basedpath)); BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); if (!bfd) { // just add "//" in front of it char temppath[FILE_MAX] = "//"; BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } } else { bfd = load_game_data(BKE_appdir_program_path(), filename[0]? filename: NULL); } #if defined(DEBUG) printf("Game data loaded from %s\n", filename); #endif if (!bfd) { usage(argv[0], isBlenderPlayer); error = true; exitcode = KX_EXIT_REQUEST_QUIT_GAME; } else { /* Setting options according to the blend file if not overriden in the command line */ #ifdef WIN32 #if !defined(DEBUG) if (closeConsole) { system->toggleConsole(0); // Close a console window } #endif // !defined(DEBUG) #endif // WIN32 Main *maggie = bfd->main; Scene *scene = bfd->curscene; G.main = maggie; if (firstTimeRunning) { G.fileflags = bfd->fileflags; gs.matmode= scene->gm.matmode; gs.glslflag= scene->gm.flag; } //Seg Fault; icon.c gIcons == 0 BKE_icons_init(1); titlename = maggie->name; // Check whether the game should be displayed full-screen if ((!fullScreenParFound) && (!windowParFound)) { // Only use file settings when command line did not override if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) { //printf("fullscreen option found in Blender file\n"); fullScreen = true; fullScreenWidth= scene->gm.xplay; fullScreenHeight= scene->gm.yplay; fullScreenFrequency= scene->gm.freqplay; fullScreenBpp = scene->gm.depth; } else { fullScreen = false; windowWidth = scene->gm.xplay; windowHeight = scene->gm.yplay; } } // Check whether the game should be displayed in stereo (dome included) if (!stereoParFound) { // Only use file settings when command line did not override if (scene->gm.stereoflag == STEREO_ENABLED) { stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode; if (stereomode == RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) stereoWindow = true; } } else { scene->gm.stereoflag = STEREO_ENABLED; } if (!samplesParFound) aasamples = scene->gm.aasamples; // Dome specific settings if (stereoFlag == STEREO_DOME) { stereomode = RAS_IRasterizer::RAS_STEREO_DOME; scene->gm.stereoflag = STEREO_DOME; if (domeFov > 89) scene->gm.dome.angle = domeFov; if (domeTilt > -180) scene->gm.dome.tilt = domeTilt; if (domeMode > 0) scene->gm.dome.mode = domeMode; if (domeWarp) { //XXX to do: convert relative to absolute path domeText= BKE_text_load(G.main, domeWarp, ""); if (!domeText) printf("error: invalid warpdata text file - %s\n", domeWarp); else scene->gm.dome.warptext = domeText; } } // GPG_Application app (system, maggie, startscenename); app.SetGameEngineData(maggie, scene, &gs, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */ BLI_strncpy(pathname, maggie->name, sizeof(pathname)); if (G.main != maggie) { BLI_strncpy(G.main->name, maggie->name, sizeof(G.main->name)); } #ifdef WITH_PYTHON setGamePythonPath(G.main->name); #endif if (firstTimeRunning) { firstTimeRunning = false; if (fullScreen) { #ifdef WIN32 if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER) { app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency, stereoWindow, stereomode, aasamples); } else #endif { app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency, stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION)); } } else { #ifdef __APPLE__ // on Mac's we'll show the executable name instead of the 'game.blend' name char tempname[1024], *appstring; ::strcpy(tempname, titlename); appstring = strstr(tempname, ".app/"); if (appstring) { appstring[2] = 0; titlename = &tempname[0]; } #endif // Strip the path so that we have the name of the game file STR_String path = titlename; #ifndef WIN32 vector<STR_String> parts = path.Explode('/'); #else // WIN32 vector<STR_String> parts = path.Explode('\\'); #endif // WIN32 STR_String title; if (parts.size()) { title = parts[parts.size()-1]; parts = title.Explode('.'); if (parts.size() > 1) { title = parts[0]; } } else { title = "blenderplayer"; } #ifdef WIN32 if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW) { app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode, aasamples); } else #endif { if (parentWindow != 0) app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples); else app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight, stereoWindow, stereomode, aasamples); if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0)) { GPU_set_mipmap(0); } GPU_set_anisotropic(U.anisotropic_filter); GPU_set_gpu_mipmapping(U.use_gpu_mipmap); } } } else { app.StartGameEngine(stereomode); exitcode = KX_EXIT_REQUEST_NO_REQUEST; } // Add the application as event consumer system->addEventConsumer(&app); // Enter main loop bool run = true; char *python_main = NULL; pynextframestate.state = NULL; pynextframestate.func = NULL; #ifdef WITH_PYTHON python_main = KX_GetPythonMain(scene); #endif // WITH_PYTHON if (python_main) { char *python_code = KX_GetPythonCode(maggie, python_main); if (python_code) { #ifdef WITH_PYTHON gpg_nextframestate.system = system; gpg_nextframestate.app = &app; gpg_nextframestate.gs = &gs; pynextframestate.state = &gpg_nextframestate; pynextframestate.func = &GPG_PyNextFrame; printf("Yielding control to Python script '%s'...\n", python_main); PyRun_SimpleString(python_code); printf("Exit Python script '%s'\n", python_main); #endif // WITH_PYTHON MEM_freeN(python_code); } else { fprintf(stderr, "ERROR: cannot yield control to Python: no Python text data block named '%s'\n", python_main); } } else { while (run) { run = GPG_NextFrame(system, &app, exitcode, exitstring, &gs); } } app.StopGameEngine(); /* 'app' is freed automatic when out of scope. * removal is needed else the system will free an already freed value */ system->removeEventConsumer(&app); BLO_blendfiledata_free(bfd); /* G.main == bfd->main, it gets referenced in free_nodesystem so we can't have a dangling pointer */ G.main = NULL; if (python_main) MEM_freeN(python_main); } } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME); } // Seg Fault; icon.c gIcons == 0 BKE_icons_free(); // Dispose the system GHOST_ISystem::disposeSystem(); } else { error = true; printf("error: couldn't create a system.\n"); } } /* refer to WM_exit_ext() and free_blender(), * these are not called in the player but we need to match some of there behavior here, * if the order of function calls or blenders state isn't matching that of blender proper, * we may get troubles later on */ free_nodesystem(); // Cleanup RNA_exit(); BLF_exit(); #ifdef WITH_INTERNATIONAL BLF_free_unifont(); BLF_free_unifont_mono(); BLF_lang_free(); #endif IMB_exit(); BKE_images_exit(); DAG_exit(); IMB_moviecache_destruct(); SYS_DeleteSystem(syshandle); int totblock= MEM_get_memory_blocks_in_use(); if (totblock!=0) { printf("Error Totblock: %d\n",totblock); MEM_set_error_callback(mem_error_cb); MEM_printmemlist(); } BKE_tempdir_session_purge(); return error ? -1 : 0; }
/** * unpackFile() looks at the existing files (abs_name, local_name) and a packed file. * * It returns a char *to the existing file name / new file name or NULL when * there was an error or when the user decides to cancel the operation. * * \warning 'abs_name' may be relative still! (use a "//" prefix) be sure to run #BLI_path_abs on it first. */ char *unpackFile(ReportList *reports, const char *abs_name, const char *local_name, PackedFile *pf, int how) { char *newname = NULL; const char *temp = NULL; if (pf != NULL) { switch (how) { case -1: case PF_KEEP: break; case PF_REMOVE: temp = abs_name; break; case PF_USE_LOCAL: { char temp_abs[FILE_MAX]; BLI_strncpy(temp_abs, local_name, sizeof(temp_abs)); BLI_path_abs(temp_abs, G.main->name); /* if file exists use it */ if (BLI_exists(temp_abs)) { temp = local_name; break; } /* else create it */ /* fall-through */ } case PF_WRITE_LOCAL: if (writePackedFile(reports, local_name, pf, 1) == RET_OK) { temp = local_name; } break; case PF_USE_ORIGINAL: { char temp_abs[FILE_MAX]; BLI_strncpy(temp_abs, abs_name, sizeof(temp_abs)); BLI_path_abs(temp_abs, G.main->name); /* if file exists use it */ if (BLI_exists(temp_abs)) { BKE_reportf(reports, RPT_INFO, "Use existing file (instead of packed): %s", abs_name); temp = abs_name; break; } /* else create it */ /* fall-through */ } case PF_WRITE_ORIGINAL: if (writePackedFile(reports, abs_name, pf, 1) == RET_OK) { temp = abs_name; } break; default: printf("unpackFile: unknown return_value %d\n", how); break; } if (temp) { newname = BLI_strdup(temp); } } return newname; }
static DerivedMesh *fluidsim_read_cache(DerivedMesh *orgdm, FluidsimModifierData *fluidmd, int framenr, int useRenderParams) { int displaymode = 0; int curFrame = framenr - 1 /*scene->r.sfra*/; /* start with 0 at start frame */ char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR]; FluidsimSettings *fss = fluidmd->fss; DerivedMesh *dm = NULL; MFace *mface; int numfaces; int mat_nr, flag, i; if(!useRenderParams) { displaymode = fss->guiDisplayMode; } else { displaymode = fss->renderDisplayMode; } BLI_strncpy(targetDir, fss->surfdataPath, sizeof(targetDir)); // use preview or final mesh? if(displaymode==1) { // just display original object return NULL; } else if(displaymode==2) { strcat(targetDir,"fluidsurface_preview_####"); } else { // 3 strcat(targetDir,"fluidsurface_final_####"); } BLI_path_abs(targetDir, G.main->name); BLI_path_frame(targetDir, curFrame, 0); // fixed #frame-no BLI_snprintf(targetFile, sizeof(targetFile), "%s.bobj.gz", targetDir); dm = fluidsim_read_obj(targetFile); if(!dm) { // switch, abort background rendering when fluidsim mesh is missing const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp if(G.background==1) { if(getenv(strEnvName2)) { int elevel = atoi(getenv(strEnvName2)); if(elevel>0) { printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n",strEnvName2, targetFile); exit(1); } } } // display org. object upon failure which is in dm return NULL; } // assign material + flags to new dm mface = orgdm->getFaceArray(orgdm); mat_nr = mface[0].mat_nr; flag = mface[0].flag; mface = dm->getFaceArray(dm); numfaces = dm->getNumFaces(dm); for(i=0; i<numfaces; i++) { mface[i].mat_nr = mat_nr; mface[i].flag = flag; } // load vertex velocities, if they exist... // TODO? use generate flag as loading flag as well? // warning, needs original .bobj.gz mesh loading filename if(displaymode==3) { fluidsim_read_vel_cache(fluidmd, dm, targetFile); } else { if(fss->meshVelocities) MEM_freeN(fss->meshVelocities); fss->meshVelocities = NULL; } return dm; }
short ED_fileselect_set_params(SpaceFile *sfile) { FileSelectParams *params; wmOperator *op = sfile->op; /* create new parameters if necessary */ if (!sfile->params) { sfile->params= MEM_callocN(sizeof(FileSelectParams), "fileselparams"); /* set path to most recently opened .blend */ BLI_split_dirfile(G.main->name, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file)); sfile->params->filter_glob[0] = '\0'; } params = sfile->params; /* set the parameters from the operator, if it exists */ if (op) { const short is_files= (RNA_struct_find_property(op->ptr, "files") != NULL); const short is_filepath= (RNA_struct_find_property(op->ptr, "filepath") != NULL); const short is_filename= (RNA_struct_find_property(op->ptr, "filename") != NULL); const short is_directory= (RNA_struct_find_property(op->ptr, "directory") != NULL); const short is_relative_path= (RNA_struct_find_property(op->ptr, "relative_path") != NULL); BLI_strncpy(params->title, op->type->name, sizeof(params->title)); if(RNA_struct_find_property(op->ptr, "filemode")) params->type = RNA_int_get(op->ptr, "filemode"); else params->type = FILE_SPECIAL; if (is_filepath && RNA_struct_property_is_set(op->ptr, "filepath")) { char name[FILE_MAX]; RNA_string_get(op->ptr, "filepath", name); if (params->type == FILE_LOADLIB) { BLI_strncpy(params->dir, name, sizeof(params->dir)); sfile->params->file[0]= '\0'; } else { BLI_split_dirfile(name, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file)); } } else { if (is_directory && RNA_struct_property_is_set(op->ptr, "directory")) { RNA_string_get(op->ptr, "directory", params->dir); sfile->params->file[0]= '\0'; } if (is_filename && RNA_struct_property_is_set(op->ptr, "filename")) { RNA_string_get(op->ptr, "filename", params->file); } } if(params->dir[0]) { BLI_cleanup_dir(G.main->name, params->dir); BLI_path_abs(params->dir, G.main->name); } if(is_directory==TRUE && is_filename==FALSE && is_filepath==FALSE && is_files==FALSE) { params->flag |= FILE_DIRSEL_ONLY; } else { params->flag &= ~FILE_DIRSEL_ONLY; } params->filter = 0; if(RNA_struct_find_property(op->ptr, "filter_blender")) params->filter |= RNA_boolean_get(op->ptr, "filter_blender") ? BLENDERFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_image")) params->filter |= RNA_boolean_get(op->ptr, "filter_image") ? IMAGEFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_movie")) params->filter |= RNA_boolean_get(op->ptr, "filter_movie") ? MOVIEFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_text")) params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_python")) params->filter |= RNA_boolean_get(op->ptr, "filter_python") ? PYSCRIPTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_font")) params->filter |= RNA_boolean_get(op->ptr, "filter_font") ? FTFONTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_sound")) params->filter |= RNA_boolean_get(op->ptr, "filter_sound") ? SOUNDFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_text")) params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_folder")) params->filter |= RNA_boolean_get(op->ptr, "filter_folder") ? FOLDERFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_btx")) params->filter |= RNA_boolean_get(op->ptr, "filter_btx") ? BTXFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_collada")) params->filter |= RNA_boolean_get(op->ptr, "filter_collada") ? COLLADAFILE : 0; if (RNA_struct_find_property(op->ptr, "filter_glob")) { RNA_string_get(op->ptr, "filter_glob", params->filter_glob); params->filter |= (OPERATORFILE|FOLDERFILE); } else { params->filter_glob[0] = '\0'; } if (params->filter != 0) { if (U.uiflag & USER_FILTERFILEEXTS) { params->flag |= FILE_FILTER; } else { params->flag &= ~FILE_FILTER; } } if (U.uiflag & USER_HIDE_DOT) { params->flag |= FILE_HIDE_DOT; } else { params->flag &= ~FILE_HIDE_DOT; } if (params->type == FILE_LOADLIB) { params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0; params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0; params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0; } if(RNA_struct_find_property(op->ptr, "display_type")) params->display= RNA_enum_get(op->ptr, "display_type"); if(params->display==FILE_DEFAULTDISPLAY) { if (U.uiflag & USER_SHOW_THUMBNAILS) { if(params->filter & (IMAGEFILE|MOVIEFILE)) params->display= FILE_IMGDISPLAY; else params->display= FILE_SHORTDISPLAY; } else { params->display= FILE_SHORTDISPLAY; } } if (is_relative_path) { if (!RNA_struct_property_is_set(op->ptr, "relative_path")) { RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS); } } } else { /* default values, if no operator */ params->type = FILE_UNIX; params->flag |= FILE_HIDE_DOT; params->flag &= ~FILE_DIRSEL_ONLY; params->display = FILE_SHORTDISPLAY; params->filter = 0; params->filter_glob[0] = '\0'; params->sort = FILE_SORT_ALPHA; } /* initialize the list with previous folders */ if (!sfile->folders_prev) sfile->folders_prev = folderlist_new(); folderlist_pushdir(sfile->folders_prev, sfile->params->dir); /* switching thumbnails needs to recalc layout [#28809] */ if (sfile->layout) { sfile->layout->dirty= TRUE; } return 1; }
void BKE_sound_load(struct Main *bmain, bSound *sound) { if (sound) { if (sound->cache) { AUD_Sound_free(sound->cache); sound->cache = NULL; } if (sound->handle) { AUD_Sound_free(sound->handle); sound->handle = NULL; sound->playback_handle = NULL; } BKE_sound_free_waveform(sound); /* XXX unused currently */ #if 0 switch (sound->type) { case SOUND_TYPE_FILE: #endif { char fullpath[FILE_MAX]; /* load sound */ PackedFile *pf = sound->packedfile; /* don't modify soundact->sound->name, only change a copy */ BLI_strncpy(fullpath, sound->name, sizeof(fullpath)); BLI_path_abs(fullpath, ID_BLEND_PATH(bmain, &sound->id)); /* but we need a packed file then */ if (pf) sound->handle = AUD_Sound_bufferFile((unsigned char *) pf->data, pf->size); /* or else load it from disk */ else sound->handle = AUD_Sound_file(fullpath); } /* XXX unused currently */ #if 0 break; } case SOUND_TYPE_BUFFER: if (sound->child_sound && sound->child_sound->handle) sound->handle = AUD_bufferSound(sound->child_sound->handle); break; case SOUND_TYPE_LIMITER: if (sound->child_sound && sound->child_sound->handle) sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end); break; } #endif if (sound->flags & SOUND_FLAGS_MONO) { void *handle = AUD_Sound_rechannel(sound->handle, AUD_CHANNELS_MONO); AUD_Sound_free(sound->handle); sound->handle = handle; } if (sound->flags & SOUND_FLAGS_CACHING) { sound->cache = AUD_Sound_cache(sound->handle); } if (sound->cache) sound->playback_handle = sound->cache; else sound->playback_handle = sound->handle; BKE_sound_update_sequencer(bmain, sound); }
static void ui_draw_but_CHARTAB(uiBut *but) { /* XXX 2.50 bad global access */ /* Some local variables */ float sx, sy, ex, ey; float width, height; float butw, buth; int x, y, cs; wchar_t wstr[2]; unsigned char ustr[16]; PackedFile *pf; int result = 0; int charmax = G.charmax; /* FO_BUILTIN_NAME font in use. There are TTF FO_BUILTIN_NAME and non-TTF FO_BUILTIN_NAME fonts */ if(!strcmp(G.selfont->name, FO_BUILTIN_NAME)) { if(G.ui_international == TRUE) { charmax = 0xff; } else { charmax = 0xff; } } /* Category list exited without selecting the area */ if(G.charmax == 0) charmax = G.charmax = 0xffff; /* Calculate the size of the button */ width = abs(rect->xmax - rect->xmin); height = abs(rect->ymax - rect->ymin); butw = floor(width / 12); buth = floor(height / 6); /* Initialize variables */ sx = rect->xmin; ex = rect->xmin + butw; sy = rect->ymin + height - buth; ey = rect->ymin + height; cs = G.charstart; /* Set the font, in case it is not FO_BUILTIN_NAME font */ if(G.selfont && strcmp(G.selfont->name, FO_BUILTIN_NAME)) { // Is the font file packed, if so then use the packed file if(G.selfont->packedfile) { pf = G.selfont->packedfile; FTF_SetFont(pf->data, pf->size, 14.0); } else { char tmpStr[256]; int err; BLI_strncpy(tmpStr, G.selfont->name, sizeof(tmpStr)); BLI_path_abs(tmpStr, G.main->name); err = FTF_SetFont((unsigned char *)tmpStr, 0, 14.0); } } else { if(G.ui_international == TRUE) { FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 14.0); } } /* Start drawing the button itself */ glShadeModel(GL_SMOOTH); glColor3ub(200, 200, 200); glRectf((rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax)); glColor3ub(0, 0, 0); for(y = 0; y < 6; y++) { // Do not draw more than the category allows if(cs > charmax) break; for(x = 0; x < 12; x++) { // Do not draw more than the category allows if(cs > charmax) break; // Draw one grid cell glBegin(GL_LINE_LOOP); glVertex2f(sx, sy); glVertex2f(ex, sy); glVertex2f(ex, ey); glVertex2f(sx, ey); glEnd(); // Draw character inside the cell memset(wstr, 0, sizeof(wchar_t)*2); memset(ustr, 0, 16); // Set the font to be either unicode or FO_BUILTIN_NAME wstr[0] = cs; if(strcmp(G.selfont->name, FO_BUILTIN_NAME)) { BLI_strncpy_wchar_as_utf8((char *)ustr, (wchar_t *)wstr, sizeof(ustr)); } else { if(G.ui_international == TRUE) { BLI_strncpy_wchar_as_utf8((char *)ustr, (wchar_t *)wstr, sizeof(ustr)); } else { ustr[0] = cs; ustr[1] = 0; } } if((G.selfont && strcmp(G.selfont->name, FO_BUILTIN_NAME)) || (G.selfont && !strcmp(G.selfont->name, FO_BUILTIN_NAME) && G.ui_international == TRUE)) { float wid; float llx, lly, llz, urx, ury, urz; float dx, dy; float px, py; // Calculate the position wid = FTF_GetStringWidth((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8); FTF_GetBoundingBox((char *) ustr, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8); dx = urx-llx; dy = ury-lly; // This isn't fully functional since the but->aspect isn't working like I suspected px = sx + ((butw/but->aspect)-dx)/2; py = sy + ((buth/but->aspect)-dy)/2; // Set the position and draw the character ui_rasterpos_safe(px, py, but->aspect); FTF_DrawString((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8); } else { ui_rasterpos_safe(sx + butw/2, sy + buth/2, but->aspect); UI_DrawString(but->font, (char *) ustr, 0); } // Calculate the next position and character sx += butw; ex +=butw; cs++; } /* Add the y position and reset x position */ sy -= buth; ey -= buth; sx = rect->xmin; ex = rect->xmin + butw; } glShadeModel(GL_FLAT); /* Return Font Settings to original */ if(U.fontsize && U.fontname[0]) { result = FTF_SetFont((unsigned char *)U.fontname, 0, U.fontsize); } else if (U.fontsize) { result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, U.fontsize); } if (result == 0) { result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11); } /* resets the font size */ if(G.ui_international == TRUE) { // uiSetCurFont(but->block, UI_HELV); } }
void BLI_cleanup_path(const char *relabase, char *dir) { ptrdiff_t a; char *start, *eind; if (relabase) { BLI_path_abs(dir, relabase); } else { if (dir[0] == '/' && dir[1] == '/') { if (dir[2] == '\0') { return; /* path is "//" - cant clean it */ } dir = dir + 2; /* skip the first // */ } } /* Note * memmove(start, eind, strlen(eind) + 1); * is the same as * strcpy( start, eind ); * except strcpy should not be used because there is overlap, * so use memmove's slightly more obscure syntax - Campbell */ #ifdef WIN32 /* Note, this should really be moved to the file selector, * since this function is used in many areas */ if (strcmp(dir, ".") == 0) { /* happens for example in FILE_MAIN */ get_default_root(dir); return; } while ( (start = strstr(dir, "\\..\\")) ) { eind = start + strlen("\\..\\") - 1; a = start - dir - 1; while (a > 0) { if (dir[a] == '\\') break; a--; } if (a < 0) { break; } else { memmove(dir + a, eind, strlen(eind) + 1); } } while ( (start = strstr(dir, "\\.\\")) ) { eind = start + strlen("\\.\\") - 1; memmove(start, eind, strlen(eind) + 1); } while ( (start = strstr(dir, "\\\\")) ) { eind = start + strlen("\\\\") - 1; memmove(start, eind, strlen(eind) + 1); } #else if (dir[0] == '.') { /* happens, for example in FILE_MAIN */ dir[0] = '/'; dir[1] = 0; return; } /* support for odd paths: eg /../home/me --> /home/me * this is a valid path in blender but we cant handle this the usual way below * simply strip this prefix then evaluate the path as usual. pythons os.path.normpath() does this */ while ((strncmp(dir, "/../", 4) == 0)) { memmove(dir, dir + 4, strlen(dir + 4) + 1); } while ( (start = strstr(dir, "/../")) ) { eind = start + (4 - 1) /* strlen("/../") - 1 */; a = start - dir - 1; while (a > 0) { if (dir[a] == '/') break; a--; } if (a < 0) { break; } else { memmove(dir + a, eind, strlen(eind) + 1); } } while ( (start = strstr(dir, "/./")) ) { eind = start + (3 - 1) /* strlen("/./") - 1 */; memmove(start, eind, strlen(eind) + 1); } while ( (start = strstr(dir, "//")) ) { eind = start + (2 - 1) /* strlen("//") - 1 */; memmove(start, eind, strlen(eind) + 1); } #endif }
static int get_sequence_len(char *filename, int *ofs) { int frame; int numdigit; if (!BLI_path_frame_get(filename, &frame, &numdigit)) { return 1; } char path[FILE_MAX]; BLI_path_abs(filename, G.main->name); BLI_split_dir_part(filename, path, FILE_MAX); if (path[0] == '\0') { /* The filename had no path, so just use the blend file path. */ BLI_split_dir_part(G.main->name, path, FILE_MAX); } DIR *dir = opendir(path); if (dir == NULL) { fprintf(stderr, "Error opening directory '%s': %s\n", path, errno ? strerror(errno) : "unknown error"); return -1; } const char *ext = ".abc"; const char *basename = BLI_path_basename(filename); const int len = strlen(basename) - (numdigit + strlen(ext)); ListBase frames; BLI_listbase_clear(&frames); struct dirent *fname; while ((fname = readdir(dir)) != NULL) { /* do we have the right extension? */ if (!strstr(fname->d_name, ext)) { continue; } if (!STREQLEN(basename, fname->d_name, len)) { continue; } CacheFrame *cache_frame = MEM_callocN(sizeof(CacheFrame), "abc_frame"); BLI_path_frame_get(fname->d_name, &cache_frame->framenr, &numdigit); BLI_addtail(&frames, cache_frame); } closedir(dir); BLI_listbase_sort(&frames, cmp_frame); CacheFrame *cache_frame = frames.first; if (cache_frame) { int frame_curr = cache_frame->framenr; (*ofs) = frame_curr; while (cache_frame && (cache_frame->framenr == frame_curr)) { ++frame_curr; cache_frame = cache_frame->next; } BLI_freelistN(&frames); return frame_curr - (*ofs); } return 1; }
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ struct wmWindowManager *wm= CTX_wm_manager(C); struct wmWindow *win= CTX_wm_window(C); struct Scene *startscene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); RAS_Rect area_rect; area_rect.SetLeft(cam_frame->xmin); area_rect.SetBottom(cam_frame->ymin); area_rect.SetRight(cam_frame->xmax); area_rect.SetTop(cam_frame->ymax); int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; Main* blenderdata = maggie1; char* startscenename = startscene->id.name+2; char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; BlendFileData *bfd= NULL; BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); BLI_strncpy(oldsce, G.main->name, sizeof(oldsce)); #ifdef WITH_PYTHON resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path setGamePythonPath(G.main->name); // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */ #endif bgl::InitExtensions(true); // VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable int disableVBO = (U.gameflags & USER_DISABLE_VBO); U.gameflags |= USER_DISABLE_VBO; // Globals to be carried on over blender files GlobalSettings gs; gs.matmode= startscene->gm.matmode; gs.glslflag= startscene->gm.flag; do { View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0) && GPU_display_list_support(); #ifdef WITH_PYTHON bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0); #endif // bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0); bool mouse_state = (startscene->gm.flag & GAME_SHOW_MOUSE) != 0; bool restrictAnimFPS = (startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES) != 0; short drawtype = v3d->drawtype; /* we do not support material mode in game engine, force change to texture mode */ if (drawtype == OB_MATERIAL) drawtype = OB_TEXTURE; if (animation_record) usefixed= false; /* override since you don't want to run full-speed for sim recording */ // create the canvas and rasterizer RAS_ICanvas* canvas = new KX_BlenderCanvas(wm, win, area_rect, ar); // default mouse state set on render panel if (mouse_state) canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); else canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); // Setup vsync int previous_vsync = 0; canvas->GetSwapInterval(previous_vsync); if (startscene->gm.vsync == VSYNC_ADAPTIVE) canvas->SetSwapInterval(-1); else canvas->SetSwapInterval((startscene->gm.vsync == VSYNC_ON) ? 1 : 0); RAS_IRasterizer* rasterizer = NULL; //Don't use displaylists with VBOs //If auto starts using VBOs, make sure to check for that here if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO) rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage); else rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage); RAS_IRasterizer::MipmapOption mipmapval = rasterizer->GetMipmapping(); // create the inputdevices KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); // create a networkdevice NG_NetworkDeviceInterface* networkdevice = new NG_LoopBackNetworkDeviceInterface(); // // create a ketsji/blendersystem (only needed for timing and stuff) KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); // create the ketsjiengine KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); // set the devices ketsjiengine->SetKeyboardDevice(keyboarddevice); ketsjiengine->SetMouseDevice(mousedevice); ketsjiengine->SetNetworkDevice(networkdevice); ketsjiengine->SetCanvas(canvas); ketsjiengine->SetRasterizer(rasterizer); ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #endif //lock frame and camera enabled - storing global values int tmp_lay= startscene->lay; Object *tmp_camera = startscene->camera; if (v3d->scenelock==0) { startscene->lay= v3d->lay; startscene->camera= v3d->camera; } // some blender stuff float camzoom; int draw_letterbox = 0; if (rv3d->persp==RV3D_CAMOB) { if (startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */ camzoom = 1.0f; draw_letterbox = 1; } else { camzoom = 1.0f / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); } } else { camzoom = 2.0; } rasterizer->SetDrawingMode(drawtype); ketsjiengine->SetCameraZoom(camzoom); // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) { exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) BLO_blendfiledata_free(bfd); char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory if (exitstring != "") BLI_strncpy(basedpath, exitstring.ReadPtr(), sizeof(basedpath)); // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in // blend files should be relative to that file, not some other file // that happened to be loaded first BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); // if it wasn't loaded, try it forced relative if (!bfd) { // just add "//" in front of it char temppath[FILE_MAX] = "//"; BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } // if we got a loaded blendfile, proceed if (bfd) { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; if (blenderdata) { BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name)); BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); #ifdef WITH_PYTHON setGamePythonPath(G.main->name); #endif } } // else forget it, we can't find it else { exitrequested = KX_EXIT_REQUEST_QUIT_GAME; } } Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); if (scene) { int startFrame = scene->r.cfra; ketsjiengine->SetAnimRecordMode(animation_record, startFrame); // Quad buffered needs a special window. if (scene->gm.stereoflag == STEREO_ENABLED) { if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode); rasterizer->SetEyeSeparation(scene->gm.eyeseparation); } rasterizer->SetBackColor(scene->gm.framing.col); } if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { if (rv3d->persp != RV3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat)); ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat)); ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); ketsjiengine->SetCameraOverrideLens(v3d->lens); } // create a scene converter, create and convert the startingscene KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); ketsjiengine->SetSceneConverter(sceneconverter); if (always_use_expand_framing) sceneconverter->SetAlwaysUseExpandFraming(true); bool usemat = false, useglslmat = false; if (GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; if (GPU_glsl_support()) useglslmat = true; else if (gs.matmode == GAME_MAT_GLSL) usemat = false; if (usemat) sceneconverter->SetMaterials(true); if (useglslmat && (gs.matmode == GAME_MAT_GLSL)) sceneconverter->SetGLSLMaterials(true); if (scene->gm.flag & GAME_NO_MATERIAL_CACHING) sceneconverter->SetCacheMaterials(false); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, networkdevice, startscenename, scene, canvas); #ifdef WITH_PYTHON // some python things PyObject *gameLogic, *gameLogic_keys; setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL); #endif // WITH_PYTHON //initialize Dome Settings if (scene->gm.stereoflag == STEREO_DOME) ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext); // initialize 3D Audio Settings AUD_I3DDevice* dev = AUD_get3DDevice(); if (dev) { dev->setSpeedOfSound(scene->audio.speed_of_sound); dev->setDopplerFactor(scene->audio.doppler_factor); dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model)); } // from see blender.c: // FIXME: this version patching should really be part of the file-reading code, // but we still get too many unrelated data-corruption crashes otherwise... if (blenderdata->versionfile < 250) do_versions_ipos_to_animato(blenderdata); if (sceneconverter) { // convert and add scene sceneconverter->ConvertScene( startscene, rasterizer, canvas); ketsjiengine->AddScene(startscene); // init the rasterizer rasterizer->Init(); // start the engine ketsjiengine->StartEngine(true); // Set the animation playback rate for ipo's and actions // the framerate below should patch with FPS macro defined in blendef.h // Could be in StartEngine set the framerate, we need the scene to do this ketsjiengine->SetAnimFrameRate(FPS); #ifdef WITH_PYTHON char *python_main = NULL; pynextframestate.state = NULL; pynextframestate.func = NULL; python_main = KX_GetPythonMain(scene); // the mainloop printf("\nBlender Game Engine Started\n"); if (python_main) { char *python_code = KX_GetPythonCode(blenderdata, python_main); if (python_code) { ketsjinextframestate.ketsjiengine = ketsjiengine; ketsjinextframestate.C = C; ketsjinextframestate.win = win; ketsjinextframestate.scene = scene; ketsjinextframestate.ar = ar; ketsjinextframestate.keyboarddevice = keyboarddevice; ketsjinextframestate.mousedevice = mousedevice; ketsjinextframestate.draw_letterbox = draw_letterbox; pynextframestate.state = &ketsjinextframestate; pynextframestate.func = &BL_KetsjiPyNextFrame; printf("Yielding control to Python script '%s'...\n", python_main); PyRun_SimpleString(python_code); printf("Exit Python script '%s'\n", python_main); MEM_freeN(python_code); } } else #endif /* WITH_PYTHON */ { while (!exitrequested) { exitrequested = BL_KetsjiNextFrame(ketsjiengine, C, win, scene, ar, keyboarddevice, mousedevice, draw_letterbox); } } printf("Blender Game Engine Finished\n"); exitstring = ketsjiengine->GetExitString(); #ifdef WITH_PYTHON if (python_main) MEM_freeN(python_main); #endif /* WITH_PYTHON */ gs = *(ketsjiengine->GetGlobalSettings()); // when exiting the mainloop #ifdef WITH_PYTHON // Clears the dictionary by hand: // This prevents, extra references to global variables // inside the GameLogic dictionary when the python interpreter is finalized. // which allows the scene to safely delete them :) // see: (space.c)->start_game //PyDict_Clear(PyModule_GetDict(gameLogic)); // Keep original items, means python plugins will autocomplete members PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic)); const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new); Py_ssize_t listIndex; for (listIndex=0; listIndex < numitems; listIndex++) { PyObject *item = PyList_GET_ITEM(gameLogic_keys_new, listIndex); if (!PySequence_Contains(gameLogic_keys, item)) { PyDict_DelItem( PyModule_GetDict(gameLogic), item); } } Py_DECREF(gameLogic_keys_new); gameLogic_keys_new = NULL; #endif ketsjiengine->StopEngine(); #ifdef WITH_PYTHON exitGamePythonScripting(); #endif networkdevice->Disconnect(); } if (sceneconverter) { delete sceneconverter; sceneconverter = NULL; } #ifdef WITH_PYTHON Py_DECREF(gameLogic_keys); gameLogic_keys = NULL; #endif } //lock frame and camera enabled - restoring global values if (v3d->scenelock==0) { startscene->lay= tmp_lay; startscene->camera= tmp_camera; } if (exitrequested != KX_EXIT_REQUEST_OUTSIDE) { // set the cursor back to normal canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); // set mipmap setting back to its original value rasterizer->SetMipmapping(mipmapval); } // clean up some stuff if (ketsjiengine) { delete ketsjiengine; ketsjiengine = NULL; } if (kxsystem) { delete kxsystem; kxsystem = NULL; } if (networkdevice) { delete networkdevice; networkdevice = NULL; } if (keyboarddevice) { delete keyboarddevice; keyboarddevice = NULL; } if (mousedevice) { delete mousedevice; mousedevice = NULL; } if (rasterizer) { delete rasterizer; rasterizer = NULL; } if (canvas) { canvas->SetSwapInterval(previous_vsync); // Set the swap interval back delete canvas; canvas = NULL; } // stop all remaining playing sounds AUD_getDevice()->stopAll(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (!disableVBO) U.gameflags &= ~USER_DISABLE_VBO; if (bfd) BLO_blendfiledata_free(bfd); BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name)); #ifdef WITH_PYTHON Py_DECREF(pyGlobalDict); // Release Python's GIL PyGILState_Release(gilstate); #endif }
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ Scene *startscene = CTX_data_scene(C); Main* maggie1 = CTX_data_main(C); int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; Main* blenderdata = maggie1; char* startscenename = startscene->id.name + 2; char pathname[FILE_MAXDIR+FILE_MAXFILE]; std::string exitstring = ""; BlendFileData *bfd = NULL; BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); KX_SetOrigPath(std::string(blenderdata->name)); #ifdef WITH_PYTHON // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject *globalDict = PyDict_New(); #endif GlobalSettings gs; gs.glslflag = startscene->gm.flag; do { // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) { exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) { BLO_blendfiledata_free(bfd); } char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory if (!exitstring.empty()) { BLI_strncpy(basedpath, exitstring.c_str(), sizeof(basedpath)); } // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in // blend files should be relative to that file, not some other file // that happened to be loaded first BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); // if it wasn't loaded, try it forced relative if (!bfd) { // just add "//" in front of it char temppath[FILE_MAX] = "//"; BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } // if we got a loaded blendfile, proceed if (bfd) { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; if (blenderdata) { BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); } } // else forget it, we can't find it else { exitrequested = KX_EXIT_REQUEST_QUIT_GAME; } } Scene *scene = bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); RAS_IRasterizer::StereoMode stereoMode = RAS_IRasterizer::RAS_STEREO_NOSTEREO; if (scene) { // Quad buffered needs a special window. if (scene->gm.stereoflag == STEREO_ENABLED) { if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) { switch (scene->gm.stereomode) { case STEREO_QUADBUFFERED: { stereoMode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED; break; } case STEREO_ABOVEBELOW: { stereoMode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW; break; } case STEREO_INTERLACED: { stereoMode = RAS_IRasterizer::RAS_STEREO_INTERLACED; break; } case STEREO_ANAGLYPH: { stereoMode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH; break; } case STEREO_SIDEBYSIDE: { stereoMode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE; break; } case STEREO_VINTERLACE: { stereoMode = RAS_IRasterizer::RAS_STEREO_VINTERLACE; break; } case STEREO_3DTVTOPBOTTOM: { stereoMode = RAS_IRasterizer::RAS_STEREO_3DTVTOPBOTTOM; break; } } } } } GHOST_ISystem *system = GHOST_ISystem::getSystem(); LA_BlenderLauncher launcher = LA_BlenderLauncher(system, blenderdata, scene, &gs, stereoMode, 0, NULL, C, cam_frame, ar, always_use_expand_framing); #ifdef WITH_PYTHON launcher.SetPythonGlobalDict(globalDict); #endif // WITH_PYTHON launcher.InitEngine(); CM_Message(std::endl << "Blender Game Engine Started"); launcher.EngineMainLoop(); CM_Message("Blender Game Engine Finished"); exitrequested = launcher.GetExitRequested(); exitstring = launcher.GetExitString(); gs = *launcher.GetGlobalSettings(); launcher.ExitEngine(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (bfd) { BLO_blendfiledata_free(bfd); } #ifdef WITH_PYTHON PyDict_Clear(globalDict); Py_DECREF(globalDict); // Release Python's GIL PyGILState_Release(gilstate); #endif }
static PyObject *bpy_lib_write(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) { static const char *kwlist[] = { "filepath", "datablocks", /* optional */ "relative_remap", "fake_user", "compress", NULL, }; /* args */ const char *filepath; char filepath_abs[FILE_MAX]; PyObject *datablocks = NULL; bool use_relative_remap = false, use_fake_user = false, use_compress = false; if (!PyArg_ParseTupleAndKeywords( args, kwds, "sO!|$O&O&O&:write", (char **)kwlist, &filepath, &PySet_Type, &datablocks, PyC_ParseBool, &use_relative_remap, PyC_ParseBool, &use_fake_user, PyC_ParseBool, &use_compress)) { return NULL; } Main *bmain_src = G.main; int write_flags = 0; if (use_relative_remap) { write_flags |= G_FILE_RELATIVE_REMAP; } if (use_compress) { write_flags |= G_FILE_COMPRESS; } BLI_strncpy(filepath_abs, filepath, FILE_MAX); BLI_path_abs(filepath_abs, G.main->name); BKE_blendfile_write_partial_begin(bmain_src); /* array of ID's and backup any data we modify */ struct { ID *id; /* original values */ short id_flag; short id_us; } *id_store_array, *id_store; int id_store_len = 0; PyObject *ret; /* collect all id data from the set and store in 'id_store_array' */ { Py_ssize_t pos, hash; PyObject *key; id_store_array = MEM_mallocN(sizeof(*id_store_array) * PySet_Size(datablocks), __func__); id_store = id_store_array; pos = hash = 0; while (_PySet_NextEntry(datablocks, &pos, &key, &hash)) { if (!pyrna_id_FromPyObject(key, &id_store->id)) { PyErr_Format(PyExc_TypeError, "Expected and ID type, not %.200s", Py_TYPE(key)->tp_name); ret = NULL; goto finally; } else { id_store->id_flag = id_store->id->flag; id_store->id_us = id_store->id->us; if (use_fake_user) { id_store->id->flag |= LIB_FAKEUSER; } id_store->id->us = 1; BKE_blendfile_write_partial_tag_ID(id_store->id, true); id_store_len += 1; id_store++; } } } /* write blend */ int retval = 0; ReportList reports; BKE_reports_init(&reports, RPT_STORE); retval = BKE_blendfile_write_partial(bmain_src, filepath_abs, write_flags, &reports); /* cleanup state */ BKE_blendfile_write_partial_end(bmain_src); if (retval) { BKE_reports_print(&reports, RPT_ERROR_ALL); BKE_reports_clear(&reports); ret = Py_None; Py_INCREF(ret); } else { if (BPy_reports_to_error(&reports, PyExc_IOError, true) == 0) { PyErr_SetString(PyExc_IOError, "Unknown error writing library data"); } ret = NULL; } finally: /* clear all flags for ID's added to the store (may run on error too) */ id_store = id_store_array; for (int i = 0; i < id_store_len; id_store++, i++) { if (use_fake_user) { if ((id_store->id_flag & LIB_FAKEUSER) == 0) { id_store->id->flag &= ~LIB_FAKEUSER; } } id_store->id->us = id_store->id_us; BKE_blendfile_write_partial_tag_ID(id_store->id, false); } MEM_freeN(id_store_array); return ret; }
void ImagesExporter::export_UV_Image(Image *image, bool use_copies) { std::string name(id_name(image)); std::string translated_name(translate_id(name)); bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_name) == mImages.end(); if (not_yet_exported) { ImBuf *imbuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (!imbuf) { fprintf(stderr, "Collada export: image does not exist:\n%s\n", image->name); return; } bool is_dirty = (imbuf->userflags & IB_BITMAPDIRTY) != 0; ImageFormatData imageFormat; BKE_imbuf_to_image_format(&imageFormat, imbuf); short image_source = image->source; bool is_generated = image_source == IMA_SRC_GENERATED; bool is_packed = image->packedfile != NULL; char export_path[FILE_MAX]; char source_path[FILE_MAX]; char export_dir[FILE_MAX]; char export_file[FILE_MAX]; // Destination folder for exported assets BLI_split_dir_part(this->export_settings->filepath, export_dir, sizeof(export_dir)); if (is_generated || is_dirty || use_copies || is_packed) { // make absolute destination path BLI_strncpy(export_file, name.c_str(), sizeof(export_file)); BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat); BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file); // make dest directory if it doesn't exist BLI_make_existing_file(export_path); } if (is_generated || is_dirty || is_packed) { // This image in its current state only exists in Blender memory. // So we have to export it. The export will keep the image state intact, // so the exported file will not be associated with the image. if (BKE_imbuf_write_as(imbuf, export_path, &imageFormat, true) == 0) { fprintf(stderr, "Collada export: Cannot export image to:\n%s\n", export_path); return; } BLI_strncpy(export_path, export_file, sizeof(export_path)); } else { // make absolute source path BLI_strncpy(source_path, image->name, sizeof(source_path)); BLI_path_abs(source_path, G.main->name); BLI_cleanup_path(NULL, source_path); if (use_copies) { // This image is already located on the file system. // But we want to create copies here. // To move images into the same export directory. // Note: If an image is already located in the export folder, // then skip the copy (as it would result in a file copy error). if (BLI_path_cmp(source_path, export_path) != 0) { if (BLI_copy(source_path, export_path) != 0) { fprintf(stderr, "Collada export: Cannot copy image:\n source:%s\ndest :%s\n", source_path, export_path); return; } } BLI_strncpy(export_path, export_file, sizeof(export_path)); } else { // Do not make any copies, but use the source path directly as reference // to the original image BLI_strncpy(export_path, source_path, sizeof(export_path)); } } COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_name, translated_name); /* set name also to mNameNC. This helps other viewers import files exported from Blender better */ img.add(mSW); fprintf(stdout, "Collada export: Added image: %s\n", export_file); mImages.push_back(translated_name); BKE_image_release_ibuf(image, imbuf, NULL); } }