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));
320 } else if(aNum > 1) {
321 TopExp::Vertices(anEdg1, aV1, aV2);
322 outPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
330 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
332 if ( theProfile.IsNull() )
334 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
335 if ( aHydAxis.IsNull() )
338 if(!BuildFace(aHydAxis, aPlane))
340 Standard_Real aPar(.0);
341 if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
342 return false; // Object is already in reference list or it has no intersection
344 insertProfileInToOrder( theProfile );
346 // Indicate model of the need to update the stream presentation
352 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
354 return GetReferenceObjects( DataTag_Profile );
357 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
359 if ( theProfile.IsNull() || !HasReference( theProfile, DataTag_Profile ) )
362 RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
364 // Indicate model of the need to update the stream presentation
370 void HYDROData_Stream::RemoveProfiles()
372 bool anIsToUpdate = IsMustBeUpdated() || NbReferenceObjects( DataTag_Profile ) > 0;
374 ClearReferenceObjects( DataTag_Profile );
376 // Indicate model of the need to update the stream presentation
377 SetToUpdate( anIsToUpdate );
380 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile )
382 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
383 if ( theProfile.IsNull() || aHydAxis.IsNull() )
386 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
387 TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
388 if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
392 AddReferenceObject( theProfile, DataTag_Profile ); // temporary for testing only
395 bool HYDROData_Stream::BuildFace( const Handle(HYDROData_PolylineXY)& theHydAxis, TopoDS_Face& thePlane) const
397 if ( theHydAxis.IsNull() ) return false;
398 TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() );
399 if(aHydraulicWire.IsNull()) return false;
400 gp_Ax2 aX2(gp::XOY());
404 BRepBndLib::Add(aHydraulicWire,B);
405 Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
406 B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
407 BRepBuilderAPI_MakeFace aMkr(aPln, axmin-500., axmax+500., aymin-500., aymax+500.); // to be tuned later according max/ Profile deviation
408 if(!aMkr.IsDone() || aMkr.Shape().IsNull()) return false;
409 thePlane = TopoDS::Face(aMkr.Shape());
412 void HYDROData_Stream::updateProfilesOrder()
414 HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
415 if ( aRefProfiles.IsEmpty() )
418 // At first we remove all profiles from order
421 Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
422 if ( aHydAxis.IsNull() )
425 if(!BuildFace(aHydAxis, aPlane))
427 Standard_Real aPar(.0);
430 TopoDS_Compound aCmp;
431 aBB.MakeCompound(aCmp);
433 HYDROData_DataMapOfRealOfHDProfile aDM;
434 TColStd_ListOfReal aList;
435 HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
436 for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
438 Handle(HYDROData_Profile) aProfile =
439 Handle(HYDROData_Profile)::DownCast( anIter.Value() );
441 TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
442 aBB.Add( aCmp, aProfileWire);
444 if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
446 aDM.Bind(aPar, aProfile);
448 //insertProfileInToOrder( aProfile );
451 if(aList.Extent() > 1) {
452 TColStd_Array1OfReal anArr(1, aList.Extent());
453 TColStd_ListIteratorOfListOfReal it(aList);
454 for (int j=1;it.More();it.Next(), j++)
455 anArr(j) = it.Value();
456 TCollection_CompareOfReal Compar;
457 SortTools_QuickSortOfReal::Sort( anArr, Compar);
458 for (int j = 1; j <= anArr.Length(); j++) {
459 const Standard_Real aKey = anArr(j);
460 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
461 insertProfileInToOrder( aProfile );
463 } else if(aList.Extent() == 1) {
464 const Standard_Real aKey = aList.Last();
465 const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
466 insertProfileInToOrder( aProfile );
470 TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
471 BRepTools::Write(aHydraulicWire, "Path.brep");
472 BRepTools::Write(aCmp, "Prof.brep");