从DWG文件上对弧进行细分

发布于 2025-02-01 12:01:31 字数 3049 浏览 2 评论 0原文

我有一个使用Forge查看器显示转换后DWG文件的应用程序。简短的描述是,我需要从DWG文件源中取出特定的巨品,并使用Edit2D扩展名将其绘制为多边形。我有这个工作,但是弧线正在造成一些问题。这不一定是完美的,但应该具有相同的形状。在大多数情况下,它只是从弧线开始到结束的一条线(我明白为什么,请参见下面的代码),但在其他情况下,它大大划分了弧线,我不确定为什么。

我首先根据其层找到polylines的ID,然后获得片段ID(这很好)。然后,我获得了这样的多线线的顶点:

export function getVertexesById(
  viewer: Autodesk.Viewing.GuiViewer3D,
  frags: Autodesk.Viewing.Private.FragmentList,
  fragIds: number[],
  dbId: number
): Point[] {
  // We need to also get the center points of arcs as lines seem to be drawn to them in the callbacks for some
  // reason.  Center points should later be removed from the point array, so we don't get strange spikes on our shapes.
  const polyPoints: Point[] = [];
  const centers: Point[] = [];

  fragIds.forEach((fid) => {
    const mesh = frags.getVizmesh(fid);
    const vbr = new Autodesk.Viewing.Private.VertexBufferReader(
      mesh.geometry,
      viewer.impl.use2dInstancing
    );
    vbr.enumGeomsForObject(dbId, {
      onLineSegment(
        x1: number,
        y1: number,
        x2: number,
        y2: number,
        _vpId: number
      ) {
        checkAddPoint(polyPoints, { x: x1, y: y1, z: 0 });
        checkAddPoint(polyPoints, { x: x2, y: y2, z: 0 });
      },
      onCircularArc: function (cx, cy, start, end, radius, _vpId) {
        centers.push({ x: cx, y: cy, z: 0 });
      },
      onEllipticalArc: function (
        cx,
        cy,
        start,
        end,
        major,
        minor,
        tilt,
        _vpId
      ) {
        centers.push({ x: cx, y: cy, z: 0 });
      },
      onOneTriangle: function (x1, y1, x2, y2, x3, y3, _vpId) {
        checkAddPoint(polyPoints, { x: x1, y: y1, z: 0 });
        checkAddPoint(polyPoints, { x: x2, y: y2, z: 0 });
        checkAddPoint(polyPoints, { x: x3, y: y3, z: 0 });
      },
      onTexQuad: function (cx, cy, width, height, rotation, _vpId) {
        centers.push({ x: cx, y: cy, z: 0 });
      },
    });
  });

  centers.forEach((c) => {
    checkRemovePoint(polyPoints, { x: c.x, y: c.y, z: 0 });
  });

  return polyPoints;
}

函数checkaddpointcheckRemovepoint只是助手函数,确保我们不复制点并考虑四舍五入(所以我们没有得到两个点,说0,0,0和0,0.00001,0

。沿着多线的所有直线绘制,当它到达弧线时,它只是从一个端点到另一个端点

。 :

请注意,房间外面的弧线中有几次休息。我在上述过程中得到的是:

”

请注意,沿着顶部我得到了我的一切。会期望的。但是,沿着两个地方的底部,我在整个生产线上都有大量的细分市场。

我回顾了学院的档案,爆炸了多线,并尤其看了看它,我找不到关于这两个片段与另一个片段的不同事物,这表明它的行为有所不同。

真的很棒的是,如果有一种简单的方法可以沿着弧线分段说每个X单位并让它返回,但是我不希望在这里,我只想知道为什么它会以不同的方式对待这些。

任何帮助将不胜感激。

edit

我还应该提到我已经记录了创建例程,而唯一击中的东西是onlinesegrensegrensegmentoncirculararc。如您所见,圆形弧唯一的检查是为了确保我们没有列表中的中心点,因此所有这些额外要点都是出于某种原因在行段部分中读取的。

I have an application using the Forge Viewer displaying converted ACAD dwg files. The short description is that I need to take specific polylines out of the dwg file source and use the Edit2D extension to draw them as polygons over the background. I have this working, but arcs are causing some issues right now. This doesn't have to be perfect but it should be decently the same shape. In most cases it is just drawing a line from the start to the end of the arc (and I understand why, see code below) but in other cases it's significantly segmenting the arc and I'm not sure why.

I start by finding the id's of the polylines based on their layer and then getting the fragment ids (this is working fine). Then I get the vertexes for the polyline like this:

export function getVertexesById(
  viewer: Autodesk.Viewing.GuiViewer3D,
  frags: Autodesk.Viewing.Private.FragmentList,
  fragIds: number[],
  dbId: number
): Point[] {
  // We need to also get the center points of arcs as lines seem to be drawn to them in the callbacks for some
  // reason.  Center points should later be removed from the point array, so we don't get strange spikes on our shapes.
  const polyPoints: Point[] = [];
  const centers: Point[] = [];

  fragIds.forEach((fid) => {
    const mesh = frags.getVizmesh(fid);
    const vbr = new Autodesk.Viewing.Private.VertexBufferReader(
      mesh.geometry,
      viewer.impl.use2dInstancing
    );
    vbr.enumGeomsForObject(dbId, {
      onLineSegment(
        x1: number,
        y1: number,
        x2: number,
        y2: number,
        _vpId: number
      ) {
        checkAddPoint(polyPoints, { x: x1, y: y1, z: 0 });
        checkAddPoint(polyPoints, { x: x2, y: y2, z: 0 });
      },
      onCircularArc: function (cx, cy, start, end, radius, _vpId) {
        centers.push({ x: cx, y: cy, z: 0 });
      },
      onEllipticalArc: function (
        cx,
        cy,
        start,
        end,
        major,
        minor,
        tilt,
        _vpId
      ) {
        centers.push({ x: cx, y: cy, z: 0 });
      },
      onOneTriangle: function (x1, y1, x2, y2, x3, y3, _vpId) {
        checkAddPoint(polyPoints, { x: x1, y: y1, z: 0 });
        checkAddPoint(polyPoints, { x: x2, y: y2, z: 0 });
        checkAddPoint(polyPoints, { x: x3, y: y3, z: 0 });
      },
      onTexQuad: function (cx, cy, width, height, rotation, _vpId) {
        centers.push({ x: cx, y: cy, z: 0 });
      },
    });
  });

  centers.forEach((c) => {
    checkRemovePoint(polyPoints, { x: c.x, y: c.y, z: 0 });
  });

  return polyPoints;
}

The functions checkAddPoint and checkRemovePoint are just helper functions that make sure we don't duplicate points and take into account rounding (so we don't get two points that are say 0,0,0 and 0,0.00001,0.

I then use those points to draw with the Edit2D extension. So what I would expect here is that it creates a series of points that would draw along all the straight lines of the polyline and when it gets to an arc it just draws from one endpoint to the other. That is mostly what I see.

Here is an example file as it looks in ACAD:

ACAD File

Notice there are a handful of breaks in the arc around the outside of the room. What I get when I do the above process is this:

Viewer

Notice all along the top I get what I would expect. However, along the bottom in 2 places I get a huge number of segments all along the line.

I looked back at the ACAD file and exploded the polyline and looked at it as much as I know how and I can't find anything different about those two segments vs. the other that would indicate why it acts differently.

What would be really awesome is if there is an easy way to just segment along an arc say every x units and have it return that but I'm not expecting that here, I just want to know why it is treating these differently.

Any help is greatly appreciated.

Edit

I should also mention that I have logged the creation routine and the only things in this that are ever hit are the onLineSegment and onCircularArc. As you see, the circular arc one only checks to make sure we don't have the center point in the list, so all of these extra points are for some reason being read in the line segment section.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文