#include <Selector_NameGenerator.h>
#include <Selector_NExplode.h>
-#include <TDF_ChildIDIterator.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Builder.hxx>
+#include <TopoDS.hxx>
#include <TopExp_Explorer.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
#include <TNaming_Tool.hxx>
#include <TNaming_NewShapeIterator.hxx>
#include <TNaming_OldShapeIterator.hxx>
#include <TNaming_Iterator.hxx>
#include <TNaming_Builder.hxx>
#include <TopTools_MapOfShape.hxx>
+#include <BRep_Tool.hxx>
+#include <TDF_ChildIDIterator.hxx>
+#include <TDF_Tool.hxx>
#include <TDataStd_Integer.hxx>
#include <TDataStd_ReferenceArray.hxx>
#include <TDataStd_IntegerArray.hxx>
#include <TDataStd_Name.hxx>
+#include <TDataStd_UAttribute.hxx>
+#include <TDataStd_ExtStringList.hxx>
#include <list>
-/// type of the selection, integerm keeps the Selector_Type value
+/// type of the selection, integer keeps the Selector_Type value
static const Standard_GUID kSEL_TYPE("db174d59-c2e3-4a90-955e-55544df090d6");
/// type of the shape, stored in case it is intersection or container
static const Standard_GUID kSHAPE_TYPE("864b3267-cb9d-4107-bf58-c3ce1775b171");
// reference attribute that contains the reference to labels where the "from" or "base" shapes
// of selection are located
static const Standard_GUID kBASE_ARRAY("7c515b1a-9549-493d-9946-a4933a22f45f");
+// if the base array contains reference to the root label, this means that it refers to an
+// external document and this list contains a tag in the document
+static const Standard_GUID kBASE_LIST("7c515b1a-9549-493d-9946-a4933a22f45a");
// array of the neighbor levels
static const Standard_GUID kLEVELS_ARRAY("ee4c4b45-e859-4e86-aa4f-6eac68e0ca1f");
// weak index (integer) of the sub-shape
static const Standard_GUID kWEAK_INDEX("e9373a61-cabc-4ee8-aabf-aea47c62ed87");
+// geometrical naming indicator
+static const Standard_GUID kGEOMETRICAL_NAMING("a5322d02-50fb-43ed-9255-75c7b93f6657");
+
+// string identifier of the weak name in modification or intersection types of algorithm
+static const std::string kWEAK_NAME_IDENTIFIER = "weak_name_";
+// string identifier of the pure weak name algorithm
+static const std::string kPUREWEAK_NAME_IDENTIFIER = "_weak_name_";
+
Selector_Selector::Selector_Selector(TDF_Label theLab) : myLab(theLab)
{
myWeakIndex = -1;
+ myAlwaysGeometricalNaming = false;
}
TDF_Label Selector_Selector::label()
return myLab;
}
+void Selector_Selector::setBaseDocument(const TDF_Label theAccess)
+{
+ myBaseDocumentLab = theAccess;
+}
+
// adds to theResult all labels that contain initial shapes for theValue located in theFinal
-static void findBases(Handle(TNaming_NamedShape) theFinal, const TopoDS_Shape& theValue,
- bool aMustBeAtFinal, TDF_LabelList& theResult)
+static void findBases(TDF_Label theAccess, Handle(TNaming_NamedShape) theFinal,
+ const TopoDS_Shape& theValue,
+ bool aMustBeAtFinal, const TDF_Label& theAdditionalDocument, TDF_LabelList& theResult)
{
- TNaming_SameShapeIterator aLabIter(theValue, theFinal->Label());
+ bool aFoundAnyShape = false;
+ TNaming_SameShapeIterator aLabIter(theValue, theAccess);
for(; aLabIter.More(); aLabIter.Next()) {
Handle(TNaming_NamedShape) aNS;
- aLabIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS);
- if (aMustBeAtFinal && aNS != theFinal)
- continue; // looking for old at the same final label only
- TNaming_Evolution anEvolution = aNS->Evolution();
- if (anEvolution == TNaming_PRIMITIVE) {
- // check that this is not in the results already
- const TDF_Label aResult = aNS->Label();
- TDF_LabelList::Iterator aResIter(theResult);
- for(; aResIter.More(); aResIter.Next()) {
- if (aResIter.Value().IsEqual(aResult))
- break;
+ if (aLabIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ if (aMustBeAtFinal && aNS != theFinal)
+ continue; // looking for old at the same final label only
+ TNaming_Evolution anEvolution = aNS->Evolution();
+ if (anEvolution == TNaming_PRIMITIVE) {
+ // check that this is not in the results already
+ const TDF_Label aResult = aNS->Label();
+ TDF_LabelList::Iterator aResIter(theResult);
+ for(; aResIter.More(); aResIter.Next()) {
+ if (aResIter.Value().IsEqual(aResult))
+ break;
+ }
+ if (!aResIter.More()) // not found, so add this new
+ theResult.Append(aResult);
+ aFoundAnyShape = true;
}
- if (!aResIter.More()) // not found, so add this new
- theResult.Append(aResult);
- }
- if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
- for(TNaming_Iterator aThisIter(aNS); aThisIter.More(); aThisIter.Next()) {
- if (aThisIter.NewShape().IsSame(theValue)) {
- // continue recursively, null NS means that any NS are ok
- findBases(theFinal, aThisIter.OldShape(), false, theResult);
+ if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
+ for(TNaming_Iterator aThisIter(aNS); aThisIter.More(); aThisIter.Next()) {
+ if (aThisIter.NewShape().IsSame(theValue)) {
+ // continue recursively, null NS means that any NS are ok
+ findBases(theAccess, theFinal, aThisIter.OldShape(),
+ false, theAdditionalDocument, theResult);
+ aFoundAnyShape = true;
+ }
}
}
}
}
+ if (!aFoundAnyShape && !theAdditionalDocument.IsNull()) { // try to find in additional document
+ static TDF_Label anEmpty;
+ if (TNaming_Tool::HasLabel(theAdditionalDocument, theValue))
+ findBases(theAdditionalDocument, Handle(TNaming_NamedShape)(), theValue,
+ false, anEmpty, theResult);
+ }
}
// returns the sub-shapes of theSubType which belong to all theShapes (so, common or intersection)
}
}
+/// Returns true if the given shapes are based on the same geometry
+static bool sameGeometry(const TopoDS_Shape theShape1, const TopoDS_Shape theShape2) {
+ if (!theShape1.IsNull() && !theShape2.IsNull() && theShape1.ShapeType() == theShape2.ShapeType())
+ {
+ if (theShape1.ShapeType() == TopAbs_FACE) { // check surfaces
+ TopLoc_Location aLoc1, aLoc2;
+ TopoDS_Face aFace1 = TopoDS::Face(theShape1);
+ Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(aFace1, aLoc1);
+ TopoDS_Face aFace2 = TopoDS::Face(theShape2);
+ Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(aFace2, aLoc2);
+ return aSurf1 == aSurf2 && aLoc1.IsEqual(aLoc2);
+ } else if (theShape1.ShapeType() == TopAbs_EDGE) { // check curves
+ TopLoc_Location aLoc1, aLoc2;
+ Standard_Real aFirst, aLast;
+ TopoDS_Edge anEdge1 = TopoDS::Edge(theShape1);
+ Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(anEdge1, aLoc1, aFirst, aLast);
+ TopoDS_Edge anEdge2 = TopoDS::Edge(theShape2);
+ Handle(Geom_Curve) aCurve2 = BRep_Tool::Curve(anEdge2, aLoc2, aFirst, aLast);
+ return aCurve1 == aCurve2 && aLoc1.IsEqual(aLoc2);
+ }
+ }
+ return false;
+}
+
/// Searches the neighbor shape by neighbors defined in theNB in theContext shape
static const TopoDS_Shape findNeighbor(const TopoDS_Shape theContext,
- const std::list<std::pair<TopoDS_Shape, int> >& theNB)
+ const std::list<std::pair<TopoDS_Shape, int> >& theNB, const bool theGeometrical)
{
// searching for neighbors with minimum level
int aMinLevel = 0;
return TopoDS_Shape(); // not found any candidate
if (aMatches.Extent() == 1)
return aMatches.First(); // already found good candidate
+ TopoDS_Compound aResultCompound; // in case of geometrical name and many candidates
// iterate all matches to find by other (higher level) neighbors the best candidate
TopoDS_Shape aGoodCandidate;
for(TopoDS_ListOfShape::Iterator aCandidate(aMatches); aCandidate.More(); aCandidate.Next()) {
if (!aFooundHigherLevel && aLevelNBs.IsEmpty()) { // iterated all, so, good candidate
if (aGoodCandidate.IsNull()) {
aGoodCandidate = aCandidate.Value();
- } else { // too many good candidates
- return TopoDS_Shape();
+ } else { // another good candidate
+ if (theGeometrical && sameGeometry(aGoodCandidate, aCandidate.Value())) {
+ static TopoDS_Builder aBuilder;
+ if (aResultCompound.IsNull()) {
+ aBuilder.MakeCompound(aResultCompound);
+ aBuilder.Add(aResultCompound, aGoodCandidate);
+ }
+ aBuilder.Add(aResultCompound, aCandidate.Value());
+ } else
+ return TopoDS_Shape();
}
}
if (!aLevelNBs.IsEmpty()) {
break;
}
}
+ if (!aResultCompound.IsNull())
+ return aResultCompound;
return aGoodCandidate;
}
bool Selector_Selector::select(const TopoDS_Shape theContext, const TopoDS_Shape theValue,
- const bool theUseNeighbors)
+ const bool theGeometricalNaming, const bool theUseNeighbors, const bool theUseIntersections)
{
if (theValue.IsNull() || theContext.IsNull())
return false;
+ myGeometricalNaming = theGeometricalNaming;
// 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)
- if (!TNaming_Tool::HasLabel(myLab, theValue)) {
+ bool aIsFound = TNaming_Tool::HasLabel(myLab, theValue);
+ if (aIsFound) { // additional check for selection and delete evolution only: also could not use
+ aIsFound = false;
+ for(TNaming_SameShapeIterator aShapes(theValue, myLab); 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 && !myBaseDocumentLab.IsNull() &&
+ TNaming_Tool::HasLabel(myBaseDocumentLab, theValue))
+ {
+ TNaming_SameShapeIterator aShapes(theValue, myBaseDocumentLab);
+ 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;
+ }
+ }
+ }
+ }
+ if (!aIsFound) {
TopAbs_ShapeEnum aSelectionType = theValue.ShapeType();
myShapeType = aSelectionType;
if (aSelectionType == TopAbs_COMPOUND || aSelectionType == TopAbs_COMPSOLID ||
aSelectionType == TopAbs_SHELL || aSelectionType == TopAbs_WIRE)
{ // iterate all sub-shapes and select them on sublabels
for(TopoDS_Iterator aSubIter(theValue); aSubIter.More(); aSubIter.Next()) {
- if (!selectBySubSelector(theContext, aSubIter.Value())) {
+ if (!selectBySubSelector(theContext, aSubIter.Value(),
+ false, theUseNeighbors, theUseIntersections)) {//for subs no geometrical naming allowed
return false; // if some selector is failed, everything is failed
}
}
// try to find the shape of the higher level type in the context shape
bool aFacesTried = false; // for identification of vertices, faces are tried, then edges
- while(aSelectionType != TopAbs_FACE || !aFacesTried) {
+ TopoDS_ListOfShape aLastCommon; // to store the commons not good, but may be used for weak
+ TopoDS_ListOfShape aLastIntersectors;
+ while(theUseIntersections && (aSelectionType != TopAbs_FACE || !aFacesTried)) {
if (aSelectionType == TopAbs_FACE) {
if (theValue.ShapeType() != TopAbs_VERTEX)
break;
TopTools_MapOfShape anIntersectors; // shapes of aSelectionType that contain theValue
TopoDS_ListOfShape anIntList; // same as anIntersectors
for(TopExp_Explorer aSelExp(theContext, aSelectionType); aSelExp.More(); aSelExp.Next()) {
+ if (aSelectionType == TopAbs_EDGE &&
+ BRep_Tool::Degenerated(TopoDS::Edge(aSelExp.Current())))
+ continue;
TopExp_Explorer aSubExp(aSelExp.Current(), theValue.ShapeType());
for(; aSubExp.More(); aSubExp.Next()) {
if (aSubExp.Current().IsSame(theValue)) {
commonShapes(anIntList, theValue.ShapeType(), aCommon);
if (aCommon.Extent() == 1 && aCommon.First().IsSame(theValue)) {
// name the intersectors
- std::list<Selector_Selector> aSubSelList;
- TopTools_MapOfShape::Iterator anInt(anIntersectors);
+ mySubSelList.clear();
+ TopoDS_ListOfShape::Iterator anInt(anIntList);
for (; anInt.More(); anInt.Next()) {
- if (!selectBySubSelector(theContext, anInt.Value())) {
+ if (!selectBySubSelector(theContext, anInt.Value(),
+ theGeometricalNaming, theUseNeighbors, false)) {
break; // if some selector is failed, stop and search another solution
}
}
if (!anInt.More()) { // all intersectors were correctly named
myType = SELTYPE_INTERSECT;
return true;
- }
+ }
+ } else if (aCommon.Extent() > 1 && aLastCommon.IsEmpty()) {
+ aLastCommon = aCommon;
+ aLastIntersectors = anIntList;
}
}
if (!theUseNeighbors)
return false;
- // searching by neighbours
+ // searching by neighbors
std::list<std::pair<TopoDS_Shape, int> > aNBs; /// neighbor sub-shape -> level of neighborhood
for(int aLevel = 1; true; aLevel++) {
TopTools_MapOfShape aNewNB;
if (aNewNB.Extent() == 0) { // there are no neighbors of the given level, stop iteration
break;
}
- // check which can be named correctly, without by neighbors type
- for(TopTools_MapOfShape::Iterator aNBIter(aNewNB); aNBIter.More(); ) {
- Selector_Selector aSelector(myLab.FindChild(1));
- if (aSelector.select(theContext, aNBIter.Value(), false)) { // add to the list of good NBs
- aNBs.push_back(std::pair<TopoDS_Shape, int>(aNBIter.Value(), aLevel));
+ // iterate by the order in theContext to keep same naming names
+ TopExp_Explorer anOrder(theContext, theValue.ShapeType());
+ for (; anOrder.More(); anOrder.Next()) {
+ if (aNewNB.Contains(anOrder.Current())) {
+ TopoDS_Shape aNewNBShape = anOrder.Current();
+ // check which can be named correctly, without "by neighbors" type
+ Selector_Selector aSelector(myLab.FindChild(1));
+ aSelector.setBaseDocument(myBaseDocumentLab);
+ if (aSelector.select(theContext, aNewNBShape, theGeometricalNaming, false, false)) {
+ // add to list of good NBs
+ aNBs.push_back(std::pair<TopoDS_Shape, int>(aNewNBShape, aLevel));
+ }
}
- aNewNB.Remove(aNBIter.Key());
- aNBIter.Initialize(aNewNB);
}
- TopoDS_Shape aResult = findNeighbor(theContext, aNBs);
+ TopoDS_Shape aResult = findNeighbor(theContext, aNBs, theGeometricalNaming);
if (!aResult.IsNull() && aResult.IsSame(theValue)) {
std::list<std::pair<TopoDS_Shape, int> >::iterator aNBIter = aNBs.begin();
for(; aNBIter != aNBs.end(); aNBIter++) {
- if (!selectBySubSelector(theContext, aNBIter->first, false)) {
+ if (!selectBySubSelector(theContext, aNBIter->first,
+ theGeometricalNaming, false, false)) {
return false; // something is wrong because before this selection was ok
}
myNBLevel.push_back(aNBIter->second);
return true;
}
}
+
+ if (aLastCommon.Extent() > 1) {
+ if (myAlwaysGeometricalNaming) {
+ TopoDS_ListOfShape::Iterator aCommonIter(aLastCommon);
+ TopoDS_Shape aFirst = aCommonIter.Value();
+ for(aCommonIter.Next(); aCommonIter.More(); aCommonIter.Next()) {
+ if (!sameGeometry(aFirst, aCommonIter.Value()))
+ break;
+ }
+ if (!aCommonIter.More()) { // all geometry is same, result is a compound
+ myType = SELTYPE_INTERSECT;
+ return true;
+ }
+ }
+ // weak naming to distinguish commons coming from intersection
+ Selector_NExplode aNexp(aLastCommon);
+ myWeakIndex = aNexp.index(theValue);
+ if (myWeakIndex != -1) {
+ // name the intersectors
+ mySubSelList.clear();
+ TopoDS_ListOfShape::Iterator anInt(aLastIntersectors);
+ for (; anInt.More(); anInt.Next()) {
+ if (!selectBySubSelector(theContext, anInt.Value(),
+ theGeometricalNaming, theUseNeighbors, theUseIntersections)) {
+ break; // if some selector is failed, stop and search another solution
+ }
+ }
+ if (!anInt.More()) { // all intersectors were correctly named
+ myType = SELTYPE_INTERSECT;
+ return true;
+ }
+ }
+ }
+
+ // pure weak naming: there is no sense to use pure weak naming for neighbors selection
+ if (theUseNeighbors) {
+ myType = SELTYPE_WEAK_NAMING;
+ Selector_NExplode aNexp(theContext, theValue.ShapeType());
+ myWeakIndex = aNexp.index(theValue);
+ if (myWeakIndex != -1) {
+ myShapeType = theValue.ShapeType();
+ // searching for context shape label to store in myFinal
+ myFinal.Nullify();
+ if (TNaming_Tool::HasLabel(myLab, theContext)) {
+ for(TNaming_SameShapeIterator aShapes(theContext, myLab); aShapes.More(); aShapes.Next())
+ {
+ Handle(TNaming_NamedShape) aNS;
+ if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ TNaming_Evolution anEvolution = aNS->Evolution();
+ if (anEvolution == TNaming_PRIMITIVE || anEvolution == TNaming_GENERATED ||
+ anEvolution == TNaming_MODIFY) {
+ // check this is a new shape
+ for(TNaming_Iterator aNSIter(aNS); aNSIter.More(); aNSIter.Next()) {
+ if (aNSIter.NewShape().IsSame(theContext)) {
+ myFinal = aNS->Label();
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return true; // could be final empty (in case it is called recursively) or not
+ }
+ }
+
return false;
}
// searching for the base shapes of the value
Handle(TNaming_NamedShape) aPrimitiveNS;
NCollection_List<Handle(TNaming_NamedShape)> aModifList;
- for(TNaming_SameShapeIterator aShapes(theValue, myLab); aShapes.More(); aShapes.Next())
- {
- Handle(TNaming_NamedShape) aNS;
- if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
- TNaming_Evolution anEvolution = aNS->Evolution();
- if (anEvolution == TNaming_PRIMITIVE) { // the value shape is declared as PRIMITIVE
- aPrimitiveNS = aNS;
- break;
- } else if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
- // check this is a new shape
- TNaming_Iterator aNSIter(aNS);
- for(; aNSIter.More(); aNSIter.Next())
- if (aNSIter.NewShape().IsSame(theValue))
- break;
- if (aNSIter.More()) // new was found
- aModifList.Append(aNS);
+ for(int aUseExternal = 0; aUseExternal < 2; aUseExternal++) {
+ TDF_Label aLab = aUseExternal == 0 ? myLab : myBaseDocumentLab;
+ if (aLab.IsNull() || !TNaming_Tool::HasLabel(aLab, theValue))
+ continue;
+ for(TNaming_SameShapeIterator aShapes(theValue, aLab); aShapes.More(); aShapes.Next())
+ {
+ Handle(TNaming_NamedShape) aNS;
+ if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ TNaming_Evolution anEvolution = aNS->Evolution();
+ if (anEvolution == TNaming_PRIMITIVE) { // the value shape is declared as PRIMITIVE
+ aPrimitiveNS = aNS;
+ break;
+ } else if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
+ // check this is a new shape
+ TNaming_Iterator aNSIter(aNS);
+ for(; aNSIter.More(); aNSIter.Next())
+ if (aNSIter.NewShape().IsSame(theValue))
+ break;
+ if (aNSIter.More()) // new was found
+ aModifList.Append(aNS);
+ }
}
}
}
if (!aModifList.IsEmpty()) {
// searching for all the base shapes of this modification
- findBases(aModifList.First(), theValue, true, myBases);
+ findBases(myLab, aModifList.First(), theValue, true, myBaseDocumentLab, myBases);
if (!myBases.IsEmpty()) {
myFinal = aModifList.First()->Label();
TopoDS_ListOfShape aCommon;
findModificationResult(aCommon);
- // trying to search by neighbours
+ // trying to search by neighbors
if (aCommon.Extent() > 1) { // more complicated selection
+ if (myAlwaysGeometricalNaming) {
+ TopoDS_ListOfShape::Iterator aCommonIter(aCommon);
+ TopoDS_Shape aFirst = aCommonIter.Value();
+ for(aCommonIter.Next(); aCommonIter.More(); aCommonIter.Next()) {
+ if (!sameGeometry(aFirst, aCommonIter.Value()))
+ break;
+ }
+ if (!aCommonIter.More()) { // all geometry is same, result is a compound
+ myType = SELTYPE_MODIFICATION;
+ return true;
+ }
+ }
if (!theUseNeighbors)
return false;
- // searching by neighbours
- std::list<std::pair<TopoDS_Shape, int> > aNBs; /// neighbor sub-shape -> level of neighborhood
+ // searching by neighbors
+ std::list<std::pair<TopoDS_Shape, int> > aNBs;//neighbor sub-shape -> level of neighborhood
for(int aLevel = 1; true; aLevel++) {
TopTools_MapOfShape aNewNB;
findNeighbors(theContext, theValue, aLevel, aNewNB);
if (aNewNB.Extent() == 0) { // there are no neighbors of the given level, stop iteration
break;
}
- // check which can be named correctly, without by neighbors type
- for(TopTools_MapOfShape::Iterator aNBIter(aNewNB); aNBIter.More(); ) {
- Selector_Selector aSelector(myLab.FindChild(1));
- if (aSelector.select(theContext, aNBIter.Value(), false)) { // add to the list of good NBs
- aNBs.push_back(std::pair<TopoDS_Shape, int>(aNBIter.Value(), aLevel));
+ // iterate by the order in theContext to keep same naming names
+ TopExp_Explorer anOrder(theContext, theValue.ShapeType());
+ for (; anOrder.More(); anOrder.Next()) {
+ if (aNewNB.Contains(anOrder.Current())) {
+ TopoDS_Shape aNewNBShape = anOrder.Current();
+ // check which can be named correctly, without "by neighbors" type
+ Selector_Selector aSelector(myLab.FindChild(1));
+ if (!myBaseDocumentLab.IsNull())
+ aSelector.setBaseDocument(myBaseDocumentLab);
+ if (aSelector.select(theContext, aNewNBShape, theGeometricalNaming, false)) {
+ // add to list of good NBs
+ aNBs.push_back(std::pair<TopoDS_Shape, int>(aNewNBShape, aLevel));
+ }
}
- aNewNB.Remove(aNBIter.Key());
- aNBIter.Initialize(aNewNB);
}
- TopoDS_Shape aResult = findNeighbor(theContext, aNBs);
+ TopoDS_Shape aResult = findNeighbor(theContext, aNBs, theGeometricalNaming);
if (!aResult.IsNull() && aResult.IsSame(theValue)) {
std::list<std::pair<TopoDS_Shape, int> >::iterator aNBIter = aNBs.begin();
for(; aNBIter != aNBs.end(); aNBIter++) {
- if (!selectBySubSelector(theContext, aNBIter->first)) {
+ if (!selectBySubSelector(theContext, aNBIter->first,
+ theGeometricalNaming, theUseNeighbors, theUseIntersections)) {
return false; // something is wrong because before this selection was ok
}
myNBLevel.push_back(aNBIter->second);
return true;
}
}
- // filter by neighbours did not help
- if (aCommon.Extent() > 1) { // weak naming between the common results
+ // filter by neighbors did not help
+ if (aCommon.Extent() > 1) {
+ if (myAlwaysGeometricalNaming) {
+ TopoDS_ListOfShape::Iterator aCommonIter(aCommon);
+ TopoDS_Shape aFirst = aCommonIter.Value();
+ for(aCommonIter.Next(); aCommonIter.More(); aCommonIter.Next()) {
+ if (!sameGeometry(aFirst, aCommonIter.Value()))
+ break;
+ }
+ if (!aCommonIter.More()) { // all geometry is same, result is a compound
+ myType = SELTYPE_FILTER_BY_NEIGHBOR;
+ return true;
+ }
+ }
+ // weak naming between the common results
Selector_NExplode aNexp(aCommon);
myWeakIndex = aNexp.index(theValue);
if (myWeakIndex == -1)
}
}
myType = SELTYPE_MODIFICATION;
- return !myBases.IsEmpty();
+ if (myBases.IsEmpty()) { // selection based on the external shape, weak name by finals compound
+ TopoDS_ListOfShape aCommon;
+ myFinal = aModifList.First()->Label();
+ Handle(TNaming_NamedShape) aNS;
+ if (myFinal.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ for(TNaming_Iterator aFinalIter(aNS); aFinalIter.More(); aFinalIter.Next()) {
+ const TopoDS_Shape& aNewShape = aFinalIter.NewShape();
+ if (!aNewShape.IsNull())
+ aCommon.Append(aNewShape);
+ }
+ }
+ Selector_NExplode aNexp(aCommon);
+ myWeakIndex = aNexp.index(theValue);
+ if (myWeakIndex == -1)
+ return false;
+ }
+ return true;
}
// not found a good result
return false;
}
+/// Stores the array of references to the label: references to elements of ref-list, then the last
+static void storeBaseArray(const TDF_Label& theLab,
+ const TDF_LabelList& theRef, const TDF_Label& theLast)
+{
+ Handle(TDataStd_ReferenceArray) anArray =
+ TDataStd_ReferenceArray::Set(theLab, kBASE_ARRAY, 0, theRef.Extent());
+ Handle(TDataStd_ExtStringList) anEntries; // entries of references to external document
+ const TDF_Label aThisDocRoot = theLab.Root();
+ TDF_LabelList::Iterator aBIter(theRef);
+ for(int anIndex = 0; true; aBIter.Next(), anIndex++) {
+ const TDF_Label& aLab = aBIter.More() ? aBIter.Value() : theLast;
+ // check this is a label of this document
+ if (aLab.Root().IsEqual(aThisDocRoot)) {
+ anArray->SetValue(anIndex, aLab);
+ } else { // store reference to external document as an entry-string
+ if (anEntries.IsNull()) {
+ anEntries = TDataStd_ExtStringList::Set(theLab, kBASE_LIST);
+ }
+ TCollection_AsciiString anEntry;
+ TDF_Tool::Entry(aLab, anEntry);
+ anEntries->Append(anEntry);
+ anArray->SetValue(anIndex, aThisDocRoot); // stored root means it is external reference
+ }
+ if (!aBIter.More())
+ break;
+ }
+}
+
void Selector_Selector::store()
{
+ static const TDF_LabelList anEmptyRefList;
myLab.ForgetAllAttributes(true); // remove old naming data
TDataStd_Integer::Set(myLab, kSEL_TYPE, (int)myType);
+ if (myGeometricalNaming)
+ TDataStd_UAttribute::Set(myLab, kGEOMETRICAL_NAMING);
switch(myType) {
case SELTYPE_CONTAINER:
case SELTYPE_INTERSECT: {
for(; aSubSel != mySubSelList.end(); aSubSel++) {
aSubSel->store();
}
+ if (myWeakIndex != -1) {
+ TDataStd_Integer::Set(myLab, kWEAK_INDEX, myWeakIndex);
+ }
break;
}
case SELTYPE_PRIMITIVE: {
- Handle(TDataStd_ReferenceArray) anArray =
- TDataStd_ReferenceArray::Set(myLab, kBASE_ARRAY, 0, 0);
- anArray->SetValue(0, myFinal);
+ storeBaseArray(myLab, anEmptyRefList, myFinal);
break;
}
case SELTYPE_MODIFICATION: {
- Handle(TDataStd_ReferenceArray) anArray =
- TDataStd_ReferenceArray::Set(myLab, kBASE_ARRAY, 0, myBases.Extent());
- TDF_LabelList::Iterator aBIter(myBases);
- for(int anIndex = 0; aBIter.More(); aBIter.Next(), anIndex++) {
- anArray->SetValue(anIndex, aBIter.Value());
- }
- anArray->SetValue(myBases.Extent(), myFinal); // final is in the end of array
+ storeBaseArray(myLab, myBases, myFinal);
if (myWeakIndex != -1) {
TDataStd_Integer::Set(myLab, kWEAK_INDEX, myWeakIndex);
}
for(; aSubSel != mySubSelList.end(); aSubSel++) {
aSubSel->store();
}
+ break;
+ }
+ case SELTYPE_WEAK_NAMING: {
+ TDataStd_Integer::Set(myLab, kWEAK_INDEX, myWeakIndex);
+ TDataStd_Integer::Set(myLab, kSHAPE_TYPE, (int)myShapeType);
+ if (!myFinal.IsNull()) {
+ storeBaseArray(myLab, anEmptyRefList, myFinal);
+ }
+ break;
}
default: { // unknown case
break;
}
}
+/// Restores references to the labels: references to elements of ref-list, then the last
+static bool restoreBaseArray(const TDF_Label& theLab, const TDF_Label& theBaseDocumetnLab,
+ TDF_LabelList& theRef, TDF_Label& theLast)
+{
+ const TDF_Label aThisDocRoot = theLab.Root();
+ Handle(TDataStd_ExtStringList) anEntries; // entries of references to external document
+ TDataStd_ListOfExtendedString::Iterator anIter;
+ Handle(TDataStd_ReferenceArray) anArray;
+ if (theLab.FindAttribute(kBASE_ARRAY, anArray)) {
+ int anUpper = anArray->Upper();
+ for(int anIndex = anArray->Lower(); anIndex <= anUpper; anIndex++) {
+ TDF_Label aLab = anArray->Value(anIndex);
+ if (aLab.IsEqual(aThisDocRoot)) { // external document reference
+ if (theBaseDocumetnLab.IsNull())
+ return false;
+ if (anEntries.IsNull()) {
+ if (!theLab.FindAttribute(kBASE_LIST, anEntries))
+ return false;
+ anIter.Initialize(anEntries->List());
+ }
+ if (!anIter.More())
+ return false;
+ TDF_Tool::Label(theBaseDocumetnLab.Data(), anIter.Value(), aLab);
+ anIter.Next();
+ }
+ if (anIndex == anUpper) {
+ theLast = aLab;
+ } else {
+ theRef.Append(aLab);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+
bool Selector_Selector::restore()
{
Handle(TDataStd_Integer) aTypeAttr;
if (!myLab.FindAttribute(kSEL_TYPE, aTypeAttr))
return false;
+ myGeometricalNaming = myLab.IsAttribute(kGEOMETRICAL_NAMING);
myType = Selector_Type(aTypeAttr->Get());
switch(myType) {
case SELTYPE_CONTAINER:
mySubSelList.clear();
for(TDF_ChildIDIterator aSub(myLab, kSEL_TYPE, false); aSub.More(); aSub.Next()) {
mySubSelList.push_back(Selector_Selector(aSub.Value()->Label()));
+ mySubSelList.back().setBaseDocument(myBaseDocumentLab);
if (!mySubSelList.back().restore())
aSubResult = false;
}
+ Handle(TDataStd_Integer) aWeakInt;
+ if (myLab.FindAttribute(kWEAK_INDEX, aWeakInt)) {
+ myWeakIndex = aWeakInt->Get();
+ }
return aSubResult;
}
case SELTYPE_PRIMITIVE: {
- Handle(TDataStd_ReferenceArray) anArray;
- if (myLab.FindAttribute(kBASE_ARRAY, anArray)) {
- myFinal = anArray->Value(0);
- return true;
- }
- return false;
+ return restoreBaseArray(myLab, myBaseDocumentLab, myBases, myFinal);
}
case SELTYPE_MODIFICATION: {
- Handle(TDataStd_ReferenceArray) anArray;
- if (myLab.FindAttribute(kBASE_ARRAY, anArray)) {
- int anUpper = anArray->Upper();
- for(int anIndex = 0; anIndex < anUpper; anIndex++) {
- myBases.Append(anArray->Value(anIndex));
- }
- myFinal = anArray->Value(anUpper);
+ if (restoreBaseArray(myLab, myBaseDocumentLab, myBases, myFinal)) {
Handle(TDataStd_Integer) aWeakInt;
if (myLab.FindAttribute(kWEAK_INDEX, aWeakInt)) {
myWeakIndex = aWeakInt->Get();
mySubSelList.clear();
for(TDF_ChildIDIterator aSub(myLab, kSEL_TYPE, false); aSub.More(); aSub.Next()) {
mySubSelList.push_back(Selector_Selector(aSub.Value()->Label()));
+ mySubSelList.back().setBaseDocument(myBaseDocumentLab);
if (!mySubSelList.back().restore())
aSubResult = false;
}
}
return true;
}
+ case SELTYPE_WEAK_NAMING: {
+ Handle(TDataStd_Integer) aWeakInt;
+ if (!myLab.FindAttribute(kWEAK_INDEX, aWeakInt))
+ return false;
+ myWeakIndex = aWeakInt->Get();
+ Handle(TDataStd_Integer) aShapeTypeAttr;
+ if (!myLab.FindAttribute(kSHAPE_TYPE, aShapeTypeAttr))
+ return false;
+ myShapeType = TopAbs_ShapeEnum(aShapeTypeAttr->Get());
+ if (!restoreBaseArray(myLab, myBaseDocumentLab, myBases, myFinal))
+ return false;
+ return true;
+ }
default: { // unknown case
}
}
}
/// Returns in theResults all shapes with history started in theBase and ended in theFinal
-static void findFinals(const TopoDS_Shape& theBase, const TDF_Label& theFinal,
- TopTools_MapOfShape& theResults)
+static void findFinals(const TDF_Label& anAccess, const TopoDS_Shape& theBase,
+ const TDF_Label& theFinal,
+ const TDF_Label& theAdditionalDoc, TopTools_MapOfShape& theResults)
{
- for(TNaming_NewShapeIterator aBaseIter(theBase, theFinal); aBaseIter.More(); aBaseIter.Next()) {
- TNaming_Evolution anEvolution = aBaseIter.NamedShape()->Evolution();
- if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
- if (aBaseIter.NamedShape()->Label().IsEqual(theFinal)) {
- theResults.Add(aBaseIter.Shape());
- } else {
- findFinals(aBaseIter.Shape(), theFinal, theResults);
+ if (TNaming_Tool::HasLabel(anAccess, theBase)) {
+ for(TNaming_NewShapeIterator aBaseIter(theBase, anAccess); aBaseIter.More(); aBaseIter.Next())
+ {
+ TNaming_Evolution anEvolution = aBaseIter.NamedShape()->Evolution();
+ if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
+ if (aBaseIter.NamedShape()->Label().IsEqual(theFinal)) {
+ theResults.Add(aBaseIter.Shape());
+ } else {
+ findFinals(anAccess, aBaseIter.Shape(), theFinal, theAdditionalDoc, theResults);
+ }
}
}
}
+ if (!theAdditionalDoc.IsNull()) { // search additionally by the additional access label
+ static TDF_Label anEmpty;
+ findFinals(theAdditionalDoc, theBase, theFinal, anEmpty, theResults);
+ }
}
void Selector_Selector::findModificationResult(TopoDS_ListOfShape& theCommon) {
for(TDF_LabelList::Iterator aBase(myBases); aBase.More(); aBase.Next()) {
+ TDF_Label anAdditionalDoc; // this document if base is started in extra document
+ if (aBase.Value().Root() != myLab.Root()) {
+ anAdditionalDoc = myLab;
+ }
TopTools_MapOfShape aFinals;
- for(TNaming_Iterator aBaseShape(aBase.Value()); aBaseShape.More(); aBaseShape.Next())
- findFinals(aBaseShape.NewShape(), myFinal, aFinals);
+ for(TNaming_Iterator aBaseShape(aBase.Value()); aBaseShape.More(); aBaseShape.Next()) {
+ findFinals(aBase.Value(), aBaseShape.NewShape(), myFinal, anAdditionalDoc, aFinals);
+ }
if (!aFinals.IsEmpty()) {
if (theCommon.IsEmpty()) { // just copy all to common
for(TopTools_MapOfShape::Iterator aFinal(aFinals); aFinal.More(); aFinal.Next()) {
}
TopoDS_ListOfShape aCommon; // common sub shapes in each sub-selector (a result)
commonShapes(aSubSelectorShapes, myShapeType, aCommon);
- if (aCommon.Extent() != 1)
- return false;
- aResult = aCommon.First();
+ if (aCommon.Extent() != 1) {
+ if (myWeakIndex != -1) {
+ Selector_NExplode aNexp(aCommon);
+ aResult = aNexp.shape(myWeakIndex);
+ } else if (myGeometricalNaming && aCommon.Extent() > 1) {
+ // check results are on the same geometry, create compound
+ TopoDS_ListOfShape::Iterator aCommonIter(aCommon);
+ TopoDS_Shape aFirst = aCommonIter.Value();
+ for(aCommonIter.Next(); aCommonIter.More(); aCommonIter.Next()) {
+ if (!sameGeometry(aFirst, aCommonIter.Value()))
+ break;
+ }
+ if (!aCommonIter.More()) { // all geometry is same, create a result compound
+ TopoDS_Builder aBuilder;
+ TopoDS_Compound aCompound;
+ aBuilder.MakeCompound(aCompound);
+ for(aCommonIter.Initialize(aCommon); aCommonIter.More(); aCommonIter.Next()) {
+ aBuilder.Add(aCompound, aCommonIter.Value());
+ }
+ aResult = aCompound;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ aResult = aCommon.First();
+ }
break;
}
case SELTYPE_PRIMITIVE: {
if (myFinal.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
aResult = aNS->Get();
}
+ break;
}
case SELTYPE_MODIFICATION: {
- TopoDS_ListOfShape aFinalsCommon; // final shapes presented in all results from bases
- findModificationResult(aFinalsCommon);
- if (aFinalsCommon.Extent() == 1) // only in this case result is valid: found only one shape
- aResult = aFinalsCommon.First();
- else if (aFinalsCommon.Extent() > 1 && myWeakIndex) {
- Selector_NExplode aNExp(aFinalsCommon);
- aResult = aNExp.shape(myWeakIndex);
+ if (myBases.IsEmpty() && myWeakIndex > 0) { // weak name by the final shapes index
+ TopoDS_ListOfShape aCommon;
+ Handle(TNaming_NamedShape) aNS;
+ if (myFinal.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ for(TNaming_Iterator aFinalIter(aNS); aFinalIter.More(); aFinalIter.Next()) {
+ const TopoDS_Shape& aNewShape = aFinalIter.NewShape();
+ if (!aNewShape.IsNull())
+ aCommon.Append(aNewShape);
+ }
+ }
+ Selector_NExplode aNexp(aCommon);
+ aResult = aNexp.shape(myWeakIndex);
+ } else { // standard case
+ TopoDS_ListOfShape aFinalsCommon; // final shapes presented in all results from bases
+ findModificationResult(aFinalsCommon);
+ if (aFinalsCommon.Extent() == 1) { // result is valid: found only one shape
+ aResult = aFinalsCommon.First();
+ } else if (aFinalsCommon.Extent() > 1 && myWeakIndex > 0) {
+ Selector_NExplode aNExp(aFinalsCommon);
+ aResult = aNExp.shape(myWeakIndex);
+ } else if (aFinalsCommon.Extent() > 1 && myGeometricalNaming) {// if same geometry - compound
+ TopoDS_ListOfShape::Iterator aCommonIter(aFinalsCommon);
+ TopoDS_Shape aFirst = aCommonIter.Value();
+ for(aCommonIter.Next(); aCommonIter.More(); aCommonIter.Next()) {
+ if (!sameGeometry(aFirst, aCommonIter.Value()))
+ break;
+ }
+ if (!aCommonIter.More()) { // all geometry is same, create a result compound
+ TopoDS_Builder aBuilder;
+ TopoDS_Compound aCompound;
+ aBuilder.MakeCompound(aCompound);
+ for(aCommonIter.Initialize(aFinalsCommon); aCommonIter.More(); aCommonIter.Next()) {
+ aBuilder.Add(aCompound, aCommonIter.Value());
+ }
+ aResult = aCompound;
+ }
+ }
}
break;
}
}
aNBs.push_back(std::pair<TopoDS_Shape, int>(aSubSel->value(), *aLevel));
}
- aResult = findNeighbor(theContext, aNBs);
+ aResult = findNeighbor(theContext, aNBs, myGeometricalNaming);
+ break;
+ }
+ case SELTYPE_WEAK_NAMING: {
+ TopoDS_Shape aContext;
+ if (myFinal.IsNull()) {
+ aContext = theContext;
+ } else {
+ Handle(TNaming_NamedShape) aNS;
+ if (myFinal.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ aContext = aNS->Get();
+ }
+ }
+ if (!aContext.IsNull()) {
+ Selector_NExplode aNexp(aContext, myShapeType);
+ aResult = aNexp.shape(myWeakIndex);
+ }
}
default: { // unknown case
}
return TopoDS_Shape(); // empty, error shape
}
-static const std::string kWEAK_NAME_IDENTIFIER = "weak_name_";
-
std::string Selector_Selector::name(Selector_NameGenerator* theNameGenerator) {
switch(myType) {
case SELTYPE_CONTAINER:
case SELTYPE_INTERSECT: {
std::string aResult;
- // add names of sub-components one by one in "[]"
+ // add names of sub-components one by one in "[]" +optionally [weak_name_1]
std::list<Selector_Selector>::iterator aSubSel = mySubSelList.begin();
for(; aSubSel != mySubSelList.end(); aSubSel++) {
aResult += '[';
aResult += aSubSel->name(theNameGenerator);
aResult += ']';
+ TopoDS_Shape aSubVal = aSubSel->value();
+ if (!aSubVal.IsNull()) {
+ TopAbs_ShapeEnum aSubType = aSubVal.ShapeType();
+ if (aSubType != TopAbs_FACE) { // in case the sub shape type must be stored
+ switch(aSubType) {
+ case TopAbs_COMPOUND: aResult += "c"; break;
+ case TopAbs_COMPSOLID: aResult += "o"; break;
+ case TopAbs_SOLID: aResult += "s"; break;
+ case TopAbs_SHELL: aResult += "h"; break;
+ case TopAbs_WIRE: aResult += "w"; break;
+ case TopAbs_EDGE: aResult += "e"; break;
+ case TopAbs_VERTEX: aResult += "v"; break;
+ default:
+ ;
+ }
+ }
+ }
+ }
+ if (myWeakIndex != -1) {
+ std::ostringstream aWeakStr;
+ aWeakStr<<"["<<kWEAK_NAME_IDENTIFIER<<myWeakIndex<<"]";
+ aResult += aWeakStr.str();
}
return aResult;
}
if (!myFinal.FindAttribute(TDataStd_Name::GetID(), aName))
return "";
aResult += theNameGenerator->contextName(myFinal) + "/" +
- std::string(TCollection_AsciiString(aName->Get()).ToCString()) + "&";
+ std::string(TCollection_AsciiString(aName->Get()).ToCString());
for(TDF_LabelList::iterator aBase = myBases.begin(); aBase != myBases.end(); aBase++) {
- if (aBase != myBases.begin())
- aResult += "&";
if (!aBase->FindAttribute(TDataStd_Name::GetID(), aName))
return "";
+ aResult += "&";
aResult += theNameGenerator->contextName(*aBase) + "/" +
std::string(TCollection_AsciiString(aName->Get()).ToCString());
- if (myWeakIndex != -1) {
- std::ostringstream aWeakStr;
- aWeakStr<<"&"<<kWEAK_NAME_IDENTIFIER<<myWeakIndex;
- aResult += aWeakStr.str();
- }
+ }
+ if (myWeakIndex != -1) {
+ std::ostringstream aWeakStr;
+ aWeakStr<<"&"<<kWEAK_NAME_IDENTIFIER<<myWeakIndex;
+ aResult += aWeakStr.str();
}
return aResult;
}
std::list<Selector_Selector>::iterator aSubSel = mySubSelList.begin();
for(; aSubSel != mySubSelList.end(); aSubSel++, aLevel++) {
aResult += "(" + aSubSel->name(theNameGenerator) + ")";
- if (*aLevel > 1)
- aResult += *aLevel;
+ if (*aLevel > 1) {
+ std::ostringstream aLevelStr;
+ aLevelStr<<*aLevel;
+ aResult += aLevelStr.str();
+ }
}
return aResult;
}
+ case SELTYPE_WEAK_NAMING: {
+ // _weak_naming_1_Context
+ std::ostringstream aWeakStr;
+ aWeakStr<<kPUREWEAK_NAME_IDENTIFIER<<myWeakIndex;
+ std::string aResult = aWeakStr.str();
+ if (!myFinal.IsNull())
+ aResult += "_" + theNameGenerator->contextName(myFinal);
+ return aResult;
+ }
default: { // unknown case
}
};
TDF_Label Selector_Selector::restoreByName(
std::string theName, const TopAbs_ShapeEnum theShapeType,
- Selector_NameGenerator* theNameGenerator)
+ Selector_NameGenerator* theNameGenerator, const bool theGeometricalNaming)
{
+ myGeometricalNaming = theGeometricalNaming;
if (theName[0] == '[') { // intersection or container
switch(theShapeType) {
case TopAbs_COMPOUND:
size_t anEndPos = theName.find(']', aStart + 1);
if (anEndPos != std::string::npos) {
std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1);
+ if (aSubStr.find(kWEAK_NAME_IDENTIFIER) == 0) { // weak name identifier
+ std::string aWeakIndex = aSubStr.substr(kWEAK_NAME_IDENTIFIER.size());
+ myWeakIndex = atoi(aWeakIndex.c_str());
+ continue;
+ }
+ TopAbs_ShapeEnum aSubShapeType = TopAbs_FACE;
+ if (anEndPos != std::string::npos && anEndPos + 1 < theName.size()) {
+ char aShapeChar = theName[anEndPos + 1];
+ if (theName[anEndPos + 1] != '[') {
+ switch(aShapeChar) {
+ case 'c': aSubShapeType = TopAbs_COMPOUND; break;
+ case 'o': aSubShapeType = TopAbs_COMPSOLID; break;
+ case 's': aSubShapeType = TopAbs_SOLID; break;
+ case 'h': aSubShapeType = TopAbs_SHELL; break;
+ case 'w': aSubShapeType = TopAbs_WIRE; break;
+ case 'e': aSubShapeType = TopAbs_EDGE; break;
+ case 'v': aSubShapeType = TopAbs_VERTEX; break;
+ default:;
+ }
+ }
+ }
mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1)));
- TDF_Label aSubContext =
- mySubSelList.back().restoreByName(aSubStr, theShapeType, theNameGenerator);
+ mySubSelList.back().setBaseDocument(myBaseDocumentLab);
+ TDF_Label aSubContext = mySubSelList.back().restoreByName(
+ aSubStr, aSubShapeType, theNameGenerator, theGeometricalNaming);
if (aSubContext.IsNull())
return aSubContext; // invalid sub-selection parsing
if (!aContext.IsNull() && !aContext.IsEqual(aSubContext)) {
return TDF_Label(); // invalid parentheses
}
return aContext;
- } else if (theName[0] == '(') { // filter by neighbours
+ } else if (theName[0] == '(') { // filter by neighbors
myType = SELTYPE_FILTER_BY_NEIGHBOR;
TDF_Label aContext;
for(size_t aStart = 0; aStart != std::string::npos;
if (anEndPos != std::string::npos) {
std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1);
mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1)));
- TDF_Label aSubContext =
- mySubSelList.back().restoreByName(aSubStr, theShapeType, theNameGenerator);
+ mySubSelList.back().setBaseDocument(myBaseDocumentLab);
+ TDF_Label aSubContext = mySubSelList.back().restoreByName(
+ aSubStr, theShapeType, theNameGenerator, theGeometricalNaming);
if (aSubContext.IsNull())
return aSubContext; // invalid sub-selection parsing
if (!aContext.IsNull() && !aContext.IsEqual(aSubContext)) {
} else {
aContext = aSubContext;
}
+ if (!aContext.IsNull()) // for filters by neighbor the latest context shape is vital
+ aContext = theNameGenerator->newestContext(aContext);
+
// searching for the level index
std::string aLevel;
for(anEndPos++; anEndPos != std::string::npos &&
return TDF_Label(); // invalid parentheses
}
return aContext;
- } else if (theName.find('&') == std::string::npos) { // wihtout '&' it can be only primitive
+ } if (theName.find(kPUREWEAK_NAME_IDENTIFIER) == 0) { // weak naming identifier
+ myType = SELTYPE_WEAK_NAMING;
+ std::string aWeakIndex = theName.substr(kPUREWEAK_NAME_IDENTIFIER.size());
+ std::size_t aContextPosition = aWeakIndex.find("_");
+ myWeakIndex = atoi(aWeakIndex.c_str());
+ myShapeType = theShapeType;
+ TDF_Label aContext;
+ if (aContextPosition != std::string::npos) { // context is also defined
+ std::string aContextName = aWeakIndex.substr(aContextPosition + 1);
+ theNameGenerator->restoreContext(aContextName, aContext, myFinal);
+ }
+ return aContext;
+ } else if (theName.find('&') == std::string::npos) { // without '&' it can be only primitive
myType = SELTYPE_PRIMITIVE;
TDF_Label aContext;
if (theNameGenerator->restoreContext(theName, aContext, myFinal)) {
return TDF_Label();
}
-bool Selector_Selector::selectBySubSelector(
- const TopoDS_Shape theContext, const TopoDS_Shape theValue, const bool theUseNeighbors)
+bool Selector_Selector::selectBySubSelector(const TopoDS_Shape theContext,
+ const TopoDS_Shape theValue, const bool theGeometricalNaming,
+ const bool theUseNeighbors, const bool theUseIntersections)
{
mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1)));
- if (!mySubSelList.back().select(theContext, theValue, theUseNeighbors)) {
+ if (!myBaseDocumentLab.IsNull())
+ mySubSelList.back().setBaseDocument(myBaseDocumentLab);
+ if (!mySubSelList.back().select(theContext, theValue,
+ theGeometricalNaming, theUseNeighbors, theUseIntersections)) {
mySubSelList.clear(); // if one of the selector is failed, all become invalid
return false;
}
return true;
}
+
+void Selector_Selector::combineGeometrical(const TopoDS_Shape theContext)
+{
+ TopoDS_Shape aValue = value();
+ if (aValue.IsNull() || aValue.ShapeType() == TopAbs_COMPOUND)
+ return;
+ myAlwaysGeometricalNaming = true;
+ mySubSelList.clear();
+ myBases.Clear();
+ myWeakIndex = -1;
+ if (select(theContext, aValue, true)) {
+ store();
+ solve(theContext);
+ return;
+ }
+ // if can not select, select the compound in a custom way
+ TopTools_MapOfShape aMap;
+ TopoDS_ListOfShape aList;
+ for(TopExp_Explorer anExp(theContext, aValue.ShapeType()); anExp.More(); anExp.Next()) {
+ if (aMap.Add(anExp.Current())) {
+ if (sameGeometry(aValue, anExp.Current()))
+ aList.Append(anExp.Current());
+ }
+ }
+ if (aList.Size() > 1) {
+ TopoDS_Builder aBuilder;
+ TopoDS_Compound aCompound;
+ aBuilder.MakeCompound(aCompound);
+ for(TopoDS_ListIteratorOfListOfShape aListIter(aList); aListIter.More(); aListIter.Next()) {
+ aBuilder.Add(aCompound, aListIter.Value());
+ }
+ if (select(theContext, aCompound, true)) {
+ store();
+ solve(theContext);
+ }
+ }
+}