From 44f924fa670420fc1bd7deefe2c6c3d595bc552c Mon Sep 17 00:00:00 2001 From: abk Date: Mon, 29 Jun 2015 15:21:11 +0300 Subject: [PATCH] Initial version of interface 'CurveCreator_ISection' was created for the curve sections. Type 'CurveCreator_Section' was inherited from the interface and extended to implement the interface. Method 'CurveCreator_Curve::getSection' was modified for the interface. Method 'CurveCreator_Utils::ConstructWire' was created to construct the wire corresponding to each polyline or spline section. --- src/CurveCreator/CMakeLists.txt | 1 + src/CurveCreator/CurveCreator_Curve.cxx | 51 ++++------ src/CurveCreator/CurveCreator_Curve.hxx | 21 ++-- src/CurveCreator/CurveCreator_ICurve.hxx | 24 +++++ src/CurveCreator/CurveCreator_Section.cxx | 70 +++++++++++++ src/CurveCreator/CurveCreator_Section.hxx | 6 +- src/CurveCreator/CurveCreator_Utils.cxx | 116 ++++++++++------------ src/CurveCreator/CurveCreator_Utils.hxx | 19 ++++ 8 files changed, 208 insertions(+), 100 deletions(-) create mode 100644 src/CurveCreator/CurveCreator_Section.cxx diff --git a/src/CurveCreator/CMakeLists.txt b/src/CurveCreator/CMakeLists.txt index e17655aa6..c085fc69f 100644 --- a/src/CurveCreator/CMakeLists.txt +++ b/src/CurveCreator/CMakeLists.txt @@ -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 ) diff --git a/src/CurveCreator/CurveCreator_Curve.cxx b/src/CurveCreator/CurveCreator_Curve.cxx index fb59efdd0..0185e6cf4 100644 --- a/src/CurveCreator/CurveCreator_Curve.cxx +++ b/src/CurveCreator/CurveCreator_Curve.cxx @@ -88,7 +88,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; } @@ -263,7 +263,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 +362,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 +397,8 @@ bool CurveCreator_Curve::joinInternal( const std::list& theSections ) return res; int anISectionMain = theSections.front(); - CurveCreator_Section* aSectionMain = getSection( anISectionMain ); + CurveCreator_Section* aSectionMain = + (CurveCreator_Section*)getSection( anISectionMain ); std::list aSectionsToJoin = theSections; aSectionsToJoin.erase( aSectionsToJoin.begin() ); // skip the main section @@ -408,7 +409,7 @@ bool CurveCreator_Curve::joinInternal( const std::list& theSections ) std::list::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 +553,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 +593,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 +608,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 +646,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 +655,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 +683,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 +697,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 +746,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(); @@ -808,7 +810,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(); @@ -948,7 +950,7 @@ bool CurveCreator_Curve::removeSeveralPoints( const SectionToPointList &theSecti CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection, const int theIPnt) const { - CurveCreator_Section* aSection = getSection( theISection ); + CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( theISection ); CurveCreator::Coordinates::const_iterator anIter = aSection->myPoints.begin() + toICoord(theIPnt); CurveCreator::Coordinates aResult(anIter, anIter + myDimension); @@ -962,7 +964,7 @@ CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection, //======================================================================= CurveCreator::Coordinates CurveCreator_Curve::getPoints( const int theISection ) const { - CurveCreator_Section* aSection = getSection( theISection ); + CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( theISection ); return aSection ? aSection->myPoints : CurveCreator::Coordinates(); } @@ -974,15 +976,6 @@ void CurveCreator_Curve::constructAISObject() 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 ); - - return aSection; -} - Handle(AIS_InteractiveObject) CurveCreator_Curve::getAISObject( const bool theNeedToBuild ) const { if ( !myAISShape && theNeedToBuild ) { @@ -997,7 +990,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; diff --git a/src/CurveCreator/CurveCreator_Curve.hxx b/src/CurveCreator/CurveCreator_Curve.hxx index 0c9cd27e9..2443eb87e 100644 --- a/src/CurveCreator/CurveCreator_Curve.hxx +++ b/src/CurveCreator/CurveCreator_Curve.hxx @@ -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; diff --git a/src/CurveCreator/CurveCreator_ICurve.hxx b/src/CurveCreator/CurveCreator_ICurve.hxx index b6429cb97..5b5d5eae3 100644 --- a/src/CurveCreator/CurveCreator_ICurve.hxx +++ b/src/CurveCreator/CurveCreator_ICurve.hxx @@ -24,6 +24,9 @@ #define _CurveCreator_ICurve_HeaderFile #include "CurveCreator_Macro.hxx" + +#include + #include #include #include @@ -49,6 +52,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 @@ -69,6 +83,9 @@ public: /*** Undo/Redo methods ***/ /***********************************************/ + //! The destructor. + virtual ~CurveCreator_ICurve() {} + //! Get number of available undo operations virtual int getNbUndo() const = 0; @@ -131,6 +148,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 ***/ diff --git a/src/CurveCreator/CurveCreator_Section.cxx b/src/CurveCreator/CurveCreator_Section.cxx new file mode 100644 index 000000000..c798950ac --- /dev/null +++ b/src/CurveCreator/CurveCreator_Section.cxx @@ -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 + +const double POINT_CONFUSION = 1e-4; + +//======================================================================= +// function: GetDifferentPoints +// purpose: +//======================================================================= +void CurveCreator_Section::GetDifferentPoints( + const int theDimension, Handle(TColgp_HArray1OfPnt)& thePoints) const +{ + std::vector 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]); + } +} diff --git a/src/CurveCreator/CurveCreator_Section.hxx b/src/CurveCreator/CurveCreator_Section.hxx index 241615c26..076dc7809 100644 --- a/src/CurveCreator/CurveCreator_Section.hxx +++ b/src/CurveCreator/CurveCreator_Section.hxx @@ -24,11 +24,13 @@ #define _CurveCreator_Section_HeaderFile #include "CurveCreator.hxx" +#include "CurveCreator_ICurve.hxx" #include //! 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 diff --git a/src/CurveCreator/CurveCreator_Utils.cxx b/src/CurveCreator/CurveCreator_Utils.cxx index 4f8ca6fb8..52ed6f0e2 100644 --- a/src/CurveCreator/CurveCreator_Utils.cxx +++ b/src/CurveCreator/CurveCreator_Utils.cxx @@ -20,6 +20,7 @@ #include "CurveCreator_Utils.hxx" #include "CurveCreator.hxx" #include "CurveCreator_Curve.hxx" +#include "CurveCreator_Section.hxx" #include "CurveCreator_UtilsICurve.hxx" #include @@ -186,14 +187,6 @@ gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) a //======================================================================= // function : constructBSpline // purpose : -// 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. //======================================================================= bool CurveCreator_Utils::constructBSpline( const Handle(TColgp_HArray1OfPnt)& thePoints, @@ -257,6 +250,47 @@ bool CurveCreator_Utils::constructBSpline( 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)); + } + } + return aWire; +} + //======================================================================= // function : constructShape // purpose : @@ -277,71 +311,25 @@ void CurveCreator_Utils::constructShape( } // Get the different points. - std::vector aTmpPoints; - gp_Pnt aFirstPoint; - CurveCreator_UtilsICurve::getPoint(theCurve, aSectionI, 0, aFirstPoint); - gp_Pnt aPoint = aFirstPoint; - aTmpPoints.push_back(aPoint); - for (int aPI = 1; aPI < aTmpPointCount; ++aPI) - { - gp_Pnt aPoint2; - CurveCreator_UtilsICurve::getPoint(theCurve, aSectionI, aPI, aPoint2); - if (!isEqualPoints(aPoint, aPoint2)) - { - aPoint = aPoint2; - aTmpPoints.push_back(aPoint); - } - } + 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); - int aPointCount = aTmpPoints.size(); - if (isClosed) - { - while (aPointCount > 1 && - isEqualPoints(aFirstPoint, aTmpPoints[aPointCount - 1])) - { - --aPointCount; - } - } // Add the vertices to the shape. - Handle(TColgp_HArray1OfPnt) aPoints = - new TColgp_HArray1OfPnt(1, aPointCount); - for (Standard_Integer aPI = 0; aPI < aPointCount; ++aPI) + for (Standard_Integer aPN = 1; aPN <= aPointCount; ++aPN) { - aPoints->SetValue(aPI + 1, aTmpPoints[aPI]); - aBuilder.Add(aShape, BRepBuilderAPI_MakeVertex(aTmpPoints[aPI])); - } - if (aPointCount == 1) - { - continue; + aBuilder.Add(aShape, BRepBuilderAPI_MakeVertex(aPoints->Value(aPN))); } - // Add the edges to the shape. + // Add the wire to the shape. const bool isPolyline = (theCurve->getSectionType(aSectionI) == CurveCreator::Polyline); - if (isPolyline) + const TopoDS_Wire aWire = ConstructWire(aPoints, isPolyline, isClosed); + if (!aWire.IsNull()) { - for (Standard_Integer aPN = 1; aPN < aPointCount; ++aPN) - { - aBuilder.Add(aShape, BRepBuilderAPI_MakeEdge( - BRepBuilderAPI_MakeVertex(aPoints->Value(aPN)), - BRepBuilderAPI_MakeVertex(aPoints->Value(aPN + 1)))); - } - if (isClosed) - { - aBuilder.Add(aShape, BRepBuilderAPI_MakeEdge( - BRepBuilderAPI_MakeVertex(aPoints->Value(aPointCount)), - BRepBuilderAPI_MakeVertex(aPoints->Value(1)))); - } - } - else - { - Handle(Geom_BSplineCurve) aBSpline; - if (constructBSpline(aPoints, isClosed, aBSpline)) - { - aBuilder.Add(aShape, - BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(aBSpline))); - } + aBuilder.Add(aShape, aWire); } } theShape = aShape; diff --git a/src/CurveCreator/CurveCreator_Utils.hxx b/src/CurveCreator/CurveCreator_Utils.hxx index 0494fceef..29393fa3f 100644 --- a/src/CurveCreator/CurveCreator_Utils.hxx +++ b/src/CurveCreator/CurveCreator_Utils.hxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -133,10 +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