Salome HOME
RNV: Remove deprecated code.
[modules/geom.git] / src / CurveCreator / CurveCreator_Utils.cxx
index c999e4c484659e8be72c3e0162ce89e90ec45968..53f68259f6f769f42b172749abdb8148dd5fdc63 100644 (file)
@@ -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
 #include "CurveCreator_Utils.hxx"
 #include "CurveCreator.hxx"
 #include "CurveCreator_Curve.hxx"
+#include "CurveCreator_Section.hxx"
 #include "CurveCreator_UtilsICurve.hxx"
 
+#include <Basics_OCCTVersion.hxx>
+
 #include <GEOMUtils.hxx>
 
 #include <gp_Pln.hxx>
@@ -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<gp_Pnt> 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<gp_Pnt>::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<float> aSelectedPoints;
+  std::list<double> aSelectedPoints;
   gp_Pnt aPnt;
   std::map<CompareSectionToPoint, int> 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)
 {