1 # Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 import ATOMGEN_ORB__POA
22 import SALOME_ComponentPy
23 import SALOME_DriverPy
27 from omniORB import CORBA
28 myORB = CORBA.ORB_init([''], CORBA.ORB_ID)
30 def ObjectToString(object):
31 return myORB.object_to_string(object)
33 def StringToObject(string):
34 return myORB.string_to_object(string)
37 from omniORB import PortableServer
38 myPOA = myORB.resolve_initial_references("RootPOA");
40 def ObjectToServant(object):
41 return myPOA.reference_to_servant(object)
45 __pyEngineName__ = "atomgen"
47 #--- Engine implementation ---
48 class ATOMGEN( ATOMGEN_ORB__POA.ATOMGEN_Gen,
49 SALOME_ComponentPy.SALOME_ComponentPy_i,
50 SALOME_DriverPy.SALOME_DriverPy_i ):
52 ATOMGEN component engine
54 def __init__ ( self, orb, poa, contID, containerName, instanceName,
59 SALOME_ComponentPy.SALOME_ComponentPy_i.__init__( self, orb, poa,
60 contID, containerName,
61 instanceName, interfaceName, 0 )
62 SALOME_DriverPy.SALOME_DriverPy_i.__init__( self, interfaceName )
64 self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
67 self.entry2PyName = {}
70 def getVersion( self ):
72 return salome_version.getVersion("ATOMGEN", True)
74 def getData( self, studyID ):
78 if self.studyData.has_key( studyID ):
80 for m in self.studyData[ studyID ]:
83 print "ATOMGEN: getData() failed because studyID ", str( studyID ), " was not found"
86 def Save( self, component, URL, isMultiFile ):
89 Nothing to do here because in our case all data
90 are stored in the SALOMEDS attributes.
94 def Load( self, component, stream, URL, isMultiFile ):
100 import StringIO, pickle
101 study = component.GetStudy()
102 self.setCurrentStudy( study )
103 iter = study.NewChildIterator(component)
106 sobject = iter.Value()
108 found, attr = sobject.FindAttribute("AttributeName")
109 if not found: continue
110 from ATOMGEN_Data import Molecule, Atom
111 mol = Molecule(attr.Value())
112 __entry2IOR__[sobject.GetID()] = ObjectToString(mol._this())
113 iter1 = study.NewChildIterator(sobject)
115 sobject1 = iter1.Value()
117 found, attr = sobject1.FindAttribute("AttributeName")
118 if not found: continue
121 iter2 = study.NewChildIterator(sobject1)
123 sobject2 = iter2.Value()
125 found, attr1 = sobject2.FindAttribute("AttributeName")
126 if not found: continue
127 found, attr2 = sobject2.FindAttribute("AttributeReal")
128 if not found: continue
129 if attr1.Value() == "x": x = attr2.Value()
130 if attr1.Value() == "y": y = attr2.Value()
131 if attr1.Value() == "z": z = attr2.Value()
132 if None not in [x, y, z]:
133 atom = Atom(name, x, y, z)
135 __entry2IOR__[sobject1.GetID()] = ObjectToString(atom._this())
138 self.appendData( data, False )
141 def IORToLocalPersistentID(self, sobject, IOR, isMultiFile, isASCII):
143 Gets persistent ID for the CORBA object.
144 It's enough to use study entry.
146 return sobject.GetID()
148 def LocalPersistentIDToIOR(self, sobject, persistentID, isMultiFile, isASCII):
149 "Converts persistent ID of the object to its IOR."
151 if __entry2IOR__.has_key(persistentID):
152 return __entry2IOR__[persistentID]
155 def Close( self, component ):
157 Called when study is closed
159 study = component.GetStudy()
160 if study and self.studyData.has_key( study._get_StudyId() ):
161 del self.studyData[ study._get_StudyId() ]
162 if study == self.study:
166 def CanPublishInStudy( self, IOR ):
168 Returns True if the object can be published.
169 Nothing to do here. Usually this method should perform
170 check for the object type.
174 def PublishInStudy( self, study, sobject, object, name ):
176 Publishes the object in the study.
178 if study and object and object._narrow(ATOMGEN_ORB.Molecule):
179 builder = study.NewBuilder()
181 # get or create component object
182 father = study.FindComponent(self._ComponentDataType)
185 father = builder.NewComponent(self._ComponentDataType)
186 attr = builder.FindOrCreateAttribute(father, "AttributeName")
187 attr.SetValue(self._ComponentDataType)
188 builder.DefineComponentInstance(father, self._this())
191 sobject = builder.NewObject(father)
192 attr = builder.FindOrCreateAttribute(sobject, "AttributeName")
194 name = object.getName()
196 attr = builder.FindOrCreateAttribute(sobject, "AttributeIOR")
197 attr.SetValue(ObjectToString(object))
199 for i in range(object.getNbAtoms()):
200 atom = object.getAtom( i )
201 sobject1 = builder.NewObject(sobject)
202 attr = builder.FindOrCreateAttribute(sobject1, "AttributeName")
203 attr.SetValue(atom.getName())
204 attr = builder.FindOrCreateAttribute(sobject1, "AttributeIOR")
205 attr.SetValue(ObjectToString(atom))
206 sobject2 = builder.NewObject(sobject1)
207 attr = builder.FindOrCreateAttribute(sobject2, "AttributeName")
209 attr = builder.FindOrCreateAttribute(sobject2, "AttributeReal")
210 attr.SetValue(atom.getX())
211 sobject2 = builder.NewObject(sobject1)
212 attr = builder.FindOrCreateAttribute(sobject2, "AttributeName")
214 attr = builder.FindOrCreateAttribute(sobject2, "AttributeReal")
215 attr.SetValue(atom.getY())
216 sobject2 = builder.NewObject(sobject1)
217 attr = builder.FindOrCreateAttribute(sobject2, "AttributeName")
219 attr = builder.FindOrCreateAttribute(sobject2, "AttributeReal")
220 attr.SetValue(atom.getZ())
221 builder.CommitCommand()
225 def setCurrentStudy( self, study ):
227 Sets the active study
230 if self.study and not self.getData( self.study._get_StudyId() ):
231 studyID = self.study._get_StudyId()
232 self.studyData[ studyID ] = []
233 self.entry2PyName[ studyID ] = {}
234 print "ATOMGEN: init new arrays for studyID ", str( studyID )
237 def importXmlFile( self, fileName ):
239 Imports atomic data from external XML file
240 and publishes the data in the active study
244 from ATOMGEN_XmlParser import readXmlFile
245 new_data = readXmlFile( fileName )
246 entries = self.appendData( new_data )
247 if len(entries) > 0 :
248 cmd = "[" + ", ".join(entries) + "] = "+__pyEngineName__
249 cmd += ".importXmlFile('" + fileName + "')"
250 attr = self._getTableAttribute()
252 attr.PutValue(cmd,attr.GetNbRows()+1,1)
255 res.append(m._this())
259 def exportXmlFile( self, fileName ):
261 Exports atomic data from the active study to
262 the external XML file
265 from ATOMGEN_XmlParser import writeXmlFile
266 studyID = self.study._get_StudyId()
267 writeXmlFile( fileName, self.studyData[ studyID ] )
268 cmd = __pyEngineName__+ ".exportXmlFile('" + fileName + "')"
269 attr = self._getTableAttribute()
271 attr.PutValue(cmd,attr.GetNbRows()+1,1)
275 def processData( self, data ):
277 Perform some specific action on the atomic data
279 if not self.study: return []
285 for i in range( nb_steps ):
287 new_mol = self._translateMolecule( mol, i, dx * (i+1), dy * (i+1), dz * (i+1) )
288 new_data.append( new_mol )
289 entries = self.appendData( new_data )
290 if len(entries) > 0 :
293 ior = ObjectToString(m)
294 so = self.study.FindObjectIOR(ior)
295 lst.append(so.GetID())
297 cmd = "[" + ", ".join(entries) + "] = "+__pyEngineName__
298 cmd += ".processData([" + ", ".join(lst) + "])"
299 attr = self._getTableAttribute()
301 attr.PutValue(cmd, attr.GetNbRows()+1,1)
304 res.append(m._this())
307 def appendData( self, new_data, publish = True ):
309 Add new molecules to data published under current study
316 for i in range(mol.getNbAtoms()):
317 mol.atoms[ i ]._this()
318 mol_servant = mol._this()
320 so = self.PublishInStudy(self.study, None, mol_servant, mol_servant.getName())
322 entries.append(so.GetID())
324 studyID = self.study._get_StudyId()
325 if self.studyData.has_key( studyID ):
326 data = self.studyData[ studyID ]
328 self.studyData[ studyID ] = data
330 print "ATOMGEN: could not append new data because studyID ", str( studyID ), " was not found"
333 def _translateMolecule( self, mol, i, dx, dy, dz ):
335 Translates atomic molecule along x, y, z axis
336 by given distances dx, dy, dz
337 Returns translated molecule
339 mol = ObjectToServant( mol )
340 from ATOMGEN_Data import Molecule, Atom
341 new_mol = Molecule( mol.name + "_translated_" + str( i ) )
342 for atom in mol.atoms:
343 new_mol.addAtom( Atom( atom.name, atom.x + dx, atom.y + dy, atom.z + dz ) )
347 def DumpPython(self, theStudy, isPublished, isMultiFile):
351 script.append("import salome")
354 script.append("import ATOMGEN\n")
355 script.append(__pyEngineName__ + " = salome.lcc.FindOrLoadComponent(\"FactoryServerPy\", \"ATOMGEN\")")
358 script.append("def RebuildData(theStudy):\n")
359 script.append(prefix+__pyEngineName__ + ".setCurrentStudy(theStudy)\n")
361 script.append(__pyEngineName__ + ".setCurrentStudy(theStudy)\n")
363 attr = self._getTableAttribute()
365 for idx in range(attr.GetNbRows()):
366 s = prefix + attr.GetValue(idx+1,1)
370 script.append(prefix+"pass")
375 all = "\n".join(script)
377 studyID = self.study._get_StudyId()
379 for k in self.entry2PyName[studyID].keys() :
380 all = all.replace(k,self.entry2PyName[studyID][k])
384 def _getTableAttribute(self):
386 Create and return AttributeTableOfString attribute
387 on the root module object. This attribute used to store
390 if self.study is not None:
391 father = self.study.FindComponent(self._ComponentDataType)
392 if father is not None :
394 hasAttribute, attribute = father.FindAttribute("AttributeTableOfString")
396 builder = self.study.NewBuilder()
397 attribute = builder.FindOrCreateAttribute(father,"AttributeTableOfString")
398 attribute.SetNbColumns(1)
403 def _getPyNames(self):
405 Generate python name for the each object published in the study.
407 if self.study is None:
410 studyID = self.study._get_StudyId()
411 self.entry2PyName[studyID] = {}
412 iter = self.study.NewChildIterator(self.study.FindComponent(self._ComponentDataType))
414 sobject = iter.Value()
416 found, attr = sobject.FindAttribute("AttributeName")
417 if not found: continue
418 self.entry2PyName[studyID][sobject.GetID()] = self._fixPythonName(attr.Value())
420 def _fixPythonName(self, in_str):
422 Make a string be a valid python name
425 allowed = string.ascii_lowercase+string.ascii_uppercase + string.digits + "_"
427 for i in range(len(in_str)):
432 if len(newstring) == 0 :
435 if newstring[0] in string.digits:
436 newstring = "a"+newstring
438 studyID = self.study._get_StudyId()
440 if newstring in self.entry2PyName[studyID].values():
441 newstring = self._fixPythonName( newstring + "_1")