Commit deafc3f5 authored by Armin Erraji's avatar Armin Erraji

Some bugfixes. Replaced RecursiveConstructImageEdge() with a while loop.

parent 38dc2990
......@@ -109,7 +109,7 @@ bool ITAPropagationPathSim::CombinatedModel::Diffraction::ConstructAperturePoint
vpVertexDiff.push_back(make_shared<VistaVector3D>(*v3LastFromVertex - v3SensorPosition));
//Iterative a given number of times to get the exact position of the diffraction apertures
const size_t iNumIterations = 5;
const size_t iNumIterations = 10;
for(size_t iCurrentIteration = 0; iCurrentIteration< iNumIterations; iCurrentIteration++)
{
......@@ -197,9 +197,14 @@ bool ITAPropagationPathSim::CombinatedModel::Diffraction::ConstructAperturePoint
//Set the aperture points of the propagation candidate starting with the last edge
while (pPropagationStartPoint != nullptr && pEdge != nullptr)
{
//Set the interaction point to the aperture point location
//v3InteractionPoint = from_vertex + vfRelativeApexPosition * (to_vertex - from_vertex)
pEdge->v3InteractionPoint = make_unique <VistaVector3D>(*pEdge->v3FromVertex + vfRelativeApexPosition.back()*(*pEdge->v3ToVertex - *pEdge->v3FromVertex));
VistaVector3D v3InteractionPoint = (1 - vfRelativeApexPosition.back()) * (*pEdge->v3FromVertex) + vfRelativeApexPosition.back()*(*pEdge->v3ToVertex);
//Set the interaction point
pEdge->v3InteractionPoint = make_unique <VistaVector3D>(v3InteractionPoint);
//Pop the last element
vfRelativeApexPosition.pop_back();
......
......@@ -29,7 +29,10 @@ namespace ITAPropagationPathSim
{
auto pPropagationFaceChild = static_pointer_cast<CPropagationFace>(pShapeChild);
pPropagationFaceChild->pHasValidImageSource = make_shared<bool>(RecursiveConstructImageSources(pPropagationFaceChild));
if (RecursiveConstructImageSources(pPropagationFaceChild))
pPropagationFaceChild->pHasValidImageSource = make_shared<bool>(true);
else
pShapeChild = nullptr;
}
}
......@@ -38,28 +41,30 @@ namespace ITAPropagationPathSim
bool ConstructImageSources(shared_ptr<const ITAGeo::CEmitter> pEmitter, vector<CPropagationShapeShared>& vpPropagationTree)
{
for (auto& pPropagationShape : vpPropagationTree)
for (auto& pStartShape : vpPropagationTree)
{
if (pPropagationShape->iShapeType == CPropagationShape::FACE)
if (pStartShape->iShapeType == CPropagationShape::FACE)
{
auto pPropagationFace = static_pointer_cast<CPropagationFace>(pPropagationShape);
auto pStartFace = static_pointer_cast<CPropagationFace>(pStartShape);
//Initialize image source and set it
pPropagationFace->v3ImageSource = make_shared<VistaVector3D>();
ITAGeoUtils::MirrorPointOverPlane(pEmitter->v3InteractionPoint, *pPropagationFace->pPlane, *pPropagationFace->v3ImageSource);
pStartFace->v3ImageSource = make_shared<VistaVector3D>();
ITAGeoUtils::MirrorPointOverPlane(pEmitter->v3InteractionPoint, *pStartFace->pPlane, *pStartFace->v3ImageSource);
//First image source is valid
pPropagationFace->pHasValidImageSource = make_shared<bool>(true);
pStartFace->pHasValidImageSource = make_shared<bool>(true);
//Add further images
for (auto& pShapeChild : pPropagationFace->vpChildren)
for (auto& pShapeChild : pStartFace->vpChildren)
{
if (pShapeChild->iShapeType == CPropagationShape::FACE)
{
pPropagationFace = static_pointer_cast<CPropagationFace>(pShapeChild);
pStartFace = static_pointer_cast<CPropagationFace>(pShapeChild);
if (RecursiveConstructImageSources(pStartFace))
pStartFace->pHasValidImageSource = make_shared<bool>(true);
else
pStartShape = nullptr;
pPropagationFace->pHasValidImageSource = make_shared<bool>(RecursiveConstructImageSources(pPropagationFace));
}
}
......@@ -278,8 +283,8 @@ namespace ITAPropagationPathSim
return false;
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3FromVertexMirrored, *pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3ToVertexMirrored, *pParentFace->pPlane, *pPropagationEdge->v3ToVertexMirrored);
ITAGeoUtils::MirrorPointOverPlane(*(pPropagationEdge->v3FromVertexMirrored.get()), *(pParentFace->pPlane.get()), *(pPropagationEdge->v3FromVertexMirrored.get()));
ITAGeoUtils::MirrorPointOverPlane(*(pPropagationEdge->v3ToVertexMirrored.get()), *(pParentFace->pPlane.get()), *(pPropagationEdge->v3ToVertexMirrored.get()));
//Recursive construction until no further faces are found
if (pParentFace->pParent != nullptr && pParentFace->pParent->iShapeType == CPropagationShape::FACE)
......@@ -299,26 +304,54 @@ namespace ITAPropagationPathSim
auto pPropagationEdge = static_pointer_cast<CPropagationEdge>(pPropagationShape);
//Create image vertices only for edges with faces as parents
if (pPropagationEdge->pParent->iShapeType == CPropagationShape::FACE)
if (pPropagationEdge->pParent != nullptr && pPropagationEdge->pParent->iShapeType == CPropagationShape::FACE)
{
auto pParentFace = static_pointer_cast<CPropagationFace>(pPropagationEdge->pParent);
pPropagationEdge->v3FromVertexMirrored = make_shared<VistaVector3D>();
pPropagationEdge->v3ToVertexMirrored = make_shared<VistaVector3D>();
pPropagationEdge->v3FromVertexMirrored = make_shared<VistaVector3D>(*pPropagationEdge->v3FromVertex);
pPropagationEdge->v3ToVertexMirrored = make_shared<VistaVector3D>(*pPropagationEdge->v3ToVertex);
pPropagationEdge->pHasValidImageEdge = make_shared<bool>(true);
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3FromVertex, *pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3ToVertex, *pParentFace->pPlane, *pPropagationEdge->v3ToVertexMirrored);
auto pParentFace = static_pointer_cast<CPropagationFace>(pPropagationEdge->pParent);
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);
//First mirroring is valid
pPropagationEdge->pHasValidImageEdge = make_shared<bool>(true);
//If both images are not valid the whole image edge is invalid
if (!bValidImageEdge)
{
*(pPropagationEdge->pHasValidImageEdge) = false;
break;
}
//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);
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3FromVertex, *pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3ToVertex, *pParentFace->pPlane, *pPropagationEdge->v3ToVertexMirrored);
if (pParentFace->pParent != nullptr && pParentFace->pParent->iShapeType == CPropagationShape::FACE)
{
pParentFace = static_pointer_cast<CPropagationFace>(pParentFace->pParent);
}
else
{
break;
}
}
//ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3FromVertex, *pParentFace->pPlane, *pPropagationEdge->v3FromVertexMirrored);
//ITAGeoUtils::MirrorPointOverPlane(*pPropagationEdge->v3ToVertex, *pParentFace->pPlane, *pPropagationEdge->v3ToVertexMirrored);
////First mirroring is valid
//pPropagationEdge->pHasValidImageEdge = make_shared<bool>(true);
////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);
//}
}
}
......@@ -334,8 +367,10 @@ namespace ITAPropagationPathSim
{
//First element of tree has never an image edge, so only construct them for its children
for (auto& pShape : vpPropagationTree)
for (auto& pShapeChild : pShape->vpChildren)
RecursiveConstructImageEdges(pShapeChild);
if(pShape != nullptr)
for (auto& pShapeChild : pShape->vpChildren)
if(pShapeChild != nullptr)
RecursiveConstructImageEdges(pShapeChild);
return true;
}
......
......@@ -279,6 +279,9 @@ void ITAPropagationPathSim::CombinatedModel::CPathEngine::CreatePropagationLists
void ITAPropagationPathSim::CombinatedModel::CPathEngine::RecursiveAddShapesToPropagationLists(shared_ptr<CPropagationShape>& pPropagationShapeIn)
{
if (pPropagationShapeIn == nullptr)
return;
//In this if case, pPropagationShapeIn is eventually tested for illuminability for the sensor
//and its branches are followed up until the first branch(illuminable by the emitter)
if (*pPropagationShapeIn->pIsIlluminableBySensor != Tristate::False)
......@@ -542,8 +545,10 @@ void ITAPropagationPathSim::CombinatedModel::CPathEngine::CanEdgeIlluminateFace(
{
auto& pFaceMesh = m_pMeshModelList->GetMeshModel(*pPropagationFace->sMeshModelName)->GetMesh()->pMesh;
bCanEdgeIlluminateFaceOut = ITAGeoUtils::CanFaceBeIlluminated(*pFaceMesh, pPropagationFace->hFace, *pPropagationEdge->v3FromVertex);
bCanEdgeIlluminateFaceOut |= ITAGeoUtils::CanFaceBeIlluminated(*pFaceMesh, pPropagationFace->hFace, *pPropagationEdge->v3ToVertex);
float eps = ITAConstants::EPS_F_L;
bCanEdgeIlluminateFaceOut = ITAGeoUtils::CanFaceBeIlluminated(*pFaceMesh, pPropagationFace->hFace, (1 - eps)*(*pPropagationEdge->v3FromVertex) + (eps)*(*pPropagationEdge->v3ToVertex));
bCanEdgeIlluminateFaceOut |= ITAGeoUtils::CanFaceBeIlluminated(*pFaceMesh, pPropagationFace->hFace, (1 - eps)*(*pPropagationEdge->v3ToVertex) + (eps)*(*pPropagationEdge->v3FromVertex));
}
void ITAPropagationPathSim::CombinatedModel::CPathEngine::CanFaceIlluminateEdge(bool &bCanFaceIlluminateEdgeOut, CPropagationFaceShared & pPropagationFace, CPropagationEdgeShared & pPropagationEdge)
......@@ -581,10 +586,12 @@ void ITAPropagationPathSim::CombinatedModel::CPathEngine::CanEdgeIlluminateEdge(
{
auto& pEdgeEndMesh = m_pMeshModelList->GetMeshModel(*pPropagationEdgeEnd->sMeshModelName)->GetMesh()->pMesh;
bCanEdgeIlluminateEdgeOut = ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hMainFace, *pPropagationEdgeStart->v3FromVertex);
bCanEdgeIlluminateEdgeOut |= ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hMainFace, *pPropagationEdgeStart->v3ToVertex);
bCanEdgeIlluminateEdgeOut |= ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hOppositeFace, *pPropagationEdgeStart->v3FromVertex);
bCanEdgeIlluminateEdgeOut |= ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hOppositeFace, *pPropagationEdgeStart->v3ToVertex);
float eps = ITAConstants::EPS_F_L;
bCanEdgeIlluminateEdgeOut = ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hMainFace, (1 - eps)*(*pPropagationEdgeStart->v3FromVertex) + (eps)*(*pPropagationEdgeStart->v3ToVertex));
bCanEdgeIlluminateEdgeOut |= ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hMainFace, (1 - eps)*(*pPropagationEdgeStart->v3ToVertex) + (eps)*(*pPropagationEdgeStart->v3FromVertex));
bCanEdgeIlluminateEdgeOut |= ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hOppositeFace, (1 - eps)*(*pPropagationEdgeStart->v3FromVertex) + (eps)*(*pPropagationEdgeStart->v3ToVertex));
bCanEdgeIlluminateEdgeOut |= ITAGeoUtils::CanFaceBeIlluminated(*pEdgeEndMesh, pPropagationEdgeEnd->hOppositeFace, (1 - eps)*(*pPropagationEdgeStart->v3ToVertex) + (eps)*(*pPropagationEdgeStart->v3FromVertex));
}
void ITAPropagationPathSim::CombinatedModel::CPathEngine::ConstructPropagationShapes()
......
......@@ -26,10 +26,17 @@ bool ITAPropagationPathSim::CombinatedModel::Reflection::ConstructPointsOfReflec
//Calculate the points of intersection
if (ITAGeoUtils::IsPointInFrontOfPlane(*pFace->pPlane,v3LastInteraction))
{
//If the face doesn't contain a valid face, the whole path will be invalid
if (*pFace->pHasValidImageSource == false)
{
pStartShape = nullptr;
break;
}
//Calculate the point of intersection.
//The point is directly saved as v3LastInteraction,
//because it will be also used in the next iteration
VistaVector3D test;
bool bValid = pFace->pPlane->CalcIntersection(VistaLineSegment(*pFace->v3ImageSource, v3LastInteraction), v3LastInteraction);
if (bValid && ITAGeoUtils::IsPointInFace(v3LastInteraction, pFace->vv3Vertices))
......
......@@ -40,16 +40,14 @@ int main( int iNumInArgs, char* pcInArgs[] )
//string sInFile = "NonSimpleRoom - Outside.skp";
string sInFile = "SimpleUrbanEnvironment.skp";
sInFile = "SimpleRoom.skp";
sInFile = "SimpleRoom2.skp";
if( iNumInArgs > 1 )
sInFile = string( pcInArgs[ 1 ] );
CMaterialDirectory oMaterialDir( "./" );
//Load geo model(for later saving of the propagation paths)
SketchUp::CModel oGeoModel;
oGeoModel.SetMaterialManager( &oMaterialDir );
if( oGeoModel.Load(sSubFolder + sInFile ) )
{
......@@ -63,7 +61,6 @@ int main( int iNumInArgs, char* pcInArgs[] )
//Load mesh model list
auto pMeshModelList = make_shared< ITAGeo::Halfedge::CMeshModelList>();
pMeshModelList->SetMaterialManager(&oMaterialDir);
if (pMeshModelList->Load(sSubFolder + sInFile))
{
......@@ -75,8 +72,12 @@ int main( int iNumInArgs, char* pcInArgs[] )
return 255;
}
auto pSensor = make_shared< CSensor >( VistaVector3D( 3.0f, 3.3f, 1.3f ) );
auto pEmitter = make_shared< CEmitter >( VistaVector3D( 2.1f, 2.2f, 1.7f ) );
//auto pSensor = make_shared< CSensor >( VistaVector3D( 3.0f, 3.3f, 1.3f ) );
//auto pEmitter = make_shared< CEmitter >( VistaVector3D( 2.1f, 2.2f, 1.7f ) );
auto pSensor = make_shared< CSensor >(VistaVector3D(3.0f, 0, 1.4f));
auto pEmitter = make_shared< CEmitter >(VistaVector3D(-3.0f, 0, 1.4f));
cout << "Emitter: " << pEmitter->vPos << endl;
cout << "Sensor: " << pSensor->vPos << endl;
......@@ -90,7 +91,7 @@ int main( int iNumInArgs, char* pcInArgs[] )
sw.start();
pPathEngine->ApplyEmitter(pEmitter,ITAGeo::DIFFRACTION_ORDER_2,ITAGeo::SPECULAR_REFLECTION_ORDER_1,ORDER_3);
pPathEngine->ApplyEmitter(pEmitter,ITAGeo::DIFFRACTION_ORDER_2,ORDER_4,ORDER_6);
cout << "Calculation time applying emitter: " << timeToString(sw.stop()) << endl;
sw.start();
......@@ -112,13 +113,30 @@ int main( int iNumInArgs, char* pcInArgs[] )
oGeoModel.AddEmitterVisualization(*pEmitter, "Emitter A");
oGeoModel.AddSensorVisualization(*pSensor, "Sensor A");
for (auto path : oPathListVisible)
for (auto& path : oPathListVisible)
{
string sPathName = "Propagation_Paths_order_" + std::to_string((long) path.size() - 2 );
long iNumReflections = 0, iNumDiffractions = 0;
for (auto& anchor : path)
{
if (anchor->iAnchorType == ITAGeo::CPropagationAnchor::SPECULAR_REFLECTION)
{
iNumReflections++;
}
else if (anchor->iAnchorType == ITAGeo::CPropagationAnchor::DIFFRACTION_OUTER_APEX)
{
iNumDiffractions++;
}
}
string sPathName = "Paths_Refl_Order_" + to_string(iNumReflections) + "_Diffr_Order_" + to_string(iNumDiffractions);
oGeoModel.AddPropagationPathVisualization(path, sPathName);
}
oPathListVisible.Store("CombinatedModelTest_" + sInFile + ".json");
oGeoModel.Store(sSubFolder +"CombinatedModelTest_"+ sInFile);
......
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