2 #include "HYDROData_CalculationCase.h"
4 #include "HYDROData_ArtificialObject.h"
5 #include "HYDROData_Document.h"
6 #include "HYDROData_Iterator.h"
7 #include "HYDROData_NaturalObject.h"
8 #include "HYDROData_Polyline.h"
9 #include "HYDROData_SplitToZonesTool.h"
10 #include "HYDROData_Region.h"
11 #include "HYDROData_Tool.h"
12 #include "HYDROData_Zone.h"
15 #include <TopoDS_Shell.hxx>
16 #include <BRep_Builder.hxx>
17 #include <BRepBuilderAPI_Sewing.hxx>
18 #include <TopExp_Explorer.hxx>
20 #define CALCULATION_REGIONS_PREF GetName() + "_Reg"
21 #define CALCULATION_ZONES_PREF GetName() + "_Zone"
23 #define PYTHON_CALCULATION_ID "KIND_CALCULATION"
25 IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
26 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
28 HYDROData_CalculationCase::HYDROData_CalculationCase()
33 HYDROData_CalculationCase::~HYDROData_CalculationCase()
37 QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
41 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
42 if ( aDocument.IsNull() )
45 QString aDocName = aDocument->GetDocPyName();
46 QString aCalculName = GetName();
48 aResList << QString( "%1 = %2.CreateObject( %3 );" )
49 .arg( aCalculName ).arg( aDocName ).arg( PYTHON_CALCULATION_ID );
50 aResList << QString( "%1.SetName( \"%2\" );" )
51 .arg( aCalculName ).arg( aCalculName );
52 aResList << QString( "" );
54 HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
55 HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
56 for ( ; anIter.More(); anIter.Next() )
58 Handle(HYDROData_Object) aRefGeomObj =
59 Handle(HYDROData_Object)::DownCast( anIter.Value() );
60 if ( !aRefGeomObj.IsNull() )
61 setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
63 aResList << QString( "" );
65 aResList << QString( "%1.SplitGeometryObjects();" ).arg( aCalculName );
66 aResList << QString( "" );
68 // Now we restore the regions and zones order
69 HYDROData_SequenceOfObjects aRegions = GetRegions();
70 anIter.Init( aRegions );
71 for ( ; anIter.More(); anIter.Next() )
73 Handle(HYDROData_Region) aRegion =
74 Handle(HYDROData_Region)::DownCast( anIter.Value() );
75 if ( aRegion.IsNull() )
78 QString aRegionName = aRegion->GetName();
85 void HYDROData_CalculationCase::SplitGeometryObjects()
87 // At first we remove previously created regions
90 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
91 if ( aDocument.IsNull() )
94 Handle(HYDROData_Polyline) aBoundaryPolyline = GetBoundaryPolyline();
95 HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
96 if ( aGeomObjects.IsEmpty() )
99 HYDROData_SplitToZonesTool::SplitDataList aSplitedZones =
100 HYDROData_SplitToZonesTool::SplitToZones( aGeomObjects, aBoundaryPolyline );
101 if ( aSplitedZones.isEmpty() )
104 QString aRegsPref = CALCULATION_REGIONS_PREF;
105 QString aZonesPref = CALCULATION_ZONES_PREF;
107 // Create result regions for case, by default one zone for one region
108 HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedZones );
109 while( anIter.hasNext() )
111 const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
114 Handle(HYDROData_Region) aRegion = addNewRegion();
116 QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
117 aRegion->SetName( aRegionName );
119 // Add the zone for region
120 Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
122 QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, aZonesPref );
123 aRegionZone->SetName( aZoneName );
125 aRegionZone->SetShape( aSplitData.Face() );
127 // Add the reference object for zone
128 for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
130 const QString& anObjName = aSplitData.ObjectNames.at( i );
132 Handle(HYDROData_Object) aRefObject = Handle(HYDROData_Object)::DownCast(
133 HYDROData_Tool::FindObjectByName( aDocument, anObjName ) );
134 if ( aRefObject.IsNull() )
137 aRegionZone->AddGeometryObject( aRefObject );
141 // The splitted data is up to date
142 SetToUpdate( false );
145 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
147 if ( !HYDROData_Tool::IsGeometryObject( theObject ) )
148 return false; // Wrong type of object
150 if ( HasReference( theObject, DataTag_GeometryObject ) )
151 return false; // Object is already in reference list
153 AddReferenceObject( theObject, DataTag_GeometryObject );
155 // Indicate model of the need to update zones splitting
161 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
163 return GetReferenceObjects( DataTag_GeometryObject );
166 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
168 if ( theObject.IsNull() )
171 RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
173 // Indicate model of the need to update zones splitting
177 void HYDROData_CalculationCase::RemoveGeometryObjects()
179 ClearReferenceObjects( DataTag_GeometryObject );
181 // Indicate model of the need to update zones splitting
185 void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_Polyline)& thePolyline )
187 Handle(HYDROData_Polyline) aPrevPolyline = GetBoundaryPolyline();
189 SetReferenceObject( thePolyline, DataTag_Polyline );
191 // Indicate model of the need to update zones splitting
192 SetToUpdate( !IsEqual( aPrevPolyline, thePolyline ) || IsMustBeUpdated() );
195 Handle(HYDROData_Polyline) HYDROData_CalculationCase::GetBoundaryPolyline() const
197 return Handle(HYDROData_Polyline)::DownCast(
198 GetReferenceObject( DataTag_Polyline ) );
201 void HYDROData_CalculationCase::RemoveBoundaryPolyline()
203 Handle(HYDROData_Polyline) aPrevPolyline = GetBoundaryPolyline();
205 ClearReferenceObjects( DataTag_Polyline );
207 // Indicate model of the need to update zones splitting
208 SetToUpdate( !aPrevPolyline.IsNull() || IsMustBeUpdated() );
211 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
213 Handle(HYDROData_Region) aNewRegion = addNewRegion();
214 if ( aNewRegion.IsNull() )
217 // Generate new name for new region
218 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
219 if ( !aDocument.IsNull() )
221 QString aRegsPref = CALCULATION_REGIONS_PREF;
223 QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
224 aNewRegion->SetName( aNewRegionName );
227 aNewRegion->AddZone( theZone );
232 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
234 if ( theRegion.IsNull() )
237 if ( HasReference( theRegion, DataTag_Region ) )
238 return false; // Object is already in reference list
240 // Move the region from other calculation
241 Handle(HYDROData_CalculationCase) aFatherCalc =
242 Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
243 if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
245 Handle(HYDROData_Region) aNewRegion = addNewRegion();
246 theRegion->CopyTo( aNewRegion );
248 aFatherCalc->RemoveRegion( theRegion );
250 theRegion->SetLabel( aNewRegion->Label() );
254 AddReferenceObject( theRegion, DataTag_Region );
260 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
262 return GetReferenceObjects( DataTag_Region );
265 void HYDROData_CalculationCase::UpdateRegionsOrder()
267 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
268 if ( aDocument.IsNull() )
271 HYDROData_SequenceOfObjects aRegions = GetRegions();
273 HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
274 for ( ; anIter.More(); anIter.Next() )
276 Handle(HYDROData_Region) aRegion =
277 Handle(HYDROData_Region)::DownCast( anIter.Value() );
278 if ( aRegion.IsNull() )
281 aRegion->SetName( "" );
284 QString aRegsPref = CALCULATION_REGIONS_PREF;
286 anIter.Init( aRegions );
287 for ( ; anIter.More(); anIter.Next() )
289 Handle(HYDROData_Region) aRegion =
290 Handle(HYDROData_Region)::DownCast( anIter.Value() );
291 if ( aRegion.IsNull() )
294 QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
295 aRegion->SetName( aRegionName );
299 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
301 if ( theRegion.IsNull() )
304 RemoveReferenceObject( theRegion->Label(), DataTag_Region );
306 // Remove region from data model
307 Handle(HYDROData_CalculationCase) aFatherCalc =
308 Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
309 if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
313 void HYDROData_CalculationCase::RemoveRegions()
315 ClearReferenceObjects( DataTag_Region );
316 myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes( true );
319 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
321 TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
323 Handle(HYDROData_Region) aNewRegion =
324 Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
325 AddRegion( aNewRegion );
330 TopoDS_Shell HYDROData_CalculationCase::GetShell()
334 // Make shell containing all region shapes
335 BRepBuilderAPI_Sewing aSewing( Precision::Confusion()*10.0 );
337 HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
338 HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
339 for ( ; aRegionIter.More(); aRegionIter.Next() ) {
340 Handle(HYDROData_Region) aRegion =
341 Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
342 if( aRegion.IsNull() ) {
346 TopoDS_Shape aRegionShape = aRegion->GetShape();
347 if( !aRegionShape.IsNull() ) {
348 aSewing.Add( aRegionShape );
350 } // regions iterator
353 TopoDS_Shape aSewedShape = aSewing.SewedShape();
355 if ( aSewedShape.ShapeType() == TopAbs_FACE && aCaseRegions.Length() ==1 ) {
356 // create shell from one face
357 BRep_Builder aBuilder;
358 aBuilder.MakeShell( aShell );
359 aBuilder.Add( aShell, aSewedShape);
361 TopExp_Explorer anExpShells( aSewedShape, TopAbs_SHELL );
362 Standard_Integer aNbOfShells = 0;
363 for ( ; anExpShells.More(); anExpShells.Next() ) {
364 aShell = TopoDS::Shell( anExpShells.Current() );
368 if ( aNbOfShells != 1 ) {
370 BRep_Builder aBuilder;
371 aBuilder.MakeShell( aShell );
373 TopExp_Explorer anExpFaces( aSewedShape, TopAbs_FACE );
374 for ( ; anExpFaces.More(); anExpFaces.Next() ) {
375 TopoDS_Face aFace = TopoDS::Face( anExpFaces.Current() );
376 if ( !aFace.IsNull() ) {
377 aBuilder.Add( aShell, aFace );
385 BRep_Builder aBuilder;
386 aBuilder.MakeShell( aShell );
388 // Make shell containing all region shapes
389 HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
390 HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
391 for ( ; aRegionIter.More(); aRegionIter.Next() ) {
392 Handle(HYDROData_Region) aRegion =
393 Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
394 if( aRegion.IsNull() ) {
398 TopoDS_Shape aRegionShape = aRegion->GetShape();
400 // Add shape (face or shell) corresponding to the region into the shell
401 if( !aRegionShape.IsNull() ) {
402 if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
403 aBuilder.Add( aShell, aRegionShape );
405 TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
406 for( ; anExp.More(); anExp.Next() ) {
407 TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
408 if( !aFace.IsNull() ) {
409 aBuilder.Add( aShell, aFace );
414 } // regions iterator
417 // Nullify shell if it is empty
418 if ( !aShell.IsNull() && !TopoDS_Iterator(aShell).More() ) {