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