#author("2024-11-20T15:54:15+09:00","default:TESLA202407","TESLA202407") #author("2024-11-20T15:54:52+09:00","default:TESLA202407","TESLA202407") [[factory_controller_01.py]] #code(Python){{ # -*- coding: utf-8 -*- # # 2024 11/20 # import math from tkinter import * import tkinter.font as tkFont import matrix import copy import threading import re import socket import time #import readchar from Cube import Cube class Space: ''' Coordiante-system: Right-handed, Matrices are column-major ones ''' WIDTH = 1280.0 HEIGHT = 960.0 SPEED = 0.05 EPSILON = 1.0e-8 ZERO = EPSILON cxyz=[ [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]] ] pcx=3 pcy=3 pcz=3 pjxy=[[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]] pjyz=[[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]] pjzx=[[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]] cwxyz=[ [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]], [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0],[0,0,0,0,0,0,0], [0,0,0,0,0,0,0]] ] def clear_cxyz(self): for i in range(7): for j in range(7): for k in range(7): self.cxyz[i][j][k]=0 def make_pjxy(self): for i in range(7): for j in range(7): self.pjxy[i][j]=0 for k in range(7): self.pjxy[i][j]+=self.cxyz[i][j][k] print("pjxy") for i in range(7): print(self.pjxy[i]) def make_pjyz(self): for i in range(7): for j in range(7): self.pjyz[i][j]=0 for k in range(7): self.pjyz[i][j]+=self.cxyz[k][i][j] print("pjyz") for i in range(7): print(self.pjyz[i]) def make_pjzx(self): for i in range(7): for j in range(7): self.pjzx[i][j]=0 for k in range(7): self.pjzx[i][j]+=self.cxyz[j][k][i] print("pjzx") for i in range(7): print(self.pjzx[i]) def make_cxyz(self): self.clear_cxyz() for cx in self.polygons_3D: ccp=cx.get_cube_center() self.cxyz[round(ccp.x)+self.pcx][round(ccp.y)+self.pcy][round(ccp.z)+self.pcz]=1 print("cxyz") for i in range(7): print(self.cxyz[i]) def rotate_z_cw_90(self): #for k in range(7): # for i in range(7): # for j in range(7): # self.cwxyz[j][6-i][k]=self.cxyz[i][j][k] #for i in range(7): # for j in range(7): # for k in range(7): # self.cxyz[i][j][k]=self.cwxyz[i][j][k] for cx in self.polygons_3D: ccp=cx.get_cube_center() cx.rotate(0.0,0.0,90.0) cx.moveTo(ccp.y,-ccp.x,ccp.z) self.update(self.polygons_3D) def rotate_x_cw_90(self): #for k in range(7): # for i in range(7): # for j in range(7): # self.cwxyz[k][j][6-i]=self.cxyz[k][i][j] #for i in range(7): # for j in range(7): # for k in range(7): # self.cxyz[i][j][k]=self.cwxyz[i][j][k] for cx in self.polygons_3D: ccp=cx.get_cube_center() cx.rotate(90.0,0.0,0.0) cx.moveTo(ccp.x,ccp.z,-ccp.y) self.update(self.polygons_3D) def rotate_y_cw_90(self): #for k in range(7): # for i in range(7): # for j in range(7): # self.cwxyz[6-i][k][j]=self.cxyz[j][k][i] #for i in range(7): # for j in range(7): # for k in range(7): # self.cxyz[i][j][k]=self.cwxyz[i][j][k] for cx in self.polygons_3D: ccp=cx.get_cube_center() cx.rotate(0.0,90.0,0.0) cx.moveTo(-ccp.z,ccp.y,ccp.x) self.update(self.polygons_3D) def max_width(self): max_width=-10.0 for cx in self.polygons_3D: ccp=cx.get_cube_center() if ccp.x>max_width: max_width=ccp.x return max_width def min_width(self): min_width=10.0 for cx in self.polygons_3D: ccp=cx.get_cube_center() if ccp.x<min_width: min_width=ccp.x return min_width def width(self): return self.max_width()-self.min_width() +1.0 def max_height(self): max_height=-10.0 for cx in self.polygons_3D: ccp=cx.get_cube_center() if ccp.y>max_height: max_height=ccp.y return max_height def min_height(self): min_height=10.0 for cx in self.polygons_3D: ccp=cx.get_cube_center() if ccp.y<min_height: min_height=ccp.y return min_height def height(self): return self.max_height()-self.min_height() +1.0 def max_depth(self): max_depth=-10.0 for cx in self.polygons_3D: ccp=cx.get_cube_center() if ccp.z>max_depth: max_depth=ccp.z return max_depth def min_depth(self): min_depth=10.0 for cx in self.polygons_3D: ccp=cx.get_cube_center() if ccp.z<min_depth: min_depth=ccp.z return min_depth def depth(self): return self.max_depth()-self.min_depth() +1.0 def move_and_rotate_for_factory(self): wx=round(self.width()) if wx<0.0: print("no tesla dice.") return hx=round(self.height()) if hx>wx: self.rotate_z_cw_90() wx=round(self.width()) hx=round(self.height()) dx=round(self.depth()) if hx>dx: self.rotate_x_cw_90() wx=round(self.width()) hx=round(self.height()) dx=round(self.depth()) if dx>wx: self.rotate_y_cw_90() wx=round(self.width()) hx=round(self.height()) dx=round(self.depth()) if self.there_is_over_hang(): self.rotate_x_cw_90() self.rotate_x_cw_90() wx=round(self.width()) hx=round(self.height()) dx=round(self.depth()) if self.there_is_space_at_the_first_corner(): if hx<=1.01: self.rotate_x_cw_90() self.rotate_x_cw_90() else: self.rotate_y_cw_90() self.rotate_y_cw_90() def min_x(self): min_x=10.0 for cx in self.polygons_3D: ccp=cx.get_cube_center() if ccp.x<min_x: min_x=ccp.x return min_x def min_y(self): min_y=10.0 for cx in self.polygons_3D: ccp=cx.get_cube_center() if ccp.y<min_y: min_y=ccp.y return min_y def there_is_over_hang(self): self.make_cxyz() imin_y=round(self.min_y()) for i in range(7): for j in range(7): if self.cxyz[i][imin_y][j]==0: if imin_y<6: if self.cxyz[i][imin_y+1][j]==1: return True def there_is_space_at_the_first_corner(self): self.make_cxyz() imin_y=round(self.min_y()) imin_x=6 imin_z=6 for i in range(7): for j in range(7): if self.cxyz[i][imin_y][j]==1: if i<imin_x: imin_x=i if j<imin_z: imin_z=j fc=self.cxyz[imin_x][imin_y][imin_z] return fc==0 #ダイスの回転 # org: top red, forward green, left yellow, right black, back blue, bottom white # #top red の場合 # forward green : 回転無し。 # yellow : 右回転 3回 # blue : 右回転2回 # black : 右回転1回 # #top white の場合 # 縦回転: 2回 # forward green : 右回転2回 # yellow : 右回転 1回 # blue : 回転無し # black : 右回転3回 # #top blue の場合 # 縦回転: 1回 # forward red : 回転なし # yellow : 右回転 3回 # white : 右回転2回 # black : 右回転1回 # #top yellow の場合 # 右回転1回 # 縦回転: 1回 # forward red : 回転なし # blue : 右回転1回 # white : 右回転2回 # green : 右回転3回 # # top green の場合 # 右回転 2回 # 縦回転: 1回 # forward red : 回転なし # yellow : 右回転1回 # white : 右回転2回 # black : 右回転3回 # #top black の場合 # 右回転 3回 # 縦回転: 1回 # forward red : 回転なし # green : 右回転1回 # white : 右回転2回 # blue : 右回転3回 def generate_rotation_procedure(self,cube): top_face_id=cube.get_top_face() top_face_color=cube.cls[top_face_id] front_face_id=cube.get_front_face() front_face_color=cube.cls[front_face_id] if top_face_color=='red': #top red の場合 # forward black : 回転無し。 # green : 右回転 3回 # yellow : 右回転2回 # blue : 右回転1回 if front_face_color=='green': rotation_proc='self.place_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.place_at_the_rotation_point()') rotation_proc=rotation_proc+'self.h_rotate_acw()\n' #rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_acw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='yellow': rotation_proc='self.place_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.place_at_the_rotation_point()') rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='blue': rotation_proc='self.place_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.place_at_the_rotation_point()') rotation_proc=rotation_proc+'self.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='gray': rotation_proc='#no need to rotate\n' return rotation_proc elif top_face_color=='white': #top white の場合 # 縦回転: 2回 # forward black : 右回転2回 # blue : 右回転 1回 # yellow : 回転無し # green : 右回転3回 rotation_proc='self.place_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.place_at_the_rotation_point()') rotation_proc=rotation_proc+'self.v_rotate_f()\nself.v_rotate_f()\n' self.factory.send_message_nl('asm m self.v_rotate_f()') self.factory.send_message_nl('asm m self.v_rotate_f()') if front_face_color=='green': #rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\nself.h_rotate_cw()\n' rotation_proc=rotation_proc+'self.h_rotate_acw()\nn' self.factory.send_message_nl('asm m self.h_rotate_acw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='yellow': return rotation_proc elif front_face_color=='blue': rotation_proc=rotation_proc+'self.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='gray': rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif top_face_color=='yellow': #top yellow の場合 # 縦回転: 1回 # forward red : 回転なし # : 右回転 3回 # white : 右回転2回 # blue : 右回転1回 rotation_proc='self.place_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.place_at_the_rotation_point()') rotation_proc=rotation_proc+'self.v_rotate_f()\n' self.factory.send_message_nl('asm m self.v_rotate_f()') if front_face_color=='green': rotation_proc=rotation_proc+'self.h_rotate_acw()\n' #rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_acw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='red': return rotation_proc elif front_face_color=='blue': rotation_proc=rotation_proc+'self.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='white': rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif top_face_color=='green': #top green の場合 # 右回転: 1回 # 縦回転: 1回 # forward red : 回転なし # black : 右回転 3回 # white : 右回転2回 # blue : 右回転1回 rotation_proc='self.place_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.place_at_the_rotation_point()') rotation_proc='self.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') rotation_proc=rotation_proc+'self.v_rotate_f()\n' self.factory.send_message_nl('asm m self.v_rotate_f()') if front_face_color=='gray': rotation_proc=rotation_proc+'self.h_rotate_acw()\n' #rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_acw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='red': return rotation_proc elif front_face_color=='yellow': rotation_proc=rotation_proc+'self.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='white': rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif top_face_color=='gray': #top green の場合 # 右回転: 2回 # 縦回転: 1回 # forward red : 回転なし # blue : 右回転 3回 # white : 右回転2回 # green : 右回転1回 rotation_proc='self.place_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.place_at_the_rotation_point()') rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') self.factory.send_message_nl('asm m self.h_rotate_cw()') rotation_proc=rotation_proc+'self.v_rotate_f()\n' self.factory.send_message_nl('asm m self.v_rotate_f()') if front_face_color=='blue': rotation_proc=rotation_proc+'self.h_rotate_acw()\n' #rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_acw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='red': return rotation_proc elif front_face_color=='green': rotation_proc=rotation_proc+'self.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='white': rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif top_face_color=='blue': #top blue の場合 # left回転: 2回->1 # 縦回転: 1回 # forward red : 回転なし # yellow : 右回転 3回->left 1 # white : 右回転2回 # grey : 右回転1回 rotation_proc='self.place_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.place_at_the_rotation_point()') rotation_proc=rotation_proc+'self.h_rotate_acw()\n' self.factory.send_message_nl('asm m self.h_rotate_acw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') rotation_proc=rotation_proc+'self.v_rotate_f()\n' self.factory.send_message_nl('asm m self.v_rotate_f()') if front_face_color=='yellow': rotation_proc=rotation_proc+'self.h_rotate_acw()\n' #rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_acw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') #self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='red': return rotation_proc elif front_face_color=='gray': rotation_proc=rotation_proc+'self.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc elif front_face_color=='white': rotation_proc=rotation_proc+'self.h_rotate_cw()\nself.h_rotate_cw()\n' self.factory.send_message_nl('asm m self.h_rotate_cw()') self.factory.send_message_nl('asm m self.h_rotate_cw()') return rotation_proc dice_array_xz=[[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] def init_assemble_info(self): for i in range(5): for j in range(5): self.dice_array_xz[i][j]=0 def generate_move_procedure(self,i,j,k): proc='' if k==0: if i==0 and j==0: proc=proc+'self.place_at_0_0()' self.dice_array_xz[i][j]=1 elif i==1 and j==0: if self.dice_array_xz[0][0]==1: proc=proc+'self.place_at_1_0_nx_00()' self.dice_array_xz[1][0]=1 elif self.dice_array_xz[0][0]==0: proc=proc+'self.place_at_1_0_nx_00()' self.dice_array_xz[1][0]=1 elif i==2 and j==0: if self.dice_array_xz[1][0]==1: proc=proc+'self.place_at_2_0_nx_10()' self.dice_array_xz[2][0]=1 elif self.dice_array_xz[1][0]==0: proc=proc+'self.place_at_2_0_nx_10()' self.dice_array_xz[2][0]=1 elif i==3 and j==0: if self.dice_array_xz[2][0]==1: proc=proc+'self.place_at_3_0_nx_20()' self.dice_array_xz[3][0]=1 elif self.dice_array_xz[2][0]==0: proc=proc+'self.place_at_3_0_nx_20()' self.dice_array_xz[3][0]=1 elif i==0 and j==1: proc=proc+'self.place_at_0_1()' self.dice_array_xz[i][j]=1 elif i==1 and j==1: if self.dice_array_xz[0][1]==1: proc=proc+'self.place_at_1_1_nx_01()' self.dice_array_xz[1][1]=1 elif self.dice_array_xz[0][1]==0: proc=proc+'self.place_at_1_1_nx_01()' self.dice_array_xz[1][1]=1 elif i==2 and j==1: if self.dice_array_xz[1][0]==1: proc=proc+'self.place_at_2_1_nx_11()' self.dice_array_xz[2][1]=1 elif self.dice_array_xz[1][0]==0: proc=proc+'self.place_at_2_1_nx_11()' self.dice_array_xz[2][1]=1 elif i==3 and j==1: if self.dice_array_xz[2][0]==1: proc=proc+'self.place_at_3_1_nx_21()' self.dice_array_xz[3][1]=1 elif self.dice_array_xz[2][0]==0: proc=proc+'self.place_at_3_1_nx_21()' self.dice_array_xz[3][1]=1 elif k==1: if i==0 and j==0: proc=proc+'self.place_at_0_0_1()' self.dice_array_xz[i][j]=1 elif i==1 and j==0: if self.dice_array_xz[0][0]==1: proc=proc+'self.place_at_1_0_1_nx_00()' self.dice_array_xz[1][0]=1 elif i==2 and j==0: if self.dice_array_xz[1][0]==1: proc=proc+'self.place_at_2_0_1_nx_10()' self.dice_array_xz[2][0]=1 elif i==3 and j==0: if self.dice_array_xz[2][0]==1: proc=proc+'self.place_at_3_0_1_nx_20()' self.dice_array_xz[3][0]=1 elif i==0 and j==1: proc=proc+'self.place_at_0_1_1()' self.dice_array_xz[i][j]=1 elif i==1 and j==1: if self.dice_array_xz[0][1]==1: proc=proc+'self.place_at_1_1_1_nx_01()' self.dice_array_xz[1][1]=1 elif i==2 and j==1: if self.dice_array_xz[1][0]==1: proc=proc+'self.place_at_2_1_1_nx_11()' self.dice_array_xz[2][1]=1 elif i==3 and j==1: if self.dice_array_xz[2][0]==1: proc=proc+'self.place_at_3_1_1_nx_21()' self.dice_array_xz[3][1]=1 self.factory.send_message_nl('asm m '+proc) return proc+'\n' def generate_assemble_procedure(self): min_y=round(self.min_height()) max_y=round(self.max_height()) min_x=round(self.min_width()) max_x=round(self.max_width()) min_z=round(self.min_depth()) max_z=round(self.max_depth()) proc='asm start.\n' self.factory.send_message_nl('asm start.') for k in reversed(range(min_z, max_z+1)): for j in range(min_y, max_y+1): for i in range(min_x, max_x+1): for cx in self.polygons_3D: ccx=cx.get_cube_center() iccx_x=round(ccx.x) iccx_y=round(ccx.y) iccx_z=round(ccx.z) if i==iccx_x and j==iccx_y and k==iccx_z: #print(cx.get_cube_center()) #print(iccx_x, iccx_y, iccx_z) #print(ccx.x, ccx.y, ccx.z) proc=proc+'self.get_dice_from_the_belt()\n' self.factory.send_message_nl('asm m self.get_dice_from_the_belt()') rproc=self.generate_rotation_procedure(cx) if rproc=='#no need to rotate\n': if k==1: proc=proc+'self.send_move_command(0.0,40.0)\n' self.factory.send_message_nl('asm m self.send_move_command(0.0,40.0)') if k==2: proc=proc+'self.send_move_command(0.0,80.0)\n' self.factory.send_message_nl('asm m self.send_move_command(0.0,80.0)') else: proc=proc+rproc proc=proc+'self.get_at_the_rotation_point()\n' self.factory.send_message_nl('asm m self.get_at_the_rotation_point()') mx=i-min_x mz=max_z-k my=j-min_y mproc=self.generate_move_procedure(mx,mz,my) proc=proc+mproc return proc def __init__(self): print("start Space.__init__") self.root = Tk() self.root.resizable(False, False) self.root.title('3D') #self.chat_client=chat_client left = (self.root.winfo_screenwidth() - Space.WIDTH) / 2 top = (self.root.winfo_screenheight() - Space.HEIGHT) / 2 self.root.geometry('%dx%d+%d+%d' % (Space.WIDTH, Space.HEIGHT, left, top)) self.graph = Canvas(self.root, width=Space.WIDTH, height=Space.HEIGHT, background='black') self.graph.pack() self.walls = [matrix.Vector3D(7.0, 0.0, 0.0), matrix.Vector3D(-7.0, 0.0, 0.0), matrix.Vector3D(0.0, 7.0, 0.0), matrix.Vector3D(0.0, -7.0, 0.0), matrix.Vector3D(0.0, 0.0, 7.0), matrix.Vector3D(0.0, 0.0, -7.0)] self.wallsnormals = [matrix.Vector3D(-1.0, 0.0, 0.0), matrix.Vector3D(1.0, 0.0, 0.0), matrix.Vector3D(0.0, -1.0, 0.0), matrix.Vector3D(0.0, 1.0, 0.0), matrix.Vector3D(0.0, 0.0, -1.0), matrix.Vector3D(0.0, 0.0, 1.0)] ################# # self.cubenormals = [] # for i in range(len(self.cubefaces)): # poly = [] # for j in range(len(self.cubefaces[i])): # poly.append(self.cube[self.cubefaces[i][j]]) # self.cubenormals.append(self.calcNormalVec(poly)) ################# self.ang = [0.0, 0.0, 0.0] # phi(x), theta(y), psi(z) of the camera self.trans = [0.0, 0.0, 2.0] # translation (x, y, z) of the camera #The matrices (Scale, Shear, Rotate, Translate) apply to the View/Camera #The Scale Matrix self.Scale = matrix.Matrix(4, 4) Scalex = 1.0 Scaley = 1.0 Scalez = 1.0 self.Scale[(0,0)] = Scalex self.Scale[(1,1)] = Scaley self.Scale[(2,2)] = Scalez #The Shear Matrix self.Shearxy = matrix.Matrix(4, 4) self.Shearxy[(0,2)] = 0.0 self.Shearxy[(1,2)] = 0.0 self.Shearxz = matrix.Matrix(4, 4) self.Shearxz[(0,1)] = 0.0 self.Shearxz[(2,1)] = 0.0 self.Shearyz = matrix.Matrix(4, 4) self.Shearyz[(1,0)] = 0.0 self.Shearyz[(2,0)] = 0.0 self.Shear = self.Shearxy*self.Shearxz*self.Shearyz #The Rotation Matrices self.Rotx = matrix.Matrix(4,4) self.Roty = matrix.Matrix(4,4) self.Rotz = matrix.Matrix(4,4) #The Translation Matrix (will contain xoffset, yoffset, zoffset) self.Tr = matrix.Matrix(4, 4) self.Tr[(0,3)] = self.trans[0] self.Tr[(1,3)] = self.trans[1] self.Tr[(2,3)] = self.trans[2] #The Projection Matrix self.Proj = matrix.Matrix(4, 4) #foc controls how much of the screen is viewed fov = 60.0 #between 30 and 90 ? zfar = 100.0 znear = 0.1 S = 1/(math.tan(math.radians(fov/2))) A = Space.WIDTH/Space.HEIGHT self.Proj[(0,0)] = S/A self.Proj[(1,1)] = S self.Proj[(2,2)] = (zfar+znear)/(znear-zfar) self.Proj[(3,2)] = -1.0 self.Proj[(2,3)] = 2*(zfar*znear)/(znear-zfar) # self.Proj[(3,3)] = 0.0 #ToScreen Matrix self.toSC = matrix.Matrix(4, 4) self.toSC[(0,0)] = Space.WIDTH/2 self.toSC[(1,1)] = -Space.HEIGHT/2 self.toSC[(0,3)] = Space.WIDTH/2 self.toSC[(1,3)] = Space.HEIGHT/2 # self.root.bind("<B1-Motion>", self.dragcallback) # self.root.bind("<ButtonRelease-1>", self.releasecallback) self.root.bind("<Key>", self.keycallback) # self.root.bind("<KeyRelease>", self.keyreleasecallback) self.fnt = tkFont.Font(family='Helvetica', size=12, weight='bold') cube1=Cube(self) cube1.set_name("s*") self.cube1=cube1 cc1=cube1.get_cube_center() self.cxyz[round(cc1.x)+self.pcx][round(cc1.y)+self.pcy][round(cc1.z)+self.pcz]=1 print(self.cxyz) self.polygons_3D=[cube1] self.update(self.polygons_3D) #self.client_start() #comment out for debug #self.mainloop() def start_3d(self): self.root.mainloop() def clear(self): cube1=Cube(self) cube1.set_name("s*") self.cube1=cube1 self.polygons_3D=[cube1] self.clear_cxyz() cc1=cube1.get_cube_center() self.cxyz[round(cc1.x)+self.pcx][round(cc1.y)+self.pcy][round(cc1.z)+self.pcz]=1 print(self.cxyz) self.update(self.polygons_3D) def lookUpCube(self,name): for i in range(len(self.polygons_3D)): cx=self.polygons_3D[i] if name==cx.name : return cx return None def update(self,polygons_3D): # Main simulation loop. self.graph.delete(ALL) self.Rotx[(1,1)] = math.cos(math.radians(360.0-self.ang[0])) self.Rotx[(1,2)] = -math.sin(math.radians(360.0-self.ang[0])) self.Rotx[(2,1)] = math.sin(math.radians(360.0-self.ang[0])) self.Rotx[(2,2)] = math.cos(math.radians(360.0-self.ang[0])) self.Roty[(0,0)] = math.cos(math.radians(360.0-self.ang[1])) self.Roty[(0,2)] = math.sin(math.radians(360.0-self.ang[1])) self.Roty[(2,0)] = -math.sin(math.radians(360.0-self.ang[1])) self.Roty[(2,2)] = math.cos(math.radians(360.0-self.ang[1])) self.Rotz[(0,0)] = math.cos(math.radians(360.0-self.ang[2])) self.Rotz[(0,1)] = -math.sin(math.radians(360.0-self.ang[2])) self.Rotz[(1,0)] = math.sin(math.radians(360.0-self.ang[2])) self.Rotz[(1,1)] = math.cos(math.radians(360.0-self.ang[2])) #The Rotation matrix self.Rot = self.Rotx*self.Roty*self.Rotz #Translation (just copying) self.Tr[(0,3)] = -self.trans[0] self.Tr[(1,3)] = -self.trans[1] self.Tr[(2,3)] = -self.trans[2] #The Transformation matrix self.Tsf = self.Scale*self.Shear*self.Rot*self.Tr #Computing the normals in __init__ and only rotating them here is the same. # print '+++++++++++++++' # for i in range(len(self.cubenormals)): # print self.Rot*self.cubenormals[i] # print '+++++++++++++++' # print '************' #Cube for ic in range(len(polygons_3D)): cubex=polygons_3D[ic] cubex.update() cubefaces=cubex.cubefaces cls=cubex.cls for i in range(len(cubefaces)): poly = [] #transformed polygon for j in range(len(cubefaces[0])): cube=cubex.cube v = cube[cubefaces[i][j]] #Scale, Shear, Rotate the vertex around X axis, then around Y axis, and finally around Z axis and Translate. r=self.Tsf*v poly.append(r) n=self.calcNormalVec(poly) #print n if not self.isPolygonFrontFace(poly[0], n): #Backface culling continue poly2d = [] inviewingvolume = False for j in range(len(poly)): #put the point from 3D to 2D ps =self.Proj*poly[j] # Puut the screenpoint in the list of transformed vertices p=self.toSC*ps x=int(p.x) y = int(p.y) poly2d.append((x, y)) #if only one point is in the screen (x[-1,1], y[-1,1], z[-1,1]) then draw the whole polygon if (-1.0 <= ps.x <= 1.0) and (-1.0 <= ps.y <= 1.0) and (-1.0 <= ps.z <= 1.0): inviewingvolume = True if inviewingvolume: self.graph.create_polygon(*poly2d, fill=cls[i]) cfx=cubex.cfaces xface=cfx[i] xface_led=xface[0] for k in range(len(xface_led)): #LED v=xface_led[k] r=self.Tsf*v ps=self.Proj*r p = self.toSC*ps x, y = int(p.x), int(p.y) self.graph.create_rectangle(x, y, x+3, y+3, fill="magenta") v=xface[1] #photo tr r=self.Tsf*v ps=self.Proj*r p=self.toSC*ps x,y=int(p.x), int(p.y) self.graph.create_rectangle(x,y, x+3, y+3, fill="cyan") # cfx=cubex.cfaces # for i in range(len(cfx)): # xface=cfx[i] # xface_led=xface[0] # for j in range(len(xface_led)): # v=xface_led[j] # r=self.Tsf*v # ps=self.Proj*r # p = self.toSC*ps # x, y = int(p.x), int(p.y) # self.graph.create_rectangle(x, y, x+3, y+3, fill="magenta") # v=xface[1] # r=self.Tsf*v # ps=self.Proj*r # p=self.toSC*ps # x,y=int(p.x), int(p.y) # self.graph.create_rectangle(x,y, x+3, y+3, fill="cyan") #Texts (these are in camera-CS) txt1 = 'xpos: '+str(self.trans[0])+' ypos: '+str(self.trans[1])+' zpos: '+str(self.trans[2]) txt2 = 'xrot: '+str(self.ang[0])+' yrot: '+str(self.ang[1])+' zrot: '+str(self.ang[2]) self.idTxt1 = self.graph.create_text(30,30, text=txt1, fill='white', anchor=SW, font=self.fnt) self.idTxt2 = self.graph.create_text(30,60, text=txt2, fill='white', anchor=SW, font=self.fnt) vFwd = self.getForwardVec2(self.ang[1]) txt3 = 'Fwd: '+str(vFwd) self.idTxt3 = self.graph.create_text(30,90, text=txt3, fill='white', anchor=SW, font=self.fnt) def isPolygonFrontFace(self, v, n):#Clockwise? '''v is a vertex of the polygon, n is the normal-vector of the polygon.''' #The camera should be at (0.0, 0.0, 0.0) but that doesn't work well. #It seems that the camera is at (0.0, 0.0, 1.0) c = matrix.Vector3D(0.0, 0.0, 1.0) vv = v-c r = vv.dot(n) return r < 0.0 def calcNormalVec(self, p): '''p is an array of vertices of the polygon/face''' v1 = p[0]-p[1] v2 = p[0]-p[3] v = v1.cross(v2) v.normalize() return v def getForwardVec1(self): #Where the camera is facing. Inverting a matrix is slow m = self.Rot.invert() f1 = m[(0,2)] f2 = m[(1,2)] f3 = m[(2,2)] v = matrix.Vector3D(f1, f2, f3) v.normalize() #Forward vector is really backward one, so need to be negated return -v def getForwardVec2(self, yrot): #Where the camera is facing. f1 = -math.sin(math.radians(yrot)) f2 = 0.0 f3 = -math.cos(math.radians(yrot)) v = matrix.Vector3D(f1, f2, f3) return v def isCollisionPlanes(self, campos, camdir): num = len(self.walls) for i in range(num): iscol, dist = self.isCollisionPlane(self.walls[i], self.wallsnormals[i], campos, camdir) if iscol and dist < 0.1: #print( i+1, dist) return True return False def isCollisionPlane(self, p, n, campos, camdir): '''instead of pointonplane (p) and normalofplane (n) we could pass a polygon and calculate its normal vector here. campos is the position of the camera and camdir is the forward vector of the camera''' dist = 0.0 #Dot Product Between Plane Normal And Ray Direction dotprod = camdir.dot(n) #Determine If Ray Parallel To Plane if ((dotprod < Space.ZERO) and (dotprod > -Space.ZERO)): return False, dist #Find Distance To Collision Point dist = (n.dot(p-campos))/dotprod #Test If Collision Behind Start if (dist < -Space.ZERO): return False, dist return True, dist def isCollisionCube(self, campos,polygons_3D): '''Checks if the camera is inside the cube (this is the bounding-box-technique (bbt) but we have a cube so we dont't need to calculate a bb) ''' for i in range(len(polygons_3D)): cube=(polygons_3D[i]).cube cubefaces=(polygons_3D[i]).cubefaces if (campos.z >= cube[cubefaces[0][0]].z and campos.z <= cube[cubefaces[2][0]].z) and (campos.y >= cube[cubefaces[5][0]].y and campos.y <= cube[cubefaces[4][0]].y) and (campos.x >= cube[cubefaces[3][0]].x and campos.x <= cube[cubefaces[1][0]].x): return True return False def keycallback(self, event): # print event.char # print event.keycode # print event.keysym #Foward if event.keysym == 'Up': vFwd = self.getForwardVec2(self.ang[1]) #Is there a collison? pos = matrix.Vector3D(self.trans[0]+vFwd.x*Space.SPEED, self.trans[1], self.trans[2]+vFwd.z*Space.SPEED) if self.isCollisionPlanes(pos, vFwd): return if self.isCollisionCube(pos,self.polygons_3D): return self.trans[0] += vFwd.x*Space.SPEED self.trans[2] += vFwd.z*Space.SPEED #Backward elif event.keysym == 'Down': vFwd = self.getForwardVec2(self.ang[1]) vBck = -vFwd #Is there a collison? pos = matrix.Vector3D(self.trans[0]-vFwd.x*Space.SPEED, self.trans[1], self.trans[2]-vFwd.z*Space.SPEED) if self.isCollisionPlanes(pos, vBck): return if self.isCollisionCube(pos,self.polygons_3D): return self.trans[0] -= vFwd.x*Space.SPEED self.trans[2] -= vFwd.z*Space.SPEED #Turn right elif event.keysym == 'Right': self.ang[1] -= 1.5 #Turn left elif event.keysym == 'Left': self.ang[1] += 1.5 #Upwards elif event.keysym == 'u': #Is there a collison? pos = matrix.Vector3D(self.trans[0], self.trans[1]+Space.SPEED, self.trans[2]) vUp = matrix.Vector3D(0.0, 1.0, 0.0) if self.isCollisionPlanes(pos, vUp): return if self.isCollisionCube(pos,self.polygons_3D): return self.trans[1] += Space.SPEED #Downwards elif event.keysym == 'd': #Is there a collison? pos = matrix.Vector3D(self.trans[0], self.trans[1]-Space.SPEED, self.trans[2]) vDwn = matrix.Vector3D(0.0, -1.0, 0.0) if self.isCollisionPlanes(pos, vDwn): return if self.isCollisionCube(pos,self.polygons_3D): return self.trans[1] -= Space.SPEED #Quit elif event.keysym == 'Escape': self.quit() if self.ang[1] >= 360.0: self.ang[1] -= 360.0 if self.ang[1] < 0.0: self.ang[1] += 360.0 self.update(self.polygons_3D) def quit(self): self.root.quit() def client_start(self): """ start client """ print("start client_start") handle_thread = threading.Thread(target=self.handler, daemon=True) self.parse("send up \"str (this s* f2d1 next s*4 f4d1)\".") self.parse("send up \"str (this s*4 f2d1 next s*44 f4d1)\".") self.update(self.polygons_3D) handle_thread = threading.Thread(target=self.handler, daemon=True) handle_thread.start() def handler(self): """ receive commands from terminal """ while True: print("input...") line=input() self.parse(line) self.update(self.polygons_3D) #def clear(self): #cube1=Cube(self) #cube1.set_name("s*") #self.polygons_3D=[self.cube1] #self.clear_cxyz() #cc1=self.cube1.get_cube_center() #self.cxyz[round(cc1.x)+self.pcx][round(cc1.y)+self.pcy][round(cc1.z)+self.pcz]=1 #self.update(self.polygons_3D) def parse(self,line): #self.python2fwb(">"+line) print("Space:parse "+line) p=line.find("send up ") if(p<0): return xl=line[(p+len("send up ")):] #print("xl="+xl) px=parser(xl) px.rb() if not (px.key("\"")): return if not px.key("str "): return px.rb() if not px.key("("): return px.rb() if not px.key("this "): return px.rb() xn=[""] if not px.d_name(xn): return px.rb() dn1=xn[0] cn=[(0,0)] if not px.connect(cn): return cn1=cn[0] px.rb() if not px.key("next "): return px.rb() xn=[""] if not px.d_name(xn): return dn2=xn[0] px.rb() if not px.connect(cn): return cn2=cn[0] px.rb() if not px.key(")"): return px.rb() if not px.key("\""): return px.rb() if not px.key("."): return print("dn1="+dn1) cc2=None cube1=self.lookUpCube(dn1) if cube1 == None: print("new "+dn1) cube1=Cube(self) cube1.set_name(dn1) self.polygons_3D.append(cube1) cc1=cube1.get_cube_center() self.cxyz[round(cc1.x)+self.pcx][round(cc1.y)+self.pcy][round(cc1.z)+self.pcz]=1 print(self.cxyz) print("dn2="+dn2) cube2=self.lookUpCube(dn2) if cube2 == None: print("new "+dn2) cube2=Cube(self) cube2.set_name(dn2) self.polygons_3D.append(cube2) print(cn1) print(cn2) if1=cn1[0] if2=cn2[0] id1=cn1[1] id2=cn2[1] v2=cube1.get_next_place_position(if1) cube2.moveTo(v2.x,v2.y,v2.z) cube1.rotate_nextdoor_cube_until_match_the_face(if1, cube2, if2) cube1.rotate_nextdoor_cube_until_match_the_direction(if1,cube2,if2,id2) self.update(self.polygons_3D) cc2=cube2.get_cube_center() self.cxyz[round(cc2.x)+self.pcx][round(cc2.y)+self.pcy][round(cc2.z)+self.pcz]+=1 #print(self.cxyz) #self.make_pjxy() #self.make_pjyz() #self.make_pjzx() #print("rotate_z_cw_90") #self.rotate_z_cw_90() #self.make_pjxy() #self.make_pjyz() #self.make_pjzx() #print("rotate_x_cw_90") #self.rotate_x_cw_90() #self.make_pjxy() #self.make_pjyz() #self.make_pjzx() def set_factory(self,factory): self.factory=factory class parser: # # srs. # ok. # fid=2. received=ack1 face 4 dir 0 uDir 0. # this face(2):dir(0)<-> next face(4):dir(0) # send up "str (this s* f2d0 next s*4 f4d0)". # fid=2, received=send up "str (this s*4 f2d0 next s*44 f4d0)". # str (this s*4 f2d0 next s*44 f4d0) # ok # fid=2, received=send up "str (this s*44 f2d0 next s*444 f4d0)". # str (this s*44 f2d0 next s*444 f4d0)". # ok # def __init__(self,line): self.line=line print("parser init "+line) def alpha(self,p2a): #print("alpha line="+self.line) c=self.line[0] p2a[0]=c if(c.isalpha()): self.line=self.line[1:] return True return False def digit(self,p2i): #print("digit line="+self.line) c=self.line[0] if(c.isdigit()): p2i[0]=int(c) self.line=self.line[1:] return True return False def d_name(self,xn): #print("d_name line="+self.line) cl=[''] if not self.alpha(cl): return False xn[0]=xn[0]+cl[0] if not self.key("*"): return False xn[0]=xn[0]+"*" dx=[0] while self.digit(dx): xn[0]=xn[0]+str(dx[0]) return True def connect(self,tx): #print("connect line="+self.line) if not self.key("f"): return False fx=[0] if not self.digit(fx): return False if not self.key("d"): return False dx=[0] if not self.digit(dx): return False tx[0]=(fx[0],dx[0]) return True def key(self,key): #print("key line="+self.line) #print("key="+key) tf=self.line.startswith(key) print(tf) if(self.line.startswith(key)): lk=len(key) self.line=self.line[lk:] return True return False def rb(self): while self.key(' '): continue # # +-----------------------------------------------------+ # | TESLA | # | +-----------+ +--------------+ DICE | # | | mbed | |m5atom | | # | | |<--UART-->|tcp_server_ex1| | # | +-----------+ +--------------+ | # | ^ | # +--------------------------- | -----------------------+ # | # wifi.... SSID YAMA-M5ATOM-EX01 # | PASS 12345678 # | # +--------------------------- | -----------------------+ # | v PC | # | +------------------+ | # | |Chat_Client | # | | | # | v | # | handler | # | | | # | v | # | parser | # | | | # +----|-------------+ # | # | put # v # +------------------+ # |ex04.py | # | | | # | v | # | handler | # +------------------+ # # coding: utf-8 #from PIL import Image, ImageFont, ImageDraw #import time #import sys #import requests #import os #import socket #import threading #from collections import deque #import subprocess #import copy class Factory_Client: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) HOST = 'localhost' PORT = 9998 def __init__(self): print("start Factory_Client.__init__") def start_input_thread(self): handle_thread2 = threading.Thread(target=self.start_input, args=(self.sock,), daemon=True) handle_thread2.start() # operation example # 1. turn on all tesla dices # 2. start this program, tesla_transformer_20240813_01.py # Graphics window will be displayed. # 3. input h. for confirmation of the connection between # this program and tesla dices. # 4. assemble the object by putting together the tesla dices. # 5. input the command, "srs." for start recursive structure analysis. # 6. the assemble object will be displayed on the graphics window. # 7. input the command, "rotate f." # 8. input the command, "generate." # 9. input the command, "assemble." def send_message_nl(self,py2x_message): msg=py2x_message+'\n' try: self.sock.sendall(msg.encode('utf-8',errors='replace')) except Exception as e: print("send message error: {0}".format(e)) return print("send the message to the factory.") def send_message(self,py2x_message): msg=py2x_message try: self.sock.sendall(msg.encode('utf-8',errors='replace')) except Exception as e: print("send message error: {0}".format(e)) def client_start(self): """start client""" try: self.sock.connect((self.HOST, self.PORT)) except Exception as e: print("factory connect error: {0}".format(e)) return print("factory {0}:{1} connected".format(self.HOST, self.PORT)) handle_thread = threading.Thread(target=self.handler, args=(self.sock,), daemon=True) handle_thread.start() def handler(self,sock): """receive the message from the server and print it.""" while True: lx="" while True: data = sock.recv(1024) dl=len(data) try: rd=data.decode('utf-8') except: rd='?'*dl for i in range(rd): c=rd[i] lx=lx+c if c=="." or c=="\n": print("[receive] "+lx) lx="" if c=="." or c=="\n": break print("[receive]-"+lx) if self.space!=None: print("factory-"+lx) class Chat_Client: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) HOST = '192.168.4.1' PORT = 23 def __init__(self): print("start Chat_Client.__init__") def set_space(self,space): self.space=space def start_input_thread(self): handle_thread2 = threading.Thread(target=self.start_input, args=(self.sock,), daemon=True) handle_thread2.start() def set_factory(self,factory): self.factory=factory # operation example # 1. turn on all tesla dices # 2. start this program, tesla_transformer_20240813_01.py # Graphics window will be displayed. # 3. input the command, "connect dice." # 4. input the commnad, "connect factory." # 5. input h. for confirmation of the connection between # this program and tesla dices. # 6. assemble the object by putting together the tesla dices. # 7. input the command, "srs." for start recursive structure analysis. # 8. the assemble object will be displayed on the graphics window. # 9. input the command, "rotate f." # 10. input the command, "generate." # 11. input the command, "assemble." def start_input(self,sock): print("sock=") print(sock) print("input...") line="" cx=bytearray(8) while True: try: line=input() if line=="clear.": self.send_message("srr.") self.space.clear() elif line.startswith("connect "): line=line[len("connect "):] while line.startswith(" "): line=line[1:] if line.startswith("factory."): self.factory.client_start() elif line.startswith("dice."): self.client_start() elif line.startswith("print "): line=line[len("print "):] while line.startswith(" "): line=line[1:] if line.startswith("xy."): space.make_pjxy() elif line.startswith("yz."): space.make_pjyz() elif line.startswith("zx."): space.make_pjzx() elif line.startswith("rotate "): line=line[len("rotate "):] while line.startswith(" "): line=line[1:] if line.startswith("z."): space.rotate_z_cw_90() elif line.startswith("y."): space.rotate_y_cw_90() elif line.startswith("x."): space.rotate_x_cw_90() elif line.startswith("f."): space.move_and_rotate_for_factory() elif line.startswith("generate."): self.proc=space.generate_assemble_procedure() print("generated proc=") print(self.proc) elif line.startswith("assemble."): self.factory.send_message_nl(self.proc) elif line.startswith("send "): space.parse(line) else: for i in range(len(line)): c=line[i] #c=readchar.readkey() #print(c) #cx[0]=c.encode('utf-8') #cx[1]=0x00 sock.sendall(c.encode('ascii',errors='replace')) time.sleep(0.01) except: print("error") def send_message_nl(self,py2x_message): msg=py2x_message+'\n' self.sock.sendall(msg.encode('ascii',errors='replace')) def send_message(self,py2x_message): msg=py2x_message try: self.sock.sendall(msg.encode('ascii',errors='replace')) except Exception as e: print(e) def parse(self,line): vf.parse(line) def client_start(self): """start client""" self.sock.connect((self.HOST, self.PORT)) handle_thread = threading.Thread(target=self.handler, args=(self.sock,), daemon=True) handle_thread.start() def handler(self,sock): """receive the message from the server and print it.""" while True: lx="" while True: data = sock.recv(1024) dl=len(data) try: rd=data.decode('utf-8') except: rd='?'*dl for i in range(dl): c=rd[i] lx=lx+c if c=="." or c=="\n": print("[receive] "+lx) self.parseLines(lx) lx="" #print(c) if c=="." or c=="\n": break print("[receive]-"+lx) if self.space!=None: print("parse-"+lx) self.parseLines(lx) def parseLines(self,ls): lsx=ls.splitlines() for i in range(len(lsx)): self.space.parse(lsx[i]) class Offline_Client: def __init__(self): print("start Offline_Client.__init__") def set_space(self,space): self.space=space def start_input_thread(self): handle_thread2 = threading.Thread(target=self.start_input, args=(self.space,), daemon=True) handle_thread2.start() def start_input(self,space): print("input...") line="" while True: try: line=input() if line=="clear.": space.clear() elif line.startswith("print "): line=line[len("print "):] while line.startswith(" "): line=line[1:] if line.startswith("xy."): space.make_pjxy() elif line.startswith("yz."): space.make_pjyz() elif line.startswith("zx."): space.make_pjzx() elif line.startswith("connect "): line=line[len("connect "):] while line.startswith(" "): line=line[1:] if line.startswith("factory."): factory.client_start() elif line.startswith("dice."): client.client_start() elif line.startswith("rotate "): line=line[len("rotate "):] while line.startswith(" "): line=line[1:] if line.startswith("z."): space.rotate_z_cw_90() elif line.startswith("y."): space.rotate_y_cw_90() elif line.startswith("x."): space.rotate_x_cw_90() elif line.startswith("f."): space.move_and_rotate_for_factory() elif line.startswith("generate."): proc=space.generate_assemble_procedure() print("generated proc=") print(proc) else: space.parse(line) except Exception as e: print(e) print("error") if __name__ == "__main__": client=Chat_Client() #client=Offline_Client() space=Space() factory=Factory_Client() client.set_space(space) space.set_factory(factory) #client.client_start() client.start_input_thread() client.set_factory(factory) space.start_3d() }}