]> SALOME platform Git repositories - modules/hydro.git/commitdiff
Salome HOME
parametrization
authorasl <asl@opencascade.com>
Mon, 29 Sep 2014 11:36:26 +0000 (11:36 +0000)
committerasl <asl@opencascade.com>
Mon, 29 Sep 2014 11:36:26 +0000 (11:36 +0000)
src/HYDROData/CMakeLists.txt
src/HYDROData/HYDROData_CalculationCase.cxx
src/HYDROData/HYDROData_CalculationCase.h
src/HYDROData/HYDROData_PriorityQueue.cxx [new file with mode: 0644]
src/HYDROData/HYDROData_PriorityQueue.h [new file with mode: 0644]
src/HYDROData/HYDROData_Region.cxx
src/HYDROData/HYDROData_Region.h
src/HYDROPy/HYDROData_CalculationCase.sip

index e50e85897d165bae3f1035e7856e0ac479cedde9..ba36b3270577a8a983220d0e1c3f71a136bffe2e 100644 (file)
@@ -29,6 +29,7 @@ set(PROJECT_HEADERS
     HYDROData_Pipes.h
     HYDROData_PolylineXY.h
     HYDROData_Polyline3D.h
+    HYDROData_PriorityQueue.h
     HYDROData_Profile.h
     HYDROData_ProfileUZ.h
     HYDROData_Projection.h
@@ -74,6 +75,7 @@ set(PROJECT_SOURCES
     HYDROData_Pipes.cxx
     HYDROData_PolylineXY.cxx
     HYDROData_Polyline3D.cxx
+    HYDROData_PriorityQueue.cxx
     HYDROData_Profile.cxx
     HYDROData_ProfileUZ.cxx
     HYDROData_Projection.cxx
index 509c2c5fb0bb63ffbd4ca5dd173f9d7aa5d15aa0..d878012a0648cbfb234971188654c6db0cf66a92 100644 (file)
@@ -8,11 +8,9 @@
 #include "HYDROData_Iterator.h"
 #include "HYDROData_NaturalObject.h"
 #include "HYDROData_PolylineXY.h"
-#include "HYDROData_SplitToZonesTool.h"
 #include "HYDROData_SplittedShapesGroup.h"
 #include "HYDROData_Region.h"
 #include "HYDROData_Tool.h"
-#include "HYDROData_Zone.h"
 
 #include <GEOMBase.h>
 
@@ -217,84 +215,132 @@ void HYDROData_CalculationCase::Update()
 
   HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups();
 
-  HYDROData_SplitToZonesTool::SplitDataList aSplitedObjects =
+  HYDROData_SplitToZonesTool::SplitDataList aSplitObjects =
     HYDROData_SplitToZonesTool::Split( aGeomObjects, aGeomGroups, aBoundaryPolyline );
-  if ( aSplitedObjects.isEmpty() )
+  if ( aSplitObjects.isEmpty() )
     return;
 
-  QString aRegsPref = CALCULATION_REGIONS_PREF;
-  QString aZonesPref = CALCULATION_ZONES_PREF;
+  HYDROData_SplitToZonesTool::SplitDataList aZonesList, anEdgesList;
 
-  QMap<QString,Handle(HYDROData_SplittedShapesGroup)> aSplittedEdgesGroupsMap;
+  HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitObjects );
+  while( anIter.hasNext() )
+  {
+    const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
+    if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone )
+      aZonesList.append( aSplitData );
+    else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge )
+      anEdgesList.append( aSplitData );
+  }
+
+  //CreateRegionsDef( aDocument, aZonesList );
+  CreateRegionsAuto( aDocument, aZonesList );
+  CreateEdgeGroupsDef( aDocument, anEdgesList );
+}
 
+void HYDROData_CalculationCase::CreateRegionsDef( const Handle(HYDROData_Document)& theDoc,
+                                                  const HYDROData_SplitToZonesTool::SplitDataList& theZones )
+{
   // Create result regions for case, by default one zone for one region
-  HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedObjects );
+  QString aRegsPref = CALCULATION_REGIONS_PREF;
+  QString aZonesPref = CALCULATION_ZONES_PREF;
+
+  HYDROData_SplitToZonesTool::SplitDataListIterator anIter( theZones );
   while( anIter.hasNext() )
   {
     const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
+    // Create new region
+    Handle(HYDROData_Region) aRegion = addNewRegion( theDoc, aRegsPref );
 
-    if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone )
-    {
-      // Create new region
-      Handle(HYDROData_Region) aRegion = addNewRegion();
+    // Add the zone for region
+    Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone( theDoc, aZonesPref, aSplitData.Face(), aSplitData.ObjectNames );
+  }
+}
 
-      QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
-      aRegion->SetName( aRegionName );
+void HYDROData_CalculationCase::CreateRegionsAuto( const Handle(HYDROData_Document)& theDoc,
+                                                   const HYDROData_SplitToZonesTool::SplitDataList& theZones )
+{
+  QMap<QString, Handle(HYDROData_Region)> aRegionsMap; //object name to region
+  QString aZonesPref = CALCULATION_ZONES_PREF;
+  HYDROData_PriorityQueue aPr( this );
 
-      // Add the zone for region
-      Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
+  // 1. First we create a default region for each object included into the calculation case
+  HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
+  for( int i=aGeomObjects.Lower(), n=aGeomObjects.Upper(); i<=n; i++ )
+  {
+    Handle(HYDROData_Object) anObj = Handle(HYDROData_Object)::DownCast( aGeomObjects.Value( i ) );
+    if( anObj.IsNull() )
+      continue;
+    QString anObjName = anObj->GetName();
+    QString aRegName = anObjName + "_reg";
+    Handle(HYDROData_Region) aRegion = addNewRegion( theDoc, aRegName, false );
+    aRegionsMap.insert( anObjName, aRegion );
+  }
 
-      QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, aZonesPref );
-      aRegionZone->SetName( aZoneName );
+  // 2. Now for each zone it is necessary to determine the most priority object
+  //    and assign to zone to corresponding region
+  HYDROData_SplitToZonesTool::SplitDataListIterator anIter( theZones );
+  while( anIter.hasNext() )
+  {
+    const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
+    HYDROData_Zone::MergeAltitudesType aMergeType;
+    Handle(HYDROData_Object) aRegObj = aPr.GetMostPriorityObject( aSplitData.ObjectNames, aMergeType );
+    if( aRegObj.IsNull() )
+      continue;
+    Handle(HYDROData_Region) aRegion = aRegionsMap[aRegObj->GetName()];
+    if( aRegion.IsNull() )
+      continue;
+    Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone( theDoc, aZonesPref, aSplitData.Face(), aSplitData.ObjectNames );
+    switch( aMergeType )
+    {
+    case HYDROData_Zone::Merge_ZMIN:
+    case HYDROData_Zone::Merge_ZMAX:
+      aRegionZone->SetMergeType( aMergeType );
+      break;
+    case HYDROData_Zone::Merge_Object:
+      aRegionZone->SetMergeType( aMergeType );
+      aRegionZone->RemoveMergeAltitude();
+      aRegionZone->SetMergeAltitude( aRegObj->GetAltitudeObject() );
+      break;
+    }
+  }
 
-      aRegionZone->SetShape( aSplitData.Face() );
+  //TODO: inform if some regions remain empty
+}
 
-      // Add the reference object for zone
-      for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
-      {
-        const QString& anObjName = aSplitData.ObjectNames.at( i );
-        
-        Handle(HYDROData_Object) aRefObject = 
-          Handle(HYDROData_Object)::DownCast( aDocument->FindObjectByName( anObjName ) );
-        if ( aRefObject.IsNull() )
-          continue;
+void HYDROData_CalculationCase::CreateEdgeGroupsDef( const Handle(HYDROData_Document)& theDoc,
+                                                     const HYDROData_SplitToZonesTool::SplitDataList& theEdges )
+{
+  QMap<QString,Handle(HYDROData_SplittedShapesGroup)> aSplittedEdgesGroupsMap;
 
-        aRegionZone->AddGeometryObject( aRefObject );
-      }
-    }
-    else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge )
-    {
-      // Create new edges group
-      if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
-        continue;
+  HYDROData_SplitToZonesTool::SplitDataListIterator anIter( theEdges );
+  while( anIter.hasNext() )
+  {
+    const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
+    // Create new edges group
+    if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
+      continue;
 
-      QString anObjName = aSplitData.ObjectNames.first();
-      if ( anObjName.isEmpty() )
-        continue;
+    QString anObjName = aSplitData.ObjectNames.first();
+    if ( anObjName.isEmpty() )
+      continue;
 #ifdef DEB_CALCULATION
-      QString aStr = aSplitData.ObjectNames.join(" "); 
+    QString aStr = aSplitData.ObjectNames.join(" "); 
          cout << " CCase: Names = "<<aStr.toStdString() << " size = " <<aSplitData.ObjectNames.size() <<endl; 
 #endif
-      Handle(HYDROData_SplittedShapesGroup) aSplittedGroup;
-      if ( !aSplittedEdgesGroupsMap.contains( anObjName ) )
-      {
-        aSplittedGroup = addNewSplittedGroup();
-
-        QString aCalcGroupName = CALCULATION_GROUPS_PREF + anObjName;
-        aSplittedGroup->SetName( aCalcGroupName );
-
-        aSplittedEdgesGroupsMap.insert( anObjName, aSplittedGroup );
-      }
-      else
-      {
-        aSplittedGroup = aSplittedEdgesGroupsMap[ anObjName ];
-      }
-
-      if ( aSplittedGroup.IsNull() )
-        continue;
-
-      aSplittedGroup->AddShape( aSplitData.Shape );
+    Handle(HYDROData_SplittedShapesGroup) aSplittedGroup;
+    if ( !aSplittedEdgesGroupsMap.contains( anObjName ) )
+    {
+      aSplittedGroup = addNewSplittedGroup( CALCULATION_GROUPS_PREF + anObjName );
+      aSplittedEdgesGroupsMap.insert( anObjName, aSplittedGroup );
     }
+    else
+    {
+      aSplittedGroup = aSplittedEdgesGroupsMap[ anObjName ];
+    }
+    if ( aSplittedGroup.IsNull() )
+      continue;
+
+    aSplittedGroup->AddShape( aSplitData.Shape );
   }
 }
 
@@ -406,20 +452,11 @@ void HYDROData_CalculationCase::RemoveBoundaryPolyline()
 
 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
 {
-  Handle(HYDROData_Region) aNewRegion = addNewRegion();
+  Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+  Handle(HYDROData_Region) aNewRegion = addNewRegion( aDocument, CALCULATION_REGIONS_PREF );
   if ( aNewRegion.IsNull() )
     return aNewRegion;
 
-  // Generate new name for new region
-  Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
-  if ( !aDocument.IsNull() )
-  {
-    QString aRegsPref = CALCULATION_REGIONS_PREF;
-
-    QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
-    aNewRegion->SetName( aNewRegionName );
-  }
-
   aNewRegion->AddZone( theZone );
 
   return aNewRegion;
@@ -427,6 +464,8 @@ Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(H
 
 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
 {
+  Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+
   if ( theRegion.IsNull() )
     return false;
   
@@ -438,7 +477,7 @@ bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRe
     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
   {
-    Handle(HYDROData_Region) aNewRegion = addNewRegion();
+    Handle(HYDROData_Region) aNewRegion = addNewRegion( aDocument, CALCULATION_REGIONS_PREF );
     theRegion->CopyTo( aNewRegion );
 
     aFatherCalc->RemoveRegion( theRegion );
@@ -737,7 +776,9 @@ HYDROData_CalculationCase::PointClassification HYDROData_CalculationCase::GetPoi
   return aRes;
 }
 
-Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
+Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion( const Handle(HYDROData_Document)& theDoc,
+                                                                  const QString& thePrefixOrName,
+                                                                  bool isPrefix )
 {
   TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
 
@@ -745,10 +786,13 @@ Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
     Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
   AddRegion( aNewRegion );
 
+  QString aRegionName = isPrefix ? HYDROData_Tool::GenerateObjectName( theDoc, thePrefixOrName ) : thePrefixOrName;
+  aNewRegion->SetName( aRegionName );
+
   return aNewRegion;
 }
 
-Handle(HYDROData_SplittedShapesGroup) HYDROData_CalculationCase::addNewSplittedGroup()
+Handle(HYDROData_SplittedShapesGroup) HYDROData_CalculationCase::addNewSplittedGroup( const QString& theName )
 {
   TDF_Label aNewLab = myLab.FindChild( DataTag_SplittedGroups ).NewChild();
 
@@ -757,6 +801,8 @@ Handle(HYDROData_SplittedShapesGroup) HYDROData_CalculationCase::addNewSplittedG
       HYDROData_Iterator::CreateObject( aNewLab, KIND_SPLITTED_GROUP ) );
   AddReferenceObject( aNewGroup, DataTag_SplittedGroups );
 
+  aNewGroup->SetName( theName );
+
   return aNewGroup;
 }
 
@@ -997,4 +1043,25 @@ GEOM::GEOM_Object_ptr HYDROData_CalculationCase::publishShapeInGEOM(
   }
 
   return aGeomObj._retn();
- }
+}
+
+void HYDROData_CalculationCase::ClearRules()
+{
+  TDF_Label aRulesLab = myLab.FindChild( DataTag_CustomRules );
+  HYDROData_PriorityQueue::ClearRules( aRulesLab );
+}
+
+void HYDROData_CalculationCase::AddRule( const Handle(HYDROData_Object)&    theObject1,
+                                         HYDROData_PriorityType             thePriority,
+                                         const Handle(HYDROData_Object)&    theObject2,
+                                         HYDROData_Zone::MergeAltitudesType theMergeType )
+{
+  TDF_Label aRulesLab = myLab.FindChild( DataTag_CustomRules );
+  HYDROData_PriorityQueue::AddRule( aRulesLab, theObject1, thePriority, theObject2, theMergeType );
+}
+
+QString HYDROData_CalculationCase::DumpRules()
+{
+  TDF_Label aRulesLab = myLab.FindChild( DataTag_CustomRules );
+  return HYDROData_PriorityQueue::DumpRules( aRulesLab );
+}
index 3629a7dd82c23cd2f9d539d12f5636294362e59c..4eb2ee1d804f51ab9e65b58154d132ffa8b22095 100644 (file)
@@ -4,6 +4,9 @@
 #define HYDROData_CalculationCase_HeaderFile
 
 #include <HYDROData_ShapesGroup.h>
+#include <HYDROData_SplitToZonesTool.h>
+#include <HYDROData_PriorityQueue.h>
+#include <HYDROData_Zone.h>
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -21,6 +24,7 @@ class Handle(HYDROData_Zone);
 class Handle(HYDROData_PolylineXY);
 class Handle(HYDROData_ShapesGroup);
 class Handle(HYDROData_SplittedShapesGroup);
+class Handle(HYDROData_Document);
 
 DEFINE_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
 
@@ -40,7 +44,7 @@ public:
     POINT_ON    ///< point is on the edge of zone face
   };
 
-protected:
+public:
 
   /**
    * Enumeration of tags corresponding to the persistent object parameters.
@@ -54,6 +58,7 @@ protected:
     DataTag_Polyline,         ///< reference boundary polyline
     DataTag_GeometryGroup,    ///< reference geometry groups
     DataTag_SplittedGroups,   ///< reference splitted groups
+    DataTag_CustomRules,      ///< custom rules
   };
 
 public:
@@ -276,18 +281,28 @@ public:
     const gp_XY&                  thePoint,
     const Handle(HYDROData_Zone)& theZone ) const;
 
+  HYDRODATA_EXPORT void ClearRules();
+  HYDRODATA_EXPORT void AddRule( const Handle(HYDROData_Object)&    theObject1,
+                                 HYDROData_PriorityType             thePriority,
+                                 const Handle(HYDROData_Object)&    theObject2,
+                                 HYDROData_Zone::MergeAltitudesType theMergeType );
+
+  HYDRODATA_EXPORT QString DumpRules();
+
 private:
 
   /**
    * Add new one region for calculation case.
    * The new region is added into the list of reference regions.
    */
-  HYDRODATA_EXPORT virtual Handle(HYDROData_Region) addNewRegion();
+  Handle(HYDROData_Region) addNewRegion( const Handle(HYDROData_Document)& theDoc,
+                                         const QString& thePrefixOrName,
+                                         bool isPrefix = true );
 
   /**
    * Add new one splitted edges group for calculation case.
    */
-  HYDRODATA_EXPORT virtual Handle(HYDROData_SplittedShapesGroup) addNewSplittedGroup();
+  Handle(HYDROData_SplittedShapesGroup) addNewSplittedGroup( const QString& theName );
 
   /**
    * Exports the given faces as shell and the given groups to GEOM module.
@@ -297,10 +312,10 @@ private:
    * \param theSplittedGroups the list of groups
    * \return true in case of success
    */
-  HYDRODATA_EXPORT bool Export( GEOM::GEOM_Gen_var                            theGeomEngine,
-                                SALOMEDS::Study_ptr                           theStudy,
-                                const TopTools_ListOfShape&                   theFaces,
-                                const HYDROData_ShapesGroup::SeqOfGroupsDefs& theGroupsDefs ) const;
+  bool Export( GEOM::GEOM_Gen_var                            theGeomEngine,
+               SALOMEDS::Study_ptr                           theStudy,
+               const TopTools_ListOfShape&                   theFaces,
+               const HYDROData_ShapesGroup::SeqOfGroupsDefs& theGroupsDefs ) const;
 
   /**
    * Publish the given shape in GEOM as a GEOM object.
@@ -315,8 +330,15 @@ private:
                                             const TopoDS_Shape& theShape, 
                                             const QString&      theName ) const;
 
-protected:
+  void CreateRegionsDef( const Handle(HYDROData_Document)& theDoc,
+                         const HYDROData_SplitToZonesTool::SplitDataList& theZones );
+  void CreateRegionsAuto( const Handle(HYDROData_Document)& theDoc,
+                          const HYDROData_SplitToZonesTool::SplitDataList& theZones );
+
+  void CreateEdgeGroupsDef( const Handle(HYDROData_Document)& theDoc,
+                            const HYDROData_SplitToZonesTool::SplitDataList& theEdges );
 
+protected:
   friend class HYDROData_Iterator;
 
   /**
diff --git a/src/HYDROData/HYDROData_PriorityQueue.cxx b/src/HYDROData/HYDROData_PriorityQueue.cxx
new file mode 100644 (file)
index 0000000..fd72c21
--- /dev/null
@@ -0,0 +1,182 @@
+
+#include <HYDROData_PriorityQueue.h>
+#include <HYDROData_CalculationCase.h>
+#include <HYDROData_Iterator.h>
+#include <TDataStd_ReferenceList.hxx>
+#include <TDataStd_Integer.hxx>
+#include <TDF_ChildIterator.hxx>
+
+HYDROData_PriorityQueue::HYDROData_PriorityQueue( HYDROData_CalculationCase* theCalcCase )
+{
+  myGeomObjects = theCalcCase->GetGeometryObjects();
+  for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
+  {
+    Handle(HYDROData_Object) anObj = Handle(HYDROData_Object)::DownCast( myGeomObjects.Value( i ) );
+    if( !anObj.IsNull() )
+    {
+      QString anObjName = anObj->GetName();
+      myNames[anObjName] = anObj;
+    }
+  }
+
+  myRules = GetRules( theCalcCase->Label().FindChild( HYDROData_CalculationCase::DataTag_CustomRules ) );
+}
+
+HYDROData_PriorityQueue::~HYDROData_PriorityQueue()
+{
+}
+
+Handle(HYDROData_Object) HYDROData_PriorityQueue::GetMostPriorityObject( const QStringList& theZoneObjects,
+                                                                         HYDROData_Zone::MergeAltitudesType& theMergeType ) const
+{
+  Handle(HYDROData_Object) aMostPriorityObj;
+  theMergeType = HYDROData_Zone::Merge_Object;
+  QStringList::const_iterator anIt = theZoneObjects.begin(), aLast = theZoneObjects.end();
+  for( ; anIt!=aLast; anIt++ )
+  {
+    HYDROData_Zone::MergeAltitudesType aLocalMerge = HYDROData_Zone::Merge_UNKNOWN;
+    Handle(HYDROData_Object) anObj = myNames[*anIt];
+    if( !anObj.IsNull() )
+      if( aMostPriorityObj.IsNull() || IsMorePriority( anObj, aMostPriorityObj, aLocalMerge ) )
+      {
+        aMostPriorityObj = anObj;
+        theMergeType = aLocalMerge;
+      }
+  }
+  return aMostPriorityObj;
+}
+
+bool HYDROData_PriorityQueue::IsMorePriority( const Handle(HYDROData_Object)& theObj1,
+                                              const Handle(HYDROData_Object)& theObj2,
+                                              HYDROData_Zone::MergeAltitudesType& theMergeType ) const
+{
+  // 1. First we check custom rules
+  HYDROData_ListOfRules::const_iterator anIt = myRules.begin(), aLast = myRules.end();
+  for( ; anIt!=aLast; anIt++ )
+  {
+    if( anIt->Object1->Label()==theObj1->Label() && anIt->Object2->Label()==theObj2->Label() )
+    {
+      theMergeType = anIt->MergeType;
+      return anIt->Priority==GREATER;
+    }
+    if( anIt->Object1->Label()==theObj2->Label() && anIt->Object2->Label()==theObj1->Label() )
+    {
+      theMergeType = anIt->MergeType;
+      return anIt->Priority==LESS;
+    }
+  }
+
+  // 2. If no custom rule found, the standard ordering list is applied
+  for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
+  {
+    if( myGeomObjects.Value( i )->Label() == theObj1->Label() )
+    {
+      theMergeType = HYDROData_Zone::Merge_Object;
+      return true;
+    }
+    if( myGeomObjects.Value( i )->Label() == theObj2->Label() )
+    {
+      theMergeType = HYDROData_Zone::Merge_Object;
+      return false;
+    }
+  }
+  return false;
+}
+
+void HYDROData_PriorityQueue::ClearRules( TDF_Label& theRulesLabel )
+{
+  theRulesLabel.ForgetAllAttributes( true );
+}
+
+enum HYDROData_PriorityQueueTag
+{
+  Object1_Tag,
+  Priority_Tag,
+  Object2_Tag,
+  Merge_Tag,
+};
+
+void HYDROData_PriorityQueue::AddRule( TDF_Label&                         theRulesLabel,
+                                       const Handle(HYDROData_Object)&    theObject1,
+                                       HYDROData_PriorityType             thePriority,
+                                       const Handle(HYDROData_Object)&    theObject2,
+                                       HYDROData_Zone::MergeAltitudesType theMergeType )
+{
+  TDF_Label aNewRuleLab = theRulesLabel.NewChild();
+
+  TDF_Label anObj1Lab = aNewRuleLab.FindChild( Object1_Tag );
+  Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set( anObj1Lab );
+  aRefs->Append( theObject1->Label() );
+  
+  TDF_Label aPriorityLab = aNewRuleLab.FindChild( Priority_Tag );
+  TDataStd_Integer::Set( aPriorityLab, thePriority );
+
+  TDF_Label anObj2Lab = aNewRuleLab.FindChild( Object2_Tag );
+  aRefs = TDataStd_ReferenceList::Set( anObj2Lab );
+  aRefs->Append( theObject2->Label() );
+
+  TDF_Label aMergeLab = aNewRuleLab.FindChild( Merge_Tag );
+  TDataStd_Integer::Set( aMergeLab, theMergeType );
+}
+
+HYDROData_ListOfRules HYDROData_PriorityQueue::GetRules( const TDF_Label& theRulesLabel )
+{
+  HYDROData_ListOfRules aRules;
+
+  Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
+  Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
+
+  TDF_ChildIterator anIt( theRulesLabel );
+  for( ; anIt.More(); anIt.Next() )
+  {
+    TDF_Label aRuleLabel = anIt.Value();
+
+    bool isObj1OK = aRuleLabel.FindChild    ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
+    bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(),       aPriorityAttr );
+    bool isObj2OK = aRuleLabel.FindChild    ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
+    bool isMergeOK = aRuleLabel.FindChild   ( Merge_Tag ).   FindAttribute( TDataStd_Integer::GetID(),       aMergeAttr );
+
+    if( isObj1OK && isPriorityOK && isObj2OK && isMergeOK )
+    {
+      HYDROData_CustomRule aRule;
+      aRule.Object1 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs1->First() ) );
+      aRule.Priority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
+      aRule.Object2 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs2->First() ) );
+      aRule.MergeType = ( HYDROData_Zone::MergeAltitudesType ) aMergeAttr->Get();
+      aRules.append( aRule );
+    }
+  }
+
+  return aRules;
+}
+
+QString HYDROData_PriorityQueue::DumpRules( const TDF_Label& theRulesLab )
+{
+  QString aDump = "Rules:\n";
+  HYDROData_ListOfRules aRules = GetRules( theRulesLab );
+  HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
+  for( ; anIt!=aLast; anIt++ )
+  {
+    QString aRule = anIt->Object1->GetName() + " ";
+    aRule += ( anIt->Priority == LESS ? "<" : ">" ) + QString( " " );
+    aRule += anIt->Object2->GetName() + " ";
+
+    switch( anIt->MergeType )
+    {
+    case HYDROData_Zone::Merge_UNKNOWN:
+      aRule += "unknown";
+      break;
+    case HYDROData_Zone::Merge_ZMIN:
+      aRule += "zmin";
+      break;
+    case HYDROData_Zone::Merge_ZMAX:
+      aRule += "zmax";
+      break;
+    case HYDROData_Zone::Merge_Object:
+      aRule += "object";
+      break;
+    }
+    aDump += aRule + "\n";
+  }
+  return aDump;
+}
diff --git a/src/HYDROData/HYDROData_PriorityQueue.h b/src/HYDROData/HYDROData_PriorityQueue.h
new file mode 100644 (file)
index 0000000..314f455
--- /dev/null
@@ -0,0 +1,58 @@
+
+#ifndef HYDROData_PriorityQueue_HeaderFile
+#define HYDROData_PriorityQueue_HeaderFile
+
+#include <QMap>
+#include <HYDROData_Object.h>
+#include <HYDROData_Zone.h>
+
+class HYDROData_CalculationCase;
+
+enum HYDROData_PriorityType
+{
+  LESS,
+  GREATER,
+};
+
+struct HYDROData_CustomRule
+{
+  Handle(HYDROData_Object)           Object1;
+  HYDROData_PriorityType             Priority;
+  Handle(HYDROData_Object)           Object2;
+  HYDROData_Zone::MergeAltitudesType MergeType;
+};
+
+typedef QList<HYDROData_CustomRule> HYDROData_ListOfRules;
+
+class HYDROData_PriorityQueue
+{
+public:
+  HYDROData_PriorityQueue( HYDROData_CalculationCase* );
+  ~HYDROData_PriorityQueue();
+
+  Handle_HYDROData_Object GetMostPriorityObject( const QStringList& theZoneObjects,
+                                                 HYDROData_Zone::MergeAltitudesType& theMergeType ) const;
+
+  bool IsMorePriority( const Handle(HYDROData_Object)& theObj1,
+                       const Handle(HYDROData_Object)& theObj2,
+                       HYDROData_Zone::MergeAltitudesType& theMergeType ) const;
+
+  static void ClearRules( TDF_Label& theRulesLabel );
+  static void AddRule( TDF_Label& theRulesLabel,
+                       const Handle(HYDROData_Object)&    theObject1,
+                       HYDROData_PriorityType             thePriority,
+                       const Handle(HYDROData_Object)&    theObject2,
+                       HYDROData_Zone::MergeAltitudesType theMergeType );
+  static HYDROData_ListOfRules GetRules( const TDF_Label& theRulesLabel );
+  static QString DumpRules( const TDF_Label& theRulesLab );
+
+private:
+  typedef QMap<QString, Handle(HYDROData_Object)> MapNameToObject;
+
+  HYDROData_SequenceOfObjects myGeomObjects;  ///< the ordered list of objects (default priority)
+  MapNameToObject             myNames;        ///< the map of name to object
+  HYDROData_ListOfRules       myRules;        ///< the list of rules
+};
+
+#endif
+
index ac6a4f757ca6b2ed550d0f98e7b3085005363f74..aad021e74f81fa9feae5bd5af3aff69549abb288 100644 (file)
@@ -4,8 +4,10 @@
 #include "HYDROData_CalculationCase.h"
 #include "HYDROData_Document.h"
 #include "HYDROData_Iterator.h"
+#include "HYDROData_Object.h"
 #include "HYDROData_ShapesTool.h"
 #include "HYDROData_Zone.h"
+#include "HYDROData_Tool.h"
 
 #include <TopoDS.hxx>
 #include <TopoDS_Shape.hxx>
@@ -74,6 +76,8 @@ HYDROData_SequenceOfObjects HYDROData_Region::GetAllReferenceObjects() const
 
 bool HYDROData_Region::AddZone( const Handle(HYDROData_Zone)& theZone )
 {
+  Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+
   if ( theZone.IsNull() )
     return false;
   
@@ -85,7 +89,7 @@ bool HYDROData_Region::AddZone( const Handle(HYDROData_Zone)& theZone )
     Handle(HYDROData_Region)::DownCast( theZone->GetFatherObject() );
   if ( !aFatherRegion.IsNull() && aFatherRegion->Label() != myLab )
   {
-    Handle(HYDROData_Zone) aNewZone = addNewZone();
+    Handle(HYDROData_Zone) aNewZone = addNewZone( aDocument, "", TopoDS_Face(), QStringList() );
     theZone->CopyTo( aNewZone );
 
     // To prevent changing of stored shape
@@ -133,7 +137,10 @@ void HYDROData_Region::RemoveZones()
   myLab.FindChild( DataTag_ChildZone ).ForgetAllAttributes( true );
 }
 
-Handle(HYDROData_Zone) HYDROData_Region::addNewZone()
+Handle(HYDROData_Zone) HYDROData_Region::addNewZone( const Handle(HYDROData_Document)& theDoc,
+                                                     const QString& thePrefix,
+                                                     const TopoDS_Face& theFace,
+                                                     const QStringList& theRefObjects )
 {
   TDF_Label aNewLab = myLab.FindChild( DataTag_ChildZone ).NewChild();
 
@@ -141,6 +148,23 @@ Handle(HYDROData_Zone) HYDROData_Region::addNewZone()
     Handle(HYDROData_Zone)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_ZONE ) );
   AddZone( aNewZone );
 
+  QString aZoneName = HYDROData_Tool::GenerateObjectName( theDoc, thePrefix );
+  aNewZone->SetName( aZoneName );
+
+  aNewZone->SetShape( theFace );
+
+  // Add the reference object for zone
+  for ( int i = 0, n = theRefObjects.length(); i < n; ++i )
+  {
+    const QString& anObjName = theRefObjects.at( i );
+    Handle(HYDROData_Object) aRefObject = 
+      Handle(HYDROData_Object)::DownCast( theDoc->FindObjectByName( anObjName ) );
+    if ( aRefObject.IsNull() )
+      continue;
+
+    aNewZone->AddGeometryObject( aRefObject );
+  }
+
   return aNewZone;
 }
 
index 3307b324377ebc93527832bd8765e24bb01f322c..a0714da1dfaf92183225c89c5a2175339575e672 100644 (file)
@@ -8,8 +8,10 @@
 DEFINE_STANDARD_HANDLE(HYDROData_Region, HYDROData_Entity)
 
 class Handle(HYDROData_Zone);
-
+class Handle(HYDROData_Document);
 class TopoDS_Shape;
+class TopoDS_Face;
+class QStringList;
 
 /**\class HYDROData_Region
  * \brief Regions are groups (lists) of zones, they can include one or several zones.
@@ -97,7 +99,10 @@ protected:
    * Create new one reference zone for region on child label.
    * The new zone is added into the list of reference zones.
    */
-  HYDRODATA_EXPORT virtual Handle(HYDROData_Zone) addNewZone();
+  HYDRODATA_EXPORT virtual Handle(HYDROData_Zone) addNewZone( const Handle(HYDROData_Document)& theDoc,
+                                                              const QString& thePrefix,
+                                                              const TopoDS_Face& theFace,
+                                                              const QStringList& theRefObjects );
 
 protected:
 
index 48a257f9c9a568a55d9a52c999fb98d4a72d4d75..5b7c7f2ce97297644332904975566cd1a804c811 100644 (file)
 
 %ExportedHeaderCode
 #include <HYDROData_CalculationCase.h>
+#include <HYDROData_PriorityQueue.h>
 %End
 
+enum HYDROData_PriorityType
+{
+  LESS,
+  GREATER,
+};
+
 class HYDROData_CalculationCase : public HYDROData_Entity
 {
 
@@ -472,6 +479,28 @@ public:
     Py_END_ALLOW_THREADS
   %End
 
+
+  void ClearRules();
+
+  void AddRule( HYDROData_Object                   theObject1,
+                HYDROData_PriorityType             thePriority,
+                HYDROData_Object                   theObject2,
+                HYDROData_Zone::MergeAltitudesType theMergeType )
+  [void ( const Handle_HYDROData_Object&, HYDROData_PriorityType, const Handle_HYDROData_Object&, HYDROData_Zone::MergeAltitudesType )];
+  %MethodCode
+    Handle(HYDROData_Object) anObject1 =
+      Handle(HYDROData_Object)::DownCast( createHandle( a0 ) );
+    Handle(HYDROData_Object) anObject2 =
+      Handle(HYDROData_Object)::DownCast( createHandle( a2 ) );
+
+    Py_BEGIN_ALLOW_THREADS
+    sipSelfWasArg ? sipCpp->HYDROData_CalculationCase::AddRule( anObject1, a1, anObject2, a3 ) : 
+                    sipCpp->AddRule( anObject1, a1, anObject2, a3 );
+    Py_END_ALLOW_THREADS
+  %End
+
+  QString DumpRules();
+
 protected:
 
   /**