Salome HOME
Merge remote branch 'origin/gdd/translations'
[modules/smesh.git] / src / Tools / MacMesh / MacMesh / CompositeBox.py
1 # Copyright (C) 2014-2015  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 email : webmaster.salome@opencascade.com
18 #
19
20
21 # INTRODUCTION HERE
22
23 import sys, math, copy, commands
24 CWD = commands.getoutput('pwd')
25 sys.path.append(CWD)
26
27 from MacObject import *
28 import Config, GenFunctions
29
30 def CompositeBox (X0 , Y0 , DX , DY , **args ) : 
31                                      
32         if args.__contains__('groups') :
33                 GroupNames = args['groups']
34         else : GroupNames = [None, None, None, None]
35         # Create a full Box just to inherit, globally, the mesh parameters of bounding objects
36         MacObject('CompBoxF',[(X0,Y0),(DX,DY)],['auto'],publish=0)
37         
38         # Save the existing number of segments on each direction
39         ExistingSegments = Config.ListObj[-1].DirectionalMeshParams
40         
41         # Sort the connection list for the full Box
42         ObjIDLists = SortObjLists(Config.Connections[-1],X0 , Y0 , DX , DY )
43         RemoveLastObj()
44         
45         print "ObjIDLists: ", ObjIDLists
46         
47         RealSegments = []
48         Direction = []
49         flag = 0
50         if not(args.__contains__('recursive')) : Config.Count = 0
51         print "Config.Count : ", Config.Count
52         Config.Criterion = GetCriterion(ObjIDLists)
53         for index, ObjList in enumerate(ObjIDLists) :
54                 if not (ObjList[0] == -1 or Config.Count >= Config.Criterion):
55                         if len(ObjList)>1 : flag = 1
56                         else : flag = 0
57                         for ObjID in ObjList:
58                            ToLook0 = [2,2,0,0][index]
59                            ToLook1 = [3,2,1,0][index]
60                            CommonSide =  FindCommonSide(Config.ListObj[ObjID].DirBoundaries(ToLook1),[X0-DX/2.,X0+DX/2.,Y0-DY/2.,Y0+DY/2.][ToLook0:ToLook0+2])
61                            ToLook2 = [1,0,3,2][index]
62                            RealSegments.append(Config.ListObj[ObjID].DirectionalMeshParams[ToLook2]*IntLen(CommonSide)/IntLen(Config.ListObj[ObjID].DirBoundaries(ToLook1)))
63                            Direction.append(ToLook0/2)
64                            
65                            if flag and Config.Count < Config.Criterion:
66                                 if index < 2 :
67                                         if abs(CommonSide[0] - (Y0-DY/2.))<1e-7 : SouthGR = GroupNames[0]
68                                         else : SouthGR = None
69                                         if abs(CommonSide[1] - (Y0+DY/2.))<1e-7 : NorthGR = GroupNames[1]
70                                         else : NorthGR = None
71                                         CompositeBox (X0, CommonSide[0]+IntLen(CommonSide)/2., DX,IntLen(CommonSide), recursive=1, groups = [SouthGR,NorthGR]+GroupNames[2:4])
72                                 else : 
73                                         if abs(CommonSide[0] - (X0-DX/2.))<1e-7 : EastGR = GroupNames[2]
74                                         else : EastGR = None
75                                         if abs(CommonSide[1] - (X0+DX/2.))<1e-7 : WestGR = GroupNames[3]
76                                         else : WestGR = None
77                                         CompositeBox (CommonSide[0]+IntLen(CommonSide)/2., Y0, IntLen(CommonSide),DY, recursive=1, groups = GroupNames[0:2]+[EastGR,WestGR])
78
79                            if Config.Count >= Config.Criterion :
80                                 break
81         if flag == 0 and Config.Count < Config.Criterion:
82                 #print "Dir : ", Direction
83                 #print "RealSegments : ", RealSegments
84                 
85                 #Xind = Direction.index(0)
86                 #Yind = Direction.index(1)
87                 #MacObject('CompBoxF',[(X0,Y0),(DX,DY)] ,[(RealSegments[Xind],RealSegments[Yind])], groups = GroupNames)
88                 MacObject('CompBoxF',[(X0,Y0),(DX,DY)] ,['auto'], groups = GroupNames)
89                 
90                 Config.Count += 1
91
92                            
93 def FindCommonSide (Int1, Int2) :
94         if abs(min(Int1[1],Int2[1])-max(Int1[0],Int2[0])) < 1e-5: return [0,0]
95         else : return [max(Int1[0],Int2[0]), min(Int1[1],Int2[1])]
96         
97 def IntLen (Interval) :
98         return abs(Interval[1]-Interval[0])     
99            
100 def RemoveLastObj() : 
101         Config.ListObj = Config.ListObj[:-1]
102         Config.Connections = Config.Connections[:-1]
103         
104 def GetCriterion (ObjListIDs):
105         return max(Config.Criterion, max(len(ObjListIDs[0]),len(ObjListIDs[1]))*max(len(ObjListIDs[2]),len(ObjListIDs[3])))
106
107 def SortObjLists (List,X0,Y0,DX,DY) :
108         """ 
109         This function sorts the list of neighbouring objects on each side, according to their intersection
110         with the object being created. From South to North and from East to West
111         """
112         Output = List
113         # First find the directions where no neighbour exists
114         # Important : Here we assume that exactly two directions have no neighbours !!!
115         #             Should we change this to allow a more general case ????
116         dummy = IndexMultiOcc(List,(-1,))
117         
118         # dummy[0] is either 0, meaning there is no neighbour on X- (West)
119         #                 or 1, meaning there is no neighbour on X+ (East)
120         # Similarly dummy[1] can be either 2 or 3 (South and North respectively)
121         # In order to get back to the formalism of groups (SNWE) 
122         #  => we do the following to define Sense of no neighbours and then the Direction list
123         #       is calculated as to include uniquely the directions where we DO have neighbours
124         if len(dummy) == 1 :
125                 # This adds a second direction where neighbours are not regarded, it is either 0 or 2
126                 dummy.append(2*(dummy[0]+2<4))
127                 print("Careful, you have neighbours on 3 or more sides of the box, we will not check if on two parallel sides the boxes are compatible !!!")
128         if len(dummy) == 2 or len(dummy) == 1 :
129                 # Sense contains : Vertical then Horizontal
130                 Sense = [dummy[1]%2,dummy[0]]
131                 DirList = [[1,0][dummy[0]],[3,2][dummy[1]%2]]
132                 for index,Direction in enumerate(DirList) :
133                         ObjList = List[Direction]
134                         RankMin = []
135                         ToLook0 = [2,2,0,0][Direction]
136                         ToLook1 = [3,2,1,0][Direction]
137                         for index1,ObjID in enumerate(ObjList) : 
138                                 RankMin.append([-1.,1.][Sense[index]] * FindCommonSide(Config.ListObj[ObjID].DirBoundaries(ToLook1),[X0-DX/2.,X0+DX/2.,Y0-DY/2.,Y0+DY/2.][ToLook0:ToLook0+2])[Sense[index]])
139                         Output[Direction] = SortList(ObjList,RankMin)
140                         
141         elif len(dummy) == 3 :
142                 # We find the direction where we do have neighbours and then we sort the object list along it
143                 Sense = dummy[0]%2
144                 Direction = [ i not in dummy for i in range(4) ].index(True)
145                 ObjList = List[Direction]
146                 RankMin = []
147                 ToLook0 = [2,2,0,0][Direction]
148                 ToLook1 = [3,2,1,0][Direction]
149                 for index1,ObjID in enumerate(ObjList) : 
150                         RankMin.append([-1.,1.][Sense] * FindCommonSide(Config.ListObj[ObjID].DirBoundaries(ToLook1),[X0-DX/2.,X0+DX/2.,Y0-DY/2.,Y0+DY/2.][ToLook0:ToLook0+2])[Sense])
151                 Output[Direction] = SortList(ObjList,RankMin)
152         else :
153                 print ("Error : the composite box being created has no neighbours, how on earth do you want us to inherit its mesh parameters!!!")
154                 
155         
156         return Output
157         
158 def IndexMultiOcc (Array,Element) :
159         """
160         This functions returns the occurrences indices of Element in Array.
161         As opposed to Array.index(Element) method, this allows determining      
162         multiple entries rather than just the first one!
163         """
164         Output = []
165         try : Array.index(Element)
166         except ValueError : print "No more occurrences"
167         else : Output.append(Array.index(Element))
168                 
169         if not(Output == []) and len(Array) > 1 :
170                 for index, ArrElem in enumerate(Array[Output[0]+1:]) :
171                         if ArrElem == Element : Output.append(index+Output[0]+1)
172                  
173         return Output
174         
175 def SortList (ValList, CritList):
176         Output = []
177         SortedCritList = copy.copy(CritList)
178         SortedCritList.sort()
179         for i in range(0,len(ValList)):
180                 index = CritList.index(SortedCritList[i])
181                 Output.append(ValList[index])
182         return Output
183
184
185