def border(left, right, start, gapy, end, height, randheight, gaptrans, randgaptrans, lengthparquet, translatey):
    height = randheight * randuni(0, height)                              # Add randomness to the height of the boards
    gaptrans = gaptrans + (randgaptrans * randuni(0, gaptrans))
    tdogapy = gapy
    tupgapy = gapy
    if end + tupgapy > lengthparquet:
        tupgapy = (lengthparquet - end)
    tipdown = start - tdogapy / 2 + gaptrans
    tipup = end + tupgapy / 2 - gaptrans
    if tipup < end:
        tipup = end
    if tipdown < 0:
        tipdown = 0
    elif tipdown > start:
        tipdown = start
    td = Vector(((left + right) / 2, tipdown, height))                     # Tip down
    tdl = Vector((left, start, height))                                   # Tip down left
    tup = Vector((left, end, height))                                     # Tip up left
    tu = Vector(((left + right) / 2, tipup, height))                       # Tip up
    tur = Vector((right, end, height))                                    # Tip up right
    tdr = Vector((right, start, height))                                  # Tip down right

    verts = (td, tdl, tup, tu, tur, tdr)

    return verts
Example #2
0
def border(left, right, start, gapy, end, height, randheight, gaptrans,
           randgaptrans, lengthparquet, translatey):
    height = randheight * randuni(
        0, height)  # Add randomness to the height of the boards
    gaptrans = gaptrans + (randgaptrans * randuni(0, gaptrans))
    tdogapy = gapy
    tupgapy = gapy
    if end + tupgapy > lengthparquet:
        tupgapy = (lengthparquet - end)
    tipdown = start - tdogapy / 2 + gaptrans
    tipup = end + tupgapy / 2 - gaptrans
    if tipup < end:
        tipup = end
    if tipdown < 0:
        tipdown = 0
    elif tipdown > start:
        tipdown = start
    td = Vector(((left + right) / 2, tipdown, height))  # Tip down
    tdl = Vector((left, start, height))  # Tip down left
    tup = Vector((left, end, height))  # Tip up left
    tu = Vector(((left + right) / 2, tipup, height))  # Tip up
    tur = Vector((right, end, height))  # Tip up right
    tdr = Vector((right, start, height))  # Tip down right

    verts = (td, tdl, tup, tu, tur, tdr)

    return verts
def planks(n, m,
		length, lengthvar,
		width, widthvar,
		longgap, shortgap,
		offset, randomoffset,
		nseed,
		randrotx, randroty, randrotz):

	#n=Number of planks, m=Floor Length, length = Planklength

	verts = []
	faces = []
	shortedges = []
	longedges = []

	seed(nseed)
	widthoffset = 0
	s = 0
	e = offset
	c = offset  # Offset per row
	ws = 0
	p = 0

	while p < n:
		p += 1
		w = width + randuni(0, widthvar)
		we = ws + w
		if randomoffset:
			e = randuni(4 * shortgap, length)  # we don't like negative plank lengths
		while (m - e) > (4 * shortgap):
			ll = len(verts)
			rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
			verts.extend(plank(s, e, ws, we, longgap, shortgap, rot))
			faces.append((ll, ll + 1, ll + 2, ll + 3))
			shortedges.extend([(ll, ll + 1), (ll + 2, ll + 3)])
			longedges.extend([(ll + 1, ll + 2), (ll + 3, ll)])
			s = e
			e += length + randuni(0, lengthvar)
		ll = len(verts)
		rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
		verts.extend(plank(s, m, ws, we, longgap, shortgap, rot))
		faces.append((ll, ll + 1, ll + 2, ll + 3))
		shortedges.extend([(ll, ll + 1), (ll + 2, ll + 3)])
		longedges.extend([(ll + 1, ll + 2), (ll + 3, ll)])
		s = 0
		#e = e - m
		if c <= (length):
			c = c + offset
		if c > (length):
			c = c - length
		e = c
		ws = we
	return verts, faces, shortedges, longedges
Example #4
0
def interval(left, right, start, translatex, gapy, end, height, randheight,
             width, gapx, gaptrans, borders, endfloor, tilt, shifty):
    height = randheight * randuni(
        0, height)  # Add randomness to the height of the boards
    if gaptrans == gapx: bgap = 0
    else: bgap = gaptrans
    if shifty == 0 and borders and tilt == 0:
        tipleft = left - gapx / 2 + bgap
        tipright = right + gapx / 2 - bgap
        if tipleft < 0: tipleft = 0  # Constrain the first left tip to 0...
        elif tipleft > left:
            tipleft = left  # ...and the other to the left of the board
        if tipright < right:
            tipright = right  # Constrain the right tips to the right of the board..
        if endfloor > 0:
            tipright = endfloor  # ...and the last one to the last board of the floor
        dr = Vector((right, start, height))  # Down right
        dl = Vector((left, start, height))  # Down left
        tl = Vector((tipleft, start + (width / 2), height))  # Tip left
        ul = Vector((left, end, height))  # Up left
        ur = Vector((right, end, height))  # Up right
        tr = Vector((tipright, start + (width / 2), height))  # Tip right

        verts = (dr, dl, tl, ul, ur, tr)

    else:
        dr = Vector((right + translatex, start, height))  # Down right
        dl = Vector((left + translatex, start, height))  # Down left
        ul = Vector((left + translatex, end, height))  # Up left
        ur = Vector((right + translatex, end, height))  # Up right

        verts = (dl, ul, ur, dr)

    return verts
Example #5
0
def interval(left, right, start, translatex, gapy, end, height, randheight, width, gapx, gaptrans, borders, endfloor, tilt, shifty):
    height = randheight * randuni(0, height)                              # Add randomness to the height of the boards
    if gaptrans == gapx: bgap = 0
    else: bgap = gaptrans
    if shifty == 0 and borders and tilt == 0:
        tipleft = left-gapx/2+bgap
        tipright = right+gapx/2-bgap
        if tipleft < 0: tipleft = 0                                       # Constrain the first left tip to 0...
        elif tipleft > left: tipleft = left                               # ...and the other to the left of the board
        if tipright < right: tipright = right                             # Constrain the right tips to the right of the board.. 
        if endfloor > 0 : tipright = endfloor                             # ...and the last one to the last board of the floor
        dr = Vector((right, start, height))                               # Down right
        dl = Vector((left, start, height))                                # Down left
        tl = Vector((tipleft, start+(width/2), height))                   # Tip left
        ul = Vector((left, end, height))                                  # Up left
        ur = Vector((right, end, height))                                 # Up right
        tr = Vector((tipright, start+(width/2), height))                  # Tip right

        verts = (dr, dl, tl, ul, ur, tr)

    else:
        dr = Vector((right + translatex, start, height))                  # Down right
        dl = Vector((left + translatex, start, height))                   # Down left
        ul = Vector((left + translatex, end, height))                     # Up left
        ur = Vector((right + translatex, end, height))                    # Up right
        
        verts = (dl, ul, ur, dr)
        
    return verts
Example #6
0
def planks(n, m, length, lengthvar, width, widthvar, longgap, shortgap, offset,
           randomoffset, nseed, randrotx, randroty, randrotz):

    #n=Number of planks, m=Floor Length, length = Planklength

    verts = []
    faces = []
    shortedges = []
    longedges = []

    seed(nseed)
    widthoffset = 0
    s = 0
    e = offset
    c = offset  # Offset per row
    ws = 0
    p = 0

    while p < n:
        p += 1
        w = width + randuni(0, widthvar)
        we = ws + w
        if randomoffset:
            e = randuni(
                0, length
            )  # I think we should change length into offset. That way we have indepent control of of the offset variation
        while e < m:
            ll = len(verts)
            rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                         randrotz * randuni(-1, 1)), 'XYZ')
            verts.extend(plank(s, e, ws, we, longgap, shortgap, rot))
            faces.append((ll, ll + 1, ll + 2, ll + 3))
            shortedges.extend([(ll, ll + 1), (ll + 2, ll + 3)])
            longedges.extend([(ll + 1, ll + 2), (ll + 3, ll)])
            s = e
            e += length + randuni(0, lengthvar)
        ll = len(verts)
        rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                     randrotz * randuni(-1, 1)), 'XYZ')
        verts.extend(plank(s, m, ws, we, longgap, shortgap, rot))
        faces.append((ll, ll + 1, ll + 2, ll + 3))
        shortedges.extend([(ll, ll + 1), (ll + 2, ll + 3)])
        longedges.extend([(ll + 1, ll + 2), (ll + 3, ll)])
        s = 0
        #e = e - m
        if c <= (length):
            c = c + offset
        if c > (length):
            c = c - length
        e = c
        ws = we
    return verts, faces, shortedges, longedges
Example #7
0
def planks(n, m, length, lengthvar, width, widthvar, longgap, shortgap, offset,
           randomoffset, nseed, randrotx, randroty, randrotz):

    #n=Number of planks, m=Floor Length, length = Planklength

    verts = []
    faces = []
    shortedges = []
    longedges = []

    seed(nseed)
    widthoffset = 0
    s = 0
    e = offset
    c = offset  # Offset per row
    ws = 0
    p = 0

    while p < n:
        p += 1
        w = width + randuni(0, widthvar)
        we = ws + w
        if randomoffset:
            e = randuni(4 * shortgap,
                        length)  # we don't like negative plank lengths
        while (m - e) > (4 * shortgap):
            ll = len(verts)
            rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                         randrotz * randuni(-1, 1)), 'XYZ')
            verts.extend(plank(s, e, ws, we, longgap, shortgap, rot))
            faces.append((ll, ll + 1, ll + 2, ll + 3))
            shortedges.extend([(ll, ll + 1), (ll + 2, ll + 3)])
            longedges.extend([(ll + 1, ll + 2), (ll + 3, ll)])
            s = e
            e += length + randuni(0, lengthvar)
        ll = len(verts)
        rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                     randrotz * randuni(-1, 1)), 'XYZ')
        verts.extend(plank(s, m, ws, we, longgap, shortgap, rot))
        faces.append((ll, ll + 1, ll + 2, ll + 3))
        shortedges.extend([(ll, ll + 1), (ll + 2, ll + 3)])
        longedges.extend([(ll + 1, ll + 2), (ll + 3, ll)])
        s = 0
        #e = e - m
        if c <= (length):
            c = c + offset
        if c > (length):
            c = c - length
        e = c
        ws = we
    return verts, faces, shortedges, longedges
Example #8
0
def transversal(left, right, start, tilt, translatex, gapy, gapx, gaptrans,
                randgaptrans, end, nbrtrans, verts, faces, locktrans,
                lengthtrans, height, randheight, borders, endfloor, shifty):
    gaptrans = gaptrans + (
        randgaptrans * randuni(0, gaptrans)
    )  # Add randomness to the gap of the transversal of the boards
    if borders:
        nbrtrans = 1  # Constrain the transversal to 1 board if borders activate
    if gaptrans < (end - start) / (
            nbrtrans + 1):  # The gap can't be > to the width of the interval
        x = 0
        lengthint = 0
        if tilt > 0:
            translatex = 0  # Constrain the board to 0 on the x axis
        width = ((end - start) - (gaptrans * (nbrtrans + 1))) * (
            1 / nbrtrans)  # Width of 1 board in the interval
        startint = start + gaptrans  # Find the start of the first board
        while right > lengthint:  # While the transversal is < to the right edge of the floor (if unlock) or the board (if locked)
            if locktrans:  # If the length of the transversal is unlock
                lengthint += lengthtrans  # Add the length

            if not locktrans or (lengthint > right):
                lengthint = right  # Constrain the length of the transversal to th length of the board (locked)

            while x < nbrtrans:  # Nbr of boards in the transversal
                x += 1
                endtrans = startint + width  # Find the end of the board

                # Create the boards in the interval
                nbvert = len(verts)
                verts.extend(
                    interval(left, lengthint, startint, translatex, gapy,
                             endtrans, height, randheight, width, gapx,
                             gaptrans, borders, endfloor, tilt, shifty))
                if shifty == 0 and borders and tilt == 0:
                    faces.append((nbvert, nbvert + 1, nbvert + 2, nbvert + 3,
                                  nbvert + 4, nbvert + 5))
                else:
                    faces.append((nbvert, nbvert + 1, nbvert + 2, nbvert + 3))
                startint = endtrans + gaptrans  # Find the start of the next board

            #------------------------------------------------------------
            # Increment / initialize
            #------------------------------------------------------------
            if locktrans:
                left = lengthint + gaptrans
                lengthint += gaptrans
                x = 0
                endtrans = start + width
                startint = start + gaptrans

            # The boards can't be > to the length of the floor
            if left > right:
                lengthint = left
def planks(n, m,
           length, lengthvar,
           width, widthvar,
           longgap, shortgap,
           offset, randomoffset,
           nseed,
           randrotx, randroty, randrotz):

    #n=Number of planks, m=Floor Length, length = Planklength

    verts = []
    faces = []
    shortedges = []
    longedges = []

    seed(nseed)
    widthoffset = 0
    s = 0
    e = offset
    c = offset  # Offset per row
    ws = 0
    p = 0

    while p < n:
        p += 1
        w = width + randuni(0, widthvar)
        we = ws + w
        if randomoffset:
            e = randuni(0, length)  # I think we should change length into offset. That way we have indepent control of of the offset variation
        while e < m:
            ll = len(verts)
            rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
            verts.extend(plank(s, e, ws, we, longgap, shortgap, rot))
            faces.append((ll, ll + 1, ll + 2, ll + 3))
            shortedges.extend([(ll, ll + 1), (ll + 2, ll + 3)])
            longedges.extend([(ll + 1, ll + 2), (ll + 3, ll)])
            s = e
            e += length + randuni(0, lengthvar)
        ll = len(verts)
        rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
        verts.extend(plank(s, m, ws, we, longgap, shortgap, rot))
        faces.append((ll, ll + 1, ll + 2, ll + 3))
        shortedges.extend([(ll, ll + 1), (ll + 2, ll + 3)])
        longedges.extend([(ll + 1, ll + 2), (ll + 3, ll)])
        s = 0
        #e = e - m
        if c <= (length):
            c = c + offset
        if c > (length):
            c = c - length
        e = c
        ws = we
    return verts, faces, shortedges, longedges
Example #10
0
def herringbone(rows, cols, planklength, plankwidth, longgap, shortgap, nseed, randrotx, randroty, randrotz, originx, originy):
	verts = []
	faces = []
	uvs = []
	
	seed(nseed)
	
	ll=0
	longside = (planklength-shortgap)/sqrt(2.0)
	shortside = (plankwidth-longgap)/sqrt(2.0)
	vstep = Vector((0,plankwidth * sqrt(2.0),0))
	hstepl = Vector((planklength * sqrt(2.0),0,0))
	hstep = Vector((planklength/sqrt(2.0)-(plankwidth-longgap)/sqrt(2.0),planklength/sqrt(2.0)+(plankwidth-longgap)/sqrt(2.0),0))
	
	dy = Vector((0,-planklength/sqrt(2.0),0))
	
	pu = [Vector((0,0,0)),Vector((longside,0,0)),Vector((longside,shortside,0)),Vector((0,shortside,0))]
	
	pv = [Vector((0,0,0)),Vector((longside,longside,0)),Vector((longside-shortside,longside+shortside,0)),Vector((-shortside,shortside,0))]
	rot = Euler((0,0,-PI/2),"XYZ")
	pvm = [rotate(v, rot)+hstep for v in pv]
	
	midpointpv = sum(pv,Vector())/4.0
	midpointpvm = sum(pvm,Vector())/4.0

	o = Vector((-originx, -originy, 0))
	midpointpvo = midpointpv - o
	midpointpvmo = midpointpvm - o

	for col in range(cols):
		for row in range(rows):
			# CLEANUP: this could be shorter: for P in pv,pvm 
			rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
			pvo = [ v + o for v in pv]
			pverts = [rotate(v - midpointpvo, rot) + midpointpvo  + row * vstep + col * hstepl + dy for v in pvo]
			verts.extend(deepcopy(pverts))
			uvs.append([v + Vector((col*2*longside,row*shortside,0)) for v in pu])
			faces.append((ll, ll + 1, ll + 2, ll + 3))
			ll = len(verts)
			rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
			pvmo = [ v + o for v in pvm]
			pverts = [rotate(v - midpointpvmo, rot) + midpointpvmo  + row * vstep + col * hstepl + dy for v in pvmo]
			verts.extend(deepcopy(pverts))
			uvs.append([v + Vector(((1+col*2)*longside,row*shortside,0)) for v in pu])
			faces.append((ll, ll + 1, ll + 2, ll + 3))
			ll = len(verts)
	
	for i in range(len(uvs)):
		pp1 = randrange(len(uvs))
		pp2 = randrange(len(uvs))
		swap(uvs,pp1,pp2)
		
	fuvs = [v for p in uvs for v in p]
	return verts, faces, fuvs
Example #11
0
def herringbone(rows, cols, planklength, plankwidth, longgap, shortgap, nseed, randrotx, randroty, randrotz, originx, originy):
	verts = []
	faces = []
	uvs = []
	
	seed(nseed)
	
	ll=0
	longside = (planklength-shortgap)/sqrt(2.0)
	shortside = (plankwidth-longgap)/sqrt(2.0)
	vstep = Vector((0,plankwidth * sqrt(2.0),0))
	hstepl = Vector((planklength * sqrt(2.0),0,0))
	hstep = Vector((planklength/sqrt(2.0)-(plankwidth-longgap)/sqrt(2.0),planklength/sqrt(2.0)+(plankwidth-longgap)/sqrt(2.0),0))
	
	dy = Vector((0,-planklength/sqrt(2.0),0))
	
	pu = [Vector((0,0,0)),Vector((longside,0,0)),Vector((longside,shortside,0)),Vector((0,shortside,0))]
	
	pv = [Vector((0,0,0)),Vector((longside,longside,0)),Vector((longside-shortside,longside+shortside,0)),Vector((-shortside,shortside,0))]
	rot = Euler((0,0,-PI/2),"XYZ")
	pvm = [rotate(v, rot)+hstep for v in pv]
	
	midpointpv = sum(pv,Vector())/4.0
	midpointpvm = sum(pvm,Vector())/4.0

	o = Vector((-originx, -originy, 0))
	midpointpvo = midpointpv - o
	midpointpvmo = midpointpvm - o

	for col in range(cols):
		for row in range(rows):
			# CLEANUP: this could be shorter: for P in pv,pvm 
			rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
			pvo = [ v + o for v in pv]
			pverts = [rotate(v - midpointpvo, rot) + midpointpvo  + row * vstep + col * hstepl + dy for v in pvo]
			verts.extend(deepcopy(pverts))
			uvs.append([v + Vector((col*2*longside,row*shortside,0)) for v in pu])
			faces.append((ll, ll + 1, ll + 2, ll + 3))
			ll = len(verts)
			rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
			pvmo = [ v + o for v in pvm]
			pverts = [rotate(v - midpointpvmo, rot) + midpointpvmo  + row * vstep + col * hstepl + dy for v in pvmo]
			verts.extend(deepcopy(pverts))
			uvs.append([v + Vector(((1+col*2)*longside,row*shortside,0)) for v in pu])
			faces.append((ll, ll + 1, ll + 2, ll + 3))
			ll = len(verts)
	
	for i in range(len(uvs)):
		pp1 = randrange(len(uvs))
		pp2 = randrange(len(uvs))
		swap(uvs,pp1,pp2)
		
	fuvs = [v for p in uvs for v in p]
	return verts, faces, fuvs
Example #12
0
def board(start, left, right, end, tilt, translatex, hyp, herringbone, gapy,
          height, randheight):

    gapx = 0
    height = randheight * randuni(
        0, height)  # Add randomness to the height of the boards
    if not herringbone:
        gapy = 0

    if tilt > 0:  # / / / -> 1 board, 3 board, 5 board...
        shiftdown = translatex
        shiftup = 0
        if herringbone:
            gapy = gapy / 2
            gapx = 0

    else:  # \ \ \-> 2 board, 4 board, 6 board...
        shiftdown = 0
        shiftup = -translatex
        if herringbone:
            gapy = gapy / 2
            gapx = gapy * 2

    dl = Vector(
        (left + shiftdown + gapx, start - gapy, height))  # down left [0,0,0]
    dr = Vector(
        (right + shiftdown + gapx, start - gapy, height))  # down right [1,0,0]
    ur = Vector(
        (right - shiftup + gapx, end - gapy, height))  # up right [1,1,0]
    ul = Vector((left - shiftup + gapx, end - gapy, height))  # up left [0,1,0]

    if herringbone:
        if tilt > 0:  # / / / -> 1 board, 3 board, 5 board...
            ur[0] = ur[0] - (hyp / 2)
            ur[1] = ur[1] + (hyp / 2)
            dr[0] = dr[0] - (hyp / 2)
            dr[1] = dr[1] + (hyp / 2)
        else:  # \ \ \-> 2 board, 4 board, 6 board...
            dl[0] = dl[0] + (hyp / 2)
            dl[1] = dl[1] + (hyp / 2)
            ul[0] = ul[0] + (hyp / 2)
            ul[1] = ul[1] + (hyp / 2)

    verts = (dl, ul, ur, dr)

    return (verts)
def transversal(left, right, start, tilt, translatex, gapy, gapx, gaptrans, randgaptrans, end, nbrtrans, verts, faces, locktrans, lengthtrans, height, randheight, borders, endfloor, shifty):
    gaptrans = gaptrans + (randgaptrans * randuni(0, gaptrans))           # Add randomness to the gap of the transversal of the boards
    if borders:
        nbrtrans = 1                                              # Constrain the transversal to 1 board if borders activate
    if gaptrans < (end - start) / (nbrtrans + 1):                               # The gap can't be > to the width of the interval
        x = 0
        lengthint = 0
        if tilt > 0:
            translatex = 0                                       # Constrain the board to 0 on the x axis
        width = ((end - start) - (gaptrans * (nbrtrans + 1))) * (1 / nbrtrans)  # Width of 1 board in the interval
        startint = start + gaptrans                                       # Find the start of the first board
        while right > lengthint:                                          # While the transversal is < to the right edge of the floor (if unlock) or the board (if locked)
            if locktrans:                                                 # If the length of the transversal is unlock
                lengthint += lengthtrans                                  # Add the length

            if not locktrans or (lengthint > right):
                lengthint = right    # Constrain the length of the transversal to th length of the board (locked)

            while x < nbrtrans:                                           # Nbr of boards in the transversal
                x += 1
                endtrans = startint + width                               # Find the end of the board

                # Create the boards in the interval
                nbvert = len(verts)
                verts.extend(interval(left, lengthint, startint, translatex, gapy, endtrans, height, randheight, width, gapx, gaptrans, borders, endfloor, tilt, shifty))
                if shifty == 0 and borders and tilt == 0:
                    faces.append((nbvert, nbvert + 1, nbvert + 2, nbvert + 3, nbvert + 4, nbvert + 5))
                else:
                    faces.append((nbvert, nbvert + 1, nbvert + 2, nbvert + 3))
                startint = endtrans + gaptrans                            # Find the start of the next board

            #------------------------------------------------------------
            # Increment / initialize
            #------------------------------------------------------------
            if locktrans:
                left = lengthint + gaptrans
                lengthint += gaptrans
                x = 0
                endtrans = start + width
                startint = start + gaptrans

            # The boards can't be > to the length of the floor
            if left > right:
                lengthint = left
def board(start, left, right, end, tilt, translatex, hyp, herringbone, gapy, height, randheight):

    gapx = 0
    height = randheight * randuni(0, height)                              # Add randomness to the height of the boards
    if not herringbone:
        gapy = 0

    if tilt > 0:                                                          # / / / -> 1 board, 3 board, 5 board...
        shiftdown = translatex
        shiftup = 0
        if herringbone:
            gapy = gapy / 2
            gapx = 0

    else:  # \ \ \-> 2 board, 4 board, 6 board...
        shiftdown = 0
        shiftup = -translatex
        if herringbone:
            gapy = gapy / 2
            gapx = gapy * 2

    dl = Vector((left + shiftdown + gapx, start - gapy, height))          # down left [0,0,0]
    dr = Vector((right + shiftdown + gapx, start - gapy, height))         # down right [1,0,0]
    ur = Vector((right - shiftup + gapx, end - gapy, height))             # up right [1,1,0]
    ul = Vector((left - shiftup + gapx, end - gapy, height))              # up left [0,1,0]

    if herringbone:
        if tilt > 0:                                                      # / / / -> 1 board, 3 board, 5 board...
            ur[0] = ur[0] - (hyp / 2)
            ur[1] = ur[1] + (hyp / 2)
            dr[0] = dr[0] - (hyp / 2)
            dr[1] = dr[1] + (hyp / 2)
        else:  # \ \ \-> 2 board, 4 board, 6 board...
            dl[0] = dl[0] + (hyp / 2)
            dl[1] = dl[1] + (hyp / 2)
            ul[0] = ul[0] + (hyp / 2)
            ul[1] = ul[1] + (hyp / 2)

    verts = (dl, ul, ur, dr)

    return (verts)
Example #15
0
def square(rows, cols, planklength, n, border, longgap, shortgap, nseed, randrotx, randroty, randrotz, originx, originy):
	verts = []
	verts2 = []
	faces = []
	faces2 = []
	uvs = []
	uvs2 = []
	seed(nseed)
	
	ll=0
	ll2=0
	net_planklength = planklength - 2.0 * border
	
	plankwidth = net_planklength/n
	longside = (net_planklength-shortgap)
	shortside = (plankwidth-longgap)
	stepv = Vector((0,planklength ,0))
	steph = Vector((planklength,0 ,0))
	nstepv = Vector((0,plankwidth ,0))
	nsteph = Vector((plankwidth,0 ,0))
	
	pv = [Vector((0,0,0)),Vector((longside,0,0)),Vector((longside,shortside,0)),Vector((0,shortside,0))]
	rot = Euler((0,0,-PI/2),"XYZ")
	pvm = [rotate(v, rot) + Vector((0,planklength - border,0)) for v in pv]
	
	midpointpv = sum(pv,Vector())/4.0
	midpointpvm = sum(pvm,Vector())/4.0
	
	offseth = Vector((border, border, 0))
	offsetv = Vector((border, 0, 0))
	
	bw = border - shortgap
	b1 = [(0,longgap/2.0,0),(0,planklength - longgap/2.0,0),(bw,planklength - longgap/2.0 - border,0),(bw,longgap/2.0 + border,0)]
	b1 = [Vector(v) for v in b1]
	d = Vector((planklength/2.0, planklength/2.0, 0))
	rot = Euler((0,0,-  PI/2),"XYZ")
	b2 = [rotate(v-d,rot)+d for v in b1]
	rot = Euler((0,0,-  PI  ),"XYZ")
	b3 = [rotate(v-d,rot)+d for v in b1]
	rot = Euler((0,0,-3*PI/2),"XYZ")
	b4 = [rotate(v-d,rot)+d for v in b1]

	o = Vector((-originx, -originy, 0))

	# CLEANUP: duplicate code, suboptimal loop nesting and a lot of repeated calculations
	# note that the uv map we create here is always aligned in the same direction even though planks alternate. This matches the saw direction in real life
	for col in range(cols):
		for row in range(rows):
			# add the regular planks
			for p in range(n):
				rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
				if (col ^ row) %2 == 1:
					pverts = [rotate(v - midpointpv, rot) + midpointpv + row * stepv + col * steph + nstepv * p + offseth + o for v in pv]
					uverts = [v + row * stepv + col * steph + nstepv * p for v in pv]
				else:
					pverts = [rotate(v - midpointpv, rot) + midpointpv + row * stepv + col * steph + nsteph * p + offsetv + o for v in pvm]
					uverts = [v + row * stepv + col * steph + nstepv * p for v in pv]
				verts.extend(deepcopy(pverts))
				uvs.append(deepcopy(uverts))
				faces.append((ll, ll + 1, ll + 2, ll + 3))
				ll = len(verts)
			# add the border planks
			if bw > 0.001:
				for vl in b1,b2,b3,b4:
					rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
					midpointvl = sum(vl,Vector())/4.0
					verts2.extend([rotate(v - midpointvl, rot) + midpointvl + row * stepv + col * steph + o for v in vl])
					uvs2.append(deepcopy([v + row * stepv + col * steph for v in b1])) # again, always the unrotated uvs to match the saw direction
					faces2.append((ll2, ll2 + 3, ll2 + 2, ll2 + 1))
					ll2 = len(verts2)
						
	for i in range(len(uvs)):
		pp1 = randrange(len(uvs))
		pp2 = randrange(len(uvs))
		swap(uvs,pp1,pp2)
	for i in range(len(uvs2)):
		pp1 = randrange(len(uvs2))
		pp2 = randrange(len(uvs2))
		swap(uvs2,pp1,pp2)
	
	fuvs = [v for p in uvs for v in p]
	fuvs2 = [v for p in uvs2 for v in p]
	
	return verts + verts2, faces + [(f[0]+ll,f[1]+ll,f[2]+ll,f[3]+ll) for f in faces2], fuvs + fuvs2
Example #16
0
def planks(n, m,
		length, lengthvar,
		width, widthvar,
		longgap, shortgap,
		offset, randomoffset, minoffset,
		nseed,
		randrotx, randroty, randrotz,
		originx, originy):

	#n=Number of planks, m=Floor Length, length = Planklength

	verts = []
	faces = []
	uvs = []
	
	seed(nseed)
	widthoffset = 0
	s = 0
	e = offset
	c = offset  # Offset per row
	ws = 0
	p = 0

	while p < n:
		p += 1
		
		uvs.append([])
		
		w = width + randuni(0, widthvar)
		we = ws + w
		if randomoffset:
			e = randuni(4 * shortgap + (offset if minoffset else 0.0), length)  # we don't like negative plank lengths
		while (m - e) > (4 * shortgap + (offset if minoffset else 0.0)):
			ll = len(verts)
			rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
			pverts = plank(s - originx, e - originx, ws - originy, we - originy, longgap, shortgap, rot)
			verts.extend(pverts)
			uvs[-1].append(deepcopy(pverts))
			faces.append((ll, ll + 3, ll + 2, ll + 1))
			s = e
			e += length + randuni(0, lengthvar)
		ll = len(verts)
		rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
		pverts = plank(s - originx, m - originx, ws - originy, we - originy, longgap, shortgap, rot)
		verts.extend(pverts)
		uvs[-1].append(deepcopy(pverts))
		faces.append((ll, ll + 3, ll + 2, ll + 1))
		s = 0
		#e = e - m
		if c <= (length):
			c = c + offset
		if c > (length):
			c = c - length
		e = c
		ws = we
		# randomly swap uvs of planks. Note: we only swap within one set of planks because different sets can have different widths.
		nplanks = len(uvs[-1])
		if nplanks < 2 : continue
		for pp in range(nplanks//2): # // to make sure it stays an int
			i = randrange(nplanks-1)
			swapx(uvs[-1],i)
		
	fuvs = [uv for col in uvs for plank in col for uv in plank]
	return verts, faces, fuvs
Example #17
0
def updateMesh(self, context):
    o = context.object

    material_list = getMaterialList(o)

    if o.pattern == 'Regular':
        nplanks = (o.width + o.originy) / o.plankwidth
        verts, faces, uvs = planks(nplanks, o.length + o.originx,
                                   o.planklength, o.planklengthvar,
                                   o.plankwidth, o.plankwidthvar, o.longgap,
                                   o.shortgap, o.offset, o.randomoffset,
                                   o.randomseed, o.randrotx, o.randroty,
                                   o.randrotz, o.originx, o.originy)
    elif o.pattern == 'Herringbone':
        # note that there is a lot of extra length and width here to make sure that  we create a pattern w.o. gaps at the edges
        v = o.plankwidth * sqrt(2.0)
        w = o.planklength * sqrt(2.0)
        nplanks = int((o.width + o.planklength + o.originy * 2) / v) + 1
        nplanksc = int((o.length + o.originx * 2) / w) + 1
        verts, faces, uvs = herringbone(nplanks, nplanksc, o.planklength,
                                        o.plankwidth, o.longgap, o.shortgap,
                                        o.randomseed, o.randrotx, o.randroty,
                                        o.randrotz, o.originx, o.originy)
    elif o.pattern == 'Square':
        rows = int((o.width + o.originy) / o.planklength) + 1
        cols = int((o.length + o.originx) / o.planklength) + 1
        verts, faces, uvs = square(rows, cols, o.planklength, o.nsquare,
                                   o.border, o.longgap, o.shortgap,
                                   o.randomseed, o.randrotx, o.randroty,
                                   o.randrotz, o.originx, o.originy)
    elif o.pattern == 'Versaille':
        rows = int((o.width + o.originy) / o.planklength) + 2
        cols = int((o.length + o.originx) / o.planklength) + 2
        verts, faces, uvs = versaille(rows, cols, o.planklength, o.plankwidth,
                                      o.longgap, o.shortgap, o.randrotx,
                                      o.randroty, o.randrotz, o.originx,
                                      o.originy, o.borderswitch)

    # create mesh &link object to scene
    emesh = o.data

    mesh = bpy.data.meshes.new(name='Planks')
    mesh.from_pydata(verts, [], faces)

    mesh.update(calc_edges=True)

    # more than one object can refer to the same emesh
    for i in bpy.data.objects:
        if i.data == emesh:
            i.data = mesh

    name = emesh.name
    emesh.user_clear(
    )  # this way the old mesh is marked as used by noone and not saved on exit
    bpy.data.meshes.remove(emesh)
    mesh.name = name
    if bpy.context.mode != 'EDIT_MESH':
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.editmode_toggle()

    bpy.ops.object.shade_smooth()

    # add uv-coords and per face random vertex colors
    rot = Euler((0, 0, o.uvrotation))
    mesh.uv_textures.new()
    uv_layer = mesh.uv_layers.active.data
    vertex_colors = mesh.vertex_colors.new().data
    offset = Vector()
    # note that the uvs that are returned are shuffled
    for poly in mesh.polygons:
        color = [rand(), rand(), rand()]
        if o.randomuv == 'Random':
            offset = Vector((rand(), rand(), 0))
        if o.randomuv == 'Restricted':
            offset = Vector((rand() * 2 - 1, rand() * 2 - 1, 0))
            for loop_index in range(poly.loop_start,
                                    poly.loop_start + poly.loop_total):
                co = offset + mesh.vertices[
                    mesh.loops[loop_index].vertex_index].co
                if co.x > o.length or co.x < 0:
                    offset[0] = 0
                if co.y > o.width or co.y < 0:
                    offset[1] = 0
        elif o.randomuv == 'Packed':
            x = []
            y = []
            for loop_index in range(poly.loop_start,
                                    poly.loop_start + poly.loop_total):
                x.append(uvs[mesh.loops[loop_index].vertex_index].x)
                y.append(uvs[mesh.loops[loop_index].vertex_index].y)
            offset = Vector((-min(x), -min(y), 0))
        for loop_index in range(poly.loop_start,
                                poly.loop_start + poly.loop_total):
            if o.randomuv == 'Shuffle':
                coords = uvs[mesh.loops[loop_index].vertex_index]
            elif o.randomuv in ('Random', 'Restricted'):
                coords = mesh.vertices[
                    mesh.loops[loop_index].vertex_index].co + offset
            elif o.randomuv == 'Packed':
                coords = uvs[mesh.loops[loop_index].vertex_index] + offset
            else:
                coords = mesh.vertices[mesh.loops[loop_index].vertex_index].co
            coords = Vector(coords)  # copy
            coords.x *= o.uvscalex
            coords.y *= o.uvscaley
            coords.rotate(rot)
            uv_layer[loop_index].uv = coords.xy
            vertex_colors[loop_index].color = color

    # subdivide mesh and warp it
    warped = o.hollowlong > 0 or o.hollowshort > 0 or o.twist > 0
    if warped:
        bm = bmesh.new()
        bm.from_mesh(mesh)

        # calculate hollowness for each face
        dshortmap = {}
        dlongmap = {}
        for face in bm.faces:
            dshort = o.hollowshort * rand()
            dlong = o.hollowlong * rand()
            for v in face.verts:
                dshortmap[v.index] = dshort
                dlongmap[v.index] = dlong

        bm.to_mesh(mesh)
        bm.free()

        # at this point all new geometry is selected and subdivide works in all selection modes
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.subdivide()  # bmesh subdivide doesn't work for me ...
        bpy.ops.object.editmode_toggle()

        bm = bmesh.new()
        bm.from_mesh(mesh)

        for v in bm.verts:
            if o.twist and len(
                    v.link_edges) == 4:  # vertex in the middle of the plank
                dtwist = o.twist * randuni(-1, 1)
                for e in v.link_edges:
                    v2 = e.other_vert(
                        v)  # the vertices on the side of the plank
                    if shortside(v2):
                        for e2 in v2.link_edges:
                            v3 = e2.other_vert(v2)
                            if len(v3.link_edges) == 2:
                                v3.co.z += dtwist
                                dtwist = -dtwist  # one corner up, the other corner down
            elif len(v.link_edges
                     ) == 3:  # vertex in the middle of a side of the plank
                for e in v.link_edges:
                    v2 = e.other_vert(v)
                    if len(
                            v2.link_edges
                    ) == 2:  # hollowness values are stored with the all original corner vertices
                        dshort = dshortmap[v2.index]
                        dlong = dlongmap[v2.index]
                        break
                if shortside(v):
                    v.co.z -= dlong
                else:
                    v.co.z -= dshort

        creases = bm.edges.layers.crease.new()
        for edge in bm.edges:
            edge[creases] = 1
            for vert in edge.verts:
                if len(vert.link_edges) == 4:
                    edge[creases] = 0
                    break

        bm.to_mesh(mesh)
        bm.free()

    # remove all modifiers to make sure the boolean will be last & only modifier
    n = len(o.modifiers)
    while n > 0:
        n -= 1
        bpy.ops.object.modifier_remove(modifier=o.modifiers[-1].name)

    # add thickness
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(o.data)

    # extrude to give thickness
    ret = bmesh.ops.extrude_face_region(bm, geom=bm.faces[:])
    ret = bmesh.ops.translate(
        bm,
        vec=Vector((0, 0, self.thickness)),
        verts=[el for el in ret['geom'] if isinstance(el, bmesh.types.BMVert)])

    # trim excess flooring
    ret = bmesh.ops.bisect_plane(bm,
                                 geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
                                 plane_co=(o.length, 0, 0),
                                 plane_no=(1, 0, 0),
                                 clear_outer=True)
    ret = bmesh.ops.bisect_plane(bm,
                                 geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
                                 plane_co=(0, 0, 0),
                                 plane_no=(-1, 0, 0),
                                 clear_outer=True)
    ret = bmesh.ops.bisect_plane(bm,
                                 geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
                                 plane_co=(0, o.width, 0),
                                 plane_no=(0, 1, 0),
                                 clear_outer=True)
    ret = bmesh.ops.bisect_plane(bm,
                                 geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
                                 plane_co=(0, 0, 0),
                                 plane_no=(0, -1, 0),
                                 clear_outer=True)

    # fill in holes caused by the trimming
    open_edges = [e for e in bm.edges if len(e.link_faces) == 1]
    bmesh.ops.edgeloop_fill(bm, edges=open_edges, mat_nr=0, use_smooth=False)

    creases = bm.edges.layers.crease.active
    if creases is not None:
        for edge in open_edges:
            edge[creases] = 1

    bmesh.update_edit_mesh(o.data)
    bpy.ops.object.mode_set(mode='OBJECT')

    # intersect with a floorplan. Note the floorplan must be 2D (all z-coords must be identical) and a closed polygon.
    if self.usefloorplan and self.floorplan != ' None ':
        # make the floorplan the only active an selected object
        bpy.ops.object.select_all(action='DESELECT')
        context.scene.objects.active = bpy.data.objects[self.floorplan]
        bpy.data.objects[self.floorplan].select = True

        # duplicate the selected geometry into a separate object
        me = context.scene.objects.active.data
        selected_faces = [p.index for p in me.polygons if p.select]
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.duplicate()
        bpy.ops.mesh.separate()
        bpy.ops.object.editmode_toggle()
        me = context.scene.objects.active.data
        for i in selected_faces:
            me.polygons[i].select = True

        # now there will be two selected objects
        # the one with the new name will be the copy
        for ob in context.selected_objects:
            if ob.name != self.floorplan:
                fpob = ob

        # make that copy active and selected
        for ob in context.selected_objects:
            ob.select = False
        fpob.select = True
        context.scene.objects.active = fpob
        # add thickness
        # let normals of select faces point in same direction
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.mesh.normals_make_consistent(inside=False)
        bpy.ops.object.editmode_toggle()
        # add solidify modifier
        # NOTE: for some reason bpy.ops.object.modifier_add doesn't work here
        # even though fpob at this point is verifyable the active and selected object ...
        mod = fpob.modifiers.new(name='Solidify', type='SOLIDIFY')
        mod.offset = 1.0  # in the direction of the normals
        mod.thickness = 2000  # very thick
        bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.mesh.normals_make_consistent(inside=False)
        bpy.ops.object.editmode_toggle()
        fpob.location -= Vector(
            (0, 0, 1000)
        )  # actually this should be in the negative direction of the normals not just plain downward...

        # at this point the floorplan object is the active and selected object
        if True:
            # make the floorboards active and selected
            for ob in context.selected_objects:
                ob.select = False
            context.scene.objects.active = o
            o.select = True

            # add-and-apply a boolean modifier to get the intersection with the floorplan copy
            bpy.ops.object.modifier_add(type='BOOLEAN')  # default is intersect
            o.modifiers[-1].object = fpob
            if True:
                bpy.ops.object.modifier_apply(apply_as='DATA',
                                              modifier="Boolean")
                # delete the copy
                bpy.ops.object.select_all(action='DESELECT')
                context.scene.objects.active = fpob
                fpob.select = True
                bpy.ops.object.delete()
            # make the floorboards active and selected
            context.scene.objects.active = o
            o.select = True

    if self.modify:
        mods = o.modifiers
        if len(mods) == 0:  # always true
            bpy.ops.object.modifier_add(type='BEVEL')
            #bpy.ops.object.modifier_add(type='EDGE_SPLIT')
            mods = o.modifiers
            mods[0].show_expanded = False
            #mods[1].show_expanded = False
            mods[0].width = self.bevel
            mods[0].segments = 2
            mods[0].limit_method = 'ANGLE'
            mods[0].angle_limit = (85 / 90.0) * PI / 2
        if warped and not ('SUBSURF' in [m.type for m in mods]):
            bpy.ops.object.modifier_add(type='SUBSURF')
            mods[-1].show_expanded = False
            mods[-1].levels = 2
        if not warped and ('SUBSURF' in [m.type for m in mods]):
            bpy.ops.object.modifier_remove(modifier='Subsurf')

    if self.preservemats and len(material_list) > 0:
        rebuildMaterialList(o, material_list)
        assignRandomMaterial(len(material_list))
Example #18
0
def versaille(rows,
              cols,
              planklength,
              plankwidth,
              longgap=0,
              shortgap=0,
              randrotx=0,
              randroty=0,
              randrotz=0,
              originx=0,
              originy=0,
              switch=False):

    o = Vector((-originx, -originy, 0)) * planklength

    # (8*w+w/W2)*W2 + w = 8*w*W2+w = (8*W2+1)*w = 1
    w = 1.0 / (8 * W2 + 2)
    #w1 = 1 - w
    q = w / W2
    #k = w*4*W2-w
    #s = (k - w)/2
    #d = ((s+2*w)/W2)/2
    #S = s/W2
    sg = shortgap
    s2 = sg / W2
    lg = longgap

    dd = -q if switch else 0

    planks1 = (
        # rectangles
        (0, [(0 + sg, 0, 0), (w * 5 - sg, 0, 0), (w * 5 - sg, w, 0),
             (0 + sg, w, 0)]),
        (0, [(6 * w + sg, 0, 0), (w * 11 - sg, 0, 0), (w * 11 - sg, w, 0),
             (6 * w + sg, w, 0)]),
        (90, [(5 * w, -2 * w + sg, 0), (w * 6, -2 * w + sg, 0),
              (w * 6, 3 * w - sg, 0), (5 * w, 3 * w - sg, 0)]),
        (0, [(3 * w + sg, 3 * w, 0), (w * 8 - sg, 3 * w, 0),
             (w * 8 - sg, w * 4, 0), (3 * w + sg, w * 4, 0)]),
        (0, [(3 * w + sg, -3 * w, 0), (w * 8 - sg, -3 * w, 0),
             (w * 8 - sg, w * -2, 0), (3 * w + sg, w * -2, 0)]),
        (90, [(5 * w, 4 * w + sg, 0), (6 * w, 4 * w + sg, 0),
              (6 * w, 6 * w - sg, 0), (5 * w, 6 * w - sg, 0)]),
        (90, [(5 * w, -3 * w - sg, 0), (5 * w, -5 * w + sg, 0),
              (6 * w, -5 * w + sg, 0), (6 * w, -3 * w - sg, 0)]),
        # squares
        (0, [(0 + sg, w + sg, 0), (w * 2 - sg, w + sg, 0),
             (w * 2 - sg, w * 3 - sg, 0), (0 + sg, w * 3 - sg, 0)]),
        (0, [(3 * w + sg, w + sg, 0), (w * 5 - sg, w + sg, 0),
             (w * 5 - sg, w * 3 - sg, 0), (3 * w + sg, w * 3 - sg, 0)]),
        (0, [(6 * w + sg, w + sg, 0), (w * 8 - sg, w + sg, 0),
             (w * 8 - sg, w * 3 - sg, 0), (6 * w + sg, w * 3 - sg, 0)]),
        (0, [(9 * w + sg, w + sg, 0), (w * 11 - sg, w + sg, 0),
             (w * 11 - sg, w * 3 - sg, 0), (9 * w + sg, w * 3 - sg, 0)]),
        (0, [(0 + sg, -2 * w + sg, 0), (w * 2 - sg, -2 * w + sg, 0),
             (w * 2 - sg, 0 - sg, 0), (0 + sg, 0 - sg, 0)]),
        (0, [(3 * w + sg, -2 * w + sg, 0), (w * 5 - sg, -2 * w + sg, 0),
             (w * 5 - sg, 0 - sg, 0), (3 * w + sg, 0 - sg, 0)]),
        (0, [(6 * w + sg, -2 * w + sg, 0), (w * 8 - sg, -2 * w + sg, 0),
             (w * 8 - sg, 0 - sg, 0), (6 * w + sg, 0 - sg, 0)]),
        (0, [(9 * w + sg, -2 * w + sg, 0), (w * 11 - sg, -2 * w + sg, 0),
             (w * 11 - sg, 0 - sg, 0), (9 * w + sg, 0 - sg, 0)]),
        (0, [(3 * w + sg, 4 * w + sg, 0), (5 * w - sg, 4 * w + sg, 0),
             (5 * w - sg, 6 * w - sg, 0), (3 * w + sg, 6 * w - sg, 0)]),
        (0, [(6 * w + sg, 4 * w + sg, 0), (8 * w - sg, 4 * w + sg, 0),
             (8 * w - sg, 6 * w - sg, 0), (6 * w + sg, 6 * w - sg, 0)]),
        (0, [(3 * w + sg, -5 * w + sg, 0), (5 * w - sg, -5 * w + sg, 0),
             (5 * w - sg, -3 * w - sg, 0), (3 * w + sg, -3 * w - sg, 0)]),
        (0, [(6 * w + sg, -5 * w + sg, 0), (8 * w - sg, -5 * w + sg, 0),
             (8 * w - sg, -3 * w - sg, 0), (6 * w + sg, -3 * w - sg, 0)]),

        # pointed
        (0, [(0 + sg, 3 * w, 0), (2 * w - sg, 3 * w, 0),
             (2 * w - sg, 4 * w, 0), (w + sg, 4 * w, 0)]),
        #left
        (0, [(w + sg, 4 * w, 0), (2 * w - sg, 4 * w, 0),
             (2 * w - sg, 5 * w - sg * 2, 0)]),
        (0, [(9 * w + sg, 3 * w, 0), (11 * w - sg, 3 * w, 0),
             (10 * w - sg, 4 * w, 0), (9 * w + sg, 4 * w, 0)]),
        #top
        (0, [(9 * w + sg, 4 * w, 0), (10 * w - sg, 4 * w, 0),
             (9 * w + sg, 5 * w - sg * 2, 0)]),
        (0, [(0 + sg, -2 * w, 0), (w + sg, -3 * w, 0), (2 * w - sg, -3 * w, 0),
             (2 * w - sg, -2 * w, 0)]),
        #bottom
        (0, [(1 * w + sg, -3 * w, 0), (2 * w - sg, -4 * w + sg + sg, 0),
             (2 * w - sg, -3 * w, 0)]),
        (0, [(9 * w + sg, -3 * w, 0), (10 * w - sg, -3 * w, 0),
             (11 * w - sg, -2 * w, 0), (9 * w + sg, -2 * w, 0)]),
        #right
        (0, [(9 * w + sg, -3 * w, 0), (9 * w + sg, -4 * w + sg * 2, 0),
             (10 * w - sg, -3 * w, 0)]),

        # long pointed
        (90, [(2 * w, 0 - sg, 0), (2 * w, -4 * w + sg, 0),
              (3 * w, -5 * w + sg, 0), (3 * w, 0 - sg, 0)]),
        (90, [(8 * w, 0 - sg, 0), (8 * w, -5 * w + sg, 0),
              (9 * w, -4 * w + sg, 0), (9 * w, 0 - sg, 0)]),
        (90, [(2 * w, w + sg, 0), (3 * w, w + sg, 0), (3 * w, 6 * w - sg, 0),
              (2 * w, 5 * w - sg, 0)]),
        (90, [(8 * w, w + sg, 0), (9 * w, w + sg, 0), (9 * w, 5 * w - sg, 0),
              (8 * w, 6 * w - sg, 0)]),
        # corner planks
        (90, [(0, -2 * w + sg, 0), (0, 3 * w - sg, 0), (-1 * w, 2 * w - sg, 0),
              (-1 * w, -1 * w + sg, 0)]),
        (90, [(11 * w, -2 * w + sg, 0), (12 * w, -1 * w + sg, 0),
              (12 * w, 2 * w - sg, 0), (11 * w, 3 * w - sg, 0)]),
        (0, [(3 * w + sg, -5 * w, 0), (4 * w + sg, -6 * w, 0),
             (7 * w - sg, -6 * w, 0), (8 * w - sg, -5 * w, 0)]),
        (0, [(3 * w + sg, 6 * w, 0), (8 * w - sg, 6 * w, 0),
             (7 * w - sg, 7 * w, 0), (4 * w + sg, 7 * w, 0)]),
        # corner triangles
        (90, [(-w - s2, -w + s2 * 2, 0), (-w - s2, 2 * w - s2 * 2, 0),
              (-2.5 * w + s2, 0.5 * w, 0)]),
        (90, [(12 * w + s2, 2 * w - s2 * 2, 0), (12 * w + s2, -w + s2 * 2, 0),
              (13.5 * w - s2, 0.5 * w, 0)]),
        (0, [(4 * w + s2 * 2, 7 * w + s2, 0), (7 * w - s2 * 2, 7 * w + s2, 0),
             (5.5 * w, 8.5 * w - s2, 0)]),
        (0, [(4 * w + s2 * 2, -6 * w - s2, 0), (5.5 * w, -7.5 * w + s2, 0),
             (7 * w - s2 * 2, -6 * w - s2, 0)]),

        # border planks
        # bottom
        (45, [(-2.5 * w - q + q + dd + lg, 0.5 * w + q - q - dd - lg, 0),
              (-2.5 * w - 2 * q + q + dd + lg + lg, 0.5 * w - q - dd + lg - lg,
               0), (5.5 * w - q + lg - lg, -7.5 * w - q + lg + lg, 0),
              (5.5 * w - lg, -7.5 * w + lg, 0)]),
        # right
        (135, [(5.5 * w - q + lg, -7.5 * w - q + lg, 0),
               (5.5 * w + lg - lg, -7.5 * w - 2 * q + lg + lg, 0),
               (13.5 * w + 2 * q + dd - lg - lg, 0.5 * w + dd - lg + lg, 0),
               (13.5 * w + q + dd - lg, 0.5 * w + q + dd - lg, 0)]),
        #top
        (45, [(13.5 * w - dd - lg, 0.5 * w + dd + lg, 0),
              (13.5 * w + q - dd - lg - lg, 0.5 * w + q + dd - lg + lg, 0),
              (5.5 * w + q - lg + lg, 8.5 * w + q - lg - lg, 0),
              (5.5 * w + lg, 8.5 * w - lg, 0)]),
        #left
        (135, [(-2.5 * w - q - dd + lg, 0.5 * w - q - dd + lg, 0),
               (5.5 * w + q - lg, 8.5 * w + q - lg, 0),
               (5.5 * w - lg + lg, 8.5 * w + 2 * q - lg - lg, 0),
               (-2.5 * w - q - q - dd + lg + lg,
                0.5 * w + q - q - dd + lg - lg, 0)]))

    verts = []
    faces = []
    uvs = []
    left = 0
    center = Vector((5.5 * w, 0.5 * w, 0)) * planklength
    delta = Vector((w, -10 * q, 0)) * planklength
    for col in range(cols):
        start = 0
        for row in range(rows):
            origin = Vector((start, left, 0))
            for uvrot, p in planks1:
                ll = len(verts)
                rot = Euler(
                    (randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                     randrotz * randuni(-1, 1)), 'XYZ')
                # randomly rotate the plank a little bit around its own center
                pverts = [rotate(Vector(v) * planklength, rot) for v in p]
                pverts = [
                    origin + delta + o +
                    rotatep(v, Euler((0, 0, radians(45)), 'XYZ'), center)
                    for v in pverts
                ]

                verts.extend(pverts)
                midpoint = vcenter(pverts)
                if uvrot > 0:
                    print(uvrot)
                    print([v - midpoint for v in pverts])
                    print([
                        rotatep(v, Euler(
                            (0, 0, radians(uvrot)), 'XYZ'), midpoint) -
                        midpoint for v in pverts
                    ])
                    print()
                uvs.append([
                    rotatep(v, Euler((0, 0, radians(uvrot)), 'XYZ'), midpoint)
                    for v in pverts
                ])
                faces.append((ll, ll + 3, ll + 2,
                              ll + 1) if len(pverts) == 4 else (ll, ll + 2,
                                                                ll + 1))

            start += planklength
        left += planklength

    fuvs = [v for p in uvs for v in p]

    return verts, faces, fuvs
Example #19
0
def square(rows, cols, planklength, n, border, longgap, shortgap, nseed,
           randrotx, randroty, randrotz, originx, originy):
    verts = []
    verts2 = []
    faces = []
    faces2 = []
    uvs = []
    uvs2 = []
    seed(nseed)

    ll = 0
    ll2 = 0
    net_planklength = planklength - 2.0 * border

    plankwidth = net_planklength / n
    longside = (net_planklength - shortgap)
    shortside = (plankwidth - longgap)
    stepv = Vector((0, planklength, 0))
    steph = Vector((planklength, 0, 0))
    nstepv = Vector((0, plankwidth, 0))
    nsteph = Vector((plankwidth, 0, 0))

    pv = [
        Vector((0, 0, 0)),
        Vector((longside, 0, 0)),
        Vector((longside, shortside, 0)),
        Vector((0, shortside, 0))
    ]
    rot = Euler((0, 0, -PI / 2), "XYZ")
    pvm = [rotate(v, rot) + Vector((0, planklength - border, 0)) for v in pv]

    midpointpv = sum(pv, Vector()) / 4.0
    midpointpvm = sum(pvm, Vector()) / 4.0

    offseth = Vector((border, border, 0))
    offsetv = Vector((border, 0, 0))

    bw = border - shortgap
    b1 = [(0, longgap / 2.0, 0), (0, planklength - longgap / 2.0, 0),
          (bw, planklength - longgap / 2.0 - border, 0),
          (bw, longgap / 2.0 + border, 0)]
    b1 = [Vector(v) for v in b1]
    d = Vector((planklength / 2.0, planklength / 2.0, 0))
    rot = Euler((0, 0, -PI / 2), "XYZ")
    b2 = [rotate(v - d, rot) + d for v in b1]
    rot = Euler((0, 0, -PI), "XYZ")
    b3 = [rotate(v - d, rot) + d for v in b1]
    rot = Euler((0, 0, -3 * PI / 2), "XYZ")
    b4 = [rotate(v - d, rot) + d for v in b1]

    o = Vector((-originx, -originy, 0))

    # CLEANUP: duplicate code, suboptimal loop nesting and a lot of repeated calculations
    # note that the uv map we create here is always aligned in the same direction even though planks alternate. This matches the saw direction in real life
    for col in range(cols):
        for row in range(rows):
            # add the regular planks
            for p in range(n):
                rot = Euler(
                    (randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                     randrotz * randuni(-1, 1)), 'XYZ')
                if (col ^ row) % 2 == 1:
                    pverts = [
                        rotate(v - midpointpv, rot) + midpointpv +
                        row * stepv + col * steph + nstepv * p + offseth + o
                        for v in pv
                    ]
                    uverts = [
                        v + row * stepv + col * steph + nstepv * p for v in pv
                    ]
                else:
                    pverts = [
                        rotate(v - midpointpv, rot) + midpointpv +
                        row * stepv + col * steph + nsteph * p + offsetv + o
                        for v in pvm
                    ]
                    uverts = [
                        v + row * stepv + col * steph + nstepv * p for v in pv
                    ]
                verts.extend(deepcopy(pverts))
                uvs.append(deepcopy(uverts))
                faces.append((ll, ll + 1, ll + 2, ll + 3))
                ll = len(verts)
            # add the border planks
            if bw > 0.001:
                for vl in b1, b2, b3, b4:
                    rot = Euler(
                        (randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                         randrotz * randuni(-1, 1)), 'XYZ')
                    midpointvl = sum(vl, Vector()) / 4.0
                    verts2.extend([
                        rotate(v - midpointvl, rot) + midpointvl +
                        row * stepv + col * steph + o for v in vl
                    ])
                    uvs2.append(
                        deepcopy([v + row * stepv + col * steph for v in b1])
                    )  # again, always the unrotated uvs to match the saw direction
                    faces2.append((ll2, ll2 + 3, ll2 + 2, ll2 + 1))
                    ll2 = len(verts2)

    for i in range(len(uvs)):
        pp1 = randrange(len(uvs))
        pp2 = randrange(len(uvs))
        swap(uvs, pp1, pp2)
    for i in range(len(uvs2)):
        pp1 = randrange(len(uvs2))
        pp2 = randrange(len(uvs2))
        swap(uvs2, pp1, pp2)

    fuvs = [v for p in uvs for v in p]
    fuvs2 = [v for p in uvs2 for v in p]

    return verts + verts2, faces + [
        (f[0] + ll, f[1] + ll, f[2] + ll, f[3] + ll) for f in faces2
    ], fuvs + fuvs2
Example #20
0
def updateMesh(self, context):
    o = context.object

    verts, faces, shortedges, longedges = planks(o.nplanks, o.length,
                                                 o.planklength, o.planklengthvar,
                                                 o.plankwidth, o.plankwidthvar,
                                                 o.longgap, o.shortgap,
                                                 o.offset, o.randomoffset,
                                                 o.randomseed,
                                                 o.randrotx, o.randroty, o.randrotz)

    # create mesh &link object to scene
    emesh = o.data

    mesh = bpy.data.meshes.new(name='Planks')
    mesh.from_pydata(verts, [], faces)

    mesh.update(calc_edges=True)

    for i in bpy.data.objects:
        if i.data == emesh:
            i.data = mesh

    name = emesh.name
    emesh.user_clear()
    bpy.data.meshes.remove(emesh)
    mesh.name = name
    if bpy.context.mode != 'EDIT_MESH':
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.editmode_toggle()

    bpy.ops.object.shade_smooth()

    # add uv-coords and per face random vertex colors
    mesh.uv_textures.new()
    uv_layer = mesh.uv_layers.active.data
    vertex_colors = mesh.vertex_colors.new().data
    for poly in mesh.polygons:
        offset = Vector((rand(), rand(), 0)) if o.randomuv else Vector((0, 0, 0))
        color = [rand(), rand(), rand()]
        for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
            coords = mesh.vertices[mesh.loops[loop_index].vertex_index].co
            uv_layer[loop_index].uv = (coords + offset).xy
            vertex_colors[loop_index].color = color

    # subdivide mesh and warp it
    warped = o.hollowlong > 0 or o.hollowshort > 0 or o.twist > 0
    if warped:
        bm = bmesh.new()
        bm.from_mesh(mesh)

        # calculate hollowness for each face
        dshortmap = {}
        dlongmap = {}
        for face in bm.faces:
            dshort = o.hollowshort * rand()
            dlong = o.hollowlong * rand()
            for v in face.verts:
                dshortmap[v.index] = dshort
                dlongmap[v.index] = dlong

        bm.to_mesh(mesh)
        bm.free()

        # at this point all new geometry is selected and subdivide works in all selection modes
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.subdivide()  # bmesh subdivide doesn't work for me ...
        bpy.ops.object.editmode_toggle()

        bm = bmesh.new()
        bm.from_mesh(mesh)

        for v in bm.verts:
            if o.twist and len(v.link_edges) == 4:  # vertex in the middle of the plank
                dtwist = o.twist * randuni(-1, 1)
                for e in v.link_edges:
                    v2 = e.other_vert(v)  # the vertices on the side of the plank
                    if shortside(v2):
                        for e2 in v2.link_edges:
                            v3 = e2.other_vert(v2)
                            if len(v3.link_edges) == 2:
                                v3.co.z += dtwist
                                dtwist = -dtwist  # one corner up, the other corner down
            elif len(v.link_edges) == 3:  # vertex in the middle of a side of the plank
                for e in v.link_edges:
                    v2 = e.other_vert(v)
                    if len(v2.link_edges) == 2:  # hollowness values are stored with the all original corner vertices
                        dshort = dshortmap[v2.index]
                        dlong = dlongmap[v2.index]
                        break
                if shortside(v):
                    v.co.z -= dlong
                else:
                    v.co.z -= dshort

        creases = bm.edges.layers.crease.new()
        for edge in bm.edges:
            edge[creases] = 1
            for vert in edge.verts:
                if len(vert.link_edges) == 4:
                    edge[creases] = 0
                    break

        bm.to_mesh(mesh)
        bm.free()

    if self.modify:
        mods = o.modifiers
        if len(mods) == 0:
            bpy.ops.object.modifier_add(type='SOLIDIFY')
            bpy.ops.object.modifier_add(type='BEVEL')
            bpy.ops.object.modifier_add(type='EDGE_SPLIT')
            mods = o.modifiers
            mods[0].show_expanded = False
            mods[1].show_expanded = False
            mods[2].show_expanded = False
            mods[0].thickness = self.thickness
            mods[1].width = self.bevel
        if warped and not ('SUBSURF' in [m.type for m in mods]):
            bpy.ops.object.modifier_add(type='SUBSURF')
            mods[-1].show_expanded = False
            mods[-1].levels = 2
        if not warped and ('SUBSURF' in [m.type for m in mods]):
            bpy.ops.object.modifier_remove(modifier='Subsurf')
    else:
        n = len(o.modifiers)
        while n > 0:
            n -= 1
            bpy.ops.object.modifier_remove(modifier=o.modifiers[-1].name)
Example #21
0
def parquet(switch, nbrboards, height, randheight, width, randwith, gapx, lengthboard, gapy, shifty, nbrshift, tilt, herringbone, randoshifty, lengthparquet, trans, gaptrans, randgaptrans, glue, borders, lengthtrans, locktrans, nbrtrans):

    x = 0
    y = 0
    verts = []
    faces = []
    listinter = []
    start = 0
    left = 0
    bool_translatey = True                                                # shifty = 0                                                             
    end = lengthboard                                                                                                                              
    interleft = 0                                                                                                                                  
    interright = 0                                                                                                                                 
    if locktrans: 
        shifty = 0                                                        # No shift with unlock !
        glue = False
        borders = False
    if shifty: locktrans = False                                          # Can't have the boards shifted and the tranversal unlocked              
    if herringbone : switch = True                                        # Constrain the computation of the length using the boards if herringbone
    if randoshifty > 0:                                                   # If randomness in the shift of the boards
        randomshift = shifty * (1-randoshifty)                            # Compute the amount of randomness in the shift
    else:
        randomshift = shifty                                              # No randomness
        
    if shifty > 0: 
        tilt = 0
        herringbone = False

    if gapy == 0:                                                         # If no gap on the Y axis : the transversal is not possible
        trans = False

    if herringbone:                                                       # Constraints if herringbone is choose :
        shifty = 0                                                        # - no shift
        tilt = math.radians(45)                                           # - Tilt = 45°
        randwith = 0                                                      # - No random on the width
        trans = False                                                     # - No transversal
    
    # Compute the new length and width of the board if tilted
    hyp, translatex, translatey = calculangle(left, end, tilt, start, width, end)
    
    randwidth = hyp + (randwith * randuni(0, hyp))                        # Randomness in the width
    right = randwidth                                                     # Right = width of the board
    end = translatey - (translatey * randuni(randomshift, shifty))        # Randomness in the length

    if herringbone or switch:                                             # Compute the length of the floor based on the length of the boards
        lengthparquet = ((round(lengthparquet / (translatey + gapy))) * (translatey + gapy)) - gapy
    noglue = gapx           
    #------------------------------------------------------------
    # Loop for the boards on the X axis
    #------------------------------------------------------------
    while x < nbrboards:                                                  # X axis 
        x += 1   

        if glue and (x % nbrshift != 0): gapx = gaptrans
        else: gapx = noglue


        if (x % nbrshift != 0): bool_translatey = not bool_translatey     # Invert the shift 
        if end > lengthparquet :                                          # Cut the last board if it's > than the floor
            end = lengthparquet

        # Creation of the first board
        nbvert = len(verts)
        verts.extend(board(start, left, right, end, tilt, translatex, hyp, herringbone, gapy, height, randheight))
        faces.append((nbvert,nbvert+1, nbvert+2, nbvert+3))
        
        # Start a new column (Y)
        start2 = end + gapy
        end2 = start2 
        #------------------------------------------------------------
        # TRANSVERSAL
        #------------------------------------------------------------
        # listinter = List of the length (left) of the interval || x = nbr of the actual column || nbrshift = nbr of columns to shift || nbrboards = Total nbr of column 
        # The modulo (%) is here to determined if the actual interval as to be shift        
        listinter.append(left)                                            # Keep the length of the actual interval
        endfloor = 0
        if x == nbrboards: endfloor = right
        if trans and ((x % nbrshift == 0) or ((x % nbrshift != 0) and (x == nbrboards))) and (end < lengthparquet) and not locktrans:
            if start2 > lengthparquet: start2 = lengthparquet             # Cut the board if it's > than the floor
            transversal(listinter[0], right, end, tilt, translatex, gapy, noglue, gaptrans, randgaptrans, start2, nbrtrans, verts, faces, locktrans, lengthtrans, height, randheight, borders, endfloor, shifty)
        elif trans and (x == nbrboards) and locktrans:
            if start2 > lengthparquet: start2 = lengthparquet             # Cut the board if it's > than the floor
            transversal(listinter[0], right, end, tilt, translatex, gapy, noglue, gaptrans, randgaptrans, start2, nbrtrans, verts, faces, locktrans, lengthtrans, height, randheight, borders, endfloor, shifty)
            
        #------------------------------------------------------------
        # BORDERS
        #------------------------------------------------------------
        # Create the borders in the X gap if boards are glued
        if borders and glue and (x % nbrshift == 0) and translatex == 0 and (x != nbrboards) and (shifty == 0) and (gaptrans*2 < gapx): 
            nbvert = len(verts) 
            verts.extend(border(right+gaptrans, right+noglue-gaptrans, start, gapy, end, height, randheight, gaptrans, randgaptrans, lengthparquet, start2 + translatey))
            faces.append((nbvert, nbvert+1, nbvert+2, nbvert+3, nbvert+4, nbvert+5))

        #------------------------------------------------------------
        # Loop for the boards on the Y axis
        #------------------------------------------------------------
        while lengthparquet > end2 :                                      # Y axis
            end2 = start2 + translatey                                    # New column
            if end2 > lengthparquet :                                     # Cut the board if it's > than the floor
                end2 = lengthparquet

            if tilt < 0:                                                  # This part is used to inversed the tilt of the boards 
                tilt = tilt * (-1)                                         
            else:
                tilt = -tilt

            # Creation of the board
            nbvert = len(verts)
            verts.extend(board(start2, left, right, end2, tilt, translatex, hyp, herringbone, gapy, height, randheight))
            faces.append((nbvert,nbvert+1, nbvert+2, nbvert+3))

            #------------------------------------------------------------
            # BORDERS
            #------------------------------------------------------------
            # Create the borders in the X gap if boards are glued
            if borders and glue and (x % nbrshift == 0) and translatex == 0 and (x != nbrboards) and (shifty == 0) and (gaptrans*2 < gapx):  
                nbvert = len(verts) 
                verts.extend(border(right+gaptrans, right+noglue-gaptrans, start2, gapy, end2, height, randheight, gaptrans, randgaptrans, lengthparquet, start2 + translatey))
                faces.append((nbvert, nbvert+1, nbvert+2, nbvert+3, nbvert+4, nbvert+5))

            # New column 
            start2 += translatey + gapy
            
            #------------------------------------------------------------
            # TRANSVERSAL
            #------------------------------------------------------------
            # x = nbr of the actual column || nbrshift = nbr of columns to shift || nbrboards = Total nbr of column 
            # The modulo (%) is  here to determined if the actual interval as to be shift  
            endfloor = 0
            if x == nbrboards: endfloor = right            
            if trans and ((x % nbrshift == 0) or ((x % nbrshift != 0) and (x == nbrboards))) and (end2 < lengthparquet) and not locktrans:
                if start2 > lengthparquet: start2 = lengthparquet         # Cut the board if it's > than the floor
                transversal(listinter[0], right, end2, tilt, translatex, gapy, noglue, gaptrans, randgaptrans, start2, nbrtrans, verts, faces, locktrans, lengthtrans, height, randheight, borders, endfloor, shifty)

            elif trans and locktrans and (x == nbrboards) and (end2 < lengthparquet) :
                if start2 > lengthparquet: start2 = lengthparquet         # Cut the board if it's > than the floor
                transversal(listinter[0], right, end2, tilt, translatex, gapy, noglue, gaptrans, randgaptrans, start2, nbrtrans, verts, faces, locktrans, lengthtrans, height, randheight, borders, endfloor, shifty)

            end2 = start2                                                 # End of the loop on Y axis
        #------------------------------------------------------------#
                                                         
        #------------------------------------------------------------
        # Increment / initialize                                      
        #------------------------------------------------------------ 
        if (x % nbrshift == 0) and not locktrans: listinter = []          # Initialize the list of interval if the nbr of boards to shift is reaches        
        if not herringbone:                                               # If not herringbone 
            left += gapx                                                  #  Add the value of gapx to the left side of the boards 
            right += gapx                                                 #  Add the value of gapx to the right side of the boards
        else:                                                             # If herringbone, we don't use the gapx anymore in the panel  
            right += gapy * 2                                             #  used only the gapy                              
            left += gapy * 2                                              #  ""     ""      ""                               
        left += randwidth                                                 # Add randomness on the left side of the boards  
        randwidth = hyp + (randwith * randuni(0, hyp))                    # Compute the new randomness on the width (hyp)
        right += randwidth                                                # Add randomness on the right side of the boards 
        #------------------------------------------------------------#
        
        #------------------------------------------------------------
        # Shift on the Y axis
        #------------------------------------------------------------
        # bool_translatey is turn on and off at each new column to reverse the direction of the shift up or down.
        if (bool_translatey and shifty > 0):                              # If the columns are shifted
            if (x % nbrshift == 0 ):                                      # If the nbr of column to shift is reach 
                end = translatey * randuni(randomshift, shifty)           # Compute and add the randomness to the new end (translatey) shifted 
            bool_translatey = False                                       # Turn on the boolean, so it will be inverted for the next colmun
        else:
            if (x % nbrshift == 0 ):
                end = translatey - (translatey * randuni(randomshift, shifty)) # Compute and add the randomness to the new end (translatey) shifted
            bool_translatey = True                                        # Turn on the boolean, so it will be inverted for the next colmun
        #------------------------------------------------------------#

        #------------------------------------------------------------
        # Herringbone only
        #------------------------------------------------------------                
        # Invert the value of the tilted parameter
        if tilt < 0:                                                      # The tilted value is inverted at each column
           tilt = tilt * (-1)                                             # so the boards will be reverse
        #------------------------------------------------------------#

    #------------------------------------------------------------         # End of the loop on X axis
    return verts, faces
def updateMesh(self, context):
	o = context.object

	verts, faces, shortedges, longedges = planks(o.nplanks, o.length,
												o.planklength, o.planklengthvar,
												o.plankwidth, o.plankwidthvar,
												o.longgap, o.shortgap,
												o.offset, o.randomoffset,
												o.randomseed,
												o.randrotx, o.randroty, o.randrotz)

	# create mesh &link object to scene
	emesh = o.data

	mesh = bpy.data.meshes.new(name='Planks')
	mesh.from_pydata(verts, [], faces)

	mesh.update(calc_edges=True)

	for i in bpy.data.objects:
		if i.data == emesh:
			i.data = mesh

	name = emesh.name
	emesh.user_clear()
	bpy.data.meshes.remove(emesh)
	mesh.name = name
	if bpy.context.mode != 'EDIT_MESH':
		bpy.ops.object.editmode_toggle()
		bpy.ops.object.editmode_toggle()

	bpy.ops.object.shade_smooth()

	# add uv-coords and per face random vertex colors
	mesh.uv_textures.new()
	uv_layer = mesh.uv_layers.active.data
	vertex_colors = mesh.vertex_colors.new().data
	for poly in mesh.polygons:
		offset = Vector((rand(), rand(), 0)) if o.randomuv else Vector((0, 0, 0))
		color = [rand(), rand(), rand()]
		for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
			coords = mesh.vertices[mesh.loops[loop_index].vertex_index].co
			uv_layer[loop_index].uv = (coords + offset).xy
			vertex_colors[loop_index].color = color

	# subdivide mesh and warp it
	warped = o.hollowlong > 0 or o.hollowshort > 0 or o.twist > 0
	if warped:
		bm = bmesh.new()
		bm.from_mesh(mesh)

		# calculate hollowness for each face
		dshortmap = {}
		dlongmap = {}
		for face in bm.faces:
			dshort = o.hollowshort * rand()
			dlong = o.hollowlong * rand()
			for v in face.verts:
				dshortmap[v.index] = dshort
				dlongmap[v.index] = dlong

		bm.to_mesh(mesh)
		bm.free()

		# at this point all new geometry is selected and subdivide works in all selection modes
		bpy.ops.object.editmode_toggle()
		bpy.ops.mesh.subdivide()  # bmesh subdivide doesn't work for me ...
		bpy.ops.object.editmode_toggle()

		bm = bmesh.new()
		bm.from_mesh(mesh)

		for v in bm.verts:
			if o.twist and len(v.link_edges) == 4:  # vertex in the middle of the plank
				dtwist = o.twist * randuni(-1, 1)
				for e in v.link_edges:
					v2 = e.other_vert(v)  # the vertices on the side of the plank
					if shortside(v2):
						for e2 in v2.link_edges:
							v3 = e2.other_vert(v2)
							if len(v3.link_edges) == 2:
								v3.co.z += dtwist
								dtwist = -dtwist  # one corner up, the other corner down
			elif len(v.link_edges) == 3:  # vertex in the middle of a side of the plank
				for e in v.link_edges:
					v2 = e.other_vert(v)
					if len(v2.link_edges) == 2:  # hollowness values are stored with the all original corner vertices
						dshort = dshortmap[v2.index]
						dlong = dlongmap[v2.index]
						break
				if shortside(v):
					v.co.z -= dlong
				else:
					v.co.z -= dshort

		creases = bm.edges.layers.crease.new()
		for edge in bm.edges:
			edge[creases] = 1
			for vert in edge.verts:
				if len(vert.link_edges) == 4:
					edge[creases] = 0
					break

		bm.to_mesh(mesh)
		bm.free()

	
	# remove all modifiers to make sure the boolean will be last & only modifier
	n = len(o.modifiers)
	while n > 0:
		n -= 1
		bpy.ops.object.modifier_remove(modifier=o.modifiers[-1].name)
	
	# add thickness
	# simply extruding would be simpler and cheaper but we get a warning convertViewVec: called in an invalid context
	# overriding the context of the operator to explicitly set the area crashes Blender, which is a known bug
	# http://blenderartists.org/forum/showthread.php?338387-addon-related-to-System-console-tells-me-quot-convertViewVec-called-in-an-invalid-contex
	# so we opt for the add-solidify-modifier-and-apply approach even though it's just a warning.
	#bpy.ops.object.editmode_toggle()
	#bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={'value':(0,0,self.thickness)})
	#bpy.ops.mesh.select_all(action='SELECT')
	#bpy.ops.mesh.normals_make_consistent(inside=False)
	#bpy.ops.object.editmode_toggle()
	bpy.ops.object.modifier_add(type='SOLIDIFY')
	o.modifiers[-1].thickness = self.thickness
	bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")
	bpy.ops.object.editmode_toggle()
	bpy.ops.mesh.select_all(action='SELECT')
	bpy.ops.mesh.normals_make_consistent(inside=False)
	bpy.ops.object.editmode_toggle()
	
	# intersect with a floorplan
	if self.usefloorplan and self.floorplan != ' None ':
		# make the floorplan the only active an selected object
		bpy.ops.object.select_all(action='DESELECT')
		context.scene.objects.active = bpy.data.objects[self.floorplan]
		bpy.data.objects[self.floorplan].select = True

		# duplicate the selected geometry into a separate object
		me = context.scene.objects.active.data
		selected_faces = [p.index for p in me.polygons if p.select]
		bpy.ops.object.editmode_toggle()
		bpy.ops.mesh.duplicate()
		bpy.ops.mesh.separate()
		bpy.ops.object.editmode_toggle()
		me = context.scene.objects.active.data
		for i in selected_faces:
			me.polygons[i].select = True

		# now there will be two selected objects
		# the one with the new name will be the copy
		for ob in context.selected_objects:
			if ob.name != self.floorplan:
				fpob = ob
		print('floorplan copy',fpob.name)
		
		# make that copy active and selected
		for ob in context.selected_objects:
			ob.select = False
		fpob.select = True
		context.scene.objects.active = fpob
		
		if True:
			# add thickness
			# let normals of select faces point in same direction
			bpy.ops.object.editmode_toggle()
			bpy.ops.mesh.select_all(action='SELECT')
			bpy.ops.mesh.normals_make_consistent(inside=False)
			bpy.ops.object.editmode_toggle()
			# add solidify modifier
			# NOTE: for some reason bpy.ops.object.modifier_add doesn't work here
			# even though fpob at this point is verifyable the active and selected object ...
			mod = fpob.modifiers.new(name='Solidify', type='SOLIDIFY')
			mod.offset = 1.0 # in the direction of the normals
			mod.thickness = 2000 # very thick
			bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")
			bpy.ops.object.editmode_toggle()
			bpy.ops.mesh.select_all(action='SELECT')
			bpy.ops.mesh.normals_make_consistent(inside=False)
			bpy.ops.object.editmode_toggle()
			fpob.location -= Vector((0,0,1000)) # actually this should be in the negative direction of the normals not just plain downward...
			
			# make the floorboards active and selected
			for ob in context.selected_objects:
				ob.select = False
			context.scene.objects.active = o
			o.select = True
			
			# add-and-apply a boolean modifier to get the intersection with the floorplan copy
			bpy.ops.object.modifier_add(type='BOOLEAN') # default is intersect
			o.modifiers[-1].object = fpob
			bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")
			# delete the copy
			bpy.ops.object.select_all(action='DESELECT')
			context.scene.objects.active = fpob
			fpob.select = True
			bpy.ops.object.delete()
			# make the floorboards active and selected
			context.scene.objects.active = o
			o.select = True
		
	if self.modify:
		mods = o.modifiers
		if len(mods) == 0: # always true
			bpy.ops.object.modifier_add(type='BEVEL')
			bpy.ops.object.modifier_add(type='EDGE_SPLIT')
			mods = o.modifiers
			mods[0].show_expanded = False
			mods[1].show_expanded = False
			mods[0].width = self.bevel
		if warped and not ('SUBSURF' in [m.type for m in mods]):
			bpy.ops.object.modifier_add(type='SUBSURF')
			mods[-1].show_expanded = False
			mods[-1].levels = 2
		if not warped and ('SUBSURF' in [m.type for m in mods]):
			bpy.ops.object.modifier_remove(modifier='Subsurf')
Example #23
0
def parquet(switch, nbrboards, height, randheight, width, randwith, gapx,
            lengthboard, gapy, shifty, nbrshift, tilt, herringbone,
            randoshifty, lengthparquet, trans, gaptrans, randgaptrans, glue,
            borders, lengthtrans, locktrans, nbrtrans):

    x = 0
    y = 0
    verts = []
    faces = []
    listinter = []
    start = 0
    left = 0
    bool_translatey = True  # shifty = 0
    end = lengthboard
    interleft = 0
    interright = 0
    if locktrans:
        shifty = 0  # No shift with unlock !
        glue = False
        borders = False
    if shifty:
        locktrans = False  # Can't have the boards shifted and the tranversal unlocked
    if herringbone:
        switch = True  # Constrain the computation of the length using the boards if herringbone
    if randoshifty > 0:  # If randomness in the shift of the boards
        randomshift = shifty * (
            1 - randoshifty)  # Compute the amount of randomness in the shift
    else:
        randomshift = shifty  # No randomness

    if shifty > 0:
        tilt = 0
        herringbone = False

    if gapy == 0:  # If no gap on the Y axis : the transversal is not possible
        trans = False

    if herringbone:  # Constraints if herringbone is choose :
        shifty = 0  # - no shift
        tilt = math.radians(45)  # - Tilt = 45°
        randwith = 0  # - No random on the width
        trans = False  # - No transversal

    # Compute the new length and width of the board if tilted
    hyp, translatex, translatey = calculangle(left, end, tilt, start, width,
                                              end)

    randwidth = hyp + (randwith * randuni(0, hyp))  # Randomness in the width
    right = randwidth  # Right = width of the board
    end = translatey - (translatey * randuni(randomshift, shifty)
                        )  # Randomness in the length

    if herringbone or switch:  # Compute the length of the floor based on the length of the boards
        lengthparquet = ((round(lengthparquet / (translatey + gapy))) *
                         (translatey + gapy)) - gapy
    noglue = gapx
    #------------------------------------------------------------
    # Loop for the boards on the X axis
    #------------------------------------------------------------
    while x < nbrboards:  # X axis
        x += 1

        if glue and (x % nbrshift != 0): gapx = gaptrans
        else: gapx = noglue

        if (x % nbrshift != 0):
            bool_translatey = not bool_translatey  # Invert the shift
        if end > lengthparquet:  # Cut the last board if it's > than the floor
            end = lengthparquet

        # Creation of the first board
        nbvert = len(verts)
        verts.extend(
            board(start, left, right, end, tilt, translatex, hyp, herringbone,
                  gapy, height, randheight))
        faces.append((nbvert, nbvert + 1, nbvert + 2, nbvert + 3))

        # Start a new column (Y)
        start2 = end + gapy
        end2 = start2
        #------------------------------------------------------------
        # TRANSVERSAL
        #------------------------------------------------------------
        # listinter = List of the length (left) of the interval || x = nbr of the actual column || nbrshift = nbr of columns to shift || nbrboards = Total nbr of column
        # The modulo (%) is here to determined if the actual interval as to be shift
        listinter.append(left)  # Keep the length of the actual interval
        endfloor = 0
        if x == nbrboards: endfloor = right
        if trans and ((x % nbrshift == 0) or (
            (x % nbrshift != 0) and
            (x == nbrboards))) and (end < lengthparquet) and not locktrans:
            if start2 > lengthparquet:
                start2 = lengthparquet  # Cut the board if it's > than the floor
            transversal(listinter[0], right, end, tilt, translatex, gapy,
                        noglue, gaptrans, randgaptrans, start2, nbrtrans,
                        verts, faces, locktrans, lengthtrans, height,
                        randheight, borders, endfloor, shifty)
        elif trans and (x == nbrboards) and locktrans:
            if start2 > lengthparquet:
                start2 = lengthparquet  # Cut the board if it's > than the floor
            transversal(listinter[0], right, end, tilt, translatex, gapy,
                        noglue, gaptrans, randgaptrans, start2, nbrtrans,
                        verts, faces, locktrans, lengthtrans, height,
                        randheight, borders, endfloor, shifty)

        #------------------------------------------------------------
        # BORDERS
        #------------------------------------------------------------
        # Create the borders in the X gap if boards are glued
        if borders and glue and (x % nbrshift == 0) and translatex == 0 and (
                x != nbrboards) and (shifty == 0) and (gaptrans * 2 < gapx):
            nbvert = len(verts)
            verts.extend(
                border(right + gaptrans, right + noglue - gaptrans, start,
                       gapy, end, height, randheight, gaptrans, randgaptrans,
                       lengthparquet, start2 + translatey))
            faces.append((nbvert, nbvert + 1, nbvert + 2, nbvert + 3,
                          nbvert + 4, nbvert + 5))

        #------------------------------------------------------------
        # Loop for the boards on the Y axis
        #------------------------------------------------------------
        while lengthparquet > end2:  # Y axis
            end2 = start2 + translatey  # New column
            if end2 > lengthparquet:  # Cut the board if it's > than the floor
                end2 = lengthparquet

            if tilt < 0:  # This part is used to inversed the tilt of the boards
                tilt = tilt * (-1)
            else:
                tilt = -tilt

            # Creation of the board
            nbvert = len(verts)
            verts.extend(
                board(start2, left, right, end2, tilt, translatex, hyp,
                      herringbone, gapy, height, randheight))
            faces.append((nbvert, nbvert + 1, nbvert + 2, nbvert + 3))

            #------------------------------------------------------------
            # BORDERS
            #------------------------------------------------------------
            # Create the borders in the X gap if boards are glued
            if borders and glue and (
                    x % nbrshift == 0) and translatex == 0 and (
                        x != nbrboards) and (shifty
                                             == 0) and (gaptrans * 2 < gapx):
                nbvert = len(verts)
                verts.extend(
                    border(right + gaptrans, right + noglue - gaptrans, start2,
                           gapy, end2, height, randheight, gaptrans,
                           randgaptrans, lengthparquet, start2 + translatey))
                faces.append((nbvert, nbvert + 1, nbvert + 2, nbvert + 3,
                              nbvert + 4, nbvert + 5))

            # New column
            start2 += translatey + gapy

            #------------------------------------------------------------
            # TRANSVERSAL
            #------------------------------------------------------------
            # x = nbr of the actual column || nbrshift = nbr of columns to shift || nbrboards = Total nbr of column
            # The modulo (%) is  here to determined if the actual interval as to be shift
            endfloor = 0
            if x == nbrboards: endfloor = right
            if trans and ((x % nbrshift == 0) or
                          ((x % nbrshift != 0) and (x == nbrboards))) and (
                              end2 < lengthparquet) and not locktrans:
                if start2 > lengthparquet:
                    start2 = lengthparquet  # Cut the board if it's > than the floor
                transversal(listinter[0], right, end2, tilt, translatex, gapy,
                            noglue, gaptrans, randgaptrans, start2, nbrtrans,
                            verts, faces, locktrans, lengthtrans, height,
                            randheight, borders, endfloor, shifty)

            elif trans and locktrans and (x == nbrboards) and (end2 <
                                                               lengthparquet):
                if start2 > lengthparquet:
                    start2 = lengthparquet  # Cut the board if it's > than the floor
                transversal(listinter[0], right, end2, tilt, translatex, gapy,
                            noglue, gaptrans, randgaptrans, start2, nbrtrans,
                            verts, faces, locktrans, lengthtrans, height,
                            randheight, borders, endfloor, shifty)

            end2 = start2  # End of the loop on Y axis
        #------------------------------------------------------------#

        #------------------------------------------------------------
        # Increment / initialize
        #------------------------------------------------------------
        if (x % nbrshift == 0) and not locktrans:
            listinter = [
            ]  # Initialize the list of interval if the nbr of boards to shift is reaches
        if not herringbone:  # If not herringbone
            left += gapx  #  Add the value of gapx to the left side of the boards
            right += gapx  #  Add the value of gapx to the right side of the boards
        else:  # If herringbone, we don't use the gapx anymore in the panel
            right += gapy * 2  #  used only the gapy
            left += gapy * 2  #  ""     ""      ""
        left += randwidth  # Add randomness on the left side of the boards
        randwidth = hyp + (randwith * randuni(0, hyp)
                           )  # Compute the new randomness on the width (hyp)
        right += randwidth  # Add randomness on the right side of the boards
        #------------------------------------------------------------#

        #------------------------------------------------------------
        # Shift on the Y axis
        #------------------------------------------------------------
        # bool_translatey is turn on and off at each new column to reverse the direction of the shift up or down.
        if (bool_translatey and shifty > 0):  # If the columns are shifted
            if (x % nbrshift == 0):  # If the nbr of column to shift is reach
                end = translatey * randuni(
                    randomshift, shifty
                )  # Compute and add the randomness to the new end (translatey) shifted
            bool_translatey = False  # Turn on the boolean, so it will be inverted for the next colmun
        else:
            if (x % nbrshift == 0):
                end = translatey - (
                    translatey * randuni(randomshift, shifty)
                )  # Compute and add the randomness to the new end (translatey) shifted
            bool_translatey = True  # Turn on the boolean, so it will be inverted for the next colmun
        #------------------------------------------------------------#

        #------------------------------------------------------------
        # Herringbone only
        #------------------------------------------------------------
        # Invert the value of the tilted parameter
        if tilt < 0:  # The tilted value is inverted at each column
            tilt = tilt * (-1)  # so the boards will be reverse
        #------------------------------------------------------------#

    #------------------------------------------------------------         # End of the loop on X axis
    return verts, faces
Example #24
0
def updateMesh(self, context):
    o = context.object

    verts, faces, shortedges, longedges = planks(
        o.nplanks, o.length, o.planklength, o.planklengthvar, o.plankwidth,
        o.plankwidthvar, o.longgap, o.shortgap, o.offset, o.randomoffset,
        o.randomseed, o.randrotx, o.randroty, o.randrotz)

    # create mesh &link object to scene
    emesh = o.data

    mesh = bpy.data.meshes.new(name='Planks')
    mesh.from_pydata(verts, [], faces)

    mesh.update(calc_edges=True)

    for i in bpy.data.objects:
        if i.data == emesh:
            i.data = mesh

    name = emesh.name
    emesh.user_clear()
    bpy.data.meshes.remove(emesh)
    mesh.name = name
    if bpy.context.mode != 'EDIT_MESH':
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.editmode_toggle()

    bpy.ops.object.shade_smooth()

    # add uv-coords and per face random vertex colors
    mesh.uv_textures.new()
    uv_layer = mesh.uv_layers.active.data
    vertex_colors = mesh.vertex_colors.new().data
    for poly in mesh.polygons:
        offset = Vector((rand(), rand(), 0)) if o.randomuv else Vector(
            (0, 0, 0))
        color = [rand(), rand(), rand()]
        for loop_index in range(poly.loop_start,
                                poly.loop_start + poly.loop_total):
            coords = mesh.vertices[mesh.loops[loop_index].vertex_index].co
            uv_layer[loop_index].uv = (coords + offset).xy
            vertex_colors[loop_index].color = color

    # subdivide mesh and warp it
    warped = o.hollowlong > 0 or o.hollowshort > 0 or o.twist > 0
    if warped:
        bm = bmesh.new()
        bm.from_mesh(mesh)

        # calculate hollowness for each face
        dshortmap = {}
        dlongmap = {}
        for face in bm.faces:
            dshort = o.hollowshort * rand()
            dlong = o.hollowlong * rand()
            for v in face.verts:
                dshortmap[v.index] = dshort
                dlongmap[v.index] = dlong

        bm.to_mesh(mesh)
        bm.free()

        # at this point all new geometry is selected and subdivide works in all selection modes
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.subdivide()  # bmesh subdivide doesn't work for me ...
        bpy.ops.object.editmode_toggle()

        bm = bmesh.new()
        bm.from_mesh(mesh)

        for v in bm.verts:
            if o.twist and len(
                    v.link_edges) == 4:  # vertex in the middle of the plank
                dtwist = o.twist * randuni(-1, 1)
                for e in v.link_edges:
                    v2 = e.other_vert(
                        v)  # the vertices on the side of the plank
                    if shortside(v2):
                        for e2 in v2.link_edges:
                            v3 = e2.other_vert(v2)
                            if len(v3.link_edges) == 2:
                                v3.co.z += dtwist
                                dtwist = -dtwist  # one corner up, the other corner down
            elif len(v.link_edges
                     ) == 3:  # vertex in the middle of a side of the plank
                for e in v.link_edges:
                    v2 = e.other_vert(v)
                    if len(
                            v2.link_edges
                    ) == 2:  # hollowness values are stored with the all original corner vertices
                        dshort = dshortmap[v2.index]
                        dlong = dlongmap[v2.index]
                        break
                if shortside(v):
                    v.co.z -= dlong
                else:
                    v.co.z -= dshort

        creases = bm.edges.layers.crease.new()
        for edge in bm.edges:
            edge[creases] = 1
            for vert in edge.verts:
                if len(vert.link_edges) == 4:
                    edge[creases] = 0
                    break

        bm.to_mesh(mesh)
        bm.free()

    # remove all modifiers to make sure the boolean will be last & only modifier
    n = len(o.modifiers)
    while n > 0:
        n -= 1
        bpy.ops.object.modifier_remove(modifier=o.modifiers[-1].name)

    # add thickness
    # simply extruding would be simpler and cheaper but we get a warning convertViewVec: called in an invalid context
    # overriding the context of the operator to explicitly set the area crashes Blender, which is a known bug
    # http://blenderartists.org/forum/showthread.php?338387-addon-related-to-System-console-tells-me-quot-convertViewVec-called-in-an-invalid-contex
    # so we opt for the add-solidify-modifier-and-apply approach even though it's just a warning.
    #bpy.ops.object.editmode_toggle()
    #bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={'value':(0,0,self.thickness)})
    #bpy.ops.mesh.select_all(action='SELECT')
    #bpy.ops.mesh.normals_make_consistent(inside=False)
    #bpy.ops.object.editmode_toggle()
    bpy.ops.object.modifier_add(type='SOLIDIFY')
    o.modifiers[-1].thickness = self.thickness
    bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")
    bpy.ops.object.editmode_toggle()
    bpy.ops.mesh.select_all(action='SELECT')
    bpy.ops.mesh.normals_make_consistent(inside=False)
    bpy.ops.object.editmode_toggle()

    # intersect with a floorplan
    if self.usefloorplan and self.floorplan != ' None ':
        # make the floorplan the only active an selected object
        bpy.ops.object.select_all(action='DESELECT')
        context.scene.objects.active = bpy.data.objects[self.floorplan]
        bpy.data.objects[self.floorplan].select = True

        # duplicate the selected geometry into a separate object
        me = context.scene.objects.active.data
        selected_faces = [p.index for p in me.polygons if p.select]
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.duplicate()
        bpy.ops.mesh.separate()
        bpy.ops.object.editmode_toggle()
        me = context.scene.objects.active.data
        for i in selected_faces:
            me.polygons[i].select = True

        # now there will be two selected objects
        # the one with the new name will be the copy
        for ob in context.selected_objects:
            if ob.name != self.floorplan:
                fpob = ob
        print('floorplan copy', fpob.name)

        # make that copy active and selected
        for ob in context.selected_objects:
            ob.select = False
        fpob.select = True
        context.scene.objects.active = fpob

        if True:
            # add thickness
            # let normals of select faces point in same direction
            bpy.ops.object.editmode_toggle()
            bpy.ops.mesh.select_all(action='SELECT')
            bpy.ops.mesh.normals_make_consistent(inside=False)
            bpy.ops.object.editmode_toggle()
            # add solidify modifier
            # NOTE: for some reason bpy.ops.object.modifier_add doesn't work here
            # even though fpob at this point is verifyable the active and selected object ...
            mod = fpob.modifiers.new(name='Solidify', type='SOLIDIFY')
            mod.offset = 1.0  # in the direction of the normals
            mod.thickness = 2000  # very thick
            bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")
            bpy.ops.object.editmode_toggle()
            bpy.ops.mesh.select_all(action='SELECT')
            bpy.ops.mesh.normals_make_consistent(inside=False)
            bpy.ops.object.editmode_toggle()
            fpob.location -= Vector(
                (0, 0, 1000)
            )  # actually this should be in the negative direction of the normals not just plain downward...

            # make the floorboards active and selected
            for ob in context.selected_objects:
                ob.select = False
            context.scene.objects.active = o
            o.select = True

            # add-and-apply a boolean modifier to get the intersection with the floorplan copy
            bpy.ops.object.modifier_add(type='BOOLEAN')  # default is intersect
            o.modifiers[-1].object = fpob
            bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")
            # delete the copy
            bpy.ops.object.select_all(action='DESELECT')
            context.scene.objects.active = fpob
            fpob.select = True
            bpy.ops.object.delete()
            # make the floorboards active and selected
            context.scene.objects.active = o
            o.select = True

    if self.modify:
        mods = o.modifiers
        if len(mods) == 0:  # always true
            bpy.ops.object.modifier_add(type='BEVEL')
            bpy.ops.object.modifier_add(type='EDGE_SPLIT')
            mods = o.modifiers
            mods[0].show_expanded = False
            mods[1].show_expanded = False
            mods[0].width = self.bevel
        if warped and not ('SUBSURF' in [m.type for m in mods]):
            bpy.ops.object.modifier_add(type='SUBSURF')
            mods[-1].show_expanded = False
            mods[-1].levels = 2
        if not warped and ('SUBSURF' in [m.type for m in mods]):
            bpy.ops.object.modifier_remove(modifier='Subsurf')
Example #25
0
def versaille(rows, cols, planklength, plankwidth,longgap=0, shortgap=0, randrotx=0, randroty=0, randrotz=0, originx=0, originy=0, switch=False):

	o = Vector((-originx, -originy, 0)) * planklength

	# (8*w+w/W2)*W2 + w = 8*w*W2+w = (8*W2+1)*w = 1 
	w = 1.0 / (8*W2+2)
	#w1 = 1 - w
	q = w/W2
	#k = w*4*W2-w
	#s = (k - w)/2
	#d = ((s+2*w)/W2)/2
	#S = s/W2
	sg = shortgap
	s2 = sg/W2
	lg = longgap

	dd=-q if switch else 0

	planks1 = (
		# rectangles
		(0,[(0+sg,0,0), (w*5-sg,0,0), (w*5-sg,w,0), (0+sg,w,0)]),
		(0,[(6*w+sg,0,0), (w*11-sg,0,0), (w*11-sg,w,0), (6*w+sg,w,0)]),
		(90,[(5*w,-2*w+sg,0), (w*6,-2*w+sg,0), (w*6,3*w-sg,0), (5*w,3*w-sg,0)]),
		(0,[(3*w+sg,3*w,0), (w*8-sg,3*w,0), (w*8-sg,w*4,0), (3*w+sg,w*4,0)]),
		(0,[(3*w+sg,-3*w,0), (w*8-sg,-3*w,0), (w*8-sg,w*-2,0), (3*w+sg,w*-2,0)]),
		(90,[(5*w,4*w+sg,0),(6*w,4*w+sg,0),(6*w,6*w-sg,0),(5*w,6*w-sg,0)]),
		(90,[(5*w,-3*w-sg,0),(5*w,-5*w+sg,0),(6*w,-5*w+sg,0),(6*w,-3*w-sg,0)]),
		# squares
		(0,[(0+sg,w+sg,0), (w*2-sg,w+sg,0), (w*2-sg,w*3-sg,0), (0+sg,w*3-sg,0)]),
		(0,[(3*w+sg,w+sg,0), (w*5-sg,w+sg,0), (w*5-sg,w*3-sg,0), (3*w+sg,w*3-sg,0)]),
		(0,[(6*w+sg,w+sg,0), (w*8-sg,w+sg,0), (w*8-sg,w*3-sg,0), (6*w+sg,w*3-sg,0)]),
		(0,[(9*w+sg,w+sg,0), (w*11-sg,w+sg,0), (w*11-sg,w*3-sg,0), (9*w+sg,w*3-sg,0)]),
		(0,[(0+sg,-2*w+sg,0), (w*2-sg,-2*w+sg,0), (w*2-sg,0-sg,0), (0+sg,0-sg,0)]),
		(0,[(3*w+sg,-2*w+sg,0), (w*5-sg,-2*w+sg,0), (w*5-sg,0-sg,0), (3*w+sg,0-sg,0)]),
		(0,[(6*w+sg,-2*w+sg,0), (w*8-sg,-2*w+sg,0), (w*8-sg,0-sg,0), (6*w+sg,0-sg,0)]),
		(0,[(9*w+sg,-2*w+sg,0), (w*11-sg,-2*w+sg,0), (w*11-sg,0-sg,0), (9*w+sg,0-sg,0)]),
		(0,[(3*w+sg,4*w+sg,0),(5*w-sg,4*w+sg,0),(5*w-sg,6*w-sg,0),(3*w+sg,6*w-sg,0)]),
		(0,[(6*w+sg,4*w+sg,0),(8*w-sg,4*w+sg,0),(8*w-sg,6*w-sg,0),(6*w+sg,6*w-sg,0)]),
		(0,[(3*w+sg,-5*w+sg,0),(5*w-sg,-5*w+sg,0),(5*w-sg,-3*w-sg,0),(3*w+sg,-3*w-sg,0)]),
		(0,[(6*w+sg,-5*w+sg,0),(8*w-sg,-5*w+sg,0),(8*w-sg,-3*w-sg,0),(6*w+sg,-3*w-sg,0)]),
		
		# pointed
		(0,[(0+sg,3*w,0),(2*w-sg,3*w,0),(2*w-sg,4*w,0),(w+sg,4*w,0)]),
		#left
		(0,[(w+sg,4*w,0),(2*w-sg,4*w,0),(2*w-sg,5*w-sg*2,0)]),
		
		(0,[(9*w+sg,3*w,0),(11*w-sg,3*w,0),(10*w-sg,4*w,0),(9*w+sg,4*w,0)]),
		#top
		(0,[(9*w+sg,4*w,0),(10*w-sg,4*w,0),(9*w+sg,5*w-sg*2,0)]),
		
		(0,[(0+sg,-2*w,0),(w+sg,-3*w,0),(2*w-sg,-3*w,0),(2*w-sg,-2*w,0)]),
		#bottom
		(0,[(1*w+sg,-3*w,0),(2*w-sg,-4*w+sg+sg,0),(2*w-sg,-3*w,0)]),
		
		(0,[(9*w+sg,-3*w,0),(10*w-sg,-3*w,0),(11*w-sg,-2*w,0),(9*w+sg,-2*w,0)]),
		#right
		(0,[(9*w+sg,-3*w,0),(9*w+sg,-4*w+sg*2,0),(10*w-sg,-3*w,0)]),
		
		# long pointed
		(90,[(2*w,0-sg,0),(2*w,-4*w+sg,0),(3*w,-5*w+sg,0),(3*w,0-sg,0)]),
		(90,[(8*w,0-sg,0),(8*w,-5*w+sg,0),(9*w,-4*w+sg,0),(9*w,0-sg,0)]),
		(90,[(2*w,w+sg,0),(3*w,w+sg,0),(3*w,6*w-sg,0),(2*w,5*w-sg,0)]),
		(90,[(8*w,w+sg,0),(9*w,w+sg,0),(9*w,5*w-sg,0),(8*w,6*w-sg,0)]),
		# corner planks
		(90,[(0,-2*w+sg,0),(0,3*w-sg,0),(-1*w,2*w-sg,0),(-1*w,-1*w+sg,0)]),
		(90,[(11*w,-2*w+sg,0),(12*w,-1*w+sg,0),(12*w,2*w-sg,0),(11*w,3*w-sg,0)]),
		(0,[(3*w+sg,-5*w,0),(4*w+sg,-6*w,0),(7*w-sg,-6*w,0),(8*w-sg,-5*w,0)]),
		(0,[(3*w+sg,6*w,0),(8*w-sg,6*w,0),(7*w-sg,7*w,0),(4*w+sg,7*w,0)]),
		# corner triangles
		(90,[(-w-s2,-w+s2*2,0),(-w-s2,2*w-s2*2,0),(-2.5*w+s2,0.5*w,0)]),
		(90,[(12*w+s2,2*w-s2*2,0),(12*w+s2,-w+s2*2,0),(13.5*w-s2,0.5*w,0)]),
		(0,[(4*w+s2*2,7*w+s2,0),(7*w-s2*2,7*w+s2,0),(5.5*w,8.5*w-s2,0)]),
		(0,[(4*w+s2*2,-6*w-s2,0),(5.5*w,-7.5*w+s2,0),(7*w-s2*2,-6*w-s2,0)]),
		
		# border planks
		# bottom
		(45,[(-2.5*w-q+q+dd+lg,0.5*w+q-q-dd-lg,0),(-2.5*w-2*q+q+dd+lg+lg,0.5*w-q-dd+lg-lg,0),(5.5*w-q+lg-lg,-7.5*w-q+lg+lg,0),(5.5*w-lg,-7.5*w+lg,0)]),
		# right
		(135,[(5.5*w-q+lg,-7.5*w-q+lg,0),(5.5*w+lg-lg,-7.5*w-2*q+lg+lg,0),(13.5*w+2*q+dd-lg-lg,0.5*w+dd-lg+lg,0),(13.5*w+q+dd-lg,0.5*w+q+dd-lg,0)]),
		#top
		(45,[(13.5*w-dd-lg,0.5*w+dd+lg,0),(13.5*w+q-dd-lg-lg,0.5*w+q+dd-lg+lg,0),(5.5*w+q-lg+lg,8.5*w+q-lg-lg,0),(5.5*w+lg,8.5*w-lg,0)]),
		#left
		(135,[(-2.5*w-q-dd+lg,0.5*w-q-dd+lg,0),(5.5*w+q-lg,8.5*w+q-lg,0),(5.5*w-lg+lg,8.5*w+2*q-lg-lg,0),(-2.5*w-q-q-dd+lg+lg,0.5*w+q-q-dd+lg-lg,0)])
	)
	
	verts = []
	faces = []
	uvs = []
	left = 0
	center = Vector((5.5*w,0.5*w,0))*planklength
	delta = Vector((w, -10*q, 0)) * planklength
	for col in range(cols):
		start = 0
		for row in range(rows):
			origin = Vector((start, left, 0))
			for uvrot,p in planks1:
				ll = len(verts)
				rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1), randrotz * randuni(-1, 1)), 'XYZ')
				# randomly rotate the plank a little bit around its own center
				pverts = [rotate(Vector(v)*planklength, rot) for v in p]
				pverts = [origin + delta + o + rotatep(v, Euler((0,0,radians(45)),'XYZ'), center) for v in pverts]
				
				verts.extend(pverts)
				midpoint = vcenter(pverts)
				if uvrot > 0:
					print(uvrot)
					print([v - midpoint for v in pverts])
					print([rotatep(v, Euler((0,0,radians(uvrot)),'XYZ'), midpoint) - midpoint for v in pverts])
					print()
				uvs.append([rotatep(v, Euler((0,0,radians(uvrot)),'XYZ'), midpoint) for v in pverts])
				faces.append((ll, ll + 3, ll + 2, ll + 1) if len(pverts)==4 else (ll, ll + 2, ll + 1))


			start += planklength
		left += planklength
	
	fuvs = [v for p in uvs for v in p]
	
	return verts, faces, fuvs
Example #26
0
def planks(n, m, length, lengthvar, width, widthvar, longgap, shortgap, offset,
           randomoffset, nseed, randrotx, randroty, randrotz, originx,
           originy):

    #n=Number of planks, m=Floor Length, length = Planklength

    verts = []
    faces = []
    uvs = []

    seed(nseed)
    widthoffset = 0
    s = 0
    e = offset
    c = offset  # Offset per row
    ws = 0
    p = 0

    while p < n:
        p += 1

        uvs.append([])

        w = width + randuni(0, widthvar)
        we = ws + w
        if randomoffset:
            e = randuni(4 * shortgap,
                        length)  # we don't like negative plank lengths
        while (m - e) > (4 * shortgap):
            ll = len(verts)
            rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                         randrotz * randuni(-1, 1)), 'XYZ')
            pverts = plank(s - originx, e - originx, ws - originy,
                           we - originy, longgap, shortgap, rot)
            verts.extend(pverts)
            uvs[-1].append(deepcopy(pverts))
            faces.append((ll, ll + 3, ll + 2, ll + 1))
            s = e
            e += length + randuni(0, lengthvar)
        ll = len(verts)
        rot = Euler((randrotx * randuni(-1, 1), randroty * randuni(-1, 1),
                     randrotz * randuni(-1, 1)), 'XYZ')
        pverts = plank(s - originx, m - originx, ws - originy, we - originy,
                       longgap, shortgap, rot)
        verts.extend(pverts)
        uvs[-1].append(deepcopy(pverts))
        faces.append((ll, ll + 3, ll + 2, ll + 1))
        s = 0
        #e = e - m
        if c <= (length):
            c = c + offset
        if c > (length):
            c = c - length
        e = c
        ws = we
        # randomly swap uvs of planks. Note: we only swap within one set of planks because different sets can have different widths.
        nplanks = len(uvs[-1])
        if nplanks < 2: continue
        for pp in range(nplanks // 2):  # // to make sure it stays an int
            i = randrange(nplanks - 1)
            swapx(uvs[-1], i)

    fuvs = [uv for col in uvs for plank in col for uv in plank]
    return verts, faces, fuvs
Example #27
0
def updateMesh(self, context):
	o = context.object

	material_list = getMaterialList(o)
		
	if o.pattern == 'Regular':
		nplanks = (o.width + o.originy) / o.plankwidth
		verts, faces, uvs = planks(nplanks, o.length + o.originx,
												o.planklength, o.planklengthvar,
												o.plankwidth, o.plankwidthvar,
												o.longgap, o.shortgap,
												o.offset, o.randomoffset, o.minoffset,
												o.randomseed,
												o.randrotx, o.randroty, o.randrotz,
												o.originx, o.originy)
	elif o.pattern == 'Herringbone':
		# note that there is a lot of extra length and width here to make sure that  we create a pattern w.o. gaps at the edges
		v = o.plankwidth * sqrt(2.0)
		w = o.planklength * sqrt(2.0)
		nplanks = int((o.width+o.planklength + o.originy*2) / v)+1
		nplanksc = int((o.length + o.originx*2) / w)+1
		verts, faces, uvs = herringbone(nplanks, nplanksc,
												o.planklength, o.plankwidth,
												o.longgap, o.shortgap,
												o.randomseed,
												o.randrotx, o.randroty, o.randrotz,
												o.originx, o.originy)
	elif o.pattern == 'Square':
		rows = int((o.width + o.originy)/ o.planklength)+1
		cols = int((o.length + o.originx)/ o.planklength)+1
		verts, faces, uvs = square(rows, cols, o.planklength, o.nsquare, o.border, o.longgap, o.shortgap, o.randomseed,
									o.randrotx, o.randroty, o.randrotz,
									o.originx, o.originy)
	elif o.pattern == 'Versaille':
		rows = int((o.width + o.originy)/ o.planklength)+2
		cols = int((o.length + o.originx)/ o.planklength)+2
		verts, faces, uvs = versaille(rows, cols, 
										o.planklength, o.plankwidth,
										o.longgap, o.shortgap,
										o.randrotx, o.randroty, o.randrotz,
										o.originx, o.originy,
										o.borderswitch)

	# create mesh &link object to scene
	emesh = o.data

	mesh = bpy.data.meshes.new(name='Planks')
	mesh.from_pydata(verts, [], faces)

	mesh.update(calc_edges=True)

	# more than one object can refer to the same emesh
	for i in bpy.data.objects:
		if i.data == emesh:
			i.data = mesh

	name = emesh.name
	emesh.user_clear() # this way the old mesh is marked as used by noone and not saved on exit
	bpy.data.meshes.remove(emesh)
	mesh.name = name
	if bpy.context.mode != 'EDIT_MESH':
		bpy.ops.object.editmode_toggle()
		bpy.ops.object.editmode_toggle()

	bpy.ops.object.shade_smooth()

	# add uv-coords and per face random vertex colors
	rot = Euler((0,0,o.uvrotation))
	mesh.uv_textures.new()
	uv_layer = mesh.uv_layers.active.data
	vertex_colors = mesh.vertex_colors.new().data
	offset = Vector()
	# note that the uvs that are returned are shuffled
	for poly in mesh.polygons:
		color = [rand(), rand(), rand()]
		if o.randomuv == 'Random':
			offset = Vector((rand(), rand(), 0))
		if o.randomuv == 'Restricted':
			offset = Vector((rand()*2-1, rand()*2-1, 0))
			for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
				co = offset + mesh.vertices[mesh.loops[loop_index].vertex_index].co
				if co.x > o.length or co.x < 0:
					offset[0] = 0
				if co.y > o.width or co.y < 0:
					offset[1] = 0
		elif o.randomuv == 'Packed':
			x = []
			y = []
			for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
				x.append(uvs[mesh.loops[loop_index].vertex_index].x)
				y.append(uvs[mesh.loops[loop_index].vertex_index].y)
			offset = Vector((-min(x), -min(y), 0))
		for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
			if o.randomuv == 'Shuffle':
				coords = uvs[mesh.loops[loop_index].vertex_index]
			elif o.randomuv in ('Random', 'Restricted'):
				coords = mesh.vertices[mesh.loops[loop_index].vertex_index].co + offset
			elif o.randomuv == 'Packed':
				coords = uvs[mesh.loops[loop_index].vertex_index] + offset
			else:
				coords = mesh.vertices[mesh.loops[loop_index].vertex_index].co
			coords = Vector(coords) # copy
			coords.x *= o.uvscalex
			coords.y *= o.uvscaley
			coords.rotate(rot)
			uv_layer[loop_index].uv = coords.xy
			vertex_colors[loop_index].color = color

	# subdivide mesh and warp it
	warped = o.hollowlong > 0 or o.hollowshort > 0 or o.twist > 0
	if warped:
		bm = bmesh.new()
		bm.from_mesh(mesh)

		# calculate hollowness for each face
		dshortmap = {}
		dlongmap = {}
		for face in bm.faces:
			dshort = o.hollowshort * rand()
			dlong = o.hollowlong * rand()
			for v in face.verts:
				dshortmap[v.index] = dshort
				dlongmap[v.index] = dlong

		bm.to_mesh(mesh)
		bm.free()

		# at this point all new geometry is selected and subdivide works in all selection modes
		bpy.ops.object.editmode_toggle()
		bpy.ops.mesh.subdivide()  # bmesh subdivide doesn't work for me ...
		bpy.ops.object.editmode_toggle()

		bm = bmesh.new()
		bm.from_mesh(mesh)

		for v in bm.verts:
			if o.twist and len(v.link_edges) == 4:  # vertex in the middle of the plank
				dtwist = o.twist * randuni(-1, 1)
				for e in v.link_edges:
					v2 = e.other_vert(v)  # the vertices on the side of the plank
					if shortside(v2):
						for e2 in v2.link_edges:
							v3 = e2.other_vert(v2)
							if len(v3.link_edges) == 2:
								v3.co.z += dtwist
								dtwist = -dtwist  # one corner up, the other corner down
			elif len(v.link_edges) == 3:  # vertex in the middle of a side of the plank
				for e in v.link_edges:
					v2 = e.other_vert(v)
					if len(v2.link_edges) == 2:  # hollowness values are stored with the all original corner vertices
						dshort = dshortmap[v2.index]
						dlong = dlongmap[v2.index]
						break
				if shortside(v):
					v.co.z -= dlong
				else:
					v.co.z -= dshort

		creases = bm.edges.layers.crease.new()
		for edge in bm.edges:
			edge[creases] = 1
			for vert in edge.verts:
				if len(vert.link_edges) == 4:
					edge[creases] = 0
					break

		bm.to_mesh(mesh)
		bm.free()

	
	# remove all modifiers to make sure the boolean will be last & only modifier
	n = len(o.modifiers)
	while n > 0:
		n -= 1
		bpy.ops.object.modifier_remove(modifier=o.modifiers[-1].name)
	
	# add thickness
	bpy.ops.object.mode_set(mode='EDIT')
	bm = bmesh.from_edit_mesh(o.data)
	
	# extrude to give thickness
	ret=bmesh.ops.extrude_face_region(bm,geom=bm.faces[:])
	ret=bmesh.ops.translate(bm,vec=Vector((0,0,self.thickness)),verts=[el for el in ret['geom'] if isinstance(el, bmesh.types.BMVert)] )
	
	# trim excess flooring
	ret = bmesh.ops.bisect_plane(bm, geom=bm.verts[:]+bm.edges[:]+bm.faces[:], plane_co=(o.length,0,0), plane_no=(1,0,0), clear_outer=True)
	ret = bmesh.ops.bisect_plane(bm, geom=bm.verts[:]+bm.edges[:]+bm.faces[:], plane_co=(0,0,0), plane_no=(-1,0,0), clear_outer=True)
	ret = bmesh.ops.bisect_plane(bm, geom=bm.verts[:]+bm.edges[:]+bm.faces[:], plane_co=(0,o.width,0), plane_no=(0,1,0), clear_outer=True)
	ret = bmesh.ops.bisect_plane(bm, geom=bm.verts[:]+bm.edges[:]+bm.faces[:], plane_co=(0,0,0), plane_no=(0,-1,0), clear_outer=True)
	
	# fill in holes caused by the trimming
	open_edges = [e for e in bm.edges if len(e.link_faces)==1]
	bmesh.ops.edgeloop_fill(bm, edges=open_edges, mat_nr=0, use_smooth=False)
	
	creases = bm.edges.layers.crease.active
	if creases is not None:
		for edge in open_edges:
			edge[creases] = 1

	bmesh.update_edit_mesh(o.data)
	bpy.ops.object.mode_set(mode='OBJECT')
	
	# intersect with a floorplan. Note the floorplan must be 2D (all z-coords must be identical) and a closed polygon.
	if self.usefloorplan and self.floorplan != ' None ':
		# make the floorplan the only active an selected object
		bpy.ops.object.select_all(action='DESELECT')
		context.scene.objects.active = bpy.data.objects[self.floorplan]
		bpy.data.objects[self.floorplan].select = True

		# duplicate the selected geometry into a separate object
		me = context.scene.objects.active.data
		selected_faces = [p.index for p in me.polygons if p.select]
		bpy.ops.object.editmode_toggle()
		bpy.ops.mesh.duplicate()
		bpy.ops.mesh.separate()
		bpy.ops.object.editmode_toggle()
		me = context.scene.objects.active.data
		for i in selected_faces:
			me.polygons[i].select = True

		# now there will be two selected objects
		# the one with the new name will be the copy
		for ob in context.selected_objects:
			if ob.name != self.floorplan:
				fpob = ob
		
		# make that copy active and selected
		for ob in context.selected_objects:
			ob.select = False
		fpob.select = True
		context.scene.objects.active = fpob
		# add thickness
		# let normals of select faces point in same direction
		bpy.ops.object.editmode_toggle()
		bpy.ops.mesh.select_all(action='SELECT')
		bpy.ops.mesh.normals_make_consistent(inside=False)
		bpy.ops.object.editmode_toggle()
		# add solidify modifier
		# NOTE: for some reason bpy.ops.object.modifier_add doesn't work here
		# even though fpob at this point is verifyable the active and selected object ...
		mod = fpob.modifiers.new(name='Solidify', type='SOLIDIFY')
		mod.offset = 1.0 # in the direction of the normals
		mod.thickness = 2000 # very thick
		bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")
		bpy.ops.object.editmode_toggle()
		bpy.ops.mesh.select_all(action='SELECT')
		bpy.ops.mesh.normals_make_consistent(inside=False)
		bpy.ops.object.editmode_toggle()
		fpob.location -= Vector((0,0,1000)) # actually this should be in the negative direction of the normals not just plain downward...
		
		# at this point the floorplan object is the active and selected object
		if True:
			# make the floorboards active and selected
			for ob in context.selected_objects:
				ob.select = False
			context.scene.objects.active = o
			o.select = True
			
			# add-and-apply a boolean modifier to get the intersection with the floorplan copy
			bpy.ops.object.modifier_add(type='BOOLEAN') # default is intersect
			o.modifiers[-1].object = fpob
			if True:
				bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")
				# delete the copy
				bpy.ops.object.select_all(action='DESELECT')
				context.scene.objects.active = fpob
				fpob.select = True
				bpy.ops.object.delete()
			# make the floorboards active and selected
			context.scene.objects.active = o
			o.select = True
		
	if self.modify:
		mods = o.modifiers
		if len(mods) == 0: # always true
			bpy.ops.object.modifier_add(type='BEVEL')
			#bpy.ops.object.modifier_add(type='EDGE_SPLIT')
			mods = o.modifiers
			mods[0].show_expanded = False
			#mods[1].show_expanded = False
			mods[0].width = self.bevel
			mods[0].segments = 2
			mods[0].limit_method = 'ANGLE'
			mods[0].angle_limit = (85/90.0)*PI/2
		if warped and not ('SUBSURF' in [m.type for m in mods]):
			bpy.ops.object.modifier_add(type='SUBSURF')
			mods[-1].show_expanded = False
			mods[-1].levels = 2
		if not warped and ('SUBSURF' in [m.type for m in mods]):
			bpy.ops.object.modifier_remove(modifier='Subsurf')

	if self.preservemats and len(material_list)>0:
		rebuildMaterialList(o, material_list)    
		assignRandomMaterial(len(material_list))
Example #28
0
def updateMesh(self, context):
    o = context.object

    verts, faces, shortedges, longedges = planks(
        o.nplanks, o.length, o.planklength, o.planklengthvar, o.plankwidth,
        o.plankwidthvar, o.longgap, o.shortgap, o.offset, o.randomoffset,
        o.randomseed, o.randrotx, o.randroty, o.randrotz)

    # create mesh &link object to scene
    emesh = o.data

    mesh = bpy.data.meshes.new(name='Planks')
    mesh.from_pydata(verts, [], faces)

    mesh.update(calc_edges=True)

    for i in bpy.data.objects:
        if i.data == emesh:
            i.data = mesh

    name = emesh.name
    emesh.user_clear()
    bpy.data.meshes.remove(emesh)
    mesh.name = name
    if bpy.context.mode != 'EDIT_MESH':
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.editmode_toggle()

    bpy.ops.object.shade_smooth()

    # add uv-coords and per face random vertex colors
    mesh.uv_textures.new()
    uv_layer = mesh.uv_layers.active.data
    vertex_colors = mesh.vertex_colors.new().data
    for poly in mesh.polygons:
        offset = Vector((rand(), rand(), 0)) if o.randomuv else Vector(
            (0, 0, 0))
        color = [rand(), rand(), rand()]
        for loop_index in range(poly.loop_start,
                                poly.loop_start + poly.loop_total):
            coords = mesh.vertices[mesh.loops[loop_index].vertex_index].co
            uv_layer[loop_index].uv = (coords + offset).xy
            vertex_colors[loop_index].color = color

    # subdivide mesh and warp it
    warped = o.hollowlong > 0 or o.hollowshort > 0 or o.twist > 0
    if warped:
        bm = bmesh.new()
        bm.from_mesh(mesh)

        # calculate hollowness for each face
        dshortmap = {}
        dlongmap = {}
        for face in bm.faces:
            dshort = o.hollowshort * rand()
            dlong = o.hollowlong * rand()
            for v in face.verts:
                dshortmap[v.index] = dshort
                dlongmap[v.index] = dlong

        bm.to_mesh(mesh)
        bm.free()

        # at this point all new geometry is selected and subdivide works in all selection modes
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.subdivide()  # bmesh subdivide doesn't work for me ...
        bpy.ops.object.editmode_toggle()

        bm = bmesh.new()
        bm.from_mesh(mesh)

        for v in bm.verts:
            if o.twist and len(
                    v.link_edges) == 4:  # vertex in the middle of the plank
                dtwist = o.twist * randuni(-1, 1)
                for e in v.link_edges:
                    v2 = e.other_vert(
                        v)  # the vertices on the side of the plank
                    if shortside(v2):
                        for e2 in v2.link_edges:
                            v3 = e2.other_vert(v2)
                            if len(v3.link_edges) == 2:
                                v3.co.z += dtwist
                                dtwist = -dtwist  # one corner up, the other corner down
            elif len(v.link_edges
                     ) == 3:  # vertex in the middle of a side of the plank
                for e in v.link_edges:
                    v2 = e.other_vert(v)
                    if len(
                            v2.link_edges
                    ) == 2:  # hollowness values are stored with the all original corner vertices
                        dshort = dshortmap[v2.index]
                        dlong = dlongmap[v2.index]
                        break
                if shortside(v):
                    v.co.z -= dlong
                else:
                    v.co.z -= dshort

        creases = bm.edges.layers.crease.new()
        for edge in bm.edges:
            edge[creases] = 1
            for vert in edge.verts:
                if len(vert.link_edges) == 4:
                    edge[creases] = 0
                    break

        bm.to_mesh(mesh)
        bm.free()

    if self.modify:
        mods = o.modifiers
        if len(mods) == 0:
            bpy.ops.object.modifier_add(type='SOLIDIFY')
            bpy.ops.object.modifier_add(type='BEVEL')
            bpy.ops.object.modifier_add(type='EDGE_SPLIT')
            if warped:
                bpy.ops.object.modifier_add(type='SUBSURF')
            mods = o.modifiers
            mods[0].show_expanded = False
            mods[1].show_expanded = False
            mods[2].show_expanded = False
            mods[0].thickness = self.thickness
            mods[1].width = self.bevel
    else:  # maybe change this to walk the modifier stack and remove all
        if warped:
            bpy.ops.object.modifier_remove(modifier='Subsurf')
        bpy.ops.object.modifier_remove(modifier='EdgeSplit')
        bpy.ops.object.modifier_remove(modifier='Bevel')
        bpy.ops.object.modifier_remove(modifier='Solidify')