1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROData_Stream.h"
21 #include "HYDROData_Document.h"
22 #include "HYDROData_PolylineXY.h"
23 #include "HYDROData_Polyline3D.h"
24 #include "HYDROData_Profile.h"
25 #include "HYDROData_ShapesGroup.h"
26 #include "HYDROData_ShapesTool.h"
27 #include "HYDROData_IAltitudeObject.h"
28 #include "HYDROData_IProfilesInterpolator.h"
29 #include "HYDROData_Tool.h"
30 #include "HYDROData_DTM.h"
31 #include "HYDROData_LISM.h"
33 #include <HYDROData_Bathymetry.h>
35 #include <TDataStd_RealArray.hxx>
37 #include <Precision.hxx>
39 #include <NCollection_DataMap.hxx>
41 #include <TColStd_Array1OfReal.hxx>
42 #include <TColStd_ListOfReal.hxx>
43 #include <TColStd_ListIteratorOfListOfReal.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45 #include <TColgp_HArray1OfPnt.hxx>
48 #include <TopoDS_Wire.hxx>
49 #include <TopoDS_Shell.hxx>
50 #include <TopoDS_Face.hxx>
51 #include <TopoDS_Edge.hxx>
52 #include <TopoDS_Vertex.hxx>
54 #include <TopExp_Explorer.hxx>
56 #include <Bnd_Box.hxx>
58 #include <BRep_Builder.hxx>
59 #include <BRepBuilderAPI_MakeEdge.hxx>
60 #include <BRepBuilderAPI_MakeWire.hxx>
61 #include <BRepBuilderAPI_MakeFace.hxx>
63 #include <BRepBndLib.hxx>
64 #include <BRepProj_Projection.hxx>
65 #include <BRepExtrema_ExtCC.hxx>
66 #include <BRepCheck_Analyzer.hxx>
76 #include <GeomAPI_Interpolate.hxx>
77 #include <Geom_BSplineCurve.hxx>
79 #include <TopTools_HArray1OfShape.hxx>
80 #include <TopTools_IndexedMapOfOrientedShape.hxx>
81 #include <TopTools_ListIteratorOfListOfShape.hxx>
82 #include <TopTools_SequenceOfShape.hxx>
83 #include <TopTools_IndexedMapOfShape.hxx>
86 #include <QStringList>
89 //#define DEB_STREAM 1
91 //#define DEB_HASINT 1
92 //#define DEB_UPDATE 1
93 #include <BRepTools.hxx>
94 #include <TCollection_AsciiString.hxx>
98 #include "HYDRO_trace.hxx"
102 typedef NCollection_DataMap<Standard_Real, Handle(HYDROData_Profile)> HYDROData_DataMapOfRealOfHDProfile;
104 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
107 HYDROData_Stream::HYDROData_Stream()
108 : HYDROData_NaturalObject( Geom_3d )
112 HYDROData_Stream::~HYDROData_Stream()
116 QStringList HYDROData_Stream::DumpToPython( const QString& thePyScriptPath,
117 MapOfTreatedObjects& theTreatedObjects ) const
119 QStringList aResList = dumpObjectCreation( theTreatedObjects );
120 QString aName = GetObjPyName();
122 int interpMethod = GetInterpolationMethod();
123 QString anInterpMethod = QString::number( interpMethod );
124 aResList << QString( "%1.SetInterpolationMethod( %2 )" ).arg( aName ).arg( anInterpMethod );
126 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
127 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aHydAxis, "SetHydraulicAxis" );
129 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
130 for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; ++i )
132 const Handle(HYDROData_Entity) aProfile = aSeqOfProfiles.Value( i );
133 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aProfile, "AddProfile" );
136 // Set bottom polyline if exists
137 const Handle(HYDROData_Polyline3D) aBottomPolyline = GetBottomPolyline();
138 if ( !aBottomPolyline.IsNull() ) {
139 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aBottomPolyline, "SetBottomPolyline" );
144 QString aDDZs = QString::number( GetDDZ(), 'f', 3 );
145 QString aSSteps = QString::number( GetSpatialStep(), 'f', 3 );
146 aResList << QString( "%1.SetDDZ( %2 )" ).arg( aName ).arg( aDDZs );
147 aResList << QString( "%1.SetSpatialStep( %2 )" ).arg( aName ).arg( aSSteps );
149 else if (interpMethod==1)
151 Handle(HYDROData_PolylineXY) aLeftBank = GetLeftBank();
152 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aLeftBank, "SetLeftBank" );
153 Handle(HYDROData_PolylineXY) aRightBank = GetRightBank();
154 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRightBank, "SetRightBank" );
156 QString aHaxStep = QString::number( GetHaxStep(), 'f', 3 );
157 QString aNbProfilePoints = QString::number( GetNbProfilePoints() );
158 aResList << QString( "%1.SetHaxStep( %2 )" ).arg( aName ).arg( aHaxStep );
159 aResList << QString( "%1.SetNbProfilePoints( %2 )" ).arg( aName ).arg( aNbProfilePoints );
162 aResList << QString( "" );
163 aResList << QString( "%1.Update()" ).arg( aName );
164 aResList << QString( "" );
169 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
171 HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
173 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
174 if ( !aHydAxis.IsNull() )
175 aResSeq.Append( aHydAxis );
177 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
178 aResSeq.Append( aSeqOfProfiles );
183 Handle(Geom_BSplineCurve) HYDROData_Stream::buildInterpolationCurve(
184 const Handle(TColgp_HArray1OfPnt)& theArrayOfPnt )
186 Handle(Geom_BSplineCurve) aBSpline;
187 GeomAPI_Interpolate anInterpolator (theArrayOfPnt, Standard_False, 1.0e-5);
188 anInterpolator.Perform() ;
189 if (anInterpolator.IsDone())
190 aBSpline = anInterpolator.Curve();
194 void HYDROData_Stream::GetWarnings(NCollection_DataMap<Handle(HYDROData_Profile), QSet<QString>>& warnings)
196 warnings = myWarnings;
199 void HYDROData_Stream::Update()
201 if (GetInterpolationMethod() == 0)
203 if (!GetHydraulicAxis().IsNull())
204 updateProfilesOrder();
206 // Update bottom polyline if exists
207 const Handle(HYDROData_Polyline3D) aBottomPolyline = GetBottomPolyline();
208 if ( !aBottomPolyline.IsNull() ) {
209 if ( GenerateBottomPolyline() ) {
210 Handle(HYDROData_PolylineXY) aPolylineXY = aBottomPolyline->GetPolylineXY();
211 if ( !aPolylineXY.IsNull() ) {
212 aPolylineXY->Update();
214 aBottomPolyline->Update();
218 Handle(HYDROData_DTM) dtm = DTM();
223 dtm->GetWarnings(myWarnings);
227 Handle(HYDROData_LISM) lism = LISM();
232 //lism->GetWarnings(myWarnings);
236 HYDROData_NaturalObject::Update();
239 bool HYDROData_Stream::IsHas2dPrs() const
244 bool HYDROData_Stream::CreatePresentations( const Handle(HYDROData_DTM)& theDTM,
245 PrsDefinition& thePrs )
247 if ( theDTM.IsNull() )
250 HYDROData_SequenceOfObjects profiles = theDTM->GetProfiles();
251 if( profiles.Length() < 2 )
254 TopoDS_Shape Out3dPres;
255 TopoDS_Shape Out2dPres;
256 TopoDS_Shape OutLeftB;
257 TopoDS_Shape OutRightB;
258 TopoDS_Shape OutInlet;
259 TopoDS_Shape OutOutlet;
261 theDTM->GetPresentationShapes(Out3dPres, Out2dPres, OutLeftB, OutRightB, OutInlet, OutOutlet);
263 thePrs.myInlet = OutInlet;
264 thePrs.myOutlet = OutOutlet;
265 thePrs.myLeftBank = OutLeftB;
266 thePrs.myRightBank = OutRightB;
267 thePrs.myPrs2D = Out2dPres;
268 thePrs.myPrs3D = Out3dPres;
269 /*std::vector<TopoDS_Wire> profiles3d;
270 profiles3d.reserve(profiles.Length());
273 HYDROData_SequenceOfObjects::Iterator anIter( profiles );
274 for (int i=1 ; anIter.More(); anIter.Next(),i++ )
276 Handle(HYDROData_Profile) aProfile =
277 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
279 if ( aProfile.IsNull() )
282 const TopoDS_Shape& aProfileShape = aProfile->GetShape3D();
283 //TopExp_Explorer exp(aProfileShape, TopAbs_EDGE);
284 profiles3d.push_back( TopoDS::Wire(aProfileShape) );
290 void HYDROData_Stream::internalUpdatePrs( const PrsDefinition& aResultPrs )
292 SetShape3D( aResultPrs.myPrs3D );
293 SetTopShape( aResultPrs.myPrs2D );
295 // Create the stream groups
296 QString aLeftGroupName = GetName() + "_Left_Bank";
298 Handle(HYDROData_ShapesGroup) aLeftGroup = createGroupObject();
299 aLeftGroup->SetName( aLeftGroupName );
300 aLeftGroup->AddShape( aResultPrs.myLeftBank );
302 QString aRightGroupName = GetName() + "_Right_Bank";
304 Handle(HYDROData_ShapesGroup) aRightGroup = createGroupObject();
305 aRightGroup->SetName( aRightGroupName );
306 aRightGroup->AddShape( aResultPrs.myRightBank );
308 QString anInGroupName = GetName() + "_Inlet";
310 Handle(HYDROData_ShapesGroup) anInGroup = createGroupObject();
311 anInGroup->SetName( anInGroupName );
312 anInGroup->AddShape( aResultPrs.myInlet );
314 QString anOutGroupName = GetName() + "_Outlet";
316 Handle(HYDROData_ShapesGroup) anOutGroup = createGroupObject();
317 anOutGroup->SetName( anOutGroupName );
318 anOutGroup->AddShape( aResultPrs.myOutlet );
322 void HYDROData_Stream::UpdatePrs( const Handle(HYDROData_DTM)& theDTM )
324 HYDROData_NaturalObject::Update();
326 PrsDefinition aResultPrs;
327 if ( !CreatePresentations( theDTM, aResultPrs ) )
330 internalUpdatePrs(aResultPrs);
333 void HYDROData_Stream::UpdatePrs( const Handle(HYDROData_LISM)& theLISM )
335 HYDROData_NaturalObject::Update();
336 PrsDefinition prsDef;
337 theLISM->GetShapePresentations(prsDef);
339 internalUpdatePrs(prsDef);
342 QColor HYDROData_Stream::DefaultFillingColor() const
344 return QColor( Qt::green );
347 QColor HYDROData_Stream::DefaultBorderColor() const
349 return QColor( Qt::transparent );
352 bool HYDROData_Stream::IsValidAsAxis( const Handle(HYDROData_PolylineXY)& theHydAxis )
354 if ( theHydAxis.IsNull() )
357 TopoDS_Shape aHydraulicShape = theHydAxis->GetShape();
358 if ( aHydraulicShape.IsNull() ||
359 aHydraulicShape.ShapeType() != TopAbs_WIRE ||
360 BRep_Tool::IsClosed( aHydraulicShape ) )
361 return false; // The polyline must be a single not closed wire
366 TopoDS_Shape HYDROData_Stream::GetLeftShape() const
368 HYDROData_SequenceOfObjects aGroups = GetGroups();
369 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 1);
372 TopoDS_Shape HYDROData_Stream::GetRightShape() const
374 HYDROData_SequenceOfObjects aGroups = GetGroups();
375 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 2);
378 TopoDS_Shape HYDROData_Stream::GetInletShape() const
380 HYDROData_SequenceOfObjects aGroups = GetGroups();
381 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 3);
384 TopoDS_Shape HYDROData_Stream::GetOutletShape() const
386 HYDROData_SequenceOfObjects aGroups = GetGroups();
387 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 4);
390 Handle(HYDROData_DTM) HYDROData_Stream::DTM() const
392 const_cast<HYDROData_Stream*>( this )->checkAndSetAltitudeObject();
393 return Handle(HYDROData_DTM)::DownCast( GetAltitudeObject() );
396 Handle(HYDROData_LISM) HYDROData_Stream::LISM() const
398 const_cast<HYDROData_Stream*>( this )->checkAndSetAltitudeObject();
399 return Handle(HYDROData_LISM)::DownCast( GetAltitudeObject() );
402 double HYDROData_Stream::GetDDZ() const
404 return DTM()->GetDDZ();
407 void HYDROData_Stream::SetDDZ( double theDDZ )
409 DTM()->SetDDZ( theDDZ );
413 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetLeftBank() const
415 return LISM()->GetLeftBank();
418 void HYDROData_Stream::SetLeftBank( const Handle(HYDROData_PolylineXY)& theBank )
420 LISM()->SetLeftBank( theBank );
424 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetRightBank() const
426 return LISM()->GetRightBank();
429 void HYDROData_Stream::SetRightBank( const Handle(HYDROData_PolylineXY)& theBank )
431 LISM()->SetRightBank( theBank );
436 double HYDROData_Stream::GetHaxStep() const
438 return LISM()->GetHaxStep();
441 void HYDROData_Stream::SetHaxStep( double theHaxStep )
443 LISM()->SetHaxStep( theHaxStep );
447 int HYDROData_Stream::GetNbProfilePoints() const
449 return LISM()->GetNbProfilePoints();
452 void HYDROData_Stream::SetNbProfilePoints( int theNbPoints )
454 LISM()->SetNbProfilePoints( theNbPoints );
458 double HYDROData_Stream::GetSpatialStep() const
460 if (GetInterpolationMethod() == 0)
461 return DTM()->GetSpatialStep();
463 return LISM()->GetHaxStep();
466 void HYDROData_Stream::SetSpatialStep( double theSpatialStep )
468 if (GetInterpolationMethod() == 0 )
469 DTM()->SetSpatialStep( theSpatialStep );
471 LISM()->SetHaxStep( theSpatialStep );
475 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
477 if (GetInterpolationMethod() == 0)
479 if ( !IsValidAsAxis( theAxis ) )
482 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
483 if ( IsEqual( aPrevAxis, theAxis ) )
486 SetReferenceObject( theAxis, DataTag_HydraulicAxis );
488 // Update the order of profiles
489 updateProfilesOrder();
491 // Indicate model of the need to update the stream presentation
496 LISM()->SetHydraulicAxis( theAxis );
503 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
505 if (GetInterpolationMethod() == 0)
506 return Handle(HYDROData_PolylineXY)::DownCast( GetReferenceObject( DataTag_HydraulicAxis ) );
508 return LISM()->GetHydraulicAxis();
511 void HYDROData_Stream::RemoveHydraulicAxis()
513 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
514 if ( aPrevAxis.IsNull() )
517 ClearReferenceObjects( DataTag_HydraulicAxis );
519 // We remove the reference profiles
522 // Indicate model of the need to update the stream presentation
526 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile,
527 const TopoDS_Face& thePlane,
528 Standard_Real& theOutPar ) const
530 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
531 return HasIntersection( aHydAxis, theProfile, thePlane, theOutPar );
534 #include <BRepAlgo_NormalProjection.hxx>
536 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_PolylineXY)& theHydAxis,
537 const Handle(HYDROData_Profile)& theProfile,
538 const TopoDS_Face& thePlane,
539 Standard_Real& theOutPar )
541 if ( theProfile.IsNull() /*|| !IsValidAsAxis( theHydAxis )*/ )
544 if (theHydAxis.IsNull())
545 return true; //empty h_axis; its's OK
547 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() ); //guide line
548 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
549 if ( aProfileWire.IsNull() )
551 DEBTRACE("aProfileWire.IsNull");
555 //BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
556 BRepAlgo_NormalProjection nproj(thePlane);
557 nproj.Add(aProfileWire);
558 nproj.SetDefaultParams();
562 DEBTRACE("!nproj.IsDone");
565 TopoDS_Shape aPrjProfile = nproj.Projection();
566 if(aPrjProfile.IsNull())
568 DEBTRACE("aPrjProfile.IsNull");
571 TopoDS_Vertex aV1, aV2;
572 if(aPrjProfile.ShapeType() == TopAbs_EDGE)
573 TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
574 else if(aPrjProfile.ShapeType() == TopAbs_WIRE)
575 TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
576 else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
577 TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
579 TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
581 anExp.Init(aPrjProfile, TopAbs_EDGE);
583 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
587 if(aV1.IsNull() || aV2.IsNull())
589 DEBTRACE("aV1.IsNull() || aV2.IsNull()");
592 gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
593 gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
596 BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2);
599 DEBTRACE("!aMk.IsDone()");
602 const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
603 Standard_Integer aNum(0);
605 TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
606 for(;anExplo.More();anExplo.Next()) aNum++;
607 // check for self-intersection
608 const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
609 Standard_Boolean hasInt(false);
610 Standard_Real aSqDist(DBL_MAX);
611 Standard_Integer anIndx(0);
612 BRepExtrema_ExtCC aCC;
613 aCC.Initialize(anEdg2);
615 anExplo.Init(aHydraulicWire, TopAbs_EDGE);
616 for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
617 const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
620 Standard_Boolean hasSol(false);
624 for(Standard_Integer i=1; i<= aCC.NbExt();i++)
625 if(aCC.SquareDistance(i) < aSqDist) {
626 aSqDist = aCC.SquareDistance(i);
632 if(aSqDist <= SquareTolerance) { // hasInt
633 const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
635 TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
636 theOutPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
638 Standard_Real aPar = aCC.ParameterOnE1(anIndx);
646 TopExp::Vertices(anEdg1, aV1, aV2);
647 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
650 } else if(aNum > 1) {
651 TopExp::Vertices(anEdg1, aV1, aV2);
652 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
657 DEBTRACE("!hasInt " << aPnt1.X() << " " << aPnt1.Y() << " " << aPnt2.X() << " " << aPnt2.Y() << " --- " << aSqDist);
661 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
663 if ( theProfile.IsNull() )
666 // Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
667 // if ( aHydAxis.IsNull() )
671 BuildRefFace( aPlane );
673 Standard_Real aPar(.0);
674 if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
675 return false; // Object is already in reference list or it has no intersection
676 //DEBTRACE("AddProfile - insertParameter " << aPar);
677 int aProfileIndex = insertParameter( aPar );
678 insertProfileInToOrder( theProfile, aProfileIndex );
680 if (GetInterpolationMethod()==0)
681 DTM()->SetProfiles( GetProfiles() );
683 LISM()->SetProfiles( GetProfiles() );
685 // Indicate model of the need to update the stream presentation
691 bool HYDROData_Stream::SetProfiles( const HYDROData_SequenceOfObjects& theProfiles,
692 const bool& theIsToOrder )
694 DEBTRACE(" --- SetProfiles " <<theIsToOrder );
697 for ( int i = 1; i <= theProfiles.Length(); ++i )
699 Handle(HYDROData_Profile) aProfile =
700 Handle(HYDROData_Profile)::DownCast( theProfiles.Value( i ) );
701 if ( aProfile.IsNull() )
704 if ( !AddProfile( aProfile ) )
706 DTM()->SetProfiles( HYDROData_SequenceOfObjects() );
711 else // Just store the sequence of objects as is
713 bool anIsToUpdate = true;
715 HYDROData_SequenceOfObjects anOldProfiles = GetProfiles();
716 if ( anOldProfiles.Length() == theProfiles.Length() )
718 anIsToUpdate = false;
720 for ( int i = 1; i <= theProfiles.Length(); ++i )
722 Handle(HYDROData_Entity) anOldProfile = anOldProfiles.Value( i );
723 Handle(HYDROData_Entity) aNewProfile = theProfiles.Value( i );
724 if ( !IsEqual( anOldProfile, aNewProfile ) )
732 SetReferenceObjects( theProfiles, DataTag_Profile );
738 if (GetInterpolationMethod()==0)
739 DTM()->SetProfiles( GetProfiles() );
741 LISM()->SetProfiles( GetProfiles() );
745 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
747 return GetReferenceObjects( DataTag_Profile );
750 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
752 if ( theProfile.IsNull() )
755 int aProfileIndex = -1;
757 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
758 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
759 for ( int i = 0 ; anIter.More(); anIter.Next(), ++i )
761 Handle(HYDROData_Profile) aProfile =
762 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
763 if ( aProfile.IsNull() )
766 if ( IsEqual( theProfile, aProfile ) )
773 if ( aProfileIndex == -1 )
776 RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
778 // Remove parameter for removed profile
779 removeParameter( aProfileIndex );
781 // Indicate model of the need to update the stream presentation
787 void HYDROData_Stream::RemoveProfiles()
789 ClearReferenceObjects( DataTag_Profile );
791 // Remove the parameters array
792 removeParametersArray();
794 // Indicate model of the need to update the stream presentation
799 int HYDROData_Stream::GetInterpolationMethod() const
801 return GetInteger( DataTag_InterpMethod );
804 void HYDROData_Stream::SetInterpolationMethod( int theMethod ) //if DTM => 0 ; if LISM => 1
806 SetInteger( DataTag_InterpMethod, theMethod );
811 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile,
812 const int theBeforeIndex )
814 //Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
815 if ( theProfile.IsNull() )
818 //TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
819 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
820 if ( aProfileWire.IsNull() )
823 if ( theBeforeIndex == -1 )
824 AddReferenceObject( theProfile, DataTag_Profile );
826 InsertReferenceObject( theProfile, DataTag_Profile, theBeforeIndex );
829 void HYDROData_Stream::BuildRefFace( TopoDS_Face& thePlane )
831 thePlane = BRepBuilderAPI_MakeFace(gp_Pln(gp_Pnt(0,0,0),gp_Dir(0,0,1))).Face();
834 void HYDROData_Stream::updateProfilesOrder()
836 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
837 if ( aRefProfiles.IsEmpty() )
840 // At first we remove all profiles from order
843 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
844 if ( aHydAxis.IsNull() )
848 BuildRefFace( aPlane );
850 Standard_Real aPar( .0 );
854 TopoDS_Compound aCmp;
855 aBB.MakeCompound(aCmp);
858 HYDROData_DataMapOfRealOfHDProfile aDM;
859 TColStd_ListOfReal aList;
860 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
861 for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
863 Handle(HYDROData_Profile) aProfile =
864 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
866 TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
867 aBB.Add( aCmp, aProfileWire );
869 if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
872 aDM.Bind( aPar, aProfile );
873 aList.Append( aPar );
876 if ( aList.IsEmpty() )
879 QVector<double> anArr( aList.Extent() );
881 TColStd_ListIteratorOfListOfReal it( aList );
882 for ( int j = 1; it.More(); it.Next(), j++ )
883 anArr[j-1] = it.Value();
886 if ( aList.Extent() > 1 )
888 //TCollection_CompareOfReal Compar;
889 //SortTools_QuickSortOfReal::Sort( anArr, Compar );
890 std::sort( anArr.begin(), anArr.end() );
892 for (int j = 1; j <= anArr.size(); j++) {
893 const Standard_Real aKey = anArr[j-1];
894 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
895 insertProfileInToOrder( aProfile );
897 } else if ( aList.Extent() == 1 ) {
898 const Standard_Real aKey = aList.Last();
899 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
900 insertProfileInToOrder( aProfile );
903 setParametersArray( anArr );
906 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
907 BRepTools::Write(aHydraulicWire, "Path.brep");
908 BRepTools::Write(aCmp, "Prof.brep");
912 ObjectKind HYDROData_Stream::getAltitudeObjectType() const
914 int InterpMethod = GetInterpolationMethod();
915 if (InterpMethod == 1)
921 void HYDROData_Stream::setParametersArray( const QVector<double>& theArray )
923 if ( theArray.size() == 0 )
925 removeParametersArray();
929 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray );
931 int n = theArray.size();
932 Handle(TDataStd_RealArray) aParamsArray =
933 TDataStd_RealArray::Set( aLabel, 1, n );
934 aParamsArray->SetID(TDataStd_RealArray::GetID());
935 for ( int i = 0; i < n; ++i )
937 const Standard_Real& aParam = theArray[i];
938 aParamsArray->SetValue( i+1, aParam );
942 TColStd_Array1OfReal* HYDROData_Stream::getParametersArray() const
944 TColStd_Array1OfReal* anArray = NULL;
946 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
947 if ( !aLabel.IsNull() )
949 Handle(TDataStd_RealArray) aParamsArray;
950 if ( aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
952 anArray = new TColStd_Array1OfReal( aParamsArray->Lower(), aParamsArray->Upper() );
953 for ( int i = aParamsArray->Lower(), n = aParamsArray->Upper(); i <= n; ++i )
955 const Standard_Real& aParam = aParamsArray->Value( i );
956 anArray->SetValue( i, aParam );
964 void HYDROData_Stream::removeParametersArray()
966 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
967 if ( !aLabel.IsNull() )
968 aLabel.ForgetAllAttributes();
971 int HYDROData_Stream::insertParameter( const Standard_Real& theParam )
975 TColStd_Array1OfReal* anArr = getParametersArray();
980 QVector<double> aNewArr( anArr->Upper() +1 );
981 bool isInserted = false;
982 for ( int i = anArr->Lower(), j = i, n = anArr->Upper(); i <= n; ++i, ++j )
984 const Standard_Real& aStoredParam = anArr->Value( i );
987 if ( theParam > aStoredParam )
994 aNewArr[j-1] = theParam;
1000 aNewArr[j-1] = aStoredParam;
1006 aNewArr[aNewArr.size()-1] = theParam;
1009 setParametersArray( aNewArr );
1014 QVector<double> aNewArr( 1 );
1015 aNewArr[0] = theParam;
1016 setParametersArray( aNewArr );
1022 void HYDROData_Stream::removeParameter( const int& theIndex )
1024 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
1025 if ( aLabel.IsNull() )
1028 Handle(TDataStd_RealArray) aParamsArray;
1029 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
1032 if ( aParamsArray->Length() == 1 )
1034 removeParametersArray();
1038 QVector<double> aNewArr( aParamsArray->Upper() - 2 );
1040 for ( int i = aParamsArray->Lower(), j = i, k = 0, n = aParamsArray->Upper(); i <= n; ++i, ++k )
1042 const Standard_Real& aStoredParam = aParamsArray->Value( i );
1043 if ( k == theIndex )
1046 aNewArr[j-1] = aStoredParam;
1050 setParametersArray( aNewArr );
1053 bool HYDROData_Stream::GenerateBottomPolyline()
1056 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
1057 if ( aDocument.IsNull() ) {
1061 // Collect bottom points ( one bottom point from each profile of the stream )
1062 HYDROData_Profile::ProfilePoints aBottomPoints;
1064 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
1065 for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; i++ ) {
1066 const Handle(HYDROData_Profile) aProfile =
1067 Handle(HYDROData_Profile)::DownCast( aSeqOfProfiles.Value( i ) );
1068 if ( aProfile.IsNull() ) {
1072 aBottomPoints.Append( aProfile->GetBottomPoint() );
1075 int aNbBottomPoints = aBottomPoints.Size();
1077 if ( aNbBottomPoints < 2 ) {
1081 // Create bottom polyline object if the stream doesn't contain it yet
1082 Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
1083 if ( aBottom.IsNull() ) {
1084 aBottom = Handle(HYDROData_Polyline3D)::DownCast( aDocument->CreateObject( KIND_POLYLINE ) );
1085 QString aBaseName = GetName() + "_bottom";
1086 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
1087 aBottom->SetName( aName );
1089 SetReferenceObject( aBottom, DataTag_BottomPolyline );
1092 // Create 2D polyline if the bottom polyline doesn't contain it yet
1093 Handle(HYDROData_PolylineXY) aPolylineXY = aBottom->GetPolylineXY();
1094 if ( aPolylineXY.IsNull() ) {
1095 aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( aDocument->CreateObject( KIND_POLYLINEXY ) );
1096 QString aBaseName = GetName() + "_bottom_2d";
1097 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
1098 aPolylineXY->SetName( aName );
1099 aBottom->SetPolylineXY( aPolylineXY, false );
1102 aPolylineXY->RemoveSections();
1103 aPolylineXY->AddSection( "", HYDROData_PolylineXY::SECTION_SPLINE, false );
1105 // Create profile if the bottom polyline doesn't contain it yet
1106 Handle(HYDROData_ProfileUZ) aProfileUZ = aBottom->GetProfileUZ();
1107 if ( aProfileUZ.IsNull() ) {
1108 Handle(HYDROData_Profile) aProfile =
1109 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
1110 QString aBaseName = GetName() + "_bottom_profile";
1111 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
1112 aProfile->SetName( aName );
1113 aProfileUZ = aProfile->GetProfileUZ( true );
1114 aBottom->SetProfileUZ( aProfileUZ );
1117 aProfileUZ->RemoveSection( 0 );
1119 aProfileUZ->CalculateAndAddPoints(aBottomPoints, aPolylineXY, true);
1124 Handle(HYDROData_Polyline3D) HYDROData_Stream::GetBottomPolyline() const
1126 return Handle(HYDROData_Polyline3D)::DownCast(
1127 GetReferenceObject( DataTag_BottomPolyline ) );
1130 bool HYDROData_Stream::SetBottomPolyline( const Handle(HYDROData_Polyline3D)& theBottom )
1132 if ( theBottom.IsNull() ) {
1136 SetReferenceObject( theBottom, DataTag_BottomPolyline );
1141 bool HYDROData_Stream::Interpolate( HYDROData_IProfilesInterpolator* theInterpolator )
1144 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
1145 if ( aDocument.IsNull() ) {
1149 if ( theInterpolator->GetCalculatedProfilesNumber() < 1 ) {
1150 theInterpolator->Calculate();
1153 if ( theInterpolator->GetErrorCode() != OK ) {
1159 for ( int aProfileInd = 0; aProfileInd < theInterpolator->GetCalculatedProfilesNumber(); aProfileInd++ ) {
1160 // Get calculated point coordinates
1161 HYDROData_Profile::ProfilePoints aResultPoints = theInterpolator->GetResultProfilePoints( aProfileInd );
1162 if ( aResultPoints.IsEmpty() ) {
1167 // Create profile object
1168 Handle(HYDROData_Profile) aProfile =
1169 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
1170 QString aBaseName = GetName() + "_interp_profile";
1171 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName );
1172 aProfile->SetName( aName );
1174 // Fill the profile with points
1175 aProfile->SetProfilePoints( aResultPoints );
1177 // Add profile to the stream
1178 bool isAdded = AddProfile( aProfile );
1192 void HYDROData_Stream::CopyTo( const Handle(HYDROData_Entity)& theDestination,
1193 bool isGenerateNewName ) const
1196 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
1197 if ( aDocument.IsNull() ) {
1202 HYDROData_Entity::CopyTo( theDestination, isGenerateNewName );
1204 Handle(HYDROData_Stream) aStreamCopy =
1205 Handle(HYDROData_Stream)::DownCast( theDestination );
1207 // Copy bottom polyline if exists
1208 if ( !aStreamCopy.IsNull() ) {
1209 const Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
1210 if ( !aBottom.IsNull() ) {
1211 aStreamCopy->ClearReferenceObjects( DataTag_BottomPolyline );
1212 aStreamCopy->GenerateBottomPolyline();
1213 const Handle(HYDROData_Polyline3D) aBottomCopy = aStreamCopy->GetBottomPolyline();
1214 if ( !aBottomCopy.IsNull() && !aBottomCopy->GetPolylineXY().IsNull() ) {
1215 aBottomCopy->GetPolylineXY()->Update();
1216 aBottomCopy->Update();
1221 void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) theArrayOfFPnt,
1222 const Handle(TColgp_HArray1OfPnt) theArrayOfLPnt,
1223 const Handle(TopTools_HArray1OfShape) theArrOfProfiles,
1224 PrsDefinition& thePrs )
1227 HYDROData_Bathymetry::AltitudePoints left;
1228 for (int i = theArrayOfLPnt->Lower(); i <= theArrayOfLPnt->Upper(); i++)
1230 left.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfLPnt->Value(i).X(),
1231 theArrayOfLPnt->Value(i).Y(),
1232 theArrayOfLPnt->Value(i).Z()));
1235 HYDROData_Bathymetry::AltitudePoints right;
1236 for (int i = theArrayOfFPnt->Lower(); i <= theArrayOfFPnt->Upper(); i++)
1238 right.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfFPnt->Value(i).X(),
1239 theArrayOfFPnt->Value(i).Y(),
1240 theArrayOfFPnt->Value(i).Z()));
1243 std::vector<HYDROData_Bathymetry::AltitudePoints> dummy;
1244 TopTools_IndexedMapOfOrientedShape ll = HYDROData_DTM::Create3DShape(left, right, dummy);
1246 TopoDS_Shape LB, RB, IL, OL;
1250 TopAbs_ShapeEnum ll1_sht = ll(1).ShapeType();
1251 TopAbs_ShapeEnum ll2_sht = ll(2).ShapeType();
1252 if ((ll1_sht == TopAbs_WIRE || ll1_sht == TopAbs_EDGE) &&
1253 (ll2_sht == TopAbs_WIRE || ll2_sht == TopAbs_EDGE))
1260 IL = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Lower())); //TODO check that
1261 OL = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Upper()));
1263 //make new compound so it's shapes will be in known order to build correct projection
1265 TopoDS_Compound newCmp;
1266 BB.MakeCompound(newCmp);
1272 thePrs.myPrs3D = newCmp;
1274 TopTools_SequenceOfShape LS;
1275 //HYDROData_DTM::Get2dFaceFrom3dPres( newCmp, TopoDS::Face(thePrs.myPrs2D), &LS, ind );
1277 HYDROData_DTM::GetPlanarFaceFromBanks(TopoDS::Edge(LB), TopoDS::Edge(RB), TopoDS::Face(thePrs.myPrs2D), &LS);
1280 TopTools_IndexedMapOfShape EE;
1281 TopExp::MapShapes(thePrs.myPrs2D, TopAbs_EDGE, EE);
1283 for (int i = 1; i <= 4; i++)
1285 TopoDS_Shape W = LS(i);
1286 TopTools_IndexedMapOfShape EW;
1287 TopExp::MapShapes(W, TopAbs_EDGE, EW);
1288 for (int k = 1; k <= EW.Extent(); k++)
1289 noncontNb += !EE.Contains(EW(k));
1291 //noncontNb > 0 => some problem with edge history
1292 assert(noncontNb == 0);
1295 thePrs.myLeftBank = LS(1);
1296 thePrs.myInlet = LS(2);
1297 thePrs.myOutlet = LS(3);
1298 thePrs.myRightBank = LS(4);