2 #include "HYDROData_Region.h"
4 #include "HYDROData_CalculationCase.h"
5 #include "HYDROData_Document.h"
6 #include "HYDROData_Iterator.h"
7 #include "HYDROData_Zone.h"
10 #include <TopoDS_Shape.hxx>
11 #include <TopoDS_Shell.hxx>
12 #include <TopoDS_Face.hxx>
13 #include <TopTools_ListOfShape.hxx>
14 #include <TopTools_ListIteratorOfListOfShape.hxx>
15 #include <TopTools_IndexedMapOfShape.hxx>
17 #include <BRep_Builder.hxx>
18 #include <BRepAlgoAPI_Fuse.hxx>
19 #include <ShapeUpgrade_UnifySameDomain.hxx>
21 #include <QStringList>
23 #define PYTHON_REGION_ID "KIND_REGION"
25 IMPLEMENT_STANDARD_HANDLE(HYDROData_Region, HYDROData_Entity)
26 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Region, HYDROData_Entity)
29 HYDROData_Region::HYDROData_Region()
34 HYDROData_Region::~HYDROData_Region()
38 QStringList HYDROData_Region::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
42 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
43 if ( aDocument.IsNull() )
46 QString aDocName = aDocument->GetDocPyName();
47 QString aRegionName = GetName();
49 aResList << QString( "%1 = %2.CreateObject( %3 );" )
50 .arg( aRegionName ).arg( aDocName ).arg( PYTHON_REGION_ID );
51 aResList << QString( "%1.SetName( \"%2\" );" )
52 .arg( aRegionName ).arg( aRegionName );
53 aResList << QString( "" );
55 HYDROData_SequenceOfObjects aZones = GetZones();
56 HYDROData_SequenceOfObjects::Iterator anIter( aZones );
57 for ( ; anIter.More(); anIter.Next() )
59 Handle(HYDROData_Zone) aRefZone =
60 Handle(HYDROData_Zone)::DownCast( anIter.Value() );
61 if ( !aRefZone.IsNull() )
62 setPythonReferenceObject( theTreatedObjects, aResList, aRefZone, "AddZone" );
64 aResList << QString( "" );
69 bool HYDROData_Region::CanBeUpdated() const
74 void HYDROData_Region::Remove()
76 Handle(HYDROData_CalculationCase) aFatherCalc =
77 Handle(HYDROData_CalculationCase)::DownCast( GetFatherObject() );
79 HYDROData_Entity::Remove();
81 if ( !aFatherCalc.IsNull() )
82 aFatherCalc->UpdateRegionsOrder();
85 bool HYDROData_Region::CanRemove()
90 HYDROData_SequenceOfObjects HYDROData_Region::GetAllReferenceObjects() const
92 HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
94 HYDROData_SequenceOfObjects aSeqOfZones = GetZones();
95 aResSeq.Append( aSeqOfZones );
100 bool HYDROData_Region::AddZone( const Handle(HYDROData_Zone)& theZone )
102 if ( theZone.IsNull() )
105 if ( HasReference( theZone, DataTag_Zone ) )
106 return false; // Object is already in reference list
108 // Move the zone from other region
109 Handle(HYDROData_Region) aFatherRegion =
110 Handle(HYDROData_Region)::DownCast( theZone->GetFatherObject() );
111 if ( !aFatherRegion.IsNull() && aFatherRegion->Label() != myLab )
113 Handle(HYDROData_Zone) aNewZone = addNewZone();
114 theZone->CopyTo( aNewZone );
116 aFatherRegion->RemoveZone( theZone );
118 theZone->SetLabel( aNewZone->Label() );
122 AddReferenceObject( theZone, DataTag_Zone );
128 HYDROData_SequenceOfObjects HYDROData_Region::GetZones() const
130 return GetReferenceObjects( DataTag_Zone );
133 void HYDROData_Region::RemoveZone( const Handle(HYDROData_Zone)& theZone )
135 if ( theZone.IsNull() )
138 RemoveReferenceObject( theZone->Label(), DataTag_Zone );
140 // Remove zone from data model
141 Handle(HYDROData_Region) aFatherRegion =
142 Handle(HYDROData_Region)::DownCast( theZone->GetFatherObject() );
143 if ( !aFatherRegion.IsNull() && aFatherRegion->Label() == myLab )
146 // If the last zone has been removed from region we remove this region
147 HYDROData_SequenceOfObjects aRefZones = GetZones();
148 if ( aRefZones.IsEmpty() )
152 void HYDROData_Region::RemoveZones()
154 ClearReferenceObjects( DataTag_Zone );
155 myLab.FindChild( DataTag_ChildZone ).ForgetAllAttributes( true );
158 Handle(HYDROData_Zone) HYDROData_Region::addNewZone()
160 TDF_Label aNewLab = myLab.FindChild( DataTag_ChildZone ).NewChild();
162 Handle(HYDROData_Zone) aNewZone =
163 Handle(HYDROData_Zone)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_ZONE ) );
169 TopoDS_Shape HYDROData_Region::GetShape() const
171 TopoDS_Shape aResShape;
173 // Unite the region zones (each zone is a face) into one face (united face)
174 // If the zones can't be united into the single face - unite them into shell
176 // Collect the list of region faces
177 TopTools_ListOfShape aRegionFacesList;
179 HYDROData_SequenceOfObjects aZones = GetZones();
180 HYDROData_SequenceOfObjects::Iterator aZoneIter( aZones );
181 for ( ; aZoneIter.More(); aZoneIter.Next() ) {
182 Handle(HYDROData_Zone) aZone =
183 Handle(HYDROData_Zone)::DownCast( aZoneIter.Value() );
185 if ( aZone.IsNull() ) {
189 TopoDS_Face aFace = TopoDS::Face( aZone->GetShape() );
190 if ( !aFace.IsNull() ) {
191 aRegionFacesList.Append( aFace );
195 // Check number of faces
196 int aNbFaces = aRegionFacesList.Extent();
197 if ( aNbFaces > 0 ) {
198 // The unite region face
199 TopoDS_Face aRegionFace;
201 if ( aNbFaces == 1 ) {
202 aRegionFace = TopoDS::Face( aRegionFacesList.First() );
204 // Fuse faces into one
205 TopoDS_Shape aFuseShape;
206 TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList );
207 for ( ; aFaceIter.More(); aFaceIter.Next() ) {
208 if ( aFuseShape.IsNull() ) {
209 aFuseShape = aFaceIter.Value();
211 BRepAlgoAPI_Fuse aFuse(aFuseShape, aFaceIter.Value());
212 if ( !aFuse.IsDone() ) {
213 aFuseShape.Nullify();
216 aFuseShape = aFuse.Shape();
220 // Check the result of fuse operation
221 if ( !aFuseShape.IsNull() ) {
222 ShapeUpgrade_UnifySameDomain anUnifier( aFuseShape );
224 TopoDS_Shape anUnitedShape = anUnifier.Shape();
226 TopTools_IndexedMapOfShape aMapOfFaces;
227 TopExp::MapShapes( anUnitedShape, TopAbs_FACE, aMapOfFaces );
228 if ( aMapOfFaces.Extent() == 1 ) {
229 aRegionFace = TopoDS::Face( aMapOfFaces(1) );
234 if ( !aRegionFace.IsNull() ) { // result shape is a face
235 aResShape = aRegionFace;
236 } else { // result shape is a shell
238 BRep_Builder aBuilder;
239 aBuilder.MakeShell( aShell );
241 TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList );
242 for ( ; aFaceIter.More(); aFaceIter.Next() ) {
243 aBuilder.Add( aShell, aFaceIter.Value() );