Author Topic: TranslateCoords with viewport twistangle <> 0  (Read 3705 times)

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1883
TranslateCoords with viewport twistangle <> 0
« on: July 15, 2006, 02:30:52 PM »
Interesting question I saw on another site.
the idea is to pick a point in paperspace and translate that point to modelspace.
In a 2d environment it seems
1) translate point from paperspace to modelspace
2) rotate it about 0,0 by minus the viewport twistangle.

The tests I'm doing are started by drawing a rectangle in modelspace with a world ucs and a topview.
Paperspace has 1 viewport with a twisted view achieved with ucs,Z,45 ->plan  type commands.
We are not trying to figure out a twisted modelspace.
Here are a couple of test subs

Code: [Select]
Sub MsPoint1()

    Dim VP As Variant
    Dim Po As AcadPoint
    Dim oDoc As AcadDocument
    Dim oUtil As AcadUtility
    Dim Zero(2) As Double
    Dim oCirc As AcadCircle
    Dim Pv As AcadPViewport
    Dim vTP As Variant
   
    Set oDoc = ThisDrawing
    Set oUtil = oDoc.Utility
    ThisDrawing.ActiveSpace = acPaperSpace
    oDoc.MSpace = False
   
    Set Pv = ThisDrawing.PaperSpace(1)
    VP = oUtil.GetPoint(, "Pick point in paperspace")
    Debug.Print Pv.TwistAngle, Pv.TwistAngle * 180 / Pi
    Set Po = ThisDrawing.PaperSpace.AddPoint(VP)
    vTP = oUtil.TranslateCoordinates(VP, acPaperSpaceDCS, acDisplayDCS, False)
    vTP = oUtil.TranslateCoordinates(vTP, acDisplayDCS, acWorld, False)
   
    Set oCirc = oDoc.ModelSpace.AddCircle(vTP, 1)
    oCirc.Copy
    oCirc.Rotate Zero, -Pv.TwistAngle
    oCirc.color = acBlue

End Sub

And this one is to test rotating in paperspace first
It doesn't work unless you uncomment it.
Code: [Select]
Sub MsPoint2()

    Dim VP As Variant
    Dim Po As AcadPoint
    Dim oDoc As AcadDocument
    Dim oUtil As AcadUtility
    Dim Zero(2) As Double
    Dim Pzero
    Dim oCirc As AcadCircle
    Dim Pv As AcadPViewport
    Dim vTP As Variant
   
    Set oDoc = ThisDrawing
    Set oUtil = oDoc.Utility
    ThisDrawing.ActiveSpace = acPaperSpace
    oDoc.MSpace = False
   
    Set Pv = ThisDrawing.PaperSpace(1)
    Pzero = Zero
    VP = oUtil.GetPoint(, "Pick point in paperspace")
    Debug.Print Pv.TwistAngle, Pv.TwistAngle * 180 / Pi
    Set Po = ThisDrawing.PaperSpace.AddPoint(VP)
    Set Po = ThisDrawing.PaperSpace.AddPoint(Zero)
   
    'Pzero = oUtil.TranslateCoordinates(Zero, acWorld, acDisplayDCS, False)
    'Pzero = oUtil.TranslateCoordinates(Pzero, acDisplayDCS, acPaperSpaceDCS, False)
    'Set Po = ThisDrawing.PaperSpace.AddPoint(Pzero)
    'Po.color = acMagenta
   
    Set Po = ThisDrawing.PaperSpace.AddPoint(VP)
    Po.Rotate Pzero, -Pv.TwistAngle
    VP = Po.Coordinates
    vTP = oUtil.TranslateCoordinates(VP, acPaperSpaceDCS, acDisplayDCS, False)
    vTP = oUtil.TranslateCoordinates(vTP, acDisplayDCS, acWorld, False)
   
    Set oCirc = oDoc.ModelSpace.AddCircle(vTP, 1)
    oCirc.color = acGreen

End Sub

Bryco

  • Water Moccasin
  • Posts: 1883
Re: TranslateCoords with viewport twistangle <> 0
« Reply #1 on: July 15, 2006, 02:44:58 PM »
Now to use this for 3d
I had so little success I wondered if anything was right.
In your viewport hit topview to reset the ucs
Ucs->x->90 then Plan.
This will give you a pviewport  with  no twist.
Running MsPoint1 you will see that TranslateCoordinates doesnt give the correct point
So I'm a bit lost at this point.
 Having written my own version of getentity I realise getentity doesn't give you the actual point
and this will definately come into play with snapping to points on an object but I dont see how it plays in a simple translation

Bryco

  • Water Moccasin
  • Posts: 1883
Re: TranslateCoords with viewport twistangle <> 0
« Reply #2 on: July 15, 2006, 04:39:22 PM »
It gets worserer.
When you pick a point the active ucs seems to be that of the viewports ucs.
So the TranslateCoordinates translates to that ucs. Since paperspace is 2d you need to then translate along the viewdir to the picked object, to find the real world coord.

This sub apprears to work (until you go to modelspace)

Code: [Select]
Sub MsPoint1a()

    Dim VP As Variant
    Dim Po As AcadPoint
    Dim oDoc As AcadDocument
    Dim oUtil As AcadUtility
    Dim Zero(2) As Double
    Dim oCirc As AcadCircle
    Dim Pv As AcadPViewport
    Dim vTP As Variant
    Dim UcsMspace As AcadUCS
    Dim UcsModelspace As AcadUCS
   
    Set oDoc = ThisDrawing
    Set oUtil = oDoc.Utility
    ThisDrawing.ActiveSpace = acPaperSpace
    oDoc.MSpace = False
   
    Set Pv = ThisDrawing.PaperSpace(1)
    VP = oUtil.GetPoint(, "Pick point in paperspace")

    Set Po = ThisDrawing.PaperSpace.AddPoint(VP)
    vTP = oUtil.TranslateCoordinates(VP, acPaperSpaceDCS, acDisplayDCS, False)
    oDoc.MSpace = True
    vTP = oUtil.TranslateCoordinates(vTP, acDisplayDCS, acUCS, False)
    vTP = oUtil.TranslateCoordinates(vTP, acUCS, acWorld, False)
    Set oCirc = oDoc.ModelSpace.AddCircle(vTP, 1)
    oCirc.Copy
    oCirc.Rotate Zero, -Pv.TwistAngle
    oCirc.color = acBlue

End Sub

Bryco

  • Water Moccasin
  • Posts: 1883
Re: TranslateCoords with viewport twistangle <> 0
« Reply #3 on: July 15, 2006, 07:53:57 PM »
I had it and now it's gone, this works anyway
Code: [Select]
Option Explicit

Private Declare Function GetCursor Lib "user32" () As Long
Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As Long, lpRect As RECT) As Long


Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type


Function ConvertPaperSpacePtToModelspace(Pt As Variant, Vp As AcadPViewport)

    Dim oDoc As AcadDocument
    Dim oUtil As AcadUtility
    Dim Ent As AcadEntity
    Dim oPt As AcadPoint
    Dim Zero(2) As Double
    Set oDoc = ThisDrawing
    Set oUtil = oDoc.Utility
    Pt = oUtil.TranslateCoordinates(Pt, acPaperSpaceDCS, acDisplayDCS, False)
    ThisDrawing.MSpace = True
    Pt = oUtil.TranslateCoordinates(Pt, acDisplayDCS, acWorld, False)
   
    Set Ent = SelectAtPt(, , Pt)
    Pt = PickPtToEnt(Ent, Pt)
   
    Set oPt = oDoc.ModelSpace.AddPoint(Pt)
    'oPt.Rotate Zero, -Vp.TwistAngle
    oPt.color = acRed
    oDoc.MSpace = False

End Function


Sub TestMsPoint()

    Dim Vpt As Variant
    Dim oDoc As AcadDocument
    Dim oUtil As AcadUtility
    Dim Pv As AcadPViewport
 
    Set oDoc = ThisDrawing
    Set oUtil = oDoc.Utility
    ThisDrawing.ActiveSpace = acPaperSpace
    oDoc.MSpace = False
   
    Set Pv = ThisDrawing.PaperSpace(1)
    Vpt = oUtil.GetPoint(, "Pick point in paperspace")
   
    ConvertPaperSpacePtToModelspace Vpt, Pv
End Sub


And a couple of functions

Code: [Select]
Private Function PickPtToEnt(Ent As AcadEntity, v) As Variant

    Dim Dir, N
    Dim newV(2) As Double
    Dim Dist As Double
    Dim dOrigin As Variant
    Dim Z As Double, Pt
   
    N = Ent.Normal
    Dir = ToWcs(ThisDrawing.GetVariable("viewdir")) '''
    If TypeOf Ent Is AcadLWPolyline Then
        Z = Ent.Elevation
    Else
        Pt = Ent.Center
        Z = (Pt(0) * N(0)) + (Pt(1) * N(1)) + (Pt(2) * N(2))
    End If
    Dir = SubtractVectors(Dir, ThisDrawing.GetVariable("ucsorg"))
    Dist = (Z - (v(0) * N(0)) - (v(1) * N(1)) - (v(2) * N(2))) _
                        / ((Dir(0) * N(0)) + (Dir(1) * N(1)) + (Dir(2) * N(2)))
    newV(0) = v(0) + Dist * Dir(0)
    newV(1) = v(1) + Dist * Dir(1)
    newV(2) = v(2) + Dist * Dir(2)
    PickPtToEnt = newV
ThisDrawing.ModelSpace.AddPoint newV
End Function


Function ToWcs(Pt As Variant) As Variant
    ToWcs = ThisDrawing.Utility.TranslateCoordinates(Pt, acUCS, acWorld, False)
End Function

Function SubtractVectors(V1, V2) As Variant
    Dim V3(2) As Double
    V3(0) = V1(0) - V2(0)
    V3(1) = V1(1) - V2(1)
    V3(2) = V1(2) - V2(2)
    SubtractVectors = V3
End Function


Public Function SelectAtPt(Optional ObType As String, Optional msg As String = "Pick:", Optional varPick As Variant, _
   Optional ssName As String = "SS") As AcadEntity

    'ObType="LWPolyline" or "Circle","Line","Insert","Viewport"
   
    Dim oSSet As AcadSelectionSet
    Dim oSSets As AcadSelectionSets
    Dim Pt1(2) As Double, Pt2(2) As Double
    Dim FType(0) As Integer
    Dim FData(0) As Variant
    Dim i As Integer, x
    FType(0) = 0
    FData(0) = ObType
    If IsMissing(varPick) Then
        'varPick = GetPointEX(, msg)
        varPick = ThisDrawing.Utility.GetPoint(, msg)
    End If
    If IsEmpty(varPick) Then Exit Function ''''''''''''''''
    x = CursorSelection(varPick)
    For i = 0 To 2
        Pt1(i) = x(i)
        Pt2(i) = x(i + 3)
    Next
    Set oSSets = ThisDrawing.SelectionSets
    DeleteSelectionSet ssName
    Set oSSet = oSSets.Add(ssName)
    If ObType = "" Then
        oSSet.Select acSelectionSetCrossing, Pt1, Pt2
    Else
        oSSet.Select acSelectionSetCrossing, Pt1, Pt2, FilterType:=FType, FilterData:=FData
    End If
    Select Case oSSet.Count
    Case 0
    Case 1
        Set SelectAtPt = oSSet(0)
    Case Else
        oSSet.Highlight True
   End Select
    oSSet.Delete

End Function



'CCP Jan 8 2004 Revised April 3 2004  by Troy Williams
Public Function CursorSelection(varPick As Variant)
    If IsEmpty(varPick) Then Exit Function ''''''''''''''''
    'varpick comes in as a wcs value
    Dim dStart(0 To 2) As Double
    Dim dEnd(0 To 2) As Double
    Dim vTemp As Variant
    Dim pts(5) As Double
    Dim R As RECT  ' receives window rectangle in pixels
    Dim RetVal As Long  ' return value
    Dim pixelHeight As Double
    Dim dblDist As Double
   
    RetVal = GetWindowRect(ThisDrawing.hwnd, R)
    pixelHeight = R.Bottom - R.Top
    dblDist = (ThisDrawing.GetVariable("pickbox") / pixelHeight) * ThisDrawing.GetVariable("viewsize")
    dblDist = dblDist * 1.04
    vTemp = ThisDrawing.Utility.TranslateCoordinates(varPick, acWorld, acUCS, False) ''''''''''''''
    dStart(0) = vTemp(0) - dblDist: dStart(1) = vTemp(1) - dblDist: dStart(2) = vTemp(2)
    dEnd(0) = vTemp(0) + dblDist: dEnd(1) = vTemp(1) + dblDist: dEnd(2) = vTemp(2)
   
    pts(0) = dStart(0)
    pts(1) = dStart(1)
    pts(2) = dStart(2)
    pts(3) = dEnd(0)
    pts(4) = dEnd(1)
    pts(5) = dEnd(2)
   
    CursorSelection = pts
    'ThisDrawing.GetVariable("pickbox")=pixels?
    'pixelHeight=windows api height of active screen in pixels
    'ThisDrawing.GetVariable("viewsize")=Stores the height of the view in the current viewport. Expressed in drawing units
End Function






Public Function DeleteSelectionSet(SSetName As String)
    Dim SSets As AcadSelectionSets
    Dim sset As AcadSelectionSet
    Set SSets = ThisDrawing.SelectionSets
    For Each sset In SSets
        If sset.Name = SSetName Then
            sset.Delete
            Exit For
        End If
    Next
    Set SSets = Nothing
End Function

DaveW

  • Guest
Re: TranslateCoords with viewport twistangle <> 0
« Reply #4 on: July 24, 2006, 10:59:12 PM »
Bryco,

I am not sure why or how, but this seems to work for me for any viewport, no mattrer what. It may provide some insight. I came across this combination after a whole lot of trial an error.



Code: [Select]
thisdrawing.ActiveSpace = acPaperSpace
thisdrawing.SendCommand "_ucs" & vbCr & "w" & vbCr

thisdrawing.MSpace = False

Set ActLayout = thisdrawing.ActiveLayout
Set util = thisdrawing.Utility




returnPnt1 = thisdrawing.Utility.GetPoint(, "Enter point inside of the viewport you wish to add balloons to: ")

Dim MyViewPortHandle As String
For Each Ent In thisdrawing.PaperSpace
  If LCase(Ent.ObjectName) = "acdbviewport" And _
     LCase(Ent.Layer) <> "0" Then
     
     Set currView = Ent
     MyViewPortHandle = currView.Handle
     currView.GetBoundingBox minExt, maxExt
     ViewportX = Round(maxExt(0) - minExt(0), 5)
     ViewportY = Round(maxExt(1) - minExt(1), 5)
     ViewportZ = Round(maxExt(2) - minExt(2), 5)
     
       If returnPnt1(0) > minExt(0) And _
          returnPnt1(0) < maxExt(0) And _
          returnPnt1(1) > minExt(1) And _
          returnPnt1(1) < maxExt(1) Then
         
          HoldPoint1(0) = minExt(0)
          HoldPoint1(1) = minExt(1)
          HoldPoint1(2) = 0
          HoldPoint2(0) = maxExt(0)
          HoldPoint2(1) = maxExt(1)
          HoldPoint2(2) = 0

          GoTo translateNow
       End If
       
  End If
Next




translateNow:


thisdrawing.ActiveSpace = acPaperSpace
thisdrawing.MSpace = True
thisdrawing.ActivePViewport = currView


thisdrawing.SendCommand "_ucs" & vbCr & "v" & vbCr

P1 = HoldPoint1
P2 = HoldPoint2

P1 = util.TranslateCoordinates(P1, acPaperSpaceDCS, acDisplayDCS, False)
M1 = util.TranslateCoordinates(P1, acDisplayDCS, acUCS, False)
     

P2 = util.TranslateCoordinates(P2, acPaperSpaceDCS, acDisplayDCS, False)
M2 = util.TranslateCoordinates(P2, acDisplayDCS, acUCS, False)


thisdrawing.ActiveSpace = acPaperSpace
thisdrawing.MSpace = True
thisdrawing.ActivePViewport = currView
thisdrawing.SendCommand "_ucs" & vbCr & "v" & vbCr

On Error Resume Next
thisdrawing.SelectionSets("newselset").Delete
On Error GoTo ET
Set ssobjects = thisdrawing.SelectionSets.Add("newselset")


  ssobjects.SelectOnScreen



Dim MinValue As Double
Dim MaxValue As Double
Dim MidValue As Double

On Error Resume Next

For Each Ent In ssobjects
   If LCase(Ent.ObjectName) = "acdb3dsolid" Then
     
      Set MySolid = Ent
      thisdrawing.MSpace = True
      thisdrawing.SendCommand "_ucs" & vbCr & "w" & vbCr


      Dim momentOfInertia As Variant
      momentOfInertia = MySolid.Centroid
      M1 = momentOfInertia
     
     
      P1 = util.TranslateCoordinates(M1, acWorld, acDisplayDCS, False)
      P1 = util.TranslateCoordinates(P1, acDisplayDCS, acPaperSpaceDCS, False)
     
      thisdrawing.MSpace = False
     
      Set MSpt = thisdrawing.PaperSpace.AddPoint(P1)

      MSpt.Color = 30
     
   End If
Next

Bryco

  • Water Moccasin
  • Posts: 1883
Re: TranslateCoords with viewport twistangle <> 0
« Reply #5 on: July 25, 2006, 12:59:24 AM »
Thanks Dave
But it seems you are doing something similar. We are both changing  mspace to get a correct translation.
How to do that without changing is the trick.

DaveW

  • Guest
Re: TranslateCoords with viewport twistangle <> 0
« Reply #6 on: July 25, 2006, 09:12:24 AM »
Your code is very impressive. I have been looking at it and getting very impatient, as I want to give it a try. I have way too much on my plate right now. I am just using the centroid, so I have a feeling my code will not work for an auto-dimensioning module, but yours will.

Before I forget, I seem to remember that in all my trial and error I got some mixed results inserting regen into the mix. Perhaps the issue is caused by the cashing of the viewports? Just a guess, but if we could get around the UCS issue in an elegant way the code could be faster and would put a clear fix to it too so that the issue is clearly seen and documented. "Your the old hand at this", as Mick says, and your help has been invaluable. Thanks for all that you have shared with me and the rest of the group.
« Last Edit: July 25, 2006, 09:14:26 AM by DaveW »

Bryco

  • Water Moccasin
  • Posts: 1883
Re: TranslateCoords with viewport twistangle <> 0
« Reply #7 on: July 25, 2006, 10:13:27 AM »
Thanks Dave. This is another part of vba that I'm probably not going to get.