X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROCurveCreator%2FCurveCreator_Utils.cxx;h=f4e49253ac69e7ff38c073248b656cbf1622a1b5;hb=8edd427af3997521bda72ca3c416cc1d490565d5;hp=ec27ddb04599b9e6b98e1d18155032b308876f3e;hpb=5ab983d4b8b4d9d77dd3da5069659afc8c338b80;p=modules%2Fhydro.git diff --git a/src/HYDROCurveCreator/CurveCreator_Utils.cxx b/src/HYDROCurveCreator/CurveCreator_Utils.cxx index ec27ddb0..f4e49253 100644 --- a/src/HYDROCurveCreator/CurveCreator_Utils.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Utils.cxx @@ -18,13 +18,51 @@ // #include "CurveCreator_Utils.h" +#include "CurveCreator.hxx" +#include "CurveCreator_UtilsICurve.hxx" #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 +#include "CurveCreator_ICurve.hxx" + +const double LOCAL_SELECTION_TOLERANCE = 0.0001; +const int SCENE_PIXEL_TOLERANCE = 10; + //======================================================================= // function : ConvertClickToPoint() // purpose : Returns the point clicked in 3D view @@ -44,24 +82,362 @@ void CurveCreator_Utils::ConvertPointToClick( const gp_Pnt& thePoint, gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) aView ) { return GEOMUtils::ConvertClickToPoint( x, y, aView ); - /* - V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt; - aView->Eye( XEye, YEye, ZEye ); - - aView->At( XAt, YAt, ZAt ); - gp_Pnt EyePoint( XEye, YEye, ZEye ); - gp_Pnt AtPoint( XAt, YAt, ZAt ); - - gp_Vec EyeVector( EyePoint, AtPoint ); - gp_Dir EyeDir( EyeVector ); - - gp_Pln PlaneOfTheView = gp_Pln( AtPoint, EyeDir ); - Standard_Real X, Y, Z; - aView->Convert( x, y, X, Y, Z ); - gp_Pnt ConvertedPoint( X, Y, Z ); - - gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project( PlaneOfTheView, ConvertedPoint ); - gp_Pnt ResultPoint = ElSLib::Value( ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), PlaneOfTheView ); - return ResultPoint; - */ +} + + +//#define USE_COMPOUND +#include "CurveCreator_Curve.hxx" // TODO - remove +void CurveCreator_Utils::constructShape( const CurveCreator_ICurve* theCurve, + const int theISection, TopoDS_Shape& theShape, + std::vector& aSectionRepresentation ) +{ + CurveCreator::SectionType aSectType = theCurve->getSectionType( theISection ); + + + int aPointSize = theCurve->getNbPoints( theISection ); + bool aSectIsClosed = theCurve->isClosed( theISection ); + if( aSectType == CurveCreator::Polyline ) + { +#ifdef USE_COMPOUND + BRep_Builder aBuilder; + TopoDS_Compound aComp; + aBuilder.MakeCompound(aComp); + + int iPoint = 0; + gp_Pnt aPrevPoint, aPoint; + if ( aPointSize == 1 ) { + CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPrevPoint ); + TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex( aPrevPoint ).Vertex(); + aBuilder.Add( aComp, aVertex ); + } + else if ( aPointSize > 1 ) { + TopoDS_Edge aPointEdge; + TopoDS_Vertex aVertex; + CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPrevPoint ); + aVertex = BRepBuilderAPI_MakeVertex( aPrevPoint ).Vertex(); + aBuilder.Add( aComp, aVertex ); + iPoint++; + for( ; iPoint < aPointSize; iPoint++ ) { + CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint ); + aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); + aBuilder.Add( aComp, aVertex ); + aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge(); + aBuilder.Add( aComp, aPointEdge ); + aPrevPoint = aPoint; + } + if( aSectIsClosed && ( aPointSize > 2 ) ) { + CurveCreator_UtilsICurve::getPoint( theCurve, theISection, 0, aPoint ); + aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); + aBuilder.Add( aComp, aVertex ); + aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge(); + aBuilder.Add( aComp, aPointEdge ); + } + theShape = aComp; + } +#endif + } + else if( aSectType == CurveCreator::Spline ) + { + std::vector aPoints; + for( int iPoint = 0; iPoint < aPointSize; iPoint++ ) + { + CurveCreator::Coordinates aCoords = theCurve->getPoint( theISection, iPoint ); + double aX = aCoords[0]; + double aY = aCoords[1]; + double aZ = aCoords[2]; + aPoints.push_back( aX ); + aPoints.push_back( aY ); + } + + if( aPointSize > 1 ) + { + Handle(Geom_BSplineCurve) aBSplineCurve; + // fill array for algorithm by the received coordinates + int aLen = aPoints.size() / 2; + Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt (1, aLen); + std::vector::const_iterator aListIter = aPoints.begin(); + for (int ind = 1; ind <= aLen; ind++) { + gp_Pnt aPnt(gp::Origin()); + aPnt.SetX(*aListIter); + aListIter++; + aPnt.SetY(*aListIter); + aListIter++; + aPnt.SetZ(0); + aHCurvePoints->SetValue(ind, aPnt); + } + // compute BSpline + GeomAPI_Interpolate aGBC(aHCurvePoints, aSectIsClosed, gp::Resolution()); + aGBC.Perform(); + if (aGBC.IsDone()) { + aBSplineCurve = aGBC.Curve(); + } + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSplineCurve ).Edge(); + + TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge ).Wire(); + theShape = aWire; + } + } + + const CurveCreator_Curve* aCurve = dynamic_cast( theCurve ); + if ( !aCurve ) + return; + + if( aSectType == CurveCreator::Polyline ) + { +#ifndef USE_COMPOUND + int iPoint = 0; + for( ; iPoint < ( aPointSize - 1 ) ; iPoint++ ){ + Handle_AIS_Point anAISPnt = aCurve->getAISPoint(theISection, iPoint); + aSectionRepresentation.push_back( anAISPnt ); + Handle_AIS_Line aLine = aCurve->getAISLine( theISection, iPoint, iPoint+1 ); + aSectionRepresentation.push_back( aLine ); + } + if( aPointSize != 0 ){ + Handle_AIS_Point anAISPnt = aCurve->getAISPoint(theISection, iPoint); + aSectionRepresentation.push_back( anAISPnt ); + if( aSectIsClosed && ( aPointSize > 1 ) ){ + Handle_AIS_Line aLine = aCurve->getAISLine( theISection, iPoint, 0 ); + aSectionRepresentation.push_back( aLine ); + } + } +#endif + } + else if( aSectType == CurveCreator::Spline ) + { + std::vector aPoints; + for( int iPoint = 0; iPoint < aPointSize; iPoint++ ) + { + Handle_AIS_Point anAISPnt = aCurve->getAISPoint( theISection, iPoint ); + aSectionRepresentation.push_back( anAISPnt ); + } + } +} + +std::list CurveCreator_Utils::getSelectedPoints( Handle(AIS_InteractiveContext) theContext ) +{ + std::list aSelectedPoints; + + gp_Pnt aPnt; + for ( theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected() ) { + TopoDS_Vertex aVertex; + TopoDS_Shape aShape = theContext->SelectedShape(); + if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) + aVertex = TopoDS::Vertex( theContext->SelectedShape() ); + else { + Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner(); + if ( !anOwner.IsNull() ) { + Handle(AIS_InteractiveObject) anAIS = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() ); + if ( !anAIS.IsNull() ) { + Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast( anAIS); + if ( !aPoint.IsNull() ) + aVertex = TopoDS::Vertex( aPoint->Vertex() ); + } + if ( aVertex.IsNull() ) { + // the following happens if there are no points in the current curve, there is only a shape + /*Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast(anOwner); + if ( aBrepOwner.IsNull() ) + continue; + if ( aBrepOwner->HasShape() ) { + const TopoDS_Shape& aShape = aBrepOwner->Shape(); + if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) + { + aVertex = TopoDS::Vertex( aShape ); + } + }*/ + } + } + } + if ( aVertex.IsNull() ) + continue; + aPnt = BRep_Tool::Pnt( aVertex ); + aSelectedPoints.push_back( aPnt.X() ); + aSelectedPoints.push_back( aPnt.Y() ); + aSelectedPoints.push_back( aPnt.Z() ); + } + + return aSelectedPoints; +} +//======================================================================= +// function : setLocalPointContext +// purpose : Open/close the viewer local context +//======================================================================= +//#define USE_GLOBAL_SELECTION +void CurveCreator_Utils::setLocalPointContext( + Handle(AIS_InteractiveContext) theContext, + const bool theOpen ) +{ +#ifdef USE_GLOBAL_SELECTION + return; +#endif + if ( !theContext ) + return; + + if ( theOpen ) { + // Open local context if there is no one + if ( !theContext->HasOpenedContext() ) { + theContext->ClearCurrents( false ); + theContext->OpenLocalContext( false/*use displayed objects*/, true/*allow shape decomposition*/ ); + } + AIS_ListOfInteractive aList; + theContext->DisplayedObjects( aList ); + int aLSize = 0; + for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) + aLSize++; + + for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) + { + Handle(AIS_InteractiveObject) anAIS = it.Value(); + if ( !anAIS.IsNull() ) + { + if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) ) + { + theContext->Load( anAIS, -1/*selection mode*/, true/*allow decomposition*/ ); + //theContext->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_WIRE ) ); + theContext->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_VERTEX ) ); + } + else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) ) + { + theContext->Load( anAIS, -1/*selection mode*/, false/*allow decomposition*/ ); + theContext->Activate( anAIS, TopAbs_VERTEX ); + } + } + continue; + } + } + else { + if ( theContext->HasOpenedContext() ) + theContext->CloseAllContexts(); + } +} + +bool CurveCreator_Utils::getNeighbourPoints( Handle(AIS_InteractiveContext) theContext, + Handle(V3d_View) theView, + const int theX, const int theY, + gp_Pnt& thePoint, gp_Pnt& thePoint1, + gp_Pnt& thePoint2 ) +{ + bool isFoundPoint = false; + if ( theContext.IsNull() ) + return isFoundPoint; + + for ( theContext->InitSelected(); theContext->MoreSelected() && !isFoundPoint; + theContext->NextSelected() ) { + TopoDS_Shape aTShape = theContext->SelectedShape(); + if ( !aTShape.IsNull() && aTShape.ShapeType() == TopAbs_VERTEX ) + continue; + else { + Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner(); + if ( anOwner.IsNull() ) + continue; + const TopLoc_Location& aLocation = anOwner->Location(); + Handle(AIS_InteractiveObject) anAIS = + Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() ); + isFoundPoint = CurveCreator_Utils::pointOnObject( theView, anAIS, theX, theY, thePoint, + thePoint1, thePoint2 ); + } + } + return isFoundPoint; +} + +bool CurveCreator_Utils::pointOnObject( Handle(V3d_View) theView, + Handle(AIS_InteractiveObject) theObject, + const int theX, const int theY, + gp_Pnt& thePoint, + gp_Pnt& thePoint1, gp_Pnt& thePoint2 ) +{ + bool isFound = false; + + if ( theObject.IsNull() || theView.IsNull() ) + return isFound; + + gp_Pnt aPoint; + Standard_Real aParameter; + gp_Pnt aPnt1, aPnt2; + Handle(AIS_Line) aLine = Handle(AIS_Line)::DownCast( theObject ); + if ( !aLine.IsNull() ) { + const Handle(Geom_Line) aGLine = aLine->Line(); + isFound = hasProjectPointOnCurve( theView, theX, theY, aGLine, aParameter ); + if ( isFound ) { + aPoint = aGLine->Value( aParameter ); + + Handle(Geom_Point) aPStart; + Handle(Geom_Point) aPEnd; + aLine->Points( aPStart, aPEnd ); + aPnt1 = aPStart->Pnt(); + aPnt2 = aPEnd->Pnt(); + + // in case of Geom line a projection is performed to the infinite line, + // so it is necessary to bound it by the line size + Bnd_Box aLineBox; + aLineBox.Set( aPnt1, gp_Vec( aPnt1, aPnt2 ) ); + isFound = !aLineBox.IsOut( aPoint ); + } + } + else { + Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject ); + if ( !aShape.IsNull() ) { + const TopoDS_Wire& aWire = TopoDS::Wire( aShape->Shape() ); + if ( !aWire.IsNull() ) { + TopExp_Explorer anExp( aWire, TopAbs_EDGE ); + for ( ; anExp.More(); anExp.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current()); + if ( !anEdge.IsNull() ) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve( anEdge, aFirst, aLast ); + + if ( aCurve->IsKind( STANDARD_TYPE(Geom_BSplineCurve) ) ) { + Handle(Geom_BSplineCurve) aBSplineCurve = Handle(Geom_BSplineCurve)::DownCast( aCurve ); + if ( !aBSplineCurve.IsNull() ) { + isFound = hasProjectPointOnCurve( theView, theX, theY, aCurve, aParameter ); + if ( isFound ) { + aPoint = aBSplineCurve->Value( aParameter ); + Standard_Integer anI1, anI2; + aBSplineCurve->LocateU( aParameter, LOCAL_SELECTION_TOLERANCE, anI1, anI2 ); + + aPnt1 = aBSplineCurve->Value( aBSplineCurve->Knot( anI1 ) ); + aPnt2 = aBSplineCurve->Value( aBSplineCurve->Knot( anI2 ) ); + } + } + } + } + } + } + } + } + if ( isFound ) { + thePoint = aPoint; + thePoint1 = aPnt1; + thePoint2 = aPnt2; + } + return isFound; +} + +bool CurveCreator_Utils::hasProjectPointOnCurve( Handle(V3d_View) theView, + const int theX, const int theY, + const Handle(Geom_Curve)& theCurve, + Standard_Real& theParameter ) +{ + bool isFound = false; + if ( theView.IsNull() ) + return isFound; + + gp_Pnt aPoint = CurveCreator_Utils::ConvertClickToPoint( theX, theY, theView ); + + GeomAPI_ProjectPointOnCurve aProj( aPoint, theCurve ); + Standard_Integer aNbPoint = aProj.NbPoints(); + if (aNbPoint > 0) { + for (Standard_Integer j = 1; j <= aNbPoint && !isFound; j++) { + gp_Pnt aNewPoint = aProj.Point( j ); + theParameter = aProj.Parameter( j ); + + int aX, anY; + CurveCreator_Utils::ConvertPointToClick( aNewPoint, theView, aX, anY ); + + int aXDelta = abs( aX - theX ); + int anYDelta = abs( anY - theY ); + isFound = aXDelta < SCENE_PIXEL_TOLERANCE && anYDelta < SCENE_PIXEL_TOLERANCE; + } + } + return isFound; }