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 QString HYDROData_Stream::GetBathyName()
393 ObjectKind ok = getAltitudeObjectType();
396 Handle(HYDROData_DTM) dtm = DTM();
398 name = dtm->GetName();
400 else if (ok == KIND_LISM)
402 Handle(HYDROData_LISM) lism = LISM();
404 name = lism->GetName();
409 Handle(HYDROData_DTM) HYDROData_Stream::DTM() const
411 const_cast<HYDROData_Stream*>( this )->checkAndSetAltitudeObject();
412 return Handle(HYDROData_DTM)::DownCast( GetAltitudeObject() );
415 Handle(HYDROData_LISM) HYDROData_Stream::LISM() const
417 const_cast<HYDROData_Stream*>( this )->checkAndSetAltitudeObject();
418 return Handle(HYDROData_LISM)::DownCast( GetAltitudeObject() );
421 double HYDROData_Stream::GetDDZ() const
423 return DTM()->GetDDZ();
426 void HYDROData_Stream::SetDDZ( double theDDZ )
428 DTM()->SetDDZ( theDDZ );
432 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetLeftBank() const
434 return LISM()->GetLeftBank();
437 void HYDROData_Stream::SetLeftBank( const Handle(HYDROData_PolylineXY)& theBank )
439 LISM()->SetLeftBank( theBank );
443 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetRightBank() const
445 return LISM()->GetRightBank();
448 void HYDROData_Stream::SetRightBank( const Handle(HYDROData_PolylineXY)& theBank )
450 LISM()->SetRightBank( theBank );
455 double HYDROData_Stream::GetHaxStep() const
457 return LISM()->GetHaxStep();
460 void HYDROData_Stream::SetHaxStep( double theHaxStep )
462 LISM()->SetHaxStep( theHaxStep );
466 int HYDROData_Stream::GetNbProfilePoints() const
468 return LISM()->GetNbProfilePoints();
471 void HYDROData_Stream::SetNbProfilePoints( int theNbPoints )
473 LISM()->SetNbProfilePoints( theNbPoints );
477 double HYDROData_Stream::GetSpatialStep() const
479 if (GetInterpolationMethod() == 0)
480 return DTM()->GetSpatialStep();
482 return LISM()->GetHaxStep();
485 void HYDROData_Stream::SetSpatialStep( double theSpatialStep )
487 if (GetInterpolationMethod() == 0 )
488 DTM()->SetSpatialStep( theSpatialStep );
490 LISM()->SetHaxStep( theSpatialStep );
494 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
496 if (GetInterpolationMethod() == 0)
498 if ( !IsValidAsAxis( theAxis ) )
501 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
502 if ( IsEqual( aPrevAxis, theAxis ) )
505 SetReferenceObject( theAxis, DataTag_HydraulicAxis );
507 // Update the order of profiles
508 updateProfilesOrder();
510 // Indicate model of the need to update the stream presentation
515 LISM()->SetHydraulicAxis( theAxis );
522 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
524 if (GetInterpolationMethod() == 0)
525 return Handle(HYDROData_PolylineXY)::DownCast( GetReferenceObject( DataTag_HydraulicAxis ) );
527 return LISM()->GetHydraulicAxis();
530 void HYDROData_Stream::RemoveHydraulicAxis()
532 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
533 if ( aPrevAxis.IsNull() )
536 ClearReferenceObjects( DataTag_HydraulicAxis );
538 // We remove the reference profiles
541 // Indicate model of the need to update the stream presentation
545 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile,
546 const TopoDS_Face& thePlane,
547 Standard_Real& theOutPar ) const
549 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
550 return HasIntersection( aHydAxis, theProfile, thePlane, theOutPar );
553 #include <BRepAlgo_NormalProjection.hxx>
555 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_PolylineXY)& theHydAxis,
556 const Handle(HYDROData_Profile)& theProfile,
557 const TopoDS_Face& thePlane,
558 Standard_Real& theOutPar )
560 if ( theProfile.IsNull() /*|| !IsValidAsAxis( theHydAxis )*/ )
563 if (theHydAxis.IsNull())
564 return true; //empty h_axis; its's OK
566 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() ); //guide line
567 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
568 if ( aProfileWire.IsNull() )
570 DEBTRACE("aProfileWire.IsNull");
574 //BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
575 BRepAlgo_NormalProjection nproj(thePlane);
576 nproj.Add(aProfileWire);
577 nproj.SetDefaultParams();
581 DEBTRACE("!nproj.IsDone");
584 TopoDS_Shape aPrjProfile = nproj.Projection();
585 if(aPrjProfile.IsNull())
587 DEBTRACE("aPrjProfile.IsNull");
590 TopoDS_Vertex aV1, aV2;
591 if(aPrjProfile.ShapeType() == TopAbs_EDGE)
592 TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
593 else if(aPrjProfile.ShapeType() == TopAbs_WIRE)
594 TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
595 else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
596 TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
598 TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
600 anExp.Init(aPrjProfile, TopAbs_EDGE);
602 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
606 if(aV1.IsNull() || aV2.IsNull())
608 DEBTRACE("aV1.IsNull() || aV2.IsNull()");
611 gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
612 gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
615 BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2);
618 DEBTRACE("!aMk.IsDone()");
621 const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
622 Standard_Integer aNum(0);
624 TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
625 for(;anExplo.More();anExplo.Next()) aNum++;
626 // check for self-intersection
627 const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
628 Standard_Boolean hasInt(false);
629 Standard_Real aSqDist(DBL_MAX);
630 Standard_Integer anIndx(0);
631 BRepExtrema_ExtCC aCC;
632 aCC.Initialize(anEdg2);
634 anExplo.Init(aHydraulicWire, TopAbs_EDGE);
635 for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
636 const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
639 Standard_Boolean hasSol(false);
643 for(Standard_Integer i=1; i<= aCC.NbExt();i++)
644 if(aCC.SquareDistance(i) < aSqDist) {
645 aSqDist = aCC.SquareDistance(i);
651 if(aSqDist <= SquareTolerance) { // hasInt
652 const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
654 TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
655 theOutPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
657 Standard_Real aPar = aCC.ParameterOnE1(anIndx);
665 TopExp::Vertices(anEdg1, aV1, aV2);
666 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
669 } else if(aNum > 1) {
670 TopExp::Vertices(anEdg1, aV1, aV2);
671 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
676 DEBTRACE("!hasInt " << aPnt1.X() << " " << aPnt1.Y() << " " << aPnt2.X() << " " << aPnt2.Y() << " --- " << aSqDist);
680 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
682 if ( theProfile.IsNull() )
685 // Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
686 // if ( aHydAxis.IsNull() )
690 BuildRefFace( aPlane );
692 Standard_Real aPar(.0);
693 if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
694 return false; // Object is already in reference list or it has no intersection
695 //DEBTRACE("AddProfile - insertParameter " << aPar);
696 int aProfileIndex = insertParameter( aPar );
697 insertProfileInToOrder( theProfile, aProfileIndex );
699 if (GetInterpolationMethod()==0)
700 DTM()->SetProfiles( GetProfiles() );
702 LISM()->SetProfiles( GetProfiles() );
704 // Indicate model of the need to update the stream presentation
710 bool HYDROData_Stream::SetProfiles( const HYDROData_SequenceOfObjects& theProfiles,
711 const bool& theIsToOrder )
713 DEBTRACE(" --- SetProfiles " <<theIsToOrder );
716 for ( int i = 1; i <= theProfiles.Length(); ++i )
718 Handle(HYDROData_Profile) aProfile =
719 Handle(HYDROData_Profile)::DownCast( theProfiles.Value( i ) );
720 if ( aProfile.IsNull() )
723 if ( !AddProfile( aProfile ) )
725 DTM()->SetProfiles( HYDROData_SequenceOfObjects() );
730 else // Just store the sequence of objects as is
732 bool anIsToUpdate = true;
734 HYDROData_SequenceOfObjects anOldProfiles = GetProfiles();
735 if ( anOldProfiles.Length() == theProfiles.Length() )
737 anIsToUpdate = false;
739 for ( int i = 1; i <= theProfiles.Length(); ++i )
741 Handle(HYDROData_Entity) anOldProfile = anOldProfiles.Value( i );
742 Handle(HYDROData_Entity) aNewProfile = theProfiles.Value( i );
743 if ( !IsEqual( anOldProfile, aNewProfile ) )
751 SetReferenceObjects( theProfiles, DataTag_Profile );
757 if (GetInterpolationMethod()==0)
758 DTM()->SetProfiles( GetProfiles() );
760 LISM()->SetProfiles( GetProfiles() );
764 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
766 return GetReferenceObjects( DataTag_Profile );
769 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
771 if ( theProfile.IsNull() )
774 int aProfileIndex = -1;
776 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
777 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
778 for ( int i = 0 ; anIter.More(); anIter.Next(), ++i )
780 Handle(HYDROData_Profile) aProfile =
781 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
782 if ( aProfile.IsNull() )
785 if ( IsEqual( theProfile, aProfile ) )
792 if ( aProfileIndex == -1 )
795 RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
797 // Remove parameter for removed profile
798 removeParameter( aProfileIndex );
800 // Indicate model of the need to update the stream presentation
806 void HYDROData_Stream::RemoveProfiles()
808 ClearReferenceObjects( DataTag_Profile );
810 // Remove the parameters array
811 removeParametersArray();
813 // Indicate model of the need to update the stream presentation
818 int HYDROData_Stream::GetInterpolationMethod() const
820 return GetInteger( DataTag_InterpMethod );
823 void HYDROData_Stream::SetInterpolationMethod( int theMethod ) //if DTM => 0 ; if LISM => 1
825 SetInteger( DataTag_InterpMethod, theMethod );
830 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile,
831 const int theBeforeIndex )
833 //Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
834 if ( theProfile.IsNull() )
837 //TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
838 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
839 if ( aProfileWire.IsNull() )
842 if ( theBeforeIndex == -1 )
843 AddReferenceObject( theProfile, DataTag_Profile );
845 InsertReferenceObject( theProfile, DataTag_Profile, theBeforeIndex );
848 void HYDROData_Stream::BuildRefFace( TopoDS_Face& thePlane )
850 thePlane = BRepBuilderAPI_MakeFace(gp_Pln(gp_Pnt(0,0,0),gp_Dir(0,0,1))).Face();
853 void HYDROData_Stream::updateProfilesOrder()
855 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
856 if ( aRefProfiles.IsEmpty() )
859 // At first we remove all profiles from order
862 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
863 if ( aHydAxis.IsNull() )
867 BuildRefFace( aPlane );
869 Standard_Real aPar( .0 );
873 TopoDS_Compound aCmp;
874 aBB.MakeCompound(aCmp);
877 HYDROData_DataMapOfRealOfHDProfile aDM;
878 TColStd_ListOfReal aList;
879 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
880 for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
882 Handle(HYDROData_Profile) aProfile =
883 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
885 TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
886 aBB.Add( aCmp, aProfileWire );
888 if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
891 aDM.Bind( aPar, aProfile );
892 aList.Append( aPar );
895 if ( aList.IsEmpty() )
898 QVector<double> anArr( aList.Extent() );
900 TColStd_ListIteratorOfListOfReal it( aList );
901 for ( int j = 1; it.More(); it.Next(), j++ )
902 anArr[j-1] = it.Value();
905 if ( aList.Extent() > 1 )
907 //TCollection_CompareOfReal Compar;
908 //SortTools_QuickSortOfReal::Sort( anArr, Compar );
909 std::sort( anArr.begin(), anArr.end() );
911 for (int j = 1; j <= anArr.size(); j++) {
912 const Standard_Real aKey = anArr[j-1];
913 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
914 insertProfileInToOrder( aProfile );
916 } else if ( aList.Extent() == 1 ) {
917 const Standard_Real aKey = aList.Last();
918 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
919 insertProfileInToOrder( aProfile );
922 setParametersArray( anArr );
925 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
926 BRepTools::Write(aHydraulicWire, "Path.brep");
927 BRepTools::Write(aCmp, "Prof.brep");
931 ObjectKind HYDROData_Stream::getAltitudeObjectType() const
933 int InterpMethod = GetInterpolationMethod();
934 if (InterpMethod == 1)
940 void HYDROData_Stream::setParametersArray( const QVector<double>& theArray )
942 if ( theArray.size() == 0 )
944 removeParametersArray();
948 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray );
950 int n = theArray.size();
951 Handle(TDataStd_RealArray) aParamsArray =
952 TDataStd_RealArray::Set( aLabel, 1, n );
953 aParamsArray->SetID(TDataStd_RealArray::GetID());
954 for ( int i = 0; i < n; ++i )
956 const Standard_Real& aParam = theArray[i];
957 aParamsArray->SetValue( i+1, aParam );
961 TColStd_Array1OfReal* HYDROData_Stream::getParametersArray() const
963 TColStd_Array1OfReal* anArray = NULL;
965 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
966 if ( !aLabel.IsNull() )
968 Handle(TDataStd_RealArray) aParamsArray;
969 if ( aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
971 anArray = new TColStd_Array1OfReal( aParamsArray->Lower(), aParamsArray->Upper() );
972 for ( int i = aParamsArray->Lower(), n = aParamsArray->Upper(); i <= n; ++i )
974 const Standard_Real& aParam = aParamsArray->Value( i );
975 anArray->SetValue( i, aParam );
983 void HYDROData_Stream::removeParametersArray()
985 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
986 if ( !aLabel.IsNull() )
987 aLabel.ForgetAllAttributes();
990 int HYDROData_Stream::insertParameter( const Standard_Real& theParam )
994 TColStd_Array1OfReal* anArr = getParametersArray();
999 QVector<double> aNewArr( anArr->Upper() +1 );
1000 bool isInserted = false;
1001 for ( int i = anArr->Lower(), j = i, n = anArr->Upper(); i <= n; ++i, ++j )
1003 const Standard_Real& aStoredParam = anArr->Value( i );
1006 if ( theParam > aStoredParam )
1013 aNewArr[j-1] = theParam;
1019 aNewArr[j-1] = aStoredParam;
1025 aNewArr[aNewArr.size()-1] = theParam;
1028 setParametersArray( aNewArr );
1033 QVector<double> aNewArr( 1 );
1034 aNewArr[0] = theParam;
1035 setParametersArray( aNewArr );
1041 void HYDROData_Stream::removeParameter( const int& theIndex )
1043 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
1044 if ( aLabel.IsNull() )
1047 Handle(TDataStd_RealArray) aParamsArray;
1048 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
1051 if ( aParamsArray->Length() == 1 )
1053 removeParametersArray();
1057 QVector<double> aNewArr( aParamsArray->Upper() - 2 );
1059 for ( int i = aParamsArray->Lower(), j = i, k = 0, n = aParamsArray->Upper(); i <= n; ++i, ++k )
1061 const Standard_Real& aStoredParam = aParamsArray->Value( i );
1062 if ( k == theIndex )
1065 aNewArr[j-1] = aStoredParam;
1069 setParametersArray( aNewArr );
1072 bool HYDROData_Stream::GenerateBottomPolyline()
1075 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document();
1076 if ( aDocument.IsNull() ) {
1080 // Collect bottom points ( one bottom point from each profile of the stream )
1081 HYDROData_Profile::ProfilePoints aBottomPoints;
1083 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
1084 for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; i++ ) {
1085 const Handle(HYDROData_Profile) aProfile =
1086 Handle(HYDROData_Profile)::DownCast( aSeqOfProfiles.Value( i ) );
1087 if ( aProfile.IsNull() ) {
1091 aBottomPoints.Append( aProfile->GetBottomPoint() );
1094 int aNbBottomPoints = aBottomPoints.Size();
1096 if ( aNbBottomPoints < 2 ) {
1100 // Create bottom polyline object if the stream doesn't contain it yet
1101 Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
1102 if ( aBottom.IsNull() ) {
1103 aBottom = Handle(HYDROData_Polyline3D)::DownCast( aDocument->CreateObject( KIND_POLYLINE ) );
1104 QString aBaseName = GetName() + "_bottom";
1105 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
1106 aBottom->SetName( aName );
1108 SetReferenceObject( aBottom, DataTag_BottomPolyline );
1111 // Create 2D polyline if the bottom polyline doesn't contain it yet
1112 Handle(HYDROData_PolylineXY) aPolylineXY = aBottom->GetPolylineXY();
1113 if ( aPolylineXY.IsNull() ) {
1114 aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( aDocument->CreateObject( KIND_POLYLINEXY ) );
1115 QString aBaseName = GetName() + "_bottom_2d";
1116 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
1117 aPolylineXY->SetName( aName );
1118 aBottom->SetPolylineXY( aPolylineXY, false );
1121 aPolylineXY->RemoveSections();
1122 aPolylineXY->AddSection( "", HYDROData_PolylineXY::SECTION_SPLINE, false );
1124 // Create profile if the bottom polyline doesn't contain it yet
1125 Handle(HYDROData_ProfileUZ) aProfileUZ = aBottom->GetProfileUZ();
1126 if ( aProfileUZ.IsNull() ) {
1127 Handle(HYDROData_Profile) aProfile =
1128 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
1129 QString aBaseName = GetName() + "_bottom_profile";
1130 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
1131 aProfile->SetName( aName );
1132 aProfileUZ = aProfile->GetProfileUZ( true );
1133 aBottom->SetProfileUZ( aProfileUZ );
1136 aProfileUZ->RemoveSection( 0 );
1138 aProfileUZ->CalculateAndAddPoints(aBottomPoints, aPolylineXY, true);
1143 Handle(HYDROData_Polyline3D) HYDROData_Stream::GetBottomPolyline() const
1145 return Handle(HYDROData_Polyline3D)::DownCast(
1146 GetReferenceObject( DataTag_BottomPolyline ) );
1149 bool HYDROData_Stream::SetBottomPolyline( const Handle(HYDROData_Polyline3D)& theBottom )
1151 if ( theBottom.IsNull() ) {
1155 SetReferenceObject( theBottom, DataTag_BottomPolyline );
1160 bool HYDROData_Stream::Interpolate( HYDROData_IProfilesInterpolator* theInterpolator )
1163 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document();
1164 if ( aDocument.IsNull() ) {
1168 if ( theInterpolator->GetCalculatedProfilesNumber() < 1 ) {
1169 theInterpolator->Calculate();
1172 if ( theInterpolator->GetErrorCode() != OK ) {
1178 for ( int aProfileInd = 0; aProfileInd < theInterpolator->GetCalculatedProfilesNumber(); aProfileInd++ ) {
1179 // Get calculated point coordinates
1180 HYDROData_Profile::ProfilePoints aResultPoints = theInterpolator->GetResultProfilePoints( aProfileInd );
1181 if ( aResultPoints.IsEmpty() ) {
1186 // Create profile object
1187 Handle(HYDROData_Profile) aProfile =
1188 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
1189 QString aBaseName = GetName() + "_interp_profile";
1190 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName );
1191 aProfile->SetName( aName );
1193 // Fill the profile with points
1194 aProfile->SetProfilePoints( aResultPoints );
1196 // Add profile to the stream
1197 bool isAdded = AddProfile( aProfile );
1211 void HYDROData_Stream::CopyTo( const Handle(HYDROData_Entity)& theDestination,
1212 bool isGenerateNewName ) const
1215 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document();
1216 if ( aDocument.IsNull() ) {
1221 HYDROData_Entity::CopyTo( theDestination, isGenerateNewName );
1223 Handle(HYDROData_Stream) aStreamCopy =
1224 Handle(HYDROData_Stream)::DownCast( theDestination );
1226 // Copy bottom polyline if exists
1227 if ( !aStreamCopy.IsNull() ) {
1228 const Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
1229 if ( !aBottom.IsNull() ) {
1230 aStreamCopy->ClearReferenceObjects( DataTag_BottomPolyline );
1231 aStreamCopy->GenerateBottomPolyline();
1232 const Handle(HYDROData_Polyline3D) aBottomCopy = aStreamCopy->GetBottomPolyline();
1233 if ( !aBottomCopy.IsNull() && !aBottomCopy->GetPolylineXY().IsNull() ) {
1234 aBottomCopy->GetPolylineXY()->Update();
1235 aBottomCopy->Update();
1240 void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) theArrayOfFPnt,
1241 const Handle(TColgp_HArray1OfPnt) theArrayOfLPnt,
1242 const Handle(TopTools_HArray1OfShape) theArrOfProfiles,
1243 PrsDefinition& thePrs )
1246 HYDROData_Bathymetry::AltitudePoints left;
1247 for (int i = theArrayOfLPnt->Lower(); i <= theArrayOfLPnt->Upper(); i++)
1249 left.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfLPnt->Value(i).X(),
1250 theArrayOfLPnt->Value(i).Y(),
1251 theArrayOfLPnt->Value(i).Z()));
1254 HYDROData_Bathymetry::AltitudePoints right;
1255 for (int i = theArrayOfFPnt->Lower(); i <= theArrayOfFPnt->Upper(); i++)
1257 right.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfFPnt->Value(i).X(),
1258 theArrayOfFPnt->Value(i).Y(),
1259 theArrayOfFPnt->Value(i).Z()));
1262 std::vector<HYDROData_Bathymetry::AltitudePoints> dummy;
1263 TopTools_IndexedMapOfOrientedShape ll = HYDROData_DTM::Create3DShape(left, right, dummy);
1265 TopoDS_Shape LB, RB, IL, OL;
1269 TopAbs_ShapeEnum ll1_sht = ll(1).ShapeType();
1270 TopAbs_ShapeEnum ll2_sht = ll(2).ShapeType();
1271 if ((ll1_sht == TopAbs_WIRE || ll1_sht == TopAbs_EDGE) &&
1272 (ll2_sht == TopAbs_WIRE || ll2_sht == TopAbs_EDGE))
1279 IL = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Lower())); //TODO check that
1280 OL = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Upper()));
1282 //make new compound so it's shapes will be in known order to build correct projection
1284 TopoDS_Compound newCmp;
1285 BB.MakeCompound(newCmp);
1291 thePrs.myPrs3D = newCmp;
1293 TopTools_SequenceOfShape LS;
1294 //HYDROData_DTM::Get2dFaceFrom3dPres( newCmp, TopoDS::Face(thePrs.myPrs2D), &LS, ind );
1296 HYDROData_DTM::GetPlanarFaceFromBanks(TopoDS::Edge(LB), TopoDS::Edge(RB), TopoDS::Face(thePrs.myPrs2D), &LS);
1299 TopTools_IndexedMapOfShape EE;
1300 TopExp::MapShapes(thePrs.myPrs2D, TopAbs_EDGE, EE);
1302 for (int i = 1; i <= 4; i++)
1304 TopoDS_Shape W = LS(i);
1305 TopTools_IndexedMapOfShape EW;
1306 TopExp::MapShapes(W, TopAbs_EDGE, EW);
1307 for (int k = 1; k <= EW.Extent(); k++)
1308 noncontNb += !EE.Contains(EW(k));
1310 //noncontNb > 0 => some problem with edge history
1311 assert(noncontNb == 0);
1314 thePrs.myLeftBank = LS(1);
1315 thePrs.myInlet = LS(2);
1316 thePrs.myOutlet = LS(3);
1317 thePrs.myRightBank = LS(4);