Author Topic: Get matrix3d from Database  (Read 3778 times)

0 Members and 1 Guest are viewing this topic.

shsss1985

  • Guest
Get matrix3d from Database
« on: February 06, 2012, 09:45:53 PM »
Hello everyone.
i gets some coordinates when i use MdiActiveDocument:
Code: [Select]
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
//
...
foreach (ObjectId oi in ids)
{
    Line ln = (Line) tr.GetObject(oi, OpenMode.ForWrite);
    Matrix3d m = doc.Editor.CurrentCoordinateSystem.Inverse();
    Point3d pt = ln.StartPoint.TransformBy(m);
    //some coordinates calculations
    ...
}

But in case when i dont use  MdiActiveDocument (i have only Database), i cant gets matrix m. Can i get this matrix "m" from db only?
Code: [Select]
    Database db = new Database(false, true);
    db.ReadDwgFile(filePath, System.IO.FileShare.Read, true, "");
   [color=red] //i tried to use Viewport to get this matrix[/color]
    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
         UcsTable acUCSTbl;
         UcsTableRecord acUCSTblRec;
         acUCSTbl = tr.GetObject(db.UcsTableId, OpenMode.ForRead) as UcsTable;

         if (!acUCSTbl.Has("ucsCoord"))
                 Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("not Exist");
         else
         {
           acUCSTblRec = tr.GetObject(acUCSTbl["ucsCoord"], OpenMode.ForRead) as UcsTableRecord;
           ViewportTable vt = tr.GetObject(db.ViewportTableId, OpenMode.ForRead) as ViewportTable;
ViewportTableRecord vtr = tr.GetObject(vt["*Active"], OpenMode.ForWrite) as ViewportTableRecord;
                                                    //vtr.SetUcs(acUCSTblRec.ObjectId);
                                                    //multiEd.UpdateTiledViewportsFromDatabase();
                                                    //multiEd.UpdateScreen();
                                                    //ucsMatrix = multiEd.CurrentUserCoordinateSystem;
                                                    //Here am stuck........
                                                    CoordinateSystem3d cs = vtr.Ucs;
                                                   
                                                    ucsMatrix = Matrix3d.PlaneToWorld(vtr.ViewDirection);
                                                    ucsMatrix = Matrix3d.Displacement(vtr.Target - Point3d.Origin)*ucsMatrix;
                                                    ucsMatrix = Matrix3d.Rotation(-vtr.ViewTwist, vtr.ViewDirection, vtr.Target) * ucsMatrix;
                                                       
                                                    ucsMatrix = ucsMatrix.Inverse();
                                                    tr.Commit();
                                                }
    }


Also i tried:
Code: [Select]
public static Matrix3d  GetUcsMatrix(Database db)
        {
            Point3d toOrigin;
            Vector3d toXAxis, toYAxis, toZAxis;

            toOrigin = db.Ucsorg;
            toXAxis = db.Ucsxdir;
            toYAxis = db.Ucsydir;
           
            toZAxis = toXAxis.CrossProduct(toYAxis);
            return Matrix3d.AlignCoordinateSystem(
                Point3d.Origin,
                Vector3d.XAxis,
                Vector3d.YAxis,
                Vector3d.ZAxis,
                toOrigin, toXAxis, toYAxis, toZAxis);
        }
and after:
Code: [Select]
Point3d pt = ln.StartPoint.TransformBy(GetUcsMatrix(db).Inverse());But it doesnt works(
« Last Edit: February 06, 2012, 11:18:31 PM by diesel »

kaefer

  • Guest
Re: Get matrix3d from Database
« Reply #1 on: February 07, 2012, 03:56:04 AM »
But it doesnt works(

Sure it does.
The matrix returned is already that one needed for your transformation direction (WCS -> UCS), so you need not invert it.

Minimal demo:
Code - F#: [Select]
  1. type Database with
  2.     member db.GetUcsMatrix =
  3.         let (origin, xAxis, yAxis) = db.Ucsorg, db.Ucsxdir, db.Ucsydir
  4.         Matrix3d.AlignCoordinateSystem(
  5.             Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
  6.             origin, xAxis, yAxis, xAxis.CrossProduct yAxis )
  7.  
  8. [<CommandMethod "Test">]
  9. let testCmd() =
  10.     let db = HostApplicationServices.WorkingDatabase
  11.     use tr = db.TransactionManager.StartTransaction()
  12.     let btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) :?> BlockTableRecord
  13.     let ln = new Line(new Point3d(0., 0., 0.), new Point3d(10., 10., 0.))
  14.     ln.TransformBy db.GetUcsMatrix
  15.     btr.AppendEntity ln |> ignore
  16.     tr.AddNewlyCreatedDBObject(ln, true)
  17.     tr.Commit()

« Last Edit: February 07, 2012, 09:39:59 AM by kaefer »

shsss1985

  • Guest
Re: Get matrix3d from Database
« Reply #2 on: February 07, 2012, 05:12:18 AM »
hmmm...so strange am removed Inverse() procedure but coordinates not even changed:
Code: [Select]
Point3d pt = ln.StartPoint.TransformBy(GetUcsMatrix(db));

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Get matrix3d from Database
« Reply #3 on: February 07, 2012, 05:40:22 AM »


diesel

How about posting a drawing with one line that you want to transform the startpoint of.
... so we're all talking about the same thing.

Regards
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

shsss1985

  • Guest
Re: Get matrix3d from Database
« Reply #4 on: February 07, 2012, 06:13:00 AM »
AutoCAD2012
VS2010

this is a test file... there 2 lines only..
Code: [Select]
Database db = new Database(false, true);
db.ReadDwgFile("C:\\test.dwg", System.IO.FileShare.ReadWrite, true, "");

...
Matrix3d e2u = getUcsMatrix(db);
using (Transaction trLn = db.TransactionManager.StartTransaction())
                {
                    try
                    {
                        BlockTable bt = (BlockTable)trLn.GetObject(db.BlockTableId, OpenMode.ForWrite);
                        BlockTableRecord btr = (BlockTableRecord)trLn.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                       
                        foreach (ObjectId objId in btr)
                        {
                            Entity ent = (Entity)trLn.GetObject(objId, OpenMode.ForRead);

                            if (ent.GetType().Name == "Line")
                            {
                                Line ln = ent as Line;
                                //if (ln.Layer == "0")
                                {
                                 
                                    geoPoint = ln.StartPoint.TransformBy(e2u);
                                   
                                    sRiga = geoPoint.X.ToString() + "," + geoPoint.Y.ToString() + ",";
                                    geoPoint = ln.EndPoint.TransformBy(e2u);
                                    sRiga += geoPoint.X.ToString() + "," + geoPoint.Y.ToString() + ";";

                                    StreamWriter sw = new StreamWriter(FO, true);
                                    sw.WriteLine("COORDINATE;");
                                    sw.WriteLine(sRiga);
                                    sw.Close();
                                    StreamWriter swFO = new StreamWriter(FOS, true);
                                    swFO.WriteLine("COORDINATE;");
                                    swFO.WriteLine(sRiga);
                                    swFO.Close();
                                }
                            }
                        }
                    }
                    catch (SystemException ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    trLn.Commit();
                }

public static Matrix3d getUcsMatrix (Database db)
        {
            System.Diagnostics.Debug.Assert(db != null);
            Point3d toOrigin;
            Vector3d toXAxis, toYAxis, toZAxis;

            toOrigin = db.Ucsorg;
            toXAxis = db.Ucsxdir;
            toYAxis = db.Ucsydir;
            toZAxis = toXAxis.CrossProduct(toYAxis);

            return Matrix3d.AlignCoordinateSystem(Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, toOrigin, toXAxis, toYAxis, toZAxis).Inverse();
        }

i get some coordinates and they're different when i use the code below:
Code: [Select]

TypedValue[] tv = new TypedValue[4] { new TypedValue((int)DxfCode.Start, "LINE"), new TypedValue(67, 0), new TypedValue(62, CL), new TypedValue(8, LL) };
                                SelectionFilter sflt = new SelectionFilter(tv);
                                PromptSelectionResult resSel = ed.SelectAll(sflt);
                                SelectionSet selSel = resSel.Value;
                                ObjectId[] ids = selSel.GetObjectIds();
                                foreach (ObjectId oi in ids)
                                {
                                    Line ln = (Line)trLn.GetObject(oi, OpenMode.ForWrite);
                                    Matrix3d ucs2wcs = doc.Editor.CurrentUserCoordinateSystem.Inverse();
                                    Point3d geoPoint = ln.StartPoint.TransformBy(ucs2wcs);
....
I think don't care about dwg file, but in attached.
Here two different way how to get coordinates (with Editor & without, using only Database).
« Last Edit: February 08, 2012, 01:49:55 AM by diesel »

kaefer

  • Guest
Re: Get matrix3d from Database
« Reply #5 on: February 07, 2012, 09:39:39 AM »
I think don't care about dwg file, but in attached.

Thanks anyway. The UCS you're interested in is named "NIMA_GEO"?

Then there's the uncomfortable fact that I screwed up in the previous message. You do need to invert the matrix when going from WCS to UCS. In my example, I went from UCS to WCS (construct the Line in UCS, then transform to WCS). But still, your GetUcsMatrix() method is completely equivalent to the CurrentUserCoordinateSystem property, except when you're in paperspace.

UCS->WCS: ed.CurrentUserCoordinateSystem
WCS->UCS: ed.CurrentUserCoordinateSystem.Inverse()

shsss1985

  • Guest
Re: Get matrix3d from Database
« Reply #6 on: February 07, 2012, 10:27:46 AM »
thx, kaefer, but i know how get UCS and WCS with Editor, its possible when the drawing is open, but if its close) we have only Database db. Maybe i have some errors in the code?
i have a little idea, maybe its wrong that i opened Entity object "forRead" only?
But if i set OpenMode.ForWrite... i have error(
and with Database my code is not working(
i wrote 2 variants of code
- with Editor
- without Editor
u can compile them and test on drawing, and u will see that results are differents(
P.S.: am working only in a Model Space

in first case we have:
COORDINATE;
1516200.2924,5031892.933,1516385.5636,5031892.8813;
COORDINATE;
1516354.1415,5032032.582,1516354.1834,5032182.7509;
COORDINATE;
1516210.8185,5032032.622,1516354.1415,5032032.582;


in second case we have:
COORDINATE;
387.0067,315.2043,530.3297,315.2043;
COORDINATE;
530.3297,315.2043,530.3297,465.3732;
COORDINATE;
376.5197,175.5124,561.7909,175.5124;
« Last Edit: February 07, 2012, 11:38:56 AM by diesel »

kaefer

  • Guest
Re: Get matrix3d from Database
« Reply #7 on: February 07, 2012, 01:36:14 PM »
in first case we have:
COORDINATE;
1516200.2924,5031892.933,1516385.5636,5031892.8813;
COORDINATE;
1516354.1415,5032032.582,1516354.1834,5032182.7509;
COORDINATE;
1516210.8185,5032032.622,1516354.1415,5032032.582;

That's the result of a successful transformation to your named UCS "NIMA_GEO".

in second case we have:
COORDINATE;
387.0067,315.2043,530.3297,315.2043;
COORDINATE;
530.3297,315.2043,530.3297,465.3732;
COORDINATE;
376.5197,175.5124,561.7909,175.5124;

Those are the WCS points. Or the UCS points, if both are identical. Sorry for being obstinate, but I can't see anything wrong with either of these values.

(Is it possible that there's more hidden code which uses a UCS attached to a viewport to derive a transformation matrix?)

shsss1985

  • Guest
Re: Get matrix3d from Database
« Reply #8 on: February 07, 2012, 10:12:43 PM »
i think i know where is the problem:
when i use
Code: [Select]
Matrix3d e2u = getUcsMatrix(db);getUcsMatrix retun for me e2u = Matrix3d.Identity;
thats why i cant trnslate coordinates.
But the other question why getUcsMatrix return wrong matrix?
maybe my db initialized nor right?
« Last Edit: February 07, 2012, 10:18:39 PM by diesel »

shsss1985

  • Guest
Re: Get matrix3d from Database
« Reply #9 on: February 08, 2012, 01:50:34 AM »
well thx all, i make it!

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Get matrix3d from Database
« Reply #10 on: February 08, 2012, 03:55:34 AM »

How ?
What was the issue.
What did you do to fix it ?
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

shsss1985

  • Guest
Re: Get matrix3d from Database
« Reply #11 on: February 08, 2012, 05:08:55 AM »
there was my bad. i was tryed to get named UCS, but the function getUcsMatrix, getting not named UCS, but active UCS, that why returned value was equal Indentity.
I used  UcsTable (db.UcsTableId) and my UcsTableRecord for getting named UCS.