###################################
### DM2_w24 # AGruber@tugraz.at ###
### hu_05 UN_headquaters  NYC   ### ##########################
### paneling                    ### 87.5 x 22.0 x 156.0 meters
################################### ##########################


##############################
import rhinoscriptsyntax as rs
import random, time, sys   ###
sys.path.append("P:/")     ###
sys.path.append("P:/WWW/dx6419/dm2/")
import DM_lib as dm        ### reload( dm )
##############################      

rs.UnitSystem(4)                                        # 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(0)                                      # nomen est omen
rs.EnableRedraw(0)

dm.newEmptyLayer("Default")
dm.eA()
rs.Command("_-purge enter", 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=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

UnoPanelCoords = dm.getUNpanelCoords(anzL=10*1, anzH=39*1, anzD=3*1, stepL=2, stepH=7, stepD=2) ### = standard for hu_05

###########################################################################################
##########################################################
frontPanels   = UnoPanelCoords[0]
backPanels    = UnoPanelCoords[1]
upSidePanels  = UnoPanelCoords[3]
sidePanels    = UnoPanelCoords[2]
allPanels     = UnoPanelCoords[4]
#################################


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 mySockelPanel(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 )
    rs.ObjectPrintWidth( crv=2)
    rs.ObjectColor (122,22,22)

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])
    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 0:
        dm.newEmptyLayer("UNO::tst", [100,110,200])
        
        for i,panel in enumerate(frontPanels+upSidePanels):          ### +backPanels+upSidePanels
            dm.esc()
            if panel[0][2] > 0:
                pass
                myTsTPanel(panel, shuffle=1)
                if i and i%9==0:
                    rs.Redraw()
                else:
                    mySockelPanel (shuffle=0)



def jitterPoint(pt, max_shift=0.3):
    return (
        pt[0] + random.uniform(-max_shift, max_shift),                  #Zufallige kleine Verschiebung
        pt[1] + random.uniform(-max_shift, max_shift),
        pt[2] + random.uniform(-max_shift, max_shift)
    )

def drawDistortedQuad(panelPts, layers=3, distort=0.2, inner_lines=3):
    if not panelPts or len(panelPts) < 4:
        return

    p0, p1, p2, p3 = panelPts

    basePts = [jitterPoint(p, distort) for p in [p0, p1, p2, p3]]
    rs.AddCurve(basePts + [basePts[0]], 1)


    for i in range(1, layers + 1):               # Generate inner quads
        t = i / float(layers + 1)
        inner = []
        for p in basePts:
            cx = sum(pt[0] for pt in basePts) / 4.0
            cy = sum(pt[1] for pt in basePts) / 4.0
            cz = sum(pt[2] for pt in basePts) / 4.0
            inner.append((
                p[0] * (1 - t) + cx * t + random.uniform(-distort, distort) * 0.3,
                p[1] * (1 - t) + cy * t + random.uniform(-distort, distort) * 0.3,
                p[2] * (1 - t) + cz * t + random.uniform(-distort, distort) * 0.3
            ))
        rs.AddCurve(inner + [inner[0]], 1)


    for i in range(inner_lines):         # Add crossing inner lines for structure
        s = random.random() 
        e = random.random()
        a = rs.PointAdd(p0, rs.VectorScale(rs.VectorCreate(p1, p0), s))
        b = rs.PointAdd(p3, rs.VectorScale(rs.VectorCreate(p2, p3), e))
        a, b = jitterPoint(a, 0.1), jitterPoint(b, 0.1)
        rs.AddCurve([a, b], 1)


def connectDistortedPanels(panelA, panelB, layers=2, distort=0.3):    
    #Connect two quads with slightly distorted line meshes
    if not panelA or not panelB or len(panelA) < 4 or len(panelB) < 4:
        return

    for i in range(4):
        pA1 = jitterPoint(panelA[i], distort)
        pA2 = jitterPoint(panelA[(i + 1) % 4], distort)
        pB1 = jitterPoint(panelB[i], distort)
        pB2 = jitterPoint(panelB[(i + 1) % 4], distort)

        for j in range(1, layers + 1):
            t = j / float(layers + 1)
            sA = rs.PointAdd(pA1, rs.VectorScale(rs.VectorCreate(pB1, pA1), t))
            sB = rs.PointAdd(pA2, rs.VectorScale(rs.VectorCreate(pB2, pA2), t))
            sA, sB = jitterPoint(sA, distort * 0.3), jitterPoint(sB, distort * 0.3)
            rs.AddCurve([sA, sB], 1)
            
            
#######################################
################ HERE YOU GO AS YOU GO:
dm.newEmptyLayer("myPROJ", [100,110,200])

for i,panelPts in enumerate(frontPanels+upSidePanels):
    drawDistortedQuad(panelPts, layers=3, distort=0.2, inner_lines=3)


########## EOS / EndOfScript
rs.EnableRedraw(1)          ### 4_the_MACs
#dm.eDup( )                 ### delete duplicate objects 
dm.printDisplay(state=1, scale=1000, thickness=1, color='Display')
dm.zA( 0.9 )
rs.CurrentLayer("Default")
