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_Bathymetry.h>
33 #include <TDataStd_RealArray.hxx>
35 #include <Precision.hxx>
37 #include <NCollection_DataMap.hxx>
39 #include <TColStd_Array1OfReal.hxx>
40 #include <TColStd_ListOfReal.hxx>
41 #include <TColStd_ListIteratorOfListOfReal.hxx>
42 #include <TColgp_Array1OfPnt.hxx>
43 #include <TColgp_HArray1OfPnt.hxx>
46 #include <TopoDS_Wire.hxx>
47 #include <TopoDS_Shell.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Vertex.hxx>
52 #include <TopExp_Explorer.hxx>
54 #include <Bnd_Box.hxx>
56 #include <BRep_Builder.hxx>
57 #include <BRepBuilderAPI_MakeEdge.hxx>
58 #include <BRepBuilderAPI_MakeWire.hxx>
59 #include <BRepBuilderAPI_MakeFace.hxx>
61 #include <BRepBndLib.hxx>
62 #include <BRepProj_Projection.hxx>
63 #include <BRepExtrema_ExtCC.hxx>
64 #include <BRepCheck_Analyzer.hxx>
74 #include <GeomAPI_Interpolate.hxx>
75 #include <Geom_BSplineCurve.hxx>
77 #include <TopTools_HArray1OfShape.hxx>
78 #include <TopTools_IndexedMapOfOrientedShape.hxx>
79 #include <TopTools_ListIteratorOfListOfShape.hxx>
80 #include <TopTools_SequenceOfShape.hxx>
81 #include <TopTools_IndexedMapOfShape.hxx>
84 #include <QStringList>
87 //#define DEB_STREAM 1
89 //#define DEB_HASINT 1
90 //#define DEB_UPDATE 1
91 #include <BRepTools.hxx>
92 #include <TCollection_AsciiString.hxx>
96 #include "HYDRO_trace.hxx"
100 typedef NCollection_DataMap<Standard_Real, Handle(HYDROData_Profile)> HYDROData_DataMapOfRealOfHDProfile;
102 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
105 HYDROData_Stream::HYDROData_Stream()
106 : HYDROData_NaturalObject( Geom_3d )
110 HYDROData_Stream::~HYDROData_Stream()
114 QStringList HYDROData_Stream::DumpToPython( const QString& thePyScriptPath,
115 MapOfTreatedObjects& theTreatedObjects ) const
117 QStringList aResList = dumpObjectCreation( theTreatedObjects );
118 QString aName = GetObjPyName();
120 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
121 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aHydAxis, "SetHydraulicAxis" );
123 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
124 for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; ++i )
126 const Handle(HYDROData_Entity) aProfile = aSeqOfProfiles.Value( i );
127 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aProfile, "AddProfile" );
130 // Set bottom polyline if exists
131 const Handle(HYDROData_Polyline3D) aBottomPolyline = GetBottomPolyline();
132 if ( !aBottomPolyline.IsNull() ) {
133 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aBottomPolyline, "SetBottomPolyline" );
136 QString aDDZs = QString::number( GetDDZ(), 'f', 3 );
137 QString aSSteps = QString::number( GetSpatialStep(), 'f', 3 );
138 aResList << QString( "%1.SetDDZ( %2 )" ).arg( aName ).arg( aDDZs );
139 aResList << QString( "%1.SetSpatialStep( %2 )" ).arg( aName ).arg( aSSteps );
141 aResList << QString( "" );
142 aResList << QString( "%1.Update()" ).arg( aName );
143 aResList << QString( "" );
148 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
150 HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
152 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
153 if ( !aHydAxis.IsNull() )
154 aResSeq.Append( aHydAxis );
156 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
157 aResSeq.Append( aSeqOfProfiles );
162 Handle(Geom_BSplineCurve) HYDROData_Stream::buildInterpolationCurve(
163 const Handle(TColgp_HArray1OfPnt)& theArrayOfPnt )
165 Handle(Geom_BSplineCurve) aBSpline;
166 GeomAPI_Interpolate anInterpolator (theArrayOfPnt, Standard_False, 1.0e-5);
167 anInterpolator.Perform() ;
168 if (anInterpolator.IsDone())
169 aBSpline = anInterpolator.Curve();
173 void HYDROData_Stream::GetWarnings(NCollection_DataMap<Handle(HYDROData_Profile), QSet<QString>>& warnings)
175 warnings = myWarnings;
178 void HYDROData_Stream::Update()
180 if (!GetHydraulicAxis().IsNull())
181 updateProfilesOrder();
183 // Update bottom polyline if exists
184 const Handle(HYDROData_Polyline3D) aBottomPolyline = GetBottomPolyline();
185 if ( !aBottomPolyline.IsNull() ) {
186 if ( GenerateBottomPolyline() ) {
187 Handle(HYDROData_PolylineXY) aPolylineXY = aBottomPolyline->GetPolylineXY();
188 if ( !aPolylineXY.IsNull() ) {
189 aPolylineXY->Update();
191 aBottomPolyline->Update();
195 Handle(HYDROData_DTM) dtm = DTM();
200 dtm->GetWarnings(myWarnings);
202 HYDROData_NaturalObject::Update();
205 bool HYDROData_Stream::IsHas2dPrs() const
210 bool HYDROData_Stream::CreatePresentations( const Handle(HYDROData_DTM)& theDTM,
211 PrsDefinition& thePrs )
213 if ( theDTM.IsNull() )
216 HYDROData_SequenceOfObjects profiles = theDTM->GetProfiles();
217 if( profiles.Length() < 2 )
220 TopoDS_Shape Out3dPres;
221 TopoDS_Shape Out2dPres;
222 TopoDS_Shape OutLeftB;
223 TopoDS_Shape OutRightB;
224 TopoDS_Shape OutInlet;
225 TopoDS_Shape OutOutlet;
227 theDTM->GetPresentationShapes(Out3dPres, Out2dPres, OutLeftB, OutRightB, OutInlet, OutOutlet);
229 thePrs.myInlet = OutInlet;
230 thePrs.myOutlet = OutOutlet;
231 thePrs.myLeftBank = OutLeftB;
232 thePrs.myRightBank = OutRightB;
233 thePrs.myPrs2D = Out2dPres;
234 thePrs.myPrs3D = Out3dPres;
235 /*std::vector<TopoDS_Wire> profiles3d;
236 profiles3d.reserve(profiles.Length());
239 HYDROData_SequenceOfObjects::Iterator anIter( profiles );
240 for (int i=1 ; anIter.More(); anIter.Next(),i++ )
242 Handle(HYDROData_Profile) aProfile =
243 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
245 if ( aProfile.IsNull() )
248 const TopoDS_Shape& aProfileShape = aProfile->GetShape3D();
249 //TopExp_Explorer exp(aProfileShape, TopAbs_EDGE);
250 profiles3d.push_back( TopoDS::Wire(aProfileShape) );
256 void HYDROData_Stream::UpdatePrs( const Handle(HYDROData_DTM)& theDTM )
258 HYDROData_NaturalObject::Update();
260 PrsDefinition aResultPrs;
261 if ( !CreatePresentations( theDTM, aResultPrs ) )
264 SetShape3D( aResultPrs.myPrs3D );
265 SetTopShape( aResultPrs.myPrs2D );
267 // Create the stream groups
268 QString aLeftGroupName = GetName() + "_Left_Bank";
270 Handle(HYDROData_ShapesGroup) aLeftGroup = createGroupObject();
271 aLeftGroup->SetName( aLeftGroupName );
272 aLeftGroup->AddShape( aResultPrs.myLeftBank );
274 QString aRightGroupName = GetName() + "_Right_Bank";
276 Handle(HYDROData_ShapesGroup) aRightGroup = createGroupObject();
277 aRightGroup->SetName( aRightGroupName );
278 aRightGroup->AddShape( aResultPrs.myRightBank );
280 QString anInGroupName = GetName() + "_Inlet";
282 Handle(HYDROData_ShapesGroup) anInGroup = createGroupObject();
283 anInGroup->SetName( anInGroupName );
284 anInGroup->AddShape( aResultPrs.myInlet );
286 QString anOutGroupName = GetName() + "_Outlet";
288 Handle(HYDROData_ShapesGroup) anOutGroup = createGroupObject();
289 anOutGroup->SetName( anOutGroupName );
290 anOutGroup->AddShape( aResultPrs.myOutlet );
293 QColor HYDROData_Stream::DefaultFillingColor() const
295 return QColor( Qt::green );
298 QColor HYDROData_Stream::DefaultBorderColor() const
300 return QColor( Qt::transparent );
303 bool HYDROData_Stream::IsValidAsAxis( const Handle(HYDROData_PolylineXY)& theHydAxis )
305 if ( theHydAxis.IsNull() )
308 TopoDS_Shape aHydraulicShape = theHydAxis->GetShape();
309 if ( aHydraulicShape.IsNull() ||
310 aHydraulicShape.ShapeType() != TopAbs_WIRE ||
311 BRep_Tool::IsClosed( aHydraulicShape ) )
312 return false; // The polyline must be a single not closed wire
317 TopoDS_Shape HYDROData_Stream::GetLeftShape() const
319 HYDROData_SequenceOfObjects aGroups = GetGroups();
320 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 1);
323 TopoDS_Shape HYDROData_Stream::GetRightShape() const
325 HYDROData_SequenceOfObjects aGroups = GetGroups();
326 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 2);
329 TopoDS_Shape HYDROData_Stream::GetInletShape() const
331 HYDROData_SequenceOfObjects aGroups = GetGroups();
332 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 3);
335 TopoDS_Shape HYDROData_Stream::GetOutletShape() const
337 HYDROData_SequenceOfObjects aGroups = GetGroups();
338 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 4);
341 Handle(HYDROData_DTM) HYDROData_Stream::DTM() const
343 const_cast<HYDROData_Stream*>( this )->checkAndSetAltitudeObject();
344 return Handle(HYDROData_DTM)::DownCast( GetAltitudeObject() );
347 double HYDROData_Stream::GetDDZ() const
349 return DTM()->GetDDZ();
352 void HYDROData_Stream::SetDDZ( double theDDZ )
354 DTM()->SetDDZ( theDDZ );
358 double HYDROData_Stream::GetSpatialStep() const
360 return DTM()->GetSpatialStep();
363 void HYDROData_Stream::SetSpatialStep( double theSpatialStep )
365 DTM()->SetSpatialStep( theSpatialStep );
369 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
371 if ( !IsValidAsAxis( theAxis ) )
374 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
375 if ( IsEqual( aPrevAxis, theAxis ) )
378 SetReferenceObject( theAxis, DataTag_HydraulicAxis );
380 // Update the order of profiles
381 updateProfilesOrder();
383 // Indicate model of the need to update the stream presentation
389 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
391 return Handle(HYDROData_PolylineXY)::DownCast(
392 GetReferenceObject( DataTag_HydraulicAxis ) );
395 void HYDROData_Stream::RemoveHydraulicAxis()
397 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
398 if ( aPrevAxis.IsNull() )
401 ClearReferenceObjects( DataTag_HydraulicAxis );
403 // We remove the reference profiles
406 // Indicate model of the need to update the stream presentation
410 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile,
411 const TopoDS_Face& thePlane,
412 Standard_Real& theOutPar ) const
414 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
415 return HasIntersection( aHydAxis, theProfile, thePlane, theOutPar );
418 #include <BRepAlgo_NormalProjection.hxx>
420 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_PolylineXY)& theHydAxis,
421 const Handle(HYDROData_Profile)& theProfile,
422 const TopoDS_Face& thePlane,
423 Standard_Real& theOutPar )
425 if ( theProfile.IsNull() /*|| !IsValidAsAxis( theHydAxis )*/ )
428 if (theHydAxis.IsNull())
429 return true; //empty h_axis; its's OK
431 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() ); //guide line
432 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
433 if ( aProfileWire.IsNull() )
435 DEBTRACE("aProfileWire.IsNull");
439 //BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
440 BRepAlgo_NormalProjection nproj(thePlane);
441 nproj.Add(aProfileWire);
442 nproj.SetDefaultParams();
446 DEBTRACE("!nproj.IsDone");
449 TopoDS_Shape aPrjProfile = nproj.Projection();
450 if(aPrjProfile.IsNull())
452 DEBTRACE("aPrjProfile.IsNull");
455 TopoDS_Vertex aV1, aV2;
456 if(aPrjProfile.ShapeType() == TopAbs_EDGE)
457 TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
458 else if(aPrjProfile.ShapeType() == TopAbs_WIRE)
459 TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
460 else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
461 TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
463 TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
465 anExp.Init(aPrjProfile, TopAbs_EDGE);
467 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
471 if(aV1.IsNull() || aV2.IsNull())
473 DEBTRACE("aV1.IsNull() || aV2.IsNull()");
476 gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
477 gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
480 BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2);
483 DEBTRACE("!aMk.IsDone()");
486 const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
487 Standard_Integer aNum(0);
489 TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
490 for(;anExplo.More();anExplo.Next()) aNum++;
491 // check for self-intersection
492 const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
493 Standard_Boolean hasInt(false);
494 Standard_Real aSqDist(DBL_MAX);
495 Standard_Integer anIndx(0);
496 BRepExtrema_ExtCC aCC;
497 aCC.Initialize(anEdg2);
499 anExplo.Init(aHydraulicWire, TopAbs_EDGE);
500 for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
501 const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
504 Standard_Boolean hasSol(false);
508 for(Standard_Integer i=1; i<= aCC.NbExt();i++)
509 if(aCC.SquareDistance(i) < aSqDist) {
510 aSqDist = aCC.SquareDistance(i);
516 if(aSqDist <= SquareTolerance) { // hasInt
517 const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
519 TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
520 theOutPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
522 Standard_Real aPar = aCC.ParameterOnE1(anIndx);
530 TopExp::Vertices(anEdg1, aV1, aV2);
531 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
534 } else if(aNum > 1) {
535 TopExp::Vertices(anEdg1, aV1, aV2);
536 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
541 DEBTRACE("!hasInt " << aPnt1.X() << " " << aPnt1.Y() << " " << aPnt2.X() << " " << aPnt2.Y() << " --- " << aSqDist);
545 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
547 if ( theProfile.IsNull() )
550 // Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
551 // if ( aHydAxis.IsNull() )
555 BuildRefFace( aPlane );
557 Standard_Real aPar(.0);
558 if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
559 return false; // Object is already in reference list or it has no intersection
560 //DEBTRACE("AddProfile - insertParameter " << aPar);
561 int aProfileIndex = insertParameter( aPar );
562 insertProfileInToOrder( theProfile, aProfileIndex );
564 DTM()->SetProfiles( GetProfiles() );
566 // Indicate model of the need to update the stream presentation
572 bool HYDROData_Stream::SetProfiles( const HYDROData_SequenceOfObjects& theProfiles,
573 const bool& theIsToOrder )
575 DEBTRACE(" --- SetProfiles " <<theIsToOrder );
578 for ( int i = 1; i <= theProfiles.Length(); ++i )
580 Handle(HYDROData_Profile) aProfile =
581 Handle(HYDROData_Profile)::DownCast( theProfiles.Value( i ) );
582 if ( aProfile.IsNull() )
585 if ( !AddProfile( aProfile ) )
587 DTM()->SetProfiles( HYDROData_SequenceOfObjects() );
592 else // Just store the sequence of objects as is
594 bool anIsToUpdate = true;
596 HYDROData_SequenceOfObjects anOldProfiles = GetProfiles();
597 if ( anOldProfiles.Length() == theProfiles.Length() )
599 anIsToUpdate = false;
601 for ( int i = 1; i <= theProfiles.Length(); ++i )
603 Handle(HYDROData_Entity) anOldProfile = anOldProfiles.Value( i );
604 Handle(HYDROData_Entity) aNewProfile = theProfiles.Value( i );
605 if ( !IsEqual( anOldProfile, aNewProfile ) )
613 SetReferenceObjects( theProfiles, DataTag_Profile );
619 DTM()->SetProfiles( GetProfiles() );
623 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
625 return GetReferenceObjects( DataTag_Profile );
628 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
630 if ( theProfile.IsNull() )
633 int aProfileIndex = -1;
635 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
636 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
637 for ( int i = 0 ; anIter.More(); anIter.Next(), ++i )
639 Handle(HYDROData_Profile) aProfile =
640 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
641 if ( aProfile.IsNull() )
644 if ( IsEqual( theProfile, aProfile ) )
651 if ( aProfileIndex == -1 )
654 RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
656 // Remove parameter for removed profile
657 removeParameter( aProfileIndex );
659 // Indicate model of the need to update the stream presentation
665 void HYDROData_Stream::RemoveProfiles()
667 ClearReferenceObjects( DataTag_Profile );
669 // Remove the parameters array
670 removeParametersArray();
672 // Indicate model of the need to update the stream presentation
676 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile,
677 const int theBeforeIndex )
679 //Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
680 if ( theProfile.IsNull() )
683 //TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
684 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
685 if ( aProfileWire.IsNull() )
688 if ( theBeforeIndex == -1 )
689 AddReferenceObject( theProfile, DataTag_Profile );
691 InsertReferenceObject( theProfile, DataTag_Profile, theBeforeIndex );
694 void HYDROData_Stream::BuildRefFace( TopoDS_Face& thePlane )
696 thePlane = BRepBuilderAPI_MakeFace(gp_Pln(gp_Pnt(0,0,0),gp_Dir(0,0,1))).Face();
699 void HYDROData_Stream::updateProfilesOrder()
701 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
702 if ( aRefProfiles.IsEmpty() )
705 // At first we remove all profiles from order
708 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
709 if ( aHydAxis.IsNull() )
713 BuildRefFace( aPlane );
715 Standard_Real aPar( .0 );
719 TopoDS_Compound aCmp;
720 aBB.MakeCompound(aCmp);
723 HYDROData_DataMapOfRealOfHDProfile aDM;
724 TColStd_ListOfReal aList;
725 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
726 for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
728 Handle(HYDROData_Profile) aProfile =
729 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
731 TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
732 aBB.Add( aCmp, aProfileWire );
734 if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
737 aDM.Bind( aPar, aProfile );
738 aList.Append( aPar );
741 if ( aList.IsEmpty() )
744 QVector<double> anArr( aList.Extent() );
746 TColStd_ListIteratorOfListOfReal it( aList );
747 for ( int j = 1; it.More(); it.Next(), j++ )
748 anArr[j-1] = it.Value();
751 if ( aList.Extent() > 1 )
753 //TCollection_CompareOfReal Compar;
754 //SortTools_QuickSortOfReal::Sort( anArr, Compar );
755 std::sort( anArr.begin(), anArr.end() );
757 for (int j = 1; j <= anArr.size(); j++) {
758 const Standard_Real aKey = anArr[j-1];
759 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
760 insertProfileInToOrder( aProfile );
762 } else if ( aList.Extent() == 1 ) {
763 const Standard_Real aKey = aList.Last();
764 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
765 insertProfileInToOrder( aProfile );
768 setParametersArray( anArr );
771 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
772 BRepTools::Write(aHydraulicWire, "Path.brep");
773 BRepTools::Write(aCmp, "Prof.brep");
777 ObjectKind HYDROData_Stream::getAltitudeObjectType() const
782 void HYDROData_Stream::setParametersArray( const QVector<double>& theArray )
784 if ( theArray.size() == 0 )
786 removeParametersArray();
790 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray );
792 int n = theArray.size();
793 Handle(TDataStd_RealArray) aParamsArray =
794 TDataStd_RealArray::Set( aLabel, 1, n );
795 aParamsArray->SetID(TDataStd_RealArray::GetID());
796 for ( int i = 0; i < n; ++i )
798 const Standard_Real& aParam = theArray[i];
799 aParamsArray->SetValue( i+1, aParam );
803 TColStd_Array1OfReal* HYDROData_Stream::getParametersArray() const
805 TColStd_Array1OfReal* anArray = NULL;
807 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
808 if ( !aLabel.IsNull() )
810 Handle(TDataStd_RealArray) aParamsArray;
811 if ( aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
813 anArray = new TColStd_Array1OfReal( aParamsArray->Lower(), aParamsArray->Upper() );
814 for ( int i = aParamsArray->Lower(), n = aParamsArray->Upper(); i <= n; ++i )
816 const Standard_Real& aParam = aParamsArray->Value( i );
817 anArray->SetValue( i, aParam );
825 void HYDROData_Stream::removeParametersArray()
827 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
828 if ( !aLabel.IsNull() )
829 aLabel.ForgetAllAttributes();
832 int HYDROData_Stream::insertParameter( const Standard_Real& theParam )
836 TColStd_Array1OfReal* anArr = getParametersArray();
841 QVector<double> aNewArr( anArr->Upper() +1 );
842 bool isInserted = false;
843 for ( int i = anArr->Lower(), j = i, n = anArr->Upper(); i <= n; ++i, ++j )
845 const Standard_Real& aStoredParam = anArr->Value( i );
848 if ( theParam > aStoredParam )
855 aNewArr[j-1] = theParam;
861 aNewArr[j-1] = aStoredParam;
867 aNewArr[aNewArr.size()-1] = theParam;
870 setParametersArray( aNewArr );
875 QVector<double> aNewArr( 1 );
876 aNewArr[0] = theParam;
877 setParametersArray( aNewArr );
883 void HYDROData_Stream::removeParameter( const int& theIndex )
885 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
886 if ( aLabel.IsNull() )
889 Handle(TDataStd_RealArray) aParamsArray;
890 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
893 if ( aParamsArray->Length() == 1 )
895 removeParametersArray();
899 QVector<double> aNewArr( aParamsArray->Upper() - 2 );
901 for ( int i = aParamsArray->Lower(), j = i, k = 0, n = aParamsArray->Upper(); i <= n; ++i, ++k )
903 const Standard_Real& aStoredParam = aParamsArray->Value( i );
907 aNewArr[j-1] = aStoredParam;
911 setParametersArray( aNewArr );
914 bool HYDROData_Stream::GenerateBottomPolyline()
917 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
918 if ( aDocument.IsNull() ) {
922 // Collect bottom points ( one bottom point from each profile of the stream )
923 HYDROData_Profile::ProfilePoints aBottomPoints;
925 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
926 for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; i++ ) {
927 const Handle(HYDROData_Profile) aProfile =
928 Handle(HYDROData_Profile)::DownCast( aSeqOfProfiles.Value( i ) );
929 if ( aProfile.IsNull() ) {
933 aBottomPoints.Append( aProfile->GetBottomPoint() );
936 int aNbBottomPoints = aBottomPoints.Size();
938 if ( aNbBottomPoints < 2 ) {
942 // Create bottom polyline object if the stream doesn't contain it yet
943 Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
944 if ( aBottom.IsNull() ) {
945 aBottom = Handle(HYDROData_Polyline3D)::DownCast( aDocument->CreateObject( KIND_POLYLINE ) );
946 QString aBaseName = GetName() + "_bottom";
947 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
948 aBottom->SetName( aName );
950 SetReferenceObject( aBottom, DataTag_BottomPolyline );
953 // Create 2D polyline if the bottom polyline doesn't contain it yet
954 Handle(HYDROData_PolylineXY) aPolylineXY = aBottom->GetPolylineXY();
955 if ( aPolylineXY.IsNull() ) {
956 aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( aDocument->CreateObject( KIND_POLYLINEXY ) );
957 QString aBaseName = GetName() + "_bottom_2d";
958 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
959 aPolylineXY->SetName( aName );
960 aBottom->SetPolylineXY( aPolylineXY, false );
963 aPolylineXY->RemoveSections();
964 aPolylineXY->AddSection( "", HYDROData_PolylineXY::SECTION_SPLINE, false );
966 // Create profile if the bottom polyline doesn't contain it yet
967 Handle(HYDROData_ProfileUZ) aProfileUZ = aBottom->GetProfileUZ();
968 if ( aProfileUZ.IsNull() ) {
969 Handle(HYDROData_Profile) aProfile =
970 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
971 QString aBaseName = GetName() + "_bottom_profile";
972 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
973 aProfile->SetName( aName );
974 aProfileUZ = aProfile->GetProfileUZ( true );
975 aBottom->SetProfileUZ( aProfileUZ );
978 aProfileUZ->RemoveSection( 0 );
980 aProfileUZ->CalculateAndAddPoints(aBottomPoints, aPolylineXY, true);
985 Handle(HYDROData_Polyline3D) HYDROData_Stream::GetBottomPolyline() const
987 return Handle(HYDROData_Polyline3D)::DownCast(
988 GetReferenceObject( DataTag_BottomPolyline ) );
991 bool HYDROData_Stream::SetBottomPolyline( const Handle(HYDROData_Polyline3D)& theBottom )
993 if ( theBottom.IsNull() ) {
997 SetReferenceObject( theBottom, DataTag_BottomPolyline );
1002 bool HYDROData_Stream::Interpolate( HYDROData_IProfilesInterpolator* theInterpolator )
1005 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
1006 if ( aDocument.IsNull() ) {
1010 if ( theInterpolator->GetCalculatedProfilesNumber() < 1 ) {
1011 theInterpolator->Calculate();
1014 if ( theInterpolator->GetErrorCode() != OK ) {
1020 for ( int aProfileInd = 0; aProfileInd < theInterpolator->GetCalculatedProfilesNumber(); aProfileInd++ ) {
1021 // Get calculated point coordinates
1022 HYDROData_Profile::ProfilePoints aResultPoints = theInterpolator->GetResultProfilePoints( aProfileInd );
1023 if ( aResultPoints.IsEmpty() ) {
1028 // Create profile object
1029 Handle(HYDROData_Profile) aProfile =
1030 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
1031 QString aBaseName = GetName() + "_interp_profile";
1032 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName );
1033 aProfile->SetName( aName );
1035 // Fill the profile with points
1036 aProfile->SetProfilePoints( aResultPoints );
1038 // Add profile to the stream
1039 bool isAdded = AddProfile( aProfile );
1053 void HYDROData_Stream::CopyTo( const Handle(HYDROData_Entity)& theDestination,
1054 bool isGenerateNewName ) const
1057 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
1058 if ( aDocument.IsNull() ) {
1063 HYDROData_Entity::CopyTo( theDestination, isGenerateNewName );
1065 Handle(HYDROData_Stream) aStreamCopy =
1066 Handle(HYDROData_Stream)::DownCast( theDestination );
1068 // Copy bottom polyline if exists
1069 if ( !aStreamCopy.IsNull() ) {
1070 const Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
1071 if ( !aBottom.IsNull() ) {
1072 aStreamCopy->ClearReferenceObjects( DataTag_BottomPolyline );
1073 aStreamCopy->GenerateBottomPolyline();
1074 const Handle(HYDROData_Polyline3D) aBottomCopy = aStreamCopy->GetBottomPolyline();
1075 if ( !aBottomCopy.IsNull() && !aBottomCopy->GetPolylineXY().IsNull() ) {
1076 aBottomCopy->GetPolylineXY()->Update();
1077 aBottomCopy->Update();
1082 void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) theArrayOfFPnt,
1083 const Handle(TColgp_HArray1OfPnt) theArrayOfLPnt,
1084 const Handle(TopTools_HArray1OfShape) theArrOfProfiles,
1085 PrsDefinition& thePrs )
1088 HYDROData_Bathymetry::AltitudePoints left;
1089 for (int i = theArrayOfLPnt->Lower(); i <= theArrayOfLPnt->Upper(); i++)
1091 left.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfLPnt->Value(i).X(),
1092 theArrayOfLPnt->Value(i).Y(),
1093 theArrayOfLPnt->Value(i).Z()));
1096 HYDROData_Bathymetry::AltitudePoints right;
1097 for (int i = theArrayOfFPnt->Lower(); i <= theArrayOfFPnt->Upper(); i++)
1099 right.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfFPnt->Value(i).X(),
1100 theArrayOfFPnt->Value(i).Y(),
1101 theArrayOfFPnt->Value(i).Z()));
1104 std::vector<HYDROData_Bathymetry::AltitudePoints> dummy;
1105 TopTools_IndexedMapOfOrientedShape ll = HYDROData_DTM::Create3DShape(left, right, dummy);
1107 TopoDS_Shape LB, RB, IL, OL;
1111 TopAbs_ShapeEnum ll1_sht = ll(1).ShapeType();
1112 TopAbs_ShapeEnum ll2_sht = ll(2).ShapeType();
1113 if ((ll1_sht == TopAbs_WIRE || ll1_sht == TopAbs_EDGE) &&
1114 (ll2_sht == TopAbs_WIRE || ll2_sht == TopAbs_EDGE))
1121 IL = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Lower())); //TODO check that
1122 OL = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Upper()));
1124 //make new compound so it's shapes will be in known order to build correct projection
1126 TopoDS_Compound newCmp;
1127 BB.MakeCompound(newCmp);
1133 thePrs.myPrs3D = newCmp;
1135 TopTools_SequenceOfShape LS;
1136 //HYDROData_DTM::Get2dFaceFrom3dPres( newCmp, TopoDS::Face(thePrs.myPrs2D), &LS, ind );
1138 HYDROData_DTM::GetPlanarFaceFromBanks(TopoDS::Edge(LB), TopoDS::Edge(RB), TopoDS::Face(thePrs.myPrs2D), &LS);
1141 TopTools_IndexedMapOfShape EE;
1142 TopExp::MapShapes(thePrs.myPrs2D, TopAbs_EDGE, EE);
1144 for (int i = 1; i <= 4; i++)
1146 TopoDS_Shape W = LS(i);
1147 TopTools_IndexedMapOfShape EW;
1148 TopExp::MapShapes(W, TopAbs_EDGE, EW);
1149 for (int k = 1; k <= EW.Extent(); k++)
1150 noncontNb += !EE.Contains(EW(k));
1152 //noncontNb > 0 => some problem with edge history
1153 assert(noncontNb == 0);
1156 thePrs.myLeftBank = LS(1);
1157 thePrs.myInlet = LS(2);
1158 thePrs.myOutlet = LS(3);
1159 thePrs.myRightBank = LS(4);