Aufgrund von Umarbeiten des s3 Storage wird es in GitLab, in nächster Zeit, mögliche Performance-Einbußen geben. Näheres dazu unter: https://maintenance.itc.rwth-aachen.de/ticket/status/messages/43/show_ticket/6670

Commit d4710ee0 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen

Merge branch 'ma_2018/erraji' of...

Merge branch 'ma_2018/erraji' of https://git.rwth-aachen.de/ita/ITAPropagationPathSim into ma_2018/erraji
parents 551e238b 78b33e95
......@@ -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( )
......@@ -18,7 +18,12 @@ 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 int iNumberIterations, const vector<CPropagationShapeShared> pPropagationListsIn, vector<CPropagationShapeShared>& pPropagationListsOut);
//!< Exclude propagation paths with an accumulated diffraction angle that is bigger than the angle threshold.
bool ITA_PROPAGATION_PATH_SIM_API AccumulatedAngleCulling(const float fAngleThreshold, shared_ptr<const CEmitter> pEmitter, const vector<CPropagationShapeShared> pPropagationTreeIn, vector<CPropagationShapeShared>& pPropagationTreeOut);
bool ITA_PROPAGATION_PATH_SIM_API AccumulatedAngleCulling(const float fAngleThreshold, 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
......@@ -19,7 +21,19 @@ namespace ITAPropagationPathSim
public:
//Constructor
CPathEngine(shared_ptr<const Halfedge::CMeshModelList> pMeshModelList);
CPathEngine();
void Configure(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 int iNumberIterationApexCalculation = 5,
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);
......@@ -28,6 +42,7 @@ namespace ITAPropagationPathSim
void ConstructPropagationPaths(CPropagationPathList& oPaths);
private:
vector<CPropagationShapeShared> m_vpPropagationShapes; //!< Vector of all propagation shapes
......@@ -40,13 +55,27 @@ 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
//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
unique_ptr <const size_t> m_pNumberIterationApexCalc; //!< Number of iterations for the calculation of the aperture points
void CreateVisibilityMap();
bool CanPointIlluminateFace(const VistaVector3D & v3Point, const string & sMeshModelName, CITAMesh::FaceHandle hFace);
bool CanPointIlluminateEdge(const VistaVector3D & v3Point, CPropagationEdgeShared & pPropagationEdge, const bool& bTestIntersection = false);
bool IsPathVisible(const VistaVector3D & v3StartPoint, const VistaVector3D & v3EndPoint);
void CanEdgeIlluminateFace(bool & bCanEdgeIlluminateFaceOut, ITAPropagationPathSim::CombinedModel::CPropagationFaceShared & pPropagationFace, ITAPropagationPathSim::CombinedModel::CPropagationEdgeShared & pPropagationEdge);
void CanFaceIlluminateEdge(bool & bCanFaceIlluminateEdgeOut, CPropagationFaceShared & pPropagationFace, CPropagationEdgeShared & pPropagationEdge);
void CanFaceIlluminateFace(bool & bCanFaceIlluminateFaceOut, CPropagationFaceShared & pPropagationFaceStart, CPropagationFaceShared & pPropagationFaceEnd);
void CanEdgeIlluminateEdge(bool & bCanEdgeIlluminateEdgeOut, CPropagationEdgeShared & pPropagationEdgeStart, CPropagationEdgeShared & pPropagationEdgeEnd);
void CanEdgeIlluminateEdge(bool & bCanEdgeIlluminateEdgeOut, CPropagationEdgeShared & pPropagationEdgeStart, CPropagationEdgeShared & pPropagationEdgeEnd, const bool& bTestIntersection = false);
void ConstructPropagationShapes();
//Create the propagation tree
......@@ -57,6 +86,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);
......
......@@ -30,11 +30,11 @@ namespace ITAPropagationPathSim
typedef string MeshModelHandle;
typedef pair < MeshModelHandle, CITAMesh::FaceHandle> PropagationFaceHandle;
struct ImageReceiverMap : map<PropagationFaceHandle, shared_ptr<ImageReceiverMap>>
{
//struct ImageReceiverMap : map<PropagationFaceHandle, shared_ptr<ImageReceiverMap>>
/* {
shared_ptr<VistaVector3D> v3ImageReceiver;
shared_ptr<bool> pHasIlluminableImageReceiver;
};
};*/
enum Tristate : uint8_t
{
......@@ -66,7 +66,7 @@ namespace ITAPropagationPathSim
unique_ptr<VistaVector3D> v3InteractionPoint;
//!< Parent shape(previous shape)
CPropagationShapeShared pParent;
weak_ptr<CPropagationShape> pParent;
//!< Child(ren) shape(s)
CPropagationShapeShared pChild; //Shape used in propagation paths
......@@ -93,7 +93,9 @@ namespace ITAPropagationPathSim
vector<shared_ptr<VistaVector3D>> vv3Vertices;
shared_ptr<VistaVector3D> v3ImageSource;
shared_ptr<VistaVector3D> v3ImageReceiver;
shared_ptr<VistaVector3D> v3ImageEdgeSourceStart;
shared_ptr<VistaVector3D> v3ImageEdgeSourceEnd;
shared_ptr<bool> pHasValidImageSource;
......@@ -114,13 +116,13 @@ namespace ITAPropagationPathSim
shared_ptr<bool> pHasValidImageEdge;
shared_ptr<VistaVector3D> v3FromVertex;//!< Start vertex of corresponding halfedge
shared_ptr<VistaVector3D> v3ToVertex;//!< End vertex of corresponding halfedge
shared_ptr<VistaVector3D> v3StartVertex;//!< Start vertex of corresponding halfedge
shared_ptr<VistaVector3D> v3EndVertex;//!< End vertex of corresponding halfedge
shared_ptr<VistaVector3D> v3MainFaceNormal;//!< Face normal of main face
shared_ptr<VistaVector3D> v3OppositeFaceNormal;//!< Face normal of opposing face
shared_ptr<VistaVector3D> v3FromVertexMirrored;
shared_ptr<VistaVector3D> v3ToVertexMirrored;
shared_ptr<VistaVector3D> v3ImageEdgeReceiverStart; //!< Start vertex of corresponding mirrored halfedge
shared_ptr<VistaVector3D> v3ImageEdgeReceiverEnd;//!< End vertex of corresponding mirrored halfedge
//!< Position of interaction point relative to the ray starting at v3FromVertex and showing in direction of (v3ToVertex - v3FromVertex)
......
......@@ -19,7 +19,7 @@ namespace ITAPropagationPathSim
namespace Reflection
{
ITA_PROPAGATION_PATH_SIM_API bool ConstructPointsOfReflection(vector<CPropagationShapeShared>& pPropagationLists, shared_ptr<const ITAGeo::CSensor> pSensor);
ITA_PROPAGATION_PATH_SIM_API bool ConstructPointsOfReflection(shared_ptr<const ITAGeo::CSensor> pSensor, const vector<CPropagationShapeShared> pPropagationListsIn, vector<CPropagationShapeShared>& pPropagationListsOut);
}
}
}
......
......@@ -12,7 +12,7 @@ namespace ITAPropagationPathSim
//Recursive construct of image sources (only visible locally)
bool RecursiveConstructImageSources(CPropagationFaceShared pPropagationFace)
{
auto v3ParentImageSource = static_pointer_cast<CPropagationFace>(pPropagationFace->pParent)->v3ImageSource;
auto v3ParentImageSource = static_pointer_cast<CPropagationFace>(pPropagationFace->pParent.lock())->v3ImageSource;
//If the previous image source lies beyond the plane, a valid path can not be built
if (!ITAGeoUtils::IsPointInFrontOfPlane(*pPropagationFace->pPlane, *v3ParentImageSource))
......@@ -97,139 +97,15 @@ namespace ITAPropagationPathSim
return true;
}
void RecursivePrepareImageReceivers(ITAPropagationPathSim::CombinedModel::CShapesMap &vpVisibilityMap, CPropagationShapeShared &vpShapeParent, std::shared_ptr<ImageReceiverMap> &pParentImageReceiverMap, int iOrder, int iMaxOrder)
{
auto vpShapeChildren = vpVisibilityMap[vpShapeParent];
for (auto& pShapeChild : vpShapeChildren)
{
if (pShapeChild->iShapeType == CPropagationShape::FACE)
{
auto pFaceChild = static_pointer_cast<CPropagationFace>(pShapeChild);
PropagationFaceHandle hPropagationFace = make_pair(*pFaceChild->sMeshModelName, pFaceChild->hFace);
(*pParentImageReceiverMap)[hPropagationFace] = make_shared<ImageReceiverMap>();
pParentImageReceiverMap->at(hPropagationFace)->v3ImageReceiver = make_shared<VistaVector3D>();
if (ITAGeoUtils::IsPointInFrontOfPlane(*pFaceChild->pPlane, *pParentImageReceiverMap->v3ImageReceiver))
{
pParentImageReceiverMap->at(hPropagationFace)->pHasIlluminableImageReceiver = make_shared<bool>(true);
ITAGeoUtils::MirrorPointOverPlane(*pParentImageReceiverMap->v3ImageReceiver, *pFaceChild->pPlane, *pParentImageReceiverMap->at(hPropagationFace)->v3ImageReceiver);
if(iOrder < iMaxOrder)
RecursivePrepareImageReceivers(vpVisibilityMap, pShapeChild, pParentImageReceiverMap->at(hPropagationFace), iOrder + 1, iMaxOrder);
}
else
{
pParentImageReceiverMap->at(hPropagationFace)->pHasIlluminableImageReceiver = make_shared<bool>(false);
}
}
}
}
shared_ptr<ImageReceiverMap> PrepareImageReceivers(shared_ptr<const ITAGeo::CSensor> pSensor, CShapesMap vpVisibilityMap, const int iMaximumOrder)
{
shared_ptr<ImageReceiverMap> pImageReceiverMap = make_shared<ImageReceiverMap>();
if (iMaximumOrder == 0)
return nullptr;
//TODO: change to: for (auto&& [pShape,pShapeChildren] : vpVisibilityMap) when c++17 applied
for (auto& pShapeKey : vpVisibilityMap)
{
if (pShapeKey.first->iShapeType == CPropagationShape::FACE)
{
auto pFace = static_pointer_cast<CPropagationFace>(pShapeKey.first);
PropagationFaceHandle hPropagationFace = make_pair(*pFace->sMeshModelName, pFace->hFace);
(*pImageReceiverMap)[hPropagationFace] = make_shared<ImageReceiverMap>();
pImageReceiverMap->at(hPropagationFace)->v3ImageReceiver = make_shared<VistaVector3D>();
if (ITAGeoUtils::IsPointInFrontOfPlane(*pFace->pPlane, pSensor->v3InteractionPoint))
{
pImageReceiverMap->at(hPropagationFace)->pHasIlluminableImageReceiver = make_shared<bool>(true);
ITAGeoUtils::MirrorPointOverPlane(pSensor->v3InteractionPoint, *pFace->pPlane, *pImageReceiverMap->at(hPropagationFace)->v3ImageReceiver);
auto vpShapeParent = pShapeKey.first;
auto pParentImageReceiverMap = pImageReceiverMap->at(hPropagationFace);
if(iMaximumOrder > 1)
RecursivePrepareImageReceivers(vpVisibilityMap, vpShapeParent, pParentImageReceiverMap, 2, iMaximumOrder);
}
else
{
pImageReceiverMap->at(hPropagationFace)->pHasIlluminableImageReceiver = make_shared<bool>(false);
}
}
}
return pImageReceiverMap;
}
bool ConstructImageReceivers(shared_ptr<const ITAGeo::CSensor> pSensor, vector<CPropagationShapeShared>& vpPropagationLists, CShapesMap vpVisibilityMap, const int iMaxReflectionOrder)
bool ConstructImageApertures(const vector<CPropagationShapeShared> vpPropagationListsIn, vector<CPropagationShapeShared>& vpPropagationListsOut)
{
//Prepare the image receiver map (TODO: Move to propagation engine)
shared_ptr<ImageReceiverMap> pImageReceiverMap = PrepareImageReceivers(pSensor, vpVisibilityMap, iMaxReflectionOrder);
vpPropagationListsOut.clear();
//Set the image receivers
for(int iteration = (int) vpPropagationLists.size()-1; iteration>=0; iteration--)
for (auto& pStartShape : vpPropagationListsIn)
{
auto pShape = vpPropagationLists[iteration];
//Only set image receivers, if at least one edge occurs
bool bEdgeOccurs = false;
//First, go to the last element
while (pShape->pChild != nullptr)
{
bEdgeOccurs |= pShape->iShapeType == CPropagationShape::EDGE;
pShape = pShape->pChild;
}
//Ignore current list if zero edges occured
if (!bEdgeOccurs)
continue;
//Thereafter set image receivers backwards until a non face shape appears
CPropagationFaceShared pFace;
auto pCurrentImageReceiverMap = pImageReceiverMap;
while (pShape->iShapeType == CPropagationShape::FACE)
{
pFace = static_pointer_cast<CPropagationFace>(pShape);
pCurrentImageReceiverMap = pCurrentImageReceiverMap->at(make_pair(*pFace->sMeshModelName, pFace->hFace));
//delete current list from propagation lists if image receiver is not valid
if (!*pCurrentImageReceiverMap->pHasIlluminableImageReceiver)
{
//vpPropagationLists.erase(vpPropagationLists.begin()+iteration);
vpPropagationLists[iteration] = nullptr;
break;
}
else
{
pFace->v3ImageReceiver = pCurrentImageReceiverMap->v3ImageReceiver;
pShape = pShape->pParent;
}
}
}
return true;
}
bool ConstructImageApertures(vector<CPropagationShapeShared>& vpPropagationLists)
{
for (auto& pStartShape : vpPropagationLists)
{
bool bValidImageApertures = true;
CPropagationShapeShared pShape = pStartShape;//Start point
while (pShape != nullptr)
{
......@@ -260,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;
......@@ -275,21 +154,21 @@ namespace ITAPropagationPathSim
bool RecursiveConstructImageEdge(shared_ptr<const CPropagationFace> pParentFace, shared_ptr<CPropagationEdge>& pPropagationEdge)
{
//Only one image must be in front of plane
bool bValidImageEdge = ITAGeoUtils::IsPointInFrontOfPlane(*pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
bValidImageEdge |= ITAGeoUtils::IsPointInFrontOfPlane(*pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
bool bValidImageEdge = ITAGeoUtils::IsPointInFrontOfPlane(*pParentFace->pPlane, *pPropagationEdge->v3ImageEdgeReceiverStart);
bValidImageEdge |= ITAGeoUtils::IsPointInFrontOfPlane(*pParentFace->pPlane, *pPropagationEdge->v3ImageEdgeReceiverStart);
//If both images are not valid the whole image edge is invalid
if (!bValidImageEdge)
return false;
ITAGeoUtils::MirrorPointOverPlane(*(pPropagationEdge->v3FromVertexMirrored.get()), *(pParentFace->pPlane.get()), *(pPropagationEdge->v3FromVertexMirrored.get()));
ITAGeoUtils::MirrorPointOverPlane(*(pPropagationEdge->v3ToVertexMirrored.get()), *(pParentFace->pPlane.get()), *(pPropagationEdge->v3ToVertexMirrored.get()));
ITAGeoUtils::MirrorPointOverPlane(*(pPropagationEdge->v3ImageEdgeReceiverStart.get()), *(pParentFace->pPlane.get()), *(pPropagationEdge->v3ImageEdgeReceiverStart.get()));
ITAGeoUtils::MirrorPointOverPlane(*(pPropagationEdge->v3ImageEdgeReceiverEnd.get()), *(pParentFace->pPlane.get()), *(pPropagationEdge->v3ImageEdgeReceiverEnd.get()));
//Recursive construction until no further faces are found
if (pParentFace->pParent != nullptr && pParentFace->pParent->iShapeType == CPropagationShape::FACE)
if (!pParentFace->pParent.expired() && pParentFace->pParent.lock()->iShapeType == CPropagationShape::FACE)
{
auto pGrandParentFace = static_pointer_cast<CPropagationFace>(pPropagationEdge->pParent);
auto pGrandParentFace = static_pointer_cast<CPropagationFace>(pPropagationEdge->pParent.lock());
bValidImageEdge = RecursiveConstructImageEdge(pGrandParentFace, pPropagationEdge);
}
......@@ -301,25 +180,27 @@ namespace ITAPropagationPathSim
if( pPropagationShape == nullptr )
return false;
//if the type is face, just go one level deeper
//Create image edge receiver in case of an edge and image edge source of an face followed by at least one edge
//Due to the structure of the propagation tree, image edge sources of each mirrored edge is saved in the corresponding following
//propagation faces and the image edge receiver are saved in the corresponding edge followed up by a number of faces
if (pPropagationShape->iShapeType == CPropagationShape::EDGE)
{
auto pPropagationEdge = static_pointer_cast<CPropagationEdge>(pPropagationShape);
//Create image vertices only for edges with faces as parents
if (pPropagationEdge->pParent != nullptr && pPropagationEdge->pParent->iShapeType == CPropagationShape::FACE)
if (!pPropagationEdge->pParent.expired() && pPropagationEdge->pParent.lock()->iShapeType == CPropagationShape::FACE)
{
pPropagationEdge->v3FromVertexMirrored = make_shared<VistaVector3D>(*pPropagationEdge->v3FromVertex);
pPropagationEdge->v3ToVertexMirrored = make_shared<VistaVector3D>(*pPropagationEdge->v3ToVertex);
pPropagationEdge->v3ImageEdgeReceiverStart = make_shared<VistaVector3D>(*pPropagationEdge->v3StartVertex);
pPropagationEdge->v3ImageEdgeReceiverEnd = make_shared<VistaVector3D>(*pPropagationEdge->v3EndVertex);
pPropagationEdge->pHasValidImageEdge = make_shared<bool>(true);
auto pParentFace = static_pointer_cast<CPropagationFace>(pPropagationEdge->pParent);
auto pParentFace = static_pointer_cast<CPropagationFace>(pPropagationEdge->pParent.lock());
while (true)
{
//Only one image must be in front of plane
bool bValidImageEdge = ITAGeoUtils::IsPointInFrontOfPlane(*pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
bValidImageEdge |= ITAGeoUtils::IsPointInFrontOfPlane(*pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
bool bValidImageEdge = ITAGeoUtils::IsPointInFrontOfPlane(*pParentFace->pPlane, *pPropagationEdge->v3ImageEdgeReceiverStart);
bValidImageEdge |= ITAGeoUtils::IsPointInFrontOfPlane(*pParentFace->pPlane, *pPropagationEdge->v3ImageEdgeReceiverEnd);
//If both images are not valid the whole image edge is invalid
if (!bValidImageEdge)
......@@ -329,12 +210,12 @@ namespace ITAPropagationPathSim
break;
}
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3FromVertex, *pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3ToVertex, *pParentFace->pPlane, *pPropagationEdge->v3ToVertexMirrored);
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3StartVertex, *pParentFace->pPlane, *pPropagationEdge->v3ImageEdgeReceiverStart);
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3EndVertex, *pParentFace->pPlane, *pPropagationEdge->v3ImageEdgeReceiverEnd);
if (pParentFace->pParent != nullptr && pParentFace->pParent->iShapeType == CPropagationShape::FACE)
if (!pParentFace->pParent.expired() && pParentFace->pParent.lock()->iShapeType == CPropagationShape::FACE)
{
pParentFace = static_pointer_cast<CPropagationFace>(pParentFace->pParent);
pParentFace = static_pointer_cast<CPropagationFace>(pParentFace->pParent.lock());
}
else
{
......@@ -342,22 +223,54 @@ namespace ITAPropagationPathSim
}
}
//ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3FromVertex, *pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
//ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3ToVertex, *pParentFace->pPlane, *pPropagationEdge->v3ToVertexMirrored);
}
}
else if (pPropagationShape->iShapeType == CPropagationShape::FACE)
{
auto pPropagationFace = static_pointer_cast<CPropagationFace>(pPropagationShape);
//Create image vertices only for edges with faces as parents
if (!pPropagationFace->pParent.expired())
{
if (pPropagationFace->pParent.lock()->iShapeType == CPropagationShape::FACE)
{
auto pParentFace = static_pointer_cast<CPropagationFace>(pPropagationFace->pParent.lock());
if (pParentFace->v3ImageEdgeSourceStart != nullptr)
{
//Only one image must be in front of plane
bool bValidImageEdge = ITAGeoUtils::IsPointInFrontOfPlane(*pPropagationFace->pPlane, *pParentFace->v3ImageEdgeSourceStart);
bValidImageEdge |= ITAGeoUtils::IsPointInFrontOfPlane(*pPropagationFace->pPlane, *pParentFace->v3ImageEdgeSourceEnd);
////First mirroring is valid
//pPropagationEdge->pHasValidImageEdge = make_shared<bool>(true);
//Set image edge source if valid
if (bValidImageEdge)
{
pPropagationFace->v3ImageEdgeSourceStart = make_shared<VistaVector3D>();
pPropagationFace->v3ImageEdgeSourceEnd = make_shared<VistaVector3D>();
ITAGeoUtils::MirrorPointOverPlane(*pParentFace->v3ImageEdgeSourceStart, *pPropagationFace->pPlane, *pPropagationFace->v3ImageEdgeSourceStart);
ITAGeoUtils::MirrorPointOverPlane(*pParentFace->v3ImageEdgeSourceEnd, *pPropagationFace->pPlane, *pPropagationFace->v3ImageEdgeSourceEnd);
////Ff grandparent is also a face, further mirroring of image vertices
//if (pParentFace->pParent != nullptr && pParentFace->pParent->iShapeType == CPropagationShape::FACE)
//{
// pParentFace = static_pointer_cast<CPropagationFace>(pParentFace->pParent);
// *pPropagationEdge->pHasValidImageEdge = RecursiveConstructImageEdge(pParentFace, pPropagationEdge);
//}
}
}
}
else if (pPropagationFace->pParent.lock()->iShapeType == CPropagationShape::EDGE)
{
auto pParentEdge = static_pointer_cast<CPropagationEdge>(pPropagationFace->pParent.lock());
//Calculate image edge source.
//A PointInFrontOfPlane test is not needed, because a backfaceculling with vertices and plane is already done.
pPropagationFace->v3ImageEdgeSourceStart = make_shared<VistaVector3D>();
pPropagationFace->v3ImageEdgeSourceEnd = make_shared<VistaVector3D>();
ITAGeoUtils::MirrorPointOverPlane(*pParentEdge->v3StartVertex, *pPropagationFace->pPlane, *pPropagationFace->v3ImageEdgeSourceStart);
ITAGeoUtils::MirrorPointOverPlane(*pParentEdge->v3EndVertex, *pPropagationFace->pPlane, *pPropagationFace->v3ImageEdgeSourceEnd);
}
}
}
//Go one level deeper
for (auto& pShapeChild : pPropagationShape->vpChildren)
RecursiveConstructImageEdges(pShapeChild);
......
......@@ -24,7 +24,6 @@ void CPropagationFace::CopyFrom(const CPropagationFace & oPropagationFaceIn)
pPlane = oPropagationFaceIn.pPlane;
vv3Vertices = oPropagationFaceIn.vv3Vertices;
v3ImageSource = oPropagationFaceIn.v3ImageSource;
v3ImageReceiver = oPropagationFaceIn.v3ImageReceiver;
pHasValidImageSource = oPropagationFaceIn.pHasValidImageSource;
}
......@@ -37,11 +36,11 @@ void CPropagationEdge::CopyFrom(const CPropagationEdge & oPropagationEdgeIn)
hEdge = oPropagationEdgeIn.hEdge;
hMainFace = oPropagationEdgeIn.hMainFace;
hOppositeFace = oPropagationEdgeIn.hOppositeFace;
v3FromVertex = oPropagationEdgeIn.v3FromVertex;
v3ToVertex = oPropagationEdgeIn.v3ToVertex;
v3StartVertex = oPropagationEdgeIn.v3StartVertex;
v3EndVertex = oPropagationEdgeIn.v3EndVertex;
v3MainFaceNormal = oPropagationEdgeIn.v3MainFaceNormal;
v3OppositeFaceNormal = oPropagationEdgeIn.v3OppositeFaceNormal;
v3FromVertexMirrored = oPropagationEdgeIn.v3FromVertexMirrored;
v3ToVertexMirrored = oPropagationEdgeIn.v3ToVertexMirrored;
v3ImageEdgeReceiverStart = oPropagationEdgeIn.v3ImageEdgeReceiverStart;
v3ImageEdgeReceiverEnd = oPropagationEdgeIn.v3ImageEdgeReceiverEnd;
pHasValidImageEdge = oPropagationEdgeIn.pHasValidImageEdge;
}
#include <ITAPropagationPathSim\CombinedModel\ReflectionLocator.h>
bool ITAPropagationPathSim::CombinedModel::Reflection::ConstructPointsOfReflection(vector<CPropagationShapeShared>& pPropagationLists, shared_ptr<const ITAGeo::CSensor> pSensor)
bool ITAPropagationPathSim::CombinedModel::Reflection::ConstructPointsOfReflection(shared_ptr<const ITAGeo::CSensor> pSensor, const vector<CPropagationShapeShared> pPropagationListsIn, vector<CPropagationShapeShared>& pPropagationListsOut)
{
for (auto& pStartShape : pPropagationLists)
pPropagationListsOut.clear();
for (auto& pStartShape : pPropagationListsIn)
{
//Empty lists are ignored
if (pStartShape == nullptr)
continue;
bool bValidReflectionPoints = true;
//First, go to the last shape
CPropagationShapeShared pShape = pStartShape;
while (pShape->pChild != nullptr)
......@@ -29,7 +34,7 @@ bool ITAPropagationPathSim::CombinedModel::Reflection::ConstructPointsOfReflecti
//If the face doesn't contain a valid face, the whole path will be invalid
if (*pFace->pHasValidImageSource == false)
{
pStartShape = nullptr;
bValidReflectionPoints = false;
break;
}
......@@ -44,16 +49,16 @@ bool ITAPropagationPathSim::CombinedModel::Reflection::ConstructPointsOfReflecti
pFace->v3InteractionPoint = make_unique<VistaVector3D>(v3LastInteraction);
}
else //invalid path because the current interaction point does not lie on the face
else //Invalid path because the current interaction point does not lie on the face
{
pStartShape = nullptr;
bValidReflectionPoints = false;
break;
}
}
else //invalid path because the last intersection is not in front of face
else //Invalid path because the last intersection is not in front of face
{
pStartShape = nullptr;
bValidReflectionPoints = false;
break;
}
......@@ -63,9 +68,12 @@ bool ITAPropagationPathSim::CombinedModel::Reflection::ConstructPointsOfReflecti
v3LastInteraction = *pShape->v3InteractionPoint;
}
pShape = pShape->pParent;
pShape = pShape->pParent.lock();
}
//If no invalid point occurs, add shapes to output list
if (bValidReflectionPoints)
pPropagationListsOut.push_back(pStartShape);