#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>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Face.hxx>
+
+#include <TopExp.hxx>
+
#include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.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"
+//#define DEB_GET_REGION_SHAPE
IMPLEMENT_STANDARD_HANDLE(HYDROData_Region, HYDROData_Entity)
IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Region, HYDROData_Entity)
{
}
-QStringList HYDROData_Region::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
+bool HYDROData_Region::CanBeUpdated() const
{
- 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;
+ return false;
}
void HYDROData_Region::Remove()
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 )
{
+ Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+
if ( theZone.IsNull() )
return false;
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
+ aNewZone->SetShape( theZone->GetShape() );
+
aFatherRegion->RemoveZone( theZone );
theZone->SetLabel( aNewZone->Label() );
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();
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;
}
-TopoDS_Shape HYDROData_Region::GetShape() const
+void getUsedGroups( const TopoDS_Shape& theShape,
+ HYDROData_ShapesGroup::SeqOfGroupsDefs& theOriGroups,
+ HYDROData_ShapesGroup::SeqOfGroupsDefs& theUsedGroups )
+{
+#ifdef DEB_GET_REGION_SHAPE
+ HYDROData_ShapesTool::DumpShapeSubShapes( std::cout, "Zone face edges:", theShape, TopAbs_EDGE );
+#endif
+
+ TopTools_IndexedMapOfShape aMapOfSubShapes;
+ TopExp::MapShapes( theShape, TopAbs_EDGE, aMapOfSubShapes );
+
+ HYDROData_ShapesGroup::SeqOfGroupsDefs::Iterator anIter( theOriGroups );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ HYDROData_ShapesGroup::GroupDefinition& anOriGroupDef = anIter.ChangeValue();
+ if ( anOriGroupDef.Shapes.IsEmpty() )
+ continue;
+
+ for ( int i = 1; i <= anOriGroupDef.Shapes.Length(); ++i )
+ {
+ TopoDS_Shape aGroupEdge = anOriGroupDef.Shapes.Value( i );
+
+ int aShapeIndex = aMapOfSubShapes.FindIndex( aGroupEdge );
+ if ( aShapeIndex <= 0 )
+ continue;
+
+ anOriGroupDef.Shapes.Remove( i );
+ --i;
+
+ bool anIsAdded = false;
+
+ HYDROData_ShapesGroup::SeqOfGroupsDefs::Iterator aUsedIter( theUsedGroups );
+ for ( ; aUsedIter.More(); aUsedIter.Next() )
+ {
+ HYDROData_ShapesGroup::GroupDefinition& aUsedGroupDef = aUsedIter.ChangeValue();
+ if ( aUsedGroupDef.Name != anOriGroupDef.Name )
+ continue;
+
+ aUsedGroupDef.Shapes.Append( aGroupEdge );
+ anIsAdded = true;
+ break;
+ }
+
+ if ( !anIsAdded )
+ {
+ HYDROData_ShapesGroup::GroupDefinition aUsedGroupDef;
+ aUsedGroupDef.Name = anOriGroupDef.Name;
+ aUsedGroupDef.Shapes.Append( aGroupEdge );
+ theUsedGroups.Append( aUsedGroupDef );
+ }
+ }
+ }
+}
+
+TopoDS_Shape HYDROData_Region::GetShape( HYDROData_ShapesGroup::SeqOfGroupsDefs* theSeqOfGroups ) const
{
+ HYDROData_ShapesGroup::SeqOfGroupsDefs aSeqOfGroups;
+ HYDROData_ShapesGroup::SeqOfGroupsDefs aSeqOfUsedGroups;
+ if ( theSeqOfGroups )
+ aSeqOfGroups = *theSeqOfGroups;
+
+#ifdef DEB_GET_REGION_SHAPE
+ HYDROData_ShapesGroup::GroupDefinition::Dump( std::cout, aSeqOfGroups );
+#endif
+
TopoDS_Shape aResShape;
// Unite the region zones (each zone is a face) into one face (united face)
HYDROData_SequenceOfObjects aZones = GetZones();
HYDROData_SequenceOfObjects::Iterator aZoneIter( aZones );
- for ( ; aZoneIter.More(); aZoneIter.Next() ) {
+ for ( ; aZoneIter.More(); aZoneIter.Next() )
+ {
Handle(HYDROData_Zone) aZone =
Handle(HYDROData_Zone)::DownCast( aZoneIter.Value() );
-
- if ( aZone.IsNull() ) {
+ if ( aZone.IsNull() )
continue;
- }
- TopoDS_Face aFace = TopoDS::Face( aZone->GetShape() );
- if ( !aFace.IsNull() ) {
- aRegionFacesList.Append( aFace );
- }
+ TopoDS_Shape aZoneShape = aZone->GetShape();
+ if ( aZoneShape.IsNull() || aZoneShape.ShapeType() != TopAbs_FACE )
+ continue;
+
+ TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
+ aRegionFacesList.Append( aZoneFace );
+
+ getUsedGroups( aZoneFace, aSeqOfGroups, aSeqOfUsedGroups );
} // 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;
+ if ( aRegionFacesList.IsEmpty() )
+ return aResShape;
+
+ // The unite region face
+ TopoDS_Face aRegionFace;
+
+ if ( aRegionFacesList.Extent() == 1 )
+ {
+ aRegionFace = TopoDS::Face( aRegionFacesList.First() );
+ }
+ else
+ {
+#ifdef DEB_GET_REGION_SHAPE
+ HYDROData_ShapesGroup::GroupDefinition::Dump( std::cout, aSeqOfUsedGroups );
+#endif
+
+ // Try to fuse all region faces into one common face
+ TopoDS_Shape aFuseShape;
+ TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList );
+ for ( ; aFaceIter.More(); aFaceIter.Next() )
+ {
+ if ( aFuseShape.IsNull() )
+ {
+ aFuseShape = aFaceIter.Value();
+ continue;
+ }
+
+ BRepAlgoAPI_Fuse aFuse( aFuseShape, aFaceIter.Value() );
+ if ( !aFuse.IsDone() )
+ {
+ aFuseShape.Nullify();
+ break;
+ }
+
+ aFuseShape = aFuse.Shape();
+ HYDROData_ShapesGroup::GroupDefinition::Update( &aSeqOfUsedGroups, &aFuse );
+ } // faces iterator
+
+#ifdef DEB_GET_REGION_SHAPE
+ HYDROData_ShapesTool::DumpShapeSubShapes( std::cout, "Fused face edges:", aFuseShape, TopAbs_EDGE );
+#endif
+
+ // Check the result of fuse operation
+ if ( !aFuseShape.IsNull() )
+ {
+ ShapeUpgrade_UnifySameDomain anUnifier( aFuseShape );
+ anUnifier.Build();
+
+ const TopoDS_Shape& anUnitedShape = anUnifier.Shape();
+
+ TopTools_SequenceOfShape aShapeFaces;
+ HYDROData_ShapesTool::ExploreShapeToShapes( anUnitedShape, TopAbs_FACE, aShapeFaces );
+ if ( aShapeFaces.Length() == 1 )
+ {
+ aRegionFace = TopoDS::Face( aShapeFaces.Value( 1 ) );
+
+#ifdef DEB_GET_REGION_SHAPE
+ HYDROData_ShapesTool::DumpShapeSubShapes( std::cout, "Result face edges:", aRegionFace, TopAbs_EDGE );
+#endif
+
+ HYDROData_ShapesGroup::GroupDefinition::Update( &aSeqOfUsedGroups, &anUnifier );
+
+ // Update the sequence of groups
+ if ( theSeqOfGroups )
+ {
+ HYDROData_ShapesGroup::SeqOfGroupsDefs::Iterator aUsedIter( aSeqOfUsedGroups );
+ for ( ; aUsedIter.More(); aUsedIter.Next() )
+ {
+ const HYDROData_ShapesGroup::GroupDefinition& aUsedGroupDef = aUsedIter.Value();
+ if ( aUsedGroupDef.Shapes.IsEmpty() )
+ continue;
+
+ HYDROData_ShapesGroup::SeqOfGroupsDefs::Iterator anOriIter( aSeqOfGroups );
+ for ( ; anOriIter.More(); anOriIter.Next() )
+ {
+ HYDROData_ShapesGroup::GroupDefinition& anOriGroupDef = anOriIter.ChangeValue();
+ if ( anOriGroupDef.Name != aUsedGroupDef.Name )
+ continue;
+
+ HYDROData_ShapesTool::AddShapes( anOriGroupDef.Shapes, aUsedGroupDef.Shapes );
+ 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) );
+
+ *theSeqOfGroups = aSeqOfGroups;
}
}
}
+ }
- 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 );
+ 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() );
- }
+ TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList );
+ for ( ; aFaceIter.More(); aFaceIter.Next() )
+ aBuilder.Add( aShell, aFaceIter.Value() );
- aResShape = aShell;
- }
+ aResShape = aShell;
}
return aResShape;
}
+
+QStringList HYDROData_Region::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
+{
+ QStringList aResList;
+
+ // Find region
+ findPythonReferenceObject( theTreatedObjects, aResList );
+
+ // Add zones
+ HYDROData_SequenceOfObjects aZones = GetZones();
+ HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
+ for ( ; aZonesIter.More(); aZonesIter.Next() ) {
+ Handle(HYDROData_Zone) aZone =
+ Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
+ if ( aZone.IsNull() ) {
+ continue;
+ }
+
+ // find zone
+ aZone->findPythonReferenceObject( theTreatedObjects, aResList );
+ theTreatedObjects.insert( aZone->GetName(), aZone );
+
+ // set zone merge type
+ QString aMergeTypeStr;
+ HYDROData_Zone::MergeAltitudesType aMergeType = aZone->GetMergeType();
+ if ( aMergeType == HYDROData_Zone::Merge_ZMIN ) {
+ aMergeTypeStr = "HYDROData_Zone.Merge_ZMIN";
+ } else if ( aMergeType == HYDROData_Zone::Merge_ZMAX ) {
+ aMergeTypeStr = "HYDROData_Zone.Merge_ZMAX";
+ } else if ( aMergeType == HYDROData_Zone::Merge_Object ) {
+ aMergeTypeStr = "HYDROData_Zone.Merge_Object";
+ }
+
+ if ( !aMergeTypeStr.isEmpty() ) {
+ aResList << QString( "%1.SetMergeType( %2 )" ).arg( aZone->GetObjPyName() ).arg( aMergeTypeStr );
+ }
+ if ( aMergeType == HYDROData_Zone::Merge_Object ) {
+ Handle(HYDROData_IAltitudeObject) aMergeAltitude = aZone->GetMergeAltitude();
+ if ( !aMergeAltitude.IsNull() ) {
+ aMergeAltitude->findPythonReferenceObject( theTreatedObjects, aResList );
+ aResList << QString( "%1.SetMergeAltitude( %2 )" ).arg( aZone->GetObjPyName() )
+ .arg( aMergeAltitude->GetObjPyName() );
+ }
+ }
+
+ // add zone
+ setPythonReferenceObject( theTreatedObjects, aResList, aZone, "AddZone" );
+ }
+
+ return aResList;
+}
\ No newline at end of file