From 3e0d42735e297e6c46a896443ba877a45678c194 Mon Sep 17 00:00:00 2001 From: szy Date: Wed, 4 Dec 2013 15:00:34 +0000 Subject: [PATCH] 4.12.2013. HasIntersection () method implementation. API is modified. --- src/HYDROData/HYDROData_Stream.cxx | 121 +++++++++++++++++++++++++++-- src/HYDROData/HYDROData_Stream.h | 7 +- src/HYDROGUI/HYDROGUI_StreamOp.cxx | 20 ++++- 3 files changed, 136 insertions(+), 12 deletions(-) diff --git a/src/HYDROData/HYDROData_Stream.cxx b/src/HYDROData/HYDROData_Stream.cxx index 2e951d99..061fa935 100644 --- a/src/HYDROData/HYDROData_Stream.cxx +++ b/src/HYDROData/HYDROData_Stream.cxx @@ -14,7 +14,20 @@ #include #include #include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #define PYTHON_STREAM_ID "KIND_STREAM" @@ -194,19 +207,97 @@ void HYDROData_Stream::RemoveHydraulicAxis() SetToUpdate( true ); } -bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile ) const +bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile, const TopoDS_Face& thePlane, + Standard_Real& outPar ) const { Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); if ( theProfile.IsNull() || aHydAxis.IsNull() ) return false; - TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() ); + TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() ); //guide line TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() ); if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() ) return false; // TODO - + return true; // temporary + BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction()); + if(!aProjector.IsDone()) + return false; + TopoDS_Shape aPrjProfile = aProjector.Shape(); + if(aPrjProfile.IsNull()) + return false; + TopoDS_Vertex aV1, aV2; + if(aPrjProfile.ShapeType() == TopAbs_EDGE) + TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2); + else if(aPrjProfile.ShapeType() == TopAbs_WIRE) + TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2); + else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){ + TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE); + if(anExp.More()) { + TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2); + } else { + anExp.Init(aPrjProfile, TopAbs_EDGE); + if(anExp.More()) { + TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2); + } + } + } + if(aV1.IsNull() || aV2.IsNull()) + return false; + gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1); + gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2); + aPnt1.SetZ(0.0); + aPnt2.SetZ(0.0); + BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2); + if(!aMk.IsDone()) + return false; + const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge + Standard_Integer aNum(0); + + TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE); + for(;anExplo.More();anExplo.Next()) aNum++; + // check for self-intersection + const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion(); + Standard_Boolean hasInt(false); + Standard_Real aSqDist(DBL_MAX); + Standard_Integer anIndx(0); + BRepExtrema_ExtCC aCC; + aCC.Initialize(anEdg2); + outPar = 0.0; + anExplo.Init(aHydraulicWire, TopAbs_EDGE); + for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) { + const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current()); + if(anEdg1.IsNull()) + continue; + aCC.Perform(anEdg1); + if(aCC.IsDone()) { + for(Standard_Integer i=1; i<= aCC.NbExt();i++) + if(aCC.SquareDistance(i) < aSqDist) { + aSqDist = aCC.SquareDistance(i); + anIndx = i; + hasInt = true; + } + } + if(hasInt) { + if(aSqDist <= SquareTolerance) { + const gp_Pnt& aPnt = aCC.PointOnE1(anIndx); + if(aNum > 1) { + TopExp::Vertices(anEdg1, aV1, aV2, Standard_True); + outPar += BRep_Tool::Pnt(aV1).Distance(aPnt); + } else { + Standard_Real aPar = aCC.ParameterOnE1(anIndx); + outPar = aPar; + } + break; + } else { + if(aNum > 1) { + TopExp::Vertices(anEdg1, aV1, aV2); + outPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2)); + } + } + } + } return true; } @@ -214,8 +305,15 @@ bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile ) { if ( theProfile.IsNull() ) return false; - - if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile ) ) + gp_Ax2 aX2(gp::XOY()); + gp_Ax3 aX3(aX2); + gp_Pln aPln(aX3); + BRepBuilderAPI_MakeFace aMkr(aPln); + if(!aMkr.IsDone()) + return false; + const TopoDS_Face& aPlane = TopoDS::Face(aMkr.Shape()); + Standard_Real aPar(.0); + if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) ) return false; // Object is already in reference list or it has no intersection insertProfileInToOrder( theProfile ); @@ -281,13 +379,20 @@ void HYDROData_Stream::updateProfilesOrder() Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); if ( aHydAxis.IsNull() ) return; - + gp_Ax2 aX2(gp::XOY()); + gp_Ax3 aX3(aX2); + gp_Pln aPln(aX3); + BRepBuilderAPI_MakeFace aMkr(aPln); + if(!aMkr.IsDone()) + return; + const TopoDS_Face& aPlane = TopoDS::Face(aMkr.Shape()); + Standard_Real aPar(.0); HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles ); for ( ; anIter.More(); anIter.Next() ) { Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( anIter.Value() ); - if ( aProfile.IsNull() || !HasIntersection( aProfile ) ) + if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) ) continue; insertProfileInToOrder( aProfile ); diff --git a/src/HYDROData/HYDROData_Stream.h b/src/HYDROData/HYDROData_Stream.h index ce9eb426..4c09d9d5 100644 --- a/src/HYDROData/HYDROData_Stream.h +++ b/src/HYDROData/HYDROData_Stream.h @@ -3,7 +3,7 @@ #define HYDROData_Stream_HeaderFile #include "HYDROData_NaturalObject.h" - +#include DEFINE_STANDARD_HANDLE(HYDROData_Stream, HYDROData_NaturalObject) class Handle(HYDROData_PolylineXY); @@ -82,8 +82,11 @@ public: /** * Returns true if profile has the intersection with reference hydraulic axis. + * Returns the parameter of inresection point on axis if axis is presented by one curve, + * if axis presented by set of edges the returns a common length of segments till the intersection point. */ - HYDRODATA_EXPORT virtual bool HasIntersection( const Handle(HYDROData_Profile)& theProfile ) const; + HYDRODATA_EXPORT virtual bool HasIntersection( const Handle(HYDROData_Profile)& theProfile, const TopoDS_Face& thePlane, + Standard_Real& outPar) const; /** diff --git a/src/HYDROGUI/HYDROGUI_StreamOp.cxx b/src/HYDROGUI/HYDROGUI_StreamOp.cxx index 36a50ca7..ba889992 100755 --- a/src/HYDROGUI/HYDROGUI_StreamOp.cxx +++ b/src/HYDROGUI/HYDROGUI_StreamOp.cxx @@ -42,7 +42,16 @@ #include #include #include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include HYDROGUI_StreamOp::HYDROGUI_StreamOp( HYDROGUI_Module* theModule, bool theIsEdit ) : HYDROGUI_Operation( theModule ), myIsEdit( theIsEdit ), @@ -237,6 +246,13 @@ void HYDROGUI_StreamOp::onAddProfiles() HYDROData_SequenceOfObjects aVerifiedProfiles; HYDROData_SequenceOfObjects aSelectedProfiles = HYDROGUI_Tool::GetSelectedObjects( module() ); + gp_Ax2 aX2(gp::XOY()); + gp_Ax3 aX3(aX2); + gp_Pln aPln(aX3); + BRepBuilderAPI_MakeFace aMkr(aPln); + if(!aMkr.IsDone()) return; + const TopoDS_Face& aPlane = TopoDS::Face(aMkr.Shape()); + Standard_Real aPar(.0); for( int i = 1, n = aSelectedProfiles.Length(); i <= n; i++ ) { Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( aSelectedProfiles.Value( i ) ); @@ -248,7 +264,7 @@ void HYDROGUI_StreamOp::onAddProfiles() anInvalidProfiles << aProfileName; } else if ( aCurrentProfiles.contains( aProfileName ) ) { // check whether the profile is already added anExistingProfiles << aProfileName; - } else if ( !myEditedObject->HasIntersection( aProfile ) ) { // check whether the profile has intersection + } else if ( !myEditedObject->HasIntersection( aProfile, aPlane, aPar ) ) { // check whether the profile has intersection aHasNoIntersectionProfiles << aProfileName; } else { aVerifiedProfiles.Append( aProfile ); -- 2.39.2