###################################
### DM2_w25 # AGruber@tugraz.at ###
### hu_06 UN_headquaters  NYC   ### CRVs 4 ROLLER.COASTER | SETUP
###################################


##############################
import rhinoscriptsyntax as rs
import random, time, sys   ###
sys.path.append("/Users/lukas/Desktop/Studium_Architektur/Semester_3/dm2")     ###
sys.path.append("P:/WWW/lukschme/dm2/")
import DM_lib as dm        ### dm.reload_lib(dm)
##############################      

rs.UnitSystem(4)                                            # meters = 4, cm = 3 etc
rs.ShowGrid(None, False)                                    # grid > False = off
rs.ShowGridAxes(None, True)                                 # y/y/z axen display > False/True = off/on
rs.ViewDisplayMode(rs.CurrentView(), "wireframe")
rs.Command("cplane w t enter", False)				        # cPlane World Top
dm.PointRadius(displayModeX=0, rad=3, styl=3)               # 0 => wireframe | info: (.., verbose=1)
#dm.PointRadius(displayModeX=1, rad=4, styl=1)               # 1 => shaded    | info: (.., verbose=1)
#dm.PointRadius(displayModeX=2, rad=2, styl=0)               # 2 => rendered  | info: (.., verbose=1)
dm.printDisplay(state=False)                                # nomen est omen
rs.EnableRedraw(False)



###_________________________________________#
### basic settings for grid to fit UN_slab  #
###                                         # ! no need 2 change !
floors = H  = dm.H = 40                     # default=40 / incl roof
slabs  = L  = dm.L = 11                     # default=11
depth  = D  = dm.D =  4                     # default= 4 / division in building_depth
floorHeight = fH = dm.fH = 4.0              # default= 4.0 / 4.0*(H-1) = 156 meters
                                            #
#############                               # get gridCoords L*D*H = 1760
UnoGridCoords = dm.getUnoGridCoords()       # get from DM_lib as dm
#################___________________________#


#######################
### my little helper: ###############
### gC (get_Coord) im UN_grid !     #
def gC(L,D,H): return dm.gC(L,D,H)  #
#####################################

##################
depthVec  = dVec = rs.VectorUnitize(rs.VectorSubtract( gC(0, 0, 0), gC(0, 2, 0) ))
lengthVec = lVec = rs.VectorUnitize(rs.VectorSubtract( gC(0, 0, 0), gC(1, 0, 0) ))
##################

UnoPanelCoords = dm.UnoPanelCoords          # get panelCoords [frontPanels, backPanels, sidePanels, upSidePanels] / default arguments s.u.
################____________________________#
UnoPanelCoords = dm.getUNpanelCoords(anzL=10*7, anzH=39, anzD=3, stepL=1, stepH=1, stepD=1) ### = all ~windows_panels
BigPanelCoords = dm.getUNpanelCoords(anzL=10*1, anzH=39, anzD=3, stepL=2, stepH=7, stepD=2) ### = all ~windows_panels
UnoPanelCoords = dm.getUNpanelCoords(anzL=10*1, anzH=39, anzD=3, stepL=2, stepH=7, stepD=2) ### = standard for hu_05
###VO Panel
UnoPanelCoords = dm.getUNpanelCoords(anzL=10*2, anzH=39*2, anzD=3*2, stepL=2, stepH=4, stepD=2) ### = 
UnoPanelCoords_sockel = dm.getUNpanelCoords(anzL=10*2, anzH=39*2, anzD=3*2, stepL=7, stepH=7, stepD=2)
###########################################################################################
##########################################################
frontPanels   = UnoPanelCoords[0]
frontPanels_sockel   = UnoPanelCoords_sockel[0]
backPanels    = UnoPanelCoords[1]
upSidePanels  = UnoPanelCoords[3]
upSidePanels_sockel  = UnoPanelCoords_sockel[3]
sidePanels    = UnoPanelCoords[2]
allPanels     = UnoPanelCoords[4]
#################################


dm.newEmptyLayer("UNO::setUp", [120,120,140])
if 1: ### SETUP >> dont' exec @ homework !
    if 0: 
        rs.AddPoints(UnoGridCoords)       ### just 4 reference
        cor = gC(0,0,0)
        rs.AddLine([0,0,0],gC(0,0,10))
    if 1:
        rs.AddLine( gC(0, 0, 0), gC(10, 0, 0) )
        rs.AddLine( gC(0, 0, 0), gC(0,  3, 0) )
        rs.AddLine( gC(0, 0, 0), gC(0, 0, 39) )
        rs.ObjectColor(rs.AllObjects()[2], [0, 222, 0] ), rs.CurveArrows(rs.AllObjects()[0], 2)
        rs.ObjectColor(rs.AllObjects()[1], [222, 0, 0] ), rs.CurveArrows(rs.AllObjects()[1], 2)
        rs.ObjectColor(rs.AllObjects()[0], [0, 0, 222] ), rs.CurveArrows(rs.AllObjects()[2], 2)
        rs.ObjectPrintWidth( rs.AllObjects()[0:3], 0.5 )
        
        p0 = gC(  0, 0, 0)
        p1 = gC( 10, 0, 0)
        p2 = gC( 10, 3, 0)
        p3 = gC(  0, 3, 0)
        unoBaseCoords = [p0, p1, p2, p3, p0]
        unoBaseCrv = rs.AddCurve( unoBaseCoords, 1)
        unoTopCoords = [dm.gC(  0, 0, 39),
                        dm.gC( 10, 0, 39),
                        dm.gC( 10, 3, 39),
                        dm.gC(  0, 3, 39),
                        dm.gC(  0, 0, 39),
                       ]
        unoTopCrv = rs.AddCurve( unoTopCoords, 1)
        rs.ZoomExtents()
    if 0: ### long version
        coords = []
        for y in range(11): ### 2 == intervall
            for z in range(0, 40, 2):
                for x in range(0, 4, 3):
                    coords.append( dm.gC(y,x,z) )
        rs.AddPoints( coords )
        dm.SetObjDisplayModeAllViewports(rs.AddPoints( coords ), displaymodeX=0, verbose=1)
    
    if 1: ### smart version / comprehension
        pnts = rs.AddPoints([ dm.gC(y,x,z) for y in range(11) for z in range(0, 40, 2) for x in range(0, 4, 3) ])
        dm.SetObjDisplayModeAllViewports(pnts, displaymodeX=2, verbose=0) ### 2 == rendered


    
    
    #### CAMERA
    #### set / get camera
    if 1:
        print ("ViewNames :"),
        print (rs.ViewNames())
        
        cam = gC(5, -20, 19.5)
        tar = gC(5, 0, 19.5)
        rs.AddLine( cam, tar )
        
        dm.setCameraTarget( cam, tar, 500.0, 0, 0, 0)
        #rs.ViewProjection(view='Perspective', mode=1)   ### 1 = parallel, 2 = perspective, 3 = two point perspective
        dm.getCameraTarget(view=rs.CurrentView(), verbose=1)
        #dm.setCameraTarget( [334.42526127, 493.18649387, 171.88081703], [756.84885751, 592.83573956, 82.0], lens=50.0, rota=0, upVec=[0,0,1] ) # ... danke, andi !

#######################################
################ HERE YOU GO AS YOU GO:
dm.newEmptyLayer("myPROJ", [111,111,111])

coordsBalkon=[]

###Test Panel uebung
def myTsTPanel(panel, shuffle=1):
    p0,p1,p2,p3 = panel
    coords = [p0,p1,p2,p3,p0]
    if shuffle:
        random.shuffle( coords )
    deg = random.randint(1,3)
    rs.ObjectColor( rs.AddCurve( coords, deg ), [40*deg, 40*deg, 40*deg] )
    crv = rs.AddCurve( [p0,p2,p1,p3,p0], 1 )

### def for my fenster
def myfenster( frontPanel, fac=0.1, abstand=0.5, abstand_flugel_left=3,abstand_flugel_right=3,rollo_offen=50,anzahl_lamellen=20, anstellwinkel=1 ):
    #creating a panel for window with rollo
    ###outerframe
    p0,p1, p2, p3 = frontPanel
    outer_frame=rs.AddCurve([p0,p1, p2, p3,p0],1)
    ###generate vector for pushing frame around
    vec_01 = rs.VectorSubtract(p0,p1)
    vec_03 = rs.VectorSubtract(p3,p0)
    normal_vec = rs.VectorCrossProduct(vec_01,vec_03)
    normal_vec = rs.VectorUnitize(-normal_vec)
    normal_vec = rs.VectorScale(normal_vec, abstand)
    ###pushing frame outwards
    outer_frame_abstand=[rs.VectorAdd(cor_outer_frame, normal_vec) for cor_outer_frame in[p0,p1, p2, p3,p0]]
    rs.AddCurve(outer_frame_abstand,1)
    lin_10=rs.AddLine(outer_frame_abstand[1],outer_frame_abstand[0])
    lin_23=rs.AddLine(outer_frame_abstand[2],outer_frame_abstand[3])
    div_lin10=rs.DivideCurve(lin_10,100)
    div_lin23=rs.DivideCurve(lin_23,100)
    
    ###choose random point --> this will determine how far open
    p_open_rollo_r=div_lin10[rollo_offen]
    p_open_rollo_l=div_lin23[rollo_offen]
    
    p_open_rollo_r=rs.VectorAdd(p_open_rollo_r,dVec*anstellwinkel)
    p_open_rollo_l=rs.VectorAdd(p_open_rollo_l,dVec*anstellwinkel)
    

    rs.AddPoint(p_open_rollo_r)
    lin_right=rs.AddLine(outer_frame_abstand[1],p_open_rollo_r)
    lin_left=rs.AddLine(outer_frame_abstand[2],p_open_rollo_l)
    
    ###connect to closet point on crv
    pnt_closest_r = rs.CurveClosestPoint(lin_10,p_open_rollo_r)
    pnt_closest_l = rs.CurveClosestPoint(lin_23,p_open_rollo_l)
    
    #rs.AddPoint(pnt_closest_r)
    rs.AddPoint(p_open_rollo_r)
    #rs.AddLine(p_open_rollo_r,pnt_closest_r)
    #rs.AddLine(p_open_rollo_l,pnt_closest_l)
    ###generating lamellen
    div_lin_right=rs.DivideCurve(lin_right,anzahl_lamellen)
    div_lin_left=rs.DivideCurve(lin_left,anzahl_lamellen)
    for i in range(anzahl_lamellen+1):
        rs.AddLine(div_lin_right[i],div_lin_left[i])

def mySidePanel(sidePanel):
    p0,p1, p2, p3 = sidePanel
    
    outer_frame_side = rs.AddCurve([p0, p1, p2, p3, p0], 1)
    lin_10_side = rs.AddLine(p1, p0)
    lin_23_side = rs.AddLine(p2, p3)
    div_lin10_side = rs.DivideCurve(lin_10_side, 50)
    div_lin23_side = rs.DivideCurve(lin_23_side, 50)
    for x in range(45):
        rs.AddLine(div_lin10_side[x], div_lin23_side[x])


def myCurtain( backPanel, fac=0.1, abstand=0.5, abstand_flugel_left=3,abstand_flugel_right=3,curtain_offen=10,anzahl_curtain=20 ):
    #creating a panel for window with rollo
    ###outerframe
    p0,p1, p2, p3 = backPanel
    outer_frame=rs.AddCurve([p0,p1, p2, p3,p0],1)
    ###generate vector for pushing frame around
    vec_01 = rs.VectorSubtract(p0,p1)
    vec_03 = rs.VectorSubtract(p3,p0)
    normal_vec = rs.VectorCrossProduct(vec_01,vec_03)
    normal_vec = rs.VectorUnitize(-normal_vec)
    normal_vec = rs.VectorScale(normal_vec, abstand)
    ###pushing frame outwards
    outer_frame_abstand=[rs.VectorAdd(cor_outer_frame, normal_vec) for cor_outer_frame in[p0,p1, p2, p3,p0]]
    rs.AddCurve(outer_frame_abstand,1)
    #p_lin_12=rs.VectorCreate(outer_frame_abstand[1],outer_frame_abstand[2])
    lin_30=rs.AddLine(outer_frame_abstand[0],outer_frame_abstand[3])
    #p_lin_12=rs.VectorScale(p_lin_12,(p_lin_12*0.5))
    p_lin_30=dm.pntInbetween(outer_frame_abstand[0],outer_frame_abstand[3],0.5)
    lin_30=rs.AddLine(outer_frame_abstand[0],p_lin_30)
    lin_12=rs.AddLine(outer_frame_abstand[1],outer_frame_abstand[2])
    halb_p_r=dm.pntInbetween(outer_frame_abstand[0],outer_frame_abstand[1],0.5)
    halb_p_l=dm.pntInbetween(outer_frame_abstand[3],outer_frame_abstand[2],0.5)
    #halb_p_m=dm.pntInbetween(halb_p_r,halb_p_l,0.5)
    halb_halb_r=dm.pntInbetween(outer_frame_abstand[0],halb_p_r,0.5)
    halb_halb_l=dm.pntInbetween(outer_frame_abstand[3],halb_p_l,0.5)
    halb_halb=dm.pntInbetween(halb_halb_r,halb_halb_l,0.5)
    lin_halb=rs.AddLine(halb_halb_r,halb_halb)
    #rs.AddPoints([halb_p_l,halb_p_r])
    

    #rs.AddLine(lin_12)
    div_lin12=rs.DivideCurve(lin_12,100)
    div_lin30=rs.DivideCurve(lin_30,100)
    div_lin_halb=rs.DivideCurve(lin_halb,100)
    
    ###choose random point --> this will determine how far open
    p_open_curtain_u=div_lin12[curtain_offen]
    p_open_curtain_d=div_lin30[curtain_offen]
    p_open_curtain_halb=div_lin_halb[curtain_offen]
    
    lin_up=rs.AddLine(outer_frame_abstand[1],p_open_curtain_u)
    lin_down=rs.AddLine(outer_frame_abstand[0],p_open_curtain_d)
    lin_middle=rs.AddLine(halb_halb_r,p_open_curtain_halb)
    
    ###generating lamellen
    div_lin_up=rs.DivideCurve(lin_up,anzahl_curtain)
    div_lin_down=rs.DivideCurve(lin_down,anzahl_curtain)
    div_lin_middle=rs.DivideCurve(lin_middle,anzahl_curtain)
    for i in range(anzahl_curtain+1):
        rs.AddCurve([div_lin_up[i],div_lin_middle[i],outer_frame_abstand[0]],3)

def myBalkon(backPanel, balkon_tiefe=5, streben_balkon=20):
    
    
    p0,p1, p2, p3 = backPanel
    outer_frame=rs.AddCurve([p0,p1, p2, p3,p0],1)
    ###generate vector for pushing frame around
    #halb = rs.VectorScale(stock,0.5)
    p_balkon_r=rs.VectorAdd(p0,-dVec*balkon_tiefe)
    p_balkon_l=rs.VectorAdd(p3,-dVec*balkon_tiefe)
    p_balkon_halb_r=dm.pntInbetween(p0,p_balkon_r,0.5)
    p_balkon_halb_l=dm.pntInbetween(p3,p_balkon_l,0.5)
    p_h_r=rs.VectorAdd(p0,[0,0,4])
    p_h_l=rs.VectorAdd(p3,[0,0,4])
    p_balkon_r_u=rs.VectorAdd(p_balkon_r,[0,0,4])
    p_balkon_l_u=rs.VectorAdd(p_balkon_l,[0,0,4])
    lin_lower=rs.AddCurve([p0,p_balkon_r,p_balkon_l,p3],1)
    lin_upper=rs.AddCurve([p_h_r,p_balkon_r_u,p_balkon_l_u,p_h_l],1)
    coordsBalkon.append([p_balkon_r,p_balkon_halb_r,p_balkon_l,p_balkon_halb_l])
    
    rs.AddLine(p_balkon_r, p_balkon_r_u)
    rs.AddLine(p_balkon_l, p_balkon_l_u)
    
    div_lin_lower=rs.DivideCurve(lin_lower,streben_balkon)
    div_lin_upper=rs.DivideCurve(lin_upper,streben_balkon)
    for z in range(streben_balkon):
        rs.AddLine(div_lin_lower[z],div_lin_upper[z])
        
    lin_boden_r=rs.AddLine(p0,p_balkon_r)
    lin_boden_l=rs.AddLine(p3,p_balkon_l)
    
    div_boden_r=rs.DivideCurve(lin_boden_r,50)
    div_boden_l=rs.DivideCurve(lin_boden_l,50)
    for b in range(50):
        rs.AddLine(div_boden_r[b],div_boden_l[b])
    
    return [p_balkon_r,p_balkon_halb_r, p_balkon_l,p_balkon_halb_l]
    #    rs.AddPoint(p_balkon_l_u)
    #    rs.AddPoint(p_balkon_r)
    #    rs.AddPoint(p_balkon_l)
    #    ###pushing frame outwards
    #    outer_frame_abstand=[rs.VectorAdd(cor_outer_frame, normal_vec) for cor_outer_frame in[p0,p1, p2, p3,p0]]
    #    rs.AddCurve(outer_frame_abstand,1)
    #    lin_12=rs.AddLine(outer_frame_abstand[1],outer_frame_abstand[2])
    #    lin_30=rs.AddLine(outer_frame_abstand[0],outer_frame_abstand[3])
    #    div_lin12=rs.DivideCurve(lin_12,100)
    #    div_lin30=rs.DivideCurve(lin_30,100)
    #    
    #    ###choose random point --> this will determine how far open
    #    p_open_curtain_u=div_lin12[curtain_offen]
    #    p_open_curtain_d=div_lin30[curtain_offen]
    #    
    #    lin_up=rs.AddLine(outer_frame_abstand[1],p_open_curtain_u)
    #    lin_down=rs.AddLine(outer_frame_abstand[0],p_open_curtain_d)
    #    
    #    ###generating lamellen
    #    div_lin_up=rs.DivideCurve(lin_up,anzahl_curtain)
    #    div_lin_down=rs.DivideCurve(lin_down,anzahl_curtain)
    #    for i in range(anzahl_curtain+1):
    #        rs.AddLine(div_lin_up[i],div_lin_down[i])

###def for my sockel
def mySockel( frontPanel, anzahl_sockel = 50, fac_pilar=0.1, abstand=0.5, fac_door=1, anzahl_door=10 ):
    #wanted to create pillar but it is not correct in x and y
    p0,p1, p2, p3 = frontPanel
    ###for right side
    #    pDr_0 = rs.VectorAdd(p0,[0,fac_pilar,0])
    #pDr_1 = rs.VectorAdd(p0,[fac_pilar,fac_pilar,0])
    #pDr_2 = rs.VectorAdd(p0,[fac_pilar,-fac_pilar,0])
    #pDr_3 = rs.VectorAdd(p0,[0,-fac_pilar,0])
    #    pDr_3=pDr_3 = rs.VectorAdd(pDr_3,lVec)
    pDr_0 = rs.VectorAdd(p0,lVec)
    pDr_0 = rs.VectorAdd(pDr_0,dVec)
    pDr_1 = rs.VectorAdd(p0,lVec)
    pDr_1 = rs.VectorAdd(pDr_1,-dVec)
    pDr_2 = rs.VectorAdd(p0,-lVec)
    pDr_2 = rs.VectorAdd(pDr_2,-dVec)
    pDr_3 = rs.VectorAdd(p0,-lVec)
    pDr_3 = rs.VectorAdd(pDr_3,dVec)
    #rs.AddPoint(pDr_3)
    points_down_r = [pDr_0,pDr_1,pDr_2,pDr_3]
    #rs.AddPoints(points_down_r)
    #    pUr_0 = rs.VectorAdd(p1,[0,fac_pilar,0])
    #    pUr_1 = rs.VectorAdd(p1,[fac_pilar,fac_pilar,0])
    #    pUr_2 = rs.VectorAdd(p1,[fac_pilar,-fac_pilar,0])
    #    pUr_3 = rs.VectorAdd(p1,[0,-fac_pilar,0])
    pUr_0 = rs.VectorAdd(p1,lVec)
    pUr_0 = rs.VectorAdd(pUr_0,dVec)
    pUr_1 = rs.VectorAdd(p1,lVec)
    pUr_1 = rs.VectorAdd(pUr_1,-dVec)
    pUr_2 = rs.VectorAdd(p1,-lVec)
    pUr_2 = rs.VectorAdd(pUr_2,-dVec)
    pUr_3 = rs.VectorAdd(p1,-lVec)
    pUr_3 = rs.VectorAdd(pUr_3,dVec)
    points_up_r = [pUr_0,pUr_1,pUr_2,pUr_3]
    #rs.AddPoints(points_up_r)
    lin_down_r=rs.AddCurve([pDr_0,pDr_1,pDr_2,pDr_3,pDr_0],1)
    lin_up_r=rs.AddCurve([pUr_0,pUr_1,pUr_2,pUr_3,pUr_0],1)
    div_down_r=rs.DivideCurve(lin_down_r,anzahl_sockel)
    div_up_r=rs.DivideCurve(lin_up_r,anzahl_sockel)
    for i in range(anzahl_sockel):
        rs.AddLine(div_down_r[i],div_up_r[i])
    ##old
    #    ###for right side
    #    pDl_0 = rs.VectorAdd(p3,[0,fac_pilar,0])
    #    pDl_1 = rs.VectorAdd(p3,[fac_pilar,fac_pilar,0])
    #    pDl_2 = rs.VectorAdd(p3,[fac_pilar,-fac_pilar,0])
    #    pDl_3 = rs.VectorAdd(p3,[0,-fac_pilar,0])
    #    points_down_l = [pDl_0,pDl_1,pDl_2,pDl_3]
    #    #rs.AddPoints(points_down_l)
    #    pUl_0 = rs.VectorAdd(p2,[0,fac_pilar,0])
    #    pUl_1 = rs.VectorAdd(p2,[fac_pilar,fac_pilar,0])
    #    pUl_2 = rs.VectorAdd(p2,[fac_pilar,-fac_pilar,0])
    #    pUl_3 = rs.VectorAdd(p2,[0,-fac_pilar,0])
    #    points_up_l = [pUl_0,pUl_1,pUl_2,pUl_3]
    #    #rs.AddPoints(points_up_l)
    #    lin_down_l=rs.AddCurve([pDl_0,pDl_1,pDl_2,pDl_3,pDl_0],1)
    #    lin_up_l=rs.AddCurve([pUl_0,pUl_1,pUl_2,pUl_3,pUl_0],1)
    #    div_down_l=rs.DivideCurve(lin_down_l,anzahl_sockel)
    #    div_up_l=rs.DivideCurve(lin_up_l,anzahl_sockel)
    #    for i in range(anzahl_sockel):
    #        rs.AddLine(div_down_l[i],div_up_l[i])

###def for door on sockel
def mysockel_door( frontPanel, anzahl = 3, fac=0.1, abstand=0.5, abstand_flugel_left=3,abstand_flugel_right=3 ):
    #door which is a simillar to my balken from hu_04 but with the vector add that you mentioned. Now I can randomly open every door
    p0,p1, p2, p3 = frontPanel
    ###creates vector for pushing forward
    vec_01 = rs.VectorSubtract(p0,p1)
    vec_03 = rs.VectorSubtract(p3,p0)
    normal_vec = rs.VectorCrossProduct(vec_01,vec_03)
    normal_vec = rs.VectorUnitize(-normal_vec)
    normal_vec = rs.VectorScale(normal_vec, abstand)
    ###create lin and points for door
    lin03=rs.AddLine(p0,p3)
    div_lin03=rs.DivideCurve(lin03,3)
    door_lower_p1 = div_lin03[1]
    door_lower_p2 = div_lin03[2]
    door_upper_p1 = div_lin03[1]
    door_upper_p1 = rs.VectorAdd(door_upper_p1,[0,0,5])
    door_upper_p2 = div_lin03[2]
    door_upper_p2 = rs.VectorAdd(door_upper_p2,[0,0,5])
    lin_inner=rs.AddCurve([door_lower_p1,door_upper_p1,door_upper_p2,door_lower_p2],1)
    ab_lo_p1= rs.VectorAdd(door_lower_p1, normal_vec)
    ab_lo_p2= rs.VectorAdd(door_lower_p2, normal_vec)
    ab_up_p1= rs.VectorAdd(door_upper_p1, normal_vec)
    ab_up_p2= rs.VectorAdd(door_upper_p2, normal_vec)
    lin_outer=rs.AddCurve([ab_lo_p1,ab_up_p1,ab_up_p2,ab_lo_p2],1)
    div_inner=rs.DivideCurve(lin_inner,anzahl)
    div_outer=rs.DivideCurve(lin_outer,anzahl)
    for i in range(anzahl):
        rs.AddLine(div_inner[i],div_outer[i])
        
    ###create vector for pushing left and right
    vec_x_left=rs.VectorSubtract(ab_lo_p2,ab_up_p2)
    vec_y_left=rs.VectorSubtract(door_lower_p2,ab_lo_p2)
    normal_door_left = rs.VectorCrossProduct(vec_x_left,vec_y_left)
    normal_door_left = rs.VectorUnitize(-normal_door_left)
    normal_door_left = rs.VectorScale(normal_door_left, abstand_flugel_left)
    vec_x_right=rs.VectorSubtract(ab_lo_p1,ab_up_p1)
    vec_y_right=rs.VectorSubtract(door_lower_p1,ab_lo_p1)
    normal_door_right = rs.VectorCrossProduct(vec_x_right,vec_y_right)
    normal_door_right = rs.VectorUnitize(normal_door_right)
    normal_door_right = rs.VectorScale(normal_door_right, abstand_flugel_right) ### with abstand I can choose how far open
    ###create both half of door
    middle_low = dm.pntInbetween(ab_lo_p1,ab_lo_p2,0.5)
    middle_high = dm.pntInbetween(ab_up_p1,ab_up_p2,0.5)
    flugel_right = [ab_lo_p2,middle_low,middle_high,ab_up_p2,ab_lo_p2]
    flugel_left = [ab_lo_p1,middle_low,middle_high,ab_up_p1,ab_lo_p1]
    coords_flugel_left = [rs.VectorAdd(cor, normal_door_left) for cor in[ab_lo_p2,middle_low,middle_high,ab_up_p2,ab_lo_p2]]
    flugel_le=rs.AddCurve(coords_flugel_left,1)
    coords_flugel_right = [rs.VectorAdd(cor, normal_door_right) for cor in[ab_lo_p1,middle_low,middle_high,ab_up_p1,ab_lo_p1]]
    flugel_ri=rs.AddCurve(coords_flugel_right,1)

###test def uebung
def myPanel_fenster_open( panelX, anzahl = 3, anzahl_door=3, fac=0.1, fac_window=0.1,fac_balken=0.5, abstand=5 ):
    # create wall panel with a window with open shutters
    ### create frame
    p0,p1, p2, p3 = panelX
    panel_curve=rs.AddCurve([p0,p1,p2,p3,p0],1)
    ### create points for later making the correct lines
    p01 = dm.pntInbetween(p0,p2, fac)
    p02 = dm.pntInbetween(p2,p0, fac)
    p03 = dm.pntInbetween(p1,p3, fac)
    p04 = dm.pntInbetween(p3,p1, fac)
    px01 = dm.pntInbetween(p01,p02, fac_window)
    px02 = dm.pntInbetween(p02,p01, fac_window)
    px03 = dm.pntInbetween(p04,p03, fac_window)
    px04 = dm.pntInbetween(p03,p04, fac_window)
    py01 = dm.pntInbetween(px01,px04, fac_balken)
    py02 = dm.pntInbetween(px02,px03, fac_balken)
    py03 = dm.pntInbetween(px04,px02, fac_balken)
    py04 = dm.pntInbetween(px01,px03, fac_balken)
    ### create points and lines for shutters right side
    p_a_l_r_1=dm.pntInbetween(p04,p01, fac_window)
    p_a_l_r_2=dm.pntInbetween(p01,p04, fac_window)
    p_balkr_1=dm.pntInbetween(px04,p_a_l_r_2, fac_window)
    p_balkr_2=dm.pntInbetween(px02,p_a_l_r_1, fac_window)
    linbalkr_1= rs.AddLine(px04,p_balkr_1)
    linbalkr_2= rs.AddLine(px02,p_balkr_2)
    linbalkr_3= rs.AddLine(p_balkr_1,p_balkr_2)
    ### create points and lines for shutters right side
    p_a_l_l_1=dm.pntInbetween(p02,p03, fac_window)
    p_a_l_l_2=dm.pntInbetween(p03,p02, fac_window)
    p_balkl_1=dm.pntInbetween(px01,p_a_l_l_2, fac_window)
    p_balkl_2=dm.pntInbetween(px03,p_a_l_l_1, fac_window)
    linbalkl_1= rs.AddLine(px01,p_balkl_1)
    linbalkl_2= rs.AddLine(px03,p_balkl_2)
    linbalkl_3= rs.AddLine(p_balkl_1,p_balkl_2)
    ### create lines to make connection between window and shutter
    linx_0103=rs.AddLine(px01,px03)
    linx_0203=rs.AddLine(px04,px02)
    liny_0102=rs.AddLine(py01,py02)
    liny_0304=rs.AddLine(py03,py04)
    coordslinx_0103 = rs.DivideCurve(linx_0103, anzahl_door, 0)
    coordslinx_0203 = rs.DivideCurve(linx_0203, anzahl_door, 0)
    coordslinbalkl_3 = rs.DivideCurve(linbalkl_3, anzahl_door, 0)
    coordslinbalkr_3 = rs.DivideCurve(linbalkr_3, anzahl_door, 0)
    ###create shutter lines
    for i in range(anzahl_door):
        pS = coordslinx_0103[i]
        pE = coordslinx_0203[i]
        pS1 = coordslinbalkl_3[i]
        pE2 = coordslinbalkr_3[i]
        rs.AddLine(pS,pS1)
        rs.AddLine(pE,pE2)
    #rs.AddPoint(p02)
    coords_frame = [p01,p03,p02,p04,p01]
    coords_window = [px01,px03,px02,px04,px01]
    frame=rs.AddCurve(coords_frame,1)
    window=rs.AddCurve(coords_window,1)
    div_frame=rs.DivideCurve(frame,anzahl*5)
    div_panel=rs.DivideCurve(panel_curve,anzahl*5)
    #div_panel=rs.DivideCurve(door,anzahl*5)
    for i in range(anzahl*5):
        rs.AddLine(div_frame[i],div_panel[i])

###test def uebung
def myPanel_dachfenster( panelX, anzahl = 3, fac=0.1, abstand=0.5 ):
    #took the one from ue_04
    p0,p1, p2, p3 = panelX
    lin_03 = rs.AddLine(p0,p3)
    lin_12 = rs.AddLine(p1,p2)
    #diag_02 = rs.AddLine(p0,p2)
    #diag_13 = rs.AddLine(p1,p3)
    vec_01 = rs.VectorSubtract(p0,p1)
    vec_03 = rs.VectorSubtract(p3,p0)
    normal_vec = rs.VectorCrossProduct(vec_01,vec_03)
    normal_vec = rs.VectorUnitize(normal_vec)
    normal_vec = rs.VectorScale(normal_vec, abstand)
    p01 = dm.pntInbetween(p0,p2, fac)
    p02 = dm.pntInbetween(p2,p0, fac)
    p03 = dm.pntInbetween(p1,p3, fac)
    p04 = dm.pntInbetween(p3,p1, fac)
    coords_abstand = [rs.VectorAdd(cor, normal_vec) for cor in[p01,p03,p02,p04,p01]]
    coords_dach = [p0,p1,p2,p3,p0]
    dach=rs.AddCurve(coords_dach,1)
    abstand=rs.AddCurve(coords_abstand,1)
    div_dach=rs.DivideCurve(dach,anzahl*5)
    div_abst=rs.DivideCurve(abstand,anzahl*5)
    for i in range(anzahl*5):
        rs.AddLine(div_dach[i],div_abst[i])



tst = 1
if tst:
    if 0: ### SETUP >> dont' exec @ homework !
        dm.newEmptyLayer("UNO::setUp", [120,120,240])
        rs.ObjectColor(rs.AddCurve( [dm.getUnoCoord(0,0,0), dm.getUnoCoord(0,0,39), dm.getUnoCoord(10,0,39), dm.getUnoCoord(10,0,0), dm.getUnoCoord(10,3,0), dm.getUnoCoord(0,3,0), dm.getUnoCoord(0,3,39), dm.getUnoCoord(10,3,39)], 1), [100,0,200])
        rs.ObjectPrintWidth( rs.AllObjects()[0], 1.0 )
        rs.ObjectColor(rs.AddLine( dm.getUnoCoord(0, 0, 0), dm.getUnoCoord(0, 3, 0) ), [222, 0, 0] )
        rs.CurveArrows(rs.AllObjects()[0], 2)
        rs.ObjectColor(rs.AddLine( dm.getUnoCoord(0, 0, 0), dm.getUnoCoord(2, 0, 0) ), [0, 222, 0] )
        rs.CurveArrows(rs.AllObjects()[0], 2)
        rs.ObjectColor(rs.AddLine( dm.getUnoCoord(0, 0, 0), dm.getUnoCoord(0, 0, 7) ), [0, 0, 222] )
        rs.CurveArrows(rs.AllObjects()[0], 2)
        rs.ZoomExtents()
        dm.textDots(frontPanels[0])
        #dm.textDots(upSidePanels[0])
    if 0:
        dm.newEmptyLayer("UNO::big", [100,110,200])
        for coords in BigPanelCoords[0]+BigPanelCoords[1]+BigPanelCoords[2]+BigPanelCoords[3]: rs.AddCurve( coords, 1 )
    if 0:
        dm.UN_slab(showAll=0)
    if 1:
        dm.newEmptyLayer("UNO::tst", [100,110,200])
        for i,panel in enumerate(frontPanels+upSidePanels):          ### +backPanels+upSidePanels
            dm.esc()
            if 0 or panel[0][2] >=11110 or (i>=20 and i<190): ###[x,y,z] >> 0,1,2
                pass
                myfenster( panel, fac=0.1, abstand=0.5, abstand_flugel_left=3,abstand_flugel_right=3,rollo_offen=random.randint(1,99),anzahl_lamellen=20, anstellwinkel=random.uniform(0,2) )
                if i and i%9==0:
                    rs.Redraw()
            elif i>=196:
                mySidePanel(panel)
            else:
                pass
                #mySockel( panel, anzahl_sockel = 20, fac_pilar=0.8, abstand=0.5, anzahl_door = 10, fac_door=0.8 )
                #mysockel_door( panel, anzahl = 100, fac=0.1, abstand=0.5, abstand_flugel_left=random.uniform(0,1.5),abstand_flugel_right=random.uniform(0,1.5) )
            if i<20 :
                p0 = frontPanels[i+0][0]
                p1 = frontPanels[i+10][1]
                p2 = frontPanels[i+10][2]
                p3 = frontPanels[i+0][3]
                rs.AddCurve( [p0, p1, p2, p3], 1)
                mySockel( panel, anzahl_sockel = 20, fac_pilar=0.8, abstand=0.5, anzahl_door = 10, fac_door=0.8 )
            if i==190 or i==191 or i==192 or i==193 or i==194 or i==195:
                print "yeah"
                p0 = upSidePanels[i-190+0][0]
                p1 = upSidePanels[i-190+3][1]
                p2 = upSidePanels[i-190+3][2]
                p3 = upSidePanels[i-190+0][3]
                rs.AddCurve( [p0, p1, p2, p3], 1)
                mySockel( panel, anzahl_sockel = 20, fac_pilar=0.8, abstand=0.5, anzahl_door = 10, fac_door=0.8 )
            if i<10 or (i==190 or i==191 or i==192):
                mysockel_door( panel, anzahl = 100, fac=0.1, abstand=0.5, abstand_flugel_left=random.uniform(0,1.5),abstand_flugel_right=random.uniform(0,1.5) )

    if 1:
        i_balkon_1=random.randint(20,29)
        i_balkon_2=random.randint(30,39)
        i_balkon_3=random.randint(40,49)
        i_balkon_4=random.randint(50,59)
        i_balkon_5=random.randint(60,69)
        i_balkon_6=random.randint(70,79)
        i_balkon_7=random.randint(80,89)
        i_balkon_8=random.randint(90,99)
        i_balkon_9=random.randint(100,109)
        i_balkon_10=random.randint(110,119)
        i_balkon_11=random.randint(120,129)
        i_balkon_12=random.randint(130,139)
        i_balkon_13=random.randint(140,149)
        i_balkon_14=random.randint(150,159)
        i_balkon_15=random.randint(160,169)
        i_balkon_16=random.randint(170,179)
        i_balkon_17=random.randint(180,189)

        #print i_balkon
        random_balkon=0
        for i,panel in enumerate(backPanels+sidePanels):          ### +backPanels+upSidePanels
                    dm.esc()
                    #random_balkon=random.randint(0,1)
                    if 0 or panel[0][2] >=11110 or (i>=20 and i<190): ###[x,y,z] >> 0,1,2
                        pass
                        ###
                        
                        if i==i_balkon_1 or i==i_balkon_2 or i==i_balkon_3 or i==i_balkon_4 or i==i_balkon_5 or i==i_balkon_6 or i==i_balkon_7 or i==i_balkon_8 or i==i_balkon_9 or i==i_balkon_10 or i==i_balkon_11 or i==i_balkon_12 or i==i_balkon_13 or i==i_balkon_14 or i==i_balkon_15 or i==i_balkon_16 or i==i_balkon_17:
                            random_balkon=1
                        else:
                            random_balkon=0
#                        counter_balkone==0
#                        if i==20 or i==30 or i==40 or i==50 or i==60 or i==70 or i==80 or i==90 or i==100 or i==110 or i==120 or i==130 or i==140  or i==150 or i==160 or i==170 or i==180:
#                            counter_balkone==0
                        if random_balkon == 1:
                            coords_b=myBalkon(panel, balkon_tiefe=7, streben_balkon=20)
                            coordsBalkon.append(coords_b)
                            #print coordsBalkon
                            random_balkon==0
                            #rs.AddCurve([coordsBalkon[3],coordsBalkon[5]],3)
                            
                        else:
                            myCurtain( panel, fac=0.1, abstand=0.5, abstand_flugel_left=3,abstand_flugel_right=3,curtain_offen=random.randint(1,99),anzahl_curtain=20 )
                        if i and i%9==0:
                            rs.Redraw()
                    elif i>=196:
                        mySidePanel(panel)
                    else:
                        pass
                        #mySockel( panel, anzahl_sockel = 20, fac_pilar=0.8, abstand=0.5, anzahl_door = 10, fac_door=0.8 )
                        #mysockel_door( panel, anzahl = 100, fac=0.1, abstand=0.5, abstand_flugel_left=random.uniform(0,1.5),abstand_flugel_right=random.uniform(0,1.5) )
                    if i<20 :
                        p0 = frontPanels[i+0][0]
                        p1 = frontPanels[i+10][1]
                        p2 = frontPanels[i+10][2]
                        p3 = frontPanels[i+0][3]
                        rs.AddCurve( [p0, p1, p2, p3], 1)
                        mySockel( panel, anzahl_sockel = 20, fac_pilar=0.8, abstand=0.5, anzahl_door = 10, fac_door=0.8 )
                    if i==190 or i==191 or i==192 or i==193 or i==194 or i==195:
                        p0 = upSidePanels[i-190+0][0]
                        p1 = upSidePanels[i-190+3][1]
                        p2 = upSidePanels[i-190+3][2]
                        p3 = upSidePanels[i-190+0][3]
                        rs.AddCurve( [p0, p1, p2, p3], 1)
                        mySockel( panel, anzahl_sockel = 20, fac_pilar=0.8, abstand=0.5, anzahl_door = 10, fac_door=0.8 )
                    if i<10 or (i==190 or i==191 or i==192):
                        mysockel_door( panel, anzahl = 100, fac=0.1, abstand=0.5, abstand_flugel_left=random.uniform(0,1.5),abstand_flugel_right=random.uniform(0,1.5) )
        #rs.AddCurve([coordsBalkon[0][0],coordsBalkon[10][1]],3)
        test_crv_innen = rs.AddCurve([coordsBalkon[0][3], coordsBalkon[2][1]], 3)
        rs.ObjectColor(test_crv_innen, (255, 120, 12))
        rs.ObjectPrintWidth(test_crv_innen, 1.0)
        test_crv_aussen = rs.AddCurve([coordsBalkon[0][2], coordsBalkon[2][0]], 3)
        rs.ObjectColor(test_crv_aussen, (255, 255, 0))
        rs.ObjectPrintWidth(test_crv_aussen, 1.0)
        #rs.AddPoint(coordsBalkon[1][3])
        test_crv = rs.AddCurve([coordsBalkon[0][2],gC(-1, 4, 4),gC(-1, -1, 4),gC(11, -1, 6),gC(11, 4, 6),coordsBalkon[2][0]] , 1)
        rs.ObjectColor(test_crv, (255, 0, 0))
        rs.ObjectPrintWidth(test_crv, 1.0)




#### CAMERA
#### set / get camera
if 0:
    print ("ViewNames :"),
    print (rs.ViewNames())
    
    cam = gC(5, -20, 19.5)
    tar = gC(5, 0, 19.5)
    rs.AddLine( cam, tar )
    
    dm.setCameraTarget( cam, tar, 500.0, 0, 0, 0)
    rs.ViewProjection(view='Perspective', mode=1)   ### 1 = parallel, 2 = perspective, 3 = two point perspective
    dm.getCameraTarget(view=rs.CurrentView(), verbose=1)
    #dm.setCameraTarget( [334.42526127, 493.18649387, 171.88081703], [756.84885751, 592.83573956, 82.0], lens=50.0, rota=0, upVec=[0,0,1] ) # ... danke, andi !



if 0:
    p0 = gC(2,0,2)
    p1 = gC(2,-10,2)
    p2 = gC(8,0,20)
    p3 = gC(8,10,20)
    p4 = gC(5,10,38)
    p5 = gC(5,3,38)

    crv_1=rs.AddCurve([p0,p1,p2,p3,p4,p5],1)
    crv_2=rs.AddCurve([p0,p1,p2,p3,p4,p5],2)
    #crv_3=rs.AddCurve([p0,p1,p2,p3,p4,p5],3)


    dom = rs.CurveDomain(crv_1)
    dom = rs.CurveDomain(crv_2)[1]
    print ("DOM ="+str(dom))

    radius=5.0
    number = 12
    anzahl = 2**8  ###divis
    deltaAngle = 360/anzahl
    dom_fac = dom / number
    all_coord=[]
    allParams=[]

    for i in range(number+1):
        param = dom_fac*i
        allParams.append(param)
        #pnt = rs.EvaluateCurve(crv_2, dom*(1/i))
        pnt = rs.EvaluateCurve(crv_2, param)
        rs.AddPoint(pnt)
        planeX = rs.CurvePerpFrame(crv_2,param)
        cir = rs.AddCircle(planeX,radius)
        coords = rs.DivideCurve(cir,anzahl,create_points=False)
        hVec = dm.vecCurvePerpXY(crv_2,param)
        hVec=rs.VectorScale(hVec,radius*1)
        hPnt = rs.VectorAdd(pnt,hVec)
        tan = rs.CurveTangent(crv_2,param)
        
        coords = []
        for a in range(anzahl):
            angX = deltaAngle*a
            hVecX = rs.VectorRotate(hVec,angX,tan)
            pntX = rs.VectorAdd(pnt,hVecX)
            #rs.AddLine(pnt,pntX)
            coords.append(pntX)
        all_coord.append(coords)
            

        
        
    #    rs.AddLine(pnt,hPnt)
    #    all_coord.append(coords)
        
    i=0
    if 1:
        for i in range(0,int(anzahl/2)):
            coords=[]
            for coordList in all_coord:
                cor = coordList[i]
                coords.append(cor)
            rs.AddCurve(coords,2)
            #rs.AddCurve(coords,1)


    for i in range(number):
        param=allParams[i]
        pnt = rs.EvaluateCurve(crv_2,param)
        paramUnten = rs.CurveClosestPoint(unoBaseCrv,pnt)
        pntUnten = rs.EvaluateCurve(unoBaseCrv,paramUnten)
        rs.AddLine(pnt,pntUnten)



#dom = rs.CurveDomain(crv_3)
#print dom


########## EOS / EndOfScript
rs.EnableRedraw(True)     ### 4_the_MACs
#dm.eDup()                 ### delete duplicate objects 
dm.printDisplay(state=True, scale=1000)
dm.zA( 0.9 )
dm.newEmptyLayer("Default")

