###########################################
###  WS24 DM2 HUE8 Lea Koraimann        ###
###########################################


##############################
import rhinoscriptsyntax as rs
import random, time, sys   ###
sys.path.append("P:/")     ###
sys.path.append("P:/WWW/lekor27/")     ###
import DM_lib as dm        ### reload( dm )
##############################    
dm.PointRadius(displayModeX=0, rad=3, styl=3)
#dm.printDisplay(1, 100)


#Korpus Curve ##################################################################


dm.newEmptyLayer("Korpus_Curve", [255,0,0])
#rs.CurrentLayer("Korpus_Curve")

p00 = (-8, 13, 0)
p01 = (-12, 5, 0)
p02 = (0, 0, 0)
p03 = (12, 5, 0)
p04 = (10, 15, 0)
p05 = (0, 18, 0)

KorpusCurveCoords_0 = [ p00, p01, p02, p03, p04, p05 ]
#rs.AddPoints (KorpusCurveCoords_0)
#rs.AddCurve (KorpusCurveCoords_0, 2 )  

p06 = (7, 16, 0)
p07 = (5, 19, 0)
p08 = (10, 25, 0)
p09 = (7.5, 30, 0)
p10 = (0, 29, 0)

KorpusCurveCoords_1 = [ p06, p07, p08, p09, p10 ]
#rs.AddPoints (KorpusCurveCoords_1)
#rs.AddCurve (KorpusCurveCoords_1, 2 )  




KorpusCurve_0 = rs.AddCurve (KorpusCurveCoords_0,2 ) 
KorpusCurve_1 = rs.AddCurve (KorpusCurveCoords_1,2 )
KorpusCurve_0_coords = rs.DivideCurve (KorpusCurve_0, 20, create_points= False )
KorpusCurve_1_coords = rs.DivideCurve (KorpusCurve_1, 10,  create_points= False )

pXpara = rs.CurveClosestPoint(KorpusCurve_0, p06)
pXcor  = rs.EvaluateCurve(KorpusCurve_0, pXpara)
#rs.AddLine( p06, pXcor )
p06 = pXcor###################################
### DM2_w24 # AGruber@tugraz.at ###
### hu_06 UN_headquaters  NYC   ### ######################################################
### paneling  / new dimensions  ### 87.5 x 22.0 meters (was lenY = 116.56 / lenX =  28.18)
################################### ######################################################


##############################
import rhinoscriptsyntax as rs
import random, time, sys   ###
sys.path.append("P:/")     ###
sys.path.append("D:/PY/")
import DM_lib as dm        ### 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(rs.CurrentView(), "wireframe")
rs.ViewDisplayMode(rs.CurrentView(), "rendered")
rs.Command("cplane w t enter", 0)                       # cPlane World Top
dm.PointRadius(displayModeX=0, rad=3, styl=3)
dm.printDisplay(1)                                 # nomen est omen
rs.EnableRedraw(0)



###_________________________________________#
### basic settings for grid to fit UN_slab  #
###                                         # 
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 from DM_lib as dm:
UnoGridCoords  = dm.UnoGridCoords           # get gridCoords L*D*H = 1760
UnoPanelCoords = dm.UnoPanelCoords          # get panelCoords [frontPanels, backPanels, sidePanels, upSidePanels] / default arguments s.u.
################____________________________#
################
lengthVec = lVec = rs.VectorUnitize(rs.VectorSubtract( dm.getUnoCoord(0, 0, 0), dm.getUnoCoord(1, 0, 0) )) ## rs.AddPoint( dm.getUnoCoord(1, 0, 0) )
depthVec  = dVec = rs.VectorUnitize(rs.VectorSubtract( dm.getUnoCoord(0, 1, 0), dm.getUnoCoord(0, 0, 0) )) ## rs.AddPoint( dm.getUnoCoord(0, 1, 0) )
################
###########################################################################################
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=6, stepD=2) ### = all ~windows_panels
UnoPanelCoords = dm.getUNpanelCoords(anzL=9*1, anzH=39, anzD=3, stepL=1, stepH=2, stepD=1) ### = standard for hu_06
###########################################################################################
##########################################################
frontPanels   = UnoPanelCoords[0] ### list of coordLists !
backPanels    = UnoPanelCoords[1]
sidePanels    = UnoPanelCoords[2]
upSidePanels  = UnoPanelCoords[3]
allPanels     = UnoPanelCoords[4]
#################################

dm.eA()
dm.newEmptyLayer("UNO::setUp", [120,120,240])

if 1: ### SETUP >> dont' exec @ homework !
    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,110,111])
    rs.ObjectColor(rs.AddLine( dm.getUnoCoord(0, 0, 0), dm.getUnoCoord(0, 1, 0) ), [222, 0, 0] )
    rs.ObjectColor(rs.AddLine( dm.getUnoCoord(0, 0, 0), dm.getUnoCoord(1, 0, 0) ), [0, 222, 0] )
    rs.ObjectColor(rs.AddLine( dm.getUnoCoord(0, 0, 0), dm.getUnoCoord(0, 0, 2) ), [0, 0, 222] )
    rs.ObjectPrintWidth( rs.AllObjects()[0:4], 1.0 )
    #rs.ZoomExtents()
    #for coords in BigPanelCoords[4]: rs.AddCurve( coords, 1 )

allPanels  = [[dm.getUnoCoord( 0, 0, 20), dm.getUnoCoord( 0, 0, 39), dm.getUnoCoord(10, 0, 39), dm.getUnoCoord(10, 0, 20)]]
allPanels.append([dm.getUnoCoord( 0, 0, 0), dm.getUnoCoord( 0, 0, 20), dm.getUnoCoord(10, 0, 20), dm.getUnoCoord(10, 0, 0)])
random.shuffle(allPanels)
def dividePanel( panel=allPanels[0], maxPanels=10, minHig=4.0 ):
        dm.esc()
        if maxPanels>500: maxPanels=500
        random.shuffle(allPanels)
        if rs.Distance( panel[0], panel[1] ) > minHig*2:
            allPanels.remove( panel )
            pMid = dm.pntInbetween(panel[0],panel[2])
            allPanels.append([panel[0], dm.pntInbetween(panel[0],panel[1]), pMid, dm.pntInbetween(panel[3],panel[0])])
            allPanels.append([dm.pntInbetween(panel[0],panel[1]), panel[1],dm.pntInbetween(panel[1],panel[2]), pMid])
            allPanels.append([pMid, dm.pntInbetween(panel[1],panel[2]), panel[2], dm.pntInbetween(panel[2],panel[3])])
            allPanels.append([dm.pntInbetween(panel[0],panel[3]), pMid, dm.pntInbetween(panel[2],panel[3]), panel[3]])
        
        if len(allPanels) <= maxPanels :
            dividePanel( panel=random.choice( allPanels[0: int(len(allPanels)*0.666)]), maxPanels=maxPanels )  

dividePanel(panel=allPanels[0], maxPanels=150, minHig=6.0 )
print "::: len(allPanels)",len(allPanels)

#_____________________________here you go:
dm.newEmptyLayer("myPROJ", [100,110,120])



def blendenPanel(panel, anz=1, blende=6, blendeSize=0.9):
    p0,p1,p2,p3 = panel
    coords = [p0,p1,p2,p3, p0]
    #rs.AddCurve( coords, 1 )
    cenPt = dm.pntInbetween( p0, p2 )
    #rs.AddPoint( cenPt )
    #planeX = rs.PlaneFromPoints( cenPt, dm.pntInbetween(p0,p1), p1 )
    #rad = rs.Distance(p0,p3)*0.5*blendeSize
    #circ = rs.AddCircle(planeX, rad)
    #hexaPnts = rs.DivideCurve(circ, 6, 0)
    #rs.DeleteObject(circ)
    #hexaPnts.append(hexaPnts[0])
    #hexagon = rs.AddCurve( hexaPnts, 1 )
    #blendenPnts = rs.DivideCurve(hexagon, anz*6, 0)
    #dm.textDots(blendenPnts)
    #blendenPnts = blendenPnts+blendenPnts

    #for blatt in range(6):
        #for i in range(blende):
            #pass
            #rs.AddLine( blendenPnts[blatt*anz], blendenPnts[blatt*anz+1+anz+i])
    #rs.Redraw()

def blumenPanel( panel, radi=5.0, radiFac=0.7, anz=20, variante = 0, prozent=100):
    p0,p1,p2,p3 = panel
    coords = [p0,p1,p2,p3, p0]
    #rs.AddCurve( coords, 1 )
    cenPt = dm.pntInbetween( p0, p2, random.uniform(0.1, 0.9) )
    #rs.AddPoint( cenPt )
    planeX = rs.PlaneFromPoints( cenPt, dm.pntInbetween(p0,p1), p1 )
    circAussen = rs.AddCircle(planeX, radi)
    coordsAussen = rs.DivideCurve(circAussen, anz, 0)
    circInnen = rs.AddCircle(planeX, radi*radiFac)
    rs.RotateObject(circInnen, cenPt, -360/anz*0.5, dVec)
    coordsInnen = rs.DivideCurve(circInnen, anz*1, 0)
    #dm.textDots( coordsAussen )
    #dm.textDots( coordsInnen )
    rs.DeleteObject( circAussen )
    rs.DeleteObject( circInnen )
    

    if prozent > random.uniform(0,100):
        circInnen = rs.AddCircle(planeX, radi*radiFac)
        for i in range(anz):
            p0 = coordsAussen[i]
            p0innen = coordsInnen[i]
            if i<anz-1:
                p2 = coordsAussen[i+1]
            else:
                p2 = coordsAussen[0]
            
            if variante == 0:
                coords = [p0, p0innen, p2]
            
            if variante == 1:
                coords = [p0innen, p0, p2, p0innen, p0innen]
            
            #rs.AddCurve( coords, 1)
            blumi = rs.AddCurve( coords, 2)
            rs.ObjectColor( blumi, [200,random.randint(80,120),150])
    ### gitter vertikal
    p0,p1,p2,p3 = panel
    if 180 > random.uniform(0,100):
        pUnten = dm.pntInbetween(p0, p3)
        pOben = dm.pntInbetween(p1, p2)
        stab = rs.AddCurve( [pUnten, cenPt, pOben], 1 )
        rs.ObjectColor ( stab, stabColor )
        rs.ObjectPrintWidth( stab, stabThickness )
        rs.ObjectName( stab, "gitter" )
    
    ### gitter horizontal
    pRechts = dm.pntInbetween(p0, p1)
    pLinx = dm.pntInbetween(p3, p2)
    if 70 > random.uniform(0,100):
        stab = rs.AddCurve( [pRechts, cenPt, pLinx], 1 )
        rs.ObjectColor ( stab, stabColor )
        rs.ObjectPrintWidth( stab, stabThickness )
        rs.ObjectName( stab, "gitter" )
    else:
        stab = rs.AddLine( cenPt, random.choice([pRechts, pLinx]),  )
        rs.ObjectColor ( stab, stabColor )
        rs.ObjectPrintWidth( stab, stabThickness )
        rs.ObjectName( stab, "gitter" )


def blumenPanel2 ( panel, radi=5.0, radiFac=0.5, anz=15, variante = 0, prozent=100):
    p0,p1,p2,p3 = panel
    coords = [p0,p1,p2,p3, p0]
    #rs.AddCurve( coords, 1 )
    cenPt = dm.pntInbetween( p0, p2, random.uniform(0.1, 0.9) )
    #rs.AddPoint( cenPt )
    if variante == 0:
        anz = random.randint(4,7)
    planeX = rs.PlaneFromPoints( cenPt, dm.pntInbetween(p0,p1), p1 )
    circAussen = rs.AddCircle(planeX, radi)
    coordsAussen = rs.DivideCurve(circAussen, anz, 0)
    circInnen = rs.AddCircle(planeX, radi*radiFac)
    rs.RotateObject(circInnen, cenPt, -360/anz*0.5, dVec)
    coordsInnen = rs.DivideCurve(circInnen, anz*1, 0)
    #dm.textDots( coordsAussen[0:5] )
    #dm.textDots( coordsInnen[0:5] )
    rs.DeleteObject( circAussen )
    rs.DeleteObject( circInnen ) 
    
    cA = coordsAussen+coordsAussen
    cI = coordsInnen+coordsInnen
    allCoords = []
    if prozent > random.uniform(0,100):
        #circInnen = rs.AddCircle(planeX, radi*radiFac)
        for i in range(anz):
            p0 = coordsAussen[i]
            p0innen = coordsInnen[i]
            if i<anz-1:
                p2 = coordsAussen[i+1]
                p1innen = coordsInnen [i+1]
            else:
                p2 = coordsAussen[0]
            
            if variante == 0:
                coords = [p0, p0innen, p2]
                allCoords.extend( [ cA[i], cI[i], dm.pntInbetween(cenPt, cI[i], 0.9)  ] )
                
                rs.AddCurve(  [ cI[i], dm.pntInbetween(cenPt, cI[i], 1.9)  ], 1 )
            if variante == 1:
                coords = [p0innen, p0, p2, p2, p1innen, p1innen]
                cI[i+1] = rs.VectorAdd( cI[i+1], dm.randVec(-0.5, 0.5) )
                cA[i+1] = rs.VectorAdd( cA[i+1], dm.randVec(-1.5, 1.5) )
                coords = [cI[i], cA[i], cA[i+1], cI[i+1], cenPt, cI[i]]
            
            #rs.AddCurve( coords, 1)
            if variante == 1:
                #rs.AddCurve( coords, 1)
                rs.AddCurve( coords, 3)
                rs.AddCurve( coords, 2)
                rs.ObjectColor( rs.AllObjects()[0:2], [100,130,0])
    
    if variante == 0:
        allCoords = [ rs.VectorAdd(cor, dm.randVec(-0.3, 0.3)) for cor in allCoords ] ### randomisieren aller coords
        allCoords.append(allCoords[0]) ### close curve
        for deg in range(2, 6):
            rs.ObjectColor( rs.AddCurve( allCoords, deg ), [random.randint(100,200),random.randint(10,200),25*deg])

    ### gitter vertikal
    p0,p1,p2,p3 = panel
    if 50 > random.uniform(0,100):
        pUnten = dm.pntInbetween(p0, p3)
        pOben = dm.pntInbetween(p1, p2)
        pts = [pUnten, pOben]
        #stab = rs.AddCurve( [pUnten, cenPt, pOben], 1 )
        stab = rs.AddCurve( [cenPt, random.choice(pts)], 1 )
        rs.ObjectColor ( stab, stabColor )
        rs.ObjectPrintWidth( stab, stabThickness )
        rs.ObjectName( stab, "gitter" )

    ### gitter horizontal
    #if 50 > random.uniform(0,100):
    else:
        pRechts = dm.pntInbetween(p0, p1)
        pLinx = dm.pntInbetween(p3, p2)
        pts = [pRechts, pLinx]
        #stab = rs.AddCurve( [pRechts, cenPt, pLinx], 1 )
        stab = rs.AddCurve( [cenPt, random.choice(pts)], 1 )
        rs.ObjectColor ( stab, stabColor )
        rs.ObjectPrintWidth( stab, stabThickness )
        rs.ObjectName( stab, "gitter" )

### testen:
#blumenPanel2( frontPanels[0], variante=0 )
#blumenPanel2( frontPanels[1], variante=1 )

stabThickness = 1.5*0
stabColor = [10,20,10]
allPanels = frontPanels[:]
for i,panel in enumerate(allPanels[0:]):#frontPanels[20:28]):
    pass
    dm.esc()
    if panel[0][2] > 24:
        anz = 64
        rnd = random.randint( anz**0.5, anz*1.0 )
        radAussen = random.uniform(3,6) ## 4 = panelbreite
        radAussen = rs.Distance(panel[0], panel[3])*0.5## 4 = panelbreite
        radiFac = random.uniform(0.1,0.3)
        anz = random.randint( 6, 10)
        vari = 1
        vari2 = random.randint( 0, 1)
        
        if random.uniform(0,100) < 60:
            pass
            blumenPanel(panel, radi=radAussen,  radiFac=radiFac, anz=anz, variante=vari )
        elif random.uniform(0,100) < 50:
            pass
            blumenPanel2 (panel, radi=radAussen+((vari2==0)*3),  radiFac=radiFac, anz=anz, variante=vari2 )
        elif random.uniform(0,100) < 10:
            blendenPanel(panel, anz=5, blende=random.randint(3,9), blendeSize=0.9)
            panel.append(panel[0])
            #rs.AddCurve( panel, 1)
            rs.AddCurve( panel, 2)
       #myPanel(panel, cnt=11)
    else:
        #panel.append(panel[0])
        rs.ObjectPrintWidth( rs.AddCurve( panel, 1), 1.0 )
    if i%100==0:
        rs.Redraw()


##############################
### nachBearbeitung / stacheln
gitters = rs.JoinCurves(rs.ObjectsByName("gitter"), delete_input=1)
for stab in gitters:
    rs.ObjectPrintWidth( stab, stabThickness*0.5 )
    rs.ObjectColor ( stab, stabColor )
    if rs.CurveLength(stab) > 1.0:
        rs.ObjectPrintWidth( stab, stabThickness )
        anz = int(rs.CurveLength(stab)*0.999)
        coords = rs.DivideCurve( stab, anz, 0)
        coords = random.sample( coords, int(anz*0.5) )
        for cor in coords[0:]:
            param = rs.CurveClosestPoint( stab, cor )
            nPlane = rs.CurvePerpFrame( stab, param )
            circ = rs.AddCircle( nPlane, random.uniform(0.5, 1.0) )
            coordsC = rs.DivideCurve( circ, 10, 0 )
            rs.DeleteObject( circ )
            coordsC = random.sample(coordsC, 4)
            tanVec = rs.CurveTangent( stab, param )
            coordsC = [rs.VectorAdd( corX, rs.VectorScale( tanVec, random.uniform(-1.0,1.0)) ) for corX in coordsC ]
            for corC in coordsC:
                lin = rs.AddLine( cor, corC )
                rs.ObjectColor ( lin, stabColor )
                rs.ObjectColor ( lin, [random.randint(60,100),random.randint(10,20),random.randint(10,20)]  )
                rs.ObjectPrintWidth( lin, stabThickness*0.3 )

#____________________________:here you end

#################################
#rs.ZoomExtents()
rs.EnableRedraw(1) ### 4 the MACs
dm.printDisplay( state=0, scale=1000 )
dm.newEmptyLayer("Default")