From ff968cf4533d4496979379513131b0aed7778faf Mon Sep 17 00:00:00 2001 From: isn Date: Tue, 13 Dec 2016 19:09:31 +0300 Subject: [PATCH] refs #1094 --- src/HYDROData/HYDROData_Channel.h | 8 +- src/HYDROData/HYDROData_DTM.cxx | 247 +++++-------------- src/HYDROData/HYDROData_DTM.h | 17 +- src/HYDROData/HYDROData_PolylineOperator.cxx | 25 +- src/HYDROData/HYDROData_Stream.cxx | 33 +-- src/HYDROData/HYDROData_Stream.h | 8 +- src/HYDROGUI/HYDROGUI_StreamOp.cxx | 18 +- src/HYDROGUI/resources/HYDROGUI_msg_en.ts | 4 +- src/HYDRO_tests/reference_data/Channel.png | Bin 8311 -> 8969 bytes 9 files changed, 127 insertions(+), 233 deletions(-) diff --git a/src/HYDROData/HYDROData_Channel.h b/src/HYDROData/HYDROData_Channel.h index 3e069097..f55bfc1d 100644 --- a/src/HYDROData/HYDROData_Channel.h +++ b/src/HYDROData/HYDROData_Channel.h @@ -43,10 +43,10 @@ public: { TopoDS_Shape myPrs3D; TopoDS_Face myPrs2D; - TopoDS_Wire myLeftBank; - TopoDS_Wire myRightBank; - TopoDS_Wire myInlet; - TopoDS_Wire myOutlet; + TopoDS_Shape myLeftBank; + TopoDS_Shape myRightBank; + TopoDS_Shape myInlet; + TopoDS_Shape myOutlet; }; protected: diff --git a/src/HYDROData/HYDROData_DTM.cxx b/src/HYDROData/HYDROData_DTM.cxx index d3a3c441..9393ac04 100644 --- a/src/HYDROData/HYDROData_DTM.cxx +++ b/src/HYDROData/HYDROData_DTM.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -51,10 +52,11 @@ #include #include #include - +#include #include #include #include +#include IMPLEMENT_STANDARD_HANDLE( HYDROData_DTM, HYDROData_Bathymetry ) IMPLEMENT_STANDARD_RTTIEXT( HYDROData_DTM, HYDROData_Bathymetry ) @@ -161,19 +163,9 @@ void HYDROData_DTM::SetSpatialStep( double theSpatialStep ) Changed( Geom_3d ); } -void HYDROData_DTM::PointToWire(const AltitudePoints& pnts, TopoDS_Wire& W ) +void HYDROData_DTM::PointsToWire(const AltitudePoints& pnts, TopoDS_Wire& W ) { - /*BRepLib_MakeWire WM; - if (pnts.empty()) - return; - for (int i = 0; i < pnts.size() - 1; i++) - { - gp_Pnt p1(pnts[i].X, pnts[i].Y, pnts[i].Z); - gp_Pnt p2(pnts[i+1].X, pnts[i+1].Y, pnts[i+1].Z); - WM.Add(BRepLib_MakeEdge(p1, p2).Edge()); - } - if (WM.IsDone())*/ - + BRepBuilderAPI_MakePolygon PM; for (int i = 0; i < pnts.size(); i++) PM.Add(gp_Pnt(pnts[i].X, pnts[i].Y, pnts[i].Z)); @@ -181,29 +173,48 @@ void HYDROData_DTM::PointToWire(const AltitudePoints& pnts, TopoDS_Wire& W ) W = PM.Wire(); } +void HYDROData_DTM::PointsToEdge(const AltitudePoints& pnts, TopoDS_Edge& E ) +{ + Handle(TColgp_HArray1OfPnt) gpPoints = new TColgp_HArray1OfPnt(1, (int)pnts.size()); + + for (int i = 0; i < pnts.size(); i++) + gpPoints->SetValue(i+1, gp_Pnt(pnts[i].X, pnts[i].Y, pnts[i].Z)); + + GeomAPI_Interpolate anInterpolator(gpPoints, Standard_False,1.0e-6); + anInterpolator.Perform() ; + if (anInterpolator.IsDone()) + { + Handle(Geom_Curve) C = anInterpolator.Curve(); + E = BRepBuilderAPI_MakeEdge(C).Edge(); + } +} + TopTools_IndexedMapOfOrientedShape HYDROData_DTM::Create3DShape(const AltitudePoints& left, const AltitudePoints& right, const std::vector& main_profiles) { TopTools_IndexedMapOfOrientedShape ll; - TopoDS_Wire LWire, RWire; - PointToWire(left, LWire); - PointToWire(right, RWire); - if (!LWire.IsNull()) - ll.Add(LWire.Oriented(TopAbs_FORWARD)); + //TopoDS_Wire LWire, RWire; + //PointsToWire(left, LWire); + //PointsToWire(right, RWire); + TopoDS_Edge LEdge, REdge; + PointsToEdge(left, LEdge); + PointsToEdge(right, REdge); + if (!LEdge.IsNull()) + ll.Add(LEdge.Oriented(TopAbs_FORWARD)); for (int k = 0; k < main_profiles.size(); k++) { TopoDS_Wire W; - PointToWire(main_profiles[k], W); + PointsToWire(main_profiles[k], W); TopAbs_Orientation Ori = TopAbs_INTERNAL; if (k == 0 || k == main_profiles.size() - 1) Ori = TopAbs_FORWARD; ll.Add(W.Oriented(Ori)); } - if (!RWire.IsNull()) - ll.Add(RWire.Oriented(TopAbs_FORWARD)); + if (!REdge.IsNull()) + ll.Add(REdge.Oriented(TopAbs_FORWARD)); //yes, add subshapes in this order (left + profiles + right) //otherwise the projected wire will be non-manifold @@ -228,7 +239,7 @@ void HYDROData_DTM::Update() bool WireIntersections; //__TODO CreateProfilesFromDTM( objs, ddz, step, points, Out3dPres, Out2dPres, OutLeftB, OutRightB, OutInlet, OutOutlet, true, true, InvInd, -1, WireIntersections ); SetAltitudePoints( points ); - + SetShape( DataTag_LeftBankShape, OutLeftB); SetShape( DataTag_RightBankShape, OutRightB); SetShape( DataTag_InletShape, OutInlet); @@ -298,179 +309,43 @@ void HYDROData_DTM::CreateProfilesFromDTM (const HYDROData_SequenceOfObjects& In Out3dPres, Out2dPres, OutLeftB, OutRightB, OutInlet, OutOutlet, Create3dPres, Create2dPres, InvInd, WireIntersections ); } -void HYDROData_DTM::ProjWireOnPlane(const TopoDS_Shape& inpWire, const Handle_Geom_Plane& RefPlane, - TopTools_DataMapOfShapeListOfShape* E2PE) +bool HYDROData_DTM::GetPlanarFaceFromBanks( const TopoDS_Edge& LB, const TopoDS_Edge& RB, TopoDS_Face& outF, + TopTools_SequenceOfShape* Boundr) { BRep_Builder BB; - - //project shape (edges) on planar face TopoDS_Face F; - BB.MakeFace(F, RefPlane, Precision::Confusion()); + Handle_Geom_Plane refpl = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1)); + BB.MakeFace(F, refpl, Precision::Confusion()); BRepAlgo_NormalProjection nproj(F); - nproj.Add(inpWire); + nproj.Add(LB); + nproj.Add(RB); nproj.SetDefaultParams(); nproj.Build(); if(!nproj.IsDone()) - return; - - TopoDS_Shape projRes = nproj.Projection(); - - // unite all vertexes/edges from projected result - BOPAlgo_Builder anAlgo; - TopExp_Explorer exp(projRes, TopAbs_EDGE); - for (;exp.More(); exp.Next()) - { - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - if (E.Orientation() != TopAbs_INTERNAL) - anAlgo.AddArgument(E); - } - anAlgo.Perform(); - int stat = anAlgo.ErrorStatus(); - TopoDS_Shape projResConn = anAlgo.Shape(); - - // make wire => vertexes and edges should be untouched after this operation! - exp.Init(projResConn, TopAbs_EDGE); - //TopTools_ListOfShape llE; - //TopoDS_Wire RW; - //BRepLib_MakeWire WM; - - //for (;exp.More();exp.Next()) - // llE.Append(exp.Current()); - // - //WM.Add(llE); - //outWire = WM.Wire(); - - //outWire.Orientation(inpWire.Orientation()); //take from the original wire - - //history mode: edge to projected edges - if (E2PE) - { - TopExp_Explorer ex(inpWire, TopAbs_EDGE); - for (;ex.More();ex.Next()) - { - const TopoDS_Edge& CE = TopoDS::Edge(ex.Current()); - TopTools_ListOfShape NEL; - const TopTools_ListOfShape& LS = nproj.Generated(CE); - TopTools_ListIteratorOfListOfShape it(LS); - for (;it.More();it.Next()) - { - const TopoDS_Shape& PCE = it.Value(); - TopTools_ListOfShape PLS = anAlgo.Modified(PCE); - if (PLS.IsEmpty()) - PLS.Append(PCE); - TopTools_ListIteratorOfListOfShape itp(PLS); - for (;itp.More();itp.Next()) - NEL.Append(itp.Value()); - } - - E2PE->Bind(CE, NEL); - } - } -} -#include -bool HYDROData_DTM::Get2dFaceFrom3dPres(const TopoDS_Compound& cmp, TopoDS_Face& outF, - TopTools_SequenceOfShape* Boundr, std::set ind ) -{ - //ind : set of indices (starts with 0). index == number of boundary (inlet, outlet, etc..) - //in compound cmp. - //if Boundr is not null => this method will return sequence of boundary wires (inlet, outlet...) - - Handle_Geom_Plane refpl = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1)); - TopTools_DataMapOfShapeListOfShape E2PE; - ProjWireOnPlane(cmp, refpl, &E2PE); - TopTools_ListOfShape ELL; + return false; - TopoDS_Iterator it(cmp); - int i = 0; - for (;it.More(); it.Next()) + //TopoDS_Shape projBanks = nproj.Projection(); + TopoDS_Vertex VFI, VLI, VFO, VLO; + TopoDS_Edge prLB = TopoDS::Edge(nproj.Generated(LB).First()); + TopoDS_Edge prRB = TopoDS::Edge(nproj.Generated(RB).First()); + TopExp::Vertices(prLB, VFI, VFO, 1); + TopExp::Vertices(prRB, VLI, VLO, 1); + TopoDS_Edge prIL = BRepLib_MakeEdge(VFI, VLI).Edge(); + TopoDS_Edge prOL = BRepLib_MakeEdge(VFO, VLO).Edge(); + TopoDS_Wire prW = BRepLib_MakeWire(prLB, prIL, prOL, prRB).Wire(); + outF = BRepBuilderAPI_MakeFace(refpl->Pln(), prW, 1).Face(); + + if (Boundr) { - const TopoDS_Wire& W = TopoDS::Wire(it.Value()); - if (W.Orientation() != TopAbs_INTERNAL) - { - TopoDS_Wire PW; - TopExp_Explorer ex(W, TopAbs_EDGE); - TopTools_ListOfShape LEpW; - TopTools_ListOfShape LEpWDummy; - for (;ex.More();ex.Next()) - { - const TopoDS_Edge& CE = TopoDS::Edge(ex.Current()); - TopTools_ListOfShape LS = E2PE.Find(CE); - LEpW.Append(LS); - } - - if (ind.count(i) != 0) - { - BRepLib_MakeWire WM; - WM.Add(LEpW); - const TopoDS_Wire& WMW = WM.Wire(); - //assume that wire is a straight line, - //take first and last vertex and make simple edge (RE) - TopoDS_Vertex VF, VL; - TopExp::Vertices(WMW, VF, VL); - TopoDS_Edge RE = BRepLib_MakeEdge(VF, VL).Edge(); - if (RE.IsNull()) - { - LEpWDummy = LEpW; //LEpW will be nullified after appending to ELL - ELL.Append(LEpW); - } - else - { - LEpWDummy.Append(RE); - ELL.Append(RE); - } - //TODO: in the new version of OCCT, USD can process separate wires - //ShapeUpgrade_UnifySameDomain USD(WMW, 1U, 0U, 1U); //concat bsplines - //USD.Build(); - //const TopoDS_Shape& RSU = USD.Shape(); - //TopExp_Explorer exp(RSU, TopAbs_EDGE); - //TopTools_ListOfShape DummyL; - //for (;it.More();it.Next()) - // DummyL.Append(it.Value()); - //if (DummyL.Extent() == 1) - // ELL.Append(DummyL.First()); //if one edge => accept this result - //else - // ELL.Append(LEpW); //else put 'as is' - } - else - { - LEpWDummy = LEpW; - ELL.Append(LEpW); - } - - if (Boundr) - { - //make inlet, outlet, left/tight banks [wires] - //shouldn't change topology of the edges - BRepLib_MakeWire IWM; - IWM.Add(LEpWDummy); - Boundr->Append(IWM.Wire()); - } - } - i++; + Boundr->Append(prLB); + Boundr->Append(prIL); + Boundr->Append(prOL); + Boundr->Append(prRB); } - //make primary wire - BRepLib_MakeWire WME; - WME.Add(ELL); - - const TopoDS_Wire& resW = WME.Wire(); - BRepBuilderAPI_MakeFace mf(refpl, resW, true); //check inside is true by def - outF = mf.Face(); - - ShapeAnalysis_Wire WA(resW, outF, Precision::Confusion()); - bool res = WA.CheckSelfIntersection(); //TODO check that this return false if OK - return res; - - ///!!! 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); - }*/ + ShapeAnalysis_Wire WA(prW, outF, Precision::Confusion()); + bool res = WA.CheckSelfIntersection(); + return !res; } void HYDROData_DTM::CreateProfiles(const std::vector& theProfiles, @@ -489,7 +364,7 @@ void HYDROData_DTM::CreateProfiles(const std::vector& bool Create3dPres, bool Create2dPres, std::set& InvInd, - bool& WireIntersections) + bool& ProjStat) { if (theProfiles.empty()) return; @@ -521,7 +396,7 @@ void HYDROData_DTM::CreateProfiles(const std::vector& if (Create2dPres) { TopoDS_Face outF; - WireIntersections = Get2dFaceFrom3dPres(cmp, outF); //__TODO + ProjStat = GetPlanarFaceFromBanks(TopoDS::Edge(OutLeftB), TopoDS::Edge(OutRightB), outF, NULL); Out2dPres = outF; }; } diff --git a/src/HYDROData/HYDROData_DTM.h b/src/HYDROData/HYDROData_DTM.h index 0ac618d4..a283f9ce 100644 --- a/src/HYDROData/HYDROData_DTM.h +++ b/src/HYDROData/HYDROData_DTM.h @@ -154,10 +154,15 @@ protected: std::vector& theMainProfiles, std::set& invalInd ); - static void PointToWire(const AltitudePoints& pnts, TopoDS_Wire& W ); + static void PointsToWire(const AltitudePoints& pnts, TopoDS_Wire& W ); - static void ProjWireOnPlane(const TopoDS_Shape& inpWire, const Handle_Geom_Plane& RefPlane, - TopTools_DataMapOfShapeListOfShape* E2PE); + static void PointsToEdge(const AltitudePoints& pnts, TopoDS_Edge& E ); + + //static void ProjWireOnPlane(const TopoDS_Shape& inpWire, const Handle_Geom_Plane& RefPlane, + //TopTools_DataMapOfShapeListOfShape* E2PE); + + static bool GetPlanarFaceFromBanks(const TopoDS_Edge& LB, const TopoDS_Edge& RB, TopoDS_Face& outF, + TopTools_SequenceOfShape* Boundr); static TopTools_IndexedMapOfOrientedShape Create3DShape(const AltitudePoints& left, const AltitudePoints& right, @@ -179,10 +184,10 @@ protected: bool Create3dPres, bool Create2dPres, std::set& InvInd, - bool& WireIntersections); + bool& ProjStat); - static bool Get2dFaceFrom3dPres(const TopoDS_Compound& cmp, TopoDS_Face& outF, - TopTools_SequenceOfShape* Boundr = NULL, std::set ind = std::set() ); + //static bool Get2dFaceFrom3dPres(const TopoDS_Compound& cmp, TopoDS_Face& outF, + //TopTools_SequenceOfShape* Boundr = NULL, std::set ind = std::set() ); static int EstimateNbPoints( const std::vector& theProfiles, double theDDZ, double theSpatialStep ); diff --git a/src/HYDROData/HYDROData_PolylineOperator.cxx b/src/HYDROData/HYDROData_PolylineOperator.cxx index 43fb6799..07387a6e 100644 --- a/src/HYDROData/HYDROData_PolylineOperator.cxx +++ b/src/HYDROData/HYDROData_PolylineOperator.cxx @@ -487,13 +487,22 @@ bool HYDROData_PolylineOperator::Extract( const Handle(HYDROData_Document)& theD LSE.Append(E); } - BRepLib_MakeWire WM; - WM.Add(LSE); - TopoDS_Shape aShapeW; - if (WM.IsDone()) - aShapeW = WM.Wire(); - else - continue; + + TopoDS_Shape aShapeOut; + if (LSE.Extent() == 1) + { + aShapeOut = LSE.First(); + } + else if (LSE.Extent() > 1) + { + BRepLib_MakeWire WM; + WM.Add(LSE); + if (WM.IsDone()) + aShapeOut = WM.Wire(); + else + continue; + } + else continue; Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( theDocument->CreateObject( KIND_POLYLINEXY ) ); @@ -501,7 +510,7 @@ bool HYDROData_PolylineOperator::Extract( const Handle(HYDROData_Document)& theD if( aPolyline.IsNull() ) return false; - aPolyline->SetShape( aShapeW ); + aPolyline->SetShape( aShapeOut ); int anIndex = 0; QString aName = K; diff --git a/src/HYDROData/HYDROData_Stream.cxx b/src/HYDROData/HYDROData_Stream.cxx index 9ffb8596..2f85c424 100644 --- a/src/HYDROData/HYDROData_Stream.cxx +++ b/src/HYDROData/HYDROData_Stream.cxx @@ -218,10 +218,10 @@ bool HYDROData_Stream::CreatePresentations( const Handle_HYDROData_DTM& theDTM, theDTM->GetPresentationShapes(Out3dPres, Out2dPres, OutLeftB, OutRightB, OutInlet, OutOutlet); - thePrs.myInlet = TopoDS::Wire(OutInlet); - thePrs.myOutlet = TopoDS::Wire(OutOutlet); - thePrs.myLeftBank = TopoDS::Wire(OutLeftB); - thePrs.myRightBank = TopoDS::Wire(OutRightB); + thePrs.myInlet = OutInlet; + thePrs.myOutlet = OutOutlet; + thePrs.myLeftBank = OutLeftB; + thePrs.myRightBank = OutRightB; thePrs.myPrs2D = Out2dPres; thePrs.myPrs3D = Out3dPres; /*std::vector profiles3d; @@ -1079,8 +1079,14 @@ void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) if (!ll.IsEmpty()) { - LB = TopoDS::Wire(ll(1)); - RB = TopoDS::Wire(ll(2)); + TopAbs_ShapeEnum ll1_sht = ll(1).ShapeType(); + TopAbs_ShapeEnum ll2_sht = ll(2).ShapeType(); + if ((ll1_sht == TopAbs_WIRE || ll1_sht == TopAbs_EDGE) && + (ll2_sht == TopAbs_WIRE || ll2_sht == TopAbs_EDGE)) + { + LB = ll(1); + RB = ll(2); + } } IL = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Lower())); //TODO check that @@ -1096,12 +1102,11 @@ void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) BB.Add(newCmp, RB); thePrs.myPrs3D = newCmp; - std::set ind; - ind.insert(1); //inlet ind - ind.insert(2); //outlet ind TopTools_SequenceOfShape LS; - HYDROData_DTM::Get2dFaceFrom3dPres( newCmp, TopoDS::Face(thePrs.myPrs2D), &LS, ind ); + //HYDROData_DTM::Get2dFaceFrom3dPres( newCmp, TopoDS::Face(thePrs.myPrs2D), &LS, ind ); + + HYDROData_DTM::GetPlanarFaceFromBanks(TopoDS::Edge(LB), TopoDS::Edge(RB), TopoDS::Face(thePrs.myPrs2D), &LS); #ifndef NDEBUG TopTools_IndexedMapOfShape EE; @@ -1119,9 +1124,9 @@ void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) assert(noncontNb == 0); #endif - thePrs.myLeftBank = TopoDS::Wire(LS(1)); - thePrs.myInlet = TopoDS::Wire(LS(2)); - thePrs.myOutlet = TopoDS::Wire(LS(3)); - thePrs.myRightBank = TopoDS::Wire(LS(4)); + thePrs.myLeftBank = LS(1); + thePrs.myInlet = LS(2); + thePrs.myOutlet = LS(3); + thePrs.myRightBank = LS(4); } \ No newline at end of file diff --git a/src/HYDROData/HYDROData_Stream.h b/src/HYDROData/HYDROData_Stream.h index 0eb6cde9..77d9bb5f 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_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 + TopoDS_Shape myLeftBank; // 3d curve of the left bank + TopoDS_Shape myRightBank; // 3d curve of the right bank + TopoDS_Shape myInlet; // first (inlet) 2d profile + TopoDS_Shape myOutlet; // last (inlet) 2d profile }; protected: diff --git a/src/HYDROGUI/HYDROGUI_StreamOp.cxx b/src/HYDROGUI/HYDROGUI_StreamOp.cxx index 2a178d83..ecac0f9f 100755 --- a/src/HYDROGUI/HYDROGUI_StreamOp.cxx +++ b/src/HYDROGUI/HYDROGUI_StreamOp.cxx @@ -420,24 +420,24 @@ void HYDROGUI_StreamOp::createPreview() HYDROData_Bathymetry::AltitudePoints points; - bool WireIntersections = false; + bool ProjStat = true; HYDROData_DTM::CreateProfilesFromDTM( aRefProfiles, ddz, ss, points, Out3dPres, Out2dPres, OutLeftB, OutRightB, - OutInlet, OutOutlet, true, true, InvInd, MAX_POINTS_IN_PREVIEW, WireIntersections ); + OutInlet, OutOutlet, true, true, InvInd, MAX_POINTS_IN_PREVIEW, ProjStat ); aPanel->clearAllBackgroundColorsForProfileList(); for (std::set::const_iterator it = InvInd.begin(); it != InvInd.end(); it++) aPanel->setBackgroundColorForProfileList(*it, QColor(Qt::yellow)); - aPrsDef.myInlet = TopoDS::Wire(OutInlet); - aPrsDef.myOutlet = TopoDS::Wire(OutOutlet); - aPrsDef.myLeftBank = TopoDS::Wire(OutLeftB); - aPrsDef.myRightBank = TopoDS::Wire(OutRightB); - if (!WireIntersections) + aPrsDef.myInlet = OutInlet; + aPrsDef.myOutlet = OutOutlet; + aPrsDef.myLeftBank = OutLeftB; + aPrsDef.myRightBank = OutRightB; + if (ProjStat) aPrsDef.myPrs2D = Out2dPres; aPrsDef.myPrs3D = Out3dPres; - if (WireIntersections) - aPanel->addWarning(tr("STREAM_SELF_INTERSECTIONS")); + if (!ProjStat) + aPanel->addWarning(tr("STREAM_PROJECTION_FAILED")); myPreviewPrs->setShape( aPrsDef.myPrs2D ); } diff --git a/src/HYDROGUI/resources/HYDROGUI_msg_en.ts b/src/HYDROGUI/resources/HYDROGUI_msg_en.ts index e19e9fad..3d162afb 100644 --- a/src/HYDROGUI/resources/HYDROGUI_msg_en.ts +++ b/src/HYDROGUI/resources/HYDROGUI_msg_en.ts @@ -255,8 +255,8 @@ All supported formats (*.brep *.iges *.igs *.step *.stp) Stream Warnings - STREAM_SELF_INTERSECTIONS - Warning: intersection(s) of banks/profiles are found + STREAM_PROJECTION_FAILED + Warning: Projection of banks/profiles are failed PREF_TAB_GENERAL diff --git a/src/HYDRO_tests/reference_data/Channel.png b/src/HYDRO_tests/reference_data/Channel.png index 028435ec70e4db8ebc7a7eb1ee14a9745b54b327..369807de4473c18df94d41e40a5d5042f0aa0228 100644 GIT binary patch literal 8969 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 P4xx2c8yUChE@%D+!x;rX literal 8311 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 H