Universal Windows Platform 앱에서 3D 인쇄하기

3D 인쇄 기능을 Universal Windows Platform(UWP) 앱에 추가하는 방법을 알아봅니다.

이 항목은 3D 모델을 올바른 형식으로 인쇄할 수 있는지 확인한 후 앱에 3D 기하 도형 데이터를 로드하고 3D 인쇄 대화 상자를 시작하는 방법을 설명합니다. 이러한 절차의 실제 예시를 보려면 3D 인쇄 UWP 샘플을 참조하세요.

중요 API

설정

Windows.Graphics.Printing3D 네임스페이스를 3D 인쇄 기능이 필요한 응용 프로그램 클래스에 추가합니다.

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 개체를 선언합니다.
  • Print3D3MFPackage 개체를 선언하여 필요한 모든 메타데이터를 사용하여 인쇄할 수 있는 3D 모델을 표시합니다.
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 스캔을 통해 데이터를 검색하거나, 웹 리소스에서 모델 데이터를 다운로드하거나, 수학 공식이나 사용자 입력을 사용하여 프로그래밍 방식으로 3D 메시를 생성합니다. 여기서는 장치 스토리지에서 프로그램 메모리에 3D 데이터 파일(몇 가지 일반적인 파일 형식 중)을 로드하는 방법을 보여 줍니다. 3D Builder 모델 라이브러리는 다운로드할 수 있는 다양한 모델을 제공합니다.

OnLoadClick 메서드에서 FileOpenPicker 클래스는 단일 파일을 앱 메모리에 로드합니다.

다음의 코드는 OnLoadClick 메서드의 FileOpenPicker 클래스를 사용하여 단일 파일을 앱 메모리에 로드하는 방법을 보여 줍니다.

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 제조 형식(.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을 구현하려면 3D 데이터 파일을 변환해야 합니다. 그러면 Printing3DModel 개체를 생성하는 데 사용할 수 있습니다.

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 인쇄 API는 TaskRequested 이벤트를 발생시키므로 적절하게 처리해야 합니다.

private void MyTaskRequested(Print3DManager sender, Print3DTaskRequestedEventArgs args) {

이 메서드의 핵심 목적은 args 매개 변수를 사용하여 Printing3D3MFPackage를 파이프라인 아래로 보내는 것입니다. Print3DTaskRequestedEventArgs 형식에는 하나의 속성인 Request가 있습니다. Print3DTaskRequest 형식이며 하나의 인쇄 작업 요청을 나타냅니다. CreateTask 메서드를 사용하면 앱이 인쇄 작업에 대한 올바른 정보를 제출하고 3D 인쇄 파이프라인 아래로 전송된 Print3DTask 개체에 대한 참조를 반환할 수 있습니다.

CreateTask의 입력 매개 변수로 인쇄 작업 이름에 대한 문자열, 사용할 프린터 ID에 대한 문자열, Print3DTaskSourceRequestedHandler 대리자가 있습니다. 대리자는 3DTaskSourceRequested 이벤트가 발생할 때 자동으로 호출됩니다(이 작업은 API 자체에 의해 수행됨). 중요한 점은 인쇄 작업이 시작될 때 이 대리자가 호출되고 올바른 3D 인쇄 패키지를 제공해야 한다는 것입니다.

Print3DTaskSourceRequestedHandler는 보낼 데이터가 포함된 Print3DTaskSourceRequestedArgs 개체라는 하나의 매개 변수를 사용합니다. 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는 처음에 선언된 클래스 변수에 할당됩니다. 이 참조는 태스크에서 throw된 특정 이벤트를 처리하는 데 사용할 수 있습니다.

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

참고

이러한 이벤트에 등록하려면 Task_SubmittingTask_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 이벤트 처리기를 등록한 뒤, 현재 애플리케이션 창에서 3D 인쇄 대화 상자를 표시하는 ShowPrintUIAsync 메서드를 호출할 수 있습니다.

// 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 샘플