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

发布于:2025-06-08 ⋅ 阅读:(25) ⋅ 点赞:(0)

这个要注册不然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);


    
  
}


网站公告

今日签到

点亮在社区的每一天
去签到