^(* ̄(oo) ̄)^

  • 首页
  • 博客
  • 文档
  • 网盘
  • 仓库
  • 简介
Keep Learning
  1. 首页
  2. 博客
  3. 正文

cad 三维实体

2025年1月3日 489点热度

绘制三维实体

绘制复杂实体时,使用扫掠功能可能会出现图形颠倒的情况。在查询相关信息后未找到明确的解决方案,根据多个测试路径,发现可能由于路径的前(从左到右)两个点影响。当第二个点的y轴大于第一个点的y轴时,图形会颠倒。故判断从左到右的前两个点,若会导致结果颠倒,则先将截面颠倒。

bool rotate = (point[0].X < point[point.Count - 1].X) ? (point[0].Y < point[1].Y) : (point[point.Count - 1].Y < point[point.Count - 2].Y);

if (rotate)
{
    Matrix3d rotationMatrix = Matrix3d.Rotation(Math.PI, Vector3d.XAxis, Point3d.Origin);
    sectionEnt.TransformBy(rotationMatrix);
}

扫掠的主要部分,调用函数提供截面以及路径和 SweepOptionsBuilder:

SweepOptionsBuilder sweepOptionsBuilder = new SweepOptionsBuilder();
sweepOptionsBuilder.Align = SweepOptionsAlignOption.AlignSweepEntityToPath;
sweepOptionsBuilder.BasePoint = pathEnt.StartPoint;
sweepOptionsBuilder.Bank = true;

Solid3d sweepEnt1 = new Solid3d();
sweepEnt1.CreateSweptSolid(sectionEnt, pathEnt, sweepOptionsBuilder.ToSweepOptions());

sweepOptionsBuilder.Align有四种,但是我使用其他三种都会报错,因为使用此种方式,才会导致的图形颠倒;sweepOptionsBuilder.BasePoint为基点,我是将图形移到了路线的起点,然后将基点设为了路径的起点;最后bank属性让扫掠实体在沿路径扫掠时,随路径的方向变化而调整其朝向。

创建三维面函数:

SweptSurface sweepEnt1 = new SweptSurface();
sweepEnt1.CreateSweptSurface(sectionEnt1, pathEnt2,sweepOptionsBuilder.ToSweepOptions());

扫掠要求为一个对象,拱形需要把圆弧转成多段线,创建拱形代码:

double archHeight = (double)tunnel.other;
var centerPoint2 = new Point3d(width / 2, height, 0);
Arc arc2 = new Arc(centerPoint2, archHeight, 0, Math.PI);
int numSegments = 20;

for (int i = 0; i <= numSegments; i++)
{
    double angle = (Math.PI / numSegments) * i; // 将弧均匀分成多个线段
    double x = centerPoint2.X + archHeight * Math.Cos(angle);
    double y = centerPoint2.Y + archHeight * Math.Sin(angle);
    sectionEnt.AddVertexAt(i, new Point2d(x, y), 0.0, 0.0, 0.0);
}

// 截面实体
Polyline sectionEnt2 = new Polyline();
sectionEnt2.AddVertexAt(0, new Point2d(centerPoint2.X - archHeight, centerPoint2.Y-height), 0.0, 0.0, 0.0);
sectionEnt2.AddVertexAt(1, new Point2d(centerPoint2.X + archHeight, centerPoint2.Y - height), 0.0, 0.0, 0.0);

for (int i = 0; i < sectionEnt2.NumberOfVertices; i++)
{
    sectionEnt.AddVertexAt(sectionEnt.NumberOfVertices, sectionEnt2.GetPoint2dAt(i), 0.0, 0.0, 0.0);
}
sectionEnt.Closed = true;

全部代码,扫掠矩形和拱形:

private static void xxxx(Database acCurDb, BlockTableRecord acBlkTblRec, Transaction acTrans, ThreeDimension.Tunnel3D tunnel)
{
    try
    {
        var point = new Point3dCollection();
        foreach (var roadway in tunnel.info)
        {
            if (roadway.start.X != "" && roadway.start.Y != "" && roadway.start.Z != "")
            {
                var p = new Point3d(double.Parse(roadway.start.X), double.Parse(roadway.start.Y), double.Parse(roadway.start.Z));
                point.Add(p);
            }
        }
        if (tunnel.info[tunnel.info.Count-1].end.X != "" && tunnel.info[tunnel.info.Count - 1].end.Y != "" && tunnel.info[tunnel.info.Count - 1].end.Z != "")
        {
            var p = new Point3d(double.Parse(tunnel.info[tunnel.info.Count - 1].end.X), 
                double.Parse(tunnel.info[tunnel.info.Count - 1].end.Y), 
                double.Parse(tunnel.info[tunnel.info.Count - 1].end.Z));
            point.Add(p);
        }

        bool rotate = (point[0].X < point[point.Count - 1].X) ? (point[0].Y < point[1].Y) : (point[point.Count - 1].Y < point[point.Count - 2].Y);
        // 截面实体
        Polyline sectionEnt = new Polyline();
        double width = (double)tunnel.width;
        double height = (double)tunnel.height;
        if (tunnel.rshape == 0)
        {
            sectionEnt.AddVertexAt(0, new Point2d(width, height), 0.0, 0.0, 0.0);
            sectionEnt.AddVertexAt(1, new Point2d(width, 0), 0.0, 0.0, 0.0);
            sectionEnt.AddVertexAt(2, new Point2d(0, 0), 0.0, 0.0, 0.0);
            sectionEnt.AddVertexAt(3, new Point2d(0, height), 0.0, 0.0, 0.0);
            sectionEnt.Closed = true;
        }
        else if(tunnel.rshape == 1)
        {
            double archHeight = (double)tunnel.other;
            var centerPoint2 = new Point3d(width / 2, height, 0);
            Arc arc2 = new Arc(centerPoint2, archHeight, 0, Math.PI);
            int numSegments = 20;

            for (int i = 0; i <= numSegments; i++)
            {
                double angle = (Math.PI / numSegments) * i; // 将弧均匀分成多个线段
                double x = centerPoint2.X + archHeight * Math.Cos(angle);
                double y = centerPoint2.Y + archHeight * Math.Sin(angle);
                sectionEnt.AddVertexAt(i, new Point2d(x, y), 0.0, 0.0, 0.0);
            }

            // 截面实体
            Polyline sectionEnt2 = new Polyline();
            sectionEnt2.AddVertexAt(0, new Point2d(centerPoint2.X - archHeight, centerPoint2.Y-height), 0.0, 0.0, 0.0);
            sectionEnt2.AddVertexAt(1, new Point2d(centerPoint2.X + archHeight, centerPoint2.Y - height), 0.0, 0.0, 0.0);

            for (int i = 0; i < sectionEnt2.NumberOfVertices; i++)
            {
                sectionEnt.AddVertexAt(sectionEnt.NumberOfVertices, sectionEnt2.GetPoint2dAt(i), 0.0, 0.0, 0.0);
            }
            sectionEnt.Closed = true;
        }
        
        Polyline3d pathEnt = new Polyline3d(Poly3dType.SimplePoly, point, false);

        if (rotate)
        {
            Matrix3d rotationMatrix = Matrix3d.Rotation(Math.PI, Vector3d.XAxis, Point3d.Origin);
            sectionEnt.TransformBy(rotationMatrix);
        }
        Matrix3d moveMatrix = Matrix3d.Displacement(new Vector3d(point[0].X - width, point[0].Y - height, point[0].Z));
        sectionEnt.TransformBy(moveMatrix);

        SweepOptionsBuilder sweepOptionsBuilder = new SweepOptionsBuilder();
        sweepOptionsBuilder.Align = SweepOptionsAlignOption.AlignSweepEntityToPath;
        sweepOptionsBuilder.BasePoint = pathEnt.StartPoint;
        sweepOptionsBuilder.Bank = true;

        Solid3d sweepEnt1 = new Solid3d();
        sweepEnt1.CreateSweptSolid(sectionEnt, pathEnt, sweepOptionsBuilder.ToSweepOptions());
        sweepEnt1.ColorIndex = 7;

        using (Transaction tr = acCurDb.TransactionManager.StartTransaction())
        {
            acBlkTblRec.AppendEntity(sweepEnt1);
            acTrans.AddNewlyCreatedDBObject(sweepEnt1, true);
            tr.Commit();
        }
        sweepEnt1.Dispose();
    }
    catch (Exception ex) 
    {
    }
}

视口相关配置,控制视图和视觉样式:

acVportTblRec.SetViewDirection(OrthographicView.RightView);
DBDictionary visualStyleDict = acTrans.GetObject(acCurDb.VisualStyleDictionaryId, OpenMode.ForRead) as DBDictionary;
if (visualStyleDict.Contains("Realistic"))
{
  // 获取 "Realistic" 视觉样式的 ObjectId
  visualStyleId = visualStyleDict.GetAt("Realistic");
}
acVportTblRec.VisualStyleId = visualStyleId;
标签: c++
最后更新:2025年1月3日

九州安所如

程序员

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2023 zhu

鲁ICP备2026022547号