Skip to content

Commit

Permalink
Merge pull request #4 from Azzinoth/master
Browse files Browse the repository at this point in the history
Updating dev
  • Loading branch information
Azzinoth authored May 4, 2024
2 parents 5785768 + df65e79 commit 6a43f46
Show file tree
Hide file tree
Showing 22 changed files with 464 additions and 144 deletions.
96 changes: 96 additions & 0 deletions .github/workflows/ContinuousIntegration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: ContinuousIntegration

on:
push:
branches: [ "master", "dev" ]
pull_request:
branches: [ "master", "dev" ]

jobs:
ContinuousIntegration:
runs-on: windows-latest

strategy:
matrix:
build_type: [Release]

steps:

- name: Checkout code
uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Checkout resources
uses: actions/checkout@v4
with:
ref: media
path: media

- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{ matrix.build_type }}

- name: Ensure all files are in place
working-directory: ${{github.workspace}}
run: |
copy "media/Tests/CI_Small.txt" CI_Small.txt
copy "media/Tests/staghornOriginal.obj" staghornOriginal.obj
Move "${{github.workspace}}\build\Release\HabiCAT3D.exe" "${{github.workspace}}\HabiCAT3D.exe"
- name: Run test
working-directory: ${{github.workspace}}
run: |
$processStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$processStartInfo.FileName = "HabiCAT3D.exe"
$processStartInfo.Arguments = "-console -run_script_file filepath=`"CI_Small.txt`""
$processStartInfo.RedirectStandardInput = $true
$processStartInfo.UseShellExecute = $false
Write-Host "Starting the executable..."
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $processStartInfo
$process.Start() | Out-Null
Write-Host "Executable started."
Write-Host "Waiting for the process to exit..."
$process.WaitForExit(300000) # 300 seconds
$substring = "All evaluations passed"
$found = $false
Get-Content "CONSOLE_LOG.txt" | ForEach-Object {
if ($_ -match $substring)
{
Write-Host $_
$found = $true
}
}
if (-not $found)
{
Write-Error "Not all evaluations succeeded."
exit 1
}
if (Test-Path "Results.rug")
{
Write-Host "Application created Results.rug successfully."
} else
{
Write-Error "Failed to detect Results.rug"
exit 1
}
if ($process.ExitCode -eq 0)
{
Write-Host "Application ran successfully and exited gracefully."
}
else
{
Write-Host "Application exit code: $($process.ExitCode)"
Write-Error "Application crashed or exited with a non-zero exit code."
exit 1
}
shell: pwsh
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ file(GLOB SubSystems_ConsoleJobs_SRC
"SubSystems/ConsoleJobs/GlobalSettingJob.cpp"
"SubSystems/ConsoleJobs/ExportLayerAsImageJob.h"
"SubSystems/ConsoleJobs/ExportLayerAsImageJob.cpp"
"SubSystems/ConsoleJobs/QueryJob.h"
"SubSystems/ConsoleJobs/QueryJob.cpp"
"SubSystems/ConsoleJobs/ConsoleJobManager.h"
"SubSystems/ConsoleJobs/ConsoleJobManager.cpp"
)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<img src="https://github.com/Azzinoth/HabiCAT3D/blob/media/HabiCAT3D_Logo.png" width=256 />
<h1> HabiCAT 3D <br>Habitat Complexity Analysis Tool 3D </h1>
<img src="https://github.com/Azzinoth/HabiCAT3D/actions/workflows/Build.yml/badge.svg" alt="Build Status">
<img src="https://github.com/Azzinoth/HabiCAT3D/actions/workflows/ContinuousIntegration.yml/badge.svg" alt="Continuous Integration">
<img src="https://github.com/Azzinoth/HabiCAT3D/blob/media/Coral_With_Rugosity.png"/>
</div>

Expand Down
4 changes: 3 additions & 1 deletion SubSystems/CGALDeclarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ typedef Kernel::Plane_3 Plane_3;

typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Triangle_3 Triangle_3;
typedef CGAL::Bbox_3 Bbox_3;
typedef CGAL::Bbox_3 Bbox_3;

#include <CGAL/convex_hull_2.h>
181 changes: 123 additions & 58 deletions SubSystems/ComplexityCore/Layers/RugosityLayerProducer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ void(*RugosityLayerProducer::OnRugosityCalculationsEndCallbackImpl)(MeshLayer) =

RugosityLayerProducer::RugosityLayerProducer()
{
RugosityAlgorithmList.push_back("Average normal(default)");
RugosityAlgorithmList.push_back("Min Rugosity");
RugosityAlgorithmList.push_back("Average normal");
RugosityAlgorithmList.push_back("Min Rugosity(default)");
RugosityAlgorithmList.push_back("Least square fitting");

OrientationSetNamesForMinRugosityList.push_back("1");
Expand Down Expand Up @@ -93,6 +93,23 @@ Point_2 RugosityLayerProducer::ProjectToLocalCoordinates(const glm::dvec3& Point
return Point_2(X, Y);
}

Point_2 RugosityLayerProducer::ProjectPointOntoPlane(const Point_3& Point, const Plane_3& Plane)
{
// Project the point onto the plane
Point_3 ProjectedPoint = Plane.projection(Point);

// Construct an orthonormal basis for the plane
Vector_3 Base1 = Plane.base1();
Vector_3 Base2 = Plane.base2();

// Express the projected point in the local coordinate system of the plane
Vector_3 DifferenceVector = ProjectedPoint - Plane.point();
double X = DifferenceVector * Base1;
double Y = DifferenceVector * Base2;

return Point_2(X, Y);
}

void RugosityLayerProducer::CalculateOneNodeRugosity(GridNode* CurrentNode)
{
if (CurrentNode->TrianglesInCell.empty())
Expand Down Expand Up @@ -123,84 +140,117 @@ void RugosityLayerProducer::CalculateOneNodeRugosity(GridNode* CurrentNode)
if (RUGOSITY_LAYER_PRODUCER.bUniqueProjectedArea)
{
CGALCorrectTotalArea = TotalArea;
double TotalProjectedArea = 0.0;

glm::dvec3 U, V;
RUGOSITY_LAYER_PRODUCER.CreateLocalCoordinateSystem(PlaneNormal, U, V);

Polygon_vector Triangles;
for (int i = 0; i < CurrentNode->TrianglesInCell.size(); i++)
if (RUGOSITY_LAYER_PRODUCER.bUniqueProjectedAreaApproximation)
{
if (COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->TrianglesArea[CurrentNode->TrianglesInCell[i]] == 0.0)
continue;

std::vector<glm::vec3> CurrentTriangle = COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->Triangles[CurrentNode->TrianglesInCell[i]];
Polygon_2 TempTriangle;

#ifndef CGAL_FOR_PROJECTION
glm::dvec3 AProjection = ProjectionPlane->ProjectPoint(CurrentTriangle[0]);
glm::dvec3 BProjection = ProjectionPlane->ProjectPoint(CurrentTriangle[1]);
glm::dvec3 CProjection = ProjectionPlane->ProjectPoint(CurrentTriangle[2]);

TempTriangle.push_back(RUGOSITY_LAYER_PRODUCER.ProjectToLocalCoordinates(AProjection, U, V));
TempTriangle.push_back(RUGOSITY_LAYER_PRODUCER.ProjectToLocalCoordinates(BProjection, U, V));
TempTriangle.push_back(RUGOSITY_LAYER_PRODUCER.ProjectToLocalCoordinates(CProjection, U, V));
Point_3 PointA(0.0f, 0.0f, 0.0f);
Plane_3 PlaneToProjectOnto(PointA, Vector_3(PlaneNormal.x, PlaneNormal.y, PlaneNormal.z));

#else CGAL_FOR_PROJECTION
for (size_t j = 0; j < CurrentTriangle.size(); j++)
std::vector<Point_2> ProjectedPoints, ConvexHullOfProjectedPoints;
for (int i = 0; i < CurrentNode->TrianglesInCell.size(); i++)
{
Point_3 Projection_CGAL_3D = plane.projection(Point_3(CurrentTriangle[j].x, CurrentTriangle[j].y, CurrentTriangle[j].z));

double X = glm::dot(glm::dvec3(Projection_CGAL_3D.x(), Projection_CGAL_3D.y(), Projection_CGAL_3D.z()), base1);
double Y = glm::dot(glm::dvec3(Projection_CGAL_3D.x(), Projection_CGAL_3D.y(), Projection_CGAL_3D.z()), base2);
if (COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->TrianglesArea[CurrentNode->TrianglesInCell[i]] == 0.0)
continue;

Point_2 AProjection_CGAL_2D(X, Y);
TempTriangle.push_back(AProjection_CGAL_2D);
std::vector<glm::vec3> CurrentTriangle = COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->Triangles[CurrentNode->TrianglesInCell[i]];
for (size_t j = 0; j < CurrentTriangle.size(); j++)
{
ProjectedPoints.push_back(RUGOSITY_LAYER_PRODUCER.ProjectPointOntoPlane(Point_3(CurrentTriangle[j].x, CurrentTriangle[j].y, CurrentTriangle[j].z), PlaneToProjectOnto));
}
}
#endif

if (!CGAL::is_ccw_strongly_convex_2(TempTriangle.vertices_begin(), TempTriangle.vertices_end()))
TempTriangle.reverse_orientation();

if (TempTriangle.area() == 0.0)
{
CGALCorrectTotalArea -= static_cast<float>(COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->TrianglesArea[CurrentNode->TrianglesInCell[i]]);
}
else
{
Triangles.push_back(TempTriangle);
}
}
CGAL::convex_hull_2(ProjectedPoints.begin(), ProjectedPoints.end(), std::back_inserter(ConvexHullOfProjectedPoints));

Polygon_set_2 TriangleGroup;
std::vector<int> CGALFailedIndexes;

std::vector<int> Ranges;
try
{
TriangleGroup.join(Triangles.begin(), Triangles.end());
Polygon_2 Polygon;
for (const auto& CurrentPoint : ConvexHullOfProjectedPoints)
Polygon.push_back(CurrentPoint);

TotalProjectedArea = abs(CGAL::to_double(Polygon.area()));
}
catch (...)
else
{
for (size_t i = 0; i < Triangles.size(); i++)
Polygon_vector Triangles;

for (int i = 0; i < CurrentNode->TrianglesInCell.size(); i++)
{
try
if (COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->TrianglesArea[CurrentNode->TrianglesInCell[i]] == 0.0)
continue;

std::vector<glm::vec3> CurrentTriangle = COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->Triangles[CurrentNode->TrianglesInCell[i]];

Polygon_2 TempTriangle;

#ifndef CGAL_FOR_PROJECTION
glm::dvec3 U, V;
RUGOSITY_LAYER_PRODUCER.CreateLocalCoordinateSystem(PlaneNormal, U, V);

glm::dvec3 AProjection = ProjectionPlane->ProjectPoint(CurrentTriangle[0]);
glm::dvec3 BProjection = ProjectionPlane->ProjectPoint(CurrentTriangle[1]);
glm::dvec3 CProjection = ProjectionPlane->ProjectPoint(CurrentTriangle[2]);

TempTriangle.push_back(RUGOSITY_LAYER_PRODUCER.ProjectToLocalCoordinates(AProjection, U, V));
TempTriangle.push_back(RUGOSITY_LAYER_PRODUCER.ProjectToLocalCoordinates(BProjection, U, V));
TempTriangle.push_back(RUGOSITY_LAYER_PRODUCER.ProjectToLocalCoordinates(CProjection, U, V));

#else CGAL_FOR_PROJECTION
for (size_t j = 0; j < CurrentTriangle.size(); j++)
{
TriangleGroup.join(Triangles[i]);
Point_3 Projection_CGAL_3D = plane.projection(Point_3(CurrentTriangle[j].x, CurrentTriangle[j].y, CurrentTriangle[j].z));

double X = glm::dot(glm::dvec3(Projection_CGAL_3D.x(), Projection_CGAL_3D.y(), Projection_CGAL_3D.z()), base1);
double Y = glm::dot(glm::dvec3(Projection_CGAL_3D.x(), Projection_CGAL_3D.y(), Projection_CGAL_3D.z()), base2);

Point_2 AProjection_CGAL_2D(X, Y);
TempTriangle.push_back(AProjection_CGAL_2D);
}
catch (...)
#endif

if (!CGAL::is_ccw_strongly_convex_2(TempTriangle.vertices_begin(), TempTriangle.vertices_end()))
TempTriangle.reverse_orientation();

if (TempTriangle.area() == 0.0)
{
CGALFailedIndexes.push_back(static_cast<int>(i));
CGALCorrectTotalArea -= static_cast<float>(COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->TrianglesArea[CurrentNode->TrianglesInCell[i]]);
}
else
{
Triangles.push_back(TempTriangle);
}
}

for (size_t i = 0; i < CGALFailedIndexes.size(); i++)
Polygon_set_2 TriangleGroup;
std::vector<int> CGALFailedIndexes;

std::vector<int> Ranges;
try
{
CGALCorrectTotalArea -= static_cast<float>(COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->TrianglesArea[CurrentNode->TrianglesInCell[CGALFailedIndexes[i]]]);
TriangleGroup.join(Triangles.begin(), Triangles.end());
}
}
catch (...)
{
for (size_t i = 0; i < Triangles.size(); i++)
{
try
{
TriangleGroup.join(Triangles[i]);
}
catch (...)
{
CGALFailedIndexes.push_back(static_cast<int>(i));
}
}

double TotalProjectedArea = 0.0;
TotalProjectedArea = RUGOSITY_LAYER_PRODUCER.CGALCalculateArea(TriangleGroup);
for (size_t i = 0; i < CGALFailedIndexes.size(); i++)
{
CGALCorrectTotalArea -= static_cast<float>(COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->TrianglesArea[CurrentNode->TrianglesInCell[CGALFailedIndexes[i]]]);
}
}

TotalProjectedArea = RUGOSITY_LAYER_PRODUCER.CGALCalculateArea(TriangleGroup);
}

if (TotalProjectedArea == 0)
{
Expand Down Expand Up @@ -541,6 +591,11 @@ void RugosityLayerProducer::OnJitterCalculationsEnd(MeshLayer NewLayer)
OverlapAware = "Yes";
NewLayer.DebugInfo->AddEntry("Unique projected area (very slow)", OverlapAware);

std::string OverlapAwareApproximation = "No";
if (RUGOSITY_LAYER_PRODUCER.bUniqueProjectedAreaApproximation)
OverlapAwareApproximation = "Yes";
NewLayer.DebugInfo->AddEntry("Approximation of unique projected area", OverlapAwareApproximation);

LastTimeTookForCalculation = float(TIME.EndTimeStamp("CalculateRugorsityTotal"));

COMPLEXITY_METRIC_MANAGER.ActiveComplexityMetricInfo->AddLayer(NewLayer);
Expand Down Expand Up @@ -614,4 +669,14 @@ bool RugosityLayerProducer::GetIsUsingUniqueProjectedArea()
void RugosityLayerProducer::SetIsUsingUniqueProjectedArea(bool NewValue)
{
bUniqueProjectedArea = NewValue;
}

bool RugosityLayerProducer::GetIsUsingUniqueProjectedAreaApproximation()
{
return bUniqueProjectedAreaApproximation;
}

void RugosityLayerProducer::SetIsUsingUniqueProjectedAreaApproximation(bool NewValue)
{
bUniqueProjectedAreaApproximation = NewValue;
}
Loading

0 comments on commit 6a43f46

Please sign in to comment.