batoolset 0.1.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/list_gui.py +513 -0
- batoolset/GUI/multi_image_display.py +989 -0
- batoolset/GUI/open.py +325 -0
- batoolset/GUI/overlay_hints.py +45 -0
- batoolset/GUI/paint2.py +1345 -0
- batoolset/GUI/scrollablepaint.py +1152 -0
- batoolset/IJ_ROIs/__init__.py +0 -0
- batoolset/IJ_ROIs/tools.py +40 -0
- batoolset/PATH/__init__.py +0 -0
- batoolset/PATH/tools.py +79 -0
- batoolset/SQLite_tools/__init__.py +0 -0
- batoolset/SQLite_tools/tools.py +840 -0
- batoolset/__init__.py +0 -0
- batoolset/binary/__init__.py +0 -0
- batoolset/binary/tools.py +123 -0
- batoolset/binarytools/__init__.py +0 -0
- batoolset/binarytools/cell_center_detector.py +290 -0
- batoolset/clipboard_tools/__init__.py +0 -0
- batoolset/clipboard_tools/tools.py +7 -0
- batoolset/colors/__init__.py +0 -0
- batoolset/colors/colorgen.py +193 -0
- batoolset/colors/tools.py +22 -0
- batoolset/command_line/__init__.py +0 -0
- batoolset/command_line/tools.py +18 -0
- batoolset/dialogs/__init__.py +0 -0
- batoolset/dialogs/opensave.py +228 -0
- batoolset/dicts/__init__.py +0 -0
- batoolset/dicts/tools.py +299 -0
- batoolset/dims/__init__.py +0 -0
- batoolset/dims/tools.py +83 -0
- batoolset/draw/__init__.py +0 -0
- batoolset/draw/shapes/Position.py +183 -0
- batoolset/draw/shapes/__init__.py +0 -0
- batoolset/draw/shapes/automated_alignment_drawing_refactored.py +346 -0
- batoolset/draw/shapes/circle2d.py +99 -0
- batoolset/draw/shapes/compute_optimal_size_all_merged.py +317 -0
- batoolset/draw/shapes/ellipse2d.py +336 -0
- batoolset/draw/shapes/freehand2d.py +235 -0
- batoolset/draw/shapes/group.py +1830 -0
- batoolset/draw/shapes/image2d.py +2469 -0
- batoolset/draw/shapes/line2d.py +575 -0
- batoolset/draw/shapes/point2d.py +257 -0
- batoolset/draw/shapes/polygon2d.py +357 -0
- batoolset/draw/shapes/polyline2d.py +235 -0
- batoolset/draw/shapes/rect2d.py +388 -0
- batoolset/draw/shapes/rectangle2d.py +601 -0
- batoolset/draw/shapes/scalebar.py +304 -0
- batoolset/draw/shapes/serializablefont.py +126 -0
- batoolset/draw/shapes/serializableguiparams.py +10 -0
- batoolset/draw/shapes/square2d.py +103 -0
- batoolset/draw/shapes/textorientation.py +45 -0
- batoolset/draw/shapes/tools.py +467 -0
- batoolset/draw/shapes/transform2D.py +350 -0
- batoolset/draw/shapes/txt2d.py +550 -0
- batoolset/draw/widgets/__init__.py +0 -0
- batoolset/draw/widgets/col.py +343 -0
- batoolset/draw/widgets/image_group.py +248 -0
- batoolset/draw/widgets/image_organizer.py +96 -0
- batoolset/draw/widgets/paint.py +184 -0
- batoolset/draw/widgets/vectorial.py +257 -0
- batoolset/figure/__init__.py +0 -0
- batoolset/figure/alignment.py +814 -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/files/__init__.py +0 -0
- batoolset/files/tools.py +1321 -0
- batoolset/images/__init__.py +0 -0
- batoolset/images/tools.py +81 -0
- batoolset/img.py +5216 -0
- batoolset/linux/__init__.py +0 -0
- batoolset/linux/tools.py +72 -0
- batoolset/lists/__init__.py +0 -0
- batoolset/lists/tools.py +436 -0
- batoolset/luts/__init__.py +0 -0
- batoolset/luts/lut_minimal_test.py +1207 -0
- batoolset/matplolib/__init__.py +0 -0
- batoolset/matplolib/tools.py +44 -0
- batoolset/np_tools/__init__.py +0 -0
- batoolset/np_tools/tools.py +252 -0
- batoolset/np_tools/trash.py +15 -0
- batoolset/pandas_tools/__init__.py +0 -0
- batoolset/pandas_tools/tools.py +880 -0
- batoolset/partials/__init__.py +0 -0
- batoolset/partials/tools.py +83 -0
- batoolset/plot_tools/__init__.py +0 -0
- batoolset/plot_tools/tools.py +70 -0
- batoolset/pyqt/__init__.py +0 -0
- batoolset/pyqt/tools.py +691 -0
- batoolset/re_tools/__init__.py +0 -0
- batoolset/re_tools/tools.py +35 -0
- batoolset/serialization/__init__.py +0 -0
- batoolset/serialization/tools.py +1192 -0
- batoolset/sets/__init__.py +0 -0
- batoolset/sets/tools.py +109 -0
- batoolset/settings/__init__.py +0 -0
- batoolset/settings/global_settings.py +134 -0
- batoolset/strings/__init__.py +0 -0
- batoolset/strings/tools.py +225 -0
- batoolset/ta/__init__.py +0 -0
- batoolset/ta/database/__init__.py +0 -0
- batoolset/ta/database/advanced_sql_plotter.py +1170 -0
- batoolset/ta/database/my_qt_table.py +79 -0
- batoolset/ta/database/preview_and_edit_sqlite_db.py +405 -0
- batoolset/ta/database/sql.py +2141 -0
- batoolset/ta/database/sql_column_name_dialog.py +122 -0
- batoolset/ta/measurements/TAmeasures.py +2226 -0
- batoolset/ta/measurements/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/get_point_on_surface_if_centroid_is_bad.py +175 -0
- batoolset/ta/measurements/measurements3D/height_map_to_projection.py +82 -0
- batoolset/ta/measurements/measurements3D/measures3D.py +208 -0
- batoolset/ta/measurements/measurements3D/triangulate.py +331 -0
- batoolset/ta/measurements/nematic.py +562 -0
- batoolset/ta/measurements/nematic_measurements.py +107 -0
- batoolset/ta/segmentation/__init__.py +0 -0
- batoolset/ta/segmentation/neo_wshed.py +314 -0
- batoolset/ta/selections/__init__.py +0 -0
- batoolset/ta/selections/selection.py +329 -0
- batoolset/ta/tracking/__init__.py +0 -0
- batoolset/ta/tracking/last_tracking_based_on_matching_or_on_translation_from_mermaid_warp.py +653 -0
- batoolset/ta/tracking/local_to_track_correspondance.py +138 -0
- batoolset/ta/tracking/rapid_detection_of_vertices.py +517 -0
- batoolset/ta/tracking/registration.py +108 -0
- batoolset/ta/tracking/swap_detector_and_fixer.py +296 -0
- batoolset/ta/tracking/track_correction.py +238 -0
- batoolset/ta/tracking/tracking_error_detector_and_fixer.py +3099 -0
- batoolset/ta/tracking/tracking_yet_another_approach_pyramidal_registration_n_neo_swapping_correction.py +725 -0
- batoolset/ta/utils/TA_tools.py +43 -0
- batoolset/ta/utils/__init__.py +0 -0
- batoolset/ta/utils/rps_tools.py +1783 -0
- batoolset/tests/__init__.py +0 -0
- batoolset/tests/rps_tools.py +51 -0
- batoolset/tests/tools.py +10 -0
- batoolset/tools/__init__.py +0 -0
- batoolset/tools/early_stopper_class.py +9 -0
- batoolset/tools/guided_data_recoverer.py +110 -0
- batoolset/tools/logger.py +100 -0
- batoolset/tools/mytimer.py +31 -0
- batoolset/tools/prompt_color.py +160 -0
- batoolset/tools/qthandler.py +118 -0
- batoolset/uitools/__init__.py +0 -0
- batoolset/uitools/blinker.py +56 -0
- batoolset/unsafe/__init__.py +0 -0
- batoolset/unsafe/tools.py +115 -0
- batoolset/utils/__init__.py +0 -0
- batoolset/utils/commontools.py +158 -0
- batoolset/utils/loadlist.py +728 -0
- batoolset/version.py +10 -0
- batoolset/xml/__init__.py +0 -0
- batoolset/xml/tools.py +65 -0
- batoolset/zip_tools/__init__.py +0 -0
- batoolset/zip_tools/tools.py +76 -0
- batoolset-0.1.0.dist-info/LICENSE +24 -0
- batoolset-0.1.0.dist-info/METADATA +45 -0
- batoolset-0.1.0.dist-info/RECORD +162 -0
- batoolset-0.1.0.dist-info/WHEEL +5 -0
- batoolset-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1830 @@
|
|
|
1
|
+
# this seems to work better and better !!!
|
|
2
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
3
|
+
set_UI()
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
import numpy as np
|
|
6
|
+
# from batoolset.draw.shapes.vectorgraphics2d import VectorGraphics2D
|
|
7
|
+
from batoolset.img import Img
|
|
8
|
+
from batoolset.lists.tools import move_left, move_right, is_iterable
|
|
9
|
+
import random
|
|
10
|
+
import sys
|
|
11
|
+
import traceback
|
|
12
|
+
# this will replace cols or rows and will be able to do both but more flexibly
|
|
13
|
+
from timeit import default_timer as timer
|
|
14
|
+
from batoolset.serialization.tools import create_objects_from_dict
|
|
15
|
+
from batoolset.draw.shapes.image2d import Image2D
|
|
16
|
+
from batoolset.draw.shapes.rectangle2d import Rectangle2D
|
|
17
|
+
from batoolset.draw.shapes.txt2d import TAText2D
|
|
18
|
+
from qtpy.QtCore import QRectF, QSizeF,QPointF
|
|
19
|
+
from qtpy.QtWidgets import QApplication
|
|
20
|
+
from qtpy.QtGui import QPainter, QColor, QBrush, QPen, QTransform
|
|
21
|
+
from batoolset.figure.alignment import pack2, align2, align_positions
|
|
22
|
+
from batoolset.tests.tools import are_ratios_almost_equal
|
|
23
|
+
from batoolset.draw.shapes.compute_optimal_size_all_merged import resize_rects_within_total_width, \
|
|
24
|
+
resize_rects_within_total_height
|
|
25
|
+
|
|
26
|
+
ORIENTATIONS = ["X","Y"] #,"grid"
|
|
27
|
+
|
|
28
|
+
def get_all_contained_images(obj):
|
|
29
|
+
"""
|
|
30
|
+
Returns a list of all iterable elements in the given object.
|
|
31
|
+
"""
|
|
32
|
+
# print(is_iterable(obj), obj)
|
|
33
|
+
if is_iterable(obj):
|
|
34
|
+
# obj is an iterable, so iterate over its elements
|
|
35
|
+
elements = []
|
|
36
|
+
for element in obj:
|
|
37
|
+
elements.extend(get_all_contained_images(element))
|
|
38
|
+
# if not elements:
|
|
39
|
+
# return None
|
|
40
|
+
return elements
|
|
41
|
+
else:
|
|
42
|
+
# obj is not an iterable, so return an empty list
|
|
43
|
+
return [obj]
|
|
44
|
+
# if not inner_elements:
|
|
45
|
+
# return None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# def get_imprecision2(grp, desired_size):
|
|
49
|
+
# if grp.orientation == 'X':
|
|
50
|
+
# take the first immutable stuff
|
|
51
|
+
def get_iterable_elements(obj):
|
|
52
|
+
"""
|
|
53
|
+
Returns a list of all iterable elements in the given object.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
# print(is_iterable(obj), obj)
|
|
57
|
+
if is_iterable(obj):
|
|
58
|
+
# obj is an iterable, so iterate over its elements
|
|
59
|
+
elements = [obj]
|
|
60
|
+
for element in obj:
|
|
61
|
+
elements.extend(get_iterable_elements(element))
|
|
62
|
+
# if not elements:
|
|
63
|
+
# return None
|
|
64
|
+
return elements
|
|
65
|
+
else:
|
|
66
|
+
# obj is not an iterable, so return an empty list
|
|
67
|
+
return []
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def get_parent_of_obj(obj, shapes_to_draw):
|
|
71
|
+
if not shapes_to_draw:
|
|
72
|
+
return
|
|
73
|
+
if not isinstance(shapes_to_draw, list):
|
|
74
|
+
shapes_to_draw=[shapes_to_draw]
|
|
75
|
+
|
|
76
|
+
for shape in shapes_to_draw:
|
|
77
|
+
iterables = get_iterable_elements(shape)
|
|
78
|
+
if iterables:
|
|
79
|
+
for itr in iterables:
|
|
80
|
+
if obj in itr:
|
|
81
|
+
return itr
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# def get_imprecision(grp, desired_size=None):
|
|
85
|
+
# # first = grp[0]
|
|
86
|
+
# # last = grp[-1]
|
|
87
|
+
#
|
|
88
|
+
# # print('first.immutable',first.immutable, last.immutable)
|
|
89
|
+
# #
|
|
90
|
+
# # if first.immutable:
|
|
91
|
+
# # for elm in grp:
|
|
92
|
+
# # if not elm.immutable:
|
|
93
|
+
# # first=elm
|
|
94
|
+
# # break
|
|
95
|
+
# # if last.immutable:
|
|
96
|
+
# # for elm in grp[::-1]:
|
|
97
|
+
# # if not elm.immutable:
|
|
98
|
+
# # last=elm
|
|
99
|
+
# # break
|
|
100
|
+
# #
|
|
101
|
+
# # print('first',first, grp.content[1]) -−> indeed I cannot use that
|
|
102
|
+
#
|
|
103
|
+
# # imprecisionX = abs(first.getRect().height() - last.getRect().height())
|
|
104
|
+
# # imprecisionY = abs(first.getRect().width() - last.getRect().width())
|
|
105
|
+
# # imprecision = min(abs(imprecisionX), abs(imprecisionY))
|
|
106
|
+
# if desired_size:
|
|
107
|
+
# imprecisionX = abs(grp.getRect().height() - desired_size)
|
|
108
|
+
# imprecisionY = abs(grp.getRect().width() -desired_size)
|
|
109
|
+
# else:
|
|
110
|
+
# imprecisionX = abs(grp.getRect().height() - int(round(grp.getRect().height())))
|
|
111
|
+
# imprecisionY = abs(grp.getRect().width() - int(round(grp.getRect().width())))
|
|
112
|
+
#
|
|
113
|
+
# imprecision = min(abs(imprecisionX), abs(imprecisionY))
|
|
114
|
+
#
|
|
115
|
+
# print('imprecision in pixels X', imprecisionX)
|
|
116
|
+
# print('imprecision in pixels Y', imprecisionY)
|
|
117
|
+
# print('imprecision', imprecision)
|
|
118
|
+
|
|
119
|
+
# def set_to_size_old(grp, size, nb_of_repeats=26):
|
|
120
|
+
# # even at 100 I get a small imprecision -−> maybe forget about that shit and take 26 always # dirty but ok for now -> I have bigger things to fix --> I tried 100 and it is perfect but 10 already seems to be enough --> maybe that is ok then --> even 3 is ok
|
|
121
|
+
# # for some reason the stuff needs to be run several times to converge --> maybe some day I'll get the reason but it is ok and does not take time to do so!!!
|
|
122
|
+
# for i in range(nb_of_repeats):
|
|
123
|
+
# grp.set_to_size_old(size)
|
|
124
|
+
# grp.size = size
|
|
125
|
+
|
|
126
|
+
def set_to_size(grp, size, nb_of_repeats=26):
|
|
127
|
+
# even at 100 I get a small imprecision -−> maybe forget about that shit and take 26 always # dirty but ok for now -> I have bigger things to fix --> I tried 100 and it is perfect but 10 already seems to be enough --> maybe that is ok then --> even 3 is ok
|
|
128
|
+
# for some reason the stuff needs to be run several times to converge --> maybe some day I'll get the reason but it is ok and does not take time to do so!!!
|
|
129
|
+
for i in range(nb_of_repeats):
|
|
130
|
+
grp.set_to_size(size)
|
|
131
|
+
# grp.size = size
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def set_to_width(grp, desired_width, nb_of_repeats=26):
|
|
135
|
+
# in fact that was not so hard to do
|
|
136
|
+
# Calculate the current aspect ratio of the object
|
|
137
|
+
|
|
138
|
+
if grp.orientation != 'X':
|
|
139
|
+
for i in range(nb_of_repeats):
|
|
140
|
+
|
|
141
|
+
current_width = grp.getRect(all=True).width()
|
|
142
|
+
current_height = grp.getRect(all=True).height()
|
|
143
|
+
|
|
144
|
+
# print('falbala',current_width, current_height, desired_width)
|
|
145
|
+
if current_width < 0 or current_height<0:
|
|
146
|
+
# TODO --> KEEP DEV NOTE THIS PREVENTS INFINITE LOOPS WITH NEGATIVE VALUES
|
|
147
|
+
#
|
|
148
|
+
# current_width = grp.getRect().width()
|
|
149
|
+
# current_height = grp.getRect().height()
|
|
150
|
+
# print('falbala fixed', current_width, current_height, desired_width)
|
|
151
|
+
current_width = 512
|
|
152
|
+
current_height = 512
|
|
153
|
+
|
|
154
|
+
aspect_ratio = current_height / current_width if current_width != 0 else 0
|
|
155
|
+
|
|
156
|
+
factor_from_current_width_to_desired_width = desired_width/current_width
|
|
157
|
+
desired_height = current_height * factor_from_current_width_to_desired_width
|
|
158
|
+
|
|
159
|
+
# corresponding_desired_height = current_width * aspect_ratio
|
|
160
|
+
|
|
161
|
+
# corresponding_desired_height = current_width*aspect_ratio
|
|
162
|
+
# factor_from_current_width_to_predicted_height = corresponding_desired_height/
|
|
163
|
+
|
|
164
|
+
grp.set_to_size(desired_height)
|
|
165
|
+
grp.size = grp.width()
|
|
166
|
+
|
|
167
|
+
# print('aspect_ratio CURRENT CHECK ', aspect_ratio, grp.getRect(), desired_width, desired_height)
|
|
168
|
+
else:
|
|
169
|
+
set_to_size(grp, desired_width, nb_of_repeats=nb_of_repeats)
|
|
170
|
+
grp.size = grp.width()
|
|
171
|
+
|
|
172
|
+
def set_to_height(grp, desired_height, nb_of_repeats=26):
|
|
173
|
+
if grp.orientation != 'Y':
|
|
174
|
+
for i in range(nb_of_repeats):
|
|
175
|
+
current_width = grp.getRect(all=True).width()
|
|
176
|
+
current_height = grp.getRect(all=True).height()
|
|
177
|
+
|
|
178
|
+
# print('falbala',current_width, current_height, desired_width)
|
|
179
|
+
if current_width < 0 or current_height<0:
|
|
180
|
+
# TODO --> KEEP DEV NOTE THIS PREVENTS INFINITE LOOPS WITH NEGATIVE VALUES
|
|
181
|
+
#
|
|
182
|
+
# current_width = grp.getRect().width()
|
|
183
|
+
# current_height = grp.getRect().height()
|
|
184
|
+
# print('falbala fixed', current_width, current_height, desired_width)
|
|
185
|
+
current_width = 512
|
|
186
|
+
current_height = 512
|
|
187
|
+
|
|
188
|
+
aspect_ratio = current_width / current_height if current_height != 0 else 0
|
|
189
|
+
|
|
190
|
+
factor_from_current_height_to_desired_height = desired_height / current_height
|
|
191
|
+
desired_width = current_width * factor_from_current_height_to_desired_height
|
|
192
|
+
|
|
193
|
+
grp.set_to_size(desired_width)
|
|
194
|
+
grp.size = grp.height()
|
|
195
|
+
|
|
196
|
+
# print('aspect_ratio CURRENT CHECK ', aspect_ratio, grp.getRect(), desired_width, desired_height)
|
|
197
|
+
else:
|
|
198
|
+
set_to_size(grp, desired_height, nb_of_repeats=nb_of_repeats)
|
|
199
|
+
grp.size = grp.height()
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
# Calculate the new height based on the desired width and the aspect ratio
|
|
203
|
+
# new_height = desired_width * aspect_ratio
|
|
204
|
+
def set_to_width_im2d(rect, desired_width):
|
|
205
|
+
current_width = rect.width()
|
|
206
|
+
current_height = rect.height()
|
|
207
|
+
aspect_ratio = current_height / current_width if current_width != 0 else 0
|
|
208
|
+
|
|
209
|
+
factor_from_current_width_to_desired_width = desired_width / current_width
|
|
210
|
+
desired_height = current_height * factor_from_current_width_to_desired_width
|
|
211
|
+
|
|
212
|
+
# corresponding_desired_height = current_width * aspect_ratio
|
|
213
|
+
|
|
214
|
+
rect.set_to_scale(current_width / desired_width)
|
|
215
|
+
# corresponding_desired_height = current_width*aspect_ratio
|
|
216
|
+
# factor_from_current_width_to_predicted_height = corresponding_desired_height/
|
|
217
|
+
# grp.set_to_size(desired_height)
|
|
218
|
+
# return new_rect
|
|
219
|
+
|
|
220
|
+
def set_to_height_im2d(rect, desired_height):
|
|
221
|
+
# current_width = rect.width()
|
|
222
|
+
# current_height = rect.height()
|
|
223
|
+
# aspect_ratio = current_width / current_height if current_height != 0 else 0
|
|
224
|
+
#
|
|
225
|
+
# desired_width = current_width * (desired_height / current_height)
|
|
226
|
+
# rect.set_to_scale(1./(desired_width/desired_height))
|
|
227
|
+
|
|
228
|
+
current_width = rect.width()
|
|
229
|
+
current_height =rect.height()
|
|
230
|
+
aspect_ratio = current_width / current_height if current_height != 0 else 0
|
|
231
|
+
|
|
232
|
+
factor_from_current_height_to_desired_height = desired_height / current_height
|
|
233
|
+
desired_width = current_width * factor_from_current_height_to_desired_height
|
|
234
|
+
|
|
235
|
+
# grp.set_to_size(desired_width)
|
|
236
|
+
rect.set_to_scale(current_height/desired_height)
|
|
237
|
+
|
|
238
|
+
# new_rect = QRectF(rect.x(), rect.y(), desired_width, desired_height)
|
|
239
|
+
|
|
240
|
+
# return new_rect
|
|
241
|
+
|
|
242
|
+
# def set_to_width(grp, size, nb_of_repeats=26):
|
|
243
|
+
# for i in range(nb_of_repeats):
|
|
244
|
+
# grp.set_to_size(size)
|
|
245
|
+
|
|
246
|
+
def areIndicesOverlapping(indices_of_all_shapes):
|
|
247
|
+
|
|
248
|
+
# Iterate over the indices_of_all_shapes list
|
|
249
|
+
for i in range(len(indices_of_all_shapes) - 1):
|
|
250
|
+
# Get the current and next elements
|
|
251
|
+
curr = indices_of_all_shapes[i]
|
|
252
|
+
next = indices_of_all_shapes[i + 1]
|
|
253
|
+
|
|
254
|
+
# print('curr, next', curr, next)
|
|
255
|
+
|
|
256
|
+
# Check if the elements overlap
|
|
257
|
+
if curr[1] >= next[0]:
|
|
258
|
+
# print('Overlap found between elements', i, 'and', i + 1)
|
|
259
|
+
return True
|
|
260
|
+
return False
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class Group(Rectangle2D):
|
|
264
|
+
_count=0 # this is a class variable
|
|
265
|
+
|
|
266
|
+
# NB maybe is text could contain the text position instead of true such as above or below --> and it would adjust to stuff below it --> TODO
|
|
267
|
+
def __init__(self, *args, space=3, x=None,y=None, width=None, height=None, fill_color=None, content=None, orientation=ORIENTATIONS[0], size=512, isText=False, add_empty_images_instead_of_None=True,**kwargs): # TODO DO NOT CALL IT ORIENTATION AS IT CAN BE MIXED WITH ANGLE -−> NEED SMARTER NAME
|
|
268
|
+
# if kwargs:
|
|
269
|
+
# print('ignored parameters', kwargs)
|
|
270
|
+
|
|
271
|
+
if x is not None and y is not None and width is not None and height is not None:
|
|
272
|
+
super(Rectangle2D, self).__init__(x,y,width,height)
|
|
273
|
+
else:
|
|
274
|
+
super(Rectangle2D, self).__init__()
|
|
275
|
+
|
|
276
|
+
# if self.width() == 0 and self.height==0:
|
|
277
|
+
# self.setWidth(size)
|
|
278
|
+
# self.setHeight(size)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
# in fact I need to reload content
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
self.content = []
|
|
285
|
+
self.space = space
|
|
286
|
+
self.orientation=orientation
|
|
287
|
+
if args:
|
|
288
|
+
for arg in args:
|
|
289
|
+
if isinstance(arg, str):
|
|
290
|
+
arg = Image2D(arg) # TODO --> need make this smarter especially with custom code files
|
|
291
|
+
if arg is None and add_empty_images_instead_of_None:
|
|
292
|
+
if self.content:
|
|
293
|
+
last = self.content[-1]
|
|
294
|
+
if isinstance(last, Image2D):
|
|
295
|
+
w,h = last.get_raw_size()
|
|
296
|
+
tmp = Image2D(width=w, height=h, crop_left=last.crop_left, crop_right=last.crop_right,crop_top=last.crop_top,crop_bottom=last.crop_bottom, theta=last.theta) # a true clone of the last
|
|
297
|
+
self.content.append(tmp)
|
|
298
|
+
else:
|
|
299
|
+
if arg is not None:
|
|
300
|
+
self.content.append(arg)
|
|
301
|
+
|
|
302
|
+
if isinstance(content, dict):
|
|
303
|
+
# Reload content from serialized object
|
|
304
|
+
content = create_objects_from_dict(content)
|
|
305
|
+
self.content.extend(content)
|
|
306
|
+
|
|
307
|
+
# print(self.content)
|
|
308
|
+
# if size is not None:
|
|
309
|
+
self.size = size # maybe useful and I need to store that ??? -−> the good thing is that it will not change and so it is better
|
|
310
|
+
# set_to_size(self,size) # shall I use that ??? --> maybe ...
|
|
311
|
+
self.set_to_size(self.size) # very good but maybe I also need to update it
|
|
312
|
+
set_to_width(self, self.size) # for now force size in x only to simplify things
|
|
313
|
+
Group._count += 1
|
|
314
|
+
self.ID = Group._count
|
|
315
|
+
self.fill_color = fill_color
|
|
316
|
+
self.immutable = False
|
|
317
|
+
self.isText = isText # this is just for pure text groups (will have a different behaviour on double click)
|
|
318
|
+
# self.scale = 1
|
|
319
|
+
|
|
320
|
+
@classmethod
|
|
321
|
+
def reset_count(cls):
|
|
322
|
+
cls._count = 0
|
|
323
|
+
|
|
324
|
+
# List-like behavior
|
|
325
|
+
def __getitem__(self, key):
|
|
326
|
+
# print(key)
|
|
327
|
+
return self.content[key]
|
|
328
|
+
|
|
329
|
+
def __len__(self):
|
|
330
|
+
return len(self.content)
|
|
331
|
+
|
|
332
|
+
def __iter__(self):
|
|
333
|
+
return iter(self.content)
|
|
334
|
+
|
|
335
|
+
def index(self, item):
|
|
336
|
+
return self.content.index(item)
|
|
337
|
+
# def __delitem__(self, index):
|
|
338
|
+
# del self[index]
|
|
339
|
+
#
|
|
340
|
+
def remove(self, *value):
|
|
341
|
+
|
|
342
|
+
try:
|
|
343
|
+
|
|
344
|
+
# print('stuff to be removed', value)
|
|
345
|
+
|
|
346
|
+
# del self.content(value)
|
|
347
|
+
# idx = self.content.index(value)
|
|
348
|
+
# del self[idx]
|
|
349
|
+
# self.content.remove(value)
|
|
350
|
+
# self.content = [x for x in self.content if x not in value]
|
|
351
|
+
for element in value:
|
|
352
|
+
try:
|
|
353
|
+
self.content.remove(element)
|
|
354
|
+
except:
|
|
355
|
+
pass
|
|
356
|
+
for inner in self.content:
|
|
357
|
+
try:
|
|
358
|
+
inner.remove(*value)
|
|
359
|
+
if inner.isEmpty():
|
|
360
|
+
self.content.remove(inner)
|
|
361
|
+
except:
|
|
362
|
+
pass
|
|
363
|
+
|
|
364
|
+
if not self.isEmpty():
|
|
365
|
+
try:
|
|
366
|
+
# print('resizing', self, self.content)
|
|
367
|
+
set_to_size(self,self.width() if self.orientation == 'X' else self.height())
|
|
368
|
+
except:
|
|
369
|
+
# print('just for info for now, comment that lines in the future')
|
|
370
|
+
traceback.print_exc()
|
|
371
|
+
print('just for info for now, comment that lines in the future')
|
|
372
|
+
pass
|
|
373
|
+
# i need go through all the stuff inside --> not that easy
|
|
374
|
+
# shall I resize it ??? TODO --> PROBABLY YES BECAUSE SIMPLER
|
|
375
|
+
|
|
376
|
+
except:
|
|
377
|
+
traceback.print_exc()
|
|
378
|
+
pass
|
|
379
|
+
|
|
380
|
+
def update(self):
|
|
381
|
+
try:
|
|
382
|
+
if not self.isEmpty():
|
|
383
|
+
# print('updating', self, self.content)
|
|
384
|
+
# set_to_size(self, self.width() if self.orientation == 'X' else self.height())
|
|
385
|
+
set_to_size(self, self.size)
|
|
386
|
+
except:
|
|
387
|
+
traceback.print_exc()
|
|
388
|
+
print('just for info for now, comment that lines in the future')
|
|
389
|
+
pass
|
|
390
|
+
|
|
391
|
+
def isEmpty(self):
|
|
392
|
+
return not self.content
|
|
393
|
+
|
|
394
|
+
def pack(self):
|
|
395
|
+
pack2(self.space, self.orientation,False, *self.content)
|
|
396
|
+
|
|
397
|
+
def align(self):
|
|
398
|
+
if self.orientation == 'X':
|
|
399
|
+
align2(align_positions[0], *self.content) # align top
|
|
400
|
+
else:
|
|
401
|
+
align2(align_positions[2], *self.content) # align Left
|
|
402
|
+
|
|
403
|
+
def set_to_scale(self, scale):
|
|
404
|
+
# the set to scale should change the size of the object --> either in width or in height depending on the object
|
|
405
|
+
# TODO
|
|
406
|
+
# maybe need repack if it is a group
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
# print('I have been called', scale)
|
|
410
|
+
|
|
411
|
+
# the scale of this one has to be magic and launch many more stuff
|
|
412
|
+
|
|
413
|
+
if self.orientation == 'X':
|
|
414
|
+
self.set_to_size(self.width() / scale)
|
|
415
|
+
else:
|
|
416
|
+
self.set_to_size(self.height()/scale)
|
|
417
|
+
# self.scale = 1
|
|
418
|
+
# pass
|
|
419
|
+
|
|
420
|
+
# def set_to_size_neo(self, desired_size):
|
|
421
|
+
# all_ok=False
|
|
422
|
+
#
|
|
423
|
+
# for elm in self:
|
|
424
|
+
# if elm.isText:
|
|
425
|
+
# all_ok=True
|
|
426
|
+
# break
|
|
427
|
+
#
|
|
428
|
+
# # print('all_ok', all_ok)
|
|
429
|
+
#
|
|
430
|
+
# if not all_ok:
|
|
431
|
+
# return self.set_to_size_old(desired_size)
|
|
432
|
+
#
|
|
433
|
+
# if self.orientation == 'X':
|
|
434
|
+
# max_w = 0
|
|
435
|
+
# max_h = 0
|
|
436
|
+
# failed_images = []
|
|
437
|
+
# text_images = []
|
|
438
|
+
# individual_width = []
|
|
439
|
+
# individual_height = []
|
|
440
|
+
# for elm in self:
|
|
441
|
+
# # try:
|
|
442
|
+
# if elm.isText:
|
|
443
|
+
# individual_width.append(elm.annotations[0].width(all=True))
|
|
444
|
+
# individual_height.append(elm.annotations[0].height(all=True))
|
|
445
|
+
# max_w = max(elm.annotations[0].width(all=True), max_w)
|
|
446
|
+
# max_h = max(elm.annotations[0].height(all=True), max_h)
|
|
447
|
+
# text_images.append(elm)
|
|
448
|
+
# else:
|
|
449
|
+
# # pass # if fails this is not a text image
|
|
450
|
+
# failed_images.append(elm) # if image is failed then we have it
|
|
451
|
+
#
|
|
452
|
+
# # I need to fit to the desired width
|
|
453
|
+
# desired_width = desired_size
|
|
454
|
+
# target_width_without_txt = desired_width - sum(individual_width)
|
|
455
|
+
#
|
|
456
|
+
# # fit into a group with the desired stuff
|
|
457
|
+
#
|
|
458
|
+
# print('max_w, max_h', max_w, max_h)
|
|
459
|
+
# print('individual_width', individual_width)
|
|
460
|
+
# print('individual_height', individual_height)
|
|
461
|
+
# print('desired_width', desired_width)
|
|
462
|
+
# print('target_width_without_txt',
|
|
463
|
+
# target_width_without_txt) # it is probably a bit more complex because I need also the spacer and the nb of elems of the spacer inside and outside
|
|
464
|
+
# print('elems in', len(failed_images))
|
|
465
|
+
# print('elems out', len(self) - len(failed_images))
|
|
466
|
+
# # try to do the fit --> TODO
|
|
467
|
+
#
|
|
468
|
+
# # TODO --> pack to the size
|
|
469
|
+
# # incompressible_space_of_group = (len(self.paint.EZFIG_panel.selected_shape)-1)*3
|
|
470
|
+
# incompressible_space_of_group = (len(text_images)) * self.space
|
|
471
|
+
# target_width_without_txt -= incompressible_space_of_group
|
|
472
|
+
#
|
|
473
|
+
# # I need fit the stuff
|
|
474
|
+
#
|
|
475
|
+
# # create a sub group for the failed images and set its size
|
|
476
|
+
# tmp = Group(*failed_images, space=self.space, orientation='X', size=target_width_without_txt)
|
|
477
|
+
# set_to_width(tmp, target_width_without_txt)
|
|
478
|
+
#
|
|
479
|
+
# # then get the height of the group
|
|
480
|
+
#
|
|
481
|
+
# max_h = tmp.height()
|
|
482
|
+
# # put the other images back into their stuff and just launch the packing of the group
|
|
483
|
+
# # and resize the images to that size
|
|
484
|
+
#
|
|
485
|
+
# for iii, elm in enumerate(text_images):
|
|
486
|
+
# # elm.scale=1.
|
|
487
|
+
# elm.setHeight(max_h)
|
|
488
|
+
# elm.setWidth(individual_width[iii])
|
|
489
|
+
# elm.set_to_scale(1)
|
|
490
|
+
#
|
|
491
|
+
# self.pack()
|
|
492
|
+
# self.align()
|
|
493
|
+
# self.update_bounds()
|
|
494
|
+
# # self.update()
|
|
495
|
+
# else:
|
|
496
|
+
#
|
|
497
|
+
#
|
|
498
|
+
# print('entering orientation Y', self)
|
|
499
|
+
# # this works but the embeded does not --> why is that
|
|
500
|
+
#
|
|
501
|
+
# # i need to fit all the shapes without the stuff to the desired width then just readd the other stuff
|
|
502
|
+
#
|
|
503
|
+
# # I need get the height
|
|
504
|
+
#
|
|
505
|
+
# # ça marche --> ça donne un moyen facile de faire tout ce que je voulais
|
|
506
|
+
# # now we fix the code so that we fit the height of an object according to that of the others --> TODO
|
|
507
|
+
# max_w = 0
|
|
508
|
+
# max_h = 0
|
|
509
|
+
# failed_images = []
|
|
510
|
+
# text_images = []
|
|
511
|
+
# individual_width = []
|
|
512
|
+
# individual_height = []
|
|
513
|
+
# for elm in self:
|
|
514
|
+
# if elm.isText:
|
|
515
|
+
# individual_width.append(elm.annotations[0].width(all=True))
|
|
516
|
+
# individual_height.append(elm.annotations[0].height(all=True))
|
|
517
|
+
# max_w = max(elm.annotations[0].width(all=True), max_w)
|
|
518
|
+
# max_h = max(elm.annotations[0].height(all=True), max_h)
|
|
519
|
+
# text_images.append(elm)
|
|
520
|
+
# else:
|
|
521
|
+
# # pass # if fails this is not a text image
|
|
522
|
+
# failed_images.append(elm) # if image is failed then we have it
|
|
523
|
+
#
|
|
524
|
+
# # I need to fit to the desired width
|
|
525
|
+
# desired_width = desired_size # 256 #
|
|
526
|
+
# target_width_without_txt = desired_width # since it is a col it does not need all of that
|
|
527
|
+
#
|
|
528
|
+
# # fit into a group with the desired stuff
|
|
529
|
+
#
|
|
530
|
+
# print('max_w, max_h', max_w, max_h)
|
|
531
|
+
# print('individual_width', individual_width)
|
|
532
|
+
# print('individual_height', individual_height)
|
|
533
|
+
# print('desired_width', desired_width)
|
|
534
|
+
# print('target_width_without_txt',
|
|
535
|
+
# target_width_without_txt) # it is probably a bit more complex because I need also the spacer and the nb of elems of the spacer inside and outside
|
|
536
|
+
# print('elems in', len(failed_images))
|
|
537
|
+
# print('elems out', len(self) - len(failed_images))
|
|
538
|
+
# # try to do the fit --> TODO
|
|
539
|
+
#
|
|
540
|
+
# # TODO --> pack to the size
|
|
541
|
+
# # incompressible_space_of_group = (len(self.paint.EZFIG_panel.selected_shape)-1)*3
|
|
542
|
+
# incompressible_space_of_group = (len(text_images)) * 3
|
|
543
|
+
# # target_width_without_txt -= incompressible_space_of_group
|
|
544
|
+
#
|
|
545
|
+
# # I need fit the stuff
|
|
546
|
+
#
|
|
547
|
+
# # create a sub group for the failed images and set its size
|
|
548
|
+
# tmp = Group(*failed_images, space=3, orientation='X')
|
|
549
|
+
# set_to_width(tmp, target_width_without_txt)
|
|
550
|
+
#
|
|
551
|
+
# # then get the height of the group
|
|
552
|
+
#
|
|
553
|
+
# max_w = tmp.width()
|
|
554
|
+
# # put the other images back into their stuff and just launch the packing of the group
|
|
555
|
+
# # and resize the images to that size
|
|
556
|
+
#
|
|
557
|
+
# for iii, elm in enumerate(text_images):
|
|
558
|
+
# # elm.scale=1.
|
|
559
|
+
# elm.setHeight(individual_height[iii])
|
|
560
|
+
# elm.setWidth(max_w)
|
|
561
|
+
# elm.set_to_scale(1)
|
|
562
|
+
#
|
|
563
|
+
#
|
|
564
|
+
#
|
|
565
|
+
# # del tmp
|
|
566
|
+
# # just pack the shape and nothing else and set x to 0
|
|
567
|
+
# # align top and pack
|
|
568
|
+
# # self.paint.EZFIG_panel.selected_shape.pack()
|
|
569
|
+
# # self.paint.EZFIG_panel.selected_shape.align()
|
|
570
|
+
# # self.paint.EZFIG_panel.selected_shape.update_bounds()
|
|
571
|
+
#
|
|
572
|
+
# set_to_width(self, target_width_without_txt)
|
|
573
|
+
#
|
|
574
|
+
# print('inner update', self.update_bounds())
|
|
575
|
+
|
|
576
|
+
def set_to_size(self, desired_size):
|
|
577
|
+
sum_along_axis = self.get_incompressible_size(axis=self.orientation)
|
|
578
|
+
if self.orientation == 'X':
|
|
579
|
+
resize_rects_within_total_width(self.content, desired_size, sum_along_axis)
|
|
580
|
+
# resize_rects_within_total_width(self.content, desired_size, self.space)
|
|
581
|
+
else:
|
|
582
|
+
# resize_rects_within_total_height(self.content, desired_size, self.space)
|
|
583
|
+
resize_rects_within_total_height(self.content, desired_size, sum_along_axis)
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
# if True:
|
|
587
|
+
# print('beforesdsqdq0')
|
|
588
|
+
# self.check_coords()
|
|
589
|
+
|
|
590
|
+
self.pack()
|
|
591
|
+
# if True:
|
|
592
|
+
# print('beforesdsqdq1')
|
|
593
|
+
# self.check_coords()
|
|
594
|
+
|
|
595
|
+
self.align()
|
|
596
|
+
# if True:
|
|
597
|
+
# print('beforesdsqdq2')
|
|
598
|
+
# self.check_coords()
|
|
599
|
+
self.update_bounds()
|
|
600
|
+
|
|
601
|
+
# def set_to_size_old(self, desired_size):
|
|
602
|
+
# # for i in range(100): # weird but somehow I need a convergence and iteration stuff (is that due to a bug, can I iterate in a smarter manner) ???
|
|
603
|
+
# # print('entering the real shit')
|
|
604
|
+
# sum_along_axis = self.get_incompressible_size(axis=self.orientation)
|
|
605
|
+
# if self.orientation == 'X':
|
|
606
|
+
# resize_rects_within_total_width(self.content, desired_size, sum_along_axis)
|
|
607
|
+
# # resize_rects_within_total_width(self.content, desired_size, self.space)
|
|
608
|
+
# else:
|
|
609
|
+
# # resize_rects_within_total_height(self.content, desired_size, self.space)
|
|
610
|
+
# resize_rects_within_total_height(self.content, desired_size, sum_along_axis)
|
|
611
|
+
#
|
|
612
|
+
# # if True:
|
|
613
|
+
# # print('beforesdsqdq0')
|
|
614
|
+
# # self.check_coords()
|
|
615
|
+
#
|
|
616
|
+
# self.pack()
|
|
617
|
+
# # if True:
|
|
618
|
+
# # print('beforesdsqdq1')
|
|
619
|
+
# # self.check_coords()
|
|
620
|
+
#
|
|
621
|
+
# self.align()
|
|
622
|
+
# # if True:
|
|
623
|
+
# # print('beforesdsqdq2')
|
|
624
|
+
# # self.check_coords()
|
|
625
|
+
# self.update_bounds()
|
|
626
|
+
|
|
627
|
+
def check_coords(self):
|
|
628
|
+
for iii,img in enumerate(self):
|
|
629
|
+
print('iii', iii, '-->', img.getRect())
|
|
630
|
+
|
|
631
|
+
def checkAR(self):
|
|
632
|
+
for iii, rect in enumerate(self.content):
|
|
633
|
+
print(are_ratios_almost_equal(rect.width() / rect.height(), rect.width(all=True) / rect.height(all=True)), 'old AR', rect.width() / rect.height(), 'new AR', rect.width(all=True) / rect.height(all=True))
|
|
634
|
+
|
|
635
|
+
# NB THE RECT AND WIDTH OF GROUP SHOULD NOT BE SCALABLE !!! --> see how I can do this in a cleaner way !!!!
|
|
636
|
+
def getRect(self,*args, **kwargs):
|
|
637
|
+
# if args or kwargs:
|
|
638
|
+
return QRectF(self.x(), self.y(), self.width(), self.height())
|
|
639
|
+
# else:
|
|
640
|
+
# # return super().getRect()
|
|
641
|
+
# return QRectF(*super().getRect())
|
|
642
|
+
def width(self,*args, **kwargs):
|
|
643
|
+
# return self.width()
|
|
644
|
+
# else:
|
|
645
|
+
return super().width()
|
|
646
|
+
|
|
647
|
+
def height(self,*args, **kwargs):
|
|
648
|
+
# if args or kwargs:
|
|
649
|
+
# return self.height()
|
|
650
|
+
# else:
|
|
651
|
+
return super().height()
|
|
652
|
+
|
|
653
|
+
def update_bounds(self):
|
|
654
|
+
# Initialize bounding_rect with maximum and minimum values
|
|
655
|
+
bounding_rect = [float('inf'), float('inf'), float('-inf'), float('-inf')]
|
|
656
|
+
|
|
657
|
+
for rect in self.content:
|
|
658
|
+
bounding_rect[0] = min(bounding_rect[0], rect.x())
|
|
659
|
+
bounding_rect[1] = min(bounding_rect[1], rect.y())
|
|
660
|
+
bounding_rect[2] = max(bounding_rect[2], rect.x() + rect.width(all=True))
|
|
661
|
+
bounding_rect[3] = max(bounding_rect[3], rect.y() + rect.height(all=True))
|
|
662
|
+
|
|
663
|
+
self.setRect(bounding_rect[0], bounding_rect[1], bounding_rect[2] - bounding_rect[0],
|
|
664
|
+
bounding_rect[3] - bounding_rect[1])
|
|
665
|
+
# print('bounding rect', self.getRect(scale=True))
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
def getCombinedBoundsAtIndices(self, image_indices):
|
|
671
|
+
if not image_indices:
|
|
672
|
+
return None
|
|
673
|
+
# if isinstance(image_indices, int):
|
|
674
|
+
# in
|
|
675
|
+
# for each there will be a begin and an end
|
|
676
|
+
begin, end = image_indices
|
|
677
|
+
# if begin == end:
|
|
678
|
+
# print('same begin and end')
|
|
679
|
+
|
|
680
|
+
# print('begin, end', begin, end)
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
# how can I keep assocition despite serialization --> by storing the element into another --> but that would complicate a bit the things though -−> see how I can do that
|
|
685
|
+
# or just say if it should be associated to above or below ????
|
|
686
|
+
if begin>end: # begin should always be before end
|
|
687
|
+
begin, end = end, begin
|
|
688
|
+
|
|
689
|
+
if begin<0:
|
|
690
|
+
begin = 0
|
|
691
|
+
if end>=len(self.content):
|
|
692
|
+
end = len(self.content)-1
|
|
693
|
+
if end<0:
|
|
694
|
+
end=0
|
|
695
|
+
|
|
696
|
+
if begin>=0 and begin<len(self.content):
|
|
697
|
+
begin_rect = self.content[begin].getRect(all=True)
|
|
698
|
+
# print('begin_rect',begin_rect)
|
|
699
|
+
if begin==end:
|
|
700
|
+
return begin_rect
|
|
701
|
+
if end>=0 and end < len(self.content):
|
|
702
|
+
end_rect = self.content[end].getRect(all=True)
|
|
703
|
+
# print('end_rect',end_rect)
|
|
704
|
+
|
|
705
|
+
try:
|
|
706
|
+
return begin_rect.united(end_rect) # this returns the combined rect of begin and end coordinates -−> that is exactly what I want
|
|
707
|
+
except:
|
|
708
|
+
return None
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
# untested
|
|
713
|
+
def translate(self, *args):
|
|
714
|
+
if len(args) == 1:
|
|
715
|
+
point = args[0]
|
|
716
|
+
QRectF.translate(self, point.x(), point.y())
|
|
717
|
+
for img in self:
|
|
718
|
+
img.translate(point.x(), point.y())
|
|
719
|
+
else:
|
|
720
|
+
QRectF.translate(self, args[0], args[1])
|
|
721
|
+
for img in self:
|
|
722
|
+
img.translate(QPointF(args[0], args[1]))
|
|
723
|
+
|
|
724
|
+
# def swap(self, element1, element2): # so in fact it is not a swap it is a replace
|
|
725
|
+
# find element1 and replace it with element2
|
|
726
|
+
# swap can be seen as a chain of replace with inverting one by the other
|
|
727
|
+
|
|
728
|
+
# def replace(self, element1, element2):
|
|
729
|
+
# pass
|
|
730
|
+
|
|
731
|
+
# def swap(self, element1, element2):
|
|
732
|
+
# loop
|
|
733
|
+
# if not isinstance(__args[0], QPointF):
|
|
734
|
+
# for elm in self.content:
|
|
735
|
+
# if elm == __args[0]:
|
|
736
|
+
# return True
|
|
737
|
+
# if elm.contains(__args[0]):
|
|
738
|
+
# return True
|
|
739
|
+
# else:
|
|
740
|
+
# if super().contains(
|
|
741
|
+
# *__args): # if anything in there contains the point return the containing element else return False
|
|
742
|
+
# for elm in self.content:
|
|
743
|
+
# if elm.contains(*__args):
|
|
744
|
+
# return elm
|
|
745
|
+
# return True
|
|
746
|
+
# return False
|
|
747
|
+
|
|
748
|
+
def move_left(self, elements, distance=1):
|
|
749
|
+
if elements is None:
|
|
750
|
+
return
|
|
751
|
+
if distance <=0:
|
|
752
|
+
return
|
|
753
|
+
if not isinstance(elements, list):
|
|
754
|
+
elements = [elements]
|
|
755
|
+
|
|
756
|
+
list_of_iterables = get_iterable_elements(self)
|
|
757
|
+
for elm in list_of_iterables:
|
|
758
|
+
indices = [i for i, x in enumerate(elm.content) if x in elements]
|
|
759
|
+
elm.content = move_left(elm.content, indices, distance) # get indices
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
# TODO --> do it recursive inside -−> TODO
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
def move_right(self, elements, distance=1):
|
|
766
|
+
if elements is None:
|
|
767
|
+
return
|
|
768
|
+
if distance <=0:
|
|
769
|
+
return
|
|
770
|
+
if not isinstance(elements, list):
|
|
771
|
+
elements = [elements]
|
|
772
|
+
# indices = [i for i, x in enumerate(self.content) if x in elements]
|
|
773
|
+
# self.content = move_right(self.content, indices, distance) # get indices
|
|
774
|
+
list_of_iterables = get_iterable_elements(self)
|
|
775
|
+
for elm in list_of_iterables:
|
|
776
|
+
indices = [i for i, x in enumerate(elm.content) if x in elements]
|
|
777
|
+
elm.content = move_right(elm.content, indices, distance) # get indices
|
|
778
|
+
|
|
779
|
+
def draw_inner_layout_selection(self, painter):
|
|
780
|
+
painter.save()
|
|
781
|
+
try:
|
|
782
|
+
inner_elements = get_all_contained_images(self)
|
|
783
|
+
# painter.setPen(QPen(QColor(0, 255, 255)))
|
|
784
|
+
|
|
785
|
+
for elm in inner_elements:
|
|
786
|
+
# rect = elm.getRect(scale=True)
|
|
787
|
+
# painter.drawRect(rect)
|
|
788
|
+
elm.draw_inner_layout_selection(painter)
|
|
789
|
+
except:
|
|
790
|
+
print('inner error')
|
|
791
|
+
traceback.print_exc()
|
|
792
|
+
painter.restore()
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
def draw(self, painter, draw=True):
|
|
796
|
+
|
|
797
|
+
if draw:
|
|
798
|
+
painter.save()
|
|
799
|
+
rect_to_plot = self.getRect()
|
|
800
|
+
if self.fill_color is not None:
|
|
801
|
+
# if the user wants to really draw a bg with a given color between the images -−> then I draw this first before drawing anything else
|
|
802
|
+
painter.setBrush(QBrush(QColor(self.fill_color)))
|
|
803
|
+
painter.drawRect(rect_to_plot)
|
|
804
|
+
|
|
805
|
+
for img in self:
|
|
806
|
+
img.draw(painter, draw=draw)
|
|
807
|
+
|
|
808
|
+
painter.restore()
|
|
809
|
+
|
|
810
|
+
# debug
|
|
811
|
+
if False:
|
|
812
|
+
pen = QPen(QColor(0xFF00FF))
|
|
813
|
+
pen.setWidthF(3)
|
|
814
|
+
painter.setPen(pen)
|
|
815
|
+
|
|
816
|
+
# print('rect_to_plot',rect_to_plot)
|
|
817
|
+
|
|
818
|
+
painter.drawRect(rect_to_plot)
|
|
819
|
+
|
|
820
|
+
# as much as it is possible do get rid of fill to better organize the stuff
|
|
821
|
+
# def fill(self, painter, draw=True):
|
|
822
|
+
# if self.fill_color is None:
|
|
823
|
+
# return
|
|
824
|
+
# if draw:
|
|
825
|
+
# painter.save()
|
|
826
|
+
# for img in self:
|
|
827
|
+
# img.fill(painter, draw=draw)
|
|
828
|
+
# painter.restore()
|
|
829
|
+
#
|
|
830
|
+
# def drawAndFill(self, painter):
|
|
831
|
+
# painter.save()
|
|
832
|
+
# self.draw(painter, draw=True)
|
|
833
|
+
# painter.restore()
|
|
834
|
+
|
|
835
|
+
def get_incompressible_size(self, axis=None):
|
|
836
|
+
# return the meaningful incompressible state of the image
|
|
837
|
+
# pass
|
|
838
|
+
# if self.orientation == 'X':
|
|
839
|
+
# print('group_count', self._count)
|
|
840
|
+
if axis is None:
|
|
841
|
+
# print('sum_incompressible_along_axis2', self.space*(len(self.content)-1))
|
|
842
|
+
return self.space*(len(self.content)-1) # THAT IS NOT ENOUGH I ALSO NEED ALL THE PROGENY INCOMPRESSIBLE SPACE IN THIS ORIENTATION --> TODO
|
|
843
|
+
else:
|
|
844
|
+
sum_incompressible_along_axis = 0
|
|
845
|
+
|
|
846
|
+
# If I don't put the below line then the size works --> I am overestimating the stuff !!!
|
|
847
|
+
# for elm in self.content:
|
|
848
|
+
# sum_incompressible_along_axis+=elm.get_incompressible_size(axis=axis)
|
|
849
|
+
# for elm in self.content:
|
|
850
|
+
# sum_incompressible_along_axis+=elm.get_incompressible_size(axis=axis) # in fact I should not atke into account the others
|
|
851
|
+
if self.orientation == axis:
|
|
852
|
+
sum_incompressible_along_axis+=self.space*(len(self.content)-1)
|
|
853
|
+
# print('sum_incompressible_along_axis', axis, sum_incompressible_along_axis, len(self.content), self.space, self.orientation, self._count)
|
|
854
|
+
return sum_incompressible_along_axis
|
|
855
|
+
|
|
856
|
+
def setTopLeft(self, *args):
|
|
857
|
+
if args:
|
|
858
|
+
cur_top_left = self.topLeft()
|
|
859
|
+
# print('cur_top_left', cur_top_left, args)
|
|
860
|
+
if len(args)==1:
|
|
861
|
+
# # assume a QpointF
|
|
862
|
+
for img in self.content:
|
|
863
|
+
# img.moveTopLeft(args[0])
|
|
864
|
+
img.translate(args[0].x()-cur_top_left.x(), args[0].y()-cur_top_left.y())
|
|
865
|
+
elif len(args) == 2:
|
|
866
|
+
for img in self.content:
|
|
867
|
+
img.translate(args[0] - cur_top_left.x(), args[1] - cur_top_left.y())
|
|
868
|
+
self.update_bounds()
|
|
869
|
+
# elif len(args)==2:
|
|
870
|
+
# for img in self.content:
|
|
871
|
+
# img.moveTopLeft(QPointF(args[0], args[1]))
|
|
872
|
+
# else:
|
|
873
|
+
# # logger.error('invalid args for top left')
|
|
874
|
+
# print('invalid args for top left')
|
|
875
|
+
|
|
876
|
+
def replace(self, old, new): # NB THIS IS NOT RECURSIVE SO IT SHOULD BE USED ONLY WITH THE IMMEDIATE PARENT
|
|
877
|
+
if old in self.content:
|
|
878
|
+
self.content[self.content.index(old)]=new
|
|
879
|
+
|
|
880
|
+
def __contains__(self, item):
|
|
881
|
+
return item in self.content
|
|
882
|
+
|
|
883
|
+
def __setitem__(self, index, item):
|
|
884
|
+
self.content[index] = item
|
|
885
|
+
|
|
886
|
+
def contains(self, *__args):
|
|
887
|
+
# hacked contains that checks whether a point or an image is contained in the stuff
|
|
888
|
+
# see for images
|
|
889
|
+
|
|
890
|
+
# if not __args:
|
|
891
|
+
# return False
|
|
892
|
+
# if len(__args)==2:
|
|
893
|
+
# # check if an innner object contains a point and return it
|
|
894
|
+
# for elm in self.content:
|
|
895
|
+
# if elm.contains()
|
|
896
|
+
# else:
|
|
897
|
+
# if isinstance(__args[0],Rectangle2D):
|
|
898
|
+
# if self == __args[0]:
|
|
899
|
+
# return True
|
|
900
|
+
# else:
|
|
901
|
+
# return super().getRect(scale=True).contains(*__args)
|
|
902
|
+
|
|
903
|
+
if not isinstance(__args[0], QPointF):
|
|
904
|
+
for elm in self.content:
|
|
905
|
+
if elm == __args[0]:
|
|
906
|
+
# print('elm found by equal', elm, __args[0])
|
|
907
|
+
return True
|
|
908
|
+
try:
|
|
909
|
+
if __args[0] in elm: # I had to override contains in images to avoid issues
|
|
910
|
+
# print('elm found by other way', __args[0], elm, __args[0] in elm)
|
|
911
|
+
return True
|
|
912
|
+
except:
|
|
913
|
+
pass # if not iterable then anyway cannot contain the stuff
|
|
914
|
+
else:
|
|
915
|
+
if super().contains(*__args): # if anything in there contains the point return the containing element else return False
|
|
916
|
+
for elm in self.content:
|
|
917
|
+
if elm.contains(*__args):
|
|
918
|
+
return elm
|
|
919
|
+
return True
|
|
920
|
+
return False
|
|
921
|
+
|
|
922
|
+
def extend(self, lst):
|
|
923
|
+
try:
|
|
924
|
+
self.content.extend(lst)
|
|
925
|
+
except:
|
|
926
|
+
# self.content.add(lst) # in case it is not a list then just add is
|
|
927
|
+
self.add(lst)
|
|
928
|
+
|
|
929
|
+
def add(self, item):
|
|
930
|
+
self.content.append(item)
|
|
931
|
+
|
|
932
|
+
# be careful with that because this is what is compared when using == !!! so if poorly implemented this can have dramatic effects
|
|
933
|
+
def __str__(self):
|
|
934
|
+
# return f"group {self.ID}"
|
|
935
|
+
return self.__repr__()
|
|
936
|
+
|
|
937
|
+
def __repr__(self): # required to appear in the printed list
|
|
938
|
+
# return self.__str__()
|
|
939
|
+
class_name = type(self).__name__
|
|
940
|
+
memory_address = hex(id(self))
|
|
941
|
+
return f"{class_name}-{self.ID}-{memory_address}"
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
# probably the AR of the group should take into account the incompressible stuff --> this is why it is unfixed untill
|
|
946
|
+
# there is always a solution for 0 space --> how can I from the 0 space find all the other solutions???
|
|
947
|
+
if __name__ == '__main__':
|
|
948
|
+
img0 = Image2D('/E/Sample_images/counter/00.png')
|
|
949
|
+
img1 = Image2D('/E/Sample_images/counter/01.png')
|
|
950
|
+
img2 = Image2D('/E/Sample_images/counter/02.png')
|
|
951
|
+
img3 = Image2D('/E/Sample_images/counter/03.png')
|
|
952
|
+
img4 = Image2D('/E/Sample_images/counter/04.png')
|
|
953
|
+
img5 = Image2D('/E/Sample_images/counter/05.png')
|
|
954
|
+
img6 = Image2D('/E/Sample_images/counter/06.png')
|
|
955
|
+
img7 = Image2D('/E/Sample_images/counter/07.png')
|
|
956
|
+
img8 = Image2D('/E/Sample_images/counter/08.png')
|
|
957
|
+
img9 = Image2D('/E/Sample_images/counter/09.png')
|
|
958
|
+
img10 = Image2D('/E/Sample_images/counter/10.png')
|
|
959
|
+
img10b = Image2D('/E/Sample_images/counter/10.png')
|
|
960
|
+
if True:
|
|
961
|
+
grp1 = Group(Group(img0, img1, img2, img3), img4, Group(img5, Group(img6, img7, img8)), img9)
|
|
962
|
+
print(get_all_contained_images(grp1))
|
|
963
|
+
# print(get_iterable_elements(grp1))
|
|
964
|
+
sys.exit(0)
|
|
965
|
+
|
|
966
|
+
print('parent_of_obj',get_parent_of_obj(img9, grp1))
|
|
967
|
+
print('parent_of_obj',get_parent_of_obj(img4, grp1))
|
|
968
|
+
print('parent_of_obj',get_parent_of_obj(img0, grp1)) # there is a bug
|
|
969
|
+
print('parent_of_obj',get_parent_of_obj(img1, grp1))
|
|
970
|
+
print('parent_of_obj',get_parent_of_obj(img5, grp1))
|
|
971
|
+
print('parent_of_obj',get_parent_of_obj(img6, grp1))
|
|
972
|
+
print('parent_of_obj',get_parent_of_obj(img7, grp1))
|
|
973
|
+
print('parent_of_obj',get_parent_of_obj(img8, grp1))
|
|
974
|
+
|
|
975
|
+
sys.exit(0)
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
grp1 = Group(Group(img0,img1, img2, img3), img4, Group(img5, Group(img6, img7, img8)), img9)
|
|
980
|
+
# print('all_iterables',get_iterable_elements(grp1))
|
|
981
|
+
print(grp1.content)
|
|
982
|
+
print(grp1.content[0].content)
|
|
983
|
+
print(grp1.content[2].content)
|
|
984
|
+
print(grp1.content[2].content[1].content)
|
|
985
|
+
grp1.move_left([img1, img8, img9]) # really need to pass a list
|
|
986
|
+
print('out')
|
|
987
|
+
print(grp1.content)
|
|
988
|
+
print(grp1.content[0].content)
|
|
989
|
+
print(grp1.content[-1].content)
|
|
990
|
+
print(grp1.content[-1].content[1].content)
|
|
991
|
+
# print(grp1.content[2].content[1].content)
|
|
992
|
+
# print(grp1.content[2].content)
|
|
993
|
+
# print('bob')
|
|
994
|
+
grp1 = Group(img0,img1, img2, img3, img4,img5, img6, img7, img8, img9)
|
|
995
|
+
# print('all_iterables2', get_iterable_elements(grp1))
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
# sys.exit(0)
|
|
1002
|
+
print('old')
|
|
1003
|
+
grp1 = Group(img0, img1, img2, img3, img4, img5, img6, img7, img8, img9)
|
|
1004
|
+
print(grp1.content)
|
|
1005
|
+
grp1.move_left(img1) # really need to pass a list
|
|
1006
|
+
print(grp1.content)
|
|
1007
|
+
print('bob')
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
grp1 = Group(img0, img1, img2, img3, img4, img5, img6, img7, img8, img9)
|
|
1011
|
+
print(grp1.content)
|
|
1012
|
+
grp1.move_left([img0, img1, img6])
|
|
1013
|
+
print(grp1.content)
|
|
1014
|
+
|
|
1015
|
+
grp1 = Group(img0, img1, img2, img3, img4, img5, img6, img7, img8, img9)
|
|
1016
|
+
print(grp1.content)
|
|
1017
|
+
grp1.move_right([img0, img1, img6])
|
|
1018
|
+
print(grp1.content)
|
|
1019
|
+
|
|
1020
|
+
print('with errors and missing')
|
|
1021
|
+
grp1 = Group(img0, img2, img3, img4, img5, img6, img7, img8, img9)
|
|
1022
|
+
print(grp1.content)
|
|
1023
|
+
grp1.move_left([img2, img1, img6])
|
|
1024
|
+
print(grp1.content)
|
|
1025
|
+
|
|
1026
|
+
grp1 = Group(img0, img2, img3, img4, img5, img6, img7, img8, img9)
|
|
1027
|
+
print(grp1.content)
|
|
1028
|
+
grp1.move_right([img0, img1, img6])
|
|
1029
|
+
print(grp1.content)
|
|
1030
|
+
grp1.move_right([img0, img1, img6])
|
|
1031
|
+
print(grp1.content)
|
|
1032
|
+
for i in range(10):
|
|
1033
|
+
grp1.move_right([img0, img1, img6])
|
|
1034
|
+
print(grp1.content)
|
|
1035
|
+
sys.exit(0)
|
|
1036
|
+
|
|
1037
|
+
if True:
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
grp1 = Group(img0, img1)
|
|
1042
|
+
print(isinstance(grp1, list))
|
|
1043
|
+
print(isinstance(grp1, Group)) # very good
|
|
1044
|
+
grp2 = Group(img2, img3)
|
|
1045
|
+
grp1.extend(grp2)
|
|
1046
|
+
print(grp1.content)
|
|
1047
|
+
grp1.extend(img10b)
|
|
1048
|
+
print(grp1.content)
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
grp3 = Group(img4, img5)
|
|
1054
|
+
grp4 = Group(img6, img7)
|
|
1055
|
+
grp3.add(grp4)
|
|
1056
|
+
print(grp3.content)
|
|
1057
|
+
|
|
1058
|
+
grp5 = Group(img8, img9, img10)
|
|
1059
|
+
grp5.remove(img10)
|
|
1060
|
+
print(grp5.content)
|
|
1061
|
+
|
|
1062
|
+
grp5.add(Group(img10))
|
|
1063
|
+
print(grp5.content)
|
|
1064
|
+
grp5.remove(img10) # very good --> the parent group is empty
|
|
1065
|
+
print(grp5.content)
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
# for extend --> maybe autodelete stuff
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
sys.exit(0)
|
|
1084
|
+
|
|
1085
|
+
app = QApplication(sys.argv) # IMPORTANT KEEP !!!!!!!!!!! # required to use strings
|
|
1086
|
+
html = '''
|
|
1087
|
+
<!DOCTYPE html>
|
|
1088
|
+
<html>
|
|
1089
|
+
<head>
|
|
1090
|
+
<title>Font Face</title>
|
|
1091
|
+
</head>
|
|
1092
|
+
<body>
|
|
1093
|
+
<font color="red">
|
|
1094
|
+
<font face="Symbol" size="5">Symbol</font><br />
|
|
1095
|
+
<font face="Times New Roman" size="5">Times New Roman</font><br />
|
|
1096
|
+
<font face="Verdana" size="5">Verdana</font><br />
|
|
1097
|
+
<font face="Comic Sans MS" size="5">Comic Sans MS</font><br />
|
|
1098
|
+
<font face="WildWest" size="5">WildWest</font><br />
|
|
1099
|
+
<font face="Bedrock" size="5">Bedrock</font><br />
|
|
1100
|
+
</font>
|
|
1101
|
+
</body>
|
|
1102
|
+
</html>
|
|
1103
|
+
'''
|
|
1104
|
+
|
|
1105
|
+
html = '''
|
|
1106
|
+
<!DOCTYPE html>
|
|
1107
|
+
<html>
|
|
1108
|
+
<head>
|
|
1109
|
+
<title>Font Face</title>
|
|
1110
|
+
</head>
|
|
1111
|
+
<body>
|
|
1112
|
+
<font color="red">
|
|
1113
|
+
<font face="Symbol" size="5">Symbol</font><br />
|
|
1114
|
+
<font face="Times New Roman" size="5">Times New Roman</font><br />
|
|
1115
|
+
<font face="Bedrock" size="5">Bedrock</font><br />
|
|
1116
|
+
</font>
|
|
1117
|
+
</body>
|
|
1118
|
+
</html>
|
|
1119
|
+
'''
|
|
1120
|
+
|
|
1121
|
+
# this works super well -−> I can think of finalizing it very soon !!!
|
|
1122
|
+
|
|
1123
|
+
# VERY GOOD -−> TRY TO FIX ALL THE STUFF!!!
|
|
1124
|
+
|
|
1125
|
+
if True:
|
|
1126
|
+
# img1 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1127
|
+
# img2 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1128
|
+
# img3 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1129
|
+
# img4 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1130
|
+
|
|
1131
|
+
# img1 = Image2D(Img(np.zeros((256, 512)), dimensions='hw'))
|
|
1132
|
+
# img2 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1133
|
+
# img3 = Image2D(Img(np.zeros((256, 512)), dimensions='hw'))
|
|
1134
|
+
# img4 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1135
|
+
img1 = Image2D('/E/Sample_images/counter/00.png')
|
|
1136
|
+
img2 = Image2D('/E/Sample_images/counter/01.png')
|
|
1137
|
+
img3 = Image2D('/E/Sample_images/counter/02.png')
|
|
1138
|
+
img4 = Image2D('/E/Sample_images/counter/03.png')
|
|
1139
|
+
img5 = Image2D('/E/Sample_images/counter/05.png')
|
|
1140
|
+
img6 = Image2D('/E/Sample_images/counter/06.png')
|
|
1141
|
+
img7 = Image2D('/E/Sample_images/counter/07.png')
|
|
1142
|
+
img8 = Image2D('/E/Sample_images/counter/08.png')
|
|
1143
|
+
img9 = Image2D('/E/Sample_images/counter/09.png')
|
|
1144
|
+
|
|
1145
|
+
grp1 = Group(img1, img2)
|
|
1146
|
+
grp5 = Group(img5, img6, Group(img7, img8, orientation='Y'))
|
|
1147
|
+
grp2 = Group(img3, img4,grp5, orientation='Y')
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
grp3 = Group(grp1, grp2)
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
set_to_size(grp3,512)
|
|
1155
|
+
|
|
1156
|
+
point = random.choice([QPointF(64,64),QPointF(430,100)])
|
|
1157
|
+
print(point)
|
|
1158
|
+
elements_under_selection = []
|
|
1159
|
+
elm = grp3
|
|
1160
|
+
while elm:
|
|
1161
|
+
if isinstance(elm, bool):
|
|
1162
|
+
break
|
|
1163
|
+
elements_under_selection.append(elm)
|
|
1164
|
+
elm = elm.contains(point)
|
|
1165
|
+
print(elements_under_selection)
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
# this is the code to get all the elements below the stuff
|
|
1169
|
+
|
|
1170
|
+
# for elm in elements_under_selection:
|
|
1171
|
+
# print(type(elm))
|
|
1172
|
+
#
|
|
1173
|
+
# elm = grp3.contains(QPointF(64,64))
|
|
1174
|
+
# if elm:
|
|
1175
|
+
# print('contained',elm)
|
|
1176
|
+
# print(elm == img1)
|
|
1177
|
+
# print(elm == img2)
|
|
1178
|
+
# print(elm==grp1)
|
|
1179
|
+
# print(elm == grp2)
|
|
1180
|
+
# print(elm == grp3)
|
|
1181
|
+
# else:
|
|
1182
|
+
# print('not contained')
|
|
1183
|
+
#
|
|
1184
|
+
# elm = grp3.contains(QPointF(430,32))
|
|
1185
|
+
# if elm:
|
|
1186
|
+
# print('contained', elm)
|
|
1187
|
+
# print(elm == img1)
|
|
1188
|
+
# print(elm == img2)
|
|
1189
|
+
# print(elm == grp1)
|
|
1190
|
+
# print(elm == grp2)
|
|
1191
|
+
# print(elm == grp3)
|
|
1192
|
+
# else:
|
|
1193
|
+
# print('not contained')
|
|
1194
|
+
|
|
1195
|
+
# print(group._count)
|
|
1196
|
+
# print(grp3, grp2)
|
|
1197
|
+
|
|
1198
|
+
print('grp3.contains(img1)', grp3.contains(img1))
|
|
1199
|
+
print('grp3.contains(img1)', grp3.contains(img4))
|
|
1200
|
+
print('grp3.contains(img1)', grp3.contains(img8))
|
|
1201
|
+
print('#'*20)
|
|
1202
|
+
print('grp3.contains(img1)', grp1.contains(img1))
|
|
1203
|
+
print('grp3.contains(img1)', grp1.contains(img4))
|
|
1204
|
+
print('grp3.contains(img1)', grp2.contains(img1))
|
|
1205
|
+
print('grp3.contains(img1)', grp2.contains(img4))
|
|
1206
|
+
print('grp3.contains(img1)', grp2.contains(img8))
|
|
1207
|
+
|
|
1208
|
+
preview(grp3)
|
|
1209
|
+
|
|
1210
|
+
sys.exit(0)
|
|
1211
|
+
|
|
1212
|
+
if False:
|
|
1213
|
+
'''
|
|
1214
|
+
solution of a grp that has two images in a row and 2 images in a col
|
|
1215
|
+
PyQt6.QtCore.QRectF(0.0, 0.0, 511.99999999999994, 202.99999999999997)
|
|
1216
|
+
|
|
1217
|
+
###sub###
|
|
1218
|
+
PyQt6.QtCore.QRectF(0.0, 0.0, 408.99999999999994, 202.99999999999997)
|
|
1219
|
+
-−> PyQt6.QtCore.QRectF(0.0, 0.0, 202.99999999999997, 202.99999999999997)
|
|
1220
|
+
-−> PyQt6.QtCore.QRectF(205.99999999999997, 0.0, 202.99999999999997, 202.99999999999997)
|
|
1221
|
+
PyQt6.QtCore.QRectF(411.99999999999994, 0.0, 100.0, 202.99999999999997)
|
|
1222
|
+
-−> PyQt6.QtCore.QRectF(411.99999999999994, 0.0, 99.99999999999999, 99.99999999999999)
|
|
1223
|
+
-−> PyQt6.QtCore.QRectF(411.99999999999994, 102.99999999999999, 99.99999999999999, 99.99999999999999)
|
|
1224
|
+
|
|
1225
|
+
so each small rect in col should be 100*100 and each big rect should be 203*203
|
|
1226
|
+
|
|
1227
|
+
-> now figure the math for that
|
|
1228
|
+
|
|
1229
|
+
if I put all same size (no space) can I compute the rect and then adjust space so that it still fits ??? --> not so easy
|
|
1230
|
+
|
|
1231
|
+
total_uncompressible_width = 512-(3-1)*3 = 506
|
|
1232
|
+
target_height = 512/512+512/512+256/512 = 2.5 --> 202.4 --> I almost have it real AR for last is in fact 256/(512-3)
|
|
1233
|
+
|
|
1234
|
+
the real AR factor should be 2.492611 to get 202.9999999 of height for both col group and for --> how can I get there ????
|
|
1235
|
+
# there isn't probably any solution and I need iter but with a good initial guess
|
|
1236
|
+
# --> take AR by default and adjust
|
|
1237
|
+
|
|
1238
|
+
solution for two groups of 256x512 and 512x512 -−> 138.54
|
|
1239
|
+
PyQt6.QtCore.QRectF(0.0, 0.0, 512.0, 138.54545454545453)
|
|
1240
|
+
###sub###
|
|
1241
|
+
PyQt6.QtCore.QRectF(0.0, 0.0, 418.6363636363636, 138.54545454545453)
|
|
1242
|
+
-−> PyQt6.QtCore.QRectF(0.0, 0.0, 277.09090909090907, 138.54545454545453)
|
|
1243
|
+
-−> PyQt6.QtCore.QRectF(280.09090909090907, 0.0, 138.54545454545453, 138.54545454545453)
|
|
1244
|
+
PyQt6.QtCore.QRectF(421.6363636363636, 0.0, 90.36363636363637, 138.54545454545453)
|
|
1245
|
+
-−> PyQt6.QtCore.QRectF(421.6363636363636, 0.0, 90.36363636363636, 45.18181818181818)
|
|
1246
|
+
-−> PyQt6.QtCore.QRectF(421.6363636363636, 48.18181818181818, 90.36363636363636, 90.36363636363636)
|
|
1247
|
+
|
|
1248
|
+
total_uncompressible_width = 512-(3-1)*3 = 506
|
|
1249
|
+
target_height = 512/256+512/512+ 90.363636/138.54545454545454 --> 3.652231 -−> perfect --> that is this one --> I need do it like that --> not that hard in fact
|
|
1250
|
+
|
|
1251
|
+
# je dois trouver 3.6 --> ça ne marche pas du tout -> réflechir en fait
|
|
1252
|
+
|
|
1253
|
+
# how can I handle the incompressible texts--> see that later
|
|
1254
|
+
|
|
1255
|
+
'''
|
|
1256
|
+
img1 = Image2D(Img(np.zeros((512,512)), dimensions='hw'))
|
|
1257
|
+
img2 = Image2D(Img(np.zeros((512,512)), dimensions='hw'))
|
|
1258
|
+
img3 = Image2D(Img(np.zeros((512,512)), dimensions='hw'))
|
|
1259
|
+
img4 = Image2D(Img(np.zeros((512,512)), dimensions='hw'))
|
|
1260
|
+
|
|
1261
|
+
img1 = Image2D(Img(np.zeros((256, 512)), dimensions='hw'))
|
|
1262
|
+
img2 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1263
|
+
img3 = Image2D(Img(np.zeros((256, 512)), dimensions='hw'))
|
|
1264
|
+
img4 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1265
|
+
|
|
1266
|
+
grp1 = group(img1,img2)
|
|
1267
|
+
grp2 = group(img3, img4, orientation='Y')
|
|
1268
|
+
|
|
1269
|
+
grp3 = group(grp1, grp2)
|
|
1270
|
+
# grp3.set_to_size(512)
|
|
1271
|
+
set_to_size(grp3,512)
|
|
1272
|
+
|
|
1273
|
+
print(grp3.getRect())
|
|
1274
|
+
|
|
1275
|
+
print(grp3.get_incompressible_size(axis=grp3.orientation)) # --> 6 --> ok
|
|
1276
|
+
|
|
1277
|
+
get_imprecision(grp3,512) # --> imprecision of 3 pixels
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
print('###sub###')
|
|
1281
|
+
|
|
1282
|
+
for elm in grp3:
|
|
1283
|
+
print(elm.getRect(scale=True))
|
|
1284
|
+
for el in elm:
|
|
1285
|
+
print('-−> ', el.getRect(scale=True))
|
|
1286
|
+
|
|
1287
|
+
preview(grp3)
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
sys.exit(0)
|
|
1291
|
+
|
|
1292
|
+
if True:
|
|
1293
|
+
# that works
|
|
1294
|
+
|
|
1295
|
+
img1 = Image2D(Img(np.zeros((512,512)), dimensions='hw'))
|
|
1296
|
+
img2 = Image2D(Img(np.zeros((512,512)), dimensions='hw'))
|
|
1297
|
+
img3 = Image2D(Img(np.zeros((512,512)), dimensions='hw'))
|
|
1298
|
+
img4 = Image2D(Img(np.zeros((512,512)), dimensions='hw'))
|
|
1299
|
+
|
|
1300
|
+
img1 = Image2D(Img(np.zeros((256, 512)), dimensions='hw'))
|
|
1301
|
+
img2 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1302
|
+
img3 = Image2D(Img(np.zeros((256, 512)), dimensions='hw'))
|
|
1303
|
+
img4 = Image2D(Img(np.zeros((512, 512)), dimensions='hw'))
|
|
1304
|
+
|
|
1305
|
+
t = np.arange(0.0, 2.0, 0.01)
|
|
1306
|
+
s = 1 + np.sin(2 * np.pi * t)
|
|
1307
|
+
fig, ax = plt.subplots()
|
|
1308
|
+
ax.plot(t, s)
|
|
1309
|
+
|
|
1310
|
+
ax.set(xlabel='time (s)', ylabel='voltage (mV)', title=None)
|
|
1311
|
+
ax.grid()
|
|
1312
|
+
|
|
1313
|
+
# plt.show()
|
|
1314
|
+
# fig.savefig("test.png")
|
|
1315
|
+
# plt.show()
|
|
1316
|
+
# ça marche --> voici deux examples de shapes
|
|
1317
|
+
fig = VectorGraphics2D(fig, x=0, y=0, width=20., height=10.) # could also be used to create empty image with
|
|
1318
|
+
|
|
1319
|
+
svg = VectorGraphics2D('/E/Sample_images/EZF_SF_scientifig_EZFig/sample_images_svg/cartman.svg', x=12, y=0,
|
|
1320
|
+
width=1, height=1, fill_color=0xFFFFFF) # pb is I can change size if I don't put
|
|
1321
|
+
|
|
1322
|
+
# grp1 = group(img1,img2)
|
|
1323
|
+
# grp2 = group(img3, img4, orientation='Y')
|
|
1324
|
+
#
|
|
1325
|
+
# grp3 = group(grp1, grp2)
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
# grp3 = group(img3, fig, space=42, orientation=random.choice(['X','Y']), fill_color=0xFF00FF)
|
|
1329
|
+
# grp3 = group(img3,fig, img1,svg, space=3, orientation=random.choice(['X','Y']), fill_color=0xFF00FF)
|
|
1330
|
+
grp3 = group(img3,fig, img1, space=3, orientation=random.choice(['X','Y']), fill_color=0xFF00FF)
|
|
1331
|
+
|
|
1332
|
+
# grp3.set_to_size(512)
|
|
1333
|
+
set_to_size(grp3,1024)
|
|
1334
|
+
|
|
1335
|
+
print(grp3.getRect())
|
|
1336
|
+
|
|
1337
|
+
print(grp3.get_incompressible_size(axis=grp3.orientation)) # --> 6 --> ok
|
|
1338
|
+
|
|
1339
|
+
get_imprecision(grp3,512) # --> imprecision of 3 pixels
|
|
1340
|
+
|
|
1341
|
+
print('###sub###')
|
|
1342
|
+
|
|
1343
|
+
for elm in grp3:
|
|
1344
|
+
print(elm.getRect(all=True))
|
|
1345
|
+
try:
|
|
1346
|
+
for el in elm:
|
|
1347
|
+
print('-−> ', el.getRect(all=True))
|
|
1348
|
+
except:
|
|
1349
|
+
pass
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
|
|
1353
|
+
preview(grp3)
|
|
1354
|
+
|
|
1355
|
+
sys.exit(0)
|
|
1356
|
+
|
|
1357
|
+
if False:
|
|
1358
|
+
|
|
1359
|
+
# this now works I shouldn't take the text as immutable -−> I may need to resize the image every time text is added -−> need to think how I can do that
|
|
1360
|
+
# this is now broken because of immutable -> see how I can fix that
|
|
1361
|
+
|
|
1362
|
+
img1 = Image2D('/E/Sample_images/counter/01.png')
|
|
1363
|
+
img2 = Image2D('/E/Sample_images/counter/01.png')
|
|
1364
|
+
img3 = Image2D('/E/Sample_images/counter/02.png')
|
|
1365
|
+
text = TAText2D(html)
|
|
1366
|
+
# text.set_rotation(-45)
|
|
1367
|
+
text.color = 0xFF0000
|
|
1368
|
+
|
|
1369
|
+
# bug in set_to_scale of the stuff
|
|
1370
|
+
|
|
1371
|
+
grp = group(text,img3,img1, fill_color=0xFFFFFF, orientation=random.choice(['X','Y'])) # --> correct
|
|
1372
|
+
# grp = group(text, img3, img1, fill_color=0xFFFFFF, orientation='Y') # --> this is incorrect in height --> see how I can handle that
|
|
1373
|
+
|
|
1374
|
+
# I need a smarter code --> maybe only compute size of mutable and scale them to size
|
|
1375
|
+
|
|
1376
|
+
# for some reason I cannot always see the text --> what is this bug ???
|
|
1377
|
+
# debug it with just that
|
|
1378
|
+
|
|
1379
|
+
# I need get the exact size of the text --> because now it seems much bigger than it really is
|
|
1380
|
+
|
|
1381
|
+
# I also need to be able to change the pen color of text --> I need split text by colors
|
|
1382
|
+
|
|
1383
|
+
# shall I draw only the stuff within the rect ??? --> maybe
|
|
1384
|
+
|
|
1385
|
+
# set_to_size(grp,512)
|
|
1386
|
+
grp.set_to_size(512) # --> good this is ok in X but then why not in Y???
|
|
1387
|
+
|
|
1388
|
+
print(grp.getRect()) # not at all right size --> 307 --> not ok
|
|
1389
|
+
|
|
1390
|
+
get_imprecision(grp)
|
|
1391
|
+
|
|
1392
|
+
preview(grp)
|
|
1393
|
+
|
|
1394
|
+
sys.exit(0)
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
if False:
|
|
1398
|
+
|
|
1399
|
+
# seems ok but see how to handle text ??? --> very hard because unscalable -−> or assume scalable and truncate the text
|
|
1400
|
+
# best is to treat it as an image with a fixed width and height
|
|
1401
|
+
|
|
1402
|
+
# I need to treat the text independently of the rest of the figure and to crop it to the height of the others when done
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
#sufficient to reproduce the size bug
|
|
1406
|
+
|
|
1407
|
+
# mathematically it is unsolvable if uncompressible size is > to desired final size -−> I need a warning for the user !!! -−> TODO
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
SPACE=10
|
|
1411
|
+
# SPACE=0
|
|
1412
|
+
|
|
1413
|
+
img1 = Image2D('/E/Sample_images/counter/00.png')
|
|
1414
|
+
img2 = Image2D('/E/Sample_images/counter/01.png')
|
|
1415
|
+
img3 = Image2D('/E/Sample_images/counter/02.png')
|
|
1416
|
+
img4 = Image2D('/E/Sample_images/counter/03.png')
|
|
1417
|
+
img5 = Image2D('/E/Sample_images/counter/05.png')
|
|
1418
|
+
img6 = Image2D('/E/Sample_images/counter/06.png')
|
|
1419
|
+
img7 = Image2D('/E/Sample_images/counter/07.png')
|
|
1420
|
+
img8 = Image2D('/E/Sample_images/counter/08.png')
|
|
1421
|
+
img9 = Image2D('/E/Sample_images/counter/09.png')
|
|
1422
|
+
|
|
1423
|
+
# I NEED MAKE SURE THAT THE SPACE IS NOT CRAEY OTHERWISE THAT CANNOT work
|
|
1424
|
+
grp1= group(img1,img2, img3, img4, img5, space=6)
|
|
1425
|
+
grp2= group(img6,img7, img8, img9, orientation='Y', space=3)
|
|
1426
|
+
grp3 = group(grp1, grp2, space=9, orientation=random.choice(['X','Y'])) # there is a big bug there
|
|
1427
|
+
|
|
1428
|
+
# also sufficient to reproduce the bug...
|
|
1429
|
+
# grp1 = group(img1,img2, space=200) # this is the space missing --> why this bug??? " --> YES THIS IS ALWAYS THE SPACE MISSING --> WHY IS THAT!!!
|
|
1430
|
+
# grp2 = group(img6, orientation='Y', space=SPACE*20)
|
|
1431
|
+
# grp3 = group(grp1, grp2, space=SPACE*2)
|
|
1432
|
+
|
|
1433
|
+
# indeed smthg needs be done recursively to match the size properly --> am I not getting the right size in some cases ????
|
|
1434
|
+
start = timer()
|
|
1435
|
+
|
|
1436
|
+
# doing it 100 time fixes the size difference but there is still smthg missing --> so there is some convergence issue somewhere
|
|
1437
|
+
# for i in range(26): # 5 to 10 times seems to be enough --> I can maybe live with that!!! # time is negligibly longer --> so I can afford to have that (it become a little bit longer if I go around 1000 there the error is null
|
|
1438
|
+
# grp3.set_to_size(512) # NB THE SET TO SIZE FIXED the BUG --> WHY DO I NEED TO DO IT TWICE
|
|
1439
|
+
set_to_size(grp3, 512)
|
|
1440
|
+
|
|
1441
|
+
print('total time', timer()-start)
|
|
1442
|
+
|
|
1443
|
+
# grp3.set_to_size(1024) # NB THE SET TO SIZE FIXED the BUG --> WHY DO I NEED TO DO IT TWICE
|
|
1444
|
+
# grp3.set_to_size(1024) # NB THE SET TO SIZE FIXED the BUG --> WHY DO I NEED TO DO IT TWICE
|
|
1445
|
+
|
|
1446
|
+
print(grp3.orientation)
|
|
1447
|
+
print(grp3.space)
|
|
1448
|
+
print(grp3.get_incompressible_size())
|
|
1449
|
+
print(grp3.get_incompressible_size(axis=grp3.orientation))
|
|
1450
|
+
|
|
1451
|
+
print(grp3.getRect()) # not ok --> probably need do this properly #(0.0, 0.0, 502.0, 218.7883919228763) vs (0.0, 0.0, 501.9999999999999, 216.95561080400537) when repeated once --> why not deterministic ???
|
|
1452
|
+
|
|
1453
|
+
# why not all same height --> they should have the same
|
|
1454
|
+
|
|
1455
|
+
# print(len(grp3))
|
|
1456
|
+
|
|
1457
|
+
# if I take the unpacked size and append to it the incompressible size I should get back to the right shape
|
|
1458
|
+
|
|
1459
|
+
print('####sub####')
|
|
1460
|
+
for elm in grp3:
|
|
1461
|
+
print(elm.getRect())
|
|
1462
|
+
|
|
1463
|
+
print(grp1.space)
|
|
1464
|
+
print(grp1.orientation)
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
# imprecisionX = grp3[0].getRect().height()-grp3[1].getRect().height()
|
|
1468
|
+
# imprecisionY = grp3[0].getRect().width()-grp3[1].getRect().width()
|
|
1469
|
+
# imprecision = min(abs(imprecisionX), abs(imprecisionY))
|
|
1470
|
+
# print('imprecision in pixels X', imprecisionX)
|
|
1471
|
+
# print('imprecision in pixels Y', imprecisionY)
|
|
1472
|
+
# print('imprecision', imprecision)
|
|
1473
|
+
get_imprecision(grp3)
|
|
1474
|
+
|
|
1475
|
+
#-4.663263553084107e-09 for 16 repeats
|
|
1476
|
+
# imprecision in pixels 0.0 for 100 or 50 or 30 or 26 repeats
|
|
1477
|
+
# imprecision in pixels 8.526512829121202e-14 for 25 repeats
|
|
1478
|
+
# -1.4921397450962104e-11 for 20 repeats
|
|
1479
|
+
# --> 26 is the first where I really get 0 --> ok
|
|
1480
|
+
|
|
1481
|
+
|
|
1482
|
+
preview(grp3)
|
|
1483
|
+
sys.exit(0)
|
|
1484
|
+
|
|
1485
|
+
# Example usage:
|
|
1486
|
+
# custom_list = col(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
|
|
1487
|
+
# print(custom_list[0])
|
|
1488
|
+
|
|
1489
|
+
orientation='X' # all same height --> ok
|
|
1490
|
+
# orientation='Y' # pb --> not all same width but all same height --> NOT GOOD --> packing is ok and align also --> it is the scaling that sucks
|
|
1491
|
+
# almost ok but height is incorrect -−> not the target height --> need a fix
|
|
1492
|
+
# VERY GOOD --> NOW BOTH ARE FIXED -> TRY TO FINISH THAT VERY SOON -−> SHOULD BE DOABLE
|
|
1493
|
+
|
|
1494
|
+
# ça marche ce truc behaves as a rect and as a list --> very useful in a way for iter
|
|
1495
|
+
if False:
|
|
1496
|
+
grp = group(Rectangle2D(QRectF(0, 0, 100, 50)),
|
|
1497
|
+
Rectangle2D(QRectF(20, 20, 200, 100)),
|
|
1498
|
+
Rectangle2D(QRectF(30, 30, 300, 150)),
|
|
1499
|
+
Rectangle2D(QRectF(60, 30, 200, 120)),
|
|
1500
|
+
Rectangle2D(QRectF(30, 30, 300, 100)), orientation=orientation)
|
|
1501
|
+
else:
|
|
1502
|
+
|
|
1503
|
+
# --> all is ok and the size is an iteration issue -−> maybe then I should not worry about that
|
|
1504
|
+
|
|
1505
|
+
INCOMPRESSIBLE_SPACE_TEST =10 # --> setting it to 0 fixes the misalignment --> that means that this is the incompressible part of the stuff that matters -> I need make functions that return the amount of incompressible space so that the AR CAN BE PROPERLY COMPUTED
|
|
1506
|
+
|
|
1507
|
+
# grp = group(Image2D('/E/Sample_images/counter/00.png'), Image2D('/E/Sample_images/counter/01.png'),Image2D('/E/Sample_images/counter/02.png'),Image2D('/E/Sample_images/counter/03.png'))
|
|
1508
|
+
img1 = Image2D('/E/Sample_images/counter/00.png')
|
|
1509
|
+
img2 = Image2D('/E/Sample_images/counter/01.png')
|
|
1510
|
+
img3 = Image2D('/E/Sample_images/counter/02.png')
|
|
1511
|
+
img4 = Image2D('/E/Sample_images/counter/03.png')
|
|
1512
|
+
|
|
1513
|
+
|
|
1514
|
+
# it seems I had never reimplemented the rotation --> is that possible !!!
|
|
1515
|
+
img1.set_rotation(45)
|
|
1516
|
+
img3.set_rotation(-33)
|
|
1517
|
+
# img1 = Rectangle2D(QRectF(20, 20, 200, 100))
|
|
1518
|
+
# img1.set_rotation(45) # --> rotation roughly works for rectangle even though the bounds are not correct and the crop is not correct either!!!
|
|
1519
|
+
# but rotation
|
|
1520
|
+
|
|
1521
|
+
# if rotated by 90degrees I would need to change the dimensions of the image and see also how to handle the other rotations ??? --> NEED THINK -−> IF NOT SAME SIZE -−> NEED BE SMART !!! --> TODO
|
|
1522
|
+
|
|
1523
|
+
img4.set_rotation(90) # TODO --> needs a fix --> need swap the dimensions of the image -−> see how to code because maybe not that easy TODO
|
|
1524
|
+
|
|
1525
|
+
# I need to think but not a bad idea!!!
|
|
1526
|
+
|
|
1527
|
+
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
grp = group(img1, img2, img3, img4, space=INCOMPRESSIBLE_SPACE_TEST/3)
|
|
1531
|
+
|
|
1532
|
+
print('rect',grp.getRect())
|
|
1533
|
+
|
|
1534
|
+
grp.setTopLeft(512, 256) # this seems to work
|
|
1535
|
+
|
|
1536
|
+
print('rect2', grp.getRect())
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
img5 = Image2D('/E/Sample_images/counter/05.png')
|
|
1540
|
+
img6 = Image2D('/E/Sample_images/counter/06.png')
|
|
1541
|
+
img7 = Image2D('/E/Sample_images/counter/07.png')
|
|
1542
|
+
img7.set_rotation(180)
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
grp2 = group(img5, img6, img7, space=INCOMPRESSIBLE_SPACE_TEST*3)
|
|
1546
|
+
|
|
1547
|
+
grp2.setTopLeft(512, 516)
|
|
1548
|
+
|
|
1549
|
+
print('rect3',grp2.getRect())
|
|
1550
|
+
|
|
1551
|
+
img8 = Image2D('/E/Sample_images/counter/08.png')
|
|
1552
|
+
img9 = Image2D('/E/Sample_images/counter/09.png')
|
|
1553
|
+
|
|
1554
|
+
# grp4 = group(img8,img9,orientation='Y')
|
|
1555
|
+
grp4 = group(img8,img9,grp,orientation='Y', space=INCOMPRESSIBLE_SPACE_TEST)
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
# ça marche aussi mais pr je ne sais quelle raison il y a un petit decalage ???
|
|
1560
|
+
html_neo = '''
|
|
1561
|
+
<!DOCTYPE html>
|
|
1562
|
+
<html>
|
|
1563
|
+
<head>
|
|
1564
|
+
<title>Font Face</title>
|
|
1565
|
+
<style>
|
|
1566
|
+
.red {
|
|
1567
|
+
color: red;
|
|
1568
|
+
}
|
|
1569
|
+
.symbol {
|
|
1570
|
+
font-family: Symbol;
|
|
1571
|
+
font-size: x-large;
|
|
1572
|
+
}
|
|
1573
|
+
.times-new-roman {
|
|
1574
|
+
font-family: "Times New Roman";
|
|
1575
|
+
font-size: x-large;
|
|
1576
|
+
}
|
|
1577
|
+
.verdana {
|
|
1578
|
+
font-family: Verdana;
|
|
1579
|
+
font-size: x-large;
|
|
1580
|
+
}
|
|
1581
|
+
.comic-sans-ms {
|
|
1582
|
+
font-family: "Comic Sans MS";
|
|
1583
|
+
font-size: x-large;
|
|
1584
|
+
}
|
|
1585
|
+
.wildwest {
|
|
1586
|
+
font-family: WildWest;
|
|
1587
|
+
font-size: x-large;
|
|
1588
|
+
}
|
|
1589
|
+
.bedrock {
|
|
1590
|
+
font-family: Bedrock;
|
|
1591
|
+
font-size: x-large;
|
|
1592
|
+
}
|
|
1593
|
+
</style>
|
|
1594
|
+
</head>
|
|
1595
|
+
<body>
|
|
1596
|
+
<div class="red">
|
|
1597
|
+
<div class="symbol">Symbol</div>
|
|
1598
|
+
<div class="times-new-roman">Times New Roman</div>
|
|
1599
|
+
<div class="verdana">Verdana</div>
|
|
1600
|
+
<div class="comic-sans-ms">Comic Sans MS</div>
|
|
1601
|
+
<div class="wildwest">WildWest</div>
|
|
1602
|
+
<div class="bedrock">Bedrock</div>
|
|
1603
|
+
</div>
|
|
1604
|
+
</body>
|
|
1605
|
+
</html>
|
|
1606
|
+
'''
|
|
1607
|
+
|
|
1608
|
+
# html=html_neo # i prefer the old way
|
|
1609
|
+
|
|
1610
|
+
# use the deprecated text size because
|
|
1611
|
+
# html = "<font color=blue size=24>this is a test<sup>2</sup><br></font><font color=green size=12>continued<sub>1</sub><br></font><font color=white size=12>test greek <font face='Symbol' size=32>a</font> another α<font face='Arial' color='Orange'>I am a sentence!</font>"
|
|
1612
|
+
text = TAText2D(html)
|
|
1613
|
+
text.set_rotation(-45)
|
|
1614
|
+
text.color = 0xFF0000 # color does not work !!! --> again needs be fixed !!!
|
|
1615
|
+
# text.set_rotation(90)
|
|
1616
|
+
|
|
1617
|
+
t = np.arange(0.0, 2.0, 0.01)
|
|
1618
|
+
s = 1 + np.sin(2 * np.pi * t)
|
|
1619
|
+
fig, ax = plt.subplots()
|
|
1620
|
+
ax.plot(t, s)
|
|
1621
|
+
|
|
1622
|
+
ax.set(xlabel='time (s)', ylabel='voltage (mV)', title=None)
|
|
1623
|
+
ax.grid()
|
|
1624
|
+
|
|
1625
|
+
# plt.show()
|
|
1626
|
+
# fig.savefig("test.png")
|
|
1627
|
+
# plt.show()
|
|
1628
|
+
# ça marche --> voici deux examples de shapes
|
|
1629
|
+
fig = VectorGraphics2D(fig, x=0, y=0, width=512, height=512) # could also be used to create empty image with
|
|
1630
|
+
|
|
1631
|
+
# there is a bug !!!!
|
|
1632
|
+
# grp5 = group(grp2, grp4,grp, orientation='Y') # ok but pb is they have no same height -−> see how I can fix that --> see how I can set height --> DO I ALWAYS NEED A TARGET HEIGHT OR CAN I TAKE THE SMALLEST OF THE TWO ???
|
|
1633
|
+
# grp5 = group(grp2,grp4, orientation=random.choice(['X','Y']), space=INCOMPRESSIBLE_SPACE_TEST, fill_color=0x00FFFF) # ok but pb is they have no same height -−> see how I can fix that --> see how I can set height --> DO I ALWAYS NEED A TARGET HEIGHT OR CAN I TAKE THE SMALLEST OF THE TWO ???
|
|
1634
|
+
# grp5 = group(grp2,group(text), grp4, orientation=random.choice(['X','Y']), space=INCOMPRESSIBLE_SPACE_TEST, fill_color=0x00FFFF) # ok but pb is they have no same height -−> see how I can fix that --> see how I can set height --> DO I ALWAYS NEED A TARGET HEIGHT OR CAN I TAKE THE SMALLEST OF THE TWO ???
|
|
1635
|
+
grp5 = group(grp2,fig, grp4, orientation=random.choice(['X','Y']), space=INCOMPRESSIBLE_SPACE_TEST, fill_color=0x00FFFF) # ok but pb is they have no same height -−> see how I can fix that --> see how I can set height --> DO I ALWAYS NEED A TARGET HEIGHT OR CAN I TAKE THE SMALLEST OF THE TWO ???
|
|
1636
|
+
|
|
1637
|
+
# I at least managed to display a text but will I manage to get its size and alike
|
|
1638
|
+
# text should always be incompressible in fact
|
|
1639
|
+
|
|
1640
|
+
# very good --> it works even with very very complex shapes !!!!
|
|
1641
|
+
|
|
1642
|
+
# see how I can convert this into an xml portable code
|
|
1643
|
+
# todo
|
|
1644
|
+
|
|
1645
|
+
# tt marche sublimement
|
|
1646
|
+
|
|
1647
|
+
# TODO --> CHECK HOW TO DO THAT AND WHY IT DOESN'T WORK !!!
|
|
1648
|
+
|
|
1649
|
+
# TODO add bg if desired for the images
|
|
1650
|
+
|
|
1651
|
+
# grp = grp5
|
|
1652
|
+
|
|
1653
|
+
# grp.set_to_size(1024) # do I have a bug here ???
|
|
1654
|
+
grp5.setTopLeft(0,0)
|
|
1655
|
+
|
|
1656
|
+
# shall I add <?xml version="1.0" ?>
|
|
1657
|
+
|
|
1658
|
+
if False:
|
|
1659
|
+
try:
|
|
1660
|
+
xml = object_to_xml(grp5)
|
|
1661
|
+
print(xml) # pickle serialization of the object would allow me to implement some sort of a save...
|
|
1662
|
+
|
|
1663
|
+
tst = xml_string_to_object(xml)
|
|
1664
|
+
|
|
1665
|
+
print(tst)
|
|
1666
|
+
except:
|
|
1667
|
+
traceback.print_exc()
|
|
1668
|
+
|
|
1669
|
+
# small error is likely due to packing --> TODO --> FIX IT
|
|
1670
|
+
|
|
1671
|
+
# here 26 is not enough --> I need a bit more
|
|
1672
|
+
# for i in range(26): # even at 100 I get a small imprecision -−> maybe forget about that shit and take 26 always # dirty but ok for now -> I have bigger things to fix --> I tried 100 and it is perfect but 10 already seems to be enough --> maybe that is ok then --> even 3 is ok
|
|
1673
|
+
# grp5.set_to_size(1024) # there is a super tiny misalignment --> is that real or a rounding artifact that would vanish with svg images
|
|
1674
|
+
set_to_size(grp5, 1024) # size is incorrect
|
|
1675
|
+
|
|
1676
|
+
print('text size', text.width(), text.height(), text.get_incompressible_size())
|
|
1677
|
+
|
|
1678
|
+
# --> the size is not respected --> there is a bug !!!
|
|
1679
|
+
|
|
1680
|
+
# imprecisionX = grp5[0].getRect().height() - grp5[1].getRect().height()
|
|
1681
|
+
# imprecisionY = grp5[0].getRect().width() - grp5[1].getRect().width()
|
|
1682
|
+
# imprecision = min(abs(imprecisionX), abs(imprecisionY))
|
|
1683
|
+
# print('imprecision in pixels X', imprecisionX)
|
|
1684
|
+
# print('imprecision in pixels Y', imprecisionY)
|
|
1685
|
+
# print('imprecision ', imprecision)
|
|
1686
|
+
get_imprecision(grp5)
|
|
1687
|
+
|
|
1688
|
+
|
|
1689
|
+
print(grp5.orientation)
|
|
1690
|
+
print(grp5.get_incompressible_size())
|
|
1691
|
+
print(grp5.get_incompressible_size(axis=grp5.orientation))
|
|
1692
|
+
|
|
1693
|
+
print(grp5.getRect()) # --> marche pas car 668.9099254763324 (0.0, 0.0, 237.55105999039787, 668.9099254763324) --> small bug somewhere --> size is ok if no space --> the pb comes from the space --> need a fix that is very smart
|
|
1694
|
+
|
|
1695
|
+
print('####INSIDE####')
|
|
1696
|
+
for elm in grp5:
|
|
1697
|
+
print(elm.getRect())
|
|
1698
|
+
|
|
1699
|
+
preview(grp5) # pb this causes the soft to exit --> I need make it modal or alike --> think of that
|
|
1700
|
+
|
|
1701
|
+
|
|
1702
|
+
|
|
1703
|
+
|
|
1704
|
+
# I may need to dissect the components
|
|
1705
|
+
# if this is an incompressible shit then setting all spaces to 0 would do the job !!
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
|
|
1709
|
+
# very good it handles spaces too --> very good
|
|
1710
|
+
|
|
1711
|
+
|
|
1712
|
+
|
|
1713
|
+
|
|
1714
|
+
|
|
1715
|
+
|
|
1716
|
+
|
|
1717
|
+
# see how I can handle figures ???? --> I would need a smart stuff
|
|
1718
|
+
# see how I can generate the file !!! --> TODO
|
|
1719
|
+
|
|
1720
|
+
|
|
1721
|
+
|
|
1722
|
+
|
|
1723
|
+
|
|
1724
|
+
|
|
1725
|
+
if False:
|
|
1726
|
+
# do all of it
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
# # grp = group(img1)
|
|
1731
|
+
#
|
|
1732
|
+
grp3 = group(grp, grp2, orientation='Y')
|
|
1733
|
+
|
|
1734
|
+
# what happens if I add a group to another group -−> can I resize it and how will it determine the optimal size
|
|
1735
|
+
|
|
1736
|
+
|
|
1737
|
+
# can a row contain a group --> see
|
|
1738
|
+
# maybe I need the y ratio or the x and the incompressible height or width --> TODO
|
|
1739
|
+
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
|
|
1743
|
+
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
# grp3 = group(grp, grp2, orientation='X')
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
# I am not very far apparently in Y --> am I doing a mistake ???? --> is that due to errors in incompressible stuff
|
|
1750
|
+
|
|
1751
|
+
# it roughly seems to work
|
|
1752
|
+
|
|
1753
|
+
# but is all of this working ???
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
|
|
1758
|
+
print('rect4', grp.getRect(), 'rect5',grp2.getRect())
|
|
1759
|
+
|
|
1760
|
+
grp = grp3
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
|
|
1765
|
+
# grp2.setTopLeft(512,256)
|
|
1766
|
+
# grp2=grp
|
|
1767
|
+
|
|
1768
|
+
# grp = grp2
|
|
1769
|
+
|
|
1770
|
+
# each group is ok but they cannot be combined
|
|
1771
|
+
# --> see what causes the bug
|
|
1772
|
+
|
|
1773
|
+
# shall I force a size on group creation -> force same height to be max height or min height upon creation --> min height is smartest
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
# print(grp[0]) # first item
|
|
1777
|
+
# print(grp[-1]) # last item
|
|
1778
|
+
# print(grp.orientation)
|
|
1779
|
+
# print(len(grp))
|
|
1780
|
+
#
|
|
1781
|
+
# print(grp.width())
|
|
1782
|
+
# print(grp.getRect())
|
|
1783
|
+
|
|
1784
|
+
if False:
|
|
1785
|
+
|
|
1786
|
+
start = timer()
|
|
1787
|
+
|
|
1788
|
+
grp.set_to_size(512)
|
|
1789
|
+
grp.checkAR()
|
|
1790
|
+
|
|
1791
|
+
end = timer() - start
|
|
1792
|
+
print('bounds =', grp.getRect())
|
|
1793
|
+
print("elapsed time",end)
|
|
1794
|
+
|
|
1795
|
+
# this is super fast and works super well --> I have my killer app...
|
|
1796
|
+
|
|
1797
|
+
grp.orientation='Y'
|
|
1798
|
+
start = timer()
|
|
1799
|
+
|
|
1800
|
+
# grp.set_to_size(512)
|
|
1801
|
+
# grp.checkAR()
|
|
1802
|
+
|
|
1803
|
+
end = timer() - start
|
|
1804
|
+
print('bounds =', grp.getRect())
|
|
1805
|
+
print("elapsed time2", end)
|
|
1806
|
+
# grp.check()
|
|
1807
|
+
|
|
1808
|
+
# print(bounding_rect)
|
|
1809
|
+
|
|
1810
|
+
# very good --> I can access all the stuff in one go -> very cool
|
|
1811
|
+
|
|
1812
|
+
# very good --> all seems good
|
|
1813
|
+
|
|
1814
|
+
# group can be groups of images or of stuff
|
|
1815
|
+
|
|
1816
|
+
# see all I can do...
|
|
1817
|
+
# all is ok now !!!
|
|
1818
|
+
# all is good !!!
|
|
1819
|
+
|
|
1820
|
+
# very good --> now try to do the same with images and plot them --> should be easy !!!
|
|
1821
|
+
# then add functions to the group
|
|
1822
|
+
|
|
1823
|
+
# maybe offer panels as collections of rows or cols --> probably the simplest and allow empty images or spacers for incomplete panels
|
|
1824
|
+
|
|
1825
|
+
# try to draw
|
|
1826
|
+
|
|
1827
|
+
# TODO --> handle translations ... and alike
|
|
1828
|
+
# try to plot groups of groups
|
|
1829
|
+
|
|
1830
|
+
preview(grp)
|