/*
JWildfire - an image and animation processor written in Java
Copyright (C) 1995-2014 Andreas Maschke
This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This software 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this software;
if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
/*
* Implementation of the marching cubes algorithm based on the
* "Marching Cubes Tutorial Applet Copyright (C) 2002 - GERVAISE Raphael & RICHARD Karen"
* http://users.polytech.unice.fr/~lingrand/MarchingCubes/applet.html
*/
package org.jwildfire.create.tina.meshgen.marchingcubes;
public class EdgesCalculator {
/**
* computes the interpolated point along a specified whose intensity equals the reference value
* @param pVertex1 first extremity of the edge
* @param pVertex2 second extremity of the edge
* @param pTargetEdge stores the resulting edge, gets invalidated when the interpolated point is beyond edge boundaries
*/
private static void computeEdge(Point3f pVertex1, int pIntensity1, Point3f pVertex2, int pIntensity2, ImageStackSampler pSampler, int pSeekValue, InvalidatablePoint pTargetEdge) {
if (pIntensity2 < pIntensity1) {
computeEdge(pVertex2, pIntensity2, pVertex1, pIntensity1, pSampler, pSeekValue, pTargetEdge);
}
float t = (pSeekValue - pIntensity1) / (float) (pIntensity2 - pIntensity1);
if (t >= 0 && t <= 1) {
pTargetEdge.x = (pVertex2.x - pVertex1.x) * t + pVertex1.x;
pTargetEdge.y = (pVertex2.y - pVertex1.y) * t + pVertex1.y;
pTargetEdge.z = (pVertex2.z - pVertex1.z) * t + pVertex1.z;
pTargetEdge.invalid = false;
}
else {
pTargetEdge.invalid = true;
}
}
/**
* computes interpolated values along each edge of the cube
* (invalidates the target if interpolated value doesn't belong to the edge)
*/
public static void computeEdges(Cube pCube, ImageStackSampler pSampler, int pSeekValue) {
Point3f[] vertices = pCube.getVertices();
InvalidatablePoint[] edges = pCube.getEdges();
int intensity0 = pSampler.getIntensity(vertices[0]);
int intensity1 = pSampler.getIntensity(vertices[1]);
int intensity2 = pSampler.getIntensity(vertices[2]);
int intensity3 = pSampler.getIntensity(vertices[3]);
int intensity4 = pSampler.getIntensity(vertices[4]);
int intensity5 = pSampler.getIntensity(vertices[5]);
int intensity6 = pSampler.getIntensity(vertices[6]);
int intensity7 = pSampler.getIntensity(vertices[7]);
computeEdge(vertices[0], intensity0, vertices[1], intensity1, pSampler, pSeekValue, edges[0]);
computeEdge(vertices[1], intensity1, vertices[2], intensity2, pSampler, pSeekValue, edges[1]);
computeEdge(vertices[2], intensity2, vertices[3], intensity3, pSampler, pSeekValue, edges[2]);
computeEdge(vertices[3], intensity3, vertices[0], intensity0, pSampler, pSeekValue, edges[3]);
computeEdge(vertices[4], intensity4, vertices[5], intensity5, pSampler, pSeekValue, edges[4]);
computeEdge(vertices[5], intensity5, vertices[6], intensity6, pSampler, pSeekValue, edges[5]);
computeEdge(vertices[6], intensity6, vertices[7], intensity7, pSampler, pSeekValue, edges[6]);
computeEdge(vertices[7], intensity7, vertices[4], intensity4, pSampler, pSeekValue, edges[7]);
computeEdge(vertices[0], intensity0, vertices[4], intensity4, pSampler, pSeekValue, edges[8]);
computeEdge(vertices[1], intensity1, vertices[5], intensity5, pSampler, pSeekValue, edges[9]);
computeEdge(vertices[3], intensity3, vertices[7], intensity7, pSampler, pSeekValue, edges[10]);
computeEdge(vertices[2], intensity2, vertices[6], intensity6, pSampler, pSeekValue, edges[11]);
}
}