Salome HOME
Implementation of python dump of SHAPER STUDY for dead fields using XAO file format.
[modules/shaper_study.git] / src / PY / SHAPERSTUDY_Object.py
1 # Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 #
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.
10 #
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.
15 #
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
19 #
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #
22
23 import SHAPERSTUDY_ORB
24 import SHAPERSTUDY_ORB__POA
25 import GEOM
26 from SHAPERSTUDY_utils import getEngine, getStudy
27 import salome
28
29 import StudyData_Swig
30
31 # converter from the integer values to idl shape_type enumerations
32 __shape_types__ = {
33   0:GEOM.COMPOUND, 1:GEOM.COMPSOLID, 2:GEOM.SOLID,
34   3:GEOM.SHELL, 4:GEOM.FACE, 5:GEOM.WIRE,
35   6:GEOM.EDGE, 7:GEOM.VERTEX, 8:GEOM.SHAPE, 9:GEOM.FLAT}
36
37 class SHAPERSTUDY_GenericObject:
38     """
39     Implement methods of SALOME::GenericObj
40     """
41     def __init__(self):
42         self.cnt=1
43
44     def Register(self):
45         """
46         Increase the reference count (mark as used by another object).
47         """
48         #print(self.GetEntry())
49         self.cnt+=1
50         #print("Register() --------- ", id(self), self.cnt)
51         return
52
53     def UnRegister(self):
54         """
55         Decrease the reference count (release by another object)
56         """
57         self.cnt-=1
58         #print("UnRegister() --------- ", id(self), self.cnt)
59         if self.cnt <= 0:
60             from SHAPERSTUDY_utils import getPOA
61             poa = getPOA()
62             oid=poa.servant_to_id(self)
63             poa.deactivate_object(oid)
64             if hasattr(self,"SetSO"):
65                 self.SetSO(None) # release a GenericObject SO
66             #print("UnRegister() --------- OK")
67         return
68
69     def Destroy(self):
70         """
71         Obsolete, left for compatibility reasons only. Use UnRegister() instead
72         """
73         self.UnRegister()
74         return
75
76     pass
77
78
79 class SHAPERSTUDY_Object(SHAPERSTUDY_ORB__POA.SHAPER_Object,
80                          SHAPERSTUDY_GenericObject):
81     """
82     Constructs an instance of SHAPERSTUDY Object.
83     """
84     def __init__ ( self, *args):
85         SHAPERSTUDY_GenericObject.__init__(self)
86         self.SO = None
87         self.data = None
88         self.entry = ""
89         self.type = 1 # by default it is a shape (Import feature in GEOMImpl_Types.hxx)
90         pass
91
92     def GetShapeType( self ):
93         """
94         Get a GEOM.shape_type of the object value.
95         """
96         if self.data is None:
97             return GEOM.SHAPE
98         global __shape_types__
99         return __shape_types__[self.data.type()];
100
101     def IsMainShape( self ):
102         """
103         Returns True if this object is not a sub-shape of another object.
104         """
105         return True
106
107     def GetSubShapeIndices( self ):
108         """
109         Get a list of ID's of sub-shapes in the main shape.
110         """
111         return []
112
113     def GetMainShape( self ):
114         """
115         Get a main shape object to which this object is a sub-shape.
116         """
117         return getShape()
118
119     def getShape( self ):
120         """
121         Get the TopoDS_Shape, for collocated case only.
122         Called by GEOM_Client to get TopoDS_Shape pointer
123         """
124         if self.data is None:
125             return 0
126         return self.data.shape()
127
128     def GetShapeStream( self ):
129         """
130         Get geometric shape of the object as a byte stream in BRep format
131         """
132         if self.data is None:
133             return b''
134         return self.data.shapeStream().encode()
135
136     def GetOldShapeStream( self ):
137         """
138         Get geometric shape of the object as a byte stream in BRep format
139         """
140         if self.data is None:
141             return b''
142         return self.data.oldShapeStream().encode()
143
144     def SetShapeByStream(self, theStream):
145         """
146         Sets geometric shape content of the object as a byte stream in BRep format
147         """
148         if self.data:
149           self.data.updateShape(theStream)
150         else:
151           self.data = StudyData_Swig.StudyData_Object(theStream)
152
153     """
154     Methods from BaseObject
155     """
156     def GetName( self ):
157         """
158         Get name of the object associated with this object.
159         """
160         return self.SO.GetName()
161
162     def SetEntry( self, theInternalEntry ):
163         """
164         Sets internal (unique) entry of the object in the component's data tree.
165         """
166         self.entry = theInternalEntry
167
168     def GetEntry( self ):
169         """
170         Get internal (unique) entry of the object in the component's data tree.
171         """
172         return self.entry
173
174     def GetType( self ):
175         """
176         Get internal type of operation created this object.
177         In SMESH is used to find out if an object is GROUP (type == 37)
178         """
179         return self.type
180
181     def SetType( self, theType ):
182         """
183         Sets internal type of operation created this object.
184         In SMESH is used to find out if an object is GROUP (type == 37, for shape it is default=1)
185         """
186         self.type = theType
187
188     def GetTick( self ):
189         """
190         Get value of a modification counter of the object
191         """
192         if self.data:
193           return self.data.getTick()
194         return 0
195
196     def GetStudyEntry( self ):
197         """
198         Get a Study entry where this object was published.
199         """
200         if self.SO:
201             return self.SO.GetID()
202         return ""
203
204     def IsShape( self ):
205         """
206         Return true if geom object represents a shape.
207         For example, method return false for GEOM_MARKER
208         """
209         return True
210
211     def IsSame( self, other ):
212         """
213         Return true if passed object is identical to this object
214         """
215         return self.GetType() == other.GetType() and self.GetEntry() == other.GetEntry()
216
217     def GetGen( self ):
218         """
219         Return the engine creating this object
220         """
221         e = getEngine()
222         return e._duplicate( e )
223
224     def SetSO( self, theSO ):
225         """
226         Sets SObject of this object (when it is published)
227         """
228         if theSO:
229             theSO.Register() # I hold a GenericObject!
230         if self.SO:
231             self.SO.UnRegister()
232         self.SO = theSO
233
234     def GetSO( self ):
235         """
236         Returns SObject of this object
237         """
238         return self.SO
239
240     def IsParametrical(self):
241         """
242         Returns true if the current object has connection to a parametrical model
243         which can be modified by parameters change.
244         """
245         return not self.IsDead() and self.type == 1 # only break link for shapes are accessible now
246
247     def IsDead(self):
248         """
249         Returns true if the shape is dead - no parametrical link to the SHAPER exists
250         """
251         return self.GetEntry().startswith("dead")
252
253     def MakeDead(self):
254         """
255         Makes the dead-copy of the shape and returns it.
256         """
257         aStudy = getStudy()
258         aBuilder = aStudy.NewBuilder()
259         aRes, aHistSO = self.SO.FindSubObject(2)
260         if not aRes: # create a "history" folder if it does not exist
261           aHistSO = aBuilder.NewObjectToTag(self.SO, 2)
262           aHistSO.SetAttrString("AttributeName", "History")
263
264         aDeadSO = aBuilder.NewObject(aHistSO)
265         anIndex = aDeadSO.Tag()
266         aDeadSO.SetAttrString("AttributeName", self.SO.GetName() + " (" + str(anIndex) + ")")
267         aRes, aPixMap = aBuilder.FindAttribute(self.SO, "AttributePixMap")
268         if aRes:
269           aDeadPixMap = aBuilder.FindOrCreateAttribute(aDeadSO, "AttributePixMap")
270           aDeadPixMap.SetPixMap(aPixMap.GetPixMap())
271         aDead = SHAPERSTUDY_Object()
272         aDeadEntry = "dead" + str(anIndex) + "_" + self.GetEntry()
273         aDead.SetEntry(aDeadEntry)
274         aDead.SetShapeByStream(self.data.oldShapeStream())
275         aDeadObj = aDead._this()
276         anIOR = salome.orb.object_to_string(aDeadObj)
277         aDeadSO.SetAttrString("AttributeIOR", anIOR)
278         aDead.SetSO(aDeadSO)
279         if self.GetTick() > 2:
280           aDead.data.setTick(self.GetTick() - 1) # set the tick of an old shape
281         # make dead-copy also sub-groups
282         aSOIter = aStudy.NewChildIterator(self.SO)
283         while aSOIter.More():
284           aGroupSO = aSOIter.Value()
285           anIOR = aGroupSO.GetIOR()
286           if len(anIOR):
287             aGroup = salome.orb.string_to_object(anIOR)
288             if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group) or \
289                isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field):
290               if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group):
291                 aDeadGroup = SHAPERSTUDY_Group()
292               else:
293                 aDeadGroup = SHAPERSTUDY_Field()
294               aDeadGroupEntry = "dead" + str(anIndex) + "_" + aGroup.GetEntry()
295               aDeadGroup.SetEntry(aDeadGroupEntry)
296               aDeadGroup.SetSelectionType(aGroup.GetSelectionType())
297               aDeadGroup.SetSelection(aGroup.GetSelection())
298               if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field): # additional field data
299                 aDeadGroup.SetValuesType(aGroup.GetValuesType())
300                 aDeadGroup.SetSteps(aGroup.GetSteps())
301                 aDeadGroup.SetComponents(aGroup.GetComponents())
302                 for aStep in aGroup.GetSteps():
303                   aStepObj = aGroup.GetStep(aStep)
304                   aDeadGroup.AddFieldStep(aStepObj.GetStamp(), aStep, aStepObj.GetValues())
305               aDeadGroupSO = aBuilder.NewObject(aDeadSO)
306               aDeadGroup.SetSO(aDeadGroupSO)
307               # 15.01.20 groups and fields names stays the same
308               #aDeadGroupSO.SetAttrString("AttributeName", aGroupSO.GetName() + " (" + str(anIndex) + ")")
309               aDeadGroupSO.SetAttrString("AttributeName", aGroupSO.GetName())
310               aRes, aPixMap = aBuilder.FindAttribute(aGroupSO, "AttributePixMap")
311               if aRes:
312                 aDeadPixMap = aBuilder.FindOrCreateAttribute(aDeadGroupSO, "AttributePixMap")
313                 aDeadPixMap.SetPixMap(aPixMap.GetPixMap())
314               aDeadGroupObj = aDeadGroup._this()
315               anIOR = salome.orb.object_to_string(aDeadGroupObj)
316               aDeadGroupSO.SetAttrString("AttributeIOR", anIOR)
317           aSOIter.Next()
318
319         return aDeadObj
320     
321     def SetShapeByPointer(self, theShape):
322         """
323         Sets the shape by the pointer to the TopoDS_Shape
324         """
325         if not self.data:
326           self.data = StudyData_Swig.StudyData_Object()
327         self.data.SetShapeByPointer(theShape)
328
329     pass
330
331 class SHAPERSTUDY_Group(SHAPERSTUDY_ORB__POA.SHAPER_Group, SHAPERSTUDY_Object):
332     """
333     Constructs an instance of SHAPERSTUDY Group
334     """
335     def __init__ ( self, *args):
336         SHAPERSTUDY_GenericObject.__init__(self)
337         self.seltype = None
338         self.selection = []
339         self.SO = None
340         self.data = None
341         self.entry = ""
342         self.type = 37 # a group type
343         pass
344
345     def SetSelectionType(self, theType):
346         """
347         Sets what is returned in the GEOM_IGroupOperations::GetType
348         """
349         self.seltype = theType
350
351     def GetSelectionType(self):
352         """
353         Returns the type of the selected sub-shapes
354         """
355         return self.seltype
356
357     def SetSelection(self, theSelection):
358         """
359         Sets what is returned in the GEOM_IGroupOperations::GetObjects
360         """
361         self.data = None # nullify the cashed shape when selection is changed
362         self.selection = theSelection
363
364     def GetSelection(self):
365         """
366         Returns the selected sub-shapes indices
367         """
368         return self.selection
369
370     def GetMainShape( self ):
371         """
372         Main shape is groups owner
373         """
374         return self.SO.GetFather().GetObject()
375
376     def GetSubShapeIndices( self ):
377         """
378         Get a list of ID's of sub-shapes in the main shape.
379         """
380         return self.selection
381
382     def getShape( self ):
383         """
384         Redefinition of the getShape method: here it creates a shape by the
385         main shape and the group index.
386         """
387         if not self.data:
388           self.data = StudyData_Swig.StudyData_Object()
389         # convert selection to long list
390         anArg = StudyData_Swig.LongList()
391         for l in self.selection:
392           anArg.append(l)
393         return self.data.groupShape(self.GetMainShape().getShape(), anArg)
394
395     def GetShapeType( self ):
396         """
397         Group shape type is always compound.
398         """
399         return GEOM.COMPOUND;
400
401     pass
402
403 class SHAPERSTUDY_Field(SHAPERSTUDY_ORB__POA.SHAPER_Field, SHAPERSTUDY_Group):
404     """
405     Constructs an instance of SHAPERSTUDY Field (inherits selection from a Group object)
406     """
407     def __init__ ( self, *args):
408         SHAPERSTUDY_GenericObject.__init__(self)
409         self.seltype = None
410         self.selection = []
411         self.SO = None
412         self.data = None
413         self.entry = None
414         self.type = 52 # a field type
415         self.valtype = None # type of the values
416         self.steps = [] # list of long
417         self.components = [] # string array, names of the components
418         self.name = None # name, string
419         self.fieldsteps = {} # FieldSteps objects identified by step ID
420         pass
421
422     def SetValuesType( self, theType ):
423       """
424       Sets the type of values in the field
425       """
426       self.valtype = theType
427
428     def GetValuesType( self ):
429       """
430       Returns the type of values in the field
431       """
432       return self.valtype
433
434
435     def GetDataType( self ):
436       """
437       Returns the type of values in the field in terms of GEOM enumeration
438       """
439       if self.valtype == 0:
440         return GEOM.FDT_Bool
441       elif self.valtype == 1:
442         return GEOM.FDT_Int
443       elif self.valtype == 2:
444         return GEOM.FDT_Double
445       elif self.valtype == 3:
446         return GEOM.FDT_String
447       return None # unknown case
448
449     def GetShape ( self ):
450       """
451       Returns the shape the field lies on
452       """
453       return super().GetMainShape()
454
455     def SetSteps( self, theSteps ):
456       self.steps = theSteps
457
458     def GetSteps( self ):
459       return self.steps
460
461     def SetComponents( self, theComponents ):
462       self.components = theComponents
463     
464     def GetComponents( self ):
465       return self.components
466
467     def GetDimension( self ):
468       aShapeType = super().GetSelectionType()
469       if aShapeType == 8:
470         return -1 # whole part
471       elif aShapeType == 7:
472         return 0 # vertex
473       elif aShapeType == 6:
474         return 1 # edge
475       elif aShapeType == 4:
476         return 2 # face
477       elif aShapeType == 2:
478         return 3 # solid
479       return None # unknown case
480
481     def ClearFieldSteps( self ):
482        self.fieldsteps = {}
483
484     def AddFieldStep( self, theStampID, theStepID, theValues):
485       aFieldStep = None
486       if self.valtype == 0:
487         aFieldStep = SHAPER_BoolFieldStep()
488       elif self.valtype == 1:
489         aFieldStep = SHAPER_IntFieldStep()
490       elif self.valtype == 2:
491         aFieldStep = SHAPER_DoubleFieldStep()
492       
493       aFieldStep.SetStep(theStampID, theStepID, theValues)
494       self.fieldsteps[theStepID] = aFieldStep._this()
495
496     def GetStep( self, theStepID ):
497        return self.fieldsteps[theStepID]
498
499     pass
500
501 class SHAPER_FieldStep:
502     """
503     Base class for all step-classes
504     """
505     def __init__ ( self, *args):
506         self.stamp = None  # long, ID of stamp
507         self.step = None   # long, ID of step
508         self.values = None # array of values of the needed type
509
510     """
511     Defines all parameters of the step
512     """
513     def SetStep( self, theStamp, theStep, theValues ):
514         self.stamp = theStamp
515         self.step = theStep
516         self.values = theValues
517      
518     """
519     Returns stamp ID
520     """
521     def GetStamp( self ):
522         return self.stamp
523     """
524     Returns step ID
525     """
526     def GetID( self ):
527         return self.step
528     """
529     Returns a name of a sub-shape if the sub-shape is published in the study
530     """
531     def GetSubShape(self, theSubID):
532         # the SHAPER study does not support sub-shapes for now
533         return ""
534         
535
536 class SHAPER_DoubleFieldStep(SHAPERSTUDY_ORB__POA.SHAPER_DoubleFieldStep, SHAPER_FieldStep):
537     """
538     Constructs an instance of SHAPERSTUDY Field step of type Double
539     """
540     def __init__ ( self, *args):
541         pass
542
543     """
544     Returns values as an array of the needed type
545     """
546     def GetValues( self ):
547         aResult = [] # to make any type of result, create a corba-type
548         for i in self.values:
549           aResult.append(float(i))
550         return aResult
551
552     pass
553
554 class SHAPER_IntFieldStep(SHAPERSTUDY_ORB__POA.SHAPER_IntFieldStep, SHAPER_FieldStep):
555     """
556     Constructs an instance of SHAPERSTUDY Field step of type Double
557     """
558     def __init__ ( self, *args):
559         pass
560
561     """
562     Returns values as an array of the needed type
563     """
564     def GetValues( self ):
565         aResult = [] # to make any type of result, create a corba-type
566         for i in self.values:
567           aResult.append(int(i))
568         return aResult
569
570     pass
571
572 class SHAPER_BoolFieldStep(SHAPERSTUDY_ORB__POA.SHAPER_BoolFieldStep, SHAPER_FieldStep):
573     """
574     Constructs an instance of SHAPERSTUDY Field step of type Double
575     """
576     def __init__ ( self, *args):
577         pass
578
579     """
580     Returns values as an array of the needed type
581     """
582     def GetValues( self ):
583         aResult = [] # to make any type of result, create a corba-type
584         for i in self.values:
585           aResult.append(int(i))
586         return aResult
587
588     pass