From e45ac569dca7c3553c60d422fc8e4e4a5f45d6c3 Mon Sep 17 00:00:00 2001 From: Armin Erraji Date: Thu, 31 Jan 2019 16:43:15 +0100 Subject: [PATCH] Added filter booleans for the configuration of the propagation path engine. --- CMakeLists.txt | 1 + .../CombinedModel/PropagationEngine.h | 20 ++++++- .../CombinedModel/PropagationEngine.cpp | 58 ++++++++++++++----- tests/CombinedModel/CombinedModelTest.cpp | 29 ++++++++-- 4 files changed, 86 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b500a75..de71fb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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( ) + diff --git a/include/ITAPropagationPathSim/CombinedModel/PropagationEngine.h b/include/ITAPropagationPathSim/CombinedModel/PropagationEngine.h index 98854b9..7dff032 100644 --- a/include/ITAPropagationPathSim/CombinedModel/PropagationEngine.h +++ b/include/ITAPropagationPathSim/CombinedModel/PropagationEngine.h @@ -19,7 +19,14 @@ namespace ITAPropagationPathSim public: //Constructor - CPathEngine(shared_ptr 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 pMeshModelList); void ApplyEmitter(shared_ptr pEmitter, const int iMaxDiffractions, const int iMaxReflections, const int iMaxCombinedOrder); @@ -40,7 +47,16 @@ namespace ITAPropagationPathSim unique_ptr m_pMaxReflectionOrder; //!< Const pointer to maximum reflection order unique_ptr m_pMaxDiffractionOrder; //!< Const pointer to maximum diffraction order unique_ptr m_pMaxCombinedOrder; //!< Const pointer to maximum order of combined diffractions and reflections - unique_ptr 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 m_pFilterNotNeighbouredEdges; //!< Filter not neighboured edges for faster filter calculation + unique_ptr 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 m_pFilterEdgeToEdgeIntersectedPaths; //!< Boolean pointer for filtering paths, where always an intersection between two edges occurs + unique_ptr m_pFilterEmitterToEdgeIntersectedPaths; //!< Boolean pointer for filtering paths, where always an intersection between the emitter and an edge occurs + unique_ptr m_pFilterSensorToEdgeIntersectedPaths; //!< Boolean pointer for filtering paths, where always an intersection between the sensor and an edge occurs + unique_ptr m_pFilterIntersectedPaths; //!< Boolean pointer for for filtering paths if intersection occurs + unique_ptr m_pIntersectionTestResolution; //!< Resolution for intersection test + unique_ptr m_pAccumulatedAngleThreshold; //!< Threshold for the accumulated diffraction angle void CreateVisibilityMap(); diff --git a/src/ITAPropagationPathSim/CombinedModel/PropagationEngine.cpp b/src/ITAPropagationPathSim/CombinedModel/PropagationEngine.cpp index a10f949..0839ce9 100644 --- a/src/ITAPropagationPathSim/CombinedModel/PropagationEngine.cpp +++ b/src/ITAPropagationPathSim/CombinedModel/PropagationEngine.cpp @@ -10,21 +10,51 @@ struct CITAMeshPtr CITAMesh* pMesh; }; -ITAPropagationPathSim::CombinedModel::CPathEngine::CPathEngine(shared_ptr 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(bFilterNotNeighbouredEdges); + m_pFilterIlluminatedRegionDiffraction = make_unique(bFilterIlluminatedRegionDiffraction); + m_pFilterEdgeToEdgeIntersectedPaths = make_unique(bFilterEdgeToEdgeIntersectedPaths); + m_pFilterEmitterToEdgeIntersectedPaths = make_unique(bFilterEmitterToEdgeIntersectedPaths); + m_pFilterSensorToEdgeIntersectedPaths = make_unique(bFilterSensorToEdgeIntersectedPaths); + m_pFilterIntersectedPaths = make_unique(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(fIntersectionTestResolution); + + //Threshold for the accumulated angle (TODO: usage not implemented yet) + //Standard value is -1 (no threshold) + m_pAccumulatedAngleThreshold = make_unique(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 pMeshModelList) { m_pMeshModelList = pMeshModelList; - m_pIgnoreIlluminatedRegionDiffraction = make_unique(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 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(); pEdgeCopy->CopyFrom(*static_pointer_cast(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 diff --git a/tests/CombinedModel/CombinedModelTest.cpp b/tests/CombinedModel/CombinedModelTest.cpp index 22517c5..e53bb6e 100644 --- a/tests/CombinedModel/CombinedModelTest.cpp +++ b/tests/CombinedModel/CombinedModelTest.cpp @@ -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(pMeshModelList, bDiffractionOnlyIntoShadowRegion); + auto pPathEngine = make_shared(); 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; -- GitLab