Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Adding Closest Grid Point Intersection to object in Revit

9 REPLIES 9
Reply
Message 1 of 10
Fangchao.gong
3424 Views, 9 Replies

Adding Closest Grid Point Intersection to object in Revit

Hi, everyone, 

 

I am working on a project in which we want to locate objects with the nearest grids intersection.

 

so i have used the column location mark property to meet my need. the solution is described with the codes belows:

 

using (TransactionGroup transGroup = new TransactionGroup(document,"Transaction Group"))
			{
				transGroup.Start("Upgrade signages identity informations");
				
				foreach (ElementId eid in SelectedElements)
				{
					var e = document.GetElement(eid) as FamilyInstance;
					LocationPoint lp = e.Location as LocationPoint;
					XYZ loc = new XYZ(lp.Point.X,lp.Point.Y,0);
					ElementId levelId = e.LevelId;
					Level level = document.GetElement(levelId) as Level;
					
					Transaction tr1 = new Transaction(document,"Get Coordinates");
					tr1.Start();
					FamilyInstance newPoteau = document.Create.NewFamilyInstance(loc, familySymbol, level, Autodesk.Revit.DB.Structure.StructuralType.Column);
					tr1.Commit();
					
					Parameter p1 = newPoteau.get_Parameter(BuiltInParameter.COLUMN_LOCATION_MARK);
					string locationParam = p1.AsString();
					

					//enlever distance dans la chaine de caractère
					
					int index1= locationParam.IndexOf('(');
					int index2= locationParam.IndexOf(')');
					
					if(index1!=-1)
					{locationParam = locationParam.Remove(index1,index2-index1+1);}
					
					int index3= locationParam.IndexOf('(');
					if(index3!=-1)
					{locationParam = locationParam.Remove(index3);}
					
					locationParam = locationParam.Replace('-',',');
					
					//Take Level Code and Increment number
					Parameter pLevel = level.get_Parameter(levelCodeParam);
					levelCode = pLevel.AsString();
					if(String.IsNullOrEmpty(levelCode))
					{
						levelCode ="??";
					}
					
					Parameter pIncrement = e.get_Parameter(incrementParam);
					increment = pIncrement.AsString();
					if(String.IsNullOrEmpty(increment))
					{
						increment="1";
					}
					
					Parameter pType = document.GetElement(e.GetTypeId()).get_Parameter(signageTypeParam);
					signageType = pType.AsString();

					
					Parameter pID= e.get_Parameter(BuiltInParameter.DOOR_NUMBER);
					signageID = signageType+"-"+levelCode+"-"+locationParam+"-"+increment;
					
					
					
					//Fill Tag
					Transaction tr2 = new Transaction (document,"Fill Tag");
					tr2.Start();
					e.get_Parameter(xyParam).Set(locationParam);
					document.Delete(newPoteau.Id);
					e.get_Parameter(signageLevelCodeParam).Set(levelCode);
					e.get_Parameter(incrementParam).Set(increment);
					e.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(signageID);
					tr2.Commit();
				}
				
				transGroup.Assimilate();
			}

I have to commit a column creation transaction in order to get the COLUMN_LOCATION_MARK property, and then delete the column in a other transaction.

 

I am pretty sure that this is not a good idea to do the thing in this way since there are so many operations on the file. so i am wondering if i can:

 

1. get the things done without commit the transaction in which we have creation and supression of a column object.

 

2. if there's a API methode to get the location mark

 

Thanks a lot.

9 REPLIES 9
Message 2 of 10

Dear Fangchao Gong,

 

Thank you for your query.

 

I do not understand what you are trying to achieve, nor what the code has to do with your brief description.

 

Please elaborate.

 

Thank you.

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 10

Hi,Jeremy, Thanks a lot for your reply. And also thanks a lot for your blog, the articles are very helpful and I have learnt a lot from them.

 

For the macro, i want to know the location of all the objects in the project ( the coordinates like X1, Y1).  While we are studying the project, we want to find the object rapidly with the grids intersection.

 

In REVIT, only the structural column have a property "COLUMN_LOCATION_MARK" which gives me the possiblity to have this kind of coordinates.

 

This is why i have written the codes above to place a structural column and then commit a transaction,after which I can get a "COLUMN_LOCATION_MARK" value.  copy and paste it to one of my object properties. and at last, delete the column object.

 

I am wondering if there is a better way to do this thing in Revit since there is so many operations on the model. 

 

 

Message 4 of 10

Dear Fangchao Gong,

 

Thank you for your update, appreciation, and more detailed explanation.

 

When you say "coordinates like X1, Y1", I must answer that every single object in Revit provides those straight out of the box, with no need whatsoever for the expensive acrobatics you describe.

 

I have no idea why you think you need a structural column and its COLUMN_LOCATION_MARK property to access this kind of coordinates.

 

Well, actually, if I attempt a guess, I would surmise that you might be after the coordinates converted from the local project coordinate system to some kind of global coordinate system.

 

In that case, there are much simpler and more direct solutions.

 

Hopefully, this one will fulfil your needs:

 

http://thebuildingcoder.typepad.com/blog/2014/11/concrete-setout-points-for-revit-structure-2015.htm...

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 5 of 10

Hi, Jeremy,

 

With a picture, i can explain better my propose. 🙂 Sorry for my English, i haven't praticed it for a long time. ( France here 🙂 )

 

To locate a object, i can have a X,Y coordinate. but it's too diffcult to find it if we have only a Dwg and Excel file. so we want to locate it with the grid intersection.

 

for exemple, the red point on the image, i want a value like (A,2).

 

If the COLUMN_LOCATION_MARK is not the only solution. i have to read all the grids intersections and calculate the distance between my object and all of them to find the smallest value?

 

 

Message 6 of 10

Dear Fangchao Gong,

 

Thank you for your update and helpful sample image.

 

Your English is perfectly fine 🙂

 

Now I understand better what you are after.

 

Yes, I would definitely suggest calculating the grid line intersection points and determining the closest one yourself.

 

That sounds vastly more efficient than asking Revit to create temporary BIM elements and commit transactions to place and query them.

 

You could even have additional fun by defining a lexicographical ordering on the grid points and managing them in a .NET dictionary.

 

That would make the lookup process extremely fast.

 

Please let me know if you need any help with that.

 

If so, please provide a complete reproducible case and sample model to play with:

 

http://thebuildingcoder.typepad.com/blog/about-the-author.html#1b

 

Thank you!

 

I hope this helps.

 

Good luck and best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 7 of 10
m.vallee
in reply to: Fangchao.gong

Hi Chao,

 

Very funny to see you here 🙂  Comment vas-tu ?

 

It seems that everybody is now digging in the Revit API !

 

The subject you want to deal with is very interesting ! Please let us know if you achieve your goals !

 

M. V.

Message 8 of 10
Fangchao.gong
in reply to: m.vallee

yes Maxime, it helps a lot the api.

 

and with the help of Jeremy, i have at last the things done .-)

 

public void getNearestIntersectionPoint()
			
		{
			UIDocument uidoc =ActiveUIDocument;
			Document doc = ActiveUIDocument.Document;
			Selection sel = uidoc.Selection;
			ICollection<ElementId> ecol = sel.GetElementIds();
			
			Dictionary<string,XYZ> intersectionPoints = getIntersections(doc);
			string intersection = "??";
			
			foreach(ElementId eid in ecol)
			{
			Element e = doc.GetElement(eid);
			LocationPoint p = e.Location as LocationPoint;
			
			XYZ xyz= new XYZ(p.Point.X, p.Point.Y,0);
			double distanceMin = 0;
			double distance =0;
			
			distanceMin =xyz.DistanceTo( intersectionPoints.First().Value);
			foreach (KeyValuePair<string,XYZ> kp in intersectionPoints)
			{
				distance = xyz.DistanceTo(kp.Value);
				if (distance<distanceMin)
				{distanceMin=distance;
				 intersection = kp.Key;
				}

			}
			
			double distanceInMeter = distanceMin/3.281; 
			MessageBox.Show(intersection);
			}
			
			
		
		}
				
		#region build dictionary
		public Dictionary<string,XYZ> getIntersections(Document doc)
		{
		
		string coordinate = null;
		string coordA= null;
		string coordB= null;
		string coordC = null;
		Dictionary<string,XYZ> intersectionPoints = new Dictionary<string,XYZ>();
		
		
		ICollection<ElementId> grids = new  FilteredElementCollector(doc).WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Grids)).WhereElementIsNotElementType().ToElementIds();
		
		ICollection<ElementId> refgrid = new  FilteredElementCollector(doc).WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Grids)).WhereElementIsNotElementType().ToElementIds();
		foreach( ElementId eid in grids)
			
		{
			Grid g = doc.GetElement(eid) as Grid;
			
			coordA = g.Name;
			
			Curve c = g.Curve;
			
			refgrid.Remove(eid);
			
			foreach(ElementId eid2 in refgrid)
			{
				Grid g2 = doc.GetElement(eid2) as Grid;
				
				coordB = g2.Name;
				Curve c2 = g2.Curve;
				
				IntersectionResultArray results;
				
    			SetComparisonResult result = c.Intersect(c2, out results);

    			if( result != SetComparisonResult.Overlap )
    			{	}
 		
    			else if( results == null || results.Size != 1 )

    			{}
    			
    			else if (results.Size>0)
    			{
    				for (int i =0; i<results.Size; i ++)
    				{
    					IntersectionResult iresult = results.get_Item(i);
    					coordC = i.ToString();
    					
    					coordinate = coordA+","+coordB+"-"+coordC;
    					
    					XYZ point = iresult.XYZPoint;
    					
    					intersectionPoints.Add(coordinate,point);
    					
    				}
    			}
    			continue;				
			}
		
		}
		return intersectionPoints;
		}
	#endregion

and Jeremy, Thank you a lot 🙂

Message 9 of 10
Fangchao.gong
in reply to: m.vallee

Hi, Maxime 😉 nice to see you here!

I can get all I want with my code. But in a not really elegant way;) so jeremy have pointed it out and I am try to iterate all the grids to find the intersection and try to get the distance with my element in order get the small distance.

But it demande much more energies. I am working on it. 😉
Message 10 of 10

I'm very interested in this but I'm not so much in the coding side. I go as far as dynamo. 

 

I do wish this was a property that Revit just automatically filled out as this would translate very nicely to equipment in BIM 360 field and give an object an actual location. 

 

Regardless of my coding knowledge I still look forward to seeing what you come up with. Maybe it could become an add-on? 

 

Thanks,

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


Rail Community