# 几何算法 


## 使用

通过 [vjmap3d.loadPluginAlgorithm](https://vjmap.com/map3d/api/functions/loadPluginAlgorithm.html) 加载几何算法插件库

或 通过 `vjmap3d.Plugins.loadPlugin("algorithm")` 加载

```js
let amLib = await vjmap3d.loadPluginAlgorithm();
let len = 1;
const brush1 = new amLib.Brush( new THREE.SphereGeometry(len) );
brush1.material.color = new THREE.Color("#0f0")
//
brush1.position.set(0,  0, 2)
brush1.updateMatrixWorld();
//
const brush2 = new amLib.Brush( new THREE.BoxGeometry(len, len, len) );
brush2.position.set(0, 0.5, 2)
//
brush2.material.color = new THREE.Color("#f00")
brush2.updateMatrixWorld();
// // 在球的表面挖去立方体的表面
const evaluator = new amLib.Evaluator();
const result = evaluator.evaluate( brush1, brush2, amLib.HOLLOW_SUBTRACTION );
app.scene.add(result)
```


<mapFrame>
<pre>
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    scene: {
        gridHelper: { visible: true } // 是否显示坐标网格
    },
    camera: {  // 相机设置
        viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
    }
})
let amLib = await vjmap3d.loadPluginAlgorithm();
let len = 1;
const brush1 = new amLib.Brush( new THREE.SphereGeometry(len) );
brush1.material.color = new THREE.Color("#0f0")
//
brush1.position.set(0,  0, 2)
brush1.updateMatrixWorld();
//
const brush2 = new amLib.Brush( new THREE.BoxGeometry(len, len, len) );
brush2.position.set(0, 0.5, 2)
//
brush2.material.color = new THREE.Color("#f00")
brush2.updateMatrixWorld();
//
const evaluator = new amLib.Evaluator();
const result = evaluator.evaluate( brush1, brush2, amLib.HOLLOW_SUBTRACTION );
app.scene.add(result)
</pre>
</mapFrame> 


## 根据三维模型生成二维CAD图示例

```js
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    scene: {
        gridHelper: { visible: true } // 是否显示坐标网格
    },
    camera: {  // 相机设置
        viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
    },
    control: {
        initState: {
            cameraTarget: new THREE.Vector3(0.1, 0, 2),
			cameraPosition: new THREE.Vector3(-2 ,2, 0),
        }
    }
})
let amLib = await vjmap3d.loadPluginAlgorithm();
let silhouette = new THREE.Mesh( new THREE.BufferGeometry(), new THREE.MeshBasicMaterial( {
    color: '#eee',
    polygonOffset: true,
    polygonOffsetFactor: 3,
    polygonOffsetUnits: 3,
    side: THREE.DoubleSide,
} ) );
let outlines = new THREE.LineSegments( new THREE.BufferGeometry(), new THREE.LineBasicMaterial( { color: 0x030303 } ) );
app.scene.add( outlines, silhouette );
let ent = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/soldier.glb", {
    splitSubEntity: true,
    position: [0, 1, 0],
    rotation: [Math.PI / 2, 0, 0]
});
ent.addTo(app);
//
app.logInfo("正在根据三维模型生成二维平面图... (生成完成后可的右上角导出成dwg图)", 10000)
let model = ent.node;
let task = amLib.createProjectionTask({
    model,
    silhouette, 
    outlines, 
    updateProgressCb: (name, progress) => console.log(name, progress),
    updateVisible: undefined,
    ANGLE_THRESHOLD: 50
});
await task.promise();
//
let positions = outlines.geometry.attributes.position.array;
let entitys = []
for(let n = 0; n < positions.length; n+=6) {
    // vjmap3d 约定 CAD/地图的 y 对应世界坐标的 -z，导出 DWG 时 z 要取反，否则图形上下镜像
    let start = [positions[n], -positions[n + 2]];
    let end = [positions[n + 3], -positions[n + 5]];
    if (vjmap3d.approxArrayEquals(start, end)) continue; // 两点重合（默认容差 1e-5；第三参 error 可放宽，如 0.01）
    entitys.push({
        typename: "DbLine",
        start: start,
        end: end,
    })
}
console.log(entitys)
let doc = app.svc.toDbDoc({
    entitys
})
//console.log(doc)
let control = new vjmap3d.ButtonGroupControl({
    buttons: [
        {
            id: "export",
            html: "导出成CAD图",
            title: "把生成的平面图导出成cad图",
            style: {
                width: "130px"
            },
            onclick: async () => {
                let res = await app.svc.updateMap({
                    mapid: "silhouette_demo",
                    filedoc: doc,
                    mapopenway: vjmap3d.MapOpenWay.Memory,
                    style: {
                        backcolor: 0 // 如果div背景色是浅色，则设置为oxFFFFFF
                    }
                })
                let href = `${app.svc.baseUrl()}_cloud/#/map/${res.mapid}?version=${res.version}&mapopenway=Memory&vector=false&isFitMap=true`
                window.open(href)
            }
        }
    ]
});
app.addControl(control, "top-right");
```

<mapFrame>
<pre>
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    scene: {
        gridHelper: { visible: true } // 是否显示坐标网格
    },
    camera: {  // 相机设置
        viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
    },
    control: {
        initState: {
            cameraTarget: new THREE.Vector3(0.1, 0, 2),
			cameraPosition: new THREE.Vector3(-2 ,2, 0),
        }
    }
})
let amLib = await vjmap3d.loadPluginAlgorithm();
let silhouette = new THREE.Mesh( new THREE.BufferGeometry(), new THREE.MeshBasicMaterial( {
    color: '#eee',
    polygonOffset: true,
    polygonOffsetFactor: 3,
    polygonOffsetUnits: 3,
    side: THREE.DoubleSide,
} ) );
let outlines = new THREE.LineSegments( new THREE.BufferGeometry(), new THREE.LineBasicMaterial( { color: 0x030303 } ) );
app.scene.add( outlines, silhouette );
let ent = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/soldier.glb", {
    splitSubEntity: true,
    position: [0, 1, 0],
    rotation: [Math.PI / 2, 0, 0]
});
ent.addTo(app);
//
app.logInfo("正在根据三维模型生成二维平面图... (生成完成后可的右上角导出成dwg图)", 10000)
let model = ent.node;
let task = amLib.createProjectionTask({
    model,
    silhouette, 
    outlines, 
    updateProgressCb: (name, progress) => console.log(name, progress),
    updateVisible: undefined,
    ANGLE_THRESHOLD: 50
});
await task.promise();
//
let positions = outlines.geometry.attributes.position.array;
let entitys = []
for(let n = 0; n < positions.length; n+=6) {
    // vjmap3d 约定 CAD/地图的 y 对应世界坐标的 -z，导出 DWG 时 z 要取反，否则图形上下镜像
    let start = [positions[n], -positions[n + 2]];
    let end = [positions[n + 3], -positions[n + 5]];
    if (vjmap3d.approxArrayEquals(start, end)) continue; // 两点重合（默认容差 1e-5；第三参 error 可放宽，如 0.01）
    entitys.push({
        typename: "DbLine",
        start: start,
        end: end,
    })
}
console.log(entitys)
let doc = app.svc.toDbDoc({
    entitys
})
//console.log(doc)
let control = new vjmap3d.ButtonGroupControl({
    buttons: [
        {
            id: "export",
            html: "导出成CAD图",
            title: "把生成的平面图导出成cad图",
            style: {
                width: "130px"
            },
            onclick: async () => {
                let res = await app.svc.updateMap({
                    mapid: "silhouette_demo",
                    filedoc: doc,
                    mapopenway: vjmap3d.MapOpenWay.Memory,
                    style: {
                        backcolor: 0 // 如果div背景色是浅色，则设置为oxFFFFFF
                    }
                })
                let href = `${app.svc.baseUrl()}_cloud/#/map/${res.mapid}?version=${res.version}&mapopenway=Memory&vector=false&isFitMap=true`
                window.open(href)
            }
        }
    ]
});
app.addControl(control, "top-right");
</pre>
</mapFrame> 


## 类型定义

```ts
import { BufferGeometry, Group, InstancedMesh, InterleavedBufferAttribute, Line, Line3, LineSegments, Mesh, MeshPhongMaterial, Plane, Points, Triangle, TrianglesDrawModes, Vector3 } from 'three';
import {Side, Material, Ray, Sphere, Matrix4, Color,
    Intersection, Box3, Vector2, Raycaster, MeshBasicMaterial,
    LineBasicMaterial, DataTexture, BufferAttribute, Object3D } from 'three';
export declare class Brush extends Mesh {

  isBrush: boolean;
  markUpdated(): void;
  isDirty(): boolean;
  prepareGeometry(): void;
  disposeCacheData(): void;

}

export declare class TypedAttributeData {

  groupAttributes: Object[];
  groupCount: number;

  getType( name: String ): string;
  getTotalLength( name: String ): number;
  getGroupSet( index?: number ): Object;
  getGroupAttrArray( name: string, index?: number ): Array<number>;
  initializeArray( name: string, type: string ): void;
  clear(): void;
  delete( key: string ): void;
  reset(): void;

}

export declare enum CSGOperation{}
export declare const ADDITION: CSGOperation;
export declare const SUBTRACTION: CSGOperation;
export declare const REVERSE_SUBTRACTION: CSGOperation;
export declare const INTERSECTION: CSGOperation;
export declare const DIFFERENCE: CSGOperation;
export declare const HOLLOW_SUBTRACTION: CSGOperation;
export declare const HOLLOW_INTERSECTION: CSGOperation;

export declare class Evaluator {

  attributes: String[];
  useGroups: boolean;
  consolidateGroups: boolean; // 运行时属性名（上游 d.ts 误写为 consolidateMaterials）
  debug: OperationDebugData;

  evaluate( a: Brush, b: Brush, operation: CSGOperation, targetBrush?: Brush ): Brush;
  evaluate( a: Brush, b: Brush, operations: CSGOperation[], targetBrushes: Brush[] ): Brush[];

  evaluateHierarchy( root: Operation, target?: Brush ): Brush;

}

export declare class Operation extends Brush {

  isOperation: boolean;
  // operation
  markUpdated(): void;
  isDirty(): boolean;
  insertBefore( brush: Brush ): void;
  insertAfter( brush: Brush ): void;

}

export declare class OperationGroup extends Group {

  isOperationGroup: boolean; // 运行时属性名（上游 d.ts 误拼为 isOperatioinGroup）
  markUpdated(): void;
  isDirty(): boolean;

}

export declare class CullableTriangle extends Triangle {

  initFrom( other: Triangle ): void;
  updateSide( plane: Plane, triangle: Triangle, coplanarIndex: number ): void;

}

export declare class TrianglePool {

  getTriangle(): Triangle;
  clear(): void;
  reset(): void;

}

export declare class TriangleSplitter {

  trianglePool: TrianglePool;
  triangles: Triangle[];
  normal: Vector3;

  initialize( tri: Triangle ): void;
  splitByTriangle( triangle: Triangle ): void;
  splitByPlane( plane: Plane, triangle: Triangle, coplanarIndex: number ): void;
  reset(): void;

}

export declare class HalfEdgeMap {

  constructor( geometry?: BufferGeometry );
  getSiblingTriangleIndex( triIndex: number, edgeIndex: number ): number;
  getSiblingEdgeIndex( triIndex: number, edgeIndex: number ): number;
  updateFrom( geomtry: BufferGeometry ): void;

}

export declare class GridMaterial extends MeshPhongMaterial {

  enableGrid: boolean;

}
// ⚠️ 注意：主包 `vjmap3d.GridMaterial` 与 `createGridMaterialGpu` 均未导出（undefined）；
// 上面这个类由算法插件导出，用 `amLib.GridMaterial`（amLib = await vjmap3d.loadPluginAlgorithm()）。
// 网格地面助手实际导出名是 `vjmap3d.Grid`：Grid({cellSize,...}) 返回 { mesh, update }。

export declare function getTriangleDefinitions( ...triangles: Triangle[] ): String[];

export declare function logTriangleDefinitions( ...triangles: Triangle[] ): void;

export declare function generateRandomTriangleColors( geometry: BufferGeometry ): void;

export declare class TriangleSetHelper extends Group {

  constructor( triangles?: Triangle[] );

  setTriangles( triangles: Triangle[] ): void;

}

export declare class EdgesHelper extends LineSegments {

  constructor( edges?: Line3[] );

  setEdges( edges: Line3[] ): void;

}

export declare class TriangleIntersectData {

  intersects: Object;
  triangle: Triangle;

  constructor( tri: Triangle );
  addTriangle( index: number, tri: Triangle ): void;
  getIntersectArray(): Array<Triangle>;

}

export declare class TriangleIntersectionSets {

  addTriangleIntersection( ia: number, tribA: Triangle, ib: number, triB: Triangle ): void;
  getTrianglesAsArray( id?: number ): Array<Triangle>;
  getTriangleIndices(): Array<number>;
  getIntersectionIndices( id: number ): void;
  getIntersectionsAsArray( id?: number, id2?: number ): Array<Triangle>;

}

export declare class OperationDebugData {

  intersectionEdges: Line3[];
  enabled: boolean;

  addIntersectingTriangles( ia: number, triA: Triangle, ib: number, triB: Triangle ): void;
  addEdge( edge: Line3 ): void;
  reset(): void;

}

export declare class PointsHelper extends InstancedMesh {

  constructor( count?: number, points?: Vector3[] );

  setPoints( points: Vector3 ): void;

}

export declare class HalfEdgeHelper extends EdgesHelper {

  constructor( geometry?: BufferGeometry, halfEdges?: HalfEdgeMap );
  setHalfEdges( geometry: BufferGeometry, halfEdges: HalfEdgeMap ): void;

}

export declare function computeMeshVolume( mesh : Mesh | BufferGeometry ) : Number;


// ⚠️ 参数对象不能省略：createProjectionTask() 无参调用会抛 ReferenceError（默认值引用了未定义的 options）。
// ANGLE_THRESHOLD 只有显式传 null 才取 50；不传（undefined）时实际按 1° 处理，需要 50 请显式传 ANGLE_THRESHOLD: 50。
export declare  function createProjectionTask({ model, silhouette, outlines, updateProgressCb, updateVisible, ANGLE_THRESHOLD }?: any): {
    onUpdate: () => void;
    cancel: () => boolean;
    promise: (tm?: any) => Promise<any>;
}


export declare class ProjectionGenerator {
    [key: string]: any;
}


export declare class SilhouetteGenerator {
    [key: string]: any;
}


  
  // Contants
  export   declare enum SplitStrategy {}
  export   declare const CENTER: SplitStrategy;
  export  declare const AVERAGE: SplitStrategy;
  export  declare const SAH: SplitStrategy;
  
  export  declare enum ShapecastIntersection {}
  export  declare const NOT_INTERSECTED: ShapecastIntersection;
  export  declare const INTERSECTED: ShapecastIntersection;
  export  declare const CONTAINED: ShapecastIntersection;
  
  // MeshBVH
  export  declare interface HitPointInfo {
    point: Vector3;
    distance: number;
    faceIndex: number;
  }
  
  export  declare interface MeshBVHOptions {
    strategy?: SplitStrategy;
    maxDepth?: number;
    maxLeafTris?: number;
    setBoundingBox?: boolean;
    useSharedArrayBuffer?: boolean;
    verbose?: boolean;
    onProgress?: ( progress: number ) => void;
  }
  
  export  declare interface MeshBVHSerializeOptions {
    cloneBuffers?: boolean;
  }
  
  export  declare interface MeshBVHDeserializeOptions {
    setIndex?: boolean;
  }
  
  
  export declare class MeshBVH {
  
    readonly geometry: BufferGeometry;
  
    static serialize( bvh: MeshBVH, options?: MeshBVHSerializeOptions ): SerializedBVH;
  
    static deserialize(
      data: SerializedBVH,
      geometry: BufferGeometry,
      options?: MeshBVHDeserializeOptions
    ): MeshBVH;
  
    constructor( geometry: BufferGeometry, options?: MeshBVHOptions );
  
    raycast( ray: Ray, materialOrSide: Side | Array<Material> | Material ): Array<Intersection>
  
    raycastFirst( ray: Ray, materialOrSide: Side | Array<Material> | Material ): Intersection;
  
    intersectsSphere( sphere: Sphere ): boolean;
  
    intersectsBox( box: Box3, boxToMesh: Matrix4 ): boolean;
  
    intersectsGeometry( geometry: BufferGeometry, geometryToBvh: Matrix4 ): boolean;
  
    closestPointToPoint(
      point: Vector3,
      target?: HitPointInfo,
      minThreshold?: number,
      maxThreshold?: number
    ): HitPointInfo | null;
  
    closestPointToGeometry(
      geometry: BufferGeometry,
      geometryToBvh: Matrix4,
      target1?: HitPointInfo,
      target2?: HitPointInfo,
      minThreshold?: number,
      maxThreshold?: number
    ): HitPointInfo | null;
  
    // union types to enable at least one of two functions:
    shapecast(
      callbacks: {
  
        intersectsBounds: (
          box: Box3,
          isLeaf: boolean,
          score: number | undefined,
          depth: number,
          nodeIndex: number
        ) => ShapecastIntersection|boolean,
  
        boundsTraverseOrder?: (
          box: Box3
        ) => number,
  
      } & ( {
  
        intersectsRange: (
          triangleOffset: number,
          triangleCount: number,
          contained: boolean,
          depth: number,
          nodeIndex: number,
          box: Box3
        ) => boolean,
  
      } | {
  
        intersectsTriangle: (
          triangle: ExtendedTriangle,
          triangleIndex: number,
          contained: boolean,
          depth: number
        ) => boolean|void
  
      } )
    ): boolean;
  
    // union types to enable at least one of two functions:
    bvhcast(
      otherBVH: MeshBVH,
      matrixToLocal: Matrix4,
      callbacks: ( {
  
        intersectsRanges: (
          offset1: number,
          count1: number,
          offset2: number,
          count2: number,
          depth1: number,
          index1: number,
          depth2: number,
          index2: number
        ) => boolean
  
      } | {
  
        intersectsTriangles: (
          triangle1: ExtendedTriangle,
          triangle2: ExtendedTriangle,
          i1: number,
          i2: number,
          depth1: number,
          index1: number,
          depth2: number,
          index2: number,
        ) => boolean,
  
      } )
    ): boolean;
  
    traverse(
      callback: (
        depth: number,
        isLeaf: boolean,
        boundingData: ArrayBuffer,
        offsetOrSplit: number,
        count: number
      ) => void,
      rootIndex?: number
    ): void;
  
    refit( nodeIndices?: Array<number> | Set<number> ): void;
  
    getBoundingBox( target: Box3 ): Box3;
  
  }
  
  // SerializedBVH
  export class SerializedBVH {
  
    roots: Array<ArrayBuffer>;
    index: ArrayBufferView;
  
  }
  
  // MeshBVHHelper
  export   declare class MeshBVHHelper extends Group {
  
    opacity: number;
    depth: number;
    displayParents: boolean;
    displayEdges: boolean;
    edgeMaterial: LineBasicMaterial;
    meshMaterial: MeshBasicMaterial;
  
    constructor( mesh: Mesh, depth?: number );
  
    update(): void;
  
    get color(): Color;
  
  }
  
  // THREE.js Extensions
  
  export   declare function computeBoundsTree( options?: MeshBVHOptions ): MeshBVH;
  
  export   declare function disposeBoundsTree(): void;
  
  export   declare function acceleratedRaycast(
    raycaster: Raycaster,
    intersects: Array<Intersection>
  ): void;
  
  
  // Debug functions
  export declare function estimateMemoryInBytes( bvh: MeshBVH ): number;
  
  export declare interface ExtremeInfo {
    nodeCount: number;
    leafNodeCount: number;
    surfaceAreaScore: number;
    depth: {min: number, max: number};
    tris: {min: number, max: number};
    splits: [number, number, number];
  }
  
  export declare function getBVHExtremes( bvh :MeshBVH ): Array<ExtremeInfo>;
  
  export declare function validateBounds( bvh: MeshBVH ): boolean;
  
  export interface TreeNode {
    bounds: Box3;
    count: number;
    offset: number;
    left?: TreeNode;
    right?: TreeNode;
  }
  
  export declare function getJSONStructure( bvh: MeshBVH ): TreeNode;
  
  // Triangle Utilities
  export declare interface HitTriangleInfo {
    face: {
      a: number,
      b: number,
      c: number,
      materialIndex: number,
      normal: Vector3
    },
    uv: Vector2
  }
  
  export declare function getTriangleHitPointInfo(
    point: Vector3,
    geometry : BufferGeometry,
    triangleIndex: number,
    target?: HitTriangleInfo
  ): HitTriangleInfo
  
  // Shader Utilities
  declare class VertexAttributeTexture extends DataTexture {
  
    overrideItemSize: number | null;
    updateFrom( attribute: BufferAttribute ): void;
  
  }
  
  // export declare class FloatVertexAttributeTexture extends VertexAttributeTexture {}
  // export declare class UIntVertexAttributeTexture extends VertexAttributeTexture {}
  // export declare class IntVertexAttributeTexture extends VertexAttributeTexture {}
  
  export declare class MeshBVHUniformStruct {
  
    updateFrom( bvh: MeshBVH ): void;
    dispose(): void;
  
  }
  
  export declare const shaderStructs: string;
  export  declare const shaderFunctions: string;
  
  // Math classes
  export  declare class ExtendedTriangle extends Triangle {
  
    needsUpdate : boolean;
  
    intersectsTriangle( other : Triangle, target? : Line3 ) : boolean;
    intersectsSphere( sphere : Sphere ) : boolean;
    closestPointToSegment( segment : Line3, target1? : Vector3, target2? : Vector3 ) : number;
    distanceToPoint( point : Vector3 ) : number;
    distanceToTriangle( tri : Triangle ) : number;
  
  }
  
  export  declare class OrientedBox {
  
    min: Vector3;
    max: Vector3;
    matrix : Matrix4;
    needsUpdate : boolean;
  
    constructor( min : Vector3, max : Vector3 );
    set( min : Vector3, max : Vector3, matrix : Matrix4 ) : OrientedBox;
    intersectsBox( box : Box3 ) : boolean;
    intersectsTriangle( tri : Triangle ) : boolean;
    closestPointToPoint( point : Vector3, target? : Vector3 ) : number;
    distanceToPoint( point : Vector3 ) : number;
    distanceToBox( box : Box3, threshold? : number, target1? : Vector3, target2? : Vector3 ) : number;
  
  }
  
  export declare  class StaticGeometryGenerator {
  
    useGroups : boolean;
    attributes : Array<string>;
    applyWorldTransforms : boolean;
  
    constructor( objects : Array<Object3D> | Object3D );
    getMaterials() : Array<Material>;
    generate( target? : BufferGeometry ) : BufferGeometry;
  
  }

export declare function mergeGeometries(geometries: BufferGeometry[], useGroups?: boolean): BufferGeometry;
export declare function mergeAttributes(attributes: BufferAttribute[]): BufferAttribute;
export declare function interleaveAttributes(attributes: BufferAttribute[]): InterleavedBufferAttribute;
export declare function estimateBytesUsed(geometry: BufferGeometry): number;
export declare function mergeVertices(geometry: BufferGeometry, tolerance?: number): BufferGeometry;
export declare function toTrianglesDrawMode(geometry: BufferGeometry, drawMode: TrianglesDrawModes): BufferGeometry;
export declare function computeMorphedAttributes(object: Mesh | Line | Points): object;
export declare function computeMikkTSpaceTangents(
    geometry: BufferGeometry,
    MikkTSpace: unknown,
    negateSign?: boolean,
): BufferGeometry;
export declare function mergeGroups(geometry: BufferGeometry): BufferGeometry;

/**
 * Modifies the supplied geometry if it is non-indexed, otherwise creates a new, non-indexed geometry. Returns the
 * geometry with smooth normals everywhere except faces that meet at an angle greater than the crease angle.
 *
 * @param geometry The input geometry.
 * @param creaseAngle The crease angle in radians.
 */
export declare function toCreasedNormals(geometry: BufferGeometry, creaseAngle?: number): BufferGeometry;


export declare class Delatin {
  data: number[];
  width: number;
  height: number;
  coords: any[];
  triangles: any[];
  _halfedges: any[];
  _candidates: any[];
  _queueIndices: any[];
  _queue: any[];
  _errors: any[];
  _rms: any[];
  _pending: any[];
  _pendingLen: number;
  _rmsSum: number;
  constructor(data: number[], width: number, height: number);
  run(maxError?: number): void;
  refine(): void;
  getMaxError(): any;
  getRMSD(): number;
  heightAt(x: any, y: any): number;
}
```