乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 66|回复: 3

Trouble shooting ZoomAndCenter

[复制链接]

85

主题

404

帖子

7

银币

中流砥柱

Rank: 25

铜币
751
发表于 2017-8-3 19:26:40 | 显示全部楼层 |阅读模式
I've got a method that zooms and centers the view on an object, based on Gile's contribution here.
My version of the code is as follows:
[ol]///
/// Zooms to and highlight the entity in question.
///
/// The ObjectID of the entity to zoom to.
/// factor to zoom out by, higher number is a wider zoom
public static void ZoomToAndHighlight(ObjectId id, double scale)
{
  using (LockedTransaction lTr = Active.Document.TransactionManager.StartLockedTransaction())
  {
    Entity ent = lTr.GetObject(id, OpenMode.ForRead, false) as Entity;
    if (ent!=null)
    {
      using (ViewTableRecord view = Active.Editor.GetCurrentView())
      {
        Active.WriteMessage($"Starting view centered on {view.CenterPoint}, height:{view.Height}, width:{view.Width}");

        // get the extents
        Extents3d ext = ent.GeometricExtents;
        // transform extents
        Matrix3d WCS2DCS = Matrix3d.PlaneToWorld(view.ViewDirection);
        WCS2DCS = Matrix3d.Displacement(view.Target - Point3d.Origin)*WCS2DCS;
        WCS2DCS = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target);
        WCS2DCS = WCS2DCS.Inverse();
        ext.TransformBy(WCS2DCS);
        double width = ext.MaxPoint.X - ext.MinPoint.X;
        double height = ext.MaxPoint.Y - ext.MinPoint.Y;
        // calculate center, width and height
        Point2d center = new Point2d((ext.MaxPoint.X + ext.MinPoint.X)/2, (ext.MaxPoint.Y + ext.MinPoint.Y)/2);
        view.Width = scale * width;
        view.Height = scale * height;
        view.CenterPoint = center;
        Active.WriteMessage($"New view to be centered at {center}, height:{height}, width:{width}, WCS2DCS:{WCS2DCS}");
        Active.Editor.SetCurrentView(view);

        // this isn't working, this just verifies what the current view is
        ViewTableRecord nView = Active.Editor.GetCurrentView();
        Active.WriteMessage($"Moved view centered on {nView.CenterPoint}, height:{nView.Height}, width:{nView.Width}");
        // TODO highlight the given entity...
      }
    }
    lTr.Commit();
  }
}
[/ol]
You can see that I'm writing the coordinates to the command line for troubleshooting purposes. The view in question should be centered on (3183274.93594949,1432379.113886) and is called out as so on the command line, but is instead centered on approximately (6365835,2864340) as shown in the cursor location. It's almost like the coordinates are getting doubled when the view is being set in SetCurrentView(view).
I double check the currentview after the move with the nView variable and it's showing the values as they were set, not whats shown on the screen.
Anyone got any ideas as to what I'm missing? UCS is set to world, but that shouldn't matter with the transformation.
回复

使用道具 举报

15

主题

687

帖子

169

银币

中流砥柱

Rank: 25

铜币
582
发表于 2017-8-4 00:00:58 | 显示全部楼层
Hi,
It seems to me there's something wrong with the WCS2DCS matrix construction.
回复

使用道具 举报

85

主题

404

帖子

7

银币

中流砥柱

Rank: 25

铜币
751
发表于 2017-8-4 02:49:25 | 显示全部楼层
Hmm.. seems there may have been a problem re-using the view variable.
If I instantiate a new ViewTableRecord (nView), the method works as expected.
The code currently looks like this:
[ol]///
/// Zooms to and highlight the entity in question.
///
/// The ObjectID of the entity to zoom to.
/// factor to zoom out by, higher number is a wider zoom
public static void ZoomToAndHighlight(ObjectId id, double scale)
{
  using (LockedTransaction lTr = Active.Document.TransactionManager.StartLockedTransaction())
  {
    Entity ent = lTr.GetObject(id, OpenMode.ForRead, false) as Entity;
    if (ent!=null)
    {
      using (ViewTableRecord view = Active.Editor.GetCurrentView())
      {
        // get the extents
        Extents3d ext = ent.GeometricExtents;
        // transform extents
        Matrix3d WCS2DCS = Matrix3d.PlaneToWorld(view.ViewDirection);
        WCS2DCS = Matrix3d.Displacement(view.Target - Point3d.Origin)*WCS2DCS;
        WCS2DCS = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target);
        WCS2DCS = WCS2DCS.Inverse();
        ext.TransformBy(WCS2DCS);
        // calculate center, width and height
        double width = ext.MaxPoint.X - ext.MinPoint.X;
        double height = ext.MaxPoint.Y - ext.MinPoint.Y;
        Point2d center = new Point2d((ext.MaxPoint.X + ext.MinPoint.X)/2, (ext.MaxPoint.Y + ext.MinPoint.Y)/2);
        // Create a new ViewTableRecord to use
        ViewTableRecord nView = new ViewTableRecord();
        nView.Width = scale * width;
        nView.Height = scale * height;
        nView.CenterPoint = center;
        Active.Editor.SetCurrentView(nView);
        nView.Dispose();
        // highlight the given entity
        Autodesk.AutoCAD.Internal.Utils.SelectObjects(new ObjectId[]{id});
      }
    }
    lTr.Commit();
  }
}
[/ol]
Gile, thank you so much for posting the framework of this method!
回复

使用道具 举报

15

主题

687

帖子

169

银币

中流砥柱

Rank: 25

铜币
582
发表于 2017-8-4 12:45:29 | 显示全部楼层
Here're the extension methods I use:
[ol]using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Autodesk.AutoCAD.EditorInput
{
    public static class ExtensionMethods
    {
        public static Matrix3d EyeToWorld(this ViewTableRecord view)
        {
            if (view == null)
                throw new ArgumentNullException("view");

            return
                Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) *
                Matrix3d.Displacement(view.Target - Point3d.Origin) *
                Matrix3d.PlaneToWorld(view.ViewDirection);
        }

        public static Matrix3d WorldToEye(this ViewTableRecord view)
        {
            return view.EyeToWorld().Inverse();
        }

        public static void Zoom(this Editor ed, Extents3d ext)
        {
            if (ed == null)
                throw new ArgumentNullException("ed");

            using (ViewTableRecord view = ed.GetCurrentView())
            {
                ext.TransformBy(view.WorldToEye());
                view.Width = ext.MaxPoint.X - ext.MinPoint.X;
                view.Height = ext.MaxPoint.Y - ext.MinPoint.Y;
                view.CenterPoint = new Point2d(
                    (ext.MaxPoint.X + ext.MinPoint.X) / 2.0,
                    (ext.MaxPoint.Y + ext.MinPoint.Y) / 2.0);
                ed.SetCurrentView(view);
            }
        }

        public static void ZoomCenter(this Editor ed, Point3d center, double scale = 1.0)
        {
            if (ed == null)
                throw new ArgumentNullException("ed");

            using (ViewTableRecord view = ed.GetCurrentView())
            {
                center = center.TransformBy(view.WorldToEye());
                view.Height /= scale;
                view.Width /= scale;
                view.CenterPoint = new Point2d(center.X, center.Y);
                ed.SetCurrentView(view);
            }
        }

        public static void ZoomExtents(this Editor ed)
        {
            if (ed == null)
                throw new ArgumentNullException("ed");

            Database db = ed.Document.Database;
            db.UpdateExt(false);
            Extents3d ext = (short)Application.GetSystemVariable("cvport") == 1 ?
                new Extents3d(db.Pextmin, db.Pextmax) :
                new Extents3d(db.Extmin, db.Extmax);
            ed.Zoom(ext);
        }

        public static void ZoomObjects(this Editor ed, IEnumerable ids)
        {
            if (ed == null)
                throw new ArgumentNullException("ed");

            using (Transaction tr = ed.Document.TransactionManager.StartTransaction())
            {
                Extents3d ext = ids
                    .Where(id => id.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Entity))))
                    .Select(id => ((Entity)tr.GetObject(id, OpenMode.ForRead)).GeometricExtents)
                    .Aggregate((e1, e2) => { e1.AddExtents(e2); return e1; });
                ed.Zoom(ext);
                tr.Commit();
            }
        }

        public static void ZoomScale(this Editor ed, double scale)
        {
            if (ed == null)
                throw new ArgumentNullException("ed");

            using (ViewTableRecord view = ed.GetCurrentView())
            {
                view.Width /= scale;
                view.Height /= scale;
                ed.SetCurrentView(view);
            }
        }

        public static void ZoomWindow(this Editor ed, Point3d p1, Point3d p2)
        {
            using (Line line = new Line(p1, p2))
            {
                ed.Zoom(line.GeometricExtents);
            }
        }
    }
}[/ol]
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-5-25 12:26 , Processed in 0.399326 second(s), 60 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表