Skip to content

Commit

Permalink
Fix point cloud voxel size issues for additive refinement pnts (#5407)
Browse files Browse the repository at this point in the history
Co-authored-by: Paul Connelly <22944042+pmconne@users.noreply.github.com>
  • Loading branch information
DStradley and pmconne authored Apr 18, 2023
1 parent a484f0c commit 6c35932
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 5 deletions.
2 changes: 1 addition & 1 deletion common/api/core-frontend.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8693,7 +8693,7 @@ export class ReadonlyTileUserSet extends ReadonlySortedArray<TileUser> {
}

// @internal
export function readPointCloudTileContent(stream: ByteStream, iModel: IModelConnection, modelId: Id64String, _is3d: boolean, range: ElementAlignedBox3d, system: RenderSystem): Promise<{
export function readPointCloudTileContent(stream: ByteStream, iModel: IModelConnection, modelId: Id64String, _is3d: boolean, tile: RealityTile, system: RenderSystem): Promise<{
graphic: RenderGraphic | undefined;
rtcCenter: Point3d | undefined;
}>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/core-frontend",
"comment": "Fixed inconsistent point sizes for additive point cloud tiles.",
"type": "none"
}
],
"packageName": "@itwin/core-frontend"
}
15 changes: 12 additions & 3 deletions core/frontend/src/tile/PntsReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@

import { ByteStream, Id64String, Logger, utf8ToString } from "@itwin/core-bentley";
import { Point3d, Range3d } from "@itwin/core-geometry";
import { BatchType, ElementAlignedBox3d, Feature, FeatureTable, PackedFeatureTable, PntsHeader, QParams3d, QPoint3d, Quantization } from "@itwin/core-common";
import { BatchType, Feature, FeatureTable, PackedFeatureTable, PntsHeader, QParams3d, QPoint3d, Quantization } from "@itwin/core-common";
import { FrontendLoggerCategory } from "../FrontendLoggerCategory";
import { IModelConnection } from "../IModelConnection";
import { Mesh } from "../render/primitives/mesh/MeshPrimitives";
import { RenderGraphic } from "../render/RenderGraphic";
import { RenderSystem } from "../render/RenderSystem";
import { RealityTile } from "./internal";

/** Schema for the [3DTILES_draco_point_compression](https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_draco_point_compression) extension. */
interface DracoPointCloud {
Expand Down Expand Up @@ -201,13 +202,14 @@ async function decodeDracoPointCloud(buf: Uint8Array): Promise<PointCloudProps |
/** Deserialize a point cloud tile and return it as a RenderGraphic.
* @internal
*/
export async function readPointCloudTileContent(stream: ByteStream, iModel: IModelConnection, modelId: Id64String, _is3d: boolean, range: ElementAlignedBox3d, system: RenderSystem): Promise<{ graphic: RenderGraphic | undefined, rtcCenter: Point3d | undefined }> {
export async function readPointCloudTileContent(stream: ByteStream, iModel: IModelConnection, modelId: Id64String, _is3d: boolean, tile: RealityTile, system: RenderSystem): Promise<{ graphic: RenderGraphic | undefined, rtcCenter: Point3d | undefined }> {
let graphic;
let rtcCenter;
const header = new PntsHeader(stream);
if (!header.isValid)
return { graphic, rtcCenter };

const range = tile.contentRange;
const featureTableJsonOffset = stream.curPos;
const featureStrData = stream.nextBytes(header.featureTableJsonLength);
const featureStr = utf8ToString(featureStrData);
Expand Down Expand Up @@ -269,7 +271,14 @@ export async function readPointCloudTileContent(stream: ByteStream, iModel: IMod
rng.extendXYZ(props.points[i], props.points[i + 1], props.points[i + 2]);
params = QParams3d.fromRange(rng);
}
const voxelSize = params.rangeDiagonal.maxAbs() / 256;
// 256 here is tile.maximumSize (on non-additive refinement tiles)
// If additiveRefinement, set voxelSize to 0 which will cause it draw to with minPixelsPerVoxel, which defaults to 2
// That way, it will draw as if in pixel mode, and voxelScale will still function
// Checking across a variety of 10 point clouds, 2 to 4 seems to work well for pixel settings (depending on the
// cloud), so 2 is a decent default
// (If voxelSize is used normally in this case, it draws different size pixels for different tiles, and since
// they can overlap ranges, no good way found to calculate a voxelSize)
const voxelSize = tile.additiveRefinement ? 0 : params.rangeDiagonal.maxAbs() / 256;

graphic = system.createPointCloud({
positions: props.points,
Expand Down
2 changes: 1 addition & 1 deletion core/frontend/src/tile/RealityTileLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export abstract class RealityTileLoader {
break;
case TileFormat.Pnts:
this._containsPointClouds = true;
const res = await readPointCloudTileContent(streamBuffer, iModel, modelId, is3d, tile.contentRange, system);
const res = await readPointCloudTileContent(streamBuffer, iModel, modelId, is3d, tile, system);
let graphic = res.graphic;
const rtcCenter = res.rtcCenter;
if (graphic && (rtcCenter || tile.transformToRoot && !tile.transformToRoot.isIdentity)) {
Expand Down

0 comments on commit 6c35932

Please sign in to comment.