revit坐标转换,空间三维坐标点(即revit的世界坐标) ,与视图窗口坐标(以视图窗口客户区左上角为原点,非屏幕左上角)的互相转换。
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
[Journaling(JournalingMode.NoCommandData)]
class TTestCmd : IExternalCommand
{
protected Application m_app;
protected Document m_doc;
protected UIApplication m_uiApp;
protected UIDocument m_uiDoc;
public Result Execute(ExternalCommandData commandData, ref string messages, ElementSet elements)
{
this.m_uiApp = commandData.Application;
this.m_uiDoc = this.m_uiApp.ActiveUIDocument;
this.m_app = this.m_uiApp.Application;
this.m_doc = this.m_uiDoc.Document;
Reference refer = null;
try
{
refer = this.m_uiDoc.Selection.PickObject(ObjectType.Element, "PickObject Element");
}
catch
{
}
if (refer == null)
return Result.Failed;
System.Drawing.PointF ptScreen = GetTransPtRevitToScreen(this.m_uiDoc, refer.GlobalPoint);
return Result.Failed;
}
public static double Hypot(params double[] arD)
{
double dSum = 0;
foreach (double dT in arD)
{
dSum += Math.Pow(dT, 2);
}
return Math.Sqrt(dSum);
}
public static XYZ GetTransPtScreenToRevit(UIDocument uiDoc, System.Drawing.PointF ptScreen)
{
Transform mat = GetTransPtRevitToScreenInternal(uiDoc);
if (mat == null)
return null;
return mat.Inverse.OfPoint(new XYZ(ptScreen.X, ptScreen.Y, 0));
}
private static System.Drawing.PointF GetTransPtRevitToScreen(UIDocument uiDoc, XYZ ptRevit)
{
Transform mat = GetTransPtRevitToScreenInternal(uiDoc);
if (mat == null)
return System.Drawing.PointF.Empty;
XYZ ptScreen = mat.OfPoint(ptRevit);
return new System.Drawing.PointF(Convert.ToSingle(ptScreen.X), Convert.ToSingle(ptScreen.Y));
}
private static Transform GetTransPtRevitToScreenInternal(UIDocument uiDoc)
{
if (uiDoc == null)
return null;
Autodesk.Revit.DB.View view = uiDoc.ActiveView;
if (view == null)
return null;
UIView uiView = uiDoc.GetOpenUIViews().FirstOrDefault(p => p.ViewId.IntegerValue == view.Id.IntegerValue);
if (uiView == null)
return null;
REVIT_RECT windowRectangle = uiView.GetWindowRectangle();
IList<XYZ> zoomCorners = uiView.GetZoomCorners();
if (zoomCorners.Count < 2)
return null;
double dDisCorner = zoomCorners[0].DistanceTo(zoomCorners[1]);
if (dDisCorner < uiDoc.Application.Application.ShortCurveTolerance)
return null;
double dScale = Hypot(windowRectangle.Right - windowRectangle.Left, windowRectangle.Bottom - windowRectangle.Top) / dDisCorner;
Transform matCrop = view.CropBox.Transform;
Transform mat = Transform.Identity;
mat.BasisX = new XYZ(matCrop.BasisX.X, -matCrop.BasisY.X, 0);
mat.BasisY = new XYZ(matCrop.BasisX.Y, -matCrop.BasisY.Y, 0);
mat.BasisZ = new XYZ(matCrop.BasisX.Z, -matCrop.BasisY.Z, 1);//"1"并没有作用,只是为了可以求逆而已
mat.Origin = new XYZ(-zoomCorners[0].DotProduct(matCrop.BasisX), zoomCorners[1].DotProduct(matCrop.BasisY), 0);
mat = mat.ScaleBasisAndOrigin(dScale);
mat.Origin += new XYZ(windowRectangle.Left, windowRectangle.Top, 0);
return mat;
}
}