############################
### diag @ IAM @ DM2_w25 ###
### hu_04 dmLodge_startUP_00
############################

##############################
import rhinoscriptsyntax as rs      ###
import random, time, sys            ###
sys.path.append("P:/")              ### add LW P:/ to rhino's default search path AND
sys.path.append("P:/WWW/lukschme/dm2")  ### add YOUR LW P:/WWW/user/dm2/ to rhino's default search path ...
import DM_lib as dm                 ### ... thus DM_lib.py can be found !
##############################      reload (dm)


rs.UnitSystem(4)                                        # km = 5, meters = 4, cm = 3 etc
rs.ShowGrid(None, 0)                                    # grid > 0 = off
rs.ShowGridAxes(None, 1)                                # y/y/z axen display > 0/1 = off/on
rs.ViewDisplayMode(view=None, mode="wireframe")			# shadeMode fuer current view
rs.AppearanceColor(item=0, color=[230, 230, 230])       ### item=0 => backgroundColor [R,G,B] | 230/230/230 == lightgray
rs.Command("cplane w t enter", 0)						# cPlane World Top
dm.printDisplay(0)                                      # nomen est omen

rs.EnableRedraw(0)                                      ### 4_the_MACs: try 0/1 !
rs.UnselectAllObjects()
dm.newEmptyLayer( "Default")                            
dm.newEmptyLayer( "LODGE", [32, 32, 32] )
dm.newEmptyLayer( "LODGE::demo")    ### newEmtyLayer ist 'current'
dm.newEmptyLayer( "LODGE::setUp",  [111,  11, 111] )    ### newEmtyLayer ist 'current'
dm.newEmptyLayer( "LODGE::crv", [200,  20, 20] )
dm.newEmptyLayer( "LODGE::pnt", [ 100,  100, 100] )
rs.Redraw()
wait = 1

def info():
    ##############################################
    """ LODGE
    Generate a small archetypal house, distorted along perspective algorithms
    A setup for the development of individual panels
    Inspired by
      Albrecht Duerer's "Underweysung" (1525)
      https://de.wikipedia.org/wiki/Perspektive#Geschichte
      https://en.wikipedia.org/wiki/Albrecht_Duerer
    And
      MVRDVs "Porterlodges for the National Park De Hoge Veluwe" (1996)
      https://mvrdv.com/projects/167/hoenderloo-lodge?photo=15877
    Parameters:
      p_width (float, optional): Approx. panel width in units
      l_dist (float, optional): Approx. length of the lodge in units
      d_dist (float, optional): Approx. depth of the lodge in units
      h_dist (float, optional): Approx. height of the lodge in units
      x_pos (float, optional): Move origin of the lodge in x
      y_pos (float, optional): Move origin of the lodge in y
      d_grid (boolean, optional): Fixed depth grid on the the small sides
      d_distord (boolean, optional): Distord basic section of the house
      demo (boolean, optional): Run demo to get an object
      verbose (int, optional): talk & sleep / Print and depict generation of the lodge
    Returns:
      return[0] = list[][][] of all panels, containing groups of 4 points
      return[1] = list[][][] of just the sleeve's panels
      return[2] = list[][][] of just the right section's panels
      return[3] = list[][][] of just the left section's panels
      return[4] = list[][][] of the sections, containing groups of 5 points
      return[5] = list[][] of all the cvs on the sleeve
      return[6] = list[][] of all the cvs on the right section
      return[7] = list[][] of all the cvs on the left section
    Example:
      allData = dm.getLodge( verbose=1000, demo=1 )
      panels = allData[0]
      panels_sleeve = allData[1] // sleeve ~= hull
      panels_right = allData[2]
      panels_left = allData[3]
        sections = allData[4]
        cvs_sleeve= allData[5]
        cvs_right= allData[6]
        cvs_left= allData[7]
    ### allData = dm.getLodge( p_width=1.2, l_dist=10, d_dist=8, h_dist=6, pos_x=0, pos_y=0, d_grid=0, d_distord=1, demo=0, verbose=0 )
    """


### exec whenever ##################################
dm.allLodgeData = dm.getLodge( demo = 1, verbose=0 )    ### activate this to get a new set of data
allLodgeData    = dm.allLodgeData                       ### this set of data is generated @ startUp (when DM_lib is loaded)
####################################################    ### allLodgeData = [ panels, panels_sleeve, panels_right, panels_left, sections, cvs_sleeve, cvs_right, cvs_left ]

'''
' check setup - just visualization of setUp >> dont execute @ final version of homework <<                                      '
'''
rs.CurrentLayer("LODGE")



def myPanel_nacktewand( panelX, anzahl = 3, fac=0.1, abstand=5 ):
    #creates just a plane wall with a small frame
    p0,p1, p2, p3 = panelX
    panel_curve=rs.AddCurve([p0,p1,p2,p3,p0],1) ###outer curve around panel
    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_frame = [p01,p03,p02,p04,p01] ###inner curve for small frame
    frame=rs.AddCurve(coords_frame,1)
    div_frame=rs.DivideCurve(frame,anzahl*5)
    div_panel=rs.DivideCurve(panel_curve,anzahl*5)
    for i in range(anzahl*5): ### filling the frame to give heftiness
        rs.AddLine(div_frame[i],div_panel[i]) 

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])

def myPanel_fenster_closed( panelX, anzahl = 3, anzahl_door=3, fac=0.1, fac_window=0.1,fac_balken=0.5, abstand=5 ):
    #create panel for wall with closed shutters
    ###create frame
    p0,p1, p2, p3 = panelX
    panel_curve=rs.AddCurve([p0,p1,p2,p3,p0],1)
    ###define points for making line
    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(p04,p03, fac_window)
    py04 = dm.pntInbetween(p03,p04, fac_window)
    ###create lines between points
    linx_0103=rs.AddLine(px01,px03)
    linx_0203=rs.AddLine(px04,px02)
    liny_0102=rs.AddLine(py01,py02)
    coordslinx_0103 = rs.DivideCurve(linx_0103, anzahl_door, 0)
    coordslinx_0203 = rs.DivideCurve(linx_0203, anzahl_door, 0)
    for i in range(anzahl_door):
        pS = coordslinx_0103[i]
        pE = coordslinx_0203[i]
        rs.AddLine(pS,pE)
    #rs.AddPoint(py02)
    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])

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])


def myPanel_schornstein( panelX, anzahl = 3, fac=0.1, abstand=5 ):
    ###changed panel _dachfenster, so that it creates higher offsets and round outputs. Also th connection goes straight up
    p0,p1, p2, p3 = panelX
    panel_curve=rs.AddCurve([p0,p1,p2,p3,p0],1)
    normal_vec = rs.VectorScale([0, 0, 1],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 = [p01,p03,p02,p04,p01]
    dach=rs.AddCurve(coords_dach,7)
    abstand=rs.AddCurve(coords_abstand,7)
    div_dach=rs.DivideCurve(dach,anzahl*5)
    div_abst=rs.DivideCurve(abstand,anzahl*5)
    div_panel=rs.DivideCurve(panel_curve,anzahl*5)
    for i in range(anzahl*5):
        rs.AddLine(div_dach[i],div_abst[i])
        rs.AddLine(div_dach[i],div_panel[i])


def myPanel_nacktesdach( panelX, anzahl = 3, fac=0.1, abstand=0.5 ):
    #creates just connections between outlines and middle point
    p0,p1, p2, p3 = panelX
    panel_curve=rs.AddCurve([p0,p1,p2,p3,p0],1)
    p01 = dm.pntInbetween(p0,p2)
    div_panel=rs.DivideCurve(panel_curve,anzahl*5)
    for i in range(anzahl*5):
        rs.AddLine(p01,div_panel[i])


############################################
for i,panelCoords in enumerate( allLodgeData[1][0:]):
    pass
    if i%4 == 0:
        random_output_wand = random.choice([1,2,3])                                             ###make random variable for wall to spread randomly over wall panels, modulo = 0 and 3
        if random_output_wand == 1:
            myPanel_fenster_open( panelCoords,anzahl=77,anzahl_door=25, fac=0.02,fac_window=0.65,fac_balken=0.5,abstand=random.uniform(2,5) )
        elif random_output_wand == 2:
            myPanel_fenster_closed( panelCoords,anzahl=77,anzahl_door=25, fac=0.02,fac_window=0.65,fac_balken=0.5,abstand=random.uniform(2,5) )
        elif random_output_wand == 3:
            myPanel_nacktewand( panelCoords,anzahl=77, fac=0.02,abstand=random.uniform(2,5) )
    if i%4 == 1:
        random_output_roof = random.choice([1,2,3])
        if random_output_roof == 1:
            myPanel_schornstein( panelCoords,anzahl=77, fac=random.uniform(0.55,0.70),abstand=random.uniform(2,5) )
        elif random_output_roof == 2:
            myPanel_nacktesdach( panelCoords,anzahl=77, fac=random.uniform(0.3,0.45),abstand=random.uniform(0.2,0.9999999))
        elif random_output_roof == 3:
            myPanel_dachfenster( panelCoords,anzahl=77, fac=random.uniform(0.1,0.2),abstand=random.uniform(0.2,0.9999999))

    if i%4 == 2:
        random_output_roof = random.choice([1,2,3])
        if random_output_roof == 1:
            myPanel_schornstein( panelCoords,anzahl=77, fac=random.uniform(0.55,0.70),abstand=random.uniform(2,5) )
        elif random_output_roof == 2:
            myPanel_nacktesdach( panelCoords,anzahl=77, fac=random.uniform(0.3,0.45),abstand=random.uniform(0.2,0.9999999))
        elif random_output_roof == 3:
            myPanel_dachfenster( panelCoords,anzahl=77, fac=random.uniform(0.1,0.2),abstand=random.uniform(0.2,0.9999999))
    if i%4 == 3:
        random_output_wand = random.choice([1,2,3])
        if random_output_wand == 1:
            myPanel_fenster_open( panelCoords,anzahl=77,anzahl_door=25, fac=0.02,fac_window=0.65,fac_balken=0.5,abstand=random.uniform(2,5) )
        elif random_output_wand == 2:
            myPanel_fenster_closed( panelCoords,anzahl=77,anzahl_door=25, fac=0.02,fac_window=0.65,fac_balken=0.5,abstand=random.uniform(2,5) )
        elif random_output_wand == 3:
            myPanel_nacktewand( panelCoords,anzahl=77, fac=0.02,abstand=random.uniform(2,5) )

'''              
' end check setup                                                                                                                   ' 
'''


#######################################
################ HERE YOU GO AS YOU GO:
rs.CurrentLayer("LODGE")                          ### or LODGE:: >> goto sublayer !



########################## HERE YOU END
#######################################


########## EOS / EndOfScript
rs.EnableRedraw(1)          ### 4_the_MACs
#dm.eDup( 1 )               ### delete duplicate objects 
dm.printDisplay(1)
dm.zA( 0.9 )
rs.CurrentLayer("Default")
if wait:
    rs.Sleep( wait )
    rs.LayerVisible("LODGE::setUp", 0)

