chili3d 笔记17 c++ 编译hlr 带隐藏线工程图

news2025/6/8 6:42:53

这个要注册不然emscripten编译不起来

---------------


行不通


----------------



结构体

 using LineSegment = std::pair<gp_Pnt, gp_Pnt>;
    using LineSegmentList = std::vector<LineSegment>;
EMSCRIPTEN_BINDINGS(Shape_Projection) {
    value_object<LineSegment>("LineSegment")
        .field("first", &LineSegment::first)
        .field("second", &LineSegment::second);

    // 绑定 LineSegmentList (std::vector<LineSegment>)
    register_vector<LineSegment>("LineSegmentList");
    class_<ProjectionResult>("ProjectionResult")
    .property("visible", &ProjectionResult::visible)
    .property("hidden", &ProjectionResult::hidden);
    class_<ShapeProjection>("ShapeProjection")
        .class_function("projection", &ShapeProjection::GetProjectionEdges);


    
  
}

 


printf无效,要用cout

deepwiki写occ代码真的强

视图偏移还有点问题

import { IApplication, Logger, PubSub, ShapeNode } from "chili-core";
import { getProjectionEdges, gp_Pnt, LineSegmentList, OccShape, ProjectionResult2 } from "chili-wasm";


interface Segment {
    first: gp_Pnt;
    second: gp_Pnt;
}



export class njsgcs_drawingView extends HTMLElement {
    private viewportCanvas2d: HTMLCanvasElement | null = null;
    private app: IApplication | null = null;
  
    constructor() {
        super();
        PubSub.default.sub("njsgcs_drawview", async (app: IApplication) => {
            Logger.info("njsgcs_drawview event triggered");
            if (this.viewportCanvas2d) {
                this.removeChild(this.viewportCanvas2d);
                this.viewportCanvas2d = null;
            }

           

            this.app = app;
            const canvas = this.createCanvas();
            this.appendChild(canvas);
        });
    }
    private drawProjectionEdges(ctx: CanvasRenderingContext2D, projection: ProjectionResult2) {
        // 清除画布
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    
        // 获取所有线段并合并用于自动缩放计算
        const allSegments = [
            ...this.toArray(projection.f_visible),
            ...this.toArray(projection.f_hidden),
            ...this.toArray(projection.s_visible),
            ...this.toArray(projection.s_hidden),
            ...this.toArray(projection.t_visible),
            ...this.toArray(projection.t_hidden),
        ];
    
        // 自动计算缩放和偏移
        const { minX, maxX, minY, maxY } = this.calculateBounds(allSegments);
        const margin = 50;
        const availableWidth = ctx.canvas.width - 2 * margin;
        const availableHeight = ctx.canvas.height - 2 * margin;
    
        const scaleX = availableWidth / (maxX - minX || 1);
        const scaleY = availableHeight / (maxY - minY || 1);
        const scale = Math.min(scaleX, scaleY) * 0.9; // 留点边距
        const offsetX = ctx.canvas.width / 2;
        const offsetY = ctx.canvas.height / 2;
    
        // 定义各视图偏移
        const views = [
            {
                name: 'front',
                segmentsVisible: this.toArray(projection.f_visible),
                segmentsHidden: this.toArray(projection.f_hidden),
                offset: { x: -availableWidth / 3, y: 0 },
            },
            {
                name: 'side',
                segmentsVisible: this.toArray(projection.s_visible),
                segmentsHidden: this.toArray(projection.s_hidden),
                offset: { x: 0, y: 0 },
            },
            {
                name: 'top',
                segmentsVisible: this.toArray(projection.t_visible),
                segmentsHidden: this.toArray(projection.t_hidden),
                offset: { x: availableWidth / 3, y: 0 },
            },
        ];
    
        // 绘制每个视图
        for (const view of views) {
            // 实线:可见线
            this.drawSegments(
                ctx,
                view.segmentsVisible,
                false,
                scale,
                offsetX + view.offset.x,
                offsetY + view.offset.y
            );
    
            // 虚线:隐藏线
            this.drawSegments(
                ctx,
                view.segmentsHidden,
                true,
                scale,
                offsetX + view.offset.x,
                offsetY + view.offset.y
            );
        }
    }  
    private calculateBounds(segments: Segment[]) {
        let minX = Infinity;
        let maxX = -Infinity;
        let minY = Infinity;
        let maxY = -Infinity;
    
        for (const segment of segments) {
            if (segment && segment.first && segment.second) {
                const points = [segment.first, segment.second];
                for (const p of points) {
                    minX = Math.min(minX, p.x);
                    maxX = Math.max(maxX, p.x);
                    minY = Math.min(minY, p.y);
                    maxY = Math.max(maxY, p.y);
                }
            }
        }
    
        return {
            minX: minX === Infinity ? 0 : minX,
            maxX: maxX === -Infinity ? 0 : maxX,
            minY: minY === Infinity ? 0 : minY,
            maxY: maxY === -Infinity ? 0 : maxY,
        };
    }
    private drawSegments(
        ctx: CanvasRenderingContext2D,
        segments: Segment[],
        isHidden: boolean,
        scale: number,
        offsetX: number,
        offsetY: number
    ) {
        ctx.strokeStyle = isHidden ? "gray" : "black";
        ctx.lineWidth = isHidden ? 1 : 2;
        ctx.setLineDash(isHidden ? [5, 5] : []);
    
        for (const segment of segments) {
            if (segment && segment.first && segment.second) {
                ctx.beginPath();
                ctx.moveTo(
                    segment.first.x * scale + offsetX,
                    -segment.first.y * scale + offsetY
                );
                ctx.lineTo(
                    segment.second.x * scale + offsetX,
                    -segment.second.y * scale + offsetY
                );
                ctx.stroke();
            }
        }
    }
    private toArray(segmentList: LineSegmentList): Segment[] {
        const result = [];
        for (let i = 0; i < segmentList.size(); i++) {
            const segment = segmentList.get(i);
        if (segment) {
            result.push(segment);
        }
        }
        return result;
    }
    private createCanvas(): HTMLCanvasElement {
        if (!this.viewportCanvas2d) {
            this.viewportCanvas2d = document.createElement("canvas");
            this.viewportCanvas2d.width = 900;
            this.viewportCanvas2d.height = 600;
            this.viewportCanvas2d.style.border = "1px solid #000";

            const ctx = this.viewportCanvas2d.getContext("2d");
            if (ctx) {
                const document = this.app!.activeView?.document;
                if (!document) return this.viewportCanvas2d;

                const geometries = document.selection.getSelectedNodes();
                const entities = geometries.filter((x) => x instanceof ShapeNode);
                for (const entity of entities) {
                    const shapeResult = entity.shape;
                    if (shapeResult.isOk) {
                        const shape = shapeResult.value; // 获取IShape  

                        // 检查是否为OccShape实例  
                        if (shape instanceof OccShape) {
                            const topoShape = shape.shape; // 访问TopoDS_Shape  
                            const ProjectionEdges=getProjectionEdges(topoShape);
                            this.drawProjectionEdges(ctx,ProjectionEdges)
                        }

                    }
                }
            }
        }
        return this.viewportCanvas2d!;
    }





}

customElements.define("njsgcs-drawing-view", njsgcs_drawingView);
import { LineSegmentList, TopoDS_Shape } from "../lib/chili-wasm";
export { LineSegmentList, ProjectionResult2 };
interface ProjectionResult2 {
    f_visible:LineSegmentList ,
    f_hidden: LineSegmentList ,
    s_visible: LineSegmentList ,
    s_hidden: LineSegmentList ,
    t_visible: LineSegmentList ,
    t_hidden:LineSegmentList ,

}
export function getProjectionEdges(
    shape: TopoDS_Shape,
   
): { f_visible: LineSegmentList; f_hidden: LineSegmentList,s_visible: LineSegmentList; s_hidden: LineSegmentList,t_visible: LineSegmentList; t_hidden: LineSegmentList} {
    console.info("test1");
    const f_result = wasm.ShapeProjection.projection(shape, new wasm.gp_Dir(0, 1, 0));
    console.info("first:"+f_result.visible.get(0)?.first);
    const s_result = wasm.ShapeProjection.projection(shape, new wasm.gp_Dir( 1,0, 0));
    const t_result = wasm.ShapeProjection.projection(shape, new wasm.gp_Dir( 0, 0,1));
   
    return {
        f_visible: f_result.visible,
        f_hidden: f_result.hidden,
        s_visible: s_result.visible,
        s_hidden: s_result.hidden,
        t_visible: t_result.visible,
        t_hidden: t_result.hidden,

    };
}
#include <BRepPrimAPI_MakeBox.hxx>  
#include <BRepPrimAPI_MakeCylinder.hxx>  
#include <BRepAlgoAPI_Cut.hxx>  
#include <gp_Pnt.hxx>  
#include <gp_Dir.hxx>  
#include <gp_Ax2.hxx>  
#include <HLRBRep_Algo.hxx>  
#include <HLRBRep_HLRToShape.hxx>  
#include <HLRAlgo_Projector.hxx>  
#include <BRepAdaptor_Curve.hxx>  
#include <GCPnts_UniformDeflection.hxx>  
#include <TopExp_Explorer.hxx>  
#include <TopoDS.hxx>  
#include <vector>  
#include <emscripten/bind.h>
#include <tuple>
#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Edge.hxx>
#include <Geom_Line.hxx>
using namespace emscripten;
std::vector<std::pair<gp_Pnt, gp_Pnt>> ExtractLineSegments(const TopoDS_Shape& shape) {  
    std::vector<std::pair<gp_Pnt, gp_Pnt>> lineSegments;  
      
    for (TopExp_Explorer edgeExplorer(shape, TopAbs_EDGE); edgeExplorer.More(); edgeExplorer.Next()) {  
        TopoDS_Edge edge = TopoDS::Edge(edgeExplorer.Current());  
          
        // 优先使用顶点方法  
        TopoDS_Vertex aFirst, aLast;  
        TopExp::Vertices(edge, aFirst, aLast, Standard_True);  
          
        if (!aFirst.IsNull() && !aLast.IsNull()) {  
            gp_Pnt startPnt = BRep_Tool::Pnt(aFirst);  
            gp_Pnt endPnt = BRep_Tool::Pnt(aLast);  
            lineSegments.emplace_back(startPnt, endPnt);  
            //std::cout << "startPnt: X=" << startPnt.X() << " Y=" << startPnt.Y() << " Z=" << startPnt.Z() << std::endl;
        } 
    }  
      
    return lineSegments;  
}
// Convert 3D edge to 2D points  
struct ProjectionResult {
    std::vector<std::pair<gp_Pnt, gp_Pnt>> visible;
    std::vector<std::pair<gp_Pnt, gp_Pnt>> hidden;
    ProjectionResult(
        const std::vector<std::pair<gp_Pnt, gp_Pnt>>& vis,
        const std::vector<std::pair<gp_Pnt, gp_Pnt>>& hid
    ) : visible(vis), hidden(hid) {}
};

class ShapeProjection {  
    public:  
      
    static ProjectionResult GetProjectionEdges(const TopoDS_Shape& shape, const gp_Dir& direction) {  
        // Create projector  
        
        gp_Ax3 viewAxis(gp_Pnt(0, 0, 0), direction);  
        gp_Trsf transformation;  
        transformation.SetTransformation(viewAxis);  
        HLRAlgo_Projector projector(transformation, Standard_False, 0.0);
          
        // Create HLR algorithm  
        Handle(HLRBRep_Algo) hlr_algo = new HLRBRep_Algo();  
        hlr_algo->Add(shape);  
        hlr_algo->Projector(projector);  
        hlr_algo->Update();  
        hlr_algo->Hide();  
          
        // Extract visible and hidden edges  
        HLRBRep_HLRToShape hlr_to_shape(hlr_algo);  
        TopoDS_Shape visible_edges = hlr_to_shape.VCompound();  
        TopoDS_Shape hidden_edges = hlr_to_shape.HCompound();  
        auto visible_line_segments = ExtractLineSegments(visible_edges);
    auto hidden_line_segments = ExtractLineSegments(hidden_edges);  
    
    return ProjectionResult(visible_line_segments, hidden_line_segments); 
    }  
    };  
    using LineSegment = std::pair<gp_Pnt, gp_Pnt>;
    using LineSegmentList = std::vector<LineSegment>;
EMSCRIPTEN_BINDINGS(Shape_Projection) {
    value_object<LineSegment>("LineSegment")
        .field("first", &LineSegment::first)
        .field("second", &LineSegment::second);

    
    register_vector<LineSegment>("LineSegmentList");
    class_<ProjectionResult>("ProjectionResult")
    .property("visible", &ProjectionResult::visible)
    .property("hidden", &ProjectionResult::hidden);
    class_<ShapeProjection>("ShapeProjection")
        .class_function("projection", &ShapeProjection::GetProjectionEdges);


    
  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2403832.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

创建一个纯直线组成的字体库

纯直线组成的字体&#xff0c;一个“却”由五组坐标点组成&#xff0c;存储5个点共占21字节&#xff0c;使用简单&#xff0c;只要画直线即可&#xff0c; “微软雅黑”&#xff0c;2个轮廓&#xff0c;55坐标点&#xff0c;使用复杂&#xff0c;还填充。 自创直线字体 “微软…

Linux进程(中)

目录 进程等待 为什么有进程等待 什么是进程等待 怎么做到进程等待 wait waitpid 进程等待 为什么有进程等待 僵尸进程无法杀死&#xff0c;需要进程等待来消灭他&#xff0c;进而解决内存泄漏问题--必须解决的 我们要通过进程等待&#xff0c;获得子进程退出情况--知…

【计算机组成原理】计算机硬件的基本组成、详细结构、工作原理

引言 计算机如同现代科技的“大脑”&#xff0c;其硬件结构的设计逻辑承载着信息处理的核心奥秘。从早期程序员手动输入指令的低效操作&#xff0c;到冯诺依曼提出“存储程序”概念引发的革命性突破&#xff0c;计算机硬件经历了从机械操控到自动化逻辑的蜕变。本文将深入拆解…

MVC分层架构模式深入剖析

&#x1f504; MVC 交互流程 #mermaid-svg-5xGt0Ka13DviDk15 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5xGt0Ka13DviDk15 .error-icon{fill:#552222;}#mermaid-svg-5xGt0Ka13DviDk15 .error-text{fill:#552222…

新能源汽车热管理核心技术解析:冬季续航提升40%的行业方案

新能源汽车热管理核心技术解析&#xff1a;冬季续航提升40%的行业方案 摘要&#xff1a;突破续航焦虑的关键在热能循环&#xff01; &#x1f449; 本文耗时72小时梳理行业前沿方案&#xff0c;含特斯拉/比亚迪等8家车企热管理系统原理图 一、热管理为何成新能源车决胜关键&am…

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1开通指南及使用心得

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年CSDN全站排名top 28。 &#x1f3c6;数年电商行业从业经验&#xff0c;AWS/阿里云资深使用用…

运行示例程序和一些基本操作

欢迎 ----> 示例 --> 选择sample CTRL B 编译代码 CTRL R 运行exe 项目 中 Shadow build 表示是否 编译生成文件和 源码是否放一块 勾上不在同一个地方 已有项目情况下怎么打开项目 方法一: 左键双击 xxx.pro 方法二: 文件菜单里面 选择打开项目

学习数字孪生,为你的职业发展开辟新赛道

你有没有想过&#xff0c;未来十年哪些技能最吃香&#xff1f; AI、大数据、智能制造、元宇宙……这些词频繁出现在招聘市场和行业报告中。而在它们背后&#xff0c;隐藏着一个“看不见但无处不在”的关键技术——数字孪生&#xff08;Digital Twin&#xff09;。 它不仅在制造…

WebRTC源码线程-1

1、概述 本篇主要是简单介绍WebRTC中的线程&#xff0c;WebRTC源码对线程做了很多的封装。 1.1 WebRTC中线程的种类 1.1.1 信令线程 用于与应用层的交互&#xff0c;比如创建offer&#xff0c;answer&#xff0c;candidate等绝大多数的操作 1.1.2 工作线程 负责内部的处理逻辑&…

MySQL中的内置函数

文章目录 一、日期函数1.1 获取当前的日期1.2 获取当前时间1.3 获取当前日期和时间1.4 提取时间日期1.5 添加日期1.6 减少日期1.7 两个日期的差值 二、字符串处理函数2.1 获取字符串的长度2.2 获取字符串的字节数2.3 字符串拼接2.4 转小写2.5 转大写2.6 子字符串第⼀次出现的索…

YOLOv8n行人检测实战:从数据集准备到模型训练

YOLOv8n行人检测实战&#xff1a;从数据集准备到模型训练 一、为什么选择YOLOv8&#xff1f;二、环境准备2.1 环境配置解析 三、安装Ultralytics框架四、数据集准备与理解4.1 数据集下载4.2 数据集结构4.3 YOLO标签格式解析 五、数据集可视化&#xff1a;理解标注数据5.1 可视化…

国标GB28181设备管理软件EasyGBS远程视频监控方案助力高效安全运营

一、方案背景​ 在商业快速扩张的背景下&#xff0c;连锁店门店数量激增&#xff0c;分布范围广。但传统人工巡检、电话汇报等管理方式效率低下&#xff0c;存在信息滞后、管理盲区&#xff0c;难以掌握店铺运营情况&#xff0c;影响企业效率与安全。网络远程视频监控系统可有…

网络寻路--图论

所以我们固定题中M条边&#xff08;因为这M条一定联通&#xff09; P8605 [蓝桥杯 2013 国 AC] 网络寻路 - 洛谷 #include<bits/stdc.h> using namespace std; #define N 100011 typedef long long ll; typedef pair<int,int> pii; int n,m; int d[N],u[N],v[N]…

LangChain4j 学习教程项目

LangChain4j 学习教程 项目地址项目简介主要功能使用的技术和库项目环境配置环境要求 依赖版本每天学习内容和目标Day 01Day 02Day 03Day 04Day 05Day 06Day 07Day 08Day 09Day 10Day 11Day 12重点学习内容 RAG 经过为期12天&#xff08;日均1小时&#xff09;的LangChain4j源码…

【读论文】U-Net: Convolutional Networks for Biomedical Image Segmentation 卷积神经网络

摘要1 Introduction2 Network Architecture3 Training3.1 Data Augmentation 4 Experiments5 Conclusion背景知识卷积激活函数池化上采样、上池化、反卷积softmax 归一化函数交叉熵损失 Olaf Ronneberger, Philipp Fischer, Thomas Brox Paper&#xff1a;https://arxiv.org/ab…

Linux 文件系统与 I/O 编程核心原理及实践笔记

文章目录 一、理解文件1.1 狭义理解1.2 广义理解1.3 文件操作的归类认识1.4 系统角度&#xff1a;进程与文件的交互1.5 实践示例 二、回顾 C 文件接口2.1 hello.c 打开文件2.2 hello.c 写文件2.3 hello.c 读文件2.4 输出信息到显示器的几种方法2.5 stdin & stdout & st…

vite+tailwind封装组件库

前言 演示视频 https://www.bilibili.com/video/BV1EST3zPEyP/?spm_id_from333.1387.homepage.video_card.click 参考 https://juejin.cn/post/7112295067682865166 https://juejin.cn/post/7046187185615142949 代码仓库 https://gitee.com/malguy/vite-components-li…

【Java学习笔记】包装类

包装类&#xff08;Wrapper&#xff09; 1. 介绍 &#xff08;1&#xff09;针对八种基本数据类型相应的引用类型 --> 包装类 &#xff08;2&#xff09;有了类的特点&#xff0c;就可以调用类中的方法 2. 分类和继承关系 基本数据类型包装类父类booleanBooleanObjectc…

【高效开发工具系列】Blackmagic Disk Speed Test for Mac:专业硬盘测速工具

博客目录 一、Blackmagic Disk Speed Test 概述二、软件核心功能解析三、v3.3 版本的新特性与改进四、实际应用场景分析五、使用技巧与最佳实践六、与其他工具的比较及优势 一、Blackmagic Disk Speed Test 概述 Blackmagic Disk Speed Test 是 Mac 平台上广受专业人士青睐的一…

UniRig:如何在矩池云一站式解决 3D 模型绑定难题

在 3D 动画制作中&#xff0c;绑定&#xff08;Rigging&#xff09;是一个至关重要但复杂耗时的步骤。它包括为 3D 模型创建骨架并分配蒙皮权重&#xff0c;以实现流畅的动画效果。由清华大学与 Tripo 联合开发的 UniRig 框架&#xff0c;为这一难题提供了全新的解决方案。 什…