def test_build(self): with open('tests/square.wkb', 'rb') as f: wkb = f.read() with open('tests/squareUV.wkb', 'rb') as f: wkbuv = f.read() ts = TriangleSoup.from_wkb_multipolygon(wkb, [wkbuv]) positions = ts.getPositionArray() normals = ts.getNormalArray() uvs = ts.getDataArray(0) box = [[0, 0, 0], [10, 10, 0]] arrays = [{ 'position': positions, 'normal': normals[1], 'uv': uvs, 'bbox': box }] transform = np.array( [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], dtype=float) transform = transform.flatten('F') glTF = GlTF.from_binary_arrays(arrays, transform, textureUri='squaretexture.jpg') t = B3dm.from_glTF(glTF) # get an array t.to_array() self.assertEqual(t.header.version, 1.0) self.assertEqual(t.header.tile_byte_length, 1492) self.assertEqual(t.header.ft_json_byte_length, 0) self.assertEqual(t.header.ft_bin_byte_length, 0) self.assertEqual(t.header.bt_json_byte_length, 0) self.assertEqual(t.header.bt_bin_byte_length, 0)
def test_build(self): with open('tests/building.wkb', 'rb') as f: wkb = f.read() ts = TriangleSoup.from_wkb_multipolygon(wkb) positions = ts.getPositionArray() normals = ts.getNormalArray() box = [[-8.74748499994166, -7.35523200035095, -2.05385796777344], [8.8036420000717, 7.29930999968201, 2.05386103222656]] arrays = [{'position': positions, 'normal': normals[1], 'bbox': box}] transform = np.array([[1, 0, 0, 1842015.125], [0, 1, 0, 5177109.25], [0, 0, 1, 247.87364196777344], [0, 0, 0, 1]], dtype=float) # translation : 1842015.125, 5177109.25, 247.87364196777344 transform = transform.flatten('F') glTF = GlTF.from_binary_arrays(arrays, transform) t = B3dm.from_glTF(glTF) # get an array t.to_array() self.assertEqual(t.header.version, 1.0) self.assertEqual(t.header.tile_byte_length, 2860) self.assertEqual(t.header.ft_json_byte_length, 0) self.assertEqual(t.header.ft_bin_byte_length, 0) self.assertEqual(t.header.bt_json_byte_length, 0) self.assertEqual(t.header.bt_bin_byte_length, 0)
def arrays2tileset(positions, normals, bboxes, transform, ids=None): print("Creating tileset...") maxTileSize = 2000 featuresPerTile = 20 indices = [i for i in range(len(positions))] # glTF is Y-up, so to get the bounding boxes in the 3D tiles # coordinate system, we have to apply a Y-to-Z transform to the # glTF bounding boxes zUpBboxes = [] for bbox in bboxes: tmp = m = bbox[0] M = bbox[1] m = [m[0], -m[2], m[1]] M = [M[0], -tmp[2], M[1]] zUpBboxes.append([m, M]) # Compute extent xMin = yMin = float('inf') xMax = yMax = -float('inf') for bbox in zUpBboxes: xMin = min(xMin, bbox[0][0]) yMin = min(yMin, bbox[0][1]) xMax = max(xMax, bbox[1][0]) yMax = max(yMax, bbox[1][1]) extent = BoundingBox([xMin, yMin], [xMax, yMax]) extentX = xMax - xMin extentY = yMax - yMin # Create quadtree tree = Node() for i in range(0, int(math.ceil(extentX / maxTileSize))): for j in range(0, int(math.ceil(extentY / maxTileSize))): tile = tile_extent(extent, maxTileSize, i, j) geoms = [] for idx, box in zip(indices, zUpBboxes): bbox = BoundingBox(box[0], box[1]) if tile.inside(bbox.center()): geoms.append(Feature(idx, bbox)) if len(geoms) == 0: continue if len(geoms) > featuresPerTile: node = Node(geoms[0:featuresPerTile]) tree.add(node) divide(tile, geoms[featuresPerTile:len(geoms)], i * 2, j * 2, maxTileSize / 2., featuresPerTile, node) else: node = Node(geoms) tree.add(node) # Export b3dm & tileset tileset = tree.to_tileset(transform) f = open("tileset.json", 'w') f.write(json.dumps(tileset)) print("Creating tiles...") nodes = tree.all_nodes() identity = np.identity(4).flatten('F') try: os.makedirs("tiles") except OSError as e: if e.errno != errno.EEXIST: raise for node in nodes: if len(node.features) != 0: binarrays = [] gids = [] for feature in node.features: pos = feature.index binarrays.append({ 'position': positions[pos], 'normal': normals[pos], 'bbox': [[float(i) for i in j] for j in bboxes[pos]], }) if ids is not None: gids.append(ids[pos]) gltf = GlTF.from_binary_arrays(binarrays, identity) bt = None if ids is not None: bt = BatchTable() bt.add_property_from_array("id", gids) b3dm = B3dm.from_glTF(gltf, bt).to_array() f = open("tiles/{0}.b3dm".format(node.id), 'wb') f.write(b3dm)
def arrays2tileset(positions, normals, bboxes, bboxesNonRotated, transform, ids=None, doubleSided=False, layerId=None): print("Creating tileset...") maxTileSize = 2000 indices = [i for i in range(len(positions))] # Compute extent xMin = yMin = float('inf') xMax = yMax = -float('inf') for bbox in bboxesNonRotated: xMin = min(xMin, bbox[0][0]) yMin = min(yMin, bbox[0][1]) xMax = max(xMax, bbox[1][0]) yMax = max(yMax, bbox[1][1]) extent = BoundingBox([xMin, yMin], [xMax, yMax]) extentX = xMax - xMin extentY = yMax - yMin # Create quadtree tree = Node() tilesArr = [] for i in range(0, int(math.ceil(extentX / maxTileSize))): for j in range(0, int(math.ceil(extentY / maxTileSize))): tile = tile_extent(extent, maxTileSize, i, j) for idx, box in zip(indices, bboxesNonRotated): bbox = BoundingBox(box[0], box[1]) if tile.inside(bbox.center()): tilesArr.append([idx, Feature(idx, bbox)]) # Sort geoms by id before creating the b3dm and tileset npTiles = np.asarray(tilesArr) npTiles = npTiles[np.argsort(npTiles[:, 0])] for npTile in npTiles: node = Node([npTile[1]]) tree.add(node) # Export b3dm & tileset tileset = tree.to_tileset(transform, layerId=layerId) f = open("tileset.json".format(node.id), 'w') f.write(json.dumps(tileset)) print("Creating tiles...") nodes = tree.all_nodes() identity = np.identity(4).flatten('F') try: os.makedirs("tiles") except OSError as e: if e.errno != errno.EEXIST: raise for node in nodes: if len(node.features) != 0: binarrays = [] gids = [] for feature in node.features: pos = feature.index binarrays.append({ 'position': positions[pos], 'normal': normals[pos][1], 'bbox': [[float(i) for i in j] for j in bboxes[pos]], }) if ids is not None: gids.append(ids[pos]) gltf = GlTF.from_binary_arrays(binarrays, identity, doubleSided=doubleSided, nMaxMin=normals[pos][0]) bt = None if ids is not None: ft = FeatureTable() ft.add_property_from_value("BATCH_LENGTH", len(gids)) bt = BatchTable() bt.add_property_from_array("id", gids) b3dm = B3dm.from_glTF(gltf, bt=bt, ft=ft).to_array() f = open("tiles/{0}.b3dm".format(node.id), 'wb') f.write(b3dm)