XYZ coordinates of the point on the face by selection

XYZ coordinates of the point on the face by selection

gprofile
Enthusiast Enthusiast
6,139 Views
9 Replies
Message 1 of 10

XYZ coordinates of the point on the face by selection

gprofile
Enthusiast
Enthusiast

Hello All,

 

I am trying to create a family which displays the spot elevation of the uneven surface, which has been discussed several times in the forum and seems to be insoluble thing. So i decided to create a small macro which prompts me to select the point on a face and displays the XYZ coordinates at the selection. 

 

 

The problem here is its throwing  "Null Reference Exception" dont really understand which object its referring to.image.pngCould somebody point where I am doing wrong.

 

 

public void selectPoint()
		{
			UIDocument uiDoc = this.ActiveUIDocument;
			Document doc = uiDoc.Document;
			
			Reference myRef = uiDoc.Selection.PickObject(ObjectType.PointOnElement);
			Element e = doc.GetElement(myRef);
			
			GeometryObject geomObj = e.GetGeometryObjectFromReference(myRef);
			Point p = geomObj as Point;
	
			TaskDialog.Show("Element Info",e.Name + p.Coord);
			
		}

 

0 Likes
Accepted solutions (1)
6,140 Views
9 Replies
Replies (9)
Message 2 of 10

dragos.turmac
Autodesk
Autodesk

Hi,

 

Have a warm welcome to the forum and C# coding traps 🙂

In C# (and any programming language for that matter) it is good practice to verify an object before using it and return or show a relevant message when it is the case. For you, one example could be:

 

Reference myRef = uiDoc.Selection.PickObject(ObjectType.PointOnElement);
if ( myRef == null )
{ TaskDialog.Show("Crash","myRef is null");
return;
} Element e = doc.GetElement(myRef); if ( e == null )
{ TaskDialog.Show("Crash","e is null");
    return;
}

One other possibility is to enter the debugging mode of Revit macro system; instead on using "Run" command of the macro, you can use the "Step Into" option. Once the C# editor pops up, press F10 to run the code line by line. When the crash occurs, you will know the line and variable that was null.



Turmac Dragos
Pr. SW. Engineer
Message 3 of 10

FAIR59
Advisor
Advisor

Use this to get the element:

 

 Element e = doc.GetElement(  myRef.ElementId);
Message 4 of 10

FAIR59
Advisor
Advisor
Accepted solution

second remark.

The GeometryObject is only in very rare cases a Point. Far more likely it will be a Surface, Edge, or Curve.

 

The reference has a property GlobalPoint, which you can use to get the coordinates of the selected point.

 

Reference myRef = uiDoc.Selection.PickObjec(ObjectType.PointOnElement);
Element e = doc.GetElement(myRef.ElementId);
			
GeometryObject geomObj = e.GetGeometryObjectFromReference(myRef);
//			Point p = geomObj as Point;
XYZ p = myRef.GlobalPoint;
string pointString = p==null? "<reference has no globalpoint>": string.Format("{0}",p);
TaskDialog.Show("Element Info",e.Name +"   "+pointString );

 

 

Message 5 of 10

gprofile
Enthusiast
Enthusiast

Haha C# trap... Many thanks for your great advice for a beginner. Will add it to my checklist before running a Macro.

0 Likes
Message 6 of 10

gprofile
Enthusiast
Enthusiast

Now I understand why Thanks a lot for your solution 🙂 !!!

 

I have just one quick question which is off topic is it possible to get the spot elevation for the point on face by the same way? I read in the revit API that it is a Enumeration member of the Built in category in Revit. A small hint or suggestion would be great.

0 Likes
Message 7 of 10

FAIR59
Advisor
Advisor

A spot elevation is an element of class SpotDimension. This has a property Origin, which will get you the "placement point" of the spot elevation.

 

// SpotElevation selected in UI

SpotDimension dim = doc.GetElement(selection.GetElementIds().FirstOrDefault()) as SpotDimension; if (dim==null) return; TaskDialog.Show("debug","placementpoint "+ string.Format("{0}", dim.Origin));
Message 8 of 10

gprofile
Enthusiast
Enthusiast

Thank you it works perfectly.

 

Sorry for my bad explanation in the last post, what I am trying to do is to convert the selection of the point on the face and give me the value of the spot elevation of that point on that face. Since the surface of my floor slab isn't flat I wasn't able to place the spot elevation tag on the desired spot.

 

 

UIDocument uiDoc = this.ActiveUIDocument;
Document doc = uiDoc.Document;
Selection selection = uiDoc.Selection;
			
			
Reference myRef = selection.PickObject(ObjectType.PointOnElement);
GeometryObject geomObj = e.GetGeometryObjectFromReference(myRef);
XYZ pt = myRef.GlobalPoint;
		
/* somewhere here i want the code to place the spot elevation annotation or get the elevation of the point selected on that face
I dont know how to place the spot elevation on that point(pt) selected */
			
SpotDimension dim = doc.GetElement(selection.GetElementIds().FirstOrDefault()) as SpotDimension;
if (dim==null) return;
TaskDialog.Show("debug","placementpoint   "+ string.Format("{0}",  dim.Origin));
			

Spot coordinates.gif

 

 Thank you

Message 9 of 10

FAIR59
Advisor
Advisor

you can place a SpotElevation anywhere on the selected face, using the Reference from PickObject

 

this code places a number of spotElevations in line on the face. If the XYZ-point is not on the face, then the  CreateSpotElevation method throws an exception, which you have to catch.

 

			Reference myRef = uiDoc.Selection.PickObject(ObjectType.PointOnElement);
			XYZ pRef = myRef.GlobalPoint;
			using (Transaction t = new Transaction(doc, "spotElevation"))
			{
				t.Start();
				for (int ip =0; ip<100; ip++)
				{
					try
					{
					using (SubTransaction st = new SubTransaction(doc))
					{
						st.Start();
						XYZ p = myRef.GlobalPoint.Add(new XYZ(ip*1,0,0));
						XYZ bend = p.Add(new XYZ(2,2,0));
						XYZ end = p.Add(new XYZ(3,2,0));
						doc.Create.NewSpotElevation(doc.ActiveView,myRef,p,bend,end,p,true);
						st.Commit();
					}
					}
					catch
					{
						
					}
					}
				t.Commit();
			}
Message 10 of 10

Anonymous
Not applicable

Can it still return the global point if I am not clicking on a specific element? i.e. I want to know the position of my mouse click with reference to Revit coordinates, regardless of whether I am clicking on an element of not. Thank you!

0 Likes