Building Coder(Revit 二次開發) - UIView 和 Windows 設備座標

原文鏈接:UIView and Windows Device Coordinates

Revit 2013 API 中新提供了一個新的視圖 API,具體地說是提供一個新類 UIView。UIView 代表一個視圖窗口,讓我們可以通過程序來移動、縮放和決定窗口平鋪時的大小等等一系列操作。也爲我們從其它可視化環境切換回視圖提供了可能。


UIView 目前只公開了三個方法:
1. GetWindowRectangle:使用窗口座標系返回視圖的繪圖區域的矩形座標;
2. GetZoomCorners:使用 Revit 模型座標系返回視圖矩形的四個角座標;
3. ZoomAndCreateRectangle:將視圖縮放並居中到一個指定的矩形區域中

UIView 是 Revit API 第一次提供了窗口座標和 Revit 座標之間的關聯,開啓了 Revit 全新的交互方式。比方說:在 Idling 事件中顯示自定義的 Tooltip ……

值得一提的是,目前 Revit API 只能通過 UIDocument.GetOpenUIViews() 方法獲取 UIView 對象。由於每個 UIView 都是和一個視圖綁定的,所以我們可以通過 UIView.ViewId 來判斷某個 UIView 是屬於哪個視圖的。


我創建了一個簡單的外部命令 WinCoords 來測試 UIView。它的功能如下:
- 獲取當前視圖
- 獲取當前文檔的所有 UIView 對象
- 找到屬於當前視圖的 UIView 對象
- 讀取當前 UIView 的窗口和 Revit 座標
- 調用 ZoomAndCenterRectangle 將 Revit 模型放大 10%

public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements )
{
	UIApplication uiapp = commandData.Application;
	UIDocument uidoc = uiapp.ActiveUIDocument;
	Document doc = uidoc.Document;
	View view = doc.ActiveView;
	UIView uiview = null;
	IList<UIView> uiviews = uidoc.GetOpenUIViews();

	foreach( UIView uv in uiviews )
	{
		if( uv.ViewId.Equals( view.Id ) )
		{
			uiview = uv;
			break;
		}
	}

	Rectangle rect = uiview.GetWindowRectangle();
	IList<XYZ> corners = uiview.GetZoomCorners();
	XYZ p = corners[0];
	XYZ q = corners[1];

	string msg = string.Format( 
		"UIView Windows rectangle: {0}; zoom corners: {1}-{2}; click Close to zoom in by 10%.", 
		RectangleString( rect ), PointString( p ), PointString( q ) );

	TaskDialog.Show( "WinCoords", msg );

	// Calculate new zoom corners to 
	// zoom in by 10%, i.e. the two corners
	// end up at 0.45 of their previous
	// distance to the centre point.

	XYZ v = q - p;
	XYZ center = p + 0.5 * v;
	v *= 0.45;
	p = center - v;
	q = center + v;

	uiview.ZoomAndCenterRectangle( p, q );

	return Result.Succeeded;
}

注意:窗口座標系中 Y 方向和通常的座標系中相反。顯示矩形座標的 RectangleString() 方法代碼如下:

/// <summary>
/// 返回一個表示矩形區域的字符串,格式是(左上角)-(右下角)
/// 窗口座標系的 Y 方向是相反方向
/// </summary>
static string RectangleString( Rectangle r )
{
	return string.Format( "({0},{1})-({2},{3})", r.Left, r.Top, r.Right, r.Bottom );
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章