Commit ffe1a443 authored by Armin Erraji's avatar Armin Erraji

Added filtering option for neighbored edges and an intersection test in combined model

parent e45ac569
......@@ -18,7 +18,7 @@ namespace ITAPropagationPathSim
namespace Diffraction
{
bool ITA_PROPAGATION_PATH_SIM_API ConstructAperturePoints(shared_ptr<const CEmitter> pEmitter, shared_ptr<const CSensor> pSensor, vector<CPropagationShapeShared>& pPropagationLists);
bool ITA_PROPAGATION_PATH_SIM_API ConstructAperturePoints(shared_ptr<const CEmitter> pEmitter, shared_ptr<const CSensor> pSensor, const vector<CPropagationShapeShared> pPropagationListsIn, vector<CPropagationShapeShared>& pPropagationListsOut);
}
}
......
......@@ -22,7 +22,7 @@ namespace ITAPropagationPathSim
ITA_PROPAGATION_PATH_SIM_API bool ConstructImageSources(shared_ptr<const CEmitter> pEmitter, vector<CPropagationShapeShared>& vpPropagationTree);
ITA_PROPAGATION_PATH_SIM_API bool ConstructImageReceivers(shared_ptr<const CSensor> pSensor, vector<CPropagationShapeShared>& vpPropagationLists, CShapesMap vpVisibilityMap, const int iMaxReflectionOrder);
ITA_PROPAGATION_PATH_SIM_API bool ConstructImageApertures(vector<CPropagationShapeShared>& vpPropagationLists);
ITA_PROPAGATION_PATH_SIM_API bool ConstructImageApertures(const vector<CPropagationShapeShared> vpPropagationListsIn, vector<CPropagationShapeShared>& vpPropagationListsOut);
......
......@@ -8,6 +8,8 @@
#include <ITAGeo/Halfedge/MeshModel.h>
#include <ITAGeo/Utils.h>
namespace ITAPropagationPathSim
{
namespace CombinedModel
......@@ -35,6 +37,7 @@ namespace ITAPropagationPathSim
void ConstructPropagationPaths(CPropagationPathList& oPaths);
private:
vector<CPropagationShapeShared> m_vpPropagationShapes; //!< Vector of all propagation shapes
......@@ -77,6 +80,10 @@ namespace ITAPropagationPathSim
void CreatePropagationLists();
void RecursiveAddShapesToPropagationLists(shared_ptr<CPropagationShape>& pPropagationShapeIn);
//Filter not visible, intersected, paths
void FilterVisiblePaths(const vector<CPropagationShapeShared> vpAllPathsIn, vector<CPropagationShapeShared>& vpVisiblePathsOut);
//Convert the propagation list
void ConvertShapeListsToPropagationPaths(ITAGeo::CPropagationPathList& oPathsOut);
......
......@@ -3,28 +3,32 @@
using namespace std;
using namespace ITAGeo;
bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(shared_ptr<const CEmitter> pEmitter, shared_ptr<const CSensor> pSensor, vector<CPropagationShapeShared>& pPropagationLists)
bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(shared_ptr<const CEmitter> pEmitter, shared_ptr<const CSensor> pSensor, const vector<CPropagationShapeShared> pPropagationListsIn, vector<CPropagationShapeShared>& pPropagationListsOut)
{
for (auto& pPropagationStartPoint : pPropagationLists)
pPropagationListsOut.clear();
for (auto& pPropagationStartPoint : pPropagationListsIn)
{
if (pPropagationStartPoint == nullptr)
continue;
//Boolean for valid apex points
bool bValidAperturePoints = true;
//The diffraction points are calculated by solving a inhomogeneous coordinate system.
//
//The diffraction points are calculated by solving a inhomogeneous coordinate system.
//E_in and E_out are direction vectors of the edges.
//Because of possibly occuring reflections during the paths, E_in can contain mirrored versions of the direction edge directions.
//VertexDiff contains the vista vectors of the difference between the FromVertices of two edges
vector<shared_ptr<VistaVector3D>> vpE_in, vpE_out, vpVertexDiff;
vector<shared_ptr<VistaVector3D>> vpE_in, vpE_out;
vector<unique_ptr<VistaVector3D>> vpVertexDiff;
//RelativeApexPosition contains the aperture position relative to the edge from- and to-vertices.
//vfE_square contains the squared length of the edge
vector<float> vfRelativeApexPosition, vfE_square;
//The propagation paths always starts at the location of the emitter
//The propagation paths always starts at the position of the emitter
shared_ptr<VistaVector3D> v3LastFromVertex = make_shared<VistaVector3D>(pEmitter->v3InteractionPoint);
//The propagation paths always ends at the location of the sensor
......@@ -50,13 +54,13 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
{
pEdge = static_pointer_cast<CPropagationEdge>(pShape);
//The start value for the aperture position is on the mid of the edge
//The start value for the aperture position is located on the mid of the edge
vfRelativeApexPosition.push_back(0.5);
//The edge direction for the outgoing part is the difference of the end points of the edge
vpE_out.push_back(make_shared<VistaVector3D>(*pEdge->v3ToVertex - *pEdge->v3FromVertex));
//Get the squared length
//Get the squared length. The length of an edge is always the same whether it was mirrored or not
vfE_square.push_back(vpE_out.back()->GetLengthSquared());
//The first shape has no parent. If the parent is a face, the edge must be mirrored(already done in a previous step)
......@@ -64,14 +68,14 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
{
vpE_in.push_back(make_shared<VistaVector3D>(*pEdge->v3ToVertexMirrored - *pEdge->v3FromVertexMirrored));
vpVertexDiff.push_back(make_shared<VistaVector3D>(*v3LastFromVertex - *pEdge->v3FromVertexMirrored));
vpVertexDiff.push_back(make_unique<VistaVector3D>(*v3LastFromVertex - *pEdge->v3FromVertexMirrored));
}
else
{
//The input edge direction does not have to be mirrored and is therefore the same direction as the output edge direction
vpE_in.push_back(vpE_out.back());
vpVertexDiff.push_back(make_shared<VistaVector3D>(*v3LastFromVertex - *pEdge->v3FromVertex));
vpVertexDiff.push_back(make_unique<VistaVector3D>(*v3LastFromVertex - *pEdge->v3FromVertex));
}
......@@ -99,19 +103,25 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
}
else //If the (imaged) sensor is not visible, the whole path is invalid
{
pPropagationStartPoint = nullptr;
bValidAperturePoints = false;
break;
}
}
//In the last step, the path candidate could be declared as invalid.
//If it is invalid, go to the next path candidate
//Also go to the next path candidate, if no edge was found
if (pPropagationStartPoint == nullptr || pEdge == nullptr)
if (bValidAperturePoints == false)
continue;
//Add path candidate to list and go to the next path candidate, if no edge was found
if (pEdge == nullptr)
{
pPropagationListsOut.push_back(pPropagationStartPoint);
continue;
}
//Add the (maybe imaged) receiver to the differences vector
vpVertexDiff.push_back(make_shared<VistaVector3D>(*v3LastFromVertex - v3SensorPosition));
vpVertexDiff.push_back(make_unique<VistaVector3D>(*v3LastFromVertex - v3SensorPosition));
//Iterative a given number of times to get the exact position of the diffraction apertures
const size_t iNumIterations = 5;
......@@ -196,16 +206,15 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
//If one apex point does not lie on the edge, the whole path is invalid
if (fRelApexPos > 1 || fRelApexPos < 0)
{
pPropagationStartPoint = nullptr;
bValidAperturePoints = false;
break;
}
}
//Set the aperture points of the propagation candidate starting with the last edge
while (pPropagationStartPoint != nullptr && pEdge != nullptr)
while (bValidAperturePoints != false && pEdge != nullptr)
{
//Set the interaction point to the aperture point location
//v3InteractionPoint = from_vertex + vfRelativeApexPosition * (to_vertex - from_vertex)
VistaVector3D v3InteractionPoint = (1 - vfRelativeApexPosition.back()) * (*pEdge->v3FromVertex) + vfRelativeApexPosition.back()*(*pEdge->v3ToVertex);
......@@ -233,6 +242,12 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
pEdge = static_pointer_cast<CPropagationEdge>(pShape);
}
if (bValidAperturePoints)
{
pPropagationListsOut.push_back(pPropagationStartPoint);
}
}
return true;
......
......@@ -98,10 +98,14 @@ namespace ITAPropagationPathSim
}
bool ConstructImageApertures(vector<CPropagationShapeShared>& vpPropagationLists)
bool ConstructImageApertures(const vector<CPropagationShapeShared> vpPropagationListsIn, vector<CPropagationShapeShared>& vpPropagationListsOut)
{
for (auto& pStartShape : vpPropagationLists)
vpPropagationListsOut.clear();
for (auto& pStartShape : vpPropagationListsIn)
{
bool bValidImageApertures = true;
CPropagationShapeShared pShape = pStartShape;//Start point
while (pShape != nullptr)
{
......@@ -132,10 +136,13 @@ namespace ITAPropagationPathSim
if (!ConstructImageSources(v3SecondarySource, vpFaces))
{
//If no valid image source could be created, ignore the propagation candidate and set its pointer to zero
pStartShape = nullptr;
bValidImageApertures = false;
break; //break the while loop
}
}
if (bValidImageApertures)
vpPropagationListsOut.push_back(pStartShape);
}
return true;
......
......@@ -3,6 +3,10 @@
#include <ITAPropagationPathSim\CombinedModel\DiffractionLocator.h>
#include <ITAPropagationPathSim\CombinedModel\ReflectionLocator.h>
#include <ITAStopWatch.h> //TODO:Delete, just for testing
#include <ITAStringUtils.h>
//Typedefs
typedef OpenMesh::PolyMesh_ArrayKernelT<> CITAMesh;
struct CITAMeshPtr
......@@ -96,6 +100,8 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ApplySensor(shared_ptr<I
void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationPaths(ITAGeo::CPropagationPathList& oPaths)
{
ITAStopWatch sw; sw.start();
int iNullCounter = 0, iReferenceCounter = 0;
for (auto& pPropagationList : m_vpPropagationLists)
{
......@@ -104,10 +110,11 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationPath
else
iReferenceCounter++;
}
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr at start\n";
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr at start. Calculation time for counting: " << timeToString(sw.stop()) <<endl;
sw.start();
//First, construct the aperture points
Diffraction::ConstructAperturePoints(m_pEmitter, m_pSensor, m_vpPropagationLists);
Diffraction::ConstructAperturePoints(m_pEmitter, m_pSensor, m_vpPropagationLists, m_vpPropagationLists);
iNullCounter = 0, iReferenceCounter = 0;
for (auto& pPropagationList : m_vpPropagationLists)
......@@ -117,11 +124,12 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationPath
else
iReferenceCounter++;
}
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after aperture points calculated\n";
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after aperture points calculated. Calculation time: " << timeToString(sw.stop()) << endl;
sw.start();
//Thereafter, with the constructed aperture points, construct the image apertures as secondary image sources
//for the faces after each edge
ImageConstruction::ConstructImageApertures(m_vpPropagationLists);
ImageConstruction::ConstructImageApertures(m_vpPropagationLists, m_vpPropagationLists);
iNullCounter = 0, iReferenceCounter = 0;
for (auto& pPropagationList : m_vpPropagationLists)
......@@ -131,8 +139,9 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationPath
else
iReferenceCounter++;
}
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after image aperture calculated\n";
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after image aperture calculated. Calculation time: " << timeToString(sw.stop()) << endl;
sw.start();
//Construct the intersection points of the reflections
Reflection::ConstructPointsOfReflection(m_vpPropagationLists, m_pSensor);
......@@ -144,12 +153,68 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationPath
else
iReferenceCounter++;
}
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after points of reflection calculated\n";
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after points of reflection calculated. Calculation time: " << timeToString(sw.stop()) << endl;
sw.start();
if (*m_pFilterIntersectedPaths)
{
FilterVisiblePaths(m_vpPropagationLists, m_vpPropagationLists);
cout << "Calculation time filtering visible paths: " << timeToString(sw.stop()) << endl;
}
sw.start();
//Convert pPropagationShapes to pPropagationAnchors
ConvertShapeListsToPropagationPaths(oPaths);
std::cout << "Calculation time converting to CPropagationPathList object : " << timeToString(sw.stop()) << endl;
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::FilterVisiblePaths(const vector<CPropagationShapeShared> vpAllPathsIn, vector<CPropagationShapeShared>& vpVisiblePathsOut)
{
vpVisiblePathsOut.clear();
bool bIsVisible;
for (auto& vpPropagationList : vpAllPathsIn)
{
if (vpPropagationList == nullptr)
continue;
//First, check for intersections between emitter and first aperture/reflection point
if (IsPathVisible(m_pEmitter->v3InteractionPoint, *vpPropagationList->v3InteractionPoint))
{
bIsVisible = true;
auto pShape = vpPropagationList;
while (pShape->pChild != nullptr)
{
if (IsPathVisible(*pShape->v3InteractionPoint, *pShape->pChild->v3InteractionPoint))
{
pShape = pShape->pChild;
}
else
{
bIsVisible = false;
break;//Break the while loop
}
}
//If the path is not already invalid, also check for intersections between sensor and last point
if (bIsVisible)
{
if (IsPathVisible(m_pSensor->v3InteractionPoint, *pShape->v3InteractionPoint))
{
vpVisiblePathsOut.push_back(vpPropagationList);
}
}
}
}
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::ConvertShapeListsToPropagationPaths(ITAGeo::CPropagationPathList& oPathsOut)
{
......@@ -219,7 +284,6 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConvertShapeListsToPropa
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::CreatePropagationTree()
{
//Set initial values for number of diffractions/reflections
......@@ -570,11 +634,31 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CreateVisibilityMap()
{
auto pPropagationEdgeTo = static_pointer_cast<CPropagationEdge>(pPropagationShapeTo);
//If only neighboured edges are allowed, verify neighboorhood
if (*m_pFilterNotNeighbouredEdges)
{
if (pPropagationEdgeTo->sMeshModelName != pPropagationEdgeFrom->sMeshModelName)
{
bCanIlluminate = false;
continue;
}
//If the edges are neighboured, at least one of their faces are equal
if (pPropagationEdgeTo->hMainFace != pPropagationEdgeFrom->hMainFace &&
pPropagationEdgeTo->hMainFace != pPropagationEdgeFrom->hOppositeFace &&
pPropagationEdgeTo->hOppositeFace != pPropagationEdgeFrom->hMainFace &&
pPropagationEdgeTo->hOppositeFace != pPropagationEdgeFrom->hOppositeFace)
{
bCanIlluminate = false;
continue;
}
}
//Start illumination test for both directions
CanEdgeIlluminateEdge(bCanIlluminate, pPropagationEdgeFrom, pPropagationEdgeTo);
if (bCanIlluminate)
CanEdgeIlluminateEdge(bCanIlluminate, pPropagationEdgeFrom, pPropagationEdgeTo,*m_pFilterEdgeToEdgeIntersectedPaths);
CanEdgeIlluminateEdge(bCanIlluminate, pPropagationEdgeFrom, pPropagationEdgeTo, *m_pFilterEdgeToEdgeIntersectedPaths);
}
}
......
......@@ -98,7 +98,7 @@ int main( int iNumInArgs, char* pcInArgs[] )
sw.start();
pPathEngine->ConfigureFilter(bOnlyNeighbouredEdgeDiffraction, bDiffractionOnlyIntoShadowRegion, bFilterNotVisiblePathsBetweenEdges, bFilterNotVisiblePointToEdge, bFilterNotVisiblePointToEdge);
pPathEngine->ConfigureFilter(bOnlyNeighbouredEdgeDiffraction, bDiffractionOnlyIntoShadowRegion, bFilterNotVisiblePathsBetweenEdges, bFilterNotVisiblePointToEdge, bFilterNotVisiblePointToEdge,bFilterNotVisiblePaths);
cout << "Calculation time configuring filter: " << timeToString(sw.stop()) << endl;
sw.start();
......
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