Skip to content

Commit

Permalink
cleanups in the code done, still needs to remove unused functions and…
Browse files Browse the repository at this point in the history
… variables

Signed-off-by: Perminder <[email protected]>
  • Loading branch information
perminder-17 committed Nov 10, 2024
1 parent f37cd36 commit 6507df7
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 78 deletions.
3 changes: 2 additions & 1 deletion avogadro/core/cube.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ class AVOGADROCORE_EXPORT Cube
std::array<float, 8> getValsCube(int i, int j, int k) const;


std::array<std::array<float, 3>, 8> getGradCube(int i, int j, int k) const;
std::array<std::array<float, 3>, 8> getGradCube(int i, int j, int k) const;

/**
* Get the data value at the specified indices.
* @param i x index
Expand Down
90 changes: 37 additions & 53 deletions avogadro/qtgui/meshgenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,12 @@ bool MeshGenerator::initialize(const Cube* cube_, Mesh* mesh_, float iso,
void MeshGenerator::FlyingEdgesAlgorithmPass1()
{
// Loop through z-dimension
int nx = m_dim.x();
int ny = m_dim.y();
int nz = m_dim.z();

for(int k = 0; k != nz; ++k) {
for(int j = 0; j != ny; ++j)
for(int k = 0; k != m_dim.z(); ++k) {
for(int j = 0; j != m_dim.y(); ++j)
{

auto curEdgeCases = edgeCases.begin() + (nx - 1) * (k * ny + j);
auto curEdgeCases = edgeCases.begin() + (m_dim.x() - 1) * (k * m_dim.y() + j);

auto curPointValues = m_cube->getRowIter(j, k);

Expand All @@ -96,10 +93,10 @@ void MeshGenerator::FlyingEdgesAlgorithmPass1()
}
}

for(int k = 0; k != nz; ++k){
for(int j = 0; j != ny; ++j)
for(int k = 0; k != m_dim.z(); ++k){
for(int j = 0; j != m_dim.y(); ++j)
{
gridEdge& curGridEdge = gridEdges[k * ny + j];
gridEdge& curGridEdge = gridEdges[k * m_dim.y() + j];
curGridEdge.xl = m_dim.x();


Expand All @@ -121,39 +118,36 @@ void MeshGenerator::FlyingEdgesAlgorithmPass1()

void MeshGenerator::FlyingEdgesAlgorithmPass2()
{
int nx = m_dim.x();
int ny = m_dim.y();
int nz = m_dim.z();
for(int k = 0; k != nz - 1; ++k){
for(int j = 0; j != ny - 1; ++j)
for(int k = 0; k != m_dim.z() - 1; ++k){
for(int j = 0; j != m_dim.y() - 1; ++j)
{
int xl, xr;
calcTrimValues(xl, xr, j, k); // xl, xr set in this function

gridEdge& ge0 = gridEdges[k * ny + j];
gridEdge& ge1 = gridEdges[k* ny +j + 1];
gridEdge& ge2 = gridEdges[(k+1) * ny + j];
gridEdge& ge3 = gridEdges[(k+1) * ny + j + 1];
gridEdge& ge0 = gridEdges[k * m_dim.y() + j];
gridEdge& ge1 = gridEdges[k* m_dim.y() +j + 1];
gridEdge& ge2 = gridEdges[(k+1) * m_dim.y() + j];
gridEdge& ge3 = gridEdges[(k+1) * m_dim.y() + j + 1];

auto const& ec0 = edgeCases.begin() + (m_dim.x()-1) * (k * m_dim.y() + j);
auto const& ec1 = edgeCases.begin() + (m_dim.x()-1) * (k * m_dim.y() + j + 1);
auto const& ec2 = edgeCases.begin() + (m_dim.x()-1) * ((k+1) * m_dim.y() + j);
auto const& ec3 = edgeCases.begin() + (m_dim.x()-1) * ((k+1) * m_dim.y() + j + 1);

// Count the number of triangles along this row of cubes
int& curTriCounter = *(triCounter.begin() + k * (ny - 1) + j);
int& curTriCounter = *(triCounter.begin() + k * (m_dim.y() - 1) + j);


auto curCubeCaseIds = cubeCases.begin() + (m_dim.x() - 1) * (k * (m_dim.y() - 1) + j);

bool isYEnd = (j == ny - 2);
bool isZEnd = (k == nz - 2);
bool isYEnd = (j == m_dim.y() - 2);
bool isZEnd = (k == m_dim.z() - 2);



for(int i = xl; i != xr; ++i)
{
bool isXEnd = (i == nx - 2);
bool isXEnd = (i == m_dim.x() - 2);

unsigned char caseId = calcCubeCase(ec0[i], ec1[i], ec2[i], ec3[i]); // todo cubeCase not decleared
curCubeCaseIds[i] = caseId;
Expand Down Expand Up @@ -210,24 +204,21 @@ void MeshGenerator::FlyingEdgesAlgorithmPass3()
{
int tmp;
int triAccum = 0;
int nx = m_dim.x();
int ny = m_dim.y();
int nz = m_dim.z();
for(int k = 0; k != nz -1; ++k) {
for(int j = 0; j != ny-1; ++j)
for(int k = 0; k != m_dim.z() -1; ++k) {
for(int j = 0; j != m_dim.y()-1; ++j)
{
int& curTriCounter = triCounter[k*(ny-1)+j];
int& curTriCounter = triCounter[k*(m_dim.y()-1)+j];

tmp = curTriCounter;
curTriCounter = triAccum;
triAccum += tmp;
}}

int pointAccum = 0;
for(int k = 0; k != nz; ++k) {
for(int j = 0; j != ny; ++j)
for(int k = 0; k != m_dim.z(); ++k) {
for(int j = 0; j != m_dim.y(); ++j)
{
gridEdge& curGridEdge = gridEdges[(k * ny) + j];
gridEdge& curGridEdge = gridEdges[(k * m_dim.y()) + j];

tmp = curGridEdge.xstart;
curGridEdge.xstart = pointAccum;
Expand All @@ -250,12 +241,9 @@ void MeshGenerator::FlyingEdgesAlgorithmPass3()

void MeshGenerator::FlyingEdgesAlgorithmPass4()
{
int nx = m_dim.x();
int ny = m_dim.y();
int nz = m_dim.z();

for(int k = 0; k != nz -1; ++k) {
for(int j = 0; j != ny-1; ++j)
for(int k = 0; k != m_dim.z() -1; ++k) {
for(int j = 0; j != m_dim.y()-1; ++j)
{
// find adjusted trim values
int xl, xr;
Expand All @@ -264,7 +252,7 @@ void MeshGenerator::FlyingEdgesAlgorithmPass4()
if(xl == xr)
continue;

int triIdx = triCounter[(k*(ny-1)) + j];
int triIdx = triCounter[(k*(m_dim.y()-1)) + j];
auto curCubeCaseIds = cubeCases.begin() + (m_dim.x()-1)*(k*(m_dim.y()-1) + j);

gridEdge const& ge0 = gridEdges[k* m_dim.y() + j];
Expand All @@ -284,12 +272,12 @@ void MeshGenerator::FlyingEdgesAlgorithmPass4()

int x3counter = 0;

bool isYEnd = (j == ny-2);
bool isZEnd = (k == nz-2);
bool isYEnd = (j == m_dim.y()-2);
bool isZEnd = (k == m_dim.z()-2);

for(int i = xl; i != xr; ++i)
{
bool isXEnd = (i == nx-2);
bool isXEnd = (i == m_dim.x()-2);

unsigned char caseId = curCubeCaseIds[i];

Expand Down Expand Up @@ -589,22 +577,19 @@ unsigned char MeshGenerator::calcCubeCase(

bool MeshGenerator::isCutEdge(int const& i, int const& j, int const& k) const
{
int nx = m_dim.x();
int ny = m_dim.y();
int nz = m_dim.z();

// Assuming edgeCases are all set
int edgeCaseIdx = k * ((nx - 1) * ny) + (j * (nx - 1)) + i;
int edgeCaseIdx = k * ((m_dim.x() - 1) * m_dim.y()) + (j * (m_dim.x() - 1)) + i;
unsigned char edgeCase = edgeCases[edgeCaseIdx];

if (edgeCase == 1 || edgeCase == 2)
{
return true;
}

if (j != ny - 1)
if (j != m_dim.y() - 1)
{
int edgeCaseIdxY = (k * (nx - 1) * ny) + ((j + 1) * (nx - 1)) + i;
int edgeCaseIdxY = (k * (m_dim.x() - 1) * m_dim.y()) + ((j + 1) * (m_dim.x() - 1)) + i;
unsigned char edgeCaseY = edgeCases[edgeCaseIdxY];

// If the sum is odd, the edge along the y-axis is cut
Expand All @@ -614,9 +599,9 @@ bool MeshGenerator::isCutEdge(int const& i, int const& j, int const& k) const
}
}

if (k != nz - 1)
if (k != m_dim.z() - 1)
{
int edgeCaseIdxZ = ((k + 1) * (nx - 1) * ny) + (j * (nx - 1)) + i;
int edgeCaseIdxZ = ((k + 1) * (m_dim.x() - 1) * m_dim.y()) + (j * (m_dim.x() - 1)) + i;
unsigned char edgeCaseZ = edgeCases[edgeCaseIdxZ];

// If the sum is odd, the edge along the z-axis is cut
Expand Down Expand Up @@ -648,12 +633,11 @@ unsigned char MeshGenerator::calcCaseEdge(bool const& prevEdge, bool const& curr
// 2000
void MeshGenerator::calcTrimValues(int& xl, int& xr, int const& j, int const& k) const
{
int ny = m_dim.y();

const gridEdge& ge0 = gridEdges[k * ny + j];
const gridEdge& ge1 = gridEdges[k * ny + j + 1];
const gridEdge& ge2 = gridEdges[(k + 1) * ny + j];
const gridEdge& ge3 = gridEdges[(k + 1) * ny + j + 1];
const gridEdge& ge0 = gridEdges[k * m_dim.y() + j];
const gridEdge& ge1 = gridEdges[k * m_dim.y() + j + 1];
const gridEdge& ge2 = gridEdges[(k + 1) * m_dim.y() + j];
const gridEdge& ge3 = gridEdges[(k + 1) * m_dim.y() + j + 1];

xl = std::min({ge0.xl, ge1.xl, ge2.xl, ge3.xl});
xr = std::max({ge0.xr, ge1.xr, ge2.xr, ge3.xr});
Expand Down
78 changes: 54 additions & 24 deletions avogadro/qtgui/meshgenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class AVOGADROQTGUI_EXPORT MeshGenerator : public QThread
*/
void run() override;

/**
* It holds the range and starting offsets of isosurface-intersected
* edges along the x, y, and z axes for each grid cell.
*/
struct gridEdge
{
gridEdge()
Expand All @@ -104,23 +108,46 @@ class AVOGADROQTGUI_EXPORT MeshGenerator : public QThread
};



/**
* Pass 1 for flying edges. Pass1 detects and records
* where the isosurface intersects each row of grid edges
* along the x-axis.
*/
void FlyingEdgesAlgorithmPass1();

/**
* Pass2 assigns case identifiers to each grid cell based on
* intersected edges and tallies the number of triangles needed
* for mesh construction.
*/
void FlyingEdgesAlgorithmPass2();

/**
* Pass3 computes cumulative offsets for triangles
* and vertices and allocates memory for the mesh structures.
*/
void FlyingEdgesAlgorithmPass3();

/**
* Calculates normals, triangles and vertices.
*/
void FlyingEdgesAlgorithmPass4();

/**
* @return The Cube being used by the class.
*/
const Core::Cube* cube() const { return m_cube; }

/**
* Determines the x-range (xl to xr) where isosurface intersections
* occur, optimizing calculations within this range.
*/
inline void calcTrimValues(
int& xl, int& xr, int const& j, int const& k) const;


void calculateTotalPoints();

/**
* Indicates which edges intersects the isosurface.
*/
inline unsigned char
calcCubeCase(unsigned char const& ec0, unsigned char const& ec1,
unsigned char const& ec2, unsigned char const& ec3) const;
Expand All @@ -146,6 +173,7 @@ class AVOGADROQTGUI_EXPORT MeshGenerator : public QThread
int progressMaximum() { return m_progmax; }

signals:

/**
* The current value of the calculation's progress.
*/
Expand All @@ -171,22 +199,32 @@ class AVOGADROQTGUI_EXPORT MeshGenerator : public QThread
unsigned long duplicate(const Vector3i& c, const Vector3f& pos);

/**
* Perform a marching cubes step on a single cube.
*/
bool marchingCube(const Vector3i& pos);

* isCutEdge checks whether the grid edge at position (i, j, k) is
* intersected by the isosurface based on edge case conditions.
* @return Boolean if it's intersected or not.
*/
bool isCutEdge(int const& i, int const& j, int const& k) const;

/**
* It computes the 3D intersection point on a cube edge via interpolation.
*/
inline std::array<float, 3> interpolateOnCube(
std::array<std::array<float, 3>, 8> const& pts,
std::array<float, 8> const& isovals,
unsigned char const& edge) const;

/**
* It linearly interpolates between two 3D points, a and b, using
* the given weight to determine the intermediate position.
*/
inline std::array<float, 3> interpolate(
std::array<float, 3> const& a,
std::array<float, 3> const& b,
float const& weight) const;

/**
* calcCaseEdge determines an edge case code (0–3) based on two boolean edge comparisons.
*/
inline unsigned char calcCaseEdge(bool const& prevEdge, bool const& currEdge) const;

float m_iso; /** The value of the isosurface. */
Expand All @@ -198,26 +236,18 @@ class AVOGADROQTGUI_EXPORT MeshGenerator : public QThread
Vector3f m_min; /** The minimum point in the cube. */
Vector3i m_dim; /** The dimensions of the cube. */

std::array<std::array<float, 3>, 8> cube_t;
std::array<float, 8> scalarCube_t;

Core::Array<Vector3f> m_vertices, m_normals;
Core::Array<unsigned int> m_indices;
std::vector<gridEdge> gridEdges;
std::vector<unsigned char> cubeCases; // size (nx-1)*(ny-1)*(nz-1)

std::vector<int> triCounter; // size of (ny-1)*(nz-1)
std::vector<unsigned char> edgeCases;
Core::Array<Vector3f> points; //
Core::Array<Vector3f> normals; // The output
Core::Array<Vector3f> tris;
Core::Array<Vector3f> points, normals;
std::vector<gridEdge> gridEdges; // size (m_dim.y() * m_dim.z())

Check notice on line 240 in avogadro/qtgui/meshgenerator.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/qtgui/meshgenerator.h#L240

class member 'MeshGenerator::gridEdges' is never used.
std::vector<unsigned char> cubeCases; //size ((m_dim.x() - 1) * (m_dim.y() - 1) * (m_dim.z() - 1))

Check notice on line 241 in avogadro/qtgui/meshgenerator.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/qtgui/meshgenerator.h#L241

class member 'MeshGenerator::cubeCases' is never used.
std::vector<int> triCounter; // size ((m_dim.y() - 1) * (m_dim.z() - 1))

Check notice on line 242 in avogadro/qtgui/meshgenerator.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/qtgui/meshgenerator.h#L242

class member 'MeshGenerator::triCounter' is never used.
std::vector<unsigned char> edgeCases; // size ((m_dim.x() - 1) * (m_dim.y()) * (m_dim.z()))

Check notice on line 243 in avogadro/qtgui/meshgenerator.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/qtgui/meshgenerator.h#L243

class member 'MeshGenerator::edgeCases' is never used.
Core::Array<Vector3f> tris; // triangles of a mesh
int m_progmin;
int m_progmax;

/**
* These are the tables of constants for the marching cubes and tetrahedra
* algorithms. They are taken from the public domain source at
* http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
* These are the lookup tables for flying edges.
* Reference : https://github.com/sandialabs/miniIsosurface/blob/master/flyingEdges/util/MarchingCubesTables.h
*/
static const unsigned char numTris[256];

Check notice on line 252 in avogadro/qtgui/meshgenerator.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/qtgui/meshgenerator.h#L252

class member 'MeshGenerator::numTris' is never used.
static const bool isCut[256][12];

Check notice on line 253 in avogadro/qtgui/meshgenerator.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/qtgui/meshgenerator.h#L253

class member 'MeshGenerator::isCut' is never used.
Expand Down

0 comments on commit 6507df7

Please sign in to comment.