OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)

This commit is contained in:
wangruiguo
2026-09-03 18:49:20 +08:00
commit d647428529
3501 changed files with 1988906 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface I3DfaceEntity extends IEntity {
shape: boolean;
hasContinuousLinetypePattern: boolean;
vertices: IPoint[];
}
export default class ThreeDface implements IGeometry {
ForEntityName: "3DFACE";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): I3DfaceEntity;
}

View File

@@ -0,0 +1,79 @@
import * as helpers from '../ParseHelpers.js';
export default class ThreeDface {
constructor() {
this.ForEntityName = '3DFACE';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value, vertices: [] };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 70: // 1 = Closed shape, 128 = plinegen?, 0 = default
entity.shape = ((curr.value & 1) === 1);
entity.hasContinuousLinetypePattern = ((curr.value & 128) === 128);
break;
case 10: // X coordinate of point
entity.vertices = parse3dFaceVertices(scanner, curr);
curr = scanner.lastReadGroup;
break;
default:
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}
function parse3dFaceVertices(scanner, curr) {
var vertices = [];
var vertexIsStarted = false;
var vertexIsFinished = false;
var verticesPer3dFace = 4; // there can be up to four vertices per face, although 3 is most used for TIN
for (let i = 0; i <= verticesPer3dFace; i++) {
var vertex = {};
while (!scanner.isEOF()) {
if (curr.code === 0 || vertexIsFinished)
break;
switch (curr.code) {
case 10: // X0
case 11: // X1
case 12: // X2
case 13: // X3
if (vertexIsStarted) {
vertexIsFinished = true;
continue;
}
vertex.x = curr.value;
vertexIsStarted = true;
break;
case 20: // Y
case 21:
case 22:
case 23:
vertex.y = curr.value;
break;
case 30: // Z
case 31:
case 32:
case 33:
vertex.z = curr.value;
break;
default:
// it is possible to have entity codes after the vertices.
// So if code is not accounted for return to entity parser where it might be accounted for
return vertices;
}
curr = scanner.next();
}
// See https://groups.google.com/forum/#!topic/comp.cad.autocad/9gn8s5O_w6E
vertices.push(vertex);
vertexIsStarted = false;
vertexIsFinished = false;
}
scanner.rewind();
return vertices;
}
;

View File

@@ -0,0 +1,16 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IArcEntity extends IEntity {
center: IPoint;
radius: number;
startAngle: number;
endAngle: number;
angleLength: number;
extrusionDirectionX: number;
extrusionDirectionY: number;
extrusionDirectionZ: number;
}
export default class Arc implements IGeometry {
ForEntityName: "ARC";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IArcEntity;
}

View File

@@ -0,0 +1,43 @@
import * as helpers from '../ParseHelpers.js';
export default class Arc {
constructor() {
this.ForEntityName = 'ARC';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10: // X coordinate of point
entity.center = helpers.parsePoint(scanner);
break;
case 40: // radius
entity.radius = curr.value;
break;
case 50: // start angle
entity.startAngle = Math.PI / 180 * curr.value;
break;
case 51: // end angle
entity.endAngle = Math.PI / 180 * curr.value;
entity.angleLength = entity.endAngle - entity.startAngle; // angleLength is deprecated
break;
case 210:
entity.extrusionDirectionX = curr.value;
break;
case 220:
entity.extrusionDirectionY = curr.value;
break;
case 230:
entity.extrusionDirectionZ = curr.value;
break;
default: // ignored attribute
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,31 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IAttdefEntity extends IEntity {
scale: number;
textStyle: 'STANDARD' | string;
text: string;
tag: string;
prompt: string;
startPoint: IPoint;
endPoint: IPoint;
thickness: number;
textHeight: number;
rotation: number;
obliqueAngle: number;
invisible: boolean;
constant: boolean;
verificationRequired: boolean;
preset: boolean;
backwards: boolean;
mirrored: boolean;
horizontalJustification: number;
fieldLength: number;
verticalJustification: number;
extrusionDirectionX: number;
extrusionDirectionY: number;
extrusionDirectionZ: number;
}
export default class Attdef implements IGeometry {
ForEntityName: "ATTDEF";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IAttdefEntity;
}

View File

@@ -0,0 +1,91 @@
import * as helpers from '../ParseHelpers.js';
export default class Attdef {
constructor() {
this.ForEntityName = 'ATTDEF';
}
parseEntity(scanner, curr) {
var entity = {
type: curr.value,
scale: 1,
textStyle: 'STANDARD'
};
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0) {
break;
}
switch (curr.code) {
case 1:
entity.text = curr.value;
break;
case 2:
entity.tag = curr.value;
break;
case 3:
entity.prompt = curr.value;
break;
case 7:
entity.textStyle = curr.value;
break;
case 10: // X coordinate of 'first alignment point'
entity.startPoint = helpers.parsePoint(scanner);
break;
case 11: // X coordinate of 'second alignment point'
entity.endPoint = helpers.parsePoint(scanner);
break;
case 39:
entity.thickness = curr.value;
break;
case 40:
entity.textHeight = curr.value;
break;
case 41:
entity.scale = curr.value;
break;
case 50:
entity.rotation = curr.value;
break;
case 51:
entity.obliqueAngle = curr.value;
break;
case 70:
entity.invisible = !!(curr.value & 0x01);
entity.constant = !!(curr.value & 0x02);
entity.verificationRequired = !!(curr.value & 0x04);
entity.preset = !!(curr.value & 0x08);
break;
case 71:
entity.backwards = !!(curr.value & 0x02);
entity.mirrored = !!(curr.value & 0x04);
break;
case 72:
// TODO: enum values?
entity.horizontalJustification = curr.value;
break;
case 73:
entity.fieldLength = curr.value;
break;
case 74:
// TODO: enum values?
entity.verticalJustification = curr.value;
break;
case 100:
break;
case 210:
entity.extrusionDirectionX = curr.value;
break;
case 220:
entity.extrusionDirectionY = curr.value;
break;
case 230:
entity.extrusionDirectionZ = curr.value;
break;
default:
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,13 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface ICircleEntity extends IEntity {
center: IPoint;
radius: number;
startAngle: number;
endAngle: number;
angleLength: number;
}
export default class Circle implements IGeometry {
ForEntityName: "CIRCLE";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ICircleEntity;
}

View File

@@ -0,0 +1,38 @@
import * as helpers from '../ParseHelpers.js';
export default class Circle {
constructor() {
this.ForEntityName = 'CIRCLE';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10: // X coordinate of point
entity.center = helpers.parsePoint(scanner);
break;
case 40: // radius
entity.radius = curr.value;
break;
case 50: // start angle
entity.startAngle = Math.PI / 180 * curr.value;
break;
case 51: // end angle
const endAngle = Math.PI / 180 * curr.value;
if (endAngle < entity.startAngle)
entity.angleLength = endAngle + 2 * Math.PI - entity.startAngle;
else
entity.angleLength = endAngle - entity.startAngle;
entity.endAngle = endAngle;
break;
default: // ignored attribute
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,21 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IDimensionEntity extends IEntity {
block: string;
anchorPoint: IPoint;
middleOfText: IPoint;
insertionPoint: IPoint;
linearOrAngularPoint1: IPoint;
linearOrAngularPoint2: IPoint;
diameterOrRadiusPoint: IPoint;
arcPoint: IPoint;
dimensionType: number;
attachmentPoint: number;
actualMeasurement: number;
text: string;
angle: number;
}
export default class Dimension implements IGeometry {
ForEntityName: "DIMENSION";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IDimensionEntity;
}

View File

@@ -0,0 +1,60 @@
import * as helpers from '../ParseHelpers.js';
export default class Dimension {
constructor() {
this.ForEntityName = 'DIMENSION';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 2: // Referenced block name
entity.block = curr.value;
break;
case 10: // X coordinate of 'first alignment point'
entity.anchorPoint = helpers.parsePoint(scanner);
break;
case 11:
entity.middleOfText = helpers.parsePoint(scanner);
break;
case 12: // Insertion point for clones of a dimension
entity.insertionPoint = helpers.parsePoint(scanner);
break;
case 13: // Definition point for linear and angular dimensions
entity.linearOrAngularPoint1 = helpers.parsePoint(scanner);
break;
case 14: // Definition point for linear and angular dimensions
entity.linearOrAngularPoint2 = helpers.parsePoint(scanner);
break;
case 15: // Definition point for diameter, radius, and angular dimensions
entity.diameterOrRadiusPoint = helpers.parsePoint(scanner);
break;
case 16: // Point defining dimension arc for angular dimensions
entity.arcPoint = helpers.parsePoint(scanner);
break;
case 70: // Dimension type
entity.dimensionType = curr.value;
break;
case 71: // 5 = Middle center
entity.attachmentPoint = curr.value;
break;
case 42: // Actual measurement
entity.actualMeasurement = curr.value;
break;
case 1: // Text entered by user explicitly
entity.text = curr.value;
break;
case 50: // Angle of rotated, horizontal, or vertical dimensions
entity.angle = curr.value;
break;
default: // check common entity attributes
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,14 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IEllipseEntity extends IEntity {
center: IPoint;
majorAxisEndPoint: IPoint;
axisRatio: number;
startAngle: number;
endAngle: number;
name: string;
}
export default class Ellipse implements IGeometry {
ForEntityName: "ELLIPSE";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IEllipseEntity;
}

View File

@@ -0,0 +1,39 @@
import * as helpers from '../ParseHelpers.js';
export default class Ellipse {
constructor() {
this.ForEntityName = 'ELLIPSE';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10:
entity.center = helpers.parsePoint(scanner);
break;
case 11:
entity.majorAxisEndPoint = helpers.parsePoint(scanner);
break;
case 40:
entity.axisRatio = curr.value;
break;
case 41:
entity.startAngle = curr.value;
break;
case 42:
entity.endAngle = curr.value;
break;
case 2:
entity.name = curr.value;
break;
default: // check common entity attributes
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,29 @@
import DxfArrayScanner, { IGroup } from "../DxfArrayScanner";
export interface IPoint {
x: number;
y: number;
z: number;
}
export interface IEntity {
lineType: string;
layer: string;
lineTypeScale: number;
visible: boolean;
colorIndex: number;
color: number;
inPaperSpace: boolean;
ownerHandle: string;
materialObjectHandle: number;
lineweight: 0 | 5 | 9 | 13 | 15 | 18 | 20 | 25 | 30 | 35 | 40 | 50 | 53 | 60 | 70 | 80 | 90 | 100 | 106 | 120 | 140 | 158 | 200 | 211 | -3 | -2 | -1;
extendedData: {
customStrings: string[];
applicationName: string;
};
type: string;
handle: number;
}
export declare type EntityName = 'POINT' | '3DFACE' | 'ARC' | 'ATTDEF' | 'CIRCLE' | 'DIMENSION' | 'ELLIPSE' | 'INSERT' | 'LINE' | 'LWPOLYLINE' | 'MTEXT' | 'POLYLINE' | 'SOLID' | 'SPLINE' | 'TEXT' | 'VERTEX';
export default interface IGeometry {
ForEntityName: EntityName;
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IEntity;
}

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,19 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IInsertEntity extends IEntity {
name: string;
xScale: number;
yScale: number;
zScale: number;
position: IPoint;
rotation: number;
columnCount: number;
rowCount: number;
columnSpacing: number;
rowSpacing: number;
extrusionDirection: IPoint;
}
export default class Insert implements IGeometry {
ForEntityName: "INSERT";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IInsertEntity;
}

View File

@@ -0,0 +1,54 @@
import * as helpers from '../ParseHelpers.js';
export default class Insert {
constructor() {
this.ForEntityName = 'INSERT';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 2:
entity.name = curr.value;
break;
case 41:
entity.xScale = curr.value;
break;
case 42:
entity.yScale = curr.value;
break;
case 43:
entity.zScale = curr.value;
break;
case 10:
entity.position = helpers.parsePoint(scanner);
break;
case 50:
entity.rotation = curr.value;
break;
case 70:
entity.columnCount = curr.value;
break;
case 71:
entity.rowCount = curr.value;
break;
case 44:
entity.columnSpacing = curr.value;
break;
case 45:
entity.rowSpacing = curr.value;
break;
case 210:
entity.extrusionDirection = helpers.parsePoint(scanner);
break;
default: // check common entity attributes
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,10 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface ILineEntity extends IEntity {
vertices: IPoint[];
extrusionDirection: IPoint;
}
export default class Line implements IGeometry {
ForEntityName: "LINE";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ILineEntity;
}

View File

@@ -0,0 +1,32 @@
import * as helpers from '../ParseHelpers.js';
export default class Line {
constructor() {
this.ForEntityName = 'LINE';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value, vertices: [] };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10: // X coordinate of point
entity.vertices.unshift(helpers.parsePoint(scanner));
break;
case 11:
entity.vertices.push(helpers.parsePoint(scanner));
break;
case 210:
entity.extrusionDirection = helpers.parsePoint(scanner);
break;
case 100:
break;
default:
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,22 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IVertex extends IPoint {
startWidth: number;
endWidth: number;
bulge: number;
}
export interface ILwpolylineEntity extends IEntity {
vertices: IVertex[];
elevation: number;
depth: number;
shape: boolean;
hasContinuousLinetypePattern: boolean;
width: number;
extrusionDirectionX: number;
extrusionDirectionY: number;
extrusionDirectionZ: number;
}
export default class Lwpolyline implements IGeometry {
ForEntityName: "LWPOLYLINE";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ILwpolylineEntity;
}

View File

@@ -0,0 +1,107 @@
import * as helpers from '../ParseHelpers.js';
export default class Lwpolyline {
constructor() {
this.ForEntityName = 'LWPOLYLINE';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value, vertices: [] };
let numberOfVertices = 0;
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 38:
entity.elevation = curr.value;
break;
case 39:
entity.depth = curr.value;
break;
case 70: // 1 = Closed shape, 128 = plinegen?, 0 = default
entity.shape = ((curr.value & 1) === 1);
entity.hasContinuousLinetypePattern = ((curr.value & 128) === 128);
break;
case 90:
numberOfVertices = curr.value;
break;
case 10: // X coordinate of point
entity.vertices = parseLWPolylineVertices(numberOfVertices, scanner);
break;
case 43:
if (curr.value !== 0)
entity.width = curr.value;
break;
case 210:
entity.extrusionDirectionX = curr.value;
break;
case 220:
entity.extrusionDirectionY = curr.value;
break;
case 230:
entity.extrusionDirectionZ = curr.value;
break;
default:
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}
function parseLWPolylineVertices(n, scanner) {
if (!n || n <= 0)
throw Error('n must be greater than 0 verticies');
const vertices = [];
let vertexIsStarted = false;
let vertexIsFinished = false;
let curr = scanner.lastReadGroup;
for (let i = 0; i < n; i++) {
const vertex = {};
while (!scanner.isEOF()) {
if (curr.code === 0 || vertexIsFinished)
break;
switch (curr.code) {
case 10: // X
if (vertexIsStarted) {
vertexIsFinished = true;
continue;
}
vertex.x = curr.value;
vertexIsStarted = true;
break;
case 20: // Y
vertex.y = curr.value;
break;
case 30: // Z
vertex.z = curr.value;
break;
case 40: // start width
vertex.startWidth = curr.value;
break;
case 41: // end width
vertex.endWidth = curr.value;
break;
case 42: // bulge
if (curr.value != 0)
vertex.bulge = curr.value;
break;
default:
// if we do not hit known code return vertices. Code might belong to entity
scanner.rewind();
if (vertexIsStarted) {
vertices.push(vertex);
}
scanner.rewind();
return vertices;
}
curr = scanner.next();
}
// See https://groups.google.com/forum/#!topic/comp.cad.autocad/9gn8s5O_w6E
vertices.push(vertex);
vertexIsStarted = false;
vertexIsFinished = false;
}
scanner.rewind();
return vertices;
}

View File

@@ -0,0 +1,16 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IMtextEntity extends IEntity {
text: string;
position: IPoint;
directionVector: IPoint;
height: number;
width: number;
rotation: number;
attachmentPoint: number;
drawingDirection: number;
}
export default class Mtext implements IGeometry {
ForEntityName: "MTEXT";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IMtextEntity;
}

View File

@@ -0,0 +1,49 @@
import * as helpers from '../ParseHelpers.js';
export default class Mtext {
constructor() {
this.ForEntityName = 'MTEXT';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 3:
entity.text ? entity.text += curr.value : entity.text = curr.value;
break;
case 1:
entity.text ? entity.text += curr.value : entity.text = curr.value;
break;
case 10:
entity.position = helpers.parsePoint(scanner);
break;
case 11:
entity.directionVector = helpers.parsePoint(scanner);
break;
case 40:
//Note: this is the text height
entity.height = curr.value;
break;
case 41:
entity.width = curr.value;
break;
case 50:
entity.rotation = curr.value;
break;
case 71:
entity.attachmentPoint = curr.value;
break;
case 72:
entity.drawingDirection = curr.value;
break;
default:
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,11 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IPointEntity extends IEntity {
position: IPoint;
thickness: number;
extrusionDirection: IPoint;
}
export default class Point implements IGeometry {
ForEntityName: "POINT";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IPointEntity;
}

View File

@@ -0,0 +1,33 @@
import * as helpers from '../ParseHelpers.js';
export default class Point {
constructor() {
this.ForEntityName = 'POINT';
}
parseEntity(scanner, curr) {
const type = curr.value;
const entity = { type };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10:
entity.position = helpers.parsePoint(scanner);
break;
case 39:
entity.thickness = curr.value;
break;
case 210:
entity.extrusionDirection = helpers.parsePoint(scanner);
break;
case 100:
break;
default: // check common entity attributes
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,20 @@
import { IVertexEntity } from './vertex';
import IGeometry, { IEntity, IPoint } from './geomtry';
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
export interface IPolylineEntity extends IEntity {
vertices: IVertexEntity[];
thickness: number;
shape: boolean;
includesCurveFitVertices: boolean;
includesSplineFitVertices: boolean;
is3dPolyline: boolean;
is3dPolygonMesh: boolean;
is3dPolygonMeshClosed: boolean;
isPolyfaceMesh: boolean;
hasContinuousLinetypePattern: boolean;
extrusionDirection: IPoint;
}
export default class Polyline implements IGeometry {
ForEntityName: "POLYLINE";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IPolylineEntity;
}

View File

@@ -0,0 +1,88 @@
import * as helpers from '../ParseHelpers.js';
import VertexParser from './vertex.js';
export default class Polyline {
constructor() {
this.ForEntityName = 'POLYLINE';
}
parseEntity(scanner, curr) {
var entity = { type: curr.value, vertices: [] };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10: // always 0
break;
case 20: // always 0
break;
case 30: // elevation
break;
case 39: // thickness
entity.thickness = curr.value;
break;
case 40: // start width
break;
case 41: // end width
break;
case 70:
entity.shape = (curr.value & 1) !== 0;
entity.includesCurveFitVertices = (curr.value & 2) !== 0;
entity.includesSplineFitVertices = (curr.value & 4) !== 0;
entity.is3dPolyline = (curr.value & 8) !== 0;
entity.is3dPolygonMesh = (curr.value & 16) !== 0;
entity.is3dPolygonMeshClosed = (curr.value & 32) !== 0; // 32 = The polygon mesh is closed in the N direction
entity.isPolyfaceMesh = (curr.value & 64) !== 0;
entity.hasContinuousLinetypePattern = (curr.value & 128) !== 0;
break;
case 71: // Polygon mesh M vertex count
break;
case 72: // Polygon mesh N vertex count
break;
case 73: // Smooth surface M density
break;
case 74: // Smooth surface N density
break;
case 75: // Curves and smooth surface type
break;
case 210:
entity.extrusionDirection = helpers.parsePoint(scanner);
break;
default:
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
entity.vertices = parsePolylineVertices(scanner, curr);
return entity;
}
}
function parsePolylineVertices(scanner, curr) {
const vertexParser = new VertexParser();
const vertices = [];
while (!scanner.isEOF()) {
if (curr.code === 0) {
if (curr.value === 'VERTEX') {
vertices.push(vertexParser.parseEntity(scanner, curr));
curr = scanner.lastReadGroup;
}
else if (curr.value === 'SEQEND') {
parseSeqEnd(scanner, curr);
break;
}
}
}
return vertices;
}
function parseSeqEnd(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code == 0)
break;
helpers.checkCommonEntityProperties(entity, curr, scanner);
curr = scanner.next();
}
return entity;
}
;

View File

@@ -0,0 +1,10 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface ISolidEntity extends IEntity {
points: IPoint[];
extrusionDirection: IPoint;
}
export default class Solid implements IGeometry {
ForEntityName: "SOLID";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ISolidEntity;
}

View File

@@ -0,0 +1,36 @@
import * as helpers from '../ParseHelpers.js';
export default class Solid {
constructor() {
this.ForEntityName = 'SOLID';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value, points: [] };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10:
entity.points[0] = helpers.parsePoint(scanner);
break;
case 11:
entity.points[1] = helpers.parsePoint(scanner);
break;
case 12:
entity.points[2] = helpers.parsePoint(scanner);
break;
case 13:
entity.points[3] = helpers.parsePoint(scanner);
break;
case 210:
entity.extrusionDirection = helpers.parsePoint(scanner);
break;
default: // check common entity attributes
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,23 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface ISplineEntity extends IEntity {
controlPoints?: IPoint[];
fitPoints?: IPoint[];
startTangent: IPoint;
endTangent: IPoint;
knotValues: number[];
closed: boolean;
periodic: boolean;
rational: boolean;
planar: boolean;
linear: boolean;
degreeOfSplineCurve: number;
numberOfKnots: number;
numberOfControlPoints: number;
numberOfFitPoints: number;
normalVector: IPoint;
}
export default class Spline implements IGeometry {
ForEntityName: "SPLINE";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ISplineEntity;
}

View File

@@ -0,0 +1,71 @@
import * as helpers from '../ParseHelpers.js';
export default class Spline {
constructor() {
this.ForEntityName = 'SPLINE';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10:
if (!entity.controlPoints)
entity.controlPoints = [];
entity.controlPoints.push(helpers.parsePoint(scanner));
break;
case 11:
if (!entity.fitPoints)
entity.fitPoints = [];
entity.fitPoints.push(helpers.parsePoint(scanner));
break;
case 12:
entity.startTangent = helpers.parsePoint(scanner);
break;
case 13:
entity.endTangent = helpers.parsePoint(scanner);
break;
case 40:
if (!entity.knotValues)
entity.knotValues = [];
entity.knotValues.push(curr.value);
break;
case 70:
if ((curr.value & 1) != 0)
entity.closed = true;
if ((curr.value & 2) != 0)
entity.periodic = true;
if ((curr.value & 4) != 0)
entity.rational = true;
if ((curr.value & 8) != 0)
entity.planar = true;
if ((curr.value & 16) != 0) {
entity.planar = true;
entity.linear = true;
}
break;
case 71:
entity.degreeOfSplineCurve = curr.value;
break;
case 72:
entity.numberOfKnots = curr.value;
break;
case 73:
entity.numberOfControlPoints = curr.value;
break;
case 74:
entity.numberOfFitPoints = curr.value;
break;
case 210:
entity.normalVector = helpers.parsePoint(scanner);
break;
default:
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,16 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface ITextEntity extends IEntity {
startPoint: IPoint;
endPoint: IPoint;
textHeight: number;
xScale: number;
rotation: number;
text: string;
halign: number;
valign: number;
}
export default class Text implements IGeometry {
ForEntityName: "TEXT";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ITextEntity;
}

View File

@@ -0,0 +1,46 @@
import * as helpers from '../ParseHelpers.js';
export default class Text {
constructor() {
this.ForEntityName = 'TEXT';
}
parseEntity(scanner, curr) {
const entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10: // X coordinate of 'first alignment point'
entity.startPoint = helpers.parsePoint(scanner);
break;
case 11: // X coordinate of 'second alignment point'
entity.endPoint = helpers.parsePoint(scanner);
break;
case 40: // Text height
entity.textHeight = curr.value;
break;
case 41:
entity.xScale = curr.value;
break;
case 50: // Rotation in degrees
entity.rotation = curr.value;
break;
case 1: // Text
entity.text = curr.value;
break;
// NOTE: 72 and 73 are meaningless without 11 (second alignment point)
case 72: // Horizontal alignment
entity.halign = curr.value;
break;
case 73: // Vertical alignment
entity.valign = curr.value;
break;
default: // check common entity attributes
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}

View File

@@ -0,0 +1,20 @@
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
import IGeometry, { IEntity, IPoint } from './geomtry';
export interface IVertexEntity extends IEntity, IPoint {
bulge: number;
curveFittingVertex: boolean;
curveFitTangent: boolean;
splineVertex: boolean;
splineControlPoint: boolean;
threeDPolylineVertex: boolean;
threeDPolylineMesh: boolean;
polyfaceMeshVertex: boolean;
faceA: number;
faceB: number;
faceC: number;
faceD: number;
}
export default class Vertex implements IGeometry {
ForEntityName: "VERTEX";
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IVertexEntity;
}

View File

@@ -0,0 +1,61 @@
import * as helpers from '../ParseHelpers.js';
export default class Vertex {
constructor() {
this.ForEntityName = 'VERTEX';
}
parseEntity(scanner, curr) {
var entity = { type: curr.value };
curr = scanner.next();
while (!scanner.isEOF()) {
if (curr.code === 0)
break;
switch (curr.code) {
case 10: // X
entity.x = curr.value;
break;
case 20: // Y
entity.y = curr.value;
break;
case 30: // Z
entity.z = curr.value;
break;
case 40: // start width
break;
case 41: // end width
break;
case 42: // bulge
if (curr.value != 0)
entity.bulge = curr.value;
break;
case 70: // flags
entity.curveFittingVertex = (curr.value & 1) !== 0;
entity.curveFitTangent = (curr.value & 2) !== 0;
entity.splineVertex = (curr.value & 8) !== 0;
entity.splineControlPoint = (curr.value & 16) !== 0;
entity.threeDPolylineVertex = (curr.value & 32) !== 0;
entity.threeDPolylineMesh = (curr.value & 64) !== 0;
entity.polyfaceMeshVertex = (curr.value & 128) !== 0;
break;
case 50: // curve fit tangent direction
break;
case 71: // polyface mesh vertex index
entity.faceA = curr.value;
break;
case 72: // polyface mesh vertex index
entity.faceB = curr.value;
break;
case 73: // polyface mesh vertex index
entity.faceC = curr.value;
break;
case 74: // polyface mesh vertex index
entity.faceD = curr.value;
break;
default:
helpers.checkCommonEntityProperties(entity, curr, scanner);
break;
}
curr = scanner.next();
}
return entity;
}
}