伊江痕 发表于 2024-3-29 12:47:37

CAD2025调用微软的机器学习库Microsoft.ML

本帖最后由 伊江痕 于 2024-3-29 13:07 编辑

软件平台:CAD2025
开发规范:.NET Standard
开发框架:.NET8.0
开发语言:C#
涉及库:CAD开发基本类库及Microsoft.ML,如图1(nuget上自行下载)
演示算法类别:线性支持向量机算法
说明:目前测试的结果是,应该只有CAD2025能很好的调用这个机器学习库,因为25支持.NET8。其他仅支持Framework框架的CAD版本,在开发的时候调用Microsoft.ML都会产生各种意想不到的问题。


伊江痕 发表于 2024-3-29 12:47:39

源代码:
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Trainers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Net8Cad
{
    public class MLTest
    {
      
      public void Run()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor editor = doc.Editor;
            Database db = HostApplicationServices.WorkingDatabase;
            try
            {
                // 数据集的获取
                var circles = GetAllT_viaSelection<Circle>(doc);
                List<PointData> pointsData = new List<PointData>();
                foreach ( var circle in circles )
                {
                  PointData pd=new PointData();
                  pd.PointX = (float)circle.Center.X;
                  pd.PointY = (float)circle.Center.Y;
                  pd.PointZ = (float)circle.Center.Z;
                  if (circle.Color.ColorIndex == 1)
                  {
                        pd.PointLabel = true;
                  }
                  else
                  {
                        pd.PointLabel = false;
                  }
                  pointsData.Add(pd);
                }

                // 构建机器学习的训练模型
                var mlContext = new MLContext();
                var trainingDataView = mlContext.Data.LoadFromEnumerable<PointData>(pointsData);
                var trainer=mlContext.BinaryClassification.Trainers.LinearSvm(
                  labelColumnName:"Label",
                  featureColumnName: "Features",
                  numberOfIterations:100);

                var trainingPipeline = mlContext.Transforms.Concatenate(
                        outputColumnName: "NumFeatures",
                        nameof(PointData.PointX),
                        nameof(PointData.PointY),
                        nameof(PointData.PointZ))
                  
                  .Append(mlContext.Transforms.Concatenate(outputColumnName: "Features", "NumFeatures"))
                  .Append(mlContext.Transforms.CopyColumns(outputColumnName: "Label",
                                                             inputColumnName: nameof(PointData.PointLabel)))
                  .Append(trainer);

                var model = trainingPipeline.Fit(trainingDataView);
                var svmModel = model.LastTransformer.Model;
                var weights = svmModel.Weights;// w1*x+w2*y+b=0
                var bias=svmModel.Bias;
                WriteMessage(doc, "训练模型为:" + $"{model}");
                WriteMessage(doc, $"weights 个数:{weights.Count} bias 值为:{bias}");
                WriteMessage(doc, $"第一个:{weights} 第二个{weights} 第三个{weights}");

                // w1*x+w2*y+b=0
                double x1 = 100;
                double x2 = 200;
                double y1 = (weights * x1 + bias) / (-weights);
                double y2 = (weights * x2 + bias) / (-weights);

                Xline xl = new Xline();
                xl.BasePoint = new Point3d(x1, y1, 0);
                xl.SecondPoint=new Point3d(x2, y2, 0);
                ToModelSpace(doc, xl);
                WriteMessage(doc, "done");
            }
            catch (System.Exception ex)
            {

                string msg = "报错为:" + ex.Message + "\n" + "位置为:" + ex.StackTrace;
                WriteMessage(doc, msg);

            }
      }
      List<T> GetAllT_viaSelection<T>(Document doc) where T : Entity
      {
            List<T> selectedLines = new List<T>();

            using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
            {
                // 设置提示词
                PromptSelectionOptions opts = new PromptSelectionOptions();
                opts.MessageForAdding = "\n请框选:\n";
                // 提示用户框选实体
                PromptSelectionResult result = doc.Editor.GetSelection(opts);
                if (result.Status != PromptStatus.OK)
                  return null;

                // 获取选中实体的ObjectId数组
                ObjectId[] objectIds = result.Value.GetObjectIds();

                // 遍历选中实体
                foreach (ObjectId objectId in objectIds)
                {
                  // 通过ObjectId打开实体
                  Entity entity = (Entity)objectId.GetObject(OpenMode.ForRead, false);

                  // 判断实体是否为Line类型
                  if (entity.GetType() == typeof(T))
                  {
                        T line = (T)entity;
                        selectedLines.Add(line);
                  }
                }

                tr.Commit();
            }
            return selectedLines;
      }
      void WriteMessage(Document doc, string message)
      {
            Editor editor = doc.Editor;
            editor.WriteMessage("\n" + message);
      }
      ObjectId ToModelSpace(Document doc, Entity entity)
      {
            ObjectId objectId;

            using (doc.LockDocument())
            {
                Database database = doc.Database;
                using (Transaction trans = database.TransactionManager.StartTransaction())
                {
                  BlockTable blockTable = (BlockTable)trans.GetObject(database.BlockTableId, OpenMode.ForWrite, false);
                  BlockTableRecord blockTableRecord = (BlockTableRecord)trans.GetObject(blockTable, OpenMode.ForWrite, false);
                  objectId = blockTableRecord.AppendEntity(entity);
                  trans.AddNewlyCreatedDBObject(entity, true);
                  trans.Commit();

                }

            }

            return objectId;
      }



    }
    public class PointData
    {
      
      public bool PointLabel { get; set; }
      
      public float PointX { get; set; }
      
      public float PointY { get; set; }
      
      public float PointZ { get; set; }
    }
}

伊江痕 发表于 2024-3-29 12:47:38

演示结果:如图
测试文件:见附件
视频演示:b站 伊江痕 链接为:伊江痕的b站演示_Microsoft.ML的使用

4551986 发表于 2024-3-29 16:03:52

高大上:lol

伊江痕 发表于 2024-3-29 16:23:44

4551986 发表于 2024-3-29 16:03
高大上

装装掰:lol                     

你有种再说一遍 发表于 2024-3-29 18:22:40

哇塞,有点东西

伊江痕 发表于 2024-3-29 19:12:10

你有种再说一遍 发表于 2024-3-29 18:22
哇塞,有点东西

我预测你会发 多线程读取数据库 的帖子
页: [1]
查看完整版本: CAD2025调用微软的机器学习库Microsoft.ML