From: isn Date: Fri, 7 Oct 2016 17:00:00 +0000 (+0300) Subject: create presentation for channel/stream from DTM X-Git-Tag: v1.6~58^2~3 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=fe0f96c33245347308c893b2f1870113c9df1b87;p=modules%2Fhydro.git create presentation for channel/stream from DTM --- diff --git a/src/HYDROData/HYDROData_Channel.cxx b/src/HYDROData/HYDROData_Channel.cxx index 79fd3d25..e8c8b3ee 100644 --- a/src/HYDROData/HYDROData_Channel.cxx +++ b/src/HYDROData/HYDROData_Channel.cxx @@ -280,23 +280,26 @@ bool HYDROData_Channel::CreatePresentations( const Handle(HYDROData_Polyline3D)& // Create presentation HYDROData_Stream::PrsDefinition aPrs; Handle(TopTools_HArray1OfShape) anArrOf2DProfiles; // we don't need 2D profiles for channel/digue presentation - bool aRes = false; - /*TODO: HYDROData_Stream::CreatePresentations( anArrayOfFPnt, anArrayOfLPnt, - anArrOfProfiles, anArrOf2DProfiles, aPrs );*/ - if ( aRes ) { - thePrs.myPrs3D = aPrs.myPrs3D; - thePrs.myPrs2D = TopoDS::Face( aPrs.myPrs2D ); - BRepBuilderAPI_MakeWire aMakeWire( aPrs.myLeftBank ) ; - thePrs.myLeftBank = aMakeWire.Wire(); - aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myRightBank ); - thePrs.myRightBank = aMakeWire.Wire(); - aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myInlet ); - thePrs.myInlet = aMakeWire.Wire(); - aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myOutlet ); - thePrs.myOutlet = aMakeWire.Wire(); - } - return aRes; + HYDROData_Stream::CreatePresentations( anArrayOfFPnt, anArrayOfLPnt, anArrOfProfiles, aPrs ); + thePrs.myInlet = aPrs.myInlet; + thePrs.myOutlet = aPrs.myOutlet; + thePrs.myLeftBank = aPrs.myLeftBank; + thePrs.myRightBank = aPrs.myRightBank; + thePrs.myPrs2D = TopoDS::Face(aPrs.myPrs2D); + thePrs.myPrs3D = aPrs.myPrs3D; + + //thePrs.myPrs2D = TopoDS::Face( aPrs.myPrs2D ); + //BRepBuilderAPI_MakeWire aMakeWire( aPrs.myLeftBank ) ; + //thePrs.myLeftBank = aMakeWire.Wire(); + //aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myRightBank ); + //thePrs.myRightBank = aMakeWire.Wire(); + //aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myInlet ); + //thePrs.myInlet = aMakeWire.Wire(); + //aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myOutlet ); + //thePrs.myOutlet = aMakeWire.Wire(); + + return true; } void HYDROData_Channel::Update() diff --git a/src/HYDROData/HYDROData_DTM.cxx b/src/HYDROData/HYDROData_DTM.cxx index f93b67f1..dba55733 100644 --- a/src/HYDROData/HYDROData_DTM.cxx +++ b/src/HYDROData/HYDROData_DTM.cxx @@ -31,6 +31,11 @@ #include #include + +#include +#include +#include + IMPLEMENT_STANDARD_HANDLE( HYDROData_DTM, HYDROData_Bathymetry ) IMPLEMENT_STANDARD_RTTIEXT( HYDROData_DTM, HYDROData_Bathymetry ) @@ -124,16 +129,7 @@ void HYDROData_DTM::SetSpatialStep( double theSpatialStep ) { SetDouble( DataTag_SpatialStep, theSpatialStep ); } -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include + void HYDROData_DTM::PointToWire(const AltitudePoints& pnts, TopoDS_Wire& W ) { BRepLib_MakeWire WM; @@ -146,23 +142,34 @@ void HYDROData_DTM::PointToWire(const AltitudePoints& pnts, TopoDS_Wire& W ) W = WM.Wire(); } -static void ProjWireOnPlane(const TopoDS_Wire& inpWire, const Handle_Geom_Plane& RefPlane, TopoDS_Wire& outWire) -{ - BRepTools_WireExplorer ex(TopoDS::Wire(inpWire.Oriented(TopAbs_FORWARD))); - BRepLib_MakeWire WM; - for (;ex.More();ex.Next()) +TopoDS_Compound HYDROData_DTM::Create3DShape(const AltitudePoints& left, + const AltitudePoints& right, + const std::vector& main_profiles) +{ + BRep_Builder BB; + TopoDS_Compound cmp; + BB.MakeCompound(cmp); + TopoDS_Wire LWire, RWire; + PointToWire(left, LWire); + PointToWire(right, RWire); + BB.Add(cmp, LWire.Oriented(TopAbs_FORWARD)); + + for (int k = 0; k < main_profiles.size(); k++) { - const TopoDS_Edge& CE = ex.Current(); - double f, l; - Handle(Geom_Curve) C3d = BRep_Tool::Curve(CE, f, l); - Handle(Geom_Curve) ProjectedCurve = GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d, f, l), RefPlane, RefPlane->Position().Direction(), Standard_True); - TopoDS_Edge ProjEdge = BRepLib_MakeEdge(ProjectedCurve); - WM.Add(ProjEdge); //auto sharing between edges if vertex is coincident + TopoDS_Wire W; + PointToWire(main_profiles[k], W); + TopAbs_Orientation Ori = TopAbs_INTERNAL; + if (k == 0 || k == main_profiles.size() - 1) + Ori = TopAbs_FORWARD; + BB.Add(cmp, W.Oriented(Ori)); } - outWire = WM.Wire(); - outWire.Orientation(inpWire.Orientation()); //take from the original wire -} + BB.Add(cmp, RWire.Oriented(TopAbs_FORWARD)); + //yes, add subshapes in this order (left + profiles + right) + //otherwise the projected wire will be non-manifold!!! + + return cmp; +} void HYDROData_DTM::Update() { @@ -190,64 +197,10 @@ void HYDROData_DTM::Update() if( ddz>EPS && step>EPS ) points = Interpolate( profiles, ddz, step, left, right, main_profiles ); + TopoDS_Compound cmp = Create3DShape( left, right, main_profiles); - BRep_Builder BB; - TopoDS_Compound cmp; - BB.MakeCompound(cmp); - TopoDS_Wire LWire, RWire; - PointToWire(left, LWire); - PointToWire(right, RWire); - BB.Add(cmp, LWire.Oriented(TopAbs_FORWARD)); - - for (int k = 0; k < main_profiles.size(); k++) - { - TopoDS_Wire W; - PointToWire(main_profiles[k], W); - TopAbs_Orientation Ori = TopAbs_INTERNAL; - if (k == 0 || k == main_profiles.size() - 1) - Ori = TopAbs_FORWARD; - BB.Add(cmp, W.Oriented(Ori)); - } - - BB.Add(cmp, RWire.Oriented(TopAbs_FORWARD)); - //in this order (left + profiles + right) - //otherwise the projected wire will be non-manifold!!! - - //cmp = 3d pres - - Handle_Geom_Plane refpl = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1)); - BRepLib_MakeWire WM; - TopoDS_Iterator it(cmp); - TopTools_IndexedMapOfShape IntW; - for (;it.More(); it.Next()) - { - const TopoDS_Wire& W = TopoDS::Wire(it.Value()); - if (W.Orientation() != TopAbs_INTERNAL) - WM.Add(W); - else - IntW.Add(W); - } - - TopoDS_Wire outW; - ProjWireOnPlane(WM.Wire(), refpl, outW); - BRepBuilderAPI_MakeFace mf(refpl, outW); //check inside is true by def - TopoDS_Face outF = mf.Face(); - - ///!!! the internal wires cant be added with 'internal' ori. - // it's possible to do with brep builder yet the result will not be correct! - // more proper way is to use BOP operation here. - for (int i = 1; i <= IntW.Extent(); i++) - { - TopoDS_Wire outIW; - const TopoDS_Wire& W = TopoDS::Wire(IntW(i)); - ProjWireOnPlane(W, refpl, outIW); - BB.Add(outF, outIW); - } - - //outF == 2d pres + SetShape(DataTag_DTM_Shape, cmp); //more safe way is to add each wire (left/right banks etc. with separate tag) SetAltitudePoints( points ); - //SetTopShape(); //2d - //this->SetShape(cmp); //3d } diff --git a/src/HYDROData/HYDROData_DTM.h b/src/HYDROData/HYDROData_DTM.h index 326e3571..6892c66b 100644 --- a/src/HYDROData/HYDROData_DTM.h +++ b/src/HYDROData/HYDROData_DTM.h @@ -30,6 +30,7 @@ class gp_Pnt; class gp_Vec2d; class TopoDS_Edge; class TopoDS_Wire; +class TopoDS_Compound; DEFINE_STANDARD_HANDLE( HYDROData_DTM, HYDROData_Bathymetry ) @@ -48,6 +49,7 @@ protected: DataTag_Profiles, DataTag_DDZ, DataTag_SpatialStep, + DataTag_DTM_Shape, }; public: @@ -89,6 +91,7 @@ public: }; protected: + friend class HYDROData_Stream; friend class HYDROData_Iterator; friend class test_HYDROData_DTM; @@ -137,6 +140,10 @@ protected: std::vector& theMainProfiles ); static void PointToWire(const AltitudePoints& pnts, TopoDS_Wire& W ); + + static TopoDS_Compound Create3DShape(const AltitudePoints& left, + const AltitudePoints& right, + const std::vector& main_profiles); }; #endif diff --git a/src/HYDROData/HYDROData_Stream.cxx b/src/HYDROData/HYDROData_Stream.cxx index 07b1755e..06a85fef 100644 --- a/src/HYDROData/HYDROData_Stream.cxx +++ b/src/HYDROData/HYDROData_Stream.cxx @@ -28,6 +28,7 @@ #include "HYDROData_IProfilesInterpolator.h" #include "HYDROData_Tool.h" #include "HYDROData_DTM.h" +#include #include @@ -63,6 +64,16 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -199,7 +210,7 @@ bool HYDROData_Stream::CreatePresentations( const Handle_HYDROData_DTM& theDTM, if( profiles.Length() < 2 ) return false; - std::vector profiles3d; + /*std::vector profiles3d; profiles3d.reserve(profiles.Length()); // Pre-processing @@ -215,11 +226,10 @@ bool HYDROData_Stream::CreatePresentations( const Handle_HYDROData_DTM& theDTM, const TopoDS_Shape& aProfileShape = aProfile->GetShape3D(); //TopExp_Explorer exp(aProfileShape, TopAbs_EDGE); profiles3d.push_back( TopoDS::Wire(aProfileShape) ); - } + }*/ - TopoDS_Edge aLeftBank, aRightBank; - //TODO: theDTM->CreateBankShapes( aLeftBank, aRightBank ); - return CreatePresentations( aLeftBank, aRightBank, profiles3d, thePrs ); + CreatePresentationsIntern( theDTM, thePrs ); + return true; } void HYDROData_Stream::UpdatePrs( const Handle_HYDROData_DTM& theDTM ) @@ -1035,64 +1045,85 @@ void HYDROData_Stream::CopyTo( const Handle(HYDROData_Entity)& theDestination, } } - -bool HYDROData_Stream::CreatePresentations( const TopoDS_Edge& theLeftBank, - const TopoDS_Edge& theRightBank, - const std::vector& theProfiles3d, - PrsDefinition& thePrs ) +static void ProjWireOnPlane(const TopoDS_Wire& inpWire, const Handle_Geom_Plane& RefPlane, TopoDS_Wire& outWire) { - //thePrs.myLeftBank = theLeftBank; - //thePrs.myRightBank = theRightBank; - // - //BRep_Builder aBB; - //TopoDS_Compound aCmp; - //aBB.MakeCompound(aCmp); - //for (size_t i = 0; i < theProfiles3d.size(); i++ ) - // aBB.Add(aCmp, theProfiles3d[i]); - // - //aBB.Add(aCmp, theLeftBank); - //aBB.Add(aCmp, theRightBank); - // - //thePrs.myPrs3D = aCmp; //3d pres - // - /*Handle_Geom_Plane RefPlane = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1)); - TopoDS_Vertex V1, V2; - TopoDS_Wire W; - ProjEdgeOnPlane(theProfiles3d[0], RefPlane, W, V1, V2);*/ - - /* Handle_Geom_Plane RefPlane = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1)); - std::vector internProf; - internProf.reserve(theProfiles3d.size() - 2); - - //project internal edges/profiles - for (size_t i = 1; i < theProfiles3d.size() - 1; i++ ) + BRepTools_WireExplorer ex(TopoDS::Wire(inpWire.Oriented(TopAbs_FORWARD))); + BRepLib_MakeWire WM; + for (;ex.More();ex.Next()) { - TopoDS_Edge ProjEdge; - ProjEdgeOnPlane(theProfiles3d[i], RefPlane, ProjEdge, TopoDS_Vertex(), TopoDS_Vertex()); - internProf.push_back (TopoDS::Edge(ProjEdge.Oriented(TopAbs_INTERNAL))); + const TopoDS_Edge& CE = ex.Current(); + double f, l; + Handle(Geom_Curve) C3d = BRep_Tool::Curve(CE, f, l); + Handle(Geom_Curve) ProjectedCurve = GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d, f, l), RefPlane, RefPlane->Position().Direction(), Standard_True); + TopoDS_Edge ProjEdge = BRepLib_MakeEdge(ProjectedCurve); + WM.Add(ProjEdge); //auto sharing between edges if vertex is coincident } - - TopoDS_Edge ProjEdgeIn, ProjEdgeOut; - TopoDS_Vertex V1In, V2In, V1Out, V2Out; + outWire = WM.Wire(); + outWire.Orientation(inpWire.Orientation()); //take from the original wire +} - ProjEdgeOnPlane(theProfiles3d.front(), RefPlane, ProjEdgeIn, TopoDS_Vertex(), TopoDS_Vertex()); - TopExp::Vertices(ProjEdgeIn, V1In, V2In); - ProjEdgeOnPlane(theProfiles3d.back(), RefPlane, ProjEdgeOut, TopoDS_Vertex(), TopoDS_Vertex()); - TopExp::Vertices(ProjEdgeOut, V1Out, V2Out); +static void Get2dFaceFrom3dPres(const TopoDS_Compound& cmp, TopoDS_Face& outF ) +{ + Handle_Geom_Plane refpl = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1)); + BRepLib_MakeWire WM; + TopoDS_Iterator it(cmp); + //TopTools_IndexedMapOfShape IntW; + for (;it.More(); it.Next()) + { + const TopoDS_Wire& W = TopoDS::Wire(it.Value()); + if (W.Orientation() != TopAbs_INTERNAL) + { + //use list of edges to protect againts non-manifold cases. + //auto sharing between edges will be added automatically + TopTools_IndexedMapOfShape ME; + TopTools_ListOfShape LE; + TopExp::MapShapes(W, TopAbs_EDGE, ME); + for (int i = 1; i <= ME.Extent(); i++) + LE.Append(ME(i)); + WM.Add(LE); + } + //else + // IntW.Add(W); + } - TopoDS_Edge ProjEdgeLeftB, ProjEdgeRightB; - ProjEdgeOnPlane(theLeftBank, RefPlane, ProjEdgeLeftB, V1In, V1Out); - ProjEdgeOnPlane(theRightBank, RefPlane, ProjEdgeRightB, V2In, V2Out); + TopoDS_Wire outW; + ProjWireOnPlane(WM.Wire(), refpl, outW); + BRepBuilderAPI_MakeFace mf(refpl, outW); //check inside is true by def + outF = mf.Face(); - BRepLib_MakeWire WM(ProjEdgeIn, ProjEdgeOut, ProjEdgeLeftB, ProjEdgeRightB); - for (size_t i = 0; i < internProf.size(); i++ ) - WM.Add(internProf[i]); + ///!!! the internal wires cant be added with 'internal' ori. + // it's possible to do with brep builder yet the result will not be correct! + // more proper way is to use BOP operation here. + /*for (int i = 1; i <= IntW.Extent(); i++) + { + TopoDS_Wire outIW; + const TopoDS_Wire& W = TopoDS::Wire(IntW(i)); + ProjWireOnPlane(W, refpl, outIW); + BB.Add(outF, outIW); + }*/ +} - TopoDS_Face outF = BRepLib_MakeFace(RefPlane, WM.Wire()).Face(); - thePrs.myPrs2D = outF;*/ +void HYDROData_Stream::CreatePresentationsIntern( const Handle_HYDROData_DTM& theDTM, + PrsDefinition& thePrs ) +{ + TopoDS_Compound cmp = TopoDS::Compound(theDTM->GetShape(HYDROData_DTM::DataTag_DTM_Shape)); + thePrs.myPrs3D = cmp; + NCollection_Sequence WW; + TopoDS_Iterator it(cmp); + for (;it.More(); it.Next()) + WW.Append(TopoDS::Wire(it.Value())); + + //same order as in HYDROData_DTM::Update() + thePrs.myLeftBank = WW.First(); + thePrs.myRightBank = WW.Last(); + thePrs.myInlet = WW(1); //TODO check this!! + thePrs.myOutlet = WW(WW.Length() - 1); + + TopoDS_Face outF; + Get2dFaceFrom3dPres(cmp, outF); + thePrs.myPrs2D = outF; - return true; /*if ( theArrayOfFPnt.IsNull() || theArrayOfLPnt.IsNull() || theArrOfProfiles.IsNull() ) { return false; } @@ -1237,4 +1268,51 @@ bool HYDROData_Stream::CreatePresentations( const TopoDS_Edge& theLeftB #endif return true;*/ +} + +void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) theArrayOfFPnt, + const Handle(TColgp_HArray1OfPnt) theArrayOfLPnt, + const Handle(TopTools_HArray1OfShape) theArrOfProfiles, + PrsDefinition& thePrs ) +{ + + HYDROData_Bathymetry::AltitudePoints left; + for (int i = theArrayOfLPnt->Lower(); i <= theArrayOfLPnt->Upper(); i++) + { + left.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfLPnt->Value(i).X(), + theArrayOfLPnt->Value(i).Y(), + theArrayOfLPnt->Value(i).Z())); + } + + HYDROData_Bathymetry::AltitudePoints right; + for (int i = theArrayOfFPnt->Lower(); i <= theArrayOfFPnt->Upper(); i++) + { + right.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfFPnt->Value(i).X(), + theArrayOfFPnt->Value(i).Y(), + theArrayOfFPnt->Value(i).Z())); + } + + std::vector dummy; + TopoDS_Compound cmp = HYDROData_DTM::Create3DShape(left, right, dummy); + TopoDS_Iterator it(cmp); + thePrs.myLeftBank = TopoDS::Wire(it.Value()); + it.Next(); + thePrs.myRightBank = TopoDS::Wire(it.Value()); + + thePrs.myInlet = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Lower())); //TODO check that + thePrs.myOutlet = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Upper())); + + //make new compound so it's shapes will be in known order to build correct projection + BRep_Builder BB; + TopoDS_Compound newCmp; + BB.MakeCompound(newCmp); + BB.Add(newCmp, thePrs.myLeftBank); + BB.Add(newCmp, thePrs.myInlet); + BB.Add(newCmp, thePrs.myOutlet); + BB.Add(newCmp, thePrs.myRightBank); + + thePrs.myPrs3D = newCmp; + + Get2dFaceFrom3dPres( newCmp, TopoDS::Face(thePrs.myPrs2D) ); + } \ No newline at end of file diff --git a/src/HYDROData/HYDROData_Stream.h b/src/HYDROData/HYDROData_Stream.h index 7abc7c29..e17e3bd4 100644 --- a/src/HYDROData/HYDROData_Stream.h +++ b/src/HYDROData/HYDROData_Stream.h @@ -52,10 +52,10 @@ public: { TopoDS_Shape myPrs3D; TopoDS_Shape myPrs2D; - TopoDS_Edge myLeftBank; // 3d curve of the left bank - TopoDS_Edge myRightBank; // 3d curve of the right bank - TopoDS_Edge myInlet; // first (inlet) 2d profile - TopoDS_Edge myOutlet; // last (inlet) 2d profile + TopoDS_Wire myLeftBank; // 3d curve of the left bank + TopoDS_Wire myRightBank; // 3d curve of the right bank + TopoDS_Wire myInlet; // first (inlet) 2d profile + TopoDS_Wire myOutlet; // last (inlet) 2d profile }; protected: @@ -87,10 +87,13 @@ public: * Creates the presentations(2D and 3D) by given first points, last points and profiles. * If 2D profiles is null - they will not used in the presentation. */ - HYDRODATA_EXPORT static bool CreatePresentations( const TopoDS_Edge& theLeftBank, - const TopoDS_Edge& theRightBank, - const std::vector& theProfiles3d, - PrsDefinition& thePrs ); + HYDRODATA_EXPORT static void CreatePresentationsIntern( const Handle_HYDROData_DTM& theDTM, + PrsDefinition& thePrs ); + + HYDRODATA_EXPORT static void CreatePresentations( const Handle(TColgp_HArray1OfPnt) theArrayOfFPnt, + const Handle(TColgp_HArray1OfPnt) theArrayOfLPnt, + const Handle(TopTools_HArray1OfShape) theArrOfProfiles, + PrsDefinition& thePrs ); public: diff --git a/src/HYDRO_tests/test_HYDROData_Stream.cxx b/src/HYDRO_tests/test_HYDROData_Stream.cxx index 652b890e..3341e77a 100644 --- a/src/HYDRO_tests/test_HYDROData_Stream.cxx +++ b/src/HYDRO_tests/test_HYDROData_Stream.cxx @@ -259,12 +259,11 @@ void test_HYDROData_Stream::test_presentation() TopoDS_Shape aPrs3d = aStream->GetShape3D(); TopoDS_Shape aPrs2d = aStream->GetTopShape(); - //TestViewer::show( aPrs2d, 0, true, "stream_dtm_2d" ); - //CPPUNIT_ASSERT_IMAGES; + TestViewer::show( aPrs2d, 0, true, "stream_dtm_2d" ); + CPPUNIT_ASSERT_IMAGES; TestViewer::eraseAll( true ); TestViewer::show( aPrs3d, 0, true, "stream_dtm_3d" ); - QTest::qWait( 125000 ); CPPUNIT_ASSERT_IMAGES aDoc->Close();