From b6156e45d774963f6c126415e9fb42d32d994bd5 Mon Sep 17 00:00:00 2001 From: asl Date: Thu, 12 Dec 2013 12:06:20 +0000 Subject: [PATCH] 2d presentation of obstacle is finished --- src/HYDROData/CMakeLists.txt | 6 +- src/HYDROData/HYDROData_Obstacle.cxx | 9 + src/HYDROData/HYDROData_Obstacle.h | 5 + src/HYDROData/HYDROData_Projection.cxx | 354 +++++++++++++++++++++++++ src/HYDROData/HYDROData_Projection.h | 43 +++ 5 files changed, 416 insertions(+), 1 deletion(-) create mode 100644 src/HYDROData/HYDROData_Projection.cxx create mode 100644 src/HYDROData/HYDROData_Projection.h diff --git a/src/HYDROData/CMakeLists.txt b/src/HYDROData/CMakeLists.txt index aa8b6132..130f4988 100644 --- a/src/HYDROData/CMakeLists.txt +++ b/src/HYDROData/CMakeLists.txt @@ -28,6 +28,7 @@ set(PROJECT_HEADERS HYDROData_Polyline3D.h HYDROData_Profile.h HYDROData_ProfileUZ.h + HYDROData_Projection.h HYDROData_Region.h HYDROData_River.h HYDROData_SplitToZonesTool.h @@ -64,6 +65,7 @@ set(PROJECT_SOURCES HYDROData_Polyline3D.cxx HYDROData_Profile.cxx HYDROData_ProfileUZ.cxx + HYDROData_Projection.cxx HYDROData_Region.cxx HYDROData_River.cxx HYDROData_SplitToZonesTool.cxx @@ -90,7 +92,9 @@ include_directories( ) add_library(HYDROData SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) -target_link_libraries(HYDROData ${GEOM_GEOMUtils} ${CAS_OCAF} ${CAS_OCAFVIS} ${CAS_TKG3d} ${CAS_TKGeomBase} ${CAS_TKGeomAlgo} ${CAS_TKBrep} ${CAS_TKIGES} ${CAS_TKSTEP} ${CAS_TKTopAlgo} ${CAS_TKBO} ${CAS_TKBool} ${CAS_TKOffset} ${QT_LIBRARIES} ${GUI_ImageComposer}) +target_link_libraries(HYDROData ${GEOM_GEOMUtils} ${CAS_OCAF} ${CAS_OCAFVIS} ${CAS_TKG3d} ${CAS_TKGeomBase} ${CAS_TKGeomAlgo} + ${CAS_TKBrep} ${CAS_TKIGES} ${CAS_TKSTEP} ${CAS_TKTopAlgo} ${CAS_TKBO} ${CAS_TKBool} ${CAS_TKOffset} + ${QT_LIBRARIES} ${GUI_ImageComposer} ${CAS_TKHLR} ) INSTALL(TARGETS HYDROData EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) set(PROJECT_LIBRARIES HYDROData) diff --git a/src/HYDROData/HYDROData_Obstacle.cxx b/src/HYDROData/HYDROData_Obstacle.cxx index 6c89c52d..0a48be15 100644 --- a/src/HYDROData/HYDROData_Obstacle.cxx +++ b/src/HYDROData/HYDROData_Obstacle.cxx @@ -31,6 +31,8 @@ #include // CAREFUL ! position of this file is critic +#include + #define PYTHON_OBSTACLE_ID "KIND_OBSTACLE" IMPLEMENT_STANDARD_HANDLE(HYDROData_Obstacle,HYDROData_ArtificialObject) @@ -329,3 +331,10 @@ TopoDS_Shape HYDROData_Obstacle::ImportSTEP( const QString& theFilePath ) const return aResShape; } + +void HYDROData_Obstacle::SetShape3D( const TopoDS_Shape& theShape ) +{ + TopoDS_Face aShape2d = HYDROData_Projection::MakeProjection( theShape ); + HYDROData_ArtificialObject::SetShape3D( theShape ); + HYDROData_ArtificialObject::SetTopShape( aShape2d ); +} diff --git a/src/HYDROData/HYDROData_Obstacle.h b/src/HYDROData/HYDROData_Obstacle.h index bfa194e6..952a8905 100644 --- a/src/HYDROData/HYDROData_Obstacle.h +++ b/src/HYDROData/HYDROData_Obstacle.h @@ -57,6 +57,11 @@ public: HYDRODATA_EXPORT static QColor DefaultBorderColor(); + /** + * Sets the 3d shape of the object. + */ + HYDRODATA_EXPORT virtual void SetShape3D( const TopoDS_Shape& theShape ); + public: /** diff --git a/src/HYDROData/HYDROData_Projection.cxx b/src/HYDROData/HYDROData_Projection.cxx new file mode 100644 index 00000000..83e0560a --- /dev/null +++ b/src/HYDROData/HYDROData_Projection.cxx @@ -0,0 +1,354 @@ +// File: Hydro_Projections.cxx +// Created: 11.12.13 17:47:42 +// Author: jgv@ROLEX +// Copyright: Open CASCADE 2013 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +HYDROData_Make3dMesh::HYDROData_Make3dMesh( const TopoDS_Shape& aShape, + const Standard_Real Tolerance ) +{ + myIntersector.Load(aShape, Tolerance); +} + +Standard_Boolean HYDROData_Make3dMesh::GetHighestOriginal(const Standard_Real aX, + const Standard_Real aY, + gp_Pnt& HighestPoint) +{ + gp_Pnt ProjPnt(aX, aY, 0.); + gp_Lin Ray(ProjPnt, -gp::DZ()); + myIntersector.PerformNearest(Ray, -Precision::Infinite(), 0.); + if (!myIntersector.IsDone() || myIntersector.NbPnt() == 0) + return Standard_False; + + HighestPoint = myIntersector.Pnt(1); + return Standard_True; +} + +//======================================================================= +//function : FindClosestDirection +//purpose : auxiliary function +//======================================================================= +TopoDS_Edge HYDROData_Projection::FindClosestDirection( const TopoDS_Vertex& StartVertex, + const TopTools_ListOfShape& Candidates, + const gp_Vec& StartDir ) +{ + Standard_Real MinAngle = M_PI; + TopoDS_Edge theEdge; + + TopTools_ListIteratorOfListOfShape itl(Candidates); + for (; itl.More(); itl.Next()) + { + TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); + BRepAdaptor_Curve BAcurve(anEdge); + gp_Pnt aPnt, aPnt2; + gp_Vec aDir, aDir2; + + Standard_Real Par, Par2 = 0.; //to avoid warning + Standard_Boolean ToReverse = Standard_False; + + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2); + if (StartVertex.IsSame(V1)) + Par = 0.99*BAcurve.FirstParameter() + 0.01*BAcurve.LastParameter(); + else + { + Par = 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter(); + ToReverse = Standard_True; + } + if (V1.IsSame(V2)) + { + Par2 = 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter(); + } + + BAcurve.D1(Par, aPnt, aDir); + if (ToReverse) + aDir.Reverse(); + + if (V1.IsSame(V2)) + { + BAcurve.D1(Par2, aPnt2, aDir2); + aDir2.Reverse(); + } + + Standard_Real anAngle = StartDir.Angle(aDir); + if (anAngle < MinAngle) + { + MinAngle = anAngle; + theEdge = anEdge; + } + + if (V1.IsSame(V2)) + { + anAngle = StartDir.Angle(aDir2); + if (anAngle < MinAngle) + { + MinAngle = anAngle; + theEdge = anEdge; + } + } + } + + return theEdge; +} + +//======================================================================= +//function : BuildOutWire +//purpose : auxiliary function +//======================================================================= +TopoDS_Wire HYDROData_Projection::BuildOutWire( const TopTools_IndexedDataMapOfShapeListOfShape& VEmap, + const TopoDS_Vertex& StartVertex, + TopoDS_Edge& StartEdge) +{ + Standard_Real AngularTol = 0.1; //0.01; //1.e-4; //Precision::Angular(); + TopTools_MapOfShape BoundEdges; + + TopoDS_Wire theWire; + BRep_Builder BB; + BB.MakeWire(theWire); + + TopoDS_Vertex V1, V2; + TopExp::Vertices(StartEdge, V1, V2); + if (StartVertex.IsSame(V1)) + StartEdge.Orientation(TopAbs_FORWARD); + else + StartEdge.Orientation(TopAbs_REVERSED); + BB.Add(theWire, StartEdge); + BoundEdges.Add(StartEdge); + + TopoDS_Vertex CurVertex = (StartVertex.IsSame(V1))? V2 : V1; + TopoDS_Edge CurEdge = StartEdge; + gp_Vec Normal(0., 0., 1.); + for (;;) + { + if (CurVertex.IsSame(StartVertex)) + { + theWire.Closed(Standard_True); + break; + } + + const TopTools_ListOfShape& Candidates = VEmap.FindFromKey(CurVertex); + Standard_Real MinAngle = M_PI; + + BRepAdaptor_Curve CurCurve(CurEdge); + TopExp::Vertices(CurEdge, V1, V2); + Standard_Real CurPar; + if (CurVertex.IsSame(V2)) + CurPar = CurCurve.LastParameter(); + else + CurPar = CurCurve.FirstParameter(); + gp_Pnt aPnt; + gp_Vec CurDir; + CurCurve.D1(CurPar, aPnt, CurDir); + if (CurDir.SquareMagnitude() < Precision::PConfusion()) + { + CurPar = (CurVertex.IsSame(V2))? + 0.01*CurCurve.FirstParameter() + 0.99*CurCurve.LastParameter() : + 0.99*CurCurve.FirstParameter() + 0.01*CurCurve.LastParameter(); + CurCurve.D1(CurPar, aPnt, CurDir); + } + if (CurVertex.IsSame(V1)) + CurDir.Reverse(); + + TopoDS_Edge theEdge; + TopTools_ListIteratorOfListOfShape itl(Candidates); + for (; itl.More(); itl.Next()) + { + TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); + if (BoundEdges.Contains(anEdge)) //if (anEdge.IsSame(CurEdge)) + continue; + + TopExp::Vertices(anEdge, V1, V2); + if (V1.IsSame(V2)) + continue; + + BRepAdaptor_Curve BAcurve(anEdge); + gp_Vec aDir; + Standard_Real aPar = (CurVertex.IsSame(V1))? + 0.99*BAcurve.FirstParameter() + 0.01*BAcurve.LastParameter() : + 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter(); + //BAcurve.FirstParameter() : BAcurve.LastParameter(); + + BAcurve.D1(aPar, aPnt, aDir); + if (CurVertex.IsSame(V2)) + aDir.Reverse(); + + Standard_Real anAngle = CurDir.AngleWithRef(aDir, Normal); + if (Abs(anAngle + M_PI) < AngularTol) //anAngle = -PI + continue; + if (anAngle < MinAngle) + { + MinAngle = anAngle; + theEdge = anEdge; + } + } + if (theEdge.IsNull()) + break; + + TopExp::Vertices(theEdge, V1, V2); + if (CurVertex.IsSame(V1)) + theEdge.Orientation(TopAbs_FORWARD); + else + theEdge.Orientation(TopAbs_REVERSED); + BB.Add(theWire, theEdge); + BoundEdges.Add(theEdge); + + CurVertex = (CurVertex.IsSame(V1))? V2 : V1; + CurEdge = theEdge; + } + + return theWire; +} + +//======================================================================= +//Function : MakeProjection +//purpose : this function makes the "shadow" of a shape on the plane XOY +//======================================================================= +TopoDS_Face HYDROData_Projection::MakeProjection( const TopoDS_Shape& aShape ) +{ + HLRAlgo_Projector theProjector(gp::XOY()); + + Handle(HLRBRep_Algo) aHLRAlgo = new HLRBRep_Algo(); + aHLRAlgo->Add(aShape); + aHLRAlgo->Projector(theProjector); + aHLRAlgo->Update(); + aHLRAlgo->Hide(); + HLRBRep_HLRToShape aHLRToShape(aHLRAlgo); + + TopoDS_Shape SharpEdges, OutLines; + TopoDS_Compound Total; + BRep_Builder BB; + BB.MakeCompound(Total); + + SharpEdges = aHLRToShape.VCompound(); + OutLines = aHLRToShape.OutLineVCompound(); + + TopoDS_Iterator itc; + if (!SharpEdges.IsNull()) + { + for (itc.Initialize(SharpEdges); itc.More(); itc.Next()) + BB.Add(Total, itc.Value()); + } + if (!OutLines.IsNull()) + { + for (itc.Initialize(OutLines); itc.More(); itc.Next()) + BB.Add(Total, itc.Value()); + } + + BRepBuilderAPI_Sewing aSewing; + Standard_Real tol = 1.0e-06; + Standard_Boolean NonManifoldMode = Standard_False; + aSewing.Init(tol, Standard_True,Standard_True,Standard_True,NonManifoldMode); + aSewing.SetFloatingEdgesMode(Standard_True); + + aSewing.Add( Total ); + aSewing.Perform(); + + TopoDS_Shape SewedEdges = aSewing.SewedShape(); + + BRepLib::BuildCurves3d( SewedEdges ); + + Bnd_Box theBox; + BRepBndLib::Add(SewedEdges, theBox); + Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; + theBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); + + gp_Pnt P1(Xmin, Ymin, 0.), P2(Xmax, Ymin, 0.); + TopoDS_Edge LowerBound = BRepLib_MakeEdge(P1, P2); + + Standard_Real Deviation = 1.e-7; //1.e-5; + BRepExtrema_DistShapeShape DSS(SewedEdges, LowerBound, Deviation); + + TopTools_IndexedDataMapOfShapeListOfShape StartShapes; + TopTools_DataMapOfShapeReal EdgesWithPars; + Standard_Integer i; + for (i = 1; i <= DSS.NbSolution(); i++) + { + if (!StartShapes.Contains( DSS.SupportOnShape1(i) )) + { + TopTools_ListOfShape aList; + aList.Append( DSS.SupportOnShape2(i) ); + StartShapes.Add( DSS.SupportOnShape1(i), aList ); + } + else + { + TopTools_ListOfShape& aList = StartShapes.ChangeFromKey( DSS.SupportOnShape1(i) ); + aList.Append( DSS.SupportOnShape2(i) ); + } + if (DSS.SupportTypeShape1(i) == BRepExtrema_IsOnEdge) + { + Standard_Real aPar; + DSS.ParOnEdgeS1(i, aPar); + EdgesWithPars.Bind( DSS.SupportOnShape1(i), aPar ); + } + } + + TopoDS_Shape aStartShape; + for (i = 1; i <= StartShapes.Extent(); i++) + { + const TopoDS_Shape& aShape = StartShapes.FindKey(i); + if (aShape.ShapeType() == TopAbs_EDGE) + { + aStartShape = aShape; + break; + } + } + if (aStartShape.IsNull()) + aStartShape = StartShapes.FindKey(1); //it is a vertex + + TopoDS_Vertex StartVertex; + TopoDS_Edge StartEdge; + gp_Vec StartDir(1.,0.,0.); + TopTools_IndexedDataMapOfShapeListOfShape VEmap; + TopExp::MapShapesAndAncestors(SewedEdges, TopAbs_VERTEX, TopAbs_EDGE, VEmap); + if (aStartShape.ShapeType() == TopAbs_EDGE) + { + StartEdge = TopoDS::Edge(aStartShape); + Standard_Real StartPar = EdgesWithPars(StartEdge); + BRepAdaptor_Curve BAcurve(StartEdge); + gp_Pnt aPnt; + gp_Vec aDir; + BAcurve.D1(StartPar, aPnt, aDir); + StartVertex = (StartDir * aDir > 0.)? + TopExp::FirstVertex(StartEdge) : TopExp::LastVertex(StartEdge); + } + else // it is a vertex + { + StartVertex = TopoDS::Vertex(aStartShape); + const TopTools_ListOfShape& Candidates = VEmap.FindFromKey(StartVertex); + StartEdge = FindClosestDirection(StartVertex, Candidates, StartDir); + } + + TopoDS_Wire OutWire = BuildOutWire(VEmap, StartVertex, StartEdge); + TopoDS_Face ProjFace = BRepLib_MakeFace(OutWire, Standard_True); //only plane + + return ProjFace; +} + diff --git a/src/HYDROData/HYDROData_Projection.h b/src/HYDROData/HYDROData_Projection.h new file mode 100644 index 00000000..3cd36bf9 --- /dev/null +++ b/src/HYDROData/HYDROData_Projection.h @@ -0,0 +1,43 @@ + +#ifndef HYDROData_Projection_HeaderFile +#define HYDROData_Projection_HeaderFile + +#include +#include + +class TopoDS_Shape; +class TopoDS_Edge; +class TopoDS_Face; +class TopoDS_Wire; +class TopoDS_Vertex; +class TopTools_ListOfShape; +class TopTools_IndexedDataMapOfShapeListOfShape; +class gp_Pnt; + +class HYDROData_Make3dMesh +{ +public: + HYDROData_Make3dMesh( const TopoDS_Shape& aShape, + const Standard_Real Tolerance ); + + Standard_Boolean GetHighestOriginal(const Standard_Real aX, + const Standard_Real aY, + gp_Pnt& HighestPoint ); + +private: + IntCurvesFace_ShapeIntersector myIntersector; +}; + +class HYDROData_Projection +{ +public: + static TopoDS_Edge FindClosestDirection( const TopoDS_Vertex& StartVertex, + const TopTools_ListOfShape& Candidates, + const gp_Vec& StartDir ); + static TopoDS_Wire BuildOutWire( const TopTools_IndexedDataMapOfShapeListOfShape& VEmap, + const TopoDS_Vertex& StartVertex, + TopoDS_Edge& StartEdge ); + static TopoDS_Face MakeProjection( const TopoDS_Shape& aShape ); +}; + +#endif -- 2.39.2