Welcome To Our Shell

Mister Spy & Souheyl Bypass Shell

Current Path : /home/ift/52_procpy/dataninja/

Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
Upload File :
Current File : //home/ift/52_procpy/dataninja/rearr_grid.py

import os
import sys
import re
import math
import procpy
import tkinter
import random


try:
    import json
except:
    import pip
    pip.main(["install","json"])
    import json


#************************************************************************

class Rearr_grid (object):

    def __init__ (self,graph):
    
        self.graph = graph
        self.max_w = graph.zoom_factor*70
        self.min_w = graph.zoom_factor*10

#************************************************************************
# not execute anywhere.
    def rearrange (self,griddata,mode):
            
        if mode == 0:
            self.fit_blocks_to_grid(griddata)
        self.newbends_for_arrows()
        
        return(griddata)

# This function never be used by any model except reaarange
#************************************************************************
    # This function never be used by any model
    def fit_blocks_to_grid (self,griddata):
        
        for block in self.graph.blocks:
            x  = griddata['X'] * int((block.bbox[0] + 0.5*griddata['X'])/griddata['X'])
            y  = griddata['Y'] * int((block.bbox[1] + 0.5*griddata['Y'])/griddata['Y'])
            dx = block.bbox[0] - x
            dy = block.bbox[1] - y
            block.newbbox = [ block.bbox[0] - dx, block.bbox[1] - dy,
                              block.bbox[2] - dx, block.bbox[3] - dy ]
        return()

#************************************************************************

    def newbends_for_arrows (self):
        print("newbends_for_arrows-nxs")
        for block in self.graph.blocks:
            block.define_exit_and_enter() # set back to general exit/entrance
            
        for block in self.graph.blocks:
            for arrow in block.arrows_out:
                try:
                    del arrow.channels  # old channelas are removed
                    del arrow.dir       # old direction of arrow is removed
                except:
                    continue

            for arrow in block.arrows_out:
                jump             = arrow.target_block
                # block is source, arrow out; jump is target, arrow in. by nxs
                arrow.channels, arrow.dir   = self.compute_channels(block,jump)
                arrow.anchorline = 0
                
        self.compare_channels()

        self.choose_points_from_channels()
        
                
#************************************************************************
#
    def choose_direction(self, source, target, var):

        # use local variable
        var1 = var

        # if there is only one single main direction in var (w, n, s, e): return
        if len(var1)==1:
            return var1

        # calculate target midpoint and bisecting lines of the source block (calc. at target_midpoint)
        target_midpoint = [(target.bbox[0]+target.bbox[2])/2,(target.bbox[1]+target.bbox[3])/2]

        # define two main directions for the general comparison below
        if "w" in var1 and "e" in var1 and "n" in var1 and "s" in var1:
            dir1 = "n"
            dir2 = "wse"
        elif "w" in var1 and "e" in var1:
            dir1 =  var1.replace("w","").replace("e","")
            dir2 = "we"
        elif "n" in var1 and "s" in var1:
            dir1 =  var1.replace("n","").replace("s","")
            dir2 = "ns"
        elif "s" in var1: # len of var1 is two
            dir1 = var1.replace("s","")
            dir2 = "s"
        elif "n" in var1:
            dir2 = "n" # len of var1 is two
            dir1 = var1.replace("n","")  


 
        G1 = 0

        if dir2 == "we" or dir2=="wse":
            t = target_midpoint[0]
            if dir1 in "sn":
                G1 = source.newbbox[0]
                G2 = source.newbbox[2]
            else:
                G1 = 0
                G2 = (source.newbbox[0]+source.newbbox[2])/2
                dir1 = "w"
                dir2 = "e"
        else:
            t = target_midpoint[1]
            G1 = source.newbbox[1]
            G2 = source.newbbox[3]
            if dir2 == "n":
                G2 = 999999
            elif dir2 == "s":
                G1 = 0
            elif dir1 == "":
                G1 = 0
                G2 = (source.newbbox[1]+source.newbbox[3])/2
                dir1 = "n"
                dir2 = "s"

        if G1 < t < G2:
            re = dir1
        else:
            re = dir2

        if len(re)>1:
            re = self.choose_direction(source, target, re)
#        print re
        return re

#************************************************************************

    def adjust_exit_and_entrance(self, block,shape,exit="",entrance=""):

        ''' 
        gives the possibility to change the exit and entrance definition of the block 
        depending on the shape of the block
        '''

        if block.shape in shape:
            exit     = block.exit.replace(exit, "")
            entrance = block.entrance.replace(entrance, "")
            block.define_exit_and_enter(exit, entrance)
 
#************************************************************************
# define the arrow exit position , by nxs
    def define_starting_channel(self,source, target, nextdirection): 

        
        exit = self.choose_direction(source,target, source.exit)
        self.adjust_exit_and_entrance(source,"iwfm", exit,"")# SHAPE-002 VALID: for diamonds: only one arrow exit on each side

        if  exit in "we": #arrows should exit in east or west
            newchannel        = [source.newbbox[1],source.newbbox[3]]
            first_dir         = 'X'  #modify by nxs
            if  exit == "e":
                channel_length = [source.newbbox[2]]
                channel_length.append({True: nextdirection['Y'][1], False:source.newbbox[2]+self.max_w}[target.newbbox[0]>source.newbbox[2]+self.min_w])
            elif  exit == "w":
                channel_length = [max(0,min(nextdirection['Y'][0],source.newbbox[0]-self.max_w)),source.newbbox[0]]

        elif  exit in "ns": #arrows should exit in north or south
            newchannel        = [source.newbbox[0],source.newbbox[2]]
            first_dir         = 'Y'
            if  exit == "n" :           
                channel_length    = [max(0,min(source.newbbox[1]-self.max_w,nextdirection['X'][0])),source.newbbox[1]] 
            elif  exit == "s":            
                channel_length    = [source.newbbox[3],max(source.newbbox[3]+self.max_w,nextdirection['X'][1])] 
#        else: ##### 
#            newchannel        = [source.newbbox[1],source.newbbox[3]]
#            channel_length    = [min(source.newbbox[2],nextdirection['Y'][0]),max(source.newbbox[0],nextdirection['Y'][1])]
#            first_dir         = 'X'

        return newchannel, channel_length, first_dir, exit

#************************************************************************
    def define_nextdirection(self,source, target):

        nextdirection = {'Y':[],'X':[]}
        #by NXS

        entrance = self.choose_direction(target, source, target.entrance)
        self.adjust_exit_and_entrance(target,"iwfm", "",entrance)# SHAPE-002 VALID: for diamonds: only one arrow enter on each side

        #### define nextdirection if entrance is west/east

        ### nxs


        if entrance =="w":
            nextdirection['Y'].append({True: max(source.newbbox[2],target.newbbox[0]-self.max_w),
                                       False: max(0,target.newbbox[0]-self.max_w)}[source.newbbox[2]<target.newbbox[0]-self.min_w])
            nextdirection['Y'].append(target.newbbox[0])
        elif entrance == "e":
            nextdirection['Y'].append(target.newbbox[2])
            nextdirection['Y'].append({True: min(source.newbbox[0],target.newbbox[2]+self.max_w),
                                       False: target.newbbox[2]+self.max_w}[source.newbbox[0]>target.newbbox[2]+self.min_w])
        else:
            nextdirection['Y']     = [target.newbbox[0],target.newbbox[2]]

        #### define nextdirection if entrance is north/south
        if entrance =="n":
            nextdirection['X'].append({True: max(source.newbbox[3],target.newbbox[1]-self.max_w),
                                       False: max(0,target.newbbox[1]-self.max_w)}[source.newbbox[3]<target.newbbox[1]-self.min_w])
            nextdirection['X'].append(target.newbbox[1])
        elif entrance == "s":
            nextdirection['X'].append(target.newbbox[3])
            nextdirection['X'].append({True: min(source.newbbox[1],target.newbbox[3]+self.max_w),
                                       False: target.newbbox[3]+self.max_w}[source.newbbox[1]>target.newbbox[3]+self.min_w])
        else:
            nextdirection['X']     = [target.newbbox[1],target.newbbox[3]]

        return nextdirection                         # <-- ENDREQ

#************************************************************************

    def compute_channels(self,source, target):

        nextdirection = self.define_nextdirection(source, target) # define nextdirection depending on entrance of target
        newchannel, channel_length, first_dir, arrow_dir = self.define_starting_channel(source, target, nextdirection)
        direction         = first_dir                              # the direction of the current newchannel, x or y
        target_dock       ={'Y':[target.newbbox[1],target.newbbox[3]],'X':[target.newbbox[0],target.newbbox[2]]} 
        target_reached    = 0                                      # is 1 if target is reached
        channel           = []                                     # the computed channels
        count             = 0                                      # counts the channels
        secondrun         = True                                  # determines the trys to create fitting channels

        ### Definition of mode: how to go around blocks #####
        if source.newbbox[3]>=target.newbbox[3]: # evtl. anpassung noetig in y-direction
            mode          = 1
        else:
            mode          = 0    

        while target_reached == 0:
            ### Not-Stopp ####################################
            if count>=20:
                if not secondrun:
                    mode       = {1:0,0:1}[mode]
                    newchannel = channel[0]
                    channel    = []
                    count      = 0
                    secondrun  = True
                else:
                    print("*********************************************")
                    print("**** Please reorder your blocks *************")
                    print("*********************************************")
                    return

            direction = {'X':'Y','Y':'X'}[direction]
            
            ### calculate optimal width of newchannel ############
            newchannel = self.channel_optimal_width(newchannel, channel_length, direction)

            ### append optimal newchannel to channel #############
            channel.append(newchannel)

            leftright=nextdirection[direction][1]>=channel_length[1]
            #target.newbbox[3]>=channel_length[1],'Y':target.newbbox[2]>=channel_length[1]}
            # unten_ leftright[direction]
            ### new channel ####################################
            newchannel = self.new_channel(newchannel,channel_length, direction, 
                                          nextdirection[direction][1]>=channel_length[1])
            ### if old direction is chosen again ###############
            if len(channel)>=2 and newchannel!="" and (abs(newchannel[0]-channel[-2][0])<1 or abs(newchannel[1]-channel[-2][1])<1):    # and in or geaendert
                
                if mode == 0:
                    newchannel=  [max(0,channel[-1][0]-self.max_w), channel[-1][0]]
                else:
                    newchannel=  [channel[-1][1], channel[-1][1]+self.max_w]
                del channel[-1]
                direction={'X':'Y','Y':'X'}[direction]

            ### no newchannel was calculated ####################
            if newchannel=="":
                 
                ### nextdirection can not be taken because it does not intersect with current channel
                if nextdirection[direction][1]<=channel_length[0] or nextdirection[direction][0]>=channel_length[1]: # --> SHAPE-001-VALID
                   newchannel = channel_length # <-- ENDREQ
                elif channel[-1][0] < (target_dock[direction][0]+target_dock[direction][1])/2 < channel[-1][1]: 
                # target_block and channel overlap but are note exactly on the same level; only if source doesnt have diamond/circle shape!
                    target_reached = 1
                    channel[-1]    = self.docking(channel[-1], source, target, target_dock[direction])
                elif (target_dock[direction][0]-channel[-1][0]<=0.5 and # --> BUG-0002-VALID
                    target_dock[direction][1]-channel[-1][1]>=-0.5):   # <-- ENDREQ
                    ### target is reached  
                    target_reached = 1  
                else:
                    ### take the shortest possible way
                    newchannel = nextdirection[direction]
                            
             
            #### Channel length ################################
            diff1 = nextdirection[{'X':'Y','Y':'X'}[direction]][0] - channel[-1][0] # --> SHAPE-001-VALID
            diff2 = nextdirection[{'X':'Y','Y':'X'}[direction]][1] - channel[-1][1]
            if (diff1<=0) and (diff2>=0):
                channel_length = channel[-1]
            else:
                channel_length = [min(channel[-1][0],nextdirection[{'X':'Y','Y':'X'}[direction]][0]),
                                  max(channel[-1][1],nextdirection[{'X':'Y','Y':'X'}[direction]][1])] # <-- ENDREQ
            count += 1

        return channel, arrow_dir

#**************************************************************

    def docking(self, channel, source, target, target_dock):

        # target_block and channel overlap but are note exactly on the same level
        if target.shape in "iwfm":
        # use target midpoint 
            midpoint = (target_dock[0]+target_dock[1])/2
            dist     = min(abs(midpoint - channel[0]),abs(midpoint - channel[1]))
            channel  = [midpoint-dist, midpoint+dist]
        elif source.shape in "iwfmce":
        # use channel (=source) midpoint
            midpoint = (channel[0]+channel[1])/2
            dist     = min(abs(midpoint - target_dock[0]),abs(midpoint - target_dock[1]))
            channel  = [midpoint-dist, midpoint+dist]
        else:
        # use intermediate channel
            channel = [max(channel[0],target_dock[0]), min(channel[1],target_dock[1])]

        return(channel)

#**************************************************************

    def block_coordinates(self,block, direction):

         if direction == 'Y':
             cx1 =  block.newbbox[0]
             cx2 =  block.newbbox[2]
             cy1 =  block.newbbox[1]
             cy2 =  block.newbbox[3]
         else:
             cx1 =  block.newbbox[1]
             cx2 =  block.newbbox[3]
             cy1 =  block.newbbox[0]
             cy2 =  block.newbbox[2]
          
         return cx1, cx2, cy1, cy2

#**************************************************************

    def new_channel(self,channel,channel_length,direction,leftright):

        #Coordinates of channel
        ax1 =  channel_length[0]
        ax2 =  channel_length[1]
        ay1 =  channel[0]
        ay2 =  channel[1]

        newchannel     = ""
        for block in self.graph.blocks:

            cx1,cx2,cy1,cy2 = self.block_coordinates(block, direction)
                  
            if (ax1<cx1<ax2 or ax1<cx2<ax2) and (ay1<cy1<ay2 or ay1<cy2<ay2 or (cy1<=ay1 and cy2>=ay2)):
                if leftright == 1:	
                    ax1 = min(ax1,cx2)
                    ax2 = min(cx1,ax2)
                else:
                    ax1 = max(ax1,cx2)
                    ax2 = max(cx1,ax2)
                newchannel = [ax1,ax2]
                 
        return newchannel

#************************************************************************

    def channel_optimal_width(self,channel, channel_length, direction):

        optimal_channel = [channel[0],channel[1]]
        minimal_width   = self.min_w
        
        #Coordinates of channel
        ax1 =  channel_length[0]
        ax2 =  channel_length[1]
        ay1 =  channel[0]
        ay2 =  channel[1]

        for block in self.graph.blocks: #blocklist:
            cx1,cx2,cy1,cy2 = self.block_coordinates(block, direction)
            if (ax1 <= cx1 < ax2) or (ax1 < cx2 <= ax2):
                if ay1 <= cy1 < ay2:
                     optimal_channel[1] = min(cy1,ay2)  
                elif ay1 < cy2 <= ay2:
                     optimal_channel[0] = max(cy2,ay1)

        if (optimal_channel[1]-optimal_channel[0])<minimal_width:
             optimal_channel = channel
        return optimal_channel

#************************************************************************

    def choose_points_from_channels(self):


        for block in self.graph.blocks:
            for arrow in block.arrows_out:
                if not 'channels' in vars(arrow):
                    continue
                jump = arrow.target_block
                arrow.newbends = []
                p             = {'X': None, 'Y': None }

                if arrow.dir in "ns": # --> SHAPE-001-VALID
                    act_direction = 'Y'
                else:
                    act_direction = 'X'                       # <-- ENDREQ
                
                for channel in arrow.channels:
                    act_direction = { 'X': 'Y', 'Y': 'X'}[act_direction]
                    #pos = random.uniform(0.01,0.99) 
                    pos = 0.5
                    p[act_direction] = pos*channel[0] + (1-pos)*channel[1]
                    if len(arrow.channels)==1:
                        if act_direction=='Y':
                            p['X']= (jump.newbbox[0]+block.newbbox[2])/2
                        else:
                            p['Y']= (jump.newbbox[1]+block.newbbox[3])/2
                    if p['X'] and p['Y']:
                        arrow.newbends.append([p['X'],p['Y']])                    

        return()


#************************************************************************

    def compare_channels(self):
        for block in self.graph.blocks:
            for arrow in block.arrows_out:
                if not 'channels' in vars(arrow):
                    continue
                pos = 0
                for channel in arrow.channels:
                    arrow.channels[pos] = self.fit_to_parallel_channels(block, arrow.target_block, arrow.channels, pos, arrow.dir)
                    pos += 1
        return()

#****************************************************************
    def fit_to_parallel_channels(self,source, target, channels, pos, dir):
        
        a = channels[pos] 
        direction_a = {True: 'X', False: 'Y'}[(dir in "ns")^(pos%2==0)]
        # the direction of the current channel depends on the direction fo the arrow and the channel number
        ax1, ax2 = self.get_channel_length(source, target, channels, pos, direction_a)

        for block in self.graph.blocks:
            for arrow in block.arrows_out:
                pos_b = 0
                
                for chan in arrow.channels:
                    direction_b = {True: 'X', False: 'Y'}[
                        (arrow.dir in "ns")^(pos_b%2==0)]
                    bx1, bx2 = self.get_channel_length(block, arrow.target_block, arrow.channels, pos_b, direction_b)
                    if block==source and arrow.target_block==target and pos_b==pos:
                        pass	
                    elif direction_a == direction_b and ((ax1 <= bx1 < ax2) or (ax1 < bx2 <= ax2)
                             or (bx1<=ax1 and bx2>=ax2)):
                        if a[0] < chan[0] < a[1] and a[1]-chan[1]<chan[0]-a[0]:
                            a[1] = chan[0]
                        elif  a[0] <  chan[1] <  a[1] and  a[1]-chan[1]> chan[0]-a[0]:
                            a[0] = chan[1]
                        elif  (chan[0]<= a[0] and  chan[1]>= a[1]) or (a[1]-chan[1])==(chan[0]-a[0]):
                            a[1] = (a[0]+a[1])/2
                                                
                    pos_b += 1
        return(a)
                     
 #******************************************************

    def get_channel_length(self,source, target,channels, pos,direction):

 
        if pos == 0 and direction == 'X':                   # --> BUG-0004-VALID 
            x1  = (source.newbbox[0]+source.newbbox[2])/2   # arrow starts from diamond shape in 
        elif pos == 0 and direction == 'Y':                 # y-direction, must be taken care off 
            x1  = (source.newbbox[1]+source.newbbox[3])/2   # here 
        else:
            x1  = (channels[pos-1][0]+channels[pos-1][1])/2
                   
        if pos == len(channels)-1 and direction=='X':
            x2  = (target.newbbox[0]+target.newbbox[2])/2
        elif pos == len(channels)-1 and direction=='Y':
            x2  = (target.newbbox[1]+target.newbbox[3])/2
        else:
            x2  = (channels[pos+1][0]+channels[pos+1][1])/2 # <-- ENDREQ

        xx1 = min(x1,x2)
        xx2 = max(x1,x2)
        
        return(xx1,xx2)


bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped)
Email: contact@elmoujehidin.net bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped) Email: contact@elmoujehidin.net