Трехмерная печать из приложения3D printing from your app

Важные APIImportant APIs

Узнайте, как добавить функцию трехмерной печати в универсальное приложение для Windows.Learn how to add 3D printing functionality to your Universal Windows app. В этом разделе рассматривается, как загрузить трехмерные геометрические данные в приложение и открыть диалоговое окно трехмерной печати после того, как вы убедитесь, что ваша трехмерная модель пригодна для печати и выполнена нужном формате.This topic covers how to load 3D geometry data into your app and launch the 3D print dialog after ensuring your 3D model is printable and in the correct format. Работающий пример этих процедур см. в статье Пример трехмерной печати UWP.For a working example of these procedures, see the 3D printing UWP sample.

Примечание

В примерах кода в этом руководстве обработка ошибок и отчетность значительно упрощены.In the sample code in this guide, error reporting and handling is greatly simplified for the sake of simplicity.

НастройкаSetup

Добавьте пространство имен Windows.Graphics.Printing3D в класс приложения, где требуется реализовать возможности трехмерной печати.In your application class that is to have 3D print functionality, add the Windows.Graphics.Printing3D namespace.

using Windows.Graphics.Printing3D;

В этом руководстве будут использоваться следующие дополнительные пространства имен.The following additional namespaces will be used in this guide.

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;

Затем добавьте в класс некоторые полезные поля-члены.Next, give your class helpful member fields. Объявите объект Print3DTask, представляющий задачу печати, которую требуется передать драйверу печати.Declare a Print3DTask object to represent the printing task that is to be passed to the print driver. Объявите объект StorageFile для хранения исходного файла трехмерных данных, которые будут загружаться в приложение.Declare a StorageFile object to hold the original 3D data file that will be loaded into the app. Объявите объект Printing3D3MFPackage, представляющий готовую для печати трехмерную модель со всеми необходимыми метаданными.Declare a Printing3D3MFPackage object, which represents a print-ready 3D model with all necessary metadata.

private Print3DTask printTask;
private StorageFile file;
private Printing3D3MFPackage package = new Printing3D3MFPackage();

Создание простого пользовательского интерфейсаCreate a simple UI

В этом примере используется три пользовательских элемента управления: кнопка загрузки (для переноса файла в память программы), кнопка исправления (для изменения файла согласно необходимости) и кнопка печати (для запуска задания печати).This sample features three user controls: a Load button which will bring a file into program memory, a Fix button which will modify the file as necessary, and a Print button which will initiate the print job. Следующий код позволяет создать эти кнопки (с соответствующими обработчиками события нажатия) в XAML-файле вашего CS-класса.The following code creates these buttons (with their on-click event handlers) in your .cs class' corresponding XAML file.

<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"/>

Добавьте поле TextBlock для обратной связи от пользовательского интерфейса.Add a TextBlock for UI feedback.

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

Получение трехмерных данныхGet the 3D data

Способы получения вашим приложением трехмерных геометрических данных будут разными.The method by which your app acquires 3D geometry data will vary. Приложение может извлечь трехмерные данные из сканирования, скачать данные модели с веб-ресурса или создать трехмерную сетку программным способом с помощью математических формул или пользовательского ввода.Your app may retrieve data from a 3D scan, download model data from a web resource, or generate a 3D mesh programmatically using mathematical formulas or user input. Для простоты в этом примере мы загрузим файл с трехмерными данными (любого из нескольких распространенных типов файлов) в память программы памяти устройства.For the sake of simplicity, this guide will show how to load a 3D data file (of any of several common file types) into program memory from device storage. Библиотека моделей 3D Builder предоставляет разнообразные модели, которые легко можно загрузить на устройство.The 3D Builder model library provides a variety of models that you can easily download to your device.

В методе OnLoadClick используйте класс FileOpenPicker для загрузки отдельного файла в память приложения.In your OnLoadClick method, use the FileOpenPicker class to load a single file into your app's memory.

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)Use 3D Builder to convert to 3D Manufacturing Format (.3mf)

На этом этапе можно загрузить файл данных 3D в памяти приложения.At this point, you are able to load a 3D data file into your app's memory. Однако геометрические данные 3D могут быть представлены в самых разных форматах, не все из которых подходят для трехмерной печати.However, 3D geometry data can come in many different formats, and not all are efficient for 3D printing. В Windows 10 для всех задач трехмерной печати используются файлы типа 3D Manufacturing Format (.3mf).Windows 10 uses the 3D Manufacturing Format (.3mf) file type for all 3D printing tasks.

Примечание

Тип файлов 3MF поддерживает в том числе функциональные возможности, не описанные в этом руководстве.The .3mf file type offers more functionality than is covered in this tutorial. Подробнее о типе файлов 3MF и функциональных возможностях, предоставляемых производителям и потребителям трехмерных продуктов, см. в спецификации 3MF.To learn more about 3MF and the features it provides to producers and consumers of 3D products, see the 3MF Specification. Чтобы узнать, как использовать эти возможности с помощью API-интерфейсов Windows 10, ознакомьтесь с учебником Создание пакета 3MF.To learn how to utilize these features with Windows 10 APIs, see the Generate a 3MF package tutorial.

Приложение 3D Builder может открывать файлы наиболее распространенных 3D-форматов и сохранять их в виде 3MF-файлов.The 3D Builder app can open files of most popular 3D formats and save them as .3mf files. В этом примере, где тип файла может варьироваться, простейшим решением будет открыть приложение 3D Builder и предложить пользователю сохранить импортированные данные в виде 3MF-файла, а затем заново загрузить их.In this example, where the file type could vary, a very simple solution is to open the 3D Builder app and prompt the user to save the imported data as a .3mf file and then reload it.

Примечание

Помимо преобразования форматов файлов конструктор 3D Builder предоставляет простые инструменты для редактирования моделей, добавления данных о цвете и выполнения других операций печати, поэтому конструктор имеет смысл интегрировать в любые приложения, где используется трехмерная печать.In addition to converting file formats, 3D Builder provides simple tools to edit your models, add color data, and perform other print-specific operations, so it is often worth integrating into an app that deals with 3D printing.

    // 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";
    }
}

Восстановление данных модели для трехмерной печатиRepair model data for 3D printing

Не все данные трехмерной модели можно напечатать, даже в 3MF-файле.Not all 3D model data is printable, even in the .3mf type. Чтобы принтер мог правильно определить, какое пространство заполнять, а какое — оставлять пустым, печатаемые модели должны представлять собой цельную бесшовную структуру, иметь обращенные наружу нормали к поверхности и разностороннюю геометрию.In order for the printer to correctly determine what space to fill and what to leave empty, the model(s) to be printed must (each) be a single seamless mesh, have outward-facing surface normals, and have manifold geometry. С этим могут возникать самые разные проблемы, и обнаружить их в сложных формах весьма затруднительно.Issues in these areas can arise in a variety of different forms and can be hard to spot in complex shapes. К счастью, современные программные решения отлично справляются с задачей преобразования необработанных геометрических данных в доступные для печати трехмерные фигуры.However, modern software solutions are often adequate for converting raw geometry to printable 3D shapes. Этот процесс называется восстановлением модели и выполняется методом OnFixClick.This is known as repairing the model and will be done in the OnFixClick method.

Необходимо преобразовать файл трехмерных данных, чтобы реализовать интерфейс IRandomAccessStream, который затем можно использовать для создания объекта Printing3DModel.The 3D data file must be converted to implement IRandomAccessStream, which can then be used to generate a Printing3DModel object.

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 теперь устранены, и он готов к печати.The Printing3DModel object is now repaired and printable. С помощью метода SaveModelToPackageAsync назначьте модель объекту Printing3D3MFPackage, объявленному при создании класса.Use SaveModelToPackageAsync to assign the model to the Printing3D3MFPackage object that you declared when creating the class.

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

}

Выполнение задачи печати: создание обработчика TaskRequestedExecute printing task: create a TaskRequested handler

В дальнейшем, когда пользователю отображается диалоговое окно трехмерной печати и пользователь решает начать печать, приложению потребуется передать нужные параметры в конвейер трехмерной печати.Later on, when the 3D print dialog is displayed to the user and the user elects to begin printing, your app will need to pass in the desired parameters to the 3D print pipeline. API трехмерной печати вызывает событие TaskRequested.The 3D print API will raise the TaskRequested event. Необходимо написать метод для правильной обработки этого события.You must write a method to handle this event appropriately. Как всегда, тип метода обработчика должен совпадать с типом события: событие TaskRequested имеет параметры Print3DManager (ссылка на объект-отправитель) и объект Print3DTaskRequestedEventArgs, в котором хранится большая часть необходимой информации.As always, the handler method must be of the same type as its event: The TaskRequested event has parameters Print3DManager (a reference to its sender object) and a Print3DTaskRequestedEventArgs object, which holds most of the relevant information.

private void MyTaskRequested(Print3DManager sender, Print3DTaskRequestedEventArgs args) {

Основное назначение этого метода — использовать параметр args для отправки пакета Printing3D3MFPackage по конвейеру.The core purpose of this method is to use the args parameter to send a Printing3D3MFPackage down the pipeline. Тип Print3DTaskRequestedEventArgs имеет одно свойство: Request.The Print3DTaskRequestedEventArgs type has one property: Request. Оно имеет тип Print3DTaskRequest и представляет один запрос задания печати.It is of the type Print3DTaskRequest and represents one print job request. Его метод CreateTask позволяет программе отправлять корректную информацию для вашего задания печати и возвращает ссылку на объект Print3DTask, который был отправлен по конвейеру трехмерной печати.Its method CreateTask allows the program to submit the correct information for your print job, and it returns a reference to the Print3DTask object which was sent down the 3D print pipeline.

CreateTask имеет следующие входные параметры: string для имени задания печати, string для идентификатора используемого принтера и делегат Print3DTaskSourceRequestedHandler.CreateTask has the following input parameters: a string for the print job name, a string for the ID of the printer to use, and a Print3DTaskSourceRequestedHandler delegate. Делегат вызывается автоматически при создании события 3DTaskSourceRequested (за это отвечает API).The delegate is automatically invoked when the 3DTaskSourceRequested event is raised (this is done by the API itself). Важно отметить, что это делегат вызывается, когда инициируется задание печати, и отвечает за предоставление правильного пакета трехмерной печати.The important thing to note is that this delegate is invoked when a print job is initiated, and it is responsible for providing the right 3D print package.

Print3DTaskSourceRequestedHandler принимает один параметр — объект Print3DTaskSourceRequestedArgs, предоставляющий данные для отправки.Print3DTaskSourceRequestedHandler takes one parameter, a Print3DTaskSourceRequestedArgs object which provides the data to be sent. Один открытый метод этого класса — SetSource — принимает печатаемый пакет.The one public method of this class, SetSource, accepts the package to be printed. Реализуйте делегат Print3DTaskSourceRequestedHandler следующим образом.Implement a Print3DTaskSourceRequestedHandler delegate as follows.

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

Затем вызовите CreateTask, используя только что определенный делегат sourceHandler:Next, call CreateTask, using the newly-defined delegate, sourceHandler.

// 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 назначается объявленной в начале переменной класса.The returned Print3DTask is assigned to the class variable declared in the beginning. Теперь при необходимости можно использовать эту ссылку для обработки определенных событий, создаваемых этой задачей.You can now (optionally) use this reference to handle certain events thrown by the task.

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

Примечание

Необходимо реализовать методы Task_Submitting и Task_Completed, если требуется зарегистрировать их для этих событий.You must implement a Task_Submitting and Task_Completed method if you wish to register them to these events.

Выполнение задачи печати: открытие диалогового окна трехмерной печатиExecute printing task: open 3D print dialog

Необходимо финальный фрагмент кода, который открывает диалоговое окно трехмерной печати.The final piece of code needed is that which launches the 3D print dialog. Как и в обычном диалоговом окне печати, в диалоговом окне трехмерной печати находится ряд параметров, которые задаются в последний момент. Здесь же можно выбрать принтер для печати (подключенный через USB или по сети).Like a conventional printing dialog window, the 3D print dialog provides a number of last-minute printing options and allows the user to choose which printer to use (whether connected by USB or the network).

Зарегистрируйте метод MyTaskRequested с событием TaskRequested.Register your MyTaskRequested method with the TaskRequested event.

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, который выведет диалоговое окно трехмерной печати в окне текущего приложения.After registering your TaskRequested event handler, you can invoke the method ShowPrintUIAsync, which brings up the 3D print dialog in the current application window.

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

Рекомендуется отменять регистрацию обработчиков событий, как только приложение восстанавливает контроль над процессом.Finally, it is a good practice to de-register your event handlers once your app resumes control.

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

Создание пакета 3MFGenerate a 3MF package
Пример трехмерной печати UWP3D printing UWP sample