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