完成下列功能:
1.板件显示 2.板件选中状态 3.标注显示 4.相机控制.
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
							
								
								
									
										15
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
{
 | 
			
		||||
    // 使用 IntelliSense 了解相关属性。 
 | 
			
		||||
    // 悬停以查看现有属性的描述。
 | 
			
		||||
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
 | 
			
		||||
    "version": "0.2.0",
 | 
			
		||||
    "configurations": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "chrome",
 | 
			
		||||
            "request": "launch",
 | 
			
		||||
            "name": "启动 Chrome 并打开 localhost",
 | 
			
		||||
            "url": "http://localhost:666",
 | 
			
		||||
            "webRoot": "${workspaceFolder}"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
{
 | 
			
		||||
    "editor.formatOnSave": true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6939
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6939
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										20
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "cadview",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "dist/index.js",
 | 
			
		||||
  "types": "dist/index.d.ts",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "build": "tsc"
 | 
			
		||||
  },
 | 
			
		||||
  "author": "",
 | 
			
		||||
  "license": "ISC",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/node": "^10.1.2",
 | 
			
		||||
    "@types/three": "^0.92.0",
 | 
			
		||||
    "typescript": "^2.8.3"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "three": "^0.92.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										249
									
								
								src/CameraControls.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								src/CameraControls.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,249 @@
 | 
			
		||||
import * as THREE from 'three';
 | 
			
		||||
 | 
			
		||||
import { KeyBoard, MouseKey } from './KeyEnum';
 | 
			
		||||
import { Vector3 } from 'three';
 | 
			
		||||
import { Viewer } from './Viewer';
 | 
			
		||||
 | 
			
		||||
//控制类型
 | 
			
		||||
enum CameraControlsEnabled
 | 
			
		||||
{
 | 
			
		||||
    Rotate = 1,
 | 
			
		||||
    Zoom = 2,
 | 
			
		||||
    Pan = 4,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//相机控制状态
 | 
			
		||||
export enum CameraControlState
 | 
			
		||||
{
 | 
			
		||||
    Null = 0, Pan = 1, Rotate = 2, Scale = 3
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class CameraControls
 | 
			
		||||
{
 | 
			
		||||
    m_TouthTypeList = [CameraControlState.Rotate, CameraControlState.Scale, CameraControlState.Pan];
 | 
			
		||||
    m_domElement: HTMLElement;//HTMLDocument
 | 
			
		||||
    //起始点击
 | 
			
		||||
    m_StartClickPoint: THREE.Vector3 = new THREE.Vector3();
 | 
			
		||||
    m_EndClickPoint: THREE.Vector3 = new THREE.Vector3();
 | 
			
		||||
    m_DollyStart: THREE.Vector2 = new THREE.Vector2();
 | 
			
		||||
    m_DollyEnd: THREE.Vector2 = new THREE.Vector2();
 | 
			
		||||
 | 
			
		||||
    m_KeyDown = new Map<KeyBoard, boolean>();
 | 
			
		||||
    m_MouseDown = new Map<MouseKey, boolean>();
 | 
			
		||||
 | 
			
		||||
    //状态
 | 
			
		||||
    m_State: CameraControlState = CameraControlState.Null;
 | 
			
		||||
    m_Viewer: Viewer;
 | 
			
		||||
    //左键使用旋转
 | 
			
		||||
    m_LeftUseRotate: boolean = true;
 | 
			
		||||
 | 
			
		||||
    constructor(viewer: Viewer)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Viewer = viewer;
 | 
			
		||||
        this.m_domElement = viewer.m_Render.domElement.parentElement;
 | 
			
		||||
        this.RegisterEvent();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RegisterEvent()
 | 
			
		||||
    {
 | 
			
		||||
        if (this.m_domElement)
 | 
			
		||||
        {
 | 
			
		||||
            this.m_domElement.addEventListener("mousedown", this.onMouseDown, false)
 | 
			
		||||
            this.m_domElement.addEventListener("mousemove", this.onMouseMove, false)
 | 
			
		||||
            this.m_domElement.addEventListener("mouseup", this.onMouseUp, false)
 | 
			
		||||
            window.addEventListener("keydown", this.onKeyDown, false);
 | 
			
		||||
            window.addEventListener("keyup", this.onKeyUp, false);
 | 
			
		||||
            this.m_domElement.addEventListener('wheel', this.onMouseWheel, false);
 | 
			
		||||
 | 
			
		||||
            this.m_domElement.addEventListener('touchstart', this.onTouchStart, false);
 | 
			
		||||
            this.m_domElement.addEventListener('touchend', this.onTouchEnd, false);
 | 
			
		||||
            this.m_domElement.addEventListener('touchmove', this.onTouchMove, false);
 | 
			
		||||
 | 
			
		||||
            window.addEventListener("blur", this.onBlur, false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * 窗体失去焦点时.
 | 
			
		||||
     * 
 | 
			
		||||
     * @memberof CameraControls
 | 
			
		||||
     */
 | 
			
		||||
    onBlur = () =>
 | 
			
		||||
    {
 | 
			
		||||
        this.m_KeyDown.clear();
 | 
			
		||||
        this.m_MouseDown.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //触屏开始事件
 | 
			
		||||
    onTouchStart = (event: TouchEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Viewer.UpdateLockTarget();
 | 
			
		||||
        this.m_StartClickPoint.set(event.touches[0].pageX, event.touches[0].pageY, 0);
 | 
			
		||||
        if (event.touches.length < 4)
 | 
			
		||||
        {
 | 
			
		||||
            if (event.touches.length == 2)
 | 
			
		||||
            {
 | 
			
		||||
                var dx = event.touches[0].pageX - event.touches[1].pageX;
 | 
			
		||||
                var dy = event.touches[0].pageY - event.touches[1].pageY;
 | 
			
		||||
                var distance = Math.sqrt(dx * dx + dy * dy);
 | 
			
		||||
                this.m_DollyStart.set(0, distance);
 | 
			
		||||
            }
 | 
			
		||||
            this.m_State = this.m_TouthTypeList[event.touches.length - 1];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    onTouchEnd = (event: TouchEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        this.m_State = CameraControlState.Null;
 | 
			
		||||
    }
 | 
			
		||||
    onTouchMove = (event: TouchEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        event.preventDefault();
 | 
			
		||||
        event.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        this.m_EndClickPoint.set(event.touches[0].pageX, event.touches[0].pageY, 0);
 | 
			
		||||
 | 
			
		||||
        let vec = this.m_EndClickPoint.clone().sub(this.m_StartClickPoint);
 | 
			
		||||
        switch (this.m_State)
 | 
			
		||||
        {
 | 
			
		||||
            case CameraControlState.Pan:
 | 
			
		||||
                {
 | 
			
		||||
                    this.m_Viewer.Pan(vec);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            case CameraControlState.Scale:
 | 
			
		||||
                {
 | 
			
		||||
                    var dx = event.touches[0].pageX - event.touches[1].pageX;
 | 
			
		||||
                    var dy = event.touches[0].pageY - event.touches[1].pageY;
 | 
			
		||||
 | 
			
		||||
                    var distance = Math.sqrt(dx * dx + dy * dy);
 | 
			
		||||
                    this.m_DollyEnd.set(0, distance);
 | 
			
		||||
                    if (distance > this.m_DollyStart.y)
 | 
			
		||||
                    {
 | 
			
		||||
                        this.m_Viewer.Zoom(0.95);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        this.m_Viewer.Zoom(1.05)
 | 
			
		||||
                    }
 | 
			
		||||
                    this.m_DollyStart.copy(this.m_DollyEnd);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            case CameraControlState.Rotate:
 | 
			
		||||
                {
 | 
			
		||||
                    this.m_Viewer.Rotate(vec.multiplyScalar(2));
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
        this.m_StartClickPoint.copy(this.m_EndClickPoint);
 | 
			
		||||
        this.m_Viewer.m_bNeedUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
    beginRotate()
 | 
			
		||||
    {
 | 
			
		||||
        this.m_State = CameraControlState.Rotate;
 | 
			
		||||
        this.m_Viewer.UpdateLockTarget();
 | 
			
		||||
    }
 | 
			
		||||
    //鼠标    
 | 
			
		||||
    onMouseDown = (event: MouseEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        event.preventDefault();
 | 
			
		||||
        let key: MouseKey = event.button;
 | 
			
		||||
        this.m_MouseDown.set(key, true);
 | 
			
		||||
        this.m_StartClickPoint.set(event.offsetX, event.offsetY, 0);
 | 
			
		||||
 | 
			
		||||
        switch (key)
 | 
			
		||||
        {
 | 
			
		||||
            case MouseKey.Left:
 | 
			
		||||
                {
 | 
			
		||||
                    if (this.m_LeftUseRotate)
 | 
			
		||||
                    {
 | 
			
		||||
                        this.beginRotate();
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            case MouseKey.Middle:
 | 
			
		||||
                {
 | 
			
		||||
                    if (this.m_KeyDown.get(KeyBoard.Control))
 | 
			
		||||
                    {
 | 
			
		||||
                        this.beginRotate();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        this.m_State = CameraControlState.Pan;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            case MouseKey.Right:
 | 
			
		||||
                {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    onMouseUp = (event: MouseEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        event.preventDefault();
 | 
			
		||||
        this.m_State = CameraControlState.Null;
 | 
			
		||||
        this.m_MouseDown.set(event.button, false);
 | 
			
		||||
    }
 | 
			
		||||
    onMouseMove = (event: MouseEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        event.preventDefault();
 | 
			
		||||
        this.m_EndClickPoint.set(event.offsetX, event.offsetY, 0);
 | 
			
		||||
        let changeVec = this.m_EndClickPoint.clone().sub(this.m_StartClickPoint);
 | 
			
		||||
        this.m_StartClickPoint.copy(this.m_EndClickPoint);
 | 
			
		||||
        if (
 | 
			
		||||
            (this.m_LeftUseRotate ||
 | 
			
		||||
                (this.m_KeyDown.get(KeyBoard.Control))
 | 
			
		||||
            )
 | 
			
		||||
            && this.m_State == CameraControlState.Rotate
 | 
			
		||||
        )
 | 
			
		||||
        {
 | 
			
		||||
            this.m_Viewer.Rotate(changeVec);
 | 
			
		||||
        }
 | 
			
		||||
        switch (this.m_State)
 | 
			
		||||
        {
 | 
			
		||||
            case CameraControlState.Pan:
 | 
			
		||||
                {
 | 
			
		||||
                    this.m_Viewer.Pan(changeVec);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            case CameraControlState.Rotate:
 | 
			
		||||
                {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            case CameraControlState.Scale:
 | 
			
		||||
                {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * 鼠标滚轮事件
 | 
			
		||||
     * 
 | 
			
		||||
     * @memberof CameraControls
 | 
			
		||||
     */
 | 
			
		||||
    onMouseWheel = (event: WheelEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        event.preventDefault();
 | 
			
		||||
        event.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        let pt = new THREE.Vector3(event.offsetX, event.offsetY, 0);
 | 
			
		||||
 | 
			
		||||
        this.m_Viewer.ScreenToWorld(pt, new Vector3().setFromMatrixColumn(this.m_Viewer.m_Camera.Camera.matrixWorld, 2));
 | 
			
		||||
        if (event.deltaY < 0)
 | 
			
		||||
        {
 | 
			
		||||
            this.m_Viewer.Zoom(0.6, pt);
 | 
			
		||||
        }
 | 
			
		||||
        else if (event.deltaY > 0)
 | 
			
		||||
        {
 | 
			
		||||
            this.m_Viewer.Zoom(1.4, pt);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    //按键
 | 
			
		||||
    onKeyDown = (event: KeyboardEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        this.m_KeyDown.set(event.keyCode, true);
 | 
			
		||||
    }
 | 
			
		||||
    onKeyUp = (event: KeyboardEvent) =>
 | 
			
		||||
    {
 | 
			
		||||
        this.m_KeyDown.set(event.keyCode, false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										220
									
								
								src/CameraUpdate.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								src/CameraUpdate.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,220 @@
 | 
			
		||||
import * as THREE from 'three';
 | 
			
		||||
import { Vector3 } from 'three';
 | 
			
		||||
import { Orbit } from './Orbit';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * 相机的控制.
 | 
			
		||||
 * ->切换相机
 | 
			
		||||
 * ->设置视口大小
 | 
			
		||||
 * ->旋转和移动相机.
 | 
			
		||||
 * 
 | 
			
		||||
 * @export
 | 
			
		||||
 * @class ViewCameraManage
 | 
			
		||||
 */
 | 
			
		||||
export class CameraUpdate
 | 
			
		||||
{
 | 
			
		||||
    private m_CurCamera: THREE.Camera;
 | 
			
		||||
    private m_CameraArray: Map<any, THREE.Camera> = new Map<any, THREE.Camera>();
 | 
			
		||||
 | 
			
		||||
    //视口的画布大小
 | 
			
		||||
    private m_Width: number;
 | 
			
		||||
    private m_Height: number;
 | 
			
		||||
    //视口显示的高度
 | 
			
		||||
    private m_ViewHeight: number = 10;
 | 
			
		||||
 | 
			
		||||
    //观察的位置
 | 
			
		||||
    private m_Target: THREE.Vector3 = new THREE.Vector3();
 | 
			
		||||
    //观察向量
 | 
			
		||||
    private m_Direction: THREE.Vector3 = new THREE.Vector3(0, 0, -1);
 | 
			
		||||
    //观察的轨道.
 | 
			
		||||
    private m_Orbit: Orbit = new Orbit();
 | 
			
		||||
 | 
			
		||||
    constructor()
 | 
			
		||||
    {
 | 
			
		||||
        this.m_CameraArray.set(THREE.OrthographicCamera, new THREE.OrthographicCamera(-2, 2, 2, -2,
 | 
			
		||||
            -100000, 100000));
 | 
			
		||||
 | 
			
		||||
        this.m_CameraArray.set(THREE.PerspectiveCamera, new THREE.PerspectiveCamera(50, 1, 0.01, 10000));
 | 
			
		||||
 | 
			
		||||
        this.m_CurCamera = this.m_CameraArray.get(THREE.OrthographicCamera);
 | 
			
		||||
 | 
			
		||||
        this.m_Orbit.UpdateRoValue(this.m_Direction);
 | 
			
		||||
 | 
			
		||||
        this.UpdateUp();
 | 
			
		||||
 | 
			
		||||
        this.Update();
 | 
			
		||||
    }
 | 
			
		||||
    get Aspect(): number
 | 
			
		||||
    {
 | 
			
		||||
        return this.m_Width / this.m_Height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get Camera(): THREE.Camera
 | 
			
		||||
    {
 | 
			
		||||
        return this.m_CurCamera;
 | 
			
		||||
    }
 | 
			
		||||
    get ViewHeight()
 | 
			
		||||
    {
 | 
			
		||||
        return this.m_ViewHeight;
 | 
			
		||||
    }
 | 
			
		||||
    set ViewHeight(height)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_ViewHeight = THREE.Math.clamp(height, 1e-8, 1e8);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SetSize(width: number, height: number)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Width = width;
 | 
			
		||||
        this.m_Height = height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 平移相机.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param {THREE.Vector3} mouseMove
 | 
			
		||||
     * @memberof CameraControl
 | 
			
		||||
     */
 | 
			
		||||
    Pan(mouseMove: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        mouseMove.y *= -1;
 | 
			
		||||
        mouseMove.multiplyScalar(-this.m_ViewHeight / this.m_Height);
 | 
			
		||||
        mouseMove.applyQuaternion(this.Camera.quaternion);
 | 
			
		||||
        this.m_Target.add(mouseMove);
 | 
			
		||||
        this.Update();
 | 
			
		||||
    }
 | 
			
		||||
    Rotate(mouseMove: THREE.Vector3, target: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Orbit.RoX -= mouseMove.y * 0.003;
 | 
			
		||||
        this.m_Orbit.RoZ -= mouseMove.x * 0.003;
 | 
			
		||||
 | 
			
		||||
        //缓存观察点
 | 
			
		||||
        let oldTargetFormCameraSpace = target.clone().applyMatrix4(this.Camera.matrixWorldInverse);
 | 
			
		||||
 | 
			
		||||
        this.m_Orbit.UpdateDirection(this.m_Direction);
 | 
			
		||||
        this.UpdateUp();
 | 
			
		||||
        this.Update();
 | 
			
		||||
 | 
			
		||||
        //-----还原观察点
 | 
			
		||||
        //得到新的观察点相对于相机的位置
 | 
			
		||||
        let newTargetFormCameraSpace = target.clone().applyMatrix4(this.Camera.matrixWorldInverse);
 | 
			
		||||
        //减去原先的位置. 得到观测点在相机内移动的向量
 | 
			
		||||
        newTargetFormCameraSpace.sub(oldTargetFormCameraSpace);
 | 
			
		||||
        //乘以相机的矩阵. 得到向量在世界坐标系的位置
 | 
			
		||||
        newTargetFormCameraSpace.applyMatrix4(this.Camera.matrix);
 | 
			
		||||
        //因为使用的是点变换,所以减去基点,得到向量
 | 
			
		||||
        newTargetFormCameraSpace.sub(this.Camera.position);
 | 
			
		||||
        //加上移动的向量. 使得观察点时钟在相机的某个位置
 | 
			
		||||
        this.m_Target.add(newTargetFormCameraSpace);
 | 
			
		||||
 | 
			
		||||
        this.Update();
 | 
			
		||||
    }
 | 
			
		||||
    Zoom(scale: number, scaleCenter?: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        if (this.Camera instanceof THREE.OrthographicCamera)
 | 
			
		||||
        {
 | 
			
		||||
            this.ViewHeight *= scale;
 | 
			
		||||
            if (scaleCenter)
 | 
			
		||||
            {
 | 
			
		||||
                this.m_Target.sub(scaleCenter);
 | 
			
		||||
                this.m_Target.multiplyScalar(scale);
 | 
			
		||||
                this.m_Target.add(scaleCenter);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (this.Camera instanceof THREE.PerspectiveCamera)
 | 
			
		||||
        {
 | 
			
		||||
            let add = scale > 1 ? 1 : -1;
 | 
			
		||||
            add *= this.Camera.position.distanceTo(this.m_Target) / 10;
 | 
			
		||||
            this.m_Target.add(this.m_Direction.clone().multiplyScalar(-add));
 | 
			
		||||
        }
 | 
			
		||||
        this.Update();
 | 
			
		||||
    }
 | 
			
		||||
    ZoomExtensBox3(box3: THREE.Box3)
 | 
			
		||||
    {
 | 
			
		||||
        if (!box3) return;
 | 
			
		||||
        this.Camera.updateMatrixWorld(false);
 | 
			
		||||
        //变换到相机坐标系
 | 
			
		||||
        box3.applyMatrix4(this.Camera.matrixWorldInverse);
 | 
			
		||||
        //
 | 
			
		||||
        box3.getCenter(this.m_Target);
 | 
			
		||||
        //世界坐标系
 | 
			
		||||
        this.m_Target.applyMatrix4(this.Camera.matrix);
 | 
			
		||||
        //size
 | 
			
		||||
        let size = box3.getSize(new Vector3());
 | 
			
		||||
        //宽高比
 | 
			
		||||
        let aspectRatio = size.x / size.y;
 | 
			
		||||
 | 
			
		||||
        let viewAspectRatio = this.Aspect;
 | 
			
		||||
        //
 | 
			
		||||
        if (aspectRatio > viewAspectRatio)
 | 
			
		||||
        {
 | 
			
		||||
            this.m_ViewHeight = size.x / viewAspectRatio;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            this.m_ViewHeight = size.y;
 | 
			
		||||
        }
 | 
			
		||||
        this.Update();
 | 
			
		||||
    }
 | 
			
		||||
    LookAt(dir: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Orbit.UpdateRoValue(dir);
 | 
			
		||||
        this.m_Direction.copy(dir);
 | 
			
		||||
        this.UpdateUp();
 | 
			
		||||
        this.Update();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    UpdateUp()
 | 
			
		||||
    {
 | 
			
		||||
        Orbit.ComputUpDirection(this.m_Direction, this.Camera.up);
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据视口大小,设置相机视口范围.
 | 
			
		||||
     * 
 | 
			
		||||
     * @returns 
 | 
			
		||||
     * @memberof CameraControl
 | 
			
		||||
     */
 | 
			
		||||
    Update()
 | 
			
		||||
    {
 | 
			
		||||
        this.Camera.position.copy(this.m_Target);
 | 
			
		||||
 | 
			
		||||
        if (this.Camera instanceof THREE.OrthographicCamera)
 | 
			
		||||
        {
 | 
			
		||||
            this.Camera.left = this.Aspect * this.m_ViewHeight / -2;
 | 
			
		||||
            this.Camera.right = this.Aspect * this.m_ViewHeight / 2;
 | 
			
		||||
            this.Camera.bottom = this.m_ViewHeight / -2;
 | 
			
		||||
            this.Camera.top = this.m_ViewHeight / 2;
 | 
			
		||||
 | 
			
		||||
            this.Camera.position.sub(this.m_Direction);
 | 
			
		||||
        }
 | 
			
		||||
        else if (this.Camera instanceof THREE.PerspectiveCamera)
 | 
			
		||||
        {
 | 
			
		||||
            this.Camera.aspect = this.Aspect;
 | 
			
		||||
            let distens = (this.m_ViewHeight / 2) / (Math.tan(THREE.Math.degToRad(this.Camera.fov) / 2));
 | 
			
		||||
 | 
			
		||||
            this.Camera.position.sub(this.m_Direction.clone().multiplyScalar(distens));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.Camera.lookAt(this.m_Target);
 | 
			
		||||
        this.Camera.updateProjectionMatrix();
 | 
			
		||||
        this.Camera.updateMatrixWorld(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SwitchCamera()
 | 
			
		||||
    {
 | 
			
		||||
        if (this.Camera instanceof THREE.OrthographicCamera)
 | 
			
		||||
        {
 | 
			
		||||
            this.m_CurCamera = this.m_CameraArray.get(THREE.PerspectiveCamera);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            this.m_CurCamera = this.m_CameraArray.get(THREE.OrthographicCamera);
 | 
			
		||||
        }
 | 
			
		||||
        this.UpdateUp();
 | 
			
		||||
        this.Update();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										288
									
								
								src/ColorPalette.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								src/ColorPalette.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,288 @@
 | 
			
		||||
import * as THREE from 'three';
 | 
			
		||||
const ColorPalette = [
 | 
			
		||||
    [255, 0, 0, 255],    //----- 0 - lets make it red for an example
 | 
			
		||||
    //[255, 255, 255, 255],//----- 0 - ByBlock - White
 | 
			
		||||
    [255, 0, 0, 255],    //----- 1 - Red
 | 
			
		||||
    // [255, 0, 0, 255],    //----- 1 - Red
 | 
			
		||||
    [255, 255, 0, 255],    //----- 2 - Yellow
 | 
			
		||||
    [0, 255, 0, 255],    //----- 3 - Green
 | 
			
		||||
    [0, 255, 255, 255],    //----- 4 - Cyan
 | 
			
		||||
    [0, 0, 255, 255],    //----- 5 - Blue
 | 
			
		||||
    [255, 0, 255, 255],    //----- 6 - Magenta
 | 
			
		||||
    // [255, 0, 0, 255],    //----- 7 - More red Red
 | 
			
		||||
    // [255, 0, 0, 255],    //----- 8 - More red Red
 | 
			
		||||
    // [255, 0, 0, 255],    //----- 9 - More red Red
 | 
			
		||||
    [255, 255, 255, 255],//----- 7 - White
 | 
			
		||||
    [255, 255, 255, 255],//----- 8
 | 
			
		||||
    [255, 255, 255, 255],//----- 9
 | 
			
		||||
    [255, 0, 0, 255],    //----- 10
 | 
			
		||||
    [255, 127, 127, 255],//----- 11
 | 
			
		||||
    [165, 0, 0, 255],    //----- 12
 | 
			
		||||
    [165, 82, 82, 255],    //----- 13
 | 
			
		||||
    [127, 0, 0, 255],    //----- 14
 | 
			
		||||
    [127, 63, 63, 255],    //----- 15
 | 
			
		||||
    [76, 0, 0, 255],        //----- 16
 | 
			
		||||
    [76, 38, 38, 255],    //----- 17
 | 
			
		||||
    [38, 0, 0, 255],        //----- 18
 | 
			
		||||
    [38, 19, 19, 255],    //----- 19
 | 
			
		||||
    [255, 63, 0, 255],    //----- 20
 | 
			
		||||
    [255, 159, 127, 255],//----- 21
 | 
			
		||||
    [165, 41, 0, 255],    //----- 22
 | 
			
		||||
    [165, 103, 82, 255],    //----- 23
 | 
			
		||||
    [127, 31, 0, 255],    //----- 24
 | 
			
		||||
    [127, 79, 63, 255],    //----- 25
 | 
			
		||||
    [76, 19, 0, 255],    //----- 26
 | 
			
		||||
    [76, 47, 38, 255],    //----- 27
 | 
			
		||||
    [38, 9, 0, 255],        //----- 28
 | 
			
		||||
    [38, 23, 19, 255],    //----- 29
 | 
			
		||||
    [255, 127, 0, 255],    //----- 30
 | 
			
		||||
    [255, 191, 127, 255],//----- 31
 | 
			
		||||
    [165, 82, 0, 255],    //----- 32
 | 
			
		||||
    [165, 124, 82, 255],    //----- 33
 | 
			
		||||
    [127, 63, 0, 255],    //----- 34
 | 
			
		||||
    [127, 95, 63, 255],    //----- 35
 | 
			
		||||
    [76, 38, 0, 255],    //----- 36
 | 
			
		||||
    [76, 57, 38, 255],    //----- 37
 | 
			
		||||
    [38, 19, 0, 255],    //----- 38
 | 
			
		||||
    [38, 28, 19, 255],    //----- 39
 | 
			
		||||
    [255, 191, 0, 255],    //----- 40
 | 
			
		||||
    [255, 223, 127, 255],//----- 41
 | 
			
		||||
    [165, 124, 0, 255],    //----- 42
 | 
			
		||||
    [165, 145, 82, 255],    //----- 43
 | 
			
		||||
    [127, 95, 0, 255],    //----- 44
 | 
			
		||||
    [127, 111, 63, 255],    //----- 45
 | 
			
		||||
    [76, 57, 0, 255],    //----- 46
 | 
			
		||||
    [76, 66, 38, 255],    //----- 47
 | 
			
		||||
    [38, 28, 0, 255],    //----- 48
 | 
			
		||||
    [38, 33, 19, 255],    //----- 49
 | 
			
		||||
    [255, 255, 0, 255],    //----- 50
 | 
			
		||||
    [255, 255, 127, 255],//----- 51
 | 
			
		||||
    [165, 165, 0, 255],    //----- 52
 | 
			
		||||
    [165, 165, 82, 255],    //----- 53
 | 
			
		||||
    [127, 127, 0, 255],    //----- 54
 | 
			
		||||
    [127, 127, 63, 255],    //----- 55
 | 
			
		||||
    [76, 76, 0, 255],    //----- 56
 | 
			
		||||
    [76, 76, 38, 255],    //----- 57
 | 
			
		||||
    [38, 38, 0, 255],    //----- 58
 | 
			
		||||
    [38, 38, 19, 255],    //----- 59
 | 
			
		||||
    [191, 255, 0, 255],    //----- 60
 | 
			
		||||
    [223, 255, 127, 255],//----- 61
 | 
			
		||||
    [124, 165, 0, 255],    //----- 62
 | 
			
		||||
    [145, 165, 82, 255],    //----- 63
 | 
			
		||||
    [95, 127, 0, 255],    //----- 64
 | 
			
		||||
    [111, 127, 63, 255],    //----- 65
 | 
			
		||||
    [57, 76, 0, 255],    //----- 66
 | 
			
		||||
    [66, 76, 38, 255],    //----- 67
 | 
			
		||||
    [28, 38, 0, 255],    //----- 68
 | 
			
		||||
    [33, 38, 19, 255],    //----- 69
 | 
			
		||||
    [127, 255, 0, 255],    //----- 70
 | 
			
		||||
    [191, 255, 127, 255],//----- 71
 | 
			
		||||
    [82, 165, 0, 255],    //----- 72
 | 
			
		||||
    [124, 165, 82, 255],    //----- 73
 | 
			
		||||
    [63, 127, 0, 255],    //----- 74
 | 
			
		||||
    [95, 127, 63, 255],    //----- 75
 | 
			
		||||
    [38, 76, 0, 255],    //----- 76
 | 
			
		||||
    [57, 76, 38, 255],    //----- 77
 | 
			
		||||
    [19, 38, 0, 255],    //----- 78
 | 
			
		||||
    [28, 38, 19, 255],    //----- 79
 | 
			
		||||
    [63, 255, 0, 255],    //----- 80
 | 
			
		||||
    [159, 255, 127, 255],//----- 81
 | 
			
		||||
    [41, 165, 0, 255],    //----- 82
 | 
			
		||||
    [103, 165, 82, 255],    //----- 83
 | 
			
		||||
    [31, 127, 0, 255],    //----- 84
 | 
			
		||||
    [79, 127, 63, 255],    //----- 85
 | 
			
		||||
    [19, 76, 0, 255],    //----- 86
 | 
			
		||||
    [47, 76, 38, 255],    //----- 87
 | 
			
		||||
    [9, 38, 0, 255],        //----- 88
 | 
			
		||||
    [23, 38, 19, 255],    //----- 89
 | 
			
		||||
    [0, 255, 0, 255],    //----- 90
 | 
			
		||||
    [127, 255, 127, 255],//----- 91
 | 
			
		||||
    [0, 165, 0, 255],    //----- 92
 | 
			
		||||
    [82, 165, 82, 255],    //----- 93
 | 
			
		||||
    [0, 127, 0, 255],    //----- 94
 | 
			
		||||
    [63, 127, 63, 255],    //----- 95
 | 
			
		||||
    [0, 76, 0, 255],        //----- 96
 | 
			
		||||
    [38, 76, 38, 255],    //----- 97
 | 
			
		||||
    [0, 38, 0, 255],        //----- 98
 | 
			
		||||
    [19, 38, 19, 255],    //----- 99
 | 
			
		||||
    [0, 255, 63, 255],    //----- 100
 | 
			
		||||
    [127, 255, 159, 255],//----- 101
 | 
			
		||||
    [0, 165, 41, 255],    //----- 102
 | 
			
		||||
    [82, 165, 103, 255],    //----- 103
 | 
			
		||||
    [0, 127, 31, 255],    //----- 104
 | 
			
		||||
    [63, 127, 79, 255],    //----- 105
 | 
			
		||||
    [0, 76, 19, 255],    //----- 106
 | 
			
		||||
    [38, 76, 47, 255],    //----- 107
 | 
			
		||||
    [0, 38, 9, 255],        //----- 108
 | 
			
		||||
    [19, 38, 23, 255],    //----- 109
 | 
			
		||||
    [0, 255, 127, 255],    //----- 110
 | 
			
		||||
    [127, 255, 191, 255],//----- 111
 | 
			
		||||
    [0, 165, 82, 255],    //----- 112
 | 
			
		||||
    [82, 165, 124, 255],    //----- 113
 | 
			
		||||
    [0, 127, 63, 255],    //----- 114
 | 
			
		||||
    [63, 127, 95, 255],    //----- 115
 | 
			
		||||
    [0, 76, 38, 255],    //----- 116
 | 
			
		||||
    [38, 76, 57, 255],    //----- 117
 | 
			
		||||
    [0, 38, 19, 255],    //----- 118
 | 
			
		||||
    [19, 38, 28, 255],    //----- 119
 | 
			
		||||
    [0, 255, 191, 255],    //----- 120
 | 
			
		||||
    [127, 255, 223, 255],//----- 121
 | 
			
		||||
    [0, 165, 124, 255],    //----- 122
 | 
			
		||||
    [82, 165, 145, 255],    //----- 123
 | 
			
		||||
    [0, 127, 95, 255],    //----- 124
 | 
			
		||||
    [63, 127, 111, 255],    //----- 125
 | 
			
		||||
    [0, 76, 57, 255],    //----- 126
 | 
			
		||||
    [38, 76, 66, 255],    //----- 127
 | 
			
		||||
    [0, 38, 28, 255],    //----- 128
 | 
			
		||||
    [19, 38, 33, 255],    //----- 129
 | 
			
		||||
    [0, 255, 255, 255],    //----- 130
 | 
			
		||||
    [127, 255, 255, 255],//----- 131
 | 
			
		||||
    [0, 165, 165, 255],    //----- 132
 | 
			
		||||
    [82, 165, 165, 255],    //----- 133
 | 
			
		||||
    [0, 127, 127, 255],    //----- 134
 | 
			
		||||
    [63, 127, 127, 255],    //----- 135
 | 
			
		||||
    [0, 76, 76, 255],    //----- 136
 | 
			
		||||
    [38, 76, 76, 255],    //----- 137
 | 
			
		||||
    [0, 38, 38, 255],    //----- 138
 | 
			
		||||
    [19, 38, 38, 255],    //----- 139
 | 
			
		||||
    [0, 191, 255, 255],    //----- 140
 | 
			
		||||
    [127, 223, 255, 255],//----- 141
 | 
			
		||||
    [0, 124, 165, 255],    //----- 142
 | 
			
		||||
    [82, 145, 165, 255],    //----- 143
 | 
			
		||||
    [0, 95, 127, 255],    //----- 144
 | 
			
		||||
    [63, 111, 127, 255],    //----- 145
 | 
			
		||||
    [0, 57, 76, 255],    //----- 146
 | 
			
		||||
    [38, 66, 76, 255],    //----- 147
 | 
			
		||||
    [0, 28, 38, 255],    //----- 148
 | 
			
		||||
    [19, 33, 38, 255],    //----- 149
 | 
			
		||||
    [0, 127, 255, 255],    //----- 150
 | 
			
		||||
    [127, 191, 255, 255],//----- 151
 | 
			
		||||
    [0, 82, 165, 255],    //----- 152
 | 
			
		||||
    [82, 124, 165, 255],    //----- 153
 | 
			
		||||
    [0, 63, 127, 255],    //----- 154
 | 
			
		||||
    [63, 95, 127, 255],    //----- 155
 | 
			
		||||
    [0, 38, 76, 255],    //----- 156
 | 
			
		||||
    [38, 57, 76, 255],    //----- 157
 | 
			
		||||
    [0, 19, 38, 255],    //----- 158
 | 
			
		||||
    [19, 28, 38, 255],    //----- 159
 | 
			
		||||
    [0, 63, 255, 255],    //----- 160
 | 
			
		||||
    [127, 159, 255, 255],//----- 161
 | 
			
		||||
    [0, 41, 165, 255],    //----- 162
 | 
			
		||||
    [82, 103, 165, 255],    //----- 163
 | 
			
		||||
    [0, 31, 127, 255],    //----- 164
 | 
			
		||||
    [63, 79, 127, 255],    //----- 165
 | 
			
		||||
    [0, 19, 76, 255],    //----- 166
 | 
			
		||||
    [38, 47, 76, 255],    //----- 167
 | 
			
		||||
    [0, 9, 38, 255],        //----- 168
 | 
			
		||||
    [19, 23, 38, 255],    //----- 169
 | 
			
		||||
    [0, 0, 255, 255],    //----- 170
 | 
			
		||||
    [127, 127, 255, 255],//----- 171
 | 
			
		||||
    [0, 0, 165, 255],    //----- 172
 | 
			
		||||
    [82, 82, 165, 255],    //----- 173
 | 
			
		||||
    [0, 0, 127, 255],    //----- 174
 | 
			
		||||
    [63, 63, 127, 255],    //----- 175
 | 
			
		||||
    [0, 0, 76, 255],        //----- 176
 | 
			
		||||
    [38, 38, 76, 255],    //----- 177
 | 
			
		||||
    [0, 0, 38, 255],        //----- 178
 | 
			
		||||
    [19, 19, 38, 255],    //----- 179
 | 
			
		||||
    [63, 0, 255, 255],    //----- 180
 | 
			
		||||
    [159, 127, 255, 255],//----- 181
 | 
			
		||||
    [41, 0, 165, 255],    //----- 182
 | 
			
		||||
    [103, 82, 165, 255],    //----- 183
 | 
			
		||||
    [31, 0, 127, 255],    //----- 184
 | 
			
		||||
    [79, 63, 127, 255],    //----- 185
 | 
			
		||||
    [19, 0, 76, 255],    //----- 186
 | 
			
		||||
    [47, 38, 76, 255],    //----- 187
 | 
			
		||||
    [9, 0, 38, 255],        //----- 188
 | 
			
		||||
    [23, 19, 38, 255],    //----- 189
 | 
			
		||||
    [127, 0, 255, 255],    //----- 190
 | 
			
		||||
    [191, 127, 255, 255],//----- 191
 | 
			
		||||
    [82, 0, 165, 255],    //----- 192
 | 
			
		||||
    [124, 82, 165, 255],    //----- 193
 | 
			
		||||
    [63, 0, 127, 255],    //----- 194
 | 
			
		||||
    [95, 63, 127, 255],    //----- 195
 | 
			
		||||
    [38, 0, 76, 255],    //----- 196
 | 
			
		||||
    [57, 38, 76, 255],    //----- 197
 | 
			
		||||
    [19, 0, 38, 255],    //----- 198
 | 
			
		||||
    [28, 19, 38, 255],    //----- 199
 | 
			
		||||
    [191, 0, 255, 255],    //----- 200
 | 
			
		||||
    [223, 127, 255, 255],//----- 201
 | 
			
		||||
    [124, 0, 165, 255],    //----- 202
 | 
			
		||||
    [145, 82, 165, 255],    //----- 203
 | 
			
		||||
    [95, 0, 127, 255],    //----- 204
 | 
			
		||||
    [111, 63, 127, 255],    //----- 205
 | 
			
		||||
    [57, 0, 76, 255],    //----- 206
 | 
			
		||||
    [66, 38, 76, 255],    //----- 207
 | 
			
		||||
    [28, 0, 38, 255],    //----- 208
 | 
			
		||||
    [33, 19, 38, 255],    //----- 209
 | 
			
		||||
    [255, 0, 255, 255],    //----- 210
 | 
			
		||||
    [255, 127, 255, 255],//----- 211
 | 
			
		||||
    [165, 0, 165, 255],    //----- 212
 | 
			
		||||
    [165, 82, 165, 255],    //----- 213
 | 
			
		||||
    [127, 0, 127, 255],    //----- 214
 | 
			
		||||
    [127, 63, 127, 255],    //----- 215
 | 
			
		||||
    [76, 0, 76, 255],    //----- 216
 | 
			
		||||
    [76, 38, 76, 255],    //----- 217
 | 
			
		||||
    [38, 0, 38, 255],    //----- 218
 | 
			
		||||
    [38, 19, 38, 255],    //----- 219
 | 
			
		||||
    [255, 0, 191, 255],    //----- 220
 | 
			
		||||
    [255, 127, 223, 255],//----- 221
 | 
			
		||||
    [165, 0, 124, 255],    //----- 222
 | 
			
		||||
    [165, 82, 145, 255],    //----- 223
 | 
			
		||||
    [127, 0, 95, 255],    //----- 224
 | 
			
		||||
    [127, 63, 111, 255],    //----- 225
 | 
			
		||||
    [76, 0, 57, 255],    //----- 226
 | 
			
		||||
    [76, 38, 66, 255],    //----- 227
 | 
			
		||||
    [38, 0, 28, 255],    //----- 228
 | 
			
		||||
    [38, 19, 33, 255],    //----- 229
 | 
			
		||||
    [255, 0, 127, 255],    //----- 230
 | 
			
		||||
    [255, 127, 191, 255],//----- 231
 | 
			
		||||
    [165, 0, 82, 255],    //----- 232
 | 
			
		||||
    [165, 82, 124, 255],    //----- 233
 | 
			
		||||
    [127, 0, 63, 255],    //----- 234
 | 
			
		||||
    [127, 63, 95, 255],    //----- 235
 | 
			
		||||
    [76, 0, 38, 255],    //----- 236
 | 
			
		||||
    [76, 38, 57, 255],    //----- 237
 | 
			
		||||
    [38, 0, 19, 255],    //----- 238
 | 
			
		||||
    [38, 19, 28, 255],    //----- 239
 | 
			
		||||
    [255, 0, 63, 255],    //----- 240
 | 
			
		||||
    [255, 127, 159, 255],//----- 241
 | 
			
		||||
    [165, 0, 41, 255],    //----- 242
 | 
			
		||||
    [165, 82, 103, 255],    //----- 243
 | 
			
		||||
    [127, 0, 31, 255],    //----- 244
 | 
			
		||||
    [127, 63, 79, 255],    //----- 245
 | 
			
		||||
    [76, 0, 19, 255],    //----- 246
 | 
			
		||||
    [76, 38, 47, 255],    //----- 247
 | 
			
		||||
    [38, 0, 9, 255],        //----- 248
 | 
			
		||||
    [38, 19, 23, 255],    //----- 249
 | 
			
		||||
    [84, 84, 84, 255],    //----- 250
 | 
			
		||||
    [118, 118, 118, 255],//----- 251
 | 
			
		||||
    [152, 152, 152, 255],//----- 252
 | 
			
		||||
    [186, 186, 186, 255],//----- 253
 | 
			
		||||
    [220, 220, 220, 255],//----- 254
 | 
			
		||||
    [255, 255, 255, 255],//----- 255
 | 
			
		||||
    [255, 255, 255, 255]    //----- ByLayer - White
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//颜色材质,对于二维图像来说可能有用,应该不对三维对象使用该材质
 | 
			
		||||
export class ColorMaterial
 | 
			
		||||
{
 | 
			
		||||
    private constructor() { }
 | 
			
		||||
    private static m_LineMaterialMap = new Map<number, THREE.LineBasicMaterial>();
 | 
			
		||||
    static GetLineMaterial(index): THREE.LineBasicMaterial
 | 
			
		||||
    {
 | 
			
		||||
        if (this.m_LineMaterialMap.has(index))
 | 
			
		||||
            return this.m_LineMaterialMap.get(index);
 | 
			
		||||
        let mat = new THREE.LineBasicMaterial({ color: this.GetColor(index) });
 | 
			
		||||
        this.m_LineMaterialMap.set(index, mat);
 | 
			
		||||
        return mat;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static GetColor(index: number)
 | 
			
		||||
    {
 | 
			
		||||
        let rgb = ColorPalette[index];
 | 
			
		||||
        if (rgb)
 | 
			
		||||
            return new THREE.Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								src/Dimension.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/Dimension.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
import { Group, Geometry, Vector3, Line, Matrix4 } from "three";
 | 
			
		||||
import { ColorMaterial } from "./ColorPalette";
 | 
			
		||||
import { DbText } from "./Text";
 | 
			
		||||
import { MoveMatrix } from "./GeUtils";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 标注实体
 | 
			
		||||
 * 
 | 
			
		||||
 * @export
 | 
			
		||||
 * @class Dimension
 | 
			
		||||
 * @extends {Group}
 | 
			
		||||
 */
 | 
			
		||||
export class Dimension extends Group
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    constructor(length: number, textHeight: number = 25, mirror: boolean = false, mirrorFoot: boolean = false)
 | 
			
		||||
    {
 | 
			
		||||
        super();
 | 
			
		||||
        let footLength = 60;
 | 
			
		||||
        if (mirrorFoot)
 | 
			
		||||
        {
 | 
			
		||||
            footLength = -footLength;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //针脚几何体
 | 
			
		||||
        let lineGeo = new Geometry();
 | 
			
		||||
        lineGeo.vertices.push(new Vector3(), new Vector3(0, footLength, 0));
 | 
			
		||||
 | 
			
		||||
        //托盘几何体
 | 
			
		||||
        let lineGeo2 = new Geometry();
 | 
			
		||||
        lineGeo2.vertices.push(new Vector3(0, footLength), new Vector3(length, footLength, 0));
 | 
			
		||||
 | 
			
		||||
        let material = ColorMaterial.GetLineMaterial(5)
 | 
			
		||||
 | 
			
		||||
        let line1 = new Line(lineGeo, material);
 | 
			
		||||
        let line2 = new Line(lineGeo, material);
 | 
			
		||||
        line2.position.x = length;
 | 
			
		||||
 | 
			
		||||
        let line3 = new Line(lineGeo2, material);
 | 
			
		||||
 | 
			
		||||
        let text = new DbText(parseFloat(length.toFixed(2)).toString(), textHeight);
 | 
			
		||||
        if (mirror)
 | 
			
		||||
        {
 | 
			
		||||
            let roMat = new Matrix4().makeRotationZ(Math.PI);
 | 
			
		||||
            text.applyMatrix(roMat);
 | 
			
		||||
            text.applyMatrix(MoveMatrix(new Vector3(length * 0.5, footLength - textHeight * 0.1)));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            text.applyMatrix(MoveMatrix(new Vector3(length * 0.5, footLength * 1.1)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        this.add(text);
 | 
			
		||||
 | 
			
		||||
        this.add(line1, line2, line3);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/DrawDimension.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/DrawDimension.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
import { Box3, Vector3, Matrix4, Mesh } from "three";
 | 
			
		||||
import { Dimension, GetBoxArr } from ".";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 绘制标注实体
 | 
			
		||||
 * 
 | 
			
		||||
 * @export
 | 
			
		||||
 * @param {Box3} box 
 | 
			
		||||
 * @returns 标注实体列表
 | 
			
		||||
 */
 | 
			
		||||
export function DrawDimension(brList: Mesh[]): Dimension[]
 | 
			
		||||
{
 | 
			
		||||
    let box = GetBoxArr(brList);
 | 
			
		||||
    let size = box.getSize(new Vector3());
 | 
			
		||||
 | 
			
		||||
    let mat4 = new Matrix4();
 | 
			
		||||
    mat4.makeBasis(
 | 
			
		||||
        new Vector3(-1, 0, 0),
 | 
			
		||||
        new Vector3(0, -1, 0),
 | 
			
		||||
        new Vector3(0, 0, 1)
 | 
			
		||||
    )
 | 
			
		||||
    mat4.setPosition(box.min.clone().add(new Vector3(size.x, -30)));
 | 
			
		||||
 | 
			
		||||
    let textHeight = 45;
 | 
			
		||||
    let dimx = new Dimension(size.x, textHeight, true);
 | 
			
		||||
    dimx.applyMatrix(mat4);
 | 
			
		||||
 | 
			
		||||
    let dimz = new Dimension(size.z, textHeight);
 | 
			
		||||
    mat4.makeBasis(
 | 
			
		||||
        new Vector3(0, 0, -1),
 | 
			
		||||
        new Vector3(1, 0, 0),
 | 
			
		||||
        new Vector3(0, -1, 0)
 | 
			
		||||
    )
 | 
			
		||||
    mat4.setPosition(box.max.clone().add(new Vector3(30, -size.y)));
 | 
			
		||||
    dimz.applyMatrix(mat4);
 | 
			
		||||
 | 
			
		||||
    let dimy = new Dimension(size.y, textHeight, true, true);
 | 
			
		||||
    mat4.makeBasis(
 | 
			
		||||
        new Vector3(0, 1, 0),
 | 
			
		||||
        new Vector3(-1, 0, 0),
 | 
			
		||||
        new Vector3(0, 0, 1)
 | 
			
		||||
    )
 | 
			
		||||
    mat4.setPosition(box.max.clone().add(new Vector3(30, -size.y)));
 | 
			
		||||
    dimy.applyMatrix(mat4);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return [dimx, dimy, dimz];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										289
									
								
								src/GeUtils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								src/GeUtils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,289 @@
 | 
			
		||||
import * as THREE from 'three';
 | 
			
		||||
import { Geometry, Vector, Vector2, Vector3 } from 'three';
 | 
			
		||||
import { Matrix2 } from './Matrix2';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export const cZeroVec = new THREE.Vector3();
 | 
			
		||||
export const cXAxis = new THREE.Vector3(1, 0, 0);
 | 
			
		||||
export const cYAxis = new THREE.Vector3(0, 1, 0);
 | 
			
		||||
export const cZAxis = new THREE.Vector3(0, 0, 1);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 旋转一个点,旋转中心在原点
 | 
			
		||||
 * 
 | 
			
		||||
 * @export
 | 
			
		||||
 * @param {Vector3} pt 点
 | 
			
		||||
 * @param {number} ang 角度.
 | 
			
		||||
 * @returns {Vector3} 返回pt不拷贝.
 | 
			
		||||
 */
 | 
			
		||||
export function rotatePoint(pt: Vector3, ang: number): Vector3
 | 
			
		||||
{
 | 
			
		||||
    new Matrix2().setRotate(ang).applyVector(pt);
 | 
			
		||||
    return pt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function equaln(v1: number, v2: number, fuzz = 1e-3)
 | 
			
		||||
{
 | 
			
		||||
    return Math.abs(v1 - v2) < fuzz;
 | 
			
		||||
}
 | 
			
		||||
export function equal<T extends Vector>(v1: T, v2: T)
 | 
			
		||||
{
 | 
			
		||||
    return v1.distanceToSquared(v2) < 1e-8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function fixAngle(an: number, fixAngle: number, fuzz: number = 0.1)
 | 
			
		||||
{
 | 
			
		||||
    if (an < 0)
 | 
			
		||||
        an += Math.PI * 2;
 | 
			
		||||
    an += fuzz;
 | 
			
		||||
    let rem = an % fixAngle;
 | 
			
		||||
    if (rem < fuzz * 2)
 | 
			
		||||
    {
 | 
			
		||||
        an -= rem;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        an -= fuzz;
 | 
			
		||||
    }
 | 
			
		||||
    return an;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 按照极坐标的方式移动一个点
 | 
			
		||||
 * 
 | 
			
		||||
 * @export
 | 
			
		||||
 * @template 
 | 
			
		||||
 * @param {T} v 向量(2d,3d)
 | 
			
		||||
 * @param {number} an 角度
 | 
			
		||||
 * @param {number} dis 距离
 | 
			
		||||
 * @returns {T} 
 | 
			
		||||
 */
 | 
			
		||||
export function polar<T extends Vector2 | Vector3>(v: T, an: number, dis: number): T
 | 
			
		||||
{
 | 
			
		||||
    v.x += Math.cos(an) * dis;
 | 
			
		||||
    v.y += Math.sin(an) * dis;
 | 
			
		||||
    return v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function angle(v: Vector3 | Vector2)
 | 
			
		||||
{
 | 
			
		||||
    if (equaln(v.y, 0) && v.x > 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
    let angle = Math.atan2(v.y, v.x);
 | 
			
		||||
    if (angle < 0) angle += Math.PI * 2;
 | 
			
		||||
    return angle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 求两个向量的夹角,顺时针为负,逆时针为正
 | 
			
		||||
 * 
 | 
			
		||||
 * @param {THREE.Vector3} v1 
 | 
			
		||||
 * @param {THREE.Vector3} v2 
 | 
			
		||||
 * @param {THREE.Vector3} [ref] 参考向量,如果为世界坐标系则为0,0,1
 | 
			
		||||
 * @returns 
 | 
			
		||||
 */
 | 
			
		||||
export function angleTo(v1: THREE.Vector3, v2: THREE.Vector3, ref: THREE.Vector3 = new THREE.Vector3(0, 0, 1))
 | 
			
		||||
{
 | 
			
		||||
    if (!ref.equals(new Vector3(0, 0, 1)))
 | 
			
		||||
    {
 | 
			
		||||
        //任意轴坐标系. 使用相机的构造矩阵.
 | 
			
		||||
        ref.multiplyScalar(-1);
 | 
			
		||||
        let up = getLoocAtUpVec(ref);
 | 
			
		||||
        let refOcs = new THREE.Matrix4();
 | 
			
		||||
        refOcs.lookAt(cZeroVec, ref, up);
 | 
			
		||||
        let refOcsInv = new THREE.Matrix4().getInverse(refOcs);
 | 
			
		||||
        v1.applyMatrix4(refOcsInv);
 | 
			
		||||
        v2.applyMatrix4(refOcsInv);
 | 
			
		||||
        v1.z = 0;
 | 
			
		||||
        v2.z = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (v1.equals(cZeroVec) || v2.equals(cZeroVec))
 | 
			
		||||
        return 0;
 | 
			
		||||
    let cv = new Vector3().crossVectors(v1, v2).normalize();
 | 
			
		||||
    return cv.z === 0 ? v1.angleTo(v2) : v1.angleTo(v2) * cv.z;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getLoocAtUpVec(dir: THREE.Vector3): THREE.Vector3
 | 
			
		||||
{
 | 
			
		||||
    if (dir.equals(cZeroVec))
 | 
			
		||||
    {
 | 
			
		||||
        throw ("zero vector")
 | 
			
		||||
    }
 | 
			
		||||
    let norm = dir.clone().normalize();
 | 
			
		||||
    if (norm.equals(cZAxis))
 | 
			
		||||
    {
 | 
			
		||||
        return new THREE.Vector3(0, 1, 0);
 | 
			
		||||
    }
 | 
			
		||||
    else if (norm.equals(cZAxis.clone().negate()))
 | 
			
		||||
    {
 | 
			
		||||
        return new THREE.Vector3(0, -1, 0);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        let xv: THREE.Vector3 = new THREE.Vector3();
 | 
			
		||||
        xv.crossVectors(cZAxis, norm);
 | 
			
		||||
 | 
			
		||||
        let up = new THREE.Vector3();
 | 
			
		||||
        up.crossVectors(norm, xv);
 | 
			
		||||
        return up;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createLookAtMat4(dir: THREE.Vector3): THREE.Matrix4
 | 
			
		||||
{
 | 
			
		||||
    let up = getLoocAtUpVec(dir);
 | 
			
		||||
    let mat = new THREE.Matrix4();
 | 
			
		||||
    mat.lookAt(cZeroVec, dir, up);
 | 
			
		||||
    return mat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function isParallelTo(v1: THREE.Vector3, v2: THREE.Vector3)
 | 
			
		||||
{
 | 
			
		||||
    return v1.clone().cross(v2).lengthSq() < 1e-9;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function ptToString(v: THREE.Vector3, fractionDigits: number = 3): string
 | 
			
		||||
{
 | 
			
		||||
    return v.toArray().map(o =>
 | 
			
		||||
    {
 | 
			
		||||
        return o.toFixed(fractionDigits)
 | 
			
		||||
    }).join(",")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function midPoint(v1: THREE.Vector3, v2: THREE.Vector3): THREE.Vector3
 | 
			
		||||
{
 | 
			
		||||
    return v1.clone().add(v2).multiplyScalar(0.5);
 | 
			
		||||
}
 | 
			
		||||
export function midPoint2(v1: THREE.Vector2, v2: THREE.Vector2): THREE.Vector2
 | 
			
		||||
{
 | 
			
		||||
    return v1.clone().add(v2).multiplyScalar(0.5);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function midPtCir(v1: THREE.Vector3, v2: THREE.Vector3)
 | 
			
		||||
{
 | 
			
		||||
    let baseline = new Vector3(1, 0, 0);
 | 
			
		||||
    let outLine = v2.clone().sub(v1);
 | 
			
		||||
    let ang = angleTo(baseline, outLine) / 2;
 | 
			
		||||
    let midLine = rotatePoint(outLine, -ang);
 | 
			
		||||
    return v1.clone().add(midLine);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function GetBox(obj: THREE.Object3D, updateMatrix?: boolean): THREE.Box3
 | 
			
		||||
{
 | 
			
		||||
    if (updateMatrix) obj.updateMatrixWorld(false);
 | 
			
		||||
    if (obj.hasOwnProperty("geometry"))
 | 
			
		||||
    {
 | 
			
		||||
        let geo = obj["geometry"];
 | 
			
		||||
        if (geo instanceof THREE.Geometry || geo instanceof THREE.BufferGeometry)
 | 
			
		||||
        {
 | 
			
		||||
            if (!geo.boundingBox)
 | 
			
		||||
                geo.computeBoundingBox();
 | 
			
		||||
            return geo.boundingBox.clone().applyMatrix4(obj.matrixWorld);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (obj.children.length > 0)
 | 
			
		||||
    {
 | 
			
		||||
        let box = obj.children.reduce((sumBox, itemObj) =>
 | 
			
		||||
        {
 | 
			
		||||
            let itemBox = GetBox(itemObj);
 | 
			
		||||
            if (itemBox)
 | 
			
		||||
                sumBox.union(itemBox);
 | 
			
		||||
            return sumBox;
 | 
			
		||||
        }, new THREE.Box3())
 | 
			
		||||
        // if (box) box.applyMatrix4(obj.matrixWorld);
 | 
			
		||||
        return box;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function GetBoxArr(arr: Array<THREE.Object3D>): THREE.Box3
 | 
			
		||||
{
 | 
			
		||||
    if (arr.length == 0)
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    return arr.map(o =>
 | 
			
		||||
    {
 | 
			
		||||
        return GetBox(o);
 | 
			
		||||
    }).filter(o =>
 | 
			
		||||
    {
 | 
			
		||||
        return o;
 | 
			
		||||
    }).reduce((sumBox: THREE.Box3, objBox: THREE.Box3) =>
 | 
			
		||||
    {
 | 
			
		||||
        return sumBox.union(objBox)
 | 
			
		||||
    }, new THREE.Box3());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function MoveMatrix(v: THREE.Vector3): THREE.Matrix4
 | 
			
		||||
{
 | 
			
		||||
    let mat = new THREE.Matrix4();
 | 
			
		||||
    mat.makeTranslation(v.x, v.y, v.z);
 | 
			
		||||
    return mat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getProjectDist(v1: Vector3, v2: Vector3)
 | 
			
		||||
{
 | 
			
		||||
    let ang = v1.angleTo(v2);
 | 
			
		||||
    let dist = v1.length();
 | 
			
		||||
    return {
 | 
			
		||||
        h: dist * Math.cos(ang),
 | 
			
		||||
        v: dist * Math.sin(ang)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
//获得输入点在2线组成的4个区间的位置
 | 
			
		||||
export function getPtPostion(sp: Vector3, ep: Vector3, c: Vector3, inPt: Vector3)
 | 
			
		||||
{
 | 
			
		||||
    let l1 = sp.clone().sub(c);
 | 
			
		||||
    let l2 = ep.clone().sub(c);
 | 
			
		||||
    let l3 = l1.clone().negate();
 | 
			
		||||
    let l4 = l2.clone().negate();
 | 
			
		||||
    let inputLine = inPt.clone().sub(c);
 | 
			
		||||
    let ang1 = angleTo(l1, l2);
 | 
			
		||||
    let ang2 = Math.PI;
 | 
			
		||||
    let ang3 = ang2 + Math.abs(ang1);
 | 
			
		||||
    let inputAng = angleTo(l1, inputLine);
 | 
			
		||||
    if (ang1 * inputAng < 0)
 | 
			
		||||
    {
 | 
			
		||||
        inputAng = (Math.PI * 2 - Math.abs(inputAng));
 | 
			
		||||
    }
 | 
			
		||||
    ang1 = Math.abs(ang1);
 | 
			
		||||
    inputAng = Math.abs(inputAng);
 | 
			
		||||
    if (inputAng <= ang1)
 | 
			
		||||
    {
 | 
			
		||||
        return { sp, ep };
 | 
			
		||||
    } else if (inputAng > ang1 && inputAng <= ang2)
 | 
			
		||||
    {
 | 
			
		||||
        return { sp: c.clone().add(l3), ep }
 | 
			
		||||
    } else if (inputAng > ang2 && inputAng <= ang3)
 | 
			
		||||
    {
 | 
			
		||||
        return { sp: c.clone().add(l3), ep: c.clone().add(l4) }
 | 
			
		||||
    } else
 | 
			
		||||
    {
 | 
			
		||||
        return { sp, ep: c.clone().add(l4) };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
export function angleAndX(v: Vector3 | Vector2)
 | 
			
		||||
{
 | 
			
		||||
    return v.x ? Math.atan(v.y / v.x) : Math.PI / 2;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * 将角度调整为0-2pi之间
 | 
			
		||||
 * 
 | 
			
		||||
 * @export
 | 
			
		||||
 * @param {number} an 
 | 
			
		||||
 */
 | 
			
		||||
export function angleTo2Pi(an: number)
 | 
			
		||||
{
 | 
			
		||||
    an = an % (Math.PI * 2);
 | 
			
		||||
    if (an < 0) an += Math.PI * 2
 | 
			
		||||
    return an;
 | 
			
		||||
}
 | 
			
		||||
export function updateGeometry(l: THREE.Line | THREE.Mesh, geometry: Geometry)
 | 
			
		||||
{
 | 
			
		||||
    let geo = l.geometry as THREE.Geometry;
 | 
			
		||||
    geo.dispose();
 | 
			
		||||
    l.geometry = geometry;
 | 
			
		||||
    geometry.verticesNeedUpdate = true;
 | 
			
		||||
    geometry.computeBoundingSphere();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										164
									
								
								src/KeyEnum.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								src/KeyEnum.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
//鼠标类型
 | 
			
		||||
export enum MouseKey
 | 
			
		||||
{
 | 
			
		||||
    Left = 0,
 | 
			
		||||
    Middle = 1,
 | 
			
		||||
    Right = 2,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum KeyBoard
 | 
			
		||||
{
 | 
			
		||||
    // 数字
 | 
			
		||||
    Digit1 = 49,
 | 
			
		||||
    Digit2 = 50,
 | 
			
		||||
    Digit3 = 51,
 | 
			
		||||
    Digit4 = 52,
 | 
			
		||||
    Digit5 = 53,
 | 
			
		||||
    Digit6 = 54,
 | 
			
		||||
    Digit7 = 55,
 | 
			
		||||
    Digit8 = 56,
 | 
			
		||||
    Digit9 = 57,
 | 
			
		||||
    Digit0 = 58,
 | 
			
		||||
    // 字母
 | 
			
		||||
    KeyA = 65,
 | 
			
		||||
    KeyB = 66,
 | 
			
		||||
    KeyC = 67,
 | 
			
		||||
    KeyD = 68,
 | 
			
		||||
    KeyE = 69,
 | 
			
		||||
    KeyF = 70,
 | 
			
		||||
    KeyG = 71,
 | 
			
		||||
    KeyH = 72,
 | 
			
		||||
    KeyI = 73,
 | 
			
		||||
    KeyJ = 74,
 | 
			
		||||
    KeyK = 75,
 | 
			
		||||
    KeyL = 76,
 | 
			
		||||
    KeyM = 77,
 | 
			
		||||
    KeyN = 78,
 | 
			
		||||
    KeyO = 79,
 | 
			
		||||
    KeyP = 80,
 | 
			
		||||
    KeyQ = 81,
 | 
			
		||||
    KeyR = 82,
 | 
			
		||||
    KeyS = 83,
 | 
			
		||||
    KeyT = 84,
 | 
			
		||||
    KeyU = 85,
 | 
			
		||||
    KeyV = 86,
 | 
			
		||||
    KeyW = 87,
 | 
			
		||||
    KeyX = 88,
 | 
			
		||||
    KeyY = 89,
 | 
			
		||||
    KeyZ = 90,
 | 
			
		||||
 | 
			
		||||
    // 符号
 | 
			
		||||
    /**
 | 
			
		||||
     * 逗号
 | 
			
		||||
     */
 | 
			
		||||
    Comma = 188,
 | 
			
		||||
    CommaChrome = 229,
 | 
			
		||||
    /**
 | 
			
		||||
     * 句号
 | 
			
		||||
     */
 | 
			
		||||
    Period = 190,
 | 
			
		||||
    /**
 | 
			
		||||
     * 分号
 | 
			
		||||
     */
 | 
			
		||||
    Semicolon = 186,
 | 
			
		||||
    /**
 | 
			
		||||
     * 引号
 | 
			
		||||
     */
 | 
			
		||||
    Quote = 222,
 | 
			
		||||
    /**
 | 
			
		||||
     * 左括号
 | 
			
		||||
     */
 | 
			
		||||
    BracketLeft = 219,
 | 
			
		||||
    /**
 | 
			
		||||
     * 右括号
 | 
			
		||||
     */
 | 
			
		||||
    BracketRight = 220,
 | 
			
		||||
    /**
 | 
			
		||||
     * 反引号
 | 
			
		||||
     */
 | 
			
		||||
    Backquote = 192,
 | 
			
		||||
    /**
 | 
			
		||||
     * 反斜杠
 | 
			
		||||
     */
 | 
			
		||||
    Backslash = 220,
 | 
			
		||||
    /**
 | 
			
		||||
     * 减号
 | 
			
		||||
     */
 | 
			
		||||
    Minus = 189,
 | 
			
		||||
    /**
 | 
			
		||||
     * 等号
 | 
			
		||||
     */
 | 
			
		||||
    Equal = 187,
 | 
			
		||||
    IntlRo = 193,
 | 
			
		||||
    IntlYen = 255,
 | 
			
		||||
    // 功能键
 | 
			
		||||
    Alt = 18,
 | 
			
		||||
    /**
 | 
			
		||||
     * 大写锁定
 | 
			
		||||
     */
 | 
			
		||||
    CapsLock = 20,
 | 
			
		||||
    Control = 17,
 | 
			
		||||
    /**
 | 
			
		||||
     * win左键
 | 
			
		||||
     */
 | 
			
		||||
    OSLeft = 91,
 | 
			
		||||
    /**
 | 
			
		||||
     * win右键
 | 
			
		||||
     */
 | 
			
		||||
    OSRight = 92,
 | 
			
		||||
    Shift = 16,
 | 
			
		||||
 | 
			
		||||
    ContextMenu = 93,
 | 
			
		||||
    Enter = 13,
 | 
			
		||||
    Space = 32,
 | 
			
		||||
    Backspace = 8,
 | 
			
		||||
    Tab = 9,
 | 
			
		||||
    Delete = 46,
 | 
			
		||||
    End = 35,
 | 
			
		||||
    Home = 36,
 | 
			
		||||
    Insert = 45,
 | 
			
		||||
    PageDown = 34,
 | 
			
		||||
    PageUp = 33,
 | 
			
		||||
    ArrowDown = 40,
 | 
			
		||||
    ArrowLeft = 37,
 | 
			
		||||
    ArrowRight = 39,
 | 
			
		||||
    ArrowUp = 38,
 | 
			
		||||
    Escape = 27,
 | 
			
		||||
    PrintScreen = 44,
 | 
			
		||||
    ScrollLock = 145,
 | 
			
		||||
    Pause = 19,
 | 
			
		||||
 | 
			
		||||
    // F数字
 | 
			
		||||
    F1 = 112,
 | 
			
		||||
    F2 = 113,
 | 
			
		||||
    F3 = 114,
 | 
			
		||||
    F5 = 116,
 | 
			
		||||
    F6 = 117,
 | 
			
		||||
    F7 = 118,
 | 
			
		||||
    F8 = 119,
 | 
			
		||||
    F9 = 120,
 | 
			
		||||
    F10 = 121,
 | 
			
		||||
    F11 = 122,
 | 
			
		||||
    F12 = 123,
 | 
			
		||||
 | 
			
		||||
    //数字键盘
 | 
			
		||||
    NumLock = 114,
 | 
			
		||||
    Numpad0 = 96,
 | 
			
		||||
    Numpad1 = 97,
 | 
			
		||||
    Numpad2 = 98,
 | 
			
		||||
    Numpad3 = 99,
 | 
			
		||||
    Numpad4 = 100,
 | 
			
		||||
    Numpad5 = 101,
 | 
			
		||||
    Numpad6 = 102,
 | 
			
		||||
    Numpad7 = 103,
 | 
			
		||||
    Numpad8 = 104,
 | 
			
		||||
    Numpad9 = 105,
 | 
			
		||||
    NumpadAdd = 107,
 | 
			
		||||
    NumpadDivide = 111,
 | 
			
		||||
    NumpadEqual = 12,
 | 
			
		||||
    NumpadMultiply = 106,
 | 
			
		||||
    NumpadSubtract = 109,
 | 
			
		||||
    NumpadDot = 110,
 | 
			
		||||
    NumpadDot1 = 190
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								src/Material.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/Material.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
import { MeshBasicMaterial, Color, LineBasicMaterial } from "three";
 | 
			
		||||
 | 
			
		||||
//板件的材质,使用这个材质避免板件将线覆盖.
 | 
			
		||||
export let boardMaterial = new MeshBasicMaterial({
 | 
			
		||||
    color: new Color(0.8, 0.8, 0.8),
 | 
			
		||||
    polygonOffset: true,
 | 
			
		||||
    polygonOffsetFactor: 1, // positive value pushes polygon further away
 | 
			
		||||
    polygonOffsetUnits: 1
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
//线框的材质
 | 
			
		||||
export let edgeMaterial = new LineBasicMaterial({ linewidth: 2, color: new Color(0, 0, 0) });
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								src/Matrix2.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/Matrix2.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
import { Vector2, Vector3 } from "three";
 | 
			
		||||
 | 
			
		||||
export class Matrix2
 | 
			
		||||
{
 | 
			
		||||
    private el = [1, 0, 0, 1];
 | 
			
		||||
    set(n11: number, n12: number, n21: number, n22: number)
 | 
			
		||||
    {
 | 
			
		||||
        let te = this.el;
 | 
			
		||||
 | 
			
		||||
        te[0] = n11; te[1] = n21;
 | 
			
		||||
        te[2] = n12; te[3] = n22;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
    applyVector(vec: Vector2 | Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        let x = vec.x, y = vec.y;
 | 
			
		||||
        let e = this.el;
 | 
			
		||||
        vec.x = e[0] * x + e[2] * y;
 | 
			
		||||
        vec.y = e[1] * x + e[3] * y;
 | 
			
		||||
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setRotate(theta: number): Matrix2
 | 
			
		||||
    {
 | 
			
		||||
        let el = this.el;
 | 
			
		||||
        let c = Math.cos(theta), s = Math.sin(theta);
 | 
			
		||||
 | 
			
		||||
        this.set(c, -s,
 | 
			
		||||
            s, c);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								src/Orbit.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/Orbit.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
import * as THREE from "three";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 轨道控制的数学类,观察向量和角度的互相转换
 | 
			
		||||
 * 当x当抬头或者低头到90度时,触发万向锁.
 | 
			
		||||
 * 
 | 
			
		||||
 * @class Orbit
 | 
			
		||||
 */
 | 
			
		||||
export class Orbit
 | 
			
		||||
{
 | 
			
		||||
    //抬头低头 正数抬头 负数低头
 | 
			
		||||
    private m_RoX: number = 0;
 | 
			
		||||
 | 
			
		||||
    //身体旋转 0为正右边 逆时针旋转
 | 
			
		||||
    RoZ: number = 0;
 | 
			
		||||
 | 
			
		||||
    get RoX()
 | 
			
		||||
    {
 | 
			
		||||
        return this.m_RoX;
 | 
			
		||||
    }
 | 
			
		||||
    set RoX(v)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_RoX = THREE.Math.clamp(v, Math.PI * -0.5, Math.PI * 0.5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 使用旋转角度 计算观察向量
 | 
			
		||||
     * 
 | 
			
		||||
     * @param {THREE.Vector3} [dir] 引用传入,如果传入,那么就不构造新的向量
 | 
			
		||||
     * @returns {THREE.Vector3} 返回观察向量
 | 
			
		||||
     * @memberof Orbit
 | 
			
		||||
     */
 | 
			
		||||
    UpdateDirection(dir?: THREE.Vector3): THREE.Vector3
 | 
			
		||||
    {
 | 
			
		||||
        let rtDir = dir ? dir : new THREE.Vector3();
 | 
			
		||||
 | 
			
		||||
        rtDir.z = Math.sin(this.m_RoX);
 | 
			
		||||
 | 
			
		||||
        //归一化专用.
 | 
			
		||||
        let d = Math.abs(Math.cos(this.m_RoX));
 | 
			
		||||
 | 
			
		||||
        rtDir.x = Math.cos(this.RoZ) * d;
 | 
			
		||||
        rtDir.y = Math.sin(this.RoZ) * d;
 | 
			
		||||
 | 
			
		||||
        return rtDir;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 使用观察向量,计算旋转角度
 | 
			
		||||
     * 
 | 
			
		||||
     * @param {THREE.Vector3} dir 
 | 
			
		||||
     * @memberof Orbit
 | 
			
		||||
     */
 | 
			
		||||
    UpdateRoValue(dir: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        dir.normalize();
 | 
			
		||||
        this.m_RoX = Math.asin(dir.z);
 | 
			
		||||
        if (dir.x < 1e-4 && dir.y < 1e-4)
 | 
			
		||||
            this.RoZ = Math.PI * 0.5;
 | 
			
		||||
        else
 | 
			
		||||
            this.RoZ = Math.atan2(dir.y, dir.x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 
 | 
			
		||||
     * 根据观察向量 求头部的向量.
 | 
			
		||||
     * 
 | 
			
		||||
     * @static
 | 
			
		||||
     * @param {THREE.Vector3} dir 
 | 
			
		||||
     * @param {THREE.Vector3} [up] 
 | 
			
		||||
     * @returns {THREE.Vector3} 
 | 
			
		||||
     * @memberof Orbit
 | 
			
		||||
     */
 | 
			
		||||
    static ComputUpDirection(dir: THREE.Vector3, up?: THREE.Vector3): THREE.Vector3
 | 
			
		||||
    {
 | 
			
		||||
        let upRes = up ? up : new THREE.Vector3();
 | 
			
		||||
        if (dir.equals(new THREE.Vector3(0, 0, -1)))
 | 
			
		||||
        {
 | 
			
		||||
            upRes.set(0, 1, 0);
 | 
			
		||||
        }
 | 
			
		||||
        else if (dir.equals(new THREE.Vector3(0, 0, 1)))
 | 
			
		||||
        {
 | 
			
		||||
            upRes.set(0, -1, 0);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            let xv = new THREE.Vector3();
 | 
			
		||||
            xv.crossVectors(new THREE.Vector3(0, 0, 1), dir);
 | 
			
		||||
            upRes.crossVectors(dir, xv);
 | 
			
		||||
            upRes.normalize();
 | 
			
		||||
        }
 | 
			
		||||
        return upRes;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								src/PlaneExt.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/PlaneExt.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
import * as THREE from 'three';
 | 
			
		||||
import { Vector3, Line3 } from "three";
 | 
			
		||||
 | 
			
		||||
export class PlaneExt extends THREE.Plane
 | 
			
		||||
{
 | 
			
		||||
    constructor(normal?: THREE.Vector3, constant?: number)
 | 
			
		||||
    {
 | 
			
		||||
        super(normal, constant);
 | 
			
		||||
    }
 | 
			
		||||
    intersectLine(line: Line3, optionalTarget?: Vector3, extendLine?: boolean): Vector3
 | 
			
		||||
    {
 | 
			
		||||
        let v1 = new Vector3();
 | 
			
		||||
 | 
			
		||||
        let result = optionalTarget || new Vector3();
 | 
			
		||||
 | 
			
		||||
        let direction = line.delta(v1);
 | 
			
		||||
 | 
			
		||||
        let denominator = this.normal.dot(direction);
 | 
			
		||||
 | 
			
		||||
        if (denominator === 0)
 | 
			
		||||
        {
 | 
			
		||||
            // line is coplanar, return origin
 | 
			
		||||
            if (this.distanceToPoint(line.start) === 0)
 | 
			
		||||
            {
 | 
			
		||||
                return result.copy(line.start);
 | 
			
		||||
            }
 | 
			
		||||
            // Unsure if this is the correct method to handle this case.
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let t = - (line.start.dot(this.normal) + this.constant) / denominator;
 | 
			
		||||
        //If you not extendLine,check intersect point in Line
 | 
			
		||||
        if (!extendLine && (t < 0 || t > 1))
 | 
			
		||||
        {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result.copy(direction).multiplyScalar(t).add(line.start);
 | 
			
		||||
    }
 | 
			
		||||
    intersectRay(ray: THREE.Ray, optionalTarget?: Vector3, extendLine?: boolean): Vector3
 | 
			
		||||
    {
 | 
			
		||||
        // 从射线初始位置
 | 
			
		||||
        let line = new THREE.Line3(ray.origin.clone(), ray.origin.clone().add(ray.direction));
 | 
			
		||||
        return this.intersectLine(line, optionalTarget, extendLine);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								src/PointPick.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/PointPick.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
import { Object3D, Raycaster, Face3, Vector3, Vector2, Mesh } from "three";
 | 
			
		||||
import { Viewer } from ".";
 | 
			
		||||
 | 
			
		||||
interface Intersect
 | 
			
		||||
{
 | 
			
		||||
    distance: number;
 | 
			
		||||
    face: Face3;
 | 
			
		||||
    faceIndex: number;
 | 
			
		||||
    object: Object3D;
 | 
			
		||||
    point: Vector3;
 | 
			
		||||
    uv: Vector2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 点选
 | 
			
		||||
 * 
 | 
			
		||||
 * @export
 | 
			
		||||
 * @param {Viewer} view 
 | 
			
		||||
 * @param {number} ptx 
 | 
			
		||||
 * @param {number} pty 
 | 
			
		||||
 * @returns {(Mesh | undefined)} 
 | 
			
		||||
 */
 | 
			
		||||
export function PointPick(view: Viewer, ptx: number, pty: number): Mesh | undefined
 | 
			
		||||
{
 | 
			
		||||
    let raycaster = new Raycaster();
 | 
			
		||||
    raycaster.setFromCamera({
 | 
			
		||||
        x: (ptx / view._Width) * 2 - 1,   //-1 到 1  所以 (x-(w/2))/(w/2) =>
 | 
			
		||||
        y: - (pty / view._Height) * 2 + 1 //y轴相反
 | 
			
		||||
    }, view.m_Camera.Camera);
 | 
			
		||||
 | 
			
		||||
    //https://github.com/mrdoob/three.js/issues/14128
 | 
			
		||||
    raycaster.ray.origin.set((ptx / view._Width) * 2 - 1, - (pty / view._Height) * 2 + 1, -1).unproject(view.m_Camera.Camera);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    let minDis = Infinity;
 | 
			
		||||
    let minObj = undefined;
 | 
			
		||||
 | 
			
		||||
    view.m_Scene.children.forEach(obj =>
 | 
			
		||||
    {
 | 
			
		||||
        if (obj instanceof Mesh)
 | 
			
		||||
        {
 | 
			
		||||
            let intersects: Intersect[] = [];
 | 
			
		||||
            obj.raycast(raycaster, intersects);
 | 
			
		||||
 | 
			
		||||
            for (let i of intersects)
 | 
			
		||||
            {
 | 
			
		||||
                if (i.distance < minDis)
 | 
			
		||||
                {
 | 
			
		||||
                    minObj = obj;
 | 
			
		||||
                    minDis = i.distance;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return minObj;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								src/RotateUV.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/RotateUV.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
import { Matrix2 } from './Matrix2';
 | 
			
		||||
import * as THREE from 'three';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export function RotateUVs(geo: THREE.Geometry)
 | 
			
		||||
{
 | 
			
		||||
    let roMat = new Matrix2();
 | 
			
		||||
    roMat.set(0, -1,
 | 
			
		||||
        1, 0);
 | 
			
		||||
 | 
			
		||||
    let addV = new THREE.Vector2(1, 0);
 | 
			
		||||
 | 
			
		||||
    for (let uvs of geo.faceVertexUvs)
 | 
			
		||||
    {
 | 
			
		||||
        for (let uv of uvs)
 | 
			
		||||
        {
 | 
			
		||||
            for (let v of uv)
 | 
			
		||||
            {
 | 
			
		||||
                roMat.applyVector(v);
 | 
			
		||||
                v.add(addV);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    geo.uvsNeedUpdate = true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								src/Text.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/Text.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
import { Font, FontLoader, Mesh, ShapeGeometry, Vector3 } from "three";
 | 
			
		||||
import { ColorMaterial } from "./ColorPalette";
 | 
			
		||||
import { MoveMatrix } from "./GeUtils";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FontLoaderUtil
 | 
			
		||||
{
 | 
			
		||||
    private static defFont:Font;
 | 
			
		||||
    static Load():Font
 | 
			
		||||
    {
 | 
			
		||||
        if(!this.defFont)
 | 
			
		||||
        {
 | 
			
		||||
            const f = require("../node_modules/three/examples/fonts/helvetiker_regular.typeface.json");
 | 
			
		||||
            let loader = new FontLoader();
 | 
			
		||||
            this.defFont = loader.parse(f);
 | 
			
		||||
        }
 | 
			
		||||
        return this.defFont;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class DbText extends Mesh
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * 
 | 
			
		||||
     * 构造一个文本对象,8位点(中心点下面)在0点
 | 
			
		||||
     * @param {string} str 数字字符串
 | 
			
		||||
     * @param {number} height 文本高度
 | 
			
		||||
     * @memberof DbText
 | 
			
		||||
     */
 | 
			
		||||
    constructor(str:string,height:number = 5)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        let font = FontLoaderUtil.Load();
 | 
			
		||||
 | 
			
		||||
        let shapes: THREE.Shape[] = font.generateShapes(str, height,0.1);
 | 
			
		||||
        let geometry = new ShapeGeometry(shapes);
 | 
			
		||||
 | 
			
		||||
        geometry.computeBoundingBox();
 | 
			
		||||
 | 
			
		||||
        super(geometry,ColorMaterial.GetLineMaterial(5));
 | 
			
		||||
 | 
			
		||||
        let center = geometry.boundingBox.getCenter(new Vector3());
 | 
			
		||||
        this.applyMatrix(MoveMatrix(new Vector3(-center.x,0,0)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/Utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/Utils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
import { Viewer, createTemplateBoard, createEdge, DrawDimension } from ".";
 | 
			
		||||
import { Geometry } from "three";
 | 
			
		||||
 | 
			
		||||
export function LoadBoard(view: Viewer, data: any[])
 | 
			
		||||
{
 | 
			
		||||
    view.m_Scene.children.forEach(obj =>
 | 
			
		||||
    {
 | 
			
		||||
        let geo = obj["geometry"] as Geometry;
 | 
			
		||||
        if (geo) geo.dispose();
 | 
			
		||||
    })
 | 
			
		||||
    view.m_Scene.children.length = 0;
 | 
			
		||||
 | 
			
		||||
    //加板
 | 
			
		||||
    let brList = createTemplateBoard(data);
 | 
			
		||||
    //线框
 | 
			
		||||
    let edgeList = brList.map(br => createEdge(br));
 | 
			
		||||
    //加标注
 | 
			
		||||
    let dims = DrawDimension(brList);
 | 
			
		||||
 | 
			
		||||
    view.m_Scene.add(...brList);
 | 
			
		||||
    view.m_Scene.add(...edgeList);
 | 
			
		||||
    view.m_Scene.add(...dims);
 | 
			
		||||
 | 
			
		||||
    view.ViewToSwiso();
 | 
			
		||||
    view.ZoomAll();
 | 
			
		||||
    view.Zoom(1.1);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										194
									
								
								src/Viewer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								src/Viewer.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
			
		||||
 | 
			
		||||
import * as THREE from "three";
 | 
			
		||||
import { CameraUpdate } from "./CameraUpdate";
 | 
			
		||||
import { GetBox, GetBoxArr, cZeroVec } from "./GeUtils";
 | 
			
		||||
import { PlaneExt } from "./PlaneExt";
 | 
			
		||||
import { PointPick, boardMaterial, CameraControls } from ".";
 | 
			
		||||
import { MeshBasicMaterial, Color, Mesh } from "three";
 | 
			
		||||
 | 
			
		||||
export class Viewer
 | 
			
		||||
{
 | 
			
		||||
    m_LookTarget: any;
 | 
			
		||||
    m_Camera: CameraUpdate = new CameraUpdate();
 | 
			
		||||
    m_bNeedUpdate: boolean = true;
 | 
			
		||||
    m_Render: THREE.WebGLRenderer;//渲染器  //暂时只用这个类型
 | 
			
		||||
    m_DomEl: HTMLElement;    //画布容器
 | 
			
		||||
 | 
			
		||||
    _Height: number;
 | 
			
		||||
    _Width: number;
 | 
			
		||||
 | 
			
		||||
    m_Scene: THREE.Scene = new THREE.Scene();
 | 
			
		||||
 | 
			
		||||
    //构造
 | 
			
		||||
    constructor(canvasContainer: HTMLElement)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_DomEl = canvasContainer;
 | 
			
		||||
        this.initRender(canvasContainer);
 | 
			
		||||
        this.OnSize();
 | 
			
		||||
        this.StartRender();
 | 
			
		||||
        new CameraControls(this);
 | 
			
		||||
        window.addEventListener("resize", () =>
 | 
			
		||||
        {
 | 
			
		||||
            this.OnSize();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        //选中
 | 
			
		||||
        let selectMaterial = new MeshBasicMaterial({ color: new Color(0.1, 0.5, 0.5) });
 | 
			
		||||
 | 
			
		||||
        let oldMesh: Mesh;
 | 
			
		||||
        this.m_Render.domElement.addEventListener("mousemove", (e: MouseEvent) =>
 | 
			
		||||
        {
 | 
			
		||||
            let mesh = PointPick(this, e.offsetX, e.offsetY);
 | 
			
		||||
            if (oldMesh)
 | 
			
		||||
                oldMesh.material = boardMaterial;
 | 
			
		||||
            if (mesh)
 | 
			
		||||
            {
 | 
			
		||||
                oldMesh = mesh;
 | 
			
		||||
                mesh.material = selectMaterial;
 | 
			
		||||
                this.m_bNeedUpdate = true;
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //初始化render
 | 
			
		||||
    initRender(canvasContainer: HTMLElement)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Render = new THREE.WebGLRenderer(
 | 
			
		||||
            {
 | 
			
		||||
                antialias: true,//antialias:true/false是否开启反锯齿
 | 
			
		||||
                precision: "highp",//precision:highp/mediump/lowp着色精度选择
 | 
			
		||||
                alpha: true,//alpha:true/false是否可以设置背景色透明
 | 
			
		||||
                // premultipliedAlpha: false,//?
 | 
			
		||||
                // stencil: false,//?
 | 
			
		||||
                // preserveDrawingBuffer: true,//preserveDrawingBuffer:true/false是否保存绘图缓冲
 | 
			
		||||
                // maxLights: 1//maxLights:最大灯光数
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
        //加到画布
 | 
			
		||||
        canvasContainer.appendChild(this.m_Render.domElement);
 | 
			
		||||
 | 
			
		||||
        this.m_Render.autoClear = true;
 | 
			
		||||
 | 
			
		||||
        //如果设置,那么它希望所有的纹理和颜色都是预乘的伽玛。默认值为false。
 | 
			
		||||
        // this.m_Render.gammaInput = true;
 | 
			
		||||
        // this.m_Render.gammaOutput = true;
 | 
			
		||||
        // this.m_Render.shadowMap.enabled = true;
 | 
			
		||||
        // this.m_Render.toneMapping = THREE.ReinhardToneMapping;
 | 
			
		||||
        //设置设备像素比。 这通常用于HiDPI设备,以防止模糊输出画布。
 | 
			
		||||
        this.m_Render.setPixelRatio(window.devicePixelRatio);
 | 
			
		||||
        this.m_Render.physicallyCorrectLights = true;
 | 
			
		||||
        //this.m_Render.toneMappingExposure = Math.pow(1, 5.0); // to allow for very bright scenes.
 | 
			
		||||
 | 
			
		||||
        //设置它的背景色为黑色
 | 
			
		||||
        this.m_Render.setClearColor(0xffffff, 1);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        this.OnSize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    OnSize = (width?, height?) =>
 | 
			
		||||
    {
 | 
			
		||||
        this._Width = width ? width : this.m_DomEl.scrollWidth;
 | 
			
		||||
        this._Height = height ? height : this.m_DomEl.scrollHeight;
 | 
			
		||||
 | 
			
		||||
        //校验.成为2的倍数 避免外轮廓错误.
 | 
			
		||||
        if (this._Width % 2 == 1)
 | 
			
		||||
            this._Width -= 1;
 | 
			
		||||
        if (this._Height % 2 == 1)
 | 
			
		||||
            this._Height -= 1;
 | 
			
		||||
 | 
			
		||||
        this.m_Render.setSize(this._Width, this._Height);
 | 
			
		||||
        this.m_Camera.SetSize(this._Width, this._Height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    StartRender = () =>
 | 
			
		||||
    {
 | 
			
		||||
        requestAnimationFrame(this.StartRender);
 | 
			
		||||
        if (this.m_Scene != null && this.m_bNeedUpdate)
 | 
			
		||||
        {
 | 
			
		||||
            this.Render();
 | 
			
		||||
            this.m_bNeedUpdate = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    Render()
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Render.render(this.m_Scene, this.m_Camera.Camera);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ScreenToWorld(pt: THREE.Vector3, planVec?: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        //变换和求交点
 | 
			
		||||
        let plan = new PlaneExt(planVec || new THREE.Vector3(0, 0, 1));
 | 
			
		||||
        let raycaster = new THREE.Raycaster();
 | 
			
		||||
        // 射线从相机射线向屏幕点位置
 | 
			
		||||
        raycaster.setFromCamera(
 | 
			
		||||
            {
 | 
			
		||||
                x: (pt.x / this._Width) * 2 - 1,
 | 
			
		||||
                y: - (pt.y / this._Height) * 2 + 1
 | 
			
		||||
            }
 | 
			
		||||
            , this.m_Camera.Camera
 | 
			
		||||
        )
 | 
			
		||||
        plan.intersectRay(raycaster.ray, pt, true);
 | 
			
		||||
    }
 | 
			
		||||
    WorldToScreen(pt: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        let widthHalf = this._Width * 0.5;
 | 
			
		||||
        let heightHalf = this._Height * 0.5;
 | 
			
		||||
 | 
			
		||||
        pt.project(this.m_Camera.Camera);
 | 
			
		||||
 | 
			
		||||
        pt.x = (pt.x * widthHalf) + widthHalf;
 | 
			
		||||
        pt.y = - (pt.y * heightHalf) + heightHalf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 更新视角观测目标(物体中心)
 | 
			
		||||
     * 
 | 
			
		||||
     * @memberof Viewer
 | 
			
		||||
     */
 | 
			
		||||
    UpdateLockTarget()
 | 
			
		||||
    {
 | 
			
		||||
        let renderList = this.m_Render.renderLists.get(this.m_Scene, this.m_Camera.Camera);
 | 
			
		||||
        let box = GetBoxArr(renderList.opaque.map(o => o.object));
 | 
			
		||||
        if (box)
 | 
			
		||||
            this.m_LookTarget = box.getCenter(new THREE.Vector3());
 | 
			
		||||
        else
 | 
			
		||||
            this.m_LookTarget = cZeroVec;
 | 
			
		||||
    }
 | 
			
		||||
    Rotate(mouseMove: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Camera.Rotate(mouseMove, this.m_LookTarget);
 | 
			
		||||
        this.m_bNeedUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
    Pan(mouseMove: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Camera.Pan(mouseMove);
 | 
			
		||||
        this.m_bNeedUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
    Zoom(scale: number, center?: THREE.Vector3)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Camera.Zoom(scale, center);
 | 
			
		||||
        this.m_bNeedUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
    ZoomAll()
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Camera.ZoomExtensBox3(GetBox(this.m_Scene, true));
 | 
			
		||||
        this.m_bNeedUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ViewToTop()
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Camera.LookAt(new THREE.Vector3(0, 0, -1));
 | 
			
		||||
        this.m_bNeedUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
    ViewToFront()
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Camera.LookAt(new THREE.Vector3(0, 1, 0));
 | 
			
		||||
        this.m_bNeedUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
    ViewToSwiso()
 | 
			
		||||
    {
 | 
			
		||||
        this.m_Camera.LookAt(new THREE.Vector3(1, 1, -1));
 | 
			
		||||
        this.m_bNeedUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										142
									
								
								src/createBoard.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								src/createBoard.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
import * as THREE from 'three';
 | 
			
		||||
import { LineSegments, Mesh } from 'three';
 | 
			
		||||
import { polar } from './GeUtils';
 | 
			
		||||
import { boardMaterial, edgeMaterial } from './Material';
 | 
			
		||||
import { RotateUVs } from './RotateUV';
 | 
			
		||||
//解析二维圆弧类.
 | 
			
		||||
export class Arc2d
 | 
			
		||||
{
 | 
			
		||||
    m_StartAn: number;
 | 
			
		||||
    m_EndAn: number;
 | 
			
		||||
    m_StartPoint: THREE.Vector2;
 | 
			
		||||
    m_EndPoint: THREE.Vector2;
 | 
			
		||||
    m_Center: THREE.Vector2;
 | 
			
		||||
    m_Radius: number;
 | 
			
		||||
    constructor(p1: THREE.Vector2, p2: THREE.Vector2, bul: number)
 | 
			
		||||
    {
 | 
			
		||||
        this.m_StartPoint = p1.clone();
 | 
			
		||||
        this.m_EndPoint = p2.clone();
 | 
			
		||||
 | 
			
		||||
        let vec: THREE.Vector2 = p2.clone().sub(p1);
 | 
			
		||||
        let len = vec.length();
 | 
			
		||||
        let an = vec.angle();
 | 
			
		||||
        this.m_Radius = len / Math.sin(2 * Math.atan(bul)) / 2;
 | 
			
		||||
        let allAngle = Math.atan(bul) * 4;
 | 
			
		||||
        let delDis = bul * len / 2;
 | 
			
		||||
        let toDis = this.m_Radius - delDis;
 | 
			
		||||
        an += Math.PI * 0.5;
 | 
			
		||||
 | 
			
		||||
        this.m_Center = p1.clone().add(p2);
 | 
			
		||||
        this.m_Center.multiplyScalar(0.5);
 | 
			
		||||
 | 
			
		||||
        polar(this.m_Center, an, toDis);
 | 
			
		||||
 | 
			
		||||
        this.m_StartAn = p1.clone().sub(this.m_Center).angle();
 | 
			
		||||
        this.m_EndAn = p2.clone().sub(this.m_Center).angle();
 | 
			
		||||
        if (bul < 0)
 | 
			
		||||
        {
 | 
			
		||||
            //一个神奇的特性 它需要这么做
 | 
			
		||||
            this.m_StartAn -= Math.PI;
 | 
			
		||||
            this.m_EndAn -= Math.PI;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//创建轮廓 通过点表和凸度    
 | 
			
		||||
export function createPath(pts: THREE.Vector2[], buls: number[], shapeOut?: THREE.Shape): THREE.Shape
 | 
			
		||||
{
 | 
			
		||||
    let shape = shapeOut || new THREE.Shape();
 | 
			
		||||
    if (pts.length === 0) return shape;
 | 
			
		||||
    let firstPt = pts[0];
 | 
			
		||||
 | 
			
		||||
    shape.moveTo(firstPt.x, firstPt.y);
 | 
			
		||||
    for (let i = 0; i < pts.length - 1; i++)
 | 
			
		||||
    {
 | 
			
		||||
        let nextPt = pts[i + 1];
 | 
			
		||||
        if (buls[i] == 0)
 | 
			
		||||
        {
 | 
			
		||||
            shape.lineTo(nextPt.x, nextPt.y)
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            let pt = pts[i];
 | 
			
		||||
            //参考
 | 
			
		||||
            //http://www.dorodnic.com/blog/tag/three-js/ 绘制一个齿轮
 | 
			
		||||
            //https://www.kirupa.com/html5/drawing_circles_canvas.htm //html5
 | 
			
		||||
            let arc2 = new Arc2d(pt, nextPt, buls[i]);
 | 
			
		||||
            let cen = arc2.m_Center;
 | 
			
		||||
            shape.absarc(cen.x, cen.y, arc2.m_Radius, arc2.m_StartAn, arc2.m_EndAn, buls[i] < 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return shape;
 | 
			
		||||
}
 | 
			
		||||
export function getVec(data: object): THREE.Vector3
 | 
			
		||||
{
 | 
			
		||||
    return new THREE.Vector3(data["x"], data["y"], data["z"]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//创建板件 暂时这么写
 | 
			
		||||
export function createBoard(boardData: object)
 | 
			
		||||
{
 | 
			
		||||
    let pts: THREE.Vector2[] = new Array();
 | 
			
		||||
    let buls: number[] = new Array();
 | 
			
		||||
    let boardPts = boardData["Pts"];
 | 
			
		||||
    let boardBuls = boardData["Buls"];
 | 
			
		||||
 | 
			
		||||
    let boardHeight = boardData["H"];
 | 
			
		||||
 | 
			
		||||
    let boardMat = new THREE.Matrix4();
 | 
			
		||||
    let matInv: THREE.Matrix4 = new THREE.Matrix4();
 | 
			
		||||
    //InitBoardMat
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        let xD = getVec(boardData["XVec"]);
 | 
			
		||||
        let yD = getVec(boardData["YVec"]);
 | 
			
		||||
        let ZD = getVec(boardData["ZVec"]);
 | 
			
		||||
        let pBase = getVec(boardData["BasePoint"]);
 | 
			
		||||
 | 
			
		||||
        boardMat.makeBasis(xD, yD, ZD);
 | 
			
		||||
        boardMat.setPosition(pBase);
 | 
			
		||||
        matInv.getInverse(boardMat, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < boardPts.length; i++)
 | 
			
		||||
    {
 | 
			
		||||
        let pt = getVec(boardPts[i]);
 | 
			
		||||
        pt.applyMatrix4(matInv);
 | 
			
		||||
        pts.push(new THREE.Vector2(pt.x, pt.y));
 | 
			
		||||
        buls.push(boardBuls[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let sp = createPath(pts, buls);
 | 
			
		||||
    let extrudeSettings = {
 | 
			
		||||
        steps: 1,
 | 
			
		||||
        bevelEnabled: false,
 | 
			
		||||
        amount: boardHeight
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let ext = new THREE.ExtrudeGeometry(sp, extrudeSettings);
 | 
			
		||||
    ext.computeBoundingSphere();
 | 
			
		||||
    ext.computeBoundingBox();
 | 
			
		||||
    ext.translate(0, 0, -boardHeight)
 | 
			
		||||
    ext.applyMatrix(boardMat);
 | 
			
		||||
 | 
			
		||||
    if (boardData["BoardName"] === "地脚线")
 | 
			
		||||
    {
 | 
			
		||||
        RotateUVs(ext);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mesh = new THREE.Mesh(ext, boardMaterial);
 | 
			
		||||
    return mesh;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createTemplateBoard(brDataList: any[])
 | 
			
		||||
{
 | 
			
		||||
    return brDataList.map(brData => createBoard(brData));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createEdge(board: Mesh): LineSegments
 | 
			
		||||
{
 | 
			
		||||
    let edge = new THREE.EdgesGeometry(board.geometry, 1);
 | 
			
		||||
    return new LineSegments(edge, edgeMaterial);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										550
									
								
								src/data.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										550
									
								
								src/data.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,550 @@
 | 
			
		||||
export var data =
 | 
			
		||||
    [
 | 
			
		||||
        {
 | 
			
		||||
            "L": 100.0,
 | 
			
		||||
            "W": 800.0,
 | 
			
		||||
            "H": 18.0,
 | 
			
		||||
            "BasePoint": {
 | 
			
		||||
                "x": 2076.407626150509,
 | 
			
		||||
                "y": 1942.2104819571228,
 | 
			
		||||
                "z": 1882.0
 | 
			
		||||
            },
 | 
			
		||||
            "XVec": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 4.930380657631324e-32,
 | 
			
		||||
                "z": -2.220446049250313e-16
 | 
			
		||||
            },
 | 
			
		||||
            "YVec": {
 | 
			
		||||
                "x": 2.220446049250313e-16,
 | 
			
		||||
                "y": 2.220446049250313e-16,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "ZVec": {
 | 
			
		||||
                "x": 9.860761315262648e-32,
 | 
			
		||||
                "y": -1.0,
 | 
			
		||||
                "z": 2.220446049250313e-16
 | 
			
		||||
            },
 | 
			
		||||
            "Pts": [
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1942.2104819571228,
 | 
			
		||||
                    "z": 1882.0
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1942.2104819571228,
 | 
			
		||||
                    "z": 1881.9999999999998
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1942.2104819571228,
 | 
			
		||||
                    "z": 1981.9999999999998
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1942.2104819571228,
 | 
			
		||||
                    "z": 1982.0
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1942.2104819571228,
 | 
			
		||||
                    "z": 1882.0
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "Buls": [
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "SubBoardLocal": [],
 | 
			
		||||
            "SubBoardAssoc": []
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "L": 800.0,
 | 
			
		||||
            "W": 100.00000000000068,
 | 
			
		||||
            "H": 18.0,
 | 
			
		||||
            "MaterialId": "EE",
 | 
			
		||||
            "BasePoint": {
 | 
			
		||||
                "x": 2876.407626150509,
 | 
			
		||||
                "y": 1960.2104819571226,
 | 
			
		||||
                "z": 1900.0000000000005
 | 
			
		||||
            },
 | 
			
		||||
            "XVec": {
 | 
			
		||||
                "x": 4.440892098500626e-16,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 2.2204460492503124e-16
 | 
			
		||||
            },
 | 
			
		||||
            "YVec": {
 | 
			
		||||
                "x": -1.0,
 | 
			
		||||
                "y": 4.440892098500626e-16,
 | 
			
		||||
                "z": 2.220446049250314e-16
 | 
			
		||||
            },
 | 
			
		||||
            "ZVec": {
 | 
			
		||||
                "x": 2.220446049250313e-16,
 | 
			
		||||
                "y": -2.220446049250313e-16,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "Handle": "293",
 | 
			
		||||
            "CabName": "1.标准柜上梁1",
 | 
			
		||||
            "BoardName": "",
 | 
			
		||||
            "Grain": 0,
 | 
			
		||||
            "Pts": [
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571228,
 | 
			
		||||
                    "z": 1900.0000000000005
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 2060.210481957123,
 | 
			
		||||
                    "z": 1900.0000000000005
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 2060.210481957123,
 | 
			
		||||
                    "z": 1900.0000000000005
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1960.210481957123,
 | 
			
		||||
                    "z": 1900.0000000000005
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571228,
 | 
			
		||||
                    "z": 1900.0000000000005
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "Buls": [
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "SubBoardLocal": [],
 | 
			
		||||
            "SubBoardAssoc": []
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "L": 1899.9999999999998,
 | 
			
		||||
            "W": 800.0,
 | 
			
		||||
            "H": 18.0,
 | 
			
		||||
            "MaterialId": "EE",
 | 
			
		||||
            "BasePoint": {
 | 
			
		||||
                "x": 2076.407626150509,
 | 
			
		||||
                "y": 2060.2104819571225,
 | 
			
		||||
                "z": -1.816324868286756e-13
 | 
			
		||||
            },
 | 
			
		||||
            "XVec": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
            },
 | 
			
		||||
            "YVec": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 4.440892098500626e-16,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "ZVec": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": -1.0,
 | 
			
		||||
                "z": 4.440892098500626e-16
 | 
			
		||||
            },
 | 
			
		||||
            "Handle": "291",
 | 
			
		||||
            "CabName": "1.标准柜上梁1",
 | 
			
		||||
            "BoardName": "背板",
 | 
			
		||||
            "Grain": 0,
 | 
			
		||||
            "Pts": [
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 2060.2104819571225,
 | 
			
		||||
                    "z": -1.021405182655144e-13
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 2060.2104819571225,
 | 
			
		||||
                    "z": -1.816324868286756e-13
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 2060.210481957123,
 | 
			
		||||
                    "z": 1899.9999999999996
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 2060.210481957123,
 | 
			
		||||
                    "z": 1899.9999999999998
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 2060.2104819571225,
 | 
			
		||||
                    "z": -1.021405182655144e-13
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "Buls": [
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "SubBoardLocal": [],
 | 
			
		||||
            "SubBoardAssoc": []
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "L": 800.0,
 | 
			
		||||
            "W": 482.0000000000002,
 | 
			
		||||
            "H": 18.0,
 | 
			
		||||
            "MaterialId": "EE",
 | 
			
		||||
            "BasePoint": {
 | 
			
		||||
                "x": 2876.407626150509,
 | 
			
		||||
                "y": 1578.210481957122,
 | 
			
		||||
                "z": 97.99999999999999
 | 
			
		||||
            },
 | 
			
		||||
            "XVec": {
 | 
			
		||||
                "x": 4.440892098500626e-16,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
            },
 | 
			
		||||
            "YVec": {
 | 
			
		||||
                "x": -1.0,
 | 
			
		||||
                "y": 4.440892098500626e-16,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
            },
 | 
			
		||||
            "ZVec": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "Handle": "290",
 | 
			
		||||
            "CabName": "1.标准柜上梁1",
 | 
			
		||||
            "BoardName": "底板",
 | 
			
		||||
            "Grain": 0,
 | 
			
		||||
            "Pts": [
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1578.210481957122,
 | 
			
		||||
                    "z": 97.99999999999999
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 2060.2104819571225,
 | 
			
		||||
                    "z": 97.99999999999999
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 2060.2104819571225,
 | 
			
		||||
                    "z": 97.99999999999999
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1578.2104819571226,
 | 
			
		||||
                    "z": 97.99999999999999
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1578.210481957122,
 | 
			
		||||
                    "z": 97.99999999999999
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "Buls": [
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "SubBoardLocal": [],
 | 
			
		||||
            "SubBoardAssoc": []
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "L": 80.0,
 | 
			
		||||
            "W": 800.0,
 | 
			
		||||
            "H": 18.0,
 | 
			
		||||
            "MaterialId": "EE",
 | 
			
		||||
            "BasePoint": {
 | 
			
		||||
                "x": 2076.407626150509,
 | 
			
		||||
                "y": 1578.2104819571223,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
            },
 | 
			
		||||
            "XVec": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
            },
 | 
			
		||||
            "YVec": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 4.440892098500626e-16,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "ZVec": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": -1.0,
 | 
			
		||||
                "z": 4.440892098500626e-16
 | 
			
		||||
            },
 | 
			
		||||
            "Handle": "28E",
 | 
			
		||||
            "CabName": "1.标准柜上梁1",
 | 
			
		||||
            "BoardName": "地脚线",
 | 
			
		||||
            "Grain": 1,
 | 
			
		||||
            "Pts": [
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1578.2104819571223,
 | 
			
		||||
                    "z": 0.0
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1578.2104819571223,
 | 
			
		||||
                    "z": 0.0
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1578.2104819571223,
 | 
			
		||||
                    "z": 80.0
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1578.2104819571223,
 | 
			
		||||
                    "z": 80.0
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1578.2104819571223,
 | 
			
		||||
                    "z": 0.0
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "Buls": [
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "SubBoardLocal": [],
 | 
			
		||||
            "SubBoardAssoc": []
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "L": 800.0,
 | 
			
		||||
            "W": 482.0,
 | 
			
		||||
            "H": 18.0,
 | 
			
		||||
            "MaterialId": "EE",
 | 
			
		||||
            "BasePoint": {
 | 
			
		||||
                "x": 2876.4076261505085,
 | 
			
		||||
                "y": 1478.210481957122,
 | 
			
		||||
                "z": 1999.9999999999996
 | 
			
		||||
            },
 | 
			
		||||
            "XVec": {
 | 
			
		||||
                "x": 4.440892098500626e-16,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
            },
 | 
			
		||||
            "YVec": {
 | 
			
		||||
                "x": -1.0,
 | 
			
		||||
                "y": 4.440892098500626e-16,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
            },
 | 
			
		||||
            "ZVec": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "Handle": "28C",
 | 
			
		||||
            "CabName": "1.标准柜上梁1",
 | 
			
		||||
            "BoardName": "顶板",
 | 
			
		||||
            "Grain": 0,
 | 
			
		||||
            "Pts": [
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571223,
 | 
			
		||||
                    "z": 1999.9999999999996
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1478.2104819571226,
 | 
			
		||||
                    "z": 1999.9999999999996
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.407626150509,
 | 
			
		||||
                    "y": 1478.210481957122,
 | 
			
		||||
                    "z": 1999.9999999999996
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2876.4076261505085,
 | 
			
		||||
                    "y": 1960.210481957122,
 | 
			
		||||
                    "z": 1999.9999999999996
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571223,
 | 
			
		||||
                    "z": 1999.9999999999996
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "Buls": [
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "SubBoardLocal": [],
 | 
			
		||||
            "SubBoardAssoc": []
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "L": 1999.9999999999996,
 | 
			
		||||
            "W": 600.0,
 | 
			
		||||
            "H": 18.0,
 | 
			
		||||
            "MaterialId": "EE",
 | 
			
		||||
            "BasePoint": {
 | 
			
		||||
                "x": 2894.4076261505094,
 | 
			
		||||
                "y": 1478.2104819571223,
 | 
			
		||||
                "z": -2.2737367544323197e-13
 | 
			
		||||
            },
 | 
			
		||||
            "XVec": {
 | 
			
		||||
                "x": 4.930380657631324e-32,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": -2.220446049250313e-16
 | 
			
		||||
            },
 | 
			
		||||
            "YVec": {
 | 
			
		||||
                "x": -2.220446049250313e-16,
 | 
			
		||||
                "y": 2.220446049250313e-16,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "ZVec": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 2.220446049250313e-16
 | 
			
		||||
            },
 | 
			
		||||
            "Handle": "28B",
 | 
			
		||||
            "CabName": "1.标准柜上梁1",
 | 
			
		||||
            "BoardName": "右侧板",
 | 
			
		||||
            "Grain": 0,
 | 
			
		||||
            "Pts": [
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2894.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571228,
 | 
			
		||||
                    "z": 1899.9999999999989
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2894.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571228,
 | 
			
		||||
                    "z": 1999.9999999999994
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2894.407626150509,
 | 
			
		||||
                    "y": 1478.2104819571228,
 | 
			
		||||
                    "z": 1999.9999999999994
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2894.4076261505094,
 | 
			
		||||
                    "y": 1478.2104819571223,
 | 
			
		||||
                    "z": -1.816324868286755e-13
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2894.4076261505094,
 | 
			
		||||
                    "y": 2078.2104819571225,
 | 
			
		||||
                    "z": -6.274980535181384e-13
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2894.407626150509,
 | 
			
		||||
                    "y": 2078.2104819571229,
 | 
			
		||||
                    "z": 1899.9999999999973
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2894.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571228,
 | 
			
		||||
                    "z": 1899.9999999999989
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "Buls": [
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "SubBoardLocal": [],
 | 
			
		||||
            "SubBoardAssoc": []
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "L": 1999.9999999999996,
 | 
			
		||||
            "W": 600.0,
 | 
			
		||||
            "H": 18.0,
 | 
			
		||||
            "MaterialId": "EE",
 | 
			
		||||
            "BasePoint": {
 | 
			
		||||
                "x": 2076.4076261505094,
 | 
			
		||||
                "y": 1478.2104819571223,
 | 
			
		||||
                "z": 1.0097419586828951e-28
 | 
			
		||||
            },
 | 
			
		||||
            "XVec": {
 | 
			
		||||
                "x": 4.930380657631324e-32,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": -2.220446049250313e-16
 | 
			
		||||
            },
 | 
			
		||||
            "YVec": {
 | 
			
		||||
                "x": -2.220446049250313e-16,
 | 
			
		||||
                "y": 2.220446049250313e-16,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "ZVec": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 2.220446049250313e-16
 | 
			
		||||
            },
 | 
			
		||||
            "Handle": "288",
 | 
			
		||||
            "CabName": "1.标准柜上梁1",
 | 
			
		||||
            "BoardName": "左侧板",
 | 
			
		||||
            "Grain": 0,
 | 
			
		||||
            "Pts": [
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571228,
 | 
			
		||||
                    "z": 1899.999999999999
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571228,
 | 
			
		||||
                    "z": 1999.9999999999996
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1478.2104819571228,
 | 
			
		||||
                    "z": 1999.9999999999996
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.4076261505094,
 | 
			
		||||
                    "y": 1478.2104819571223,
 | 
			
		||||
                    "z": 1.0097419586828951e-28
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.4076261505094,
 | 
			
		||||
                    "y": 2078.2104819571225,
 | 
			
		||||
                    "z": -4.4586556668946279e-13
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 2078.2104819571229,
 | 
			
		||||
                    "z": 1899.9999999999978
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "x": 2076.407626150509,
 | 
			
		||||
                    "y": 1960.2104819571228,
 | 
			
		||||
                    "z": 1899.999999999999
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "Buls": [
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0,
 | 
			
		||||
                0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "SubBoardLocal": [],
 | 
			
		||||
            "SubBoardAssoc": []
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
							
								
								
									
										9
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
export * from "./Viewer";
 | 
			
		||||
export * from "./CameraControls";
 | 
			
		||||
export * from "./GeUtils";
 | 
			
		||||
export * from "./createBoard";
 | 
			
		||||
export * from "./Dimension";
 | 
			
		||||
export * from "./DrawDimension";
 | 
			
		||||
export * from "./Material";
 | 
			
		||||
export * from "./PointPick"
 | 
			
		||||
export * from "./Utils"
 | 
			
		||||
							
								
								
									
										19
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
{
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "declaration": true,
 | 
			
		||||
        "outDir": "./dist",
 | 
			
		||||
        "target": "esnext",
 | 
			
		||||
        "lib": [
 | 
			
		||||
            "es2017",
 | 
			
		||||
            "dom"
 | 
			
		||||
        ],
 | 
			
		||||
        "types": [
 | 
			
		||||
            "node"
 | 
			
		||||
        ],
 | 
			
		||||
        "module": "commonjs",
 | 
			
		||||
        "experimentalDecorators": true
 | 
			
		||||
    },
 | 
			
		||||
    "include": [
 | 
			
		||||
        "./src/**/*"
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user