CyberChaos(さいばかおす)

プログラミング言語、トランスパイラ、RPA、ChatGPT、データマイニング、リバースエンジニアリングのための忘備録

F#でAutoCADCHATBOTプログラムを書き換えてみた結果orz

2024-05-18 15:00:49 | Visual C#

C#でAutoCADCHATBOT動作確認に成功!

の記事の続編。

F#はVB.net同様、手動でのパス通しをする羽目になった。

open Autodesk.AutoCAD.Runtime
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Geometry

type MyCommands() =
    interface IExtensionApplication with
        member this.Initialize() = 
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nMyCommands initialized")
        member this.Terminate() = 
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nMyCommands terminated")

    [<CommandMethod("bot")>]
    member this.ProcessUserInput() =
        let doc = Application.DocumentManager.MdiActiveDocument
        let ed = doc.Editor
        ed.WriteMessage("\nProcessUserInput called")

        let userInput = this.GetStringFromUserInput("CAD", "何をしましょうか?")
        if userInput.Contains("直線") then
            this.CreateLine()
        elif userInput.Contains("円") then
            this.CreateCircle()
        else
            ed.WriteMessage("\nそのような操作はできません。")

    member private this.CreateLine() =
        let doc = Application.DocumentManager.MdiActiveDocument
        let ed = doc.Editor

        let start_x = this.GetDoubleFromUserInput("始点のX座標を入力してください。")
        let start_y = this.GetDoubleFromUserInput("始点のY座標を入力してください。")
        let end_x = this.GetDoubleFromUserInput("終点のX座標を入力してください。")
        let end_y = this.GetDoubleFromUserInput("終点のY座標を入力してください。")

        this.DrawLine(start_x, start_y, end_x, end_y)

    member private this.CreateCircle() =
        let doc = Application.DocumentManager.MdiActiveDocument
        let ed = doc.Editor

        let center_x = this.GetDoubleFromUserInput("中心のX座標を入力してください。")
        let center_y = this.GetDoubleFromUserInput("中心のY座標を入力してください。")
        let radius = this.GetDoubleFromUserInput("半径を入力してください。")

        this.DrawCircle(center_x, center_y, radius)

    member private this.GetDoubleFromUserInput(prompt: string) : double =
        let ed = Application.DocumentManager.MdiActiveDocument.Editor
        let mutable result = ed.GetDouble(prompt)
        while result.Status <> PromptStatus.OK do
            ed.WriteMessage("\n数値を入力してください。")
            result <- ed.GetDouble(prompt)
        result.Value

    member private this.GetStringFromUserInput(title: string, prompt: string) : string =
        let ed = Application.DocumentManager.MdiActiveDocument.Editor
        (ed.GetString(prompt)).StringResult

    member private this.DrawLine(startX: double, startY: double, endX: double, endY: double) =
        let doc = Application.DocumentManager.MdiActiveDocument
        let db = doc.Database

        use tr = db.TransactionManager.StartTransaction()
        let bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) :?> BlockTable
        let btr = tr.GetObject(bt.[BlockTableRecord.ModelSpace], OpenMode.ForWrite) :?> BlockTableRecord

        let startPoint = Point3d(startX, startY, 0.0)
        let endPoint = Point3d(endX, endY, 0.0)
        let line = new Line(startPoint, endPoint)
        btr.AppendEntity(line) |> ignore
        tr.AddNewlyCreatedDBObject(line, true) |> ignore

        tr.Commit()

    member private this.DrawCircle(centerX: double, centerY: double, radius: double) =
        let doc = Application.DocumentManager.MdiActiveDocument
        let db = doc.Database

        use tr = db.TransactionManager.StartTransaction()
        let bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) :?> BlockTable
        let btr = tr.GetObject(bt.[BlockTableRecord.ModelSpace], OpenMode.ForWrite) :?> BlockTableRecord

        let centerPoint = Point3d(centerX, centerY, 0.0)
        let circle = new Circle(centerPoint, Vector3d.ZAxis, radius)
        btr.AppendEntity(circle) |> ignore
        tr.AddNewlyCreatedDBObject(circle, true) |> ignore

        tr.Commit()

 

ACETUCS-BUTTON

というコマンドが勝手に呼び出され、ロード中・・・と表示されたままフリーズ・

誰もACETUCS-BUTTONなんていうコマンドを入力した覚えがないんだけど。

F#は使えない言語ということでソッコー没!

次はC++でためしてみることになった。

どうなるかわからんが、とりあえずChatGPTの吐いたソースコードをここに投げておこう。

#include "acutads.h"
#include "acedads.h"
#include "acdocman.h"
#include "dbents.h"
#include "dbmain.h"
#include "dbsymtb.h"
#include "dbapserv.h"
#include "geassign.h"
#include "acarray.h"

class MyCommands
{
public:
    static void ProcessUserInput()
    {
        AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
        AcDbBlockTable* pBlockTable;
        AcDbBlockTableRecord* pBlockTableRecord;

        acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);
        pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
        pBlockTable->close();

        ACHAR szPrompt[512];
        acutPrintf(_T("\nCAD、何をしましょうか?: "));
        acedGetString(0, szPrompt);
        CString userInput = szPrompt;

        if (userInput.Find(_T("直線")) != -1)
        {
            CreateLine(pBlockTableRecord);
        }
        else if (userInput.Find(_T("円")) != -1)
        {
            CreateCircle(pBlockTableRecord);
        }
        else
        {
            acutPrintf(_T("\nそのような操作はできません。"));
        }

        pBlockTableRecord->close();
    }

private:
    static void CreateLine(AcDbBlockTableRecord* pBlockTableRecord)
    {
        double start_x = GetDoubleFromUserInput(_T("始点のX座標を入力してください。"));
        double start_y = GetDoubleFromUserInput(_T("始点のY座標を入力してください。"));
        double end_x = GetDoubleFromUserInput(_T("終点のX座標を入力してください。"));
        double end_y = GetDoubleFromUserInput(_T("終点のY座標を入力してください。"));

        AcDbLine* pLine = new AcDbLine(AcGePoint3d(start_x, start_y, 0), AcGePoint3d(end_x, end_y, 0));
        pBlockTableRecord->appendAcDbEntity(pLine);
        pLine->close();
    }

    static void CreateCircle(AcDbBlockTableRecord* pBlockTableRecord)
    {
        double center_x = GetDoubleFromUserInput(_T("中心のX座標を入力してください。"));
        double center_y = GetDoubleFromUserInput(_T("中心のY座標を入力してください。"));
        double radius = GetDoubleFromUserInput(_T("半径を入力してください。"));

        AcDbCircle* pCircle = new AcDbCircle(AcGePoint3d(center_x, center_y, 0), AcGeVector3d::kZAxis, radius);
        pBlockTableRecord->appendAcDbEntity(pCircle);
        pCircle->close();
    }

    static double GetDoubleFromUserInput(const ACHAR* prompt)
    {
        double value;
        ACHAR szPrompt[512];
        acutPrintf(prompt);
        acedInitGet(0, _T("Cancel"));
        if (RTNORM != acedGetReal(szPrompt, &value))
        {
            acutPrintf(_T("\n数値を入力してください。"));
            acutPrintf(_T("\n操作をキャンセルしました。"));
            acedGetPoint(nullptr, _T("\n続行するにはリターン キーを押してください。"));
            acutPrintf(_T("\n"));
            return -1.0;
        }
        return value;
    }
};

extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
    switch (msg)
    {
    case AcRx::kInitAppMsg:
        acrxDynamicLinker->unlockApplication(pkt);
        acrxRegisterAppMDIAware(pkt);
        break;
    case AcRx::kUnloadAppMsg:
        // Do nothing
        break;
    }
    return AcRx::kRetOK;
}

extern "C" void
ProcessUserInput()
{
    MyCommands::ProcessUserInput();
}