View3D

View3D

View3D は、方向性のない 3 次元ビューです。パース ビューとアイソメ ビューの 2 種類の 3D ビューがあり、Revit ユーザ インタフェースでは直交投影ビューとも呼ばれます。違いは、投影光線の関係に基づいています。View3D.IsPerspective プロパティは、3D ビューがパース ビューまたはアイソメ ビューであるかどうかを示します。

パース ビュー

次の図は、パースビューを作成する方法を示しています。

図 96: パース投影

  • 直線投影光線は、モデルの各点を通過して投影面と交差し、投影内容を形成します。
  • ワールド座標系からビュー面への変換を簡単に行うために、座標系の表示はビューアに基づいています。
  • 原点は View.Origin プロパティで表され、ビューアの位置です。
  • ビューアのワールド座標は、ViewOrientation3D.EyePosition プロパティ(View3D.GetOrientation()から取得)を使用して取得されます。したがって、3D ビューでは、View.Origin は対応する ViewOrientation3D.EyePosition と常に等しくなります。
  • 上の図で示すように、座標系の表示は、次のように決定されます。
    • X 軸は View.RightDirection によって決定されます。
    • Y 軸は View.UpDirection によって決定されます。
    • Z 軸は View.ViewDirection によって決定されます。
  • ビューの方向は、3D 空間ではターゲットの点からビューアまで、および画面空間では画面からビューアまでです。

静的メソッドである View3D.CreatePerspective()メソッドを使用して、新しいパース ビューを作成できます。

コード領域: View3D.CreatePerspective()

public static View3D View3D.CreatePerspective (Document document, ElementId viewFamilyTypeId;

viewFamilyTypeId パラメータは、3 次元の ViewType である必要があります。

次のコードサンプルは、パース 3D ビューを作成する方法を示しています。

コード領域: パース 3D ビューを作成

// Find a 3D view type
IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(document).OfClass(typeof(ViewFamilyType))
                                                let type = elem as ViewFamilyType
                                                where type.ViewFamily == ViewFamily.ThreeDimensional
                                                select type;
// Create a new Perspective View3D
View3D view3D = View3D.CreatePerspective(document, viewFamilyTypes.First().Id);
if (null != view3D)
{
    // By default, the 3D view uses a default orientation.
    // Change the orientation by creating and setting a ViewOrientation3D 
    XYZ eye = new XYZ(0, -100, 10); 
    XYZ up = new XYZ(0, 0, 1); 
    XYZ forward = new XYZ(0, 1, 0); 
    view3D.SetOrientation(new ViewOrientation3D(eye, up, forward));

    // turn off the far clip plane with standard parameter API
    Parameter farClip = view3D.LookupParameter("Far Clip Active");
    farClip.Set(0);
}

パース ビューのトリミング ボックスは、ビューアの位置にある頂点を持つ角錐の一部です。2 つの平行なクリップ面の間のジオメトリです。トリミング ボックスは、クリップ アウトされ、ビュー平面に投影されるモデルの部分をバインドします。

  • トリミング ボックスは、View.CropBox プロパティによって表されます。これは BoundingBoxXYZ オブジェクトを返します。
  • CropBox.Min および CropBox.Max 点が、前の図で示されています。パースビューの CropBox.Min 点は、トリミング ボックスのクリップ平面を後方のクリップ面に投影して生成します。

トリミング ボックス座標は、表示されている座標系に基づいています。CropBox.Min と CropBox.Max をワールド座標系に変換するには、Transform.OfPoint()を使用します。変換の詳細は、「Geometry.Transform」(「ジオメトリ」)を参照してください。

投影面および前方と後方のクリップ平面は、ビュー方向に垂直になります。CropBox.Max と CropBox.Min の間の線分がビュー方向に平行になります。これらの係数を使用して、トリミング ボックス ジオメトリを計算できます。

図 97: パース 3D ビュー

前の図では、トリミングした後に画面に投影面が表示されています。トリミング領域は、投影面とトリミング ボックスの長方形の交差部分になります。

  • ジオメトリ情報は View.CropRegion プロパティを使用して取得されます。このプロパティは、BoundingBoxUV インスタンスを返します。
  • View.OutLine.Max プロパティは、右上隅を示します。
  • View.OutLine.Min プロパティは、左下隅を示します。
  • トリミング ボックスのように、トリミング領域の座標は表示している座標系に基づいています。次の式は等しくなっています。
View.CropBox.Max.X(Y) / View.OutLine.Max.X(Y) == View.CropBox.Min.X(Y) / View.OutLine.Min.X(Y) 

オブジェクトのパース ビュー投影のサイズは、投影の中心はオブジェクトからの距離の逆数が異なるため、スケール、パースビューに対しても意味があります。パース 3D ビューの Scale プロパティは常に 0 (ゼロ)を返します。

アイソメ ビュー

新しいアイソメ ビューは、静的 View3D.CreateIsometric()メソッドを使用して作成できます。

図 98: 平行投影

アイソメ ビューは、モデルを光線に対して垂直な平面に投影することで、平行投影光線を使用して生成されます。表示される座標系は、パース ビューに似ていますが、トリミング ボックスは投影光線に対して平行または垂直な平面を持つ平行 6 面体です。View.CropBox プロパティは、座標が表示される座標系に基づいた 2 つの対角コーナーを示します。

図 99: ビュー平面のウィンドウを画面のビューポートにスケール

モデルはビュー平面に投影され、次に画面にスケールされます。View.Scale プロパティは、実際のモデル サイズの比率をビュー サイズに表します。関連する式は次のとおりです。

View.CropBox.Max.X(Y) / View.OutLine.Max.X(Y) == View.CropBox.Min.X(Y) / View.OutLine.Min.X(Y) == View.Scale 

コード領域: View3D.CreateIsometric()

public static View3D View3D.CreateIsometric (Document document, ElementId viewFamilyTypeId;

viewFamilyTypeId パラメータは、3 次元の ViewType である必要があります。Revit は次を決定します。

  • ビューアの位置。
  • ビューの方向を使用して、表示する座標系を作成する方法。
  • モデルをトリミングするためにトリミング ボックスを作成する方法。

ビューが作成されると、トリミング ボックスのサイズを変更して、モデルのさまざまな部分を表示できます。既定の方向を変更することもできます。API は、表示する座標系の変更をサポートしていません。

次のコードサンプルは、アイソメ 3D ビューを作成する方法を示しています。

コード領域: アイソメ 3D ビューを作成

// Find a 3D view type

IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(document).OfClass(typeof(ViewFamilyType))
                                              let type = elem as ViewFamilyType
                                              where type.ViewFamily == ViewFamily.ThreeDimensional
                                              select type;

// Create a new View3D
View3D view3D = View3D.CreateIsometric(document, viewFamilyTypes.First().Id);
if (null != view3D)
{
    // By default, the 3D view uses a default orientation.
    // Change the orientation by creating and setting a ViewOrientation3D 
    XYZ eye = new XYZ(10, 10, 10);
    XYZ up = new XYZ(0, 0, 1);
    XYZ forward = new XYZ(0, 1, 0);

    ViewOrientation3D viewOrientation3D = newViewOrientation3D(eye, up, forward);
    view3D.SetOrientation(viewOrientation3D);
}

3D ビュー SectionBox

各ビューにはトリミング ボックスがあります。トリミング ボックスは、ビューで投影、表示するモデルの部分にフォーカスしています。3D ビューの場合、断面ボックスという名前の別のボックスがあります。

  • 断面ボックスは、3D ビューに表示されるモデルの部分を決定します。
  • 断面ボックスを使用して、3D モデルの表示部分をクリップします。
  • ボックスの外側の部分は、トリミング ボックス内にある場合でも表示されません。
  • 断面ボックスはモデルを使用して回転、移動できるトリミング ボックスとは異なります。

断面ボックスはモデルが大きい場合に特に便利です。たとえば、大きなビルをレンダリングする場合は断面ボックスを使用します。断面ボックスは計算に使用されるモデルの部分を制限します。断面ボックスを表示するには、3D ビューの[要素プロパティ]ダイアログ ボックスで、[範囲]セクションの[断面図]を選択します。IsSectionBoxActive プロパティを使用して設定することもできます。下の例では、アクティブなビューが 3D ビューである場合に、断面ボックスがアクティブになっているかどうかを設定します。

コード領域: 断面ボックスを表示/非表示

private void ShowHideSectionBox(UIDocument document, bool active)
{
    if (document.ActiveView is View3D)
    {
        View3D view3d = document.ActiveView as View3D;
        view3d.IsSectionBoxActive = active;
    }
}

図 100: 断面ボックス

ボックス範囲を取得して変更するには、View3D.GetSectionBox()メソッドと View3D.SetSectionBox()メソッドを使用します。一部の場合では、View3D.SetSectionBox()を呼び出すと、副作用が発生する場合があります。プロパティを特定の値に設定すると、ボックスの容量を変更したり、ビューに表示できます。断面ボックスを表示しないようにするには、IsSectionBoxActive プロパティを false に設定します。

次のコード サンプルは、断面ボックスの範囲を変更する方法を示しています。

コード領域: 断面ボックスの範囲を変更

private void ExpandSectionBox(View3D view)
{
    // The orignial section box
    BoundingBoxXYZ sectionBox = view.GetSectionBox();

    // Expand the section box
    Autodesk.Revit.DB.XYZ deltaXYZ = sectionBox.Max - sectionBox.Min;
    sectionBox.Max += deltaXYZ / 2;
    sectionBox.Min -= deltaXYZ / 2;

    //After reseting the section box, it will be shown in the view.
    //It only works when the Section Box is active
    view.SetSectionBox(sectionBox);
}

GetSectionBox()メソッドが返す BoundingBoxXYZ の最大点と最小点の座標は、グローバル座標ではありません。最大点および最小点の座標をグローバル座標に変換するには、BoundingBoxXYZ.Transform プロパティから取得した変換からそれぞれ点を変換する必要があります。

コードの領域: 最大点および最小点の座標をグローバル座標に変換

private void ConvertMaxMinToGlobal(View3D view, out XYZ max, out XYZ min)
{
    BoundingBoxXYZ sectionbox = view.GetSectionBox();
    Transform transform = sectionbox.Transform;
    max = transform.OfPoint(sectionbox.Max);
    min = transform.OfPoint(sectionbox.Min);
}

ビューをロックする

View3D クラスには、Revit ユーザ インタフェースで使用可能なロック機能に対応するメソッドとプロパティがあります。

View3D.SaveOrientationAndLock()メソッドは、方向を保存してビューをロックし、View3D.RestoreOrientationAndLock()は、ビューの方向を復元してこれをロックします。View3D.Unlock()は、ビューが現在ロックされている場合は、ビューのロックを解除します。IsLocked プロパティは、3D ビューが現在ロックされているかどうかを返します。