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_PolylineXY.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 #include <TopTools_ListOfShape.hxx>
21 #include <TopTools_ListIteratorOfListOfShape.hxx>
23 #define CALCULATION_REGIONS_PREF GetName() + "_Reg"
24 #define CALCULATION_ZONES_PREF GetName() + "_Zone"
26 #define PYTHON_CALCULATION_ID "KIND_CALCULATION"
28 IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
29 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
31 HYDROData_CalculationCase::HYDROData_CalculationCase()
36 HYDROData_CalculationCase::~HYDROData_CalculationCase()
40 void HYDROData_CalculationCase::SetName( const QString& theName )
42 QString anOldCaseName = GetName();
43 if ( anOldCaseName != theName )
45 HYDROData_SequenceOfObjects aRegions = GetRegions();
47 HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
48 for ( ; anIter.More(); anIter.Next() )
50 Handle(HYDROData_Region) aRegion =
51 Handle(HYDROData_Region)::DownCast( anIter.Value() );
52 if ( aRegion.IsNull() )
55 QString aRegionName = aRegion->GetName();
56 if ( aRegionName.startsWith( anOldCaseName ) )
58 aRegionName.replace( anOldCaseName, theName );
59 aRegion->SetName( aRegionName );
62 HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
63 HYDROData_SequenceOfObjects::Iterator anIter( aZones );
64 for ( ; anIter.More(); anIter.Next() )
66 Handle(HYDROData_Zone) aRegZone =
67 Handle(HYDROData_Zone)::DownCast( anIter.Value() );
68 if ( aRegZone.IsNull() )
71 QString aRegionZoneName = aRegZone->GetName();
72 if ( aRegionZoneName.startsWith( anOldCaseName ) )
74 aRegionZoneName.replace( anOldCaseName, theName );
75 aRegZone->SetName( aRegionZoneName );
81 HYDROData_Entity::SetName( theName );
84 QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
88 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
89 if ( aDocument.IsNull() )
92 QString aDocName = aDocument->GetDocPyName();
93 QString aCalculName = GetName();
95 aResList << QString( "%1 = %2.CreateObject( %3 );" )
96 .arg( aCalculName ).arg( aDocName ).arg( PYTHON_CALCULATION_ID );
97 aResList << QString( "%1.SetName( \"%2\" );" )
98 .arg( aCalculName ).arg( aCalculName );
99 aResList << QString( "" );
101 HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
102 HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
103 for ( ; anIter.More(); anIter.Next() )
105 Handle(HYDROData_Object) aRefGeomObj =
106 Handle(HYDROData_Object)::DownCast( anIter.Value() );
107 if ( !aRefGeomObj.IsNull() )
108 setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
110 aResList << QString( "" );
112 aResList << QString( "%1.SplitGeometryObjects();" ).arg( aCalculName );
113 aResList << QString( "" );
115 // Now we restore the regions and zones order
116 HYDROData_SequenceOfObjects aRegions = GetRegions();
117 anIter.Init( aRegions );
118 for ( ; anIter.More(); anIter.Next() )
120 Handle(HYDROData_Region) aRegion =
121 Handle(HYDROData_Region)::DownCast( anIter.Value() );
122 if ( aRegion.IsNull() )
125 QString aRegionName = aRegion->GetName();
132 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetAllReferenceObjects() const
134 HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
136 Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
137 if ( !aBoundaryPolyline.IsNull() )
138 aResSeq.Append( aBoundaryPolyline );
140 HYDROData_SequenceOfObjects aSeqOfRegions = GetRegions();
141 aResSeq.Append( aSeqOfRegions );
146 void HYDROData_CalculationCase::Update()
148 HYDROData_Entity::Update();
150 // At first we remove previously created regions
153 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
154 if ( aDocument.IsNull() )
157 Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
158 HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
159 if ( aGeomObjects.IsEmpty() )
162 HYDROData_SplitToZonesTool::SplitDataList aSplitedZones =
163 HYDROData_SplitToZonesTool::SplitToZones( aGeomObjects, aBoundaryPolyline );
164 if ( aSplitedZones.isEmpty() )
167 QString aRegsPref = CALCULATION_REGIONS_PREF;
168 QString aZonesPref = CALCULATION_ZONES_PREF;
170 // Create result regions for case, by default one zone for one region
171 HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedZones );
172 while( anIter.hasNext() )
174 const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
177 Handle(HYDROData_Region) aRegion = addNewRegion();
179 QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
180 aRegion->SetName( aRegionName );
182 // Add the zone for region
183 Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
185 QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, aZonesPref );
186 aRegionZone->SetName( aZoneName );
188 aRegionZone->SetShape( aSplitData.Face() );
190 // Add the reference object for zone
191 for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
193 const QString& anObjName = aSplitData.ObjectNames.at( i );
195 Handle(HYDROData_Object) aRefObject = Handle(HYDROData_Object)::DownCast(
196 HYDROData_Tool::FindObjectByName( aDocument, anObjName ) );
197 if ( aRefObject.IsNull() )
200 aRegionZone->AddGeometryObject( aRefObject );
205 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
207 if ( !HYDROData_Tool::IsGeometryObject( theObject ) )
208 return false; // Wrong type of object
210 if ( HasReference( theObject, DataTag_GeometryObject ) )
211 return false; // Object is already in reference list
213 AddReferenceObject( theObject, DataTag_GeometryObject );
215 // Indicate model of the need to update zones splitting
221 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
223 return GetReferenceObjects( DataTag_GeometryObject );
226 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
228 if ( theObject.IsNull() )
231 RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
233 // Indicate model of the need to update zones splitting
237 void HYDROData_CalculationCase::RemoveGeometryObjects()
239 ClearReferenceObjects( DataTag_GeometryObject );
241 // Indicate model of the need to update zones splitting
245 void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
247 Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
249 SetReferenceObject( thePolyline, DataTag_Polyline );
251 // Indicate model of the need to update zones splitting
252 SetToUpdate( !IsEqual( aPrevPolyline, thePolyline ) || IsMustBeUpdated() );
255 Handle(HYDROData_PolylineXY) HYDROData_CalculationCase::GetBoundaryPolyline() const
257 return Handle(HYDROData_PolylineXY)::DownCast(
258 GetReferenceObject( DataTag_Polyline ) );
261 void HYDROData_CalculationCase::RemoveBoundaryPolyline()
263 Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
265 ClearReferenceObjects( DataTag_Polyline );
267 // Indicate model of the need to update zones splitting
268 SetToUpdate( !aPrevPolyline.IsNull() || IsMustBeUpdated() );
271 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
273 Handle(HYDROData_Region) aNewRegion = addNewRegion();
274 if ( aNewRegion.IsNull() )
277 // Generate new name for new region
278 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
279 if ( !aDocument.IsNull() )
281 QString aRegsPref = CALCULATION_REGIONS_PREF;
283 QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
284 aNewRegion->SetName( aNewRegionName );
287 aNewRegion->AddZone( theZone );
292 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
294 if ( theRegion.IsNull() )
297 if ( HasReference( theRegion, DataTag_Region ) )
298 return false; // Object is already in reference list
300 // Move the region from other calculation
301 Handle(HYDROData_CalculationCase) aFatherCalc =
302 Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
303 if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
305 Handle(HYDROData_Region) aNewRegion = addNewRegion();
306 theRegion->CopyTo( aNewRegion );
308 aFatherCalc->RemoveRegion( theRegion );
310 theRegion->SetLabel( aNewRegion->Label() );
314 AddReferenceObject( theRegion, DataTag_Region );
320 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
322 return GetReferenceObjects( DataTag_Region );
325 void HYDROData_CalculationCase::UpdateRegionsOrder()
327 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
328 if ( aDocument.IsNull() )
331 HYDROData_SequenceOfObjects aRegions = GetRegions();
333 HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
334 for ( ; anIter.More(); anIter.Next() )
336 Handle(HYDROData_Region) aRegion =
337 Handle(HYDROData_Region)::DownCast( anIter.Value() );
338 if ( aRegion.IsNull() )
341 aRegion->SetName( "" );
344 QString aRegsPref = CALCULATION_REGIONS_PREF;
346 anIter.Init( aRegions );
347 for ( ; anIter.More(); anIter.Next() )
349 Handle(HYDROData_Region) aRegion =
350 Handle(HYDROData_Region)::DownCast( anIter.Value() );
351 if ( aRegion.IsNull() )
354 QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
355 aRegion->SetName( aRegionName );
359 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
361 if ( theRegion.IsNull() )
364 RemoveReferenceObject( theRegion->Label(), DataTag_Region );
366 // Remove region from data model
367 Handle(HYDROData_CalculationCase) aFatherCalc =
368 Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
369 if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
373 void HYDROData_CalculationCase::RemoveRegions()
375 ClearReferenceObjects( DataTag_Region );
376 myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes( true );
379 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
381 TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
383 Handle(HYDROData_Region) aNewRegion =
384 Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
385 AddRegion( aNewRegion );
390 TopoDS_Shell HYDROData_CalculationCase::GetShell()
394 TopTools_ListOfShape aFacesList;
396 // Make shell containing all region shapes
397 BRepBuilderAPI_Sewing aSewing( Precision::Confusion()*10.0 );
399 HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
400 HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
401 for ( ; aRegionIter.More(); aRegionIter.Next() ) {
402 Handle(HYDROData_Region) aRegion =
403 Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
404 if( aRegion.IsNull() ) {
408 TopoDS_Shape aRegionShape = aRegion->GetShape();
409 if( !aRegionShape.IsNull() ) {
410 if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
411 TopoDS_Face aFace = TopoDS::Face( aRegionShape );
412 if ( !aFace.IsNull() ) {
413 aFacesList.Append( aFace );
414 aSewing.Add( aFace );
417 TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
418 for ( ; anExp.More(); anExp.Next() ) {
419 TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
420 if ( !aFace.IsNull() ) {
421 aFacesList.Append( aFace );
422 aSewing.Add( aFace );
427 } // regions iterator
430 TopoDS_Shape aSewedShape = aSewing.SewedShape();
432 if ( !aSewedShape.IsNull() )
434 if ( aSewedShape.ShapeType() == TopAbs_FACE && aCaseRegions.Length() ==1 ) {
435 // create shell from one face
436 BRep_Builder aBuilder;
437 aBuilder.MakeShell( aShell );
438 aBuilder.Add( aShell, aSewedShape);
440 TopExp_Explorer anExpShells( aSewedShape, TopAbs_SHELL );
441 Standard_Integer aNbOfShells = 0;
442 for ( ; anExpShells.More(); anExpShells.Next() ) {
443 aShell = TopoDS::Shell( anExpShells.Current() );
447 if ( aNbOfShells != 1 ) {
449 BRep_Builder aBuilder;
450 aBuilder.MakeShell( aShell );
452 TopExp_Explorer anExpFaces( aSewedShape, TopAbs_FACE );
453 for ( ; anExpFaces.More(); anExpFaces.Next() ) {
454 TopoDS_Face aFace = TopoDS::Face( anExpFaces.Current() );
455 if ( !aFace.IsNull() ) {
456 aBuilder.Add( aShell, aFace );
463 if ( !aShell.IsNull() ) {
464 TopTools_IndexedMapOfShape aMapOfFaces;
465 TopExp::MapShapes( aShell, TopAbs_FACE, aMapOfFaces );
466 if ( aMapOfFaces.Extent() != aFacesList.Extent() ) {
468 BRep_Builder aBuilder;
469 aBuilder.MakeShell( aShell );
471 TopTools_ListIteratorOfListOfShape anIter( aFacesList );
472 for ( ; anIter.More(); anIter.Next() ) {
473 TopoDS_Face aFace = TopoDS::Face( anIter.Value() );
474 aBuilder.Add( aShell, aFace );
481 BRep_Builder aBuilder;
482 aBuilder.MakeShell( aShell );
484 // Make shell containing all region shapes
485 HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
486 HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
487 for ( ; aRegionIter.More(); aRegionIter.Next() ) {
488 Handle(HYDROData_Region) aRegion =
489 Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
490 if( aRegion.IsNull() ) {
494 TopoDS_Shape aRegionShape = aRegion->GetShape();
496 // Add shape (face or shell) corresponding to the region into the shell
497 if( !aRegionShape.IsNull() ) {
498 if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
499 aBuilder.Add( aShell, aRegionShape );
501 TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
502 for( ; anExp.More(); anExp.Next() ) {
503 TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
504 if( !aFace.IsNull() ) {
505 aBuilder.Add( aShell, aFace );
510 } // regions iterator
513 // Nullify shell if it is empty
514 if ( !aShell.IsNull() && !TopoDS_Iterator(aShell).More() ) {