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?
Solved! Go to Solution.
Solved by _gile. Go to Solution.
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();
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();
}
}
}
}
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();
}
}
Can't find what you're looking for? Ask the community or share your knowledge.