1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROData_ChannelAltitude.h"
21 #include "HYDROData_Document.h"
22 #include "HYDROData_Object.h"
23 #include "HYDROData_Channel.h"
24 #include "HYDROData_Projection.h"
25 #include "HYDROData_Polyline3D.h"
26 #include "HYDROData_Profile.h"
29 #include "HYDRO_trace.hxx"
32 #include <BRepBuilderAPI_MakeVertex.hxx>
33 #include <BRepExtrema_DistShapeShape.hxx>
35 #include <Precision.hxx>
39 #include <TopoDS_Shape.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Vertex.hxx>
43 #include <TopoDS_Wire.hxx>
44 #include <TopExp_Explorer.hxx>
45 #include <TopAbs_ShapeEnum.hxx>
46 #include <BRep_Tool.hxx>
47 #include <BRepTools.hxx>
48 #include <Geom_Curve.hxx>
50 #include <gp_Trsf.hxx>
54 IMPLEMENT_STANDARD_HANDLE(HYDROData_ChannelAltitude, HYDROData_IAltitudeObject)
55 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ChannelAltitude, HYDROData_IAltitudeObject)
57 HYDROData_ChannelAltitude::HYDROData_ChannelAltitude()
58 : HYDROData_IAltitudeObject()
62 HYDROData_ChannelAltitude::~HYDROData_ChannelAltitude()
66 double HYDROData_ChannelAltitude::GetAltitudeForPoint( const gp_XY& thePoint ) const
68 DEBTRACE("HYDROData_ChannelAltitude::GetAltitudeForPoint");
69 double aResAltitude = GetInvalidAltitude();
71 Handle(HYDROData_Channel) aChannel =
72 Handle(HYDROData_Channel)::DownCast(GetFatherObject());
73 if (aChannel.IsNull())
75 DEBTRACE("aChannel.IsNull()");
78 DEBTRACE("aChannel: " << aChannel->GetName().toStdString());
79 Handle(HYDROData_Polyline3D) aGuideLine = aChannel->GetGuideLine();
80 if (aGuideLine.IsNull())
82 DEBTRACE("aGuideLine.IsNull()");
85 DEBTRACE("aGuideLine: " << aGuideLine->GetName().toStdString());
86 Handle (HYDROData_Profile) aProfile = aChannel->GetProfile();
87 if (aProfile.IsNull())
91 DEBTRACE("aProfile: " << aProfile->GetName().toStdString());
93 // --- See GEOMImpl_ProjectionDriver.cxx
95 TopoDS_Shape aShape = aGuideLine->GetShape3D();
96 gp_Pnt P1(thePoint.X(), thePoint.Y(), 0); // plutot altitude moyenne
97 TopoDS_Shape aPoint = BRepBuilderAPI_MakeVertex(P1).Shape();
99 if (aPoint.IsNull() || aShape.IsNull())
101 DEBTRACE("aPoint.IsNull() || aShape.IsNull()");
105 if (aShape.ShapeType() != TopAbs_EDGE && aShape.ShapeType() != TopAbs_WIRE)
107 DEBTRACE("Projection aborted : the shape is neither an edge nor a wire");
111 // Perform projection.
112 BRepExtrema_DistShapeShape aDistShSh(aPoint, aShape, Extrema_ExtFlag_MIN);
114 if (aDistShSh.IsDone() == Standard_False)
116 DEBTRACE("Projection not done");
120 Standard_Boolean hasValidSolution = Standard_False;
121 Standard_Integer aNbSolutions = aDistShSh.NbSolution();
124 Standard_Real aTolConf = BRep_Tool::Tolerance(TopoDS::Vertex(aPoint));
125 Standard_Real aTolAng = 1.e-4;
127 for (i = 1; i <= aNbSolutions; i++)
129 Standard_Boolean isValid = Standard_False;
130 BRepExtrema_SupportType aSupportType = aDistShSh.SupportTypeShape2(i);
131 TopoDS_Shape aSupportShape = aDistShSh.SupportOnShape2(i);
133 if (aSupportType == BRepExtrema_IsOnEdge)
135 // Minimal distance inside edge is really a projection.
136 isValid = Standard_True;
137 aDistShSh.ParOnEdgeS2(i, aParam);
139 else if (aSupportType == BRepExtrema_IsVertex)
141 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
143 if (aDistShSh.Value() <= aTolConf)
145 // The point lies on the shape. This means this point
146 // is really a projection.
147 for (; anExp.More() && !isValid; anExp.Next())
149 TopoDS_Edge aCurEdge = TopoDS::Edge(anExp.Current());
151 if (aCurEdge.IsNull() == Standard_False)
153 TopoDS_Vertex aVtx[2];
155 TopExp::Vertices(aCurEdge, aVtx[0], aVtx[1]);
157 for (int j = 0; j < 2; j++)
159 if (aSupportShape.IsSame(aVtx[j]))
161 // The current edge is a projection edge.
162 isValid = Standard_True;
163 aSupportShape = aCurEdge;
164 aParam = BRep_Tool::Parameter(aVtx[j], aCurEdge);
173 // Minimal distance to vertex is not always a real projection.
174 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aPoint));
175 gp_Pnt aPrjPnt = BRep_Tool::Pnt(TopoDS::Vertex(aSupportShape));
176 gp_Vec aDProjP(aPrjPnt, aPnt);
178 for (; anExp.More() && !isValid; anExp.Next())
180 TopoDS_Edge aCurEdge = TopoDS::Edge(anExp.Current());
182 if (aCurEdge.IsNull() == Standard_False)
184 TopoDS_Vertex aVtx[2];
186 TopExp::Vertices(aCurEdge, aVtx[0], aVtx[1]);
188 for (int j = 0; j < 2; j++)
190 if (aSupportShape.IsSame(aVtx[j]))
192 // Check if the point is a projection to the current edge.
193 Standard_Real anEdgePars[2];
194 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aCurEdge, anEdgePars[0], anEdgePars[1]);
198 aParam = BRep_Tool::Parameter(aVtx[j], aCurEdge);
199 aCurve->D1(aParam, aVal, aD1);
201 if (Abs(aD1.Dot(aDProjP)) <= aTolAng)
203 // The current edge is a projection edge.
204 isValid = Standard_True;
205 aSupportShape = aCurEdge;
217 if (hasValidSolution)
219 DEBTRACE("Projection aborted : multiple solutions");
223 // Store the valid solution.
224 hasValidSolution = Standard_True;
226 // Normalize parameter.
227 TopoDS_Edge aSupportEdge = TopoDS::Edge(aSupportShape);
228 Standard_Real aF, aL;
230 BRep_Tool::Range(aSupportEdge, aF, aL);
232 if (Abs(aL - aF) <= aTolConf)
234 DEBTRACE("Projection aborted : degenerated projection edge");
238 // aParam = (aParam - aF) / (aL - aF);
239 // aProj.SetU(aParam);
241 // // Compute edge index.
242 // TopExp_Explorer anExp(aShape, TopAbs_EDGE);
245 // for (; anExp.More(); anExp.Next(), anIndex++)
247 // if (aSupportShape.IsSame(anExp.Current()))
249 // aProj.SetIndex(anIndex);
254 // if (!anExp.More())
256 // DEBTRACE("Projection aborted : Can't define edge index");
257 // return aResAltitude;
260 // Construct a projection vertex.
261 const gp_Pnt &aPntProj = aDistShSh.PointOnShape2(i);
262 TopoDS_Shape aProj = BRepBuilderAPI_MakeVertex(aPntProj).Shape();
263 DEBTRACE("projection: (" << aPntProj.X() << ", " << aPntProj.Y() << ", " << aPntProj.Z() << ")");
265 //aFunction->SetValue(aProj);
269 if (!hasValidSolution)
271 DEBTRACE("Projection aborted : no projection");