From 3cafbaa955bdf7e0fd6c0cf3306dd5d438bfa6e2 Mon Sep 17 00:00:00 2001 From: FewerElk Date: Sun, 12 Mar 2023 12:18:59 +0100 Subject: [PATCH 1/8] update for the 2.0 version --- errors.py => Python_3D_Libs_errors.py | 3 +++ object3D.py | 2 +- screen.py | 26 +++++++++++++++++--------- testfile.py | 4 ++-- 4 files changed, 23 insertions(+), 12 deletions(-) rename errors.py => Python_3D_Libs_errors.py (85%) diff --git a/errors.py b/Python_3D_Libs_errors.py similarity index 85% rename from errors.py rename to Python_3D_Libs_errors.py index b3c7644..e33ef69 100644 --- a/errors.py +++ b/Python_3D_Libs_errors.py @@ -14,4 +14,7 @@ class CubePointsError(Object3DError): pass class PointError(Exception): + pass + +class NotTestedCodeWarning(Warning): pass \ No newline at end of file diff --git a/object3D.py b/object3D.py index 470aa41..b367edf 100644 --- a/object3D.py +++ b/object3D.py @@ -1,5 +1,5 @@ """Classe of 3D objects""" -from errors import * +from Python_3D_Libs_errors import * class Object3D(object): def __init__(self, points, color, id_='DO NOT TOUCH IT !'): diff --git a/screen.py b/screen.py index 9b6edb4..345aa48 100644 --- a/screen.py +++ b/screen.py @@ -2,7 +2,7 @@ #IMPORT from tkinter import * import object3D #Dev in the project -from errors import * +from Python_3D_Libs_errors import * class Screen(object): """Screen is a class who create a Tk screen, and who can have 3d objects.""" @@ -75,7 +75,8 @@ def showgridf(self): self.showgrid = True def allow_move(self): - self.screen.bind("", self.move) + """Allow translations""" + self.screen.bind("", self.move) self.last_x = 0 self.last_y = 0 @@ -164,15 +165,12 @@ def reload(self): #Checking if the tuple has 3 items if not(len(x) == 2): raise PointError("A point hasn't got 3 coords.") - - - self.build() def set_priority(self): """Give the priority of visual (what I show or not)""" pass - def convertise(self, point3d, perspective="//"): + def convertise(self, point3d, perspective="()"): """Convertise points 3d to a points 2d. Arguments: - point 3d : the point 3d (tuple of the 3 axis) @@ -191,16 +189,26 @@ def _convertise_parallel(self, point3d): """Convertise a 3d point to a 2d point with the rules of the isometric perspective. Arguments : - point3d : the point3d who will be convertised.""" - return (point3d[0]/(point3d[2]*self.x+1.5), - point3d[1]/(point3d[2]+self.y+1.5)) #will be changed, it is for a test. + raise NotTestedCodeWarning("This method wasn't tested / coded ! Please check the version of the librairie.") def _convertise_humain(self, point3d): """Convertise a 3d point to a 2d point with the rules of the "humain" perspective. Arguments : - point3d : the point3d who will be convertised.""" + return ((point3d[0] + point3d[2]/2)*self.zoom + self.x, + (point3d[1] + point3d[2]/2)*self.zoom + self.y) + factor = (point3d[2] / 10) * self.zoom + return ((point3d[0] * factor), + (point3d[1] * factor)) + + def set_zoom(self, zoom): + """Modify the zoom factor. + Arguments : + - zoom : the new zoom factor --> float (0 < zoom)""" + self.zoom = zoom - def build(self, mode="//"): + def build(self, mode="()"): """Build all the 3d object into the screen""" for i in self.list_object: #convert edges diff --git a/testfile.py b/testfile.py index 2f03ede..ae0873a 100644 --- a/testfile.py +++ b/testfile.py @@ -2,11 +2,11 @@ from object3D import * if __name__ == "__main__": - print("DO NOT USE IT LIKE THAT ! It is a module of a librairie !") module = Screen(410, 410, "yo le test") a = object3D.Cube([(10, 10, 10), (20, 10, 10), (20, 10, 20), (10, 10, 20), (10, 20, 20), (10, 20, 10), (20, 20, 10), (20, 20, 20)], color="blue", id_=module.get_id()) module.add_object(a) module.allow_move() - module.addframe() module.addquitbutton("EXIT") + module.set_zoom(5) + module.build() module.mainloop() \ No newline at end of file From 38c4c5c0e4a8cdc5d7a2dea9ff274d2752e7c709 Mon Sep 17 00:00:00 2001 From: FewerElk Date: Sun, 12 Mar 2023 12:26:11 +0100 Subject: [PATCH 2/8] Logical error found --- screen.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/screen.py b/screen.py index 345aa48..ede1c34 100644 --- a/screen.py +++ b/screen.py @@ -84,37 +84,46 @@ def move(self, event): x = event.x y = event.y #Determine the type of the event + # + #### ! LOGICAL ERROR HERE ! ###### + # --> execute testfile.py if x < self.last_x: etx = "Left" elif x > self.last_x: - etx = "Right" + etx = "Right" # else: etx = None if y < self.last_y: ety = "Up" elif y > self.last_y: - ety = "Down" + ety = "Down" # else: ety = None #Move + MOD = 50 if etx == "Left": v = self.last_x - x + v /= MOD self.move_l(v) if etx == "Right": v = x - self.last_x + v /= MOD self.move_r(v) if ety == "Up": v = self.last_y - y + v /= MOD self.move_u(v) if ety == "Down": v = y - self.last_y + v /= MOD self.move_d(v) self.last_x = x self.last_y = y self.reload() + self.build() self.allow_move() From 968a6cef60953e46a97a4fcae84e1fdfacd9da3c Mon Sep 17 00:00:00 2001 From: FewerElk Date: Sun, 12 Mar 2023 18:26:09 +0100 Subject: [PATCH 3/8] editing : - Object3D.__repr__() - Object3D.__str__() - Screen.__repr__() - Screen.__str__() - Screen.__del__() --- object3D.py | 35 +++++++++++++++++++++++++++-------- screen.py | 39 ++++++++++++++++++++------------------- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/object3D.py b/object3D.py index b367edf..7e38911 100644 --- a/object3D.py +++ b/object3D.py @@ -19,19 +19,38 @@ def __init__(self, points, color, id_='DO NOT TOUCH IT !'): self.id_ = id_ def __repr__(self): - print(""" + a = """ ------------------------------------------------------ 3D object with id {0} - ----------- Points -------------""".format(self.id_)) + ----------- Points -------------\n""".format(self.id_) for j, i in enumerate(self.list_points): - print(str(j+1) + " : " + i.__repr__()) - print("----------- Edges -------------") + a += str(j+1) + " : " + i.__repr__() + "\n" + a += "----------- Edges -------------\n" for j, i in enumerate(self.list_edges): - print(str(j+1) + " : " + i.__repr__()) - print("----------- Faces -------------") + a += str(j+1) + " : " + i.__repr__() + "\n" + a += "----------- Faces -------------\n" for j, i in enumerate(self.list_faces): - print(str(j+1) + " : " + i.__repr__()) - print("------------------------------------------------------\n") + a += str(j+1) + " : " + i.__repr__() + "\n" + a += "------------------------------------------------------\n" + + return a + + def __str__(self): + a = """ + ------------------------------------------------------ + 3D object with id {0} + ----------- Points -------------\n""".format(self.id_) + for j, i in enumerate(self.list_points): + a += str(j+1) + " : " + i.__repr__() + "\n" + a += "----------- Edges -------------\n" + for j, i in enumerate(self.list_edges): + a += str(j+1) + " : " + i.__repr__() + "\n" + a += "----------- Faces -------------\n" + for j, i in enumerate(self.list_faces): + a += str(j+1) + " : " + i.__repr__() + "\n" + a += "------------------------------------------------------\n" + + return a def get(self): diff --git a/screen.py b/screen.py index ede1c34..42b8535 100644 --- a/screen.py +++ b/screen.py @@ -53,6 +53,24 @@ def __init__(self, width, height, title, background="white", type3d="num", lock= self.list_object = [] + def __str__(self): + for i, j in enumerate(self.list_object): + return "Object {0} : \n{1}".format(i, j) + if self.list_object == []: + return "There is nothing to show..." + + def __repr__(self): + for i, j in enumerate(self.list_object): + return "Object {0} : \n{1}".format(str(i), j) + if self.list_object == []: + return "There is nothing to show..." + + def __del__(self): + try: + self.root.destroy() + except: + pass + def addquitbutton(self, text): """Show the quit button in the screen, and ad text to it.""" if self.quitbtn == None: @@ -125,6 +143,7 @@ def move(self, event): self.reload() self.build() self.allow_move() + print(self) def move_l(self, value): @@ -157,27 +176,14 @@ def add_object(self, object3d): def reload(self): """Reload the Screen.""" - self.list_points = [] - self.priority = [] #self.set_priority() self.screen.destroy() self.screen = Canvas(self.screen_f, width=self.width, height=self.height, bg=self.bc) self.screen.pack() - #Enumerating the list of objects and giving their points list - for i in self.list_object: - #i = one object - x = i.get() - #giving i's list of tuple - for j in x: - #j = a tuple - #Checking if the tuple has 3 items - if not(len(x) == 2): - raise PointError("A point hasn't got 3 coords.") - def set_priority(self): """Give the priority of visual (what I show or not)""" - pass + ... def convertise(self, point3d, perspective="()"): """Convertise points 3d to a points 2d. @@ -235,11 +241,6 @@ def build(self, mode="()"): if j[1][0] == "color": self.screen.create_polygon(j[0][0], j[0][1], j[0][2], j[0][3], fill=j[1][1], outline="black") - #show edges - """ - for j in i.list_edges2d: - self.screen.create_line(j[0][0], j[0][1], j[1][0], j[1][1], fill="black")""" - self.screen.update() self.root.update() From e287e4b064aa8f5adff36e439c69ba816c93162e Mon Sep 17 00:00:00 2001 From: FewerElk Date: Sun, 12 Mar 2023 18:46:12 +0100 Subject: [PATCH 4/8] Translation duplication fixed --- screen.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/screen.py b/screen.py index 42b8535..ca46a57 100644 --- a/screen.py +++ b/screen.py @@ -143,7 +143,6 @@ def move(self, event): self.reload() self.build() self.allow_move() - print(self) def move_l(self, value): @@ -176,10 +175,13 @@ def add_object(self, object3d): def reload(self): """Reload the Screen.""" - #self.set_priority() self.screen.destroy() self.screen = Canvas(self.screen_f, width=self.width, height=self.height, bg=self.bc) self.screen.pack() + #reset lists + for i in self.list_object: + i.list_faces2d = [] + i.list_edges2d = [] def set_priority(self): """Give the priority of visual (what I show or not)""" @@ -212,9 +214,6 @@ def _convertise_humain(self, point3d): - point3d : the point3d who will be convertised.""" return ((point3d[0] + point3d[2]/2)*self.zoom + self.x, (point3d[1] + point3d[2]/2)*self.zoom + self.y) - factor = (point3d[2] / 10) * self.zoom - return ((point3d[0] * factor), - (point3d[1] * factor)) def set_zoom(self, zoom): """Modify the zoom factor. @@ -222,6 +221,13 @@ def set_zoom(self, zoom): - zoom : the new zoom factor --> float (0 < zoom)""" self.zoom = zoom + def modify_zoom(self, mod): + """Modify the zoom factor + Arguments : + - mod : the modificator of the zoom (float or int). It is added to Screen.zoom + --> return Screen.zoom""" + self.zoom += mod + return self.zoom def build(self, mode="()"): """Build all the 3d object into the screen""" From 8affac40f52470e378e2f46352d6c647626a3bd3 Mon Sep 17 00:00:00 2001 From: FewerElk Date: Sun, 12 Mar 2023 18:57:42 +0100 Subject: [PATCH 5/8] trying to resolve translation problem (Screen.move() --> logical error) --- screen.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/screen.py b/screen.py index ca46a57..24d57f2 100644 --- a/screen.py +++ b/screen.py @@ -95,8 +95,8 @@ def showgridf(self): def allow_move(self): """Allow translations""" self.screen.bind("", self.move) - self.last_x = 0 - self.last_y = 0 + self.last_x = self.width / 2 + self.last_y = self.height / 2 def move(self, event): x = event.x @@ -104,17 +104,17 @@ def move(self, event): #Determine the type of the event # #### ! LOGICAL ERROR HERE ! ###### - # --> execute testfile.py + # --> execute testfile.py and try to move with left click and motion if x < self.last_x: etx = "Left" elif x > self.last_x: - etx = "Right" # + etx = "Right" else: etx = None if y < self.last_y: ety = "Up" elif y > self.last_y: - ety = "Down" # + ety = "Down" else: ety = None From 93059fb8d9a6734a8305295db158927e262d1354 Mon Sep 17 00:00:00 2001 From: FewerElk Date: Sun, 12 Mar 2023 19:17:08 +0100 Subject: [PATCH 6/8] Trying to find the logical error --- screen.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/screen.py b/screen.py index 24d57f2..31a92cf 100644 --- a/screen.py +++ b/screen.py @@ -94,9 +94,7 @@ def showgridf(self): def allow_move(self): """Allow translations""" - self.screen.bind("", self.move) - self.last_x = self.width / 2 - self.last_y = self.height / 2 + self.screen.bind("", self.move) def move(self, event): x = event.x From 6e64bc3cb7c8843fa9abad9e51cc83e21ea5618f Mon Sep 17 00:00:00 2001 From: FewerElk Date: Mon, 13 Mar 2023 18:22:39 +0100 Subject: [PATCH 7/8] Anarchic translation fixed --- screen.py | 101 +++++++++++++++++++++------------------------------- testfile.py | 7 +++- 2 files changed, 47 insertions(+), 61 deletions(-) diff --git a/screen.py b/screen.py index 31a92cf..6878809 100644 --- a/screen.py +++ b/screen.py @@ -18,6 +18,7 @@ def __init__(self, width, height, title, background="white", type3d="num", lock= - showgrid : define if we show the grid of the 3 axis (default True). - title : the title of the screen. """ + self.MOVE = 5 self.width = width self.height = height self.title = title @@ -44,9 +45,19 @@ def __init__(self, width, height, title, background="white", type3d="num", lock= self.screen_f = Frame(self.root) self.screen_f.pack() - self.screen = Canvas(self.screen_f, width=self.width, height=self.height, bg=self.bc) + self.screen = Canvas(self.screen_f, width=self.width, height=self.height, bg=self.bc, cursor="watch") self.screen.pack() + self.move_frame = Frame(self.root, border=5, bg="white", cursor="fleur") + self.move_frame.pack() + + self.move_frame_up = Frame(self.move_frame) + self.move_frame_up.pack() + self.move_frame_middle = Frame(self.move_frame) + self.move_frame_middle.pack() + self.move_frame_down = Frame(self.move_frame) + self.move_frame_down.pack() + self.quitbtnFrame = Frame(self.root) self.quitbtnFrame.pack() self.quitbtn = None @@ -74,7 +85,7 @@ def __del__(self): def addquitbutton(self, text): """Show the quit button in the screen, and ad text to it.""" if self.quitbtn == None: - self.quitbtn = Button(self.quitbtnFrame, text=text, command=self.root.destroy) + self.quitbtn = Button(self.quitbtnFrame, text=text, command=self.root.destroy, bg="red") self.quitbtn.pack() return 1 else: @@ -94,70 +105,40 @@ def showgridf(self): def allow_move(self): """Allow translations""" - self.screen.bind("", self.move) - - def move(self, event): - x = event.x - y = event.y - #Determine the type of the event - # - #### ! LOGICAL ERROR HERE ! ###### - # --> execute testfile.py and try to move with left click and motion - if x < self.last_x: - etx = "Left" - elif x > self.last_x: - etx = "Right" - else: - etx = None - if y < self.last_y: - ety = "Up" - elif y > self.last_y: - ety = "Down" - else: - ety = None - - #Move - MOD = 50 - if etx == "Left": - v = self.last_x - x - v /= MOD - self.move_l(v) - if etx == "Right": - v = x - self.last_x - v /= MOD - self.move_r(v) - if ety == "Up": - v = self.last_y - y - v /= MOD - self.move_u(v) - if ety == "Down": - v = y - self.last_y - v /= MOD - self.move_d(v) - - self.last_x = x - self.last_y = y - + # !!! movements are inversed !!! # + Button(self.move_frame_up, text="\u2191", command=self.move_u).pack() + Button(self.move_frame_middle, text="\u2190", command=self.move_r).pack(side=LEFT) + Button(self.move_frame_middle, text="X", command=self.move_reset, bg="red").pack(side=LEFT) + Button(self.move_frame_middle, text="\u2192", command=self.move_l).pack(side=LEFT) + Button(self.move_frame_down, text="\u2193", command=self.move_d).pack() + + def move(self): + """DON'T CALL ME ! + Total reload for apply move""" self.reload() self.build() - self.allow_move() + def move_reset(self): + """Reset all move modifficators""" + self.x = 0 + self.y = 0 + self.move() - def move_l(self, value): - print("I go to the left with value {0}".format(value)) - self.x += value + def move_l(self): + self.x += self.MOVE + self.move() - def move_r(self, value): - print("I go to the right with value {0}".format(value)) - self.x -= value + def move_r(self): + self.x -= self.MOVE + self.move() - def move_u(self, value): - print("I go to the up with value {0}".format(value)) - self.y -= value + def move_u(self): + self.y -= self.MOVE + self.move() - def move_d(self, value): - print("I go to the down with value {0}".format(value)) - self.y += value + def move_d(self): + self.y += self.MOVE + self.move() def mainloop(self): mainloop() @@ -174,7 +155,7 @@ def add_object(self, object3d): def reload(self): """Reload the Screen.""" self.screen.destroy() - self.screen = Canvas(self.screen_f, width=self.width, height=self.height, bg=self.bc) + self.screen = Canvas(self.screen_f, width=self.width, height=self.height, bg=self.bc, cursor="watch") self.screen.pack() #reset lists for i in self.list_object: diff --git a/testfile.py b/testfile.py index ae0873a..d23db69 100644 --- a/testfile.py +++ b/testfile.py @@ -1,8 +1,13 @@ +"""Test file of the librairie. Use for : +--> test it +--> understand how it run +--> debug it +!!! It isn't callable !!!""" from screen import * from object3D import * if __name__ == "__main__": - module = Screen(410, 410, "yo le test") + module = Screen(700, 500, "test") a = object3D.Cube([(10, 10, 10), (20, 10, 10), (20, 10, 20), (10, 10, 20), (10, 20, 20), (10, 20, 10), (20, 20, 10), (20, 20, 20)], color="blue", id_=module.get_id()) module.add_object(a) module.allow_move() From 331c67613dfaac61b494fadd2acdfa25b62ac36e Mon Sep 17 00:00:00 2001 From: FewerElk Date: Mon, 13 Mar 2023 18:45:56 +0100 Subject: [PATCH 8/8] zoom can be now set by users --- screen.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++-- testfile.py | 1 + 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/screen.py b/screen.py index 6878809..42e2136 100644 --- a/screen.py +++ b/screen.py @@ -26,6 +26,7 @@ def __init__(self, width, height, title, background="white", type3d="num", lock= self.type = type3d self.lock = lock self.showgrid = showgrid + self.zoom = 1 #Spectator values : self.x = 0 @@ -48,8 +49,13 @@ def __init__(self, width, height, title, background="white", type3d="num", lock= self.screen = Canvas(self.screen_f, width=self.width, height=self.height, bg=self.bc, cursor="watch") self.screen.pack() - self.move_frame = Frame(self.root, border=5, bg="white", cursor="fleur") - self.move_frame.pack() + self.move_g = Frame(self.root) + self.move_g.pack() + + #translations + + self.move_frame = Frame(self.move_g, border=5, bg="white", cursor="fleur") + self.move_frame.pack(side=LEFT) self.move_frame_up = Frame(self.move_frame) self.move_frame_up.pack() @@ -58,6 +64,11 @@ def __init__(self, width, height, title, background="white", type3d="num", lock= self.move_frame_down = Frame(self.move_frame) self.move_frame_down.pack() + #zoom + + self.zoom_frame = Frame(self.move_g, border=5, bg="white", cursor="double_arrow") + self.zoom_frame.pack(side=LEFT) + self.quitbtnFrame = Frame(self.root) self.quitbtnFrame.pack() self.quitbtn = None @@ -82,6 +93,39 @@ def __del__(self): except: pass + def allow_zoom(self): + """Allow user to move""" + Label(self.zoom_frame, text="ZOOM", bg="white").pack() + Button(self.zoom_frame, text="+", command=self.user_zoom_up).pack() + Button(self.zoom_frame, text="X", command=self.reset_zoom, bg="red").pack() + Button(self.zoom_frame, text=" - ", command=self.user_zoom_down).pack() + self.zoom_show = Label(self.zoom_frame, text="{0} %".format(self.zoom*100), bg="white") + self.zoom_show.pack() + + def user_zoom_up(self): + """Add 1 to self.zoom""" + self.modify_zoom(1) + self.move() + self.zoom_show.destroy() + self.zoom_show = Label(self.zoom_frame, text="{0} %".format(self.zoom*100), bg="white") + self.zoom_show.pack() + + def reset_zoom(self): + """Reset the zoom factor""" + self.zoom = 1 + self.move() + self.zoom_show.destroy() + self.zoom_show = Label(self.zoom_frame, text="{0} %".format(self.zoom*100), bg="white") + self.zoom_show.pack() + + def user_zoom_down(self): + """Remove 1 to self.zoom""" + self.modify_zoom(-1) + self.move() + self.zoom_show.destroy() + self.zoom_show = Label(self.zoom_frame, text="{0} %".format(self.zoom*100), bg="white") + self.zoom_show.pack() + def addquitbutton(self, text): """Show the quit button in the screen, and ad text to it.""" if self.quitbtn == None: @@ -106,6 +150,7 @@ def showgridf(self): def allow_move(self): """Allow translations""" # !!! movements are inversed !!! # + Label(self.move_frame_up, text="MOVE", bg="white").pack() Button(self.move_frame_up, text="\u2191", command=self.move_u).pack() Button(self.move_frame_middle, text="\u2190", command=self.move_r).pack(side=LEFT) Button(self.move_frame_middle, text="X", command=self.move_reset, bg="red").pack(side=LEFT) @@ -199,6 +244,9 @@ def set_zoom(self, zoom): Arguments : - zoom : the new zoom factor --> float (0 < zoom)""" self.zoom = zoom + self.zoom_show.destroy() + self.zoom_show = Label(self.zoom_frame, text="{0} %".format(self.zoom*100), bg="white") + self.zoom_show.pack() def modify_zoom(self, mod): """Modify the zoom factor @@ -207,6 +255,9 @@ def modify_zoom(self, mod): --> return Screen.zoom""" self.zoom += mod return self.zoom + self.zoom_show.destroy() + self.zoom_show = Label(self.zoom_frame, text="{0} %".format(self.zoom*100), bg="white") + self.zoom_show.pack() def build(self, mode="()"): """Build all the 3d object into the screen""" diff --git a/testfile.py b/testfile.py index d23db69..957d268 100644 --- a/testfile.py +++ b/testfile.py @@ -11,6 +11,7 @@ a = object3D.Cube([(10, 10, 10), (20, 10, 10), (20, 10, 20), (10, 10, 20), (10, 20, 20), (10, 20, 10), (20, 20, 10), (20, 20, 20)], color="blue", id_=module.get_id()) module.add_object(a) module.allow_move() + module.allow_zoom() module.addquitbutton("EXIT") module.set_zoom(5) module.build()