1 # Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 import SHAPERSTUDY_ORB__POA
24 import SHAPERSTUDY_ORB
25 import SALOME_ComponentPy
26 import SALOME_DriverPy
28 from SHAPERSTUDY_utils import findOrCreateComponent, moduleName, getStudy, getORB
30 import SHAPERSTUDY_Object
31 import SHAPERSTUDY_IOperations
38 class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
39 SALOME_ComponentPy.SALOME_ComponentPy_i,
40 SALOME_DriverPy.SALOME_DriverPy_i):
43 ShapeType = {"AUTO":-1, "COMPOUND":0, "COMPSOLID":1, "SOLID":2, "SHELL":3, "FACE":4, "WIRE":5, "EDGE":6, "VERTEX":7, "SHAPE":8, "FLAT":9}
45 ShaperIcons = {GEOM.COMPOUND:"SHAPER_ICON_COMPSOLID",
46 GEOM.COMPSOLID:"SHAPER_ICON_COMPSOLID",
47 GEOM.SOLID:"SHAPER_ICON_SOLID",
48 GEOM.SHELL:"SHAPER_ICON_SHELL",
49 GEOM.FACE:"SHAPER_ICON_FACE",
50 GEOM.WIRE:"SHAPER_ICON_WIRE",
51 GEOM.EDGE:"SHAPER_ICON_EDGE",
52 GEOM.VERTEX:"SHAPER_ICON_VERTEX",
53 GEOM.SHAPE:"SHAPER_ICON_SOLID",
54 GEOM.FLAT:"SHAPER_ICON_FACE"
57 def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ):
59 Construct an instance of SHAPERSTUDY module engine.
60 The class SHAPERSTUDY implements CORBA interface Gen (see SHAPERSTUDY_Gen.idl).
61 It is inherited (via GEOM_Gen) from the classes SALOME_ComponentPy_i (implementation of
62 Engines::EngineComponent CORBA interface - SALOME component) and SALOME_DriverPy_i
63 (implementation of SALOMEDS::Driver CORBA interface - SALOME module's engine).
65 SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
66 contID, containerName, instanceName, interfaceName, False)
67 SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
69 #self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
73 def FindOrCreateShape( self, theInternalEntry ):
75 Searches existing or creates a new SHAPERSTUDY_Object to interact with SHAPER
77 # Searching in the study tree
78 aComponent = findOrCreateComponent()
79 aSOIter = getStudy().NewChildIterator(aComponent)
83 anObj = salome.orb.string_to_object(anIOR)
84 if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
85 if anObj.GetEntry() == theInternalEntry:
89 aShapeObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
90 aShapeObj.SetEntry(theInternalEntry)
91 return aShapeObj._this()
93 def AddInStudy( self, theObject, theName, theFather ):
95 Adds in theStudy a object theObject under theFather with a name theName,
96 if theFather is not NULL the object is placed under theFather's SObject.
97 Returns a SObject where theObject is placed
100 aBuilder = aStudy.NewBuilder()
101 isGroup = theObject.GetType() == 37 or theObject.GetType() == 52
104 return None # Group may be added only under the shape-father
105 theFather = findOrCreateComponent()
107 if isGroup: # add group to the third sub-label or later to keep space for reference and "History"
109 anIter = aStudy.NewChildIterator(theFather)
111 aCurrentTag = anIter.Value().Tag() + 1
112 if aTag < aCurrentTag:
115 aResultSO = aBuilder.NewObjectToTag(theFather, aTag)
117 aResultSO = aBuilder.NewObject(theFather);
118 aResultSO.SetAttrString("AttributeName", theName)
119 if theObject is not None:
120 anIOR = salome.orb.object_to_string(theObject)
121 aResultSO.SetAttrString("AttributeIOR", anIOR)
122 theObject.SetSO(aResultSO)
124 aAttr = aBuilder.FindOrCreateAttribute(aResultSO, "AttributePixMap")
125 aPixmap = aAttr._narrow(salome.SALOMEDS.AttributePixMap)
128 aType = SHAPERSTUDY_Object.__shape_types__[theObject.GetSelectionType()]
130 aType = theObject.GetShapeType()
131 aPixmap.SetPixMap(SHAPERSTUDY.ShaperIcons[aType])
133 # add a red-reference that means that this is an active reference to SHAPER result
135 aSub = aBuilder.NewObjectToTag(aResultSO, 1)
136 aBuilder.Addreference(aSub, aResultSO)
140 def AddSubShape( theMainShape, theIndices ):
142 Add a sub-shape defined by indices in theIndices
143 (contains unique IDs of sub-shapes inside theMainShape)
145 # no sub-shapes for the moment
146 go = SHAPERSTUDY_Object()._this()
149 # For now it is impossible to remove anything from the SHAPER-STUDY
150 def RemoveObject( self, theObject ):
152 Removes the object from the component
154 # can not be removed for the moment
157 def GetIFieldOperations( self ):
160 return SHAPERSTUDY_IOperations.SHAPERSTUDY_IFieldOperations()._this()
162 def GetIGroupOperations( self ):
165 return SHAPERSTUDY_IOperations.SHAPERSTUDY_IGroupOperations()._this()
167 def GetIShapesOperations( self ):
170 return SHAPERSTUDY_IOperations.SHAPERSTUDY_IShapesOperations()._this()
172 def GetIMeasureOperations( self ):
175 return SHAPERSTUDY_IOperations.SHAPERSTUDY_IMeasureOperations()._this()
177 def GetStringFromIOR( self, theObject ):
179 Returns a string which contains an IOR of the SHAPERSTUDY_Object
182 if theObject and getORB():
183 IOR = getORB().object_to_string( theObject )
187 def GetAllDumpNames( self ):
189 Returns all names with which Object's was dumped
190 into python script to avoid the same names in SMESH script
194 def GetDumpName( self, theStudyEntry ):
196 Returns a name with which a GEOM_Object was dumped into python script
199 theStudyEntry is an entry of the Object in the study
203 def Save( self, component, URL, isMultiFile ):
205 Saves data: all objects into one file
207 aResult = "" # string-pairs of internal entries and shape streams
209 # get all sub-SObjects with IOR defined
210 anIters = [aStudy.NewChildIterator(findOrCreateComponent())]
213 aLast = anIters[len(anIters) - 1]
219 anIters.append(aStudy.NewChildIterator(aSO))
222 anIters.remove(aLast)
224 for aSO in aSOList: # for each sobject export shapes stream if exists
228 anObj = salome.orb.string_to_object(anIOR)
229 if type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Group:
231 aResult = aResult + '|'
232 # store internal entry, type and list of indices of the group selection (separated by spaces)
233 aResult = aResult + anObj.GetEntry() + "|" + str(anObj.GetSelectionType())
234 aSelList = anObj.GetSelection()
235 aResult = aResult + "|" + str(' '.join(str(anI) for anI in aSelList))
236 elif type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Field:
238 aResult = aResult + '|'
239 # same as for group, but in addition to the second string part - field specifics
240 aResult = aResult + anObj.GetEntry() + "|" + str(anObj.GetSelectionType())
241 aResult = aResult + " " + str(anObj.GetDataType()) # values type
242 aSteps = anObj.GetSteps()
243 aResult = aResult + " " + str(len(aSteps)) # number of steps
244 aComps = anObj.GetComponents()
245 aResult = aResult + " " + str(len(aComps)) # number of components
246 for aComp in aComps: # components strings: but before remove spaces and '|'
247 aCoded = aComp.replace(" ", "__space__").replace("|", "__vertical_bar__")
248 aResult = aResult + " " + aCoded
249 for aStepNum in range(len(aSteps)):
250 aVals = anObj.GetStep(aStepNum + 1).GetValues()
252 aResult = aResult + " " + str(len(aVals)) # first the number of values in the step
253 aResult = aResult + " " + str(anObj.GetStep(aStepNum + 1).GetStamp()) # ID of stamp in step
255 aResult = aResult + " " + str(aVal) # all values of step
256 aSelList = anObj.GetSelection()
257 aResult = aResult + "|" + str(' '.join(str(anI) for anI in aSelList))
258 elif isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
260 aResult = aResult + '|'
261 # store internal entry, current and old shapes in BRep format
262 aResult = aResult + anObj.GetEntry() + "|" + anObj.GetShapeStream().decode()
263 aResult = aResult + "|" + anObj.GetOldShapeStream().decode()
265 return aResult.encode()
267 def Load( self, component, stream, URL, isMultiFile ):
272 __entry2IOR__.clear()
273 aList=stream.decode().split('|')
282 aNewShapeStream = aSub
284 else: # create objects by 3 arguments
286 if anId.startswith('group') or (anId.startswith('dead') and anId.count("group") > 0): # group object
287 anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Group()
289 anObj.SetSelection([int(anI) for anI in aSub.split(' ')])
290 anObj.SetSelectionType(int(aNewShapeStream))
291 elif anId.startswith('field') or (anId.startswith('dead') and anId.count("field") > 0): # field object
292 anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Field()
294 anObj.SetSelection([int(anI) for anI in aSub.split(' ')])
295 aParams = aNewShapeStream.split(" ")
296 anObj.SetSelectionType(int(aParams[0]))
297 aTypeStr = aParams[1]
298 if (aTypeStr == "FDT_Bool"):
299 anObj.SetValuesType(0)
300 elif (aTypeStr == "FDT_Int"):
301 anObj.SetValuesType(1)
302 elif (aTypeStr == "FDT_Double"):
303 anObj.SetValuesType(2)
304 elif (aTypeStr == "FDT_String"):
305 anObj.SetValuesType(3)
307 aNumSteps = int(aParams[2])
308 for aVal in range(aNumSteps):
309 aSteps.append(aVal + 1)
310 anObj.SetSteps(aSteps)
311 aCompNum = int(aParams[3])
313 for aCompNameIndex in range(aCompNum):
314 aCompName = aParams[4 + aCompNameIndex].replace("__space__", " ").replace("__vertical_bar__", "|")
315 aCompNames.append(aCompName)
316 anObj.SetComponents(aCompNames)
317 aNumValsInStep = int(aParams[4 + aCompNum])
318 for aStepNum in range(aNumSteps):
319 aStepStartIndex = 4 + aCompNum + aStepNum * (aNumValsInStep + 1) + 1
320 aStampId = int(aParams[aStepStartIndex])
322 for aValIndex in range(aNumValsInStep):
323 aVals.append(float(aParams[aStepStartIndex + aValIndex + 1]))
324 anObj.AddFieldStep(aStampId, aStepNum + 1, aVals)
325 else: # shape object by BRep in the stream: set old first then new
326 anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
328 anObj.SetShapeByStream(aSub)
329 anObj.SetShapeByStream(aNewShapeStream)
332 anIOR = salome.orb.object_to_string(anObj._this())
333 __entry2IOR__[anId] = anIOR
334 print("Store for entry "+anId+" IOR=", anIOR)
338 def IORToLocalPersistentID(self, sobject, IOR, isMultiFile, isASCII):
340 Gets persistent ID for the CORBA object.
341 The internal entry of the Object is returned.
343 anObj = salome.orb.string_to_object(IOR)
344 if anObj and (isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object) or \
345 isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Field)):
346 return anObj.GetEntry()
349 def LocalPersistentIDToIOR(self, sobject, persistentID, isMultiFile, isASCII):
350 "Converts persistent ID of the object to its IOR."
352 print("Requires presistent ID="+persistentID)
353 if persistentID in __entry2IOR__:
354 aRes = __entry2IOR__[persistentID]
355 if len(aRes): # set SO from the study, the sobject param is temporary, don't store it
356 print("Found res="+str(aRes))
357 salome.orb.string_to_object(aRes).SetSO(getStudy().FindObjectID(sobject.GetID()))
361 def DumpPython( self, isPublished, isMultiFile ):
363 Dump module data to the Python script.
365 return ("".encode(), 1)
369 def CreateGroup( self, theMainShape, theShapeType ):
371 Creates a new group which will store sub-shapes of theMainShape
373 return GetIGroupOperations().CreateGroup( theMainShape, theShapeType );
375 def ExtractShapes( self, aShape, aType, isSorted = False ):
377 Extract shapes (excluding the main shape) of given type.
381 aType The shape type (see geompy.ShapeType)
382 isSorted Boolean flag to switch sorting on/off.
385 List of sub-shapes of type aType, contained in aShape.
387 return [ SHAPERSTUDY_Object()._this() ]
389 def GetSubShape( self, aShape, ListOfID ):
391 Obtain a composite sub-shape of aShape, composed from sub-shapes
392 of aShape, selected by their unique IDs inside aShape
395 aShape Shape to get sub-shape of.
396 ListOfID List of sub-shapes indices.
398 return SHAPERSTUDY_Object()._this()
400 def GetSubShapeID( self, aShape, aSubShape ):
402 Obtain unique ID of sub-shape aSubShape inside aShape
403 of aShape, selected by their unique IDs inside aShape
406 aShape Shape to get sub-shape of.
407 aSubShape Sub-shapes of aShape.
411 def MinDistance( self, theShape1, theShape2 ):
413 Get minimal distance between the given shapes.
417 def NumberOfEdges( self, theShape ):
419 Gives quantity of edges in the given shape.
423 def NumberOfFaces( self, ):
425 Gives quantity of faces in the given shape.
429 def PointCoordinates( self, theVertex ):
431 Get point coordinates
435 def SubShapeAll( self, aShape, aType ):
437 Explode a shape on sub-shapes of a given type.
438 If the shape itself matches the type, it is also returned.
440 return [ SHAPERSTUDY_Object()._this() ]
442 def SubShapeName( self, aSubObj, aMainObj ):
444 Get name for sub-shape aSubObj of shape aMainObj
448 def SubShapes( self, aShape, anIDs ):
450 Get a set of sub-shapes defined by their unique IDs inside theMainShape
452 return [ SHAPERSTUDY_Object()._this() ]
454 def Tolerance( self, theShape ):
456 Get min and max tolerances of sub-shapes of theShape
459 [FaceMin,FaceMax, EdgeMin,EdgeMax, VertMin,VertMax]
461 return [0,0, 0,0, 0,0]
463 def UnionList( self, theGroup, theSubShapes ):
465 Adds to the group all the given shapes. No errors, if some shapes are already included.
467 return GetIGroupOperations().UnionList( theGroup, theSubShapes )
469 def IsFather(theFather, theChild):
471 Returns true if theChild SObject is a child of theFather SObject
473 aChild = theChild.GetFather()
474 while aChild.Depth() > theFather.Depth():
475 aChild = aChild.GetFather()
476 return aChild.GetID() == theFather.GetID()
478 def BreakLink(self, theEntry):
480 Breaks links to not-dead shape, make the shape as dead
483 aSO = aStudy.FindObjectID(theEntry)
486 aRes, aSSO = aSO.ReferencedObject()
488 return # only SObjects referenced to the SHAPEr STUDY objects are allowed
489 anIOR = aSSO.GetIOR()
491 return # must be referenced to the SHAPER STUDY shape
492 anObj = salome.orb.string_to_object(anIOR)
493 if not anObj or not isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
496 return # do nothing for reference to already dead shape
497 aDeadShape = anObj.MakeDead()
499 # Replace shape object in the parent mesh
500 aMeshSObject = aSO.GetFather()
501 aMeshObject = aMeshSObject.GetObject()
502 aMeshObject.ReplaceShape(aDeadShape)
504 aBuilder = aStudy.NewBuilder()
505 aBuilder.RemoveReference(aSO) # reset reference to the dead shape
506 aBuilder.Addreference(aSO, aDeadShape.GetSO())
508 # check also sub-structure of the mesh to find references to sub-objects that become dead
509 aRoot = aSO.GetFather()
510 anIters = [aStudy.NewChildIterator(aRoot)]
513 aLast = anIters[len(anIters) - 1]
516 aRes, aSubRef = aSub.ReferencedObject()
517 if aRes and SHAPERSTUDY.IsFather(aSSO, aSubRef):
518 aReferenced = aSubRef.GetObject()
519 if aReferenced and not aReferenced.IsDead():
520 aSubList.append(aSub)
521 anIters.append(aStudy.NewChildIterator(aSub))
524 anIters.remove(aLast)
526 # associate the number of sub-objects of the referenced objects
527 aMapSubEntryToIndex = {}
528 aSSOIter = aStudy.NewChildIterator(aSSO)
530 while aSSOIter.More():
531 aSub = aSSOIter.Value()
533 aMapSubEntryToIndex[aSub.GetID()] = anIndex
534 anIndex = anIndex + 1
536 for aSubSO in aSubList:
537 aRes, aSubRef = aSubSO.ReferencedObject()
538 if aRes and aSubRef.GetID() in aMapSubEntryToIndex:
539 anIndex = aMapSubEntryToIndex[aSubRef.GetID()]
540 aDeadIter = aStudy.NewChildIterator(aDeadShape.GetSO())
541 while aDeadIter.More(): # iterate dead subs to find object with the same index
542 aDeadSubSO = aDeadIter.Value()
543 if aDeadSubSO.GetIOR():
544 anIndex = anIndex - 1
546 # for a submesh there is no ReplaceShape, but the shape is not updated
547 # anyway, so no need to update it here
548 #aSubMeshSO = aSubSO.GetFather() # Replace shape object in the parent mesh
549 #aSubMeshObject = aSubMeshSO.GetObject()
551 # aSubMeshObject.ReplaceShape(aDeadSubSO.GetObject())
552 aBuilder.RemoveReference(aSubSO) # reset reference to the dead shape
553 aBuilder.Addreference(aSubSO, aDeadSubSO)