batoolset-gui 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- batoolset/GUI/__init__.py +0 -0
- batoolset/GUI/customdialog.py +136 -0
- batoolset/GUI/exception_handler.py +74 -0
- batoolset/GUI/list_gui.py +514 -0
- batoolset/GUI/multi_image_display.py +1038 -0
- batoolset/GUI/open.py +325 -0
- batoolset/GUI/overlay_hints.py +45 -0
- batoolset/GUI/paint2.py +1369 -0
- batoolset/GUI/scrollablepaint.py +1165 -0
- batoolset/dialogs/__init__.py +0 -0
- batoolset/dialogs/opensave.py +228 -0
- batoolset/drawings/__init__.py +0 -0
- batoolset/drawings/math_text.py +294 -0
- batoolset/drawings/pdf_svg_renderer.py +376 -0
- batoolset/drawings/shapes/Position.py +183 -0
- batoolset/drawings/shapes/__init__.py +0 -0
- batoolset/drawings/shapes/automated_alignment_drawing_refactored.py +346 -0
- batoolset/drawings/shapes/circle2d.py +99 -0
- batoolset/drawings/shapes/compute_optimal_size_all_merged.py +328 -0
- batoolset/drawings/shapes/ellipse2d.py +336 -0
- batoolset/drawings/shapes/freehand2d.py +235 -0
- batoolset/drawings/shapes/group.py +1985 -0
- batoolset/drawings/shapes/image2d.py +3157 -0
- batoolset/drawings/shapes/line2d.py +579 -0
- batoolset/drawings/shapes/point2d.py +257 -0
- batoolset/drawings/shapes/polygon2d.py +357 -0
- batoolset/drawings/shapes/polyline2d.py +235 -0
- batoolset/drawings/shapes/rect2d.py +388 -0
- batoolset/drawings/shapes/rectangle2d.py +601 -0
- batoolset/drawings/shapes/scalebar.py +310 -0
- batoolset/drawings/shapes/serializablefont.py +133 -0
- batoolset/drawings/shapes/serializableguiparams.py +14 -0
- batoolset/drawings/shapes/square2d.py +102 -0
- batoolset/drawings/shapes/test_publication_style.py +220 -0
- batoolset/drawings/shapes/textorientation.py +45 -0
- batoolset/drawings/shapes/tools.py +467 -0
- batoolset/drawings/shapes/transform2D.py +350 -0
- batoolset/drawings/shapes/txt2d.py +615 -0
- batoolset/drawings/svg_clip_renderer.py +247 -0
- batoolset/drawings/svg_embed.py +165 -0
- batoolset/drawings/svg_text_renderer.py +183 -0
- batoolset/drawings/widgets/__init__.py +0 -0
- batoolset/drawings/widgets/col.py +343 -0
- batoolset/drawings/widgets/image_group.py +248 -0
- batoolset/drawings/widgets/image_organizer.py +96 -0
- batoolset/drawings/widgets/paint.py +184 -0
- batoolset/drawings/widgets/vectorial.py +256 -0
- batoolset/figure/__init__.py +0 -0
- batoolset/figure/alignment.py +822 -0
- batoolset/figure/column.py +1117 -0
- batoolset/figure/fig_tools.py +285 -0
- batoolset/figure/minimal_debugger_scale_etc.py +139 -0
- batoolset/figure/panel.py +697 -0
- batoolset/figure/row.py +852 -0
- batoolset/figure/user_selection.py +287 -0
- batoolset/icons/__init__.py +0 -0
- batoolset/icons/tools.py +248 -0
- batoolset/luts/__init__.py +0 -0
- batoolset/luts/lut_minimal_test.py +1308 -0
- batoolset/luts/lutcreatorfromformula.py +209 -0
- batoolset/luts/luteditor.py +243 -0
- batoolset/pyqts/__init__.py +0 -0
- batoolset/pyqts/pleasewaitdialog.py +14 -0
- batoolset/pyqts/tools.py +760 -0
- batoolset/serializations/__init__.py +0 -0
- batoolset/serializations/tools.py +1338 -0
- batoolset/theme.py +647 -0
- batoolset/uis/__init__.py +0 -0
- batoolset/uis/blinker.py +56 -0
- batoolset_gui-0.2.0.dist-info/METADATA +54 -0
- batoolset_gui-0.2.0.dist-info/RECORD +74 -0
- batoolset_gui-0.2.0.dist-info/WHEEL +5 -0
- batoolset_gui-0.2.0.dist-info/licenses/LICENSE +24 -0
- batoolset_gui-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1117 @@
|
|
|
1
|
+
# TODO --> handle inner selection on double click or synchronize to tab name --> if image --> go there, if row --> only allow rows, pb is that rows can also contain other rows --> makes it complex... --> maybe that will not work
|
|
2
|
+
|
|
3
|
+
# TODO --> do all
|
|
4
|
+
# in fact + adds an image / adds a new row or a new col in fact --> good idea
|
|
5
|
+
# should I have two figs --> one horiz and one vertical does that make sense and is that useful ??? think about it
|
|
6
|
+
# https://docs.python.org/2/library/operator.html
|
|
7
|
+
# TODO try remove row if possible to only handle panels
|
|
8
|
+
# in a way a figure can be a panel of panels --> if so the I would just have one element --> in fact that would really simplify things like crazy
|
|
9
|
+
# pas mal mais du coup faudrait pas packer par defaut ou bien si sauf si l'utilisateur veut pas
|
|
10
|
+
# peut être plus flexible --> supress fig and row just keep panel and make it more flexible
|
|
11
|
+
# faire un stacker(horizontal or vertical)
|
|
12
|
+
# that may work in a way
|
|
13
|
+
# seule difference est que le panel ne doit contenir que des images de même taille alors que la row non mais en gros la row est un panel de panel
|
|
14
|
+
# puis je appliquer la regle des rows aux panels
|
|
15
|
+
# --> j'ai besoin d'une orientation des le depart
|
|
16
|
+
# est ce que ça peut marcher --> peut etre
|
|
17
|
+
# should I put a warning if they don't have the same size initially --> ? think about it
|
|
18
|
+
# should I have linear panel and 2D panel and give them different rules panel1D panel2D #dans panel2D ttes les images doivent avoir la meme taille. Panel1D --> c'est un peu une row en fait
|
|
19
|
+
|
|
20
|
+
# single row size is ok --> the bug only occurs when several rows are combined --> do a rapid demo sample
|
|
21
|
+
import os
|
|
22
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
23
|
+
set_UI()# panel1D --> orientation --> hor/ver
|
|
24
|
+
# panel2D --> more stuff and same size required
|
|
25
|
+
import random
|
|
26
|
+
|
|
27
|
+
from batoolset.drawings.shapes.image2d import Image2D
|
|
28
|
+
from batoolset.drawings.shapes.point2d import Point2D
|
|
29
|
+
from batoolset.drawings.shapes.rect2d import Rect2D
|
|
30
|
+
from qtpy.QtCore import QPointF, QRectF
|
|
31
|
+
# from sympy import nsolve, exp, Symbol
|
|
32
|
+
# logger
|
|
33
|
+
# from batoolset.figure import fig_tools
|
|
34
|
+
from batoolset.figure.alignment import alignLeft, setToWidth2, updateBoudingRect, packY, packX, _brute_force_find_height, \
|
|
35
|
+
_brute_force_find_width
|
|
36
|
+
from batoolset.figure.fig_tools import get_master_bounds2, get_common_scaling_factor
|
|
37
|
+
from batoolset.tools.logger import TA_logger
|
|
38
|
+
|
|
39
|
+
logger = TA_logger()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# keep this in mind: https://stackoverflow.com/questions/34827132/changing-the-order-of-operation-for-add-mul-etc-methods-in-a-custom-c
|
|
43
|
+
|
|
44
|
+
# do rows and columns and no need to take images --> they just pack horiz or vertically and that's it each image or stuff handles itslef
|
|
45
|
+
# a row like that cannot be appended another row or can it --> yes in fact just add to it
|
|
46
|
+
|
|
47
|
+
# shall i make it a qrectf ???? or not or shall I really keep it as that
|
|
48
|
+
# shall I really use p1 or the x coord of the rect --> maybe simpler to use qrectf in fact
|
|
49
|
+
# TODO check everything and clean things up
|
|
50
|
+
# think about the expected behaviour and handle that
|
|
51
|
+
# for scale --> be careful and always be sure to keep original
|
|
52
|
+
|
|
53
|
+
# scale --> see how to handle self scale --> shall it handle it or not
|
|
54
|
+
class Column(Rect2D):
|
|
55
|
+
|
|
56
|
+
def __init__(self, *args, space=3, height=None):
|
|
57
|
+
self.images = []
|
|
58
|
+
# if args:
|
|
59
|
+
for img in args:
|
|
60
|
+
# if isinstance(img, Column):
|
|
61
|
+
# self.images += img.images
|
|
62
|
+
# else:
|
|
63
|
+
if img.isSet:
|
|
64
|
+
self.images.append(img)
|
|
65
|
+
# init super empty
|
|
66
|
+
super(Rect2D, self).__init__()
|
|
67
|
+
# self.isSet = True # required to allow dragging
|
|
68
|
+
self.space = space
|
|
69
|
+
self.sameWidth(space=space)
|
|
70
|
+
self.heightInPixel = height
|
|
71
|
+
self.setToHeight(height)
|
|
72
|
+
self.updateBoudingRect()
|
|
73
|
+
|
|
74
|
+
def __ior__(self, other):
|
|
75
|
+
return self.__or__(other=other)
|
|
76
|
+
|
|
77
|
+
def __or__(self, other):
|
|
78
|
+
return self.__floordiv__(other=other)
|
|
79
|
+
|
|
80
|
+
def __mod__(self, other):
|
|
81
|
+
if isinstance(other, Column):
|
|
82
|
+
pos = self.get_P1()
|
|
83
|
+
other_pos = other.get_P1()
|
|
84
|
+
self.set_P1(other_pos)
|
|
85
|
+
other.set_P1(pos)
|
|
86
|
+
else:
|
|
87
|
+
logger.error('swapping not implemented yet for ' + str(type(other)))
|
|
88
|
+
|
|
89
|
+
# the add should be append to last row or create last element as a row and append to it
|
|
90
|
+
|
|
91
|
+
# def __add__(self, other):
|
|
92
|
+
def __truediv__(self, other):
|
|
93
|
+
# from batoolset.figure.panel import Panel
|
|
94
|
+
|
|
95
|
+
if isinstance(other, Column):
|
|
96
|
+
P1 = self.get_P1()
|
|
97
|
+
final_height = self.height()
|
|
98
|
+
# print(self.images)
|
|
99
|
+
# print(len(self.images))
|
|
100
|
+
# print(other.images)
|
|
101
|
+
# print(len(other.images))
|
|
102
|
+
self.images = self.images + other.images
|
|
103
|
+
# self.sameWidth(space=self.space)
|
|
104
|
+
self.setToHeight(final_height)
|
|
105
|
+
self.set_P1(P1)
|
|
106
|
+
# elif isinstance(other, Image2D):
|
|
107
|
+
else:
|
|
108
|
+
P1 = self.get_P1()
|
|
109
|
+
final_height = self.height()
|
|
110
|
+
self.images.append(other)
|
|
111
|
+
# self.sameWidth(space=self.space)
|
|
112
|
+
self.setToHeight(final_height)
|
|
113
|
+
self.set_P1(P1)
|
|
114
|
+
|
|
115
|
+
# elif isinstance(other, Panel):
|
|
116
|
+
# self.images.append(other)
|
|
117
|
+
# self.sameHeight(space=self.space)
|
|
118
|
+
# self.setToWidth(self.widthInPixel)
|
|
119
|
+
return self
|
|
120
|
+
|
|
121
|
+
# def __truediv__(self, other):
|
|
122
|
+
def __floordiv__(self, other):
|
|
123
|
+
from batoolset.figure.row import Row
|
|
124
|
+
P1 = self.get_P1()
|
|
125
|
+
# pas mal mais faudrait remettre à la taille souihaitée
|
|
126
|
+
# final_width = self.width()
|
|
127
|
+
row = Row(self, other, space=self.space)
|
|
128
|
+
row.sameHeight(self.space)
|
|
129
|
+
|
|
130
|
+
# print('in there')
|
|
131
|
+
|
|
132
|
+
# row.setToWidth(final_width)
|
|
133
|
+
row.set_P1(P1)
|
|
134
|
+
return row
|
|
135
|
+
|
|
136
|
+
# same here make it smarter
|
|
137
|
+
def __sub__(self, other):
|
|
138
|
+
if other in self.images:
|
|
139
|
+
self.images.remove(other)
|
|
140
|
+
self.setToHeight(self.heightInPixel)
|
|
141
|
+
return self
|
|
142
|
+
|
|
143
|
+
def is_empty(self):
|
|
144
|
+
if self.images is None or not self.images:
|
|
145
|
+
return True
|
|
146
|
+
return False
|
|
147
|
+
|
|
148
|
+
# # hack to make column hashable to be able to add it to a dict, see https://stackoverflow.com/questions/10994229/how-to-make-an-object-properly-hashable
|
|
149
|
+
# def __eq__(self, other):
|
|
150
|
+
# try:
|
|
151
|
+
# return hash(str(self)) == other.__hash__()
|
|
152
|
+
# except:
|
|
153
|
+
# return False
|
|
154
|
+
#
|
|
155
|
+
# # hack to make column hashable to be able to add it to a dict, see https://stackoverflow.com/questions/10994229/how-to-make-an-object-properly-hashable
|
|
156
|
+
# def __hash__(self):
|
|
157
|
+
# return hash(str(self))
|
|
158
|
+
|
|
159
|
+
def __len__(self):
|
|
160
|
+
if self.images is None:
|
|
161
|
+
return 0
|
|
162
|
+
return len(self.images)
|
|
163
|
+
|
|
164
|
+
# def setWidthInPixel(self, heightInPixel):
|
|
165
|
+
# self.heightInPixel = heightInPixel
|
|
166
|
+
# self.packY()
|
|
167
|
+
|
|
168
|
+
def packX(self, space=3):
|
|
169
|
+
last_x = 0
|
|
170
|
+
last_y = 0
|
|
171
|
+
|
|
172
|
+
for i in range(len(self.images)):
|
|
173
|
+
img = self.images[i]
|
|
174
|
+
if i != 0:
|
|
175
|
+
last_x += space
|
|
176
|
+
img.set_P1(last_x, img.get_P1().y())
|
|
177
|
+
last_x = img.boundingRect().x() + img.boundingRect().width()
|
|
178
|
+
|
|
179
|
+
self.updateBoudingRect()
|
|
180
|
+
|
|
181
|
+
def packY(self, space=3):
|
|
182
|
+
last_x = 0
|
|
183
|
+
last_y = 0
|
|
184
|
+
|
|
185
|
+
for i in range(len(self.images)):
|
|
186
|
+
img = self.images[i]
|
|
187
|
+
if i != 0:
|
|
188
|
+
last_y += space
|
|
189
|
+
img.set_P1(img.get_P1().x(), last_y)
|
|
190
|
+
# get all the bounding boxes and pack them with desired space in between
|
|
191
|
+
# get first point and last point in x
|
|
192
|
+
x = img.boundingRect().x()
|
|
193
|
+
y = img.boundingRect().y()
|
|
194
|
+
last_x = img.boundingRect().x() + img.boundingRect().width()
|
|
195
|
+
last_y = img.boundingRect().y() + img.boundingRect().height()
|
|
196
|
+
self.updateBoudingRect()
|
|
197
|
+
|
|
198
|
+
# I think there is a bug here --> see how to handle that in fact
|
|
199
|
+
# TODO should I use qrectf or rect2D and how are the two in sync
|
|
200
|
+
def updateBoudingRect(self):
|
|
201
|
+
'''updates the image bounding rect depending on content'''
|
|
202
|
+
x = None
|
|
203
|
+
y = None
|
|
204
|
+
x2 = None
|
|
205
|
+
y2 = None
|
|
206
|
+
|
|
207
|
+
# why are they not up o date ??? is that because components are not up to date
|
|
208
|
+
# or is that because the rect is not ok ??? --> shall I use rect2D or rectf --> + do the code once for good
|
|
209
|
+
# shall I update it ???? or not
|
|
210
|
+
# why P1
|
|
211
|
+
|
|
212
|
+
# if not self:
|
|
213
|
+
# return
|
|
214
|
+
for img in self:
|
|
215
|
+
|
|
216
|
+
# topLeft = img.get_P1()
|
|
217
|
+
topLeft = img.boundingRect().topLeft()
|
|
218
|
+
if x is None:
|
|
219
|
+
x = topLeft.x()
|
|
220
|
+
if y is None:
|
|
221
|
+
y = topLeft.y()
|
|
222
|
+
x = min(topLeft.x(), x)
|
|
223
|
+
y = min(topLeft.y(), y)
|
|
224
|
+
|
|
225
|
+
# print(img, img.boundingRect(), type(img))
|
|
226
|
+
# print(img, img.boundingRect(), type(img), img.boundingRect().height())
|
|
227
|
+
|
|
228
|
+
if x2 is None:
|
|
229
|
+
x2 = topLeft.x() + img.boundingRect().width()
|
|
230
|
+
if y2 is None:
|
|
231
|
+
y2 = topLeft.y() + img.boundingRect().height()
|
|
232
|
+
x2 = max(topLeft.x() + img.boundingRect().width(), x2)
|
|
233
|
+
y2 = max(topLeft.y() + img.boundingRect().height(), y2)
|
|
234
|
+
|
|
235
|
+
# print(x,y,x2-x, y2-y)
|
|
236
|
+
self.setX(x)
|
|
237
|
+
self.setY(y)
|
|
238
|
+
self.setWidth(x2 - x)
|
|
239
|
+
self.setHeight(y2 - y)
|
|
240
|
+
|
|
241
|
+
# print('bounds from inside', self)
|
|
242
|
+
#
|
|
243
|
+
# bounds = get_master_bounds2(self.images)
|
|
244
|
+
# self.setX(bounds.x())
|
|
245
|
+
# self.setY(bounds.y())
|
|
246
|
+
# self.setWidth(bounds.width())
|
|
247
|
+
# self.setHeight(bounds.height())
|
|
248
|
+
# return bounds
|
|
249
|
+
|
|
250
|
+
# def boundingRect(self):
|
|
251
|
+
# return self.updateBoudingRect()
|
|
252
|
+
# # return get_master_bounds2(self.images)
|
|
253
|
+
|
|
254
|
+
def setOrigin(self, *args):
|
|
255
|
+
self.set_P1(*args)
|
|
256
|
+
|
|
257
|
+
def set_P1(self, *args):
|
|
258
|
+
curP1 = self.get_P1()
|
|
259
|
+
Rect2D.set_P1(self, *args)
|
|
260
|
+
newP1 = self.get_P1()
|
|
261
|
+
for img in self:
|
|
262
|
+
img.translate(newP1.x() - curP1.x(), newP1.y() - curP1.y())
|
|
263
|
+
|
|
264
|
+
self.updateBoudingRect()
|
|
265
|
+
|
|
266
|
+
def translate(self, *args):
|
|
267
|
+
if len(args) == 1:
|
|
268
|
+
point = args[0]
|
|
269
|
+
QRectF.translate(self, point.x(), point.y())
|
|
270
|
+
for img in self:
|
|
271
|
+
img.translate(point.x(), point.y())
|
|
272
|
+
else:
|
|
273
|
+
QRectF.translate(self, args[0], args[1])
|
|
274
|
+
for img in self:
|
|
275
|
+
img.translate(QPointF(args[0], args[1]))
|
|
276
|
+
|
|
277
|
+
def draw(self, painter, draw=True):
|
|
278
|
+
if draw:
|
|
279
|
+
painter.save()
|
|
280
|
+
if draw:
|
|
281
|
+
for img in self:
|
|
282
|
+
img.draw(painter, draw=draw)
|
|
283
|
+
painter.restore()
|
|
284
|
+
|
|
285
|
+
def fill(self, painter, draw=True):
|
|
286
|
+
if self.fill_color is None:
|
|
287
|
+
return
|
|
288
|
+
if draw:
|
|
289
|
+
painter.save()
|
|
290
|
+
if draw:
|
|
291
|
+
for img in self:
|
|
292
|
+
img.fill(painter, draw=draw)
|
|
293
|
+
painter.restore()
|
|
294
|
+
|
|
295
|
+
def drawAndFill(self, painter):
|
|
296
|
+
painter.save()
|
|
297
|
+
self.draw(painter, draw=True)
|
|
298
|
+
painter.restore()
|
|
299
|
+
|
|
300
|
+
def __iter__(self):
|
|
301
|
+
''' Returns the Iterator object '''
|
|
302
|
+
self._index = -1
|
|
303
|
+
return self
|
|
304
|
+
|
|
305
|
+
def __next__(self):
|
|
306
|
+
'''' Returns the next image or panel in the row '''
|
|
307
|
+
self._index += 1
|
|
308
|
+
if self._index < len(self.images):
|
|
309
|
+
return self.images[self._index]
|
|
310
|
+
# End of Iteration
|
|
311
|
+
raise StopIteration
|
|
312
|
+
|
|
313
|
+
def __lshift__(self, other):
|
|
314
|
+
# move image left with respect to self
|
|
315
|
+
if isinstance(other, Image2D):
|
|
316
|
+
# swap the position of the two images and repack
|
|
317
|
+
if other in self.images:
|
|
318
|
+
pos = self.images.index(other)
|
|
319
|
+
if pos - 1 >= 0:
|
|
320
|
+
self.images[pos - 1], self.images[pos] = self.images[pos], self.images[pos - 1]
|
|
321
|
+
else:
|
|
322
|
+
return self
|
|
323
|
+
self.packX(self.space)
|
|
324
|
+
return self
|
|
325
|
+
else:
|
|
326
|
+
logger.error('not implemented yet swapping two objects ' + str(type(other)))
|
|
327
|
+
|
|
328
|
+
def __rshift__(self, other):
|
|
329
|
+
# move image left with respect to self
|
|
330
|
+
if isinstance(other, Image2D):
|
|
331
|
+
# swap the position of the two images and repack
|
|
332
|
+
if other in self.images:
|
|
333
|
+
pos = self.images.index(other)
|
|
334
|
+
if pos + 1 < len(self.images):
|
|
335
|
+
self.images[pos + 1], self.images[pos] = self.images[pos], self.images[pos + 1]
|
|
336
|
+
else:
|
|
337
|
+
return self
|
|
338
|
+
self.packX(self.space)
|
|
339
|
+
return self
|
|
340
|
+
else:
|
|
341
|
+
logger.error('not implemented yet swapping two objects ' + str(type(other)))
|
|
342
|
+
|
|
343
|
+
def sameWidth(self, space):
|
|
344
|
+
if space is None:
|
|
345
|
+
space = 0
|
|
346
|
+
max_width = None
|
|
347
|
+
# if not self:
|
|
348
|
+
# return
|
|
349
|
+
for img in self:
|
|
350
|
+
if max_width is None:
|
|
351
|
+
# print('TUTU',img)
|
|
352
|
+
# print('TUTA',img, img.boundingRect(), img.boundingRect().height)
|
|
353
|
+
# print('TOTO',img, img.boundingRect(), img.boundingRect().height())
|
|
354
|
+
max_width = img.boundingRect().width()
|
|
355
|
+
max_width = max(img.boundingRect().width(), max_width)
|
|
356
|
+
for img in self:
|
|
357
|
+
img.setToWidth(max_width)
|
|
358
|
+
|
|
359
|
+
self.packY(space)
|
|
360
|
+
self.alignLeft() # updateBounds=False
|
|
361
|
+
self.updateBoudingRect()
|
|
362
|
+
|
|
363
|
+
# Aligns objects within the block
|
|
364
|
+
def arrangeRow(self):
|
|
365
|
+
self.alignLeft()
|
|
366
|
+
|
|
367
|
+
# Align vectorial objects to the top
|
|
368
|
+
# in fact should align in y
|
|
369
|
+
def alignLeft(self): # , updateBounds=False
|
|
370
|
+
first_left = None
|
|
371
|
+
for img in self:
|
|
372
|
+
cur_pos = img.get_P1()
|
|
373
|
+
if first_left is None:
|
|
374
|
+
first_left = cur_pos
|
|
375
|
+
img.set_P1(first_left.x(), cur_pos.y())
|
|
376
|
+
|
|
377
|
+
# if updateBounds:
|
|
378
|
+
self.updateBoudingRect()
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
# ça marche mais peut surement etre grandement amelioré
|
|
382
|
+
def setToHeight(self, height_in_px):
|
|
383
|
+
# from timeit import default_timer as timer
|
|
384
|
+
# start = timer()
|
|
385
|
+
if height_in_px is None:
|
|
386
|
+
return
|
|
387
|
+
# pure_image_height = (self.boundingRect().height()) - self.getIncompressibleHeight()
|
|
388
|
+
# # print(width_in_px, self.getIncompressibleWidth(), (nb_cols - 1.) * self.space )
|
|
389
|
+
# height_in_px -= self.getIncompressibleHeight()
|
|
390
|
+
# ratio = height_in_px / pure_image_height
|
|
391
|
+
# for img in self:
|
|
392
|
+
# img.setToHeight(img.boundingRect().height() * ratio)
|
|
393
|
+
# self.packY(self.space)
|
|
394
|
+
# self.updateBoudingRect()
|
|
395
|
+
# print('desired ',height_in_px)
|
|
396
|
+
# topleft = Point2D(self.boundingRect().topLeft())
|
|
397
|
+
|
|
398
|
+
topleft = Point2D(self.boundingRect().topLeft())
|
|
399
|
+
# causes a bug I think
|
|
400
|
+
self.sameWidth(self.space)
|
|
401
|
+
# print('setToWidth row 1', timer() - start)
|
|
402
|
+
|
|
403
|
+
# print('setToWidth row 2', timer() - start)
|
|
404
|
+
# alignTop(topleft, *self.images)
|
|
405
|
+
# print('setToWidth row 3', timer() - start)
|
|
406
|
+
# packX(self.space, topleft, *self.images)
|
|
407
|
+
|
|
408
|
+
# self.updateBoudingRect() # I should also updat the bounding rect of output -> that is my error
|
|
409
|
+
|
|
410
|
+
sizes = []
|
|
411
|
+
for elm in self:
|
|
412
|
+
sizes.append(elm.height())
|
|
413
|
+
# print("inner size", elm)
|
|
414
|
+
|
|
415
|
+
# new way to compute size --> much smarter than previous way --> start replace everywhere
|
|
416
|
+
# sizes
|
|
417
|
+
scaling = get_common_scaling_factor(sizes, height_in_px, self.space)
|
|
418
|
+
# print('scaling, ', scaling)
|
|
419
|
+
# need set to scale
|
|
420
|
+
# need
|
|
421
|
+
|
|
422
|
+
for elm in self:
|
|
423
|
+
# elm.setWidth(scaling*elm.width())
|
|
424
|
+
# elm.setHeight(scaling*elm.height())
|
|
425
|
+
try:
|
|
426
|
+
elm.scale *= scaling
|
|
427
|
+
except:
|
|
428
|
+
# elm.setToHeight(height_in_px)
|
|
429
|
+
elm.setToHeight(elm.height() * scaling)
|
|
430
|
+
# elm.scale *= scaling
|
|
431
|
+
|
|
432
|
+
# pb there is a bug and the image and stuff don't match definitely my new code is better and smarter
|
|
433
|
+
# this does noyt work but why ????
|
|
434
|
+
# need pack them in x
|
|
435
|
+
packY(self.space, None, *self.images)
|
|
436
|
+
|
|
437
|
+
min_h = 10000000
|
|
438
|
+
max_h = 0
|
|
439
|
+
for elm in self:
|
|
440
|
+
width = elm.width()
|
|
441
|
+
# print('size of inner elm', )
|
|
442
|
+
min_h = min(min_h, width)
|
|
443
|
+
max_h = max(max_h, width)
|
|
444
|
+
|
|
445
|
+
if max_h-min_h > 0.05:
|
|
446
|
+
# TODO do something better for gigantic images
|
|
447
|
+
# closest = _brute_force_find_width(self, min_h - 1, max_h + 1, (max_h - min_h) / 10, height_in_px)
|
|
448
|
+
#
|
|
449
|
+
# if closest is not None:
|
|
450
|
+
# if closest[0] - height_in_px < 0.05:
|
|
451
|
+
# self.setToWidth(closest[2])
|
|
452
|
+
# return closest
|
|
453
|
+
# else:
|
|
454
|
+
# closest = _brute_force_find_width(self, min_h - 1, max_h + 1, 1, height_in_px)
|
|
455
|
+
#
|
|
456
|
+
# value = closest[0]
|
|
457
|
+
# closest = _brute_force_find_width(self, value - 1, value + 1, 1, height_in_px)
|
|
458
|
+
|
|
459
|
+
closest = _brute_force_find_width(self, min_h - 1, max_h + 1, 1, height_in_px)
|
|
460
|
+
|
|
461
|
+
# print('closest1', closest)
|
|
462
|
+
value = closest[0]
|
|
463
|
+
if closest[0] - height_in_px < 0.05:
|
|
464
|
+
self.setToWidth(closest[2])
|
|
465
|
+
return closest
|
|
466
|
+
# for height in np.arange(value - 1, value + 1, 0.01):
|
|
467
|
+
# col1.setToHeight(height)
|
|
468
|
+
# print('bob', height, col1.width(), col1.height())
|
|
469
|
+
# if (col1.width() - desired_width) <= mn and col1.width() - desired_width >= 0:
|
|
470
|
+
# closest = (col1.width(), col1.height(), height)
|
|
471
|
+
# mn = col1.width() - desired_width
|
|
472
|
+
|
|
473
|
+
# it is never finding the solution
|
|
474
|
+
closest = _brute_force_find_width(self, value - 0.5, value + 0.5, 0.1, height_in_px)
|
|
475
|
+
|
|
476
|
+
if closest[0] - height_in_px < 0.05:
|
|
477
|
+
self.setToWidth(closest[2])
|
|
478
|
+
return closest
|
|
479
|
+
# maybe skip steps if good enough --> close enough to desired value
|
|
480
|
+
|
|
481
|
+
# print('closest, value-1, value+1',closest, value-1, value+1)
|
|
482
|
+
|
|
483
|
+
# --> pas mal et assez rapide --> pourrait faire n iterations
|
|
484
|
+
# bug can be 0 --> never crosses
|
|
485
|
+
value = closest[0]
|
|
486
|
+
closest = _brute_force_find_width(self, value - 0.1, value + 0.1, 0.01, height_in_px) # almost perfect
|
|
487
|
+
|
|
488
|
+
# (128.00066196944778, 42.80999999999944, 42.80999999999944) --> solution est à peu pres ça --> comment la trouver
|
|
489
|
+
# (128.5352647965376, 43.0, 43) # ineteger search then refinement --> could search between max height and min height of the shape of the column
|
|
490
|
+
# (128.00066196944888, 42.80999999999984, 42.80999999999984)
|
|
491
|
+
|
|
492
|
+
# this is a very good estimate
|
|
493
|
+
|
|
494
|
+
self.setToWidth(closest[2])
|
|
495
|
+
|
|
496
|
+
packY(self.space, None, *self.images)
|
|
497
|
+
self.set_P1(topleft)
|
|
498
|
+
self.updateBoudingRect()
|
|
499
|
+
|
|
500
|
+
#
|
|
501
|
+
#
|
|
502
|
+
# alignLeft(topleft, *self.images)
|
|
503
|
+
# packY(self.space, topleft, *self.images)
|
|
504
|
+
# setToHeight2(self.space, height_in_px, *self.images)
|
|
505
|
+
# bounds = updateBoudingRect(*self.images)
|
|
506
|
+
#
|
|
507
|
+
# max_width = -1
|
|
508
|
+
# cur_height = bounds.height()
|
|
509
|
+
# cur_width = bounds.width()
|
|
510
|
+
# all_widths_are_the_same = True
|
|
511
|
+
# for img in self.images:
|
|
512
|
+
# max_width = max(max_width, img.boundingRect().width())
|
|
513
|
+
# if max_width != cur_width:
|
|
514
|
+
# all_widths_are_the_same = False
|
|
515
|
+
#
|
|
516
|
+
# if not all_widths_are_the_same:
|
|
517
|
+
# setToWidth2(self.space, max_width, *self.images)
|
|
518
|
+
# bounds = updateBoudingRect(*self.images)
|
|
519
|
+
# all_widths_are_the_same = True
|
|
520
|
+
# else:
|
|
521
|
+
# bounds = updateBoudingRect(*self.images)
|
|
522
|
+
#
|
|
523
|
+
# sign = 1
|
|
524
|
+
# if bounds.height() >= height_in_px:
|
|
525
|
+
# sign = -1
|
|
526
|
+
#
|
|
527
|
+
# # bug cause also cyclic inside --> need pass whether increase or decrease once for good initially
|
|
528
|
+
# # print(bounds.height(), 'vs heigth desired', height_in_px, 'sign', sign)
|
|
529
|
+
# # print('heigth', all_widths_are_the_same)
|
|
530
|
+
# # dirty height/width fix for complex panels figure out the math for it and replace this code
|
|
531
|
+
# # TODO also speed this up so that the action is only faked and not really done (just done once at the end to gain time)
|
|
532
|
+
# if not all_widths_are_the_same or (
|
|
533
|
+
# bounds.height() != height_in_px and abs(bounds.height() - height_in_px) > 0.3):
|
|
534
|
+
# # print('setToHeight col 9', timer() - start)
|
|
535
|
+
# while True:
|
|
536
|
+
# # print(max_width)
|
|
537
|
+
# setToWidth2(self.space, max_width, *self.images)
|
|
538
|
+
# bounds = updateBoudingRect(*self.images)
|
|
539
|
+
# if sign < 0:
|
|
540
|
+
# if bounds.height() <= height_in_px:
|
|
541
|
+
# break
|
|
542
|
+
# else:
|
|
543
|
+
# if bounds.height() >= height_in_px:
|
|
544
|
+
# break
|
|
545
|
+
# max_width += 1 * sign
|
|
546
|
+
#
|
|
547
|
+
# cur_height = bounds.height()
|
|
548
|
+
# if bounds.height() != height_in_px:
|
|
549
|
+
# if bounds.height() >= height_in_px:
|
|
550
|
+
# sign = -1
|
|
551
|
+
# else:
|
|
552
|
+
# sign = 1
|
|
553
|
+
# # print('setToHeight col 10', timer() - start)
|
|
554
|
+
# # max_width -= 1
|
|
555
|
+
# while True:
|
|
556
|
+
# setToWidth2(self.space, max_width, *self.images)
|
|
557
|
+
# bounds = updateBoudingRect(*self.images)
|
|
558
|
+
# if sign < 0:
|
|
559
|
+
# if bounds.height() <= height_in_px:
|
|
560
|
+
# break
|
|
561
|
+
# else:
|
|
562
|
+
# if bounds.height() >= height_in_px:
|
|
563
|
+
# break
|
|
564
|
+
# max_width += 0.25 * sign # critical time consuming step --> seems ok with this value
|
|
565
|
+
#
|
|
566
|
+
# self.updateBoudingRect()
|
|
567
|
+
|
|
568
|
+
# will not work with scale should I override scale here of the rect2D...
|
|
569
|
+
# Forces the block to be of width (width_in_px)
|
|
570
|
+
# def setToHeight_old(self, height_in_px):
|
|
571
|
+
# # from timeit import default_timer as timer
|
|
572
|
+
# # start = timer()
|
|
573
|
+
# if height_in_px is None:
|
|
574
|
+
# return
|
|
575
|
+
# # pure_image_height = (self.boundingRect().height()) - self.getIncompressibleHeight()
|
|
576
|
+
# # # print(width_in_px, self.getIncompressibleWidth(), (nb_cols - 1.) * self.space )
|
|
577
|
+
# # height_in_px -= self.getIncompressibleHeight()
|
|
578
|
+
# # ratio = height_in_px / pure_image_height
|
|
579
|
+
# # for img in self:
|
|
580
|
+
# # img.setToHeight(img.boundingRect().height() * ratio)
|
|
581
|
+
# # self.packY(self.space)
|
|
582
|
+
# # self.updateBoudingRect()
|
|
583
|
+
# # print('desired ',height_in_px)
|
|
584
|
+
# topleft = Point2D(self.boundingRect().topLeft())
|
|
585
|
+
# alignLeft(topleft, *self.images)
|
|
586
|
+
# packY(self.space, topleft, *self.images)
|
|
587
|
+
# setToHeight2(self.space, height_in_px, *self.images)
|
|
588
|
+
# bounds = updateBoudingRect(*self.images)
|
|
589
|
+
#
|
|
590
|
+
# max_width = -1
|
|
591
|
+
# cur_height = bounds.height()
|
|
592
|
+
# cur_width = bounds.width()
|
|
593
|
+
# all_widths_are_the_same = True
|
|
594
|
+
# for img in self.images:
|
|
595
|
+
# max_width = max(max_width, img.boundingRect().width())
|
|
596
|
+
# if max_width != cur_width:
|
|
597
|
+
# all_widths_are_the_same = False
|
|
598
|
+
#
|
|
599
|
+
# if not all_widths_are_the_same:
|
|
600
|
+
# setToWidth2(self.space, max_width, *self.images)
|
|
601
|
+
# bounds = updateBoudingRect(*self.images)
|
|
602
|
+
# all_widths_are_the_same = True
|
|
603
|
+
# else:
|
|
604
|
+
# bounds = updateBoudingRect(*self.images)
|
|
605
|
+
#
|
|
606
|
+
# sign = 1
|
|
607
|
+
# if bounds.height() >= height_in_px:
|
|
608
|
+
# sign = -1
|
|
609
|
+
#
|
|
610
|
+
# # bug cause also cyclic inside --> need pass whether increase or decrease once for good initially
|
|
611
|
+
# # print(bounds.height(), 'vs heigth desired', height_in_px, 'sign', sign)
|
|
612
|
+
# # print('heigth', all_widths_are_the_same)
|
|
613
|
+
# # dirty height/width fix for complex panels figure out the math for it and replace this code
|
|
614
|
+
# # TODO also speed this up so that the action is only faked and not really done (just done once at the end to gain time)
|
|
615
|
+
# if not all_widths_are_the_same or (
|
|
616
|
+
# bounds.height() != height_in_px and abs(bounds.height() - height_in_px) > 0.3):
|
|
617
|
+
# # print('setToHeight col 9', timer() - start)
|
|
618
|
+
# while True:
|
|
619
|
+
# # print(max_width)
|
|
620
|
+
# setToWidth2(self.space, max_width, *self.images)
|
|
621
|
+
# bounds = updateBoudingRect(*self.images)
|
|
622
|
+
# if sign < 0:
|
|
623
|
+
# if bounds.height() <= height_in_px:
|
|
624
|
+
# break
|
|
625
|
+
# else:
|
|
626
|
+
# if bounds.height() >= height_in_px:
|
|
627
|
+
# break
|
|
628
|
+
# max_width += 1 * sign
|
|
629
|
+
#
|
|
630
|
+
# cur_height = bounds.height()
|
|
631
|
+
# if bounds.height() != height_in_px:
|
|
632
|
+
# if bounds.height() >= height_in_px:
|
|
633
|
+
# sign = -1
|
|
634
|
+
# else:
|
|
635
|
+
# sign = 1
|
|
636
|
+
# # print('setToHeight col 10', timer() - start)
|
|
637
|
+
# # max_width -= 1
|
|
638
|
+
# while True:
|
|
639
|
+
# setToWidth2(self.space, max_width, *self.images)
|
|
640
|
+
# bounds = updateBoudingRect(*self.images)
|
|
641
|
+
# if sign < 0:
|
|
642
|
+
# if bounds.height() <= height_in_px:
|
|
643
|
+
# break
|
|
644
|
+
# else:
|
|
645
|
+
# if bounds.height() >= height_in_px:
|
|
646
|
+
# break
|
|
647
|
+
# max_width += 0.25 * sign # critical time consuming step --> seems ok with this value
|
|
648
|
+
#
|
|
649
|
+
# self.updateBoudingRect()
|
|
650
|
+
|
|
651
|
+
def get_shape_at_coord(self, x, y):
|
|
652
|
+
'''returns the shape under the mouse or None if none is found
|
|
653
|
+
|
|
654
|
+
:param x:
|
|
655
|
+
:param y:
|
|
656
|
+
:return:
|
|
657
|
+
'''
|
|
658
|
+
for img in self.images:
|
|
659
|
+
if img.boundingRect().contains(x, y):
|
|
660
|
+
return img
|
|
661
|
+
return None
|
|
662
|
+
|
|
663
|
+
def setToWidth(self, width_in_px):
|
|
664
|
+
if width_in_px is None:
|
|
665
|
+
return
|
|
666
|
+
# nb_cols = len(self)
|
|
667
|
+
|
|
668
|
+
# probably need do more complex stuff here and take or not scaled size --> TODO
|
|
669
|
+
# in fact c'est l'original size que je veux ???
|
|
670
|
+
# pure_image_width = (self.boundingRect().width()) - self.getIncompressibleWidth()
|
|
671
|
+
# # print(width_in_px, self.getIncompressibleWidth(), (nb_cols - 1.) * self.space )
|
|
672
|
+
# width_in_px -= self.getIncompressibleWidth()
|
|
673
|
+
# ratio = width_in_px / pure_image_width
|
|
674
|
+
# for img in self:
|
|
675
|
+
# img.setToWidth(img.boundingRect().width() * ratio)
|
|
676
|
+
# self.packY(self.space)
|
|
677
|
+
# self.updateBoudingRect()
|
|
678
|
+
topleft = Point2D(self.boundingRect().topLeft())
|
|
679
|
+
alignLeft(topleft, *self.images)
|
|
680
|
+
setToWidth2(self.space, width_in_px, *self.images)
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
self.updateBoudingRect() # this was my bug --> really needs be done # probably not needed now that I use set to height
|
|
684
|
+
|
|
685
|
+
# @return the block incompressible width
|
|
686
|
+
def getIncompressibleHeight(self):
|
|
687
|
+
nb_cols = len(self)
|
|
688
|
+
extra_space = (nb_cols - 1.) * self.space
|
|
689
|
+
return extra_space
|
|
690
|
+
|
|
691
|
+
def getIncompressibleWidth(self):
|
|
692
|
+
extra_space = 0
|
|
693
|
+
return extra_space
|
|
694
|
+
|
|
695
|
+
# can I pass an ignoring char if some images need be ignored
|
|
696
|
+
# probably need return the increment
|
|
697
|
+
def setLettering(self, letter):
|
|
698
|
+
# TODO implement increment
|
|
699
|
+
# set letter for increasing stuff # check if letter is string or letter or array if so do or do not increase letters
|
|
700
|
+
for img in self:
|
|
701
|
+
img.setLettering(letter)
|
|
702
|
+
# self.letter = letter
|
|
703
|
+
|
|
704
|
+
def get_equation(self):
|
|
705
|
+
# TODO --> maybe get a width equation and a height one
|
|
706
|
+
# need get the equa of inner also
|
|
707
|
+
# maybe need even get the final equations to that I just append them all and get exactly what I need to solve
|
|
708
|
+
# how should I increment that
|
|
709
|
+
# UnevaluatedExpr(x + x)
|
|
710
|
+
if not self:
|
|
711
|
+
return None
|
|
712
|
+
|
|
713
|
+
# in fact all heights should be equal and the sum of width would also be equal --> I need both sets of equations in fact --> maybe just do the get equation
|
|
714
|
+
# maybe I should just append the equations
|
|
715
|
+
# append both x and y equations and do the maths with them --> put them into a solvable form
|
|
716
|
+
# what is the best way to do that ???
|
|
717
|
+
equas_w = []
|
|
718
|
+
equas_h = []
|
|
719
|
+
equas_to_solve = []
|
|
720
|
+
|
|
721
|
+
# print(len(self))
|
|
722
|
+
for img in self:
|
|
723
|
+
|
|
724
|
+
# print(img)
|
|
725
|
+
|
|
726
|
+
equa_w, equa_h, equa_to_solve = img.get_equation()
|
|
727
|
+
|
|
728
|
+
# print(equa_w)
|
|
729
|
+
|
|
730
|
+
if equa_w:
|
|
731
|
+
equas_w.extend(equa_w)
|
|
732
|
+
if equa_h:
|
|
733
|
+
equas_h.extend(equa_h)
|
|
734
|
+
if equa_to_solve:
|
|
735
|
+
equas_to_solve.extend(equa_to_solve)
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
# do I need increment ??? --> maybe not or maybe yes
|
|
740
|
+
# fig_tools.common_value+=1
|
|
741
|
+
# do I need a formula there # that would be the sum of others
|
|
742
|
+
# final equation is a concatenate of all equa for width
|
|
743
|
+
# id(self) # to set the variable
|
|
744
|
+
# --> is there an additional factor that would handle the resize if they are all the same size ???
|
|
745
|
+
|
|
746
|
+
# in a cal all weidth need be the same --> must put the equas so that this is true
|
|
747
|
+
# and in fact just return one equation for a row the top most row that needs be resized
|
|
748
|
+
# print(equas_w)
|
|
749
|
+
# print("tutu", len(equas_w), len(equas_h))
|
|
750
|
+
|
|
751
|
+
for iii in range(1, len(equas_w)):
|
|
752
|
+
# print('entering')
|
|
753
|
+
# print(iii)
|
|
754
|
+
# first - sec = 0
|
|
755
|
+
equa = equas_w[0] - equas_w[iii]
|
|
756
|
+
equas_to_solve.append(equa)
|
|
757
|
+
# if len(equa_w)==1:
|
|
758
|
+
# equa = equa_w[0] - equa_w[1]
|
|
759
|
+
# equas_to_solve.append(equa)
|
|
760
|
+
|
|
761
|
+
final_equa = None
|
|
762
|
+
for equa in equas_h:
|
|
763
|
+
if final_equa is None:
|
|
764
|
+
final_equa = equa
|
|
765
|
+
else:
|
|
766
|
+
final_equa += equa
|
|
767
|
+
|
|
768
|
+
# see how I can do that
|
|
769
|
+
# variable = Symbol('a'+str(id(self)))
|
|
770
|
+
# final_equa
|
|
771
|
+
|
|
772
|
+
# this is the equation I want
|
|
773
|
+
final_equa += self.getIncompressibleHeight()
|
|
774
|
+
equas_to_solve.append(final_equa) # pb is that for this equa I need to add the width --> how to I do that
|
|
775
|
+
# this lists the variables in the formula --> do I don't need to store them separately
|
|
776
|
+
print(final_equa.free_symbols) # returns all the variables contained in it
|
|
777
|
+
|
|
778
|
+
# since they all have the same width I need return just one width equation
|
|
779
|
+
return [equas_w[0]], equas_h, equas_to_solve
|
|
780
|
+
|
|
781
|
+
# def get_width_equation(self):
|
|
782
|
+
# # TODO --> maybe get a width equation and a height one
|
|
783
|
+
#
|
|
784
|
+
# # need get the equa of inner also
|
|
785
|
+
# # maybe need even get the final equations to that I just append them all and get exactly what I need to solve
|
|
786
|
+
# # how should I increment that
|
|
787
|
+
# # UnevaluatedExpr(x + x)
|
|
788
|
+
# if not self:
|
|
789
|
+
# return None
|
|
790
|
+
#
|
|
791
|
+
# equas = []
|
|
792
|
+
# for img in self:
|
|
793
|
+
# equas.append(img.get_width_equation())
|
|
794
|
+
# # do I need increment ??? --> maybe not or maybe yes
|
|
795
|
+
# # fig_tools.common_value+=1
|
|
796
|
+
# # do I need a formula there # that would be the sum of others
|
|
797
|
+
# # final equation is a concatenate of all equa for width
|
|
798
|
+
# # id(self) # to set the variable
|
|
799
|
+
# # --> is there an additional factor that would handle the resize if they are all the same size ???
|
|
800
|
+
# final_equa = None
|
|
801
|
+
# for equa in equas:
|
|
802
|
+
# if final_equa is None:
|
|
803
|
+
# final_equa = equa
|
|
804
|
+
# else:
|
|
805
|
+
# final_equa += equa
|
|
806
|
+
#
|
|
807
|
+
# # see how I can do that
|
|
808
|
+
# # variable = Symbol('a'+str(id(self)))
|
|
809
|
+
# # final_equa
|
|
810
|
+
#
|
|
811
|
+
# # this is the equation I want
|
|
812
|
+
# final_equa += self.getIncompressibleWidth()
|
|
813
|
+
# # this lists the variables in the formula --> do I don't need to store them separately
|
|
814
|
+
# print(final_equa.free_symbols) # returns all the variables contained in it
|
|
815
|
+
#
|
|
816
|
+
# return final_equa
|
|
817
|
+
#
|
|
818
|
+
# # make no sense ??? la height n'est pas la somme mais juste une des valeurs de la colonne --> c'est tout je pense en fait
|
|
819
|
+
#
|
|
820
|
+
# def get_height_equation(self):
|
|
821
|
+
# # TODO --> maybe get a width equation and a height one
|
|
822
|
+
#
|
|
823
|
+
# # need get the equa of inner also
|
|
824
|
+
# # maybe need even get the final equations to that I just append them all and get exactly what I need to solve
|
|
825
|
+
# # how should I increment that
|
|
826
|
+
# # UnevaluatedExpr(x + x)
|
|
827
|
+
# equas = []
|
|
828
|
+
# for img in self:
|
|
829
|
+
# equas.append(img.get_height_equation())
|
|
830
|
+
# # do I need increment ??? --> maybe not or maybe yes
|
|
831
|
+
# # fig_tools.common_value+=1
|
|
832
|
+
# # do I need a formula there # that would be the sum of others
|
|
833
|
+
# # final equation is a concatenate of all equa for width
|
|
834
|
+
# # id(self) # to set the variable
|
|
835
|
+
# # --> is there an additional factor that would handle the resize if they are all the same size ???
|
|
836
|
+
# final_equa = None
|
|
837
|
+
# for equa in equas:
|
|
838
|
+
# if final_equa is None:
|
|
839
|
+
# final_equa = equa
|
|
840
|
+
# else:
|
|
841
|
+
# final_equa += equa
|
|
842
|
+
#
|
|
843
|
+
# # see how I can do that
|
|
844
|
+
# # variable = Symbol('a'+str(id(self)))
|
|
845
|
+
# final_equa += self.getIncompressibleHeight() # useless because 0 but ok still
|
|
846
|
+
#
|
|
847
|
+
# # this lists the variables in the formula --> do I don't need to store them separately
|
|
848
|
+
# print(final_equa.free_symbols) # returns all the variables contained in it
|
|
849
|
+
#
|
|
850
|
+
# return final_equa
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
# allows to duplicate an object
|
|
854
|
+
# marche pas --> ilo faut le hard coder
|
|
855
|
+
def __copy__(self):
|
|
856
|
+
return self
|
|
857
|
+
|
|
858
|
+
def __deepcopy__(self, memo):
|
|
859
|
+
return self
|
|
860
|
+
|
|
861
|
+
if __name__ == '__main__':
|
|
862
|
+
img1 = Image2D('/E/Sample_images/counter/00.png')
|
|
863
|
+
img2 = Image2D('/E/Sample_images/counter/01.png')
|
|
864
|
+
img3 = Image2D('/E/Sample_images/counter/02.png')
|
|
865
|
+
img4 = Image2D('/E/Sample_images/counter/03.png')
|
|
866
|
+
img5 = Image2D('/E/Sample_images/counter/04.png')
|
|
867
|
+
img6 = Image2D('/E/Sample_images/counter/05.png')
|
|
868
|
+
img7 = Image2D('/E/Sample_images/counter/06.png')
|
|
869
|
+
img8 = Image2D('/E/Sample_images/counter/07.png')
|
|
870
|
+
img9 = Image2D('/E/Sample_images/counter/08.png')
|
|
871
|
+
if False:
|
|
872
|
+
result = img1 | img2
|
|
873
|
+
result |= img3
|
|
874
|
+
result |= img4
|
|
875
|
+
|
|
876
|
+
print(result)
|
|
877
|
+
preview(result)
|
|
878
|
+
if False:
|
|
879
|
+
result = Column(img4, img2, img3) # ça a l'air de marcher
|
|
880
|
+
result |= img1
|
|
881
|
+
|
|
882
|
+
result.setToHeight(300)
|
|
883
|
+
|
|
884
|
+
# all seems ok now --> just try to finalize all
|
|
885
|
+
preview(result)
|
|
886
|
+
|
|
887
|
+
if False:
|
|
888
|
+
from batoolset.figure.row import Row
|
|
889
|
+
|
|
890
|
+
row1 = Row(img1, img2)
|
|
891
|
+
row2 = Row(img3, img4)
|
|
892
|
+
row1 |= row2
|
|
893
|
+
|
|
894
|
+
preview(row1)
|
|
895
|
+
|
|
896
|
+
if False:
|
|
897
|
+
from batoolset.figure.row import Row
|
|
898
|
+
|
|
899
|
+
row1 = Row(img1, img2)
|
|
900
|
+
row2 = Row(img3, img4)
|
|
901
|
+
row1 /= row2
|
|
902
|
+
|
|
903
|
+
preview(row1)
|
|
904
|
+
|
|
905
|
+
if False:
|
|
906
|
+
col1 = Column(img1, img2)
|
|
907
|
+
col2 = Column(img3, img4)
|
|
908
|
+
col1 |= col2
|
|
909
|
+
|
|
910
|
+
preview(col1)
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
if False:
|
|
914
|
+
# attempt to solve a complex equation --> does not work because solution is too complex --> would need better estimates --> maybe do that later
|
|
915
|
+
from batoolset.figure.row import Row
|
|
916
|
+
|
|
917
|
+
# all works if space is 0 but does not work otherwise!!!
|
|
918
|
+
# need take incompressibility into account
|
|
919
|
+
# or do it without space then fit the image within the same space taking into account incompressibility
|
|
920
|
+
# --> will that work ---> not so easy in fact because incompressibility will change the AR and I need that
|
|
921
|
+
# --> brute force is a good solution then
|
|
922
|
+
|
|
923
|
+
# in both cases the width is ok, but in one case the height is bad --> need fix so that the height of the two is the same --> need decrease height of big and increase height of the other
|
|
924
|
+
|
|
925
|
+
# space = random.choice([0,3])
|
|
926
|
+
space = 3
|
|
927
|
+
col1 = Column(img1, img2, space=space)
|
|
928
|
+
print(type(col1)) # --> this is now a row
|
|
929
|
+
|
|
930
|
+
# print('equa', col1.get_equation(), len(col1))
|
|
931
|
+
# import sys
|
|
932
|
+
# sys.exit(0)
|
|
933
|
+
|
|
934
|
+
# col2 = Column(img3, img4, space=space)
|
|
935
|
+
# col1 /= col2
|
|
936
|
+
# a col with two images --> two width must be equal
|
|
937
|
+
# print('equa', col1.get_equation(), len(col1))
|
|
938
|
+
# import sys
|
|
939
|
+
# sys.exit(0)
|
|
940
|
+
|
|
941
|
+
row1 = Row(img5, img6, img7, space=space)
|
|
942
|
+
|
|
943
|
+
col1 |= row1
|
|
944
|
+
|
|
945
|
+
print(type(col1)) # --> this is now a row
|
|
946
|
+
equas_w, equas_h, equas_to_solve = col1.get_equation()
|
|
947
|
+
print('equa', (equas_w, equas_h, equas_to_solve), len(col1))
|
|
948
|
+
|
|
949
|
+
# TODO --> try to solve all these equas
|
|
950
|
+
# get all equas to solve in the end and edit the last one so that it matches the desired size
|
|
951
|
+
# see if there is a bug ???
|
|
952
|
+
variables = []
|
|
953
|
+
for equa in equas_to_solve:
|
|
954
|
+
variables.extend(equa.free_symbols)
|
|
955
|
+
|
|
956
|
+
variables = list(
|
|
957
|
+
set(variables)) # remove dupes # --> it cannot find the solution --> probably because estimate is too far away from the stuff --> need a better starting estimate --> need pack and get to the closest value
|
|
958
|
+
# in a way maybe brute force is smarter .... in the end --> see
|
|
959
|
+
|
|
960
|
+
estimates = [0.5 for _ in variables]
|
|
961
|
+
|
|
962
|
+
print(variables)
|
|
963
|
+
|
|
964
|
+
print(len(variables))
|
|
965
|
+
print(len(equas_to_solve))
|
|
966
|
+
|
|
967
|
+
# or I do have a bug in my equas --> maybe that is the problem too
|
|
968
|
+
test = nsolve(equas_to_solve, variables, estimates)
|
|
969
|
+
# Traceback (most recent call last):
|
|
970
|
+
# File "/home/aigouy/mon_prog/Python/epyseg_pkg/epyseg/figure/column.py", line 864, in <module>
|
|
971
|
+
# test = nsolve(equas_to_solve, variables, estimates)
|
|
972
|
+
# File "/usr/local/lib/python3.7/site-packages/sympy/utilities/decorator.py", line 88, in func_wrapper
|
|
973
|
+
# return func(*args, **kwargs)
|
|
974
|
+
# File "/usr/local/lib/python3.7/site-packages/sympy/solvers/solvers.py", line 2954, in nsolve
|
|
975
|
+
# x = findroot(f, x0, J=J, **kwargs)
|
|
976
|
+
# File "/usr/local/lib/python3.7/site-packages/mpmath/calculus/optimization.py", line 988, in findroot
|
|
977
|
+
# % (norm(f(*xl))**2, tol))
|
|
978
|
+
# ValueError: Could not find root within given tolerance. (4.11873256516330155209 > 2.16840434497100886801e-19)
|
|
979
|
+
# Try another starting point or tweak arguments.
|
|
980
|
+
#
|
|
981
|
+
# Process finished with exit code 1
|
|
982
|
+
# -> this is probably a bug!!!
|
|
983
|
+
# The second command tried to solve the same equations with a different initial guess, one farther from the actual solution. This time sympy failed hard. This is regrettably common when solving nonlinear equations with bad initial guesses for the solution. When we see that message:
|
|
984
|
+
# Try another starting point or tweak arguments.
|
|
985
|
+
# it means that we need to guess again on our starting point. It is often a good idea when solving nonlinear systems to plot the functions to get an idea of where they are zero.
|
|
986
|
+
|
|
987
|
+
# gives me an error because estimates are too far from point -> maybe brute force is best and faster or start from brute force to get a rough estimate and solve it numerically!!!
|
|
988
|
+
print(test)
|
|
989
|
+
|
|
990
|
+
import sys
|
|
991
|
+
sys.exit(0)
|
|
992
|
+
|
|
993
|
+
if True:
|
|
994
|
+
from batoolset.figure.row import Row
|
|
995
|
+
|
|
996
|
+
# all works if space is 0 but does not work otherwise!!!
|
|
997
|
+
# need take incompressibility into account
|
|
998
|
+
# or do it without space then fit the image within the same space taking into account incompressibility
|
|
999
|
+
# --> will that work ---> not so easy in fact because incompressibility will change the AR and I need that
|
|
1000
|
+
# --> brute force is a good solution then
|
|
1001
|
+
|
|
1002
|
+
# in both cases the width is ok, but in one case the height is bad --> need fix so that the height of the two is the same --> need decrease height of big and increase height of the other
|
|
1003
|
+
|
|
1004
|
+
# space = random.choice([0,3])
|
|
1005
|
+
space = 3
|
|
1006
|
+
col1 = Column(img1, img2, space=space)
|
|
1007
|
+
print(type(col1)) # --> this is now a row
|
|
1008
|
+
|
|
1009
|
+
# print('equa', col1.get_equation(), len(col1))
|
|
1010
|
+
# import sys
|
|
1011
|
+
# sys.exit(0)
|
|
1012
|
+
|
|
1013
|
+
# col2 = Column(img3, img4, space=space)
|
|
1014
|
+
# col1 /= col2
|
|
1015
|
+
# a col with two images --> two width must be equal
|
|
1016
|
+
# print('equa', col1.get_equation(), len(col1))
|
|
1017
|
+
# import sys
|
|
1018
|
+
# sys.exit(0)
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
row1 = Row(img5, img6, img7, space=space)
|
|
1022
|
+
|
|
1023
|
+
col1 |= row1
|
|
1024
|
+
|
|
1025
|
+
desired_height = 128
|
|
1026
|
+
|
|
1027
|
+
col1.setToWidth(desired_height) # --> need take into account the incompressible part of each and every object to compute the scaling --> TODO
|
|
1028
|
+
# so they don't have the same width and height which is a pb especially because I asked for it!!!!
|
|
1029
|
+
# they are not same height --> why is that
|
|
1030
|
+
for elm in col1:
|
|
1031
|
+
print('size of inner elm', elm)
|
|
1032
|
+
|
|
1033
|
+
# brute force to really find same height of object
|
|
1034
|
+
import numpy as np
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
# print('min_h, max_h',min_h, max_h)
|
|
1039
|
+
|
|
1040
|
+
# en brute force ça marche mais pas top qd meme et en plus c'est lent --> comment puis-je calculer le truc numeriquement
|
|
1041
|
+
# col1.sameHeight(3)
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
# ok then do the brute force stuff if needed
|
|
1046
|
+
|
|
1047
|
+
# now this is really fast
|
|
1048
|
+
# so if I don't do crap in fact brute force is fast
|
|
1049
|
+
# I could also detect the sign inversion and stop after it by just taking the closest
|
|
1050
|
+
# or I could further refine by scanning in between the two
|
|
1051
|
+
# maybe get the max and min size of all the images in there and screen in between them
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
#pas mal --> presque ça --> peut etre le plus simple c'est vraiment la brute force
|
|
1055
|
+
# could I estimate the 0 intersection from a set of values and use that ???
|
|
1056
|
+
|
|
1057
|
+
# could do the same for a col
|
|
1058
|
+
# see how to do that
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
# min_h = 10000000
|
|
1066
|
+
# max_h = 0
|
|
1067
|
+
# for elm in col1:
|
|
1068
|
+
# height = elm.height()
|
|
1069
|
+
# # print('size of inner elm', )
|
|
1070
|
+
# min_h = min(min_h, height)
|
|
1071
|
+
# max_h = max(max_h, height)
|
|
1072
|
+
# closest = _brute_force_find_height(col1, min_h - 1, max_h + 1,0.5, desired_height)
|
|
1073
|
+
#
|
|
1074
|
+
#
|
|
1075
|
+
# # print('closest1', closest)
|
|
1076
|
+
# value = closest[1]
|
|
1077
|
+
# # for height in np.arange(value - 1, value + 1, 0.01):
|
|
1078
|
+
# # col1.setToHeight(height)
|
|
1079
|
+
# # print('bob', height, col1.width(), col1.height())
|
|
1080
|
+
# # if (col1.width() - desired_width) <= mn and col1.width() - desired_width >= 0:
|
|
1081
|
+
# # closest = (col1.width(), col1.height(), height)
|
|
1082
|
+
# # mn = col1.width() - desired_width
|
|
1083
|
+
#
|
|
1084
|
+
# closest = _brute_force_find_height(col1, value - 0.5, value + 0.5,0.01,desired_height)
|
|
1085
|
+
#
|
|
1086
|
+
# # --> pas mal et assez rapide --> pourrait faire n iterations
|
|
1087
|
+
# value = closest[1]
|
|
1088
|
+
# closest = _brute_force_find_height(col1, value - 0.1, value + 0.1, 0.001,desired_height) # almost perfect
|
|
1089
|
+
#
|
|
1090
|
+
#
|
|
1091
|
+
# # (128.00066196944778, 42.80999999999944, 42.80999999999944) --> solution est à peu pres ça --> comment la trouver
|
|
1092
|
+
# # (128.5352647965376, 43.0, 43) # ineteger search then refinement --> could search between max height and min height of the shape of the column
|
|
1093
|
+
# # (128.00066196944888, 42.80999999999984, 42.80999999999984)
|
|
1094
|
+
#
|
|
1095
|
+
# # this is a very good estimate
|
|
1096
|
+
#
|
|
1097
|
+
# col1.setToHeight(closest[2])
|
|
1098
|
+
print(type(col1))
|
|
1099
|
+
print(col1)
|
|
1100
|
+
|
|
1101
|
+
# print(closest)
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
# preview(col1)
|
|
1106
|
+
|
|
1107
|
+
# rewrite the equa with incompressibility... --> not so easy in fact
|
|
1108
|
+
# will then work if I set to min height in fact --> yes or no ??? --> not sure
|
|
1109
|
+
# in fact that is tough due to incompressible size
|
|
1110
|
+
# alternatively
|
|
1111
|
+
# the pb is that incompressibility changes the AR of the object --> so that makes my equation harder to handle and some of my assumptions wrong
|
|
1112
|
+
# need a smarter equation and need assume ratio width height not the same
|
|
1113
|
+
# TODO --> ...
|
|
1114
|
+
# need speed up the tracking
|
|
1115
|
+
# in tracking ask for fast vs precise
|
|
1116
|
+
|
|
1117
|
+
# TODO --> add combinations of rows
|