Salome HOME
Merge branch 'V7_7_BR' into hydro/imps_2015
authorPaul RASCLE <paul.rascle@edf.fr>
Mon, 1 Feb 2016 10:39:48 +0000 (11:39 +0100)
committerPaul RASCLE <paul.rascle@edf.fr>
Mon, 1 Feb 2016 10:39:48 +0000 (11:39 +0100)
17 files changed:
src/CurveCreator/CMakeLists.txt
src/CurveCreator/CurveCreator.hxx
src/CurveCreator/CurveCreator_Curve.cxx
src/CurveCreator/CurveCreator_Curve.hxx
src/CurveCreator/CurveCreator_ICurve.hxx
src/CurveCreator/CurveCreator_Operation.cxx
src/CurveCreator/CurveCreator_Section.cxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_Section.hxx
src/CurveCreator/CurveCreator_TableView.cxx
src/CurveCreator/CurveCreator_TableView.h
src/CurveCreator/CurveCreator_Utils.cxx
src/CurveCreator/CurveCreator_Utils.hxx
src/CurveCreator/CurveCreator_UtilsICurve.cxx
src/CurveCreator/CurveCreator_UtilsICurve.hxx
src/CurveCreator/CurveCreator_Widget.cxx
src/CurveCreator/CurveCreator_Widget.h
src/SKETCHER/Sketcher_Utils.cxx

index e17655aa69d66cd65265181548c1391aa85076fe..c085fc69f014213067c4a1ded8b8bf7becee394d 100644 (file)
@@ -94,6 +94,7 @@ SET(_other_SOURCES
   CurveCreator_Diff.cxx
   CurveCreator_Displayer.cxx
   CurveCreator_Operation.cxx
+  CurveCreator_Section.cxx
   CurveCreator_Utils.cxx
   CurveCreator_UtilsICurve.cxx
 )
index f7e8d33eec9e2dc7e2a08801e2a37c5df4662766..e95749664421732fcf4e3ced4527b73e4fae9998 100644 (file)
@@ -33,7 +33,7 @@ struct CurveCreator_PosPoint;
 namespace CurveCreator
 {
   //! Points coordinates
-  typedef float TypeCoord;
+  typedef double TypeCoord;
 
   /** List of coordinates in format depends on section dimension:
    *  2D: [x1, y1,     x2, y2,     x3, y3,     ..]
index fb59efdd09ede81cc6cadca409cf0a33f0c46c38..e6be346fa1e7f9781004835cd385ff69f48e97b3 100644 (file)
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Wire.hxx>
 
+#include <Prs3d_PointAspect.hxx>
+#include <Handle_Prs3d_PointAspect.hxx>
+#include <iostream>
+#define DEBTRACE(msg) {std::cerr<<std::flush<<__FILE__<<" ["<<__LINE__<<"] : "<<msg<<std::endl<<std::flush;}
+
 #include <stdio.h>
 
 //=======================================================================
@@ -88,7 +93,7 @@ std::string CurveCreator_Curve::getUniqSectionName() const
         std::string aName(aBuffer);
         int j;
         for( j = 0 ; j < mySections.size() ; j++ ){
-            aSection = getSection( j );
+            aSection = (CurveCreator_Section*)getSection( j );
             if ( aSection && aSection->myName == aName )
               break;
         }
@@ -247,6 +252,7 @@ void CurveCreator_Curve::getCoordinates( int theISection, int theIPoint, double&
 
 void CurveCreator_Curve::redisplayCurve()
 {
+  //DEBTRACE("redisplayCurve");
   if( myDisplayer ) {
     myDisplayer->eraseAll( false );
     myAISShape = NULL;
@@ -263,7 +269,7 @@ bool CurveCreator_Curve::moveSectionInternal(const int theISection,
   int aMovedSectionId = theISection >= 0 ? theISection : mySections.size()-1;
 
   if (aMovedSectionId != theNewIndex) {
-    CurveCreator_Section* aSection = getSection( aMovedSectionId );
+    CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( aMovedSectionId );
 
     // Remove section
     CurveCreator::Sections::iterator anIter = mySections.begin() + aMovedSectionId;
@@ -362,7 +368,7 @@ bool CurveCreator_Curve::clearInternal()
 
   CurveCreator_Section* aSection;
   for (; i < aNbSections; i++) {
-    aSection = getSection( i );
+    aSection = (CurveCreator_Section*)getSection( i );
     if ( aSection )
       delete aSection;
   }
@@ -397,7 +403,8 @@ bool CurveCreator_Curve::joinInternal( const std::list<int>& theSections )
     return res;
 
   int anISectionMain = theSections.front();
-  CurveCreator_Section* aSectionMain = getSection( anISectionMain );
+  CurveCreator_Section* aSectionMain =
+    (CurveCreator_Section*)getSection( anISectionMain );
 
   std::list <int> aSectionsToJoin = theSections;
   aSectionsToJoin.erase( aSectionsToJoin.begin() ); // skip the main section
@@ -408,7 +415,7 @@ bool CurveCreator_Curve::joinInternal( const std::list<int>& theSections )
   std::list<int>::const_iterator anIt = aSectionsToJoin.begin(), aLast = aSectionsToJoin.end();
   CurveCreator_Section* aSection;
   for (; anIt != aLast; anIt++) {
-    aSection = getSection( *anIt );
+    aSection = (CurveCreator_Section*)getSection( *anIt );
     aSectionMain->myPoints.insert(aSectionMain->myPoints.end(), aSection->myPoints.begin(),
                                   aSection->myPoints.end());
     res = removeSectionInternal(*anIt);
@@ -552,12 +559,12 @@ int CurveCreator_Curve::getNbPoints( const int theISection ) const
     const int aNbSections = getNbSections();
 
     for (; i < aNbSections; i++) {
-      aSection = getSection( i );
+      aSection = (CurveCreator_Section*)getSection( i );
       if ( aSection )
         aNbCoords += aSection->myPoints.size();
     }
   } else {
-    aSection = getSection( theISection );
+    aSection = (CurveCreator_Section*)getSection( theISection );
     if ( aSection )
       aNbCoords = aSection->myPoints.size();
   }
@@ -592,7 +599,8 @@ void CurveCreator_Curve::saveCoordDiff( const SectionToPointCoordsList &theOldCo
 //! Get "closed" flag of the specified section
 bool CurveCreator_Curve::isClosed( const int theISection ) const
 {
-  CurveCreator_Section* aSection = getSection( theISection );
+  const CurveCreator_Section* aSection =
+    (CurveCreator_Section*)getSection( theISection );
   return aSection ? aSection->myIsClosed : false;
 }
 
@@ -606,14 +614,14 @@ bool CurveCreator_Curve::setClosedInternal( const int theISection,
     int i;
 
     for (i = 0; i < aSize; i++) {
-      aSection = getSection( i );
+      aSection = (CurveCreator_Section*)getSection( i );
       if( aSection ) {
         aSection->myIsClosed = theIsClosed;
         redisplayCurve();
       }
     }
   } else {
-    aSection = getSection( theISection );
+    aSection = (CurveCreator_Section*)getSection( theISection );
     if ( aSection ) {
       aSection->myIsClosed = theIsClosed;
       redisplayCurve();
@@ -644,7 +652,7 @@ bool CurveCreator_Curve::setClosed( const int theISection,
 //! Returns specified section name
 std::string CurveCreator_Curve::getSectionName( const int theISection ) const
 {
-  CurveCreator_Section* aSection = getSection( theISection );
+  CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( theISection );
   return aSection ? aSection->myName : "";
 }
 
@@ -653,7 +661,7 @@ bool CurveCreator_Curve::setSectionNameInternal( const int theISection,
                                                  const std::string& theName )
 {
   bool res = false;
-  CurveCreator_Section* aSection = getSection( theISection );
+  CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( theISection );
   if( aSection ) {
     aSection->myName = theName;
     res = true;
@@ -681,7 +689,7 @@ bool CurveCreator_Curve::setSectionName( const int theISection,
 CurveCreator::SectionType CurveCreator_Curve::getSectionType
   ( const int theISection ) const
 {
-  CurveCreator_Section* aSection = getSection( theISection );
+  CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( theISection );
   return aSection ? aSection->myType : CurveCreator::Polyline;
 }
 
@@ -695,13 +703,13 @@ bool CurveCreator_Curve::setSectionTypeInternal( const int theISection,
     const int aNbSections = getNbSections();
 
     for (; i < aNbSections; i++) {
-      aSection = getSection( i );
+      aSection = (CurveCreator_Section*)getSection( i );
       if ( aSection )
         aSection->myType = theType;
     }
     redisplayCurve();
   } else {
-    aSection = getSection( theISection );
+    aSection = (CurveCreator_Section*)getSection( theISection );
     if ( aSection && aSection->myType != theType ){
       aSection->myType = theType;
       redisplayCurve();
@@ -744,7 +752,7 @@ bool CurveCreator_Curve::addPointsInternal( const CurveCreator::SectionsMap &the
   CurveCreator_Section *aSection = 0;
   for ( ; anIt != theSectionsMap.end(); anIt++ ) {
     int anISection = anIt->first;
-    aSection = getSection( anISection );
+    aSection = (CurveCreator_Section*)getSection( anISection );
     if( aSection ) {
       CurveCreator::PosPointsList aSectionPoints = anIt->second;
       CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
@@ -777,6 +785,7 @@ bool CurveCreator_Curve::addPoints( const CurveCreator::Coordinates& theCoords,
                                     const int theISection,
                                     const int theIPnt )
 {
+  //DEBTRACE("addPoints");
   bool res = false;
   CurveCreator::Coordinates aCoords = theCoords;
   // Set the difference.
@@ -808,7 +817,7 @@ bool CurveCreator_Curve::setPointInternal( const CurveCreator::SectionsMap &theS
   CurveCreator_Section *aSection = 0;
   for ( ; anIt != theSectionsMap.end(); anIt++ ) {
     int anISection = anIt->first;
-    aSection = getSection( anISection );
+    aSection = (CurveCreator_Section*)getSection( anISection );
     if( aSection ) { 
       CurveCreator::PosPointsList aSectionPoints = anIt->second;
       CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
@@ -832,6 +841,7 @@ bool CurveCreator_Curve::setPoint( const int theISection,
                                    const int theIPnt,
                                    const CurveCreator::Coordinates& theNewCoords )
 {
+  //DEBTRACE("setPoint");
   bool res = false;
   // Set the difference.
   startOperation();
@@ -860,6 +870,7 @@ bool CurveCreator_Curve::setPoint( const int theISection,
 bool CurveCreator_Curve::setSeveralPoints( const SectionToPointCoordsList &theSectionToPntCoords,
                                            const bool theIsToSaveDiff )
 {
+  //DEBTRACE("setSeveralPoints");
   bool res = false;
   // Set the difference.
   startOperation();
@@ -948,7 +959,8 @@ bool CurveCreator_Curve::removeSeveralPoints( const SectionToPointList &theSecti
 CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection,
                                                         const int theIPnt) const
 {
-  CurveCreator_Section* aSection = getSection( theISection );
+  //DEBTRACE("getPoint");
+  CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( theISection );
   CurveCreator::Coordinates::const_iterator
     anIter = aSection->myPoints.begin() + toICoord(theIPnt);
   CurveCreator::Coordinates aResult(anIter, anIter + myDimension);
@@ -962,29 +974,29 @@ CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection,
 //=======================================================================
 CurveCreator::Coordinates CurveCreator_Curve::getPoints( const int theISection ) const
 {
-  CurveCreator_Section* aSection = getSection( theISection );
+  //DEBTRACE("getPoints");
+  CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( theISection );
   return aSection ? aSection->myPoints : CurveCreator::Coordinates();
 }
 
 void CurveCreator_Curve::constructAISObject()
 {
+  //DEBTRACE("constructAISObject");
   TopoDS_Shape aShape;
   CurveCreator_Utils::constructShape( this, aShape );
 
   myAISShape = new AIS_Shape( aShape );
-}
-
-CurveCreator_Section* CurveCreator_Curve::getSection( const int theSectionId ) const
-{
-  CurveCreator_Section *aSection = 0;
-  if ( theSectionId >= 0 && theSectionId < mySections.size() )
-    aSection = mySections.at( theSectionId );
+  Handle(Prs3d_PointAspect) anAspect = myAISShape->Attributes()->PointAspect();
+  anAspect->SetScale( 3.0 );
+  anAspect->SetTypeOfMarker(Aspect_TOM_O_POINT);
+  anAspect->SetColor(Quantity_NOC_ROYALBLUE4);
+  myAISShape->Attributes()->SetPointAspect( anAspect );
 
-  return aSection;
 }
 
 Handle(AIS_InteractiveObject) CurveCreator_Curve::getAISObject( const bool theNeedToBuild ) const
 {
+  //DEBTRACE("getAISObject");
   if ( !myAISShape && theNeedToBuild ) {
     CurveCreator_Curve* aCurve = (CurveCreator_Curve*)this;
     aCurve->constructAISObject();
@@ -997,7 +1009,7 @@ bool CurveCreator_Curve::removeSectionPoints( const int theSectionId,
 {
   bool aRes = false;
 
-  CurveCreator_Section* aSection = getSection( theSectionId );
+  CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( theSectionId );
   if ( !aSection )
     return aRes;
 
index 0c9cd27e9d09e8509a4a90b2f326e91ac85aadcb..2443eb87eae8c6a75df4d7e94cbc71f598481873 100644 (file)
@@ -205,6 +205,21 @@ public:
   virtual bool setSectionType( const int theISection, 
                                const CurveCreator::SectionType theType );
 
+  //! A virtual method.
+  const CurveCreator_ISection* getSection(const int theSectionIndex) const
+  {
+    if (theSectionIndex >= 0 && theSectionIndex < mySections.size())
+    {
+      return (CurveCreator_ISection*)mySections[theSectionIndex];
+    }
+    return NULL;
+  }
+
+  //! A virtual method.
+  CurveCreator_ISection* getSection(const int theSectionIndex)
+  {
+    return (CurveCreator_ISection*)mySections[theSectionIndex];
+  }
 
   /***********************************************/
   /***           Point methods                 ***/
@@ -298,12 +313,6 @@ protected:
 
 protected:
   virtual void constructAISObject();
-  /**
-   * Returns the section by the section index or NULL if the index is out of the section
-   * list range
-   * \param theSectionId the section index
-   */
-  CurveCreator_Section* getSection( const int theSectionId ) const;
 
 protected:
   bool                            mySkipSorting;
index b6429cb9747cb212cee2825a35753318aec1182b..20f8508e8e2d39389578684d6e6641767aa07515 100644 (file)
 #ifndef _CurveCreator_ICurve_HeaderFile
 #define _CurveCreator_ICurve_HeaderFile
 
+#include "CurveCreator.hxx"
 #include "CurveCreator_Macro.hxx"
+
+#include <TColgp_HArray1OfPnt.hxx>
+
 #include <deque>
 #include <vector>
 #include <string>
@@ -49,6 +53,17 @@ namespace CurveCreator
 
 };
 
+//! The type represents the interface to the curve section.
+struct CURVECREATOR_EXPORT CurveCreator_ISection
+{
+  //! The destructor.
+  virtual ~CurveCreator_ISection() {}
+
+  //! Calculates the different points of the section.
+  virtual void GetDifferentPoints(
+    const int theDimension, Handle(TColgp_HArray1OfPnt)& thePoints) const = 0;
+};
+
 /**
  *  The CurveCreator_ICurve object is represented as one or more sets of
  *  connected points; thus CurveCreator_ICurve object can contain several
@@ -62,13 +77,16 @@ public:
   typedef std::pair<int,int> SectionToPoint;
   typedef std::deque<SectionToPoint> SectionToPointList;
 
-  typedef std::deque< std::pair< SectionToPoint,std::deque< float > > > SectionToPointCoordsList;
+  typedef std::deque< std::pair< SectionToPoint, CurveCreator::Coordinates > > SectionToPointCoordsList;
 
 public:
   /***********************************************/
   /***          Undo/Redo methods              ***/
   /***********************************************/
 
+  //! The destructor.
+  virtual ~CurveCreator_ICurve() {}
+
   //! Get number of available undo operations
   virtual int getNbUndo() const = 0;
 
@@ -131,6 +149,13 @@ public:
   virtual bool setSectionType( const int theISection, 
                                const CurveCreator::SectionType theType ) = 0;
 
+  //! Returns the curve section with the index.
+  virtual const CurveCreator_ISection* getSection(
+    const int theSectionIndex) const = 0;
+
+  //! Returns the curve section with the index.
+  virtual CurveCreator_ISection* getSection(const int theSectionIndex) = 0;
+
 
   /***********************************************/
   /***           Point methods                 ***/
@@ -143,14 +168,14 @@ public:
    *  Insert one or several points to the specified section starting from the given theIPnt index
    *  (or add these at the end of section points if \a theIPnt is -1).
    */
-  virtual bool addPoints( const std::deque<float>& theCoords,
+  virtual bool addPoints( const CurveCreator::Coordinates& theCoords,
                           const int theISection,
                           const int theIPnt = -1 ) = 0;
 
   //! Set coordinates of specified point
   virtual bool setPoint( const int theISection,
                          const int theIPnt,
-                         const std::deque<float>& theNewCoords ) = 0;
+                         const CurveCreator::Coordinates& theNewCoords ) = 0;
   
   //! Set coordinates of specified points from different sections
   virtual bool setSeveralPoints( const SectionToPointCoordsList &theSectionToPntCoords,
@@ -162,13 +187,13 @@ public:
   virtual bool removeSeveralPoints( const SectionToPointList &theSectionToPntIDs) = 0;
 
   //! Get coordinates of specified point
-  virtual std::deque<float> getPoint( const int theISection, 
+  virtual CurveCreator::Coordinates getPoint( const int theISection, 
                                       const int theIPnt ) const = 0;
 
   /**
    * Get points of a section (the total points in Curve if theISection is equal to -1)..
    */
-  virtual std::deque<float> getPoints( const int theISection = -1 ) const = 0;
+  virtual CurveCreator::Coordinates getPoints( const int theISection = -1 ) const = 0;
 
   /**
    *  Get number of points in specified section or (the total number of points
index 32d29697e220ecb49af815383f7d40c6c73de2eb..17c278a979bd5e0bf31a2cd1d522066e6620887e 100644 (file)
@@ -341,7 +341,7 @@ void CurveCreator_Operation::apply(CurveCreator_Curve *theCurve)
 
           int nbPoints = pInt[0];
           int nbCoords = pInt[1];
-          int nbParams = 3+nbCoords;
+          int nbParams = 3+nbCoords*sizeof(double)/sizeof(int);
           for (int i = 0; i < nbPoints*nbParams; i=i+nbParams) {
             aCoords.clear();
             aPoints.clear();
diff --git a/src/CurveCreator/CurveCreator_Section.cxx b/src/CurveCreator/CurveCreator_Section.cxx
new file mode 100644 (file)
index 0000000..c798950
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (C) 2013-2015  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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File:        CurveCreator_Section.cxx
+// Author:      Aleksandr BOBKOV
+
+#include "CurveCreator_Section.hxx"
+
+#include <vector>
+
+const double POINT_CONFUSION = 1e-4;
+
+//=======================================================================
+// function: GetDifferentPoints
+// purpose:
+//=======================================================================
+void CurveCreator_Section::GetDifferentPoints(
+  const int theDimension, Handle(TColgp_HArray1OfPnt)& thePoints) const
+{
+  std::vector<gp_Pnt> aTmpPoints;
+  CurveCreator::Coordinates::const_iterator aPIt = myPoints.begin();
+  CurveCreator::Coordinates::const_iterator aPItLast = myPoints.end();
+  const gp_Pnt aFirstPoint(
+    *aPIt, *(aPIt + 1), (theDimension == 2) ? 0 : *(aPIt + 2));
+  gp_Pnt aPoint = aFirstPoint;
+  aTmpPoints.push_back(aPoint);
+
+  for (; aPIt != aPItLast; aPIt += theDimension)
+  {
+    const gp_Pnt aPoint2(
+      *aPIt, *(aPIt + 1), (theDimension == 2) ? 0 : *(aPIt + 2));
+    if (!aPoint.IsEqual(aPoint2, POINT_CONFUSION))
+    {
+      aPoint = aPoint2;
+      aTmpPoints.push_back(aPoint);
+    }
+  }
+
+  int aPointCount = aTmpPoints.size();
+  if (myIsClosed)
+  {
+    while (aPointCount > 1 &&
+      aFirstPoint.IsEqual(aTmpPoints[aPointCount - 1], POINT_CONFUSION))
+    {
+      --aPointCount;
+    }
+  }
+
+  thePoints = new TColgp_HArray1OfPnt(1, aPointCount);
+  for (int aPI = 0; aPI < aPointCount; ++aPI)
+  {
+    thePoints->SetValue(aPI + 1, aTmpPoints[aPI]);
+  }
+}
index 241615c2680aff95a3ae6d5b74a36f894ebd7da4..076dc78091c85e665e95363cb17e03023fdb086a 100644 (file)
 #define _CurveCreator_Section_HeaderFile
 
 #include "CurveCreator.hxx"
+#include "CurveCreator_ICurve.hxx"
 
 #include <string>
 
 //! Structure to store sections representing the CurveCreator_Curve object
-struct CurveCreator_Section
+struct CURVECREATOR_EXPORT CurveCreator_Section :
+  public CurveCreator_ISection
 {
   //! Constructor. Initializes object with default values.
   CurveCreator_Section() : myName("Section"),myType(CurveCreator::Polyline), myIsClosed(false)
@@ -39,6 +41,8 @@ struct CurveCreator_Section
   CurveCreator::SectionType myType;     //!< type of the section
   bool                      myIsClosed; //!< closed or not
 
+  //! A virtual method.
+  void GetDifferentPoints(const int theDimension, Handle(TColgp_HArray1OfPnt)& thePoints) const;
 };
 
 #endif
index b8fd0bf6e355a7846a8e412491c3a64b8af8d1d8..31bbb5c4d9cf123ae2b9ef52503c1028ab38b4f5 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <QTableWidget>
 #include <QTableWidgetItem>
+#include <QHeaderView>
 
 #include <QtxDoubleSpinBox.h>
 
@@ -109,6 +110,8 @@ CurveCreator_TableView::CurveCreator_TableView( CurveCreator_ICurve* theCurve,
   //aLabels << tr( "SECTION_LABEL" ) << tr( "IDENTIFIER_LABEL" ) << aCoord1 << aCoord2;
   aLabels << tr( "TABLE_SECTION" ) << tr("TABLE_INDEX") << aCoord1 << aCoord2;
   setHorizontalHeaderLabels( aLabels );
+
+  connect( horizontalHeader(), SIGNAL( sectionClicked( int ) ), this, SLOT( OnHeaderClick( int ) ) );
 }
 
 void CurveCreator_TableView::setCurve( CurveCreator_ICurve* theCurve )
@@ -131,13 +134,14 @@ void CurveCreator_TableView::setLocalPointsToTable(
 
     QTableWidgetItem* anItem;
     anItem = new QTableWidgetItem( myCurve->getSectionName( anISection ).c_str() );
-    anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
+    anItem->setFlags( anItem->flags() & ~Qt::ItemIsEditable );
     anItem->setData( Qt::UserRole, anISection );
     setItem( aRowId, 0, anItem );
 
     anItem = new QTableWidgetItem( QString::number( anIPoint + 1 ) );
     anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
     anItem->setData( Qt::UserRole, anIPoint );
+    anItem->setData( Qt::DisplayRole, anIPoint );
     setItem( aRowId, 1, anItem );
 
     gp_Pnt aPoint;
@@ -149,7 +153,7 @@ void CurveCreator_TableView::setLocalPointsToTable(
       setItem( aRowId, 2, anItem );
     }
     anItem->setData( Qt::UserRole, aPoint.X() );
-    anItem->setData( Qt::DisplayRole, QString::number( aPoint.X(), 'f', 2 ) );
+    anItem->setData( Qt::DisplayRole, QString::number( aPoint.X(), 'f', 2 ).toDouble() );
 
     anItem = item( aRowId, 3 );
     if ( !anItem ) {
@@ -157,7 +161,7 @@ void CurveCreator_TableView::setLocalPointsToTable(
       setItem( aRowId, 3, anItem );
     }
     anItem->setData( Qt::UserRole, aPoint.Y() );
-    anItem->setData( Qt::DisplayRole, QString::number( aPoint.Y(), 'f', 2 ) );
+    anItem->setData( Qt::DisplayRole, QString::number( aPoint.Y(), 'f', 2 ).toDouble() );
 
     aRowId++;
   }
@@ -176,3 +180,8 @@ int CurveCreator_TableView::getPointId( const int theRowId ) const
 {
   return item( theRowId, 1 )->data( Qt::UserRole ).toInt();
 }
+
+void CurveCreator_TableView::OnHeaderClick( int theLogicalId )
+{
+  sortByColumn( theLogicalId, Qt::AscendingOrder );
+}
index e6e8d1cd673172df853ba0af1c99583c612d8135..6028e04dd1d8560a4ea6bfc95cec4423c04f98e5 100644 (file)
@@ -63,6 +63,9 @@ public:
    */
   int getPointId( const int theRowId ) const;
 
+private slots:
+  void OnHeaderClick( int );
+
 private:
   CurveCreator_ICurve* myCurve;
 
index 7b6075c2b3063c1fabe73885852eecc60a78ac3e..863432b4cd3fbb2b892a7ea0cc178a70ce63f5e2 100644 (file)
@@ -20,6 +20,7 @@
 #include "CurveCreator_Utils.hxx"
 #include "CurveCreator.hxx"
 #include "CurveCreator_Curve.hxx"
+#include "CurveCreator_Section.hxx"
 #include "CurveCreator_UtilsICurve.hxx"
 
 #include <Basics_OCCTVersion.hxx>
@@ -183,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));
     }
-    int aNbPoints = aPoints.size();
+  }
+  else
+  {
+    Handle(Geom_BSplineCurve) aBSpline;
+    if (constructBSpline(thePoints, theIsClosed, aBSpline))
+    {
+      aBuilder.Add(aWire, BRepBuilderAPI_MakeEdge(aBSpline));
+    }
+  }
+  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;
 }
 
 /**
@@ -516,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;
 
index 78be98b009f98315c60a7ffca808b540305c6142..29393fa3f2c942de66168b7ed775dac9e01b08d0 100644 (file)
@@ -29,7 +29,9 @@
 #include <gp_Pnt.hxx>
 #include <Geom_Curve.hxx>
 #include <TopoDS_Shape.hxx>
+#include <TopoDS_Wire.hxx>
 #include <TColgp_HArray1OfPnt.hxx>
+#include <Geom_BSplineCurve.hxx>
 
 #include <list>
 #include <vector> // TODO: remove
@@ -132,6 +134,28 @@ public:
                                                  gp_Pnt& thePoint, gp_Pnt& thePoint1,
                                                  gp_Pnt& thePoint2 );
 
+  /**
+   * The algorithm builds the cubic B-spline passing through the points that the
+   * tangent vector in each given point P is calculated by the following way:
+   * if point P is preceded by a point A and is followed by a point B then
+   * the tangent vector is equal to (P - A) / |P - A| + (B - P) / |B - P|;
+   * if point P is preceded by a point A but is not followed by any point then
+   * the tangent vector is equal to P - A;
+   * if point P is followed by a point B but is not preceded by any point then
+   * the tangent vector is equal to B - P.
+   */
+  CURVECREATOR_EXPORT static bool constructBSpline( const Handle(TColgp_HArray1OfPnt)& thePoints,
+                                                    const Standard_Boolean theIsClosed,
+                                                    Handle(Geom_BSplineCurve)& theBSpline );
+
+  /**
+   * Constructs the wire corresponding to the section.
+   */
+  CURVECREATOR_EXPORT static TopoDS_Wire ConstructWire(
+    Handle(TColgp_HArray1OfPnt) thePoints,
+    const bool theIsPolyline,
+    const bool theIsClosed);
+
 protected:
   /*
    * Returns whether the clicked point belong to the curve or has a very near projection
index a0bd400a957f604730394ad3ba398616ee0a9892..cf6dc203de5fb93fa2d2ec8cd3319efe5bc0e4fd 100644 (file)
@@ -25,7 +25,7 @@
 const double LOCAL_SELECTION_TOLERANCE = 0.0001;
 
 int CurveCreator_UtilsICurve::findLocalPointIndex( const CurveCreator_ICurve* theCurve,
-                                             int theSectionId, float theX, float theY )
+                                             int theSectionId, double theX, double theY )
 {
   int aPntIndex = -1;
   if ( !theCurve )
index 89ff253f547d24c2546a1c6ec082289d4ac307ba..39c73b537a7d718080baec813d2cea11df750953 100644 (file)
@@ -39,7 +39,7 @@ public:
    * \param theY the Y coordinate of the point
    */
   CURVECREATOR_EXPORT static int  findLocalPointIndex( const CurveCreator_ICurve* theCurve,
-                                          int theSectionId, float theX, float theY );
+                                          int theSectionId, double theX, double theY );
 
   CURVECREATOR_EXPORT static void findSectionsToPoints( const CurveCreator_ICurve* theCurve,
                                           const double theX, const double theY,
index 393fa49dcf3f3538f2e4c27497d0b1fc0c5673c0..d401b8bc64782c09b6f75d513c031414c3656cc7 100644 (file)
@@ -48,6 +48,7 @@
 #include <QApplication>
 #include <QTableWidget>
 #include <QTime>
+#include <QSplitter>
 
 //#define MEASURE_TIME
 
@@ -206,8 +207,14 @@ CurveCreator_Widget::CurveCreator_Widget(QWidget* parent,
   aSectLayout->setMargin( 5 );
   aSectLayout->setSpacing( 5 );
   aSectLayout->addWidget(aTB);
-  aSectLayout->addWidget(mySectionView);
-  aSectLayout->addWidget( myLocalPointView );
+
+  QSplitter* aSplitter = new QSplitter(aSectionGroup);
+  aSplitter->setOrientation(Qt::Vertical);
+
+  aSplitter->addWidget(mySectionView);
+  aSplitter->addWidget( myLocalPointView );
+
+  aSectLayout->addWidget(aSplitter);
   aSectionGroup->setLayout(aSectLayout);
   QVBoxLayout* aLay = new QVBoxLayout();
   aLay->setMargin( 0 );
@@ -1005,10 +1012,18 @@ void CurveCreator_Widget::onMousePress( SUIT_ViewWindow*, QMouseEvent* theEvent
  */
 void CurveCreator_Widget::onMouseRelease( SUIT_ViewWindow* theWindow, QMouseEvent* theEvent )
 {
-  if ( getActionMode() != ModificationMode )
+  ActionMode aMode = getActionMode();
+  if ( aMode != ModificationMode )
   {
     // Emit selectionChanged() signal
     getOCCViewer()->performSelectionChanged();
+
+    if ( aMode == AdditionMode )
+    {
+      Handle(AIS_InteractiveContext) aCtx = getAISContext();
+      if ( !aCtx.IsNull() )
+        aCtx->ClearSelected();
+    }
     return;
   } 
   if (theEvent->button() != Qt::LeftButton) return;
@@ -1059,7 +1074,7 @@ void CurveCreator_Widget::onMouseRelease( SUIT_ViewWindow* theWindow, QMouseEven
   if ( myDragStarted ) {
     bool isDragged = myDragged;
     CurveCreator_ICurve::SectionToPointList aDraggedPoints;
-    QMap<CurveCreator_ICurve::SectionToPoint, std::deque< float > > anInitialDragPointsCoords;
+    QMap<CurveCreator_ICurve::SectionToPoint, CurveCreator::Coordinates > anInitialDragPointsCoords;
     if ( myDragged ) {
       aDraggedPoints = myDragPoints;
       anInitialDragPointsCoords = myInitialDragPointsCoords;
@@ -1105,7 +1120,7 @@ void CurveCreator_Widget::onMouseRelease( SUIT_ViewWindow* theWindow, QMouseEven
         for ( ; anIt != aLast; anIt++ ) {
           int aSectionId = anIt->first;
           int aPointId = anIt->second;
-          std::deque<float> aPos = myCurve->getPoint( aSectionId, aPointId );
+          CurveCreator::Coordinates aPos = myCurve->getPoint( aSectionId, aPointId );
 
           aCoordList.push_back(
             std::make_pair( std::make_pair( aSectionId, aPointId ), aPos ) );
@@ -1195,7 +1210,7 @@ void CurveCreator_Widget::onCellChanged( int theRow, int theColumn )
 
   double aX  = myLocalPointView->item( theRow, 2 )->data( Qt::UserRole ).toDouble();
   double anY = myLocalPointView->item( theRow, 3 )->data( Qt::UserRole ).toDouble();
-  std::deque<float> aChangedPos;
+  CurveCreator::Coordinates aChangedPos;
   aChangedPos.push_back( aX );
   aChangedPos.push_back( anY );
   myCurve->setPoint( aCurrSect, aPntIndex, aChangedPos );
@@ -1338,7 +1353,7 @@ void CurveCreator_Widget::moveSelectedPoints( const int theXPosition,
   double anYDelta = aStartPnt.Y() - anEndPnt.Y();
 
   CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
-  std::deque<float> aChangedPos;
+  CurveCreator::Coordinates aChangedPos;
   CurveCreator_ICurve::SectionToPointList::const_iterator anIt = myDragPoints.begin(),
                                                           aLast = myDragPoints.end();
   for ( ; anIt != aLast; anIt++ ) {
@@ -1490,7 +1505,7 @@ void CurveCreator_Widget::finishCurveModification(
  * \param theX the X coordinate of the point
  * \param theY the Y coordinate of the point
  */
-int CurveCreator_Widget::findLocalPointIndex( int theSectionId, float theX, float theY )
+int CurveCreator_Widget::findLocalPointIndex( int theSectionId, double theX, double theY )
 {
   return CurveCreator_UtilsICurve::findLocalPointIndex( myCurve, theSectionId, theX, theY );
 }
index 1fa317f5658ffba5821952a5e2a715db2b477462..87433c553c36f22beb49dacaf56fe853b9d72175 100644 (file)
@@ -195,7 +195,7 @@ private:
                                       CurveCreator_ICurve::SectionToPointList() );
 
   // curve algorithm
-  int  findLocalPointIndex( int theSectionId, float theX, float theY );
+  int  findLocalPointIndex( int theSectionId, double theX, double theY );
   void findSectionsToPoints( const double theX, const double theY,
                              CurveCreator_ICurve::SectionToPointList& thePoints );
   void convert( const CurveCreator_ICurve::SectionToPointList& thePoints,
index d707546faf1a392b4462ac38af789c4fd8813308..351de0b98c9cd4e78a96544e139eb7a9549b8398 100644 (file)
@@ -32,7 +32,9 @@
 #include <BRepBuilderAPI_MakeWire.hxx>
 #include <ElSLib.hxx>
 #include <GeomAPI_Interpolate.hxx>
+#include <TColgp_Array1OfVec.hxx>
 #include <TColgp_HArray1OfPnt.hxx>
+#include <TColStd_HArray1OfBoolean.hxx>
 #include <TopoDS_Wire.hxx>
 
 const double POINT_CONFUSION_TOLERANCE = 0.0001;
@@ -98,57 +100,134 @@ TopoDS_Shape Sketcher_Utils::MakePolyline
 }
 
 //=======================================================================
-// function : MakeInterpolation
-// purpose  : 
+// function : constructBSpline
+// purpose  : See function 'constructBSpline' in file 'CurveCreator_Utils.cxx'.
 //=======================================================================
-TopoDS_Shape Sketcher_Utils::MakeInterpolation
-                              (const std::list <double> &theCoords2D,
-                               const Standard_Boolean    IsClosed,
-                               const gp_Ax3             &thePlane)
+static bool constructBSpline(
+  const Handle(TColgp_HArray1OfPnt)& thePoints,
+  const Standard_Boolean theIsClosed,
+  Handle(Geom_BSplineCurve)& theBSpline)
 {
-  std::list <gp_Pnt> aPoints;
-  TopoDS_Shape       aResult;
-
-  To3D(theCoords2D, thePlane, aPoints);
-
-  Standard_Integer aNbPnts = aPoints.size();
-
-  if (aNbPnts > 1) {
-    if (IsClosed &&
-        aPoints.front().IsEqual(aPoints.back(), POINT_CONFUSION_TOLERANCE)) {
-      // The polyline should be closed, first and last points are confused.
-      // Remove the last point.
-      aPoints.pop_back();
-      --aNbPnts;
-    }
+  const int aPointCount = thePoints->Length();
+  if (aPointCount <= 1)
+  {
+    return false;
   }
 
-  if (aNbPnts == 1) {
-    // The result is vertex.
-    aResult = BRepBuilderAPI_MakeVertex(aPoints.front()).Vertex();
-  } else if (aNbPnts > 1) {
-    std::list <gp_Pnt>::const_iterator anIter        = aPoints.begin();
-    Handle(TColgp_HArray1OfPnt)        aHCurvePoints =
-      new TColgp_HArray1OfPnt(1, aNbPnts);
-    Standard_Integer                   i;
-
-    for (i = 1; anIter != aPoints.end(); ++anIter, ++i) {
-      aHCurvePoints->SetValue(i, *anIter);
+  // 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);
     }
+  }
 
-    // Compute BSpline
-    Standard_Real       aTol = Precision::Confusion();
-    GeomAPI_Interpolate aGBC(aHCurvePoints, IsClosed, aTol);
+  // Interpolate.
+  aInterpolator.Load(aTangents, aTangentFlags, Standard_False);
+  aInterpolator.Perform();
+  const bool aResult = (aInterpolator.IsDone() == Standard_True);
+  if (aResult)
+  {
+    theBSpline = aInterpolator.Curve();
+  }
+  return aResult;
+}
 
-    aGBC.Perform();
+//=======================================================================
+// function : MakeInterpolation
+// purpose  : 
+//=======================================================================
+TopoDS_Shape Sketcher_Utils::MakeInterpolation(
+  const std::list<double>& theCoords2D,
+  const Standard_Boolean theIsClosed,
+  const gp_Ax3& thePlane)
+{
+  if (theCoords2D.size() == 0)
+  {
+    return TopoDS_Shape();
+  }
 
-    if (aGBC.IsDone()) {
-      TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aGBC.Curve()).Edge();
-      aResult = BRepBuilderAPI_MakeWire(anEdge).Wire();
+  // Get the different points.
+  std::list<gp_Pnt> aTmpPoints;
+  To3D(theCoords2D, thePlane, aTmpPoints);
+  gp_Pnt aFirstPoint = aTmpPoints.front();
+  gp_Pnt aPoint = aFirstPoint;
+  std::list<gp_Pnt>::iterator aPIt = aTmpPoints.begin();
+  for (++aPIt; aPIt != aTmpPoints.end();)
+  {
+    const gp_Pnt aPoint2 = *aPIt;
+    if (!aPoint.IsEqual(aPoint2, POINT_CONFUSION_TOLERANCE))
+    {
+      aPoint = aPoint2;
+      ++aPIt;
+    }
+    else
+    {
+      aTmpPoints.erase(aPIt);
+    }
+  }
+  if (theIsClosed)
+  {
+    while (--aPIt != aTmpPoints.begin() &&
+      aFirstPoint.IsEqual(*aPIt, POINT_CONFUSION_TOLERANCE))
+    {
+      aTmpPoints.erase(aPIt);
     }
   }
 
-  return aResult;
+  // Process the single point case.
+  const int aPointCount = aTmpPoints.size();
+  if (aPointCount == 1)
+  {
+    return BRepBuilderAPI_MakeVertex(aTmpPoints.front());
+  }
+
+  // Process the other cases.
+  Handle(TColgp_HArray1OfPnt) aPoints =
+    new TColgp_HArray1OfPnt(1, aPointCount);
+  aPIt = aTmpPoints.begin();
+  for (Standard_Integer aPN = 1; aPIt != aTmpPoints.end(); ++aPIt, ++aPN)
+  {
+    aPoints->SetValue(aPN, *aPIt);
+  }
+  Handle(Geom_BSplineCurve) aBSpline;
+  if (constructBSpline(aPoints, theIsClosed, aBSpline))
+  {
+    return BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(aBSpline));
+  }
+  return TopoDS_Shape();
 }
 
 //=======================================================================