2 #include "HYDROData_Stream.h"
4 #include "HYDROData_Document.h"
5 #include "HYDROData_PolylineXY.h"
6 #include "HYDROData_Profile.h"
8 #include <BRep_Builder.hxx>
9 #include <BRepBuilderAPI_MakeEdge.hxx>
10 #include <BRepBuilderAPI_MakeWire.hxx>
11 #include <BRepBuilderAPI_MakeFace.hxx>
14 #include <TopoDS_Wire.hxx>
15 #include <TopoDS_Shell.hxx>
16 #include <TopoDS_Face.hxx>
17 #include <TopoDS_Edge.hxx>
18 #include <TopoDS_Vertex.hxx>
20 #include <TopExp_Explorer.hxx>
21 #include <BRepProj_Projection.hxx>
22 #include <BRepExtrema_ExtCC.hxx>
30 #include <Precision.hxx>
31 #include <QStringList>
33 #define PYTHON_STREAM_ID "KIND_STREAM"
35 IMPLEMENT_STANDARD_HANDLE(HYDROData_Stream,HYDROData_NaturalObject)
36 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
39 HYDROData_Stream::HYDROData_Stream()
40 : HYDROData_NaturalObject()
44 HYDROData_Stream::~HYDROData_Stream()
48 QStringList HYDROData_Stream::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
52 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
53 if ( aDocument.IsNull() )
56 QString aDocName = aDocument->GetDocPyName();
57 QString aStreamName = GetName();
59 aResList << QString( "%1 = %2.CreateObject( %3 );" )
60 .arg( aStreamName ).arg( aDocName ).arg( PYTHON_STREAM_ID );
61 aResList << QString( "%1.SetName( \"%2\" );" )
62 .arg( aStreamName ).arg( aStreamName );
63 aResList << QString( "" );
70 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
72 HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
74 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
75 if ( !aHydAxis.IsNull() )
76 aResSeq.Append( aHydAxis );
78 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
79 aResSeq.Append( aSeqOfProfiles );
84 TopoDS_Shape HYDROData_Stream::GetTopShape() const
89 TopoDS_Shape HYDROData_Stream::GetShape3D() const
94 void HYDROData_Stream::Update()
96 HYDROData_NaturalObject::Update();
98 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
99 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
100 if ( aHydAxis.IsNull() || aRefProfiles.IsEmpty() )
103 TopoDS_Shell a2dShell;
104 BRep_Builder a2dShellBuilder;
105 a2dShellBuilder.MakeShell( a2dShell );
107 bool anIsFirst = true;
108 gp_Pnt aPrevFirstPoint, aPrevLastPoint;
110 // Construct the top presentation
111 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
112 for ( ; anIter.More(); anIter.Next() )
114 Handle(HYDROData_Profile) aProfile =
115 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
116 if ( aProfile.IsNull() )
120 if ( !aProfile->GetFirstPoint( aPnt1 ) || !aProfile->GetLastPoint( aPnt2 ) )
123 gp_Pnt aCurFirstPoint( aPnt1.X(), aPnt1.Y(), 0 );
124 gp_Pnt aCurLastPoint( aPnt2.X(), aPnt2.Y(), 0 );
128 aPrevFirstPoint = aCurFirstPoint;
129 aPrevLastPoint = aCurLastPoint;
134 BRepBuilderAPI_MakeEdge aFirstEdge( aPrevFirstPoint, aPrevLastPoint );
135 BRepBuilderAPI_MakeEdge aSecondEdge( aPrevLastPoint, aCurLastPoint );
136 BRepBuilderAPI_MakeEdge aThirdEdge( aCurLastPoint, aCurFirstPoint );
137 BRepBuilderAPI_MakeEdge aFourthEdge( aCurFirstPoint, aPrevFirstPoint );
139 BRepBuilderAPI_MakeWire aMakeWire( aFirstEdge.Edge(), aSecondEdge.Edge(),
140 aThirdEdge.Edge(), aFourthEdge.Edge() );
142 TopoDS_Wire aSectProfileWire = aMakeWire.Wire();
144 BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
146 if( aMakeFace.IsDone() )
148 a2dShellBuilder.Add( a2dShell, aMakeFace.Face() );
151 aPrevFirstPoint = aCurFirstPoint;
152 aPrevLastPoint = aCurLastPoint;
155 SetTopShape( a2dShell );
157 // Construct the 3D presentation
161 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
163 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
165 if ( theAxis.IsNull() )
167 RemoveHydraulicAxis();
168 return !aPrevAxis.IsNull();
171 if ( IsEqual( aPrevAxis, theAxis ) )
174 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theAxis->GetShape() );
175 if ( aHydraulicWire.IsNull() )
176 return false; // The polyline must be a single wire
178 SetReferenceObject( theAxis, DataTag_HydraulicAxis );
180 // Update the order of profiles
181 updateProfilesOrder();
183 // Indicate model of the need to update the stream presentation
189 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
191 return Handle(HYDROData_PolylineXY)::DownCast(
192 GetReferenceObject( DataTag_HydraulicAxis ) );
195 void HYDROData_Stream::RemoveHydraulicAxis()
197 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
198 if ( aPrevAxis.IsNull() )
201 ClearReferenceObjects( DataTag_HydraulicAxis );
203 // We remove the reference profiles
206 // Indicate model of the need to update the stream presentation
210 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile, const TopoDS_Face& thePlane,
211 Standard_Real& outPar ) const
213 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
214 if ( theProfile.IsNull() || aHydAxis.IsNull() )
217 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() ); //guide line
218 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
219 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
223 return true; // temporary
224 BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
225 if(!aProjector.IsDone())
227 TopoDS_Shape aPrjProfile = aProjector.Shape();
228 if(aPrjProfile.IsNull())
230 TopoDS_Vertex aV1, aV2;
231 if(aPrjProfile.ShapeType() == TopAbs_EDGE)
232 TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
233 else if(aPrjProfile.ShapeType() == TopAbs_WIRE)
234 TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
235 else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
236 TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
238 TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
240 anExp.Init(aPrjProfile, TopAbs_EDGE);
242 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
246 if(aV1.IsNull() || aV2.IsNull())
248 gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
249 gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
252 BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2);
255 const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
256 Standard_Integer aNum(0);
258 TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
259 for(;anExplo.More();anExplo.Next()) aNum++;
260 // check for self-intersection
261 const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
262 Standard_Boolean hasInt(false);
263 Standard_Real aSqDist(DBL_MAX);
264 Standard_Integer anIndx(0);
265 BRepExtrema_ExtCC aCC;
266 aCC.Initialize(anEdg2);
268 anExplo.Init(aHydraulicWire, TopAbs_EDGE);
269 for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
270 const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
275 for(Standard_Integer i=1; i<= aCC.NbExt();i++)
276 if(aCC.SquareDistance(i) < aSqDist) {
277 aSqDist = aCC.SquareDistance(i);
283 if(aSqDist <= SquareTolerance) {
284 const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
286 TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
287 outPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
289 Standard_Real aPar = aCC.ParameterOnE1(anIndx);
295 TopExp::Vertices(anEdg1, aV1, aV2);
296 outPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
304 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
306 if ( theProfile.IsNull() )
308 gp_Ax2 aX2(gp::XOY());
311 BRepBuilderAPI_MakeFace aMkr(aPln);
314 const TopoDS_Face& aPlane = TopoDS::Face(aMkr.Shape());
315 Standard_Real aPar(.0);
316 if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
317 return false; // Object is already in reference list or it has no intersection
319 insertProfileInToOrder( theProfile );
321 // Indicate model of the need to update the stream presentation
327 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
329 return GetReferenceObjects( DataTag_Profile );
332 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
334 if ( theProfile.IsNull() || !HasReference( theProfile, DataTag_Profile ) )
337 RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
339 // Indicate model of the need to update the stream presentation
345 void HYDROData_Stream::RemoveProfiles()
347 bool anIsToUpdate = IsMustBeUpdated() || NbReferenceObjects( DataTag_Profile ) > 0;
349 ClearReferenceObjects( DataTag_Profile );
351 // Indicate model of the need to update the stream presentation
352 SetToUpdate( anIsToUpdate );
355 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile )
357 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
358 if ( theProfile.IsNull() || aHydAxis.IsNull() )
361 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
362 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
363 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
367 AddReferenceObject( theProfile, DataTag_Profile ); // temporary for testing only
370 void HYDROData_Stream::updateProfilesOrder()
372 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
373 if ( aRefProfiles.IsEmpty() )
376 // At first we remove all profiles from order
379 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
380 if ( aHydAxis.IsNull() )
382 gp_Ax2 aX2(gp::XOY());
385 BRepBuilderAPI_MakeFace aMkr(aPln);
388 const TopoDS_Face& aPlane = TopoDS::Face(aMkr.Shape());
389 Standard_Real aPar(.0);
390 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
391 for ( ; anIter.More(); anIter.Next() )
393 Handle(HYDROData_Profile) aProfile =
394 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
395 if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
398 insertProfileInToOrder( aProfile );