void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[][4]) { MeshDeformBind mdb; MVert *mvert; int a; waitcursor(1); start_progress_bar(); memset(&mdb, 0, sizeof(MeshDeformBind)); /* get mesh and cage mesh */ mdb.vertexcos= MEM_callocN(sizeof(float)*3*totvert, "MeshDeformCos"); mdb.totvert= totvert; mdb.cagedm= mesh_create_derived_no_deform(scene, mmd->object, NULL, CD_MASK_BAREMESH); mdb.totcagevert= mdb.cagedm->getNumVerts(mdb.cagedm); mdb.cagecos= MEM_callocN(sizeof(*mdb.cagecos)*mdb.totcagevert, "MeshDeformBindCos"); copy_m4_m4(mdb.cagemat, cagemat); mvert= mdb.cagedm->getVertArray(mdb.cagedm); for(a=0; a<mdb.totcagevert; a++) copy_v3_v3(mdb.cagecos[a], mvert[a].co); for(a=0; a<mdb.totvert; a++) mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a*3); /* solve */ #if 0 if(mmd->mode == MOD_MDEF_VOLUME) harmonic_coordinates_bind(scene, mmd, &mdb); else heat_weighting_bind(scene, dm, mmd, &mdb); #else harmonic_coordinates_bind(scene, mmd, &mdb); #endif /* assign bind variables */ mmd->bindcagecos= (float*)mdb.cagecos; mmd->totvert= mdb.totvert; mmd->totcagevert= mdb.totcagevert; copy_m4_m4(mmd->bindmat, mmd->object->obmat); /* transform bindcagecos to world space */ for(a=0; a<mdb.totcagevert; a++) mul_m4_v3(mmd->object->obmat, mmd->bindcagecos+a*3); /* free */ mdb.cagedm->release(mdb.cagedm); MEM_freeN(mdb.vertexcos); /* compact weights */ modifier_mdef_compact_influences((ModifierData*)mmd); end_progress_bar(); waitcursor(0); }
void image_preview_event(int event) { int exec = 0; if (event == 0) { G.scene->r.scemode &= ~R_COMP_CROP; exec = 1; } else { if (image_preview_active(curarea, NULL, NULL)) { G.scene->r.scemode |= R_COMP_CROP; exec = 1; } else G.scene->r.scemode &= ~R_COMP_CROP; } if (exec && G.scene->nodetree) { Scene *scene = G.scene; /* should work when no node editor in screen..., so we execute right away */ ntreeCompositTagGenerators(G.scene->nodetree); G.is_break = FALSE; G.scene->nodetree->timecursor = set_timecursor; G.scene->nodetree->test_break = blender_test_break; BIF_store_spare(); ntreeCompositExecTree(scene->nodetree, &scene->r, 1, &scene->view_settings, &scene->display_settings); /* 1 is do_previews */ G.scene->nodetree->timecursor = NULL; G.scene->nodetree->test_break = NULL; scrarea_do_windraw(curarea); waitcursor(0); WM_event_add_notifier(C, NC_IMAGE, ima_v); } }
void comap(void) { int k; int maxkeys, icolort, maxreg, ix, iy, numtot, numcor, lastkey, doc_read, pkey; float *plist = NULL, *ptr, *dbuf, xt, yt; double davx, davx2, davy, davy2, bx, by, xmin, xmax, ymin, ymax, xr, yr, sigx, sigy, xrange, yrange; char outstr[81]; /* Set wait cursor */ waitcursor(iwin, TRUE, 79); /* Recover all the lines from the doc file and store in the dbuf array. column 1 is the key, following columns are registers. correspondence analysis may have up to 24 registers. */ doc_read = TRUE; pkey = 0; maxkeys = MYMAX(key1,key2) + 1; maxreg = MYMAX(itxreg,ityreg) + 1; dbuf = (float *) NULL; if (unsdal(docxnam, &doc_read, pkey, plist, maxreg, &dbuf, &lastkey, maxkeys,maxreg) > 0) { /* Problem retrieving doc file, assume it does not exist */ if (dbuf) free(dbuf); sprintf(outstr," Could not read document file: %s",docxnam); spout(outstr); /* unset wait cursor */ waitcursor(iwin, FALSE, 0); return; } if (lastkey < MYMIN(key1,key2)) { if (dbuf) free(dbuf); sprintf(outstr," both keys needed %d & %d > lastkey = %d", key1,key2,lastkey); spout(outstr); /* unset wait cursor */ waitcursor(iwin, FALSE, 0); return; } /* Determine maximum/minimum x and y coordinates, avg, etc; */ xmin = ymin = FLT_MAX; xmax = ymax = -xmin; davx = davx2 = davy = davy2 = 0; /* Run time allocate of memory space for nkey[], bufx, bufy */ if ( (nkey = (int *) calloc((key1 * key2), sizeof(float)) ) == (int *) NULL) { spout(" *** Could not allocate memory"); waitcursor(iwin, FALSE, 0); return; } if ( (bufx = (float *) calloc((key1 * key2), sizeof(float)) ) == (float *) NULL) { spout(" *** Could not allocate memory"); waitcursor(iwin, FALSE, 0); return; } if ( (bufy = (float *) calloc((key1 * key2), sizeof(float)) ) == (float *) NULL) { spout(" ***Could not allocate memory"); waitcursor(iwin, FALSE, 0); return; } /* Remember current color in icontx */ icolort = icolor; /* Set current color to image almost white */ wicolor(icontx,colorgo+2); /* Clear the screen */ //clearover(NULL,NULL,NULL); ptr = dbuf + (key1-1) * maxreg; nline = 0; for (k = key1; k <= key2; k++) { /* Check that the key has some registers. */ if ( (*ptr) > 0.0) { nkey[nline] = k; /* image number */ bx = *(ptr + itxreg); /* dbuf[k][itxreg] */ by = *(ptr + ityreg); /* dbuf[k][ityreg] */ /* Record bx & by */ bufx[nline] = bx; bufy[nline] = by; nline++; /* Record max and min for bx & by */ xmin = MYMIN(bx,xmin); xmax = MYMAX(bx,xmax); ymin = MYMIN(by,ymin); ymax = MYMAX(by,ymax); /* record average and standard deviation for bx & by */ davx += bx; davx2 += (double)(bx * bx); davy += by; davy2 += (double)( by * by); } ptr += maxreg; } /* for (pkey = key1; pkey <= key2; pkey++) */ /* Calculate sigma and average */ davx /= (float) nline; davy /= (float) nline; sigx = sqrt((davx2 - (davx * davx / (float) nline)) / (double) (nline - 1)); sigy = sqrt((davy2 - (davy * davy / (float) nline)) / (double) (nline - 1)); xt = 2.0 * stndrt * sigx; yt = 2.0 * stndrt * sigy; xr = xmax - xmin; yr = ymax - ymin; xrange = MYMIN(xt, xr); yrange = MYMIN(yt, yr); /* Set plot size */ ixsize = iwidex - 2; iysize = ihighx - 2; ixmar = iymar = 1; numtot = numcor = 0; /* Find scale factors */ factxa = (float) (ixsize -1) / xrange; factxb = - (xmin * factxa) + ixmar + 0.5; factya = (float) (iysize-1) / yrange; factyb = - (ymin * factya) + iymar + 0.5; for (k = 0; k < nline; k++) { ix = (bufx[k] - xmin) * factxa + ixmar + 0.5; iy = (bufy[k] - ymin) * factya + iymar + 0.5; if (ix >= ixmar && ix <= ixsize && iy >= iymar && iy <= iysize) { /* Image is inside the plot extent; find the label number */ if (sayno) { /* write image number at this location on plot */ sprintf(outstr,"%d",nkey[k]); // itsize,just, inten,ipen, overprint witext(icontx,outstr,ix,iy, 0,0, -9,2, FALSE); } else { /* Draw a permanent circle at this position */ xorc(iwin, icontx, TRUE, ix, iy, itrad); xorc(imagsav, icontx, TRUE, ix, iy, itrad); } /* Increment total number of images within plot extent */ numcor += 1; } else { /* Image is outside of plot extent */ nkey[k] = - nkey[k]; } numtot += 1; /* Increment total number of images */ } sprintf(outstr," Images: %d Images within plot: %d",numtot,numcor); spout(outstr); /* Replace current color in icontx */ wicolor(icontx,icolort); /* Initialize bin counter for this map */ nowbin = 0; /* Set flag for each bin mask */ gotbin = gotavim = gotav = FALSE; /* Cancel wait cursor */ waitcursor(iwin, FALSE, 0); /* Start masking of correspondence map */ corr_mask(0); }
void ED_object_enter_editmode(bContext *C, int flag) { Scene *scene= CTX_data_scene(C); Base *base= NULL; Object *ob; ScrArea *sa= CTX_wm_area(C); View3D *v3d= NULL; int ok= 0; if (scene->id.lib) return; if (sa && sa->spacetype==SPACE_VIEW3D) v3d= sa->spacedata.first; if ((flag & EM_IGNORE_LAYER)==0) { base= CTX_data_active_base(C); /* active layer checked here for view3d */ if (base==NULL) return; else if (v3d && (base->lay & v3d->lay)==0) return; else if (!v3d && (base->lay & scene->lay)==0) return; } else { base= scene->basact; } if (ELEM3(NULL, base, base->object, base->object->data)) return; ob = base->object; if (object_data_is_libdata(ob)) { error_libdata(); return; } if (flag & EM_WAITCURSOR) waitcursor(1); ob->restore_mode = ob->mode; /* note, when switching scenes the object can have editmode data but * not be scene->obedit: bug 22954, this avoids calling self eternally */ if ((ob->restore_mode & OB_MODE_EDIT)==0) ED_object_toggle_modes(C, ob->mode); ob->mode= OB_MODE_EDIT; if (ob->type==OB_MESH) { BMEditMesh *em; ok= 1; scene->obedit = ob; /* context sees this */ EDBM_mesh_make(CTX_data_tool_settings(C), scene, ob); em = BMEdit_FromObject(ob); if (LIKELY(em)) { /* order doesn't matter */ EDBM_mesh_normals_update(em); BMEdit_RecalcTessellation(em); BM_mesh_select_mode_flush(em->bm); } WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene); } else if (ob->type==OB_ARMATURE) { bArmature *arm= base->object->data; if (!arm) return; /* * The function object_data_is_libdata make a problem here, the * check for ob->proxy return 0 and let blender enter to edit mode * this causes a crash when you try leave the edit mode. * The problem is that i can't remove the ob->proxy check from * object_data_is_libdata that prevent the bugfix #6614, so * i add this little hack here. */ if (arm->id.lib) { error_libdata(); return; } ok=1; scene->obedit= ob; ED_armature_to_edit(ob); /* to ensure all goes in restposition and without striding */ DAG_id_tag_update(&ob->id, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); // XXX: should this be OB_RECALC_DATA? WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, scene); } else if (ob->type==OB_FONT) { scene->obedit= ob; // XXX for context ok= 1; make_editText(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, scene); } else if (ob->type==OB_MBALL) { scene->obedit= ob; // XXX for context ok= 1; make_editMball(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MBALL, scene); } else if (ob->type==OB_LATTICE) { scene->obedit= ob; // XXX for context ok= 1; make_editLatt(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_LATTICE, scene); } else if (ob->type==OB_SURF || ob->type==OB_CURVE) { ok= 1; scene->obedit= ob; // XXX for context make_editNurb(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_CURVE, scene); } if (ok) { DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { scene->obedit= NULL; // XXX for context ob->mode &= ~OB_MODE_EDIT; WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); } if (flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode"); if (flag & EM_WAITCURSOR) waitcursor(0); }
void ED_object_exit_editmode(bContext *C, int flag) { /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */ Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); int freedata = flag & EM_FREEDATA; if (obedit==NULL) return; if (flag & EM_WAITCURSOR) waitcursor(1); if (obedit->type==OB_MESH) { Mesh *me= obedit->data; // if (EM_texFaceCheck()) if (me->edit_btmesh->bm->totvert>MESH_MAX_VERTS) { error("Too many vertices"); return; } EDBM_mesh_load(obedit); if (freedata) { EDBM_mesh_free(me->edit_btmesh); MEM_freeN(me->edit_btmesh); me->edit_btmesh= NULL; } if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) { mesh_octree_table(NULL, NULL, NULL, 'e'); mesh_mirrtopo_table(NULL, 'e'); } } else if (obedit->type==OB_ARMATURE) { ED_armature_from_edit(obedit); if (freedata) ED_armature_edit_free(obedit); } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { load_editNurb(obedit); if (freedata) free_editNurb(obedit); } else if (obedit->type==OB_FONT && freedata) { load_editText(obedit); if (freedata) free_editText(obedit); } else if (obedit->type==OB_LATTICE) { load_editLatt(obedit); if (freedata) free_editLatt(obedit); } else if (obedit->type==OB_MBALL) { load_editMball(obedit); if (freedata) free_editMball(obedit); } /* freedata only 0 now on file saves and render */ if (freedata) { ListBase pidlist; PTCacheID *pid; /* for example; displist make is different in editmode */ scene->obedit= NULL; // XXX for context /* flag object caches as outdated */ BKE_ptcache_ids_from_object(&pidlist, obedit, NULL, 0); for (pid=pidlist.first; pid; pid=pid->next) { if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; } BLI_freelistN(&pidlist); BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED); /* also flush ob recalc, doesn't take much overhead, but used for particles */ DAG_id_tag_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); if (flag & EM_DO_UNDO) ED_undo_push(C, "Editmode"); if (flag & EM_WAITCURSOR) waitcursor(0); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); obedit->mode &= ~OB_MODE_EDIT; } }
void backmen(int leftsidet) { static Widget iw_rowcolh; Widget iw_rowcolv; Widget iw_dums, iw_pushc, iw_pusha; float * fptrdum = NULL; if (iw_backmen == (Widget)0) { /* Create background enhancing menu widget first */ iw_backmen = wid_dialog(iw_win, 0, "Contrast options", -1,-1); iw_rowcolv = wid_rowcol(iw_backmen, 'v', -1,-1); /* Create label for scales */ wid_labelg(iw_rowcolv, 0, "Lower and upper end of ramp:", -1,-1); /* Create a horizontal row-col widget for scales */ iw_rowcolh = wid_rowcol(iw_rowcolv, 'h', -1,-1); /* Create scale widget for starting value ------------------ ngo */ iw_ngob = wid_scale(iw_rowcolh, 0, "", imagego,imageend, ngo, 180,50, -1,-1); /* Create scale widget for ending value -------------------- nend */ iw_nendb = wid_scale(iw_rowcolh, 0, "", imagego,imageend, nend, 180,50, -1,-1); XtAddCallback(iw_ngob, XmNvalueChangedCallback, (XtCallbackProc)backmen_butm,"0"); XtAddCallback(iw_nendb,XmNvalueChangedCallback, (XtCallbackProc)backmen_butm,"0"); /* Create box for apply ----------------------------------- apply */ iw_dums = wid_stdbut(iw_rowcolv, iw_backmen, &iw_dums, &iw_pushc, &iw_pusha, "CA", fin_cb,fin_cb ,backmen_buta, NULL); } else { /* Enhance menu widget already exists, update it */ /* Alter scale widget for starting value ------------------- ngo */ iw_ngob = wid_scale(iw_rowcolh, iw_ngob, "", imagego,imageend, ngo, 180,50, -1,-1); /* Alter scale widget for ending value -------------------- nend */ iw_nendb = wid_scale(iw_rowcolh, iw_nendb, "", imagego,imageend, nend, 180,50, -1,-1); } /* Set wait cursor */ waitcursor(iwin, TRUE, 79); if (leftsidet) { /* Free up ximage buffer, before creating a new one */ if (imagel) { XFree((void *)imagel); imagel = NULL; } /* Show left image using original ramp */ nsam2 = nsaml; nrow2 = nrowl; showimage(filedatal, TRUE, &cptrduml, TRUE, &imagel, FALSE, &fptrdum, FALSE, (float) filedatal->fmin_spi, (float) filedatal->fmax_spi, imagego, imageend); /* Shift left image to shifted location & display */ pickdisp(TRUE, FALSE); } else { /* Show right image using original ramp */ nsam2 = nsamr; nrow2 = nrowr; /* Free up ximage buffer, before creating a new one */ if (imager) { XFree((void *)imager); imager = NULL; } showimage(filedatar, TRUE, &cptrdumr, TRUE, &imager, FALSE, &fptrdum, FALSE, (float) filedatar->fmin_spi, (float) filedatar->fmax_spi, imagego, imageend); /* Shift right image to shifted location and display */ pickdisp(FALSE, TRUE); } leftside = leftsidet; /* Cancel waitcursor */ waitcursor(iwin, FALSE, 79); XtManageChild(iw_backmen); }
void backmen_buta(Widget iw_temp, XtPointer data, XtPointer calldata) { float fmint, fmaxt; float *fptrdum = NULL; /* Remove menu */ XtUnmanageChild(iw_backmen); /* Set wait cursor */ waitcursor(iwin, TRUE, 79); /* Set location for images */ placed = TRUE; if (leftside) { ixuln = ixull; iyuln = iyull; nsam2 = nsaml; nrow2 = nrowl; /* Find new displayed levels of fmin_spi and fmax_spi for left image */ fmint = (((float)(ngo - imagego) / (float)(imageend - imagego))) * (filedatal->fmax_spi - filedatal->fmin_spi) + filedatal->fmin_spi; fmaxt = (((float)(nend - imagego) / (float)(imageend - imagego))) * (filedatal->fmax_spi - filedatal->fmin_spi)+ filedatal->fmin_spi; /* Free up ximage buffer, before creating a new one */ if (imagel) { XFree((void *)imagel); imagel = NULL; } /* Show left image using new ramp */ showimage(filedatal, TRUE, &cptrduml, TRUE, &imagel, FALSE, &fptrdum, FALSE, fmint, fmaxt, imagego, imageend); /* Shift left image to shifted location and display */ pickdisp(TRUE, FALSE); } else { /* Set location for right images */ placed = TRUE; ixuln = ixulr; iyuln = iyulr; nsam2 = nsamr; nrow2 = nrowr; /* Find new displayed levels of fmin_spi and fmax_spi for right image */ fmint = (((float)(ngo - imagego) / (float)(imageend - imagego))) * (filedatar->fmax_spi - filedatar->fmin_spi) + filedatar->fmin_spi; fmaxt = (((float)(nend - imagego) / (float)(imageend - imagego))) * (filedatar->fmax_spi - filedatar->fmin_spi) + filedatar->fmin_spi; /* Free up ximage buffer, before creating a new one */ if (imager) { XFree((void *)imager); imager = NULL; } /* Show right image using new ramp */ showimage(filedatar, TRUE, &cptrdumr, TRUE, &imager, FALSE, &fptrdum, FALSE, fmint, fmaxt, imagego, imageend); /* Shift right image to shifted location and display */ pickdisp(FALSE, TRUE); } //printf ("%d...%d File Range: %7.2f ...%7.2f \n",imagego,imageend, // filedatar->fmin_spi,filedatar->fmax_spi); //printf ("%d...%d Range: %7.2f ...%7.2f \n",ngo,nend, fmint,fmaxt); /* Apply normal uncontrasted ramp to whole image */ ngo = imagego; nend = imageend; XmScaleSetValue(iw_ngob, ngo); XmScaleSetValue(iw_nendb, nend); /* Apply normal uncontrasted ramp to whole screen */ backmen_butm(NULL,NULL,NULL); /* Cancel waitcursor */ waitcursor(iwin, FALSE, 79); return; }
int fluidsimBake(bContext *C, ReportList *reports, Object *ob) { Scene *scene= CTX_data_scene(C); FILE *fileCfg; int i; Object *fsDomain = NULL; FluidsimSettings *domainSettings; Object *obit = NULL; /* object iterator */ Base *base; int origFrame = scene->r.cfra; char debugStrBuffer[256]; int dirExist = 0; int gridlevels = 0; int simAborted = 0; // was the simulation aborted by user? int doExportOnly = 0; char *exportEnvStr = "BLENDER_ELBEEMEXPORTONLY"; const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp //char *channelNames[3] = { "translation","rotation","scale" }; char *suffixConfig = "fluidsim.cfg"; char *suffixSurface = "fluidsurface"; char newSurfdataPath[FILE_MAXDIR+FILE_MAXFILE]; // modified output settings char targetDir[FILE_MAXDIR+FILE_MAXFILE]; // store & modify output settings char targetFile[FILE_MAXDIR+FILE_MAXFILE]; // temp. store filename from targetDir for access int outStringsChanged = 0; // modified? copy back before baking int haveSomeFluid = 0; // check if any fluid objects are set // config vars, inited before either export or run... double calcViscosity = 0.0; int noFrames; double aniFrameTime; float aniFrlen; int channelObjCount; float *bbStart = NULL; float *bbSize = NULL; float domainMat[4][4]; float invDomMat[4][4]; // channel data int allchannelSize; // fixed by no. of frames int startFrame = 1; // dont use scene->r.sfra here, always start with frame 1 // easy frame -> sim time calc float *timeAtFrame=NULL, *timeAtIndex=NULL; // domain float *channelDomainTime = NULL; float *channelDomainViscosity = NULL; float *channelDomainGravity = NULL; // objects (currently max. 256 objs) float *channelObjMove[256][3]; // object movments , 0=trans, 1=rot, 2=scale float *channelObjInivel[256]; // initial velocities float *channelObjActive[256]; // obj active channel /* fluid control channels */ float *channelAttractforceStrength[256]; float *channelAttractforceRadius[256]; float *channelVelocityforceStrength[256]; float *channelVelocityforceRadius[256]; FluidsimModifierData *fluidmd = NULL; Mesh *mesh = NULL; if(getenv(strEnvName)) { int dlevel = atoi(getenv(strEnvName)); elbeemSetDebugLevel(dlevel); snprintf(debugStrBuffer,256,"fluidsimBake::msg: Debug messages activated due to envvar '%s'\n",strEnvName); elbeemDebugOut(debugStrBuffer); } if(getenv(exportEnvStr)) { doExportOnly = atoi(getenv(exportEnvStr)); snprintf(debugStrBuffer,256,"fluidsimBake::msg: Exporting mode set to '%d' due to envvar '%s'\n",doExportOnly, exportEnvStr); elbeemDebugOut(debugStrBuffer); } // make sure it corresponds to startFrame setting // old: noFrames = scene->r.efra - scene->r.sfra +1; noFrames = scene->r.efra - 0; if(noFrames<=0) { BKE_report(reports, RPT_ERROR, "No frames to export - check your animation range settings."); return 0; } /* no object pointer, find in selected ones.. */ if(!ob) { for(base=scene->base.first; base; base= base->next) { if ((base)->flag & SELECT) { FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim); if(fluidmdtmp && (base->object->type==OB_MESH)) { if(fluidmdtmp->fss->type == OB_FLUIDSIM_DOMAIN) { ob = base->object; break; } } } } // no domains found? if(!ob) return 0; } channelObjCount = 0; for(base=scene->base.first; base; base= base->next) { FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim); obit = base->object; if( fluidmdtmp && (obit->type==OB_MESH) && (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH (fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE) ) { channelObjCount++; } } if (channelObjCount>=255) { BKE_report(reports, RPT_ERROR, "Cannot bake with more then 256 objects."); return 0; } /* check if there's another domain... */ for(base=scene->base.first; base; base= base->next) { FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim); obit = base->object; if( fluidmdtmp &&(obit->type==OB_MESH)) { if(fluidmdtmp->fss->type == OB_FLUIDSIM_DOMAIN) { if(obit != ob) { BKE_report(reports, RPT_ERROR, "There should be only one domain object."); return 0; } } } } // check if theres any fluid // abort baking if not... for(base=scene->base.first; base; base= base->next) { FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim); obit = base->object; if( fluidmdtmp && (obit->type==OB_MESH) && ((fluidmdtmp->fss->type == OB_FLUIDSIM_FLUID) || (fluidmdtmp->fss->type == OB_FLUIDSIM_INFLOW) )) { haveSomeFluid = 1; break; } } if(!haveSomeFluid) { BKE_report(reports, RPT_ERROR, "No fluid objects in scene."); return 0; } /* these both have to be valid, otherwise we wouldnt be here */ /* dont use ob here after...*/ fsDomain = ob; fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); domainSettings = fluidmd->fss; ob = NULL; mesh = fsDomain->data; // calculate bounding box fluid_get_bb(mesh->mvert, mesh->totvert, fsDomain->obmat, domainSettings->bbStart, domainSettings->bbSize); // reset last valid frame domainSettings->lastgoodframe = -1; /* rough check of settings... */ if(domainSettings->previewresxyz > domainSettings->resolutionxyz) { snprintf(debugStrBuffer,256,"fluidsimBake::warning - Preview (%d) >= Resolution (%d)... setting equal.\n", domainSettings->previewresxyz , domainSettings->resolutionxyz); elbeemDebugOut(debugStrBuffer); domainSettings->previewresxyz = domainSettings->resolutionxyz; } // set adaptive coarsening according to resolutionxyz // this should do as an approximation, with in/outflow // doing this more accurate would be overkill // perhaps add manual setting? if(domainSettings->maxRefine <0) { if(domainSettings->resolutionxyz>128) { gridlevels = 2; } else if(domainSettings->resolutionxyz>64) { gridlevels = 1; } else { gridlevels = 0; } } else { gridlevels = domainSettings->maxRefine; } snprintf(debugStrBuffer,256,"fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name , gridlevels ); elbeemDebugOut(debugStrBuffer); // prepare names... strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR); strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR); BLI_convertstringcode(targetDir, G.sce); // fixed #frame-no strcpy(targetFile, targetDir); strcat(targetFile, suffixConfig); if(!doExportOnly) { strcat(targetFile,".tmp"); } // dont overwrite/delete original file // 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 = fopen(targetFile, "w"); if(fileCfg) { dirExist = 1; fclose(fileCfg); // remove cfg dummy from directory test if(!doExportOnly) { BLI_delete(targetFile, 0,0); } } if((strlen(targetDir)<1) || (!dirExist)) { char blendDir[FILE_MAXDIR+FILE_MAXFILE], blendFile[FILE_MAXDIR+FILE_MAXFILE]; // invalid dir, reset to current/previous strcpy(blendDir, G.sce); BLI_splitdirstring(blendDir, blendFile); if(strlen(blendFile)>6){ int len = strlen(blendFile); if( (blendFile[len-6]=='.')&& (blendFile[len-5]=='b')&& (blendFile[len-4]=='l')&& (blendFile[len-3]=='e')&& (blendFile[len-2]=='n')&& (blendFile[len-1]=='d') ){ blendFile[len-6] = '\0'; } } // todo... strip .blend ? snprintf(newSurfdataPath,FILE_MAXFILE+FILE_MAXDIR,"//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name); 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(outStringsChanged) { char dispmsg[FILE_MAXDIR+FILE_MAXFILE+256]; int selection=0; strcpy(dispmsg,"Output settings set to: '"); 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 strcpy(targetDir, newSurfdataPath); strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR); BLI_convertstringcode(targetDir, G.sce); // fixed #frame-no } // -------------------------------------------------------------------------------------------- // dump data for start frame // CHECK more reasonable to number frames according to blender? // dump data for frame 0 scene->r.cfra = startFrame; ED_update_for_newframe(C, 1); // init common export vars for both file export and run for(i=0; i<256; i++) { channelObjMove[i][0] = channelObjMove[i][1] = channelObjMove[i][2] = NULL; channelObjInivel[i] = NULL; channelObjActive[i] = NULL; channelAttractforceStrength[i] = NULL; channelAttractforceRadius[i] = NULL; channelVelocityforceStrength[i] = NULL; channelVelocityforceRadius[i] = NULL; } allchannelSize = scene->r.efra; // always use till last frame aniFrameTime = (domainSettings->animEnd - domainSettings->animStart)/(double)noFrames; // blender specific - scale according to map old/new settings in anim panel: aniFrlen = scene->r.framelen; if(domainSettings->viscosityMode==1) { /* manual mode, visc=value/(10^-vexp) */ calcViscosity = (1.0/pow(10.0,domainSettings->viscosityExponent)) * domainSettings->viscosityValue; } else { calcViscosity = fluidsimViscosityPreset[ domainSettings->viscosityMode ]; } bbStart = domainSettings->bbStart; bbSize = domainSettings->bbSize; // always init { int timeIcu[1] = { FLUIDSIM_TIME }; float timeDef[1] = { 1. }; int gravIcu[3] = { FLUIDSIM_GRAV_X, FLUIDSIM_GRAV_Y, FLUIDSIM_GRAV_Z }; float gravDef[3]; int viscIcu[1] = { FLUIDSIM_VISC }; float viscDef[1] = { 1. }; gravDef[0] = domainSettings->gravx; gravDef[1] = domainSettings->gravy; gravDef[2] = domainSettings->gravz; // time channel is a bit special, init by hand... timeAtIndex = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatindex"); for(i=0; i<=scene->r.efra; i++) { timeAtIndex[i] = (float)(i-startFrame); } fluidsimInitChannel(scene, &channelDomainTime, allchannelSize, timeAtIndex, timeIcu,timeDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB // time channel is a multiplicator for aniFrameTime if(channelDomainTime) { for(i=0; i<allchannelSize; i++) { channelDomainTime[i*2+0] = aniFrameTime * channelDomainTime[i*2+0]; if(channelDomainTime[i*2+0]<0.) channelDomainTime[i*2+0] = 0.; } } timeAtFrame = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatframe"); timeAtFrame[0] = timeAtFrame[1] = domainSettings->animStart; // start at index 1 if(channelDomainTime) { for(i=2; i<=allchannelSize; i++) { timeAtFrame[i] = timeAtFrame[i-1]+channelDomainTime[(i-1)*2+0]; } } else { for(i=2; i<=allchannelSize; i++) { timeAtFrame[i] = timeAtFrame[i-1]+aniFrameTime; } } fluidsimInitChannel(scene, &channelDomainViscosity, allchannelSize, timeAtFrame, viscIcu,viscDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB if(channelDomainViscosity) { for(i=0; i<allchannelSize; i++) { channelDomainViscosity[i*2+0] = calcViscosity * channelDomainViscosity[i*2+0]; } } fluidsimInitChannel(scene, &channelDomainGravity, allchannelSize, timeAtFrame, gravIcu,gravDef, domainSettings->ipo, CHANNEL_VEC ); } // domain channel init // init obj movement channels channelObjCount=0; for(base=scene->base.first; base; base= base->next) { FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim); obit = base->object; if( fluidmdtmp && (obit->type==OB_MESH) && (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH (fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE) ) { // cant use fluidsimInitChannel for obj channels right now, due // to the special DXXX channels, and the rotation specialities IpoCurve *icuex[3][3]; //IpoCurve *par_icuex[3][3]; #if 0 int icuIds[3][3] = { {OB_LOC_X, OB_LOC_Y, OB_LOC_Z}, {OB_ROT_X, OB_ROT_Y, OB_ROT_Z}, {OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z} }; int icudIds[3][3] = { {OB_DLOC_X, OB_DLOC_Y, OB_DLOC_Z}, {OB_DROT_X, OB_DROT_Y, OB_DROT_Z}, {OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z} }; #endif // relative ipos IpoCurve *icudex[3][3]; //IpoCurve *par_icudex[3][3]; int j,k; float vals[3] = {0.0,0.0,0.0}; int o = channelObjCount; int inivelIcu[3] = { FLUIDSIM_VEL_X, FLUIDSIM_VEL_Y, FLUIDSIM_VEL_Z }; float inivelDefs[3]; int activeIcu[1] = { FLUIDSIM_ACTIVE }; float activeDefs[1] = { 1 }; // default to on inivelDefs[0] = fluidmdtmp->fss->iniVelx; inivelDefs[1] = fluidmdtmp->fss->iniVely; inivelDefs[2] = fluidmdtmp->fss->iniVelz; // check & init loc,rot,size for(j=0; j<3; j++) { for(k=0; k<3; k++) { // XXX prevent invalid memory access until this works icuex[j][k]= NULL; icudex[j][k]= NULL; // XXX icuex[j][k] = find_ipocurve(obit->ipo, icuIds[j][k] ); // XXX icudex[j][k] = find_ipocurve(obit->ipo, icudIds[j][k] ); // XXX lines below were already disabled! //if(obit->parent) { //par_icuex[j][k] = find_ipocurve(obit->parent->ipo, icuIds[j][k] ); //par_icudex[j][k] = find_ipocurve(obit->parent->ipo, icudIds[j][k] ); //} } } for(j=0; j<3; j++) { channelObjMove[o][j] = MEM_callocN( allchannelSize*4*sizeof(float), "fluidsiminit_objmovchannel"); for(i=1; i<=allchannelSize; i++) { for(k=0; k<3; k++) { if(icuex[j][k]) { // IPO exists, use it ... // XXX calc_icu(icuex[j][k], aniFrlen*((float)i) ); vals[k] = icuex[j][k]->curval; if(obit->parent) { // add parent transform, multiply scaling, add trafo&rot //calc_icu(par_icuex[j][k], aniFrlen*((float)i) ); //if(j==2) { vals[k] *= par_icuex[j][k]->curval; } //else { vals[k] += par_icuex[j][k]->curval; } } } else { // use defaults from static values float setval=0.0; if(j==0) { setval = obit->loc[k]; if(obit->parent){ setval += obit->parent->loc[k]; } } else if(j==1) { setval = ( 180.0*obit->rot[k] )/( 10.0*M_PI ); if(obit->parent){ setval = ( 180.0*(obit->rot[k]+obit->parent->rot[k]) )/( 10.0*M_PI ); } } else { setval = obit->size[k]; if(obit->parent){ setval *= obit->parent->size[k]; } } vals[k] = setval; } if(icudex[j][k]) { // XXX calc_icu(icudex[j][k], aniFrlen*((float)i) ); //vals[k] += icudex[j][k]->curval; // add transform, multiply scaling, add trafo&rot if(j==2) { vals[k] *= icudex[j][k]->curval; } else { vals[k] += icudex[j][k]->curval; } if(obit->parent) { // add parent transform, multiply scaling, add trafo&rot //calc_icu(par_icuex[j][k], aniFrlen*((float)i) ); //if(j==2) { vals[k] *= par_icudex[j][k]->curval; } //else { vals[k] += par_icudex[j][k]->curval; } } } } // k for(k=0; k<3; k++) { float set = vals[k]; if(j==1) { // rot is downscaled by 10 for ipo !? set = 360.0 - (10.0*set); } channelObjMove[o][j][(i-1)*4 + k] = set; } // k channelObjMove[o][j][(i-1)*4 + 3] = timeAtFrame[i]; } } { int attrFSIcu[1] = { FLUIDSIM_ATTR_FORCE_STR }; int attrFRIcu[1] = { FLUIDSIM_ATTR_FORCE_RADIUS }; int velFSIcu[1] = { FLUIDSIM_VEL_FORCE_STR }; int velFRIcu[1] = { FLUIDSIM_VEL_FORCE_RADIUS }; float attrFSDefs[1]; float attrFRDefs[1]; float velFSDefs[1]; float velFRDefs[1]; attrFSDefs[0] = fluidmdtmp->fss->attractforceStrength; attrFRDefs[0] = fluidmdtmp->fss->attractforceRadius; velFSDefs[0] = fluidmdtmp->fss->velocityforceStrength; velFRDefs[0] = fluidmdtmp->fss->velocityforceRadius; fluidsimInitChannel(scene, &channelAttractforceStrength[o], allchannelSize, timeAtFrame, attrFSIcu,attrFSDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT ); fluidsimInitChannel(scene, &channelAttractforceRadius[o], allchannelSize, timeAtFrame, attrFRIcu,attrFRDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT ); fluidsimInitChannel(scene, &channelVelocityforceStrength[o], allchannelSize, timeAtFrame, velFSIcu,velFSDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT ); fluidsimInitChannel(scene, &channelVelocityforceRadius[o], allchannelSize, timeAtFrame, velFRIcu,velFRDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT ); } fluidsimInitChannel(scene, &channelObjInivel[o], allchannelSize, timeAtFrame, inivelIcu,inivelDefs, fluidmdtmp->fss->ipo, CHANNEL_VEC ); fluidsimInitChannel(scene, &channelObjActive[o], allchannelSize, timeAtFrame, activeIcu,activeDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT ); channelObjCount++; } } // init trafo matrix Mat4CpyMat4(domainMat, fsDomain->obmat); if(!Mat4Invert(invDomMat, domainMat)) { snprintf(debugStrBuffer,256,"fluidsimBake::error - Invalid obj matrix?\n"); elbeemDebugOut(debugStrBuffer); BKE_report(reports, RPT_ERROR, "Invalid object matrix."); // FIXME add fatal msg FS_FREE_CHANNELS; return 0; } // -------------------------------------------------------------------------------------------- // start writing / exporting strcpy(targetFile, targetDir); strcat(targetFile, suffixConfig); if(!doExportOnly) { strcat(targetFile,".tmp"); } // dont overwrite/delete original file // make sure these directories exist as well if(outStringsChanged) { BLI_make_existing_file(targetFile); } if(!doExportOnly) { ListBase threads; // perform simulation with El'Beem api and threads elbeemSimulationSettings fsset; elbeemResetSettings(&fsset); fsset.version = 1; // setup global settings for(i=0 ; i<3; i++) fsset.geoStart[i] = bbStart[i]; for(i=0 ; i<3; i++) fsset.geoSize[i] = bbSize[i]; // simulate with 50^3 fsset.resolutionxyz = (int)domainSettings->resolutionxyz; fsset.previewresxyz = (int)domainSettings->previewresxyz; // 10cm water domain fsset.realsize = domainSettings->realsize; fsset.viscosity = calcViscosity; // earth gravity fsset.gravity[0] = domainSettings->gravx; fsset.gravity[1] = domainSettings->gravy; fsset.gravity[2] = domainSettings->gravz; // simulate 5 frames, each 0.03 seconds, output to ./apitest_XXX.bobj.gz fsset.animStart = domainSettings->animStart; fsset.aniFrameTime = aniFrameTime; fsset.noOfFrames = noFrames; // is otherwise subtracted in parser strcpy(targetFile, targetDir); strcat(targetFile, suffixSurface); // defaults for compressibility and adaptive grids fsset.gstar = domainSettings->gstar; fsset.maxRefine = domainSettings->maxRefine; // check <-> gridlevels fsset.generateParticles = domainSettings->generateParticles; fsset.numTracerParticles = domainSettings->generateTracers; fsset.surfaceSmoothing = domainSettings->surfaceSmoothing; fsset.surfaceSubdivs = domainSettings->surfaceSubdivs; fsset.farFieldSize = domainSettings->farFieldSize; strcpy( fsset.outputPath, targetFile); // domain channels fsset.channelSizeFrameTime = fsset.channelSizeViscosity = fsset.channelSizeGravity = allchannelSize; fsset.channelFrameTime = channelDomainTime; fsset.channelViscosity = channelDomainViscosity; fsset.channelGravity = channelDomainGravity; fsset.runsimCallback = &runSimulationCallback; fsset.runsimUserData = &fsset; if( (domainSettings->typeFlags&OB_FSBND_NOSLIP)) fsset.domainobsType = FLUIDSIM_OBSTACLE_NOSLIP; else if((domainSettings->typeFlags&OB_FSBND_PARTSLIP)) fsset.domainobsType = FLUIDSIM_OBSTACLE_PARTSLIP; else if((domainSettings->typeFlags&OB_FSBND_FREESLIP)) fsset.domainobsType = FLUIDSIM_OBSTACLE_FREESLIP; fsset.domainobsPartslip = domainSettings->partSlipValue; fsset.generateVertexVectors = (domainSettings->domainNovecgen==0); // init blender trafo matrix // fprintf(stderr,"elbeemInit - mpTrafo:\n"); { int j; for(i=0; i<4; i++) { for(j=0; j<4; j++) { fsset.surfaceTrafo[i*4+j] = invDomMat[j][i]; // fprintf(stderr,"elbeemInit - mpTrafo %d %d = %f (%d) \n", i,j, fsset.surfaceTrafo[i*4+j] , (i*4+j) ); } } } // init solver with settings elbeemInit(); elbeemAddDomain(&fsset); // init objects channelObjCount = 0; for(base=scene->base.first; base; base= base->next) { FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim); obit = base->object; //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG if( fluidmdtmp && // if has to match 3 places! // CHECKMATCH (obit->type==OB_MESH) && (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) && (fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE)) { float *verts=NULL; int *tris=NULL; int numVerts=0, numTris=0; int o = channelObjCount; int deform = (fluidmdtmp->fss->domainNovecgen); // misused value // todo - use blenderInitElbeemMesh int modifierIndex = modifiers_indexInObject(obit, (ModifierData *)fluidmdtmp); elbeemMesh fsmesh; elbeemResetMesh( &fsmesh ); fsmesh.type = fluidmdtmp->fss->type; // get name of object for debugging solver fsmesh.name = obit->id.name; initElbeemMesh(scene, obit, &numVerts, &verts, &numTris, &tris, 0, modifierIndex); fsmesh.numVertices = numVerts; fsmesh.numTriangles = numTris; fsmesh.vertices = verts; fsmesh.triangles = tris; fsmesh.channelSizeTranslation = fsmesh.channelSizeRotation = fsmesh.channelSizeScale = fsmesh.channelSizeInitialVel = fsmesh.channelSizeActive = allchannelSize; fsmesh.channelTranslation = channelObjMove[o][0]; fsmesh.channelRotation = channelObjMove[o][1]; fsmesh.channelScale = channelObjMove[o][2]; fsmesh.channelActive = channelObjActive[o]; if( (fsmesh.type == OB_FLUIDSIM_FLUID) || (fsmesh.type == OB_FLUIDSIM_INFLOW)) { fsmesh.channelInitialVel = channelObjInivel[o]; fsmesh.localInivelCoords = ((fluidmdtmp->fss->typeFlags&OB_FSINFLOW_LOCALCOORD)?1:0); } if( (fluidmdtmp->fss->typeFlags&OB_FSBND_NOSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP; else if((fluidmdtmp->fss->typeFlags&OB_FSBND_PARTSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_PARTSLIP; else if((fluidmdtmp->fss->typeFlags&OB_FSBND_FREESLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_FREESLIP; fsmesh.obstaclePartslip = fluidmdtmp->fss->partSlipValue; fsmesh.volumeInitType = fluidmdtmp->fss->volumeInitType; fsmesh.obstacleImpactFactor = fluidmdtmp->fss->surfaceSmoothing; // misused value if(fsmesh.type == OB_FLUIDSIM_CONTROL) { // control fluids will get exported as whole deform = 1; fsmesh.cpsTimeStart = fluidmdtmp->fss->cpsTimeStart; fsmesh.cpsTimeEnd = fluidmdtmp->fss->cpsTimeEnd; fsmesh.cpsQuality = fluidmdtmp->fss->cpsQuality; fsmesh.obstacleType = (fluidmdtmp->fss->flag & OB_FLUIDSIM_REVERSE); fsmesh.channelSizeAttractforceRadius = fsmesh.channelSizeVelocityforceStrength = fsmesh.channelSizeVelocityforceRadius = fsmesh.channelSizeAttractforceStrength = allchannelSize; fsmesh.channelAttractforceStrength = channelAttractforceStrength[o]; fsmesh.channelAttractforceRadius = channelAttractforceRadius[o]; fsmesh.channelVelocityforceStrength = channelVelocityforceStrength[o]; fsmesh.channelVelocityforceRadius = channelVelocityforceRadius[o]; } else { // set channels to 0 fsmesh.channelAttractforceStrength = fsmesh.channelAttractforceRadius = fsmesh.channelVelocityforceStrength = fsmesh.channelVelocityforceRadius = NULL; } // animated meshes if(deform) { fsmesh.channelSizeVertices = allchannelSize; fluidsimInitMeshChannel(C, &fsmesh.channelVertices, allchannelSize, obit, numVerts, timeAtFrame, modifierIndex); scene->r.cfra = startFrame; ED_update_for_newframe(C, 1); // remove channels fsmesh.channelTranslation = fsmesh.channelRotation = fsmesh.channelScale = NULL; } elbeemAddMesh(&fsmesh); if(verts) MEM_freeN(verts); if(tris) MEM_freeN(tris); if(fsmesh.channelVertices) MEM_freeN(fsmesh.channelVertices); channelObjCount++; } // valid mesh } // objects //domainSettings->type = OB_FLUIDSIM_DOMAIN; // enable for bake display again // set to neutral, -1 means user abort, -2 means init error globalBakeState = 0; globalBakeFrame = 0; BLI_init_threads(&threads, fluidsimSimulateThread, 1); BLI_insert_thread(&threads, targetFile); { int done = 0; float noFramesf = (float)noFrames; float percentdone = 0.0; int lastRedraw = -1; g_break= 0; G.afbreek= 0; /* blender_test_break uses this global */ start_progress_bar(); while(done==0) { char busy_mess[80]; waitcursor(1); // lukep we add progress bar as an interim mesure percentdone = globalBakeFrame / noFramesf; sprintf(busy_mess, "baking fluids %d / %d |||", globalBakeFrame, (int) noFramesf); progress_bar(percentdone, busy_mess ); // longer delay to prevent frequent redrawing PIL_sleep_ms(2000); BLI_lock_thread(LOCK_CUSTOM1); if(globalBakeState != 0) done = 1; // 1=ok, <0=error/abort BLI_unlock_thread(LOCK_CUSTOM1); if (!G.background) { g_break= blender_test_break(); if(g_break) { // abort... BLI_lock_thread(LOCK_CUSTOM1); if(domainSettings) domainSettings->lastgoodframe = startFrame+globalBakeFrame; done = -1; globalBakeFrame = 0; globalBakeState = -1; simAborted = 1; BLI_unlock_thread(LOCK_CUSTOM1); break; } } // redraw the 3D for showing progress once in a while... if(lastRedraw!=globalBakeFrame) { #if 0 ScrArea *sa; scene->r.cfra = startFrame+globalBakeFrame; lastRedraw = globalBakeFrame; ED_update_for_newframe(C, 1); sa= G.curscreen->areabase.first; while(sa) { if(sa->spacetype == SPACE_VIEW3D) { scrarea_do_windraw(sa); } sa= sa->next; } screen_swapbuffers(); #endif } // redraw } end_progress_bar(); } BLI_end_threads(&threads); } // El'Beem API init, thread creation // -------------------------------------------------------------------------------------------- else { // write config file to be run with command line simulator BKE_report(reports, RPT_WARNING, "Config file export not supported."); } // config file export done! // -------------------------------------------------------------------------------------------- FS_FREE_CHANNELS; // go back to "current" blender time waitcursor(0); if(globalBakeState >= 0) { if(domainSettings) domainSettings->lastgoodframe = startFrame+globalBakeFrame; } scene->r.cfra = origFrame; ED_update_for_newframe(C, 1); if(!simAborted) { char elbeemerr[256]; // check if some error occurred if(globalBakeState==-2) { elbeemGetErrorString(elbeemerr); BKE_reportf(reports, RPT_ERROR, "Failed to initialize [Msg: %s]", elbeemerr); return 0; } // init error } // elbeemFree(); return 1; }