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