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 <TCollection_CompareOfReal.hxx>
43 #include <TColgp_Array1OfPnt.hxx>
44 #include <TColgp_HArray1OfPnt.hxx>
47 #include <TopoDS_Wire.hxx>
48 #include <TopoDS_Shell.hxx>
49 #include <TopoDS_Face.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Vertex.hxx>
53 #include <TopExp_Explorer.hxx>
55 #include <Bnd_Box.hxx>
57 #include <BRep_Builder.hxx>
58 #include <BRepBuilderAPI_MakeEdge.hxx>
59 #include <BRepBuilderAPI_MakeWire.hxx>
60 #include <BRepBuilderAPI_MakeFace.hxx>
62 #include <BRepBndLib.hxx>
63 #include <BRepProj_Projection.hxx>
64 #include <BRepExtrema_ExtCC.hxx>
65 #include <BRepCheck_Analyzer.hxx>
67 #include <BRepLib_MakeEdge.hxx>
68 #include <BRepLib_MakeWire.hxx>
69 #include <BRep_Builder.hxx>
70 #include <GeomProjLib.hxx>
71 #include <Geom_TrimmedCurve.hxx>
72 #include <Geom_Plane.hxx>
73 #include <BRepTools_WireExplorer.hxx>
74 #include <TopTools_IndexedMapOfShape.hxx>
75 #include <BRepBuilderAPI_MakeFace.hxx>
85 #include <GeomAPI_Interpolate.hxx>
86 #include <Geom_BSplineCurve.hxx>
88 #include <TopTools_HArray1OfShape.hxx>
90 #include <SortTools_QuickSortOfReal.hxx>
93 #include <QStringList>
95 //#define DEB_STREAM 1
97 //#define DEB_HASINT 1
98 //#define DEB_UPDATE 1
99 #include <BRepTools.hxx>
100 #include <TCollection_AsciiString.hxx>
103 typedef NCollection_DataMap<Standard_Real, Handle(HYDROData_Profile)> HYDROData_DataMapOfRealOfHDProfile;
105 IMPLEMENT_STANDARD_HANDLE(HYDROData_Stream,HYDROData_NaturalObject)
106 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
109 HYDROData_Stream::HYDROData_Stream()
110 : HYDROData_NaturalObject( Geom_3d )
114 HYDROData_Stream::~HYDROData_Stream()
118 QStringList HYDROData_Stream::DumpToPython( const QString& thePyScriptPath,
119 MapOfTreatedObjects& theTreatedObjects ) const
121 QStringList aResList = dumpObjectCreation( theTreatedObjects );
122 QString aName = GetObjPyName();
124 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
125 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aHydAxis, "SetHydraulicAxis" );
127 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
128 for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; ++i )
130 const Handle(HYDROData_Entity) aProfile = aSeqOfProfiles.Value( i );
131 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aProfile, "AddProfile" );
134 // Set bottom polyline if exists
135 const Handle(HYDROData_Polyline3D) aBottomPolyline = GetBottomPolyline();
136 if ( !aBottomPolyline.IsNull() ) {
137 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aBottomPolyline, "SetBottomPolyline" );
140 QString aDDZs = QString::number( GetDDZ(), 'f', 3 );
141 QString aSSteps = QString::number( GetSpatialStep(), 'f', 3 );
142 aResList << QString( "%1.SetDDZ( %2 )" ).arg( aName ).arg( aDDZs );
143 aResList << QString( "%1.SetSpatialStep( %2 )" ).arg( aName ).arg( aSSteps );
145 aResList << QString( "" );
146 aResList << QString( "%1.Update()" ).arg( aName );
147 aResList << QString( "" );
152 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
154 HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
156 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
157 if ( !aHydAxis.IsNull() )
158 aResSeq.Append( aHydAxis );
160 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
161 aResSeq.Append( aSeqOfProfiles );
166 Handle(Geom_BSplineCurve) HYDROData_Stream::buildInterpolationCurve(
167 const Handle(TColgp_HArray1OfPnt)& theArrayOfPnt )
169 Handle(Geom_BSplineCurve) aBSpline;
170 GeomAPI_Interpolate anInterpolator (theArrayOfPnt, Standard_False, 1.0e-5);
171 anInterpolator.Perform() ;
172 if (anInterpolator.IsDone())
173 aBSpline = anInterpolator.Curve();
177 void HYDROData_Stream::Update()
179 updateProfilesOrder();
181 // Update bottom polyline if exists
182 const Handle(HYDROData_Polyline3D) aBottomPolyline = GetBottomPolyline();
183 if ( !aBottomPolyline.IsNull() ) {
184 if ( GenerateBottomPolyline() ) {
185 Handle(HYDROData_PolylineXY) aPolylineXY = aBottomPolyline->GetPolylineXY();
186 if ( !aPolylineXY.IsNull() ) {
187 aPolylineXY->Update();
189 aBottomPolyline->Update();
193 Handle_HYDROData_DTM dtm = DTM();
198 bool HYDROData_Stream::IsHas2dPrs() const
203 bool HYDROData_Stream::CreatePresentations( const Handle_HYDROData_DTM& theDTM,
204 PrsDefinition& thePrs )
206 if ( theDTM.IsNull() )
209 HYDROData_SequenceOfObjects profiles = theDTM->GetProfiles();
210 if( profiles.Length() < 2 )
213 /*std::vector<TopoDS_Wire> profiles3d;
214 profiles3d.reserve(profiles.Length());
217 HYDROData_SequenceOfObjects::Iterator anIter( profiles );
218 for (int i=1 ; anIter.More(); anIter.Next(),i++ )
220 Handle(HYDROData_Profile) aProfile =
221 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
223 if ( aProfile.IsNull() )
226 const TopoDS_Shape& aProfileShape = aProfile->GetShape3D();
227 //TopExp_Explorer exp(aProfileShape, TopAbs_EDGE);
228 profiles3d.push_back( TopoDS::Wire(aProfileShape) );
231 CreatePresentationsIntern( theDTM, thePrs );
235 void HYDROData_Stream::UpdatePrs( const Handle_HYDROData_DTM& theDTM )
237 HYDROData_NaturalObject::Update();
239 PrsDefinition aResultPrs;
240 if ( !CreatePresentations( theDTM, aResultPrs ) )
243 SetShape3D( aResultPrs.myPrs3D );
244 SetTopShape( aResultPrs.myPrs2D );
246 // Create the stream groups
247 QString aLeftGroupName = GetName() + "_Left_Bank";
249 Handle(HYDROData_ShapesGroup) aLeftGroup = createGroupObject();
250 aLeftGroup->SetName( aLeftGroupName );
251 aLeftGroup->AddShape( aResultPrs.myLeftBank );
253 QString aRightGroupName = GetName() + "_Right_Bank";
255 Handle(HYDROData_ShapesGroup) aRightGroup = createGroupObject();
256 aRightGroup->SetName( aRightGroupName );
257 aRightGroup->AddShape( aResultPrs.myRightBank );
259 QString anInGroupName = GetName() + "_Inlet";
261 Handle(HYDROData_ShapesGroup) anInGroup = createGroupObject();
262 anInGroup->SetName( anInGroupName );
263 anInGroup->AddShape( aResultPrs.myInlet );
265 QString anOutGroupName = GetName() + "_Outlet";
267 Handle(HYDROData_ShapesGroup) anOutGroup = createGroupObject();
268 anOutGroup->SetName( anOutGroupName );
269 anOutGroup->AddShape( aResultPrs.myOutlet );
272 QColor HYDROData_Stream::DefaultFillingColor() const
274 return QColor( Qt::green );
277 QColor HYDROData_Stream::DefaultBorderColor() const
279 return QColor( Qt::transparent );
282 bool HYDROData_Stream::IsValidAsAxis( const Handle(HYDROData_PolylineXY)& theHydAxis )
284 if ( theHydAxis.IsNull() )
287 TopoDS_Shape aHydraulicShape = theHydAxis->GetShape();
288 if ( aHydraulicShape.IsNull() ||
289 aHydraulicShape.ShapeType() != TopAbs_WIRE ||
290 BRep_Tool::IsClosed( aHydraulicShape ) )
291 return false; // The polyline must be a single not closed wire
296 TopoDS_Shape HYDROData_Stream::GetLeftShape() const
298 HYDROData_SequenceOfObjects aGroups = GetGroups();
299 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 1);
302 TopoDS_Shape HYDROData_Stream::GetRightShape() const
304 HYDROData_SequenceOfObjects aGroups = GetGroups();
305 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 2);
308 TopoDS_Shape HYDROData_Stream::GetInletShape() const
310 HYDROData_SequenceOfObjects aGroups = GetGroups();
311 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 3);
314 TopoDS_Shape HYDROData_Stream::GetOutletShape() const
316 HYDROData_SequenceOfObjects aGroups = GetGroups();
317 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 4);
320 Handle_HYDROData_DTM HYDROData_Stream::DTM() const
322 const_cast<HYDROData_Stream*>( this )->checkAndSetAltitudeObject();
323 return Handle(HYDROData_DTM)::DownCast( GetAltitudeObject() );
326 double HYDROData_Stream::GetDDZ() const
328 return DTM()->GetDDZ();
331 void HYDROData_Stream::SetDDZ( double theDDZ )
333 DTM()->SetDDZ( theDDZ );
336 double HYDROData_Stream::GetSpatialStep() const
338 return DTM()->GetSpatialStep();
341 void HYDROData_Stream::SetSpatialStep( double theSpatialStep )
343 DTM()->SetSpatialStep( theSpatialStep );
346 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
348 if ( !IsValidAsAxis( theAxis ) )
351 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
352 if ( IsEqual( aPrevAxis, theAxis ) )
355 SetReferenceObject( theAxis, DataTag_HydraulicAxis );
357 // Update the order of profiles
358 updateProfilesOrder();
360 // Indicate model of the need to update the stream presentation
366 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
368 return Handle(HYDROData_PolylineXY)::DownCast(
369 GetReferenceObject( DataTag_HydraulicAxis ) );
372 void HYDROData_Stream::RemoveHydraulicAxis()
374 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
375 if ( aPrevAxis.IsNull() )
378 ClearReferenceObjects( DataTag_HydraulicAxis );
380 // We remove the reference profiles
383 // Indicate model of the need to update the stream presentation
387 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile,
388 const TopoDS_Face& thePlane,
389 Standard_Real& theOutPar ) const
391 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
392 return HasIntersection( aHydAxis, theProfile, thePlane, theOutPar );
395 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_PolylineXY)& theHydAxis,
396 const Handle(HYDROData_Profile)& theProfile,
397 const TopoDS_Face& thePlane,
398 Standard_Real& theOutPar )
400 if ( theProfile.IsNull() || !IsValidAsAxis( theHydAxis ) )
403 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() ); //guide line
404 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
405 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
408 BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
409 if(!aProjector.IsDone())
411 TopoDS_Shape aPrjProfile = aProjector.Shape();
412 if(aPrjProfile.IsNull())
414 TopoDS_Vertex aV1, aV2;
415 if(aPrjProfile.ShapeType() == TopAbs_EDGE)
416 TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
417 else if(aPrjProfile.ShapeType() == TopAbs_WIRE)
418 TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
419 else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
420 TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
422 TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
424 anExp.Init(aPrjProfile, TopAbs_EDGE);
426 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
430 if(aV1.IsNull() || aV2.IsNull())
432 gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
433 gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
436 BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2);
439 const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
440 Standard_Integer aNum(0);
442 TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
443 for(;anExplo.More();anExplo.Next()) aNum++;
444 // check for self-intersection
445 const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
446 Standard_Boolean hasInt(false);
447 Standard_Real aSqDist(DBL_MAX);
448 Standard_Integer anIndx(0);
449 BRepExtrema_ExtCC aCC;
450 aCC.Initialize(anEdg2);
452 anExplo.Init(aHydraulicWire, TopAbs_EDGE);
453 for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
454 const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
457 Standard_Boolean hasSol(false);
461 for(Standard_Integer i=1; i<= aCC.NbExt();i++)
462 if(aCC.SquareDistance(i) < aSqDist) {
463 aSqDist = aCC.SquareDistance(i);
469 if(aSqDist <= SquareTolerance) { // hasInt
470 const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
472 TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
473 theOutPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
475 Standard_Real aPar = aCC.ParameterOnE1(anIndx);
483 TopExp::Vertices(anEdg1, aV1, aV2);
484 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
487 } else if(aNum > 1) {
488 TopExp::Vertices(anEdg1, aV1, aV2);
489 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
497 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
499 if ( theProfile.IsNull() )
502 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
503 if ( aHydAxis.IsNull() )
507 if(!BuildFace(aHydAxis, aPlane))
510 Standard_Real aPar(.0);
511 if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
512 return false; // Object is already in reference list or it has no intersection
514 int aProfileIndex = insertParameter( aPar );
515 insertProfileInToOrder( theProfile, aProfileIndex );
517 // Indicate model of the need to update the stream presentation
523 bool HYDROData_Stream::SetProfiles( const HYDROData_SequenceOfObjects& theProfiles,
524 const bool& theIsToOrder )
528 for ( int i = 1; i <= theProfiles.Length(); ++i )
530 Handle(HYDROData_Profile) aProfile =
531 Handle(HYDROData_Profile)::DownCast( theProfiles.Value( i ) );
532 if ( aProfile.IsNull() )
535 if ( !AddProfile( aProfile ) )
537 DTM()->SetProfiles( HYDROData_SequenceOfObjects() );
542 else // Just store the sequence of objects as is
544 bool anIsToUpdate = true;
546 HYDROData_SequenceOfObjects anOldProfiles = GetProfiles();
547 if ( anOldProfiles.Length() == theProfiles.Length() )
549 anIsToUpdate = false;
551 for ( int i = 1; i <= theProfiles.Length(); ++i )
553 Handle(HYDROData_Entity) anOldProfile = anOldProfiles.Value( i );
554 Handle(HYDROData_Entity) aNewProfile = theProfiles.Value( i );
555 if ( !IsEqual( anOldProfile, aNewProfile ) )
563 SetReferenceObjects( theProfiles, DataTag_Profile );
569 DTM()->SetProfiles( GetProfiles() );
573 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
575 return GetReferenceObjects( DataTag_Profile );
578 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
580 if ( theProfile.IsNull() )
583 int aProfileIndex = -1;
585 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
586 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
587 for ( int i = 0 ; anIter.More(); anIter.Next(), ++i )
589 Handle(HYDROData_Profile) aProfile =
590 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
591 if ( aProfile.IsNull() )
594 if ( IsEqual( theProfile, aProfile ) )
601 if ( aProfileIndex == -1 )
604 RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
606 // Remove parameter for removed profile
607 removeParameter( aProfileIndex );
609 // Indicate model of the need to update the stream presentation
615 void HYDROData_Stream::RemoveProfiles()
617 ClearReferenceObjects( DataTag_Profile );
619 // Remove the parameters array
620 removeParametersArray();
622 // Indicate model of the need to update the stream presentation
626 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile,
627 const int theBeforeIndex )
629 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
630 if ( theProfile.IsNull() || aHydAxis.IsNull() )
633 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
634 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
635 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
638 if ( theBeforeIndex == -1 )
639 AddReferenceObject( theProfile, DataTag_Profile );
641 InsertReferenceObject( theProfile, DataTag_Profile, theBeforeIndex );
644 bool HYDROData_Stream::BuildFace( const Handle(HYDROData_PolylineXY)& theHydAxis,
645 TopoDS_Face& thePlane )
647 if ( !IsValidAsAxis( theHydAxis ) )
650 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() );
652 gp_Ax2 aX2(gp::XOY());
656 BRepBndLib::Add(aHydraulicWire,B);
657 Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
658 B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
659 BRepBuilderAPI_MakeFace aMkr(aPln, axmin-500., axmax+500., aymin-500., aymax+500.); // to be tuned later according max/ Profile deviation
660 if(!aMkr.IsDone() || aMkr.Shape().IsNull()) return false;
661 thePlane = TopoDS::Face(aMkr.Shape());
665 void HYDROData_Stream::updateProfilesOrder()
667 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
668 if ( aRefProfiles.IsEmpty() )
671 // At first we remove all profiles from order
674 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
675 if ( aHydAxis.IsNull() )
679 if ( !BuildFace( aHydAxis, aPlane ) )
682 Standard_Real aPar( .0 );
686 TopoDS_Compound aCmp;
687 aBB.MakeCompound(aCmp);
690 HYDROData_DataMapOfRealOfHDProfile aDM;
691 TColStd_ListOfReal aList;
692 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
693 for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
695 Handle(HYDROData_Profile) aProfile =
696 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
698 TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
699 aBB.Add( aCmp, aProfileWire );
701 if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
704 aDM.Bind( aPar, aProfile );
705 aList.Append( aPar );
708 if ( aList.IsEmpty() )
711 TColStd_Array1OfReal anArr( 1, aList.Extent() );
713 TColStd_ListIteratorOfListOfReal it( aList );
714 for ( int j = 1; it.More(); it.Next(), j++ )
715 anArr( j ) = it.Value();
718 if ( aList.Extent() > 1 )
720 TCollection_CompareOfReal Compar;
721 SortTools_QuickSortOfReal::Sort( anArr, Compar );
723 for (int j = 1; j <= anArr.Length(); j++) {
724 const Standard_Real aKey = anArr(j);
725 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
726 insertProfileInToOrder( aProfile );
728 } else if ( aList.Extent() == 1 ) {
729 const Standard_Real aKey = aList.Last();
730 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
731 insertProfileInToOrder( aProfile );
734 setParametersArray( anArr );
737 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
738 BRepTools::Write(aHydraulicWire, "Path.brep");
739 BRepTools::Write(aCmp, "Prof.brep");
743 ObjectKind HYDROData_Stream::getAltitudeObjectType() const
748 void HYDROData_Stream::setParametersArray( const TColStd_Array1OfReal& theArray )
750 if ( theArray.Length() == 0 )
752 removeParametersArray();
756 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray );
758 Handle(TDataStd_RealArray) aParamsArray =
759 TDataStd_RealArray::Set( aLabel, theArray.Lower(), theArray.Upper() );
761 for ( int i = theArray.Lower(), n = theArray.Upper(); i <= n; ++i )
763 const Standard_Real& aParam = theArray( i );
764 aParamsArray->SetValue( i, aParam );
768 TColStd_Array1OfReal* HYDROData_Stream::getParametersArray() const
770 TColStd_Array1OfReal* anArray = NULL;
772 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
773 if ( !aLabel.IsNull() )
775 Handle(TDataStd_RealArray) aParamsArray;
776 if ( aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
778 anArray = new TColStd_Array1OfReal( aParamsArray->Lower(), aParamsArray->Upper() );
779 for ( int i = aParamsArray->Lower(), n = aParamsArray->Upper(); i <= n; ++i )
781 const Standard_Real& aParam = aParamsArray->Value( i );
782 anArray->SetValue( i, aParam );
790 void HYDROData_Stream::removeParametersArray()
792 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
793 if ( !aLabel.IsNull() )
794 aLabel.ForgetAllAttributes();
797 int HYDROData_Stream::insertParameter( const Standard_Real& theParam )
801 TColStd_Array1OfReal* anArr = getParametersArray();
806 TColStd_Array1OfReal aNewArr( anArr->Lower(), anArr->Upper() + 1 );
808 bool isInserted = false;
809 for ( int i = anArr->Lower(), j = i, n = anArr->Upper(); i <= n; ++i, ++j )
811 const Standard_Real& aStoredParam = anArr->Value( i );
814 if ( theParam > aStoredParam )
820 aNewArr( j ) = theParam;
826 aNewArr( j ) = aStoredParam;
832 aNewArr( aNewArr.Upper() ) = theParam;
835 setParametersArray( aNewArr );
840 TColStd_Array1OfReal aNewArr( 1, 1 );
841 aNewArr.SetValue( 1, theParam );
842 setParametersArray( aNewArr );
848 void HYDROData_Stream::removeParameter( const int& theIndex )
850 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
851 if ( aLabel.IsNull() )
854 Handle(TDataStd_RealArray) aParamsArray;
855 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
858 if ( aParamsArray->Length() == 1 )
860 removeParametersArray();
864 TColStd_Array1OfReal aNewArr( aParamsArray->Lower(), aParamsArray->Upper() - 1 );
866 for ( int i = aParamsArray->Lower(), j = i, k = 0, n = aParamsArray->Upper(); i <= n; ++i, ++k )
868 const Standard_Real& aStoredParam = aParamsArray->Value( i );
872 aNewArr.SetValue( j, aStoredParam );
876 setParametersArray( aNewArr );
879 bool HYDROData_Stream::GenerateBottomPolyline()
882 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
883 if ( aDocument.IsNull() ) {
887 // Collect bottom points ( one bottom point from each profile of the stream )
888 HYDROData_Profile::ProfilePoints aBottomPoints;
890 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
891 for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; i++ ) {
892 const Handle(HYDROData_Profile) aProfile =
893 Handle(HYDROData_Profile)::DownCast( aSeqOfProfiles.Value( i ) );
894 if ( aProfile.IsNull() ) {
898 aBottomPoints.Append( aProfile->GetBottomPoint() );
901 int aNbBottomPoints = aBottomPoints.Size();
903 if ( aNbBottomPoints < 2 ) {
907 // Create bottom polyline object if the stream doesn't contain it yet
908 Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
909 if ( aBottom.IsNull() ) {
910 aBottom = Handle(HYDROData_Polyline3D)::DownCast( aDocument->CreateObject( KIND_POLYLINE ) );
911 QString aBaseName = GetName() + "_bottom";
912 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
913 aBottom->SetName( aName );
915 SetReferenceObject( aBottom, DataTag_BottomPolyline );
918 // Create 2D polyline if the bottom polyline doesn't contain it yet
919 Handle(HYDROData_PolylineXY) aPolylineXY = aBottom->GetPolylineXY();
920 if ( aPolylineXY.IsNull() ) {
921 aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( aDocument->CreateObject( KIND_POLYLINEXY ) );
922 QString aBaseName = GetName() + "_bottom_2d";
923 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
924 aPolylineXY->SetName( aName );
925 aBottom->SetPolylineXY( aPolylineXY, false );
928 aPolylineXY->RemoveSections();
929 aPolylineXY->AddSection( "", HYDROData_PolylineXY::SECTION_SPLINE, false );
931 // Create profile if the bottom polyline doesn't contain it yet
932 Handle(HYDROData_ProfileUZ) aProfileUZ = aBottom->GetProfileUZ();
933 if ( aProfileUZ.IsNull() ) {
934 Handle(HYDROData_Profile) aProfile =
935 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
936 QString aBaseName = GetName() + "_bottom_profile";
937 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
938 aProfile->SetName( aName );
939 aProfileUZ = aProfile->GetProfileUZ( true );
940 aBottom->SetProfileUZ( aProfileUZ );
943 aProfileUZ->RemoveSection( 0 );
945 aProfileUZ->CalculateAndAddPoints(aBottomPoints, aPolylineXY);
950 Handle(HYDROData_Polyline3D) HYDROData_Stream::GetBottomPolyline() const
952 return Handle(HYDROData_Polyline3D)::DownCast(
953 GetReferenceObject( DataTag_BottomPolyline ) );
956 bool HYDROData_Stream::SetBottomPolyline( const Handle(HYDROData_Polyline3D)& theBottom )
958 if ( theBottom.IsNull() ) {
962 SetReferenceObject( theBottom, DataTag_BottomPolyline );
967 bool HYDROData_Stream::Interpolate( HYDROData_IProfilesInterpolator* theInterpolator )
970 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
971 if ( aDocument.IsNull() ) {
975 if ( theInterpolator->GetCalculatedProfilesNumber() < 1 ) {
976 theInterpolator->Calculate();
979 if ( theInterpolator->GetErrorCode() != OK ) {
985 for ( int aProfileInd = 0; aProfileInd < theInterpolator->GetCalculatedProfilesNumber(); aProfileInd++ ) {
986 // Get calculated point coordinates
987 HYDROData_Profile::ProfilePoints aResultPoints = theInterpolator->GetResultProfilePoints( aProfileInd );
988 if ( aResultPoints.IsEmpty() ) {
993 // Create profile object
994 Handle(HYDROData_Profile) aProfile =
995 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
996 QString aBaseName = GetName() + "_interp_profile";
997 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName );
998 aProfile->SetName( aName );
1000 // Fill the profile with points
1001 aProfile->SetProfilePoints( aResultPoints );
1003 // Add profile to the stream
1004 bool isAdded = AddProfile( aProfile );
1018 void HYDROData_Stream::CopyTo( const Handle(HYDROData_Entity)& theDestination,
1019 bool isGenerateNewName ) const
1022 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
1023 if ( aDocument.IsNull() ) {
1028 HYDROData_Entity::CopyTo( theDestination, isGenerateNewName );
1030 Handle(HYDROData_Stream) aStreamCopy =
1031 Handle(HYDROData_Stream)::DownCast( theDestination );
1033 // Copy bottom polyline if exists
1034 if ( !aStreamCopy.IsNull() ) {
1035 const Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
1036 if ( !aBottom.IsNull() ) {
1037 aStreamCopy->ClearReferenceObjects( DataTag_BottomPolyline );
1038 aStreamCopy->GenerateBottomPolyline();
1039 const Handle(HYDROData_Polyline3D) aBottomCopy = aStreamCopy->GetBottomPolyline();
1040 if ( !aBottomCopy.IsNull() && !aBottomCopy->GetPolylineXY().IsNull() ) {
1041 aBottomCopy->GetPolylineXY()->Update();
1042 aBottomCopy->Update();
1048 static void ProjWireOnPlane(const TopoDS_Wire& inpWire, const Handle_Geom_Plane& RefPlane, TopoDS_Wire& outWire)
1050 BRepTools_WireExplorer ex(TopoDS::Wire(inpWire.Oriented(TopAbs_FORWARD)));
1051 BRepLib_MakeWire WM;
1052 for (;ex.More();ex.Next())
1054 const TopoDS_Edge& CE = ex.Current();
1056 Handle(Geom_Curve) C3d = BRep_Tool::Curve(CE, f, l);
1057 Handle(Geom_Curve) ProjectedCurve = GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d, f, l), RefPlane, RefPlane->Position().Direction(), Standard_True);
1058 TopoDS_Edge ProjEdge = BRepLib_MakeEdge(ProjectedCurve);
1059 WM.Add(ProjEdge); //auto sharing between edges if vertex is coincident
1061 outWire = WM.Wire();
1062 outWire.Orientation(inpWire.Orientation()); //take from the original wire
1066 static void Get2dFaceFrom3dPres(const TopoDS_Compound& cmp, TopoDS_Face& outF )
1068 Handle_Geom_Plane refpl = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1));
1069 BRepLib_MakeWire WM;
1070 TopoDS_Iterator it(cmp);
1071 //TopTools_IndexedMapOfShape IntW;
1072 for (;it.More(); it.Next())
1074 const TopoDS_Wire& W = TopoDS::Wire(it.Value());
1075 if (W.Orientation() != TopAbs_INTERNAL)
1077 //use list of edges to protect againts non-manifold cases.
1078 //auto sharing between edges will be added automatically
1079 TopTools_IndexedMapOfShape ME;
1080 TopTools_ListOfShape LE;
1081 TopExp::MapShapes(W, TopAbs_EDGE, ME);
1082 for (int i = 1; i <= ME.Extent(); i++)
1091 ProjWireOnPlane(WM.Wire(), refpl, outW);
1092 BRepBuilderAPI_MakeFace mf(refpl, outW); //check inside is true by def
1095 ///!!! the internal wires cant be added with 'internal' ori.
1096 // it's possible to do with brep builder yet the result will not be correct!
1097 // more proper way is to use BOP operation here.
1098 /*for (int i = 1; i <= IntW.Extent(); i++)
1101 const TopoDS_Wire& W = TopoDS::Wire(IntW(i));
1102 ProjWireOnPlane(W, refpl, outIW);
1103 BB.Add(outF, outIW);
1107 void HYDROData_Stream::CreatePresentationsIntern( const Handle_HYDROData_DTM& theDTM,
1108 PrsDefinition& thePrs )
1110 TopoDS_Compound cmp = TopoDS::Compound(theDTM->GetShape(HYDROData_DTM::DataTag_DTM_Shape));
1111 thePrs.myPrs3D = cmp;
1112 NCollection_Sequence<TopoDS_Wire> WW;
1113 TopoDS_Iterator it(cmp);
1114 for (;it.More(); it.Next())
1115 WW.Append(TopoDS::Wire(it.Value()));
1117 //same order as in HYDROData_DTM::Update()
1118 thePrs.myLeftBank = WW.First();
1119 thePrs.myRightBank = WW.Last();
1120 thePrs.myInlet = WW(1); //TODO check this!!
1121 thePrs.myOutlet = WW(WW.Length() - 1);
1124 Get2dFaceFrom3dPres(cmp, outF);
1125 thePrs.myPrs2D = outF;
1127 /*if ( theArrayOfFPnt.IsNull() || theArrayOfLPnt.IsNull() || theArrOfProfiles.IsNull() ) {
1131 if ( theArrayOfFPnt->Length() != theArrayOfLPnt->Length() ) {
1135 // Construct of the 3D presentation
1136 Handle(Geom_BSplineCurve) aBSpline = buildInterpolationCurve (theArrayOfFPnt);
1137 if(aBSpline.IsNull())
1140 TopoDS_Edge anEdgLeft, anEdgRight;
1142 BRepBuilderAPI_MakeEdge aMakeEdge(aBSpline);
1143 if(aMakeEdge.IsDone())
1144 anEdgLeft = aMakeEdge.Edge();
1146 if(anEdgLeft.IsNull())
1150 aBSpline = buildInterpolationCurve (theArrayOfLPnt);
1151 if(aBSpline.IsNull())
1154 aMakeEdge.Init(aBSpline);
1155 if(aMakeEdge.IsDone())
1156 anEdgRight = aMakeEdge.Edge();
1158 if(anEdgRight.IsNull())
1162 TopoDS_Compound aCmp;
1163 aBB.MakeCompound(aCmp);
1164 for (int i=1 ; i < theArrOfProfiles->Length() +1; i++ )
1165 aBB.Add(aCmp, theArrOfProfiles->Value(i));
1167 aBB.Add(aCmp,anEdgLeft);
1168 aBB.Add(aCmp,anEdgRight);
1169 BRepCheck_Analyzer aCh(aCmp);
1171 thePrs.myPrs3D = aCmp;
1174 BRepTools::Write(aCmp, "str3d.brep");
1175 thePrs.myPrs3D = aCmp;
1179 // Construct the top presentation
1180 int aNbPoints = theArrayOfFPnt->Length();
1181 Handle(TColgp_HArray1OfPnt) anArrayOfFPnt = new TColgp_HArray1OfPnt(1, aNbPoints);
1182 Handle(TColgp_HArray1OfPnt) anArrayOfLPnt = new TColgp_HArray1OfPnt(1, aNbPoints);
1183 for( int i=1; i <= aNbPoints; i++ ) {
1184 gp_Pnt aPnt = theArrayOfFPnt->Value(i);
1185 aPnt.SetZ(.0); // make 2d
1186 anArrayOfFPnt->SetValue(i, aPnt);
1187 aPnt = theArrayOfLPnt->Value(i);
1189 anArrayOfLPnt->SetValue(i, aPnt);
1193 aBSpline = buildInterpolationCurve (anArrayOfFPnt);
1194 if(aBSpline.IsNull())
1197 aMakeEdge.Init(aBSpline);
1198 if(aMakeEdge.IsDone())
1199 anEdgLeft = aMakeEdge.Edge();
1202 aBSpline = buildInterpolationCurve (anArrayOfLPnt);
1203 if(aBSpline.IsNull())
1206 aMakeEdge.Init(aBSpline);
1207 if(aMakeEdge.IsDone())
1208 anEdgRight = aMakeEdge.Edge();
1209 if(anEdgRight.IsNull())
1212 BRepBuilderAPI_MakeEdge aMakeEdge2(anArrayOfFPnt->Value(1),anArrayOfLPnt->Value(1));
1213 TopoDS_Edge aBotEdge, aTopEdge;
1214 if(aMakeEdge2.IsDone())
1215 aBotEdge = aMakeEdge2.Edge();
1217 BRepBuilderAPI_MakeEdge aMakeEdge3(anArrayOfFPnt->Value(anArrayOfFPnt->Length()),anArrayOfLPnt->Value(anArrayOfLPnt->Length()));
1218 if(aMakeEdge3.IsDone())
1219 aTopEdge = aMakeEdge3.Edge();
1221 // Make wire for 2D presentation with updating of corresponding edges
1222 BRepBuilderAPI_MakeWire aMakeWire;
1224 aMakeWire.Add( aBotEdge );
1225 thePrs.myInlet = aMakeWire.Edge();
1227 aMakeWire.Add( anEdgLeft );
1228 thePrs.myLeftBank = aMakeWire.Edge();
1230 aMakeWire.Add( aTopEdge );
1231 thePrs.myOutlet = aMakeWire.Edge();
1233 aMakeWire.Add( anEdgRight );
1234 thePrs.myRightBank = aMakeWire.Edge();
1236 TopoDS_Wire aSectProfileWire;
1237 if(aMakeWire.IsDone())
1238 aSectProfileWire = aMakeWire.Wire();
1240 BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
1243 if( aMakeFace.IsDone() )
1244 aFace = aMakeFace.Face();
1246 TopoDS_Shape aPrs2D;
1248 if ( !theArrOf2DProfiles.IsNull() ) {
1250 aBB.MakeCompound(aCmp);
1251 aBB.Add(aCmp,aFace);
1252 for(int i=1;i <= theArrOf2DProfiles->Length(); i++)
1253 aBB.Add(aCmp, theArrOf2DProfiles->Value(i));
1262 thePrs.myPrs2D = aPrs2D;
1265 BRepTools::Write(aPrs2D, "str2d.brep");
1266 thePrs.myPrs2D = aPrs2D;
1273 void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) theArrayOfFPnt,
1274 const Handle(TColgp_HArray1OfPnt) theArrayOfLPnt,
1275 const Handle(TopTools_HArray1OfShape) theArrOfProfiles,
1276 PrsDefinition& thePrs )
1279 HYDROData_Bathymetry::AltitudePoints left;
1280 for (int i = theArrayOfLPnt->Lower(); i <= theArrayOfLPnt->Upper(); i++)
1282 left.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfLPnt->Value(i).X(),
1283 theArrayOfLPnt->Value(i).Y(),
1284 theArrayOfLPnt->Value(i).Z()));
1287 HYDROData_Bathymetry::AltitudePoints right;
1288 for (int i = theArrayOfFPnt->Lower(); i <= theArrayOfFPnt->Upper(); i++)
1290 right.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfFPnt->Value(i).X(),
1291 theArrayOfFPnt->Value(i).Y(),
1292 theArrayOfFPnt->Value(i).Z()));
1295 std::vector<HYDROData_Bathymetry::AltitudePoints> dummy;
1296 TopoDS_Compound cmp = HYDROData_DTM::Create3DShape(left, right, dummy);
1297 TopoDS_Iterator it(cmp);
1298 thePrs.myLeftBank = TopoDS::Wire(it.Value());
1300 thePrs.myRightBank = TopoDS::Wire(it.Value());
1302 thePrs.myInlet = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Lower())); //TODO check that
1303 thePrs.myOutlet = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Upper()));
1305 //make new compound so it's shapes will be in known order to build correct projection
1307 TopoDS_Compound newCmp;
1308 BB.MakeCompound(newCmp);
1309 BB.Add(newCmp, thePrs.myLeftBank);
1310 BB.Add(newCmp, thePrs.myInlet);
1311 BB.Add(newCmp, thePrs.myOutlet);
1312 BB.Add(newCmp, thePrs.myRightBank);
1314 thePrs.myPrs3D = newCmp;
1316 Get2dFaceFrom3dPres( newCmp, TopoDS::Face(thePrs.myPrs2D) );