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 <Bnd_Box.hxx>
31 #include <BRepBndLib.hxx>
32 #include <TColStd_Array1OfReal.hxx>
33 #include <Precision.hxx>
34 #include <QStringList>
36 #include <NCollection_DataMap.hxx>
37 typedef NCollection_DataMap<Standard_Real, Handle(HYDROData_Profile)> HYDROData_DataMapOfRealOfHDProfile;
38 //typedef HYDROData_DataMapOfRealOfHDProfile::Iterator HYDROData_DataMapIteratorOfDataMapOfRealOfHDProfile;
39 #include <TColStd_ListOfReal.hxx>
40 #include <TColStd_ListIteratorOfListOfReal.hxx>
41 #include <TCollection_CompareOfReal.hxx>
42 #include <SortTools_QuickSortOfReal.hxx>
43 //#define DEB_HASINT 1
45 #include <BRepTools.hxx>
46 #include <TCollection_AsciiString.hxx>
47 #include <BRep_Builder.hxx>
50 #define PYTHON_STREAM_ID "KIND_STREAM"
52 IMPLEMENT_STANDARD_HANDLE(HYDROData_Stream,HYDROData_NaturalObject)
53 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
56 HYDROData_Stream::HYDROData_Stream()
57 : HYDROData_NaturalObject()
61 HYDROData_Stream::~HYDROData_Stream()
65 QStringList HYDROData_Stream::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
69 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
70 if ( aDocument.IsNull() )
73 QString aDocName = aDocument->GetDocPyName();
74 QString aStreamName = GetName();
76 aResList << QString( "%1 = %2.CreateObject( %3 );" )
77 .arg( aStreamName ).arg( aDocName ).arg( PYTHON_STREAM_ID );
78 aResList << QString( "%1.SetName( \"%2\" );" )
79 .arg( aStreamName ).arg( aStreamName );
80 aResList << QString( "" );
87 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
89 HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
91 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
92 if ( !aHydAxis.IsNull() )
93 aResSeq.Append( aHydAxis );
95 HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
96 aResSeq.Append( aSeqOfProfiles );
101 TopoDS_Shape HYDROData_Stream::GetTopShape() const
103 return getTopShape();
106 TopoDS_Shape HYDROData_Stream::GetShape3D() const
111 void HYDROData_Stream::Update()
113 HYDROData_NaturalObject::Update();
115 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
116 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
117 if ( aHydAxis.IsNull() || aRefProfiles.IsEmpty() )
120 TopoDS_Shell a2dShell;
121 BRep_Builder a2dShellBuilder;
122 a2dShellBuilder.MakeShell( a2dShell );
124 bool anIsFirst = true;
125 gp_Pnt aPrevFirstPoint, aPrevLastPoint;
127 // Construct the top presentation
128 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
129 for ( ; anIter.More(); anIter.Next() )
131 Handle(HYDROData_Profile) aProfile =
132 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
133 if ( aProfile.IsNull() )
137 if ( !aProfile->GetFirstPoint( aPnt1 ) || !aProfile->GetLastPoint( aPnt2 ) )
140 gp_Pnt aCurFirstPoint( aPnt1.X(), aPnt1.Y(), 0 );
141 gp_Pnt aCurLastPoint( aPnt2.X(), aPnt2.Y(), 0 );
145 aPrevFirstPoint = aCurFirstPoint;
146 aPrevLastPoint = aCurLastPoint;
151 BRepBuilderAPI_MakeEdge aFirstEdge( aPrevFirstPoint, aPrevLastPoint );
152 BRepBuilderAPI_MakeEdge aSecondEdge( aPrevLastPoint, aCurLastPoint );
153 BRepBuilderAPI_MakeEdge aThirdEdge( aCurLastPoint, aCurFirstPoint );
154 BRepBuilderAPI_MakeEdge aFourthEdge( aCurFirstPoint, aPrevFirstPoint );
156 BRepBuilderAPI_MakeWire aMakeWire( aFirstEdge.Edge(), aSecondEdge.Edge(),
157 aThirdEdge.Edge(), aFourthEdge.Edge() );
159 TopoDS_Wire aSectProfileWire = aMakeWire.Wire();
161 BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
163 if( aMakeFace.IsDone() )
165 a2dShellBuilder.Add( a2dShell, aMakeFace.Face() );
168 aPrevFirstPoint = aCurFirstPoint;
169 aPrevLastPoint = aCurLastPoint;
172 SetTopShape( a2dShell );
174 // Construct the 3D presentation
178 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
180 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
182 if ( theAxis.IsNull() )
184 RemoveHydraulicAxis();
185 return !aPrevAxis.IsNull();
188 if ( IsEqual( aPrevAxis, theAxis ) )
191 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theAxis->GetShape() );
192 if ( aHydraulicWire.IsNull() )
193 return false; // The polyline must be a single wire
195 SetReferenceObject( theAxis, DataTag_HydraulicAxis );
197 // Update the order of profiles
198 updateProfilesOrder();
200 // Indicate model of the need to update the stream presentation
206 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
208 return Handle(HYDROData_PolylineXY)::DownCast(
209 GetReferenceObject( DataTag_HydraulicAxis ) );
212 void HYDROData_Stream::RemoveHydraulicAxis()
214 Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
215 if ( aPrevAxis.IsNull() )
218 ClearReferenceObjects( DataTag_HydraulicAxis );
220 // We remove the reference profiles
223 // Indicate model of the need to update the stream presentation
227 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile, const TopoDS_Face& thePlane,
228 Standard_Real& outPar ) const
230 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
231 if ( theProfile.IsNull() || aHydAxis.IsNull() )
234 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() ); //guide line
235 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
236 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
240 //return true; // temporary
241 BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
242 if(!aProjector.IsDone())
244 TopoDS_Shape aPrjProfile = aProjector.Shape();
245 if(aPrjProfile.IsNull())
247 TopoDS_Vertex aV1, aV2;
248 if(aPrjProfile.ShapeType() == TopAbs_EDGE)
249 TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
250 else if(aPrjProfile.ShapeType() == TopAbs_WIRE)
251 TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
252 else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
253 TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
255 TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
257 anExp.Init(aPrjProfile, TopAbs_EDGE);
259 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
263 if(aV1.IsNull() || aV2.IsNull())
265 gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
266 gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
269 BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2);
272 const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
273 Standard_Integer aNum(0);
275 TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
276 for(;anExplo.More();anExplo.Next()) aNum++;
277 // check for self-intersection
278 const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
279 Standard_Boolean hasInt(false);
280 Standard_Real aSqDist(DBL_MAX);
281 Standard_Integer anIndx(0);
282 BRepExtrema_ExtCC aCC;
283 aCC.Initialize(anEdg2);
285 anExplo.Init(aHydraulicWire, TopAbs_EDGE);
286 for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
287 const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
290 Standard_Boolean hasSol(false);
294 for(Standard_Integer i=1; i<= aCC.NbExt();i++)
295 if(aCC.SquareDistance(i) < aSqDist) {
296 aSqDist = aCC.SquareDistance(i);
302 if(aSqDist <= SquareTolerance) { // hasInt
303 const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
305 TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
306 outPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
308 Standard_Real aPar = aCC.ParameterOnE1(anIndx);
316 TopExp::Vertices(anEdg1, aV1, aV2);
317 outPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
327 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
329 if ( theProfile.IsNull() )
331 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
332 if ( aHydAxis.IsNull() )
335 if(!BuildFace(aHydAxis, aPlane))
337 Standard_Real aPar(.0);
338 if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
339 return false; // Object is already in reference list or it has no intersection
341 insertProfileInToOrder( theProfile );
343 // Indicate model of the need to update the stream presentation
349 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
351 return GetReferenceObjects( DataTag_Profile );
354 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
356 if ( theProfile.IsNull() || !HasReference( theProfile, DataTag_Profile ) )
359 RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
361 // Indicate model of the need to update the stream presentation
367 void HYDROData_Stream::RemoveProfiles()
369 bool anIsToUpdate = IsMustBeUpdated() || NbReferenceObjects( DataTag_Profile ) > 0;
371 ClearReferenceObjects( DataTag_Profile );
373 // Indicate model of the need to update the stream presentation
374 SetToUpdate( anIsToUpdate );
377 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile )
379 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
380 if ( theProfile.IsNull() || aHydAxis.IsNull() )
383 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
384 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
385 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
389 AddReferenceObject( theProfile, DataTag_Profile ); // temporary for testing only
392 bool HYDROData_Stream::BuildFace( const Handle(HYDROData_PolylineXY)& theHydAxis, TopoDS_Face& thePlane) const
394 if ( theHydAxis.IsNull() ) return false;
395 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() );
396 if(aHydraulicWire.IsNull()) return false;
397 gp_Ax2 aX2(gp::XOY());
401 BRepBndLib::Add(aHydraulicWire,B);
402 Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
403 B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
404 BRepBuilderAPI_MakeFace aMkr(aPln, axmin-500., axmax+500., aymin-500., aymax+500.); // to be tuned later according max/ Profile deviation
405 if(!aMkr.IsDone() || aMkr.Shape().IsNull()) return false;
406 thePlane = TopoDS::Face(aMkr.Shape());
409 void HYDROData_Stream::updateProfilesOrder()
411 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
412 if ( aRefProfiles.IsEmpty() )
415 // At first we remove all profiles from order
418 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
419 if ( aHydAxis.IsNull() )
422 if(!BuildFace(aHydAxis, aPlane))
424 Standard_Real aPar(.0);
427 TopoDS_Compound aCmp;
428 aBB.MakeCompound(aCmp);
430 HYDROData_DataMapOfRealOfHDProfile aDM;
431 TColStd_ListOfReal aList;
432 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
433 for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
435 Handle(HYDROData_Profile) aProfile =
436 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
438 TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
439 aBB.Add( aCmp, aProfileWire);
441 if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
443 aDM.Bind(aPar, aProfile);
445 //insertProfileInToOrder( aProfile );
448 if(aList.Extent() > 1) {
449 TColStd_Array1OfReal anArr(1, aList.Extent());
450 TColStd_ListIteratorOfListOfReal it(aList);
451 for (int j=1;it.More();it.Next(), j++)
452 anArr(j) = it.Value();
453 TCollection_CompareOfReal Compar;
454 SortTools_QuickSortOfReal::Sort( anArr, Compar);
455 for (int j = 1; j <= anArr.Length(); j++) {
456 const Standard_Real aKey = anArr(j);
457 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
458 insertProfileInToOrder( aProfile );
460 } else if(aList.Extent() == 1) {
461 const Standard_Real aKey = aList.Last();
462 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
463 insertProfileInToOrder( aProfile );
467 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
468 BRepTools::Write(aHydraulicWire, "Path.brep");
469 BRepTools::Write(aCmp, "Prof.brep");