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"
32 #include <TDataStd_RealArray.hxx>
34 #include <Precision.hxx>
36 #include <NCollection_DataMap.hxx>
38 #include <TColStd_Array1OfReal.hxx>
39 #include <TColStd_ListOfReal.hxx>
40 #include <TColStd_ListIteratorOfListOfReal.hxx>
41 #include <TCollection_CompareOfReal.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>
79 #include <SortTools_QuickSortOfReal.hxx>
82 #include <QStringList>
84 //#define DEB_STREAM 1
86 //#define DEB_HASINT 1
87 //#define DEB_UPDATE 1
88 #include <BRepTools.hxx>
89 #include <TCollection_AsciiString.hxx>
92 typedef NCollection_DataMap<Standard_Real, Handle(HYDROData_Profile)> HYDROData_DataMapOfRealOfHDProfile;
94 IMPLEMENT_STANDARD_HANDLE(HYDROData_Stream,HYDROData_NaturalObject)
95 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
98 HYDROData_Stream::HYDROData_Stream()
99 : HYDROData_NaturalObject( Geom_3d )
103 HYDROData_Stream::~HYDROData_Stream()
107 void HYDROData_Stream::SetLabel( const TDF_Label& theLabel )
109 HYDROData_NaturalObject::SetLabel( theLabel );
111 if( GetAltitudeObject().IsNull() )
113 Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( myLab );
114 Handle(HYDROData_DTM) aDTM =
115 Handle(HYDROData_DTM)::DownCast( aDoc->CreateObject( KIND_DTM ) );
116 SetAltitudeObject( aDTM );
120 QStringList HYDROData_Stream::DumpToPython( const QString& thePyScriptPath,
121 MapOfTreatedObjects& theTreatedObjects ) const
123 QStringList aResList = dumpObjectCreation( theTreatedObjects );
124 QString aName = GetObjPyName();
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" );
142 QString aDDZs = QString::number( GetDDZ(), 'f', 3 );
143 QString aSSteps = QString::number( GetSpatialStep(), 'f', 3 );
144 aResList << QString( "%1.SetDDZ( %2 )" ).arg( aName ).arg( aDDZs );
145 aResList << QString( "%1.SetSpatialStep( %2 )" ).arg( aName ).arg( aSSteps );
147 aResList << QString( "" );
148 aResList << QString( "%1.Update()" ).arg( aName );
149 aResList << QString( "" );
154 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
156 HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
158 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
159 if ( !aHydAxis.IsNull() )
160 aResSeq.Append( aHydAxis );
162 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
163 aResSeq.Append( aSeqOfProfiles );
168 Handle(Geom_BSplineCurve) HYDROData_Stream::buildInterpolationCurve(
169 const Handle(TColgp_HArray1OfPnt)& theArrayOfPnt )
171 Handle(Geom_BSplineCurve) aBSpline;
172 GeomAPI_Interpolate anInterpolator (theArrayOfPnt, Standard_False, 1.0e-5);
173 anInterpolator.Perform() ;
174 if (anInterpolator.IsDone())
175 aBSpline = anInterpolator.Curve();
179 void HYDROData_Stream::Update()
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();
198 bool HYDROData_Stream::IsHas2dPrs() const
203 bool HYDROData_Stream::CreatePresentations( const Handle(HYDROData_PolylineXY)& theHydAxis,
204 const HYDROData_SequenceOfObjects& theProfiles,
205 PrsDefinition& thePrs )
207 if ( theHydAxis.IsNull() || theProfiles.Length() < 2 )
210 Handle(TColgp_HArray1OfPnt) anArrayOfFPnt = new TColgp_HArray1OfPnt(1, theProfiles.Length());
211 Handle(TColgp_HArray1OfPnt) anArrayOfLPnt = new TColgp_HArray1OfPnt(1, theProfiles.Length());
212 Handle(TopTools_HArray1OfShape) anArrOfProfiles = new TopTools_HArray1OfShape(1, theProfiles.Length());
213 Handle(TopTools_HArray1OfShape) anArrOf2DProfiles = new TopTools_HArray1OfShape(1, theProfiles.Length());
216 HYDROData_SequenceOfObjects::Iterator anIter( theProfiles );
217 for (int i=1 ; anIter.More(); anIter.Next(),i++ )
219 Handle(HYDROData_Profile) aProfile =
220 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
221 if ( aProfile.IsNull() )
224 const TopoDS_Shape& aProf3d = aProfile->GetShape3D();
226 if ( !aProfile->GetLeftPoint( aPnt1, false ) || !aProfile->GetRightPoint( aPnt2, false ) )
229 anArrOfProfiles->SetValue(i,aProfile->GetShape3D());//aProfile->GetTopShape();
230 anArrOf2DProfiles->SetValue(i,aProfile->GetTopShape());
232 gp_Pnt aCurFP, aCurLP;
233 TopoDS_Vertex aV1, aV2;
234 TopExp::Vertices(TopoDS::Wire(aProf3d), aV1, aV2);
235 gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
236 if(aP1.X() == aPnt1.X() && aP1.Y() == aPnt1.Y())
240 aP1 = BRep_Tool::Pnt(aV2);
241 if(aP1.X() == aPnt2.X() && aP1.Y() == aPnt2.Y())
245 anArrayOfFPnt->SetValue(i,aCurFP);
246 anArrayOfLPnt->SetValue(i,aCurLP);
249 return CreatePresentations( anArrayOfFPnt, anArrayOfLPnt, anArrOfProfiles, anArrOf2DProfiles, thePrs );
252 void HYDROData_Stream::UpdatePrs()
254 HYDROData_NaturalObject::Update();
256 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
257 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
259 PrsDefinition aResultPrs;
260 if ( !CreatePresentations( aHydAxis, aRefProfiles, aResultPrs ) )
263 SetShape3D( aResultPrs.myPrs3D );
264 SetTopShape( aResultPrs.myPrs2D );
266 // Create the stream groups
267 QString aLeftGroupName = GetName() + "_Left_Bank";
269 Handle(HYDROData_ShapesGroup) aLeftGroup = createGroupObject();
270 aLeftGroup->SetName( aLeftGroupName );
271 aLeftGroup->AddShape( aResultPrs.myLeftBank );
273 QString aRightGroupName = GetName() + "_Right_Bank";
275 Handle(HYDROData_ShapesGroup) aRightGroup = createGroupObject();
276 aRightGroup->SetName( aRightGroupName );
277 aRightGroup->AddShape( aResultPrs.myRightBank );
279 QString anInGroupName = GetName() + "_Inlet";
281 Handle(HYDROData_ShapesGroup) anInGroup = createGroupObject();
282 anInGroup->SetName( anInGroupName );
283 anInGroup->AddShape( aResultPrs.myInlet );
285 QString anOutGroupName = GetName() + "_Outlet";
287 Handle(HYDROData_ShapesGroup) anOutGroup = createGroupObject();
288 anOutGroup->SetName( anOutGroupName );
289 anOutGroup->AddShape( aResultPrs.myOutlet );
292 QColor HYDROData_Stream::DefaultFillingColor() const
294 return QColor( Qt::green );
297 QColor HYDROData_Stream::DefaultBorderColor() const
299 return QColor( Qt::transparent );
302 bool HYDROData_Stream::IsValidAsAxis( const Handle(HYDROData_PolylineXY)& theHydAxis )
304 if ( theHydAxis.IsNull() )
307 TopoDS_Shape aHydraulicShape = theHydAxis->GetShape();
308 if ( aHydraulicShape.IsNull() ||
309 aHydraulicShape.ShapeType() != TopAbs_WIRE ||
310 BRep_Tool::IsClosed( aHydraulicShape ) )
311 return false; // The polyline must be a single not closed wire
316 TopoDS_Shape HYDROData_Stream::GetLeftShape() const
318 HYDROData_SequenceOfObjects aGroups = GetGroups();
319 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 1);
322 TopoDS_Shape HYDROData_Stream::GetRightShape() const
324 HYDROData_SequenceOfObjects aGroups = GetGroups();
325 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 2);
328 TopoDS_Shape HYDROData_Stream::GetInletShape() const
330 HYDROData_SequenceOfObjects aGroups = GetGroups();
331 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 3);
334 TopoDS_Shape HYDROData_Stream::GetOutletShape() const
336 HYDROData_SequenceOfObjects aGroups = GetGroups();
337 return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 4);
340 Handle_HYDROData_DTM HYDROData_Stream::DTM() const
342 return Handle(HYDROData_DTM)::DownCast( GetAltitudeObject() );
345 double HYDROData_Stream::GetDDZ() const
347 return DTM()->GetDDZ();
350 void HYDROData_Stream::SetDDZ( double theDDZ )
352 DTM()->SetDDZ( theDDZ );
355 double HYDROData_Stream::GetSpatialStep() const
357 return DTM()->GetSpatialStep();
360 void HYDROData_Stream::SetSpatialStep( double theSpatialStep )
362 DTM()->SetSpatialStep( theSpatialStep );
365 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
367 if ( !IsValidAsAxis( theAxis ) )
370 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
371 if ( IsEqual( aPrevAxis, theAxis ) )
374 SetReferenceObject( theAxis, DataTag_HydraulicAxis );
376 // Update the order of profiles
377 updateProfilesOrder();
379 // Indicate model of the need to update the stream presentation
385 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
387 return Handle(HYDROData_PolylineXY)::DownCast(
388 GetReferenceObject( DataTag_HydraulicAxis ) );
391 void HYDROData_Stream::RemoveHydraulicAxis()
393 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
394 if ( aPrevAxis.IsNull() )
397 ClearReferenceObjects( DataTag_HydraulicAxis );
399 // We remove the reference profiles
402 // Indicate model of the need to update the stream presentation
406 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile,
407 const TopoDS_Face& thePlane,
408 Standard_Real& theOutPar ) const
410 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
411 return HasIntersection( aHydAxis, theProfile, thePlane, theOutPar );
414 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_PolylineXY)& theHydAxis,
415 const Handle(HYDROData_Profile)& theProfile,
416 const TopoDS_Face& thePlane,
417 Standard_Real& theOutPar )
419 if ( theProfile.IsNull() || !IsValidAsAxis( theHydAxis ) )
422 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() ); //guide line
423 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
424 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
427 BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
428 if(!aProjector.IsDone())
430 TopoDS_Shape aPrjProfile = aProjector.Shape();
431 if(aPrjProfile.IsNull())
433 TopoDS_Vertex aV1, aV2;
434 if(aPrjProfile.ShapeType() == TopAbs_EDGE)
435 TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
436 else if(aPrjProfile.ShapeType() == TopAbs_WIRE)
437 TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
438 else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
439 TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
441 TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
443 anExp.Init(aPrjProfile, TopAbs_EDGE);
445 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
449 if(aV1.IsNull() || aV2.IsNull())
451 gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
452 gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
455 BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2);
458 const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
459 Standard_Integer aNum(0);
461 TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
462 for(;anExplo.More();anExplo.Next()) aNum++;
463 // check for self-intersection
464 const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
465 Standard_Boolean hasInt(false);
466 Standard_Real aSqDist(DBL_MAX);
467 Standard_Integer anIndx(0);
468 BRepExtrema_ExtCC aCC;
469 aCC.Initialize(anEdg2);
471 anExplo.Init(aHydraulicWire, TopAbs_EDGE);
472 for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
473 const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
476 Standard_Boolean hasSol(false);
480 for(Standard_Integer i=1; i<= aCC.NbExt();i++)
481 if(aCC.SquareDistance(i) < aSqDist) {
482 aSqDist = aCC.SquareDistance(i);
488 if(aSqDist <= SquareTolerance) { // hasInt
489 const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
491 TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
492 theOutPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
494 Standard_Real aPar = aCC.ParameterOnE1(anIndx);
502 TopExp::Vertices(anEdg1, aV1, aV2);
503 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
506 } else if(aNum > 1) {
507 TopExp::Vertices(anEdg1, aV1, aV2);
508 theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
516 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
518 if ( theProfile.IsNull() )
521 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
522 if ( aHydAxis.IsNull() )
526 if(!BuildFace(aHydAxis, aPlane))
529 Standard_Real aPar(.0);
530 if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
531 return false; // Object is already in reference list or it has no intersection
533 int aProfileIndex = insertParameter( aPar );
534 insertProfileInToOrder( theProfile, aProfileIndex );
536 // Indicate model of the need to update the stream presentation
542 bool HYDROData_Stream::SetProfiles( const HYDROData_SequenceOfObjects& theProfiles,
543 const bool& theIsToOrder )
547 for ( int i = 1; i <= theProfiles.Length(); ++i )
549 Handle(HYDROData_Profile) aProfile =
550 Handle(HYDROData_Profile)::DownCast( theProfiles.Value( i ) );
551 if ( aProfile.IsNull() )
554 if ( !AddProfile( aProfile ) )
556 DTM()->SetProfiles( HYDROData_SequenceOfObjects() );
561 else // Just store the sequence of objects as is
563 bool anIsToUpdate = true;
565 HYDROData_SequenceOfObjects anOldProfiles = GetProfiles();
566 if ( anOldProfiles.Length() == theProfiles.Length() )
568 anIsToUpdate = false;
570 for ( int i = 1; i <= theProfiles.Length(); ++i )
572 Handle(HYDROData_Entity) anOldProfile = anOldProfiles.Value( i );
573 Handle(HYDROData_Entity) aNewProfile = theProfiles.Value( i );
574 if ( !IsEqual( anOldProfile, aNewProfile ) )
582 SetReferenceObjects( theProfiles, DataTag_Profile );
588 DTM()->SetProfiles( GetProfiles() );
592 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
594 return GetReferenceObjects( DataTag_Profile );
597 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
599 if ( theProfile.IsNull() )
602 int aProfileIndex = -1;
604 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
605 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
606 for ( int i = 0 ; anIter.More(); anIter.Next(), ++i )
608 Handle(HYDROData_Profile) aProfile =
609 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
610 if ( aProfile.IsNull() )
613 if ( IsEqual( theProfile, aProfile ) )
620 if ( aProfileIndex == -1 )
623 RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
625 // Remove parameter for removed profile
626 removeParameter( aProfileIndex );
628 // Indicate model of the need to update the stream presentation
634 void HYDROData_Stream::RemoveProfiles()
636 ClearReferenceObjects( DataTag_Profile );
638 // Remove the parameters array
639 removeParametersArray();
641 // Indicate model of the need to update the stream presentation
645 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile,
646 const int theBeforeIndex )
648 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
649 if ( theProfile.IsNull() || aHydAxis.IsNull() )
652 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
653 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
654 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
657 if ( theBeforeIndex == -1 )
658 AddReferenceObject( theProfile, DataTag_Profile );
660 InsertReferenceObject( theProfile, DataTag_Profile, theBeforeIndex );
663 bool HYDROData_Stream::BuildFace( const Handle(HYDROData_PolylineXY)& theHydAxis,
664 TopoDS_Face& thePlane )
666 if ( !IsValidAsAxis( theHydAxis ) )
669 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() );
671 gp_Ax2 aX2(gp::XOY());
675 BRepBndLib::Add(aHydraulicWire,B);
676 Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
677 B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
678 BRepBuilderAPI_MakeFace aMkr(aPln, axmin-500., axmax+500., aymin-500., aymax+500.); // to be tuned later according max/ Profile deviation
679 if(!aMkr.IsDone() || aMkr.Shape().IsNull()) return false;
680 thePlane = TopoDS::Face(aMkr.Shape());
684 void HYDROData_Stream::updateProfilesOrder()
686 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
687 if ( aRefProfiles.IsEmpty() )
690 // At first we remove all profiles from order
693 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
694 if ( aHydAxis.IsNull() )
698 if ( !BuildFace( aHydAxis, aPlane ) )
701 Standard_Real aPar( .0 );
705 TopoDS_Compound aCmp;
706 aBB.MakeCompound(aCmp);
709 HYDROData_DataMapOfRealOfHDProfile aDM;
710 TColStd_ListOfReal aList;
711 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
712 for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
714 Handle(HYDROData_Profile) aProfile =
715 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
717 TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
718 aBB.Add( aCmp, aProfileWire );
720 if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
723 aDM.Bind( aPar, aProfile );
724 aList.Append( aPar );
727 if ( aList.IsEmpty() )
730 TColStd_Array1OfReal anArr( 1, aList.Extent() );
732 TColStd_ListIteratorOfListOfReal it( aList );
733 for ( int j = 1; it.More(); it.Next(), j++ )
734 anArr( j ) = it.Value();
737 if ( aList.Extent() > 1 )
739 TCollection_CompareOfReal Compar;
740 SortTools_QuickSortOfReal::Sort( anArr, Compar );
742 for (int j = 1; j <= anArr.Length(); j++) {
743 const Standard_Real aKey = anArr(j);
744 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
745 insertProfileInToOrder( aProfile );
747 } else if ( aList.Extent() == 1 ) {
748 const Standard_Real aKey = aList.Last();
749 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
750 insertProfileInToOrder( aProfile );
753 setParametersArray( anArr );
756 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
757 BRepTools::Write(aHydraulicWire, "Path.brep");
758 BRepTools::Write(aCmp, "Prof.brep");
762 ObjectKind HYDROData_Stream::getAltitudeObjectType() const
767 void HYDROData_Stream::setParametersArray( const TColStd_Array1OfReal& theArray )
769 if ( theArray.Length() == 0 )
771 removeParametersArray();
775 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray );
777 Handle(TDataStd_RealArray) aParamsArray =
778 TDataStd_RealArray::Set( aLabel, theArray.Lower(), theArray.Upper() );
780 for ( int i = theArray.Lower(), n = theArray.Upper(); i <= n; ++i )
782 const Standard_Real& aParam = theArray( i );
783 aParamsArray->SetValue( i, aParam );
787 TColStd_Array1OfReal* HYDROData_Stream::getParametersArray() const
789 TColStd_Array1OfReal* anArray = NULL;
791 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
792 if ( !aLabel.IsNull() )
794 Handle(TDataStd_RealArray) aParamsArray;
795 if ( aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
797 anArray = new TColStd_Array1OfReal( aParamsArray->Lower(), aParamsArray->Upper() );
798 for ( int i = aParamsArray->Lower(), n = aParamsArray->Upper(); i <= n; ++i )
800 const Standard_Real& aParam = aParamsArray->Value( i );
801 anArray->SetValue( i, aParam );
809 void HYDROData_Stream::removeParametersArray()
811 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
812 if ( !aLabel.IsNull() )
813 aLabel.ForgetAllAttributes();
816 int HYDROData_Stream::insertParameter( const Standard_Real& theParam )
820 TColStd_Array1OfReal* anArr = getParametersArray();
825 TColStd_Array1OfReal aNewArr( anArr->Lower(), anArr->Upper() + 1 );
827 bool isInserted = false;
828 for ( int i = anArr->Lower(), j = i, n = anArr->Upper(); i <= n; ++i, ++j )
830 const Standard_Real& aStoredParam = anArr->Value( i );
833 if ( theParam > aStoredParam )
839 aNewArr( j ) = theParam;
845 aNewArr( j ) = aStoredParam;
851 aNewArr( aNewArr.Upper() ) = theParam;
854 setParametersArray( aNewArr );
859 TColStd_Array1OfReal aNewArr( 1, 1 );
860 aNewArr.SetValue( 1, theParam );
861 setParametersArray( aNewArr );
867 void HYDROData_Stream::removeParameter( const int& theIndex )
869 TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
870 if ( aLabel.IsNull() )
873 Handle(TDataStd_RealArray) aParamsArray;
874 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
877 if ( aParamsArray->Length() == 1 )
879 removeParametersArray();
883 TColStd_Array1OfReal aNewArr( aParamsArray->Lower(), aParamsArray->Upper() - 1 );
885 for ( int i = aParamsArray->Lower(), j = i, k = 0, n = aParamsArray->Upper(); i <= n; ++i, ++k )
887 const Standard_Real& aStoredParam = aParamsArray->Value( i );
891 aNewArr.SetValue( j, aStoredParam );
895 setParametersArray( aNewArr );
898 bool HYDROData_Stream::GenerateBottomPolyline()
901 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
902 if ( aDocument.IsNull() ) {
906 // Collect bottom points ( one bottom point from each profile of the stream )
907 HYDROData_Profile::ProfilePoints aBottomPoints;
909 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
910 for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; i++ ) {
911 const Handle(HYDROData_Profile) aProfile =
912 Handle(HYDROData_Profile)::DownCast( aSeqOfProfiles.Value( i ) );
913 if ( aProfile.IsNull() ) {
917 aBottomPoints.Append( aProfile->GetBottomPoint() );
920 int aNbBottomPoints = aBottomPoints.Size();
922 if ( aNbBottomPoints < 2 ) {
926 // Create bottom polyline object if the stream doesn't contain it yet
927 Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
928 if ( aBottom.IsNull() ) {
929 aBottom = Handle(HYDROData_Polyline3D)::DownCast( aDocument->CreateObject( KIND_POLYLINE ) );
930 QString aBaseName = GetName() + "_bottom";
931 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
932 aBottom->SetName( aName );
934 SetReferenceObject( aBottom, DataTag_BottomPolyline );
937 // Create 2D polyline if the bottom polyline doesn't contain it yet
938 Handle(HYDROData_PolylineXY) aPolylineXY = aBottom->GetPolylineXY();
939 if ( aPolylineXY.IsNull() ) {
940 aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( aDocument->CreateObject( KIND_POLYLINEXY ) );
941 QString aBaseName = GetName() + "_bottom_2d";
942 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
943 aPolylineXY->SetName( aName );
944 aBottom->SetPolylineXY( aPolylineXY, false );
947 aPolylineXY->RemoveSections();
948 aPolylineXY->AddSection( "", HYDROData_PolylineXY::SECTION_SPLINE, false );
950 // Create profile if the bottom polyline doesn't contain it yet
951 Handle(HYDROData_ProfileUZ) aProfileUZ = aBottom->GetProfileUZ();
952 if ( aProfileUZ.IsNull() ) {
953 Handle(HYDROData_Profile) aProfile =
954 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
955 QString aBaseName = GetName() + "_bottom_profile";
956 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
957 aProfile->SetName( aName );
958 aProfileUZ = aProfile->GetProfileUZ( true );
959 aBottom->SetProfileUZ( aProfileUZ );
962 aProfileUZ->RemoveSection( 0 );
964 aProfileUZ->CalculateAndAddPoints(aBottomPoints, aPolylineXY);
969 Handle(HYDROData_Polyline3D) HYDROData_Stream::GetBottomPolyline() const
971 return Handle(HYDROData_Polyline3D)::DownCast(
972 GetReferenceObject( DataTag_BottomPolyline ) );
975 bool HYDROData_Stream::SetBottomPolyline( const Handle(HYDROData_Polyline3D)& theBottom )
977 if ( theBottom.IsNull() ) {
981 SetReferenceObject( theBottom, DataTag_BottomPolyline );
986 bool HYDROData_Stream::Interpolate( HYDROData_IProfilesInterpolator* theInterpolator )
989 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
990 if ( aDocument.IsNull() ) {
994 if ( theInterpolator->GetCalculatedProfilesNumber() < 1 ) {
995 theInterpolator->Calculate();
998 if ( theInterpolator->GetErrorCode() != OK ) {
1004 for ( int aProfileInd = 0; aProfileInd < theInterpolator->GetCalculatedProfilesNumber(); aProfileInd++ ) {
1005 // Get calculated point coordinates
1006 HYDROData_Profile::ProfilePoints aResultPoints = theInterpolator->GetResultProfilePoints( aProfileInd );
1007 if ( aResultPoints.IsEmpty() ) {
1012 // Create profile object
1013 Handle(HYDROData_Profile) aProfile =
1014 Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
1015 QString aBaseName = GetName() + "_interp_profile";
1016 QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName );
1017 aProfile->SetName( aName );
1019 // Fill the profile with points
1020 aProfile->SetProfilePoints( aResultPoints );
1022 // Add profile to the stream
1023 bool isAdded = AddProfile( aProfile );
1037 void HYDROData_Stream::CopyTo( const Handle(HYDROData_Entity)& theDestination,
1038 bool isGenerateNewName ) const
1041 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
1042 if ( aDocument.IsNull() ) {
1047 HYDROData_Entity::CopyTo( theDestination, isGenerateNewName );
1049 Handle(HYDROData_Stream) aStreamCopy =
1050 Handle(HYDROData_Stream)::DownCast( theDestination );
1052 // Copy bottom polyline if exists
1053 if ( !aStreamCopy.IsNull() ) {
1054 const Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
1055 if ( !aBottom.IsNull() ) {
1056 aStreamCopy->ClearReferenceObjects( DataTag_BottomPolyline );
1057 aStreamCopy->GenerateBottomPolyline();
1058 const Handle(HYDROData_Polyline3D) aBottomCopy = aStreamCopy->GetBottomPolyline();
1059 if ( !aBottomCopy.IsNull() && !aBottomCopy->GetPolylineXY().IsNull() ) {
1060 aBottomCopy->GetPolylineXY()->Update();
1061 aBottomCopy->Update();
1067 bool HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) theArrayOfFPnt,
1068 const Handle(TColgp_HArray1OfPnt) theArrayOfLPnt,
1069 const Handle(TopTools_HArray1OfShape) theArrOfProfiles,
1070 const Handle(TopTools_HArray1OfShape) theArrOf2DProfiles,
1071 PrsDefinition& thePrs )
1073 if ( theArrayOfFPnt.IsNull() || theArrayOfLPnt.IsNull() || theArrOfProfiles.IsNull() ) {
1077 if ( theArrayOfFPnt->Length() != theArrayOfLPnt->Length() ) {
1081 // Construct of the 3D presentation
1082 Handle(Geom_BSplineCurve) aBSpline = buildInterpolationCurve (theArrayOfFPnt);
1083 if(aBSpline.IsNull())
1086 TopoDS_Edge anEdgLeft, anEdgRight;
1088 BRepBuilderAPI_MakeEdge aMakeEdge(aBSpline);
1089 if(aMakeEdge.IsDone())
1090 anEdgLeft = aMakeEdge.Edge();
1092 if(anEdgLeft.IsNull())
1096 aBSpline = buildInterpolationCurve (theArrayOfLPnt);
1097 if(aBSpline.IsNull())
1100 aMakeEdge.Init(aBSpline);
1101 if(aMakeEdge.IsDone())
1102 anEdgRight = aMakeEdge.Edge();
1104 if(anEdgRight.IsNull())
1108 TopoDS_Compound aCmp;
1109 aBB.MakeCompound(aCmp);
1110 for (int i=1 ; i < theArrOfProfiles->Length() +1; i++ )
1111 aBB.Add(aCmp, theArrOfProfiles->Value(i));
1113 aBB.Add(aCmp,anEdgLeft);
1114 aBB.Add(aCmp,anEdgRight);
1115 BRepCheck_Analyzer aCh(aCmp);
1117 thePrs.myPrs3D = aCmp;
1120 BRepTools::Write(aCmp, "str3d.brep");
1121 thePrs.myPrs3D = aCmp;
1125 // Construct the top presentation
1126 int aNbPoints = theArrayOfFPnt->Length();
1127 Handle(TColgp_HArray1OfPnt) anArrayOfFPnt = new TColgp_HArray1OfPnt(1, aNbPoints);
1128 Handle(TColgp_HArray1OfPnt) anArrayOfLPnt = new TColgp_HArray1OfPnt(1, aNbPoints);
1129 for( int i=1; i <= aNbPoints; i++ ) {
1130 gp_Pnt aPnt = theArrayOfFPnt->Value(i);
1131 aPnt.SetZ(.0); // make 2d
1132 anArrayOfFPnt->SetValue(i, aPnt);
1133 aPnt = theArrayOfLPnt->Value(i);
1135 anArrayOfLPnt->SetValue(i, aPnt);
1139 aBSpline = buildInterpolationCurve (anArrayOfFPnt);
1140 if(aBSpline.IsNull())
1143 aMakeEdge.Init(aBSpline);
1144 if(aMakeEdge.IsDone())
1145 anEdgLeft = aMakeEdge.Edge();
1148 aBSpline = buildInterpolationCurve (anArrayOfLPnt);
1149 if(aBSpline.IsNull())
1152 aMakeEdge.Init(aBSpline);
1153 if(aMakeEdge.IsDone())
1154 anEdgRight = aMakeEdge.Edge();
1155 if(anEdgRight.IsNull())
1158 BRepBuilderAPI_MakeEdge aMakeEdge2(anArrayOfFPnt->Value(1),anArrayOfLPnt->Value(1));
1159 TopoDS_Edge aBotEdge, aTopEdge;
1160 if(aMakeEdge2.IsDone())
1161 aBotEdge = aMakeEdge2.Edge();
1163 BRepBuilderAPI_MakeEdge aMakeEdge3(anArrayOfFPnt->Value(anArrayOfFPnt->Length()),anArrayOfLPnt->Value(anArrayOfLPnt->Length()));
1164 if(aMakeEdge3.IsDone())
1165 aTopEdge = aMakeEdge3.Edge();
1167 // Make wire for 2D presentation with updating of corresponding edges
1168 BRepBuilderAPI_MakeWire aMakeWire;
1170 aMakeWire.Add( aBotEdge );
1171 thePrs.myInlet = aMakeWire.Edge();
1173 aMakeWire.Add( anEdgLeft );
1174 thePrs.myLeftBank = aMakeWire.Edge();
1176 aMakeWire.Add( aTopEdge );
1177 thePrs.myOutlet = aMakeWire.Edge();
1179 aMakeWire.Add( anEdgRight );
1180 thePrs.myRightBank = aMakeWire.Edge();
1182 TopoDS_Wire aSectProfileWire;
1183 if(aMakeWire.IsDone())
1184 aSectProfileWire = aMakeWire.Wire();
1186 BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
1189 if( aMakeFace.IsDone() )
1190 aFace = aMakeFace.Face();
1192 TopoDS_Shape aPrs2D;
1194 if ( !theArrOf2DProfiles.IsNull() ) {
1196 aBB.MakeCompound(aCmp);
1197 aBB.Add(aCmp,aFace);
1198 for(int i=1;i <= theArrOf2DProfiles->Length(); i++)
1199 aBB.Add(aCmp, theArrOf2DProfiles->Value(i));
1208 thePrs.myPrs2D = aPrs2D;
1211 BRepTools::Write(aPrs2D, "str2d.brep");
1212 thePrs.myPrs2D = aPrs2D;