C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)※記載されている内容は個人の意見であり、所属する団体等を代表する意見では御座いません・・・・よ!

スクリプトでパレットは作れるのか?

APIフォーラムにパレットの質問が出ていたのでちょっと挑戦しようと思ったのですが、
アドインを作るのが面倒・・・
なので、スクリプトでパレットを表示させて確認しようと思ったところでハマってます。(現在進行形)

良く考えたら、アドインでパレットは使ってきましたが、スクリプトでは
使ったことが無いです。

手元の雛形と、こちらのパレットを使ったサンプルを混ぜた形で試しています。
https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-F0068478-49F0-4E5E-9BAD-3116D8FCBCAF

スクリプトのエントリーポイントになっているpython側です。

# Fusion360API Python script

import traceback
import adsk
import adsk.core as core
import adsk.fusion as fusion
import json

_app: core.Application = None
_ui: core.UserInterface = None
_handlers = []

CMD_INFO = {
    'id': 'kantoku_test',
    'name': 'test',
    'tooltip': 'test'
}

_PALETTE_ID = "palette_test"

class MyCommandCreatedHandler(core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: core.CommandCreatedEventArgs):
        core.Application.get().log(args.firingEvent.name)
        try:
            global _handlers
            cmd: core.Command = core.Command.cast(args.command)
            inputs: core.CommandInputs = cmd.commandInputs

            onDestroy = MyCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

            onExecute = MyExecuteHandler()
            cmd.execute.add(onExecute)
            _handlers.append(onExecute)

        except:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


class MyExecuteHandler(core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: core.CommandEventArgs):
        palettes = _ui.palettes
        palette: core.Palette = palettes.itemById(_PALETTE_ID)
        if palette:
            palette.deleteMe()

        palette = palettes.add(
            id=_PALETTE_ID,
            name="palette test",
            htmlFileURL="html/index.html",
            isVisible=True,
            showCloseButton=True,
            isResizable=True,
            width=400,
            height=400,
            useNewWebBrowser=True
        )

        global _handlers
        onHTMLEvent = MyHTMLEventHandler()
        palette.incomingFromHTML.add(onHTMLEvent)   
        _handlers.append(onHTMLEvent)

        onClosed = MyCloseEventHandler()
        palette.closed.add(onClosed)
        _handlers.append(onClosed) 

        palette.isVisible = True


class MyHTMLEventHandler(core.HTMLEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            htmlArgs = core.HTMLEventArgs.cast(args)            
            data = json.loads(htmlArgs.data)
            msg = "An event has been fired from the html to Fusion with the following data:\n"
            msg += '    Command: {}\n    arg1: {}\n    arg2: {}'.format(htmlArgs.action, data['arg1'], data['arg2'])
            _ui.messageBox(msg)
        except:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


class MyCloseEventHandler(adsk.core.UserInterfaceGeneralEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            _app.log('Close button is clicked.') 
        except:
            _app.log('Failed:\n{}'.format(traceback.format_exc()))


class MyCommandDestroyHandler(core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: core.CommandEventArgs):
        core.Application.get().log(args.firingEvent.name)
        adsk.terminate()


def run(context):
    try:
        global _app, _ui
        _app = core.Application.get()
        _ui = _app.userInterface

        cmdDef: core.CommandDefinition = _ui.commandDefinitions.itemById(
            CMD_INFO['id']
        )

        if not cmdDef:
            cmdDef = _ui.commandDefinitions.addButtonDefinition(
                CMD_INFO['id'],
                CMD_INFO['name'],
                CMD_INFO['tooltip']
            )

        global _handlers
        onCommandCreated = MyCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        cmdDef.execute()

        adsk.autoTerminate(False)

    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

続いてパレットに表示させるhtml側で、上のファイルに対して相対パスが "html/index.html"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
    <body>
        <p>Click the button below to send data to Fusion.</p>
        <button type='button' onclick='sendInfoToFusion()'>Click to send info to Fusion</button> 
        <p id='p1'>Run the "Send Info to HTML" command in the ADD-INS panel to update this text.</p>
        <br /><br />
	
    </body>
    <script>
        function sendInfoToFusion(){
            var today = new Date();
            var dd = String(today.getDate()).padStart(2, '0');
            var mm = String(today.getMonth() + 1).padStart(2, '0');
            var yyyy = today.getFullYear();

            var hours = String(today.getHours()).padStart(2, '0');
            var minutes = String(today.getMinutes()).padStart(2, '0');
            var seconds = String(today.getSeconds()).padStart(2, '0');

            var date = dd + '/' + mm + '/' + yyyy;
            var time = hours + ':' + minutes + ':' + seconds;
            var args = {
                arg1 : "Sample argument 1",
                arg2 : "Sample argument 2"
            };
            console.log(JSON.stringify(args));
            adsk.fusionSendData('send', JSON.stringify(args));
        }
        
        window.fusionJavaScriptHandler = {handle: function(action, data){
            try {
                if (action == 'send') {
					// Update a paragraph with the data passed in.
					document.getElementById('p1').innerHTML = data;
				}
				else if (action == 'debugger') {
                    debugger;
				}
				else {
					return 'Unexpected command type: ' + action;
                }
            } catch (e) {
                console.log(e);
                console.log('exception caught with command: ' + action + ', data: ' + data);
            }
            return 'OK';
        }};
    </script>
</html>

htmlは、あちらのサンプルとはちょっと違いますが、確認のための追記等で動作的には同じです。


ん~パレットの表示は出来ているのですが、ボタンをクリックしてもincomingFromHTML関数が
呼び出さあれないんです・・・なぜだろう?

パレット側でも開発者モード?(呼び名がわからない)を開いてコンソールで確認すると
特別エラーが出ているわけでもなく、ボタンのクリックには反応しているのですが、
何故かpython側に通知が来ない・・・何か見落としている???