feat(All):Initial
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
import DxfArrayScanner, {IGroup} from '../DxfArrayScanner';
|
||||
import * as helpers from '../ParseHelpers'
|
||||
import IGeometry, {IEntity, IPoint} from './geomtry';
|
||||
|
||||
export interface IHatchEntity extends IEntity {
|
||||
boundaryLoops: any[];
|
||||
definitionLines: any[];
|
||||
seedPoints: any[];
|
||||
patternName: string;
|
||||
isSolid: boolean;
|
||||
hatchStyle: string;
|
||||
patternType: number;
|
||||
patternAngle: number;
|
||||
patternScale: number;
|
||||
}
|
||||
|
||||
export default class Hatch implements IGeometry {
|
||||
public ForEntityName = 'HATCH' as const;
|
||||
|
||||
public parseEntity(scanner: DxfArrayScanner, curr: IGroup) {
|
||||
let entity = {type: curr.value} as IHatchEntity;
|
||||
|
||||
let numBoundaryLoops = 0;
|
||||
let numDefinitionLines = 0;
|
||||
let numSeedPoints = 0;
|
||||
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0) break;
|
||||
|
||||
while (numBoundaryLoops > 0) {
|
||||
const loop = ParseBoundaryLoop(curr, scanner)
|
||||
if (loop) {
|
||||
entity.boundaryLoops.push(loop);
|
||||
numBoundaryLoops--;
|
||||
curr = scanner.next();
|
||||
} else {
|
||||
numBoundaryLoops = 0
|
||||
}
|
||||
}
|
||||
|
||||
while (numDefinitionLines > 0) {
|
||||
const line = ParseDefinitionLine(curr, scanner)
|
||||
if (line) {
|
||||
entity.definitionLines.push(line);
|
||||
numDefinitionLines--;
|
||||
curr = scanner.next();
|
||||
} else {
|
||||
numDefinitionLines = 0
|
||||
}
|
||||
}
|
||||
|
||||
while (numSeedPoints > 0) {
|
||||
const pt = ParseSeedPoint(curr, scanner);
|
||||
if (pt) {
|
||||
entity.seedPoints.push(pt);
|
||||
numSeedPoints--;
|
||||
curr = scanner.next();
|
||||
} else {
|
||||
numSeedPoints = 0
|
||||
}
|
||||
}
|
||||
|
||||
if (curr.code === 0) break;
|
||||
|
||||
switch (curr.code) {
|
||||
case 2: // 填充图案名
|
||||
entity.patternName = curr.value as string;
|
||||
break;
|
||||
case 70: // 实体填充标志(实体填充 = 1;图案填充 = 0)
|
||||
entity.isSolid = curr.value != 0;
|
||||
break;
|
||||
case 91: // 边界路径(环)数
|
||||
numBoundaryLoops = curr.value as number;
|
||||
if (numBoundaryLoops > 0) {
|
||||
entity.boundaryLoops = []
|
||||
}
|
||||
break;
|
||||
/**
|
||||
* 图案填充样式:
|
||||
* 0 = 对“奇数奇偶校验”区域进行图案填充(普通样式)
|
||||
* 1 = 仅对最外层区域进行图案填充(“外部”样式)
|
||||
* 2 = 对整个区域进行图案填充(“忽略”样式)
|
||||
*/
|
||||
case 75:
|
||||
entity.hatchStyle = curr.value as string;
|
||||
break;
|
||||
/**
|
||||
* 填充图案类型:
|
||||
* 0 = 用户定义;1 = 预定义;2 = 自定义
|
||||
*/
|
||||
case 76:
|
||||
entity.patternType = curr.value as number;
|
||||
break;
|
||||
case 52: // 填充图案角度(仅限图案填充)
|
||||
entity.patternAngle = (curr.value as number) * Math.PI / 180;
|
||||
break;
|
||||
case 41: // 填充图案比例或间距(仅限图案填充)
|
||||
entity.patternScale = curr.value as number;
|
||||
break;
|
||||
case 78: // 图案定义直线数
|
||||
numDefinitionLines = curr.value as number;
|
||||
if (numDefinitionLines > 0) {
|
||||
entity.definitionLines = []
|
||||
}
|
||||
break;
|
||||
case 98: // 种子点数
|
||||
numSeedPoints = curr.value as number;
|
||||
if (numSeedPoints > 0) {
|
||||
entity.seedPoints = []
|
||||
}
|
||||
break;
|
||||
default: // 检查通用实体属性
|
||||
helpers.checkCommonEntityProperties(entity, curr, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
|
||||
return entity;
|
||||
};
|
||||
}
|
||||
|
||||
function ParseBoundaryLoop(curr: IGroup, scanner: DxfArrayScanner) {
|
||||
let entity:any = null
|
||||
|
||||
const ParsePolyline = () => {
|
||||
const pl: { vertices: IPoint[], isClosed: boolean } = {vertices: [], isClosed: false};
|
||||
let numVertices = 0;
|
||||
while (true) {
|
||||
if (numVertices > 0) {
|
||||
for (let i = 0; i < numVertices; i++) {
|
||||
if (curr.code != 10) {
|
||||
break
|
||||
}
|
||||
const p = helpers.parsePoint(scanner)
|
||||
curr = scanner.next();
|
||||
if (curr.code == 42) {
|
||||
// @ts-ignore
|
||||
p.bulge = curr.value;
|
||||
curr = scanner.next();
|
||||
}
|
||||
pl.vertices.push(p)
|
||||
}
|
||||
return pl
|
||||
}
|
||||
|
||||
switch (curr.code) {
|
||||
case 73:
|
||||
pl.isClosed = curr.value as boolean;
|
||||
break;
|
||||
case 93:
|
||||
numVertices = curr.value as number;
|
||||
break;
|
||||
default:
|
||||
return pl;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
}
|
||||
|
||||
const ParseEdge = () => {
|
||||
if (curr.code != 72) {
|
||||
return null
|
||||
}
|
||||
const e:any = {type: curr.value}
|
||||
curr = scanner.next();
|
||||
const isSpline = e.type == 4;
|
||||
|
||||
while (true) {
|
||||
switch (curr.code) {
|
||||
case 10:
|
||||
if (isSpline) {
|
||||
if (!e.controlPoints) {
|
||||
e.controlPoints = [];
|
||||
}
|
||||
e.controlPoints.push(helpers.parsePoint(scanner));
|
||||
} else {
|
||||
e.start = helpers.parsePoint(scanner);
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (isSpline) {
|
||||
if (!e.fitPoints) {
|
||||
e.fitPoints = [];
|
||||
}
|
||||
e.fitPoints.push(helpers.parsePoint(scanner));
|
||||
} else {
|
||||
e.end = helpers.parsePoint(scanner);
|
||||
}
|
||||
break;
|
||||
case 40:
|
||||
if (isSpline) {
|
||||
if (!e.knotValues) {
|
||||
e.knotValues = [];
|
||||
}
|
||||
e.knotValues.push(curr.value);
|
||||
} else {
|
||||
e.radius = curr.value;
|
||||
}
|
||||
break;
|
||||
case 50:
|
||||
e.startAngle = (curr.value as number) * Math.PI / 180;
|
||||
break;
|
||||
case 51:
|
||||
e.endAngle = (curr.value as number) * Math.PI / 180;
|
||||
break;
|
||||
case 73:
|
||||
if (isSpline) {
|
||||
e.rational = curr.value;
|
||||
} else {
|
||||
e.isCcw = curr.value;
|
||||
}
|
||||
break;
|
||||
case 74:
|
||||
e.periodic = curr.value;
|
||||
break;
|
||||
case 94:
|
||||
e.degreeOfSplineCurve = curr.value;
|
||||
break;
|
||||
|
||||
//XXX暂时忽略一些群体,主要是样条
|
||||
case 95:
|
||||
case 96:
|
||||
case 42:
|
||||
case 97:
|
||||
break;
|
||||
default:
|
||||
return e
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
}
|
||||
|
||||
let polylineParsed = false;
|
||||
let numEdges = 0;
|
||||
let numSourceRefs = 0;
|
||||
|
||||
while (true) {
|
||||
if (!entity) {
|
||||
if (curr.code != 92) {
|
||||
return null;
|
||||
}
|
||||
entity = {type: curr.value};
|
||||
curr = scanner.next();
|
||||
}
|
||||
|
||||
if ((entity.type & 2) && !polylineParsed) {
|
||||
entity.polyline = ParsePolyline()
|
||||
polylineParsed = true
|
||||
}
|
||||
|
||||
while (numEdges) {
|
||||
const edge = ParseEdge();
|
||||
if (edge) {
|
||||
entity.edges.push(edge);
|
||||
numEdges--;
|
||||
} else {
|
||||
numEdges = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (numSourceRefs) {
|
||||
if (curr.code == 330) {
|
||||
entity.sourceRefs.push(curr.value);
|
||||
numSourceRefs--;
|
||||
curr = scanner.next();
|
||||
} else {
|
||||
numSourceRefs = 0
|
||||
}
|
||||
}
|
||||
|
||||
switch (curr.code) {
|
||||
case 93:
|
||||
numEdges = curr.value as number;
|
||||
if (numEdges > 0) {
|
||||
entity.edges = []
|
||||
}
|
||||
break;
|
||||
case 97:
|
||||
numSourceRefs = curr.value as number;
|
||||
if (numSourceRefs > 0) {
|
||||
entity.sourceRefs = []
|
||||
}
|
||||
break;
|
||||
default:
|
||||
scanner.rewind();
|
||||
return entity;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
}
|
||||
|
||||
function ParseDefinitionLine(curr: IGroup, scanner: DxfArrayScanner) {
|
||||
/* 假设总是从53组开始. */
|
||||
if (curr.code != 53) {
|
||||
return null
|
||||
}
|
||||
const entity:any = {
|
||||
angle: (curr.value as number) * Math.PI / 180,
|
||||
base: {x: 0, y: 0},
|
||||
offset: {x: 0, y: 0}
|
||||
};
|
||||
curr = scanner.next();
|
||||
|
||||
let numDashes = 0;
|
||||
while (true) {
|
||||
switch (curr.code) {
|
||||
case 43:
|
||||
entity.base.x = curr.value as number;
|
||||
break;
|
||||
case 44:
|
||||
entity.base.y = curr.value as number;
|
||||
break;
|
||||
case 45:
|
||||
entity.offset.x = curr.value as number;
|
||||
break;
|
||||
case 46:
|
||||
entity.offset.y = curr.value as number;
|
||||
break;
|
||||
case 49:
|
||||
if (numDashes > 0) {
|
||||
entity.dashes.push(curr.value);
|
||||
numDashes--;
|
||||
}
|
||||
break;
|
||||
case 79:
|
||||
numDashes = curr.value as number;
|
||||
if (curr.value) {
|
||||
entity.dashes = []
|
||||
}
|
||||
break;
|
||||
default:
|
||||
scanner.rewind();
|
||||
return entity;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
}
|
||||
|
||||
function ParseSeedPoint(curr: IGroup, scanner: DxfArrayScanner) {
|
||||
if (curr.code != 10) {
|
||||
return null
|
||||
}
|
||||
return helpers.parsePoint(scanner);
|
||||
}
|
||||
Reference in New Issue
Block a user