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.
Files changed (74) hide show
  1. batoolset/GUI/__init__.py +0 -0
  2. batoolset/GUI/customdialog.py +136 -0
  3. batoolset/GUI/exception_handler.py +74 -0
  4. batoolset/GUI/list_gui.py +514 -0
  5. batoolset/GUI/multi_image_display.py +1038 -0
  6. batoolset/GUI/open.py +325 -0
  7. batoolset/GUI/overlay_hints.py +45 -0
  8. batoolset/GUI/paint2.py +1369 -0
  9. batoolset/GUI/scrollablepaint.py +1165 -0
  10. batoolset/dialogs/__init__.py +0 -0
  11. batoolset/dialogs/opensave.py +228 -0
  12. batoolset/drawings/__init__.py +0 -0
  13. batoolset/drawings/math_text.py +294 -0
  14. batoolset/drawings/pdf_svg_renderer.py +376 -0
  15. batoolset/drawings/shapes/Position.py +183 -0
  16. batoolset/drawings/shapes/__init__.py +0 -0
  17. batoolset/drawings/shapes/automated_alignment_drawing_refactored.py +346 -0
  18. batoolset/drawings/shapes/circle2d.py +99 -0
  19. batoolset/drawings/shapes/compute_optimal_size_all_merged.py +328 -0
  20. batoolset/drawings/shapes/ellipse2d.py +336 -0
  21. batoolset/drawings/shapes/freehand2d.py +235 -0
  22. batoolset/drawings/shapes/group.py +1985 -0
  23. batoolset/drawings/shapes/image2d.py +3157 -0
  24. batoolset/drawings/shapes/line2d.py +579 -0
  25. batoolset/drawings/shapes/point2d.py +257 -0
  26. batoolset/drawings/shapes/polygon2d.py +357 -0
  27. batoolset/drawings/shapes/polyline2d.py +235 -0
  28. batoolset/drawings/shapes/rect2d.py +388 -0
  29. batoolset/drawings/shapes/rectangle2d.py +601 -0
  30. batoolset/drawings/shapes/scalebar.py +310 -0
  31. batoolset/drawings/shapes/serializablefont.py +133 -0
  32. batoolset/drawings/shapes/serializableguiparams.py +14 -0
  33. batoolset/drawings/shapes/square2d.py +102 -0
  34. batoolset/drawings/shapes/test_publication_style.py +220 -0
  35. batoolset/drawings/shapes/textorientation.py +45 -0
  36. batoolset/drawings/shapes/tools.py +467 -0
  37. batoolset/drawings/shapes/transform2D.py +350 -0
  38. batoolset/drawings/shapes/txt2d.py +615 -0
  39. batoolset/drawings/svg_clip_renderer.py +247 -0
  40. batoolset/drawings/svg_embed.py +165 -0
  41. batoolset/drawings/svg_text_renderer.py +183 -0
  42. batoolset/drawings/widgets/__init__.py +0 -0
  43. batoolset/drawings/widgets/col.py +343 -0
  44. batoolset/drawings/widgets/image_group.py +248 -0
  45. batoolset/drawings/widgets/image_organizer.py +96 -0
  46. batoolset/drawings/widgets/paint.py +184 -0
  47. batoolset/drawings/widgets/vectorial.py +256 -0
  48. batoolset/figure/__init__.py +0 -0
  49. batoolset/figure/alignment.py +822 -0
  50. batoolset/figure/column.py +1117 -0
  51. batoolset/figure/fig_tools.py +285 -0
  52. batoolset/figure/minimal_debugger_scale_etc.py +139 -0
  53. batoolset/figure/panel.py +697 -0
  54. batoolset/figure/row.py +852 -0
  55. batoolset/figure/user_selection.py +287 -0
  56. batoolset/icons/__init__.py +0 -0
  57. batoolset/icons/tools.py +248 -0
  58. batoolset/luts/__init__.py +0 -0
  59. batoolset/luts/lut_minimal_test.py +1308 -0
  60. batoolset/luts/lutcreatorfromformula.py +209 -0
  61. batoolset/luts/luteditor.py +243 -0
  62. batoolset/pyqts/__init__.py +0 -0
  63. batoolset/pyqts/pleasewaitdialog.py +14 -0
  64. batoolset/pyqts/tools.py +760 -0
  65. batoolset/serializations/__init__.py +0 -0
  66. batoolset/serializations/tools.py +1338 -0
  67. batoolset/theme.py +647 -0
  68. batoolset/uis/__init__.py +0 -0
  69. batoolset/uis/blinker.py +56 -0
  70. batoolset_gui-0.2.0.dist-info/METADATA +54 -0
  71. batoolset_gui-0.2.0.dist-info/RECORD +74 -0
  72. batoolset_gui-0.2.0.dist-info/WHEEL +5 -0
  73. batoolset_gui-0.2.0.dist-info/licenses/LICENSE +24 -0
  74. 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