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

Unnamed UCS

13 REPLIES 13
Reply
Message 1 of 14
Anonymous
1503 Views, 13 Replies

Unnamed UCS

Dear All

I have been struggling in a certain code using vb.net and I really need help. I searched the internet but to no avail.

 

Before putting the code on, let me explain to you my problem: My assembly reads a dwg that contains an unnamed UCS in a viewport of a certain layout. All I need is to read that UCS. I found that unnamed UCSs are not found in the UCS tables, so the only suggested way was to use the editor property CurrentUserCoordinateSystem. I am using this way but always failing.

The steps I am following are:

1- activate the layout

2- switch to model space

3- read the CurrentUserCoordinateSystem

 

But I am always getting the WCS and not the UCS in the viewport. An important note is that, if I activate the model space of the viewport then run my assembly, it would work and get the actual UCS. Please help me figuring out the problem, it is taking me days without success. Here is the code:

 

lytmgr.CurrentLayout = pstrres.StringResult
ed.SwitchToModelSpace()
ucs = ed.CurrentUserCoordinateSystem
ed.WriteMessage(vbLf & "UCS is " & ucs.ToString)
Dim dmat As Double() = ucs.ToArray()
dmat(3) = 0
dmat(7) = 0
dmat(11) = 0
ucs = New Matrix3d(dmat)
ucs = ucs.Transpose()
ed.WriteMessage(vbLf & "Real ucs is " & ucs.ToString)
ed.SwitchToPaperSpace()

 

 

Thanks in advance

Tags (3)
13 REPLIES 13
Message 2 of 14
fenton.webb
in reply to: Anonymous

We need a sample project to investigate this further...




Fenton Webb
AutoCAD Engineering
Autodesk

Message 3 of 14
Anonymous
in reply to: Anonymous

You will find in the attached zipped file, a test drawing and a visual studio project that contains an assembly for autocad 2013. Run the code and you will see that it is not giving the required results. Waiting your answer

Message 4 of 14
Balaji_Ram
in reply to: Anonymous

Hi,

 

Can you please try this code snippet to retrieve the UCS of the viewport using the COM API ?

 

' Needs Autodesk.AutoCAD.Interop and Autodesk.AutoCAD.Interop.Common references 
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common

    <CommandMethod("GetUCS", CommandFlags.NoTileMode)> _
    Public Sub GetUCS_PaperSpace()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor
        Dim db As Database = doc.Database

        Dim peo As New PromptEntityOptions("Select a viewport : ")
        peo.SetRejectMessage("Select a viewport.")
        peo.AddAllowedClass(GetType(Autodesk.AutoCAD.DatabaseServices.Viewport), True)
        Dim per As PromptEntityResult = ed.GetEntity(peo)
        If per.Status <> PromptStatus.OK Then
            Return
        End If
        Dim vpId As ObjectId = per.ObjectId

        Dim acadDoc As AcadDocument = Autodesk.AutoCAD.ApplicationServices.DocumentExtension.GetAcadDocument(doc)
        acadDoc.MSpace = True

        Using tr As Transaction = db.TransactionManager.StartTransaction()
            Dim vp As Autodesk.AutoCAD.DatabaseServices.Viewport = TryCast(tr.GetObject(vpId, OpenMode.ForRead), Autodesk.AutoCAD.DatabaseServices.Viewport)

            acadDoc.ActivePViewport = vp.AcadObject 

            Dim ucsMat As Matrix3d = ed.CurrentUserCoordinateSystem
            Dim cs As CoordinateSystem3d = ucsMat.CoordinateSystem3d

            ed.WriteMessage([String].Format(vbLf & "Origin : {0}", cs.Origin))
            ed.WriteMessage([String].Format(vbLf & "X Vec  : {0}", cs.Xaxis))
            ed.WriteMessage([String].Format(vbLf & "Y Vec  : {0}", cs.Yaxis))

            tr.Commit()
        End Using

        acadDoc.MSpace = False
    End Sub

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 5 of 14
Anonymous
in reply to: Anonymous

Dear Balaji_Ram

 

I tried this snippet and it didnt work. It is giving me the world UCS.

Let me clarify something to you first, the snippet works when the UCS is named, and also my VB.Net code works when the UCS is named. What I want actually is to get the unnamed ucs of a viewport.
I know it is not saved in the database, but can I save it in code, or get it so I can work on it.

 

Thanks

Message 6 of 14
hgasty1001
in reply to: Anonymous

Hi,

 

I'm not sure to understand, why not to check UCSXDIR and UCSYDIR ?

 

Gaston Nunez

Message 7 of 14
Anonymous
in reply to: hgasty1001

Here are the two functions I am using, I have collected everything on the internet to be able to solve my problem, but still to no avail. Please help me, I have been suffering in this problem for about a month.

 

The getActiveUcs function checks to see if there is a named ucs, if not it creates a named ucs from the unnamed ucs.

The getUCS function applies the first function to the required viewport.

 

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common



Public Class Test

    <CommandMethod("GetUCS", CommandFlags.NoTileMode)> _
    Public Sub GetUCS_PaperSpace()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor
        Dim db As Database = doc.Database

        Dim peo As New PromptEntityOptions("Select a viewport : ")
        peo.SetRejectMessage("Select a viewport.")
        peo.AddAllowedClass(GetType(Autodesk.AutoCAD.DatabaseServices.Viewport), True)
        Dim per As PromptEntityResult = ed.GetEntity(peo)
        If per.Status <> PromptStatus.OK Then
            Return
        End If
        Dim vpId As ObjectId = per.ObjectId

        Dim acadDoc As AcadDocument = Autodesk.AutoCAD.ApplicationServices.DocumentExtension.GetAcadDocument(doc)
        acadDoc.MSpace = True

        Using tr As Transaction = db.TransactionManager.StartTransaction()
            Dim vp As Autodesk.AutoCAD.DatabaseServices.Viewport = TryCast(tr.GetObject(vpId, OpenMode.ForRead), Autodesk.AutoCAD.DatabaseServices.Viewport)

            acadDoc.ActivePViewport = vp.AcadObject

            Dim ucs As AcadUCS = getActiveUcs()
            ed.WriteMessage([String].Format(vbLf & "Origin : {0}", ucs.ToString))

            Dim ucsMat As Matrix3d = ed.CurrentUserCoordinateSystem
            Dim cs As CoordinateSystem3d = ucsMat.CoordinateSystem3d

            ed.WriteMessage([String].Format(vbLf & "Origin : {0}", cs.Origin))
            ed.WriteMessage([String].Format(vbLf & "X Vec  : {0}", cs.Xaxis))
            ed.WriteMessage([String].Format(vbLf & "Y Vec  : {0}", cs.Yaxis))

            tr.Commit()
        End Using

        acadDoc.MSpace = False
    End Sub

    Function getActiveUcs() As AcadUCS
        ' get the active UCS
        ' if the UCS is not saved, save it
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim ThisDrawing As AcadDocument = Autodesk.AutoCAD.ApplicationServices.DocumentExtension.GetAcadDocument(doc)
        Dim ed As Editor = doc.Editor

        Dim Origin
        Dim xaxis
        Dim yaxis
        Dim Zero(0 To 2) As Double
        Zero(0) = 0 : Zero(1) = 0 : Zero(2) = 0
        Dim currentUCSName As String
        currentUCSName = ThisDrawing.GetVariable("UCSNAME")

        If currentUCSName = "" Then
            ' Current UCS is not saved so get the data and save it
            ' A ucs is saved when a user makes and saves one or
            ' a user clicks on an isoview button

            If ThisDrawing.GetVariable("WORLDUCS") = 1 Then
                ' active UCS is identical to WCS
                xaxis = Zero : yaxis = Zero
                xaxis(0) = 1 : yaxis(1) = 1
                getActiveUcs = ThisDrawing.UserCoordinateSystems.Add(Zero, xaxis, yaxis, "World")
            Else
                Origin = ThisDrawing.GetVariable("UCSORG")
                xaxis = ThisDrawing.GetVariable("UCSXDIR")
                yaxis = ThisDrawing.GetVariable("UCSYDIR")

                getActiveUcs = ThisDrawing.UserCoordinateSystems.Add(Zero, xaxis, yaxis, "Active")
                'Changing the origin later stops the error message
                '-2145320930   UCS X axis and Y axis are not perpendicular
                getActiveUcs.Origin = Origin
                ThisDrawing.ActiveUCS = getActiveUcs
            End If
        Else
            getActiveUcs = ThisDrawing.UserCoordinateSystems.Item(currentUCSName)
        End If

    End Function
End Class

 

This code doesnt work for the first time it is applied, but if you do the function again it works!!!!!!
I am not able to figure out the problem, any help is much appreciated.

Message 8 of 14
Balaji_Ram
in reply to: Anonymous

I am trying out with your code and will get back to you soon.



Balaji
Developer Technical Services
Autodesk Developer Network

Message 9 of 14
Anonymous
in reply to: Balaji_Ram

Thanks, your help is much appreciated.
Message 10 of 14
Balaji_Ram
in reply to: Anonymous

Hi,

 

The problem is not with the code and seems specific to that paperspace viewport of the drawing that you shared. After I switched to the modelspace and saved the drawing in AutoCAD, it worked ok. The UCS in that viewport might have been set incorrectly but it is hard to identify why and how.

 

Your code as well as the code that I posted earlier work correctly for any other viewport created with an unnamed UCS. Both the code works ok with the attached drawings. These drawings were saved after the viewport UCS was set right using the above step.

 

 

 

 

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 11 of 14
Anonymous
in reply to: Balaji_Ram

It seems that i figured out why it was not working on the other drawings. The problem is undefined for me. Take your test drawings, and add a new layer to the drawing, the run the macro. You will see that it wouldnt work anymore. I have no idea why!!
Message 12 of 14
Anonymous
in reply to: Balaji_Ram

The code is working but for example if you add a new layer, and then run the code, it wont work!!!!!
Message 13 of 14
Balaji_Ram
in reply to: Anonymous

Hi,

 

To me this problem seems specific to this drawing and the code has worked for even a new layout created in the same drawing. I could not find a way to resolve this issue for the layout that you are testing with. 

 

A workaround to get the UCS origin, x direction and y direction for the viewport could be get the values directly by retrieving the values for DXF codes 110, 111 and 112. I still do not like approaching it this way Smiley Embarassed

 

Here is a sample code that will display the DXF codes after you select the paperspace viewport. You can use the values from the above DXF codes to get the UCS values.

 

    <DllImport("acdb19.dll", CallingConvention:=CallingConvention.Cdecl, EntryPoint:="?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")> _
    Public Shared Function acdbGetAdsName_R19_64(name As Long(), objId As ObjectId) As Integer
    End Function

    <DllImport("accore.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Cdecl, EntryPoint:="acdbEntGet")> _
    Public Shared Function acdbEntGet(ename As Long()) As System.IntPtr
    End Function

    <DllImport("accore.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Cdecl, EntryPoint:="acdbEntGetX")> _
    Public Shared Function acdbEntGetX(ename As Long(), rb As IntPtr) As System.IntPtr
    End Function

    <CommandMethod("GetEntityDxf")> _
    Public Shared Sub GetEntityDxf()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor

        Dim per As PromptEntityResult = ed.GetEntity(vbLf & "Select an Entity: ")

        If per.Status <> PromptStatus.OK Then
            Return
        End If

        Dim ename As Long() = New Long() {0, 0}

        ' extract the id into an ename
        Dim result As Integer = acdbGetAdsName_R19_64(ename, per.ObjectId)

        ' now I have the ename lets entget it into a result buffer
        Dim rb As New ResultBuffer()
        Interop.AttachUnmanagedObject(rb, acdbEntGet(ename), True)

        ' print out what we have
        Dim iter As ResultBufferEnumerator = rb.GetEnumerator()

        While iter.MoveNext()
            Dim TmpVal As TypedValue = iter.Current

            Dim strValue As String = (If(TmpVal.Value IsNot Nothing, TmpVal.Value.ToString(), "*Nothing*"))

            ed.WriteMessage(vbLf & " - Code: " & TmpVal.TypeCode.ToString() & " = " & strValue)
        End While
    End Sub

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 14 of 14
Anonymous
in reply to: Balaji_Ram

Thanks for your efforts.

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost