20200213のC#に関する記事は3件です。

Unity勉強日誌~ブレンドシェイプ操作方法その①

はじめに。

ゲーム作ってみたいな~と思い、つい先日からUnityをさわり始めましたHITOMI2236です。今回ブレンドシェイプについて調べたのでここに記録しようと思います。個人用のメモですが、もし同じところで迷っている人がいたら、時間短縮のために読んでくれたら幸いです。

1 . ブレンドシェイプのモデルについて

ブレンドシェイプ検証用にMayaで簡単なモデルを作りました。HumanIKの各関節部分にCubeを配置しただけのモデルです。頭部の部分に簡単なブレンドシェイプをつけており、わかりやすくするために名前を「face_object」に変更しています。
blendShape_01_01.png
blendShape_01_01.png

これをFBXで書き出します。書き出す時にはもちろんですがアニメーション項目ないのブレンドシェイプのチェックボックスをオンにしましょう。私は結構忘れます。

書き出したFBXをUnityにドラッグアンドドロップしてPrefab化し、Hierarchyに追加します。

ブレンドシェイプがついてるオブジェクトを確認してみるとInspecterに「Skinned Mesh Render」という項目が表示されているのがわかります。その中にBlendShapesという項目があり、どうやらこの数値を増やすと形が変形するようです。

blendShape_01_02.png

2 . ブレンドシェイプを制御するプログラム。

モデルの名前は「blendShapeCharacter」,
ブレンドシェイプ情報を持っているオブジェクト名は「face_object」です。
「face_object」が持っているブレンドシェイプの名前は「blendShape1.blendAction」です。

skinShape.rb
using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class blenderShapeControll : MonoBehaviour {
    public GameObject head;
    public SkinnedMeshRenderer skinnedMeshRenderer;
    private float m_weight;
    private int m_Index;


    void Start() {

        m_weight = 0;
        head = GameObject.Find("blendShapeCharacter/face_object");
        skinnedMeshRenderer = head.GetComponent<SkinnedMeshRenderer>();
        m_Index = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.blendAction");

    }

    void Update() {

        if (Input.GetKey(KeyCode.A))
        {
            if (m_weight == 0) {
                m_weight = 100;
            } else {
                m_weight = 0;
            }
            skinnedMeshRenderer.SetBlendShapeWeight(m_Index, m_weight);
        } 
    }
}

Aボタンを押すとブレンドシェイプが100と0に切り替わるシンプルなプログラムです。

GameObject.Find("blendShapeCharacter/face_object");

ここでブレンドシェイプの情報を持っているオブジェクトを検索して、

skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.blendAction");

ここでそのオブジェクトが持っているスキンメッシュのインデックスを取得しているようです.

skinnedMeshRenderer.SetBlendShapeWeight(index, weight);

SetBlendShapeWeightで対象のウェイトを操作する。
以上のような手順?になりました。

最後に

多分クラス化しようと考えているので、フェイシャルのブレンドやインデックスの一覧取得方法など調べてみようかなと考えています。

趣味で3D作品を作っています。もしよければ見て上げてください。星つけてくれたら嬉しいな!
そして、フレンドになって技術共有しましょう!
sketchfab

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Radzen.BlazorのDatePickerでカレンダーダイアログ表示する

Radzen.BlazorのDatePickerをダイアログで表示する

はじめに

<本記事の対象者>
Blazor(ブレイザー)を始めたけど、ダイアログ表示&返却がうまく動かないひと

<記事概要>
Radzen.Blazorは非常に強力なフロント側のフレームワークを提供してくれますが、DialogServiceまわりが扱いにくいと感じたので、通常のEventCallbackで結果を返すやり方の説明です。
参考URL:https://blazor.radzen.com/dialog

開発環境

Visual Studio 2019 v16.4.5(Bootstrap v4.3.1)
Radzen.Blazor v2.1.20

セットアップ

  1. Visual Studio 2019のセットアップ
    https://docs.microsoft.com/ja-jp/visualstudio/install/install-visual-studio?view=vs-2019

  2. Blazorプロジェクトの作成手順
    [ファイル] - [新規作成] - [プロジェクト...] で新しいプロジェクトを作成する。
    20200213_1.jpg
    20200213_2.jpg
    20200213_3.JPG
    作成すると以下の構成でソリューションが作成されます。
    20200213_4.JPG

  3. Radzen.Blazorのセットアップ
    https://blazor.radzen.com/get-started

  4. 実行
     【F5】でビルド実行されます。
     レガシーEdgeは対応していないので最新Edgeをお勧めします。Chromeでも動きますが、Edgeの方が速い気がします。
    20200213_5.JPG

やり方

デフォルト構成の変更

NavMenu.razorを変更し、カレンダー画面を呼べるようにします。
25行目に下記を挿入する。

NavMenu.razor
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="calendar">
                <span class="oi oi-calendar" aria-hidden="true"></span> Calendar
            </NavLink>
        </li>

新規ファイルの追加

以下の2つを追加します。
・Calendar.razor : カレンダー画面(上記のナビメニューの遷移先)
・CalendarDialog.razor : カレンダー画面上のボタンを押して表示するカレンダーダイアログ画面

Calendar.razor
@page "/calendar"

<h3>Calendar</h3>

<div>日付:@CurrentDatetimePrint</div>

<RadzenButton Text="ダイアログ表示" Click="RadzenButton_Click"></RadzenButton>

<CalendarDialog @ref="calendarDialog" currentDatetime="_currentDatetime" OnSelected="CalendarDialog_Selected"></CalendarDialog>

@code {

    private CalendarDialog calendarDialog { get; set; }

    private DateTime _currentDatetime { get; set; } = DateTime.Now;

    public string CurrentDatetimePrint
    {
        get
        {
            return string.Format("{0}", _currentDatetime.ToString("yyyyMMdd"));
        }
    }

    private void RadzenButton_Click()
    {
        calendarDialog.Open();
    }

    private void CalendarDialog_Selected(DateTime result)
    {
        _currentDatetime = result;
    }

}
CalendarDialog.razor
<div class="modal @ModalClass" tabindex="-1" role="dialog" style="display:@ModalDisplay">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-body">
                <RadzenDatePicker TValue="DateTime" Inline="true" Change="@(args => Change(args, "Calendar", "MM/dd/yyyy"))" />
            </div>
            <div class="modal-footer">
                <button @onclick="OnClickOK">OK</button>
                <button @onclick="OnClickCancel">Cancel</button>
            </div>
        </div>
    </div>
</div>

@if (ShowBackdrop)
{
    <div class="modal-backdrop fade show"></div>
}

@code {

    [Parameter]
    public DateTime currentDatetime { get; set; } = DateTime.Now;
    [Parameter]
    public EventCallback<DateTime> OnSelected { get; set; }

    private DateTime _resultDatetime;

    public string ModalDisplay = "none;";
    public string ModalClass = "";
    public bool ShowBackdrop = false;

    public void Open()
    {
        ModalDisplay = "block;";
        ModalClass = "Show";
        ShowBackdrop = true;
        StateHasChanged();
    }

    public void Close()
    {
        ModalDisplay = "none";
        ModalClass = "";
        ShowBackdrop = false;
        StateHasChanged();
    }

    DateTime calendarDialogResult = DateTime.Now;

    void Change(DateTime? value, string name, string format)
    {
        _resultDatetime = (DateTime)value;
        StateHasChanged();
    }

    private void OnClickOK()
    {
        OnSelected.InvokeAsync(_resultDatetime);
        Close();
        StateHasChanged();
    }

    private void OnClickCancel()
    {
        OnSelected.InvokeAsync(currentDatetime);
        Close();
        StateHasChanged();
    }

}

ポイントとしては、
「<div class="modal ~」のところはBootstrapを使用し、modal-bodyに「RadzenDatePicker」を埋め込んでいます。
なのでUIがどっちつかずになっているのがデメリットです。

デモ

20200213_10.gif

終わりに

Webシステム開発では、WindowsFormみたいにダイアログが別画面に分かれてないので不便でした。Blazorはダイアログをコンポーネント化して、Javascript構文なしで書けるため、別画面として捉えて開発することができるのが良いですね。

また、Blazorは半年以前の個人サイト情報はあまり参考にならないくらい仕様変更が発生しています。
備忘録としてザックリ書きましたが、今後も仕様が変わる可能性があるため、あとから見直します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iTextSharpでPDFの綴じ方向を取得する方法

iTextSharpでPDFの綴じ方向を取得するには、ViewerPreferencesを取得します。
Java版のiTextも似たようなものだと思います。

using iTextSharp.text.pdf;

var pr = new PdfReader(stream);
var vp = iTextSharp.text.pdf.intern.PdfViewerPreferencesImp.GetViewerPreferences(pr.Catalog).GetViewerPreferences();
this.Direction = Directions.Default;
if (vp.Contains(PdfName.DIRECTION))
{
    var name = vp.GetAsName(PdfName.DIRECTION);
    if (name == PdfName.R2L)
    {
        this.Direction = Directions.R2L;
    }
    else if (name == PdfName.L2R)
    {
        this.Direction = Directions.L2R;
    }
}
pr.Close();

(参考元:http://itext.2136553.n4.nabble.com/Using-getSimpleViewerPreferences-td2167775.html)

Viewer Preferenceを取得する部分は、iTextSharp.text.pdf.intern.PdfViewerPreferencesImp.GetViewerPreferences(pr.Catalog).GetViewerPreferences();
なんだこれ…。

綴じ方向とは、Adobe ReaderのCtrl+Dで確認できる設定です。
image.png
注意点として、

  • ここで「綴じ方: 左」と表示されていても実際にはDirectionが設定されていない場合がある
  • 実際には右綴じなのに「綴じ方: 左」と表示されるファイルが結構ある。

一方で取得ではなく設定したいならこんな感じです。

using iTextSharp.text.pdf;

var org = new PdfReader(file);
using (var outfile = new System.IO.FileStream(TemporaryFile, System.IO.FileMode.CreateNew))
{
    var st = new PdfStamper(org, outfile);
    st.AddViewerPreference(PdfName.DIRECTION, R2L ? PdfName.R2L : PdfName.L2R);
    st.Close();
}
org.Close();

(参考元:https://kiwanami.hatenadiary.org/entry/20101215/1292400269)

Viewer Preferencesに関してはこの辺りが参考になりそうです。
とりあえず綴じ方向以外はあまり有用そうには見えませんね。

ちなみに使っているのはLGPL版の4.1.6です。
AGPLに移行後の最新版は知りませんが、非ジェネリック版のCollectionを使っていたりAPIが直感的じゃなかったりで使いづらいですね。
上のとか、PdfReader.ViewerPreferencesにgetアクセサ追加とかが順当ですよね。
実際のPdfReader.ViewerPreferencesはsetアクセサしかない上、int型です。
まぁJava由来ですからね。PDFの仕様自体が難解ですし。

ソースコードは開発中のBookViewer後継アプリBookViewerApp3のものです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む