Closed lllllleo42 closed 4 months ago
When you say
... to batch create tileset.json, ...
then it might be that the pipeline functionality is not what you're looking for. The pipeline function (as it was introduced several years ago aimed at performing a sequence of operations on each tile content of an existing tileset (e.g. to optimize each B3DM, and then ZIP it...).
When you say that you want to "batch create tileset.json", then this sounds like you wanted to call the createTilesetJson
function for a set of input GLB files. Is that correct?
(If this is correct, then this functionality could probably be implemented with a few (very few) lines of code in a custom script, but I'd like to make sure that I understood this correctly...)
Thank you for answering my question. Sorry again for my poor English expression. Yes, your understanding is right. I wanted to call the createTilesetJson function for a set of input GLB files. However, I have too many glb files to input, making the command line too long, so I want to use some pipeline tools. Thanks again.
When you say that you want to "batch create tileset.json", then this sounds like you wanted to call the
createTilesetJson
function for a set of input GLB files. Is that correct?
I have too many glb files to input, making the command line too long, so I want to use some pipeline tools.
The createTilesetJson
command can accept a directory as the --input
parameter. So when you have a directory like C:\AllMyInputFiles
that contains 1000 GLB files, then you can just say
npx 3d-tiles-tools createTilesetJson -i C:/AllMyInputFiles -o C:/AllMyInputFiles/tileset.json
and it will create a single tileset.json
that refers to all the 1000 GLB files in that directory.
(Note that the structure of this tileset JSON will be really simple, and it could be possible to create a "better" one, with more information about what the GLB files are, and how they should be combined)
If you want to create one tileset.json
file for each GLB, then you could of course run
npx 3d-tiles-tools createTilesetJson -i C:/AllMyInputFiles/input0001.glb -o C:/AllMyInputFiles/tileset0001.json
npx 3d-tiles-tools createTilesetJson -i C:/AllMyInputFiles/input0002.glb -o C:/AllMyInputFiles/tileset0002.json
npx 3d-tiles-tools createTilesetJson -i C:/AllMyInputFiles/input0003.glb -o C:/AllMyInputFiles/tileset0003.json
....
1000 times - but .... you shouldn't do this 🙂 If this is the goal, then you could solve this with a small, custom script (and I'll post an example here if this is what you're trying to do...)
Thanks. Actually, what I'm trying to do is converting many glb files to a 3dtiles file. However, I need to assign latitude and longitude coordinates to each glb file, Otherwise, there will be many models overlapping in the same location. So I came up with a stupid but simple solution, which is to use the createTilesetJson
function for each glb file and generate tileset.json separately. And finally, merg these tileset into a single one. I guess it's kind of stupid😥Thanks again for answering my questions.
It's not stupid. It sounds like a reasonable use-case, and could be a natural extension of the functionality that is already offered by createTilesetJson
.
But when adding a new functionality, then one should have a clear idea about the degrees of freedom, and what this function can or cannot do. Right now, the createTilesetJson
is targeted at creating a very simple tileset.json
for one or more GLB files. Assigning different positions to the GLBs is not covered by that.
If the desired funcitonality was supposed to be added, then I'd have to think this through more thoroughly. And this request does have some overlap to https://github.com/CesiumGS/3d-tiles-tools/issues/84 .
In both cases, one important question is:
Where does the latitude/longitude/height information for each model come from?
So you have your directory with GLB files, like exampleA.glb
, exampleB.glb
, exampleC.glb
.... And each of them has a different latitude/longitude/height. So the pseudocode(!!!) of the function that you would need could be
magic.addContent("exampleA.glb", 35, 140, 10);
magic.addContent("exampleB.glb", 37, 135, 30);
magic.addContent("exampleC.glb", 36, 142, 01);
...
tileset = magic.buildThat();
But this works well only for "few" files. When there are many files (hundreds), then the latitude/longitude/height information is probably contained in some CSV file or some JSON structure (maybe something that is queried via a REST API or so...)
I just started drafting some tests for this.
NOTE: During thest tests, I noticed that https://github.com/CesiumGS/3d-tiles-tools/issues/112 . This is fixed via https://github.com/CesiumGS/3d-tiles-tools/pull/113 , but this is not merged yet.
The approach that you described would probably work, in principle:
createTilesetJson
functionality to create one tileset.json
for each input file (using the proper cartographic position)merge
functionality to create one tileset that refers to each of them as external tilesetscombine
functionality to create a single tilesetThis is drafted here.
NOTE: This does use the "library-level" functionality, and not the command line functionality. All this is not "public" yet. This is only a DRAFT.
import fs from "fs";
import path from "path";
import { TilesetJsonCreator } from "./src/tools/tilesetProcessing/TilesetJsonCreator";
import { TilesetOperations } from "./src/tools/tilesetProcessing/TilesetOperations";
import { Paths } from "./src/base";
const baseDir = "./input";
const glbDir = path.resolve(baseDir, "glbFiles");
const tilesetsBaseDir = path.resolve(baseDir, "tilesets");
const mergedFileName = path.resolve(baseDir, "merged/tileset-merged.json");
const combinedFileName = path.resolve(
baseDir,
"combined/tileset-combined.json"
);
const inputs = [
{
fileName: "exampleA.glb",
lonLatHeightDegrees: [-75.15, 39.94, 50.0],
},
{
fileName: "exampleB.glb",
lonLatHeightDegrees: [-75.1502, 39.94, 50.2],
},
{
fileName: "exampleC.glb",
lonLatHeightDegrees: [-75.1504, 39.94, 50.4],
},
];
async function run() {
const overwrite = true;
const tilesetFileNames: string[] = [];
for (const input of inputs) {
const fileName = input.fileName;
console.log("Create tileset JSON for " + fileName);
const inputGlbName = path.resolve(glbDir, fileName);
const tilesetName = "tileset-" + Paths.replaceExtension(fileName, "");
const tilesetDir = path.resolve(tilesetsBaseDir, tilesetName);
const outputGlbName = path.resolve(tilesetDir, fileName);
Paths.ensureDirectoryExists(tilesetDir);
fs.copyFileSync(inputGlbName, outputGlbName);
const tileset = await TilesetJsonCreator.createTilesetFromContents(
tilesetDir,
[fileName]
);
console.log("Assigning position for " + fileName);
const cartographicPositionDegrees = input.lonLatHeightDegrees;
const transform =
TilesetJsonCreator.computeTransformFromCartographicPositionDegrees(
cartographicPositionDegrees
);
tileset.root.transform = transform;
const tilesetFileName = path.resolve(tilesetDir, "tileset.json");
console.log("Writing " + tilesetFileName + " for content file " + fileName);
fs.writeFileSync(tilesetFileName, JSON.stringify(tileset, null, 2));
tilesetFileNames.push(tilesetFileName);
}
console.log("Merging...");
await TilesetOperations.merge(tilesetFileNames, mergedFileName, overwrite);
console.log("Combining...");
await TilesetOperations.combine(mergedFileName, combinedFileName, overwrite);
console.log("Done, output at " + combinedFileName);
}
run();
I tried this out, with some example GLB files, and it should work in principle:
But ... this is quirky: It should not be necessary to apply a sequence of three operations, with lots of intermediate steps and input/output files and directories, just to accomplish this task.
There should be a simpler functionality for that. But I'll have to think about how this could be offered sensibly. For example, how to define the cartographic position that each GLB should have. It wouldn't make sense to try to offer this as a pure command-line function. There has to be some sort of input file (CSV or JSON) that defines the position for each GLB. And this means that the implementation should be carefully thought through.
(One could say that we'll have to get our ducks in a row before implementing that 😁 )
Thanks!!!It really helped me a lot😀
Since the last part is no longer related to the pipeline function, and boiled down to a somewhat specific (but potentially very useful) functionality, I tried to summarize this in https://github.com/CesiumGS/3d-tiles-tools/issues/130
I want to use the pipeline tool to batch create tileset.json, but I can't find the tutorial. I can only find a step to define a pipeline JSON file