#include "HYDROData_ArtificialObject.h"
#include "HYDROData_Bathymetry.h"
#include "HYDROData_Document.h"
-#include "HYDROData_EdgesGroup.h"
+#include "HYDROData_ShapesGroup.h"
#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>
+
+#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>
-#include <BRepTopAdaptor_FClass2d.hxx>
-#include <TopAbs.hxx>
+
#define CALCULATION_REGIONS_PREF GetName() + "_Reg"
#define CALCULATION_ZONES_PREF GetName() + "_Zone"
+#define CALCULATION_GROUPS_PREF GetName() + "_"
#define PYTHON_CALCULATION_ID "KIND_CALCULATION"
+#define EXPORT_NAME "HYDRO_" + GetName()
+
IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
}
}
}
+
+ 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;
+
+ QString aGroupName = aGroup->GetName();
+ if ( aGroupName.startsWith( anOldCaseName ) )
+ {
+ aGroupName.replace( anOldCaseName, theName );
+ aGroup->SetName( aGroupName );
+ }
+ }
}
HYDROData_Entity::SetName( theName );
{
HYDROData_Entity::Update();
- // At first we remove previously created regions
+ // At first we remove previously created objects
RemoveRegions();
+ RemoveSplittedGroups();
Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
if ( aDocument.IsNull() )
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, aRegsPref );
+ 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, aZonesPref );
- 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;
- aRegionZone->AddGeometryObject( aRefObject );
+ QString anObjName = aSplitData.ObjectNames.first();
+ if ( anObjName.isEmpty() )
+ continue;
+
+ 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 );
}
}
}
SetToUpdate( true );
}
-bool HYDROData_CalculationCase::AddGeometryGroup( const Handle(HYDROData_EdgesGroup)& theGroup )
+bool HYDROData_CalculationCase::AddGeometryGroup( const Handle(HYDROData_ShapesGroup)& theGroup )
{
if ( theGroup.IsNull() )
return false;
return GetReferenceObjects( DataTag_GeometryGroup );
}
-void HYDROData_CalculationCase::RemoveGeometryGroup( const Handle(HYDROData_EdgesGroup)& theGroup )
+void HYDROData_CalculationCase::RemoveGeometryGroup( const Handle(HYDROData_ShapesGroup)& theGroup )
{
if ( theGroup.IsNull() )
return;
void HYDROData_CalculationCase::RemoveRegions()
{
- ClearReferenceObjects( DataTag_Region );
- myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes( true );
+ myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes();
}
-Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
+HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetSplittedGroups() const
{
- TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
-
- Handle(HYDROData_Region) aNewRegion =
- Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
- AddRegion( aNewRegion );
-
- return aNewRegion;
+ return GetReferenceObjects( DataTag_SplittedGroups );
}
-TopoDS_Shell HYDROData_CalculationCase::GetShell()
+void HYDROData_CalculationCase::RemoveSplittedGroups()
{
- TopoDS_Shell aShell;
-
- TopTools_ListOfShape aFacesList;
-
- // Make shell containing all region shapes
- BRepBuilderAPI_Sewing aSewing( Precision::Confusion()*10.0 );
-
- 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();
- if( !aRegionShape.IsNull() ) {
- if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
- TopoDS_Face aFace = TopoDS::Face( aRegionShape );
- if ( !aFace.IsNull() ) {
- aFacesList.Append( aFace );
- aSewing.Add( aFace );
- }
- } else {
- TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
- for ( ; anExp.More(); anExp.Next() ) {
- TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
- if ( !aFace.IsNull() ) {
- aFacesList.Append( aFace );
- aSewing.Add( aFace );
- }
- }
- }
- }
- } // regions iterator
-
- aSewing.Perform();
- TopoDS_Shape aSewedShape = aSewing.SewedShape();
-
- if ( !aSewedShape.IsNull() )
- {
- if ( aSewedShape.ShapeType() == TopAbs_FACE && aCaseRegions.Length() ==1 ) {
- // create shell from one face
- BRep_Builder aBuilder;
- aBuilder.MakeShell( aShell );
- aBuilder.Add( aShell, aSewedShape);
- } else {
- TopExp_Explorer anExpShells( aSewedShape, TopAbs_SHELL );
- Standard_Integer aNbOfShells = 0;
- for ( ; anExpShells.More(); anExpShells.Next() ) {
- aShell = TopoDS::Shell( anExpShells.Current() );
- aNbOfShells++;
- }
-
- if ( aNbOfShells != 1 ) {
- aShell.Nullify();
- BRep_Builder aBuilder;
- aBuilder.MakeShell( aShell );
-
- TopExp_Explorer anExpFaces( aSewedShape, TopAbs_FACE );
- for ( ; anExpFaces.More(); anExpFaces.Next() ) {
- TopoDS_Face aFace = TopoDS::Face( anExpFaces.Current() );
- if ( !aFace.IsNull() ) {
- aBuilder.Add( aShell, aFace );
- }
- }
- }
- }
- }
-
- if ( !aShell.IsNull() ) {
- TopTools_IndexedMapOfShape aMapOfFaces;
- TopExp::MapShapes( aShell, TopAbs_FACE, aMapOfFaces );
- if ( aMapOfFaces.Extent() != aFacesList.Extent() ) {
- aShell.Nullify();
- BRep_Builder aBuilder;
- aBuilder.MakeShell( aShell );
-
- TopTools_ListIteratorOfListOfShape anIter( aFacesList );
- for ( ; anIter.More(); anIter.Next() ) {
- TopoDS_Face aFace = TopoDS::Face( anIter.Value() );
- aBuilder.Add( aShell, aFace );
- }
- }
- }
-
-/* TODO: old version
- // Make shell
- BRep_Builder aBuilder;
- aBuilder.MakeShell( aShell );
-
- // Make shell containing all region shapes
- 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();
-
- // Add shape (face or shell) corresponding to the region into the shell
- if( !aRegionShape.IsNull() ) {
- if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
- aBuilder.Add( aShell, aRegionShape );
- } else {
- TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
- for( ; anExp.More(); anExp.Next() ) {
- TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
- if( !aFace.IsNull() ) {
- aBuilder.Add( aShell, aFace );
- }
- }
- }
- }
- } // regions iterator
-*/
-
- // Nullify shell if it is empty
- if ( !aShell.IsNull() && !TopoDS_Iterator(aShell).More() ) {
- aShell.Nullify();
- }
-
- return aShell;
+ myLab.FindChild( DataTag_SplittedGroups ).ForgetAllAttributes();
}
double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY& thePoint ) const
return aResZone;
}
+
HYDROData_CalculationCase::PointClassification HYDROData_CalculationCase::GetPointClassification(
const gp_XY& thePoint,
const Handle(HYDROData_Zone)& theZone ) const
aRes = POINT_ON;
return aRes;
}
+
+Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
+{
+ TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
+
+ Handle(HYDROData_Region) aNewRegion =
+ Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
+ AddRegion( aNewRegion );
+
+ 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 )
+{
+ // Get faces
+ // TODO to be revised
+ 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();
+ aFaces.Append( aRegionShape );
+ }
+
+ // Get groups
+ // TODO to be revised
+ HYDROData_SequenceOfObjects aSplittedGroups = GetSplittedGroups();
+
+ return Export( theGeomEngine, theStudy, aFaces, aSplittedGroups );
+}
+
+bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var theGeomEngine,
+ SALOMEDS::Study_ptr theStudy,
+ const TopTools_ListOfShape& theFaces,
+ const HYDROData_SequenceOfObjects& theSplittedGroups )
+{
+ // Sew faces
+ BRepBuilderAPI_Sewing aSewing( Precision::Confusion()*10.0 );
+ aSewing.SetNonManifoldMode( Standard_True );
+
+ TopTools_ListIteratorOfListOfShape aFaceIter( theFaces );
+ for ( ; aFaceIter.More(); aFaceIter.Next() ) {
+ TopoDS_Shape aShape = aFaceIter.Value();
+ if ( !aShape.IsNull() && (aShape.ShapeType() == TopAbs_FACE) ) {
+ TopoDS_Face aFace = TopoDS::Face( aShape );
+ if ( !aFace.IsNull() ) {
+ aSewing.Add( aFace );
+ }
+ } else {
+ TopExp_Explorer anExp( aShape, TopAbs_FACE );
+ for ( ; anExp.More(); anExp.Next() ) {
+ TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
+ if ( !aFace.IsNull() ) {
+ aSewing.Add( aFace );
+ }
+ }
+ }
+ } // 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;
+ }
+
+ // Publish the sewed shape
+ QString aName = EXPORT_NAME;
+ GEOM::GEOM_Object_ptr aMainShape =
+ publishShapeInGEOM( theGeomEngine, theStudy, aSewedShape, aName );
+
+ if ( aMainShape->_is_nil() ) {
+ return false;
+ }
+
+ // Create groups
+ TopTools_IndexedMapOfShape aMapOfSubShapes;
+ TopExp::MapShapes( aSewedShape, aMapOfSubShapes );
+
+ QHash<QString, QSet<int> > aGroupsData;
+
+ HYDROData_SequenceOfObjects::Iterator anIter( theSplittedGroups );
+ for ( ; anIter.More(); anIter.Next() ) {
+ // Get shapes group
+ Handle(HYDROData_ShapesGroup) aGroup =
+ Handle(HYDROData_ShapesGroup)::DownCast( anIter.Value() );
+ if ( aGroup.IsNull() ) {
+ continue;
+ }
+
+ QSet<int> anIndexes;
+
+ // Get shapes of the group
+ TopTools_SequenceOfShape aShapes;
+ aGroup->GetShapes( aShapes );
+ for( int i = 1, aNbShapes = aShapes.Length(); i <= aNbShapes; i++ ) {
+ const TopoDS_Shape& aShape = aShapes.Value( i );
+ const TopoDS_Shape ModifiedShape = aSewing.Modified( aShape );
+ if ( !ModifiedShape.IsNull() ) {
+ int anIndex = aMapOfSubShapes.FindIndex( ModifiedShape );
+ if ( anIndex > 0 ) {
+ anIndexes << anIndex;
+ }
+ }
+ }
+
+ if ( anIndexes.count() > 0 ) {
+ aGroupsData.insert( aGroup->GetName(), anIndexes );
+ }
+ }
+
+ GEOM::GEOM_IGroupOperations_var aGroupOp =
+ theGeomEngine->GetIGroupOperations( theStudy->StudyId() );
+
+ foreach ( const QString& aGroupName, aGroupsData.keys() ) {
+ QSet<int> aGroupIndexes = aGroupsData.value( aGroupName );
+
+ GEOM::GEOM_Object_var aGroup = aGroupOp->CreateGroup( aMainShape, TopAbs_EDGE );
+ if ( !CORBA::is_nil(aGroup) && aGroupOp->IsDone() ) {
+ GEOM::ListOfLong_var anIndexes = new GEOM::ListOfLong;
+ int aListIndex = 0;
+ foreach ( const int anIndex, aGroupIndexes ) {
+ anIndexes[aListIndex++] = anIndex;
+ }
+
+ aGroupOp->UnionIDs( aGroup, anIndexes );
+ if ( aGroupOp->IsDone() ) {
+ SALOMEDS::SObject_var aGroupSO =
+ theGeomEngine->AddInStudy( theStudy, aGroup, qPrintable( aName ), 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 )
+{
+ 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( theName ) );
+ if ( aResultSO->_is_nil() ) {
+ aGeomObj = GEOM::GEOM_Object::_nil();
+ }
+ }
+
+ return aGeomObj._retn();
+ }