3 Commits
1.2.0 ... v2

Author SHA1 Message Date
xief
623fa9ac9a 使用新的webcad api进行建模 2022-02-16 13:48:57 +08:00
FishOrBear
e712b7b4e2 同步代码 2020-05-07 10:51:27 +08:00
FishOrBear
85db279fab 更新版本,修复镜像槽问题 2020-04-30 17:12:30 +08:00
29 changed files with 8330 additions and 2393 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
/node_modules /node_modules
/dist /package-lock.json
.history

31
.vscode/settings.json vendored
View File

@@ -3,8 +3,10 @@
"typescript.tsdk": "node_modules\\typescript\\lib", "typescript.tsdk": "node_modules\\typescript\\lib",
//格式化设置 //格式化设置
"editor.tabSize": 4, "editor.tabSize": 4,
"editor.formatOnPaste": true, "editor.formatOnPaste": false,
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.insertSpaces": true,
"editor.detectIndentation": false,
//格式设置 //格式设置
"typescript.format.placeOpenBraceOnNewLineForFunctions": true, "typescript.format.placeOpenBraceOnNewLineForFunctions": true,
"typescript.format.placeOpenBraceOnNewLineForControlBlocks": true, "typescript.format.placeOpenBraceOnNewLineForControlBlocks": true,
@@ -12,5 +14,30 @@
"javascript.format.placeOpenBraceOnNewLineForFunctions": true, "javascript.format.placeOpenBraceOnNewLineForFunctions": true,
"javascript.format.enable": true, "javascript.format.enable": true,
"files.insertFinalNewline": true, "files.insertFinalNewline": true,
"editor.detectIndentation": true, "typescript.format.semicolons": "insert",
"files.trimFinalNewlines": true,
"files.trimTrailingWhitespace": true,
//保存时
"editor.codeActionsOnSave": {
"source.organizeImports": true,
},
"gitlens.remotes": [
{
"domain": "gitee.com",
"type": "Custom",
"name": "码云",
"protocol": "https",
"urls": {
"repository": "https://gitee.com/cf-fz/${repoPath}",
"branches": "https://gitee.com/cf-fz/${repoPath}/branches",
"branch": "https://gitee.com/cf-fz/${repoPath}/commits/${branch}",
"commit": "https://gitee.com/cf-fz/${repoPath}/commit/${id}",
"file": "https://gitee.com/cf-fz/${repoPath}?path=${file}${line}",
"fileInBranch": "https://gitee.com/cf-fz/${repoPath}/blob/${branch}/${file}${line}",
"fileInCommit": "https://gitee.com/cf-fz/${repoPath}/blob/${id}/${file}${line}",
"fileLine": "#L${line}",
"fileRange": "#L${start}-L${end}"
}
}
],
} }

View File

@@ -1,3 +1,6 @@
# 显示板件的控件 # 显示板件的控件
使用例子请参照项目:[CADViewSample](http://git.cf/cx/CADViewSample) 使用例子请参照项目:[CADViewSample](http://git.cf/cx/CADViewSample)
删除"@types/webpack-merge" 下的 node_modules/webpack 定义 坑爹导致项目跑不起来

View File

@@ -1,6 +1,15 @@
import * as HardSourceWebpackPlugin from 'hard-source-webpack-plugin';
import * as webpack from 'webpack'; import * as webpack from 'webpack';
import ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const TS_LOADER = [
{ loader: 'cache-loader', options: { cacheDirectory: "node_modules/.cache_loader" } },
{
loader: 'ts-loader',
options: {
transpileOnly: true,
experimentalWatchApi: true,
},
}
];
const config: webpack.Configuration = { const config: webpack.Configuration = {
devtool: "source-map", devtool: "source-map",
@@ -8,20 +17,13 @@ const config: webpack.Configuration = {
resolve: { resolve: {
extensions: [".ts", ".tsx", ".js", "json"] extensions: [".ts", ".tsx", ".js", "json"]
}, },
externals: {
'three': "THREE"
},
//模块加载器设置 //模块加载器设置
module: { module: {
rules: [ rules: [
{ {
test: /\.tsx?$/, test: /\.tsx?$/,
exclude: /node_modules/, exclude: /node_modules/,
loader: 'ts-loader', use: TS_LOADER,
options: {
transpileOnly: true,
experimentalWatchApi: true,
},
}, },
{ test: /\.css$/, loader: ['style-loader', 'css-loader'] }, { test: /\.css$/, loader: ['style-loader', 'css-loader'] },
{ test: /\.[(jpg)|(png)|(obj)|(json)]$/, loader: "url-loader" }, { test: /\.[(jpg)|(png)|(obj)|(json)]$/, loader: "url-loader" },
@@ -29,8 +31,6 @@ const config: webpack.Configuration = {
}, },
plugins: [ plugins: [
new HardSourceWebpackPlugin(),
new ForkTsCheckerWebpackPlugin({ checkSyntacticErrors: true }),
] ]
} }

View File

@@ -1,13 +1,16 @@
import path from 'path';
import * as webpack from 'webpack'; import * as webpack from 'webpack';
import * as merge from 'webpack-merge'; import merge from 'webpack-merge';
import common from './webpack.common'; import common from './webpack.common';
import * as path from 'path';
const config: webpack.Configuration = merge( const config: webpack.Configuration = merge(
common, common,
{ {
mode: "production", mode: "production",
entry: "./src/index.ts", entry: "./src/index.ts",
externals: {
'three': "THREE"
},
//输出设置 //输出设置
output: { output: {
filename: "cad.js", filename: "cad.js",

View File

@@ -1,7 +1,7 @@
import * as webpack from 'webpack'; import * as webpack from 'webpack';
import * as merge from 'webpack-merge'; import merge from 'webpack-merge';
import common from './webpack.common'; import common from './webpack.common';
import * as HtmlWebPackPlugin from "html-webpack-plugin"; import HtmlWebPackPlugin from "html-webpack-plugin";
const config: webpack.Configuration = merge( const config: webpack.Configuration = merge(
common, common,
@@ -9,7 +9,7 @@ const config: webpack.Configuration = merge(
mode: "development", mode: "development",
entry: "./src/ViewSrc/index.ts", entry: "./src/ViewSrc/index.ts",
output: { pathinfo: false }, output: { pathinfo: false },
devtool: "cheap-module-eval-source-map", devtool: "eval-source-map",
devServer: { devServer: {
contentBase: "./dist/", contentBase: "./dist/",
port: 7776, port: 7776,
@@ -26,6 +26,4 @@ const config: webpack.Configuration = merge(
} }
); );
config.externals = {};
export default config; export default config;

4453
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +1,50 @@
{ {
"name": "cadview", "name": "cadview",
"version": "1.2.0", "version": "1.1.9",
"description": "", "description": "",
"main": "src/index.ts", "main": "dist/index.js",
"private": true, "types": "dist/index.d.ts",
"scripts": { "private": true,
"build": "tsc", "scripts": {
"umd": "webpack --config ./config/webpack.umd.ts", "t": "tsc --noEmit -w",
"dev": "webpack-dev-server --config ./config/webpack.view.ts", "build": "tsc",
"type": "ts-node ./utils/copy_type.ts" "umd": "webpack --config ./config/webpack.umd.ts",
}, "dev": "webpack-dev-server --config ./config/webpack.view.ts",
"repository": { "postinstall": "ts-node ./utils/rmtype.ts"
"type": "git", },
"url": "http://git.cf/cx/CADViewComponent.git" "repository": {
}, "type": "git",
"author": "cx", "url": "http://git.cf/cx/CADViewComponent.git"
"license": "ISC", },
"devDependencies": { "author": "cx",
"@types/hard-source-webpack-plugin": "^0.9.0", "license": "ISC",
"@types/node": "^10.11.7", "devDependencies": {
"@types/uglifyjs-webpack-plugin": "^1.1.0", "@types/hard-source-webpack-plugin": "^1.0.1",
"@types/webpack": "^4.4.16", "@types/node": "^13.13.52",
"@types/webpack-dev-server": "^3.1.1", "@types/three": "^0.103.2",
"@types/webpack-env": "^1.13.6", "@types/uglifyjs-webpack-plugin": "^1.1.0",
"@types/webpack-merge": "^4.1.3", "@types/webpack": "^4.41.32",
"awesome-typescript-loader": "^5.2.1", "@types/webpack-dev-server": "^3.11.6",
"fork-ts-checker-webpack-plugin": "^0.4.8", "@types/webpack-env": "^1.15.2",
"hard-source-webpack-plugin": "^0.12.0", "@types/webpack-merge": "^4.1.5",
"html-webpack-plugin": "^3.2.0", "awesome-typescript-loader": "^5.2.1",
"ts-loader": "^5.2.1", "cache-loader": "^4.1.0",
"ts-node": "^7.0.1", "fork-ts-checker-webpack-plugin": "^4.1.6",
"typescript": "^3.7.5", "hard-source-webpack-plugin": "^0.13.1",
"uglifyjs-webpack-plugin": "^2.0.1", "html-webpack-plugin": "^4.5.2",
"webpack": "^4.20.2", "ts-loader": "^7.0.5",
"webpack-cli": "^3.1.2", "ts-node": "^8.10.2",
"webpack-dev-server": "^3.1.9", "typescript": "^4.5.5",
"webpack-merge": "^4.1.4" "uglifyjs-webpack-plugin": "^2.2.0",
}, "webpack": "^4.46.0",
"dependencies": { "webpack-cli": "^3.3.12",
"@types/three": "^0.92.25", "webpack-dev-server": "^3.11.3",
"three": "^0.95.0", "webpack-merge": "^4.2.2"
"wolfy87-eventemitter": "^5.2.5" },
} "dependencies": {
"@jscad/modeling": "^2.7.1",
"flatbush": "^3.3.0",
"three": "^0.115.0",
"webcad_ue4_api": "http://gitea.cf/cx/webcad-ue4-api/archive/0.2.3.tar.gz"
}
} }

View File

@@ -56,7 +56,6 @@ export class CameraControls
} }
/** /**
* 窗体失去焦点时. * 窗体失去焦点时.
*
* @memberof CameraControls * @memberof CameraControls
*/ */
onBlur = () => onBlur = () =>
@@ -136,7 +135,7 @@ export class CameraControls
//最后一次按中键的时间 //最后一次按中键的时间
lastMiddleClickTime = 0; lastMiddleClickTime = 0;
//鼠标 //鼠标
onMouseDown = (event: MouseEvent) => onMouseDown = (event: MouseEvent) =>
{ {
event.preventDefault(); event.preventDefault();
@@ -220,12 +219,11 @@ export class CameraControls
} }
/** /**
* 鼠标滚轮事件 * 鼠标滚轮事件
* *
* @memberof CameraControls * @memberof CameraControls
*/ */
onMouseWheel = (event: WheelEvent) => onMouseWheel = (event: WheelEvent) =>
{ {
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
let pt = new THREE.Vector3(event.offsetX, event.offsetY, 0); let pt = new THREE.Vector3(event.offsetX, event.offsetY, 0);

View File

@@ -1,21 +1,20 @@
import * as THREE from 'three'; import { Box3, Camera, MathUtils, OrthographicCamera, PerspectiveCamera, Vector3 } from 'three';
import { Vector3 } from 'three';
import { Orbit } from './Orbit'; import { Orbit } from './Orbit';
/** /**
* *
* 相机的控制. * 相机的控制.
* ->切换相机 * ->切换相机
* ->设置视口大小 * ->设置视口大小
* ->旋转和移动相机. * ->旋转和移动相机.
* *
* @export * @export
* @class ViewCameraManage * @class ViewCameraManage
*/ */
export class CameraUpdate export class CameraUpdate
{ {
private m_CurCamera: THREE.Camera; private m_CurCamera: Camera;
private m_CameraArray: Map<any, THREE.Camera> = new Map<any, THREE.Camera>(); private m_CameraArray: Map<any, Camera> = new Map<any, Camera>();
//视口的画布大小 //视口的画布大小
private m_Width: number; private m_Width: number;
@@ -24,9 +23,9 @@ export class CameraUpdate
private m_ViewHeight: number = 10; private m_ViewHeight: number = 10;
//观察的位置 //观察的位置
private m_Target: THREE.Vector3 = new THREE.Vector3(); private m_Target: Vector3 = new Vector3();
//观察向量 //观察向量
private m_Direction: THREE.Vector3 = new THREE.Vector3(0, 0, -1); private m_Direction: Vector3 = new Vector3(0, 0, -1);
//观察的轨道. //观察的轨道.
private m_Orbit: Orbit = new Orbit(); private m_Orbit: Orbit = new Orbit();
@@ -35,12 +34,12 @@ export class CameraUpdate
constructor() constructor()
{ {
this.m_CameraArray.set(THREE.OrthographicCamera, new THREE.OrthographicCamera(-2, 2, 2, -2, this.m_CameraArray.set(OrthographicCamera, new OrthographicCamera(-2, 2, 2, -2,
-1e6, 1e6)); -1e6, 1e6));
this.m_CameraArray.set(THREE.PerspectiveCamera, new THREE.PerspectiveCamera(50, 1, 0.01, 10000)); this.m_CameraArray.set(PerspectiveCamera, new PerspectiveCamera(50, 1, 0.01, 10000));
this.m_CurCamera = this.m_CameraArray.get(THREE.OrthographicCamera); this.m_CurCamera = this.m_CameraArray.get(OrthographicCamera);
this.m_Orbit.UpdateRoValue(this.m_Direction); this.m_Orbit.UpdateRoValue(this.m_Direction);
@@ -53,7 +52,7 @@ export class CameraUpdate
return this.m_Width / this.m_Height; return this.m_Width / this.m_Height;
} }
get Camera(): THREE.Camera get Camera(): Camera
{ {
return this.m_CurCamera; return this.m_CurCamera;
} }
@@ -63,7 +62,7 @@ export class CameraUpdate
} }
set ViewHeight(height) set ViewHeight(height)
{ {
this.m_ViewHeight = THREE.Math.clamp(height, this.m_MinViewHeight, this.m_MaxViewHeight); this.m_ViewHeight = MathUtils.clamp(height, this.m_MinViewHeight, this.m_MaxViewHeight);
} }
SetSize(width: number, height: number) SetSize(width: number, height: number)
@@ -74,11 +73,11 @@ export class CameraUpdate
/** /**
* 平移相机. * 平移相机.
* *
* @param {THREE.Vector3} mouseMove * @param {Vector3} mouseMove
* @memberof CameraControl * @memberof CameraControl
*/ */
Pan(mouseMove: THREE.Vector3) Pan(mouseMove: Vector3)
{ {
mouseMove.y *= -1; mouseMove.y *= -1;
mouseMove.multiplyScalar(-this.m_ViewHeight / this.m_Height); mouseMove.multiplyScalar(-this.m_ViewHeight / this.m_Height);
@@ -86,7 +85,7 @@ export class CameraUpdate
this.m_Target.add(mouseMove); this.m_Target.add(mouseMove);
this.Update(); this.Update();
} }
Rotate(mouseMove: THREE.Vector3, target: THREE.Vector3) Rotate(mouseMove: Vector3, target: Vector3)
{ {
this.m_Orbit.RoX -= mouseMove.y * 0.003; this.m_Orbit.RoX -= mouseMove.y * 0.003;
this.m_Orbit.RoZ -= mouseMove.x * 0.003; this.m_Orbit.RoZ -= mouseMove.x * 0.003;
@@ -112,9 +111,9 @@ export class CameraUpdate
this.Update(); this.Update();
} }
Zoom(scale: number, scaleCenter?: THREE.Vector3) Zoom(scale: number, scaleCenter?: Vector3)
{ {
if (this.Camera instanceof THREE.OrthographicCamera) if (this.Camera instanceof OrthographicCamera)
{ {
this.ViewHeight *= scale; this.ViewHeight *= scale;
if (scaleCenter && this.m_ViewHeight < this.m_MaxViewHeight) if (scaleCenter && this.m_ViewHeight < this.m_MaxViewHeight)
@@ -124,7 +123,7 @@ export class CameraUpdate
this.m_Target.add(scaleCenter); this.m_Target.add(scaleCenter);
} }
} }
else if (this.Camera instanceof THREE.PerspectiveCamera) else if (this.Camera instanceof PerspectiveCamera)
{ {
let add = scale > 1 ? 1 : -1; let add = scale > 1 ? 1 : -1;
add *= this.Camera.position.distanceTo(this.m_Target) / 10; add *= this.Camera.position.distanceTo(this.m_Target) / 10;
@@ -132,7 +131,7 @@ export class CameraUpdate
} }
this.Update(); this.Update();
} }
ZoomExtensBox3(box3: THREE.Box3) ZoomExtensBox3(box3: Box3)
{ {
if (!box3 || box3.isEmpty()) return; if (!box3 || box3.isEmpty()) return;
this.Camera.updateMatrixWorld(false); this.Camera.updateMatrixWorld(false);
@@ -159,7 +158,7 @@ export class CameraUpdate
} }
this.Update(); this.Update();
} }
LookAt(dir: THREE.Vector3) LookAt(dir: Vector3)
{ {
this.m_Orbit.UpdateRoValue(dir); this.m_Orbit.UpdateRoValue(dir);
this.m_Direction.copy(dir); this.m_Direction.copy(dir);
@@ -173,15 +172,15 @@ export class CameraUpdate
} }
/** /**
* 根据视口大小,设置相机视口范围. * 根据视口大小,设置相机视口范围.
* *
* @returns * @returns
* @memberof CameraControl * @memberof CameraControl
*/ */
Update() Update()
{ {
this.Camera.position.copy(this.m_Target); this.Camera.position.copy(this.m_Target);
if (this.Camera instanceof THREE.OrthographicCamera) if (this.Camera instanceof OrthographicCamera)
{ {
this.Camera.left = this.Aspect * this.m_ViewHeight / -2; this.Camera.left = this.Aspect * this.m_ViewHeight / -2;
this.Camera.right = this.Aspect * this.m_ViewHeight / 2; this.Camera.right = this.Aspect * this.m_ViewHeight / 2;
@@ -190,10 +189,10 @@ export class CameraUpdate
this.Camera.position.sub(this.m_Direction); this.Camera.position.sub(this.m_Direction);
} }
else if (this.Camera instanceof THREE.PerspectiveCamera) else if (this.Camera instanceof PerspectiveCamera)
{ {
this.Camera.aspect = this.Aspect; this.Camera.aspect = this.Aspect;
let distens = (this.m_ViewHeight / 2) / (Math.tan(THREE.Math.degToRad(this.Camera.fov) / 2)); let distens = (this.m_ViewHeight / 2) / (Math.tan(MathUtils.degToRad(this.Camera.fov) / 2));
this.Camera.position.sub(this.m_Direction.clone().multiplyScalar(distens)); this.Camera.position.sub(this.m_Direction.clone().multiplyScalar(distens));
} }
@@ -209,13 +208,13 @@ export class CameraUpdate
SwitchCamera() SwitchCamera()
{ {
if (this.Camera instanceof THREE.OrthographicCamera) if (this.Camera instanceof OrthographicCamera)
{ {
this.m_CurCamera = this.m_CameraArray.get(THREE.PerspectiveCamera); this.m_CurCamera = this.m_CameraArray.get(PerspectiveCamera);
} }
else else
{ {
this.m_CurCamera = this.m_CameraArray.get(THREE.OrthographicCamera); this.m_CurCamera = this.m_CameraArray.get(OrthographicCamera);
} }
this.UpdateUp(); this.UpdateUp();
this.Update(); this.Update();

View File

@@ -5,7 +5,6 @@ import { MoveMatrix } from "./GeUtils";
/** /**
* 标注实体 * 标注实体
*
* @export * @export
* @class Dimension * @class Dimension
* @extends {Group} * @extends {Group}
@@ -42,12 +41,12 @@ export class Dimension extends Group
if (mirror) if (mirror)
{ {
let roMat = new Matrix4().makeRotationZ(Math.PI); let roMat = new Matrix4().makeRotationZ(Math.PI);
text.applyMatrix(roMat); text.applyMatrix4(roMat);
text.applyMatrix(MoveMatrix(new Vector3(length * 0.5, footLength - textHeight * 0.1))); text.applyMatrix4(MoveMatrix(new Vector3(length * 0.5, footLength - textHeight * 0.1)));
} }
else else
{ {
text.applyMatrix(MoveMatrix(new Vector3(length * 0.5, footLength * 1.1))); text.applyMatrix4(MoveMatrix(new Vector3(length * 0.5, footLength * 1.1)));
} }

View File

@@ -1,12 +1,12 @@
import { Box3, Vector3, Matrix4, Mesh } from "three"; import { Box3, Matrix4, Mesh, Vector3 } from "three";
import { Dimension, GetBoxArr } from "."; import { Dimension, GetBoxArr } from ".";
/** /**
* 绘制标注实体 * 绘制标注实体
* *
* @export * @export
* @param {Box3} box * @param {Box3} box
* @returns 标注实体列表 * @returns 标注实体列表
*/ */
export function DrawDimension(brList: Mesh[]): Dimension[] export function DrawDimension(brList: Mesh[]): Dimension[]
@@ -24,7 +24,7 @@ export function DrawDimension(brList: Mesh[]): Dimension[]
let textHeight = 45; let textHeight = 45;
let dimx = new Dimension(size.x, textHeight, true); let dimx = new Dimension(size.x, textHeight, true);
dimx.applyMatrix(mat4); dimx.applyMatrix4(mat4);
let dimz = new Dimension(size.z, textHeight); let dimz = new Dimension(size.z, textHeight);
mat4.makeBasis( mat4.makeBasis(
@@ -33,7 +33,7 @@ export function DrawDimension(brList: Mesh[]): Dimension[]
new Vector3(0, -1, 0) new Vector3(0, -1, 0)
) )
mat4.setPosition(box.max.clone().add(new Vector3(30, -size.y))); mat4.setPosition(box.max.clone().add(new Vector3(30, -size.y)));
dimz.applyMatrix(mat4); dimz.applyMatrix4(mat4);
let dimy = new Dimension(size.y, textHeight, true, true); let dimy = new Dimension(size.y, textHeight, true, true);
mat4.makeBasis( mat4.makeBasis(
@@ -42,7 +42,7 @@ export function DrawDimension(brList: Mesh[]): Dimension[]
new Vector3(0, 0, 1) new Vector3(0, 0, 1)
) )
mat4.setPosition(box.max.clone().add(new Vector3(30, -size.y))); mat4.setPosition(box.max.clone().add(new Vector3(30, -size.y)));
dimy.applyMatrix(mat4); dimy.applyMatrix4(mat4);
return [dimx, dimy, dimz]; return [dimx, dimy, dimz];

View File

@@ -1,16 +1,15 @@
import * as THREE from 'three'; import { Geometry, Vector, Vector2, Vector3, Box3, Matrix4, Object3D, Line, Mesh } from 'three';
import { Geometry, Vector, Vector2, Vector3, Box3 } from 'three';
import { Matrix2 } from './Matrix2'; import { Matrix2 } from './Matrix2';
export const cZeroVec = new THREE.Vector3(); export const cZeroVec = new Vector3();
export const cXAxis = new THREE.Vector3(1, 0, 0); export const cXAxis = new Vector3(1, 0, 0);
export const cYAxis = new THREE.Vector3(0, 1, 0); export const cYAxis = new Vector3(0, 1, 0);
export const cZAxis = new THREE.Vector3(0, 0, 1); export const cZAxis = new Vector3(0, 0, 1);
/** /**
* 旋转一个点,旋转中心在原点 * 旋转一个点,旋转中心在原点
* *
* @export * @export
* @param {Vector3} pt 点 * @param {Vector3} pt 点
* @param {number} ang 角度. * @param {number} ang 角度.
@@ -26,6 +25,12 @@ export function equaln(v1: number, v2: number, fuzz = 1e-3)
{ {
return Math.abs(v1 - v2) < fuzz; return Math.abs(v1 - v2) < fuzz;
} }
export function equalv3(v1: Vector3, v2: Vector3, fuzz = 1e-8)
{
return equaln(v1.x, v2.x, fuzz) && equaln(v1.y, v2.y, fuzz) && equaln(v1.z, v2.z, fuzz);
}
export function equal<T extends Vector>(v1: T, v2: T) export function equal<T extends Vector>(v1: T, v2: T)
{ {
return v1.distanceToSquared(v2) < 1e-8; return v1.distanceToSquared(v2) < 1e-8;
@@ -50,13 +55,13 @@ export function fixAngle(an: number, fixAngle: number, fuzz: number = 0.1)
/** /**
* 按照极坐标的方式移动一个点 * 按照极坐标的方式移动一个点
* *
* @export * @export
* @template * @template
* @param {T} v 向量(2d,3d) * @param {T} v 向量(2d,3d)
* @param {number} an 角度 * @param {number} an 角度
* @param {number} dis 距离 * @param {number} dis 距离
* @returns {T} * @returns {T}
*/ */
export function polar<T extends Vector2 | Vector3>(v: T, an: number, dis: number): T export function polar<T extends Vector2 | Vector3>(v: T, an: number, dis: number): T
{ {
@@ -76,22 +81,22 @@ export function angle(v: Vector3 | Vector2)
/** /**
* 求两个向量的夹角,顺时针为负,逆时针为正 * 求两个向量的夹角,顺时针为负,逆时针为正
* *
* @param {THREE.Vector3} v1 * @param {Vector3} v1
* @param {THREE.Vector3} v2 * @param {Vector3} v2
* @param {THREE.Vector3} [ref] 参考向量,如果为世界坐标系则为0,0,1 * @param {Vector3} [ref] 参考向量,如果为世界坐标系则为0,0,1
* @returns * @returns
*/ */
export function angleTo(v1: THREE.Vector3, v2: THREE.Vector3, ref: THREE.Vector3 = new THREE.Vector3(0, 0, 1)) export function angleTo(v1: Vector3, v2: Vector3, ref: Vector3 = new Vector3(0, 0, 1))
{ {
if (!ref.equals(new Vector3(0, 0, 1))) if (!ref.equals(new Vector3(0, 0, 1)))
{ {
//任意轴坐标系. 使用相机的构造矩阵. //任意轴坐标系. 使用相机的构造矩阵.
ref.multiplyScalar(-1); ref.multiplyScalar(-1);
let up = getLoocAtUpVec(ref); let up = getLoocAtUpVec(ref);
let refOcs = new THREE.Matrix4(); let refOcs = new Matrix4();
refOcs.lookAt(cZeroVec, ref, up); refOcs.lookAt(cZeroVec, ref, up);
let refOcsInv = new THREE.Matrix4().getInverse(refOcs); let refOcsInv = new Matrix4().getInverse(refOcs);
v1.applyMatrix4(refOcsInv); v1.applyMatrix4(refOcsInv);
v2.applyMatrix4(refOcsInv); v2.applyMatrix4(refOcsInv);
v1.z = 0; v1.z = 0;
@@ -103,7 +108,7 @@ export function angleTo(v1: THREE.Vector3, v2: THREE.Vector3, ref: THREE.Vector3
return cv.z === 0 ? v1.angleTo(v2) : v1.angleTo(v2) * cv.z; return cv.z === 0 ? v1.angleTo(v2) : v1.angleTo(v2) * cv.z;
} }
export function getLoocAtUpVec(dir: THREE.Vector3): THREE.Vector3 export function getLoocAtUpVec(dir: Vector3): Vector3
{ {
if (dir.equals(cZeroVec)) if (dir.equals(cZeroVec))
{ {
@@ -112,37 +117,37 @@ export function getLoocAtUpVec(dir: THREE.Vector3): THREE.Vector3
let norm = dir.clone().normalize(); let norm = dir.clone().normalize();
if (norm.equals(cZAxis)) if (norm.equals(cZAxis))
{ {
return new THREE.Vector3(0, 1, 0); return new Vector3(0, 1, 0);
} }
else if (norm.equals(cZAxis.clone().negate())) else if (norm.equals(cZAxis.clone().negate()))
{ {
return new THREE.Vector3(0, -1, 0); return new Vector3(0, -1, 0);
} }
else else
{ {
let xv: THREE.Vector3 = new THREE.Vector3(); let xv: Vector3 = new Vector3();
xv.crossVectors(cZAxis, norm); xv.crossVectors(cZAxis, norm);
let up = new THREE.Vector3(); let up = new Vector3();
up.crossVectors(norm, xv); up.crossVectors(norm, xv);
return up; return up;
} }
} }
export function createLookAtMat4(dir: THREE.Vector3): THREE.Matrix4 export function createLookAtMat4(dir: Vector3): Matrix4
{ {
let up = getLoocAtUpVec(dir); let up = getLoocAtUpVec(dir);
let mat = new THREE.Matrix4(); let mat = new Matrix4();
mat.lookAt(cZeroVec, dir, up); mat.lookAt(cZeroVec, dir, up);
return mat; return mat;
} }
export function isParallelTo(v1: THREE.Vector3, v2: THREE.Vector3) export function isParallelTo(v1: Vector3, v2: Vector3)
{ {
return v1.clone().cross(v2).lengthSq() < 1e-9; return v1.clone().cross(v2).lengthSq() < 1e-9;
} }
export function ptToString(v: THREE.Vector3, fractionDigits: number = 3): string export function ptToString(v: Vector3, fractionDigits: number = 3): string
{ {
return v.toArray().map(o => return v.toArray().map(o =>
{ {
@@ -150,16 +155,16 @@ export function ptToString(v: THREE.Vector3, fractionDigits: number = 3): string
}).join(",") }).join(",")
} }
export function midPoint(v1: THREE.Vector3, v2: THREE.Vector3): THREE.Vector3 export function midPoint(v1: Vector3, v2: Vector3): Vector3
{ {
return v1.clone().add(v2).multiplyScalar(0.5); return v1.clone().add(v2).multiplyScalar(0.5);
} }
export function midPoint2(v1: THREE.Vector2, v2: THREE.Vector2): THREE.Vector2 export function midPoint2(v1: Vector2, v2: Vector2): Vector2
{ {
return v1.clone().add(v2).multiplyScalar(0.5); return v1.clone().add(v2).multiplyScalar(0.5);
} }
export function midPtCir(v1: THREE.Vector3, v2: THREE.Vector3) export function midPtCir(v1: Vector3, v2: Vector3)
{ {
let baseline = new Vector3(1, 0, 0); let baseline = new Vector3(1, 0, 0);
let outLine = v2.clone().sub(v1); let outLine = v2.clone().sub(v1);
@@ -170,11 +175,11 @@ export function midPtCir(v1: THREE.Vector3, v2: THREE.Vector3)
/** /**
* 获得Three对象的包围盒. * 获得Three对象的包围盒.
* @param obj * @param obj
* @param [updateMatrix] 是否应该更新对象矩阵 * @param [updateMatrix] 是否应该更新对象矩阵
* @returns box * @returns box
*/ */
export function GetBox(obj: THREE.Object3D, updateMatrix?: boolean): THREE.Box3 export function GetBox(obj: Object3D, updateMatrix?: boolean): Box3
{ {
let box = new Box3(); let box = new Box3();
if (updateMatrix) obj.updateMatrixWorld(false); if (updateMatrix) obj.updateMatrixWorld(false);
@@ -199,7 +204,7 @@ export function GetBox(obj: THREE.Object3D, updateMatrix?: boolean): THREE.Box3
return box; return box;
} }
export function GetBoxArr(arr: Array<THREE.Object3D>): THREE.Box3 export function GetBoxArr(arr: Array<Object3D>): Box3
{ {
let box = new Box3(); let box = new Box3();
for (let o of arr) for (let o of arr)
@@ -211,9 +216,9 @@ export function GetBoxArr(arr: Array<THREE.Object3D>): THREE.Box3
return box; return box;
} }
export function MoveMatrix(v: THREE.Vector3): THREE.Matrix4 export function MoveMatrix(v: Vector3): Matrix4
{ {
let mat = new THREE.Matrix4(); let mat = new Matrix4();
mat.makeTranslation(v.x, v.y, v.z); mat.makeTranslation(v.x, v.y, v.z);
return mat; return mat;
} }
@@ -265,9 +270,9 @@ export function angleAndX(v: Vector3 | Vector2)
} }
/** /**
* 将角度调整为0-2pi之间 * 将角度调整为0-2pi之间
* *
* @export * @export
* @param {number} an * @param {number} an
*/ */
export function angleTo2Pi(an: number) export function angleTo2Pi(an: number)
{ {
@@ -275,9 +280,9 @@ export function angleTo2Pi(an: number)
if (an < 0) an += Math.PI * 2 if (an < 0) an += Math.PI * 2
return an; return an;
} }
export function updateGeometry(l: THREE.Line | THREE.Mesh, geometry: Geometry) export function updateGeometry(l: Line | Mesh, geometry: Geometry)
{ {
let geo = l.geometry as THREE.Geometry; let geo = l.geometry as Geometry;
geo.dispose(); geo.dispose();
l.geometry = geometry; l.geometry = geometry;
geometry.verticesNeedUpdate = true; geometry.verticesNeedUpdate = true;

View File

@@ -1,9 +1,9 @@
import * as THREE from "three"; import { MathUtils, Vector3 } from "three";
/** /**
* 轨道控制的数学类,观察向量和角度的互相转换 * 轨道控制的数学类,观察向量和角度的互相转换
* 当x当抬头或者低头到90度时,触发万向锁. * 当x当抬头或者低头到90度时,触发万向锁.
* *
* @class Orbit * @class Orbit
*/ */
export class Orbit export class Orbit
@@ -20,19 +20,19 @@ export class Orbit
} }
set RoX(v) set RoX(v)
{ {
this.m_RoX = THREE.Math.clamp(v, Math.PI * -0.5, Math.PI * 0.5); this.m_RoX = MathUtils.clamp(v, Math.PI * -0.5, Math.PI * 0.5);
} }
/** /**
* 使用旋转角度 计算观察向量 * 使用旋转角度 计算观察向量
* *
* @param {THREE.Vector3} [dir] 引用传入,如果传入,那么就不构造新的向量 * @param {Vector3} [dir] 引用传入,如果传入,那么就不构造新的向量
* @returns {THREE.Vector3} 返回观察向量 * @returns {Vector3} 返回观察向量
* @memberof Orbit * @memberof Orbit
*/ */
UpdateDirection(dir?: THREE.Vector3): THREE.Vector3 UpdateDirection(dir?: Vector3): Vector3
{ {
let rtDir = dir ? dir : new THREE.Vector3(); let rtDir = dir ? dir : new Vector3();
rtDir.z = Math.sin(this.m_RoX); rtDir.z = Math.sin(this.m_RoX);
@@ -47,11 +47,11 @@ export class Orbit
/** /**
* 使用观察向量,计算旋转角度 * 使用观察向量,计算旋转角度
* *
* @param {THREE.Vector3} dir * @param {Vector3} dir
* @memberof Orbit * @memberof Orbit
*/ */
UpdateRoValue(dir: THREE.Vector3) UpdateRoValue(dir: Vector3)
{ {
dir.normalize(); dir.normalize();
this.m_RoX = Math.asin(dir.z); this.m_RoX = Math.asin(dir.z);
@@ -62,30 +62,30 @@ export class Orbit
} }
/** /**
* *
* 根据观察向量 求头部的向量. * 根据观察向量 求头部的向量.
* *
* @static * @static
* @param {THREE.Vector3} dir * @param {Vector3} dir
* @param {THREE.Vector3} [up] * @param {Vector3} [up]
* @returns {THREE.Vector3} * @returns {Vector3}
* @memberof Orbit * @memberof Orbit
*/ */
static ComputUpDirection(dir: THREE.Vector3, up?: THREE.Vector3): THREE.Vector3 static ComputUpDirection(dir: Vector3, up?: Vector3): Vector3
{ {
let upRes = up ? up : new THREE.Vector3(); let upRes = up ? up : new Vector3();
if (dir.equals(new THREE.Vector3(0, 0, -1))) if (dir.equals(new Vector3(0, 0, -1)))
{ {
upRes.set(0, 1, 0); upRes.set(0, 1, 0);
} }
else if (dir.equals(new THREE.Vector3(0, 0, 1))) else if (dir.equals(new Vector3(0, 0, 1)))
{ {
upRes.set(0, -1, 0); upRes.set(0, -1, 0);
} }
else else
{ {
let xv = new THREE.Vector3(); let xv = new Vector3();
xv.crossVectors(new THREE.Vector3(0, 0, 1), dir); xv.crossVectors(new Vector3(0, 0, 1), dir);
upRes.crossVectors(dir, xv); upRes.crossVectors(dir, xv);
upRes.normalize(); upRes.normalize();
} }

View File

@@ -1,9 +1,9 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { Vector3, Line3, Plane } from "three"; import { Vector3, Line3 } from "three";
export class PlaneExt extends Plane export class PlaneExt extends THREE.Plane
{ {
constructor(normal?: Vector3, constant?: number) constructor(normal?: THREE.Vector3, constant?: number)
{ {
super(normal, constant); super(normal, constant);
} }

View File

@@ -1,4 +1,4 @@
import { Font, FontLoader, Mesh, ShapeGeometry, Vector3, Shape } from "three"; import { Font, FontLoader, Mesh, ShapeGeometry, Vector3 } from "three";
import { ColorMaterial } from "./ColorPalette"; import { ColorMaterial } from "./ColorPalette";
import { MoveMatrix } from "./GeUtils"; import { MoveMatrix } from "./GeUtils";
@@ -30,7 +30,7 @@ export class DbText extends Mesh
{ {
let font = FontLoaderUtil.Load(); let font = FontLoaderUtil.Load();
let shapes: Shape[] = font.generateShapes(str, height, 0.1); let shapes: THREE.Shape[] = font.generateShapes(str, height);
let geometry = new ShapeGeometry(shapes); let geometry = new ShapeGeometry(shapes);
geometry.computeBoundingBox(); geometry.computeBoundingBox();
@@ -38,6 +38,6 @@ export class DbText extends Mesh
super(geometry, ColorMaterial.GetBasicMaterial(5)); super(geometry, ColorMaterial.GetBasicMaterial(5));
let center = geometry.boundingBox.getCenter(new Vector3()); let center = geometry.boundingBox.getCenter(new Vector3());
this.applyMatrix(MoveMatrix(new Vector3(-center.x, 0, 0))); this.applyMatrix4(MoveMatrix(new Vector3(-center.x, 0, 0)));
} }
} }

View File

@@ -71,32 +71,8 @@ export class ThreeBSP
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs); vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs);
vertex.applyMatrix4(this.matrix); vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex); polygon.vertices.push(vertex);
} else if (typeof THREE.Face4) }
{ else
vertex = geometry.vertices[face.a];
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs);
vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex);
vertex = geometry.vertices[face.b];
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[1].x, faceVertexUvs[1].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs);
vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex);
vertex = geometry.vertices[face.c];
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[2].x, faceVertexUvs[2].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs);
vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex);
vertex = geometry.vertices[face.d];
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[3].x, faceVertexUvs[3].y) : null;
vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[3], uvs);
vertex.applyMatrix4(this.matrix);
polygon.vertices.push(vertex);
} else
{ {
throw 'Invalid face type at index ' + i; throw 'Invalid face type at index ' + i;
} }

View File

@@ -1,5 +1,5 @@
import { Object3D, Mesh } from "three"; import { Object3D } from "three";
import { createTemplateBoard, DrawDimension, Viewer, selectMaterial } from "."; import { createTemplateBoard, DrawDimension, Viewer } from ".";
function dispose(m: Object3D) function dispose(m: Object3D)
{ {
@@ -21,8 +21,7 @@ export function LoadBoard(view: Viewer, data: any[], clear: boolean = true)
if (data.length === 0) return; if (data.length === 0) return;
//加板 //加板
let { meshs, edgesa, relations } = createTemplateBoard(data); let { meshs, edgesa } = createTemplateBoard(data);
//加标注 //加标注
let dims = DrawDimension(meshs); let dims = DrawDimension(meshs);
@@ -33,6 +32,4 @@ export function LoadBoard(view: Viewer, data: any[], clear: boolean = true)
view.ViewToSwiso(); view.ViewToSwiso();
view.ZoomAll(); view.ZoomAll();
view.Zoom(1.1); view.Zoom(1.1);
return relations;
} }

444
src/ViewSrc/data.json Normal file
View File

@@ -0,0 +1,444 @@
[
{
"L": 4408.678960586129,
"W": 4408.678960586129,
"H": 18,
"CabName": "主卧",
"BoardName": "",
"BasePoint": {
"x": -82.91743119266054,
"y": 73.39449541284404,
"z": 0
},
"XVec": {
"x": 0,
"y": 1,
"z": 0
},
"YVec": {
"x": 0,
"y": 0,
"z": 1
},
"ZVec": {
"x": 1,
"y": 0,
"z": 0
},
"Grain": 0,
"Pts": [
{
"x": 4408.678960586129,
"y": 2204.3394802930643
},
{
"x": 0,
"y": 2204.3394802930648
},
{
"x": 4408.678960586129,
"y": 2204.3394802930643
}
],
"Buls": [
-0.9999999999999999,
-0.9999999999999999,
0
],
"SubBoardLocal": [
{
"L": 633.2307692307686,
"W": 633.2307692307686,
"H": 5,
"CabName": "",
"BoardName": "",
"BasePoint": {
"x": -95.91743119266054,
"y": 2910.9647449366785,
"z": 1405.2625572161414
},
"XVec": {
"x": 0,
"y": 1,
"z": 0
},
"YVec": {
"x": 0,
"y": 0,
"z": 1
},
"ZVec": {
"x": 1,
"y": 0,
"z": 0
},
"Grain": 0,
"Pts": [
{
"x": 633.2307692307686,
"y": 316.6153846153843
},
{
"x": 0,
"y": 316.61538461538436
},
{
"x": 633.2307692307686,
"y": 316.6153846153843
}
],
"Buls": [
-0.9999999999999999,
-0.9999999999999999,
0
],
"SubBoardLocal": [],
"SubBoardAssoc": null,
"Drillings": null
},
{
"L": 557.8461538461524,
"W": 557.8461538461524,
"H": 5,
"CabName": "",
"BoardName": "",
"BasePoint": {
"x": -82.91743119266054,
"y": 3016.50320647514,
"z": 2257.1087110622957
},
"XVec": {
"x": 0,
"y": 1,
"z": 0
},
"YVec": {
"x": 0,
"y": 0,
"z": 1
},
"ZVec": {
"x": 1,
"y": 0,
"z": 0
},
"Grain": 0,
"Pts": [
{
"x": 557.8461538461524,
"y": 278.9230769230762
},
{
"x": 0,
"y": 278.9230769230763
},
{
"x": 557.8461538461524,
"y": 278.9230769230762
}
],
"Buls": [
-0.9999999999999999,
-0.9999999999999999,
0
],
"SubBoardLocal": [],
"SubBoardAssoc": null,
"Drillings": null
},
{
"L": 444.76923076923117,
"W": 686,
"H": 5,
"CabName": "",
"BoardName": "",
"BasePoint": {
"x": -95.91743119266054,
"y": 1689.7339757059085,
"z": 1556.0317879853721
},
"XVec": {
"x": 0,
"y": 1,
"z": 0
},
"YVec": {
"x": 0,
"y": 0,
"z": 1
},
"ZVec": {
"x": 1,
"y": 0,
"z": 0
},
"Grain": 0,
"Pts": [
{
"x": 0,
"y": 0
},
{
"x": 686,
"y": 0
},
{
"x": 686,
"y": 444.76923076923117
},
{
"x": 0,
"y": 444.76923076923117
},
{
"x": 0,
"y": 0
}
],
"Buls": [
0,
0,
0,
0,
0
],
"SubBoardLocal": [],
"SubBoardAssoc": null,
"Drillings": null
},
{
"L": 625.6923076923076,
"W": 1349.3846153846157,
"H": 5,
"CabName": "",
"BoardName": "",
"BasePoint": {
"x": -82.91743119266054,
"y": 1177.1185910905238,
"z": 2626.493326446911
},
"XVec": {
"x": 0,
"y": 1,
"z": 0
},
"YVec": {
"x": 0,
"y": 0,
"z": 1
},
"ZVec": {
"x": 1,
"y": 0,
"z": 0
},
"Grain": 0,
"Pts": [
{
"x": 0,
"y": 0
},
{
"x": 1349.3846153846157,
"y": 0
},
{
"x": 1349.3846153846157,
"y": 625.6923076923076
},
{
"x": 0,
"y": 625.6923076923076
},
{
"x": 0,
"y": 0
}
],
"Buls": [
0,
0,
0,
0,
0
],
"SubBoardLocal": [],
"SubBoardAssoc": null,
"Drillings": null
}
],
"SubBoardAssoc": null,
"Drillings": null
},
{
"L": 2000,
"W": 600,
"H": 18,
"CabName": "主卧",
"BoardName": "",
"BasePoint": {
"x": 1099.0825688073396,
"y": 73.39449541284404,
"z": 0
},
"XVec": {
"x": 0,
"y": 1,
"z": 0
},
"YVec": {
"x": 0,
"y": 0,
"z": 1
},
"ZVec": {
"x": 1,
"y": 0,
"z": 0
},
"Grain": 0,
"Pts": [
{
"x": 0,
"y": 0
},
{
"x": 600,
"y": 0
},
{
"x": 600,
"y": 2000
},
{
"x": 0,
"y": 2000
},
{
"x": 0,
"y": 0
}
],
"Buls": [
0,
0,
0,
0,
0
],
"SubBoardLocal": [
{
"L": 144.00000000000023,
"W": 170.42201834862385,
"H": 5,
"CabName": "",
"BoardName": "",
"BasePoint": {
"x": 1099.0825688073396,
"y": 288.2935779816515,
"z": 1001.247706422018
},
"XVec": {
"x": 0,
"y": 1,
"z": 0
},
"YVec": {
"x": 0,
"y": 0,
"z": 1
},
"ZVec": {
"x": 1,
"y": 0,
"z": 0
},
"Grain": 0,
"Pts": [
{
"x": 0,
"y": 0
},
{
"x": 170.42201834862385,
"y": 0
},
{
"x": 170.42201834862385,
"y": 144.00000000000023
},
{
"x": 0,
"y": 144.00000000000023
},
{
"x": 0,
"y": 0
}
],
"Buls": [
0,
0,
0,
0,
0
],
"SubBoardLocal": [],
"SubBoardAssoc": null,
"Drillings": null
},
{
"L": 189.0974955047293,
"W": 189.0974955047293,
"H": 18,
"CabName": "",
"BoardName": "",
"BasePoint": {
"x": 1099.0825688073396,
"y": 234.6989586696538,
"z": 1267.3595091283692
},
"XVec": {
"x": 0,
"y": 1,
"z": 0
},
"YVec": {
"x": 0,
"y": 0,
"z": 1
},
"ZVec": {
"x": 1,
"y": 0,
"z": 0
},
"Grain": 0,
"Pts": [
{
"x": 189.0974955047293,
"y": 94.54874775236476
},
{
"x": -1.4210854715202004e-14,
"y": 94.54874775236478
},
{
"x": 189.0974955047293,
"y": 94.54874775236476
}
],
"Buls": [
-0.9999999999999999,
-0.9999999999999999,
0
],
"SubBoardLocal": [],
"SubBoardAssoc": null,
"Drillings": null
}
],
"SubBoardAssoc": null,
"Drillings": null
}
]

14
src/ViewSrc/index.html Normal file
View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>WebCAD</title>
</head>
<body>
</body>
</html>

View File

@@ -2,21 +2,20 @@
// import "./style.css"; // import "./style.css";
import { Vector3 } from "three"; import { Vector3 } from "three";
import { CameraControlState } from "../CameraControls"; import { CameraControlState } from "../CameraControls";
import { data } from "../data";
import { GetBox } from "../GeUtils"; import { GetBox } from "../GeUtils";
import { LoadBoard } from "../Utils"; import { LoadBoard } from "../Utils";
import { Viewer } from "../Viewer"; import { Viewer } from "../Viewer";
let btn = document.createElement("button"); let btn = document.createElement("button");
btn.innerHTML = "载入" btn.innerHTML = "载入";
document.body.appendChild(btn); document.body.appendChild(btn);
let btn2 = document.createElement("button"); let btn2 = document.createElement("button");
btn2.innerHTML = "清理" btn2.innerHTML = "清理";
document.body.appendChild(btn2); document.body.appendChild(btn2);
let btn3 = document.createElement("button"); let btn3 = document.createElement("button");
btn3.innerHTML = "爆炸图" btn3.innerHTML = "爆炸图";
document.body.appendChild(btn3); document.body.appendChild(btn3);
let el = document.createElement("canvas"); let el = document.createElement("canvas");
@@ -36,15 +35,16 @@ view.m_CameraCtrl.m_TouthTypeList = [CameraControlState.Pan, CameraControlState.
btn.onclick = () => btn.onclick = () =>
{ {
console.time(); console.time();
let data = require("./data.json");
for (let i = 0; i < 1; i++) for (let i = 0; i < 1; i++)
LoadBoard(view, data); LoadBoard(view, data);
console.timeEnd(); console.timeEnd();
} };
btn2.onclick = () => btn2.onclick = () =>
{ {
// LoadBoard(view, []); // LoadBoard(view, []);
} };
btn3.onclick = () => btn3.onclick = () =>
{ {
@@ -91,5 +91,5 @@ btn3.onclick = () =>
if (count === 60) if (count === 60)
clearInterval(t); clearInterval(t);
}, 16) }, 16);
} };

12
src/ViewSrc/style.css Normal file
View File

@@ -0,0 +1,12 @@
body {
font-size: 11px;
overflow: hidden;
}
html,
body {
background: #5C7080;
height: 100%;
padding: 0;
margin: 0;
}

View File

@@ -37,9 +37,18 @@ export class Viewer
this.OnSize(); this.OnSize();
}); });
let oldMesh: Mesh;
this.m_Render.domElement.addEventListener("mousemove", (e: MouseEvent) => this.m_Render.domElement.addEventListener("mousemove", (e: MouseEvent) =>
{ {
this.SelectByPoint(e.offsetX, e.offsetY); let mesh = PointPick(this, e.offsetX, e.offsetY);
if (oldMesh)
oldMesh.material = boardMaterial;
if (mesh && mesh.material !== ColorMaterial.GetBasicMaterial(1))
{
oldMesh = mesh;
mesh.material = selectMaterial;
}
this.m_bNeedUpdate = true;
}) })
} }
@@ -187,40 +196,4 @@ export class Viewer
this.m_Camera.LookAt(new Vector3(1, 1, -1)); this.m_Camera.LookAt(new Vector3(1, 1, -1));
this.m_bNeedUpdate = true; this.m_bNeedUpdate = true;
} }
oldMesh: Mesh;
SelectByPoint(x: number, y: number)
{
let mesh = PointPick(this, x, y);
if (this.oldMesh)
this.oldMesh.material = boardMaterial;
if (mesh && mesh.material !== ColorMaterial.GetBasicMaterial(1))
{
this.oldMesh = mesh;
mesh.material = selectMaterial;
}
this.m_bNeedUpdate = true;
}
SelectBlock(blockMeshMap: Map<number, number>, dataID: number)
{
if (blockMeshMap.has(dataID))
{
let meshId = blockMeshMap.get(dataID);
if (this.oldMesh)
this.oldMesh.material = boardMaterial;
this.m_Scene.children.forEach(obj =>
{
if (obj instanceof Mesh)
{
if (obj.id == meshId)
{
this.oldMesh = obj;
obj.material = selectMaterial;
this.m_bNeedUpdate = true;
}
}
})
}
}
} }

View File

@@ -1,25 +1,23 @@
import * as THREE from 'three'; import { CylinderGeometry, EdgesGeometry, Geometry, LineSegments, Matrix4, Mesh, Shape, Vector2, Vector3 } from 'three';
import { CylinderGeometry, Geometry, LineSegments, Mesh, Shape, Vector2 } from 'three'; import { boardUVGenerator2, ExtrudeSolid, Polyline } from 'webcad_ue4_api';
import { ColorMaterial } from './ColorPalette'; import { ColorMaterial } from './ColorPalette';
import { polar } from './GeUtils'; import { polar } from './GeUtils';
import { boardMaterial, edgeMaterial } from './Material'; import { boardMaterial, edgeMaterial } from './Material';
import { RotateUVs } from './RotateUV';
import { ThreeBSP } from './ThreeCSG';
//解析二维圆弧类. //解析二维圆弧类.
export class Arc2d export class Arc2d
{ {
m_StartAn: number; m_StartAn: number;
m_EndAn: number; m_EndAn: number;
m_StartPoint: THREE.Vector2; m_StartPoint: Vector2;
m_EndPoint: THREE.Vector2; m_EndPoint: Vector2;
m_Center: THREE.Vector2; m_Center: Vector2;
m_Radius: number; m_Radius: number;
constructor(p1: THREE.Vector2, p2: THREE.Vector2, bul: number) constructor(p1: Vector2, p2: Vector2, bul: number)
{ {
this.m_StartPoint = p1.clone(); this.m_StartPoint = p1.clone();
this.m_EndPoint = p2.clone(); this.m_EndPoint = p2.clone();
let vec: THREE.Vector2 = p2.clone().sub(p1); let vec: Vector2 = p2.clone().sub(p1);
let len = vec.length(); let len = vec.length();
let an = vec.angle(); let an = vec.angle();
this.m_Radius = len / Math.sin(2 * Math.atan(bul)) / 2; this.m_Radius = len / Math.sin(2 * Math.atan(bul)) / 2;
@@ -44,7 +42,7 @@ export class Arc2d
} }
} }
//创建轮廓 通过点表和凸度 //创建轮廓 通过点表和凸度
export function createPath(pts: Vector2[], buls: number[], shapeOut?: Shape): Shape export function createPath(pts: Vector2[], buls: number[], shapeOut?: Shape): Shape
{ {
let shape = shapeOut || new Shape(); let shape = shapeOut || new Shape();
@@ -57,7 +55,7 @@ export function createPath(pts: Vector2[], buls: number[], shapeOut?: Shape): Sh
let nextPt = pts[i + 1]; let nextPt = pts[i + 1];
if (buls[i] == 0) if (buls[i] == 0)
{ {
shape.lineTo(nextPt.x, nextPt.y) shape.lineTo(nextPt.x, nextPt.y);
} }
else else
{ {
@@ -72,32 +70,32 @@ export function createPath(pts: Vector2[], buls: number[], shapeOut?: Shape): Sh
} }
return shape; return shape;
} }
export function getVec(data: object): THREE.Vector3 export function getVec(data: object): Vector3
{ {
return new THREE.Vector3(data["x"], data["y"], data["z"]); return new Vector3(data["x"], data["y"], data["z"]);
} }
//创建板件 暂时这么写 function Conver2Ext(boardData: object): ExtrudeSolid
export function createBoard(boardData: object)
{ {
let pts: THREE.Vector2[] = []; let pts: Vector2[] = [];
let buls: number[] = []; let buls: number[] = [];
let boardPts = boardData["Pts"]; let boardPts = boardData["Pts"];
let boardBuls = boardData["Buls"]; let boardBuls = boardData["Buls"];
let boardHeight = boardData["H"]; let boardHeight = boardData["H"];
let boardMat = new THREE.Matrix4(); let boardMat = new Matrix4();
let matInv: THREE.Matrix4 = new THREE.Matrix4(); let matInv: Matrix4 = new Matrix4();
//InitBoardMat //InitBoardMat
let xD = getVec(boardData["XVec"]); let xD = getVec(boardData["XVec"]);
let yD = getVec(boardData["YVec"]); let yD = getVec(boardData["YVec"]);
let ZD = getVec(boardData["ZVec"]); let ZD = getVec(boardData["ZVec"]);
let pBase = getVec(boardData["BasePoint"]); let pBase = getVec(boardData["BasePoint"]);
pBase.add(ZD.clone().multiplyScalar(-boardHeight));
boardMat.makeBasis(xD, yD, ZD); boardMat.makeBasis(xD, yD, ZD);
boardMat.setPosition(pBase); boardMat.setPosition(pBase);
matInv.getInverse(boardMat, true); matInv.getInverse(boardMat);
if (boardPts && boardPts.length !== 0) if (boardPts && boardPts.length !== 0)
for (let i = 0; i < boardPts.length; i++) for (let i = 0; i < boardPts.length; i++)
@@ -105,14 +103,13 @@ export function createBoard(boardData: object)
let pt = getVec(boardPts[i]); let pt = getVec(boardPts[i]);
if (boardPts[i].z !== undefined) if (boardPts[i].z !== undefined)
pt.applyMatrix4(matInv); pt.applyMatrix4(matInv);
pts.push(new THREE.Vector2(pt.x, pt.y)); pts.push(new Vector2(pt.x, pt.y));
buls.push(boardBuls[i]); buls.push(boardBuls[i]);
} }
else else
{ {
let length = boardData["L"]; let length = boardData["L"];
let width = boardData["W"]; let width = boardData["W"];
let height = boardData["H"];
pts.push(new Vector2(0, 0), pts.push(new Vector2(0, 0),
new Vector2(width, 0), new Vector2(width, 0),
new Vector2(width, length), new Vector2(width, length),
@@ -122,72 +119,66 @@ export function createBoard(boardData: object)
buls.push(0, 0, 0, 0, 0); buls.push(0, 0, 0, 0, 0);
} }
let sp = createPath(pts, buls); let ext = new ExtrudeSolid();
let extrudeSettings = { ext.OCSNoClone.copy(boardMat);
steps: 1, let pl = new Polyline(pts.map((p, i) => { return { pt: p, bul: buls[i] }; }));
bevelEnabled: false, ext.Thickness = boardHeight;
amount: boardHeight ext.ContourCurve = pl;
};
let ext = new THREE.ExtrudeGeometry(sp, extrudeSettings) as Geometry; if (checkObjectArray(boardData, "SubBoardLocal"))
ext.computeBoundingSphere(); ext.Grooves.push(...boardData["SubBoardLocal"].map(Conver2Ext));
ext.computeBoundingBox(); return ext;
ext.translate(0, 0, -boardHeight) }
ext.applyMatrix(boardMat);
//外边. //创建板件 暂时这么写
let edges: (LineSegments | Mesh)[] = [createEdge(ext)]; export function createBoard(boardData: object)
{
let ext = Conver2Ext(boardData);
if (boardData["BoardName"] === "地脚线")
Object.defineProperty(ext, "UCGenerator",
{
get: function ()
{
return boardUVGenerator2;
},
});
//差集 //板件被镜像时.
if (checkObjectArray(boardData, "SubBoardLocal") // if (!equalv3(xD.clone().cross(yD), ZD))
|| checkObjectArray(boardData, "Drillings")) // {
// for (let f of ext.faces)
// [f.a, f.c] = [f.c, f.a];
// }
//边
let edges: (LineSegments | Mesh)[] = [new LineSegments(ext.EdgeGeometry, edgeMaterial)];
edges[0].applyMatrix4(ext.OCSNoClone);
if (checkObjectArray(boardData, "Drillings"))
{ {
let thisCsg = new ThreeBSP(ext); let dris = boardData["Drillings"];
for (let dri of dris)
if (boardData["SubBoardLocal"])
{ {
let subBoardList = boardData["SubBoardLocal"].map(d => createBoard(d)); let geo = new CylinderGeometry(dri.r, dri.r, dri.h, 8);
for (let br of subBoardList) geo.rotateX(Math.PI * 0.5);
{
edges.push(...br.edges); if (dri.f === 0) //0正
let subCsg = new ThreeBSP(br.mesh); geo.translate(dri.x, dri.y, -dri.h * 0.5 + boardData["H"]);
thisCsg = thisCsg.subtract(subCsg); else //1反
} geo.translate(dri.x, dri.y, dri.h * 0.5);
geo.applyMatrix4(ext.OCSNoClone);
let mesh = new Mesh(geo, ColorMaterial.GetBasicMaterial(1));
edges.push(mesh);
} }
if (boardData["Drillings"])
{
let dris = boardData["Drillings"];
for (let dri of dris)
{
let geo = new CylinderGeometry(dri.r, dri.r, dri.h, 8);
geo.rotateX(Math.PI * 0.5);
if (dri.f === 0) //0正
geo.translate(dri.x, dri.y, -dri.h * 0.5);
else //1反
geo.translate(dri.x, dri.y, dri.h * 0.5 - boardData["H"]);
geo.applyMatrix(boardMat);
let mesh = new Mesh(geo, ColorMaterial.GetBasicMaterial(1));
edges.push(mesh);
// let edge = createEdge(geo);
// edge.material = new LineBasicMaterial({ color: new Color(1, 0, 0) });
// edges.push(edge);
// let subCsg = new ThreeBSP(geo);
// thisCsg = thisCsg.subtract(subCsg);
}
}
ext = thisCsg.toGeometry();
} }
if (boardData["BoardName"] === "地脚线") let mesh = new Mesh(ext.MeshGeometry, boardMaterial);
RotateUVs(ext); mesh.userData = ext.Normal;
edges.forEach(e => e.userData = ext.Normal);
let mesh = new THREE.Mesh(ext, boardMaterial); mesh.applyMatrix4(ext.OCSNoClone);
mesh.userData = ZD; mesh.updateWorldMatrix(false, true);
edges.forEach(e => e.userData = ZD);
return { mesh, edges }; return { mesh, edges };
} }
@@ -200,28 +191,17 @@ export function createTemplateBoard(brDataList: any[])
{ {
let meshs = []; let meshs = [];
let edgesa = []; let edgesa = [];
let relations = {
blockMeshMap: new Map<number, number>(),
meshBlockMap: new Map<number, number>()
};
for (let d of brDataList) for (let d of brDataList)
{ {
let { mesh, edges } = createBoard(d); let { mesh, edges } = createBoard(d);
meshs.push(mesh); meshs.push(mesh);
edgesa.push(...edges); edgesa.push(...edges);
if (d['DataID'])
{
relations.blockMeshMap.set(d['DataID'], mesh.id);
relations.meshBlockMap.set(mesh.id, d['DataID']);
}
} }
return { meshs, edgesa, relations }; return { meshs, edgesa };
} }
export function createEdge(geo: Geometry): LineSegments export function createEdge(geo: Geometry): LineSegments
{ {
let edge = new THREE.EdgesGeometry(geo, 1); let edge = new EdgesGeometry(geo, 1);
return new LineSegments(edge, edgeMaterial); return new LineSegments(edge, edgeMaterial);
} }

View File

@@ -1,10 +1,13 @@
{ {
"compileOnSave": true,
"compilerOptions": { "compilerOptions": {
"sourceMap": true,
"declaration": true,
"outDir": "./dist", "outDir": "./dist",
"target": "es5", "sourceMap": true,
"module": "commonjs",
"target": "es2020",
"noLib": false,
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"lib": [ "lib": [
"esnext", "esnext",
"dom" "dom"
@@ -12,13 +15,13 @@
"types": [ "types": [
"node", "node",
"webpack-env", "webpack-env",
"webpack-dev-server" "webpack-dev-server",
], ],
"module": "commonjs", "jsx": "react",
"experimentalDecorators": true "experimentalDecorators": true
}, },
"include": [ "include": [
"./src/**/*", "./src/**/*",
// "./config/**/*" "./config/**/*"
] ]
} }

1
umd/cad.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -96,7 +96,7 @@ downloadTypes({
urlPath: "https://gitee.com/BearCAD/DefinitelyType2/raw/master/three/", urlPath: "https://gitee.com/BearCAD/DefinitelyType2/raw/master/three/",
files: [ files: [
// "index.d.ts", // "index.d.ts",
"three-core.d.ts", // "three-core.d.ts",
// "three-outlinepass.d.ts", // "three-outlinepass.d.ts",
// "three-smaapass.d.ts" // "three-smaapass.d.ts"
] ]

7
utils/rmtype.ts Normal file
View File

@@ -0,0 +1,7 @@
import fs from "fs";
fs.rmdir(".\\node_modules\\@types\\webpack-merge\\node_modules\\webpack", { recursive: true }, (err) =>
{
console.log("删除webpack目录");
if (err) console.log(err);
});

5117
yarn.lock Normal file

File diff suppressed because it is too large Load Diff