@mlightcad/libredwg-web
Version:
A DWG/DXF JavaScript parser based on libredwg
968 lines • 42.8 kB
JavaScript
import { HEADER_VARIABLES } from '../database';
import { Dwg_Object_Type } from '../types';
import { LibreEntityConverter } from './entityConverter';
import { idToString, isModelSpace, isPaperSpace } from './utils';
/**
* Class used to convert Dwg_Data instance to DwgDatabase instance.
*/
export class LibreDwgConverter {
libredwg;
entityConverter;
constructor(instance) {
this.libredwg = instance;
this.entityConverter = new LibreEntityConverter(instance);
}
convert(data) {
this.entityConverter.clear();
const db = {
tables: {
APPID: {
entries: []
},
BLOCK_RECORD: {
entries: []
},
DIMSTYLE: {
entries: []
},
LAYER: {
entries: []
},
LTYPE: {
entries: []
},
STYLE: {
entries: []
},
VPORT: {
entries: []
}
},
objects: {
DICTIONARY: [],
IMAGEDEF: [],
LAYOUT: [],
SPATIAL_FILTER: []
},
header: {},
entities: [],
classes: []
};
const libredwg = this.libredwg;
this.convertHeader(data, db.header);
this.convertClasses(data, db.classes);
const num_objects = libredwg.dwg_get_num_objects(data);
for (let i = 0; i < num_objects; i++) {
const obj = libredwg.dwg_get_object(data, i);
if (obj) {
const tio = libredwg.dwg_object_to_object_tio(obj);
if (tio) {
const fixedtype = libredwg.dwg_object_get_fixedtype(obj);
switch (fixedtype) {
case Dwg_Object_Type.DWG_TYPE_LAYER:
{
const layer = this.convertLayer(tio, obj);
db.tables.LAYER.entries.push(layer);
this.entityConverter.layers.set(layer.handle, layer.name);
}
break;
case Dwg_Object_Type.DWG_TYPE_LTYPE:
{
const ltype = this.convertLineType(tio, obj);
db.tables.LTYPE.entries.push(ltype);
this.entityConverter.ltypes.set(ltype.handle, ltype.name);
}
break;
default:
break;
}
}
}
}
for (let i = 0; i < num_objects; i++) {
const obj = libredwg.dwg_get_object(data, i);
if (obj) {
const tio = libredwg.dwg_object_to_object_tio(obj);
if (tio) {
const fixedtype = libredwg.dwg_object_get_fixedtype(obj);
switch (fixedtype) {
case Dwg_Object_Type.DWG_TYPE_APPID:
db.tables.APPID.entries.push(this.convertAppId(tio));
break;
case Dwg_Object_Type.DWG_TYPE_BLOCK_HEADER:
{
const btr = this.convertBlockRecord(tio, obj);
db.tables.BLOCK_RECORD.entries.push(btr);
// Store entities in model space and paper space to db.entities to keep the
// the consistent data structure as DXF file
if (isModelSpace(btr.name) || isPaperSpace(btr.name)) {
btr.entities.forEach(entity => {
db.entities.push(entity);
// Store ATTRIB entity in db.entities to keep the the consistent data
// structure as DXF file
if (entity.type === 'INSERT') {
entity.attribs.forEach(attrib => {
db.entities.push(attrib);
});
}
});
}
}
break;
case Dwg_Object_Type.DWG_TYPE_DIMSTYLE:
db.tables.DIMSTYLE.entries.push(this.convertDimStyle(tio, obj));
break;
case Dwg_Object_Type.DWG_TYPE_STYLE:
db.tables.STYLE.entries.push(this.convertStyle(tio, obj));
break;
case Dwg_Object_Type.DWG_TYPE_VPORT:
db.tables.VPORT.entries.push(this.convertViewport(tio, obj));
break;
case Dwg_Object_Type.DWG_TYPE_DICTIONARY:
db.objects.DICTIONARY.push(this.convertDictionary(tio, obj));
break;
case Dwg_Object_Type.DWG_TYPE_IMAGEDEF:
db.objects.IMAGEDEF.push(this.convertImageDef(tio, obj));
break;
case Dwg_Object_Type.DWG_TYPE_LAYOUT:
db.objects.LAYOUT.push(this.convertLayout(tio, obj));
break;
case Dwg_Object_Type.DWG_TYPE_SPATIAL_FILTER:
db.objects.SPATIAL_FILTER.push(this.convertSpatialFilter(tio, obj));
break;
default:
break;
}
}
}
}
// Process viewport entities: sort by objectId (handle) and assign viewportId
const viewportEntities = db.entities.filter(entity => entity.type === 'VIEWPORT');
viewportEntities.sort((a, b) => {
// Convert handle to hex number for sorting
const handleA = parseInt(a.handle, 16);
const handleB = parseInt(b.handle, 16);
return handleA - handleB;
});
// Assign viewportId starting from 1
viewportEntities.forEach((viewport, index) => {
viewport.viewportId = index + 1;
});
return db;
}
getConversionStats() {
return {
unknownEntityCount: this.entityConverter.unknownEntityCount
};
}
convertHeader(data, header) {
const libredwg = this.libredwg;
HEADER_VARIABLES.forEach(name => {
let var_name = name;
if (name == 'DIMBLK' || name == 'DIMBLK1' || name == 'DIMBLK2') {
var_name = var_name + '_T';
}
let value = libredwg.dwg_dynapi_header_value(data, var_name).data;
// Get object name if the 'value' is one Dwg_Object_Ref instance.
// TODO: handle 'CMLSTYLE' correctly
if (name == 'CELTYPE' ||
name == 'CLAYER' ||
name == 'CLAYER' ||
name == 'DIMSTYLE' ||
name == 'DIMTXSTY' ||
name == 'TEXTSTYLE') {
value = !!value ? libredwg.dwg_ref_get_object_name(value) : '';
}
else if (name == 'DRAGVS') {
value = !!value ? libredwg.dwg_ref_get_absref(value) : 2;
}
// @ts-expect-error header variable name
header[name] = value;
});
}
convertClasses(data, classes) {
const libredwg = this.libredwg;
const count = libredwg.dwg_get_num_classes(data);
for (let index = 0; index < count; index++) {
const cls = libredwg.dwg_get_class(data, index);
classes.push({
dxfName: cls.dxfname,
cppName: cls.cppname,
appName: cls.appname,
capabilitiesFlag: cls.proxyflag,
instanceCount: cls.num_instances,
wasAProxyFlag: cls.s_zombie,
// DWG_TYPE_PROXY_ENTITY = 0x1F2 /* 498 */,
// DWG_TYPE_PROXY_OBJECT = 0x1F3 /* 499 */,
isAnEntityFlag: cls.item_class_id === 0x1f2
});
}
}
convertAppId(item) {
const libredwg = this.libredwg;
const name = libredwg.dwg_dynapi_entity_value(item, 'name').data;
const flag = libredwg.dwg_dynapi_entity_value(item, 'flag').data;
return {
name: name,
standardFlag: flag
};
}
convertBlockRecord(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonTableEntryAttrs(item, obj);
// The BLOCK_HEADER has only the abbrevated name, but we want "*D30" instead of "*D".
// So get full name from BLOCK entity.
const block = libredwg.dwg_entity_block_header_get_block(item);
if (block.name) {
commonAttrs.name = block.name;
}
// The number of entities
const num_owned = libredwg.dwg_dynapi_entity_value(item, 'num_owned')
.data;
const flags = libredwg.dwg_dynapi_entity_value(item, 'flag').data;
const description = libredwg.dwg_dynapi_entity_value(item, 'description')
.data;
const basePoint = libredwg.dwg_dynapi_entity_value(item, 'base_pt')
.data;
const insertionUnits = libredwg.dwg_dynapi_entity_value(item, 'insert_units').data;
const explodability = libredwg.dwg_dynapi_entity_value(item, 'explodable')
.data;
const scalability = libredwg.dwg_dynapi_entity_value(item, 'block_scaling')
.data;
const layout_ptr = libredwg.dwg_dynapi_entity_value(item, 'layout')
.data;
const layout = idToString(libredwg.dwg_ref_get_absref(layout_ptr));
let bmpPreview = '';
const uint8ArrayToHexString = (bytes) => {
const hexChars = new Array(bytes.length);
for (let i = 0; i < bytes.length; i++) {
hexChars[i] = bytes[i].toString(16).toUpperCase();
}
return hexChars.join('');
};
const bmpPreviewBinaryData = libredwg.dwg_entity_block_header_get_preview(item);
if (bmpPreviewBinaryData && bmpPreviewBinaryData.length > 0) {
bmpPreview = uint8ArrayToHexString(bmpPreviewBinaryData);
}
// Sometimes function get_first_owned_entity returns 0 when trying to iterate entities in one block.
// I guess it is one bug on libredwg. I logged [one bug](https://github.com/LibreDWG/libredwg/issues/1199)
// on libredwg too. In this time, I try to use property 'entities' of block header to iterate entities.
let entities = this.convertEntities(obj, commonAttrs.handle);
if (!entities || entities.length == 0) {
entities = [];
const entities_ptr = libredwg.dwg_dynapi_entity_value(item, 'entities')
.data;
if (entities_ptr) {
const object_ref_ptr_array = libredwg.dwg_ptr_to_object_ref_ptr_array(entities_ptr, num_owned);
const converter = this.entityConverter;
for (let index = 0; index < num_owned; index++) {
const object = libredwg.dwg_ref_get_object(object_ref_ptr_array[index]);
const entity = converter.convert(object);
if (entity) {
entity.ownerBlockRecordSoftId = commonAttrs.handle;
entities.push(entity);
}
}
}
}
return {
...commonAttrs,
flags: flags,
description: description,
basePoint: basePoint,
layout: layout,
insertionUnits: insertionUnits,
explodability: explodability,
scalability: scalability,
bmpPreview: bmpPreview,
entities: entities
};
}
convertEntities(obj, ownerHandle) {
const libredwg = this.libredwg;
const converter = this.entityConverter;
const entities = [];
let next = libredwg.get_first_owned_entity(obj);
while (next) {
const entity = converter.convert(next);
if (entity) {
entity.ownerBlockRecordSoftId = ownerHandle;
entities.push(entity);
}
next = libredwg.get_next_owned_entity(obj, next);
}
return entities;
}
convertDimStyle(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonTableEntryAttrs(item, obj);
const DIMTOL = libredwg.dwg_dynapi_entity_value(item, 'DIMTOL')
.data;
const DIMLIM = libredwg.dwg_dynapi_entity_value(item, 'DIMLIM')
.data;
const DIMTIH = libredwg.dwg_dynapi_entity_value(item, 'DIMTIH')
.data;
const DIMTOH = libredwg.dwg_dynapi_entity_value(item, 'DIMTOH')
.data;
const DIMSE1 = libredwg.dwg_dynapi_entity_value(item, 'DIMSE1')
.data;
const DIMSE2 = libredwg.dwg_dynapi_entity_value(item, 'DIMSE2')
.data;
const DIMALT = libredwg.dwg_dynapi_entity_value(item, 'DIMALT')
.data;
const DIMTOFL = libredwg.dwg_dynapi_entity_value(item, 'DIMTOFL')
.data;
const DIMSAH = libredwg.dwg_dynapi_entity_value(item, 'DIMSAH')
.data;
const DIMTIX = libredwg.dwg_dynapi_entity_value(item, 'DIMTIX')
.data;
const DIMSOXD = libredwg.dwg_dynapi_entity_value(item, 'DIMSOXD')
.data;
const DIMALTD = libredwg.dwg_dynapi_entity_value(item, 'DIMALTD')
.data;
const DIMZIN = libredwg.dwg_dynapi_entity_value(item, 'DIMZIN')
.data;
const DIMSD1 = libredwg.dwg_dynapi_entity_value(item, 'DIMSD1')
.data;
const DIMSD2 = libredwg.dwg_dynapi_entity_value(item, 'DIMSD2')
.data;
const DIMTOLJ = libredwg.dwg_dynapi_entity_value(item, 'DIMTOLJ')
.data;
const DIMJUST = libredwg.dwg_dynapi_entity_value(item, 'DIMJUST')
.data;
const DIMFIT = libredwg.dwg_dynapi_entity_value(item, 'DIMFIT')
.data;
const DIMUPT = libredwg.dwg_dynapi_entity_value(item, 'DIMUPT')
.data;
const DIMTZIN = libredwg.dwg_dynapi_entity_value(item, 'DIMTZIN')
.data;
const DIMALTZ = libredwg.dwg_dynapi_entity_value(item, 'DIMALTZ')
.data;
const DIMALTTZ = libredwg.dwg_dynapi_entity_value(item, 'DIMALTTZ')
.data;
const DIMTAD = libredwg.dwg_dynapi_entity_value(item, 'DIMTAD')
.data;
const DIMUNIT = libredwg.dwg_dynapi_entity_value(item, 'DIMUNIT')
.data;
const DIMAUNIT = libredwg.dwg_dynapi_entity_value(item, 'DIMAUNIT')
.data;
const DIMDEC = libredwg.dwg_dynapi_entity_value(item, 'DIMDEC')
.data;
const DIMTDEC = libredwg.dwg_dynapi_entity_value(item, 'DIMTDEC')
.data;
const DIMALTU = libredwg.dwg_dynapi_entity_value(item, 'DIMALTU')
.data;
const DIMALTTD = libredwg.dwg_dynapi_entity_value(item, 'DIMALTTD')
.data;
const DIMSCALE = libredwg.dwg_dynapi_entity_value(item, 'DIMSCALE')
.data;
const DIMASZ = libredwg.dwg_dynapi_entity_value(item, 'DIMASZ')
.data;
const DIMEXO = libredwg.dwg_dynapi_entity_value(item, 'DIMEXO')
.data;
const DIMDLI = libredwg.dwg_dynapi_entity_value(item, 'DIMDLI')
.data;
const DIMEXE = libredwg.dwg_dynapi_entity_value(item, 'DIMEXE')
.data;
const DIMRND = libredwg.dwg_dynapi_entity_value(item, 'DIMRND')
.data;
const DIMDLE = libredwg.dwg_dynapi_entity_value(item, 'DIMDLE')
.data;
const DIMTP = libredwg.dwg_dynapi_entity_value(item, 'DIMTP').data;
const DIMTM = libredwg.dwg_dynapi_entity_value(item, 'DIMTM').data;
const DIMFXL = libredwg.dwg_dynapi_entity_value(item, 'DIMFXL')
.data;
const DIMJOGANG = libredwg.dwg_dynapi_entity_value(item, 'DIMJOGANG')
.data;
const DIMTFILL = libredwg.dwg_dynapi_entity_value(item, 'DIMTFILL')
.data;
const DIMTFILLCLR = libredwg.dwg_dynapi_entity_value(item, 'DIMTFILLCLR')
.data;
const DIMAZIN = libredwg.dwg_dynapi_entity_value(item, 'DIMAZIN')
.data;
const DIMARCSYM = libredwg.dwg_dynapi_entity_value(item, 'DIMARCSYM')
.data;
const DIMTXT = libredwg.dwg_dynapi_entity_value(item, 'DIMTXT')
.data;
const DIMCEN = libredwg.dwg_dynapi_entity_value(item, 'DIMCEN')
.data;
const DIMTSZ = libredwg.dwg_dynapi_entity_value(item, 'DIMTSZ')
.data;
const DIMALTF = libredwg.dwg_dynapi_entity_value(item, 'DIMALTF')
.data;
const DIMLFAC = libredwg.dwg_dynapi_entity_value(item, 'DIMLFAC')
.data;
const DIMTVP = libredwg.dwg_dynapi_entity_value(item, 'DIMTVP')
.data;
const DIMTFAC = libredwg.dwg_dynapi_entity_value(item, 'DIMTFAC')
.data;
const DIMGAP = libredwg.dwg_dynapi_entity_value(item, 'DIMGAP')
.data;
const DIMPOST = libredwg.dwg_dynapi_entity_value(item, 'DIMPOST')
.data;
const DIMAPOST = libredwg.dwg_dynapi_entity_value(item, 'DIMAPOST')
.data;
const DIMBLK_T = libredwg.dwg_dynapi_entity_value(item, 'DIMBLK_T')
.data;
const DIMBLK1_T = libredwg.dwg_dynapi_entity_value(item, 'DIMBLK1_T')
.data;
const DIMBLK2_T = libredwg.dwg_dynapi_entity_value(item, 'DIMBLK2_T')
.data;
const DIMALTRND = libredwg.dwg_dynapi_entity_value(item, 'DIMALTRND')
.data;
const DIMCLRD_N = libredwg.dwg_dynapi_entity_value(item, 'DIMCLRD_N')
.data;
const DIMCLRE_N = libredwg.dwg_dynapi_entity_value(item, 'DIMCLRE_N')
.data;
const DIMCLRT_N = libredwg.dwg_dynapi_entity_value(item, 'DIMCLRT_N')
.data;
const DIMCLRD = libredwg.dwg_dynapi_entity_value(item, 'DIMCLRD')
.data;
const DIMCLRE = libredwg.dwg_dynapi_entity_value(item, 'DIMCLRE')
.data;
const DIMCLRT = libredwg.dwg_dynapi_entity_value(item, 'DIMCLRT')
.data;
const DIMADEC = libredwg.dwg_dynapi_entity_value(item, 'DIMADEC')
.data;
const DIMFRAC = libredwg.dwg_dynapi_entity_value(item, 'DIMFRAC')
.data;
const DIMLUNIT = libredwg.dwg_dynapi_entity_value(item, 'DIMLUNIT')
.data;
const DIMDSEP = libredwg.dwg_dynapi_entity_value(item, 'DIMDSEP')
.data;
const DIMTMOVE = libredwg.dwg_dynapi_entity_value(item, 'DIMTMOVE')
.data;
const DIMATFIT = libredwg.dwg_dynapi_entity_value(item, 'DIMATFIT')
.data;
const DIMFXLON = libredwg.dwg_dynapi_entity_value(item, 'DIMFXLON')
.data;
const DIMTXTDIRECTION = libredwg.dwg_dynapi_entity_value(item, 'DIMTXTDIRECTION').data;
const DIMALTMZF = libredwg.dwg_dynapi_entity_value(item, 'DIMALTMZF')
.data;
const DIMALTMZS = libredwg.dwg_dynapi_entity_value(item, 'DIMALTMZS')
.data;
const DIMMZF = libredwg.dwg_dynapi_entity_value(item, 'DIMMZF')
.data;
const DIMMZS = libredwg.dwg_dynapi_entity_value(item, 'DIMMZS')
.data;
const DIMLWD = libredwg.dwg_dynapi_entity_value(item, 'DIMLWD')
.data;
const DIMLWE = libredwg.dwg_dynapi_entity_value(item, 'DIMLWE')
.data;
const DIMTXSTY_Ptr = libredwg.dwg_dynapi_entity_value(item, 'DIMTXSTY')
.data;
const DIMTXSTY = libredwg.dwg_ref_get_absref(DIMTXSTY_Ptr);
const DIMLDRBLK_Ptr = libredwg.dwg_dynapi_entity_value(item, 'DIMLDRBLK')
.data;
const DIMLDRBLK = libredwg.dwg_ref_get_absref(DIMLDRBLK_Ptr);
return {
...commonAttrs,
DIMPOST: DIMPOST,
DIMAPOST: DIMAPOST,
DIMBLK: DIMBLK_T,
DIMBLK1: DIMBLK1_T,
DIMBLK2: DIMBLK2_T,
DIMSCALE: DIMSCALE,
DIMASZ: DIMASZ,
DIMEXO: DIMEXO,
DIMDLI: DIMDLI,
DIMEXE: DIMEXE,
DIMRND: DIMRND,
DIMDLE: DIMDLE,
DIMTP: DIMTP,
DIMTM: DIMTM,
DIMTXT: DIMTXT,
DIMCEN: DIMCEN,
DIMTSZ: DIMTSZ,
DIMALTF: DIMALTF,
DIMLFAC: DIMLFAC,
DIMTVP: DIMTVP,
DIMTFAC: DIMTFAC,
DIMGAP: DIMGAP,
DIMALTRND: DIMALTRND,
DIMTOL: DIMTOL,
DIMLIM: DIMLIM,
DIMTIH: DIMTIH,
DIMTOH: DIMTOH,
DIMSE1: DIMSE1,
DIMSE2: DIMSE2,
DIMTAD: DIMTAD,
DIMZIN: DIMZIN,
DIMAZIN: DIMAZIN,
DIMALT: DIMALT,
DIMALTD: DIMALTD,
DIMTOFL: DIMTOFL,
DIMSAH: DIMSAH,
DIMTIX: DIMTIX,
DIMSOXD: DIMSOXD,
DIMCLRD: DIMCLRD,
DIMCLRE: DIMCLRE,
DIMCLRT: DIMCLRT,
DIMADEC: DIMADEC,
DIMUNIT: DIMUNIT,
DIMDEC: DIMDEC,
DIMTDEC: DIMTDEC,
DIMALTU: DIMALTU,
DIMALTTD: DIMALTTD,
DIMAUNIT: DIMAUNIT,
DIMFRAC: DIMFRAC,
DIMLUNIT: DIMLUNIT,
DIMDSEP: String.fromCharCode(DIMDSEP),
DIMTMOVE: DIMTMOVE,
DIMJUST: DIMJUST,
DIMSD1: DIMSD1,
DIMSD2: DIMSD2,
DIMTOLJ: DIMTOLJ,
DIMTZIN: DIMTZIN,
DIMALTZ: DIMALTZ,
DIMALTTZ: DIMALTTZ,
DIMFIT: DIMFIT,
DIMUPT: DIMUPT,
DIMATFIT: DIMATFIT,
DIMTXSTY: DIMTXSTY,
DIMLDRBLK: DIMLDRBLK,
DIMLWD: DIMLWD,
DIMLWE: DIMLWE,
DIMFXL: DIMFXL,
DIMJOGANG: DIMJOGANG,
DIMTFILL: DIMTFILL,
DIMTFILLCLR: DIMTFILLCLR,
DIMARCSYM: DIMARCSYM,
DIMCLRD_N: DIMCLRD_N,
DIMCLRE_N: DIMCLRE_N,
DIMCLRT_N: DIMCLRT_N,
DIMFXLON: DIMFXLON,
DIMTXTDIRECTION: DIMTXTDIRECTION,
DIMALTMZF: DIMALTMZF,
DIMALTMZS: DIMALTMZS,
DIMMZF: DIMMZF,
DIMMZS: DIMMZS
};
}
convertLayer(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonTableEntryAttrs(item, obj);
const flag = libredwg.dwg_dynapi_entity_value(item, 'flag').data;
const frozen = libredwg.dwg_dynapi_entity_value(item, 'frozen')
.data;
const off = libredwg.dwg_dynapi_entity_value(item, 'off').data;
const frozenInNew = libredwg.dwg_dynapi_entity_value(item, 'frozen_in_new')
.data;
const locked = libredwg.dwg_dynapi_entity_value(item, 'plotflockedlag')
.data;
const plotFlag = libredwg.dwg_dynapi_entity_value(item, 'plotflag')
.data;
const linewt = libredwg.dwg_dynapi_entity_value(item, 'linewt')
.data;
const color = libredwg.dwg_dynapi_entity_value(item, 'color')
.data;
const ltypeRef = libredwg.dwg_dynapi_entity_value(item, 'ltype')
.data;
let ltypeName = 'Continuous';
if (ltypeRef) {
try {
ltypeName = libredwg.dwg_ref_get_object_name(ltypeRef);
}
catch {
// ref may be invalid in some DWG files
}
}
// - 0xc0 for ByLayer (also c3 and rgb of 0x100)
// - 0xc1 for ByBlock (also c3 and rgb of 0)
// - 0xc2 for entities (default), with names with an additional name flag RC
// - 0xc3 for truecolor
// - 0xc5 for foreground color
// - 0xc8 for none (also c3 and rgb of 0x101)
const method = color.method;
let colorIndex = 256;
let rgbColor = 0xffffff;
// NOTE: Some older DWG formats use method=0x0 and provide the ACI index via color.index.
if (method === 0xc3 || ((color.rgb >>> 24) & 0xff) === 0xc3) {
colorIndex = color.rgb & 0x000000ff;
}
else if (method == 0xc2 || ((color.rgb >>> 24) & 0xff) === 0xc2) {
rgbColor = color.rgb & 0x00ffffff;
}
else if (color.index >= 1 && color.index <= 255) {
// Older DWG format: ACI index is directly available in color.index.
colorIndex = color.index;
}
return {
...commonAttrs,
standardFlag: flag,
colorIndex: colorIndex,
color: rgbColor,
colorName: color.name,
transparency: color.alpha,
lineType: ltypeName,
frozen: frozen != 0,
off: off != 0,
frozenInNew: frozenInNew != 0,
locked: locked != 0,
plotFlag: plotFlag,
lineweight: linewt,
plotStyleNameObjectId: '',
materialObjectId: ''
};
}
convertLineType(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonTableEntryAttrs(item, obj);
const flag = libredwg.dwg_dynapi_entity_value(item, 'flag').data;
const description = libredwg.dwg_dynapi_entity_value(item, 'description')
.data;
const numDashes = libredwg.dwg_dynapi_entity_value(item, 'numdashes')
.data;
const patternLen = libredwg.dwg_dynapi_entity_value(item, 'pattern_len')
.data;
const dashes = libredwg.dwg_dynapi_entity_value(item, 'dashes')
.data;
const dashArray = dashes
? libredwg.dwg_ptr_to_ltype_dash_array(dashes, numDashes)
: [];
return {
...commonAttrs,
description: description,
standardFlag: flag,
numberOfLineTypes: numDashes,
totalPatternLength: patternLen,
pattern: this.convertLineTypePattern(dashArray)
};
}
convertLineTypePattern(dashes) {
const patterns = [];
dashes.forEach(dash => {
patterns.push({
elementLength: dash.length || 0,
elementTypeFlag: dash.complex_shapecode,
shapeNumber: dash.shape_flag,
// TODO: convert style handle to style object id
// styleObjectId: dash.style,
scale: dash.scale,
rotation: dash.rotation,
offsetX: dash.x_offset,
offsetY: dash.y_offset,
text: dash.text
});
});
return patterns;
}
convertStyle(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonTableEntryAttrs(item, obj);
const standardFlag = libredwg.dwg_dynapi_entity_value(item, 'flag')
.data;
const widthFactor = libredwg.dwg_dynapi_entity_value(item, 'width_factor')
.data;
const obliqueAngle = libredwg.dwg_dynapi_entity_value(item, 'oblique_angle')
.data;
const textGenerationFlag = libredwg.dwg_dynapi_entity_value(item, 'generation').data;
const lastHeight = libredwg.dwg_dynapi_entity_value(item, 'last_height')
.data;
const font = libredwg.dwg_dynapi_entity_value(item, 'font_file')
.data;
const bigFont = libredwg.dwg_dynapi_entity_value(item, 'bigfont_file')
.data;
return {
...commonAttrs,
standardFlag: standardFlag,
fixedTextHeight: 0, // TODO: Set the correct value
widthFactor: widthFactor,
obliqueAngle: obliqueAngle,
textGenerationFlag: textGenerationFlag,
lastHeight: lastHeight,
font: font,
bigFont: bigFont
};
}
convertViewport(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonTableEntryAttrs(item, obj);
const standardFlag = libredwg.dwg_dynapi_entity_value(item, 'flag')
.data;
const viewHeight = libredwg.dwg_dynapi_entity_value(item, 'VIEWSIZE')
.data;
const aspectRatio = libredwg.dwg_dynapi_entity_value(item, 'aspect_ratio')
.data;
const center = libredwg.dwg_dynapi_entity_value(item, 'VIEWCTR')
.data;
const viewTarget = libredwg.dwg_dynapi_entity_value(item, 'view_target')
.data;
const viewDirectionFromTarget = libredwg.dwg_dynapi_entity_value(item, 'VIEWDIR').data;
const viewTwistAngle = libredwg.dwg_dynapi_entity_value(item, 'view_twist')
.data;
const lensLength = libredwg.dwg_dynapi_entity_value(item, 'lens_length')
.data;
const frontClippingPlane = libredwg.dwg_dynapi_entity_value(item, 'front_clip_z').data;
const backClippingPlane = libredwg.dwg_dynapi_entity_value(item, 'back_clip_z').data;
const viewMode = libredwg.dwg_dynapi_entity_value(item, 'VIEWMODE')
.data;
const renderMode = libredwg.dwg_dynapi_entity_value(item, 'render_mode')
.data;
const isDefaultLightingOn = libredwg.dwg_dynapi_entity_value(item, 'use_default_lights')
.data != 0;
const defaultLightningType = libredwg.dwg_dynapi_entity_value(item, 'default_lightning_type').data;
const brightness = libredwg.dwg_dynapi_entity_value(item, 'brightness')
.data;
const contrast = libredwg.dwg_dynapi_entity_value(item, 'contrast')
.data;
const ambient_color = libredwg.dwg_dynapi_entity_value(item, 'ambient_color').data;
// ViewportTableRecord
const lowerLeftCorner = libredwg.dwg_dynapi_entity_value(item, 'lower_left')
.data;
const upperRightCorner = libredwg.dwg_dynapi_entity_value(item, 'upper_right').data;
// TODO: Not sure whether 'circleSides' is equal to 'circle_zoom'
const circleSides = libredwg.dwg_dynapi_entity_value(item, 'circle_zoom')
.data;
const ucsIconSetting = libredwg.dwg_dynapi_entity_value(item, 'UCSICON')
.data;
// TODO: Not sure whether 'gridSpacing' is equal to 'GRIDUNIT'
const gridSpacing = libredwg.dwg_dynapi_entity_value(item, 'GRIDUNIT')
.data;
const snapRotationAngle = libredwg.dwg_dynapi_entity_value(item, 'SNAPANG')
.data;
const snapBasePoint = libredwg.dwg_dynapi_entity_value(item, 'SNAPBASE')
.data;
// TODO: Not sure whether 'snapSpacing' is equal to 'SNAPUNIT'
const snapSpacing = libredwg.dwg_dynapi_entity_value(item, 'SNAPUNIT')
.data;
const ucsOrigin = libredwg.dwg_dynapi_entity_value(item, 'ucsorg')
.data;
const ucsXAxis = libredwg.dwg_dynapi_entity_value(item, 'ucsxdir')
.data;
const ucsYAxis = libredwg.dwg_dynapi_entity_value(item, 'ucsydir')
.data;
const elevation = libredwg.dwg_dynapi_entity_value(item, 'ucs_elevation')
.data;
const majorGridLines = libredwg.dwg_dynapi_entity_value(item, 'grid_major')
.data;
const background = libredwg.dwg_dynapi_entity_value(item, 'background')
.data;
const backgroundObjectId = background
? idToString(libredwg.dwg_ref_get_absref(background))
: undefined;
const visualstyle = libredwg.dwg_dynapi_entity_value(item, 'visualstyle')
.data;
const visualStyleObjectId = visualstyle
? idToString(libredwg.dwg_ref_get_absref(visualstyle))
: undefined;
// BITCODE_B UCSFOLLOW;
// BITCODE_B FASTZOOM;
// BITCODE_B GRIDMODE; /* DXF 76: on or off */
// BITCODE_B SNAPMODE; /* DXF 75: on or off */
// BITCODE_B SNAPSTYLE;
// BITCODE_BS SNAPISOPAIR;
// BITCODE_B ucs_at_origin;
// BITCODE_B UCSVP;
// BITCODE_BS UCSORTHOVIEW;
// BITCODE_BS grid_flags; /* bit 1: bound to limits, bit 2: adaptive */
// BITCODE_H sun;
// BITCODE_H named_ucs;
// BITCODE_H base_ucs;
return {
...commonAttrs,
standardFlag: standardFlag,
lowerLeftCorner: lowerLeftCorner,
upperRightCorner: upperRightCorner,
center: center,
snapBasePoint: snapBasePoint,
snapSpacing: snapSpacing,
gridSpacing: gridSpacing,
viewDirectionFromTarget: viewDirectionFromTarget,
viewTarget: viewTarget,
lensLength: lensLength,
frontClippingPlane: frontClippingPlane,
backClippingPlane: backClippingPlane,
viewHeight: viewHeight,
aspectRatio: aspectRatio,
snapRotationAngle: snapRotationAngle,
viewTwistAngle: viewTwistAngle,
circleSides: circleSides,
frozenLayers: [], // TODO: Set the correct value
styleSheet: '', // TODO: Set the correct value
renderMode: renderMode,
viewMode: viewMode,
ucsIconSetting: ucsIconSetting,
ucsOrigin: ucsOrigin,
ucsXAxis: ucsXAxis,
ucsYAxis: ucsYAxis,
orthographicType: 0, // TODO: Set the correct value
elevation: elevation,
shadePlotSetting: 0, // TODO: Set the correct value
majorGridLines: majorGridLines,
backgroundObjectId: backgroundObjectId,
// shadePlotObjectId: undefined,
visualStyleObjectId: visualStyleObjectId,
isDefaultLightingOn: isDefaultLightingOn,
defaultLightingType: defaultLightningType,
brightness: brightness,
contrast: contrast,
// TODO: Not sure whether 'index' or 'rgb' should be used
ambientColor: ambient_color.index
};
}
getCommonTableEntryAttrs(tio, obj) {
const libredwg = this.libredwg;
const object_tio = libredwg.dwg_object_get_tio(obj);
const ownerhandle = libredwg.dwg_object_object_get_ownerhandle_object(object_tio);
const handle = libredwg.dwg_object_get_handle_object(obj);
return {
handle: idToString(handle.value),
ownerHandle: idToString(ownerhandle.absolute_ref),
name: libredwg.dwg_dynapi_entity_value(tio, 'name').data
};
}
convertDictionary(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonObjectAttrs(obj);
const isHardOwner = libredwg.dwg_dynapi_entity_value(item, 'is_hardowner')
.data;
const cloningFlag = libredwg.dwg_dynapi_entity_value(item, 'cloning')
.data;
const numitems = libredwg.dwg_dynapi_entity_value(item, 'numitems')
.data;
const itemhandles_ptr = libredwg.dwg_dynapi_entity_value(item, 'itemhandles').data;
const itemhandles = libredwg.dwg_ptr_to_object_ref_array(itemhandles_ptr, numitems);
const texts = libredwg.dwg_object_dictionary_get_texts(obj);
const entries = {};
itemhandles.forEach((handle, index) => (entries[texts[index]] = idToString(handle.absolute_ref)));
return {
...commonAttrs,
isHardOwner: !!isHardOwner,
cloningFlag: cloningFlag,
entries: entries
};
}
convertImageDef(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonObjectAttrs(obj);
// const classVersion = libredwg.dwg_dynapi_entity_value(item, 'class_version').data as number
const size = libredwg.dwg_dynapi_entity_value(item, 'image_size')
.data;
const fileName = libredwg.dwg_dynapi_entity_value(item, 'file_path')
.data;
const isLoaded = libredwg.dwg_dynapi_entity_value(item, 'is_loaded')
.data;
const sizeOfOnePixel = libredwg.dwg_dynapi_entity_value(item, 'pixel_size')
.data;
const resolutionUnits = libredwg.dwg_dynapi_entity_value(item, 'resunits')
.data;
return {
...commonAttrs,
fileName: fileName,
size: size,
sizeOfOnePixel: sizeOfOnePixel,
isLoaded: isLoaded,
resolutionUnits: resolutionUnits
};
}
convertLayout(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonObjectAttrs(obj);
// AcDbLayout
const layoutName = libredwg.dwg_dynapi_entity_value(item, 'layout_name')
.data;
const tabOrder = libredwg.dwg_dynapi_entity_value(item, 'tab_order')
.data;
const controlFlag = libredwg.dwg_dynapi_entity_value(item, 'layout_flags')
.data;
const insertionPoint = libredwg.dwg_dynapi_entity_value(item, 'INSBASE')
.data;
const minLimit = libredwg.dwg_dynapi_entity_value(item, 'LIMMIN')
.data;
const maxLimit = libredwg.dwg_dynapi_entity_value(item, 'LIMMAX')
.data;
const ucsOrigin = libredwg.dwg_dynapi_entity_value(item, 'UCSORG')
.data;
const ucsXAxis = libredwg.dwg_dynapi_entity_value(item, 'UCSXDIR')
.data;
const ucsYAxis = libredwg.dwg_dynapi_entity_value(item, 'UCSYDIR')
.data;
const orthographicType = libredwg.dwg_dynapi_entity_value(item, 'UCSORTHOVIEW').data;
const minExtent = libredwg.dwg_dynapi_entity_value(item, 'EXTMIN')
.data;
const maxExtent = libredwg.dwg_dynapi_entity_value(item, 'EXTMAX')
.data;
const elevation = libredwg.dwg_dynapi_entity_value(item, 'ucs_elevation')
.data;
const block_header_ref = libredwg.dwg_dynapi_entity_value(item, 'block_header').data;
const paperSpaceTableId = idToString(libredwg.dwg_ref_get_absref(block_header_ref));
const active_viewport_ref = libredwg.dwg_dynapi_entity_value(item, 'active_viewport').data;
const viewportId = idToString(libredwg.dwg_ref_get_absref(active_viewport_ref));
const named_ucs_ref = libredwg.dwg_dynapi_entity_value(item, 'named_ucs')
.data;
const namedUcsId = !!named_ucs_ref
? idToString(libredwg.dwg_ref_get_absref(named_ucs_ref))
: undefined;
// BITCODE_H base_ucs;
// BITCODE_BL num_viewports; // r2004+
// BITCODE_H *viewports; // r2004+
return {
...commonAttrs,
layoutName: layoutName,
controlFlag: controlFlag,
tabOrder: tabOrder,
minLimit: minLimit,
maxLimit: maxLimit,
insertionPoint: insertionPoint,
minExtent: minExtent,
maxExtent: maxExtent,
elevation: elevation,
ucsOrigin: ucsOrigin,
ucsXAxis: ucsXAxis,
ucsYAxis: ucsYAxis,
orthographicType: orthographicType,
paperSpaceTableId: paperSpaceTableId,
viewportId: viewportId,
namedUcsId: namedUcsId,
// orthographicUcsId?: string;
shadePlotId: '' // TODO: Set the correct value
};
}
convertSpatialFilter(item, obj) {
const libredwg = this.libredwg;
const commonAttrs = this.getCommonObjectAttrs(obj);
const origin = libredwg.dwg_dynapi_entity_value(item, 'origin')
.data;
const numberOfPointsOnClipBoundary = libredwg.dwg_dynapi_entity_value(item, 'num_clip_verts').data;
const clip_verts_ptr = libredwg.dwg_dynapi_entity_value(item, 'clip_verts')
.data;
const vertices = libredwg.dwg_ptr_to_point2d_array(clip_verts_ptr, numberOfPointsOnClipBoundary);
const extrusionDirection = libredwg.dwg_dynapi_entity_value(item, 'extrusion').data;
const clipBoundaryVisible = libredwg.dwg_dynapi_entity_value(item, 'display_boundary_on').data;
const frontClippingPlaneFlag = libredwg.dwg_dynapi_entity_value(item, 'front_clip_on').data;
const frontClippingPlaneDistance = libredwg.dwg_dynapi_entity_value(item, 'front_clip_z').data;
const backClippingPlaneFlag = libredwg.dwg_dynapi_entity_value(item, 'back_clip_on').data;
const backClippingPlaneDistance = libredwg.dwg_dynapi_entity_value(item, 'back_clip_z').data;
const transform_ptr = libredwg.dwg_dynapi_entity_value(item, 'transform')
.data;
const matrix = libredwg.dwg_ptr_to_double_array(transform_ptr, 12);
const inverse_transform_ptr = libredwg.dwg_dynapi_entity_value(item, 'inverse_transform').data;
const invertBlockMatrix = libredwg.dwg_ptr_to_double_array(inverse_transform_ptr, 12);
return {
...commonAttrs,
origin: origin,
numberOfPointsOnClipBoundary: numberOfPointsOnClipBoundary,
vertices: vertices,
extrusionDirection: extrusionDirection,
clipBoundaryVisible: !!clipBoundaryVisible,
frontClippingPlaneFlag: !!frontClippingPlaneFlag,
frontClippingPlaneDistance: frontClippingPlaneDistance,
backClippingPlaneFlag: !!backClippingPlaneFlag,
backClippingPlaneDistance: backClippingPlaneDistance,
matrix: matrix,
invertBlockMatrix: invertBlockMatrix
};
}
getCommonObjectAttrs(obj) {
const libredwg = this.libredwg;
const object_tio = libredwg.dwg_object_get_tio(obj);
const ownerhandle = libredwg.dwg_object_object_get_ownerhandle_object(object_tio);
const handle = libredwg.dwg_object_get_handle_object(obj);
return {
handle: idToString(handle.value),
ownerHandle: idToString(ownerhandle.absolute_ref)
};
}
}
//# sourceMappingURL=converter.js.map