From ef1096f4d88cbde902053605b1082ecd55d982fc Mon Sep 17 00:00:00 2001 From: adv Date: Wed, 11 Dec 2013 15:22:29 +0000 Subject: [PATCH] Calculation case services implementation (Feature #11). --- src/HYDROData/HYDROData_CalculationCase.cxx | 121 ++++++++++++++++++++ src/HYDROData/HYDROData_CalculationCase.h | 38 ++++++ 2 files changed, 159 insertions(+) diff --git a/src/HYDROData/HYDROData_CalculationCase.cxx b/src/HYDROData/HYDROData_CalculationCase.cxx index 9d6b58f4..5d910ddc 100644 --- a/src/HYDROData/HYDROData_CalculationCase.cxx +++ b/src/HYDROData/HYDROData_CalculationCase.cxx @@ -2,6 +2,7 @@ #include "HYDROData_CalculationCase.h" #include "HYDROData_ArtificialObject.h" +#include "HYDROData_Bathymetry.h" #include "HYDROData_Document.h" #include "HYDROData_Iterator.h" #include "HYDROData_NaturalObject.h" @@ -518,4 +519,124 @@ TopoDS_Shell HYDROData_CalculationCase::GetShell() return aShell; } +double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY& thePoint ) const +{ + double aResAltitude = HYDROData_Bathymetry::GetInvalidAltitude(); + + Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint ); + if ( aZone.IsNull() ) + return aResAltitude; + + HYDROData_Zone::MergeBathymetriesType aZoneMergeType = aZone->GetMergeType(); + if ( !aZone->IsMergingNeed() ) + { + aZoneMergeType = HYDROData_Zone::Merge_UNKNOWN; + } + else if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN ) + { + return aResAltitude; + } + + if ( aZoneMergeType == HYDROData_Zone::Merge_Object ) + { + Handle(HYDROData_Bathymetry) aMergeBathymetry = aZone->GetMergeBathymetry(); + if ( !aMergeBathymetry.IsNull() ) + aResAltitude = aMergeBathymetry->GetAltitudeForPoint( thePoint ); + } + else + { + HYDROData_SequenceOfObjects aZoneObjects = aZone->GetGeometryObjects(); + HYDROData_SequenceOfObjects::Iterator anIter( aZoneObjects ); + for ( ; anIter.More(); anIter.Next() ) + { + Handle(HYDROData_Object) aZoneObj = + Handle(HYDROData_Object)::DownCast( anIter.Value() ); + if ( aZoneObj.IsNull() ) + continue; + + Handle(HYDROData_Bathymetry) anObjBathymetry = aZoneObj->GetBathymetry(); + if ( anObjBathymetry.IsNull() ) + continue; + + double aPointAltitude = anObjBathymetry->GetAltitudeForPoint( thePoint ); + if ( ValuesEquals( aPointAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) ) + continue; + + if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN ) + { + aResAltitude = aPointAltitude; + break; + } + else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMIN ) + { + if ( ValuesEquals( aResAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) || + aResAltitude > aPointAltitude ) + { + aResAltitude = aPointAltitude; + } + } + else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMAX ) + { + if ( ValuesEquals( aResAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) || + aResAltitude < aPointAltitude ) + { + aResAltitude = aPointAltitude; + } + } + } + } + + return aResAltitude; +} + +Handle(HYDROData_Zone) HYDROData_CalculationCase::GetZoneFromPoint( const gp_XY& thePoint ) const +{ + Handle(HYDROData_Zone) aResZone; + HYDROData_SequenceOfObjects aRegions = GetRegions(); + + HYDROData_SequenceOfObjects::Iterator anIter( aRegions ); + for ( ; anIter.More() && aResZone.IsNull(); anIter.Next() ) + { + Handle(HYDROData_Region) aRegion = + Handle(HYDROData_Region)::DownCast( anIter.Value() ); + if ( aRegion.IsNull() ) + continue; + + HYDROData_SequenceOfObjects aZones = aRegion->GetZones(); + HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones ); + for ( ; aZonesIter.More() && aResZone.IsNull(); aZonesIter.Next() ) + { + Handle(HYDROData_Zone) aRegZone = + Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() ); + if ( aRegZone.IsNull() ) + continue; + + PointClassification aPointRelation = GetPointClassification( thePoint, aRegZone ); + if ( aPointRelation != POINT_OUT ) + aResZone = aRegZone; // We found the desired zone + } + } + + return aResZone; +} + +HYDROData_CalculationCase::PointClassification HYDROData_CalculationCase::GetPointClassification( + const gp_XY& thePoint, + const Handle(HYDROData_Zone)& theZone ) const +{ + PointClassification aRes = POINT_OUT; + if ( theZone.IsNull() ) + return aRes; + + TopoDS_Face aZoneFace = TopoDS::Face( theZone->GetShape() ); + if ( aZoneFace.IsNull() ) + return aRes; + + // TODO: classify the point position relative to zone + // POINT_OUT - point is out of zone face + // POINT_IN - point is inside of zone face + // POINT_ON - point is on the edge of zone face + + return aRes; +} diff --git a/src/HYDROData/HYDROData_CalculationCase.h b/src/HYDROData/HYDROData_CalculationCase.h index f6787a27..b4a8261d 100644 --- a/src/HYDROData/HYDROData_CalculationCase.h +++ b/src/HYDROData/HYDROData_CalculationCase.h @@ -5,6 +5,8 @@ #include +class gp_XY; + class TopoDS_Shell; class Handle(HYDROData_Object); @@ -21,6 +23,14 @@ DEFINE_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity) */ class HYDROData_CalculationCase : public HYDROData_Entity { +public: + + enum PointClassification + { + POINT_OUT, + POINT_IN, + POINT_ON + }; protected: @@ -148,6 +158,34 @@ public: */ HYDRODATA_EXPORT virtual TopoDS_Shell GetShell(); + +public: + // Public methods to work with Calculation services + + /** + * Returns altitude for given point. + * \param thePoint the point to examine + * \return result altitude value + */ + HYDRODATA_EXPORT virtual double GetAltitudeForPoint( const gp_XY& thePoint ) const; + + /** + * Returns zone to which the point is belongs. + * \param thePoint the point to examine + * \return result zone + */ + HYDRODATA_EXPORT virtual Handle(HYDROData_Zone) GetZoneFromPoint( const gp_XY& thePoint ) const; + + /** + * Returns classification of point for given zone. + * \param thePoint the point to examine + * \param theZone the zone to examine + * \return result classification + */ + HYDRODATA_EXPORT virtual PointClassification GetPointClassification( + const gp_XY& thePoint, + const Handle(HYDROData_Zone)& theZone ) const; + private: /** -- 2.39.2