1 # Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
26 import sys, math, copy, commands
27 CWD = commands.getoutput('pwd')
30 from MacObject import *
31 import Config, GenFunctions
33 def CompositeBox (X0 , Y0 , DX , DY , **args ) :
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)
41 # Save the existing number of segments on each direction
42 ExistingSegments = Config.ListObj[-1].DirectionalMeshParams
44 # Sort the connection list for the full Box
45 ObjIDLists = SortObjLists(Config.Connections[-1],X0 , Y0 , DX , DY )
48 print "ObjIDLists: ", ObjIDLists
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
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)
68 if flag and Config.Count < Config.Criterion:
70 if abs(CommonSide[0] - (Y0-DY/2.))<1e-7 : SouthGR = GroupNames[0]
72 if abs(CommonSide[1] - (Y0+DY/2.))<1e-7 : NorthGR = GroupNames[1]
74 CompositeBox (X0, CommonSide[0]+IntLen(CommonSide)/2., DX,IntLen(CommonSide), recursive=1, groups = [SouthGR,NorthGR]+GroupNames[2:4])
76 if abs(CommonSide[0] - (X0-DX/2.))<1e-7 : EastGR = GroupNames[2]
78 if abs(CommonSide[1] - (X0+DX/2.))<1e-7 : WestGR = GroupNames[3]
80 CompositeBox (CommonSide[0]+IntLen(CommonSide)/2., Y0, IntLen(CommonSide),DY, recursive=1, groups = GroupNames[0:2]+[EastGR,WestGR])
82 if Config.Count >= Config.Criterion :
84 if flag == 0 and Config.Count < Config.Criterion:
85 #print "Dir : ", Direction
86 #print "RealSegments : ", RealSegments
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)
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])]
100 def IntLen (Interval) :
101 return abs(Interval[1]-Interval[0])
103 def RemoveLastObj() :
104 Config.ListObj = Config.ListObj[:-1]
105 Config.Connections = Config.Connections[:-1]
107 def GetCriterion (ObjListIDs):
108 return max(Config.Criterion, max(len(ObjListIDs[0]),len(ObjListIDs[1]))*max(len(ObjListIDs[2]),len(ObjListIDs[3])))
110 def SortObjLists (List,X0,Y0,DX,DY) :
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
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,))
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
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]
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)
144 elif len(dummy) == 3 :
145 # We find the direction where we do have neighbours and then we sort the object list along it
147 Direction = [ i not in dummy for i in range(4) ].index(True)
148 ObjList = List[Direction]
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)
156 print ("Error : the composite box being created has no neighbours, how on earth do you want us to inherit its mesh parameters!!!")
161 def IndexMultiOcc (Array,Element) :
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!
168 try : Array.index(Element)
169 except ValueError : print "No more occurrences"
170 else : Output.append(Array.index(Element))
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)
178 def SortList (ValList, CritList):
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])