Page MenuHome

Blender_surface_farsthary.patch

File Metadata

Author
Raul Fernandez Hernandez (farsthary)
Created
Nov 13 2013, 3:00 PM

Blender_surface_farsthary.patch

This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
Index: source/blender/blenkernel/BKE_isosurface.h
===================================================================
--- source/blender/blenkernel/BKE_isosurface.h (revision 0)
+++ source/blender/blenkernel/BKE_isosurface.h (revision 0)
@@ -0,0 +1,110 @@
+/**
+ * blenlib/BKE_isosurface.h (dic-2009 nzc)
+ *
+ * $Id: BKE_isosurface.h 22181 2009-12-19 14:40:10Z farsthary $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by Raúl Fernández Hernández (farsthary).
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Raúl Fernádez Hernández.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef BKE_ISOSURFACE_H
+#define BKE_ISOSURFACE_H
+
+
+typedef struct XYZ {
+ float x,y,z;
+} XYZ;
+
+typedef struct TRIANGLE {
+ XYZ p[3];
+} TRIANGLE;
+
+typedef struct GRIDCELL {
+ XYZ p[8];
+ float val[8];
+} GRIDCELL;
+
+#define ISO_UPDATE_ALWAYS 0
+#define ISO_UPDATE_HALFRES 1
+#define ISO_UPDATE_FAST 2
+#define ISO_UPDATE_NEVER 3
+
+
+void make_hash_isosurface(ParticleSystem *psys, ParticleSettings *part);
+void make_cube(float *central_pos, float cell_resol, GRIDCELL *cube, float radius, ParticleSystem *psys, float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7);
+
+typedef struct HashBucket
+{
+ struct LinkNode *listpoints;
+
+} HashBucket;
+
+typedef struct SpatialHash
+{
+ float isolevel;
+
+ float cell_size; /* spatial resolution , UI defined */
+ float inv_cell_size;
+ float radius;
+
+ int cell_resol; //cell subdivision
+ int totalbuckets;
+
+ HashBucket *buckets;
+ struct LinkNode *linked_cubelist;
+
+} SpatialHash;
+
+typedef struct HashNearest {
+ int index;
+ float dist;
+ float co[3];
+} HashNearest;
+
+
+float BLI_surface_eval(float radius, float *pos, float *centerpos, ParticleSystem *psys);
+
+SpatialHash* BLI_hash_new(int cell_resol, float cell_size, float isolevel, float radius);
+
+int BLI_spatialhash_insert(SpatialHash *hash, float *co, ParticleSystem *psys); /* This is used in surface generation */
+void BLI_spatialhash_free(SpatialHash *hash);
+int BLI_spatial_hash(float x, float y, float z, SpatialHash *hash);
+
+//------- NN search ------
+/* Construction: first insert points. Normal is optional. */
+void BLI_hash_insert(SpatialHash *hash, int index, float *co, float *nor);
+
+/* Find nearest returns index, and -1 if no node is found.
+ * Find n nearest returns number of points found, with results in nearest.
+ * Normal is optional, but if given will limit results to points in normal direction from co. */
+int BLI_hash_find_nearest(SpatialHash *hash, float *co, float *nor, HashNearest *nearest);
+int BLI_hash_find_n_nearest(SpatialHash *hash, int n, float *co, float *nor, HashNearest *nearest);
+
+/* Range search returns number of points found, with results in nearest */
+/* Normal is optional, but if given will limit results to points in normal direction from co. */
+/* Remember to free nearest after use! */
+int BLI_hash_range_search(SpatialHash *hash, float range, float *co, float *nor, HashNearest **nearest);
+
+
+#endif
\ No newline at end of file
Index: source/blender/blenkernel/BKE_particle.h
===================================================================
--- source/blender/blenkernel/BKE_particle.h (revision 34627)
+++ source/blender/blenkernel/BKE_particle.h (working copy)
@@ -58,6 +58,7 @@
struct SurfaceModifierData;
struct BVHTreeRay;
struct BVHTreeRayHit;
+struct TRIANGLE;
#define PARTICLE_P ParticleData *pa; int p
#define LOOP_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
@@ -184,7 +185,8 @@
float *vedata, *ved; /* velocity data */
float *ma_r, *ma_g, *ma_b;
int tot_vec_size, flag;
- int totpoint, totve;
+ int totpoint, totve , tottris;
+ struct TRIANGLE *tris;
} ParticleDrawData;
#define PARTICLE_DRAW_DATA_UPDATED 1
Index: source/blender/blenkernel/intern/isosurface.c
===================================================================
--- source/blender/blenkernel/intern/isosurface.c (revision 0)
+++ source/blender/blenkernel/intern/isosurface.c (revision 0)
@@ -0,0 +1,1199 @@
+/**
+ * $Id: isosurface.c 22181 2009-12-19 14:40:10Z farsthary $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by Raul Fernandez Hernandez (farsthary).
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Raúl Fernández Hernández.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+ /* this code was based on the excelent public implementation as appear inn
+ "Polygonising a scalar field" Written by Paul Bourke in May 1994,
+ Based on tables by Cory Gene Bloyd */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <float.h>
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_meta_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_particle_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_kdtree.h"
+#include "BLI_kdopbvh.h"
+#include "BLI_linklist.h"
+#include "BLI_math.h"
+
+#include "BKE_utildefines.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+
+#include "BKE_animsys.h"
+#include "BKE_isosurface.h"
+#include "BKE_scene.h"
+#include "BKE_blender.h"
+#include "BKE_library.h"
+#include "BKE_displist.h"
+#include "BKE_mball.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_mball.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+//************* Constructing the hash array for polygonalization **************
+ static int edgeTable[256]={
+0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
+0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
+0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
+0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
+0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
+0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
+0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
+0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
+0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
+0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
+0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
+0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
+0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
+0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
+0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
+0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
+0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
+0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
+0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
+0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
+0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
+0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
+0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
+0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
+0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
+0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
+0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
+0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
+0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
+0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
+0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
+0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 };
+
+static int triTable[256][16] =
+{{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
+{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
+{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
+{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
+{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
+{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
+{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
+{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
+{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
+{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
+{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
+{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
+{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
+{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
+{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
+{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
+{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
+{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
+{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
+{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
+{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
+{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
+{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
+{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
+{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
+{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
+{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
+{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
+{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
+{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
+{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
+{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
+{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
+{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
+{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
+{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
+{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
+{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
+{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
+{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
+{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
+{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
+{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
+{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
+{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
+{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
+{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
+{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
+{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
+{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
+{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
+{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
+{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
+{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
+{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
+{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
+{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
+{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
+{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
+{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
+{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
+{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
+{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
+{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
+{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
+{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
+{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
+{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
+{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
+{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
+{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
+{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
+{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
+{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
+{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
+{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
+{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
+{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
+{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
+{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
+{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
+{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
+{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
+{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
+{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
+{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
+{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
+{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
+{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
+{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
+{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
+{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
+{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
+{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
+{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
+{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
+{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
+{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
+{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
+{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
+{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
+{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
+{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
+{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
+{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
+{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
+{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
+{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
+{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
+{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
+
+
+/*
+ Linearly interpolate the position where an isosurface cuts
+ an edge between two vertices, each with their own scalar value
+*/
+XYZ VertexInterp(float isolevel,XYZ p1,XYZ p2,float valp1,float valp2)
+{
+ float mu;
+ XYZ p;
+
+ if (fabs(isolevel-valp1) < 0.00001)
+ return(p1);
+ if (fabs(isolevel-valp2) < 0.00001)
+ return(p2);
+ if (fabs(valp1-valp2) < 0.00001)
+ return(p1);
+ mu = (isolevel - valp1) / (valp2 - valp1);
+ p.x = p1.x + mu * (p2.x - p1.x);
+ p.y = p1.y + mu * (p2.y - p1.y);
+ p.z = p1.z + mu * (p2.z - p1.z);
+
+ return(p);
+}
+
+/*
+ Given a grid cell and an isolevel, calculate the triangular
+ facets required to represent the isosurface through the cell.
+ Return the number of triangular facets, the array "triangles"
+ will be loaded up with the vertices at most 5 triangular facets.
+ 0 will be returned if the grid cell is either totally above
+ of totally below the isolevel.
+*/
+
+int Polygonise(GRIDCELL grid,float isolevel,TRIANGLE *triangles)
+{
+ int i,ntriang;
+ int cubeindex;
+ XYZ vertlist[12];
+
+ /*
+ Determine the index into the edge table which
+ tells us which vertices are inside of the surface
+ */
+ cubeindex = 0;
+ if (grid.val[0] < isolevel) cubeindex |= 1;
+ if (grid.val[1] < isolevel) cubeindex |= 2;
+ if (grid.val[2] < isolevel) cubeindex |= 4;
+ if (grid.val[3] < isolevel) cubeindex |= 8;
+ if (grid.val[4] < isolevel) cubeindex |= 16;
+ if (grid.val[5] < isolevel) cubeindex |= 32;
+ if (grid.val[6] < isolevel) cubeindex |= 64;
+ if (grid.val[7] < isolevel) cubeindex |= 128;
+
+ /* Cube is entirely in/out of the surface */
+ if (edgeTable[cubeindex] == 0)
+ return(0);
+
+ /* Find the vertices where the surface intersects the cube */
+ if (edgeTable[cubeindex] & 1)
+ vertlist[0] = VertexInterp(isolevel,grid.p[0],grid.p[1],grid.val[0],grid.val[1]);
+ if (edgeTable[cubeindex] & 2)
+ vertlist[1] = VertexInterp(isolevel,grid.p[1],grid.p[2],grid.val[1],grid.val[2]);
+ if (edgeTable[cubeindex] & 4)
+ vertlist[2] = VertexInterp(isolevel,grid.p[2],grid.p[3],grid.val[2],grid.val[3]);
+ if (edgeTable[cubeindex] & 8)
+ vertlist[3] = VertexInterp(isolevel,grid.p[3],grid.p[0],grid.val[3],grid.val[0]);
+ if (edgeTable[cubeindex] & 16)
+ vertlist[4] = VertexInterp(isolevel,grid.p[4],grid.p[5],grid.val[4],grid.val[5]);
+ if (edgeTable[cubeindex] & 32)
+ vertlist[5] = VertexInterp(isolevel,grid.p[5],grid.p[6],grid.val[5],grid.val[6]);
+ if (edgeTable[cubeindex] & 64)
+ vertlist[6] = VertexInterp(isolevel,grid.p[6],grid.p[7],grid.val[6],grid.val[7]);
+ if (edgeTable[cubeindex] & 128)
+ vertlist[7] = VertexInterp(isolevel,grid.p[7],grid.p[4],grid.val[7],grid.val[4]);
+ if (edgeTable[cubeindex] & 256)
+ vertlist[8] = VertexInterp(isolevel,grid.p[0],grid.p[4],grid.val[0],grid.val[4]);
+ if (edgeTable[cubeindex] & 512)
+ vertlist[9] = VertexInterp(isolevel,grid.p[1],grid.p[5],grid.val[1],grid.val[5]);
+ if (edgeTable[cubeindex] & 1024)
+ vertlist[10] = VertexInterp(isolevel,grid.p[2],grid.p[6],grid.val[2],grid.val[6]);
+ if (edgeTable[cubeindex] & 2048)
+ vertlist[11] = VertexInterp(isolevel,grid.p[3],grid.p[7],grid.val[3],grid.val[7]);
+
+ /* Create the triangle */
+ ntriang = 0;
+ for (i=0;triTable[cubeindex][i]!=-1;i+=3) {
+ triangles[ntriang].p[0] = vertlist[triTable[cubeindex][i ]];
+ triangles[ntriang].p[1] = vertlist[triTable[cubeindex][i+1]];
+ triangles[ntriang].p[2] = vertlist[triTable[cubeindex][i+2]];
+ ntriang++;
+ }
+
+ return(ntriang);
+}
+
+//************************Polygonize tetrahedron*******************************************************
+/*
+ Polygonise a tetrahedron given its vertices within a cube
+ This is an alternative algorithm to polygonisegrid.
+ It results in a smoother surface but more triangular facets.
+
+ + 0
+ /|\
+ / | \
+ / | \
+ / | \
+ / | \
+ / | \
+ +-------------+ 1
+ 3 \ | /
+ \ | /
+ \ | /
+ \ | /
+ \ | /
+ \|/
+ + 2
+
+ It's main purpose is still to polygonise a gridded dataset and
+ would normally be called 6 times, one for each tetrahedron making
+ up the grid cell.
+ Given the grid labelling as in PolygniseGrid one would call
+ PolygoniseTri(grid,iso,triangles,0,2,3,7);
+ PolygoniseTri(grid,iso,triangles,0,2,6,7);
+ PolygoniseTri(grid,iso,triangles,0,4,6,7);
+ PolygoniseTri(grid,iso,triangles,0,6,1,2);
+ PolygoniseTri(grid,iso,triangles,0,6,1,4);
+ PolygoniseTri(grid,iso,triangles,5,6,1,4);
+*/
+int PolygoniseTri(GRIDCELL g,float iso,TRIANGLE *tri,int v0,int v1,int v2,int v3)
+{
+ int ntri = 0;
+ int triindex;
+
+ /*
+ Determine which of the 16 cases we have given which vertices
+ are above or below the isosurface
+ */
+ triindex = 0;
+ if (g.val[v0] < iso) triindex |= 1;
+ if (g.val[v1] < iso) triindex |= 2;
+ if (g.val[v2] < iso) triindex |= 4;
+ if (g.val[v3] < iso) triindex |= 8;
+
+ /* Form the vertices of the triangles for each case */
+ switch (triindex) {
+ case 0x00:
+ case 0x0F:
+ break;
+ case 0x0E:
+ case 0x01:
+ tri[0].p[0] = VertexInterp(iso,g.p[v0],g.p[v1],g.val[v0],g.val[v1]);
+ tri[0].p[1] = VertexInterp(iso,g.p[v0],g.p[v2],g.val[v0],g.val[v2]);
+ tri[0].p[2] = VertexInterp(iso,g.p[v0],g.p[v3],g.val[v0],g.val[v3]);
+ ntri++;
+ break;
+ case 0x0D:
+ case 0x02:
+ tri[0].p[0] = VertexInterp(iso,g.p[v1],g.p[v0],g.val[v1],g.val[v0]);
+ tri[0].p[1] = VertexInterp(iso,g.p[v1],g.p[v3],g.val[v1],g.val[v3]);
+ tri[0].p[2] = VertexInterp(iso,g.p[v1],g.p[v2],g.val[v1],g.val[v2]);
+ ntri++;
+ break;
+ case 0x0C:
+ case 0x03:
+ tri[0].p[0] = VertexInterp(iso,g.p[v0],g.p[v3],g.val[v0],g.val[v3]);
+ tri[0].p[1] = VertexInterp(iso,g.p[v0],g.p[v2],g.val[v0],g.val[v2]);
+ tri[0].p[2] = VertexInterp(iso,g.p[v1],g.p[v3],g.val[v1],g.val[v3]);
+ ntri++;
+ tri[1].p[0] = tri[0].p[2];
+ tri[1].p[1] = VertexInterp(iso,g.p[v1],g.p[v2],g.val[v1],g.val[v2]);
+ tri[1].p[2] = tri[0].p[1];
+ ntri++;
+ break;
+ case 0x0B:
+ case 0x04:
+ tri[0].p[0] = VertexInterp(iso,g.p[v2],g.p[v0],g.val[v2],g.val[v0]);
+ tri[0].p[1] = VertexInterp(iso,g.p[v2],g.p[v1],g.val[v2],g.val[v1]);
+ tri[0].p[2] = VertexInterp(iso,g.p[v2],g.p[v3],g.val[v2],g.val[v3]);
+ ntri++;
+ break;
+ case 0x0A:
+ case 0x05:
+ tri[0].p[0] = VertexInterp(iso,g.p[v0],g.p[v1],g.val[v0],g.val[v1]);
+ tri[0].p[1] = VertexInterp(iso,g.p[v2],g.p[v3],g.val[v2],g.val[v3]);
+ tri[0].p[2] = VertexInterp(iso,g.p[v0],g.p[v3],g.val[v0],g.val[v3]);
+ ntri++;
+ tri[1].p[0] = tri[0].p[0];
+ tri[1].p[1] = VertexInterp(iso,g.p[v1],g.p[v2],g.val[v1],g.val[v2]);
+ tri[1].p[2] = tri[0].p[1];
+ ntri++;
+ break;
+ case 0x09:
+ case 0x06:
+ tri[0].p[0] = VertexInterp(iso,g.p[v0],g.p[v1],g.val[v0],g.val[v1]);
+ tri[0].p[1] = VertexInterp(iso,g.p[v1],g.p[v3],g.val[v1],g.val[v3]);
+ tri[0].p[2] = VertexInterp(iso,g.p[v2],g.p[v3],g.val[v2],g.val[v3]);
+ ntri++;
+ tri[1].p[0] = tri[0].p[0];
+ tri[1].p[1] = VertexInterp(iso,g.p[v0],g.p[v2],g.val[v0],g.val[v2]);
+ tri[1].p[2] = tri[0].p[2];
+ ntri++;
+ break;
+ case 0x07:
+ case 0x08:
+ tri[0].p[0] = VertexInterp(iso,g.p[v3],g.p[v0],g.val[v3],g.val[v0]);
+ tri[0].p[1] = VertexInterp(iso,g.p[v3],g.p[v2],g.val[v3],g.val[v2]);
+ tri[0].p[2] = VertexInterp(iso,g.p[v3],g.p[v1],g.val[v3],g.val[v1]);
+ ntri++;
+ break;
+ }
+
+ return(ntri);
+}
+
+//******************************************************************************************
+
+float BLI_surface_eval(float radius, float *pos, float *centerpos, ParticleSystem *psys) //slow, fix this
+{
+ KDTree *tree = psys->tree;
+ KDTreeNearest *ptn = NULL;
+
+ int neighbours,n;
+ float q,val=0.f;
+
+ neighbours =BLI_kdtree_range_search(tree, radius, pos, NULL, &ptn);
+ for(n=0; n<neighbours; n++)
+ {
+ q = ptn[n].dist;
+ val+=(1-q)*(1-q);
+}
+ if(ptn){ MEM_freeN(ptn); ptn=NULL;}
+
+ return val;
+}
+
+//-------------- HASH table ------------------------
+#define HASHBIT (5)
+#define HASHSIZE (size_t)(1<<(3*HASHBIT)) /*! < hash table size (32768) */
+#define HASH(i,j,k) ((((( (i) & 31)<<5) | ( (j) & 31))<<5 ) | ( (k) & 31) )
+
+int hash_cell(float x, float inv_cell_size)
+{
+return ((int)(fabs(x)*inv_cell_size));
+}
+
+/* the hash function is the composition of two functions,
+ one provided by the client and one by the implementer.
+ This is because the implementer doesn't understand the element
+ type, the client doesn't know how many buckets there are,
+ and the implementer probably doesn't trust the client to achieve diffusion.
+ The client function hclient first converts the key into an integer
+ hash code, and the implementation function himpl converts the
+ hash code into a bucket index. The actual hash function is
+ the composition of these two functions */
+
+int BLI_spatial_hash(float x,float y,float z,SpatialHash *hash)
+{
+/* Client Hash function of a double hashing scheme client-implementer */
+int i= hash_cell(x, hash->inv_cell_size);
+int j= hash_cell(y, hash->inv_cell_size);
+int k= hash_cell(z, hash->inv_cell_size);
+
+/* Implementer Hash function of a double hashing scheme client-implementer */
+return HASH(i,j,k);
+}
+
+/* Creates or free a Spatial hash */
+SpatialHash* BLI_hash_new(int cell_resol,float cell_size,float isolevel, float radius)
+{
+ int i;
+ SpatialHash *hash=MEM_mallocN(sizeof(SpatialHash),"Spatial Hash");
+
+ hash->cell_size=cell_size;
+ hash->inv_cell_size=1.f/cell_size;
+
+ hash->isolevel=isolevel;
+
+ hash->cell_resol=cell_resol;
+ hash->radius=radius;
+
+
+ /* preallocate buckets */
+ hash->totalbuckets = HASHSIZE;
+ hash->buckets=MEM_mallocN(hash->totalbuckets*sizeof(HashBucket),"Buckets buffer");
+
+ hash->linked_cubelist=NULL;
+
+ for (i=0;i<hash->totalbuckets;i++)
+ {
+ (hash->buckets[i]).listpoints=NULL;
+ }
+
+ return hash;
+}
+
+void BLI_spatialhash_free(SpatialHash *hash) /* check memory issues */
+{
+ int i=0;
+ for (i=0;i<hash->totalbuckets;i++)
+ {
+ if ((hash->buckets[i]).listpoints) BLI_linklist_free((hash->buckets[i]).listpoints,NULL);
+ (hash->buckets[i]).listpoints=NULL;
+ }
+ if (hash->linked_cubelist) BLI_linklist_free(hash->linked_cubelist,NULL);
+ hash->linked_cubelist=NULL;
+ MEM_freeN(hash->buckets);
+ MEM_freeN(hash);
+}
+
+int is_surface_cell(GRIDCELL *grid, SpatialHash *hash)
+{
+ int cubeindex;
+ /*
+ Determine the index into the edge table which
+ tells us which vertices are inside of the surface
+ */
+ cubeindex = 0;
+ if (grid->val[0] < hash->isolevel) cubeindex |= 1;
+ if (grid->val[1] < hash->isolevel) cubeindex |= 2;
+ if (grid->val[2] < hash->isolevel) cubeindex |= 4;
+ if (grid->val[3] < hash->isolevel) cubeindex |= 8;
+ if (grid->val[4] < hash->isolevel) cubeindex |= 16;
+ if (grid->val[5] < hash->isolevel) cubeindex |= 32;
+ if (grid->val[6] < hash->isolevel) cubeindex |= 64;
+ if (grid->val[7] < hash->isolevel) cubeindex |= 128;
+
+ /* Cube is entirely in/out of the surface */
+ if (edgeTable[cubeindex] == 0){
+ return 0;
+ }
+
+ return cubeindex;
+}
+
+int face_offset(int cubeindex)
+{
+ int faceoffset=0;
+ /* Find the vertices where the surface intersects the cube */
+ if (edgeTable[cubeindex] & 1){
+ faceoffset |= 1; faceoffset |= 32;
+ }
+ if (edgeTable[cubeindex] & 2){
+ faceoffset |= 1; faceoffset |= 8;
+ }
+ if (edgeTable[cubeindex] & 4){
+ faceoffset |= 1; faceoffset = 32;
+ }
+ if (edgeTable[cubeindex] & 8){
+ faceoffset |= 1; faceoffset |= 2;
+ }
+ if (edgeTable[cubeindex] & 16){
+ faceoffset |= 4; faceoffset |= 32;
+ }
+ if (edgeTable[cubeindex] & 32){
+ faceoffset |= 4; faceoffset |= 8;
+ }
+ if (edgeTable[cubeindex] & 64){
+ faceoffset |= 16; faceoffset |= 4;
+ }
+ if (edgeTable[cubeindex] & 128){
+ faceoffset |= 2; faceoffset |= 4;
+ }
+ if (edgeTable[cubeindex] & 256){
+ faceoffset |= 2; faceoffset |= 32;
+ }
+ if (edgeTable[cubeindex] & 512){
+ faceoffset |= 8; faceoffset |= 32;
+ }
+ if (edgeTable[cubeindex] & 1024){
+ faceoffset |= 8; faceoffset |= 16;
+ }
+ if (edgeTable[cubeindex] & 2048){
+ faceoffset |= 16; faceoffset |= 2;
+ }
+ return faceoffset;
+}
+
+int in_bucket_list(int x, int y, int z, int bucket_index, SpatialHash *hash)
+{
+ int index;
+
+ LinkNode *list = (hash->buckets[bucket_index]).listpoints;
+
+ for (index = 0; list; list= list->next, index++)
+ {
+ int *pos = (int *)(list->link);
+ if (x == pos[0] && y == pos[1] && z == pos[2])
+ return 1;
+ }
+
+ return 0;
+}
+
+void make_cube(float *central_pos, float cell_resol, GRIDCELL *cube, float radius, ParticleSystem *psys, float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7)
+{
+ float pos[3];
+ float deltha = 0.5f*cell_resol;
+
+ float x01=central_pos[0]-deltha;
+ float x02=central_pos[0]+deltha;
+
+ float y01=central_pos[1]-deltha;
+ float y02=central_pos[1]+deltha;
+
+ float z01=central_pos[2]-deltha;
+ float z02=central_pos[2]+deltha;
+
+
+ /*--------- vertex 0------------------- */
+ cube->p[0].x=pos[0]=x01;
+ cube->p[0].y=pos[1]=y01;
+ cube->p[0].z=pos[2]=z01;
+
+ if (v0 >= 0) cube->val[0]= v0;
+ else
+ cube->val[0]=BLI_surface_eval(radius, pos, central_pos, psys);
+
+ /*--------- vertex 1----------------- */
+ cube->p[1].x=pos[0]=x02;
+ cube->p[1].y=pos[1]=y01;
+ cube->p[1].z=pos[2]=z01;
+
+ if (v1 >= 0) cube->val[1]=v1;
+ else
+ cube->val[1]=BLI_surface_eval(radius, pos, central_pos, psys);
+
+ /*--------- vertex 2----------------- */
+ cube->p[2].x=pos[0]=x02;
+ cube->p[2].y=pos[1]=y01;
+ cube->p[2].z=pos[2]=z02;
+
+ if (v2 >= 0) cube->val[2]=v2;
+ else
+ cube->val[2]=BLI_surface_eval(radius, pos, central_pos, psys);
+
+ /*--------- vertex 3----------------- */
+ cube->p[3].x=pos[0]=x01;
+ cube->p[3].y=pos[1]=y01;
+ cube->p[3].z=pos[2]=z02;
+
+ if (v3 >= 0) cube->val[3]=v3;
+ else
+ cube->val[3]=BLI_surface_eval(radius, pos, central_pos, psys);
+
+ /*--------- vertex 4----------------- */
+ cube->p[4].x=pos[0]=x01;
+ cube->p[4].y=pos[1]=y02;
+ cube->p[4].z=pos[2]=z01;
+
+ if (v4 >= 0) cube->val[4]=v4;
+ else
+ cube->val[4]=BLI_surface_eval(radius, pos, central_pos, psys);
+
+ /*--------- vertex 5----------------- */
+ cube->p[5].x=pos[0]=x02;
+ cube->p[5].y=pos[1]=y02;
+ cube->p[5].z=pos[2]=z01;
+
+ if (v5 >= 0) cube->val[5]=v5;
+ else
+ cube->val[5]=BLI_surface_eval(radius, pos, central_pos, psys);
+
+ /*--------- vertex 6----------------- */
+ cube->p[6].x=pos[0]=x02;
+ cube->p[6].y=pos[1]=y02;
+ cube->p[6].z=pos[2]=z02;
+
+ if (v6 >= 0) cube->val[6]=v6;
+ else
+ cube->val[6]=BLI_surface_eval(radius, pos, central_pos, psys);
+
+ /*--------- vertex 7----------------- */
+ cube->p[7].x=pos[0]=x01;
+ cube->p[7].y=pos[1]=y02;
+ cube->p[7].z=pos[2]=z02;
+
+ if (v7 >= 0) cube->val[7]=v7;
+ else
+ cube->val[7]=BLI_surface_eval(radius, pos, central_pos, psys);
+}
+
+int March3D(int x, int y, int z, SpatialHash *hash, ParticleSystem *psys, float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7)
+{
+ int faceoffset, bucket_index, *ico, result, cubeindex = 0;
+ float pos[3];
+ GRIDCELL *cell=malloc(sizeof(GRIDCELL)); //allocation?
+
+ bucket_index = BLI_spatial_hash(x, y, z, hash);
+ if (in_bucket_list(x, y, z, bucket_index, hash))
+ return 0;
+
+ pos[0]=x*hash->cell_size;
+ pos[1]=y*hash->cell_size;
+ pos[2]=z*hash->cell_size;
+
+ make_cube(pos, hash->cell_size, cell, hash->radius, psys, v0, v1, v2, v3, v4, v5, v6, v7);
+ cubeindex = is_surface_cell(cell, hash);
+
+ if (!cubeindex)
+ return 0;
+
+ ico=malloc(3*sizeof(int)); //watch this too
+ ico[0]=x;
+ ico[1]=y;
+ ico[2]=z;
+ BLI_linklist_prepend(&(hash->buckets[bucket_index]).listpoints,ico);
+ BLI_linklist_prepend(&(hash->linked_cubelist), cell);
+
+ result=1;
+
+ v0=-1; v1=-1; v2=-1; v3=-1;
+ v4=-1; v5=-1; v6=-1; v7=-1;
+
+ faceoffset=face_offset(cubeindex);
+
+ /* march trough neighbours cells */
+ if (faceoffset & 1){
+ v5=cell->val[1];
+ v7=cell->val[3];
+ v4=cell->val[0];
+ v6=cell->val[2];
+
+ result += March3D(x,y-1,z, hash, psys, -1, v1, v2, -1, -1, v5, v6, -1);
+ }
+
+ if (faceoffset & 2){
+ v5=cell->val[4];
+ v1=cell->val[0];
+ v2=cell->val[3];
+ v6=cell->val[7];
+
+ result += March3D(x-1,y,z, hash, psys, -1, v1, v2, -1, -1, v5, v6, -1);
+ }
+
+ if (faceoffset & 4){
+ v0=cell->val[4];
+ v1=cell->val[5];
+ v2=cell->val[6];
+ v3=cell->val[7];
+
+ result += March3D(x,y+1,z, hash, psys, v0, v1, v2, v3, -1, -1, -1, -1);
+ }
+
+ if (faceoffset & 8){
+ v0=cell->val[1];
+ v7=cell->val[6];
+ v4=cell->val[5];
+ v3=cell->val[2];
+
+ result += March3D(x+1,y,z, hash, psys, v0, -1, -1, v3, v4, -1, -1, v7);
+ }
+
+ if (faceoffset & 16){
+ v0=cell->val[3];
+ v1=cell->val[2];
+ v4=cell->val[7];
+ v5=cell->val[6];
+
+ result += March3D(x,y,z+1, hash, psys, v0, v1, -1, -1, v4, v5, -1, -1);
+ }
+
+ if (faceoffset & 32){
+ v7=cell->val[4];
+ v3=cell->val[0];
+ v2=cell->val[1];
+ v6=cell->val[5];
+
+ result += March3D(x,y,z-1, hash, psys, -1, -1, v2, v3, -1, -1, v6, v7);
+ }
+
+ return result;
+}
+
+/* Construction: inserted particles have an extention in space that could overlaps several cells */
+int BLI_spatialhash_insert(SpatialHash *hash, float *co, ParticleSystem *psys)
+{
+ int inserted=0;
+ float tco[3];
+ int cell_limit=0;
+ GRIDCELL *cell=malloc(sizeof(GRIDCELL)); //free this
+
+ tco[0]=((int)(co[0]*hash->inv_cell_size)+0.5f)*hash->cell_size;
+ tco[1]=((int)(co[1]*hash->inv_cell_size)+0.5f)*hash->cell_size;
+ tco[2]=((int)(co[2]*hash->inv_cell_size)+0.5f)*hash->cell_size;
+
+ make_cube(tco, hash->cell_size, cell, hash->radius, psys, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ while(!is_surface_cell(cell, hash) && cell_limit<20)
+ {
+ //march toward the normal (implement)
+ tco[1]-=hash->cell_size;
+
+ make_cube(tco, hash->cell_size, cell, hash->radius, psys, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ cell_limit++;
+ }
+
+ if (cell_limit < 20) { /* if found a surface cell seed */
+ int ico[3];
+
+ /* find bucket index where should be inserted */
+ ico[0]=(int)(tco[0]*hash->inv_cell_size);
+ ico[1]=(int)(tco[1]*hash->inv_cell_size);
+ ico[2]=(int)(tco[2]*hash->inv_cell_size);
+
+ /* iterates to the neighbours cells that probably contains surface also */
+ inserted += March3D(ico[0], ico[1], ico[2], hash, psys, -1, -1, -1, -1, -1, -1, -1, -1);
+ }
+
+ return inserted;
+}
+
+
+//******************************************************************************************
+
+/* the actual process of filling the cube list with scalar values */ /* Problema de direccionamiento
+void make_cubelist(SpatialHash *hash, GRIDCELL *cubelist, ParticleSystem *psys)
+{
+ int l=0,m=0;
+ int i,j,k;
+ int *posorig;
+ float resol= hash->cell_size/hash->cell_resol;
+
+ for (m=0;m<hash->totalbuckets;m++)
+ {
+ LinkNode *list=(hash->buckets[m]).listpoints;
+ while (list)
+ {
+ posorig=(int *)(list->link);
+ float sub_center_pos[3];
+
+ // Cell subdivision, working Ok
+ for(i=0;i<hash->cell_resol;i++)
+ for(j=0;j<hash->cell_resol;j++)
+ for(k=0;k<hash->cell_resol;k++)
+ {
+ sub_center_pos[0]=(posorig[0]-0.5f)*hash->cell_size +0.5f*resol*(2*i+1);
+ sub_center_pos[1]=(posorig[1]-0.5f)*hash->cell_size +0.5f*resol*(2*j+1);
+ sub_center_pos[2]=(posorig[2]-0.5f)*hash->cell_size +0.5f*resol*(2*k+1);
+
+ make_cube(sub_center_pos, resol, &cubelist[l], hash->radius, psys);
+ l++;
+ } ///
+
+ sub_center_pos[0]=posorig[0]*hash->cell_size;
+ sub_center_pos[1]=posorig[1]*hash->cell_size;
+ sub_center_pos[2]=posorig[2]*hash->cell_size;
+
+ make_cube(sub_center_pos, resol, &cubelist[l], hash->radius, psys);
+
+ l++; ///
+ list=list->next; ///
+ }
+
+ }
+
+} //*/
+
+void make_cubelist_linked(SpatialHash *hash, GRIDCELL *cubelist, int inserted_cells)
+{
+ int i;
+ GRIDCELL *cell=NULL;
+ struct LinkNode *index = hash->linked_cubelist;
+ for (i=0; i<inserted_cells; i++)
+ {
+ cell=(GRIDCELL *)(index->link);
+
+ cubelist[i]=*cell;
+
+ index = index->next;
+ }
+
+}
+
+/* Make a spatial hash array for cells with particles overlapping,
+ build GRIDCELL structres (cubes) from the center hash array
+ pass the cube list to the polygonizer to build the surface */
+
+//this function fills the triangles for the PartilceDrawData struct
+void make_hash_isosurface(ParticleSystem *psys, ParticleSettings *part) //check memory management
+{
+ TRIANGLE triangles[10];
+ TRIANGLE *tris = NULL;
+
+ int i,totpart=psys->totpart;
+ ParticleData *pi=NULL;
+ GRIDCELL *cubelist;
+
+ int cell_resol=1; //UI set
+ float cell_size= 3.f * part->size;
+
+
+ float radius_search= part->fluid->radius; //UI set 2.5
+ float isolevel=0.5f; //part->to; // //UI set
+
+ int inserted_cells = 0;
+ int l,total=0;
+ PARTICLE_P;
+
+ SpatialHash *hash=BLI_hash_new(cell_resol, cell_size, isolevel, radius_search);
+
+ LOOP_SHOWN_PARTICLES{
+ inserted_cells+=BLI_spatialhash_insert(hash,pa->state.co, psys);
+ }
+
+ inserted_cells*=hash->cell_resol*hash->cell_resol*hash->cell_resol;
+
+ /* Build the cube list */
+ cubelist=MEM_mallocN(inserted_cells*sizeof(GRIDCELL),"Hash cube");
+ make_cubelist_linked(hash, cubelist, inserted_cells);
+
+ /* Feed the polygonizer , marching cubes */
+ for (i=0;i<inserted_cells;i++)
+ {
+ int n=0;
+ n=Polygonise(cubelist[i], isolevel, triangles);
+
+ tris = realloc(tris,(total+n)*sizeof(TRIANGLE)); //improve this
+ for (l=0;l<n;l++)
+ tris[total+l] = triangles[l];
+ total += n;
+
+ }
+
+ /* for (i=0;i<inserted_cells;i++) //Marching thetraedrom
+ {
+ int n=0;
+
+ n=PolygoniseTri(cubelist[i],isolevel,triangles,0,2,3,7);
+
+ tris = realloc(tris,(total+n)*sizeof(TRIANGLE)); //improve this
+ for (l=0;l<n;l++)
+ tris[total+l] = triangles[l];
+ total += n;
+ //---------------------------------------------------------------
+
+ n=PolygoniseTri(cubelist[i],isolevel,triangles,0,2,6,7);
+
+ tris = realloc(tris,(total+n)*sizeof(TRIANGLE)); //improve this
+ for (l=0;l<n;l++)
+ tris[total+l] = triangles[l];
+ total += n;
+ //---------------------------------------------------------------
+
+ n=PolygoniseTri(cubelist[i],isolevel,triangles,0,4,6,7);
+
+ tris = realloc(tris,(total+n)*sizeof(TRIANGLE)); //improve this
+ for (l=0;l<n;l++)
+ tris[total+l] = triangles[l];
+ total += n;
+ //---------------------------------------------------------------
+
+ n=PolygoniseTri(cubelist[i],isolevel,triangles,0,6,1,2);
+
+ tris = realloc(tris,(total+n)*sizeof(TRIANGLE)); //improve this
+ for (l=0;l<n;l++)
+ tris[total+l] = triangles[l];
+ total += n;
+ //---------------------------------------------------------------
+
+ n=PolygoniseTri(cubelist[i],isolevel,triangles,0,6,1,4);
+
+ tris = realloc(tris,(total+n)*sizeof(TRIANGLE)); //improve this
+ for (l=0;l<n;l++)
+ tris[total+l] = triangles[l];
+ total += n;
+ //---------------------------------------------------------------
+
+ n=PolygoniseTri(cubelist[i],isolevel,triangles,5,6,1,4);
+
+ tris = realloc(tris,(total+n)*sizeof(TRIANGLE)); //improve this
+ for (l=0;l<n;l++)
+ tris[total+l] = triangles[l];
+ total += n;
+ } //*/
+
+ BLI_spatialhash_free(hash);
+ hash=NULL;
+ if (cubelist) MEM_freeN(cubelist);
+ cubelist=NULL;
+
+ psys->pdd->tris=tris;
+ psys->pdd->tottris=total;
+
+}
+
+//*****************************************************************************
+float squared_distance(float *co1, float *co2)
+{
+ return (co1[0]-co2[0])*(co1[0]-co2[0]) + (co1[1]-co2[1])*(co1[1]-co2[1]) + (co1[2]-co2[2])*(co1[2]-co2[2]);
+}
+
+
+/* for now only insert points */
+ void BLI_hash_insert(SpatialHash *hash, int index, float *co, float *nor)
+ {
+ int bucket_index = BLI_spatial_hash(co[0], co[1], co[2], hash);
+ BLI_linklist_prepend(&(hash->buckets[bucket_index]).listpoints,co);
+ }
+
+// not implemented yet
+int BLI_hash_find_nearest(SpatialHash *hash, float *co, float *nor, HashNearest *nearest)
+{
+ int bucket_index = BLI_spatial_hash(co[0], co[1], co[2], hash);
+ int index;
+ float squared_dist=0.f;
+ float min=10000.f; //A big number
+
+ LinkNode *list = (hash->buckets[bucket_index]).listpoints;
+
+ for (index = 0; list; list= list->next, index++)
+ {
+ float *pos = (float *)(list->link); //int *?
+ squared_dist=squared_distance(co, pos);
+ if (squared_dist<min)
+ min=squared_dist;
+ }
+
+ //create here the neares neighbour and return a meaning value, not implemented yet
+ return 0;
+}
+
+int BLI_hash_find_n_nearest(SpatialHash *hash, int n, float *co, float *nor, HashNearest *nearest)
+{
+ return 0; //to be implemented
+}
+
+/* Range search returns number of points found, with results in nearest */
+/* Normal is optional, but if given will limit results to points in normal direction from co. */
+/* Remember to free nearest after use! */
+int BLI_hash_range_search(SpatialHash *hash, float range, float *co, float *nor, HashNearest **nearest)
+{
+return 0;//to be implemented
+}
\ No newline at end of file
Index: source/blender/blenkernel/intern/particle_system.c
===================================================================
--- source/blender/blenkernel/intern/particle_system.c (revision 34779)
+++ source/blender/blenkernel/intern/particle_system.c (working copy)
@@ -75,7 +75,7 @@
#include "BKE_effect.h"
#include "BKE_particle.h"
#include "BKE_global.h"
-
+#include "BKE_isosurface.h"
#include "BKE_DerivedMesh.h"
#include "BKE_object.h"
#include "BKE_material.h"
@@ -3498,6 +3498,10 @@
psys_update_effectors(sim);
+ if (part->draw_as==PART_DRAW_SURF){
+ make_hash_isosurface(psys,part);
+ }
+
if(part->type != PART_HAIR)
sim->colliders = get_collider_cache(sim->scene, sim->ob, NULL);
Index: source/blender/editors/space_view3d/drawobject.c
===================================================================
--- source/blender/editors/space_view3d/drawobject.c (revision 34627)
+++ source/blender/editors/space_view3d/drawobject.c (working copy)
@@ -68,6 +68,7 @@
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_unit.h"
+#include "BKE_isosurface.h"
#include "smoke_API.h"
@@ -3260,6 +3261,26 @@
}
/* *********** drawing for particles ************* */
+/* Draw individual particle roperties , should be better optimized */
+static void draw_particle_surface(ParticleDrawData *pdd)
+{
+ int i,j,tottris=pdd->tottris;
+
+ for (i=0;i<tottris;i++)
+ {
+ glBegin(GL_LINE_LOOP);
+ {
+ for (j = 0; j < 3; j++)
+ {
+ glVertex3f(pdd->tris[i].p[j].x, pdd->tris[i].p[j].y, pdd->tris[i].p[j].z);
+ }
+ }
+ glEnd();
+
+
+ }
+}
+
static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select)
{
/* draw created data arrays */
@@ -3399,6 +3420,11 @@
drawcircball(GL_LINE_LOOP, state->co, pixsize, imat);
break;
}
+ case PART_DRAW_SURF:
+ {
+ draw_particle_surface(pdd);
+ break;
+ }
case PART_DRAW_BB:
{
float xvec[3], yvec[3], zvec[3], bb_center[3];
@@ -4059,8 +4085,8 @@
psys->flag &= ~PSYS_DRAWING;
- /* draw data can't be saved for billboards as they must update to target changes */
- if(draw_as == PART_DRAW_BB) {
+ /* draw data can't be saved for billboards and isosurfaces as they must update to target changes */
+ if(draw_as == PART_DRAW_BB || draw_as == PART_DRAW_SURF) {
psys_free_pdd(psys);
pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
}
Index: source/blender/makesdna/DNA_particle_types.h
===================================================================
--- source/blender/makesdna/DNA_particle_types.h (revision 34779)
+++ source/blender/makesdna/DNA_particle_types.h (working copy)
@@ -412,6 +412,7 @@
#define PART_DRAW_GR 8
#define PART_DRAW_BB 9
#define PART_DRAW_REND 10
+#define PART_DRAW_SURF 11
/* part->integrator */
#define PART_INT_EULER 0
Index: source/blender/makesrna/intern/rna_particle.c
===================================================================
--- source/blender/makesrna/intern/rna_particle.c (revision 34779)
+++ source/blender/makesrna/intern/rna_particle.c (working copy)
@@ -64,6 +64,7 @@
{PART_DRAW_CIRC, "CIRC", 0, "Circle", ""},
{PART_DRAW_CROSS, "CROSS", 0, "Cross", ""},
{PART_DRAW_AXIS, "AXIS", 0, "Axis", ""},
+ {PART_DRAW_SURF, "SURF", 0, "Surface", ""},
{0, NULL, 0, NULL, NULL}
};

Event Timeline