]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Done in the frames of python dump issue #1648 : allow user to rename results without...
authormpv <mpv@opencascade.com>
Wed, 24 Aug 2016 09:31:55 +0000 (12:31 +0300)
committermpv <mpv@opencascade.com>
Wed, 24 Aug 2016 09:31:55 +0000 (12:31 +0300)
12 files changed:
src/ExchangePlugin/Test/TestExport.py
src/ExchangePlugin/Test/TestImport.py
src/InitializationPlugin/InitializationPlugin_Plugin.cpp
src/Model/Model_AttributeSelection.cpp
src/Model/Model_BodyBuilder.cpp
src/Model/Model_Data.cpp
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.h
src/Model/Model_SelectionNaming.cpp
src/Model/Model_SelectionNaming.h
src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp

index 0f6f48aa430f0bb9e372ee47dcda3565da289ab4..eda5c0aff3e2a9c0f647177d637695757e61dfec 100644 (file)
@@ -98,8 +98,8 @@ def testExportXAO():
 #     aGroupFeature.data().setName("")
 #     aSelectionListAttr = aGroupFeature.selectionList("group_list")
 #     aSelectionListAttr.setSelectionType("face")
-#     aSelectionListAttr.append("Box_1_1/Shape1_1")
-#     aSelectionListAttr.append("Box_1_1/Shape2_1")
+#     aSelectionListAttr.append("Box_1_1/Shape1")
+#     aSelectionListAttr.append("Box_1_1/Shape2")
 #     aGroupFeature.execute()
     aSession.finishOperation()
 
index 0dbffdea69f9e85dd709510b5f1f7b8f96838365..55e805cd538f34f563dff5f1ba22a50376502db0 100644 (file)
@@ -73,7 +73,7 @@ def testImportXAO():
     aSelectionList = aFeature1.selectionList("group_list")
     assert aSelectionList.selectionType() == "solid"
     assert aSelectionList.size() == 1
-    assert aSelectionList.value(0).namingName("") == "mygeom_1_1"
+    assert aSelectionList.value(0).namingName("") == "mygeom_1"
 
     aFeature2 = aCompositeFeature.subFeature(1, False)
     assert aFeature2.getKind() == "Group"
@@ -82,8 +82,9 @@ def testImportXAO():
     aSelectionList = aFeature2.selectionList("group_list") 
     assert aSelectionList.selectionType() == "face"
     assert aSelectionList.size() == 2
-    assert aSelectionList.value(0).namingName("") == "mygeom_1/Shape1_1"
-    assert aSelectionList.value(1).namingName("") == "mygeom_1/Shape2_1"
+    assert aSelectionList.value(0).namingName("") == "mygeom_1/Shape1"
+    print aSelectionList.value(1).namingName("")
+    assert aSelectionList.value(1).namingName("") == "mygeom_1/Shape2"
 
 if __name__ == '__main__':
 #=========================================================================
index c6ad9ab0c43e40e27914f95a88daaa58ee391285..93b60ffd2fc316daefd759d540d6f0a46b80aae6 100644 (file)
@@ -71,18 +71,12 @@ void InitializationPlugin_Plugin::processEvent(const std::shared_ptr<Events_Mess
       }
     }
     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-
     // the viewer update should be unblocked in order to avoid the features blinking before they are
     // hidden
     aMsg = std::shared_ptr<Events_Message>(
                   new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
 
     Events_Loop::loop()->send(aMsg);
-
-  } else if (theMessage.get()) {
-    Events_InfoMessage("InitializationPlugin_Plugin",
-        "InitializationPlugin_Plugin::processEvent: unhandled message caught: %1")
-            .arg(theMessage->eventID().eventText()).send();
   }
 }
 
index d35ea9cee6f24cfb6bf52730b097b95c56fcd824..ac66944c56b40d3a4f15ece7dcf2ef0bfc89587f 100644 (file)
@@ -176,10 +176,6 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
   //myIsInitialized = true;
 
   owner()->data()->sendAttributeUpdated(this);
-
-  std::string aSelName = namingName();
-  if(!aSelName.empty())
-    TDataStd_Name::Set(selectionLabel(), aSelName.c_str()); //set name
 }
 
 std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
@@ -876,11 +872,6 @@ std::string Model_AttributeSelection::namingName(const std::string& theDefaultNa
   std::string aName("");
   if(!this->isInitialized())
     return !theDefaultName.empty() ? theDefaultName : aName;
-  Handle(TDataStd_Name) anAtt;
-  if(selectionLabel().FindAttribute(TDataStd_Name::GetID(), anAtt)) {
-    aName = TCollection_AsciiString(anAtt->Get()).ToCString();
-    return aName;
-  }
 
   std::shared_ptr<GeomAPI_Shape> aSubSh = value();
   ResultPtr aCont = context();
index bfa8d62fe1a32d7a78b6a20dd77aa45c8e1e4172..56d22c8c16ad58faaa8d17cd1f29108238e67b48 100755 (executable)
@@ -235,6 +235,15 @@ void Model_BodyBuilder::storeModified(const std::shared_ptr<GeomAPI_Shape>& theO
           TDataStd_Name::Set(aSubBuilder.NamedShape()->Label(), aSolidName.c_str());
         }
       }
+    } else if(!aBuilder.NamedShape()->IsEmpty()) {
+      Handle(TDataStd_Name) anAttr;
+      if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+        std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
+        if(!aName.empty()) {
+          std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+          aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
+        }
+      }
     }
   }
 }
@@ -284,10 +293,9 @@ TNaming_Builder* Model_BodyBuilder::builder(const int theTag)
 
 void Model_BodyBuilder::buildName(const int theTag, const std::string& theName)
 {
-  std::string aName = data()->name() + "/" + theName; 
   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
-  aDoc->addNamingName(builder(theTag)->NamedShape()->Label(), aName);
-  TDataStd_Name::Set(builder(theTag)->NamedShape()->Label(),aName.c_str());
+  //aDoc->addNamingName(builder(theTag)->NamedShape()->Label(), theName);
+  TDataStd_Name::Set(builder(theTag)->NamedShape()->Label(), theName.c_str());
 }
 void Model_BodyBuilder::generated(
   const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag)
@@ -316,8 +324,8 @@ void Model_BodyBuilder::generated(const std::shared_ptr<GeomAPI_Shape>& theOldSh
       TDF_Label aChildLabel = aLabel.FindChild(aTag);
       TNaming_Builder aBuilder(aChildLabel);
       aBuilder.Generated(anOldShape, anExp.Current());
-      TCollection_AsciiString aChildName = TCollection_AsciiString((data()->name() + "/" + theName + "_").c_str()) + aTag;
-      aDoc->addNamingName(aChildLabel, aChildName.ToCString());
+      TCollection_AsciiString aChildName = TCollection_AsciiString((theName + "_").c_str()) + aTag;
+      //aDoc->addNamingName(aChildLabel, aChildName.ToCString());
       TDataStd_Name::Set(aChildLabel, aChildName.ToCString());
       aTag++;
     }
@@ -455,8 +463,8 @@ void Model_BodyBuilder::loadAndOrientGeneratedShapes (
           TDF_Label aChildLabel = aLabel.FindChild(aTag);
           TNaming_Builder aBuilder(aChildLabel);
           aBuilder.Generated(aRoot, anExp.Current());
-          TCollection_AsciiString aChildName = TCollection_AsciiString((data()->name() + "/" + theName + "_").c_str()) + aTag;
-          aDoc->addNamingName(aChildLabel, aChildName.ToCString());
+          TCollection_AsciiString aChildName = TCollection_AsciiString((theName + "_").c_str()) + aTag;
+          //aDoc->addNamingName(aChildLabel, aChildName.ToCString());
           TDataStd_Name::Set(aChildLabel, aChildName.ToCString());
           aTag++;
         }
@@ -711,23 +719,6 @@ void Model_BodyBuilder::loadDisconnectedEdges(
     }
   }
 
-  /*  TopTools_IndexedDataMapOfShapeListOfShape aDM;
-  TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, aDM);
-  for(int i=1; i <= aDM.Extent(); i++) {
-  if(aDM.FindFromIndex(i).Extent() > 1) continue;
-  if (BRep_Tool::Degenerated(TopoDS::Edge(aDM.FindKey(i))))
-  continue;
-  builder(theTag)->Generated(aDM.FindKey(i));
-  TCollection_AsciiString aStr(theTag);
-  std::string aName = theName + aStr.ToCString();
-  buildName(theTag, aName);
-  #ifdef DEB_IMPORT
-  aName +=  + ".brep";
-  BRepTools::Write(aDM.FindKey(i), aName.c_str());
-  #endif
-  theTag++;
-  }
-  */
   TopTools_MapOfShape anEdgesToDelete;
   TopExp_Explorer anEx(aShape,TopAbs_EDGE); 
   std::string aName;
index 7fb08b88dc82847763cfcd804cc33619f44d54c0..7f86b2116b0bc3c38fa6f24a681d3684c8f78b7e 100644 (file)
@@ -112,6 +112,10 @@ void Model_Data::setName(const std::string& theName)
   }
   if (mySendAttributeUpdated && isModified)
     ModelAPI_ObjectRenamedMessage::send(myObject, anOldName, theName, this);
+  if (isModified && myObject && myObject->document()) {
+    std::dynamic_pointer_cast<Model_Document>(myObject->document())->
+      changeNamingName(anOldName, theName);
+  }
 }
 
 AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
index 0d5767605342df462b4621bde193eeecf9964495..fdfaa6f6970b47511770cd250fac59957c812b3d 100755 (executable)
@@ -1169,12 +1169,38 @@ void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName
   myNamingNames[theName] = theLabel;
 }
 
+void Model_Document::changeNamingName(const std::string theOldName, const std::string theNewName)
+{
+  std::map<std::string, TDF_Label>::iterator aFind = myNamingNames.find(theOldName);
+  if (aFind != myNamingNames.end()) {
+    myNamingNames[theNewName] = aFind->second;
+    myNamingNames.erase(theOldName);
+  }
+}
+
 TDF_Label Model_Document::findNamingName(std::string theName)
 {
   std::map<std::string, TDF_Label>::iterator aFind = myNamingNames.find(theName);
-  if (aFind == myNamingNames.end())
-    return TDF_Label(); // not found
-  return aFind->second;
+  if (aFind != myNamingNames.end()) {
+    return aFind->second;
+  }
+  // not found exact name, try to find by sub-components
+  std::string::size_type aSlash = theName.rfind('/');
+  if (aSlash != std::string::npos) {
+    std::string anObjName = theName.substr(0, aSlash);
+    aFind = myNamingNames.find(anObjName);
+    if (aFind != myNamingNames.end()) {
+      TCollection_ExtendedString aSubName(theName.substr(aSlash + 1).c_str());
+      // searching sub-labels with this name
+      TDF_ChildIDIterator aNamesIter(aFind->second, TDataStd_Name::GetID(), Standard_True);
+      for(; aNamesIter.More(); aNamesIter.Next()) {
+        Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value());
+        if (aName->Get() == aSubName)
+          return aName->Label();
+      }
+    }
+  }
+  return TDF_Label(); // not found
 }
 
 ResultPtr Model_Document::findByName(const std::string theName)
index f00d87a013f238ac23ac0d02bba7650157ffcd31..46ffb4c86feef45319ee2eab33c03db3605b56d0 100644 (file)
@@ -187,6 +187,8 @@ class Model_Document : public ModelAPI_Document
 
   //! Registers the name of the shape for the topological naming needs
   void addNamingName(const TDF_Label theLabel, std::string theName);
+  //! Updates the name of some object
+  void changeNamingName(std::string theOldName, const std::string theNewName);
   //! Returns the label, keeper of the name  for the topological naming needs
   TDF_Label findNamingName(std::string theName);
   //! Returns the result by name of the result (names of results must be unique, used for naming
@@ -283,6 +285,7 @@ class Model_Document : public ModelAPI_Document
   friend class Model_AttributeSelection;
   friend class Model_ResultPart;
   friend class Model_ResultCompSolid;
+  friend class Model_SelectionNaming;
   friend class DFBrowser;
 
  private:
index 517311b1edd765c0ae73ccfda572204cab7bbf41..72c85936b48c00153b3cf9eda46f7905e8ad9cc7 100644 (file)
@@ -222,6 +222,8 @@ class Model_Objects
   friend class Model_AttributeReference;
   friend class Model_AttributeRefAttr;
   friend class Model_AttributeRefList;
+  friend class Model_AttributeRefList;
+  friend class Model_SelectionNaming;
 };
 
 #endif
index 5d408bb86468bdcb564ff1facb3c177e739e61ce..5bf2d58c9f71c9e010ad0bb56de1f4f5e05bd124 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "Model_SelectionNaming.h"
 #include "Model_Document.h"
+#include "Model_Objects.h"
 #include <ModelAPI_Feature.h>
 #include <Events_InfoMessage.h>
 #include <ModelAPI_Session.h>
@@ -45,7 +46,8 @@ Model_SelectionNaming::Model_SelectionNaming(TDF_Label theSelectionLab)
 }
 
 std::string Model_SelectionNaming::getShapeName(
-  std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape)
+  std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape,
+  const bool theAddContextName)
 {
   std::string aName;
   // check if the subShape is already in DF
@@ -54,8 +56,9 @@ std::string Model_SelectionNaming::getShapeName(
   if(!aNS.IsNull() && !aNS->IsEmpty()) { // in the document    
     if(aNS->Label().FindAttribute(TDataStd_Name::GetID(), anAttr)) {
       aName = TCollection_AsciiString(anAttr->Get()).ToCString();
-      if(!aName.empty()) {         
-        const TDF_Label& aLabel = theDoc->findNamingName(aName);
+      // indexes are added to sub-shapes not primitives (primitives must not be located at the same label)
+      if(!aName.empty() && aNS->Evolution() != TNaming_PRIMITIVE && theAddContextName) {
+        const TDF_Label& aLabel = aNS->Label();//theDoc->findNamingName(aName);
         static const std::string aPostFix("_");
         TNaming_Iterator anItL(aNS);
         for(int i = 1; anItL.More(); anItL.Next(), i++) {
@@ -65,7 +68,18 @@ std::string Model_SelectionNaming::getShapeName(
             break;
           }
         }
-      }        
+      }
+      if (theAddContextName && aName.find("/") == std::string::npos) { // searching for the context object
+        for(TDF_Label anObjL = aNS->Label(); anObjL.Depth() > 4; anObjL = anObjL.Father()) {
+          int aDepth = anObjL.Depth();
+          if (aDepth == 5 || aDepth == 7) {
+            ObjectPtr anObj = theDoc->objects()->object(anObjL);
+            if (anObj) {
+              aName = anObj->data()->name() + "/" + aName;
+            }
+          }
+        }
+      }
     }
   }
   return aName;
@@ -113,9 +127,17 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
 #endif
   std::shared_ptr<Model_Document> aDoc = 
     std::dynamic_pointer_cast<Model_Document>(theContext->document());
+  if (theContext->groupName() == ModelAPI_ResultPart::group()) {
+    ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theContext);
+    int anIndex;
+    return aPart->data()->name() + "/" + aPart->nameInPart(theSubSh, anIndex);
+  }
+
+  // add the result name to the name of the shape (it was in BodyBuilder, but did not work on Result rename)
+  bool isNeedContextName = theContext->shape().get() && !theContext->shape()->isEqual(theSubSh);
 
   // check if the subShape is already in DF
-  aName = getShapeName(aDoc, aSubShape);
+  aName = getShapeName(aDoc, aSubShape, isNeedContextName);
   if(aName.empty() ) { // not in the document!
     TopAbs_ShapeEnum aType = aSubShape.ShapeType();
     switch (aType) {
@@ -162,7 +184,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
         // build name of the sub-shape Edge
         for(int i=1; i <= aSMap.Extent(); i++) {
           const TopoDS_Shape& aFace = aSMap.FindKey(i);
-          std::string aFaceName = getShapeName(aDoc, aFace);
+          std::string aFaceName = getShapeName(aDoc, aFace, isNeedContextName);
           if(i == 1)
             aName = aFaceName;
           else 
@@ -170,7 +192,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
         }
         TopTools_ListIteratorOfListOfShape itl(aListOfNbs);
         for (;itl.More();itl.Next()) {
-          std::string aFaceName = getShapeName(aDoc, itl.Value());
+          std::string aFaceName = getShapeName(aDoc, itl.Value(), isNeedContextName);
           aName += "&" + aFaceName;
         }                
       }
@@ -219,7 +241,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
             TopTools_ListIteratorOfListOfShape itl(aListE);
             for (int i = 1;itl.More();itl.Next(),i++) {
               const TopoDS_Shape& anEdge = itl.Value();
-              std::string anEdgeName = getShapeName(aDoc, anEdge);
+              std::string anEdgeName = getShapeName(aDoc, anEdge, isNeedContextName);
               if (anEdgeName.empty()) { // edge is not in DS, trying by faces anyway
                 isByFaces = true;
                 aName.clear();
@@ -239,7 +261,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
           TopTools_ListIteratorOfListOfShape itl(aList);
           for (int i = 1;itl.More();itl.Next(),i++) {
             const TopoDS_Shape& aFace = itl.Value();
-            std::string aFaceName = getShapeName(aDoc, aFace);
+            std::string aFaceName = getShapeName(aDoc, aFace, isNeedContextName);
             if(i == 1)
               aName = aFaceName;
             else 
@@ -249,10 +271,8 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
       }
       break;
     }
-    // register name                   
-    // aDoc->addNamingName(selectionLabel(), aName);
-    // the selected sub-shape will not be shared and as result it will not require registration
   }
+
   return aName;
 }
 
@@ -309,9 +329,13 @@ const TopoDS_Shape getShapeFromNS(
   if (n == std::string::npos) n = 0;
   std::string aSubString = theSubShapeName.substr(n + 1);
   n = aSubString.rfind('_');
-  if (n == std::string::npos) return aSelection;
-  aSubString = aSubString.substr(n+1);
-  int indx = atoi(aSubString.c_str());
+  int indx;
+  if (n == std::string::npos) {// for primitives this is a first 
+    indx = 1;
+  } else {
+    aSubString = aSubString.substr(n+1);
+    indx = atoi(aSubString.c_str());
+  }
 
   TNaming_Iterator anItL(theNS);
   for(int i = 1; anItL.More(); anItL.Next(), i++) {
@@ -326,18 +350,19 @@ const TopoDS_Shape findFaceByName(
   const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc)
 {
   TopoDS_Shape aFace;
-  std::string::size_type n, nb = theSubShapeName.rfind('/');                   
-  if (nb == std::string::npos) nb = 0;
-  std::string aSubString = theSubShapeName.substr(nb + 1);
-  n = aSubString.rfind('_');
-  if (n != std::string::npos) {
-    std::string aSubStr2 = aSubString.substr(0, n);
-    aSubString  = theSubShapeName.substr(0, nb + 1);
-    aSubString = aSubString + aSubStr2;        
-  } else
-    aSubString = theSubShapeName;
-
-  const TDF_Label& aLabel = theDoc->findNamingName(aSubString);
+  //std::string::size_type n, nb = theSubShapeName.rfind('/');                 
+  //if (nb == std::string::npos) nb = 0;
+  //std::string aSubString = theSubShapeName.substr(nb + 1);
+  std::string aSubString = theSubShapeName;
+
+  TDF_Label aLabel = theDoc->findNamingName(aSubString);
+  if (aLabel.IsNull()) { // try to remove additional artificial suffix
+    std::string::size_type n = aSubString.rfind('_');
+    if (n != std::string::npos) {
+      aSubString = aSubString.substr(0, n);
+       aLabel = theDoc->findNamingName(aSubString);
+    }
+  }
   if(aLabel.IsNull()) return aFace;
   Handle(TNaming_NamedShape) aNS;
   if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -634,7 +659,7 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
    // possible this is body where postfix is added to distinguish several shapes on the same label
   int aSubShapeId = -1; // -1 means sub shape not found
   // for result body the name wihtout "_" has higher priority than with it: it is always added
-  if ((!aCont.get() || (aCont->groupName() == ModelAPI_ResultBody::group())) && 
+  if ((!aCont.get()/* || (aCont->groupName() == ModelAPI_ResultBody::group())*/) && 
        aContName == aSubShapeName) {
     size_t aPostIndex = aContName.rfind('_');
     if (aPostIndex != std::string::npos) {
@@ -699,7 +724,7 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
         return true;
       } else if (aSubShapeId > 0) { // try to find sub-shape by the index
         TopExp_Explorer anExp(aCont->shape()->impl<TopoDS_Shape>(), aType);
-        for(; aSubShapeId > 0 && anExp.More(); aSubShapeId--) {
+        for(; aSubShapeId > 1 && anExp.More(); aSubShapeId--) {
           anExp.Next();
         }
         if (anExp.More()) {
index 134d0186eff45392bf3b2d92d16bd0e919b95764..82f1eca7a09c028cbdc8e614aed149fc1005bb7f 100644 (file)
@@ -63,7 +63,8 @@ public:
 
 protected:
   /// Gets the stored name from the document
-  std::string getShapeName(std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape);
+  std::string getShapeName(std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape,
+    const bool theAddContextName);
 };
 
 #endif
index ce17351bc7b6f90f45c9f8d30e80a5cfb6bb4edd..bf32bdbbd7b50d68d4341300beadd07261baff7b 100644 (file)
@@ -301,7 +301,9 @@ std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr<GeomAPI_Shape>&
     aResult<<": "<<aCount<<std::endl;
   }
   // output the main characteristics
-  aResult<<"Volume: "<<setprecision(2)<<GeomAlgoAPI_ShapeTools::volume(theShape)<<std::endl;
+  if (GeomAlgoAPI_ShapeTools::volume(theShape) > 1.e-7) {
+    aResult<<"Volume: "<<std::fixed<<setprecision(3)<<GeomAlgoAPI_ShapeTools::volume(theShape)<<std::endl;
+  }
   std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
   aResult<<"Center of mass: ";
   double aCenterVals[3] = {aCenter->x(), aCenter->y(), aCenter->z()};