X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FCurveCreator%2FCurveCreator_Utils.cxx;h=53f68259f6f769f42b172749abdb8148dd5fdc63;hb=338ca530244e35ce6cce63f1570744f6e12dee97;hp=c999e4c484659e8be72c3e0162ce89e90ec45968;hpb=ff7fc4d6c2f5e6de741fd7f0b9ebf01de04d0e10;p=modules%2Fgeom.git diff --git a/src/CurveCreator/CurveCreator_Utils.cxx b/src/CurveCreator/CurveCreator_Utils.cxx index c999e4c48..53f68259f 100644 --- a/src/CurveCreator/CurveCreator_Utils.cxx +++ b/src/CurveCreator/CurveCreator_Utils.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2013-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,8 +20,11 @@ #include "CurveCreator_Utils.hxx" #include "CurveCreator.hxx" #include "CurveCreator_Curve.hxx" +#include "CurveCreator_Section.hxx" #include "CurveCreator_UtilsICurve.hxx" +#include + #include #include @@ -143,7 +146,7 @@ gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) a // we need the projection to the XOY plane // 1. find a point in the plane of the eye and the normal to the plane Standard_Real X, Y, Z; - Quantity_Parameter Vx, Vy, Vz; + Standard_Real Vx, Vy, Vz; aView->ConvertWithProj( x, y, X, Y, Z, Vx, Vy, Vz ); // 2. build a ray from the point by the normal to the XOY plane and intersect it @@ -181,116 +184,155 @@ gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) a return ResultPoint; } -void CurveCreator_Utils::constructShape( const CurveCreator_ICurve* theCurve, - TopoDS_Shape& theShape ) +//======================================================================= +// function : constructBSpline +// purpose : +//======================================================================= +bool CurveCreator_Utils::constructBSpline( + const Handle(TColgp_HArray1OfPnt)& thePoints, + const Standard_Boolean theIsClosed, + Handle(Geom_BSplineCurve)& theBSpline) { - BRep_Builder aBuilder; - TopoDS_Compound aComp; - aBuilder.MakeCompound( aComp ); - for( int iSection = 0 ; iSection < theCurve->getNbSections() ; iSection++ ) + const int aPointCount = thePoints->Length(); + if (aPointCount <= 1) { - int theISection = iSection; + return false; + } - CurveCreator::SectionType aSectType = theCurve->getSectionType( theISection ); - int aPointSize = theCurve->getNbPoints( theISection ); - if ( aPointSize == 0 ) - continue; + // Calculate the tangents. + TColgp_Array1OfVec aTangents(1, aPointCount); + Handle(TColStd_HArray1OfBoolean) aTangentFlags = + new TColStd_HArray1OfBoolean(1, aPointCount); + GeomAPI_Interpolate aInterpolator(thePoints, theIsClosed, 0); + if (aPointCount == 2) + { + aTangentFlags->SetValue(1, Standard_False); + aTangentFlags->SetValue(2, Standard_False); + } + else + { + for (Standard_Integer aPN = 1; aPN <= aPointCount; ++aPN) + { + gp_Vec aTangent; + if (aPN != 1 || theIsClosed) + { + const Standard_Integer aPN1 = (aPN != 1) ? (aPN - 1) : aPointCount; + aTangent = gp_Vec(thePoints->Value(aPN1), + thePoints->Value(aPN)).Normalized(); + } + if (aPN < aPointCount || theIsClosed) + { + const Standard_Integer aPN2 = (aPN != aPointCount) ? (aPN + 1) : 1; + const gp_Vec aTangent2 = aTangent + + gp_Vec(thePoints->Value(aPN), thePoints->Value(aPN2)).Normalized(); + if (aTangent2.SquareMagnitude() >= Precision::SquareConfusion()) + { + aTangent = aTangent2.Normalized(); + } + else + { + aTangent = -aTangent; + } + } + aTangents.SetValue(aPN, aTangent); + aTangentFlags->SetValue(aPN, Standard_True); + } + } - bool aSectIsClosed = theCurve->isClosed( theISection ); - bool isPolyline = aSectType == CurveCreator::Polyline; - - int iPoint = 0; - gp_Pnt aPrevPoint, aPoint; - // filters the curve points to skip equal points - std::vector aPoints; - CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint ); - aPoints.push_back( aPoint ); - aPrevPoint = aPoint; - iPoint++; - for( ; iPoint < aPointSize; iPoint++ ) { - CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint ); - if ( !isEqualPoints( aPrevPoint, aPoint ) ) - aPoints.push_back( aPoint ); - aPrevPoint = aPoint; + // Interpolate. + aInterpolator.Load(aTangents, aTangentFlags, Standard_False); + aInterpolator.Perform(); + const bool aResult = (aInterpolator.IsDone() == Standard_True); + if (aResult) + { + theBSpline = aInterpolator.Curve(); + } + return aResult; +} + +//======================================================================= +// function : constructWire +// purpose : +//======================================================================= +TopoDS_Wire CurveCreator_Utils::ConstructWire( + Handle(TColgp_HArray1OfPnt) thePoints, + const bool theIsPolyline, + const bool theIsClosed) +{ + TopoDS_Wire aWire; + BRep_Builder aBuilder; + aBuilder.MakeWire(aWire); + const int aPointCount = thePoints->Length(); + if (theIsPolyline) + { + const TopoDS_Vertex aFirstVertex = + BRepBuilderAPI_MakeVertex(thePoints->Value(1)); + TopoDS_Vertex aVertex = aFirstVertex; + for (Standard_Integer aPN = 1; aPN < aPointCount; ++aPN) + { + const TopoDS_Vertex aVertex2 = + BRepBuilderAPI_MakeVertex(thePoints->Value(aPN + 1)); + aBuilder.Add(aWire, BRepBuilderAPI_MakeEdge(aVertex, aVertex2)); + aVertex = aVertex2; + } + if (theIsClosed && aPointCount > 1) + { + aBuilder.Add(aWire, BRepBuilderAPI_MakeEdge(aVertex, aFirstVertex)); + } + } + else + { + Handle(Geom_BSplineCurve) aBSpline; + if (constructBSpline(thePoints, theIsClosed, aBSpline)) + { + aBuilder.Add(aWire, BRepBuilderAPI_MakeEdge(aBSpline)); } - int aNbPoints = aPoints.size(); + } + return aWire; +} - if ( aNbPoints == 1 ) { - aPoint = aPoints.front(); - TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); - aBuilder.Add( aComp, aVertex ); +//======================================================================= +// function : constructShape +// purpose : +//======================================================================= +void CurveCreator_Utils::constructShape( + const CurveCreator_ICurve* theCurve, TopoDS_Shape& theShape) +{ + BRep_Builder aBuilder; + TopoDS_Compound aShape; + aBuilder.MakeCompound(aShape); + const int aSectionCount = theCurve->getNbSections(); + for (int aSectionI = 0; aSectionI < aSectionCount; ++aSectionI) + { + const int aTmpPointCount = theCurve->getNbPoints(aSectionI); + if (aTmpPointCount == 0) + { + continue; } - else if ( aNbPoints > 1 ) { - Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt(1, aNbPoints); - TColgp_Array1OfVec aTangents(1, aNbPoints); - Handle(TColStd_HArray1OfBoolean) aTangentFlags = new TColStd_HArray1OfBoolean(1, aNbPoints); - gp_Vec aNullVec(0, 0, 0); - - TopoDS_Edge aPointEdge; - TopoDS_Vertex aVertex; - - std::vector::const_iterator aPointIt = aPoints.begin(), aPointLast = aPoints.end(); - aPoint = *aPointIt; - - int aHIndex = 1; - aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); - aBuilder.Add( aComp, aVertex ); - if ( !isPolyline ) { - aHCurvePoints->SetValue( aHIndex, aPoint ); - aTangents.SetValue( aHIndex, aNullVec ); - aTangentFlags->SetValue( aHIndex, Standard_False ); - aHIndex++; - } - aPrevPoint = aPoint; - aPointIt++; - for( ; aPointIt != aPointLast; aPointIt++ ) { - aPoint = *aPointIt; - aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); - aBuilder.Add( aComp, aVertex ); - if ( isPolyline ) { - TopoDS_Edge aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge(); - aBuilder.Add( aComp, aPointEdge ); - } - else { - aHCurvePoints->SetValue( aHIndex, aPoint ); - aTangents.SetValue( aHIndex, aNullVec ); - aTangentFlags->SetValue( aHIndex, Standard_False ); - aHIndex++; - } - aPrevPoint = aPoint; - } - if( aSectIsClosed && ( aNbPoints > 2 ) ) { - aPoint = aPoints.front(); - aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); - aBuilder.Add( aComp, aVertex ); - if ( isPolyline ) { - aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge(); - aBuilder.Add( aComp, aPointEdge ); - } - } - if( !isPolyline ) { - // compute BSpline - Handle(Geom_BSplineCurve) aBSplineCurve; - GeomAPI_Interpolate aGBC(aHCurvePoints, aSectIsClosed, gp::Resolution()); - // correct the spline degree to be as 3 for non-periodic spline if number of points - // less than 3. It is need to have a knot in each spline point. This knots are used - // to found a neighbour points when a new point is inserted between two existing. - if (!aSectIsClosed ) { - if (aHCurvePoints->Length() == 3) - aGBC.Load(aTangents, aTangentFlags); - } + // Get the different points. + const CurveCreator_ISection* aSection = theCurve->getSection(aSectionI); + Handle(TColgp_HArray1OfPnt) aPoints; + aSection->GetDifferentPoints(theCurve->getDimension(), aPoints); + const int aPointCount = aPoints->Length(); + const bool isClosed = theCurve->isClosed(aSectionI); - aGBC.Perform(); - if ( aGBC.IsDone() ) - aBSplineCurve = aGBC.Curve(); - TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSplineCurve ).Edge(); - TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge ).Wire(); - aBuilder.Add( aComp, aWire ); - } + // Add the vertices to the shape. + for (Standard_Integer aPN = 1; aPN <= aPointCount; ++aPN) + { + aBuilder.Add(aShape, BRepBuilderAPI_MakeVertex(aPoints->Value(aPN))); + } + + // Add the wire to the shape. + const bool isPolyline = + (theCurve->getSectionType(aSectionI) == CurveCreator::Polyline); + const TopoDS_Wire aWire = ConstructWire(aPoints, isPolyline, isClosed); + if (!aWire.IsNull()) + { + aBuilder.Add(aShape, aWire); } } - theShape = aComp; + theShape = aShape; } /** @@ -514,7 +556,7 @@ void CurveCreator_Utils::getSelectedPoints( Handle(AIS_InteractiveContext) theCo { thePoints.clear(); - std::list aSelectedPoints; + std::list aSelectedPoints; gp_Pnt aPnt; std::map aPointsMap; @@ -576,14 +618,22 @@ void CurveCreator_Utils::setSelectedPoints( Handle(AIS_InteractiveContext) theCo //ASL: we switch off automatic highlight to improve performance of selection theContext->SetAutomaticHilight( Standard_False ); - Handle_SelectMgr_Selection aSelection = anAISShape->Selection( AIS_Shape::SelectionMode( TopAbs_VERTEX ) ); + Handle(SelectMgr_Selection) aSelection = anAISShape->Selection( AIS_Shape::SelectionMode( TopAbs_VERTEX ) ); for( aSelection->Init(); aSelection->More(); aSelection->Next() ) - { - Handle_SelectBasics_SensitiveEntity aSenEntity = aSelection->Sensitive(); - Handle_Select3D_SensitivePoint aSenPnt = Handle_Select3D_SensitivePoint::DownCast( aSenEntity ); + { +#if OCC_VERSION_LARGE > 0x06080100 + const Handle(SelectMgr_SensitiveEntity) aHSenEntity = aSelection->Sensitive(); + if( aHSenEntity.IsNull() ) + continue; + Handle(SelectBasics_SensitiveEntity) aSenEntity = aHSenEntity->BaseSensitive(); +#else + Handle(SelectBasics_SensitiveEntity) aSenEntity = aSelection->Sensitive(); +#endif + + Handle(Select3D_SensitivePoint) aSenPnt = Handle(Select3D_SensitivePoint)::DownCast( aSenEntity ); gp_Pnt anOwnerPnt = aSenPnt->Point(); - Handle_SelectMgr_EntityOwner anOwner = Handle_SelectMgr_EntityOwner::DownCast( aSenPnt->OwnerId() ); + Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast( aSenPnt->OwnerId() ); CurveCreator_ICurve::SectionToPointList::const_iterator anIt = thePoints.begin(), @@ -637,7 +687,7 @@ void CurveCreator_Utils::setLocalPointContext( const CurveCreator_ICurve* theCur } else { if ( theContext->HasOpenedContext() ) - theContext->CloseAllContexts(); + theContext->CloseAllContexts( Standard_True ); } } @@ -841,7 +891,8 @@ Handle(TColgp_HArray1OfPnt) CurveCreator_Utils::getPoints anExp.Next(); - if (IsBSpline) { + if (IsBSpline) + { // There should be a single BSpline curve in the wire. if (anExp.More()) { return aResult; @@ -869,16 +920,20 @@ Handle(TColgp_HArray1OfPnt) CurveCreator_Utils::getPoints IsClosed = aV[0].IsSame(aV[1]) ? true : false; - const Standard_Integer aNbPoints = aBSplCurve->NbKnots(); - TColStd_Array1OfReal aKnots(1, aNbPoints); - + Standard_Integer aNbPoints = aBSplCurve->NbKnots(); + TColStd_Array1OfReal aKnots(1, aNbPoints); aBSplCurve->Knots(aKnots); - aResult = new TColgp_HArray1OfPnt(1, aBSplCurve->NbKnots()); - for (i = aKnots.Lower(); i <= aKnots.Upper(); ++i) { - aResult->SetValue(i, aBSplCurve->Value(aKnots.Value(i))); - } - } else { + // Don't consider the last point as it coincides with the first + if (IsClosed) + --aNbPoints; + + aResult = new TColgp_HArray1OfPnt(1, aNbPoints); + for (i = 1; i <= aNbPoints; ++i) + aResult->SetValue(i, aBSplCurve->Value( aKnots.Value(i) )); + } + else + { // This is a polyline. TopTools_ListOfShape aVertices; Standard_Integer aNbVtx = 1; @@ -910,6 +965,13 @@ Handle(TColgp_HArray1OfPnt) CurveCreator_Utils::getPoints IsClosed = aFirstVtx.IsSame(aLastVtx) ? true : false; + // Store a last vertex + if (!IsClosed) + { + aVertices.Append(aLastVtx); + aNbVtx++; + } + // Fill the array of points. aResult = new TColgp_HArray1OfPnt(1, aNbVtx); @@ -930,7 +992,7 @@ Handle(TColgp_HArray1OfPnt) CurveCreator_Utils::getPoints // purpose : //======================================================================= void CurveCreator_Utils::FindPlane - (const Handle_TColgp_HArray1OfPnt &thePoints, + (const Handle(TColgp_HArray1OfPnt) &thePoints, gp_Pln &thePlane, Standard_Integer &thePlnStatus) {