.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Transform object from Modelspace to Paperspace by Viewport

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
stefanveurink68AXD
468 Views, 5 Replies

Transform object from Modelspace to Paperspace by Viewport

I once found these transformations somewhere on the internet: 

    public static class ucssen
    {
        public static Matrix3d DCS2WCS(this Viewport vp) =>
        Matrix3d.Rotation(-vp.TwistAngle, vp.ViewDirection, vp.ViewTarget) *
        Matrix3d.Displacement(vp.ViewTarget.GetAsVector()) *
        Matrix3d.PlaneToWorld(vp.ViewDirection);

        public static Matrix3d DCS2WCS2(this Viewport vp) =>
        Matrix3d.Rotation(vp.TwistAngle, vp.ViewDirection, vp.ViewTarget) *
        Matrix3d.Displacement(vp.ViewTarget.GetAsVector()) *
        Matrix3d.PlaneToWorld(vp.ViewDirection);

        public static Matrix3d WCS2DCS(this Viewport vp) =>
            Matrix3d.WorldToPlane(vp.ViewDirection) *
            Matrix3d.Displacement(vp.ViewTarget.GetAsVector().Negate()) *
            Matrix3d.Rotation(vp.TwistAngle, vp.ViewDirection, vp.ViewTarget);

        public static Matrix3d DCS2PSDCS(this Viewport vp) =>
            Matrix3d.Scaling(vp.CustomScale, vp.CenterPoint) *
            Matrix3d.Displacement(vp.ViewCenter.Convert3d().GetVectorTo(vp.CenterPoint));

        public static Matrix3d PSDCS2DCS(this Viewport vp) =>
            Matrix3d.Displacement(vp.CenterPoint.GetVectorTo(vp.ViewCenter.Convert3d())) *
            Matrix3d.Scaling(1.0 / vp.CustomScale, vp.CenterPoint);

        public static Point3d Convert3d(this Point2d pt) =>
            new Point3d(pt.X, pt.Y, 0.0);
    }

 

Which I was using for transforming objects through viewports (so from modelspace to paperspace, and vise versa, like the 'chspace'-command), by: 

 

Matrix3d ViewportToModel = deVp.DCS2WCS() * deVp.PSDCS2DCS();
Matrix3d ModelToViewport = deVp.DCS2PSDCS() * deVp.DCS2WCS2(); 

 

However, seems the one ModelToViewport doesn't always work correctly (while lots of times it does). There's some not-logical (to me) displacement I can't explain. 

 

Anyone knows what could be going wrong here?

5 REPLIES 5
Message 2 of 6
_gile
in reply to: stefanveurink68AXD

Hi,


@stefanveurink68AXD wrote:

I once found these transformations somewhere on the internet: 


 

They seems to come from this GeometryExtension library (which does not contain any DCS2WCS2 method).

 

Anyway,

 

Matrix3d ModelToViewport = deVp.DCS2PSDCS() * deVp.DCS2WCS2();

 

Should be:

 

Matrix3d ModelToViewport = deVp.DCS2PSDCS() * deVp.WCS2DCS();

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 6

Well, I've got this code, and it isn't working correctly in all cases. See the added file. in this right viewport it's working, in the left one the displacement isn't correct. Neither with your Matrix3d. 

 

Any idea what could be the problem? Cause I can't figure it out and trust me I tried it a lot. 

 

 

 

        private void transformeneditPL(Polyline pl, Viewport vp) 
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            using (DocumentLock docLock = doc.LockDocument())
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Viewport deVp = (Viewport)tr.GetObject(vp.ObjectId, OpenMode.ForRead);

                    Matrix3d VPnaarModel = deVp.DCS2WCS() * deVp.PSDCS2DCS();

                    Matrix3d MODELnaarVP = deVp.DCS2PSDCS() * deVp.DCS2WCS(); // * deVp.WCS2DCS();//

                    //1 maak een kopie
                    Polyline nieuwePL = new Polyline(); 
                    nieuwePL.Layer = pl.Layer; 

                    //2 transform de polyline en plaats hem
                    if (MnaarPisTruePnaarMisFalse) //dan dus modelspace naar paperspace
                    {
                        for (int i = 0; i < pl.NumberOfVertices; i++)
                        {
                            Point3d nieuwpunt = new Point3d(pl.GetPoint2dAt(i).X, pl.GetPoint2dAt(i).Y, 0);
                            Point3d nieuwpunttransformed = nieuwpunt.TransformBy(MODELnaarVP);
                            Point2d nieuwpunt2d = new Point2d(nieuwpunttransformed.X, nieuwpunttransformed.Y);

                            nieuwePL.AddVertexAt(nieuwePL.NumberOfVertices, nieuwpunt2d, pl.GetBulgeAt(i), pl.GetStartWidthAt(i) * vp.CustomScale, pl.GetEndWidthAt(i) * vp.CustomScale); //bulge startwidth etc gaat denk ik naar segment niet naar vertex. 
                        }


                        BlockTableRecord btvp = (BlockTableRecord)tr.GetObject(vp.BlockId, OpenMode.ForWrite);
                        Layout layvp = (Layout)tr.GetObject(btvp.LayoutId, OpenMode.ForRead);

   
                        LayoutManager lm = LayoutManager.Current;
                        lm.CurrentLayout = layvp.LayoutName;
                        
                        btvp.AppendEntity(nieuwePL);
                        tr.AddNewlyCreatedDBObject(nieuwePL, true);
                        tr.Commit();
                       
                    }
                }
            }
        }

 

 

 

 

 

 

Message 4 of 6
_gile
in reply to: stefanveurink68AXD

Hi,

This matrix multiplication is not correct.

Matrix3d MODELnaarVP = deVp.DCS2PSDCS() * deVp.DCS2WCS();

It should be:

Matrix3d MODELnaarVP = deVp.DCS2PSDCS() * deVp.WCS2DCS();

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 6
stefanveurink68AXD
in reply to: _gile

Wow. Seems I need a little holiday. Thanks.

Message 6 of 6
_gile
in reply to: stefanveurink68AXD

You can do this in a much more simpler way:

private static void TransformToPaperSpace(Transaction tr, Viewport viewport, ObjectId id)
{
    var ids = new ObjectIdCollection { id };
    var mapping = new IdMapping();
    viewport.Database.DeepCloneObjects(ids, viewport.OwnerId, mapping, false);
    var entity = (Entity)tr.GetObject(mapping[id].Value, OpenMode.ForWrite);
    entity.TransformBy(viewport.DCS2PSDCS() * viewport.WCS2DCS());
}

 

Testing command:

[CommandMethod("TEST", CommandFlags.NoTileMode)]
public static void Test()
{
    var doc = Application.DocumentManager.MdiActiveDocument;
    var db = doc.Database;
    var ed = doc.Editor;

    var peo = new PromptEntityOptions("\nSelect viewport: ");
    peo.SetRejectMessage("\nSelected object is not a viewport.");
    peo.AddAllowedClass(typeof(Viewport), true);
    var per = ed.GetEntity(peo);
    if (per.Status != PromptStatus.OK) return;

    using (var tr = db.TransactionManager.StartTransaction())
    {
        var viewport = (Viewport)tr.GetObject(per.ObjectId, OpenMode.ForRead);

        peo.Message = "\nSelect polyline: ";
        peo.SetRejectMessage("\nSelected object is not a polyline.");
        peo.RemoveAllowedClass(typeof(Viewport));
        peo.AddAllowedClass(typeof(Polyline), true);
        ed.SwitchToModelSpace();
        Application.SetSystemVariable("CVPORT", viewport.Number);
        per = ed.GetEntity(peo);
        if (per.Status != PromptStatus.OK) return;
        var plineId = per.ObjectId;
        ed.SwitchToPaperSpace();

        TransformToPaperSpace(tr, viewport, plineId);

        tr.Commit();
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report