2 #include "HYDROData_Region.h"
4 #include "HYDROData_CalculationCase.h"
5 #include "HYDROData_Document.h"
6 #include "HYDROData_Iterator.h"
7 #include "HYDROData_ShapesTool.h"
8 #include "HYDROData_Zone.h"
11 #include <TopoDS_Shape.hxx>
12 #include <TopoDS_Shell.hxx>
13 #include <TopoDS_Face.hxx>
17 #include <TopTools_ListOfShape.hxx>
18 #include <TopTools_SequenceOfShape.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
20 #include <TopTools_IndexedMapOfShape.hxx>
22 #include <BRep_Builder.hxx>
23 #include <BRepAlgoAPI_Fuse.hxx>
25 #include <ShapeUpgrade_UnifySameDomain.hxx>
27 #include <QStringList>
29 //#define DEB_GET_REGION_SHAPE
31 IMPLEMENT_STANDARD_HANDLE(HYDROData_Region, HYDROData_Entity)
32 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Region, HYDROData_Entity)
35 HYDROData_Region::HYDROData_Region()
40 HYDROData_Region::~HYDROData_Region()
44 QStringList HYDROData_Region::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
46 QStringList aResList = dumpObjectCreation( theTreatedObjects );
47 QString aRegionName = GetName();
49 HYDROData_SequenceOfObjects aZones = GetZones();
50 HYDROData_SequenceOfObjects::Iterator anIter( aZones );
51 for ( ; anIter.More(); anIter.Next() )
53 Handle(HYDROData_Zone) aRefZone =
54 Handle(HYDROData_Zone)::DownCast( anIter.Value() );
55 if ( !aRefZone.IsNull() )
56 setPythonReferenceObject( theTreatedObjects, aResList, aRefZone, "AddZone" );
59 aResList << QString( "" );
60 aResList << QString( "%1.Update();" ).arg( aRegionName );
61 aResList << QString( "" );
66 bool HYDROData_Region::CanBeUpdated() const
71 void HYDROData_Region::Remove()
73 Handle(HYDROData_CalculationCase) aFatherCalc =
74 Handle(HYDROData_CalculationCase)::DownCast( GetFatherObject() );
76 HYDROData_Entity::Remove();
78 if ( !aFatherCalc.IsNull() )
79 aFatherCalc->UpdateRegionsOrder();
82 bool HYDROData_Region::CanRemove()
87 HYDROData_SequenceOfObjects HYDROData_Region::GetAllReferenceObjects() const
89 HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
91 HYDROData_SequenceOfObjects aSeqOfZones = GetZones();
92 aResSeq.Append( aSeqOfZones );
97 bool HYDROData_Region::AddZone( const Handle(HYDROData_Zone)& theZone )
99 if ( theZone.IsNull() )
102 if ( HasReference( theZone, DataTag_Zone ) )
103 return false; // Object is already in reference list
105 // Move the zone from other region
106 Handle(HYDROData_Region) aFatherRegion =
107 Handle(HYDROData_Region)::DownCast( theZone->GetFatherObject() );
108 if ( !aFatherRegion.IsNull() && aFatherRegion->Label() != myLab )
110 Handle(HYDROData_Zone) aNewZone = addNewZone();
111 theZone->CopyTo( aNewZone );
113 // To prevent changing of stored shape
114 aNewZone->SetShape( theZone->GetShape() );
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 void getUsedGroups( const TopoDS_Shape& theShape,
170 HYDROData_ShapesGroup::SeqOfGroupsDefs& theOriGroups,
171 HYDROData_ShapesGroup::SeqOfGroupsDefs& theUsedGroups )
173 #ifdef DEB_GET_REGION_SHAPE
174 HYDROData_ShapesTool::DumpShapeSubShapes( std::cout, "Zone face edges:", theShape, TopAbs_EDGE );
177 TopTools_IndexedMapOfShape aMapOfSubShapes;
178 TopExp::MapShapes( theShape, TopAbs_EDGE, aMapOfSubShapes );
180 HYDROData_ShapesGroup::SeqOfGroupsDefs::Iterator anIter( theOriGroups );
181 for ( ; anIter.More(); anIter.Next() )
183 HYDROData_ShapesGroup::GroupDefinition& anOriGroupDef = anIter.ChangeValue();
184 if ( anOriGroupDef.Shapes.IsEmpty() )
187 for ( int i = 1; i <= anOriGroupDef.Shapes.Length(); ++i )
189 TopoDS_Shape aGroupEdge = anOriGroupDef.Shapes.Value( i );
191 bool anIsFound = false;
192 for ( int anIndex = 1; anIndex <= aMapOfSubShapes.Extent(); anIndex++ )
194 if ( aGroupEdge.IsPartner( aMapOfSubShapes.FindKey( anIndex ) ) )
204 anOriGroupDef.Shapes.Remove( i );
207 bool anIsAdded = false;
209 HYDROData_ShapesGroup::SeqOfGroupsDefs::Iterator aUsedIter( theUsedGroups );
210 for ( ; aUsedIter.More(); aUsedIter.Next() )
212 HYDROData_ShapesGroup::GroupDefinition& aUsedGroupDef = aUsedIter.ChangeValue();
213 if ( aUsedGroupDef.Name != anOriGroupDef.Name )
216 aUsedGroupDef.Shapes.Append( aGroupEdge );
223 HYDROData_ShapesGroup::GroupDefinition aUsedGroupDef;
224 aUsedGroupDef.Name = anOriGroupDef.Name;
225 aUsedGroupDef.Shapes.Append( aGroupEdge );
226 theUsedGroups.Append( aUsedGroupDef );
232 TopoDS_Shape HYDROData_Region::GetShape( HYDROData_ShapesGroup::SeqOfGroupsDefs* theSeqOfGroups ) const
234 HYDROData_ShapesGroup::SeqOfGroupsDefs aSeqOfGroups;
235 HYDROData_ShapesGroup::SeqOfGroupsDefs aSeqOfUsedGroups;
236 if ( theSeqOfGroups )
237 aSeqOfGroups = *theSeqOfGroups;
239 #ifdef DEB_GET_REGION_SHAPE
240 HYDROData_ShapesGroup::GroupDefinition::Dump( std::cout, aSeqOfGroups );
243 TopoDS_Shape aResShape;
245 // Unite the region zones (each zone is a face) into one face (united face)
246 // If the zones can't be united into the single face - unite them into shell
248 // Collect the list of region faces
249 TopTools_ListOfShape aRegionFacesList;
251 HYDROData_SequenceOfObjects aZones = GetZones();
252 HYDROData_SequenceOfObjects::Iterator aZoneIter( aZones );
253 for ( ; aZoneIter.More(); aZoneIter.Next() )
255 Handle(HYDROData_Zone) aZone =
256 Handle(HYDROData_Zone)::DownCast( aZoneIter.Value() );
257 if ( aZone.IsNull() )
260 TopoDS_Shape aZoneShape = aZone->GetShape();
261 if ( aZoneShape.IsNull() || aZoneShape.ShapeType() != TopAbs_FACE )
264 TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
265 aRegionFacesList.Append( aZoneFace );
267 getUsedGroups( aZoneFace, aSeqOfGroups, aSeqOfUsedGroups );
270 if ( aRegionFacesList.IsEmpty() )
273 // The unite region face
274 TopoDS_Face aRegionFace;
276 if ( aRegionFacesList.Extent() == 1 )
278 aRegionFace = TopoDS::Face( aRegionFacesList.First() );
282 #ifdef DEB_GET_REGION_SHAPE
283 HYDROData_ShapesGroup::GroupDefinition::Dump( std::cout, aSeqOfUsedGroups );
286 // Try to fuse all region faces into one common face
287 TopoDS_Shape aFuseShape;
288 TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList );
289 for ( ; aFaceIter.More(); aFaceIter.Next() )
291 if ( aFuseShape.IsNull() )
293 aFuseShape = aFaceIter.Value();
297 BRepAlgoAPI_Fuse aFuse( aFuseShape, aFaceIter.Value() );
298 if ( !aFuse.IsDone() )
300 aFuseShape.Nullify();
304 aFuseShape = aFuse.Shape();
305 HYDROData_ShapesGroup::GroupDefinition::Update( &aSeqOfUsedGroups, &aFuse );
308 #ifdef DEB_GET_REGION_SHAPE
309 HYDROData_ShapesTool::DumpShapeSubShapes( std::cout, "Fused face edges:", aFuseShape, TopAbs_EDGE );
312 // Check the result of fuse operation
313 if ( !aFuseShape.IsNull() )
315 ShapeUpgrade_UnifySameDomain anUnifier( aFuseShape );
318 const TopoDS_Shape& anUnitedShape = anUnifier.Shape();
320 TopTools_SequenceOfShape aShapeFaces;
321 HYDROData_ShapesTool::ExploreShapeToShapes( anUnitedShape, TopAbs_FACE, aShapeFaces );
322 if ( aShapeFaces.Length() == 1 )
324 aRegionFace = TopoDS::Face( aShapeFaces.Value( 1 ) );
326 #ifdef DEB_GET_REGION_SHAPE
327 HYDROData_ShapesTool::DumpShapeSubShapes( std::cout, "Result face edges:", aRegionFace, TopAbs_EDGE );
330 HYDROData_ShapesGroup::GroupDefinition::Update( &aSeqOfUsedGroups, &anUnifier );
332 // Update the sequence of groups
333 if ( theSeqOfGroups )
335 HYDROData_ShapesGroup::SeqOfGroupsDefs::Iterator aUsedIter( aSeqOfUsedGroups );
336 for ( ; aUsedIter.More(); aUsedIter.Next() )
338 const HYDROData_ShapesGroup::GroupDefinition& aUsedGroupDef = aUsedIter.Value();
339 if ( aUsedGroupDef.Shapes.IsEmpty() )
342 HYDROData_ShapesGroup::SeqOfGroupsDefs::Iterator anOriIter( aSeqOfGroups );
343 for ( ; anOriIter.More(); anOriIter.Next() )
345 HYDROData_ShapesGroup::GroupDefinition& anOriGroupDef = anOriIter.ChangeValue();
346 if ( anOriGroupDef.Name != aUsedGroupDef.Name )
349 HYDROData_ShapesTool::AddShapes( anOriGroupDef.Shapes, aUsedGroupDef.Shapes );
354 *theSeqOfGroups = aSeqOfGroups;
360 if ( !aRegionFace.IsNull() )
362 // result shape is a face
363 aResShape = aRegionFace;
367 // result shape is a shell
369 BRep_Builder aBuilder;
370 aBuilder.MakeShell( aShell );
372 TopTools_ListIteratorOfListOfShape aFaceIter( aRegionFacesList );
373 for ( ; aFaceIter.More(); aFaceIter.Next() )
374 aBuilder.Add( aShell, aFaceIter.Value() );