mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-29 02:40:36 +05:00
620 lines
19 KiB
C++
620 lines
19 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_Diff.cxx
|
|
// Author: Sergey KHROMOV
|
|
|
|
#include "CurveCreator_Diff.hxx"
|
|
#include "CurveCreator_Curve.hxx"
|
|
|
|
#include <list>
|
|
|
|
//=======================================================================
|
|
// function: Constructor
|
|
// purpose:
|
|
//=======================================================================
|
|
CurveCreator_Diff::CurveCreator_Diff()
|
|
: myNbUndos (0),
|
|
myPUndo (NULL),
|
|
myPRedo (NULL)
|
|
{
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: Destructor
|
|
// purpose:
|
|
//=======================================================================
|
|
CurveCreator_Diff::~CurveCreator_Diff()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: init
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve)
|
|
{
|
|
CurveCreator_Operation::Type aType = CurveCreator_Operation::Clear;
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(aType)) {
|
|
isOK = true;
|
|
|
|
const int aNbSections = theCurve->getNbSections();
|
|
|
|
// Construct undo for Clear command.
|
|
if (aNbSections > 0) {
|
|
setNbUndos(aNbSections);
|
|
|
|
for (int i = 0; i < aNbSections && isOK; i++) {
|
|
// Add AddSection command.
|
|
isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isOK) {
|
|
clear();
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: init
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const int theIntParam)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theIntParam)) {
|
|
// Construct undo for RemoveSection command.
|
|
// If the last section is removed, one AddSection command is enough.
|
|
// If not last section is removed, two commands are requred: AddSection
|
|
// and MoveSection.
|
|
const int aLastIndex = theCurve->getNbSections() - 1;
|
|
|
|
if (theIntParam == aLastIndex) {
|
|
setNbUndos(1);
|
|
} else {
|
|
setNbUndos(2);
|
|
}
|
|
|
|
isOK = addSectionToUndo(theCurve, theIntParam, myPUndo[0]);
|
|
|
|
if (isOK && theIntParam != aLastIndex) {
|
|
isOK = myPUndo[1].init(CurveCreator_Operation::MoveSection,
|
|
aLastIndex, theIntParam);
|
|
}
|
|
}
|
|
|
|
if (!isOK) {
|
|
clear();
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: init
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const int theIntParam1,
|
|
const int theIntParam2)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theIntParam1, theIntParam2)) {
|
|
// Construct undo for different commands.
|
|
switch (theType) {
|
|
case CurveCreator_Operation::SetType:
|
|
case CurveCreator_Operation::SetClosed:
|
|
isOK = setTypeOrClosedToUndo
|
|
(theCurve, theType, theIntParam1, theIntParam2);
|
|
break;
|
|
case CurveCreator_Operation::MoveSection:
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(theType, theIntParam2, theIntParam1);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isOK) {
|
|
clear();
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: init
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const std::list<int>& theParams)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL || theParams.empty()) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theParams)) {
|
|
// Construct undo for different commands.
|
|
switch (theType) {
|
|
case CurveCreator_Operation::Join:
|
|
{
|
|
int aSectionMain = theParams.front();
|
|
const int aNbPointsMain = theCurve->getNbPoints(aSectionMain);
|
|
|
|
std::list<int> aSectionsToJoin = theParams;
|
|
aSectionsToJoin.erase( aSectionsToJoin.begin() );
|
|
// it is important to sort the section indices in order to correct perform undo
|
|
// for the move sections to the previous positions
|
|
aSectionsToJoin.sort();
|
|
// 1rst undo for remove points from the main and n-1 undoes to contain joined sections
|
|
int aSectionsToJoinNb = aSectionsToJoin.size();
|
|
int aNbUndos = 2*aSectionsToJoinNb + 1;
|
|
setNbUndos( aNbUndos );
|
|
|
|
// Add joined sections to undo
|
|
std::list<int>::const_iterator anIt = aSectionsToJoin.begin(),
|
|
aLast = aSectionsToJoin.end();
|
|
anIt = aSectionsToJoin.begin();
|
|
int aLastSectionId = -1;
|
|
for (int i = 0; anIt != aLast && i < aSectionsToJoinNb; anIt++, i++) {
|
|
int anISection = *anIt;
|
|
isOK = addSectionToUndo( theCurve, anISection, myPUndo[i*2] );
|
|
if (isOK) {
|
|
isOK = myPUndo[i*2+1].init(CurveCreator_Operation::MoveSection,
|
|
aLastSectionId, anISection);
|
|
if (!isOK)
|
|
break;
|
|
}
|
|
}
|
|
// Construct undo for RemovePoints command.
|
|
if (isOK) {
|
|
int aNbPointsInJoined = 0;
|
|
anIt = aSectionsToJoin.begin();
|
|
for ( ; anIt != aLast; anIt++ )
|
|
aNbPointsInJoined += theCurve->getNbPoints( *anIt );
|
|
|
|
int aJoinedSize = aNbPointsMain + aNbPointsInJoined;
|
|
CurveCreator_ICurve::SectionToPointList aSectionToPointList;
|
|
for (int anIPoint = aNbPointsMain; anIPoint < aJoinedSize; anIPoint++)
|
|
aSectionToPointList.push_back(std::make_pair(aSectionMain, anIPoint));
|
|
|
|
isOK = myPUndo[aNbUndos-1].init(CurveCreator_Operation::RemovePoints, aSectionToPointList);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isOK) {
|
|
clear();
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: init
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const std::string& theName,
|
|
const CurveCreator::Coordinates &theCoords,
|
|
const int theIntParam1,
|
|
const int theIntParam2)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theName, theCoords, theIntParam1, theIntParam2)) {
|
|
// Construct undo for different commands.
|
|
switch (theType) {
|
|
case CurveCreator_Operation::AddSection:
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::RemoveSection, -1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if( !isOK )
|
|
clear();
|
|
return isOK;
|
|
}
|
|
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const std::string &theName,
|
|
const int theIntParam1 )
|
|
{
|
|
bool isOK = false;
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theName, theIntParam1 )) {
|
|
// Construct undo for different commands.
|
|
switch (theType) {
|
|
case CurveCreator_Operation::RenameSection:
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
|
|
theCurve->getSectionName(theIntParam1), theIntParam1);
|
|
break;
|
|
}
|
|
}
|
|
if( !isOK ){
|
|
clear();
|
|
}
|
|
return isOK;
|
|
}
|
|
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const CurveCreator_ICurve::SectionToPointList &theParamList1)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theParamList1)) {
|
|
// Construct undo for different commands.
|
|
switch (theType) {
|
|
case CurveCreator_Operation::RemovePoints:
|
|
{
|
|
// Construct undo for RemovePoints command.
|
|
CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointCoords;
|
|
CurveCreator::Coordinates aPointsToAdd;
|
|
const CurveCreator::Dimension aDim = theCurve->getDimension();
|
|
CurveCreator_ICurve::SectionToPointList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
|
|
std::list<int> aPoints;
|
|
int aSectionId, aPointId;
|
|
for ( ; anIt != aLast; anIt++ ) {
|
|
aPointsToAdd.clear();
|
|
aSectionId = anIt->first;
|
|
aPointId = anIt->second;
|
|
const CurveCreator::Coordinates &aPoints =
|
|
theCurve->getPoints(aSectionId);
|
|
CurveCreator::Coordinates::const_iterator anIterBegin =
|
|
aPoints.begin() + (aDim*aPointId);
|
|
CurveCreator::Coordinates::const_iterator anIterEnd =
|
|
anIterBegin + aDim;
|
|
aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
|
|
aSectionToPointCoords.push_back(std::make_pair(*anIt, aPointsToAdd));
|
|
}
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
|
|
aSectionToPointCoords);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isOK) {
|
|
clear();
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|
|
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theParamList1)) {
|
|
// Construct undo for different commands.
|
|
switch (theType) {
|
|
case CurveCreator_Operation::InsertPoints:
|
|
{
|
|
// Construct undo for RemovePoints command.
|
|
CurveCreator_ICurve::SectionToPointList aSectionToPointList;
|
|
CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
|
|
for ( ; anIt != aLast; anIt++ ) {
|
|
aSectionToPointList.push_back(anIt->first);
|
|
}
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
|
|
aSectionToPointList);
|
|
}
|
|
break;
|
|
case CurveCreator_Operation::SetCoordinates:
|
|
{
|
|
// Construct undo for SetCoordinates command.
|
|
CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointOldCoords;
|
|
CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
|
|
for ( ; anIt != aLast; anIt++ ) {
|
|
CurveCreator::Coordinates anOldCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
|
|
aSectionToPointOldCoords.push_back(std::make_pair(anIt->first, anOldCoords));
|
|
}
|
|
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
|
|
aSectionToPointOldCoords);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isOK) {
|
|
clear();
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|
|
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL && theOldParamList.size() > 0) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
// Construct redo for SetCoordinates command.
|
|
CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointActualCoords;
|
|
CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt =
|
|
theOldParamList.begin(), aLast = theOldParamList.end();
|
|
for ( ; anIt != aLast; anIt++ ) {
|
|
CurveCreator::Coordinates anActualCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
|
|
aSectionToPointActualCoords.push_back(std::make_pair(anIt->first, anActualCoords));
|
|
}
|
|
|
|
if (myPRedo->init(CurveCreator_Operation::SetCoordinates, aSectionToPointActualCoords)) {
|
|
// Undo for SetCoordinates command.
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
|
|
theOldParamList);
|
|
}
|
|
|
|
if (!isOK) {
|
|
clear();
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: applyUndo
|
|
// purpose:
|
|
//=======================================================================
|
|
void CurveCreator_Diff::applyUndo(CurveCreator_Curve *theCurve)
|
|
{
|
|
if (myNbUndos > 0 && myPUndo != NULL) {
|
|
for (int i = 0; i < myNbUndos; i++) {
|
|
myPUndo[i].apply(theCurve);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: applyRedo
|
|
// purpose:
|
|
//=======================================================================
|
|
void CurveCreator_Diff::applyRedo(CurveCreator_Curve *theCurve)
|
|
{
|
|
if (myPRedo != NULL) {
|
|
myPRedo->apply(theCurve);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: clear
|
|
// purpose:
|
|
//=======================================================================
|
|
void CurveCreator_Diff::clear()
|
|
{
|
|
if (myPUndo != NULL) {
|
|
delete [] myPUndo;
|
|
myPUndo = NULL;
|
|
}
|
|
|
|
myNbUndos = 0;
|
|
|
|
if (myPRedo != NULL) {
|
|
delete myPRedo;
|
|
myPRedo = NULL;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: setNbUndos
|
|
// purpose:
|
|
//=======================================================================
|
|
void CurveCreator_Diff::setNbUndos(const int theNbUndos)
|
|
{
|
|
myNbUndos = theNbUndos;
|
|
myPUndo = new CurveCreator_Operation[myNbUndos];
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: getSectionIndex
|
|
// purpose:
|
|
//=======================================================================
|
|
int CurveCreator_Diff::getSectionIndex(const CurveCreator_Curve *theCurve,
|
|
const int theIndex) const
|
|
{
|
|
return (theIndex == -1 ? theCurve->getNbSections() - 1 : theIndex);
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: addSectionToUndo
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::addSectionToUndo
|
|
(const CurveCreator_Curve *theCurve,
|
|
const int theIndex,
|
|
CurveCreator_Operation &theOperation) const
|
|
{
|
|
const std::string aName = theCurve->getSectionName(theIndex);
|
|
const CurveCreator::Coordinates &aPnts = theCurve->getPoints(theIndex);
|
|
const CurveCreator::SectionType aType = theCurve->getSectionType(theIndex);
|
|
const bool isClosed = theCurve->isClosed(theIndex);
|
|
|
|
bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
|
|
aName, aPnts, aType, isClosed);
|
|
|
|
return isOK;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: setTypeOrClosedToUndo
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::setTypeOrClosedToUndo
|
|
(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const int theIntParam1,
|
|
const int theIntParam2)
|
|
{
|
|
bool isOK = true;
|
|
|
|
// Compute number of modified sections.
|
|
const bool isSetType = (theType == CurveCreator_Operation::SetType);
|
|
int aNbModif = 0;
|
|
std::list<int> aListOfInd;
|
|
int aValue;
|
|
int i;
|
|
|
|
if (theIntParam2 == -1) {
|
|
// The operation is applied to all sections. We need to collect
|
|
// really modified sections for undo.
|
|
const int aNbSections = theCurve->getNbSections();
|
|
|
|
if (aNbSections > 0) {
|
|
// Get sections to be modified.
|
|
for (i = 0; i < aNbSections; i++) {
|
|
if (isSetType) {
|
|
aValue = theCurve->getSectionType(i);
|
|
} else {
|
|
aValue = theCurve->isClosed(i);
|
|
}
|
|
|
|
if (theIntParam1 != aValue) {
|
|
aNbModif++;
|
|
aListOfInd.push_back(i);
|
|
}
|
|
}
|
|
|
|
if (aNbSections == aNbModif) {
|
|
// All sections are modified. We can use one single command
|
|
// with -1 section index.
|
|
aNbModif = 1;
|
|
aListOfInd.clear();
|
|
aListOfInd.push_back(-1);
|
|
}
|
|
}
|
|
} else {
|
|
// There is only particular section modified.
|
|
// Check if there is a real modification required.
|
|
if (isSetType) {
|
|
aValue = theCurve->getSectionType(theIntParam2);
|
|
} else {
|
|
aValue = theCurve->isClosed(theIntParam2);
|
|
}
|
|
|
|
if (theIntParam1 != aValue) {
|
|
aNbModif = 1;
|
|
aListOfInd.push_back(theIntParam2);
|
|
}
|
|
}
|
|
|
|
if (aNbModif > 0) {
|
|
// Store the undos
|
|
std::list<int>::iterator anIter = aListOfInd.begin();
|
|
|
|
if (isSetType) {
|
|
aValue = theCurve->getSectionType(*anIter);
|
|
} else {
|
|
aValue = theCurve->isClosed(*anIter);
|
|
}
|
|
|
|
setNbUndos(aNbModif);
|
|
|
|
for (i = 0; anIter != aListOfInd.end() && isOK; i++, anIter++) {
|
|
isOK = myPUndo[i].init(theType, aValue, *anIter);
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|