Salome HOME
aaaab43c631fe3001dfbc0d59cb897eb52e910a0
[modules/shaper.git] / src / ConnectorPlugin / ConnectorPlugin_ExportFeature.py
1 ## Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 ##
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, or (at your option) any later version.
7 ##
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.
12 ##
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
16 ##
17 ## See http:##www.salome-platform.org/ or
18 ## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 ##
20
21 ## @package Plugins
22 #  ExportFeature class definition
23
24 import EventsAPI
25 import ModelAPI
26 import GeomAPI
27 import GeomAlgoAPI
28
29 import salome
30 from salome.geom import geomBuilder
31
32 def getObjectIndex(theName):
33     aStudy = salome.myStudy
34     aId = 0
35     aObj = aStudy.FindObjectByName(theName, "GEOM")
36     while len(aObj) != 0:
37         aId = aId + 1
38         aName = theName + '_' + str(aId)
39         aObj = aStudy.FindObjectByName(aName, "GEOM")
40     return aId
41
42 ## @ingroup Plugins
43 #  Feature to export all shapes and groups into the GEOM module
44 class ExportFeature(ModelAPI.ModelAPI_Feature):
45
46     ## The constructor.
47     def __init__(self):
48         ModelAPI.ModelAPI_Feature.__init__(self)
49         ## Shape that will be exported (the compound if there are several exported bodies)
50         self.shape = None
51         ## BRep representation of the exported shape (a stream that will be sent to GEOM and converted to GEOM object)
52         self.brep = None
53
54     @staticmethod
55     ## Export kind. Static.
56     def ID():
57         return "ExportToGEOM"
58
59     ## Returns the kind of a feature.
60     def getKind(self):
61         return ExportFeature.ID()
62
63     ## This feature is action: has no property pannel and executes immideately.
64     def isAction(self):
65         return True
66
67     ## This feature has no attributes, as it is action.
68     def initAttributes(self):
69       pass
70
71     ## Exports all bodies
72     def exportBodies(self):
73         global ShapeIndex
74         kResultBodyType = "Bodies"
75         aPartSize = self.Part.size(kResultBodyType)
76         if aPartSize == 0:
77             EventsAPI.Events_InfoMessage("ExportFeature","No results in the active document").send()
78             return
79
80         anObjList = [self.Part.object(kResultBodyType, idx) for idx in xrange(aPartSize)]
81         aShapesList = GeomAlgoAPI.ShapeList()
82         aName = ""
83         for idx, anObject in enumerate(anObjList):
84             aResult = ModelAPI.modelAPI_Result(anObject)
85             aBodyResult = ModelAPI.modelAPI_ResultBody(aResult)
86             if not aBodyResult:
87                 continue
88             aShape = aBodyResult.shape()
89             if aShape is not None and not aShape.isNull():
90               aShapesList.append(aShape)
91               if len(aShapesList) == 1:
92                 aName = aBodyResult.data().name()
93
94         # issue 1045: create compound if there are more than one shape
95         if len(aShapesList) > 1:
96           self.shape = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.compound(aShapesList)
97           aName = "ShaperResults"
98         elif len(aShapesList) == 1:
99           self.shape = aShapesList[0]
100
101         # so, only one shape is always in the result
102         aDump = self.shape.getShapeStream()
103         # Load shape to SALOME Geom
104         aBrep = self.geompy.RestoreShape(aDump)
105
106         # Make unique name
107         aId = getObjectIndex(aName)
108         if aId != 0:
109             aName = aName + '_' + str(aId)
110
111         self.geompy.addToStudy(aBrep, aName)
112         self.brep = aBrep
113
114     ## Exports all groups
115     def exportGroups(self):
116         # iterate all features to find groups
117         aFeaturesNum = self.Part.size("Features")
118         groupIndex = 0
119         for anIndex in range(0, aFeaturesNum):
120             aFeature = self.Part.object("Features", anIndex)
121             aSelectionList = aFeature.data().selectionList("group_list")
122             # if a group has been found
123             if aSelectionList:
124                 aFeature = ModelAPI.objectToFeature(aFeature)
125                 if aFeature.firstResult() is not None:
126                   aName = aFeature.firstResult().data().name()
127                 groupIndex = groupIndex + 1
128                 self.createGroupFromList(aSelectionList, aName)
129
130     ## Returns a type of the shape in the old GEOM representation
131     def shapeType(self, shape):
132         if shape.isVertex():
133             return "VERTEX"
134         elif shape.isEdge():
135             return "EDGE"
136         elif shape.isFace():
137             return "FACE"
138
139         return "SOLID"
140
141     ## Creates a group by given list of selected objects and the name
142     #  @param theSelectionList: list of selected objects
143     #  @param theGroupName: name of the group to create
144     def createGroupFromList(self, theSelectionList, theGroupName):
145         # iterate on all selected entities of the group
146         # and get the corresponding ID
147         aSelectionNum = theSelectionList.size()
148         Ids = []
149         groupType = ""
150         for aSelIndex in range(0, aSelectionNum):
151             aSelection = theSelectionList.value(aSelIndex)
152             # issue 1326: bodies that are already concealed did not exported, so groups should not be invalid
153             aContext =  ModelAPI.modelAPI_Result(aSelection.context())
154             # chcking of concealment removed because of #1799, remark #13 "aContext.isConcealed()"
155             if aContext is None or aContext.isDisabled():
156                 continue
157
158             anID = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(self.shape, aSelection.value())
159             if anID == 0:
160                 #it may be a compound of objects if movement of the group to the end
161                 # splits the original element to several (issue 1146)
162                 anExp = GeomAPI.GeomAPI_ShapeExplorer(aSelection.value(), GeomAPI.GeomAPI_Shape.SHAPE)
163                 while anExp.more():
164                     anID = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(self.shape, anExp.current())
165                     if anID != 0:
166                         Ids.append(anID)
167                         groupType = self.shapeType(anExp.current())
168                     anExp.next()
169             else:
170                 Ids.append(anID)
171                 groupType = self.shapeType(aSelection.value())
172
173         if len(Ids) <> 0:
174           aGroup = self.geompy.CreateGroup(self.brep, self.geompy.ShapeType[groupType])
175           self.geompy.UnionIDs(aGroup,Ids)
176           self.geompy.addToStudyInFather(self.brep, aGroup, theGroupName)
177
178     ## Exports all fields
179     def exportFields(self):
180         # iterate all features to find fields
181         aFeaturesNum = self.Part.size("Features")
182         fieldIndex = 0
183         for anIndex in range(0, aFeaturesNum):
184             aFeature = self.Part.object("Features", anIndex)
185             aSelectionList = aFeature.data().selectionList("selected")
186             # if a field has been found
187             if aSelectionList:
188                 aFeature = ModelAPI.objectToFeature(aFeature)
189                 if aFeature.firstResult() is not None:
190                   aName = aFeature.firstResult().data().name()
191                 fieldIndex = fieldIndex + 1
192                 self.createFieldFromFeature(aFeature, aName)
193
194     ## Returns a type of the shape type in the old GEOM representation
195     def selectionDim(self, theSelectionType):
196         selType=theSelectionType.lower() # more or less independed approach
197         if selType== "vertex":
198             return 0
199         if selType== "edge":
200             return 1
201         if selType== "face":
202             return 2
203         if selType== "solid":
204             return 3
205         return -1
206
207     ## Returns a type of the shape type in the GeomAPI_Shape representation
208     def geomAPISelectionDim(self, theSelectionType):
209         selType=theSelectionType.lower() # more or less independed approach
210         if selType== "vertex":
211             return GeomAPI.GeomAPI_Shape.VERTEX
212         if selType== "edge":
213             return GeomAPI.GeomAPI_Shape.EDGE
214         if selType== "face":
215             return GeomAPI.GeomAPI_Shape.FACE
216         if selType== "solid":
217             return GeomAPI.GeomAPI_Shape.SOLID
218         return GeomAPI.GeomAPI_Shape.SHAPE
219
220     ## Creates a field by the field feature and the name
221     #  @param theField: the field feature
222     #  @param theFieldName: name of the field to create
223     def createFieldFromFeature(self, theField, theFieldName):
224         # iterate on all selected entities of the field
225         # and get the corresponding ID
226         aTables = theField.tables("values")
227         aSelection = theField.selectionList("selected")
228
229         # set component names
230         aComps = theField.stringArray("components_names")
231         aCompNames = []
232         aCompNum = aComps.size()
233         for aCompIndex in range(0, aCompNum):
234           aCompNames.append(aComps.value(aCompIndex))
235
236         #if len(Ids) <> 0:
237         aDim = self.selectionDim(aSelection.selectionType())
238         aResField = self.geompy.CreateField(self.brep, theFieldName, aTables.type(), aDim, aCompNames)
239         #self.geompy.UnionIDs(theField,Ids)
240         self.geompy.addToStudyInFather(self.brep, aResField, theFieldName)
241
242         # set default values to all not filled sub-shapes (fields in GEOM support only full set of subs)
243         Ids={}
244         anExp = GeomAPI.GeomAPI_ShapeExplorer(self.shape, self.geomAPISelectionDim(aSelection.selectionType()))
245         while anExp.more():
246           anID = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(self.shape, anExp.current())
247           if anID != 0:
248             Ids[anID]=anExp.current()
249           anExp.next()
250
251         SelectedIds={}
252         for aSelIndex in range(aSelection.size()):
253           selShape = aSelection.value(aSelIndex).value()
254           # searching for this shape in Ids
255           for a in Ids.items():
256             if (a[1].isSame(selShape)):
257               SelectedIds[a[0]] = aSelIndex
258
259         # values here are in the same order as in field
260         listOfValues = Ids.items()
261         listOfValues.sort()
262         # set steps
263         aStepsNum = aTables.tables()
264         for aStepIndex in range(0, aStepsNum):
265           aStamp = theField.intArray("stamps").value(aStepIndex)
266           aValues = []
267           for aValId in listOfValues:
268             aRow = 0 # default value if not from selection
269             if SelectedIds.has_key(aValId[0]): # take the value from the table
270               aRow = SelectedIds[aValId[0]] + 1 # plus one to avoid default string
271             aCols = aTables.columns()
272             for aCol in range(0, aCols):
273               aVal = aTables.valueStr(aRow, aCol, aStepIndex)
274               if aTables.type() == 0: # bool
275                 if aVal == "True":
276                   aVal = True
277                 else:
278                   aVal = False
279               elif aTables.type() == 1: # int
280                 aVal = int(aVal)
281               elif aTables.type() == 2: # double
282                 aVal = float(aVal)
283               aValues.append(aVal)
284           aStep = aResField.addStep(aStepIndex + 1, aStamp, aValues)
285           if aStep:
286             self.geompy.addToStudyInFather( aResField, aStep, aStep.GetName() )
287
288     ## Exports all shapes and groups into the GEOM module.
289     def execute(self):
290         aSession = ModelAPI.ModelAPI_Session.get()
291         ## Get active document
292         self.Part = aSession.activeDocument()
293         ## List of objects created in the old geom for later use
294         self.geomObjects = []
295         ## geomBuilder tool
296         salome.salome_init(0,1)
297         self.geompy = geomBuilder.New(salome.myStudy)
298
299         # Export bodies and groups
300         self.exportBodies()
301         self.exportGroups()
302         self.exportFields()
303         pass