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 void HYDROData_CalculationCase::SetName( const QString& theName )
39 QString anOldCaseName = GetName();
40 if ( anOldCaseName != theName )
42 HYDROData_SequenceOfObjects aRegions = GetRegions();
44 HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
45 for ( ; anIter.More(); anIter.Next() )
47 Handle(HYDROData_Region) aRegion =
48 Handle(HYDROData_Region)::DownCast( anIter.Value() );
49 if ( aRegion.IsNull() )
52 QString aRegionName = aRegion->GetName();
53 if ( aRegionName.startsWith( anOldCaseName ) )
55 aRegionName.replace( anOldCaseName, theName );
56 aRegion->SetName( aRegionName );
59 HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
60 HYDROData_SequenceOfObjects::Iterator anIter( aZones );
61 for ( ; anIter.More(); anIter.Next() )
63 Handle(HYDROData_Zone) aRegZone =
64 Handle(HYDROData_Zone)::DownCast( anIter.Value() );
65 if ( aRegZone.IsNull() )
68 QString aRegionZoneName = aRegZone->GetName();
69 if ( aRegionZoneName.startsWith( anOldCaseName ) )
71 aRegionZoneName.replace( anOldCaseName, theName );
72 aRegZone->SetName( aRegionZoneName );
78 HYDROData_Entity::SetName( theName );
81 QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
85 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
86 if ( aDocument.IsNull() )
89 QString aDocName = aDocument->GetDocPyName();
90 QString aCalculName = GetName();
92 aResList << QString( "%1 = %2.CreateObject( %3 );" )
93 .arg( aCalculName ).arg( aDocName ).arg( PYTHON_CALCULATION_ID );
94 aResList << QString( "%1.SetName( \"%2\" );" )
95 .arg( aCalculName ).arg( aCalculName );
96 aResList << QString( "" );
98 HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
99 HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
100 for ( ; anIter.More(); anIter.Next() )
102 Handle(HYDROData_Object) aRefGeomObj =
103 Handle(HYDROData_Object)::DownCast( anIter.Value() );
104 if ( !aRefGeomObj.IsNull() )
105 setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
107 aResList << QString( "" );
109 aResList << QString( "%1.SplitGeometryObjects();" ).arg( aCalculName );
110 aResList << QString( "" );
112 // Now we restore the regions and zones order
113 HYDROData_SequenceOfObjects aRegions = GetRegions();
114 anIter.Init( aRegions );
115 for ( ; anIter.More(); anIter.Next() )
117 Handle(HYDROData_Region) aRegion =
118 Handle(HYDROData_Region)::DownCast( anIter.Value() );
119 if ( aRegion.IsNull() )
122 QString aRegionName = aRegion->GetName();
129 void HYDROData_CalculationCase::SplitGeometryObjects()
131 // At first we remove previously created regions
134 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
135 if ( aDocument.IsNull() )
138 Handle(HYDROData_Polyline) aBoundaryPolyline = GetBoundaryPolyline();
139 HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
140 if ( aGeomObjects.IsEmpty() )
143 HYDROData_SplitToZonesTool::SplitDataList aSplitedZones =
144 HYDROData_SplitToZonesTool::SplitToZones( aGeomObjects, aBoundaryPolyline );
145 if ( aSplitedZones.isEmpty() )
148 QString aRegsPref = CALCULATION_REGIONS_PREF;
149 QString aZonesPref = CALCULATION_ZONES_PREF;
151 // Create result regions for case, by default one zone for one region
152 HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedZones );
153 while( anIter.hasNext() )
155 const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
158 Handle(HYDROData_Region) aRegion = addNewRegion();
160 QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
161 aRegion->SetName( aRegionName );
163 // Add the zone for region
164 Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
166 QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, aZonesPref );
167 aRegionZone->SetName( aZoneName );
169 aRegionZone->SetShape( aSplitData.Face() );
171 // Add the reference object for zone
172 for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
174 const QString& anObjName = aSplitData.ObjectNames.at( i );
176 Handle(HYDROData_Object) aRefObject = Handle(HYDROData_Object)::DownCast(
177 HYDROData_Tool::FindObjectByName( aDocument, anObjName ) );
178 if ( aRefObject.IsNull() )
181 aRegionZone->AddGeometryObject( aRefObject );
185 // The splitted data is up to date
186 SetToUpdate( false );
189 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
191 if ( !HYDROData_Tool::IsGeometryObject( theObject ) )
192 return false; // Wrong type of object
194 if ( HasReference( theObject, DataTag_GeometryObject ) )
195 return false; // Object is already in reference list
197 AddReferenceObject( theObject, DataTag_GeometryObject );
199 // Indicate model of the need to update zones splitting
205 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
207 return GetReferenceObjects( DataTag_GeometryObject );
210 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
212 if ( theObject.IsNull() )
215 RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
217 // Indicate model of the need to update zones splitting
221 void HYDROData_CalculationCase::RemoveGeometryObjects()
223 ClearReferenceObjects( DataTag_GeometryObject );
225 // Indicate model of the need to update zones splitting
229 void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_Polyline)& thePolyline )
231 Handle(HYDROData_Polyline) aPrevPolyline = GetBoundaryPolyline();
233 SetReferenceObject( thePolyline, DataTag_Polyline );
235 // Indicate model of the need to update zones splitting
236 SetToUpdate( !IsEqual( aPrevPolyline, thePolyline ) || IsMustBeUpdated() );
239 Handle(HYDROData_Polyline) HYDROData_CalculationCase::GetBoundaryPolyline() const
241 return Handle(HYDROData_Polyline)::DownCast(
242 GetReferenceObject( DataTag_Polyline ) );
245 void HYDROData_CalculationCase::RemoveBoundaryPolyline()
247 Handle(HYDROData_Polyline) aPrevPolyline = GetBoundaryPolyline();
249 ClearReferenceObjects( DataTag_Polyline );
251 // Indicate model of the need to update zones splitting
252 SetToUpdate( !aPrevPolyline.IsNull() || IsMustBeUpdated() );
255 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
257 Handle(HYDROData_Region) aNewRegion = addNewRegion();
258 if ( aNewRegion.IsNull() )
261 // Generate new name for new region
262 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
263 if ( !aDocument.IsNull() )
265 QString aRegsPref = CALCULATION_REGIONS_PREF;
267 QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
268 aNewRegion->SetName( aNewRegionName );
271 aNewRegion->AddZone( theZone );
276 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
278 if ( theRegion.IsNull() )
281 if ( HasReference( theRegion, DataTag_Region ) )
282 return false; // Object is already in reference list
284 // Move the region from other calculation
285 Handle(HYDROData_CalculationCase) aFatherCalc =
286 Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
287 if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
289 Handle(HYDROData_Region) aNewRegion = addNewRegion();
290 theRegion->CopyTo( aNewRegion );
292 aFatherCalc->RemoveRegion( theRegion );
294 theRegion->SetLabel( aNewRegion->Label() );
298 AddReferenceObject( theRegion, DataTag_Region );
304 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
306 return GetReferenceObjects( DataTag_Region );
309 void HYDROData_CalculationCase::UpdateRegionsOrder()
311 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
312 if ( aDocument.IsNull() )
315 HYDROData_SequenceOfObjects aRegions = GetRegions();
317 HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
318 for ( ; anIter.More(); anIter.Next() )
320 Handle(HYDROData_Region) aRegion =
321 Handle(HYDROData_Region)::DownCast( anIter.Value() );
322 if ( aRegion.IsNull() )
325 aRegion->SetName( "" );
328 QString aRegsPref = CALCULATION_REGIONS_PREF;
330 anIter.Init( aRegions );
331 for ( ; anIter.More(); anIter.Next() )
333 Handle(HYDROData_Region) aRegion =
334 Handle(HYDROData_Region)::DownCast( anIter.Value() );
335 if ( aRegion.IsNull() )
338 QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
339 aRegion->SetName( aRegionName );
343 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
345 if ( theRegion.IsNull() )
348 RemoveReferenceObject( theRegion->Label(), DataTag_Region );
350 // Remove region from data model
351 Handle(HYDROData_CalculationCase) aFatherCalc =
352 Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
353 if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
357 void HYDROData_CalculationCase::RemoveRegions()
359 ClearReferenceObjects( DataTag_Region );
360 myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes( true );
363 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
365 TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
367 Handle(HYDROData_Region) aNewRegion =
368 Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
369 AddRegion( aNewRegion );
374 TopoDS_Shell HYDROData_CalculationCase::GetShell()
378 // Make shell containing all region shapes
379 BRepBuilderAPI_Sewing aSewing( Precision::Confusion()*10.0 );
381 HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
382 HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
383 for ( ; aRegionIter.More(); aRegionIter.Next() ) {
384 Handle(HYDROData_Region) aRegion =
385 Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
386 if( aRegion.IsNull() ) {
390 TopoDS_Shape aRegionShape = aRegion->GetShape();
391 if( !aRegionShape.IsNull() ) {
392 aSewing.Add( aRegionShape );
394 } // regions iterator
397 TopoDS_Shape aSewedShape = aSewing.SewedShape();
399 if ( aSewedShape.ShapeType() == TopAbs_FACE && aCaseRegions.Length() ==1 ) {
400 // create shell from one face
401 BRep_Builder aBuilder;
402 aBuilder.MakeShell( aShell );
403 aBuilder.Add( aShell, aSewedShape);
405 TopExp_Explorer anExpShells( aSewedShape, TopAbs_SHELL );
406 Standard_Integer aNbOfShells = 0;
407 for ( ; anExpShells.More(); anExpShells.Next() ) {
408 aShell = TopoDS::Shell( anExpShells.Current() );
412 if ( aNbOfShells != 1 ) {
414 BRep_Builder aBuilder;
415 aBuilder.MakeShell( aShell );
417 TopExp_Explorer anExpFaces( aSewedShape, TopAbs_FACE );
418 for ( ; anExpFaces.More(); anExpFaces.Next() ) {
419 TopoDS_Face aFace = TopoDS::Face( anExpFaces.Current() );
420 if ( !aFace.IsNull() ) {
421 aBuilder.Add( aShell, aFace );
429 BRep_Builder aBuilder;
430 aBuilder.MakeShell( aShell );
432 // Make shell containing all region shapes
433 HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
434 HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
435 for ( ; aRegionIter.More(); aRegionIter.Next() ) {
436 Handle(HYDROData_Region) aRegion =
437 Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
438 if( aRegion.IsNull() ) {
442 TopoDS_Shape aRegionShape = aRegion->GetShape();
444 // Add shape (face or shell) corresponding to the region into the shell
445 if( !aRegionShape.IsNull() ) {
446 if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
447 aBuilder.Add( aShell, aRegionShape );
449 TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
450 for( ; anExp.More(); anExp.Next() ) {
451 TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
452 if( !aFace.IsNull() ) {
453 aBuilder.Add( aShell, aFace );
458 } // regions iterator
461 // Nullify shell if it is empty
462 if ( !aShell.IsNull() && !TopoDS_Iterator(aShell).More() ) {