mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-07-15 12:35:51 +03:00
Reorganizing structure to have Module/TK/Package/FILES structure. New structure reflect the structure inside IDE. Migrate FILES, PACKAGES, EXTRLIB to CMake version to handle changes on updates. No changes were done to installation layout, all installation result keep as before. The migration was done using python script, see PR, which refactor automatically the structure. Updated doc generation to have valid path to modules, toolkits and packages. In case of PR into new version, IR-790 can be used as a target for the previous version.
645 lines
21 KiB
C++
645 lines
21 KiB
C++
// Created by: DAUTRY Philippe
|
|
// Copyright (c) 1997-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <Standard_DomainError.hxx>
|
|
#include <Standard_ImmutableObject.hxx>
|
|
#include <Standard_NullObject.hxx>
|
|
#include <TDF_AttributeIterator.hxx>
|
|
#include <TDF_ChildIterator.hxx>
|
|
#include <TDF_Data.hxx>
|
|
#include <TDF_IDFilter.hxx>
|
|
#include <TDF_Label.hxx>
|
|
#include <TDF_LabelNode.hxx>
|
|
#include <TDF_LabelNodePtr.hxx>
|
|
#include <TDF_Tool.hxx>
|
|
|
|
// Attribute methods ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//=======================================================================
|
|
// function : Imported
|
|
// purpose : Sets imported and all its descendants.
|
|
//=======================================================================
|
|
void TDF_Label::Imported(const Standard_Boolean aStatus) const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no status.");
|
|
if (myLabelNode->IsImported() != aStatus)
|
|
{
|
|
myLabelNode->Imported(aStatus);
|
|
for (TDF_ChildIterator itr(*this, Standard_True); itr.More(); itr.Next())
|
|
itr.Value().myLabelNode->Imported(aStatus);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : FindAttribute
|
|
// purpose : Finds an attributes according to an ID.
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TDF_Label::FindAttribute(const Standard_GUID& anID,
|
|
Handle(TDF_Attribute)& anAttribute) const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no attribute.");
|
|
TDF_AttributeIterator itr(myLabelNode); // Without removed attributes.
|
|
for (; itr.More(); itr.Next())
|
|
{
|
|
if (itr.PtrValue()->ID() == anID)
|
|
{
|
|
anAttribute = itr.PtrValue();
|
|
return Standard_True;
|
|
}
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : FindAttribute
|
|
// purpose : Finds an attributes according to an ID and a Transaction.
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TDF_Label::FindAttribute(const Standard_GUID& anID,
|
|
const Standard_Integer aTransaction,
|
|
Handle(TDF_Attribute)& anAttribute) const
|
|
{
|
|
Handle(TDF_Attribute) locAtt;
|
|
if (FindAttribute(anID, locAtt))
|
|
{
|
|
while ((!locAtt.IsNull()) && (locAtt->myTransaction > aTransaction))
|
|
locAtt = locAtt->myBackup;
|
|
if (!locAtt.IsNull())
|
|
{
|
|
anAttribute = locAtt;
|
|
return Standard_True;
|
|
}
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
// Label comfort methods ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
//=======================================================================
|
|
// function : Depth
|
|
// purpose : Returns the depth of the label in the tree.
|
|
// Root has depth 0. So the depth is the number of fathers.
|
|
//=======================================================================
|
|
|
|
Standard_Integer TDF_Label::Depth() const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no depth.");
|
|
return myLabelNode->Depth();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : IsDescendant
|
|
// purpose : Returns True if <me> is a descendant of <aLabel>.
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TDF_Label::IsDescendant(const TDF_Label& aLabel) const
|
|
{
|
|
// Cet algorithme remonte jusqu'a la racine. On peut s'arreter
|
|
// si la profondeur atteinte est inferieure a celle de <aLabel>.
|
|
|
|
const TDF_LabelNode* lp1 = aLabel.myLabelNode;
|
|
TDF_LabelNode* lp2 = myLabelNode;
|
|
#ifdef OCCT_DEBUG
|
|
if ((lp1 == NULL) || (lp2 == NULL))
|
|
throw Standard_NullObject("A null label has no ancestor nor descendant.");
|
|
#endif
|
|
if ((lp1 != NULL) && (lp2 != NULL))
|
|
{
|
|
const Standard_Integer d1 = lp1->Depth();
|
|
Standard_Integer d2 = lp2->Depth();
|
|
// Tester (d1 > d2) optimise la recherche ET dispense du test (lp2 != NULL)
|
|
while ((d2 > d1) && (lp2 != lp1))
|
|
{
|
|
lp2 = lp2->Father();
|
|
d2 = lp2->Depth();
|
|
}
|
|
return (lp1 == lp2);
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
const TDF_Label TDF_Label::Root() const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no root.");
|
|
return myLabelNode->RootNode();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : NbChildren
|
|
// purpose : Returns the number of children.
|
|
//=======================================================================
|
|
|
|
Standard_Integer TDF_Label::NbChildren() const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no children.");
|
|
Standard_Integer n = 0;
|
|
if (myLabelNode->FirstChild() != NULL)
|
|
for (TDF_ChildIterator itr(*this); itr.More(); itr.Next())
|
|
++n;
|
|
return n;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
TDF_Label TDF_Label::FindChild(const Standard_Integer aTag, const Standard_Boolean create) const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no child.");
|
|
if (create && ((Depth() + 1) & TDF_LabelNodeFlagsMsk))
|
|
throw Standard_OutOfRange("Depth value out of range");
|
|
|
|
return FindOrAddChild(aTag, create);
|
|
}
|
|
|
|
// Attribute comfort methods ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
//=======================================================================
|
|
// function : IsA
|
|
// purpose : Returns true if owns an attribute with <anID> as ID.
|
|
//=======================================================================
|
|
|
|
// Standard_Boolean TDF_Label::IsA(const Standard_GUID& anID) const
|
|
// {
|
|
// Handle(TDF_Attribute) att;
|
|
// return FindAttribute(anID,att);
|
|
// }
|
|
|
|
//=======================================================================
|
|
// function : IsAttribute
|
|
// purpose : Returns true if owns an attribute with <anID> as ID.
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TDF_Label::IsAttribute(const Standard_GUID& anID) const
|
|
{
|
|
Handle(TDF_Attribute) att;
|
|
return FindAttribute(anID, att);
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : HasAttribute
|
|
// purpose : Returns true if the label has at least one unremoved attribute.
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TDF_Label::HasAttribute() const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no attribute.");
|
|
|
|
if (!myLabelNode->FirstAttribute().IsNull())
|
|
{
|
|
TDF_AttributeIterator itr(myLabelNode); // Without removed attributes.
|
|
return itr.More();
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : NbAttributes
|
|
// purpose : Returns the number of attributes.
|
|
//=======================================================================
|
|
|
|
Standard_Integer TDF_Label::NbAttributes() const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no attribute.");
|
|
Standard_Integer n = 0;
|
|
if (!myLabelNode->FirstAttribute().IsNull())
|
|
for (TDF_AttributeIterator itr(myLabelNode); itr.More(); itr.Next())
|
|
++n;
|
|
return n;
|
|
}
|
|
|
|
// Miscelleaneous +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Integer TDF_Label::Transaction() const
|
|
{
|
|
if (IsNull())
|
|
throw Standard_NullObject("A null Label has no transaction.");
|
|
return myLabelNode->Data()->Transaction();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : Dump
|
|
// purpose : This method is equivalent to operator <<
|
|
//=======================================================================
|
|
|
|
Standard_OStream& TDF_Label::Dump(Standard_OStream& anOS) const
|
|
{
|
|
TDF_IDFilter f;
|
|
TDF_AttributeIndexedMap m;
|
|
TDF_Label::InternalDump(anOS, f, m, Standard_False);
|
|
return anOS;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void TDF_Label::ExtendedDump(Standard_OStream& anOS,
|
|
const TDF_IDFilter& aFilter,
|
|
TDF_AttributeIndexedMap& aMap) const
|
|
{
|
|
TDF_Label::InternalDump(anOS, aFilter, aMap, Standard_True);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void TDF_Label::EntryDump(Standard_OStream& anOS) const
|
|
{
|
|
if (IsNull())
|
|
{
|
|
anOS << "This label is null.";
|
|
}
|
|
else
|
|
{
|
|
TCollection_AsciiString entry;
|
|
TDF_Tool::Entry(*this, entry);
|
|
anOS << entry;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : FindOrAddChild
|
|
// purpose : Finds or adds a label child having <aTag> as tag.
|
|
//=======================================================================
|
|
|
|
TDF_LabelNode* TDF_Label::FindOrAddChild(const Standard_Integer aTag,
|
|
const Standard_Boolean create) const
|
|
{
|
|
TDF_LabelNode* currentLnp = myLabelNode->FirstChild();
|
|
TDF_LabelNode* lastLnp = NULL;
|
|
TDF_LabelNode* lastFoundLnp = myLabelNode->myLastFoundChild; // jfa 10.01.2003
|
|
TDF_LabelNode* childLabelNode = NULL;
|
|
|
|
// Finds the right place.
|
|
|
|
// jfa 10.01.2003
|
|
// 1. Check, if we access to a child, which is after last touched upon
|
|
if (lastFoundLnp != NULL)
|
|
{
|
|
if (lastFoundLnp->Tag() == aTag)
|
|
{
|
|
return lastFoundLnp;
|
|
}
|
|
else if (lastFoundLnp->Tag() < aTag)
|
|
{
|
|
lastLnp = lastFoundLnp;
|
|
currentLnp = lastFoundLnp->Brother();
|
|
}
|
|
}
|
|
// jfa 10.01.2003 end
|
|
|
|
// To facilitate many tools, label brethren are stored in increasing order.
|
|
while ((currentLnp != NULL) && (currentLnp->Tag() < aTag))
|
|
{
|
|
lastLnp = currentLnp;
|
|
currentLnp = currentLnp->Brother();
|
|
}
|
|
|
|
if ((currentLnp != NULL) && (currentLnp->Tag() == aTag))
|
|
{
|
|
// The label exists.
|
|
childLabelNode = currentLnp;
|
|
}
|
|
else if (create)
|
|
{
|
|
// Creates the label to be inserted always before currentLnp.
|
|
const TDF_HAllocator& anAllocator = myLabelNode->Data()->LabelNodeAllocator();
|
|
childLabelNode = new (anAllocator) TDF_LabelNode(aTag, myLabelNode);
|
|
childLabelNode->myBrother = currentLnp; // May be NULL.
|
|
childLabelNode->Imported(IsImported());
|
|
// Inserts the label:
|
|
if (lastLnp == NULL) // ... at beginning.
|
|
myLabelNode->myFirstChild = childLabelNode;
|
|
else // ... somewhere.
|
|
lastLnp->myBrother = childLabelNode;
|
|
// Update table for fast access to the labels.
|
|
if (myLabelNode->Data()->IsAccessByEntries())
|
|
myLabelNode->Data()->RegisterLabel(childLabelNode);
|
|
}
|
|
|
|
if (lastLnp) // agv 14.07.2010
|
|
myLabelNode->myLastFoundChild = lastLnp; // jfa 10.01.2003
|
|
|
|
return childLabelNode;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : InternalDump
|
|
// purpose : Private method.
|
|
//=======================================================================
|
|
|
|
void TDF_Label::InternalDump(Standard_OStream& anOS,
|
|
const TDF_IDFilter& aFilter,
|
|
TDF_AttributeIndexedMap& aMap,
|
|
const Standard_Boolean extended) const
|
|
{
|
|
if (IsNull())
|
|
{
|
|
anOS << "This label is null.";
|
|
}
|
|
else
|
|
{
|
|
TCollection_AsciiString entry;
|
|
TDF_Tool::Entry(*this, entry);
|
|
anOS << entry << "\t";
|
|
if (IsImported())
|
|
anOS << "IS ";
|
|
else
|
|
anOS << "NOT";
|
|
anOS << " imported; ";
|
|
if (MayBeModified())
|
|
anOS << "MAYBE";
|
|
else
|
|
anOS << "NOT";
|
|
anOS << " modified; ";
|
|
if (AttributesModified())
|
|
anOS << "HAS attributes";
|
|
else
|
|
anOS << "NO attribute";
|
|
anOS << " modified; ";
|
|
if (HasAttribute())
|
|
{
|
|
Standard_Integer nba = NbAttributes();
|
|
anOS << "has " << nba << " attribute";
|
|
if (nba > 1)
|
|
anOS << "s";
|
|
anOS << "." << std::endl;
|
|
for (TDF_AttributeIterator itr(myLabelNode); itr.More(); itr.Next())
|
|
{
|
|
// CLE
|
|
// const Handle(TDF_Attribute)& att = itr.Value();
|
|
Handle(TDF_Attribute) att = itr.Value();
|
|
// ENDCLE
|
|
if (extended && aFilter.IsKept(att))
|
|
anOS << "\t# " << aMap.Add(att);
|
|
att->TDF_Attribute::Dump(anOS);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
anOS << " has no attribute" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
Standard_Boolean TDF_Label::HasLowerNode(const TDF_Label& aLabel) const
|
|
{
|
|
return (myLabelNode < aLabel.myLabelNode);
|
|
}
|
|
|
|
Standard_Boolean TDF_Label::HasGreaterNode(const TDF_Label& aLabel) const
|
|
{
|
|
return (myLabelNode > aLabel.myLabelNode);
|
|
}
|
|
|
|
// from insertor ////////////////////////////////////////////////////////
|
|
|
|
//=================================================================================================
|
|
|
|
// void TDF_Label::Add(const Handle(TDF_Attribute)& anAttribute) const
|
|
// { AddToNode(myLabelNode,anAttribute); }
|
|
|
|
//=================================================================================================
|
|
|
|
void TDF_Label::AddAttribute(const Handle(TDF_Attribute)& anAttribute,
|
|
const Standard_Boolean append /* = Standard_False*/) const
|
|
{
|
|
AddToNode(myLabelNode, anAttribute, append);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
// void TDF_Label::Forget(const Handle(TDF_Attribute)& anAttribute) const
|
|
// { ForgetFromNode(myLabelNode,anAttribute); }
|
|
|
|
//=================================================================================================
|
|
|
|
void TDF_Label::ForgetAttribute(const Handle(TDF_Attribute)& anAttribute) const
|
|
{
|
|
ForgetFromNode(myLabelNode, anAttribute);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
// Standard_Boolean TDF_Label::Forget (const Standard_GUID& anID) const
|
|
// {
|
|
// Handle(TDF_Attribute) anAttribute;
|
|
// //if (Label().FindAttribute(anID,anAttribute)) {
|
|
// if (FindAttribute(anID,anAttribute)) {
|
|
// Forget(anAttribute);
|
|
// return Standard_True;
|
|
// }
|
|
// return Standard_False;
|
|
// }
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean TDF_Label::ForgetAttribute(const Standard_GUID& anID) const
|
|
{
|
|
Handle(TDF_Attribute) anAttribute;
|
|
// if (Label().FindAttribute(anID,anAttribute)) {
|
|
if (FindAttribute(anID, anAttribute))
|
|
{
|
|
ForgetAttribute(anAttribute);
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
// void TDF_Label::ForgetAll (const Standard_Boolean clearChildren) const
|
|
// {
|
|
// for (TDF_AttributeIterator itr1(myLabelNode); itr1.More(); itr1.Next())
|
|
// ForgetFromNode(myLabelNode,itr1.Value());
|
|
// if (clearChildren)
|
|
// for (TDF_ChildIterator itr2(myLabelNode); itr2.More(); itr2.Next()) {
|
|
// itr2.Value().ForgetAll(clearChildren);
|
|
// }
|
|
// }
|
|
|
|
//=================================================================================================
|
|
|
|
void TDF_Label::ForgetAllAttributes(const Standard_Boolean clearChildren) const
|
|
{
|
|
TDF_AttributeIterator itr1(myLabelNode);
|
|
// AGV-OCC5031: iterator must be incremented before removal of the attribute
|
|
while (itr1.More())
|
|
{
|
|
const Handle(TDF_Attribute) anAttr = itr1.Value();
|
|
itr1.Next();
|
|
ForgetFromNode(myLabelNode, anAttr);
|
|
}
|
|
// while (itr1.More()) {
|
|
// ForgetFromNode(myLabelNode,itr1.Value());
|
|
// itr1.Next();
|
|
// }
|
|
if (clearChildren)
|
|
for (TDF_ChildIterator itr2(myLabelNode); itr2.More(); itr2.Next())
|
|
{
|
|
itr2.Value().ForgetAllAttributes(clearChildren);
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
// void TDF_Label::Resume (const Handle(TDF_Attribute)& anAttribute) const
|
|
// { ResumeToNode(myLabelNode,anAttribute); }
|
|
|
|
//=================================================================================================
|
|
|
|
void TDF_Label::ResumeAttribute(const Handle(TDF_Attribute)& anAttribute) const
|
|
{
|
|
ResumeToNode(myLabelNode, anAttribute);
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : AddToNode
|
|
// purpose : Private method used by Add
|
|
//=======================================================================
|
|
|
|
void TDF_Label::AddToNode(const TDF_LabelNodePtr& toNode,
|
|
const Handle(TDF_Attribute)& anAttribute,
|
|
const Standard_Boolean append) const
|
|
{
|
|
// check that modification is allowed
|
|
if (!toNode->Data()->IsModificationAllowed())
|
|
{
|
|
TCollection_AsciiString aMess;
|
|
aMess = "Attribute \"";
|
|
aMess += anAttribute->DynamicType()->Name();
|
|
aMess += "\" is added to label outside transaction";
|
|
throw Standard_ImmutableObject(aMess.ToCString());
|
|
}
|
|
|
|
if (!anAttribute->Label().IsNull())
|
|
throw Standard_DomainError("Attribute to add is already attached to a label.");
|
|
Handle(TDF_Attribute) dummyAtt;
|
|
// if (Find(anAttribute->ID(),dummyAtt))
|
|
if (FindAttribute(anAttribute->ID(), dummyAtt))
|
|
throw Standard_DomainError("This label has already such an attribute.");
|
|
|
|
anAttribute->myTransaction = toNode->Data()->Transaction(); /// myData->Transaction();
|
|
anAttribute->mySavedTransaction = 0;
|
|
|
|
// append to the end of the attribute list
|
|
dummyAtt.Nullify();
|
|
if (append)
|
|
{
|
|
for (TDF_AttributeIterator itr(toNode); itr.More(); itr.Next())
|
|
dummyAtt = itr.Value();
|
|
}
|
|
|
|
toNode->AddAttribute(dummyAtt, anAttribute);
|
|
toNode->AttributesModified(anAttribute->myTransaction != 0);
|
|
// if (myData->NotUndoMode()) anAttribute->AfterAddition();
|
|
if (toNode->Data()->NotUndoMode())
|
|
anAttribute->AfterAddition();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : ForgetFromNode
|
|
// purpose : Private method used by Forget
|
|
//=======================================================================
|
|
|
|
void TDF_Label::ForgetFromNode(const TDF_LabelNodePtr& fromNode,
|
|
const Handle(TDF_Attribute)& anAttribute) const
|
|
{
|
|
// check that modification is allowed
|
|
if (!fromNode->Data()->IsModificationAllowed())
|
|
{
|
|
TCollection_AsciiString aMess;
|
|
aMess = "Attribute \"";
|
|
aMess += anAttribute->DynamicType()->Name();
|
|
aMess += "\" is removed from label outside transaction";
|
|
throw Standard_ImmutableObject(aMess.ToCString());
|
|
}
|
|
|
|
if (fromNode != anAttribute->Label().myLabelNode)
|
|
throw Standard_DomainError("Attribute to forget not attached to my label.");
|
|
|
|
Standard_Integer curTrans = fromNode->Data()->Transaction();
|
|
if (!anAttribute->IsForgotten())
|
|
{
|
|
if ((curTrans == 0)
|
|
|| ((anAttribute->myTransaction == curTrans) && anAttribute->myBackup.IsNull()))
|
|
{
|
|
// 1- No transaction is open;
|
|
// OR
|
|
// 2- The attribute has been created in the current transaction;
|
|
// ==> Complete disparition of the attribute.
|
|
Handle(TDF_Attribute) lastAtt;
|
|
for (TDF_AttributeIterator itr(fromNode, Standard_False); itr.More(); itr.Next())
|
|
{
|
|
if (itr.Value() == anAttribute)
|
|
{
|
|
// if (myData->NotUndoMode()) {
|
|
if (fromNode->Data()->NotUndoMode())
|
|
{
|
|
anAttribute->BeforeForget();
|
|
anAttribute->BeforeRemoval();
|
|
}
|
|
fromNode->RemoveAttribute(lastAtt, anAttribute);
|
|
anAttribute->Forget(fromNode->Data()->Transaction());
|
|
break;
|
|
}
|
|
lastAtt = itr.Value();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// One case is here ignored:
|
|
// The attribute has been modified in the current transaction.
|
|
// (It has at least one backup.) We don't restore the previous
|
|
// version before forgetting. It may generated a strange behaviour
|
|
// in case of forgetting, committing, aborting...
|
|
if (fromNode->Data()->NotUndoMode())
|
|
anAttribute->BeforeForget();
|
|
anAttribute->Forget(fromNode->Data()->Transaction());
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : ResumeToNode
|
|
// purpose : Private method used by Resume
|
|
//=======================================================================
|
|
|
|
void TDF_Label::ResumeToNode(const TDF_LabelNodePtr& toNode,
|
|
const Handle(TDF_Attribute)& anAttribute) const
|
|
{
|
|
if (anAttribute.IsNull())
|
|
throw Standard_NullObject("The attribute is a null handle.");
|
|
if (!anAttribute->Label().IsNull())
|
|
throw Standard_NullObject("Cannot resume an attribute already attached to a label.");
|
|
if (!anAttribute->IsForgotten())
|
|
throw Standard_DomainError("Cannot resume an unforgotten attribute.");
|
|
|
|
AddToNode(toNode, anAttribute, Standard_False);
|
|
anAttribute->Resume();
|
|
if (toNode->Data()->NotUndoMode())
|
|
anAttribute->AfterResume();
|
|
}
|
|
|
|
//////////////////end from insertor ///////////////////////////////////////////////////
|