Finding distance between points in multiple views

Finding distance between points in multiple views

Khadourwaseem
Enthusiast Enthusiast
4,935 Views
11 Replies
Message 1 of 12

Finding distance between points in multiple views

Khadourwaseem
Enthusiast
Enthusiast

So I have a probelm, My command prompts the user to place three points on a view to place an annotation symbol, but I need to find the distance between my points and the relationship between them in all views and sections,
(See image) I need to know if P2 is placed higher or lower of P1, and P3 is it to the right or left of P2 and then calculate the distance between them, 
I've tried this method from Jeremy The Building Coder: Planes, Projections and Picking Points (typepad.com)
but the U&V can flip between views, (For example in the north, south elevations the distance between P1&P2 is The U value, and in east, west it's the V value)
For now my command works only on plans. but i want to make it unviersal. Is there such a wayБезымянный.png


0 Likes
Accepted solutions (2)
4,936 Views
11 Replies
Replies (11)
Message 2 of 12

jeremy_tammik
Alumni
Alumni

Basically, your thee points are simple 3D points with cartesian coordinates stored in XYZ objects, so their Euclidian distances and projected offsets along the cardinal axes are trivial to calculate.

 

So, the question remains open what you actually wish to achieve.

 

Do you wish to display the distances between these points using Revit dimensioning in the different views?

 

The most effective approach is probably to figure out what you want and how to achieve it manually in the user interface first.

 

Once that is clear, you can step into the programming environment and explore how to automate it.

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 12

Khadourwaseem
Enthusiast
Enthusiast

All i want to do is to:

  1. calculate the vertical distance between P1 and P2, and figure out if P2 is ABOVE or BELOW P1 
  2. Figure out if P3 is to right or left of P2

My plug in:  place a family instance and set it to one of four possible states : 1. top right, 2.Top left, 3. bottom rightm 4. Bottom left.  depending on the user input

I tried this method:The Building Coder: Planes, Projections and Picking Points (typepad.com)
but you see the vertical distance between p1, p2 is sometimes defined by the distance in U Value (q1.U -q2.U) and sometimes it’s the V Value (q1.V - q2.V) depending on the view.

I need a way to make sure  the vertical axis IS either V or U in all views, sections, plans and so on. Thanks 🙂



0 Likes
Message 4 of 12

jeremy_tammik
Alumni
Alumni

Sorry, but I still do not understand your context.

 

Where do the points P1, P2, etc. come from? Are they picked by the user, or points on a BIM element, or something else?

 

If they are points on a BIM element, they have XYZ coordinates.

 

What does 'vertical' mean? Are you talking about the Z axis in 3D space, or the Y axis on a 2D plane?

 

You mention U and V. Where do they come from?

  

Can you briefly describe the complete situation to clarify the context?

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 5 of 12

Khadourwaseem
Enthusiast
Enthusiast

 

I’m sorry for not being able to explain my idea clearly.. 

But to elaborate, the P1, P2, P3 are points picked by the user, to place an annotation symbol(XYZ P1 = uidoc.selection.Pickpoints()),
And the annotation symbol is a floor detail symbol (generic annotation family)  that has four states and I want the user to be able the set the state of the family in a way that if he click p1, and then click somewhere up on the view and then clicks to the right, the family will be set to a specific state, and if the user click the first point somewhere on the sheet and then goes down and click somewhere, and then goes to the left, he places a new family annotation symbol with a different state.
I have no idea what view the user will be placing the family on, or if some of the  points he places will be snapped to a wall or a floor or to a door or something else. 

I think it’s wrong to use XYZ points for this but I can't seem to find another way to do it.
For now the plugin works only in plan views with nothing in the model (See video). But once the user is in any other view, or elevation it breaks

0 Likes
Message 6 of 12

RPTHOMAS108
Mentor
Mentor
Accepted solution

If you want to compare points in the coordinate system of the view you have to transform them into the coordinate system of the view.

 

Plans and model ordinarily have same system, unless plan view is rotated.

 

 Private Function TObj175(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
        Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
        If UIDoc Is Nothing Then Return Result.Cancelled Else
        Dim IntDoc As Document = UIDoc.Document

        Dim AcView As View = UIDoc.ActiveGraphicalView

        Dim T As Transform = Transform.Identity
        T.BasisX = AcView.RightDirection 'To right of screen
        T.BasisY = AcView.UpDirection 'To top of screen
        T.BasisZ = AcView.ViewDirection 'Towards viewer
        T.Origin = AcView.Origin

        Dim R As Reference = Nothing
        Try
            R = UIDoc.Selection.PickObject(Selection.ObjectType.PointOnElement)
        Catch ex As Exception

        End Try
        Dim Pt As XYZ = R.GlobalPoint
        Dim PtT As XYZ = T.Inverse.OfPoint(Pt) 'Tranform to screen coord space

        Dim SB As New Text.StringBuilder()

        SB.AppendLine(String.Format("Model x={0:F3},y={1:F3},z={2:F3}", Pt.X, Pt.Y, Pt.Z))
        SB.AppendLine(String.Format("Screen x={0:F3},y={1:F3},z={2:F3}", PtT.X, PtT.Y, PtT.Z))

        TaskDialog.Show("Coords", SB.ToString)


        Return Result.Succeeded
    End Function

 

 

 

0 Likes
Message 7 of 12

jeremy_tammik
Alumni
Alumni
Accepted solution

Thank you Richard for the illuminating explanation and nice sample code!

 

Here it is in C#:

 

bool TransformPickPointToScreen( UIDocument uidoc )
{
  Document doc = uidoc.Document;
  View view = uidoc.ActiveGraphicalView;

  Transform t = Transform.Identity;
  t.Origin = view.Origin;
  t.BasisX = view.RightDirection; // right on screen
  t.BasisY = view.UpDirection; // top of screen
  t.BasisZ = view.ViewDirection; // towards viewer

  Transform x_model_to_screen = t.Inverse;

  Reference r;

  try
  {
    r = uidoc.Selection.PickObject( ObjectType.PointOnElement );
  }
  catch(Autodesk.Revit.Exceptions.OperationCanceledException)
  {
    return false;
  }

  XYZ p = r.GlobalPoint; // model
  XYZ q = x_model_to_screen.OfPoint( p ); // screen

  StringBuilder sb = new StringBuilder();
  sb.AppendFormat( "Model x={0:F3},y={1:F3},z={2:F3}", p.X, p.Y, p.Z );
  sb.AppendFormat( "Screen x={0:F3},y={1:F3},z={2:F3}", q.X, q.Y, q.Z );

  TaskDialog.Show( "Coords", sb.ToString() );

  return true;
}

  

https://github.com/jeremytammik/the_building_coder_samples/compare/2021.0.150.23...2021.0.150.24

 

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 8 of 12

Khadourwaseem
Enthusiast
Enthusiast

Thank you. 🙂

0 Likes
Message 9 of 12

Khadourwaseem
Enthusiast
Enthusiast

I have a follow up:

1. If i want to move an element up, left, or right. how can i transfer from the coordinate system of the screen to the global coordinate system

0 Likes
Message 10 of 12

RPTHOMAS108
Mentor
Mentor

Depends what method you are using to move the element.

 

The destination location in model coords can be found similar to above but with .Inverse omitted.

0 Likes
Message 11 of 12

Khadourwaseem
Enthusiast
Enthusiast

I am using this method :

XYZ aboveleft_vector = new XYZ(How much I want to move the element left&right, How much I want to move the element up&down, 0);

ElementTransformUtils.MoveElement(doc, Floor_detail_Instance.Id, aboveleft_vector);
It works just fine in a plan view, but for different views. Is there an example or a post where I can see how it can be done

0 Likes
Message 12 of 12

RPTHOMAS108
Mentor
Mentor

You can use Transform.OfVector, this ignores origin in transformation.

 

ElementTransformUtils is expecting vector in model co-ords so again without inverse.

 

Alternatively you can convert start and end point locations to model space first using OfPoint and get the vector by subtracting the start from the end.

 

Depends also what you are trying to move, some things are fixed to a plane (so can't be moved in global z for example).

0 Likes