首页 > 其他分享 >(pdm集成CAD SDK)在线CAD绘制条形码、二维码的教程

(pdm集成CAD SDK)在线CAD绘制条形码、二维码的教程

时间:2025-01-18 15:43:17浏览次数:1  
标签:条形码 return val pdm position const CAD public SDK

一、条形码绘制

1. 原理

绘制条形码需要根据不同的应用场景选择适当的条形码标准,如常见的 codabar 、CODE30、CODE128等,每一种条形码标准都有它特定的数据编码规则,调用这些编码规则进行数据编码时会将数据字符按照所选编码规则转换成条和空的组合(一组二进制数据)。不同的条形码标准使用不同的编码规则来表示0到9的数字或26个英文字母。

其中,为了确保扫描的准确性,条形码中还包括一个校验字符。这个字符通过特定的算法计算得出,用于检验整个条形码的准确性。在生成目标条形码时需对目标内容进行校验,若目标内容符合条形码的编码要求则再进行下一步的绘制。

2. mxcad实现绘制条形码

根据上述条形码绘制原理可知,只要我们能够知道条形码的编码规则将条形码内容转换为一串二进制数据并根据二进制数据的具体值确定条形码条、空的组合,我们就可以在 mxcad 中通过[填充实体McDbHatch]绘制出条形码。为方便后续对条形码的管理和扩展,我们可以将其绘制为[自定义实体McDbCustomEntity]并为其添加自定义属性。

1)条形码编码规则编写,下面以 CODE39 为例:

class Barcode{
    constructor(data, options){
        this.data = data;
        this.text = options.text || data;
        this.options = options;
    }
}
class CODE39 extends Barcode {
    constructor(data, options){
        data = data.toUpperCase();
        // Calculate mod43 checksum if enabled
        if(options.mod43){
            data += getCharacter(mod43checksum(data));
        }
        super(data, options);
    }
    encode(){
        // First character is always a *
        var result = getEncoding("*");
        // Take every character and add the binary representation to the result
        for(let i = 0; i < this.data.length; i++){
            result += getEncoding(this.data[i]) + "0";
        }
        // Last character is always a *
        result += getEncoding("*");
        return {
            data: result,
            text: this.text
        };
    }
    valid(){
        return this.data.search(/^[0-9A-Z\-\.\ \$\/\+\%]+$/) !== -1;
    }
}
// All characters. The position in the array is the (checksum) value
var characters = [
    "0", "1", "2", "3",
    "4", "5", "6", "7",
    "8", "9", "A", "B",
    "C", "D", "E", "F",
    "G", "H", "I", "J",
    "K", "L", "M", "N",
    "O", "P", "Q", "R",
    "S", "T", "U", "V",
    "W", "X", "Y", "Z",
    "-", ".", " ", "$",
    "/", "+", "%", "*"
];
// The decimal representation of the characters, is converted to the
// corresponding binary with the getEncoding function
var encodings = [
    20957, 29783, 23639, 30485,
    20951, 29813, 23669, 20855,
    29789, 23645, 29975, 23831,
    30533, 22295, 30149, 24005,
    21623, 29981, 23837, 22301,
    30023, 23879, 30545, 22343,
    30161, 24017, 21959, 30065,
    23921, 22385, 29015, 18263,
    29141, 17879, 29045, 18293,
    17783, 29021, 18269, 17477,
    17489, 17681, 20753, 35770
];
// Get the binary representation of a character by converting the encodings
// from decimal to binary
function getEncoding(character){
    return getBinary(characterValue(character));
}
function getBinary(characterValue){
    return encodings[characterValue].toString(2);
}
function getCharacter(characterValue){
    return characters[characterValue];
}
function characterValue(character){
    return characters.indexOf(character);
}
function mod43checksum(data){
    var checksum = 0;
    for(let i = 0; i < data.length; i++){
        checksum += characterValue(data[i]);
    }
    checksum = checksum % 43;
    return checksum;
}
export {CODE39};

更多编码规则可参考开源条形码js库JsBarCode

2) 实现自定义实体

import { McGeVector3d, McDbHatch, McGePoint3d, McGePoint3dArray, McDbCustomEntity, IMcDbDwgFiler, MxCADWorldDraw, McDbEntity, McDbText, McDb, MxCpp, McGeMatrix3d } from 'mxcad';
import Barcode from './';// 引入条形码类型
// 自定义条形码
class McDbTestBarCode extends McDbCustomEntity {
    /** 条形码位置 */
    private position: McGePoint3d = new McGePoint3d();
    /** 字高  */
    private textHeight: number = 120;
    /** 条形码信息文字 */
    private text: string = '';
    // 条形码高度
    private codeHeight: number = 300;
    // 条形码宽度
    private codeWidth: number = 10;
    // 条形码类型
    private codeType: string = 'CODE39';
    // 条形码内容设置
    private codeContent: string = 'ABCDEFG';
    // 是否显示条形码文字内容
    private showText: boolean = false;
    constructor(imp?: any) {
        super(imp);
    }
    public create(imp: any) {
        return new McDbTestBarCode(imp)
    }
    /** 获取类名 */
    public getTypeName(): string {
        return "McDbTestBarCode";
    }
    //设置或获取基点
    public set barCodePos(val: McGePoint3d) {
        this.position = val.clone();
    }
    public get barCodePos(): McGePoint3d {
        return this.position;
    }
    //设置或获取条形码文字
    public set barCodeText(val: string) {
        this.text = val;
    }
    public get barCodeText(): string {
        return this.text;
    }
    //设置或获取条形码高度
    public set barCodeHeight(val: number) {
        this.codeHeight = val;
    }
    public get barCodeHeight(): number {
        return this.codeHeight;
    }
    //设置或获取条形码类型
    public set barCodeType(val: string) {
        this.codeType = val;
    }
    public get barCodeType(): string {
        return this.codeType;
    }
    //设置或获取条形码宽度
    public set barCodeWidth(val: number) {
        this.codeWidth = val;
    }
    public get barCodeWidth(): number {
        return this.codeWidth;
    }
    // 设置或获取条形码文字高度
    public set barCodeTextHeight(val: number) {
        this.textHeight = val;
    }
    public get barCodeHeigth(): number {
        return this.textHeight;
    }
    // 设置或获取是否显示条形码文字内容
    public set barCodeShowText(val: boolean) {
        this.showText = val;
    }
    public get barCodeShowText(): boolean {
        return this.showText;
    }
    // 设置或获取条形码文字内容
    public set barCodeContent(val: string) {
        this.codeContent = val;
    }
    public get barCodeContent(): string {
        return this.codeContent;
    }
    /** 读取数据 */
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.position = filter.readPoint("position").val;
        this.codeWidth = filter.readDouble("codeWidth").val;
        this.codeHeight = filter.readDouble("codeHeight").val;
        this.textHeight = filter.readDouble("textHeight").val;
        this.text = filter.readString("text").val;
        this.codeType = filter.readString("codeType").val;
        this.codeContent = filter.readString("codeContent").val;
        const isShowText = filter.readLong("showText").val;
        this.showText = isShowText ? true : false;
        return true;
    }
    /** 写入数据 */
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("position", this.position);
        filter.writeDouble("codeWidth", this.codeWidth);
        filter.writeDouble("codeHeight", this.codeHeight);
        filter.writeString("text", this.text);
        filter.writeDouble("textHeight", this.textHeight);
        filter.writeString("codeType", this.codeType);
        filter.writeString("codeContent", this.codeContent);
        const isShowText = this.showText ? 1 : 0;
        filter.writeLong("showText", isShowText);
        return true;
    }
    /** 移动夹点 */
    public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
        this.assertWrite();
        if (iIndex === 0) {
            this.position.x += dXOffset;
            this.position.y += dYOffset;
            this.position.z += dZOffset;
        }
    };
    /** 获取夹点 */
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray();
        ret.append(this.position);
        return ret;
    };
    /** 动态绘制 */
    public worldDraw(draw: MxCADWorldDraw): void {
        const code = new Barcode[this.codeType](this.codeContent, {flat: true});
        if (!code.valid()) return alert('条形码类型与内容不匹配!请重新设置!');
        let encoded = code.encode();
        const v = McGeVector3d.kYAxis.clone().mult(this.codeHeight);
        const _v = McGeVector3d.kXAxis.clone().mult(this.codeWidth);
        encoded.data.split('').forEach((val, index) => {
            const solid = new McDbHatch();
            const point1 = new McGePoint3d(this.position.x + index * this.codeWidth, this.position.y, this.position.z);
            const point2 = point1.clone().addvec(v);
            const point3 = point2.clone().addvec(_v);
            const point4 = point1.clone().addvec(_v);
            const points = new McGePoint3dArray([point1, point2, point3, point4]);
            solid.appendLoop(points);
            if (val == '1') {
                draw.drawEntity(solid);
            }
        })
        if (this.showText) {
            const text = this.getCodeText();
            draw.drawEntity(text);
        }
    };
    // 设置条形码文字实体
    private getCodeText(): McDbEntity {
        if (!this.text) this.text = this.codeContent;
        const text = new McDbText();
        text.textString = this.text;
        text.height = this.textHeight;
        const v = McGeVector3d.kYAxis.clone().negate().mult(this.textHeight * (4 / 3));
        text.position = text.alignmentPoint = this.position.clone().addvec(v);
        text.horizontalMode = McDb.TextHorzMode.kTextLeft;
        return text
    }
    // 编辑变换
    public transformBy(_mat: McGeMatrix3d): boolean {
        this.position.transformBy(_mat);
        return true;
    }
}

3)调用条形码自定义实体McDbTestBarCode绘制条形码

async function Mx_drawBarCode() {
    const mxcad = MxCpp.getCurrentMxCAD();
    mxcad.newFile();
    mxcad.setViewBackgroundColor(255, 255, 255);
    // CODE39 类型条形码
    const barCode = new McDbTestBarCode();
    barCode.barCodePos = new McGePoint3d(100, 100, 0);
    barCode.barCodeShowText = true;
    mxcad.drawEntity(barCode);
    // CODE128 类型条形码
    const barCode2 = new McDbTestBarCode();
    barCode2.barCodeContent = 'A little test!';
    barCode2.barCodeType = 'CODE128';
    barCode2.barCodePos = new McGePoint3d(-2000, 100, 0);
    barCode2.barCodeShowText = true;
    mxcad.drawEntity(barCode2);
    // EAN13 类型条形码
    const barCode3 = new McDbTestBarCode();
    barCode3.barCodeContent = '5901234123457';
    barCode3.barCodeType = 'EAN13';
    barCode3.barCodePos = new McGePoint3d(-2000, -800, 0);
    barCode3.barCodeShowText = true;
    mxcad.drawEntity(barCode3);
    // codabar 类型条形码
    const barCode4 = new McDbTestBarCode();
    barCode4.barCodeContent = 'C1234567890D';
    barCode4.barCodeType = 'codabar';
    barCode4.barCodePos = new McGePoint3d(100, -800, 0);
    barCode4.barCodeShowText = true;
    mxcad.drawEntity(barCode4);
    mxcad.zoomAll();
    mxcad.zoomScale(4);
}

4) 绘制效果演示:

 

二、绘制二维码

1.原理

二维码是一种矩阵式二维条码,它能在水平和垂直两个方向上存储信息。二维码中的原始数据可以是数字、字母、二进制数据或其他字符‌,根据原始数据的类型,选择合适的编码模式。例如,数字数据使用数字模式,字母和数字混合使用alphanumeric模式,其他类型的数据则使用字节模式‌。

原始数据经过编码后的数据将放入一个二维矩阵中。这个过程可能需要使用掩模技术,通过应用特定的掩模图案来优化二维码中的黑白点的分布,避免出现与定位标记相似的模式‌,其中, 需要在矩阵的特定区域添加格式化和版本信息,以及必要时添加校正标记‌。

2.mxcad 实现绘制二维码

二维码的编码规则我们可以直接借助二维码开源js库QRCode.js ,更多详细内容看参考:https://github.com/davidshimjs/qrcodejs

结合QRcode.js ,我们可以在mxcad中通过[填充实体McDbHatch]绘制出二维矩阵中的黑白块。为方便后续对二维码的管理和扩展,我们可以将其绘制为[自定义实体McDbCustomEntity]并为其添加自定义属性。

1)QRcode.js扩写:

// 增加 QRCode类的 makeMxcadCode 方法
QRCode.prototype.makeMxcadCode = function (sText) {
        this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
        this._oQRCode.addData(sText);
        this._oQRCode.make();
        return this._oDrawing.drawMxcadHatch(this._oQRCode);
    };

 绘制mxcad填充代码:

// 绘制mxcad填充代码(扩写Drawing类)
Drawing.prototype.drawMxcadHatch = function (oQRCode): McDbEntity[] {
    const entityArr = [];
    var _htOption = this._htOption;
    var nCount = oQRCode.getModuleCount();
    var nWidth = _htOption.width / nCount;
    var nHeight = _htOption.height / nCount;
    for (var row = 0; row < nCount; row++) {
        for (var col = 0; col < nCount; col++) {
            var bIsDark = oQRCode.isDark(row, col);
            var nLeft = col * nWidth;
            var nTop = row * nHeight;
            if (bIsDark) {
                // 矩形填充
                const pos = new McGePoint3d(nLeft, nTop, 0);
                const v_y = McGeVector3d.kYAxis.clone().negate().mult(nHeight);
                const v_x = McGeVector3d.kXAxis.clone().mult(nWidth);
                const pos1 = pos.clone().addvec(v_y);
                const pos2 = pos.clone().addvec(v_x);
                const pos3 = pos.clone().addvec(v_x).addvec(v_y);
                const solid = new McDbHatch();
                const ptArr = new McGePoint3dArray([pos, pos1, pos3, pos2]);
                solid.appendLoop(ptArr);
                entityArr.push(solid);
            }
        }
    }
    return entityArr;
};

2)实现自定义实体

import { MxCpp, McDbCustomEntity, McGePoint3d, IMcDbDwgFiler, McGePoint3dArray, MxCADWorldDraw, McGeMatrix3d, McDbEntity } from "mxcad";
import { QRCode } from './qrCode'
// 自定义二维码实体
class McDbTestQrCode extends McDbCustomEntity {
    /** 二维码的位置 */
    private position: McGePoint3d = new McGePoint3d();
    // 二维码高度
    private codeHeight: number = 300;
    // 二维码宽度
    private codeWidth: number = 10;
    // 二维码内容设置
    private codeContent: string = 'https://demo.mxdraw3d.com:3000/mxcad/';
    constructor(imp?: any) {
        super(imp);
    }
    public create(imp: any) {
        return new McDbTestQrCode(imp)
    }
    /** 获取类名 */
    public getTypeName(): string {
        return "McDbTestQrCode";
    }
    //设置或获取基点
    public set qrCodePos(val: McGePoint3d) {
        this.position = val.clone();
    }
    public get qrCodePos(): McGePoint3d {
        return this.position;
    }
    //设置或获取码高度
    public set qrCodeHeight(val: number) {
        this.codeHeight = val;
    }
    public get qarCodeHeight(): number {
        return this.codeHeight;
    }
    //设置或获取码宽度
    public set qrCodeWidth(val: number) {
        this.codeWidth = val;
    }
    public get qrCodeWidth(): number {
        return this.codeWidth;
    }
    // 设置或获取二维码内容
    public set qrCodeContent(val: string) {
        this.codeContent = val;
    }
    public get qrCodeContent(): string {
        return this.codeContent;
    }
    /** 读取数据 */
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.position = filter.readPoint("position").val;
        this.codeWidth = filter.readDouble("codeWidth").val;
        this.codeHeight = filter.readDouble("codeHeight").val;
        this.codeContent = filter.readString("codeContent").val;
        return true;
    }
    /** 写入数据 */
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("position", this.position);
        filter.writeDouble("codeWidth", this.codeWidth);
        filter.writeDouble("codeHeight", this.codeHeight);
        filter.writeString("codeContent", this.codeContent);
        return true;
    }
    /** 移动夹点 */
    public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
        this.assertWrite();
        if (iIndex === 0) {
            this.position.x += dXOffset;
            this.position.y += dYOffset;
            this.position.z += dZOffset;
        }
    };
    /** 获取夹点 */
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray();
        ret.append(this.position);
        return ret;
    };
    /** 动态绘制 */
    public worldDraw(draw: MxCADWorldDraw): void {
        const qrcode = new QRCode('', {
            width: this.codeWidth,
            height: this.codeHeight
        });
        const objArr = qrcode.makeMxcadCode(this.codeContent);
        objArr.forEach((obj: McDbEntity) => {
            const entity = obj.clone() as McDbEntity;
            entity.move(new McGePoint3d(0, 0, 0), this.position);
            draw.drawEntity(entity);
        })
    };
    // 编辑变换
    public transformBy(_mat: McGeMatrix3d): boolean {
        this.position.transformBy(_mat);
        return true;
    }
}

3)调用二维码自定义实体McDbTestQrCode绘制二维码:

//画二维码
async function Mx_drawQrCode() {
    const mxcad = MxCpp.getCurrentMxCAD();
    mxcad.newFile();
    const qrcode = new McDbTestQrCode();
    qrcode.qrCodePos = new McGePoint3d(1000, 1000, 0);
    qrcode.qrCodeContent = 'https://demo.mxdraw3d.com:3000/mxcad/';
    qrcode.qrCodeWidth = 1500;
    qrcode.qrCodeHeight = 1500;
    mxcad.drawEntity(qrcode);
    mxcad.zoomAll();
};

4) 绘制效果演示:

 

标签:条形码,return,val,pdm,position,const,CAD,public,SDK
From: https://www.cnblogs.com/yzy0224/p/18678509

相关文章

  • Zalo SDK集成指南
    配置部分1.官方sdk链接 https://developers.zalo.me/docs/sdk/android-sdk/tong-quan2.zalosdk主要提供的功能集成zalo登录获取用户信息,朋友列表支持android4.3及以上3.demo链接 https://gitlab.com/zalosdk/repositories集成步骤第一步:去Zolo后台创建应用  http:/......
  • cad.net CurveInfo类
    曲线信息类主要是缓存一层包围盒1,存档曲线Curve2,复合曲线CompositeCurve3d3,单元曲线Curve3d验证包围盒在这里:https://www.cnblogs.com/JJBox/p/18677417publicclassCurveInfo:DRect{publicintRegionColor=0;//染色:斜区0,横区1,竖区2publicMyGro......
  • go项目zero中自定义sdk的引用与使用规范
    在Go项目中,`gomodtidy`命令会自动删除没有直接引用的依赖。如果你的项目中某个SDK被引用但是没有在业务代码中直接使用,`gomodtidy`可能会将其清理掉,因为它被认为是"未使用"的依赖。如果你希望保留这些依赖(例如某些SDK),可以采取以下几种方法:###1.显式调用SDK中......
  • 【韩国汉阳大学主办】第六届土木建筑及灾害防控国际学术会议暨第三届智慧城市建筑与基
    第六届土木建筑及灾害防控国际学术会议暨第三届智慧城市建筑与基础设施耐久性国际学术会议(CADPC&DuraBI2025)20256thInternationalConferenceonCivil,ArchitectureandDisasterPreventionandControl&3rdInternationalConferenceonDurabilityofBuildinga......
  • 使用 wx-server-sdk
    在云函数中使用wx-server-sdk云函数属于管理端,在云函数中运行的代码拥有不受限的数据库读写权限和云文件读写权限。需特别注意,云函数运行环境即是管理端,与云函数中的传入的openId对应的微信用户是否是小程序的管理员/开发者无关。云函数中使用wx-server-sdk需在对应云函......
  • Bartender SDK C#调用二次开发 代码示例
    说明软件版本:Bartender2022是否支持32位:否SDK类型:Engine类调用(还有另一种风格的SDK,忘记是啥了)引用COM库参考路径:Seagull\BarTender2022\SDK\Assemblies\Seagull.BarTender.Print.dll可能只能用framework4.8跑启动引擎//启动引擎(第一次运行耗时较多)EnginebtEngine=......
  • caddy的用法 小型静态服务器
    caddy的用法小型静态服务器欢迎使用Caddy安装Caddy的各种方法快速入门使用API使用Caddyfile静态文件命令行......
  • c++&& SDK打包过程
     在C++中,SDK(SoftwareDevelopmentKit)打包工具的选择和使用通常取决于您的具体需求和目标平台。以下是一个详细的步骤描述,用于创建和打包一个C++SDK。这里我们假设您已经有一个C++项目需要打包为SDK。步骤一:准备你的C++项目项目结构规划:确定你的SDK包含哪些功能,比如源代......
  • 【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit(4)
    1.问题描述:添加了很多的marker点,每个marker点都设置了customInfoWindow,但是每次只能显示一个customInfoWindow吗?解决方案:Marker的InfoWindow每次只能显示一个。2.问题描述:在地图选型中,1.使用华为MapKit,和使用高德、腾讯等SDK上,有什么优缺点比较吗?2.MapKit是否需要商业授......
  • zenoh flow python sdk 简单说明
    zenohflow是zenoh团队提供的面向dataflow的编程框架,可以提供灵活的进行数据处理,zenohflow提供了基于rust以及python的扩展能力,我们只需要进行flow的yaml定义就可以灵活的进行数据处理,基于rust的开发模式可能比较费事,而且有难度,zenoh-flow-python是基于python快速开发......