Salome HOME
Merge branch 'V8_3_BR' into ngr/python3_dev
[modules/smesh.git] / src / Tools / MacMesh / MacMesh / CompositeBox.py
1 # Copyright (C) 2014-2016  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, subprocess
24 CWD = subprocess.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 = sorted(copy.copy(CritList))
178     for i in range(0,len(ValList)):
179         index = CritList.index(SortedCritList[i])
180         Output.append(ValList[index])
181     return Output