]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Make naming names in sub-elements of sketch based on names, not persistent indexes...
authormpv <mpv@opencascade.com>
Wed, 10 Aug 2016 13:01:22 +0000 (16:01 +0300)
committermpv <mpv@opencascade.com>
Wed, 10 Aug 2016 13:01:22 +0000 (16:01 +0300)
src/Model/Model_AttributeSelection.cpp
src/Model/Model_SelectionNaming.cpp
src/Model/Model_SelectionNaming.h

index 33326b35137d576f65f694a611256d1dd2bcad3b..923b2cd48ee10399871c5022f32fb9f88727f008 100644 (file)
@@ -642,6 +642,7 @@ void Model_AttributeSelection::selectBody(
 static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape,
   const int theID, const FeaturePtr& theContextFeature, std::shared_ptr<Model_Document> theDoc,
   std::string theAdditionalName, std::map<int, int>& theOrientations,
+  std::map<int, std::string>& theSubNames, // name of sub-elements by ID to be exported instead of indexes
   Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)(),
   const int theOrientation = 0)
 {
@@ -652,29 +653,32 @@ static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape,
   TNaming_Builder aBuilder(aLab);
   aBuilder.Generated(theShape);
   std::stringstream aName;
-  aName<<theContextFeature->name()<<"/";
-  if (!theAdditionalName.empty())
-    aName<<theAdditionalName<<"/";
-  if (theShape.ShapeType() == TopAbs_FACE) aName<<"Face";
-  else if (theShape.ShapeType() == TopAbs_WIRE) aName<<"Wire";
-  else if (theShape.ShapeType() == TopAbs_EDGE) aName<<"Edge";
-  else if (theShape.ShapeType() == TopAbs_VERTEX) aName<<"Vertex";
-
-  if (theRefs.IsNull()) {
-    aName<<theID;
-    if (theOrientation == 1)
-      aName<<"f";
-    else if (theOrientation == -1)
-      aName<<"r";
-  } else { // make a composite name from all sub-elements indexes: "1_2_3_4"
-    TColStd_MapIteratorOfPackedMapOfInteger aRef(theRefs->GetMap());
-    for(; aRef.More(); aRef.Next()) {
-      aName<<"-"<<aRef.Key();
-      if (theOrientations.find(aRef.Key()) != theOrientations.end()) {
-        if (theOrientations[aRef.Key()] == 1)
-          aName<<"f";
-        else if (theOrientations[aRef.Key()] == -1)
-          aName<<"r";
+  aName<<theContextFeature->name();
+  if (theShape.ShapeType() != TopAbs_COMPOUND) { // compound means the whole result for construction
+    aName<<"/";
+    if (!theAdditionalName.empty())
+      aName<<theAdditionalName<<"/";
+    if (theShape.ShapeType() == TopAbs_FACE) aName<<"Face";
+    else if (theShape.ShapeType() == TopAbs_WIRE) aName<<"Wire";
+    else if (theShape.ShapeType() == TopAbs_EDGE) aName<<"Edge";
+    else if (theShape.ShapeType() == TopAbs_VERTEX) aName<<"Vertex";
+
+    if (theRefs.IsNull()) {
+      aName<<theID;
+      if (theOrientation == 1)
+        aName<<"f";
+      else if (theOrientation == -1)
+        aName<<"r";
+    } else { // make a composite name from all sub-elements indexes: "1_2_3_4"
+      TColStd_MapIteratorOfPackedMapOfInteger aRef(theRefs->GetMap());
+      for(; aRef.More(); aRef.Next()) {
+        aName<<"-"<<theSubNames[aRef.Key()];
+        if (theOrientations.find(aRef.Key()) != theOrientations.end()) {
+          if (theOrientations[aRef.Key()] == 1)
+            aName<<"f";
+          else if (theOrientations[aRef.Key()] == -1)
+            aName<<"r";
+        }
       }
     }
   }
@@ -721,6 +725,7 @@ void Model_AttributeSelection::selectConstruction(
   // iterate and store the result ids of sub-elements and sub-elements to sub-labels
   Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab);
   std::map<int, int> anOrientations; //map from edges IDs to orientations of these edges in face
+  std::map<int, std::string> aSubNames; //map from edges IDs to names of edges
   aRefs->Clear();
   const int aSubNum = aComposite->numberOfSubs();
   for(int a = 0; a < aSubNum; a++) {
@@ -740,6 +745,7 @@ void Model_AttributeSelection::selectConstruction(
           gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex));
           if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) {
             aRefs->Add(aComposite->subFeatureId(a));
+            aSubNames[aComposite->subFeatureId(a)] = Model_SelectionNaming::shortName(aConstr);
           }
         } else { // get first or last vertex of the edge: last is stored with additional delta
           const TopoDS_Shape& anEdge = aConstr->shape()->impl<TopoDS_Shape>();
@@ -748,6 +754,8 @@ void Model_AttributeSelection::selectConstruction(
             gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVExp.Current()));
             if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) {
               aRefs->Add(aDelta + aComposite->subFeatureId(a));
+              aSubNames[aDelta + aComposite->subFeatureId(a)] =
+                Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA);
               break;
             }
             aDelta += kSTART_VERTEX_DELTA;
@@ -763,6 +771,7 @@ void Model_AttributeSelection::selectConstruction(
             if (allCurves.Contains(aCurve)) {
               int anID = aComposite->subFeatureId(a);
               aRefs->Add(anID);
+              aSubNames[anID] = Model_SelectionNaming::shortName(aConstr);
               if (aShapeType != TopAbs_EDGE) { // face needs the sub-edges on sub-labels
                 // add edges to sub-label to support naming for edges selection
                 TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE);
@@ -775,7 +784,7 @@ void Model_AttributeSelection::selectConstruction(
                     anOrientations[anID] = anOrient;
                     registerSubShape(
                       selectionLabel(), anEdge, anID, aContextFeature, aMyDoc, "", anOrientations,
-                      Handle(TDataStd_IntPackedMap)(), anOrient);
+                      aSubNames, Handle(TDataStd_IntPackedMap)(), anOrient);
                   }
                 }
               } else { // put vertices of the selected edge to sub-labels
@@ -787,7 +796,8 @@ void Model_AttributeSelection::selectConstruction(
 
                   std::stringstream anAdditionalName; 
                   registerSubShape(
-                    selectionLabel(), aV, aTagIndex, aContextFeature, aMyDoc, "", anOrientations);
+                    selectionLabel(), aV, aTagIndex, aContextFeature, aMyDoc, "", anOrientations,
+                    aSubNames);
                 }
               }
             }
@@ -800,7 +810,7 @@ void Model_AttributeSelection::selectConstruction(
   TNaming_Builder aBuilder(selectionLabel());
   aBuilder.Generated(aSubShape);
     registerSubShape(
-      selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, "", anOrientations, aRefs); 
+      selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, "", anOrientations, aSubNames, aRefs); 
 }
 
 bool Model_AttributeSelection::selectPart(
index 6f39a650f8b2755ff0786ce806efa26ed7ff71a2..68311d6f24a7bf0dd69984589568dedf3ad29398 100644 (file)
@@ -29,7 +29,7 @@
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_CompositeFeature.h>
 #include <TColStd_MapOfTransient.hxx>
-
+#include <algorithm>
 
 #ifdef DEB_NAMING
 #include <BRepTools.hxx>
@@ -458,40 +458,63 @@ std::string getContextName(const std::string& theSubShapeName)
 {
   std::string aName;
   std::string::size_type n = theSubShapeName.find('/');                        
-  if (n == std::string::npos) return aName;
+  if (n == std::string::npos) return theSubShapeName;
   aName = theSubShapeName.substr(0, n);
   return aName;
 }
 
 /// Parses naming name of sketch sub-elements: takes indices and orientation 
 /// (if theOriented = true) from this name. Map theIDs constains indices -> 
-/// orientations (true by default)
-bool parseSubIndices(const std::string& theName, const char* theShapeType, 
-                     std::map<int, bool>& theIDs, const bool theOriented = false)
+/// orientations and start/end vertices: negative is reversed, 2 - start, 3 - end
+bool parseSubIndices(CompositeFeaturePtr theComp, //< to iterate names
+  const std::string& theName, const char* theShapeType, 
+  std::map<int, int>& theIDs, const bool theOriented = false)
 {
   // collect all IDs in the name
-  std::set<int> anIDs;
+  std::map<std::string, int> aNames; // short name of sub -> ID of sub of theComp
+  const int aSubNum = theComp->numberOfSubs();
+  for(int a = 0; a < aSubNum; a++) {
+    FeaturePtr aSub = theComp->subFeature(a);
+    const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+    std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
+    // there may be many shapes (circle and center)
+    for(; aRes != aResults.cend(); aRes++) {
+      ResultConstructionPtr aConstr = 
+        std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+      if (aConstr.get()) {
+        aNames[Model_SelectionNaming::shortName(aConstr)] = theComp->subFeatureId(a);
+      }
+    }
+  }
+
   size_t aPrevPos = theName.find("/") + 1, aLastNamePos;
   bool isShape = false; // anyway the first world must be 'Vertex'
   do {
     aLastNamePos = theName.find('-', aPrevPos);
-    const std::string anID = theName.substr(aPrevPos, aLastNamePos - aPrevPos);
+    std::string anID = theName.substr(aPrevPos, aLastNamePos - aPrevPos);
     if (!isShape) {
       if (anID != theShapeType)
         return false;
       isShape = true;
     } else {
-      bool anOrientation = true; // default
+      int anOrientation = 1; // default
       if (theOriented) { // here must be a symbol in the end of digit 'f' or 'r'
-        const char aSymbol = theName.back();
-        anOrientation = aSymbol == 'f';
+        const char aSymbol = anID.back();
+        if (aSymbol == 'r') anOrientation = -1;
+        anID.pop_back();
+      }
+      // check start/end symbols
+      if (anID.back() == 's') {
+        anOrientation *= 2;
+        anID.pop_back();
+      } else if (anID.back() == 'e') {
+        anOrientation *= 3;
+        anID.pop_back();
+      }
+
+      if (aNames.find(anID) != aNames.end()) {
+        theIDs[aNames[anID]] = anOrientation;
       }
-      int anInt = 0;
-      try {
-        anInt = std::stoi(anID, nullptr);
-      } catch (const std::invalid_argument&) {}
-      if (anInt != 0)
-        theIDs[anInt] = anOrientation;
     }
     aPrevPos = aLastNamePos + 1;
   } while (aLastNamePos != std::string::npos);
@@ -560,6 +583,27 @@ std::shared_ptr<GeomAPI_Shape> Model_SelectionNaming::findAppropriateFace(
   return aResult;
 }
 
+std::string Model_SelectionNaming::shortName(
+  std::shared_ptr<ModelAPI_ResultConstruction>& theConstr, const int theEdgeVertexPos)
+{
+  std::string aName = theConstr->data()->name();
+  // remove "-", "/" and "&" command-symbols
+  aName.erase(std::remove(aName.begin(), aName.end(), '-'), aName.end());
+  aName.erase(std::remove(aName.begin(), aName.end(), '/'), aName.end());
+  aName.erase(std::remove(aName.begin(), aName.end(), '&'), aName.end());
+  // remove the last 's', 'e', 'f' and 'r' symbols: they are used as markers of start/end/forward/rewersed indicators
+  static const std::string aSyms("sefr");
+  while(aSyms.find(aName.back()) != std::string::npos) {
+    aName.pop_back();
+  }
+  if (theEdgeVertexPos == 1) {
+    aName += "s"; // start
+  } else if (theEdgeVertexPos == 2) {
+    aName += "e"; // end
+  }
+  return aName;
+}
+
 // type ::= COMP | COMS | SOLD | SHEL | FACE | WIRE | EDGE | VERT
 bool Model_SelectionNaming::selectSubShape(const std::string& theType, 
   const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc,
@@ -611,9 +655,16 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
   case TopAbs_SOLID:
   case TopAbs_SHELL:
   case TopAbs_WIRE:
-  default: //TopAbs_SHAPE
+  default: {//TopAbs_SHAPE
+    /// case when the whole sketch is selected, so, selection type is compound, but there is no value
+    if (aCont.get() && aCont->shape().get() && 
+        aCont->shape()->impl<TopoDS_Shape>().ShapeType() == aType) {
+      theCont = aCont;
+      return true;
+    }
     return false;
   }
+  }
   // another try to find edge or vertex by faces
   std::list<std::string> aListofNames;
   size_t aN = aSelection.IsNull() ? ParseName(theSubShapeName, aListofNames) : 0;
@@ -656,8 +707,9 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
       if (aComposite.get()) {
         if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
           // collect all IDs in the name
-          std::map<int, bool> anIDs;
-          if (!parseSubIndices(theSubShapeName, aType == TopAbs_EDGE ? "Edge" : "Vertex", anIDs))
+          std::map<int, int> anIDs;
+          if (!parseSubIndices(aComposite, theSubShapeName, 
+              aType == TopAbs_EDGE ? "Edge" : "Vertex", anIDs))
             return false;
 
           const int aSubNum = aComposite->numberOfSubs();
@@ -665,38 +717,39 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
             int aCompID = aComposite->subFeatureId(a);
             if (anIDs.find(aCompID) != anIDs.end()) { // found the vertex/edge shape
               FeaturePtr aSub = aComposite->subFeature(a);
-              ResultConstructionPtr aV = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>
-                (*(aSub->results().begin()));
-              if (aV) {
-                theShapeToBeSelected = aV->shape();
-                return true;
-              }
-            } else if (aType == TopAbs_VERTEX &&
-                       (anIDs.find(aCompID + kSTART_VERTEX_DELTA) != anIDs.end() ||
-                       anIDs.find(aCompID + 2 * kSTART_VERTEX_DELTA) != anIDs.end())) {
-              FeaturePtr aSub = aComposite->subFeature(a);
               const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
-              std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
+              std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIt = aResults.cbegin();
               // there may be many shapes (circle and center)
-              for(; aRes != aResults.cend(); aRes++) {
-                ResultConstructionPtr aE = 
-                  std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
-                if (aE && aE->shape()->isEdge()) {
-                  const TopoDS_Shape& anEdge = aE->shape()->impl<TopoDS_Shape>();
-                  TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); // first vertex
-                  if (anIDs.find(aCompID + kSTART_VERTEX_DELTA) == anIDs.end())
-                    aVExp.Next(); // second vertex
-                  std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
-                  aShapeToBeSelected->setImpl(new TopoDS_Shape(aVExp.Current()));
-                  theShapeToBeSelected = aShapeToBeSelected;
-                  return true;
+              for(; aRIt != aResults.cend(); aRIt++) {
+                ResultConstructionPtr aRes = 
+                  std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRIt);
+                if (aRes) {
+                  int anOrientation = abs(anIDs[aCompID]);
+                  TopoDS_Shape aShape = aRes->shape()->impl<TopoDS_Shape>();
+                  if (anOrientation == 1) {
+                    if (aType == aShape.ShapeType()) {
+                      theShapeToBeSelected = aRes->shape();
+                      return true;
+                    }
+                  } else { // take first or second vertex of the edge
+                    TopoDS_Shape aShape = aRes->shape()->impl<TopoDS_Shape>();
+                    TopExp_Explorer anExp(aShape, aType);
+                    for(; anExp.More() && anOrientation != 2; anOrientation--)
+                      anExp.Next();
+                    if (anExp.More()) {
+                      std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
+                      aShapeToBeSelected->setImpl(new TopoDS_Shape(anExp.Current()));
+                      theShapeToBeSelected = aShapeToBeSelected;
+                      return true;
+                    }
+                  }
                 }
               }
             }
           }
         } else if (aType == TopAbs_FACE) { // sketch faces is identified by format "Sketch_1/Face-2f-8f-11r"
-          std::map<int, bool> anIDs;
-          if (!parseSubIndices(theSubShapeName, "Face", anIDs, true))
+          std::map<int, int> anIDs;
+          if (!parseSubIndices(aComposite, theSubShapeName, "Face", anIDs, true))
             return false;
 
           NCollection_DataMap<Handle(Geom_Curve), int> allCurves; // curves and orientations of edges
@@ -716,7 +769,7 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
                   if (!anEdge.IsNull()) {
                     Standard_Real aFirst, aLast;
                     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
-                    allCurves.Bind(aCurve, anIDs[aSubID] ? 1 : -1);
+                    allCurves.Bind(aCurve, anIDs[aSubID] > 0 ? 1 : -1);
                   }
                 }
               }
index 8a7fbfda02a7d9a844680e3f3115135512d411e0..134d0186eff45392bf3b2d92d16bd0e919b95764 100644 (file)
@@ -53,6 +53,14 @@ public:
   /// Returns orientation of the edge in the context shape
   static int edgeOrientation(const TopoDS_Shape& theContext, TopoDS_Edge& theEdge);
 
+  /// Returns the name of sketch sub-element, shortened by exclusion of some symbols and with added
+  /// the vertex position (if needed)
+  /// \param theConstr result with name - basis for the name
+  /// \param theEdgeVertexPos position of the vertex on edge: 1 - first , 2 - second
+  /// \returns the generated name
+  static std::string shortName(std::shared_ptr<ModelAPI_ResultConstruction>& theConstr,
+    const int theEdgeVertexPos = 0);
+
 protected:
   /// Gets the stored name from the document
   std::string getShapeName(std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape);