#include "HYDROData_Region.h"
-#include <QString>
+#include "HYDROData_CalculationCase.h"
+#include "HYDROData_Document.h"
+#include "HYDROData_Iterator.h"
+#include "HYDROData_Zone.h"
-#define PYTHON_REGION_ID "KIND_REGION"
+#include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopExp.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepAlgoAPI_Fuse.hxx>
+#include <ShapeUpgrade_UnifySameDomain.hxx>
+
+#include <QStringList>
+#define PYTHON_REGION_ID "KIND_REGION"
-IMPLEMENT_STANDARD_HANDLE(HYDROData_Region, HYDROData_Domain)
-IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Region, HYDROData_Domain)
+IMPLEMENT_STANDARD_HANDLE(HYDROData_Region, HYDROData_Entity)
+IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Region, HYDROData_Entity)
HYDROData_Region::HYDROData_Region()
+ : HYDROData_Entity()
{
}
{
}
-QString HYDROData_Region::getPythonKindId() const
+QStringList HYDROData_Region::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
{
- return QString( PYTHON_REGION_ID );
+ QStringList aResList;
+
+ Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+ if ( aDocument.IsNull() )
+ return aResList;
+
+ QString aDocName = aDocument->GetDocPyName();
+ QString aRegionName = GetName();
+
+ aResList << QString( "%1 = %2.CreateObject( %3 );" )
+ .arg( aRegionName ).arg( aDocName ).arg( PYTHON_REGION_ID );
+ aResList << QString( "%1.SetName( \"%2\" );" )
+ .arg( aRegionName ).arg( aRegionName );
+ aResList << QString( "" );
+
+ HYDROData_SequenceOfObjects aZones = GetZones();
+ HYDROData_SequenceOfObjects::Iterator anIter( aZones );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ Handle(HYDROData_Zone) aRefZone =
+ Handle(HYDROData_Zone)::DownCast( anIter.Value() );
+ if ( !aRefZone.IsNull() )
+ setPythonReferenceObject( theTreatedObjects, aResList, aRefZone, "AddZone" );
+ }
+ aResList << QString( "" );
+
+ return aResList;
}
+bool HYDROData_Region::CanBeUpdated() const
+{
+ return false;
+}
+
+void HYDROData_Region::Remove()
+{
+ Handle(HYDROData_CalculationCase) aFatherCalc =
+ Handle(HYDROData_CalculationCase)::DownCast( GetFatherObject() );
+
+ HYDROData_Entity::Remove();
+
+ if ( !aFatherCalc.IsNull() )
+ aFatherCalc->UpdateRegionsOrder();
+}
+bool HYDROData_Region::CanRemove()
+{
+ return false;
+}
+
+HYDROData_SequenceOfObjects HYDROData_Region::GetAllReferenceObjects() const
+{
+ HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
+
+ HYDROData_SequenceOfObjects aSeqOfZones = GetZones();
+ aResSeq.Append( aSeqOfZones );
+
+ return aResSeq;
+}
+
+bool HYDROData_Region::AddZone( const Handle(HYDROData_Zone)& theZone )
+{
+ if ( theZone.IsNull() )
+ return false;
+
+ if ( HasReference( theZone, DataTag_Zone ) )
+ return false; // Object is already in reference list
+
+ // Move the zone from other region
+ Handle(HYDROData_Region) aFatherRegion =
+ Handle(HYDROData_Region)::DownCast( theZone->GetFatherObject() );
+ if ( !aFatherRegion.IsNull() && aFatherRegion->Label() != myLab )
+ {
+ Handle(HYDROData_Zone) aNewZone = addNewZone();
+ theZone->CopyTo( aNewZone );
+
+ aFatherRegion->RemoveZone( theZone );
+
+ theZone->SetLabel( aNewZone->Label() );
+ }
+ else
+ {
+ AddReferenceObject( theZone, DataTag_Zone );
+ }
+
+ return true;
+}
+HYDROData_SequenceOfObjects HYDROData_Region::GetZones() const
+{
+ return GetReferenceObjects( DataTag_Zone );
+}
+
+void HYDROData_Region::RemoveZone( const Handle(HYDROData_Zone)& theZone )
+{
+ if ( theZone.IsNull() )
+ return;
+
+ RemoveReferenceObject( theZone->Label(), DataTag_Zone );
+
+ // Remove zone from data model
+ Handle(HYDROData_Region) aFatherRegion =
+ Handle(HYDROData_Region)::DownCast( theZone->GetFatherObject() );
+ if ( !aFatherRegion.IsNull() && aFatherRegion->Label() == myLab )
+ theZone->Remove();
+
+ // If the last zone has been removed from region we remove this region
+ HYDROData_SequenceOfObjects aRefZones = GetZones();
+ if ( aRefZones.IsEmpty() )
+ Remove();
+}
+
+void HYDROData_Region::RemoveZones()
+{
+ ClearReferenceObjects( DataTag_Zone );
+ myLab.FindChild( DataTag_ChildZone ).ForgetAllAttributes( true );
+}
+
+Handle(HYDROData_Zone) HYDROData_Region::addNewZone()
+{
+ TDF_Label aNewLab = myLab.FindChild( DataTag_ChildZone ).NewChild();
+
+ Handle(HYDROData_Zone) aNewZone =
+ Handle(HYDROData_Zone)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_ZONE ) );
+ AddZone( aNewZone );
+
+ return aNewZone;
+}
+
+TopoDS_Shape HYDROData_Region::GetShape() const
+{
+ TopoDS_Shape aResShape;
+
+ // Unite the region zones (each zone is a face) into one face (united face)
+ // If the zones can't be united into the single face - unite them into shell
+
+ // Collect the list of region faces
+ TopTools_ListOfShape aRegionFacesList;
+
+ HYDROData_SequenceOfObjects aZones = GetZones();
+ HYDROData_SequenceOfObjects::Iterator aZoneIter( aZones );
+ for ( ; aZoneIter.More(); aZoneIter.Next() ) {
+ Handle(HYDROData_Zone) aZone =
+ Handle(HYDROData_Zone)::DownCast( aZoneIter.Value() );
+
+ if ( aZone.IsNull() ) {
+ continue;
+ }
+
+ TopoDS_Face aFace = TopoDS::Face( aZone->GetShape() );
+ if ( !aFace.IsNull() ) {
+ aRegionFacesList.Append( aFace );
+ }
+ } // zones iterator
+
+ // Check number of faces
+ int aNbFaces = aRegionFacesList.Extent();
+ if ( aNbFaces > 0 ) {
+ // The unite region face
+ TopoDS_Face aRegionFace;
+
+ if ( aNbFaces == 1 ) {
+ aRegionFace = TopoDS::Face( aRegionFacesList.First() );
+ } else {
+ // Fuse faces into one
+ TopoDS_Shape aFuseShape;
+ TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList );
+ for ( ; aFaceIter.More(); aFaceIter.Next() ) {
+ if ( aFuseShape.IsNull() ) {
+ aFuseShape = aFaceIter.Value();
+ } else {
+ BRepAlgoAPI_Fuse aFuse(aFuseShape, aFaceIter.Value());
+ if ( !aFuse.IsDone() ) {
+ aFuseShape.Nullify();
+ break;
+ }
+ aFuseShape = aFuse.Shape();
+ }
+ } // faces iterator
+
+ // Check the result of fuse operation
+ if ( !aFuseShape.IsNull() ) {
+ ShapeUpgrade_UnifySameDomain anUnifier( aFuseShape );
+ anUnifier.Build();
+ TopoDS_Shape anUnitedShape = anUnifier.Shape();
+
+ TopTools_IndexedMapOfShape aMapOfFaces;
+ TopExp::MapShapes( anUnitedShape, TopAbs_FACE, aMapOfFaces );
+ if ( aMapOfFaces.Extent() == 1 ) {
+ aRegionFace = TopoDS::Face( aMapOfFaces(1) );
+ }
+ }
+ }
+
+ if ( !aRegionFace.IsNull() ) { // result shape is a face
+ aResShape = aRegionFace;
+ } else { // result shape is a shell
+ TopoDS_Shell aShell;
+ BRep_Builder aBuilder;
+ aBuilder.MakeShell( aShell );
+
+ TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList );
+ for ( ; aFaceIter.More(); aFaceIter.Next() ) {
+ aBuilder.Add( aShell, aFaceIter.Value() );
+ }
+
+ aResShape = aShell;
+ }
+ }
+
+ return aResShape;
+}