Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
triangleIterator.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file
11 /// @brief
12 /// @author
13 
16 
17 // Utility headers
18 // AUTO-REMOVED #include <utility/vector1.hh>
19 #include <numeric/xyzMatrix.fwd.hh>
20 // AUTO-REMOVED #include <numeric/xyzVector.io.hh>
21 #include <numeric/xyzVector.hh>
22 // AUTO-REMOVED #include <numeric/xyz.functions.hh>
23 #include <utility/exit.hh>
25 
26 #include <utility/vector1.hh>
27 #include <ObjexxFCL/FArray4D.hh>
28 
29 
30 using namespace ObjexxFCL;
31 using namespace numeric;
32 
33 namespace protocols {
34 namespace viewer {
35 
36 
37 triangleIterator::triangleIterator(FArray3D_float const & density, float const & threshold) {
38  densityPtr = &density;
39  size = numeric::xyzVector<int>(density.size1(), density.size2(), density.size3());
40 
41  gradPtr = new FArray4D_float(3, size[0], size[1], size[2]);
42  computeGradient();
43  this->threshold = threshold;
44 
45  // This will start us off looking for triangles at (0, 0, 0)
46  nextX = nextY = 0;
47  nextZ = -1;
48 
49  aquireNextQueue();
50 }
51 
52 triangleIterator::~triangleIterator() {
53  delete gradPtr; gradPtr = NULL;
54 }
55 
56 bool triangleIterator::hasNext() const {
57  return !vertQueue.empty();
58 }
59 
60 // Takes three parallel arrays of length three which this methods sets
61 // to contain the vertix positions, normals, and velocities, respectively
62 // for the next triangle. The precondition is hasNext() is true.
63 void triangleIterator::next(xyzVector_float vertices[3], xyzVector_float normals[3]) {
64  assert(hasNext());
65 
66  for (int v = 0 ; v < 3 ; v++) {
67  vertices[v] = vertQueue.back();
68  normals[v] = nrmlQueue.back();
69 
70  vertQueue.pop_back();
71  nrmlQueue.pop_back();
72  }
73 
74  if (vertQueue.empty())
75  aquireNextQueue();
76 }
77 
78 
79 void triangleIterator::aquireNextQueue() {
80  const FArray3D_float & density(*(this->densityPtr));
81 
82  // This function should only be called to fill up the queue.
83  assert(vertQueue.size() == 0);
84 
85  // We always start at (x, y, z) + (0, 0, 1)
86  // so that we don't process the same triangle twice.
87  bool starting = true;
88  nextZ++;
89 
90  // Look for a 2x2x2 cube with triangles.
91  for (int x = starting ? nextX : 0 ; x < size[0] -1 ; x++) {
92  for (int y = starting ? nextY : 0 ; y < size[1] - 1; y++) {
93  for (int z = starting ? nextZ : 0 ; z < size[2] - 1; z++) {
94  // Load this baby into a bitfield to see if we have any triangels.
95  int bitfield = 0;
96  for (int i = 1 ; i <= 8 ; i++) {
97  int vx = x + VERTEX_OFF[i][0];
98  int vy = y + VERTEX_OFF[i][1];
99  int vz = z + VERTEX_OFF[i][2];
100  if (density(vx + 1, vy + 1, vz + 1) > threshold) {
101  bitfield |= (1 << (i - 1));
102  }
103  }
104 
105  // Load up the triangles
106  for (int j = 0 ; POLY_CASES[bitfield][j] != 0 ; j++) {
107  for (int k = 0 ; k < 3 ; k++) {
108  // look up the edge
109  int edgeIndex = POLY_CASES[bitfield][j++];
110 
111  // find the adjacent vertices
112  int v0 = EDGE_NGHBRS[edgeIndex][0];
113  int x0 = x + VERTEX_OFF[v0][0] + 1;
114  int y0 = y + VERTEX_OFF[v0][1] + 1;
115  int z0 = z + VERTEX_OFF[v0][2] + 1;
116 
117  int v1 = EDGE_NGHBRS[edgeIndex][1];
118  int x1 = x + VERTEX_OFF[v1][0] + 1;
119  int y1 = y + VERTEX_OFF[v1][1] + 1;
120  int z1 = z + VERTEX_OFF[v1][2] + 1;
121 
122  // look up the level set values
123  float phi0 = density(x0, y0, z0) - threshold;
124  float phi1 = density(x1, y1, z1) - threshold;
125 
126  // compute the distance to front
127  xyzVector_float p0(x0, y0, z0);
128  xyzVector_float p1(x1, y1, z1);
129  float dist = phi0 / (phi0 - phi1);
130 
131  // compute the position, normal and gradient
132  xyzVector_float vert = p0 * (1.0f - dist) + p1 * dist;
133  xyzVector_float nrml;
134  evalGradient(vert, nrml);
135 
136  // stick them in queues
137  vertQueue.push_back(vert);
138  nrmlQueue.push_back(-nrml);
139  }
140  }
141 
142  // If we managaed to fill up the queue then we're done.
143  if (!vertQueue.empty()) {
144  nextX = x;
145  nextY = y;
146  nextZ = z;
147  return;
148  }
149  starting = false;
150  }
151  starting = false;
152  }
153  starting = false;
154  }
155 }
156 
157 void triangleIterator::computeGradient() {
158 /*
159  FArray4D_float & grad(*gradPtr);
160  const FArray3D_float & density(*densityPtr);
161 
162  grad = 0.0;
163  // this is proportional to the gradient, but not equal because we don't know the grid spacing
164  for (int i = 2 ; i < size[0] ; i++) {
165  for (int j = 2 ; j < size[1] ; j++) {
166  for (int k = 2 ; k < size[2] ; k++) {
167  grad(1, i, j, k) = density(i+1, j, k) - density(i-1, j, k);
168  grad(2, i, j, k) = density(i, j+1, k) - density(i, j-1, k);
169  grad(3, i, j, k) = density(i, j, k+1) - density(i, j, k-1);
170  }
171  }
172  }
173 */
174 }
175 
176 void triangleIterator::evalGradient(const xyzVector_float & pt, xyzVector_float & gradResult) {
177  // get the gradient of the density
181  gradResult = xyzVector_float( gx[0] , gx[1], gx[2] );
182 
183 /*
184  // hopefully this linearly interpolates the gradient (with normalization)
185 
186  FArray4D_float & gradient(*gradPtr);
187 
188  float x = pt(1);
189  float y = pt(2);
190  float z = pt(3);
191  if (x < 2.0) x = 2.0; else if (x > (size[0] - 1.0)) x = size[0] - 1.0;
192  if (y < 2.0) y = 2.0; else if (y > (size[1] - 1.0)) y = size[1] - 1.0;
193  if (z < 2.0) z = 2.0; else if (z > (size[2] - 1.0)) z = size[2] - 1.0;
194 
195  int x1 = (int) x;
196  int y1 = (int) y;
197  int z1 = (int) z; // x;
198  int x2 = x1 + 1;
199  int y2 = y1 + 1;
200  int z2 = z1 + 1;
201 
202  float coefX2 = x - x1;
203  float coefY2 = y - y1;
204  float coefZ2 = z - z1;
205  float coefX1 = 1.0 - coefX2;
206  float coefY1 = 1.0 - coefY2;
207  float coefZ1 = 1.0 - coefZ2;
208 
209  gradResult(1) = gradResult(2) = gradResult(3) = 0.0;
210  for (int dim = 1 ; dim <= 3 ; dim++) {
211  gradResult(dim) += gradient(dim, x1, y1, z1) * coefX1 * coefY1 * coefZ1;
212  gradResult(dim) += gradient(dim, x2, y1, z1) * coefX2 * coefY1 * coefZ1;
213  gradResult(dim) += gradient(dim, x1, y2, z1) * coefX1 * coefY2 * coefZ1;
214  gradResult(dim) += gradient(dim, x2, y2, z1) * coefX2 * coefY2 * coefZ1;
215  gradResult(dim) += gradient(dim, x1, y1, z2) * coefX1 * coefY1 * coefZ2;
216  gradResult(dim) += gradient(dim, x2, y1, z2) * coefX2 * coefY1 * coefZ2;
217  gradResult(dim) += gradient(dim, x1, y2, z2) * coefX1 * coefY2 * coefZ2;
218  gradResult(dim) += gradient(dim, x2, y2, z2) * coefX2 * coefY2 * coefZ2;
219  }
220  gradResult.normalize_any();
221 */
222 }
223 
224 
225 }
226 }