mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-30 19:30:36 +05:00
1038 lines
30 KiB
C++
1038 lines
30 KiB
C++
// 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_Curve.cxx
|
|
// Author: Sergey KHROMOV
|
|
|
|
#include "CurveCreator_Curve.hxx"
|
|
|
|
#include "CurveCreator.hxx"
|
|
#include "CurveCreator_PosPoint.hxx"
|
|
#include "CurveCreator_Section.hxx"
|
|
#include "CurveCreator_Displayer.hxx"
|
|
#include "CurveCreator_Utils.hxx"
|
|
|
|
#include <AIS_Shape.hxx>
|
|
#include <AIS_InteractiveObject.hxx>
|
|
#include <Geom_CartesianPoint.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Lin.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Wire.hxx>
|
|
|
|
#include <stdio.h>
|
|
|
|
//=======================================================================
|
|
// function: Constructor
|
|
// purpose:
|
|
//=======================================================================
|
|
CurveCreator_Curve::CurveCreator_Curve( const CurveCreator::Dimension theDimension )
|
|
: myIsLocked (false),
|
|
myDimension (theDimension),
|
|
myDisplayer (NULL),
|
|
myAISShape (NULL),
|
|
myNbUndos (0),
|
|
myNbRedos (0),
|
|
myUndoDepth (-1),
|
|
myOpLevel(0),
|
|
mySkipSorting(false)
|
|
{
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: Destructor
|
|
// purpose:
|
|
//=======================================================================
|
|
CurveCreator_Curve::~CurveCreator_Curve()
|
|
{
|
|
// Delete all allocated data.
|
|
clear();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: getDimension
|
|
// purpose:
|
|
//=======================================================================
|
|
CurveCreator::Dimension CurveCreator_Curve::getDimension() const
|
|
{
|
|
return myDimension;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: getUniqSectionName
|
|
// purpose: return unique section name
|
|
//=======================================================================
|
|
std::string CurveCreator_Curve::getUniqSectionName() const
|
|
{
|
|
CurveCreator_Section* aSection;
|
|
for( int i = 0 ; i < 1000000 ; i++ ){
|
|
char aBuffer[255];
|
|
sprintf( aBuffer, "Section_%d", i+1 );
|
|
std::string aName(aBuffer);
|
|
int j;
|
|
for( j = 0 ; j < mySections.size() ; j++ ){
|
|
aSection = getSection( j );
|
|
if ( aSection && aSection->myName == aName )
|
|
break;
|
|
}
|
|
if( j == mySections.size() )
|
|
return aName;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: setDisplayer
|
|
// purpose: set curve changes Displayer
|
|
//=======================================================================
|
|
void CurveCreator_Curve::setDisplayer( CurveCreator_Displayer* theDisplayer )
|
|
{
|
|
myDisplayer = theDisplayer;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: getDisplayer
|
|
// purpose: get curve changes Displayer
|
|
//=======================================================================
|
|
CurveCreator_Displayer* CurveCreator_Curve::getDisplayer()
|
|
{
|
|
return myDisplayer;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: removeDisplayer
|
|
// purpose: remove the attached Displayer
|
|
//=======================================================================
|
|
void CurveCreator_Curve::removeDisplayer()
|
|
{
|
|
myDisplayer = NULL;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: addDiff
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Curve::addEmptyDiff()
|
|
{
|
|
bool isEnabled = false;
|
|
|
|
if (myUndoDepth != 0) {
|
|
// Forget all Redos after the current one.
|
|
if (myNbRedos > 0) {
|
|
myNbRedos = 0;
|
|
myListDiffs.erase(myCurrenPos, myListDiffs.end());
|
|
}
|
|
|
|
if (myUndoDepth == -1 || myNbUndos < myUndoDepth) {
|
|
// Increase the number of undos.
|
|
myNbUndos++;
|
|
} else {
|
|
// If there are too many differences, remove the first one.
|
|
myListDiffs.pop_front();
|
|
}
|
|
|
|
// Add new difference.
|
|
myListDiffs.push_back(CurveCreator_Diff());
|
|
myCurrenPos = myListDiffs.end();
|
|
isEnabled = true;
|
|
}
|
|
|
|
return isEnabled;
|
|
}
|
|
|
|
void CurveCreator_Curve::startOperation()
|
|
{
|
|
myOpLevel++;
|
|
}
|
|
|
|
void CurveCreator_Curve::finishOperation()
|
|
{
|
|
myOpLevel--;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: toICoord
|
|
// purpose:
|
|
//=======================================================================
|
|
int CurveCreator_Curve::toICoord(const int theIPnt) const
|
|
{
|
|
return theIPnt * myDimension;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: setUndoDepth
|
|
// purpose:
|
|
//=======================================================================
|
|
void CurveCreator_Curve::setUndoDepth(const int theDepth)
|
|
{
|
|
if (theDepth == 0) {
|
|
// Reset all undo/redo data.
|
|
myNbUndos = 0;
|
|
myNbRedos = 0;
|
|
myListDiffs.clear();
|
|
myCurrenPos = myListDiffs.end();
|
|
myUndoDepth = 0;
|
|
} else if (theDepth == -1) {
|
|
// There is nothing to do as the depth become unlimited.
|
|
myUndoDepth = -1;
|
|
} else if (theDepth > 0) {
|
|
// The new "real" depth is set.
|
|
if (theDepth < myNbRedos) {
|
|
// The new depth is less then number of redos. Remove the latest redos.
|
|
int aShift = (myNbRedos - theDepth);
|
|
ListDiff::iterator aFromPos = myListDiffs.end();
|
|
|
|
while (aShift--) {
|
|
aFromPos--;
|
|
}
|
|
|
|
myListDiffs.erase(aFromPos, myListDiffs.end());
|
|
myNbRedos = theDepth;
|
|
}
|
|
|
|
if (theDepth < myNbUndos + myNbRedos) {
|
|
// The new depth is less then the total number of differences.
|
|
// Remove the first undos.
|
|
int aShift = (myNbUndos + myNbRedos - theDepth);
|
|
ListDiff::iterator aToPos = myListDiffs.begin();
|
|
|
|
while (aShift--) {
|
|
aToPos++;
|
|
}
|
|
|
|
myListDiffs.erase(myListDiffs.begin(), aToPos);
|
|
myNbUndos = theDepth - myNbRedos;
|
|
}
|
|
|
|
myUndoDepth = theDepth;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: getUndoDepth
|
|
// purpose:
|
|
//=======================================================================
|
|
int CurveCreator_Curve::getUndoDepth() const
|
|
{
|
|
return myUndoDepth;
|
|
}
|
|
|
|
void CurveCreator_Curve::getCoordinates( int theISection, int theIPoint, double& theX, double& theY, double& theZ ) const
|
|
{
|
|
CurveCreator::Coordinates aCoords = getPoint( theISection, theIPoint );
|
|
theX = aCoords[0];
|
|
theY = aCoords[1];
|
|
theZ = 0.;
|
|
if( getDimension() == CurveCreator::Dim3d ){
|
|
theZ = aCoords[2];
|
|
}
|
|
}
|
|
|
|
void CurveCreator_Curve::redisplayCurve()
|
|
{
|
|
if( myDisplayer ) {
|
|
myDisplayer->eraseAll( false );
|
|
myAISShape = NULL;
|
|
|
|
myDisplayer->display( getAISObject( true ), true );
|
|
}
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::moveSectionInternal(const int theISection,
|
|
const int theNewIndex)
|
|
{
|
|
bool res = false;
|
|
int aMovedSectionId = theISection >= 0 ? theISection : mySections.size()-1;
|
|
|
|
if (aMovedSectionId != theNewIndex) {
|
|
CurveCreator_Section* aSection = getSection( aMovedSectionId );
|
|
|
|
// Remove section
|
|
CurveCreator::Sections::iterator anIter = mySections.begin() + aMovedSectionId;
|
|
|
|
mySections.erase(anIter);
|
|
|
|
// Insert section.
|
|
anIter = mySections.begin() + theNewIndex;
|
|
mySections.insert(anIter, aSection);
|
|
res = true;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: moveSection
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Curve::moveSection(const int theISection,
|
|
const int theNewIndex)
|
|
{
|
|
bool res = false;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::MoveSection,
|
|
theISection, theNewIndex);
|
|
}
|
|
|
|
// Update the curve.
|
|
res = moveSectionInternal(theISection, theNewIndex);
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
/************ Implementation of INTERFACE methods ************/
|
|
|
|
/***********************************************/
|
|
/*** Undo/Redo methods ***/
|
|
/***********************************************/
|
|
|
|
//! Get number of available undo operations
|
|
int CurveCreator_Curve::getNbUndo() const
|
|
{
|
|
return myNbUndos;
|
|
}
|
|
|
|
//! Undo previous operation
|
|
bool CurveCreator_Curve::undo()
|
|
{
|
|
bool res = false;
|
|
if (myNbUndos > 0) {
|
|
myNbUndos--;
|
|
myNbRedos++;
|
|
myCurrenPos--;
|
|
myCurrenPos->applyUndo(this);
|
|
res = true;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
//! Get number of available redo operations
|
|
int CurveCreator_Curve::getNbRedo() const
|
|
{
|
|
return myNbRedos;
|
|
}
|
|
|
|
//! Redo last previously "undone" operation
|
|
bool CurveCreator_Curve::redo()
|
|
{
|
|
bool res = false;
|
|
if (myNbRedos > 0) {
|
|
myCurrenPos->applyRedo(this);
|
|
myCurrenPos++;
|
|
myNbRedos--;
|
|
myNbUndos++;
|
|
res = true;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/***********************************************/
|
|
/*** Section methods ***/
|
|
/***********************************************/
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::clearInternal()
|
|
{
|
|
// erase curve from the viewer
|
|
if( myDisplayer ) {
|
|
myDisplayer->eraseAll( true );
|
|
myAISShape = NULL;
|
|
}
|
|
// Delete all allocated data.
|
|
int i = 0;
|
|
const int aNbSections = getNbSections();
|
|
|
|
CurveCreator_Section* aSection;
|
|
for (; i < aNbSections; i++) {
|
|
aSection = getSection( i );
|
|
if ( aSection )
|
|
delete aSection;
|
|
}
|
|
|
|
mySections.clear();
|
|
|
|
return true;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: clear
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Curve::clear()
|
|
{
|
|
bool res = false;
|
|
startOperation();
|
|
// Set the difference.
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this);
|
|
}
|
|
res = clearInternal();
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::joinInternal( const std::list<int>& theSections )
|
|
{
|
|
bool res = false;
|
|
if ( theSections.empty() )
|
|
return res;
|
|
|
|
int anISectionMain = theSections.front();
|
|
CurveCreator_Section* aSectionMain = getSection( anISectionMain );
|
|
|
|
std::list <int> aSectionsToJoin = theSections;
|
|
aSectionsToJoin.erase( aSectionsToJoin.begin() ); // skip the main section
|
|
// it is important to sort and reverse the section ids in order to correctly remove them
|
|
aSectionsToJoin.sort();
|
|
aSectionsToJoin.reverse();
|
|
|
|
std::list<int>::const_iterator anIt = aSectionsToJoin.begin(), aLast = aSectionsToJoin.end();
|
|
CurveCreator_Section* aSection;
|
|
for (; anIt != aLast; anIt++) {
|
|
aSection = getSection( *anIt );
|
|
aSectionMain->myPoints.insert(aSectionMain->myPoints.end(), aSection->myPoints.begin(),
|
|
aSection->myPoints.end());
|
|
res = removeSectionInternal(*anIt);
|
|
if ( !res )
|
|
break;
|
|
}
|
|
|
|
redisplayCurve();
|
|
return res;
|
|
}
|
|
|
|
bool CurveCreator_Curve::join( const std::list<int>& theSections )
|
|
{
|
|
bool res = false;
|
|
|
|
if ( !theSections.empty() )
|
|
{
|
|
startOperation();
|
|
if (addEmptyDiff())
|
|
myListDiffs.back().init(this, CurveCreator_Operation::Join, theSections);
|
|
|
|
res = joinInternal( theSections );
|
|
|
|
finishOperation();
|
|
}
|
|
return res;
|
|
}
|
|
|
|
//! Get number of sections
|
|
int CurveCreator_Curve::getNbSections() const
|
|
{
|
|
return mySections.size();
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
int CurveCreator_Curve::addSectionInternal
|
|
(const std::string& theName, const CurveCreator::SectionType theType,
|
|
const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
|
|
{
|
|
CurveCreator_Section *aSection = new CurveCreator_Section;
|
|
|
|
std::string aName = theName;
|
|
if( aName.empty() ){
|
|
aName = getUniqSectionName();
|
|
}
|
|
aSection->myName = aName;
|
|
aSection->myType = theType;
|
|
aSection->myIsClosed = theIsClosed;
|
|
aSection->myPoints = thePoints;
|
|
mySections.push_back(aSection);
|
|
redisplayCurve();
|
|
return mySections.size()-1;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: addSection
|
|
// purpose: adds an empty section
|
|
//=======================================================================
|
|
int CurveCreator_Curve::addSection
|
|
(const std::string& theName, const CurveCreator::SectionType theType,
|
|
const bool theIsClosed)
|
|
{
|
|
int resISection = -1;
|
|
// Set the difference.
|
|
startOperation();
|
|
CurveCreator::Coordinates aCoords; //empty list
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
|
|
theName, aCoords, theType, theIsClosed);
|
|
}
|
|
|
|
resISection = addSectionInternal(theName, theType, theIsClosed, aCoords);
|
|
|
|
finishOperation();
|
|
return resISection;
|
|
}
|
|
//=======================================================================
|
|
// function: addSection
|
|
// purpose: adds a section with the given points
|
|
//=======================================================================
|
|
int CurveCreator_Curve::addSection
|
|
(const std::string& theName, const CurveCreator::SectionType theType,
|
|
const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
|
|
{
|
|
int resISection = -1;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
|
|
theName, thePoints, theType, theIsClosed);
|
|
}
|
|
|
|
resISection = addSectionInternal(theName, theType, theIsClosed, thePoints);
|
|
|
|
finishOperation();
|
|
return resISection;
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::removeSectionInternal( const int theISection )
|
|
{
|
|
if (theISection == -1) {
|
|
delete mySections.back();
|
|
mySections.pop_back();
|
|
} else {
|
|
CurveCreator::Sections::iterator anIterRm = mySections.begin() + theISection;
|
|
|
|
delete *anIterRm;
|
|
mySections.erase(anIterRm);
|
|
}
|
|
redisplayCurve();
|
|
return true;
|
|
}
|
|
|
|
//! Removes the given sections.
|
|
bool CurveCreator_Curve::removeSection( const int theISection )
|
|
{
|
|
bool res = false;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff())
|
|
myListDiffs.back().init(this, CurveCreator_Operation::RemoveSection, theISection);
|
|
|
|
res = removeSectionInternal( theISection );
|
|
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* Get number of points in specified section or (the total number of points
|
|
* in Curve if theISection is equal to -1).
|
|
*/
|
|
int CurveCreator_Curve::getNbPoints( const int theISection ) const
|
|
{
|
|
int aNbCoords = 0;
|
|
|
|
CurveCreator_Section* aSection;
|
|
if (theISection == -1) {
|
|
int i = 0;
|
|
const int aNbSections = getNbSections();
|
|
|
|
for (; i < aNbSections; i++) {
|
|
aSection = getSection( i );
|
|
if ( aSection )
|
|
aNbCoords += aSection->myPoints.size();
|
|
}
|
|
} else {
|
|
aSection = getSection( theISection );
|
|
if ( aSection )
|
|
aNbCoords = aSection->myPoints.size();
|
|
}
|
|
|
|
return aNbCoords/myDimension;
|
|
}
|
|
|
|
void CurveCreator_Curve::setSkipSorting( const bool theIsToSkip )
|
|
{
|
|
mySkipSorting = theIsToSkip;
|
|
}
|
|
|
|
bool CurveCreator_Curve::canPointsBeSorted()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Saves points coordinates difference.
|
|
* \param theOldCoords the old points coordinates
|
|
*/
|
|
void CurveCreator_Curve::saveCoordDiff( const SectionToPointCoordsList &theOldCoords )
|
|
{
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, theOldCoords);
|
|
}
|
|
finishOperation();
|
|
}
|
|
|
|
//! Get "closed" flag of the specified section
|
|
bool CurveCreator_Curve::isClosed( const int theISection ) const
|
|
{
|
|
CurveCreator_Section* aSection = getSection( theISection );
|
|
return aSection ? aSection->myIsClosed : false;
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::setClosedInternal( const int theISection,
|
|
const bool theIsClosed )
|
|
{
|
|
CurveCreator_Section* aSection = 0;
|
|
if (theISection == -1) {
|
|
int aSize = mySections.size();
|
|
int i;
|
|
|
|
for (i = 0; i < aSize; i++) {
|
|
aSection = getSection( i );
|
|
if( aSection ) {
|
|
aSection->myIsClosed = theIsClosed;
|
|
redisplayCurve();
|
|
}
|
|
}
|
|
} else {
|
|
aSection = getSection( theISection );
|
|
if ( aSection ) {
|
|
aSection->myIsClosed = theIsClosed;
|
|
redisplayCurve();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set "closed" flag of the specified section (all sections if
|
|
* \a theISection is -1).
|
|
*/
|
|
bool CurveCreator_Curve::setClosed( const int theISection,
|
|
const bool theIsClosed )
|
|
{
|
|
bool res = false;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::SetClosed,
|
|
theIsClosed, theISection);
|
|
}
|
|
res = setClosedInternal( theISection, theIsClosed );
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
//! Returns specified section name
|
|
std::string CurveCreator_Curve::getSectionName( const int theISection ) const
|
|
{
|
|
CurveCreator_Section* aSection = getSection( theISection );
|
|
return aSection ? aSection->myName : "";
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::setSectionNameInternal( const int theISection,
|
|
const std::string& theName )
|
|
{
|
|
bool res = false;
|
|
CurveCreator_Section* aSection = getSection( theISection );
|
|
if( aSection ) {
|
|
aSection->myName = theName;
|
|
res = true;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/** Set name of the specified section */
|
|
bool CurveCreator_Curve::setSectionName( const int theISection,
|
|
const std::string& theName )
|
|
{
|
|
bool res = false;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::RenameSection,
|
|
theName, theISection);
|
|
}
|
|
res = setSectionNameInternal( theISection, theName );
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
//! Get type of the specified section
|
|
CurveCreator::SectionType CurveCreator_Curve::getSectionType
|
|
( const int theISection ) const
|
|
{
|
|
CurveCreator_Section* aSection = getSection( theISection );
|
|
return aSection ? aSection->myType : CurveCreator::Polyline;
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::setSectionTypeInternal( const int theISection,
|
|
const CurveCreator::SectionType theType )
|
|
{
|
|
CurveCreator_Section* aSection;
|
|
if (theISection == -1) {
|
|
int i = 0;
|
|
const int aNbSections = getNbSections();
|
|
|
|
for (; i < aNbSections; i++) {
|
|
aSection = getSection( i );
|
|
if ( aSection )
|
|
aSection->myType = theType;
|
|
}
|
|
redisplayCurve();
|
|
} else {
|
|
aSection = getSection( theISection );
|
|
if ( aSection && aSection->myType != theType ){
|
|
aSection->myType = theType;
|
|
redisplayCurve();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set type of the specified section (or all sections
|
|
* if \a theISection is -1).
|
|
*/
|
|
bool CurveCreator_Curve::setSectionType( const int theISection,
|
|
const CurveCreator::SectionType theType )
|
|
{
|
|
bool res = false;
|
|
startOperation();
|
|
// Set the difference.
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::SetType,
|
|
theType, theISection);
|
|
}
|
|
|
|
res = setSectionTypeInternal( theISection, theType );
|
|
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
|
|
/***********************************************/
|
|
/*** Point methods ***/
|
|
/***********************************************/
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::addPointsInternal( const CurveCreator::SectionsMap &theSectionsMap )
|
|
{
|
|
bool res = false;
|
|
CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
|
|
CurveCreator_Section *aSection = 0;
|
|
for ( ; anIt != theSectionsMap.end(); anIt++ ) {
|
|
int anISection = anIt->first;
|
|
aSection = getSection( anISection );
|
|
if( aSection ) {
|
|
CurveCreator::PosPointsList aSectionPoints = anIt->second;
|
|
CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
|
|
for( ; aPntIt != aSectionPoints.end(); aPntIt++ ){
|
|
int anIPnt = (*aPntIt)->myID;
|
|
CurveCreator::Coordinates aCoords = (*aPntIt)->myCoords;
|
|
CurveCreator::Coordinates::iterator anIterPosition;
|
|
if(anIPnt == -1)
|
|
anIterPosition = aSection->myPoints.end();
|
|
else
|
|
anIterPosition = aSection->myPoints.begin() + toICoord(anIPnt);
|
|
CurveCreator::Coordinates::const_iterator aFirstPosition =
|
|
aCoords.begin();
|
|
aSection->myPoints.insert(anIterPosition,
|
|
aCoords.begin(), aCoords.end());
|
|
}
|
|
res = true;
|
|
}
|
|
}
|
|
if(res)
|
|
redisplayCurve();
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* Add one point to the specified section starting from the given theIPnt index
|
|
* (or at the end of points if \a theIPnt is -1).
|
|
*/
|
|
bool CurveCreator_Curve::addPoints( const CurveCreator::Coordinates& theCoords,
|
|
const int theISection,
|
|
const int theIPnt )
|
|
{
|
|
bool res = false;
|
|
CurveCreator::Coordinates aCoords = theCoords;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff()) {
|
|
CurveCreator_ICurve::SectionToPointCoordsList aList;
|
|
aList.push_back(std::make_pair(std::make_pair(theISection, theIPnt), theCoords));
|
|
myListDiffs.back().init(this, CurveCreator_Operation::InsertPoints,
|
|
aList);
|
|
}
|
|
CurveCreator::SectionsMap aSectionsMap;
|
|
CurveCreator::PosPointsList aPoints;
|
|
CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( theIPnt, theCoords );
|
|
aPoints.push_back( aPosPoint );
|
|
aSectionsMap[theISection] = aPoints;
|
|
|
|
res = addPointsInternal( aSectionsMap );
|
|
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::setPointInternal( const CurveCreator::SectionsMap &theSectionsMap )
|
|
{
|
|
bool res = false;
|
|
// Update the curve.
|
|
CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
|
|
CurveCreator_Section *aSection = 0;
|
|
for ( ; anIt != theSectionsMap.end(); anIt++ ) {
|
|
int anISection = anIt->first;
|
|
aSection = getSection( anISection );
|
|
if( aSection ) {
|
|
CurveCreator::PosPointsList aSectionPoints = anIt->second;
|
|
CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
|
|
for( ; aPntIt != aSectionPoints.end(); aPntIt++ ){
|
|
int anIPnt = (*aPntIt)->myID;
|
|
CurveCreator::Coordinates aCoords = (*aPntIt)->myCoords;
|
|
for ( int i = 0; i < myDimension; i++)
|
|
aSection->myPoints.at(toICoord(anIPnt) + i) = aCoords[i];
|
|
}
|
|
res = true;
|
|
}
|
|
}
|
|
if(res)
|
|
redisplayCurve();
|
|
|
|
return res;
|
|
}
|
|
|
|
//! Set coordinates of specified point
|
|
bool CurveCreator_Curve::setPoint( const int theISection,
|
|
const int theIPnt,
|
|
const CurveCreator::Coordinates& theNewCoords )
|
|
{
|
|
bool res = false;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff()) {
|
|
CurveCreator_ICurve::SectionToPointCoordsList aList;
|
|
aList.push_back(std::make_pair(std::make_pair(theISection, theIPnt), theNewCoords));
|
|
myListDiffs.back().init(this, CurveCreator_Operation::SetCoordinates,
|
|
aList);
|
|
}
|
|
CurveCreator::SectionsMap aSectionsMap;
|
|
CurveCreator::PosPointsList aPoints;
|
|
CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( theIPnt, theNewCoords );
|
|
aPoints.push_back( aPosPoint );
|
|
aSectionsMap[theISection] = aPoints;
|
|
|
|
int aSize1 = getNbPoints( theISection );
|
|
res = setPointInternal( aSectionsMap );
|
|
int aSize2 = getNbPoints( theISection );
|
|
|
|
finishOperation();
|
|
|
|
return res;
|
|
}
|
|
|
|
//! Set coordinates of specified points from different sections
|
|
bool CurveCreator_Curve::setSeveralPoints( const SectionToPointCoordsList &theSectionToPntCoords,
|
|
const bool theIsToSaveDiff )
|
|
{
|
|
bool res = false;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (theIsToSaveDiff && addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::SetCoordinates,
|
|
theSectionToPntCoords);
|
|
}
|
|
CurveCreator::SectionsMap aSectionsMap;
|
|
CurveCreator::PosPointsList aPosPoints;
|
|
CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt =
|
|
theSectionToPntCoords.begin(), aLast = theSectionToPntCoords.end();
|
|
int aSectionId, aPointId;
|
|
for ( ; anIt != aLast; anIt++ ) {
|
|
aPosPoints.clear();
|
|
aSectionId = anIt->first.first;
|
|
aPointId = anIt->first.second;
|
|
CurveCreator::Coordinates aNewCoords = anIt->second;
|
|
CurveCreator_PosPoint* aPosPoint =
|
|
new CurveCreator_PosPoint( aPointId, aNewCoords );
|
|
if( aSectionsMap.find(aSectionId) != aSectionsMap.end() )
|
|
aPosPoints = aSectionsMap[aSectionId];
|
|
aPosPoints.push_back( aPosPoint );
|
|
aSectionsMap[aSectionId] = aPosPoints;
|
|
|
|
}
|
|
res = setPointInternal( aSectionsMap );
|
|
finishOperation();
|
|
|
|
return res;
|
|
}
|
|
|
|
//! For internal use only! Undo/Redo are not used here.
|
|
bool CurveCreator_Curve::removePointsInternal( const SectionToPointList &thePoints )
|
|
{
|
|
bool aRes = false;
|
|
std::map<int, std::list<int> > aConvPoints;
|
|
convert( thePoints, aConvPoints );
|
|
std::map<int, std::list<int> >::const_iterator anIt = aConvPoints.begin(),
|
|
aLast = aConvPoints.end();
|
|
for ( ; anIt != aLast; anIt++ ) {
|
|
int aSectionId = anIt->first;
|
|
aRes = removeSectionPoints(aSectionId, anIt->second);
|
|
}
|
|
if( aRes)
|
|
redisplayCurve();
|
|
|
|
return aRes;
|
|
}
|
|
|
|
//! Remove point with given id
|
|
bool CurveCreator_Curve::removePoint( const int theISection, const int theIPnt )
|
|
{
|
|
bool res = false;
|
|
// Set the difference.
|
|
startOperation();
|
|
SectionToPointList aListOfSectionsToPoints;
|
|
aListOfSectionsToPoints.push_back(std::make_pair(theISection, theIPnt));
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints,
|
|
aListOfSectionsToPoints);
|
|
}
|
|
res = removePointsInternal( aListOfSectionsToPoints );
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
//! Remove several points from different sections with given ids
|
|
bool CurveCreator_Curve::removeSeveralPoints( const SectionToPointList &theSectionToPntIDs)
|
|
{
|
|
bool res = false;
|
|
// Set the difference.
|
|
startOperation();
|
|
if (addEmptyDiff()) {
|
|
myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints,
|
|
theSectionToPntIDs);
|
|
}
|
|
res = removePointsInternal( theSectionToPntIDs );
|
|
finishOperation();
|
|
return res;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: getCoordinates
|
|
// purpose:
|
|
//=======================================================================
|
|
CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection,
|
|
const int theIPnt) const
|
|
{
|
|
CurveCreator_Section* aSection = getSection( theISection );
|
|
CurveCreator::Coordinates::const_iterator
|
|
anIter = aSection->myPoints.begin() + toICoord(theIPnt);
|
|
CurveCreator::Coordinates aResult(anIter, anIter + myDimension);
|
|
|
|
return aResult;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: getPoints
|
|
// purpose:
|
|
//=======================================================================
|
|
CurveCreator::Coordinates CurveCreator_Curve::getPoints( const int theISection ) const
|
|
{
|
|
CurveCreator_Section* aSection = getSection( theISection );
|
|
return aSection ? aSection->myPoints : CurveCreator::Coordinates();
|
|
}
|
|
|
|
void CurveCreator_Curve::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 );
|
|
|
|
return aSection;
|
|
}
|
|
|
|
Handle(AIS_InteractiveObject) CurveCreator_Curve::getAISObject( const bool theNeedToBuild ) const
|
|
{
|
|
if ( !myAISShape && theNeedToBuild ) {
|
|
CurveCreator_Curve* aCurve = (CurveCreator_Curve*)this;
|
|
aCurve->constructAISObject();
|
|
}
|
|
return myAISShape;
|
|
}
|
|
|
|
bool CurveCreator_Curve::removeSectionPoints( const int theSectionId,
|
|
const std::list<int>& thePointIds )
|
|
{
|
|
bool aRes = false;
|
|
|
|
CurveCreator_Section* aSection = getSection( theSectionId );
|
|
if ( !aSection )
|
|
return aRes;
|
|
|
|
std::list<int> aSectionPoints = thePointIds;
|
|
aSectionPoints.sort();
|
|
std::list<int>::const_reverse_iterator aPntIt = aSectionPoints.rbegin();
|
|
for ( ; aPntIt != aSectionPoints.rend(); aPntIt++ ) {
|
|
int aPntIndx = *aPntIt;
|
|
CurveCreator::Coordinates::iterator aFirstPosition;
|
|
if ( aPntIndx == -1 )
|
|
aFirstPosition = aSection->myPoints.end() - getDimension();
|
|
else
|
|
aFirstPosition = aSection->myPoints.begin() + toICoord( aPntIndx );
|
|
aSection->myPoints.erase( aFirstPosition, aFirstPosition + getDimension() );
|
|
aRes = true;
|
|
}
|
|
return aRes;
|
|
}
|
|
|
|
void CurveCreator_Curve::convert( const SectionToPointList& thePoints,
|
|
std::map< int, std::list<int> >& theConvPoints )
|
|
{
|
|
theConvPoints.clear();
|
|
|
|
SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
|
|
std::list<int> aPoints;
|
|
int aSectionId, aPointId;
|
|
for ( ; anIt != aLast; anIt++ ) {
|
|
aSectionId = anIt->first;
|
|
aPointId = anIt->second;
|
|
aPoints.clear();
|
|
if ( theConvPoints.find( aSectionId ) != theConvPoints.end() )
|
|
aPoints = theConvPoints[aSectionId];
|
|
aPoints.push_back( aPointId );
|
|
theConvPoints[aSectionId] = aPoints;
|
|
}
|
|
}
|