-// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023 CEA, EDF
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// 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
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include <Selector_Algo.h>
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <Geom_Surface.hxx>
#include <BRep_Tool.hxx>
#include <TNaming_Builder.hxx>
#include <TNaming_Tool.hxx>
#include <TNaming_SameShapeIterator.hxx>
#include <TNaming_Iterator.hxx>
+#include <TNaming_NewShapeIterator.hxx>
#include <TDataStd_ReferenceArray.hxx>
#include <TDataStd_ExtStringList.hxx>
#include <TDataStd_Integer.hxx>
#include <TDataStd_UAttribute.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BRep_Builder.hxx>
/// type of the selection, integer keeps the Selector_Type value
myAlwaysGeometricalNaming = false;
}
+static TDF_Label findGoodLabelWithShape(const TDF_Label theAccess, const TopoDS_Shape& theShape) {
+ TDF_Label aResult;
+ TDF_Label aMyOpLab;
+ bool aMyOpLabIsComputed = false;
+ if (TNaming_Tool::HasLabel(theAccess, theShape)) { // selection and delete evolution are not used
+ for(TNaming_SameShapeIterator aShapes(theShape, theAccess); aShapes.More(); aShapes.Next())
+ {
+ Handle(TNaming_NamedShape) aNS;
+ if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ if (aNS->Evolution() == TNaming_MODIFY || aNS->Evolution() == TNaming_GENERATED ||
+ aNS->Evolution() == TNaming_PRIMITIVE) {
+ // getting label of this operation to avoid usage of ready shapes of this
+ if (!aMyOpLabIsComputed) {
+ aMyOpLab = theAccess;
+ if (!aMyOpLab.IsNull()) {
+ int aDepth = aMyOpLab.Depth();
+ if (aDepth < 3)
+ aMyOpLab.Nullify();
+ else {
+ for(; aDepth != 3; aDepth--)
+ aMyOpLab = aMyOpLab.Father();
+ }
+ }
+ aMyOpLabIsComputed = true;
+ }
+ if (!aMyOpLab.IsNull() && aNS->Label().IsDescendant(aMyOpLab))
+ continue;
+ aResult = aNS->Label();
+ break;
+ }
+ }
+ }
+ }
+ return aResult;
+}
+
#define SET_ALGO_FLAGS(algo) \
algo->myLab = theAccess; \
algo->myBaseDocumentLab = theBaseDocument; \
// check the value shape can be named as it is, or it is needed to construct it from the
// higher level shapes (like a box vertex by faces that form this vertex)
- bool aIsFound = TNaming_Tool::HasLabel(theAccess, theValue);
- if (aIsFound) { // additional check for selection and delete evolution only: also could not use
- aIsFound = false;
- for(TNaming_SameShapeIterator aShapes(theValue, theAccess); aShapes.More(); aShapes.Next())
- {
- Handle(TNaming_NamedShape) aNS;
- if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
- if (aNS->Evolution() == TNaming_MODIFY || aNS->Evolution() == TNaming_GENERATED ||
- aNS->Evolution() == TNaming_PRIMITIVE) {
- aIsFound = true;
- break;
- }
- }
- }
- }
- // searching in the base document
- if (!aIsFound && !theBaseDocument.IsNull() && TNaming_Tool::HasLabel(theBaseDocument, theValue))
- {
- TNaming_SameShapeIterator aShapes(theValue, theBaseDocument);
- for(; aShapes.More(); aShapes.Next())
- {
- Handle(TNaming_NamedShape) aNS;
- if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
- if (aNS->Evolution() == TNaming_MODIFY || aNS->Evolution() == TNaming_GENERATED ||
- aNS->Evolution() == TNaming_PRIMITIVE) {
- aIsFound = true;
- break;
- }
- }
- }
- }
+ bool aIsFound = !findGoodLabelWithShape(theAccess, theValue).IsNull();
+ if (!aIsFound && !theBaseDocument.IsNull()) // searching in the base document
+ aIsFound = !findGoodLabelWithShape(theBaseDocument, theValue).IsNull();
if (!aIsFound) {
TopAbs_ShapeEnum aSelectionType = theValue.ShapeType();
if (aSelectionType == TopAbs_COMPOUND || aSelectionType == TopAbs_COMPSOLID ||
// searching by neighbors
Selector_FilterByNeighbors* aNBs = new Selector_FilterByNeighbors;
SET_ALGO_FLAGS(aNBs);
- if (aNBs->select(theContext, theValue)) {
+ // searching a context lab to store in NB algorithm
+ TDF_Label aContextLab = findGoodLabelWithShape(theAccess, theContext);
+ if (aContextLab.IsNull() && !theBaseDocument.IsNull()) // search also in the base document
+ aContextLab = findGoodLabelWithShape(theBaseDocument, theContext);
+ if (aNBs->select(aContextLab, theContext, theValue)) {
delete anIntersect;
return aNBs;
}
}
return NULL; // not found value in the tree, not found context shape in the tree also
}
+ // getting label of this operation to avoid usage of ready shapes of this
+ TDF_Label aMyOpLab = theAccess;
+ if (!aMyOpLab.IsNull()) {
+ int aDepth = aMyOpLab.Depth();
+ if (aDepth < 3)
+ aMyOpLab.Nullify();
+ else {
+ for(; aDepth != 3; aDepth--)
+ aMyOpLab = aMyOpLab.Father();
+ }
+ }
// searching for the base shapes of the value
Handle(TNaming_NamedShape) aPrimitiveNS;
NCollection_List<Handle(TNaming_NamedShape)> aModifList;
Handle(TNaming_NamedShape) aNS;
if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
TNaming_Evolution anEvolution = aNS->Evolution();
+ if (anEvolution == TNaming_SELECTED || anEvolution == TNaming_DELETE)
+ continue;
+ if (!aMyOpLab.IsNull() && aNS->Label().IsDescendant(aMyOpLab))
+ continue;
if (anEvolution == TNaming_PRIMITIVE) { // the value shape is declared as PRIMITIVE
aPrimitiveNS = aNS;
break;
// searching by neighbors
Selector_FilterByNeighbors* aNBs = new Selector_FilterByNeighbors;
SET_ALGO_FLAGS(aNBs);
- if (aNBs->select(theContext, theValue)) {
+ // searching a context lab to store in NB algorithm
+ TDF_Label aContextLab = findGoodLabelWithShape(theAccess, theContext);
+ if (aContextLab.IsNull() && !theBaseDocument.IsNull()) // search also in the base document
+ aContextLab = findGoodLabelWithShape(theBaseDocument, theContext);
+ if (aNBs->select(aContextLab, theContext, theValue)) {
delete aModify;
return aNBs;
}
}
Selector_Algo* Selector_Algo::restoreByName(TDF_Label theLab, TDF_Label theBaseDocLab,
- std::string theName, const TopAbs_ShapeEnum theShapeType,
+ std::wstring theName, const TopAbs_ShapeEnum theShapeType, const bool theGeomNaming,
Selector_NameGenerator* theNameGenerator, TDF_Label& theContextLab)
{
Selector_Algo* aResult = NULL;
- if (theName[0] == '[') { // intersection or container
+ if (theName[0] == L'[') { // intersection or container
switch(theShapeType) {
case TopAbs_COMPOUND:
case TopAbs_COMPSOLID:
break;
default:;
}
- } else if (theName[0] == '(') { // filter by neighbors
+ } else if (theName[0] == L'(') { // filter by neighbors
aResult = new Selector_FilterByNeighbors;
- } else if (theName.find(pureWeakNameID()) == 0) { // weak naming identifier
+ } else if (theName.find(pureWeakNameID()) == 0 ||
+ theName.find(oldPureWeakNameID()) == 0) { // weak naming identifier
aResult = new Selector_WeakName;
- } else if (theName.find('&') != std::string::npos) { // modification
+ } else if (theName.find(L'&') != std::wstring::npos) { // modification
aResult = new Selector_Modify;
} else { // primitive
aResult = new Selector_Primitive;
if (aResult) {
aResult->myLab = theLab;
aResult->myBaseDocumentLab = theBaseDocLab;
+ aResult->myGeometricalNaming = theGeomNaming;
theContextLab = aResult->restoreByName(theName, theShapeType, theNameGenerator);
if (theContextLab.IsNull()) {
delete aResult;
if (myGeometricalNaming)
TDataStd_UAttribute::Set(myLab, kGEOMETRICAL_NAMING);
}
+
+/// Returns true if theSub is in theContext shape
+static bool isInContext(const TopoDS_Shape& theContext, const TopoDS_Shape& theSub) {
+ for(TopExp_Explorer anExp(theContext, theSub.ShapeType()); anExp.More(); anExp.Next()) {
+ if (anExp.Current().IsSame(theSub))
+ return true;
+ }
+ return false;
+}
+
+bool Selector_Algo::findNewVersion(const TopoDS_Shape& theContext, TopoDS_Shape& theResult) const
+{
+ if (theResult.IsNull())
+ return false;
+ if (!TNaming_Tool::HasLabel(myLab, theResult)) {
+ if (theResult.ShapeType() == TopAbs_COMPOUND) { // do it for all elements of compound
+ BRep_Builder aBuilder;
+ TopoDS_Compound aResultingCompound;
+ aBuilder.MakeCompound(aResultingCompound);
+ bool aWasChanged = false;
+ for (TopoDS_Iterator anIter(theResult); anIter.More(); anIter.Next()) {
+ TopoDS_Shape aSub = anIter.Value();
+ if (findNewVersion(theContext, aSub))
+ aWasChanged = true;
+ aBuilder.Add(aResultingCompound, aSub);
+ }
+ if (aWasChanged)
+ theResult = aResultingCompound;
+ return aWasChanged;
+ }
+ } else {
+ // check theResult is in theContext
+ if (isInContext(theContext, theResult))
+ return false;
+ // searching the next modifications of the result shape in document
+ TopTools_MapOfShape aResultShapes;
+ for(TNaming_NewShapeIterator aBaseIter(theResult, myLab); aBaseIter.More(); aBaseIter.Next())
+ {
+ TNaming_Evolution anEvolution = aBaseIter.NamedShape()->Evolution();
+ if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
+ TopoDS_Shape aNextModification = aBaseIter.Shape();
+ if (aNextModification.IsNull())
+ continue;
+ if (isInContext(theContext, aNextModification)) {
+ // don't add vertices generated from edges
+ if (aNextModification.ShapeType() <= theResult.ShapeType())
+ aResultShapes.Add(aNextModification);
+ }
+ else if (findNewVersion(theContext, aNextModification)) {
+ if (aNextModification.ShapeType() <= theResult.ShapeType())
+ aResultShapes.Add(aNextModification);
+ }
+ }
+ }
+ if (aResultShapes.IsEmpty())
+ return false;
+ if (aResultShapes.Size() == 1) {
+ theResult = TopTools_MapIteratorOfMapOfShape(aResultShapes).Value();
+ } else { // make a compound of all results
+ BRep_Builder aBuilder;
+ TopoDS_Compound aResultingCompound;
+ aBuilder.MakeCompound(aResultingCompound);
+ for(TopTools_MapIteratorOfMapOfShape anIter(aResultShapes); anIter.More(); anIter.Next())
+ aBuilder.Add(aResultingCompound, anIter.Value());
+ theResult = aResultingCompound;
+ }
+ return true;
+ }
+ return false;
+}