Commit d442e10b authored by Armin Erraji's avatar Armin Erraji

Removed CreateImageReceiver() and added filter for edges and faces. If the...

Removed CreateImageReceiver() and added filter for edges and faces. If the main face or the opposite face is the same face as the face, where the reflection occurs, the combination wont lead to valid paths.
parent fabb0f5c
......@@ -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
{
......@@ -93,7 +93,7 @@ namespace ITAPropagationPathSim
vector<shared_ptr<VistaVector3D>> vv3Vertices;
shared_ptr<VistaVector3D> v3ImageSource;
shared_ptr<VistaVector3D> v3ImageReceiver;
//shared_ptr<VistaVector3D> v3ImageReceiver;
shared_ptr<bool> pHasValidImageSource;
......
......@@ -10,6 +10,11 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
if (pPropagationStartPoint == nullptr)
continue;
//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
......@@ -116,10 +121,12 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
//Length of direction vector between two adjacent points in the shortest path.
vector<float> vfDirectionVectorLength;
//Get the length of the shortest paths between two adjecent aperture points
//The length is determined by the relative aperture position of the last iteration
//The first direction vector(between the source and the first (imaged) edge) does not contain a correction vector for the source
vfDirectionVectorLength.push_back((*vpVertexDiff[0] - vfRelativeApexPosition[0] * *vpE_in[0]).GetLength());
//Get the length of the shortest paths between two adjecent aperture points
for (int i = 1; i < vfRelativeApexPosition.size(); i++)
{
vfDirectionVectorLength.push_back((*vpVertexDiff[i] - (vfRelativeApexPosition[i] * *vpE_in[i]) + (vfRelativeApexPosition[i-1] * *vpE_out[i-1])).GetLength());
......@@ -128,7 +135,7 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
//The last direction vector(between the last edge and the (imaged) receiver) does not contain a correction vector for the receiver
vfDirectionVectorLength.push_back((*vpVertexDiff.back() - vfRelativeApexPosition.back() * *vpE_out.back()).GetLength());
// The terms can be written in short form to:
// The terms can be written in tridiagonal matrix form as following:
// b[i-1] * vfRelativeApexPosition[i-1] + a[i] * vfRelativeApexPosition[i] + b[i] * vfRelativeApexPosition[i+1] = c[i]
// with b[-1] * vfRelativeApexPosition[-1] = 0 and b[n-1] * vfRelativeApexPosition[n] =0 and with n, the number of diffractions
//┌ ┐ ┌ ┐ ┌ ┐
......@@ -147,11 +154,11 @@ bool ITAPropagationPathSim::CombinedModel::Diffraction::ConstructAperturePoints(
}
for (int i = 0; i < vfE_square.size() - 1; i++)
{
b.push_back(-vpE_out[i]->Dot(*vpE_in[i + 1] / vfDirectionVectorLength[i + 1]));
b.push_back(-vpE_out[i]->Dot(*vpE_in[i + 1]) / vfDirectionVectorLength[i + 1]);
}
//To get vfRelativeApexPosition, the Gaussian-elimination is used to delete
//the term b[i-1] * vfRelativeApexPosition[i-1] in each row, so that
//the term b[i-1] * vfRelativeApexPosition[i-1] in each row, so that
//in the last row, only one variable is left over.
//Thereafter the searched vfRelativeApexPosition can be calculated.
//d[i] replaces a[i] and e[i] replaces c[i]
......
......@@ -97,134 +97,6 @@ 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)
{
//Prepare the image receiver map (TODO: Move to propagation engine)
shared_ptr<ImageReceiverMap> pImageReceiverMap = PrepareImageReceivers(pSensor, vpVisibilityMap, iMaxReflectionOrder);
//Set the image receivers
for(int iteration = (int) vpPropagationLists.size()-1; iteration>=0; iteration--)
{
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)
{
......
......@@ -61,53 +61,59 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ApplySensor(shared_ptr<I
//Create propagation lists with each one containing a possible propagation path candidate
CreatePropagationLists();
//Construct image receivers
ImageConstruction::ConstructImageReceivers(m_pSensor, m_vpPropagationLists, m_mvpShapeVisibilityMap, *m_pMaxReflectionOrder);
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationPaths(ITAGeo::CPropagationPathList& oPaths)
{
int iCounter = 0;
int iNullCounter = 0, iReferenceCounter = 0;
for (auto& pPropagationList : m_vpPropagationLists)
{
if (pPropagationList == nullptr)
iCounter++;
iNullCounter++;
else
iReferenceCounter++;
}
std::cout << iCounter << " times nullptr at start\n";
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr at start\n";
//First, construct the aperture points
Diffraction::ConstructAperturePoints(m_pEmitter, m_pSensor, m_vpPropagationLists);
iCounter = 0;
iNullCounter = 0, iReferenceCounter = 0;
for (auto& pPropagationList : m_vpPropagationLists)
{
if (pPropagationList == nullptr)
iCounter++;
iNullCounter++;
else
iReferenceCounter++;
}
std::cout << iCounter << " times nullptr after aperture points calculated\n";
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after aperture points calculated\n";
//Thereafter, with the constructed aperture points, construct the image apertures as secondary image sources
//for the faces after each edge
ImageConstruction::ConstructImageApertures(m_vpPropagationLists);
iCounter = 0;
iNullCounter = 0, iReferenceCounter = 0;
for (auto& pPropagationList : m_vpPropagationLists)
{
if (pPropagationList == nullptr)
iCounter++;
iNullCounter++;
else
iReferenceCounter++;
}
std::cout << iCounter << " times nullptr after image aperture calculated\n";
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after image aperture calculated\n";
//Construct the intersection points of the reflections
Reflection::ConstructPointsOfReflection(m_vpPropagationLists, m_pSensor);
iCounter = 0;
iNullCounter = 0, iReferenceCounter = 0;
for (auto& pPropagationList : m_vpPropagationLists)
{
if (pPropagationList == nullptr)
iCounter++;
iNullCounter++;
else
iReferenceCounter++;
}
std::cout << iCounter << " times nullptr after points of reflection calculated\n";
std::cout << iReferenceCounter << " references and " << iNullCounter << " times nullptr after points of reflection calculated\n";
//Convert pPropagationShapes to pPropagationAnchors
ConvertShapeListsToPropagationPaths(oPaths);
......@@ -146,9 +152,6 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConvertShapeListsToPropa
shared_ptr<CSpecularReflection> pReflectionAnchor = make_shared<CSpecularReflection>();
pReflectionAnchor->v3InteractionPoint = *pFace->v3InteractionPoint;
float x = (*pFace->v3InteractionPoint)[0];
float y = (*pFace->v3InteractionPoint)[1];
oPath.push_back(pReflectionAnchor);
break;
}
......@@ -486,6 +489,11 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CreateVisibilityMap()
{
auto pPropagationFaceTo = static_pointer_cast<CPropagationFace>(pPropagationShapeTo);
//If the faces are the same, they are not able to create valid paths
if (pPropagationFaceFrom->sMeshModelName == pPropagationFaceTo->sMeshModelName
&& pPropagationFaceFrom->hFace == pPropagationFaceTo->hFace)
continue;
//Start illumination test for both directions
CanFaceIlluminateFace(bCanIlluminate, pPropagationFaceTo, pPropagationFaceFrom);
if (bCanIlluminate)
......@@ -496,6 +504,13 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CreateVisibilityMap()
{
auto pPropagationEdgeTo = static_pointer_cast<CPropagationEdge>(pPropagationShapeTo);
//If the faces are the same, they are not able to create valid paths
if (pPropagationFaceFrom->sMeshModelName == pPropagationEdgeTo->sMeshModelName)
if(pPropagationFaceFrom->hFace == pPropagationEdgeTo->hMainFace
|| pPropagationFaceFrom->hFace == pPropagationEdgeTo->hOppositeFace)
continue;
//Start illumination test for both directions
CanEdgeIlluminateFace(bCanIlluminate, pPropagationFaceFrom, pPropagationEdgeTo);
if (bCanIlluminate)
......@@ -510,6 +525,13 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CreateVisibilityMap()
{
auto pPropagationFaceTo = static_pointer_cast<CPropagationFace>(pPropagationShapeTo);
//If the faces are the same, they are not able to create valid paths
if (pPropagationFaceTo->sMeshModelName == pPropagationEdgeFrom->sMeshModelName)
if (pPropagationFaceTo->hFace == pPropagationEdgeFrom->hMainFace
|| pPropagationFaceTo->hFace == pPropagationEdgeFrom->hOppositeFace)
continue;
//Start illumination test for both directions
CanEdgeIlluminateFace(bCanIlluminate, pPropagationFaceTo, pPropagationEdgeFrom);
if (bCanIlluminate)
......@@ -521,6 +543,7 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CreateVisibilityMap()
{
auto pPropagationEdgeTo = static_pointer_cast<CPropagationEdge>(pPropagationShapeTo);
//Start illumination test for both directions
CanEdgeIlluminateEdge(bCanIlluminate, pPropagationEdgeFrom, pPropagationEdgeTo);
if (bCanIlluminate)
......
......@@ -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;
}
......
......@@ -89,7 +89,7 @@ int main( int iNumInArgs, char* pcInArgs[] )
sw.start();
pPathEngine->ApplyEmitter(pEmitter,ITAGeo::DIFFRACTION_ORDER_2,ORDER_2,ORDER_3);
pPathEngine->ApplyEmitter(pEmitter,ITAGeo::DIFFRACTION_ORDER_3,ORDER_2,ORDER_5);
cout << "Calculation time applying emitter: " << timeToString(sw.stop()) << endl;
sw.start();
......@@ -107,6 +107,10 @@ int main( int iNumInArgs, char* pcInArgs[] )
pMeshModelList->FilterVisiblePaths(oPathListAll, oPathListVisible);
cout << "All paths: " << to_string(oPathListAll.size()) << endl;
cout << "Visible paths: " << to_string(oPathListVisible.size()) << endl;
//Add emitter and sensor to visualization
oGeoModel.AddEmitterVisualization(*pEmitter, "Emitter A");
oGeoModel.AddSensorVisualization(*pSensor, "Sensor A");
......
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