| |
136 |
# geometric functions for positioning role names
|
| |
137 |
|
| |
138 |
def NearestPointOnLine(pointA, pointB, pointC):
|
| |
139 |
""" Find the nearest point on the line from A to B """
|
| |
140 |
x0, y0 = pointA
|
| |
141 |
x1, y1 = pointB
|
| |
142 |
x2, y2 = pointC
|
| |
143 |
if x0 == x1:
|
| |
144 |
return x0, y2
|
| |
145 |
dx, dy = x1 - x0, y1 - y0
|
| |
146 |
x = ( ((dx * dx) * x2 + (dx * dy) * (y2 - y0) + (dy * dy) * x0) /
|
| |
147 |
(dx * dx + dy * dy) )
|
| |
148 |
y = (dy / dx) * (x - x0) + y0
|
| |
149 |
return x, y
|
| |
150 |
|
| |
151 |
def dist(pointA, pointB):
|
| |
152 |
x0, y0 = pointA
|
| |
153 |
x1, y1 = pointB
|
| |
154 |
dx, dy = x1 - x0, y1 - y0
|
| |
155 |
return math.sqrt(dx * dx + dy * dy)
|
| |
156 |
|
| |
157 |
def SetLineFollowerMetrics(line, follower):
|
| |
158 |
""" Impossible to explain without drawing a diagram. """
|
| |
159 |
pointA, pointB = line.GetEnds()
|
| |
160 |
pointC = follower.GetPos()
|
| |
161 |
junction = NearestPointOnLine(pointA, pointB, pointC)
|
| |
162 |
parallel = dist(pointA, junction) / dist(pointA, pointB)
|
| |
163 |
orthagonal = dist(junction, pointC)
|
| |
164 |
if ((pointB[1] > 0 and pointC[0] < junction[0]) or
|
| |
165 |
(pointB[1] == 0 and pointC[1] < junction[1]) or
|
| |
166 |
(pointB[1] < 0 and pointC[0] > junction[0])):
|
| |
167 |
orthagonal = -orthagonal
|
| |
168 |
# if follower is clockwise from the line, make orthagonal negative
|
| |
169 |
follower._SetInShell('parallel', parallel)
|
| |
170 |
follower._SetInShell('orthagonal', orthagonal)
|
| |
171 |
|
| |
172 |
|
| |
2071 |
def GetEnds(self):
|
| |
2072 |
x, y = self.GetPos()
|
| |
2073 |
nodea = self.Get('NodeA')
|
| |
2074 |
nodeb = self.Get('NodeB')
|
| |
2075 |
endb = nodeb.GetPos()
|
| |
2076 |
enda = nodea.AdjustEnd(endb)
|
| |
2077 |
endb = nodeb.AdjustEnd(enda)
|
| |
2078 |
return enda, endb
|
| |
2079 |
|
| |
2080 |
def AddFollower(self, follower_shape):
|
| |
2081 |
if not follower_shape in self.followers:
|
| |
2082 |
self.followers.append(follower_shape)
|
| |
2083 |
SetLineFollowerMetrics(self, follower_shape)
|
| |
2084 |
|
| |
3006 |
def GetEnds(self):
|
| |
3007 |
orm_object = self.Get('Target')
|
| |
3008 |
x, y = self.GetPos()
|
| |
3009 |
nodea = self.Get('NodeA')
|
| |
3010 |
nodeb = self.Get('NodeB')
|
| |
3011 |
|
| |
3012 |
# connect base on reading sequence, not fact sequence
|
| |
3013 |
seq = [ x.Seq for x in nodea.Target.ORMFactReading.ORMRoleSequence.GetList('ORMRolePosition')
|
| |
3014 |
if x.ORMRole.ID == orm_object.ID ][0]
|
| |
3015 |
endb = nodeb.GetPos()
|
| |
3016 |
enda = nodea.AdjustEnd(endb, seq) # nodeA should be a fact shape
|
| |
3017 |
endb = nodeb.AdjustEnd(enda)
|
| |
3018 |
return enda, endb
|
| |
3019 |
|
| |
3189 |
def GetEnds(self):
|
| |
3190 |
x, y = self.GetPos()
|
| |
3191 |
nodea = self.Get('NodeA')
|
| |
3192 |
nodeb = self.Get('NodeB')
|
| |
3193 |
|
| |
3194 |
constraintlist = self.Get('Target')
|
| |
3195 |
cr_list = constraintlist.GetList('ORMRolePosition')
|
| |
3196 |
fact_roles = [cr.ORMRole for cr in cr_list if cr.ORMRole.ORMFactTypeID == nodea.Target.ID]
|
| |
3197 |
|
| |
3198 |
seq_xref = dict([ (x.ORMRoleID, x.Seq) for x in nodea.Target.ORMFactReading.ORMRoleSequence.GetList('ORMRolePosition') ])
|
| |
3199 |
seq_numbers = [seq_xref[role.ID] for role in fact_roles]
|
| |
3200 |
if not seq_numbers: return
|
| |
3201 |
|
| |
3202 |
min_seq = min(seq_numbers)
|
| |
3203 |
max_seq = max(seq_numbers)
|
| |
3204 |
seq = (min_seq + max_seq) / 2.0
|
| |
3205 |
|
| |
3206 |
endb = nodeb.GetPos()
|
| |
3207 |
enda = nodea.AdjustEnd(endb, seq) # nodeA should be a fact shape
|
| |
3208 |
endb = nodeb.AdjustEnd(enda)
|
| |
3209 |
return enda, endb
|
| |
3210 |
|
| 4833 |
|
if nodea.GetSelected(): # need a better solution
|
| 4834 |
|
if shape.GetSelected() and follow: return # we're both selected (extra move)
|
| 4835 |
|
self.pdc.TranslateId(dcid, dx, dy) # move will be repeated twice?
|
| 4836 |
|
x,y = shape.GetPos()
|
| 4837 |
|
shape.SetTempPos(x+dx, y+dy)
|
| 4838 |
|
else: # we are not following
|
| 4839 |
|
self.pdc.TranslateId(dcid, dx, dy)
|
| 4840 |
|
x,y = shape.GetPos()
|
| 4841 |
|
shape.SetTempPos(x+dx, y+dy)
|
| |
4917 |
if nodea.GetSelected() and shape.GetSelected() and follow:
|
| |
4918 |
return # we're both selected; prevent double move
|
| |
4919 |
self.pdc.TranslateId(dcid, dx, dy)
|
| |
4920 |
x,y = shape.GetPos()
|
| |
4921 |
shape.SetTempPos(x+dx, y+dy)
|
| |
4922 |
if nodea.NodeAID and nodea.NodeBID and not follow:
|
| |
4923 |
SetLineFollowerMetrics(nodea, shape)
|
| 4855 |
|
for follower_shape in shape.GetFollowers():
|
| 4856 |
|
self.MoveID(follower_shape.dcid, dx, dy, 1)
|
| |
4937 |
if shape.NodeAID and shape.NodeBID:
|
| |
4938 |
self.MoveLineFollowers(shape)
|
| |
4939 |
else:
|
| |
4940 |
for follower in shape.GetFollowers():
|
| |
4941 |
self.MoveID(follower.dcid, dx, dy, 1)
|
| |
4942 |
|
| |
4943 |
def MoveLineFollowers(self, line):
|
| |
4944 |
pointA, pointB = line.GetEnds()
|
| |
4945 |
length = dist(pointA, pointB) or 1
|
| |
4946 |
x0, y0 = pointA
|
| |
4947 |
x1, y1 = pointB
|
| |
4948 |
width, height = x1 - x0, y1 - y0
|
| |
4949 |
for f in line.GetFollowers():
|
| |
4950 |
x2 = x0 + width * f.parallel - height * f.orthagonal / length
|
| |
4951 |
y2 = y0 + height * f.parallel + width * f.orthagonal / length
|
| |
4952 |
|
| |
4953 |
# # draw the lines used to position the follower
|
| |
4954 |
# junctionX = x0 + width * f.parallel
|
| |
4955 |
# junctionY = y0 + height * f.parallel
|
| |
4956 |
# self.pdc.SetPen(self.CachedPen(1, 1, wx.DOT))
|
| |
4957 |
# self.pdc.DrawLine(x0, y0, junctionX, junctionY)
|
| |
4958 |
# self.pdc.DrawLine(junctionX, junctionY, x2, y2)
|
| |
4959 |
|
| |
4960 |
# x, y = f.GetPos()
|
| |
4961 |
# dx, dy = x2 - x, y2 - y
|
| |
4962 |
# self.MoveID(f.dcid, dx, dy, 1) # drifting for some reason
|
| |
4963 |
f.SetTempPos(x2, y2)
|
| |
4964 |
self.RedrawID(f.dcid)
|