def write(self, pbrtwriter: PbrtWriter): from random import uniform, randint from tqdm import tqdm from util import tqdmpos def uni01(x): return uniform(0, 1) print("Preparing rain instance...") with pbrtwriter.attribute(): pbrtwriter.material("glass", "float eta", [1.33], "rgb Kt", [.28, .72, 1]) for i in tqdm(range(100), ascii=True): with pbrtwriter.objectb("RainStreak%02d" % i): for dummy_1 in range(100 * self.rainfall): with pbrtwriter.attribute(): x, y, z = map(uni01, [None] * 3) l = uniform(0, 0.1) pbrtwriter.translate((x, y, z)) pbrtwriter.shape("cylinder", "float radius", [0.001], "float zmin", [-l / 2], "float zmax", [l / 2]) # Pbrt cylinder is z-base. pbrtwriter.concatTransform( [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1]) sz = self.size print("Writing rain streaks...") for x, y, z in tqdmpos(range(sz), range(sz), range(256)): ind = randint(0, 99) with pbrtwriter.attribute(): pbrtwriter.translate((x, y, z)) pbrtwriter.objectInstance("RainStreak%02d" % ind)
def _writeElement(self, pbrtwriter: PbrtWriter, ele, material): from_pt = ele["from"] to_pt = ele["to"] cube = minus(to_pt, from_pt) mid = mult(plus(from_pt, to_pt), .5) with pbrtwriter.attribute(): pbrtwriter.translate(mid) if "rotation" in ele: import math rot = ele["rotation"] axis = rot["axis"] org = minus(mid, mult(rot["origin"], 1. / 16)) ang = rot["angle"] rxyz = {"x": (1, 0, 0), "y": (0, 1, 0), "z": (0, 0, 1)} sxyz = {"x": (0, 1, 1), "y": (1, 0, 1), "z": (1, 1, 0)} pbrtwriter.translate(mult(org, -1)) pbrtwriter.rotate(ang, rxyz[axis]) if "rescale" in rot and rot["rescale"]: scale = 1 / math.cos(ang / 180. * math.pi) pbrtwriter.scale(plus(mult(sxyz[axis], scale), rxyz[axis])) pbrtwriter.translate(org) for facename in ele["faces"]: face = ele["faces"][facename] tex = face["texture"] uv = face["uv"] delta_f, l_f, dir_, shape = pt_map[facename] delta = delta_f(cube) l1, l2 = l_f(cube) with pbrtwriter.attribute(): if "rotation" in face: rxyz = {"x": (1, 0, 0), "y": (0, 1, 0), "z": (0, 0, 1)} # shape[-1] should be "x", "y" or "z" pbrtwriter.rotate(face["rotation"] * dir_, rxyz[shape[-1]]) if material: material.write(pbrtwriter, face) pbrtwriter.translate(delta) params = [ "float l1", [l1], "float l2", [l2], "float dir", [dir_], "float u0", uv[0], "float v0", uv[1], "float u1", uv[2], "float v1", uv[3] ] if ResourceManager().hasAlpha(tex + ".png"): params.append("texture alpha") params.append("%s-alpha" % tex) pbrtwriter.shape(shape, *params)
def write(self, pbrtwriter: PbrtWriter): """Write file with pbrt format Args: pbrtwriter: Pbrtwriter Object Returns: Number of render block(0 or 1) """ if self.empty(): return 0 with pbrtwriter.attribute(): for model, transforms, material in self.models: for t in transforms: if t["type"] == "rotate": self._writeRotate(pbrtwriter, t["axis"], t["angle"]) elif t["type"] == "scale": self._writeScale(pbrtwriter, t["axis"], t["value"]) for ele in model["elements"]: self._writeElement(pbrtwriter, ele, material) for t in transforms[::-1]: if t["type"] == "rotate": self._writeRotate(pbrtwriter, t["axis"], -t["angle"]) elif t["type"] == "scale": self._writeScale(pbrtwriter, t["axis"], 1 / t["value"]) return 1
def _write(self, pbrtwriter: PbrtWriter): print("Writing liquid blocks...") for x, y, z in tqdmpos(range(self.X), range(self.Y), range(self.Z)): if self.level[y][z][x] == None: continue pt = (x, y, z) with pbrtwriter.attribute(): pbrtwriter.translate(plus(pt, (.5, 0, .5))) if self.getLevel((x, y + 1, z)) != None: # When a water block is on current block, the water should be full. ps = [1] * 9 else: dt = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 0), (0, 1), (1, -1), (1, 0), (1, 1)] hs = [None] * 9 for i in range(9): hs[i] = self.getHeight((x + dt[i][1], y, z + dt[i][0])) ps = [[0, 1, 3, 4], [1, 4], [1, 2, 4, 5], [3, 4], [4], [4, 5], [3, 4, 6, 7], [4, 7], [4, 5, 7, 8]] ps = [self.calAvg(map(lambda x: hs[x], p)) for p in ps] if self.getLevel((x, y + 1, z)) is None: from math import pi with pbrtwriter.attribute(): pbrtwriter.translate((-.5, 0, -.5)) pbrtwriter.shape("heightfield", "integer nv", [3], "integer nu", [3], "float Py", ps) if self.getLevel((x, y - 1, z)) is None: pbrtwriter.shape("quady") def flat(xs): ret = [] for x in xs: ret += list(x) return ret def trimesh(mv, pts, inds): with pbrtwriter.attribute(): pbrtwriter.translate(mv) pbrtwriter.shape("trianglemesh", "point P", flat(pts), "integer indices", flat(inds)) def rev(inds): ret = list(inds) for i in range(len(ret)): tri = ret[i] ret[i] = (tri[0], tri[2], tri[1]) return ret indx = [(0, 1, 2), (1, 3, 2), (2, 3, 4), (3, 5, 4)] if self.getLevel((x - 1, y, z)) is None: pts = [ (0, 0, -.5), (0, ps[0], -.5), (0, 0, 0), (0, ps[3], 0), (0, 0, .5), (0, ps[6], .5), ] trimesh((-.5, 0, 0), pts, rev(indx)) if self.getLevel((x + 1, y, z)) is None: pts = [ (0, 0, -.5), (0, ps[2], -.5), (0, 0, 0), (0, ps[5], 0), (0, 0, .5), (0, ps[8], .5), ] trimesh((.5, 0, 0), pts, indx) if self.getLevel((x, y, z - 1)) is None: pts = [ (-.5, 0, 0), (-.5, ps[0], 0), (0, 0, 0), (0, ps[1], 0), (.5, 0, 0), (.5, ps[2], 0), ] trimesh((0, 0, -.5), pts, indx) if self.getLevel((x, y, z + 1)) is None: pts = [ (-.5, 0, 0), (-.5, ps[6], 0), (0, 0, 0), (0, ps[7], 0), (.5, 0, 0), (.5, ps[8], 0), ] trimesh((0, 0, .5), pts, rev(indx))
def write(self, pbrtwriter: PbrtWriter): with pbrtwriter.attribute(): pbrtwriter.rotate(270, [1, 0, 0]) pbrtwriter.lightSource("infinite", "integer nsamples", [16], "rgb L", [1, 1, 1], "string mapname", [self.filename])