From d5fdaaf3cd5a96fb223a9c48a3c97398cfaf1c1e Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 26 Dec 2019 09:39:38 +0300 Subject: [PATCH] Implementation of Open/Save and Break-Link functionality on SHAPER shapes --- idl/SHAPERSTUDY_Gen.idl | 15 +++++- src/PY/SHAPERSTUDY.py | 81 ++++++++++++++++++++++-------- src/PY/SHAPERSTUDY_Object.py | 46 ++++++++++++++++- src/PY/SHAPERSTUDY_utils.py | 6 ++- src/StudyData/StudyData_Object.cpp | 34 +++++-------- src/StudyData/StudyData_Object.h | 10 ++-- 6 files changed, 140 insertions(+), 52 deletions(-) diff --git a/idl/SHAPERSTUDY_Gen.idl b/idl/SHAPERSTUDY_Gen.idl index 9e7824d..de9c636 100644 --- a/idl/SHAPERSTUDY_Gen.idl +++ b/idl/SHAPERSTUDY_Gen.idl @@ -30,7 +30,7 @@ module SHAPERSTUDY_ORB { -interface SHAPER_Object : GEOM::GEOM_Object +interface SHAPER_Object : GEOM::GEOM_Object { /*! * \brief Puts the shape to the object by BRep stream. @@ -48,7 +48,18 @@ interface SHAPER_Object : GEOM::GEOM_Object * \brief Returns SObject of this object */ SALOMEDS::SObject GetSO(); - + /*! + * \brief Returns true if shape is already dead + */ + boolean IsDead(); + /*! + * \brief Makes the dead-copy of the shape and returns it + */ + SHAPER_Object MakeDead(); + /*! + * \brief Returns the stream of the previous version of the shape stored here + */ + SALOMEDS::TMPFile GetOldShapeStream(); }; interface Gen : GEOM::GEOM_Gen diff --git a/src/PY/SHAPERSTUDY.py b/src/PY/SHAPERSTUDY.py index 2c6b6bf..bc0df39 100644 --- a/src/PY/SHAPERSTUDY.py +++ b/src/PY/SHAPERSTUDY.py @@ -176,7 +176,6 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, Parameters: theStudyEntry is an entry of the Object in the study """ - print("My Test") return "test" def Save( self, component, URL, isMultiFile ): @@ -184,15 +183,28 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, Saves data: all objects into one file """ aResult = "" # string-pairs of internal entries and shape streams - aSOIter = getStudy().NewChildIterator(findOrCreateComponent()) + aStudy = getStudy() + aSOIter = aStudy.NewChildIterator(findOrCreateComponent()) while aSOIter.More(): - aSO = aSOIter.Value() - anIOR = aSO.GetIOR() - anObj = salome.orb.string_to_object(anIOR) - if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object): - if len(aResult): - aResult = aResult + '|' - aResult = aResult + anObj.GetEntry() + "|" + anObj.GetShapeStream().decode() + aSOVal = aSOIter.Value() + aSOList = [aSOVal] + # collect also the history shape objects + aRes, aHistSO = aSOVal.FindSubObject(2) + if aRes: + aSOIter2 = aStudy.NewChildIterator(aHistSO) + while aSOIter2.More(): + aSOList.append(aSOIter2.Value()) + aSOIter2.Next() + # for each sobject export shapes stream if exists + for aSO in aSOList: + anIOR = aSO.GetIOR() + anObj = salome.orb.string_to_object(anIOR) + if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object): + if len(aResult): + aResult = aResult + '|' + aResult = aResult + anObj.GetEntry() + "|" + anObj.GetShapeStream().decode() + aResult = aResult + "|" + anObj.GetOldShapeStream().decode() + aSOIter.Next() return aResult.encode() @@ -203,20 +215,26 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, global __entry2IOR__ __entry2IOR__.clear() - list=stream.decode().split('|') - isId = True + aList=stream.decode().split('|') + aSubNum = 1 anId = "" - for sub in list: - if isId: - anId = sub - else: # create shapes by BRep in the stream + aNewShapeStream = "" + for aSub in aList: + if aSubNum == 1: + anId = aSub + aSubNum = 2 + elif aSubNum == 2: + aNewShapeStream = aSub + aSubNum = 3 + else: # create shapes by BRep in the stream: set old first then new aShapeObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object() - aShapeObj.SetShapeByStream(sub) + if len(aSub): + aShapeObj.SetShapeByStream(aSub) + aShapeObj.SetShapeByStream(aNewShapeStream) aShapeObj.SetEntry(anId) anIOR = salome.orb.object_to_string(aShapeObj._this()) __entry2IOR__[anId] = anIOR - - isId = not isId + aSubNum = 1 return 1 @@ -234,7 +252,10 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, "Converts persistent ID of the object to its IOR." global __entry2IOR__ if persistentID in __entry2IOR__: - return __entry2IOR__[persistentID] + aRes = __entry2IOR__[persistentID] + if len(aRes): # set SO from the study, the sobject param is temporary, don't store it + salome.orb.string_to_object(aRes).SetSO(getStudy().FindObjectID(sobject.GetID())) + return aRes return "" def DumpPython( self, isPublished, isMultiFile ): @@ -347,6 +368,24 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, def BreakLink(self, theEntry): """ - Breaks links to parametrical mode for parametrical shape + Breaks links to not-dead shape, make the shape as dead """ - print("##### Break parametrical links", theEntry) + aStudy = getStudy() + aSO = aStudy.FindObjectID(theEntry) + if not aSO: + return + aRes, aSSO = aSO.ReferencedObject() + if not aRes: + return # only SObjects referenced to the SHAPEr STUDY objects are allowed + anIOR = aSSO.GetIOR() + if not anIOR: + return # must be referenced to the SHAPER STUDY shape + anObj = salome.orb.string_to_object(anIOR) + if not anObj or not isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object): + return + if anObj.IsDead(): + return # do nothing for reference to already dead shape + aDeadShape = anObj.MakeDead() + aBuilder = aStudy.NewBuilder() + aBuilder.RemoveReference(aSO) # reset reference to the dead shape + aBuilder.Addreference(aSO, aDeadShape.GetSO()) diff --git a/src/PY/SHAPERSTUDY_Object.py b/src/PY/SHAPERSTUDY_Object.py index f30b79f..2e97799 100644 --- a/src/PY/SHAPERSTUDY_Object.py +++ b/src/PY/SHAPERSTUDY_Object.py @@ -22,7 +22,8 @@ import SHAPERSTUDY_ORB__POA import GEOM -from SHAPERSTUDY_utils import getEngine +from SHAPERSTUDY_utils import getEngine, getStudy +import salome import StudyData_Swig @@ -86,6 +87,14 @@ class SHAPERSTUDY_Object(SHAPERSTUDY_ORB__POA.SHAPER_Object): return b'' return self.data.shapeStream().encode() + def GetOldShapeStream( self ): + """ + Get geometric shape of the object as a byte stream in BRep format + """ + if self.data is None: + return b'' + return self.data.oldShapeStream().encode() + def SetShapeByStream(self, theStream): """ Sets geometric shape content of the object as a byte stream in BRep format @@ -174,6 +183,39 @@ class SHAPERSTUDY_Object(SHAPERSTUDY_ORB__POA.SHAPER_Object): Returns true if the current object has connection to a parametrical model which can be modified by parameters change. """ - return True + return not self.IsDead() + + def IsDead(self): + """ + Returns true if the shape is dead - no parametrical link to the SHAPER exists + """ + return self.GetEntry().startswith("dead") + + def MakeDead(self): + """ + Makes the dead-copy of the shape and returns it. + """ + aStudy = getStudy() + aBuilder = aStudy.NewBuilder() + aRes, aHistSO = self.SO.FindSubObject(2) + if not aRes: # create a "history" folder if it does not exist + aHistSO = aBuilder.NewObjectToTag(self.SO, 2) + aHistSO.SetAttrString("AttributeName", "History") + + aDeadSO = aBuilder.NewObject(aHistSO) + anIndex = aDeadSO.Tag() + aDeadSO.SetAttrString("AttributeName", self.SO.GetName() + " (" + str(anIndex) + ")") + aDead = SHAPERSTUDY_Object() + aDeadEntry = "dead" + str(anIndex) + "_" + self.GetEntry() + aDead.SetEntry(aDeadEntry) + aDead.SetShapeByStream(self.data.oldShapeStream()) + aDeadObj = aDead._this() + anIOR = salome.orb.object_to_string(aDeadObj) + aDeadSO.SetAttrString("AttributeIOR", anIOR) + aDead.SetSO(aDeadSO) + if self.GetTick() > 2: + aDead.data.setTick(self.GetTick() - 1) # set the tick of an old shape + return aDeadObj + pass diff --git a/src/PY/SHAPERSTUDY_utils.py b/src/PY/SHAPERSTUDY_utils.py index 9c3bf41..8feefe5 100644 --- a/src/PY/SHAPERSTUDY_utils.py +++ b/src/PY/SHAPERSTUDY_utils.py @@ -127,7 +127,7 @@ __engine__ = None def getEngine(): global __engine__ if __engine__ is None: - __engine__ = getLCC().FindOrLoadComponent( "FactoryServer", moduleName() ) + __engine__ = getLCC().FindOrLoad_Component( "FactoryServer", moduleName() ) pass return __engine__ @@ -146,9 +146,9 @@ def getEngineIOR(): ### def findOrCreateComponent(): study = getStudy() + builder = study.NewBuilder() father = study.FindComponent( moduleName() ) if father is None: - builder = study.NewBuilder() father = builder.NewComponent( moduleName() ) attr = builder.FindOrCreateAttribute( father, "AttributeName" ) attr.SetValue( "ShaperStudy" ) @@ -162,5 +162,7 @@ def findOrCreateComponent(): except: pass pass + # load the SHAPER-STUDY file if it is not done yet + builder.LoadWith(father, getEngine()) return father diff --git a/src/StudyData/StudyData_Object.cpp b/src/StudyData/StudyData_Object.cpp index cfe70d0..2d28415 100644 --- a/src/StudyData/StudyData_Object.cpp +++ b/src/StudyData/StudyData_Object.cpp @@ -35,7 +35,6 @@ StudyData_Object::StudyData_Object(const std::string theFile) myStream = theFile; } - int StudyData_Object::type() const { if (myShape.IsNull()) @@ -43,31 +42,15 @@ int StudyData_Object::type() const return (int) myShape.ShapeType(); } - std::string StudyData_Object::shapeStream() const { return myStream; - - /* - - if (myShape.IsNull()) - return NULL; - - //Returns the number of bytes that have been stored in the stream's buffer. - int size = myStream.size(); - - //Allocate octect buffer of required size - CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size); - - //Copy ostrstream content to the octect buffer - memcpy(OctetBuf, myStream.c_str(), size); - - //Create and return TMPFile - SALOMEDS::TMPFile_var SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1); - return SeqFile._retn(); - */ } +std::string StudyData_Object::oldShapeStream() const +{ + return myOldStream.empty() ? myStream : myOldStream; +} long long StudyData_Object::shape() const { @@ -82,12 +65,19 @@ void StudyData_Object::updateShape(const std::string theFile) // update the current shape std::istringstream streamBrep(theFile.c_str()); BRep_Builder aBuilder; + myOldShape = myShape; BRepTools::Read(myShape, streamBrep, aBuilder); myTick++; + myOldStream = myStream; myStream = theFile; } -int StudyData_Object::getTick() +int StudyData_Object::getTick() const { return myTick; } + +void StudyData_Object::setTick(const int theValue) +{ + myTick = theValue; +} diff --git a/src/StudyData/StudyData_Object.h b/src/StudyData/StudyData_Object.h index a54b764..2679eb0 100644 --- a/src/StudyData/StudyData_Object.h +++ b/src/StudyData/StudyData_Object.h @@ -37,6 +37,7 @@ public: int type() const; std::string shapeStream() const; + std::string oldShapeStream() const; long long shape() const; @@ -44,11 +45,14 @@ public: void updateShape(const std::string theFile); // returns the version number of the shape starting from 1 - int getTick(); + int getTick() const; + + // sets the version number of the shape starting from 1 + void setTick(const int theValue); private: - std::string myStream; // the current stream of a shape - TopoDS_Shape myShape; // latest shape of this object + std::string myStream, myOldStream; // the current and old stream of a shape + TopoDS_Shape myShape, myOldShape; // latest shape of this object and the old one int myTick; // version index of the shape }; -- 2.39.2