/// <summary> 根据给定的参数创建出视口 </summary> /// <param name="docMdf"></param> /// <param name="layout"></param> /// <param name="clipCurveInModel"></param> /// <param name="bottomLeftPt">图框的左下角点</param> /// <param name="bottomRightPt">图框的右下角点</param> /// <param name="bottomLength"></param> private void CreateViewport(DocumentModifier docMdf, CoordinateSystem3d modelUcs, Layout layout, Curve clipCurveInModel, Point3d bottomLeftPt, Point3d bottomRightPt, double bottomLength) { var brt = layout.BlockTableRecordId.GetObject(OpenMode.ForRead) as BlockTableRecord; brt.UpgradeOpen(); // 视口的裁剪区域,此区域可以由多段线、圆弧或样条曲线等来定义,而且曲线可以不闭合。 var layoutClipCurve = Curve.CreateFromGeCurve(geCurve: clipCurveInModel.GetGeCurve()); brt.AppendEntity(layoutClipCurve); docMdf.acTransaction.AddNewlyCreatedDBObject(layoutClipCurve, true); var viewExt = new AdvancedExtents3d(layoutClipCurve.GeometricExtents); var center = viewExt.GetAnchor(AdvancedExtents3d.Anchor.GeometryCenter); // 创建视口 Viewport acVport = new Viewport(); brt.AppendEntity(acVport); docMdf.acTransaction.AddNewlyCreatedDBObject(acVport, true); brt.DowngradeOpen(); // 设置视口所对应的裁剪图形 acVport.NonRectClipEntityId = layoutClipCurve.ObjectId; acVport.NonRectClipOn = true; acVport.On = true; // 如果是新创建的布局,则此视口必须要先设置其 on 为true。 // 将视口放置到不打印层 acVport.Layer = ACadConstants.LayerName_Defpoints; layoutClipCurve.Layer = ACadConstants.LayerName_Defpoints; // ----------------------------------------------- 设置视口的显示区域 acVport.PerspectiveOn = false; // ViewHeight属性– 表示视口内模型空间视图的高度。它决定的视口显示的缩放比例 // 如果要按1:1显示,则需要将其设置为视口多段线所对应的Extents3d的高度。 acVport.ViewHeight = viewExt.GetHeight(); // ViewCenter属性- 表示视口内视图的观察中心。它决定的视口显示的平面定位 // 如果要视图内容范围完全匹配多段线的区域,则需要将其设置为视口多段线的几何中心点。 acVport.ViewCenter = center.ToXYPlane(); //ViewHeight属性– 表示视口内模型空间视图的高度。 acVport.ViewDirection = new Vector3d(0, 0, 1); // ViewTarget属性– 表示视口内视图的目标点的位置。 acVport.ViewTarget = new Point3d(0, 0, 0); acVport.Locked = true; // ----------------------------------------------- 视口对象在布局中的定位 // 对视口所绑定的几何曲线的平移和缩放操作可以对视口进行变换,变换过程中视口中的显示内容在布局中的位置也发生同等变换,即是将视口与其中的内容作为一个整体进行变换 // 但是直接对acVport进行变换,并不会生效。 var scale = bottomLength / bottomLeftPt.DistanceTo(bottomRightPt); var layoutOrigin = new Point3d(0, 0, 0); var disp = bottomLeftPt.GetVectorTo(layoutOrigin).Subtract(modelUcs.Origin.GetAsVector()); docMdf.WriteNow(scale, disp, bottomLeftPt, modelUcs.Origin); layoutClipCurve.TransformBy(Matrix3d.Displacement(disp)); layoutClipCurve.TransformBy(Matrix3d.Scaling(scaleAll: scale, center: (new Point3d(0, 0, 0)))); // //var angle = origin.GetVectorTo(bottomRightPt).GetAngleTo(new Vector3d(1, 0, 0)); //ViewportUtil.RotateViewport(acVport, _docMdf, layout, new Point2d(0, 0), angle); }
/// <summary> 获取 Extents3d 的几何描述信息,并附加到 <seealso cref="StringBuilder"/> 中 </summary> private void AppendDescription(Extents3d ext, ref StringBuilder description) { const string sep = ";"; var adExt = new AdvancedExtents3d(ext); description.Append(ext.MinPoint + sep); description.Append(ext.MaxPoint + sep); description.Append((adExt.GetAnchor(AdvancedExtents3d.Anchor.GeometryCenter)) + sep); description.Append(adExt.GetWidth() + sep); description.Append(adExt.GetHeight() + sep); description.Append(adExt.GetDepth() + sep); }
// 开始具体的调试操作 public static ExternalCmdResult CreateViewport(DocumentModifier docMdf, SelectionSet impliedSelection) { // 打开布局 var lm = LayoutManager.Current; var layout = lm.GetLayoutId(name: "A3").GetObject(OpenMode.ForRead) as Layout; lm.CurrentLayout = layout.LayoutName; // lm.SetCurrentLayoutId(layout.Id); AutoCAD 2016 var brt = layout.BlockTableRecordId.GetObject(OpenMode.ForRead) as BlockTableRecord; brt.UpgradeOpen(); // 从模型空间中获取视口裁剪框 var handle = ExtensionMethods.ConvertToHandle("a31b"); var pl_Model = handle.GetDBObject <Curve>(docMdf.acDataBase); // 视口的裁剪区域,此区域可以由多段线、圆弧或样条曲线等来定义,而且曲线可以不闭合。 var layoutClipCurve = Curve.CreateFromGeCurve(geCurve: pl_Model.GetGeCurve()); brt.AppendEntity(layoutClipCurve); docMdf.acTransaction.AddNewlyCreatedDBObject(layoutClipCurve, true); var viewExt = new AdvancedExtents3d(layoutClipCurve.GeometricExtents); var center = viewExt.GetAnchor(AdvancedExtents3d.Anchor.GeometryCenter); // 创建视口 Viewport acVport = new Viewport(); brt.AppendEntity(acVport); docMdf.acTransaction.AddNewlyCreatedDBObject(acVport, true); brt.DowngradeOpen(); // 设置视口所对应的裁剪图形 acVport.On = true; acVport.NonRectClipEntityId = layoutClipCurve.ObjectId; acVport.NonRectClipOn = true; // ----------------------------------------------- 设置视口的显示区域 acVport.PerspectiveOn = false; // ViewHeight属性– 表示视口内模型空间视图的高度。它决定的视口显示的缩放比例 // 如果要按1:1显示,则需要将其设置为视口多段线所对应的Extents3d的高度。 acVport.ViewHeight = viewExt.GetHeight(); // ViewCenter属性- 表示视口内视图的观察中心。它决定的视口显示的平面定位 // 如果要视图内容范围完全匹配多段线的区域,则需要将其设置为视口多段线的几何中心点。 acVport.ViewCenter = center.ToXYPlane(); //ViewHeight属性– 表示视口内模型空间视图的高度。 acVport.ViewDirection = new Vector3d(0, 0, 1); // ViewTarget属性– 表示视口内视图的目标点的位置。 acVport.ViewTarget = new Point3d(0, 0, 0); acVport.Locked = false; // ----------------------------------------------- 视口对象在布局中的定位 // 对视口所绑定的几何曲线的平移和缩放操作可以对视口进行变换,变换过程中视口中的显示内容在布局中的位置也发生同等变换,即是将视口与其中的内容作为一个整体进行变换 // 但是直接对acVport进行变换,并不会生效。 layoutClipCurve.TransformBy(Matrix3d.Displacement(new Vector3d(-10, 10, 0))); layoutClipCurve.TransformBy(Matrix3d.Scaling(3, center)); // 对视口所绑定的几何曲线 layoutClipCurve 的Rotation 操作可以对视口进行旋转,但是奇怪的是,在变换过程中,视口中的显示内容相对于布局空间未发生旋转,却进行了平移与缩放。 // 平移的后的视图中心点依然与视口的几何中心点重合,缩放的比例可以暂且简单理解为"1/cos(angle)"。 // 而如果要实现视口中内容随视口进行整体旋转,必须对acVport对象进行旋转变换。 var angle = 45.0 / 180.0 * Math.PI; acVport.TransformBy(Matrix3d.Rotation(angle, new Vector3d(0, 0, 1), new Point3d(0, 0, 0))); layoutClipCurve.TransformBy(Matrix3d.Rotation(angle, new Vector3d(0, 0, 1), new Point3d(0, 0, 0))); // return(ExternalCmdResult.Commit); }