int BLI_delete(char *file, int dir, int recursive) { int err; if (recursive) { callLocalErrorCallBack("Recursive delete is unsupported on Windows"); err= 1; } else if (dir) { err= !RemoveDirectory(file); if (err) printf ("Unable to remove directory"); } else { err= !DeleteFile(file); if (err) callLocalErrorCallBack("Unable to delete file"); } return err; }
void BLI_recurdir_fileops(char *dirname) { char *lslash; char tmp[MAXPATHLEN]; // First remove possible slash at the end of the dirname. // This routine otherwise tries to create // blah1/blah2/ (with slash) after creating // blah1/blah2 (without slash) strcpy(tmp, dirname); lslash= BLI_last_slash(tmp); if (lslash == tmp + strlen(tmp) - 1) { *lslash = 0; } if (BLI_exists(tmp)) return; lslash= BLI_last_slash(tmp); if (lslash) { /* Split about the last slash and recurse */ *lslash = 0; BLI_recurdir_fileops(tmp); } if(dirname[0]) /* patch, this recursive loop tries to create a nameless directory */ if (!CreateDirectory(dirname, NULL)) callLocalErrorCallBack("Unable to create directory\n"); }
int BLI_create_symlink(const char *file, const char *to) { callLocalErrorCallBack("Linking files is unsupported on Windows"); (void)file; (void)to; return 1; }
int BLI_copy(const char *file, const char *to) { int err; // windows doesn't support copying to a directory // it has to be 'cp filename filename' and not // 'cp filename destdir' BLI_strncpy(str, to, sizeof(str)); // points 'to' to a directory ? if (BLI_last_slash(str) == (str + strlen(str) - 1)) { if (BLI_last_slash(file) != NULL) { strcat(str, BLI_last_slash(file) + 1); } } err= !CopyFile(file,str,FALSE); if (err) { callLocalErrorCallBack("Unable to copy file!"); printf(" Copy from '%s' to '%s' failed\n", file, str); } return err; }
int BLI_copy(const char *file, const char *to) { int err; /* windows doesn't support copying to a directory * it has to be 'cp filename filename' and not * 'cp filename destdir' */ BLI_strncpy(str, to, sizeof(str)); /* points 'to' to a directory ? */ if (BLI_last_slash(str) == (str + strlen(str) - 1)) { if (BLI_last_slash(file) != NULL) { strcat(str, BLI_last_slash(file) + 1); } } UTF16_ENCODE(file); UTF16_ENCODE(str); err = !CopyFileW(file_16, str_16, false); UTF16_UN_ENCODE(str); UTF16_UN_ENCODE(file); if (err) { callLocalErrorCallBack("Unable to copy file!"); printf(" Copy from '%s' to '%s' failed\n", file, str); } return err; }
int BLI_delete(const char *file, bool dir, bool recursive) { int err; UTF16_ENCODE(file); if (recursive) { callLocalErrorCallBack("Recursive delete is unsupported on Windows"); err = 1; } else if (dir) { err = !RemoveDirectoryW(file_16); if (err) printf("Unable to remove directory"); } else { err = !DeleteFileW(file_16); if (err) callLocalErrorCallBack("Unable to delete file"); } UTF16_UN_ENCODE(file); return err; }
static bool delete_unique(const char *path, const bool dir) { bool err; UTF16_ENCODE(path); if (dir) { err = !RemoveDirectoryW(path_16); if (err) printf("Unable to remove directory"); } else { err = !DeleteFileW(path_16); if (err) callLocalErrorCallBack("Unable to delete file"); } UTF16_UN_ENCODE(path); return err; }
int BLI_move(char *file, char *to) { int err; // windows doesn't support moveing to a directory // it has to be 'mv filename filename' and not // 'mv filename destdir' strcpy(str, to); // points 'to' to a directory ? if (BLI_last_slash(str) == (str + strlen(str) - 1)) { if (BLI_last_slash(file) != NULL) { strcat(str, BLI_last_slash(file) + 1); } } err= !MoveFile(file, str); if (err) { callLocalErrorCallBack("Unable to move file"); printf(" Move from '%s' to '%s' failed\n", file, str); } return err; }
int BLI_edgefill(int mat_nr) { /* - fill works with its own lists, so create that first (no faces!) - for vertices, put in ->tmp.v the old pointer - struct elements xs en ys are not used here: don't hide stuff in it - edge flag ->f becomes 2 when it's a new edge - mode: & 1 is check for crossings, then create edges (TO DO ) */ ListBase tempve, temped; EditVert *eve; EditEdge *eed,*nexted; PolyFill *pflist,*pf; float *minp, *maxp, *v1, *v2, norm[3], len; short a,c,poly=0,ok=0,toggle=0; /* reset variables */ eve= fillvertbase.first; while(eve) { eve->f= 0; eve->xs= 0; eve->h= 0; eve= eve->next; } /* first test vertices if they are in edges */ /* including resetting of flags */ eed= filledgebase.first; while(eed) { eed->f= eed->f1= eed->h= 0; eed->v1->f= 1; eed->v2->f= 1; eed= eed->next; } eve= fillvertbase.first; while(eve) { if(eve->f & 1) { ok=1; break; } eve= eve->next; } if(ok==0) return 0; /* NEW NEW! define projection: with 'best' normal */ /* just use the first three different vertices */ /* THIS PART STILL IS PRETTY WEAK! (ton) */ eve= fillvertbase.last; len= 0.0; v1= eve->co; v2= 0; eve= fillvertbase.first; while(eve) { if(v2) { if( compare_v3v3(v2, eve->co, COMPLIMIT)==0) { len= normal_tri_v3( norm,v1, v2, eve->co); if(len != 0.0) break; } } else if(compare_v3v3(v1, eve->co, COMPLIMIT)==0) { v2= eve->co; } eve= eve->next; } if(len==0.0) return 0; /* no fill possible */ norm[0]= fabs(norm[0]); norm[1]= fabs(norm[1]); norm[2]= fabs(norm[2]); if(norm[2]>=norm[0] && norm[2]>=norm[1]) { cox= 0; coy= 1; } else if(norm[1]>=norm[0] && norm[1]>=norm[2]) { cox= 0; coy= 2; } else { cox= 1; coy= 2; } /* STEP 1: COUNT POLYS */ eve= fillvertbase.first; while(eve) { /* get first vertex with no poly number */ if(eve->xs==0) { poly++; /* now a sortof select connected */ ok= 1; eve->xs= poly; while(ok) { ok= 0; toggle++; if(toggle & 1) eed= filledgebase.first; else eed= filledgebase.last; while(eed) { if(eed->v1->xs==0 && eed->v2->xs==poly) { eed->v1->xs= poly; eed->f1= poly; ok= 1; } else if(eed->v2->xs==0 && eed->v1->xs==poly) { eed->v2->xs= poly; eed->f1= poly; ok= 1; } else if(eed->f1==0) { if(eed->v1->xs==poly && eed->v2->xs==poly) { eed->f1= poly; ok= 1; } } if(toggle & 1) eed= eed->next; else eed= eed->prev; } } } eve= eve->next; } /* printf("amount of poly's: %d\n",poly); */ /* STEP 2: remove loose edges and strings of edges */ eed= filledgebase.first; while(eed) { if(eed->v1->h++ >250) break; if(eed->v2->h++ >250) break; eed= eed->next; } if(eed) { /* otherwise it's impossible to be sure you can clear vertices */ callLocalErrorCallBack("No vertices with 250 edges allowed!"); return 0; } /* does it only for vertices with ->h==1 */ testvertexnearedge(); ok= 1; while(ok) { ok= 0; toggle++; if(toggle & 1) eed= filledgebase.first; else eed= filledgebase.last; while(eed) { if(toggle & 1) nexted= eed->next; else nexted= eed->prev; if(eed->v1->h==1) { eed->v2->h--; BLI_remlink(&fillvertbase,eed->v1); BLI_remlink(&filledgebase,eed); ok= 1; } else if(eed->v2->h==1) { eed->v1->h--; BLI_remlink(&fillvertbase,eed->v2); BLI_remlink(&filledgebase,eed); ok= 1; } eed= nexted; } } if(filledgebase.first==0) { /* printf("All edges removed\n"); */ return 0; } /* CURRENT STATUS: - eve->f :1= availalble in edges - eve->xs :polynumber - eve->h :amount of edges connected to vertex - eve->tmp.v :store! original vertex number - eed->f : - eed->f1 :poly number */ /* STEP 3: MAKE POLYFILL STRUCT */ pflist= (PolyFill *)MEM_callocN(poly*sizeof(PolyFill),"edgefill"); pf= pflist; for(a=1;a<=poly;a++) { pf->nr= a; pf->min[0]=pf->min[1]=pf->min[2]= 1.0e20; pf->max[0]=pf->max[1]=pf->max[2]= -1.0e20; pf++; } eed= filledgebase.first; while(eed) { pflist[eed->f1-1].edges++; eed= eed->next; } eve= fillvertbase.first; while(eve) { pflist[eve->xs-1].verts++; minp= pflist[eve->xs-1].min; maxp= pflist[eve->xs-1].max; minp[cox]= (minp[cox])<(eve->co[cox]) ? (minp[cox]) : (eve->co[cox]); minp[coy]= (minp[coy])<(eve->co[coy]) ? (minp[coy]) : (eve->co[coy]); maxp[cox]= (maxp[cox])>(eve->co[cox]) ? (maxp[cox]) : (eve->co[cox]); maxp[coy]= (maxp[coy])>(eve->co[coy]) ? (maxp[coy]) : (eve->co[coy]); if(eve->h>2) pflist[eve->xs-1].f= 1; eve= eve->next; } /* STEP 4: FIND HOLES OR BOUNDS, JOIN THEM * ( bounds just to divide it in pieces for optimization, * the edgefill itself has good auto-hole detection) * WATCH IT: ONLY WORKS WITH SORTED POLYS!!! */ if(poly>1) { short *polycache, *pc; /* so, sort first */ qsort(pflist, poly, sizeof(PolyFill), vergpoly); /*pf= pflist; for(a=1;a<=poly;a++) { printf("poly:%d edges:%d verts:%d flag: %d\n",a,pf->edges,pf->verts,pf->f); PRINT2(f, f, pf->min[0], pf->min[1]); pf++; }*/ polycache= pc= MEM_callocN(sizeof(short)*poly, "polycache"); pf= pflist; for(a=0; a<poly; a++, pf++) { for(c=a+1;c<poly;c++) { /* if 'a' inside 'c': join (bbox too) * Careful: 'a' can also be inside another poly. */ if(boundisect(pf, pflist+c)) { *pc= c; pc++; } /* only for optimize! */ /* else if(pf->max[cox] < (pflist+c)->min[cox]) break; */ } while(pc!=polycache) { pc--; mergepolysSimp(pf, pflist+ *pc); } } MEM_freeN(polycache); } /* printf("after merge\n"); pf= pflist; for(a=1;a<=poly;a++) { printf("poly:%d edges:%d verts:%d flag: %d\n",a,pf->edges,pf->verts,pf->f); pf++; } */ /* STEP 5: MAKE TRIANGLES */ tempve.first= fillvertbase.first; tempve.last= fillvertbase.last; temped.first= filledgebase.first; temped.last= filledgebase.last; fillvertbase.first=fillvertbase.last= 0; filledgebase.first=filledgebase.last= 0; pf= pflist; for(a=0;a<poly;a++) { if(pf->edges>1) { splitlist(&tempve,&temped,pf->nr); scanfill(pf, mat_nr); } pf++; } BLI_movelisttolist(&fillvertbase,&tempve); BLI_movelisttolist(&filledgebase,&temped); /* FREE */ MEM_freeN(pflist); return 1; }
int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3]) { /* * - fill works with its own lists, so create that first (no faces!) * - for vertices, put in ->tmp.v the old pointer * - struct elements xs en ys are not used here: don't hide stuff in it * - edge flag ->f becomes 2 when it's a new edge * - mode: & 1 is check for crossings, then create edges (TO DO ) * - returns number of triangle faces added. */ ListBase tempve, temped; ScanFillVert *eve; ScanFillEdge *eed, *nexted; PolyFill *pflist, *pf; float *min_xy_p, *max_xy_p; short a, c, poly = 0, ok = 0, toggle = 0; int totfaces = 0; /* total faces added */ float mat_2d[3][3]; BLI_assert(!nor_proj || len_squared_v3(nor_proj) > FLT_EPSILON); /* reset variables */ eve = sf_ctx->fillvertbase.first; a = 0; while (eve) { eve->f = 0; eve->poly_nr = 0; eve->edge_tot = 0; eve = eve->next; a += 1; } if (flag & BLI_SCANFILL_CALC_QUADTRI_FASTPATH) { if (a == 3) { eve = sf_ctx->fillvertbase.first; addfillface(sf_ctx, eve, eve->next, eve->next->next); return 1; } else if (a == 4) { float vec1[3], vec2[3]; eve = sf_ctx->fillvertbase.first; /* no need to check 'eve->next->next->next' is valid, already counted */ /* use shortest diagonal for quad */ sub_v3_v3v3(vec1, eve->co, eve->next->next->co); sub_v3_v3v3(vec2, eve->next->co, eve->next->next->next->co); if (dot_v3v3(vec1, vec1) < dot_v3v3(vec2, vec2)) { addfillface(sf_ctx, eve, eve->next, eve->next->next); addfillface(sf_ctx, eve->next->next, eve->next->next->next, eve); } else { addfillface(sf_ctx, eve->next, eve->next->next, eve->next->next->next); addfillface(sf_ctx, eve->next->next->next, eve, eve->next); } return 2; } } /* first test vertices if they are in edges */ /* including resetting of flags */ eed = sf_ctx->filledgebase.first; while (eed) { eed->poly_nr = 0; eed->v1->f = SF_VERT_AVAILABLE; eed->v2->f = SF_VERT_AVAILABLE; eed = eed->next; } eve = sf_ctx->fillvertbase.first; while (eve) { if (eve->f & SF_VERT_AVAILABLE) { ok = 1; break; } eve = eve->next; } if (ok == 0) { return 0; } else { float n[3]; if (nor_proj) { copy_v3_v3(n, nor_proj); } else { /* define projection: with 'best' normal */ /* Newell's Method */ /* Similar code used elsewhere, but this checks for double ups * which historically this function supports so better not change */ float *v_prev; zero_v3(n); eve = sf_ctx->fillvertbase.last; v_prev = eve->co; for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) { add_newell_cross_v3_v3v3(n, v_prev, eve->co); v_prev = eve->co; } } } if (UNLIKELY(normalize_v3(n) == 0.0f)) { return 0; } axis_dominant_v3_to_m3(mat_2d, n); } /* STEP 1: COUNT POLYS */ if (flag & BLI_SCANFILL_CALC_HOLES) { eve = sf_ctx->fillvertbase.first; while (eve) { mul_v2_m3v3(eve->xy, mat_2d, eve->co); /* get first vertex with no poly number */ if (eve->poly_nr == 0) { poly++; /* now a sort of select connected */ ok = 1; eve->poly_nr = poly; while (ok) { ok = 0; toggle++; if (toggle & 1) eed = sf_ctx->filledgebase.first; else eed = sf_ctx->filledgebase.last; while (eed) { if (eed->v1->poly_nr == 0 && eed->v2->poly_nr == poly) { eed->v1->poly_nr = poly; eed->poly_nr = poly; ok = 1; } else if (eed->v2->poly_nr == 0 && eed->v1->poly_nr == poly) { eed->v2->poly_nr = poly; eed->poly_nr = poly; ok = 1; } else if (eed->poly_nr == 0) { if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) { eed->poly_nr = poly; ok = 1; } } if (toggle & 1) eed = eed->next; else eed = eed->prev; } } } eve = eve->next; } /* printf("amount of poly's: %d\n", poly); */ } else { poly = 1; eve = sf_ctx->fillvertbase.first; while (eve) { mul_v2_m3v3(eve->xy, mat_2d, eve->co); eve->poly_nr = poly; eve = eve->next; } eed = sf_ctx->filledgebase.first; while (eed) { eed->poly_nr = poly; eed = eed->next; } } /* STEP 2: remove loose edges and strings of edges */ eed = sf_ctx->filledgebase.first; while (eed) { if (eed->v1->edge_tot++ > 250) break; if (eed->v2->edge_tot++ > 250) break; eed = eed->next; } if (eed) { /* otherwise it's impossible to be sure you can clear vertices */ callLocalErrorCallBack("No vertices with 250 edges allowed!"); return 0; } /* does it only for vertices with (->h == 1) */ testvertexnearedge(sf_ctx); ok = 1; while (ok) { ok = 0; toggle++; if (toggle & 1) eed = sf_ctx->filledgebase.first; else eed = sf_ctx->filledgebase.last; while (eed) { if (toggle & 1) nexted = eed->next; else nexted = eed->prev; if (eed->v1->edge_tot == 1) { eed->v2->edge_tot--; BLI_remlink(&sf_ctx->fillvertbase, eed->v1); BLI_remlink(&sf_ctx->filledgebase, eed); ok = 1; } else if (eed->v2->edge_tot == 1) { eed->v1->edge_tot--; BLI_remlink(&sf_ctx->fillvertbase, eed->v2); BLI_remlink(&sf_ctx->filledgebase, eed); ok = 1; } eed = nexted; } } if (sf_ctx->filledgebase.first == 0) { /* printf("All edges removed\n"); */ return 0; } /* CURRENT STATUS: * - eve->f :1 = available in edges * - eve->poly_nr :polynumber * - eve->edge_tot :amount of edges connected to vertex * - eve->tmp.v :store! original vertex number * * - eed->f :1 = boundary edge (optionally set by caller) * - eed->poly_nr :poly number */ /* STEP 3: MAKE POLYFILL STRUCT */ pflist = (PolyFill *)MEM_callocN(poly * sizeof(PolyFill), "edgefill"); pf = pflist; for (a = 1; a <= poly; a++) { pf->nr = a; pf->min_xy[0] = pf->min_xy[1] = 1.0e20; pf->max_xy[0] = pf->max_xy[1] = -1.0e20; pf++; } eed = sf_ctx->filledgebase.first; while (eed) { pflist[eed->poly_nr - 1].edges++; eed = eed->next; } eve = sf_ctx->fillvertbase.first; while (eve) { pflist[eve->poly_nr - 1].verts++; min_xy_p = pflist[eve->poly_nr - 1].min_xy; max_xy_p = pflist[eve->poly_nr - 1].max_xy; min_xy_p[0] = (min_xy_p[0]) < (eve->xy[0]) ? (min_xy_p[0]) : (eve->xy[0]); min_xy_p[1] = (min_xy_p[1]) < (eve->xy[1]) ? (min_xy_p[1]) : (eve->xy[1]); max_xy_p[0] = (max_xy_p[0]) > (eve->xy[0]) ? (max_xy_p[0]) : (eve->xy[0]); max_xy_p[1] = (max_xy_p[1]) > (eve->xy[1]) ? (max_xy_p[1]) : (eve->xy[1]); if (eve->edge_tot > 2) pflist[eve->poly_nr - 1].f = 1; eve = eve->next; } /* STEP 4: FIND HOLES OR BOUNDS, JOIN THEM * ( bounds just to divide it in pieces for optimization, * the edgefill itself has good auto-hole detection) * WATCH IT: ONLY WORKS WITH SORTED POLYS!!! */ if (poly > 1) { short *polycache, *pc; /* so, sort first */ qsort(pflist, poly, sizeof(PolyFill), vergpoly); #if 0 pf = pflist; for (a = 1; a <= poly; a++) { printf("poly:%d edges:%d verts:%d flag: %d\n", a, pf->edges, pf->verts, pf->f); PRINT2(f, f, pf->min[0], pf->min[1]); pf++; } #endif polycache = pc = MEM_callocN(sizeof(short) * poly, "polycache"); pf = pflist; for (a = 0; a < poly; a++, pf++) { for (c = a + 1; c < poly; c++) { /* if 'a' inside 'c': join (bbox too) * Careful: 'a' can also be inside another poly. */ if (boundisect(pf, pflist + c)) { *pc = c; pc++; } /* only for optimize! */ /* else if (pf->max_xy[0] < (pflist+c)->min[cox]) break; */ } while (pc != polycache) { pc--; mergepolysSimp(sf_ctx, pf, pflist + *pc); } } MEM_freeN(polycache); } #if 0 printf("after merge\n"); pf = pflist; for (a = 1; a <= poly; a++) { printf("poly:%d edges:%d verts:%d flag: %d\n", a, pf->edges, pf->verts, pf->f); pf++; } #endif /* STEP 5: MAKE TRIANGLES */ tempve.first = sf_ctx->fillvertbase.first; tempve.last = sf_ctx->fillvertbase.last; temped.first = sf_ctx->filledgebase.first; temped.last = sf_ctx->filledgebase.last; sf_ctx->fillvertbase.first = sf_ctx->fillvertbase.last = NULL; sf_ctx->filledgebase.first = sf_ctx->filledgebase.last = NULL; pf = pflist; for (a = 0; a < poly; a++) { if (pf->edges > 1) { splitlist(sf_ctx, &tempve, &temped, pf->nr); totfaces += scanfill(sf_ctx, pf, flag); } pf++; } BLI_movelisttolist(&sf_ctx->fillvertbase, &tempve); BLI_movelisttolist(&sf_ctx->filledgebase, &temped); /* FREE */ MEM_freeN(pflist); return totfaces; }
int BLI_link(char *file, char *to) { callLocalErrorCallBack("Linking files is unsupported on Windows"); return 1; }