Provide the backward compatibility of selection mechanism.
}
} else if (theName[0] == '(') { // 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
aResult = new Selector_Modify;
static const Standard_GUID kSHAPE_TYPE("864b3267-cb9d-4107-bf58-c3ce1775b171");
return kSHAPE_TYPE;
}
+ /// old string identifier of the weak name in modification or intersection types of algorithm
+ static const std::string& oldWeakNameID()
+ {
+ static const std::string kWEAK_NAME_IDENTIFIER = "weak_name_";
+ return kWEAK_NAME_IDENTIFIER;
+ }
+ /// old string identifier of the pure weak name
+ static const std::string& oldPureWeakNameID()
+ {
+ static const std::string kPURE_WEAK_NAME_IDENTIFIER = "_weak_name_";
+ return kPURE_WEAK_NAME_IDENTIFIER;
+ }
/// string identifier of the weak name in modification or intersection types of algorithm
static const std::string& weakNameID()
{
- static const std::string kWEAK_NAME_IDENTIFIER = "weak_name_";
+ static const std::string kWEAK_NAME_IDENTIFIER = std::string("new_") + oldWeakNameID();
return kWEAK_NAME_IDENTIFIER;
}
/// string identifier of the pure weak name
static const std::string& pureWeakNameID()
{
- static const std::string kPURE_WEAK_NAME_IDENTIFIER = "_weak_name_";
+ static const std::string kPURE_WEAK_NAME_IDENTIFIER = std::string("_new") + oldPureWeakNameID();
return kPURE_WEAK_NAME_IDENTIFIER;
}
/// Stores the type of an algorithm in the data tree (in myLab)
Selector_Intersect::Selector_Intersect() : Selector_AlgoWithSubs()
{
myWeakIndex = -1; // no index by default
+ myRecomputeWeakIndex = false;
}
// returns the sub-shapes of theSubType which belong to all theShapes (so, common or intersection)
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(weakNameID()) == 0) { // weak name identifier
- std::string aWeakIndex = aSubStr.substr(weakNameID().size());
+ size_t aFoundOldWeak = aSubStr.find(oldWeakNameID());
+ size_t aFoundNewWeak = aFoundOldWeak != std::string::npos ?
+ aSubStr.find(weakNameID()) :
+ aFoundOldWeak;
+ if (aFoundOldWeak == 0 || aFoundNewWeak == 0) { // weak name identifier
+ std::string aWeakIndex = aSubStr.substr(aFoundOldWeak + oldWeakNameID().size());
myWeakIndex = atoi(aWeakIndex.c_str());
+ myRecomputeWeakIndex = aFoundOldWeak == 0;
continue;
}
TopAbs_ShapeEnum aSubShapeType = TopAbs_FACE;
commonShapes(aSubSelectorShapes, myShapeType, aCommon);
if (aCommon.Extent() != 1) {
if (myWeakIndex != -1) {
- Selector_NExplode aNexp(aCommon);
+ Selector_NExplode aNexp(aCommon, myRecomputeWeakIndex);
aResult = aNexp.shape(myWeakIndex);
+ myRecomputeWeakIndex = false;
} else if (geometricalNaming() && aCommon.Extent() > 1) {
// check results are on the same geometry, create compound
TopoDS_ListOfShape::Iterator aCommonIter(aCommon);
{
TopAbs_ShapeEnum myShapeType; ///< type of this shape
int myWeakIndex; ///< weak index in case intersection produces several shapes
+ bool myRecomputeWeakIndex; ///< if the index is stored with old (unstable) order, recompute it
public:
/// Initializes the selection of this kind
SELECTOR_EXPORT bool select(const TopoDS_Shape theContext, const TopoDS_Shape theValue);
Selector_Modify::Selector_Modify() : Selector_Algo()
{
myWeakIndex = -1; // no index by default
+ myRecomputeWeakIndex = false;
}
// adds to theResult all labels that contain initial shapes for theValue located in theFinal
anEnd = theName.find('&', aStart);
std::string aSubStr =
theName.substr(aStart, anEnd == std::string::npos ? anEnd : anEnd - aStart);
- if (aSubStr.find(weakNameID()) == 0) { // weak name identifier
- std::string aWeakIndex = aSubStr.substr(weakNameID().size());
- myWeakIndex = atoi(aWeakIndex.c_str());
+ size_t aFoundOldWeak = aSubStr.find(oldWeakNameID());
+ size_t aFoundNewWeak = aFoundOldWeak != std::string::npos ?
+ aSubStr.find(weakNameID()) :
+ aFoundOldWeak;
+ if (aFoundOldWeak == 0 || aFoundNewWeak == 0) { // weak name identifier
+ std::string aWeakIndex = aSubStr.substr(aFoundOldWeak + oldWeakNameID().size());\r myWeakIndex = atoi(aWeakIndex.c_str());
+ myRecomputeWeakIndex = aFoundOldWeak == 0;
continue;
}
TDF_Label aSubContext, aValue;
aCommon.Append(aNewShape);
}
}
- Selector_NExplode aNexp(aCommon);
+ Selector_NExplode aNexp(aCommon, myRecomputeWeakIndex);
aResult = aNexp.shape(myWeakIndex);
+ myRecomputeWeakIndex = false;
} else { // standard case
TopoDS_ListOfShape aFinalsCommon; // final shapes presented in all results from bases
findModificationResult(aFinalsCommon);
aResult = aFinalsCommon.First();
findNewVersion(theContext, aResult);
} else if (aFinalsCommon.Extent() > 1 && myWeakIndex > 0) {
- Selector_NExplode aNExp(aFinalsCommon);
+ Selector_NExplode aNExp(aFinalsCommon, myRecomputeWeakIndex);
aResult = aNExp.shape(myWeakIndex);
+ myRecomputeWeakIndex = false;
findNewVersion(theContext, aResult);
} else if (aFinalsCommon.Extent() > 1 && geometricalNaming()) {// if same geometry - compound
TopoDS_ListOfShape::Iterator aCommonIter(aFinalsCommon);
TDF_Label myFinal; ///< final label of the primitive or generation, where the value is
TDF_LabelList myBases; ///< initial labels that contain shapes that produce the modification
int myWeakIndex; ///< weak index in case modification produces several shapes
+ bool myRecomputeWeakIndex; ///< if the index is stored with old (unstable) order, recompute it
public:
/// Initializes the selection of this kind by list of named shapes where the modification results
/// are presented and the selected value.
#include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx>
-#include <vector>
#include <algorithm>
-static std::pair<gp_Pnt, double> ShapeToDouble (const TopoDS_Shape& S)
+static void dummy(gp_Pnt& thePoint)
+{
+ // do nothing (new approach to order shapes)
+}
+
+static void pointToDouble(gp_Pnt& thePoint)
+{
+ // old approach to order shapes
+ double dMidXYZ = thePoint.X() * 999.0 + thePoint.Y() * 99.0 + thePoint.Z() * 0.9;
+ thePoint.SetCoord(dMidXYZ, 0.0, 0.0);
+}
+
+static std::pair<gp_Pnt, double> ShapeToDouble (const TopoDS_Shape& S,
+ void (*convertPoint)(gp_Pnt&))
{
// Computing of CentreOfMass
gp_Pnt GPoint;
Len = GPr.Mass();
}
+ (*convertPoint)(GPoint);
return std::make_pair(GPoint, Len);
}
{
typedef NCollection_DataMap<TopoDS_Shape, std::pair<gp_Pnt, double> > DataMapOfShapeDouble;
- CompareShapes(DataMapOfShapeDouble* theCashMap) : myMap(theCashMap) {}
+ CompareShapes(DataMapOfShapeDouble* theCashMap, void (*convertPoint)(gp_Pnt&))
+ : myMap(theCashMap), myConvertPoint(convertPoint) {}
bool operator() (const TopoDS_Shape& lhs, const TopoDS_Shape& rhs);
DataMapOfShapeDouble* myMap;
+ void (*myConvertPoint)(gp_Pnt&);
};
bool CompareShapes::operator() (const TopoDS_Shape& theShape1,
const TopoDS_Shape& theShape2)
{
if (!myMap->IsBound(theShape1)) {
- myMap->Bind(theShape1, ShapeToDouble(theShape1));
+ myMap->Bind(theShape1, ShapeToDouble(theShape1, myConvertPoint));
}
if (!myMap->IsBound(theShape2)) {
- myMap->Bind(theShape2, ShapeToDouble(theShape2));
+ myMap->Bind(theShape2, ShapeToDouble(theShape2, myConvertPoint));
}
const std::pair<gp_Pnt, double>& val1 = myMap->Find(theShape1);
return !exchange;
}
-Selector_NExplode::Selector_NExplode(const TopoDS_ListOfShape& theShapes)
+Selector_NExplode::Selector_NExplode(const TopoDS_ListOfShape& theShapes, const bool theOldOrder)
+ : myToBeReordered(theOldOrder)
{
- std::vector<TopoDS_Shape> aShapesVec;
-
for(TopoDS_ListOfShape::Iterator anIter(theShapes); anIter.More(); anIter.Next()) {
- aShapesVec.push_back(anIter.Value());
+ mySorted.push_back(anIter.Value());
}
CompareShapes::DataMapOfShapeDouble aCash;
- CompareShapes shComp(&aCash);
- std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
-
- std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
- for (; anIter != aShapesVec.end(); ++anIter) {
- mySorted.Append(*anIter);
- }
+ CompareShapes shComp(&aCash, theOldOrder ? pointToDouble : dummy);
+ std::stable_sort(mySorted.begin(), mySorted.end(), shComp);
}
-Selector_NExplode::Selector_NExplode(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType)
+Selector_NExplode::Selector_NExplode(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType,
+ const bool theOldOrder)
+ : myToBeReordered(theOldOrder)
{
- std::vector<TopoDS_Shape> aShapesVec;
TopTools_MapOfShape anAdded; // to avoid same shapes duplication
for(TopExp_Explorer anExp(theShape, theType); anExp.More(); anExp.Next()) {
if (anAdded.Add(anExp.Current()))
- aShapesVec.push_back(anExp.Current());
+ mySorted.push_back(anExp.Current());
}
CompareShapes::DataMapOfShapeDouble aCash;
- CompareShapes shComp(&aCash);
- std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
-
- std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
- for (; anIter != aShapesVec.end(); ++anIter) {
- mySorted.Append(*anIter);
- }
+ CompareShapes shComp(&aCash, theOldOrder ? pointToDouble : dummy);
+ std::stable_sort(mySorted.begin(), mySorted.end(), shComp);
}
int Selector_NExplode::index(const TopoDS_Shape& theSubShape)
{
- TopoDS_ListOfShape::Iterator anIter(mySorted);
- for(int anIndex = 1; anIter.More(); anIter.Next(), anIndex++) {
- if (anIter.Value().IsSame(theSubShape))
+ // reorder if necessary
+ reorder();
+
+ std::vector<TopoDS_Shape>::iterator anIter = mySorted.begin();
+ for(int anIndex = 1; anIter != mySorted.end(); anIter++, anIndex++) {
+ if ((*anIter).IsSame(theSubShape))
return anIndex;
}
return -1; // not found
}
-TopoDS_Shape Selector_NExplode::shape(const int theIndex)
+TopoDS_Shape Selector_NExplode::shape(int& theIndex)
{
- TopoDS_ListOfShape::Iterator anIter(mySorted);
- for(int anIndex = 1; anIter.More(); anIter.Next(), anIndex++) {
- if (anIndex == theIndex)
- return anIter.Value();
+ std::vector<TopoDS_Shape>::iterator anIter = mySorted.begin();
+ for(int anIndex = 1; anIter != mySorted.end(); anIter++, anIndex++) {
+ if (anIndex == theIndex) {
+ TopoDS_Shape aShape = *anIter;
+ if (myToBeReordered)
+ theIndex = index(aShape);
+ return aShape;
+ }
}
return TopoDS_Shape(); // not found
}
+
+void Selector_NExplode::reorder()
+{
+ if (!myToBeReordered)
+ return;
+
+ myToBeReordered = false;
+ CompareShapes::DataMapOfShapeDouble aCash;
+ CompareShapes shComp(&aCash, dummy);
+ std::stable_sort(mySorted.begin(), mySorted.end(), shComp);
+}
#include "Selector.h"
#include <TopoDS_Shape.hxx>
-#include <TopoDS_ListOfShape.hxx>
+
+#include <vector>
/// \class Selector_NExplode
/// \ingroup DataModel
{
public:
/// \brief Initializes the sorted list of shapes by the shapes list.
- SELECTOR_EXPORT Selector_NExplode(const TopoDS_ListOfShape& theShapes);
+ SELECTOR_EXPORT Selector_NExplode(const TopoDS_ListOfShape& theShapes,
+ const bool theOldOrder = false);
/// \brief Initializes the sorted list of shapes by the context shape and type of sub-shapes.
- SELECTOR_EXPORT Selector_NExplode(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType);
+ SELECTOR_EXPORT Selector_NExplode(const TopoDS_Shape& theShape,
+ const TopAbs_ShapeEnum theType,
+ const bool theOldOrder = false);
/// Returns an index (started from one) of sub-shape in the sorted list. Returns 0 if not found.
SELECTOR_EXPORT int index(const TopoDS_Shape& theSubShape);
/// Returns a shape by an index (started from one). Returns null if not found.
- SELECTOR_EXPORT TopoDS_Shape shape(const int theIndex);
+ /// Recompute the index if the old order was used. The value will contain the new ordered index.
+ SELECTOR_EXPORT TopoDS_Shape shape(int& theIndex);
+
+private:
+ /// Reorder list of shapes.
+ void reorder();
protected:
- TopoDS_ListOfShape mySorted; ///< keep the ordered list of shapes
+ std::vector<TopoDS_Shape> mySorted; ///< keep the ordered list of shapes
+ bool myToBeReordered; ///< the list has to be reordered
};
#endif
#include <TNaming_Iterator.hxx>
#include <TDataStd_Integer.hxx>
-Selector_WeakName::Selector_WeakName() : Selector_Algo()
+Selector_WeakName::Selector_WeakName() : Selector_Algo(), myRecomputeWeakIndex(false)
{
}
TDF_Label Selector_WeakName::restoreByName(std::string theName,
const TopAbs_ShapeEnum theShapeType, Selector_NameGenerator* theNameGenerator)
{
- std::string aWeakIndex = theName.substr(pureWeakNameID().size());
+ size_t aFoundWeak = theName.find(oldPureWeakNameID());
+ std::string aWeakIndex = theName.substr(aFoundWeak + oldPureWeakNameID().size());
std::size_t aContextPosition = aWeakIndex.find("_");
myWeakIndex = atoi(aWeakIndex.c_str());
+ myRecomputeWeakIndex = aFoundWeak == 0;
myShapeType = theShapeType;
TDF_Label aContext;
if (aContextPosition != std::string::npos) { // context is also defined
}
}
if (!aContext.IsNull()) {
- Selector_NExplode aNexp(aContext, myShapeType);
+ Selector_NExplode aNexp(aContext, myShapeType, myRecomputeWeakIndex);
TopoDS_Shape aResult = aNexp.shape(myWeakIndex);
+ myRecomputeWeakIndex = false;
if (!aResult.IsNull()) {
Selector_Algo::store(aResult);
return true;
{
TopAbs_ShapeEnum myShapeType; ///< type of this shape
int myWeakIndex; ///< weak index in case modification produces several shapes
+ bool myRecomputeWeakIndex; ///< if the index is stored with old (unstable) order, recompute it
TDF_Label myContext; ///< context shape label
public:
/// Initializes the selection of this kind