X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_Region.cxx;h=ac6a4f757ca6b2ed550d0f98e7b3085005363f74;hb=81c9f5cdf82909d0aebd2c491c50fa7516cc80b7;hp=7f4fae7a41224cdc8258ca42ce07eb77c5c95faf;hpb=b2793422d30042c499edd45b1a13e1b38f9189dd;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_Region.cxx b/src/HYDROData/HYDROData_Region.cxx index 7f4fae7a..ac6a4f75 100644 --- a/src/HYDROData/HYDROData_Region.cxx +++ b/src/HYDROData/HYDROData_Region.cxx @@ -1,15 +1,32 @@ #include "HYDROData_Region.h" +#include "HYDROData_CalculationCase.h" #include "HYDROData_Document.h" #include "HYDROData_Iterator.h" +#include "HYDROData_ShapesTool.h" #include "HYDROData_Zone.h" -#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include -#include +#include -#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) @@ -18,107 +35,72 @@ IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Region, HYDROData_Entity) HYDROData_Region::HYDROData_Region() : HYDROData_Entity() { - SetMergeType( Merge_ZMIN ); } HYDROData_Region::~HYDROData_Region() { } -QStringList HYDROData_Region::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const +bool HYDROData_Region::CanBeUpdated() const { - QStringList aResList; - - Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( this ); - 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; } -Handle(HYDROData_Zone) HYDROData_Region::AddNewZone() +void HYDROData_Region::Remove() { - TDF_Label aNewLab = myLab.FindChild( ChildTag_Zone ).NewChild(); + Handle(HYDROData_CalculationCase) aFatherCalc = + Handle(HYDROData_CalculationCase)::DownCast( GetFatherObject() ); - return Handle(HYDROData_Zone)::DownCast( - HYDROData_Iterator::CreateObject( aNewLab, KIND_ZONE ) ); -} + HYDROData_Entity::Remove(); -void HYDROData_Region::RemoveChildZones() -{ - myLab.FindChild( ChildTag_Zone ).ForgetAllAttributes( true ); + if ( !aFatherCalc.IsNull() ) + aFatherCalc->UpdateRegionsOrder(); } -void HYDROData_Region::SetMergeType( const MergeBathymetriesType& theType ) +bool HYDROData_Region::CanRemove() { - Handle(TDataStd_Integer) anInt; - if ( !myLab.FindChild( DataTag_MergeType ).FindAttribute( TDataStd_Integer::GetID(), anInt ) ) - anInt = TDataStd_Integer::Set( myLab, 0 ); - anInt->Set( (int)theType ); + return false; } -HYDROData_Region::MergeBathymetriesType HYDROData_Region::GetMergeType() const +HYDROData_SequenceOfObjects HYDROData_Region::GetAllReferenceObjects() const { - MergeBathymetriesType aMergeType = Merge_ZMIN; - - Handle(TDataStd_Integer) anInt; - if ( myLab.FindChild( DataTag_MergeType ).FindAttribute( TDataStd_Integer::GetID(), anInt ) ) - aMergeType = (MergeBathymetriesType)anInt->Get(); + HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects(); - return aMergeType; -} + HYDROData_SequenceOfObjects aSeqOfZones = GetZones(); + aResSeq.Append( aSeqOfZones ); -int HYDROData_Region::NbZones() const -{ - return NbReferenceObjects( DataTag_Zone ); + return aResSeq; } -void HYDROData_Region::AddZone( const Handle(HYDROData_Zone)& theZone ) +bool HYDROData_Region::AddZone( const Handle(HYDROData_Zone)& theZone ) { - AddReferenceObject( theZone, DataTag_Zone ); -} + if ( theZone.IsNull() ) + return false; + + if ( HasReference( theZone, DataTag_Zone ) ) + return false; // Object is already in reference list -void HYDROData_Region::SetZone( const int theIndex, - const Handle(HYDROData_Zone)& theZone ) -{ - SetReferenceObject( theZone, DataTag_Zone, theIndex ); -} + // 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 ); -void HYDROData_Region::InsertZone( const int theBeforeIndex, - const Handle(HYDROData_Zone)& theZone ) -{ - InsertReferenceObject( theZone, DataTag_Zone, theBeforeIndex ); -} + // To prevent changing of stored shape + aNewZone->SetShape( theZone->GetShape() ); -void HYDROData_Region::SetZones( const HYDROData_SequenceOfObjects& theZones ) -{ - SetReferenceObjects( theZones, DataTag_Zone ); -} + aFatherRegion->RemoveZone( theZone ); -Handle(HYDROData_Zone) HYDROData_Region::GetZone( const int theIndex ) const -{ - return Handle(HYDROData_Zone)::DownCast( - GetReferenceObject( DataTag_Zone, theIndex ) ); + theZone->SetLabel( aNewZone->Label() ); + } + else + { + AddReferenceObject( theZone, DataTag_Zone ); + } + + return true; } HYDROData_SequenceOfObjects HYDROData_Region::GetZones() const @@ -132,16 +114,236 @@ void HYDROData_Region::RemoveZone( const Handle(HYDROData_Zone)& theZone ) return; RemoveReferenceObject( theZone->Label(), DataTag_Zone ); -} -void HYDROData_Region::RemoveZone( const int theIndex ) -{ - RemoveReferenceObject( DataTag_Zone, theIndex ); + // 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; +} + +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) + // 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_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 + + 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; + } + } + + *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 ); + + TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList ); + for ( ; aFaceIter.More(); aFaceIter.Next() ) + aBuilder.Add( aShell, aFaceIter.Value() ); + + aResShape = aShell; + } + + return aResShape; +}