mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-30 19:30:36 +05:00
589 lines
18 KiB
C++
589 lines
18 KiB
C++
// Copyright (C) 2013 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.
|
|
//
|
|
// 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,
|
|
const CurveCreator_Operation::Type theType)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType)) {
|
|
isOK = true;
|
|
|
|
const int aNbSections = theCurve->getNbSections();
|
|
|
|
if (theType == CurveCreator_Operation::Clear) {
|
|
// 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]);
|
|
}
|
|
}
|
|
} else { // theType == CurveCreator_Operation::Join
|
|
// Construct undo for Join command.
|
|
if (aNbSections > 1) {
|
|
// Add the RemovePoints command to remove points of
|
|
// the second section fron the first one.
|
|
const int aNbPoints = theCurve->getNbPoints(0);
|
|
|
|
setNbUndos(aNbSections);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
|
|
0, aNbPoints, -1);
|
|
|
|
for (int i = 1; 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;
|
|
case CurveCreator_Operation::Join:
|
|
{
|
|
// 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;
|
|
const int aNbPoints = theCurve->getNbPoints(theIntParam1);
|
|
|
|
if (theIntParam2 == aLastIndex) {
|
|
setNbUndos(2);
|
|
} else {
|
|
setNbUndos(3);
|
|
}
|
|
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
|
|
theIntParam1, aNbPoints, -1);
|
|
|
|
if (isOK) {
|
|
isOK = addSectionToUndo(theCurve, theIntParam2, myPUndo[1]);
|
|
|
|
if (isOK && theIntParam2 != aLastIndex) {
|
|
isOK = myPUndo[2].init(CurveCreator_Operation::MoveSection,
|
|
aLastIndex, theIntParam2);
|
|
}
|
|
}
|
|
}
|
|
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 int theIntParam1,
|
|
const int theIntParam2,
|
|
const int theIntParam3)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theIntParam1, theIntParam2, theIntParam3)) {
|
|
// Construct undo for RemovePoints command.
|
|
const CurveCreator::Dimension aDim = theCurve->getDimension();
|
|
const CurveCreator::Coordinates &aPoints =
|
|
theCurve->getPoints(theIntParam1);
|
|
CurveCreator::Coordinates::const_iterator anIterBegin =
|
|
aPoints.begin() + (aDim*theIntParam2);
|
|
CurveCreator::Coordinates::const_iterator anIterEnd;
|
|
|
|
if (theIntParam3 == -1) {
|
|
anIterEnd = aPoints.end();
|
|
} else {
|
|
anIterEnd = anIterBegin + (aDim*theIntParam3);
|
|
}
|
|
|
|
CurveCreator::Coordinates aPointsToAdd;
|
|
|
|
setNbUndos(1);
|
|
aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
|
|
aPointsToAdd, theIntParam1, theIntParam2);
|
|
}
|
|
|
|
if (!isOK) {
|
|
clear();
|
|
}
|
|
}
|
|
|
|
return isOK;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: init
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
const CurveCreator::Coordinates &theCoords,
|
|
const int theIntParam)
|
|
{
|
|
bool isOK = false;
|
|
|
|
if (theCurve != NULL) {
|
|
clear();
|
|
|
|
// Set redo.
|
|
myPRedo = new CurveCreator_Operation;
|
|
|
|
if (myPRedo->init(theType, theCoords, theIntParam)) {
|
|
// Construct undo for AddPoints command.
|
|
const int aSectionInd = getSectionIndex(theCurve, theIntParam);
|
|
const CurveCreator::Dimension aDim = theCurve->getDimension();
|
|
const CurveCreator::Coordinates &aPoints =
|
|
theCurve->getPoints(aSectionInd);
|
|
const int aNbPoints = (aPoints.size()/aDim);
|
|
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
|
|
aSectionInd, aNbPoints, -1);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: init
|
|
// purpose:
|
|
//=======================================================================
|
|
bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
|
|
const CurveCreator_Operation::Type theType,
|
|
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, theCoords, theIntParam1, theIntParam2)) {
|
|
// Construct undo for different commands.
|
|
switch (theType) {
|
|
case CurveCreator_Operation::InsertPoints:
|
|
{
|
|
const CurveCreator::Dimension aDim = theCurve->getDimension();
|
|
const int aNbPoints = (theCoords.size()/aDim);
|
|
const int aSectionInd = getSectionIndex(theCurve, theIntParam1);
|
|
int aPointInd;
|
|
|
|
if (theIntParam2 == -1) {
|
|
aPointInd = theCurve->getNbPoints(aSectionInd);
|
|
} else {
|
|
aPointInd = theIntParam2;
|
|
}
|
|
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
|
|
aSectionInd, aPointInd, aNbPoints);
|
|
}
|
|
break;
|
|
case CurveCreator_Operation::SetCoordinates:
|
|
{
|
|
const CurveCreator::Coordinates anOldCoords =
|
|
theCurve->getCoordinates(theIntParam1, theIntParam2);
|
|
|
|
setNbUndos(1);
|
|
isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
|
|
anOldCoords, theIntParam1, theIntParam2);
|
|
}
|
|
break;
|
|
default:
|
|
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;
|
|
}
|
|
|
|
//=======================================================================
|
|
// 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 CurveCreator::Coordinates &aPnts = theCurve->getPoints(theIndex);
|
|
const CurveCreator::Type aType = theCurve->getType(theIndex);
|
|
const bool isClosed = theCurve->isClosed(theIndex);
|
|
|
|
bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
|
|
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->getType(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->getType(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->getType(*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;
|
|
}
|