Commit: 249ccbdca76f0c4845681ef376fe025e78e2cd76
Author: Martin Felke
Date:   Sun Oct 5 15:54:18 2014 +0200
Branches: fracture_modifier
https://developer.blender.org/rB249ccbdca76f0c4845681ef376fe025e78e2cd76

rewrote access to voro++ to direct memory access, no file descriptors needed 
any more, needs test under win / mac as well

===================================================================

M       extern/voro++/src/c_interface.cc
M       extern/voro++/src/c_interface.hh
M       source/blender/blenkernel/intern/fracture.c

===================================================================

diff --git a/extern/voro++/src/c_interface.cc b/extern/voro++/src/c_interface.cc
index 902f98a..ea6b053 100644
--- a/extern/voro++/src/c_interface.cc
+++ b/extern/voro++/src/c_interface.cc
@@ -40,6 +40,10 @@ void container_put(container* con, particle_order* p_order, 
int n,double x,doubl
        
 }
 
+// redesign... need a struct with function pointers which are callable from C, 
call C++ functions themselves and return their returnvalues to C
+// first we need to iterate over a container, lets maybe return a vector of 
cells here
+// this will be converted to an array of equivalent cell structs
+
 void container_print_custom(loop_order* l_order, container* con, const char* 
format, FILE* fp)
 {
        voro::container* c = (voro::container*)con;
@@ -48,6 +52,86 @@ void container_print_custom(loop_order* l_order, container* 
con, const char* for
        c->print_custom(*lo, format, fp);
 }
 
+void container_compute_cells(container* con, cell* cells)
+{
+       int i = 0, v = 0, fo = 0, fv = 0, n = 0;
+       voro::container* cn = (voro::container*)con;
+       voro::voronoicell_neighbor vc;
+       voro::c_loop_all vl(*cn);
+       cell c;
+       if(vl.start()) {
+               do {
+                       if (cn->compute_cell(vc,vl)) {
+
+                               // adapted from voro++
+                               std::vector<double> verts;
+                               std::vector<int> face_orders;
+                               std::vector<int> face_verts;
+                               std::vector<int> neighbors;
+                               double *pp, centroid[3];
+                               pp = vl.p[vl.ijk]+vl.ps*vl.q;
+
+                               //cell particle index
+                               c.index = cn->id[vl.ijk][vl.q];
+
+                               //verts
+                               vc.vertices(*pp, pp[1], pp[2], verts);
+                               c.totvert = vc.p;
+                               c.verts = new float[c.totvert][3];
+                               for (v = 0; v < c.totvert; v++) {
+                                       c.verts[v][0] = (float)verts[v * 3];
+                                       c.verts[v][1] = (float)verts[v * 3 + 1];
+                                       c.verts[v][2] = (float)verts[v * 3 + 2];
+                               }
+
+                               //faces
+                               c.totpoly = vc.number_of_faces();
+                               vc.face_orders(face_orders);
+                               c.poly_totvert = new int[c.totpoly];
+
+                               for (fo = 0; fo < c.totpoly; fo++) {
+                                       c.poly_totvert[fo] = face_orders[fo];
+                               }
+
+                               vc.face_vertices(face_verts);
+                               c.poly_indices = new int*[c.totpoly];
+                               int skip = 0;
+                               for (fo = 0; fo < c.totpoly; fo++) {
+                                       int num_verts = c.poly_totvert[fo];
+                                       c.poly_indices[fo] = new int[num_verts];
+                                       for (fv = 0; fv < num_verts; fv++) {
+                                               c.poly_indices[fo][fv] = 
face_verts[skip + 1 + fv];
+                                       }
+                                       skip += (num_verts+1);
+                               }
+
+                               //neighbors
+                               vc.neighbors(neighbors);
+                               c.neighbors = new int[c.totpoly];
+                               for (n = 0; n < c.totpoly; n++)
+                               {
+                                       c.neighbors[n] = neighbors[n];
+                               }
+
+                               //centroid
+                               vc.centroid(centroid[0], centroid[1], 
centroid[2]);
+                               c.centroid[0] = (float)centroid[0] + (float)*pp;
+                               c.centroid[1] = (float)centroid[1] + 
(float)pp[1];
+                               c.centroid[2] = (float)centroid[2] + 
(float)pp[2];
+
+                               //valid cell, store
+                               cells[i] = c;
+
+                       }
+                       else {//invalid cell, set NULL XXX TODO (Somehow !!!)
+                               cells[i] = c;
+                       }
+                       i++;
+               }
+               while(vl.inc());
+       }
+}
+
 void container_free(container* con)
 {
        voro::container* c = (voro::container*)con;
@@ -65,3 +149,15 @@ void particle_order_free(particle_order* p_order)
        voro::particle_order* po = (voro::particle_order*)p_order;
        delete po;
 }
+
+cell* cells_new(int totcells)
+{
+       return new cell[totcells];
+}
+
+void cells_free(cell *cells)
+{
+       if (cells) delete [] cells;
+}
+
+
diff --git a/extern/voro++/src/c_interface.hh b/extern/voro++/src/c_interface.hh
index f93c7ec..af29288 100644
--- a/extern/voro++/src/c_interface.hh
+++ b/extern/voro++/src/c_interface.hh
@@ -14,6 +14,35 @@ typedef struct particle_order {
        int size;
 } particle_order;
 
+/* Necessary Voro++ data for fracture:
+ * %i the particle/cell index
+ *
+ * %w number of vertices (totvert)
+ * %P global vertex coordinates
+ * v  vertex section delimiter
+ *
+ * %s number of faces (totpoly)
+ * %a number of vertices in each face (sum is totloop)
+ * %t the indices to the cell vertices, describes which vertices build each 
face
+ * %n neighboring cell index for each face
+ * f  face section delimiter
+ *
+ * %C the centroid of the voronoi cell
+ * c  centroid section delimiter
+ */
+
+typedef struct cell {
+       float (*verts)[3];
+       int *poly_totvert;
+       int **poly_indices;
+       int *neighbors;
+
+       float centroid[3];
+       int index;
+       int totvert;
+       int totpoly;
+} cell;
+
 container* container_new(double ax_,double bx_,double ay_,double by_,double 
az_,double bz_,
                          int nx_,int ny_,int nz_,int xperiodic_,int 
yperiodic_,int zperiodic_,int init_mem);
 particle_order* particle_order_new(void);
@@ -26,6 +55,11 @@ void container_free(container* con);
 void loop_order_free(loop_order* lo);
 void particle_order_free(particle_order* po);
 
+// cell array for direct access
+cell* cells_new(int totcell);
+void cells_free(cell* cells);
+void container_compute_cells(container* con, cell* cells);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/fracture.c 
b/source/blender/blenkernel/intern/fracture.c
index 342b70c..7917816 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -72,14 +72,25 @@
 #endif
 
 /* prototypes */
+#if 0
 static void parse_stream(FILE *fp, int expected_shards, ShardID shard_id, 
FracMesh *fm, int algorithm, Object *obj, DerivedMesh *dm, short 
inner_material_index);
 static Shard *parse_shard(FILE *fp);
 static void parse_verts(FILE *fp, MVert *mvert, int totvert);
 static void parse_polys(FILE *fp, MPoly *mpoly, int totpoly, int *r_totloop);
 static void parse_loops(FILE *fp, MLoop *mloop, int totloop, MPoly *mpoly, int 
totpoly);
 static void parse_neighbors(FILE *fp, int *neighbors, int totpoly);
+#endif
+
 static void add_shard(FracMesh *fm, Shard *s);
 
+#if 1
+static Shard *parse_cell(cell c);
+static void parse_cell_verts(cell c, MVert *mvert, int totvert);
+static void parse_cell_polys(cell c, MPoly *mpoly, int totpoly, int 
*r_totloop);
+static void parse_cell_loops(cell c, MLoop *mloop, int totloop, MPoly *mpoly, 
int totpoly);
+static void parse_cell_neighbors(cell c, int *neighbors, int totpoly);
+#endif
+
 static void add_shard(FracMesh *fm, Shard *s)
 {
        fm->shard_map = MEM_reallocN(fm->shard_map, sizeof(Shard*) * 
(fm->shard_count+1));
@@ -159,6 +170,7 @@ static int shard_sortsize(const void *s1, const void *s2, 
void* context)
                                return  0;
 }
 
+#if 0
 /* parse the voro++ raw data */
 static void parse_stream(FILE *fp, int expected_shards, ShardID parent_id, 
FracMesh *fm, int algorithm, Object* obj, DerivedMesh *dm, short 
inner_material_index)
 {
@@ -510,6 +522,7 @@ static void parse_neighbors(FILE* fp, int *neighbors, int 
totpoly)
                neighbors[i] = n;
        }
 }
+#endif
 
 Shard* BKE_custom_data_to_shard(Shard* s, DerivedMesh* dm)
 {
@@ -756,6 +769,375 @@ FracMesh *BKE_create_fracture_container(DerivedMesh* dm)
 
 
 
+
+
+#if 1
+
+/* parse the voro++ cell data */
+static void parse_cells(cell* cells, int expected_shards, ShardID parent_id, 
FracMesh *fm, int algorithm, Object* obj, DerivedMesh *dm, short 
inner_material_index)
+{
+       /*Parse voronoi raw data*/
+       int i = 0;
+       Shard* s = NULL, *p = BKE_shard_by_id(fm, parent_id, dm);
+       float obmat[4][4]; /* use unit matrix for now */
+       float centroid[3];
+       BMesh* bm_parent = NULL;
+       DerivedMesh *dm_parent = NULL;
+       Shard **tempshards;
+       Shard **tempresults;
+
+       tempshards = MEM_mallocN(sizeof(Shard*) * expected_shards, 
"tempshards");
+       tempresults = MEM_mallocN(sizeof(Shard*) * expected_shards, 
"tempresults");
+
+       p->flag = 0;
+       p->flag |= SHARD_FRACTURED;
+       unit_m4(obmat);
+
+       if (algorithm == MOD_FRACTURE_BOOLEAN) {
+               MPoly* mpoly, *mp;
+               int totpoly, i;
+               dm_parent = BKE_shard_create_dm(p, true);
+               mpoly = dm_parent->getPolyArray(dm_parent);
+               totpoly = dm_parent->getNumPolys(dm_parent);
+               for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
+                       mp->flag &= ~ME_FACE_SEL;
+               }
+       }
+       else if (algorithm == MOD_FRACTURE_BISECT || algorithm == 
MOD_FRACTURE_BISECT_FILL ||
+                        algorithm == MOD_FRACTURE_BISECT_FAST || algorithm == 
MOD_FRACTURE_BISECT_FAST_FILL)
+       {
+#define MYTAG (1 << 6)
+               bm_parent = shard_to_bmesh(p);
+               copy_v3_v3(centroid, p->centroid);
+       }
+
+       for (i = 0; i < expected_shards; i++) {
+               if (fm->cancel == 1) {
+                       break;
+               }
+
+               printf("Parsing shard: %d\n", i);
+               s = parse_cell(cells[i]);
+               tempshards[i] = s;
+               tempresults[i] = NULL;
+               fm->progress_counter++;
+       }
+
+       if (algorithm != MOD_FRACTURE_BISECT_FAST && algorithm != 
MOD_FRACTURE_BISECT_FAST_FILL) {
+               for (i = 0; i < expected_shards; i++) {
+                       Shard* t;
+                       if (fm->cancel == 1)
+                               break;
+
+                       printf("Processing shard: %d\n", i);
+                       t = tempshards[i];
+
+                       if (t != NULL) {
+                               t->parent_id = parent_id;
+                               t->flag = SHARD_INTACT;
+                       }
+
+                       if (t == NULL || t->totvert == 0 || t->totloop == 0 || 
t->totpoly == 0) {
+                               /* invalid shard, stop parsing */
+                               break;
+                       }
+
+                       /* XXX TODO, need object for material as well, or 
atleast a material index... */
+                       if (algorithm == MOD_FRACTURE_BOOLEAN) {
+                               s = BKE_fracture_shard_boolean(obj, dm_parent, 
t, inner_material_index);
+                       }
+                       else if (algorithm == MOD_FRACTURE_BISECT || algorithm 
== MOD_FRACTURE_BISECT_FILL) {
+                               float co[3] = {0, 0, 0};
+                               printf("Bisecting cell %d...\n", i);
+                               s = BKE_fracture_shard_bisect(bm_parent, t, 
obmat, algorithm == MOD_FRACTURE_BISECT_FILL, false, true, 0, co, 
inner_material_index);
+                       }
+                       else {
+                               /* do not fracture case */
+                               s = t;
+                       }
+
+                       if (s != NULL) {
+                               s->parent_id = parent_id;
+                               s->flag = SHARD_INTACT;
+
+                               tempresults[i] = s;
+                       }
+
+                       fm->progress_counter++;
+               }
+       }
+       else {
+               for (i = 0; i < expected_shards; i++) {
+                       Shard* s = NULL;
+                       Shard* s2 = NULL;
+                       Shard* t;
+                       int index = 0;
+
+                       if (fm->cancel == 1) {
+                               break;
+                       }
+
+                       printf("Processing shard: %d\n", i);
+                       t = tempshards[i];
+
+                       if (t != NULL) {
+                               t->parent_id = parent_id;
+                               t->flag = SHARD_INTACT;
+                       }
+
+                       if (t == NULL || t->totvert == 0 || t->totloop == 0 || 
t->totpoly == 0) {
+                               /* invalid shard, stop parsing*/
+                               break;
+                       }
+
+                       index = (int)(BLI_frand() * (t->totpoly-1));
+                       if (index == 0) {
+                               index = 1;
+                       }
+
+                       printf("Bisecting cell %d...\n", i);
+                       printf("Bisecting 

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to