10 #include "imstkTypes.h" 14 using namespace imstk;
20 isIntersect(
const double a,
const double b,
const double c,
const double d)
22 return ((a <= d && a >= c) || (c <= b && c >= a)) ? true :
false;
30 segmentToPlane(
const Vec3d& a,
const Vec3d& b,
const Vec3d& n,
const Vec3d& planePt, Vec3d& intersectionPt)
33 double length = dir.norm();
35 double denom = n.dot(dir);
38 if (std::abs(denom) < 0.00000001)
43 double t = (planePt - a).dot(n) / denom;
55 intersectionPt = a + t * dir;
60 orientTet(std::array<Vec3d, 4>& tet)
62 Vec3d a = tet[1] - tet[0];
63 Vec3d b = tet[2] - tet[0];
64 Vec3d c = tet[3] - tet[0];
65 if (a.cross(b).dot(c) < 0)
67 std::swap(tet[2], tet[3]);
75 splitTet(
const std::array<Vec3d, 4>& inputTetVerts,
76 const Vec3d& planePos,
const Vec3d& planeNormal,
77 std::list<std::array<Vec3d, 4>>& resultTetVerts)
82 for (
int j = 0; j < 4; j++)
84 const Vec3d& vert = inputTetVerts[j];
85 const double proj = (vert - planePos).dot(planeNormal);
99 if (outCount == 0 || inCount == 0)
105 std::pair<int, int> iEdges[4];
108 for (
int j = 0; j < 4; j++)
110 for (
int k = j + 1; k < 4; k++)
113 if (side[j] != side[k])
117 if (segmentToPlane(inputTetVerts[j], inputTetVerts[k], planeNormal, planePos, iPt))
119 iEdges[iPtSize] = std::pair<int, int>(j, k);
133 int isolatedVertId = -1;
139 for (
int i = 0; i < 4; i++)
141 trueCount +=
static_cast<int>(side[i]);
142 falseCount +=
static_cast<int>(!side[i]);
146 if (trueCount == 3 && falseCount == 1)
148 int otherVertSize = 0;
149 for (
int i = 0; i < 4; i++)
153 otherVertIds[otherVertSize++] = i;
164 int otherVertSize = 0;
165 for (
int i = 0; i < 4; i++)
173 otherVertIds[otherVertSize++] = i;
184 std::array<Vec3d, 4> tet1;
188 tet1[3] = inputTetVerts[isolatedVertId];
190 resultTetVerts.push_back(tet1);
197 std::array<Vec3d, 4> tet2;
201 tet2[3] = inputTetVerts[otherVertIds[0]];
203 resultTetVerts.push_back(tet2);
205 std::array<Vec3d, 4> tet3;
208 tet3[2] = inputTetVerts[otherVertIds[0]];
209 tet3[3] = inputTetVerts[otherVertIds[2]];
211 resultTetVerts.push_back(tet3);
213 std::array<Vec3d, 4> tet4;
215 tet4[1] = inputTetVerts[otherVertIds[0]];
216 tet4[2] = inputTetVerts[otherVertIds[1]];
217 tet4[3] = inputTetVerts[otherVertIds[2]];
219 resultTetVerts.push_back(tet4);
228 for (
int i = 0; i < 4; i++)
232 outVertIds[outVertSize++] = i;
236 inVertIds[inVertSize++] = i;
253 for (
int i = 0; i < iPtSize; i++)
255 if (iEdges[i].first == outVertIds[0]
256 || iEdges[i].second == outVertIds[0])
258 iPts0[iPts0Size++] = i;
262 iPts1[iPts1Size++] = i;
266 std::array<Vec3d, 4> tet1;
267 tet1[0] = iPts[iPts0[0]];
268 tet1[1] = iPts[iPts0[1]];
269 tet1[2] = inputTetVerts[outVertIds[0]];
270 tet1[3] = inputTetVerts[outVertIds[1]];
272 resultTetVerts.push_back(tet1);
274 std::array<Vec3d, 4> tet2;
275 tet2[0] = iPts[iPts0[0]];
276 tet2[1] = iPts[iPts0[1]];
277 tet2[2] = iPts[iPts1[0]];
278 tet2[3] = inputTetVerts[outVertIds[1]];
280 resultTetVerts.push_back(tet2);
282 std::array<Vec3d, 4> tet3;
283 tet3[0] = iPts[iPts0[1]];
284 tet3[1] = iPts[iPts1[0]];
285 tet3[2] = iPts[iPts1[1]];
286 tet3[3] = inputTetVerts[outVertIds[1]];
288 resultTetVerts.push_back(tet3);
297 for (
int i = 0; i < iPtSize; i++)
299 if (iEdges[i].first == inVertIds[0]
300 || iEdges[i].second == inVertIds[0])
302 iPts0[iPts0Size++] = i;
306 iPts1[iPts1Size++] = i;
310 std::array<Vec3d, 4> tet1;
311 tet1[0] = iPts[iPts0[0]];
312 tet1[1] = iPts[iPts0[1]];
313 tet1[2] = inputTetVerts[inVertIds[0]];
314 tet1[3] = inputTetVerts[inVertIds[1]];
316 resultTetVerts.push_back(tet1);
318 std::array<Vec3d, 4> tet2;
319 tet2[0] = iPts[iPts0[0]];
320 tet2[1] = iPts[iPts0[1]];
321 tet2[2] = iPts[iPts1[0]];
322 tet2[3] = inputTetVerts[inVertIds[1]];
324 resultTetVerts.push_back(tet2);
326 std::array<Vec3d, 4> tet3;
327 tet3[0] = iPts[iPts0[1]];
328 tet3[1] = iPts[iPts1[0]];
329 tet3[2] = iPts[iPts1[1]];
330 tet3[3] = inputTetVerts[inVertIds[1]];
332 resultTetVerts.push_back(tet3);
349 static std::list<std::array<Vec3d, 4>>
350 split(
const std::array<Vec3d, 4>& inputTetVerts,
351 const Vec3d& planeOrigin,
352 const Vec3d& u,
const double width,
353 const Vec3d& v,
const double height,
360 for (
int i = 0; i < 4; i++)
362 const Vec3d& vert = inputTetVerts[i];
363 proj[i][2] = (vert - planeOrigin).dot(n);
376 if (outCount == 0 || inCount == 0)
378 return std::list<std::array<Vec3d, 4>>();
382 Vec2d min = Vec2d(IMSTK_DOUBLE_MAX, IMSTK_DOUBLE_MAX);
383 Vec2d max = Vec2d(IMSTK_DOUBLE_MIN, IMSTK_DOUBLE_MIN);
384 for (
int i = 0; i < 4; i++)
387 const Vec3d& vert = inputTetVerts[i];
388 proj[i][0] = (vert - planeOrigin).dot(u);
389 proj[i][1] = (vert - planeOrigin).dot(v);
391 min[0] = std::min(proj[i][0], min[0]);
392 max[0] = std::max(proj[i][0], max[0]);
394 min[1] = std::min(proj[i][1], min[1]);
395 max[1] = std::max(proj[i][1], max[1]);
400 if (!isIntersect(min[0], max[0], -width, width)
401 || !isIntersect(min[1], max[1], -height, height))
403 return std::list<std::array<Vec3d, 4>>();
407 std::list<std::array<Vec3d, 4>> newTets;
408 splitTet(inputTetVerts, planeOrigin, n, newTets);
416 splitTest(
const std::array<Vec3d, 4>& inputTetVerts,
417 const Vec3d& planeOrigin,
418 const Vec3d& u,
const double width,
419 const Vec3d& v,
const double height,
426 for (
int i = 0; i < 4; i++)
428 const Vec3d& vert = inputTetVerts[i];
429 proj[i][2] = (vert - planeOrigin).dot(n);
442 if (outCount == 0 || inCount == 0)
448 Vec2d min = Vec2d(IMSTK_DOUBLE_MAX, IMSTK_DOUBLE_MAX);
449 Vec2d max = Vec2d(IMSTK_DOUBLE_MIN, IMSTK_DOUBLE_MIN);
450 for (
int i = 0; i < 4; i++)
453 const Vec3d& vert = inputTetVerts[i];
454 proj[i][0] = (vert - planeOrigin).dot(u);
455 proj[i][1] = (vert - planeOrigin).dot(v);
457 min[0] = std::min(proj[i][0], min[0]);
458 max[0] = std::max(proj[i][0], max[0]);
460 min[1] = std::min(proj[i][1], min[1]);
461 max[1] = std::max(proj[i][1], max[1]);
466 if (!isIntersect(min[0], max[0], -width, width)
467 || !isIntersect(min[1], max[1], -height, height))