Commit 68d08e4b authored by David Llewellyn-Jones's avatar David Llewellyn-Jones

First attempt voxel rendering to support SVX export.

parent 8607932e
......@@ -1075,3 +1075,55 @@ bool CartesianAssignControlVarsToFunction (FnControlPersist * psFnControlData, F
return FALSE;
}
void CartesianOutputVoxelSlice (unsigned char * pcData, int nResolution, int nChannels, int nSlice, FuncPersist * psFuncData) {
CartesianPersist * psCartesianData = psFuncData->Func.psCartesianData;
int nX;
int nY;
int nChannel;
double fXFunc;
double fYFunc;
double fZFunc;
double fXStep;
double fYStep;
double fZStep;
double fZSlice;
unsigned char ucFill;
fXStep = psFuncData->fXWidth / ((double)nResolution);
fYStep = psFuncData->fYWidth / ((double)nResolution);
fZStep = psFuncData->fZWidth / ((double)nResolution);
fZSlice = psFuncData->fZMin + (nSlice * fZStep);
for (nX = 0; nX < nResolution; nX++) {
fXFunc = psFuncData->fXMin + (nX * fXStep);
for (nY = 0; nY < nResolution; nY++) {
fYFunc = psFuncData->fYMin + (nY * fYStep);
if (psCartesianData->psVariableX) {
SetVariable (psCartesianData->psVariableX, fXFunc);
}
if (psCartesianData->psVariableY) {
SetVariable (psCartesianData->psVariableY, fYFunc);
}
fZFunc = ApproximateOperation (psFuncData->psFunction);
if ((fZFunc > (fZSlice - fZStep)) && (fZFunc < (fZSlice + fZStep))) {
ucFill = 255u;
}
else {
ucFill = 0u;
}
for (nChannel = 0; nChannel < nChannels; nChannel++) {
if (ucFill != 0) {
pcData[(((nX + ((nResolution - nY - 1) * nResolution)) * nChannels) + nChannel)] = ucFill;
}
}
}
}
}
......@@ -58,6 +58,7 @@ int CartesianCountStoredVertices (double fMultiplier, FuncPersist const * psFunc
int CartesianCountStoredFaces (double fMultiplier, FuncPersist const * psFuncData);
int CartesianOutputStoredTrianglesSTL (Recall * hFile, bool boBinary, bool boScreenCoords, double fMultiplier, double fScale, FuncPersist const * psFuncData);
bool CartesianAssignControlVarsToFunction (FnControlPersist * psFnControlData, FuncPersist * psFuncData);
void CartesianOutputVoxelSlice (unsigned char * pcData, int nResolution, int nChannels, int nSlice, FuncPersist * psFuncData);
///////////////////////////////////////////////////////////////////
// Function definitions
......
......@@ -1747,3 +1747,123 @@ bool CurveAssignControlVarsToFunction (FnControlPersist * psFnControlData, FuncP
return boFound;
}
void CurveOutputVoxelSlice (unsigned char * pcData, int nResolution, int nChannels, int nSlice, FuncPersist * psFuncData) {
CurvePersist * psCurveData = psFuncData->Func.psCurveData;
int nPiece;
int nPieces;
int nSegments;
int nSegment;
double fStep;
double fTheta;
double fTexTheta;
Variable * psA;
Variable * psP;
int nX;
int nY;
int nChannel;
double fXFunc;
double fYFunc;
double fZFunc;
double fXStep;
double fYStep;
double fZStep;
double fZSlice;
Vector3 vPos;
Vector3 vOffset;
Vector3 vTangent;
Vector3 vNormal;
Vector3 vBinormal;
Vector3 vSecondDeriv;
Vector3 vTwist1;
Vector3 vTwist2;
Vector3 vUp;
float fSin;
float fCos;
float fRadius;
fXStep = psFuncData->fXWidth / ((double)nResolution);
fYStep = psFuncData->fYWidth / ((double)nResolution);
fZStep = psFuncData->fZWidth / ((double)nResolution);
nPieces = nResolution;
nSegments = nResolution;
fZSlice = psFuncData->fZMin + (nSlice * fZStep);
psA = FindVariable (psFuncData->psVariables, "a");
psP = FindVariable (psFuncData->psVariables, "p");
for (nPiece = 0; nPiece < (nPieces - 1); nPiece++) {
for (nSegment = 0; nSegment < (nSegments - 0); nSegment++) {
fStep = ((double)(nPiece)) / ((double)(nPieces - 1.0f));
fTexTheta = ((double)(nSegment)) / ((double)nSegments - 1.0f);
fTheta = fTexTheta * (2.0 * M_PI);
if (psA) {
SetVariable (psA, fStep);
}
vPos = ApproximateVecSym (psCurveData->pvCurve);
// Calculate the tangent vector
vTangent = ApproximateVecSym (psCurveData->pvCurveDeriv);
// Calculate the second derivative for the binormal calculation
vSecondDeriv = ApproximateVecSym (psCurveData->pvCurveDeriv2);
// Normalise the tangent vector
Normalise (& vTangent);
// Calculate the Frenet frame binormal vector
vBinormal = CrossProduct (& vTangent, & vSecondDeriv);
// Tackle inflection points and straight lines
if (Length (& vBinormal) < INFLECTION_ZEROCHECK) {
vBinormal = CrossProduct (& vTangent, & vUp);
}
Normalise (& vBinormal);
// Calculate the Frenet frame normal vector
vNormal = CrossProduct (& vTangent, & vBinormal);
if (psP) {
SetVariable (psP, fTheta);
}
fSin = sin (fTheta);
fCos = cos (fTheta);
// Transform the position in relation to the Frenet frame
// vOffset = (vNormal * fSin) + (fBinormal * fCos);
vTwist1 = ScaleVector (& vNormal, fCos);
vTwist2 = ScaleVector (& vBinormal, fSin);
vOffset = AddVectors (& vTwist1, & vTwist2);
fRadius = ApproximateOperation (psFuncData->psFunction);
// Set the curve position
fXFunc = (vPos.fX + (fRadius * vOffset.fX));
fYFunc = (vPos.fY + (fRadius * vOffset.fY));
fZFunc = (vPos.fZ + (fRadius * vOffset.fZ));
// Translate the function
fXFunc += psCurveData->fXCentre;
fYFunc += psCurveData->fYCentre;
fZFunc += psCurveData->fZCentre;
// Convert this to a position on the slice
if ((fZFunc > fZSlice) && (fZFunc < (fZSlice + fZStep))) {
nX = (fXFunc - psFuncData->fXMin) / fXStep;
nY = (fYFunc - psFuncData->fYMin) / fYStep;
if ((nX > 0) && (nX < nResolution) && (nY > 0) && (nY < nResolution)) {
for (nChannel = 0; nChannel < nChannels; nChannel++) {
pcData[(((nX + ((nResolution - nY - 1) * nResolution)) * nChannels) + nChannel)] = 255;
}
}
}
}
}
}
......@@ -67,6 +67,7 @@ int CurveCountStoredVertices (double fMultiplier, FuncPersist const * psFuncData
int CurveCountStoredFaces (double fMultiplier, FuncPersist const * psFuncData);
int CurveOutputStoredTrianglesSTL (Recall * hFile, bool boBinary, bool boScreenCoords, double fMultiplier, double fScale, FuncPersist const * psFuncData);
bool CurveAssignControlVarsToFunction (FnControlPersist * psFnControlData, FuncPersist * psFuncData);
void CurveOutputVoxelSlice (unsigned char * pcData, int nResolution, int nChannels, int nSlice, FuncPersist * psFuncData);
///////////////////////////////////////////////////////////////////
// Function definitions
......
......@@ -1376,10 +1376,13 @@ void OutputVoxelSlice (unsigned char * pcData, int nResolution, int nChannels, i
// TODO: Actually store something in the slice
switch (psFuncData->eType) {
case FUNCTYPE_CARTESIAN:
CartesianOutputVoxelSlice (pcData, nResolution, nChannels, nSlice, psFuncData);
break;
case FUNCTYPE_SPHERICAL:
SphericalOutputVoxelSlice (pcData, nResolution, nChannels, nSlice, psFuncData);
break;
case FUNCTYPE_CURVE:
CurveOutputVoxelSlice (pcData, nResolution, nChannels, nSlice, psFuncData);
break;
default:
// Do nothing
......
......@@ -1306,3 +1306,70 @@ bool SphericalAssignControlVarsToFunction (FnControlPersist * psFnControlData, F
return boFound;
}
void SphericalOutputVoxelSlice (unsigned char * pcData, int nResolution, int nChannels, int nSlice, FuncPersist * psFuncData) {
SphericalPersist * psSphericalData = psFuncData->Func.psSphericalData;
int nX;
int nY;
int nChannel;
double fXFunc;
double fYFunc;
double fZFunc;
double fXStep;
double fYStep;
double fZStep;
unsigned char ucFill;
double fAFunc;
double fPFunc;
double fRFunc;
double fDiag;
double fAdjacent;
double fOpposite;
double fElevation;
double fDistance;
fXStep = psFuncData->fXWidth / ((double)nResolution);
fYStep = psFuncData->fYWidth / ((double)nResolution);
fZStep = psFuncData->fZWidth / ((double)nResolution);
fZFunc = psFuncData->fZMin + (nSlice * fZStep);
for (nX = 0; nX < nResolution; nX++) {
fXFunc = psFuncData->fXMin + (nX * fXStep);
for (nY = 0; nY < nResolution; nY++) {
fYFunc = psFuncData->fYMin + (nY * fYStep);
// Calculate the angles
fOpposite = (fXFunc - psSphericalData->fXCentre);
fAdjacent = (fYFunc - psSphericalData->fYCentre);
fElevation = (fZFunc - psSphericalData->fZCentre);
fAFunc = atan2 (fOpposite, fAdjacent);
fDiag = sqrt ((fAdjacent * fAdjacent) + (fOpposite * fOpposite));
fPFunc = atan2 (fElevation, fDiag);
if (psSphericalData->psVariableA) {
SetVariable (psSphericalData->psVariableA, fAFunc);
}
if (psSphericalData->psVariableP) {
SetVariable (psSphericalData->psVariableP, fPFunc);
}
fRFunc = ApproximateOperation (psFuncData->psFunction);
fDistance = sqrt ((fAdjacent * fAdjacent) + (fOpposite * fOpposite) + (fElevation * fElevation));
if ((fRFunc > (fDistance - fZStep)) && (fRFunc < (fDistance + fZStep))) {
ucFill = 255u;
}
else {
ucFill = 0u;
}
for (nChannel = 0; nChannel < nChannels; nChannel++) {
if (ucFill != 0) {
pcData[(((nX + ((nResolution - nY - 1) * nResolution)) * nChannels) + nChannel)] = ucFill;
}
}
}
}
}
......@@ -60,6 +60,7 @@ int SphericalCountStoredVertices (double fMultiplier, FuncPersist const * psFunc
int SphericalCountStoredFaces (double fMultiplier, FuncPersist const * psFuncData);
int SphericalOutputStoredTrianglesSTL (Recall * hFile, bool boBinary, bool boScreenCoords, double fMultiplier, double fScale, FuncPersist const * psFuncData);
bool SphericalAssignControlVarsToFunction (FnControlPersist * psFnControlData, FuncPersist * psFuncData);
void SphericalOutputVoxelSlice (unsigned char * pcData, int nResolution, int nChannels, int nSlice, FuncPersist * psFuncData);
///////////////////////////////////////////////////////////////////
// Function definitions
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment