Commit e45ac569 authored by Armin Erraji's avatar Armin Erraji

Added filter booleans for the configuration of the propagation path engine.

parent 96c64075
......@@ -68,3 +68,4 @@ if( ITA_GEOMETRICAL_ACOUSTICS_WITH_TESTS OR ITA_PROPAGATION_PATH_SIM_WITH_TESTS
set( ITAPropagationPathSim_COMMON_BUILD TRUE )
add_subdirectory( "${CMAKE_CURRENT_SOURCE_DIR}/tests" )
endif( )
......@@ -19,7 +19,14 @@ namespace ITAPropagationPathSim
public:
//Constructor
CPathEngine(shared_ptr<const Halfedge::CMeshModelList> pMeshModelList, bool bIgnoreIlluminatedRegionDiffraction = false);
CPathEngine();
void ConfigureFilter(const bool bFilterNotNeighbouredEdges = false , const bool bFilterIlluminatedRegionDiffraction = false ,
const bool bFilterEdgeToEdgeIntersectedPaths = false, const bool bFilterEmitterToEdgeIntersectedPaths = false,
const bool bFilterSensorToEdgeIntersectedPaths = false, const bool bFilterIntersectedPaths = false,
const float fIntersectionTestResolution = 0.001f, const float fAccumulatedAngleThreshold = -1.0f);
void InitializePathEnvironment(shared_ptr<const Halfedge::CMeshModelList> pMeshModelList);
void ApplyEmitter(shared_ptr<CEmitter> pEmitter, const int iMaxDiffractions, const int iMaxReflections, const int iMaxCombinedOrder);
......@@ -40,7 +47,16 @@ namespace ITAPropagationPathSim
unique_ptr<const int> m_pMaxReflectionOrder; //!< Const pointer to maximum reflection order
unique_ptr<const int> m_pMaxDiffractionOrder; //!< Const pointer to maximum diffraction order
unique_ptr<const int> m_pMaxCombinedOrder; //!< Const pointer to maximum order of combined diffractions and reflections
unique_ptr<const bool> m_pIgnoreIlluminatedRegionDiffraction; //!< Const pointer to bolean whether to ignore diffractions that can only diffract in illuminated regions(and have therefore a low impact to the whole IR)
//Filter member variables
unique_ptr<const bool> m_pFilterNotNeighbouredEdges; //!< Filter not neighboured edges for faster filter calculation
unique_ptr<const bool> m_pFilterIlluminatedRegionDiffraction; //!< Boolean pointer whether to ignore diffractions that can only diffract in illuminated regions(and have therefore a low impact to the whole IR)
unique_ptr<const bool> m_pFilterEdgeToEdgeIntersectedPaths; //!< Boolean pointer for filtering paths, where always an intersection between two edges occurs
unique_ptr<const bool> m_pFilterEmitterToEdgeIntersectedPaths; //!< Boolean pointer for filtering paths, where always an intersection between the emitter and an edge occurs
unique_ptr<const bool> m_pFilterSensorToEdgeIntersectedPaths; //!< Boolean pointer for filtering paths, where always an intersection between the sensor and an edge occurs
unique_ptr<const bool> m_pFilterIntersectedPaths; //!< Boolean pointer for for filtering paths if intersection occurs
unique_ptr<const float> m_pIntersectionTestResolution; //!< Resolution for intersection test
unique_ptr <const float> m_pAccumulatedAngleThreshold; //!< Threshold for the accumulated diffraction angle
void CreateVisibilityMap();
......
......@@ -10,21 +10,51 @@ struct CITAMeshPtr
CITAMesh* pMesh;
};
ITAPropagationPathSim::CombinedModel::CPathEngine::CPathEngine(shared_ptr<const ITAGeo::Halfedge::CMeshModelList> pMeshModelList, bool bIgnoreIlluminatedRegionDiffraction /* =false*/)
ITAPropagationPathSim::CombinedModel::CPathEngine::CPathEngine()
{
//Initialize filter variables with standard values(no filters)
ConfigureFilter();
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::ConfigureFilter(const bool bFilterNotNeighbouredEdges, const bool bFilterIlluminatedRegionDiffraction, const bool bFilterEdgeToEdgeIntersectedPaths,
const bool bFilterEmitterToEdgeIntersectedPaths, const bool bFilterSensorToEdgeIntersectedPaths, const bool bFilterIntersectedPaths,
const float fIntersectionTestResolution, const float fAccumulatedAngleThreshold)
{
//Set filter variables
m_pFilterNotNeighbouredEdges = make_unique<const bool>(bFilterNotNeighbouredEdges);
m_pFilterIlluminatedRegionDiffraction = make_unique<const bool>(bFilterIlluminatedRegionDiffraction);
m_pFilterEdgeToEdgeIntersectedPaths = make_unique<const bool>(bFilterEdgeToEdgeIntersectedPaths);
m_pFilterEmitterToEdgeIntersectedPaths = make_unique<const bool>(bFilterEmitterToEdgeIntersectedPaths);
m_pFilterSensorToEdgeIntersectedPaths = make_unique<const bool>(bFilterSensorToEdgeIntersectedPaths);
m_pFilterIntersectedPaths = make_unique<const bool>(bFilterIntersectedPaths);
//Resolution for the intersection test. A too low resolution can lead to falsely ignored paths and a too high resolution results in a long computation time.
//Initial value is 1 mm
m_pIntersectionTestResolution = make_unique<const float>(fIntersectionTestResolution);
//Threshold for the accumulated angle (TODO: usage not implemented yet)
//Standard value is -1 (no threshold)
m_pAccumulatedAngleThreshold = make_unique<const float>(fAccumulatedAngleThreshold);
//Recreate the visibility map, if m_pMeshModelList already initialized
if (m_pMeshModelList != nullptr)
{
m_mvpShapeVisibilityMap.clear();
CreateVisibilityMap();
}
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::InitializePathEnvironment(shared_ptr<const ITAGeo::Halfedge::CMeshModelList> pMeshModelList)
{
m_pMeshModelList = pMeshModelList;
m_pIgnoreIlluminatedRegionDiffraction = make_unique<bool>(bIgnoreIlluminatedRegionDiffraction);
//Calculate the face normals
for (int i = 0; i < m_pMeshModelList->GetNumMeshes(); i++)
{
// Calculate mesh normals
CITAMesh* pMesh = m_pMeshModelList->at(i)->GetMesh()->pMesh;
pMesh->request_face_normals();
pMesh->update_face_normals();
pMesh->request_halfedge_normals();
pMesh->request_vertex_normals();
}
//Get all propagation shapes of the mesh model list
......@@ -34,7 +64,6 @@ ITAPropagationPathSim::CombinedModel::CPathEngine::CPathEngine(shared_ptr<const
CreateVisibilityMap();
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::ApplyEmitter(shared_ptr<ITAGeo::CEmitter> pEmitter, const int iMaxDiffractions, const int iMaxReflections, const int iMaxCombinedOrder)
{
//Set emitter
......@@ -244,8 +273,7 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CreatePropagationTree()
CPropagationEdgeShared pEdgeCopy = make_shared<CPropagationEdge>();
pEdgeCopy->CopyFrom(*static_pointer_cast<CPropagationEdge>(pPropagationShape));
//TODO: Implement option to choose whether to test intersections or not (last optional boolean value)
bool bCanIlluminated = CanPointIlluminateEdge(m_pEmitter->v3InteractionPoint, pEdgeCopy);
bool bCanIlluminated = CanPointIlluminateEdge(m_pEmitter->v3InteractionPoint, pEdgeCopy,*m_pFilterEmitterToEdgeIntersectedPaths);
if (bCanIlluminated)
{
......@@ -335,8 +363,7 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::RecursiveAddShapesToProp
//If the illuminability is not found out yet, check for illuminability
if (*pPropagationShapeIn->pIsIlluminableBySensor == Tristate::Undefined)
{
//TODO: Implement option to choose whether to test intersections or not (last optional boolean value)
if(CanPointIlluminateEdge(m_pSensor->v3InteractionPoint,pEdge))
if(CanPointIlluminateEdge(m_pSensor->v3InteractionPoint,pEdge,*m_pFilterSensorToEdgeIntersectedPaths))
{
*pPropagationShapeIn->pIsIlluminableBySensor = Tristate::True;
}
......@@ -547,8 +574,7 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CreateVisibilityMap()
//Start illumination test for both directions
CanEdgeIlluminateEdge(bCanIlluminate, pPropagationEdgeFrom, pPropagationEdgeTo);
if (bCanIlluminate)
//TODO: Implement option to choose whether to test intersections or not (last optional boolean value)
CanEdgeIlluminateEdge(bCanIlluminate, pPropagationEdgeFrom, pPropagationEdgeTo);
CanEdgeIlluminateEdge(bCanIlluminate, pPropagationEdgeFrom, pPropagationEdgeTo,*m_pFilterEdgeToEdgeIntersectedPaths);
}
}
......@@ -645,7 +671,7 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CanFaceIlluminateEdge(bo
bMainFaceIlluminated = ITAGeoUtils::CanFaceBeIlluminated(*pEdgeMesh, pPropagationEdge->hMainFace, *pVertex);
bOppositeFaceIlluminated = ITAGeoUtils::CanFaceBeIlluminated(*pEdgeMesh, pPropagationEdge->hOppositeFace, *pVertex);
if (*m_pIgnoreIlluminatedRegionDiffraction)
if (*m_pFilterIlluminatedRegionDiffraction)
bCanFaceIlluminateEdgeOut = bMainFaceIlluminated != bOppositeFaceIlluminated; // A XOR B, only valid, if at least one point can lie in the shadow region
else
bCanFaceIlluminateEdgeOut = bMainFaceIlluminated || bOppositeFaceIlluminated; // A OR B, also valid, if face can only lie in the illuminated region
......@@ -681,7 +707,7 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CanEdgeIlluminateEdge(bo
bMainFaceIlluminated = ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hMainFace, (1 - eps)*(*pPropagationEdgeStart->v3FromVertex) + (eps)*(*pPropagationEdgeStart->v3ToVertex));
bOppositeFaceIlluminated = ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hOppositeFace, (1 - eps)*(*pPropagationEdgeStart->v3FromVertex) + (eps)*(*pPropagationEdgeStart->v3ToVertex));
if (*m_pIgnoreIlluminatedRegionDiffraction)
if (*m_pFilterIlluminatedRegionDiffraction)
bCanEdgeIlluminateEdgeOut = bMainFaceIlluminated != bOppositeFaceIlluminated; // A XOR B, only valid, if at least one point can lie in the shadow region
else
bCanEdgeIlluminateEdgeOut = bMainFaceIlluminated || bOppositeFaceIlluminated; // A OR B, also valid, if face can only lie in the illuminated region
......@@ -693,7 +719,7 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CanEdgeIlluminateEdge(bo
bMainFaceIlluminated = ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hMainFace, (1 - eps)*(*pPropagationEdgeStart->v3ToVertex) + (eps)*(*pPropagationEdgeStart->v3FromVertex));
bOppositeFaceIlluminated = ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hOppositeFace, (1 - eps)*(*pPropagationEdgeStart->v3ToVertex) + (eps)*(*pPropagationEdgeStart->v3FromVertex));
if (*m_pIgnoreIlluminatedRegionDiffraction)
if (*m_pFilterIlluminatedRegionDiffraction)
bCanEdgeIlluminateEdgeOut = bMainFaceIlluminated != bOppositeFaceIlluminated; // A XOR B, only valid, if at least one point can lie in the shadow region
else
bCanEdgeIlluminateEdgeOut = bMainFaceIlluminated || bOppositeFaceIlluminated; // A OR B, also valid, if face can only lie in the illuminated region
......
......@@ -80,16 +80,35 @@ int main( int iNumInArgs, char* pcInArgs[] )
cout << "Emitter: " << pEmitter->vPos << endl;
cout << "Sensor: " << pSensor->vPos << endl;
//Configuration of the engine
const bool bOnlyNeighbouredEdgeDiffraction = false;
const bool bDiffractionOnlyIntoShadowRegion = true;
const bool bFilterNotVisiblePathsBetweenEdges = false; //Intersection test between edges(expensive)
const bool bFilterNotVisiblePointToEdge = true; //Intersection test between emitter/sensor and edges
const bool bFilterNotVisiblePaths = true; //Intersection test of calculated sub paths
const int iMaxDiffractionOrder = 3;
const int iMaxReflectionOrder = 2;
const int iMaxCombinedOrder = 5;
ITAStopWatch sw; sw.start();
bool bDiffractionOnlyIntoShadowRegion = true;
auto pPathEngine = make_shared<CombinedModel::CPathEngine>(pMeshModelList, bDiffractionOnlyIntoShadowRegion);
auto pPathEngine = make_shared<CombinedModel::CPathEngine>();
cout << "Calculation time initialization path engine: " << timeToString(sw.stop()) << endl;
sw.start();
pPathEngine->ApplyEmitter(pEmitter,ITAGeo::DIFFRACTION_ORDER_3,ORDER_2,ORDER_5);
pPathEngine->ConfigureFilter(bOnlyNeighbouredEdgeDiffraction, bDiffractionOnlyIntoShadowRegion, bFilterNotVisiblePathsBetweenEdges, bFilterNotVisiblePointToEdge, bFilterNotVisiblePointToEdge);
cout << "Calculation time configuring filter: " << timeToString(sw.stop()) << endl;
sw.start();
pPathEngine->InitializePathEnvironment(pMeshModelList);
cout << "Calculation time initialization path environment: " << timeToString(sw.stop()) << endl;
sw.start();
pPathEngine->ApplyEmitter(pEmitter, iMaxDiffractionOrder, iMaxReflectionOrder, iMaxCombinedOrder);
cout << "Calculation time applying emitter: " << timeToString(sw.stop()) << endl;
sw.start();
......@@ -104,8 +123,10 @@ int main( int iNumInArgs, char* pcInArgs[] )
pPathEngine->ConstructPropagationPaths(oPathListAll);
cout << "Calculation time propagation path creation: " << timeToString(sw.stop()) << endl;
sw.start();
pMeshModelList->FilterVisiblePaths(oPathListAll, oPathListVisible);
cout << "Calculation time filtering visible paths: " << timeToString(sw.stop()) << endl;
cout << "All paths: " << to_string(oPathListAll.size()) << endl;
cout << "Visible paths: " << to_string(oPathListVisible.size()) << endl;
......
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