From 8097d9e51b8b3a2b80b63c4db394994838c72d9b Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Tue, 4 Aug 2015 15:42:33 +0200 Subject: [PATCH] channel: projection point on guideline --- src/HYDROData/HYDROData_ChannelAltitude.cxx | 253 +++++++++++++++++--- src/HYDROData/HYDROData_ChannelAltitude.h | 5 +- src/HYDROData/HYDROData_ObstacleAltitude.h | 5 +- 3 files changed, 227 insertions(+), 36 deletions(-) diff --git a/src/HYDROData/HYDROData_ChannelAltitude.cxx b/src/HYDROData/HYDROData_ChannelAltitude.cxx index 0070f9c3..fd3917cc 100644 --- a/src/HYDROData/HYDROData_ChannelAltitude.cxx +++ b/src/HYDROData/HYDROData_ChannelAltitude.cxx @@ -20,16 +20,36 @@ #include "HYDROData_Document.h" #include "HYDROData_Object.h" +#include "HYDROData_Channel.h" #include "HYDROData_Projection.h" +#include "HYDROData_Polyline3D.h" +#include "HYDROData_Profile.h" #define _DEVDEBUG_ #include "HYDRO_trace.hxx" #include -#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include +#include + +#include +#include +#include IMPLEMENT_STANDARD_HANDLE(HYDROData_ChannelAltitude, HYDROData_IAltitudeObject) IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ChannelAltitude, HYDROData_IAltitudeObject) @@ -48,33 +68,210 @@ double HYDROData_ChannelAltitude::GetAltitudeForPoint( const gp_XY& thePoint ) c DEBTRACE("HYDROData_ChannelAltitude::GetAltitudeForPoint"); double aResAltitude = GetInvalidAltitude(); - Handle(HYDROData_Object) anObject = - Handle(HYDROData_Object)::DownCast( GetFatherObject() ); - if ( anObject.IsNull() ) - { - DEBTRACE("---"); - return aResAltitude; - } - - TopoDS_Shape anObjectShape3D = anObject->GetShape3D(); - DEBTRACE("object: " << anObject->GetName().toStdString()); - if ( anObjectShape3D.IsNull() ) - { - DEBTRACE("---"); - return aResAltitude; - } - else - { - DEBTRACE("anObjectShape3D type " << anObjectShape3D.ShapeType()); - BRepTools::Write(anObjectShape3D, "digue3D.brep"); - } - - HYDROData_Make3dMesh aMesher3D( anObjectShape3D, Precision::Intersection() ); - - gp_Pnt aHighestPoint; - if ( aMesher3D.GetHighestOriginal( thePoint.X(), thePoint.Y(), aHighestPoint ) ) - aResAltitude = aHighestPoint.Z(); - DEBTRACE("aResAltitude=" << aResAltitude); + Handle(HYDROData_Channel) aChannel = + Handle(HYDROData_Channel)::DownCast(GetFatherObject()); + if (aChannel.IsNull()) + { + DEBTRACE("aChannel.IsNull()"); + return aResAltitude; + } + DEBTRACE("aChannel: " << aChannel->GetName().toStdString()); + Handle(HYDROData_Polyline3D) aGuideLine = aChannel->GetGuideLine(); + if (aGuideLine.IsNull()) + { + DEBTRACE("aGuideLine.IsNull()"); + return aResAltitude; + } + DEBTRACE("aGuideLine: " << aGuideLine->GetName().toStdString()); + Handle (HYDROData_Profile) aProfile = aChannel->GetProfile(); + if (aProfile.IsNull()) + { + return aResAltitude; + } + DEBTRACE("aProfile: " << aProfile->GetName().toStdString()); + + // --- See GEOMImpl_ProjectionDriver.cxx + + TopoDS_Shape aShape = aGuideLine->GetShape3D(); + gp_Pnt P1(thePoint.X(), thePoint.Y(), 0); // plutot altitude moyenne + TopoDS_Shape aPoint = BRepBuilderAPI_MakeVertex(P1).Shape(); + + if (aPoint.IsNull() || aShape.IsNull()) + { + DEBTRACE("aPoint.IsNull() || aShape.IsNull()"); + return aResAltitude; + } + + if (aShape.ShapeType() != TopAbs_EDGE && aShape.ShapeType() != TopAbs_WIRE) + { + DEBTRACE("Projection aborted : the shape is neither an edge nor a wire"); + return aResAltitude; + } + + // Perform projection. + BRepExtrema_DistShapeShape aDistShSh(aPoint, aShape, Extrema_ExtFlag_MIN); + + if (aDistShSh.IsDone() == Standard_False) + { + DEBTRACE("Projection not done"); + return aResAltitude; + } + + Standard_Boolean hasValidSolution = Standard_False; + Standard_Integer aNbSolutions = aDistShSh.NbSolution(); + Standard_Integer i; + double aParam = 0.; + Standard_Real aTolConf = BRep_Tool::Tolerance(TopoDS::Vertex(aPoint)); + Standard_Real aTolAng = 1.e-4; + + for (i = 1; i <= aNbSolutions; i++) + { + Standard_Boolean isValid = Standard_False; + BRepExtrema_SupportType aSupportType = aDistShSh.SupportTypeShape2(i); + TopoDS_Shape aSupportShape = aDistShSh.SupportOnShape2(i); + + if (aSupportType == BRepExtrema_IsOnEdge) + { + // Minimal distance inside edge is really a projection. + isValid = Standard_True; + aDistShSh.ParOnEdgeS2(i, aParam); + } + else if (aSupportType == BRepExtrema_IsVertex) + { + TopExp_Explorer anExp(aShape, TopAbs_EDGE); + + if (aDistShSh.Value() <= aTolConf) + { + // The point lies on the shape. This means this point + // is really a projection. + for (; anExp.More() && !isValid; anExp.Next()) + { + TopoDS_Edge aCurEdge = TopoDS::Edge(anExp.Current()); + + if (aCurEdge.IsNull() == Standard_False) + { + TopoDS_Vertex aVtx[2]; + + TopExp::Vertices(aCurEdge, aVtx[0], aVtx[1]); + + for (int j = 0; j < 2; j++) + { + if (aSupportShape.IsSame(aVtx[j])) + { + // The current edge is a projection edge. + isValid = Standard_True; + aSupportShape = aCurEdge; + aParam = BRep_Tool::Parameter(aVtx[j], aCurEdge); + break; + } + } + } + } + } + else + { + // Minimal distance to vertex is not always a real projection. + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aPoint)); + gp_Pnt aPrjPnt = BRep_Tool::Pnt(TopoDS::Vertex(aSupportShape)); + gp_Vec aDProjP(aPrjPnt, aPnt); + + for (; anExp.More() && !isValid; anExp.Next()) + { + TopoDS_Edge aCurEdge = TopoDS::Edge(anExp.Current()); + + if (aCurEdge.IsNull() == Standard_False) + { + TopoDS_Vertex aVtx[2]; + + TopExp::Vertices(aCurEdge, aVtx[0], aVtx[1]); + + for (int j = 0; j < 2; j++) + { + if (aSupportShape.IsSame(aVtx[j])) + { + // Check if the point is a projection to the current edge. + Standard_Real anEdgePars[2]; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aCurEdge, anEdgePars[0], anEdgePars[1]); + gp_Pnt aVal; + gp_Vec aD1; + + aParam = BRep_Tool::Parameter(aVtx[j], aCurEdge); + aCurve->D1(aParam, aVal, aD1); + + if (Abs(aD1.Dot(aDProjP)) <= aTolAng) + { + // The current edge is a projection edge. + isValid = Standard_True; + aSupportShape = aCurEdge; + break; + } + } + } + } + } + } + } + + if (isValid) + { + if (hasValidSolution) + { + DEBTRACE("Projection aborted : multiple solutions"); + return aResAltitude; + } + + // Store the valid solution. + hasValidSolution = Standard_True; + + // Normalize parameter. + TopoDS_Edge aSupportEdge = TopoDS::Edge(aSupportShape); + Standard_Real aF, aL; + + BRep_Tool::Range(aSupportEdge, aF, aL); + + if (Abs(aL - aF) <= aTolConf) + { + DEBTRACE("Projection aborted : degenerated projection edge"); + return aResAltitude; + } + +// aParam = (aParam - aF) / (aL - aF); +// aProj.SetU(aParam); +// +// // Compute edge index. +// TopExp_Explorer anExp(aShape, TopAbs_EDGE); +// int anIndex = 0; +// +// for (; anExp.More(); anExp.Next(), anIndex++) +// { +// if (aSupportShape.IsSame(anExp.Current())) +// { +// aProj.SetIndex(anIndex); +// break; +// } +// } +// +// if (!anExp.More()) +// { +// DEBTRACE("Projection aborted : Can't define edge index"); +// return aResAltitude; +// } + + // Construct a projection vertex. + const gp_Pnt &aPntProj = aDistShSh.PointOnShape2(i); + TopoDS_Shape aProj = BRepBuilderAPI_MakeVertex(aPntProj).Shape(); + DEBTRACE("projection: (" << aPntProj.X() << ", " << aPntProj.Y() << ", " << aPntProj.Z() << ")"); + return aPntProj.Z(); + //aFunction->SetValue(aProj); + } + } + + if (!hasValidSolution) + { + DEBTRACE("Projection aborted : no projection"); + return aResAltitude; + } + return aResAltitude; } diff --git a/src/HYDROData/HYDROData_ChannelAltitude.h b/src/HYDROData/HYDROData_ChannelAltitude.h index 695f855e..0eb7b701 100644 --- a/src/HYDROData/HYDROData_ChannelAltitude.h +++ b/src/HYDROData/HYDROData_ChannelAltitude.h @@ -22,9 +22,6 @@ #include "HYDROData_IAltitudeObject.h" -#define _DEVDEBUG_ -#include "HYDRO_trace.hxx" - DEFINE_STANDARD_HANDLE(HYDROData_ChannelAltitude, HYDROData_IAltitudeObject) @@ -52,7 +49,7 @@ public: /** * Returns the kind of this object. */ - HYDRODATA_EXPORT virtual const ObjectKind GetKind() const { DEBTRACE("GetKind"); return KIND_CHANNEL_ALTITUDE; } + HYDRODATA_EXPORT virtual const ObjectKind GetKind() const { return KIND_CHANNEL_ALTITUDE; } public: diff --git a/src/HYDROData/HYDROData_ObstacleAltitude.h b/src/HYDROData/HYDROData_ObstacleAltitude.h index fcabf5df..ba95ba9b 100644 --- a/src/HYDROData/HYDROData_ObstacleAltitude.h +++ b/src/HYDROData/HYDROData_ObstacleAltitude.h @@ -22,9 +22,6 @@ #include "HYDROData_IAltitudeObject.h" -#define _DEVDEBUG_ -#include "HYDRO_trace.hxx" - DEFINE_STANDARD_HANDLE(HYDROData_ObstacleAltitude, HYDROData_IAltitudeObject) @@ -52,7 +49,7 @@ public: /** * Returns the kind of this object. */ - HYDRODATA_EXPORT virtual const ObjectKind GetKind() const { DEBTRACE("HYDROData_ObstacleAltitude::GetKind"); return KIND_OBSTACLE_ALTITUDE; } + HYDRODATA_EXPORT virtual const ObjectKind GetKind() const { return KIND_OBSTACLE_ALTITUDE; } public: -- 2.39.2