ユニバーサル Windows プラットフォーム アプリからの 3D 印刷

ユニバーサル Windows プラットフォーム (UWP) アプリに 3D 印刷機能を追加する方法について説明します。

このトピックでは、アプリに 3D 形状データを読み込んだ後、その 3D モデルが印刷可能であり、正しい形式になっていることを確認してから 3D 印刷ダイアログを起動する方法について説明します。 以下の手順の実例については、3D 印刷の UWP サンプルをご覧ください。

重要な API

セットアップ

3D 印刷機能を必要とするアプリケーション クラスに Windows.Graphics.Printing3D 名前空間を追加します。

using Windows.Graphics.Printing3D;

このガイドでは、次の名前空間も使用します。

using System;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

次に、有用なメンバー フィールドをクラスに追加します。

  • 印刷ドライバーに渡される印刷タスクを表す Print3DTask オブジェクトを宣言します。
  • アプリに読み込まれる元の 3D データ ファイルを保持するために、StorageFile オブジェクトを宣言します。
  • 必要なすべてのメタデータを含む印刷対応の 3D モデルを表す Printing3D3MFPackage オブジェクトを宣言します。
private Print3DTask printTask;
private StorageFile file;
private Printing3D3MFPackage package = new Printing3D3MFPackage();

シンプルな UI の作成

このサンプルでは、[ 読み込み ] ボタンを使用してファイルをプログラム メモリに取り込み、 修正 ボタンを使用してファイルに必要な変更を加え、 印刷 ボタンを使用して印刷ジョブを開始します。 次のコードでは、これらのボタン (クリック時のイベント ハンドラーを含む) を、.cs クラスの対応する XAML ファイルに作成します。

<StackPanel Orientation="Vertical" VerticalAlignment="Center">
    <Button x:Name="loadbutton" Content="Load Model from File" HorizontalAlignment="Center" Margin="5,5,5,5" VerticalAlignment="Center" Click="OnLoadClick"/>
    <Button x:Name="fixbutton" Content="Fix Model" HorizontalAlignment="Center" Margin="5,5,5,5" VerticalAlignment="Center" Click="OnFixClick"/>
    <Button x:Name="printbutton" Content="Print" HorizontalAlignment="center" Margin="5,5,5,5" VerticalAlignment="Center" Click="OnPrintClick"/>

このサンプルには、UI フィードバック用の TextBlock も含まれています。

    <TextBlock x:Name="OutputTextBlock" TextAlignment="Center"></TextBlock>
</StackPanel>

3D データの取得

アプリで 3D ジオメトリ データを取得する方法は異なる場合があります。 たとえば、3D スキャンからデータを取得したり、Web リソースからのモデル データをダウンロードしたり、数式やユーザー入力を使ってプログラムによって 3D メッシュを生成したりできます。 ここでは、3Dデータファイル(いくつかの一般的なファイルタイプのいずれか)をデバイスストレージからプログラムメモリに読み込む方法を示します。 3D Builder モデル ライブラリには、ダウンロードできるさまざまなモデルが用意されています。

メソッドでは OnLoadClickFileOpenPicker クラスは 1 つのファイルをアプリ メモリに読み込みます。

次のコードは、 メソッドの FileOpenPicker クラスを使用して、アプリ メモリに 1 つのファイルを読み込む方法を OnLoadClick 示しています。

private async void OnLoadClick(object sender, RoutedEventArgs e) {

    FileOpenPicker openPicker = new FileOpenPicker();

    // allow common 3D data file types
    openPicker.FileTypeFilter.Add(".3mf");
    openPicker.FileTypeFilter.Add(".stl");
    openPicker.FileTypeFilter.Add(".ply");
    openPicker.FileTypeFilter.Add(".obj");

    // pick a file and assign it to this class' 'file' member
    file = await openPicker.PickSingleFileAsync();
    if (file == null) {
        return;
    }

3D Builder による 3D Manufacturing Format (.3mf) への変換

3D ジオメトリ データはさまざまな形式で提供される可能性があり、すべてが 3D 印刷に効率的なわけではありません。 Windows では、すべての 3D 印刷タスクに 3D 製造形式 (.3mf) ファイルの種類が使用されます。

3MF の詳細と、3D 製品のプロデューサーとコンシューマー向けにサポートされている機能については、3MF 仕様を参照してください。 Windows API でこれらの機能を利用する方法については、 3MF パッケージの生成 に関するチュートリアルを参照してください。

注意

3D Builder アプリでは、一般的なほとんどの 3D 形式のファイルを開くことができ、それらを .3mf ファイル形式で保存することができます。 また、モデルの編集、色データの追加、その他の印刷固有の操作を実行するためのツールも提供されます。

この例では、ファイルの種類が異なる場合は、3D Builder アプリを開き、インポートしたデータを .3mf ファイルとして保存してから再読み込みするようにユーザーに求めるメッセージを表示できます。

    // if user loaded a non-3mf file type
    if (file.FileType != ".3mf") {

        // elect 3D Builder as the application to launch
        LauncherOptions options = new LauncherOptions();
        options.TargetApplicationPackageFamilyName = "Microsoft.3DBuilder_8wekyb3d8bbwe";

        // Launch the retrieved file in 3D builder
        bool success = await Windows.System.Launcher.LaunchFileAsync(file, options);

        // prompt the user to save as .3mf
        OutputTextBlock.Text = "save " + file.Name + " as a .3mf file and reload.";
        
        // have user choose another file (ideally the newly-saved .3mf file)
        file = await openPicker.PickSingleFileAsync();

    } else {
        // if the file type is .3mf
        // notify user that load was successful
        OutputTextBlock.Text = file.Name + " loaded as file";
    }
}

3D 印刷可能なモデル データへの修復

.3mf 形式であっても、すべての 3D モデル データが印刷可能なわけではありません。 プリンターが塗りつぶす領域と空の領域を正しく決定するには、印刷する各モデルが単一のシームレス メッシュであり、外向きのサーフェス法線を持ち、多様なジオメトリを持っている必要があります。 これらの問題は、さまざまな形で現れることがあり、図形が複雑な場合は、見つけるのが難しいことがあります。 ただし、最新のソフトウェア ソリューションは、多くの場合、元データの形状を印刷可能な 3D 図形に変換するのに十分な機能を備えています。 これはモデル の修復 と呼ばれ、ここに示すメソッドで OnFixClick 実装されています。

注意

IRandomAccessStream を実装し、Printing3DModel オブジェクトを生成します。これを行うには、3D データ ファイルを変換する必要があります。

private async void OnFixClick(object sender, RoutedEventArgs e) {

    // read the loaded file's data as a data stream
    IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read);

    // assign a Printing3DModel to this data stream
    Printing3DModel model = await package.LoadModelFromPackageAsync(fileStream);

    // use Printing3DModel's repair function
    OutputTextBlock.Text = "repairing model";
    var data = model.RepairAsync();

Printing3DModel オブジェクトが修復され、印刷可能になりました。 SaveModelToPackageAsync を使って、クラスを作成したときに宣言した Printing3D3MFPackage オブジェクトにモデルを割り当てます。

    // save model to this class' Printing3D3MFPackage
    OutputTextBlock.Text = "saving model to 3MF package";
    await package.SaveModelToPackageAsync(model);

}

印刷タスクの実行: TaskRequested ハンドラーの作成

その後、3D 印刷ダイアログがユーザーに表示され、ユーザーが印刷を開始することを選択した場合、アプリは目的のパラメーターを 3D 印刷パイプラインに渡す必要があります。 3D print API は TaskRequested イベントを発生させます。これには適切な処理が必要です。

private void MyTaskRequested(Print3DManager sender, Print3DTaskRequestedEventArgs args) {

このメソッドの主な目的は、args パラメーターを使って、Printing3D3MFPackage をパイプラインに送信することです。 Print3DTaskRequestedEventArgs 型には、Request という 1 つのプロパティがあります。 その型は Print3DTaskRequest で、1 つの印刷ジョブ要求を表します。 そのメソッド CreateTask を使用すると、アプリは印刷ジョブの正しい情報を送信し、3D 印刷パイプラインから送信された Print3DTask オブジェクトへの参照を返すことができます。

CreateTask には、印刷ジョブ名を表す string、使うプリンターの ID を表す string、および Print3DTaskSourceRequestedHandler デリゲートという入力パラメーターがあります。 このデリゲートは、3DTaskSourceRequested イベントが発生したときに自動的に呼び出されます (これは API によって行われます)。 重要なのは、印刷ジョブが開始されたときにこのデリゲートが呼び出され、適切な 3D 印刷パッケージを提供する役割を果たすということです。

Print3DTaskSourceRequestedHandler は、送信するデータを含む Print3DTaskSourceRequestedArgs オブジェクトという 1 つのパラメーターを受け取ります。 SetSource メソッドは、印刷するパッケージを受け入れます。 次のコードは、 Print3DTaskSourceRequestedHandler デリゲート実装 (sourceHandler) を示しています。

// this delegate handles the API's request for a source package
Print3DTaskSourceRequestedHandler sourceHandler = delegate (Print3DTaskSourceRequestedArgs sourceRequestedArgs) {
    sourceRequestedArgs.SetSource(package);
};

次に、新しく定義されたデリゲートを使用して CreateTask を呼び出します。

// the Print3DTaskRequest ('Request'), a member of 'args', creates a Print3DTask to be sent down the pipeline.
printTask = args.Request.CreateTask("Print Title", "Default", sourceHandler);

返される Print3DTask は、最初に宣言されたクラス変数に割り当てられます。 この参照は、タスクによってスローされた特定のイベントを処理するために使用できます。

// optional events to handle
printTask.Completed += Task_Completed; 
printTask.Submitting += Task_Submitting;

注意

これらのイベントに Task_Submitting および Task_Completed メソッドを登録するには、それらを実装する必要があります。

印刷タスクの実行: 3D 印刷ダイアログを開く

最後に、多数の印刷オプションを提供する 3D 印刷ダイアログを起動する必要があります。

ここでは、TaskRequested イベントにメソッドを登録MyTaskRequestedします。

private async void OnPrintClick(object sender, RoutedEventArgs e) {

    // get a reference to this class' Print3DManager
    Print3DManager myManager = Print3DManager.GetForCurrentView();

    // register the method 'MyTaskRequested' to the Print3DManager's TaskRequested event
    myManager.TaskRequested += MyTaskRequested;

TaskRequested イベント ハンドラーを登録した後、ShowPrintUIAsync メソッドを呼び出すと、現在のアプリケーション ウィンドウに 3D 印刷ダイアログが表示されます。

// show the 3D print dialog
OutputTextBlock.Text = "opening print dialog";
var result = await Print3DManager.ShowPrintUIAsync();

また、アプリが制御を再開したら、イベント ハンドラーの登録を解除することをお勧めします。

    // remove the print task request after dialog is shown            
    myManager.TaskRequested -= MyTaskRequested;
}

Windows 10を使用した 3D 印刷3MF パッケージの生成
3D 印刷の UWP サンプル