1 # Copyright (C) 2007-2012 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 getData( self, studyID ):
74 if self.studyData.has_key( studyID ):
76 for m in self.studyData[ studyID ]:
79 print "ATOMGEN: getData() failed because studyID ", str( studyID ), " was not found"
82 def Save( self, component, URL, isMultiFile ):
85 Nothing to do here because in our case all data
86 are stored in the SALOMEDS attributes.
90 def Load( self, component, stream, URL, isMultiFile ):
96 import StringIO, pickle
97 study = component.GetStudy()
98 self.setCurrentStudy( study )
99 iter = study.NewChildIterator(component)
102 sobject = iter.Value()
104 found, attr = sobject.FindAttribute("AttributeName")
105 if not found: continue
106 from ATOMGEN_Data import Molecule, Atom
107 mol = Molecule(attr.Value())
108 __entry2IOR__[sobject.GetID()] = ObjectToString(mol._this())
109 iter1 = study.NewChildIterator(sobject)
111 sobject1 = iter1.Value()
113 found, attr = sobject1.FindAttribute("AttributeName")
114 if not found: continue
117 iter2 = study.NewChildIterator(sobject1)
119 sobject2 = iter2.Value()
121 found, attr1 = sobject2.FindAttribute("AttributeName")
122 if not found: continue
123 found, attr2 = sobject2.FindAttribute("AttributeReal")
124 if not found: continue
125 if attr1.Value() == "x": x = attr2.Value()
126 if attr1.Value() == "y": y = attr2.Value()
127 if attr1.Value() == "z": z = attr2.Value()
128 if None not in [x, y, z]:
129 atom = Atom(name, x, y, z)
131 __entry2IOR__[sobject1.GetID()] = ObjectToString(atom._this())
134 self.appendData( data, False )
137 def IORToLocalPersistentID(self, sobject, IOR, isMultiFile, isASCII):
139 Gets persistent ID for the CORBA object.
140 It's enough to use study entry.
142 return sobject.GetID()
144 def LocalPersistentIDToIOR(self, sobject, persistentID, isMultiFile, isASCII):
145 "Converts persistent ID of the object to its IOR."
147 if __entry2IOR__.has_key(persistentID):
148 return __entry2IOR__[persistentID]
151 def Close( self, component ):
153 Called when study is closed
155 study = component.GetStudy()
156 if study and self.studyData.has_key( study._get_StudyId() ):
157 del self.studyData[ study._get_StudyId() ]
158 if study == self.study:
162 def CanPublishInStudy( self, IOR ):
164 Returns True if the object can be published.
165 Nothing to do here. Usually this method should perform
166 check for the object type.
170 def PublishInStudy( self, study, sobject, object, name ):
172 Publishes the object in the study.
174 if study and object and object._narrow(ATOMGEN_ORB.Molecule):
175 builder = study.NewBuilder()
177 # get or create component object
178 father = study.FindComponent(self._ComponentDataType)
181 father = builder.NewComponent(self._ComponentDataType)
182 attr = builder.FindOrCreateAttribute(father, "AttributeName")
183 attr.SetValue(self._ComponentDataType)
184 builder.DefineComponentInstance(father, self._this())
187 sobject = builder.NewObject(father)
188 attr = builder.FindOrCreateAttribute(sobject, "AttributeName")
190 name = object.getName()
192 attr = builder.FindOrCreateAttribute(sobject, "AttributeIOR")
193 attr.SetValue(ObjectToString(object))
195 for i in range(object.getNbAtoms()):
196 atom = object.getAtom( i )
197 sobject1 = builder.NewObject(sobject)
198 attr = builder.FindOrCreateAttribute(sobject1, "AttributeName")
199 attr.SetValue(atom.getName())
200 attr = builder.FindOrCreateAttribute(sobject1, "AttributeIOR")
201 attr.SetValue(ObjectToString(atom))
202 sobject2 = builder.NewObject(sobject1)
203 attr = builder.FindOrCreateAttribute(sobject2, "AttributeName")
205 attr = builder.FindOrCreateAttribute(sobject2, "AttributeReal")
206 attr.SetValue(atom.getX())
207 sobject2 = builder.NewObject(sobject1)
208 attr = builder.FindOrCreateAttribute(sobject2, "AttributeName")
210 attr = builder.FindOrCreateAttribute(sobject2, "AttributeReal")
211 attr.SetValue(atom.getY())
212 sobject2 = builder.NewObject(sobject1)
213 attr = builder.FindOrCreateAttribute(sobject2, "AttributeName")
215 attr = builder.FindOrCreateAttribute(sobject2, "AttributeReal")
216 attr.SetValue(atom.getZ())
217 builder.CommitCommand()
221 def setCurrentStudy( self, study ):
223 Sets the active study
226 if self.study and not self.getData( self.study._get_StudyId() ):
227 studyID = self.study._get_StudyId()
228 self.studyData[ studyID ] = []
229 self.entry2PyName[ studyID ] = {}
230 print "ATOMGEN: init new arrays for studyID ", str( studyID )
233 def importXmlFile( self, fileName ):
235 Imports atomic data from external XML file
236 and publishes the data in the active study
240 from ATOMGEN_XmlParser import readXmlFile
241 new_data = readXmlFile( fileName )
242 entries = self.appendData( new_data )
243 if len(entries) > 0 :
244 cmd = "[" + ", ".join(entries) + "] = "+__pyEngineName__
245 cmd += ".importXmlFile('" + fileName + "')"
246 attr = self._getTableAttribute()
248 attr.PutValue(cmd,attr.GetNbRows()+1,1)
251 res.append(m._this())
255 def exportXmlFile( self, fileName ):
257 Exports atomic data from the active study to
258 the external XML file
261 from ATOMGEN_XmlParser import writeXmlFile
262 studyID = self.study._get_StudyId()
263 writeXmlFile( fileName, self.studyData[ studyID ] )
264 cmd = __pyEngineName__+ ".exportXmlFile('" + fileName + "')"
265 attr = self._getTableAttribute()
267 attr.PutValue(cmd,attr.GetNbRows()+1,1)
271 def processData( self, data ):
273 Perform some specific action on the atomic data
275 if not self.study: return []
281 for i in range( nb_steps ):
283 new_mol = self._translateMolecule( mol, i, dx * (i+1), dy * (i+1), dz * (i+1) )
284 new_data.append( new_mol )
285 entries = self.appendData( new_data )
286 if len(entries) > 0 :
289 ior = ObjectToString(m)
290 so = self.study.FindObjectIOR(ior)
291 lst.append(so.GetID())
293 cmd = "[" + ", ".join(entries) + "] = "+__pyEngineName__
294 cmd += ".processData([" + ", ".join(lst) + "])"
295 attr = self._getTableAttribute()
297 attr.PutValue(cmd, attr.GetNbRows()+1,1)
300 res.append(m._this())
303 def appendData( self, new_data, publish = True ):
305 Add new molecules to data published under current study
312 for i in range(mol.getNbAtoms()):
313 mol.atoms[ i ]._this()
314 mol_servant = mol._this()
316 so = self.PublishInStudy(self.study, None, mol_servant, mol_servant.getName())
318 entries.append(so.GetID())
320 studyID = self.study._get_StudyId()
321 if self.studyData.has_key( studyID ):
322 data = self.studyData[ studyID ]
324 self.studyData[ studyID ] = data
326 print "ATOMGEN: could not append new data because studyID ", str( studyID ), " was not found"
329 def _translateMolecule( self, mol, i, dx, dy, dz ):
331 Translates atomic molecule along x, y, z axis
332 by given distances dx, dy, dz
333 Returns translated molecule
335 mol = ObjectToServant( mol )
336 from ATOMGEN_Data import Molecule, Atom
337 new_mol = Molecule( mol.name + "_translated_" + str( i ) )
338 for atom in mol.atoms:
339 new_mol.addAtom( Atom( atom.name, atom.x + dx, atom.y + dy, atom.z + dz ) )
343 def DumpPython(self, theStudy, isPublished, isMultiFile):
347 script.append("import salome")
350 script.append("import ATOMGEN\n")
351 script.append(__pyEngineName__ + " = salome.lcc.FindOrLoadComponent(\"FactoryServerPy\", \"ATOMGEN\")")
354 script.append("def RebuildData(theStudy):\n")
355 script.append(prefix+__pyEngineName__ + ".setCurrentStudy(theStudy)\n")
357 script.append(__pyEngineName__ + ".setCurrentStudy(theStudy)\n")
359 attr = self._getTableAttribute()
361 for idx in range(attr.GetNbRows()):
362 s = prefix + attr.GetValue(idx+1,1)
366 script.append(prefix+"pass")
371 all = "\n".join(script)
373 studyID = self.study._get_StudyId()
375 for k in self.entry2PyName[studyID].keys() :
376 all = all.replace(k,self.entry2PyName[studyID][k])
380 def _getTableAttribute(self):
382 Create and return AttributeTableOfString attribute
383 on the root module object. This attribute used to store
386 if self.study is not None:
387 father = self.study.FindComponent(self._ComponentDataType)
388 if father is not None :
390 hasAttribute, attribute = father.FindAttribute("AttributeTableOfString")
392 builder = self.study.NewBuilder()
393 attribute = builder.FindOrCreateAttribute(father,"AttributeTableOfString")
394 attribute.SetNbColumns(1)
399 def _getPyNames(self):
401 Generate python name for the each object published in the study.
403 if self.study is None:
406 studyID = self.study._get_StudyId()
407 self.entry2PyName[studyID] = {}
408 iter = self.study.NewChildIterator(self.study.FindComponent(self._ComponentDataType))
410 sobject = iter.Value()
412 found, attr = sobject.FindAttribute("AttributeName")
413 if not found: continue
414 self.entry2PyName[studyID][sobject.GetID()] = self._fixPythonName(attr.Value())
416 def _fixPythonName(self, in_str):
418 Make a string be a valid python name
421 allowed = string.ascii_lowercase+string.ascii_uppercase + string.digits + "_"
423 for i in range(len(in_str)):
428 if len(newstring) == 0 :
431 if newstring[0] in string.digits:
432 newstring = "a"+newstring
434 studyID = self.study._get_StudyId()
436 if newstring in self.entry2PyName[studyID].values():
437 newstring = self._fixPythonName( newstring + "_1")