diff --git a/include/ITAPropagationPathSim/CombinedModel/PropagationEngine.h b/include/ITAPropagationPathSim/CombinedModel/PropagationEngine.h index 74054c966fc011743c9b46105d7a26c659942381..98854b9f191d621e5d498a6e539fedeaf3d43b10 100644 --- a/include/ITAPropagationPathSim/CombinedModel/PropagationEngine.h +++ b/include/ITAPropagationPathSim/CombinedModel/PropagationEngine.h @@ -45,10 +45,12 @@ namespace ITAPropagationPathSim 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 diff --git a/src/ITAPropagationPathSim/CombinedModel/PropagationEngine.cpp b/src/ITAPropagationPathSim/CombinedModel/PropagationEngine.cpp index 00d6d22caa742292d9e5a73dd1a5b3383354e24a..a10f949ac9e7930e84db842eddd52d16f1f8f0dc 100644 --- a/src/ITAPropagationPathSim/CombinedModel/PropagationEngine.cpp +++ b/src/ITAPropagationPathSim/CombinedModel/PropagationEngine.cpp @@ -244,8 +244,9 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CreatePropagationTree() CPropagationEdgeShared pEdgeCopy = make_shared(); pEdgeCopy->CopyFrom(*static_pointer_cast(pPropagationShape)); - bool bCanIlluminated = CanPointIlluminateFace(m_pEmitter->v3InteractionPoint, *pEdgeCopy->sMeshModelName, pEdgeCopy->hMainFace); - bCanIlluminated =bCanIlluminated || CanPointIlluminateFace(m_pEmitter->v3InteractionPoint, *pEdgeCopy->sMeshModelName, pEdgeCopy->hOppositeFace); + //TODO: Implement option to choose whether to test intersections or not (last optional boolean value) + bool bCanIlluminated = CanPointIlluminateEdge(m_pEmitter->v3InteractionPoint, pEdgeCopy); + if (bCanIlluminated) { //Add edge copy to propagation tree @@ -334,8 +335,8 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::RecursiveAddShapesToProp //If the illuminability is not found out yet, check for illuminability if (*pPropagationShapeIn->pIsIlluminableBySensor == Tristate::Undefined) { - if (CanPointIlluminateFace(m_pSensor->v3InteractionPoint, *pEdge->sMeshModelName, pEdge->hMainFace) - || CanPointIlluminateFace(m_pSensor->v3InteractionPoint, *pEdge->sMeshModelName, pEdge->hOppositeFace)) + //TODO: Implement option to choose whether to test intersections or not (last optional boolean value) + if(CanPointIlluminateEdge(m_pSensor->v3InteractionPoint,pEdge)) { *pPropagationShapeIn->pIsIlluminableBySensor = Tristate::True; } @@ -546,6 +547,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); } } @@ -563,6 +565,64 @@ bool ITAPropagationPathSim::CombinedModel::CPathEngine::CanPointIlluminateFace(c return ITAGeoUtils::CanFaceBeIlluminated(*pFaceMesh, hFace, v3Point); } +bool ITAPropagationPathSim::CombinedModel::CPathEngine::CanPointIlluminateEdge(const VistaVector3D& v3Point, CPropagationEdgeShared& pPropagationEdge, const bool& bTestIntersection /* = false */) +{ + if (!CanPointIlluminateFace(v3Point, *pPropagationEdge->sMeshModelName, pPropagationEdge->hMainFace) + && !CanPointIlluminateFace(v3Point, *pPropagationEdge->sMeshModelName, pPropagationEdge->hOppositeFace)) + { + return false; + } + if (bTestIntersection) + { + //Resolution (100 µm) + float fResolution = 10000 * ITAConstants::EPS_F_L; + VistaVector3D v3EdgeDirection = *pPropagationEdge->v3ToVertex - *pPropagationEdge->v3FromVertex; + float fRelativeStepSize = fResolution / (v3EdgeDirection.GetLength()); + float fRelativePosition = fRelativeStepSize; + + while (fRelativePosition < 1) + { + //If a visible path is found, the edge can be illuminated by the point + if (IsPathVisible(v3Point, *pPropagationEdge->v3FromVertex + fRelativePosition * v3EdgeDirection)) + return true; + else //Search further points on the edge + fRelativePosition += fRelativeStepSize; + + } + + //No Visible path found + return false; + } + else + { + return true; + } +} + +bool ITAPropagationPathSim::CombinedModel::CPathEngine::IsPathVisible(const VistaVector3D& v3StartPoint, const VistaVector3D& v3EndPoint) +{ + //Search for intersections between two neighbored anchors and repeat it for all neighbored anchors of the path + + //Iterate intersection search over all mesh models + for (int iteration = 0; iteration < m_pMeshModelList->size(); iteration++) + { + //Iterate intersection search over all faces of current mesh model + auto pMesh = m_pMeshModelList->at(iteration)->GetMesh()->pMesh; + auto faceIter = pMesh->faces_begin(); + while (faceIter != pMesh->faces_end()) + { + CITAMesh::FaceHandle hFace(*faceIter++); + + //If one of the path sections crosses one of the faces, the whole path won't be visible + if (ITAGeoUtils::IsLineIntersectingFace(v3StartPoint, v3EndPoint, pMesh, hFace) == EIntersecting::BETWEEN) + return false; + } + } + + //No intersections occur + return true; +} + void ITAPropagationPathSim::CombinedModel::CPathEngine::CanEdgeIlluminateFace(bool &bCanEdgeIlluminateFaceOut, CPropagationFaceShared & pPropagationFace, CPropagationEdgeShared & pPropagationEdge) { auto& pFaceMesh = m_pMeshModelList->GetMeshModel(*pPropagationFace->sMeshModelName)->GetMesh()->pMesh; @@ -610,7 +670,7 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CanFaceIlluminateFace(bo } } -void ITAPropagationPathSim::CombinedModel::CPathEngine::CanEdgeIlluminateEdge(bool &bCanEdgeIlluminateEdgeOut, CPropagationEdgeShared & pPropagationEdgeStart, CPropagationEdgeShared & pPropagationEdgeEnd ) +void ITAPropagationPathSim::CombinedModel::CPathEngine::CanEdgeIlluminateEdge(bool &bCanEdgeIlluminateEdgeOut, CPropagationEdgeShared & pPropagationEdgeStart, CPropagationEdgeShared & pPropagationEdgeEnd, const bool& bTestIntersection /* = false */) { auto& pEdgeEndMesh = m_pMeshModelList->GetMeshModel(*pPropagationEdgeEnd->sMeshModelName)->GetMesh()->pMesh; @@ -638,7 +698,31 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::CanEdgeIlluminateEdge(bo else bCanEdgeIlluminateEdgeOut = bMainFaceIlluminated || bOppositeFaceIlluminated; // A OR B, also valid, if face can only lie in the illuminated region + //If boolean set, also test for intersections( + if (bCanEdgeIlluminateEdgeOut && bTestIntersection) + { + //Set output parameter to false + bCanEdgeIlluminateEdgeOut = false; + //Resolution (100 µm) + float fResolution = 10 * ITAConstants::EPS_F_L; + VistaVector3D v3EdgeDirection = *pPropagationEdgeStart->v3ToVertex - *pPropagationEdgeStart->v3FromVertex; + float fRelativeStepSize = fResolution / (v3EdgeDirection.GetLength()); + float fRelativePosition = fRelativeStepSize; + + while (fRelativePosition < 1) + { + if (CanPointIlluminateEdge(*pPropagationEdgeStart->v3FromVertex + fRelativePosition* v3EdgeDirection, pPropagationEdgeEnd, bTestIntersection)) + { + bCanEdgeIlluminateEdgeOut = true; //if at least one position doesn't contain a intersection with other faces + break; + } + else + { + fRelativePosition += fRelativeStepSize; + } + } + } } void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationShapes()