#include "HYDROData_CalculationCase.h"
#include "HYDROData_ArtificialObject.h"
+#include "HYDROData_IAltitudeObject.h"
#include "HYDROData_Document.h"
+#include "HYDROData_ShapesGroup.h"
#include "HYDROData_Iterator.h"
#include "HYDROData_NaturalObject.h"
-#include "HYDROData_Polyline.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"
-#define PYTHON_CALCULATION_ID "KIND_CALCULATION"
+#include <GEOMBase.h>
+
+#include <QSet>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Edge.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_Sewing.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
+
+#include <BRepTools.hxx>
+
+#include <TopAbs.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopExp.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+
+//#define DEB_CALCULATION 1
+#ifdef DEB_CALCULATION
+#include <BRepTools.hxx>
+#include <TopLoc_Location.hxx>
+#endif
+#define CALCULATION_REGIONS_PREF GetName() + "_Reg"
+#define CALCULATION_ZONES_PREF GetName() + "_Zone"
+#define CALCULATION_GROUPS_PREF GetName() + "_"
+
+#define EXPORT_NAME "HYDRO_" + GetName()
IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
{
}
+void HYDROData_CalculationCase::SetName( const QString& theName )
+{
+ QString anOldCaseName = GetName();
+ if ( anOldCaseName != theName )
+ {
+ HYDROData_SequenceOfObjects aRegions = GetRegions();
+
+ HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ Handle(HYDROData_Region) aRegion =
+ Handle(HYDROData_Region)::DownCast( anIter.Value() );
+ if ( aRegion.IsNull() )
+ continue;
+
+ HYDROData_Tool::UpdateChildObjectName( anOldCaseName, theName, aRegion );
+
+ HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
+ HYDROData_SequenceOfObjects::Iterator anIter( aZones );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ Handle(HYDROData_Zone) aRegZone =
+ Handle(HYDROData_Zone)::DownCast( anIter.Value() );
+ if ( aRegZone.IsNull() )
+ continue;
+
+ HYDROData_Tool::UpdateChildObjectName( anOldCaseName, theName, aRegZone );
+ }
+ }
+
+ HYDROData_SequenceOfObjects aGroups = GetGeometryGroups();
+
+ anIter.Init( aGroups );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ Handle(HYDROData_SplittedShapesGroup) aGroup =
+ Handle(HYDROData_SplittedShapesGroup)::DownCast( anIter.Value() );
+ if ( aGroup.IsNull() )
+ continue;
+
+ HYDROData_Tool::UpdateChildObjectName( anOldCaseName, theName, aGroup );
+ }
+ }
+
+ HYDROData_Entity::SetName( theName );
+}
+
QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
{
- QStringList aResList;
+ QStringList aResList = dumpObjectCreation( theTreatedObjects );
- Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
- if ( aDocument.IsNull() )
- return aResList;
-
- QString aDocName = aDocument->GetDocPyName();
- QString aCalculName = GetName();
-
- aResList << QString( "%1 = %2.CreateObject( %3 );" )
- .arg( aCalculName ).arg( aDocName ).arg( PYTHON_CALCULATION_ID );
- aResList << QString( "%1.SetName( \"%2\" );" )
- .arg( aCalculName ).arg( aCalculName );
- aResList << QString( "" );
+ QString aCalculName = GetObjPyName();
HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
{
Handle(HYDROData_Object) aRefGeomObj =
Handle(HYDROData_Object)::DownCast( anIter.Value() );
- if ( !aRefGeomObj.IsNull() )
- setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
+ setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
}
aResList << QString( "" );
- aResList << QString( "%1.SplitGeometryObjects();" ).arg( aCalculName );
+ QString aGroupName = HYDROData_Tool::GenerateNameForPython( theTreatedObjects, "case_geom_group" );
+
+ HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups();
+ anIter.Init( aGeomGroups );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ Handle(HYDROData_ShapesGroup) aGeomGroup =
+ Handle(HYDROData_ShapesGroup)::DownCast( anIter.Value() );
+ if ( aGeomGroup.IsNull() )
+ continue;
+
+ Handle(HYDROData_Object) aFatherGeom =
+ Handle(HYDROData_Object)::DownCast( aGeomGroup->GetFatherObject() );
+ if ( aFatherGeom.IsNull() )
+ continue;
+
+ int aGroupId = aFatherGeom->GetGroupId( aGeomGroup );
+ aResList << QString( "%1 = %2.GetGroup( %3 );" )
+ .arg( aGroupName ).arg( aFatherGeom->GetObjPyName() ).arg( aGroupId );
+
+ aResList << QString( "%1.AddGeometryGroup( %2 );" ).arg( aCalculName ).arg( aGroupName );
+ }
+ aResList << QString( "" );
+
+ Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
+ setPythonReferenceObject( theTreatedObjects, aResList, aBoundaryPolyline, "SetBoundaryPolyline" );
+ aResList << QString( "" );
+
+ aResList << QString( "%1.Update();" ).arg( aCalculName );
aResList << QString( "" );
// Now we restore the regions and zones order
continue;
QString aRegionName = aRegion->GetName();
- // TODO
+
+ HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
+ HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
+ for ( ; aZonesIter.More(); aZonesIter.Next() )
+ {
+ Handle(HYDROData_Zone) aRegZone =
+ Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
+ if ( aRegZone.IsNull() )
+ continue;
+
+ // TODO
+ }
}
+ aResList << QString( "" );
return aResList;
}
-void HYDROData_CalculationCase::SplitGeometryObjects()
+HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetAllReferenceObjects() const
+{
+ HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
+
+ Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
+ if ( !aBoundaryPolyline.IsNull() )
+ aResSeq.Append( aBoundaryPolyline );
+
+ HYDROData_SequenceOfObjects aSeqOfRegions = GetRegions();
+ aResSeq.Append( aSeqOfRegions );
+
+ return aResSeq;
+}
+
+void HYDROData_CalculationCase::Update()
{
- // At first we remove previously created regions
+ HYDROData_Entity::Update();
+
+ // At first we remove previously created objects
RemoveRegions();
+ RemoveSplittedGroups();
Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
if ( aDocument.IsNull() )
return;
- Handle(HYDROData_Polyline) aBoundaryPolyline = GetBoundaryPolyline();
+ Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
if ( aGeomObjects.IsEmpty() )
return;
- HYDROData_SplitToZonesTool::SplitDataList aSplitedZones =
- HYDROData_SplitToZonesTool::SplitToZones( aGeomObjects, aBoundaryPolyline );
- if ( aSplitedZones.isEmpty() )
+ HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups();
+
+ HYDROData_SplitToZonesTool::SplitDataList aSplitedObjects =
+ HYDROData_SplitToZonesTool::Split( aGeomObjects, aGeomGroups, aBoundaryPolyline );
+ if ( aSplitedObjects.isEmpty() )
return;
+ QString aRegsPref = CALCULATION_REGIONS_PREF;
+ QString aZonesPref = CALCULATION_ZONES_PREF;
+
+ QMap<QString,Handle(HYDROData_SplittedShapesGroup)> aSplittedEdgesGroupsMap;
+
// Create result regions for case, by default one zone for one region
- HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedZones );
+ HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedObjects );
while( anIter.hasNext() )
{
const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
- // Create new region
- Handle(HYDROData_Region) aRegion = addNewRegion();
+ if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone )
+ {
+ // Create new region
+ Handle(HYDROData_Region) aRegion = addNewRegion();
+
+ QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
+ aRegion->SetName( aRegionName );
- QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, "Region" );
- aRegion->SetName( aRegionName );
+ // Add the zone for region
+ Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
- // Add the zone for region
- Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
+ QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, aZonesPref );
+ aRegionZone->SetName( aZoneName );
- QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, "Zone" );
- aRegionZone->SetName( aZoneName );
+ aRegionZone->SetShape( aSplitData.Face() );
- aRegionZone->SetShape( aSplitData.Face() );
+ // 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(
+ HYDROData_Tool::FindObjectByName( aDocument, anObjName ) );
+ if ( aRefObject.IsNull() )
+ continue;
- // Add the reference object for zone
- for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
+ aRegionZone->AddGeometryObject( aRefObject );
+ }
+ }
+ else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge )
{
- const QString& anObjName = aSplitData.ObjectNames.at( i );
-
- Handle(HYDROData_Object) aRefObject = Handle(HYDROData_Object)::DownCast(
- HYDROData_Tool::FindObjectByName( aDocument, anObjName ) );
- if ( aRefObject.IsNull() )
+ // Create new edges group
+ if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
+ continue;
+
+ QString anObjName = aSplitData.ObjectNames.first();
+ if ( anObjName.isEmpty() )
continue;
- aRegionZone->AddGeometryObject( aRefObject );
+ 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 );
}
}
-
- // The splitted data is up to date
- SetToUpdate( false );
}
bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
AddReferenceObject( theObject, DataTag_GeometryObject );
- // Indicate model of the need to update zones splitting
+ // Indicate model of the need to update splitting
SetToUpdate( true );
return true;
RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
- // Indicate model of the need to update zones splitting
+ // Indicate model of the need to update splitting
SetToUpdate( true );
}
{
ClearReferenceObjects( DataTag_GeometryObject );
- // Indicate model of the need to update zones splitting
+ // Indicate model of the need to update splitting
+ SetToUpdate( true );
+}
+
+bool HYDROData_CalculationCase::AddGeometryGroup( const Handle(HYDROData_ShapesGroup)& theGroup )
+{
+ if ( theGroup.IsNull() )
+ return false;
+
+ if ( HasReference( theGroup, DataTag_GeometryGroup ) )
+ return false; // Object is already in reference list
+
+ AddReferenceObject( theGroup, DataTag_GeometryGroup );
+
+ // Indicate model of the need to update splitting
+ SetToUpdate( true );
+
+ return true;
+}
+
+HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryGroups() const
+{
+ return GetReferenceObjects( DataTag_GeometryGroup );
+}
+
+void HYDROData_CalculationCase::RemoveGeometryGroup( const Handle(HYDROData_ShapesGroup)& theGroup )
+{
+ if ( theGroup.IsNull() )
+ return;
+
+ RemoveReferenceObject( theGroup->Label(), DataTag_GeometryGroup );
+
+ // Indicate model of the need to update splitting
+ SetToUpdate( true );
+}
+
+void HYDROData_CalculationCase::RemoveGeometryGroups()
+{
+ ClearReferenceObjects( DataTag_GeometryGroup );
+
+ // Indicate model of the need to update splitting
SetToUpdate( true );
}
-void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_Polyline)& thePolyline )
+void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
{
+ Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
+
SetReferenceObject( thePolyline, DataTag_Polyline );
+
+ // Indicate model of the need to update zones splitting
+ SetToUpdate( !IsEqual( aPrevPolyline, thePolyline ) || IsMustBeUpdated() );
}
-Handle(HYDROData_Polyline) HYDROData_CalculationCase::GetBoundaryPolyline() const
+Handle(HYDROData_PolylineXY) HYDROData_CalculationCase::GetBoundaryPolyline() const
{
- return Handle(HYDROData_Polyline)::DownCast(
+ return Handle(HYDROData_PolylineXY)::DownCast(
GetReferenceObject( DataTag_Polyline ) );
}
void HYDROData_CalculationCase::RemoveBoundaryPolyline()
{
+ Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
+
ClearReferenceObjects( DataTag_Polyline );
+
+ // Indicate model of the need to update zones splitting
+ SetToUpdate( !aPrevPolyline.IsNull() || IsMustBeUpdated() );
}
Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
if ( !aDocument.IsNull() )
{
- QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, "Region" );
+ QString aRegsPref = CALCULATION_REGIONS_PREF;
+
+ QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
aNewRegion->SetName( aNewRegionName );
}
return GetReferenceObjects( DataTag_Region );
}
+void HYDROData_CalculationCase::UpdateRegionsOrder()
+{
+ Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+ if ( aDocument.IsNull() )
+ return;
+
+ HYDROData_SequenceOfObjects aRegions = GetRegions();
+
+ HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ Handle(HYDROData_Region) aRegion =
+ Handle(HYDROData_Region)::DownCast( anIter.Value() );
+ if ( aRegion.IsNull() )
+ continue;
+
+ aRegion->SetName( "" );
+ }
+
+ QString aRegsPref = CALCULATION_REGIONS_PREF;
+
+ anIter.Init( aRegions );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ Handle(HYDROData_Region) aRegion =
+ Handle(HYDROData_Region)::DownCast( anIter.Value() );
+ if ( aRegion.IsNull() )
+ continue;
+
+ QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
+ aRegion->SetName( aRegionName );
+ }
+}
+
void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
{
if ( theRegion.IsNull() )
void HYDROData_CalculationCase::RemoveRegions()
{
- ClearReferenceObjects( DataTag_Region );
- myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes( true );
+ myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes();
+}
+
+HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetSplittedGroups() const
+{
+ return GetReferenceObjects( DataTag_SplittedGroups );
+}
+
+void HYDROData_CalculationCase::RemoveSplittedGroups()
+{
+ myLab.FindChild( DataTag_SplittedGroups ).ForgetAllAttributes();
+}
+
+double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY& thePoint ) const
+{
+ double aResAltitude = HYDROData_IAltitudeObject::GetInvalidAltitude();
+
+ Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
+ if ( aZone.IsNull() )
+ return aResAltitude;
+
+ HYDROData_Zone::MergeAltitudesType 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_IAltitudeObject) aMergeAltitude = aZone->GetMergeAltitude();
+ if ( !aMergeAltitude.IsNull() )
+ aResAltitude = aMergeAltitude->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_IAltitudeObject) anObjAltitude = aZoneObj->GetAltitudeObject();
+ if ( anObjAltitude.IsNull() )
+ continue;
+
+ double aPointAltitude = anObjAltitude->GetAltitudeForPoint( thePoint );
+ if ( ValuesEquals( aPointAltitude, HYDROData_IAltitudeObject::GetInvalidAltitude() ) )
+ continue;
+
+ if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
+ {
+ aResAltitude = aPointAltitude;
+ break;
+ }
+ else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMIN )
+ {
+ if ( ValuesEquals( aResAltitude, HYDROData_IAltitudeObject::GetInvalidAltitude() ) ||
+ aResAltitude > aPointAltitude )
+ {
+ aResAltitude = aPointAltitude;
+ }
+ }
+ else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMAX )
+ {
+ if ( ValuesEquals( aResAltitude, HYDROData_IAltitudeObject::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;
+
+ BRepTopAdaptor_FClass2d aClassifier( aZoneFace, Precision::Confusion() );
+ TopAbs_State State = aClassifier.Perform( gp_Pnt2d(thePoint), Standard_False );
+ if (State == TopAbs_OUT)
+ aRes = POINT_OUT;
+ else if(State == TopAbs_IN)
+ aRes = POINT_IN;
+ else if(State == TopAbs_ON)
+ aRes = POINT_ON;
+ return aRes;
}
Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
return aNewRegion;
}
+Handle(HYDROData_SplittedShapesGroup) HYDROData_CalculationCase::addNewSplittedGroup()
+{
+ TDF_Label aNewLab = myLab.FindChild( DataTag_SplittedGroups ).NewChild();
+
+ Handle(HYDROData_SplittedShapesGroup) aNewGroup =
+ Handle(HYDROData_SplittedShapesGroup)::DownCast(
+ HYDROData_Iterator::CreateObject( aNewLab, KIND_SPLITTED_GROUP ) );
+ AddReferenceObject( aNewGroup, DataTag_SplittedGroups );
+
+ return aNewGroup;
+}
+
+bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var theGeomEngine,
+ SALOMEDS::Study_ptr theStudy ) const
+{
+ HYDROData_ShapesGroup::SeqOfGroupsDefs aSeqOfGroupsDefs;
+
+ // Get groups definitions
+ HYDROData_SequenceOfObjects aSplittedGroups = GetSplittedGroups();
+
+ HYDROData_SequenceOfObjects::Iterator anIter( aSplittedGroups );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ // Get shapes group
+ Handle(HYDROData_ShapesGroup) aGroup =
+ Handle(HYDROData_ShapesGroup)::DownCast( anIter.Value() );
+ if ( aGroup.IsNull() )
+ continue;
+
+ HYDROData_ShapesGroup::GroupDefinition aGroupDef;
+
+ aGroupDef.Name = aGroup->GetName().toLatin1().constData();
+ aGroup->GetShapes( aGroupDef.Shapes );
+
+ aSeqOfGroupsDefs.Append( aGroupDef );
+ }
+
+ // Get faces
+ TopTools_ListOfShape aFaces;
+ HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
+ HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
+ for ( ; aRegionIter.More(); aRegionIter.Next() )
+ {
+ Handle(HYDROData_Region) aRegion =
+ Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
+ if( aRegion.IsNull() )
+ continue;
+
+ TopoDS_Shape aRegionShape = aRegion->GetShape( &aSeqOfGroupsDefs );
+ aFaces.Append( aRegionShape );
+ }
+
+ return Export( theGeomEngine, theStudy, aFaces, aSeqOfGroupsDefs );
+}
+
+bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var theGeomEngine,
+ SALOMEDS::Study_ptr theStudy,
+ const TopTools_ListOfShape& theFaces,
+ const HYDROData_ShapesGroup::SeqOfGroupsDefs& theGroupsDefs ) const
+{
+ // Sew faces
+ BRepBuilderAPI_Sewing aSewing( Precision::Confusion() * 10.0 );
+ aSewing.SetNonManifoldMode( Standard_False );
+#ifdef DEB_CALCULATION
+ TCollection_AsciiString aNam("Sh_");
+ int i=1;
+#endif
+ TopTools_ListIteratorOfListOfShape aFaceIter( theFaces );
+ for ( ; aFaceIter.More(); aFaceIter.Next() )
+ {
+ TopoDS_Shape aShape = aFaceIter.Value();
+ if ( aShape.IsNull() )
+ continue;
+
+ if ( aShape.ShapeType() == TopAbs_FACE )
+ {
+ aSewing.Add( aShape );
+#ifdef DEB_CALCULATION
+ TCollection_AsciiString aName = aNam + ++i + ".brep";
+ BRepTools::Write(aShape ,aName.ToCString());
+#endif
+ }
+ else
+ {
+#ifdef DEB_CALCULATION
+ int j = 1;
+#endif
+ TopExp_Explorer anExp( aShape, TopAbs_FACE );
+ for (; anExp.More(); anExp.Next() ) {
+ aSewing.Add( anExp.Current() );
+#ifdef DEB_CALCULATION
+
+ TCollection_AsciiString aName = aNam + i + "_" + ++j + ".brep";
+ BRepTools::Write(anExp.Current() ,aName.ToCString());
+#endif
+ }
+ }
+ } // faces iterator
+
+ aSewing.Perform();
+ TopoDS_Shape aSewedShape = aSewing.SewedShape();
+
+ // If the sewed shape is empty - return false
+ if ( aSewedShape.IsNull() || !TopoDS_Iterator( aSewedShape ).More() )
+ return false;
+
+#ifdef DEB_CALCULATION
+ BRepTools::Write(aSewedShape ,"Sew.brep");
+#endif
+ // Publish the sewed shape
+ QString aName = EXPORT_NAME;
+ GEOM::GEOM_Object_ptr aMainShape =
+ publishShapeInGEOM( theGeomEngine, theStudy, aSewedShape, aName );
+
+ if ( aMainShape->_is_nil() )
+ return false;
+
+ if ( theGroupsDefs.IsEmpty() )
+ return true;
+
+ // Create groups
+ TopTools_IndexedMapOfShape aMapOfSubShapes;
+ TopExp::MapShapes( aSewedShape, aMapOfSubShapes );
+
+ NCollection_DataMap< TCollection_AsciiString, NCollection_Sequence<int> > aGroupsData;
+
+ for ( int aGrId = 1, nbGroups = theGroupsDefs.Length(); aGrId <= nbGroups; ++aGrId )
+ {
+ const HYDROData_ShapesGroup::GroupDefinition& aGroupDef = theGroupsDefs.Value( aGrId );
+
+ NCollection_Sequence<int> aGroupIndexes;
+ for( int i = 1, n = aGroupDef.Shapes.Length(); i <= n; i++ )
+ {
+ const TopoDS_Shape& aShape = aGroupDef.Shapes.Value( i );
+#ifdef DEB_CALCULATION
+ cout << "\nOld shape(" << i << ") = " << aShape.TShape() <<endl;
+#endif
+ const TopoDS_Shape& aModifiedShape = aSewing.Modified( aShape );
+ if ( aModifiedShape.IsNull() )
+ continue;
+
+#ifdef DEB_CALCULATION
+ const TopLoc_Location& aL1 = aShape.Location();
+ const TopLoc_Location& aL2 = aModifiedShape.Location();
+ cout << "\nNew shape(" << i << ") = " << aModifiedShape.TShape() << " Location is Equal = " << aL1.IsEqual(aL2)<<endl;
+#endif
+
+ int anIndex = aMapOfSubShapes.FindIndex(aModifiedShape);
+ if ( anIndex > 0 ) {
+ aGroupIndexes.Append( anIndex );
+ } else {
+#ifdef DEB_CALCULATION
+ TCollection_AsciiString aNam("Lost_");
+ if(!aMapOfSubShapes.Contains(aModifiedShape)) {
+ for ( int anIndex = 1; anIndex <= aMapOfSubShapes.Extent(); anIndex++ )
+ {
+ const TopoDS_Shape& aS = aMapOfSubShapes.FindKey( anIndex );
+ if ( aModifiedShape.IsPartner( aS ) )
+ {
+ cout <<"\nIndex in Map = " << anIndex << "TShape = " << aS.TShape() <<endl;
+ TCollection_AsciiString aName = aNam + i + "_" + anIndex + ".brep";
+ BRepTools::Write(aS ,aName.ToCString());
+ break;
+ }
+ }
+ }
+#endif
+ }
+ }
+ if ( !aGroupIndexes.IsEmpty() )
+ aGroupsData.Bind( aGroupDef.Name, aGroupIndexes );
+ }
+
+ if ( !aGroupsData.IsEmpty() )
+ {
+ GEOM::GEOM_IGroupOperations_var aGroupOp =
+ theGeomEngine->GetIGroupOperations( theStudy->StudyId() );
+
+ NCollection_DataMap< TCollection_AsciiString, NCollection_Sequence<int> >::Iterator aMapIt( aGroupsData );
+ for ( ; aMapIt.More(); aMapIt.Next() )
+ {
+ const TCollection_AsciiString& aGroupName = aMapIt.Key();
+ const NCollection_Sequence<int>& aGroupIndexes = aMapIt.Value();
+
+ GEOM::GEOM_Object_var aGeomGroup = aGroupOp->CreateGroup( aMainShape, TopAbs_EDGE );
+ if ( CORBA::is_nil( aGeomGroup ) || !aGroupOp->IsDone() )
+ continue;
+
+ GEOM::ListOfLong_var aGeomIndexes = new GEOM::ListOfLong;
+ aGeomIndexes->length( aGroupIndexes.Length() );
+
+ for( int i = 1, n = aGroupIndexes.Length(); i <= n; i++ )
+ aGeomIndexes[ i - 1 ] = aGroupIndexes.Value( i );
+
+ aGroupOp->UnionIDs( aGeomGroup, aGeomIndexes );
+ if ( aGroupOp->IsDone() )
+ {
+ SALOMEDS::SObject_var aGroupSO =
+ theGeomEngine->AddInStudy( theStudy, aGeomGroup, aGroupName.ToCString(), aMainShape );
+ }
+ }
+ }
+
+ return true;
+}
+
+GEOM::GEOM_Object_ptr HYDROData_CalculationCase::publishShapeInGEOM(
+ GEOM::GEOM_Gen_var theGeomEngine, SALOMEDS::Study_ptr theStudy,
+ const TopoDS_Shape& theShape, const QString& theName ) const
+{
+ GEOM::GEOM_Object_var aGeomObj;
+
+ if ( theGeomEngine->_is_nil() || theStudy->_is_nil() ||
+ theShape.IsNull() ) {
+ return aGeomObj._retn();
+ }
+
+ std::ostringstream aStreamShape;
+ // Write TopoDS_Shape in ASCII format to the stream
+ BRepTools::Write( theShape, aStreamShape );
+ // Returns the number of bytes that have been stored in the stream's buffer.
+ int aSize = aStreamShape.str().size();
+ // Allocate octect buffer of required size
+ CORBA::Octet* anOctetBuf = SALOMEDS::TMPFile::allocbuf( aSize );
+ // Copy ostrstream content to the octect buffer
+ memcpy( anOctetBuf, aStreamShape.str().c_str(), aSize );
+ // Create TMPFile
+ SALOMEDS::TMPFile_var aSeqFile = new SALOMEDS::TMPFile( aSize, aSize, anOctetBuf, 1 );
+
+ // Restore shape from the stream and get the GEOM object
+ GEOM::GEOM_IInsertOperations_var anInsOp = theGeomEngine->GetIInsertOperations( theStudy->StudyId() );
+ aGeomObj = anInsOp->RestoreShape( aSeqFile );
+
+ // Puplish the GEOM object
+ if ( !aGeomObj->_is_nil() ) {
+ QString aName = GEOMBase::GetDefaultName( theName );
+
+ SALOMEDS::SObject_var aResultSO =
+ theGeomEngine->PublishInStudy( theStudy, SALOMEDS::SObject::_nil(),
+ aGeomObj, qPrintable( aName ) );
+ if ( aResultSO->_is_nil() ) {
+ aGeomObj = GEOM::GEOM_Object::_nil();
+ }
+ }
+
+ return aGeomObj._retn();
+ }