Unreal Engineにdxf形式のサポートを追加する

画像



こんにちは私の名前はドミトリーです。 私は趣味としてアンリアルエンジンでコンピューターゲームを作っています。 今日は、Unreal Engineでdxfファイルのサポートを追加する方法を説明します。 (記事の最後にいつものように情報源)。



DXFは、オートデスクが開発したオープンベクターグラフィックス形式です。 開かれているため、この形式はベクターグラフィックスの膨大な数のエディターによってサポートされています。







それでは、インポートしたファイルに関する情報を含むクラスを作成することから始めましょう。

UCLASS(BlueprintType) class DXFPLUGINRUNTIME_API UDXFSketch : public UObject { GENERATED_BODY() public: #if WITH_EDITORONLY_DATA UPROPERTY(VisibleAnywhere, Instanced, Category = ImportSettings) class UAssetImportData* AssetImportData; virtual void PostInitProperties() override; #endif // WITH_EDITORONLY_DATA UPROPERTY(VisibleAnywhere, BlueprintReadOnly) TArray<FDXFLayer> Layers; UPROPERTY() float DXFBackGroundSize; };
      
      





ここで、UAssetImportDataオブジェクトをクラスに追加したことに注意してください。このオブジェクトにはソースファイルに関する情報が含まれ、アセットを再インポートするために必要です。 PostInitProperties()メソッドは、このクラスのインスタンスを作成します。 FDXFLayerオブジェクトの配列には、実際にはdxfファイルからのすべての情報が含まれています。



作成されたアセットは、ファクトリクラスを作成する必要があります。 この記事で新しいアセットの作成について詳しく読んでください

 UCLASS() class UDXFSketchFactory : public UFactory, public FReimportHandler { GENERATED_UCLASS_BODY() // UFactory interface virtual UObject* FactoryCreateBinary(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const uint8*& Buffer, const uint8* BufferEnd, FFeedbackContext* Warn) override; virtual bool CanCreateNew() const override; // End of UFactory interface // Begin FReimportHandler interface virtual bool CanReimport(UObject* Obj, TArray<FString>& OutFilenames) override; virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override; virtual EReimportResult::Type Reimport(UObject* Obj) override; virtual int32 GetPriority() const override; // End FReimportHandler interface bool LoadFile(UDXFSketch* Sketch, const uint8*& Buffer, const uint8* BufferEnd); };
      
      





インポートされたアセットと通常のアセットのファクトリクラスの主な違いは、FactoryCreateNewではなくFactoryCreateBinaryメソッドを使用することです。 このメソッドには、パラメーターの中でも特に、バイトの配列(インポートされたファイル)への参照と、この配列の末尾へのポインターが与えられます。



そしてもちろん、コンストラクター:



 UDXFSketchFactory::UDXFSketchFactory(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { SupportedClass = UDXFSketch::StaticClass(); Formats.Add(TEXT("dxf;DXF")); bCreateNew = false; bEditorImport = true; }
      
      





ファイルを再インポートできるように、FReimportHandlerクラスも基本クラスに追加する必要があります。これにより、Reimportメソッドが追加されます。



LoadFileメソッドの目的も明確です。 ファイルを解析するための車輪を再発明しないために、私はribbonsoftのdxflibライブラリを使用しました。



資産がインポートされました。 ただし、インポートされたファイルの内容を理解するには、アセットのエディターを作成するとよいでしょう。 (アセットのエディターの作成について詳しくは、 こちらをご覧ください )。 前の記事を完全に再説明するのではなく、必要なタブ(この場合はデータを描画するビューポートタブとプロパティパネルのタブ)を作成するFAssetEditorToolkitから派生オブジェクトを作成する必要があると言うだけです。 プロパティパネルの作成は既に検討されています。 それでは、ビューポートについて話しましょう。



[ビューポート]タブで、SDXFEditorViewportオブジェクトを作成します

 class SDXFEditorViewport : public SCompoundWidget { public: SLATE_BEGIN_ARGS(SDXFEditorViewport) { } SLATE_ARGUMENT(TWeakPtr<FDXFAssetEditor>, CustomEditor) SLATE_END_ARGS() public: void Construct( const FArguments& InArgs); TSharedPtr<FSceneViewport> GetViewport( ) const; TSharedPtr<SViewport> GetViewportWidget( ) const; TSharedPtr<SScrollBar> GetVerticalScrollBar( ) const; TSharedPtr<SScrollBar> GetHorizontalScrollBar( ) const; void UpdateScreen(); protected: TSharedRef<SWidget> GenerateViewOptionsMenu() const; private: // Callback for clicking the View Options menu button. FReply HandleViewOptionsMenuButtonClicked(); // Callback for the horizontal scroll bar. void HandleHorizontalScrollBarScrolled( float InScrollOffsetFraction ); // Callback for getting the visibility of the horizontal scroll bar. EVisibility HandleHorizontalScrollBarVisibility( ) const; // Callback for the vertical scroll bar. void HandleVerticalScrollBarScrolled( float InScrollOffsetFraction ); // Callback for getting the visibility of the horizontal scroll bar. EVisibility HandleVerticalScrollBarVisibility( ) const; // Callback for clicking an item in the 'Zoom' menu. void HandleZoomMenuEntryClicked( double ZoomValue ); // Callback for getting the zoom percentage text. FText HandleZoomPercentageText( ) const; // Callback for changes in the zoom slider. void HandleZoomSliderChanged( float NewValue ); // Callback for getting the zoom slider's value. float HandleZoomSliderValue( ) const; void HandleLayerActive(int Num); void HandleAllLayersActive(); private: // Pointer back to the Asset editor tool that owns us. TWeakPtr<FDXFAssetEditor> AssetEditor; // Level viewport client. TSharedPtr<class FDXFEditorViewportClient> ViewportClient; // Slate viewport for rendering and IO. TSharedPtr<FSceneViewport> Viewport; // Viewport widget. TSharedPtr<SViewport> ViewportWidget; // Vertical scrollbar. TSharedPtr<SScrollBar> TextureViewportVerticalScrollBar; // Horizontal scrollbar. TSharedPtr<SScrollBar> TextureViewportHorizontalScrollBar; // Holds the anchor for the view options menu. TSharedPtr<SMenuAnchor> ViewOptionsMenuAnchor; };
      
      





これはインターフェイスオブジェクトであり、すべてのインターフェイス要素(スライダーメニューなど)を作成し、さらに、実際にファイルからロードされたプリミティブが描画されるFDXFEditorViewportClientオブジェクトを作成します。



 class FDXFEditorViewportClient: public FViewportClient { public: /** Constructor */ FDXFEditorViewportClient(TWeakPtr<FDXFAssetEditor> InTextureEditor, TWeakPtr<SDXFEditorViewport> InTextureEditorViewport); /** FViewportClient interface */ virtual void Draw(FViewport* Viewport, FCanvas* Canvas) override; virtual bool InputKey(FViewport* Viewport, int32 ControllerId, FKey Key, EInputEvent Event, float AmountDepressed = 1.0f, bool bGamepad = false) override; virtual UWorld* GetWorld() const override { return nullptr; } /** Returns the ratio of the size of the Texture texture to the size of the viewport */ float GetViewportVerticalScrollBarRatio() const; float GetViewportHorizontalScrollBarRatio() const; void SetZoom(double ZoomValue); void ZoomIn(); void ZoomOut(); double GetZoom() const; DrawVar Vars; //variables for drawning viewport private: /** Updates the states of the scrollbars */ void UpdateScrollBars(); /** Returns the positions of the scrollbars relative to the Texture textures */ FVector2D GetViewportScrollBarPositions() const; private: /** Pointer back to the Texture editor tool that owns us */ TWeakPtr<FDXFAssetEditor> AssetEditor; /** Pointer back to the Texture viewport control that owns us */ TWeakPtr<SDXFEditorViewport> AssetEditorViewport; };
      
      







実際にはエディターが作成されますが、もう少し些細なことがあります。 Unreal Engineには、サムネイルなどのコンセプトがあります。これは、アセットアイコンの代わりにコンテンツブラウザに表示される小さな画像です。 このサムネイルを作成するには、UThumbnailRendererから派生したオブジェクトを作成する必要があります。

 UCLASS() class UDXFThumbnailRenderer : public UThumbnailRenderer { GENERATED_BODY() // Begin UThumbnailRenderer Object virtual void GetThumbnailSize(UObject* Object, float Zoom, uint32& OutWidth, uint32& OutHeight) const override; virtual void Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* Viewport, FCanvas* Canvas) override; // End UThumbnailRenderer Object };
      
      





このオブジェクトには、実際にサムネイルを描画するDrawメソッドがあります。 もちろん、このオブジェクトを作成したら、登録する必要があります。

 void FDXFPluginEditor::StartupModule() { // Register DXFSketch AssetActions TSharedRef<IAssetTypeActions> Action = MakeShareable(new FDXFSketchAssetActions); IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get(); AssetTools.RegisterAssetTypeActions(Action); CreatedAssetTypeActions.Add(Action); //Registrate ToolBarCommand for costom graph FDXFToolBarCommandsCommands::Register(); //Registrate Thumbnail render UThumbnailManager::Get().RegisterCustomRenderer(UDXFSketch::StaticClass(), UDXFThumbnailRenderer::StaticClass()); }
      
      





サムネイルレンダリングはどこから来たのですか? そのような場所として、FDXFAssetEditorオブジェクトのHandleReimportManagerPostReimportメソッドを選択しました。このメソッドは、ファイルをインポートした後に実行されます。

 void FDXFAssetEditor::HandleReimportManagerPostReimport(UObject* InObject, bool bSuccess) { TArray<UObject*> SelectedObjects; SelectedObjects.Add(InObject); AssetData = CastChecked<UDXFSketch>(InObject); if (bSuccess) { PropertyEditor->SetObjects(SelectedObjects); } DXFViewport->UpdateScreen(); FThumbnailRenderingInfo* RenderInfo = GUnrealEd->GetThumbnailManager()->GetRenderingInfo(AssetData); if (RenderInfo != NULL) { RenderInfo->Renderer; //Render Thumbnail } }
      
      





画像



しかし、インポートしたアセットを使用するにはどうすればよいですか? 残念ながら、dxfファイルをテクスチャとしてオーバーレイすると失敗します。 ただし、たとえば、ポイントをロードし、その座標を使用してオブジェクトを配置できます。 または、いわゆるSplineMeshを作成し、線に沿って引き伸ばします。 これまでのところ、プラグインはライン、閉じたパス、およびポイントを認識します(ブラシを使用してキャンバスをadobe illustratorに挿入すると、これらのポイントは10ポイントで構成されるスプラインになります)。



実際にはそれだけです。 プロジェクトをプラグインとして作成したので、プロジェクトにdxfサポートを追加するには、そのディレクトリにPluginsフォルダーを作成し、そこにDXFPluginフォルダーをドロップします。VSのプラグインソースを確認するには、古いVSプロジェクトファイルを削除して新しいものを生成する必要があります。 (プラグインの詳細については、 こちらをご覧ください



ソースを含むプロジェクトは こちら



All Articles