How to get intersection point on wall

How to get intersection point on wall

desdinova
Advocate Advocate
5,117 Views
18 Replies
Message 1 of 19

How to get intersection point on wall

desdinova
Advocate
Advocate

hi friends

I want to get the point reference on the wall that intersects the detail line.

Please see the attachment that shows what i want to get. 

Thanks in advance..intersection.png

0 Likes
5,118 Views
18 Replies
Replies (18)
Message 2 of 19

ollikat
Collaborator
Collaborator
Hi.

Although I don't have much experience playing with the intersection stuff, I think I can give you some tips from API that might help you to start.

From detail line you can get curve from "GeometryCurve" property. Then you need to get the faces from the walls (I think there's lot of story about this in BuildingCoder site for example). Then you need to loop trough the faces and use The Intersect() method of Face object, that takes a Curve as an argument.

Hope this helps.
Message 3 of 19

jeremytammik
Autodesk
Autodesk

Hi.

 

Use the ReferenceIntersector class:

 

http://www.revitapidocs.com/2017/36f82b40-1065-2305-e260-18fc618e756f.htm

 

Here is a full explanation of using it:

 

https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2018/ENU/Revit-API/files/GUID-...

 

Here is a full-fledged example:

 

http://thebuildingcoder.typepad.com/blog/2011/02/dimension-walls-using-findreferencesbydirection.htm...

 

It uses the ReferenceIntersector class to determine a point on a neighbouring, parallel wall to create dimensioning.

 

At that time, the method was called FindReferencesByDirection. It was later wrapped in the ReferenceIntersector class. The external command CmdDimensionWallsFindRefs demonstrating its use has been updated to use the new class and is available in The Building Coder samples on GitHub:

 

https://github.com/jeremytammik/the_building_coder_samples

 

Cheers,

 

Jeremy



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

0 Likes
Message 4 of 19

AH_Yafim
Enthusiast
Enthusiast

Hi,

@desdinova 

 

Have you found a solution?

With the suggestion by @ollikat  I was able to find the intersections as SetComparisonResult but I can't get the XYZ points themselves.

 

The solution that Jeremy linked to with ReferenceIntersector is good but it doesn't find angled walls.. all walls with this method have to be parallel.

 

 

Any luck there?

Thanks

0 Likes
Message 5 of 19

jeremytammik
Autodesk
Autodesk

You say: 'ReferenceIntersector is good but it doesn't find angled walls.. all walls with this method have to be parallel.'

  

That statement is incorrect.

  



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

0 Likes
Message 6 of 19

AH_Yafim
Enthusiast
Enthusiast

@jeremytammik 

 

Sorry for misleading. I meant to say that my implementation of it found only parallel walls, and seemed not to create the dimension line if oblique walls were involved.

I'd love to know how it can be done otherwise, but I've gone through the examples and the API and haven't found a way.

 

The code I'm using is:

def GetIntersectingElements(doc, origin, vec):
viewTypeCollector = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()
	for i in viewTypeCollector:
		if i.ViewFamily == ViewFamily.ThreeDimensional:
			view3D = i
			viewType = i

	t = Transaction(doc, "Create Temporary 3D View")
	t.Start()
	view3D = View3D.CreateIsometric(doc, viewType.Id)	
	t.Commit()

	wallFilter = ElementClassFilter(Wall)
	refIntersector = ReferenceIntersector(wallFilter, FindReferenceTarget.Edge, view3D)

	referenceWithContext = refIntersector.Find( origin, vec )
	refArray = ReferenceArray()
	for ref in referenceWithContext:
		refArray.Append(ref.GetReference())

	return refArray


# MAIN
origin = uidoc.Selection.PickPoint()
tGroup = TransactionGroup(doc, "Create Dimensions XY")
tGroup.Start()

references = GetIntersectingElements( doc, origin, XYZ(1,0,0) )

t2 = Transaction(doc, "Create Dimension X")
t2.Start()

refLine = Line.CreateUnbound( origin, XYZ(1,0,0) )	
gridDimension = doc.Create.NewDimension(doc.ActiveView, refLine, references)

t2.Commit()
tGroup.Commit()

 

This successfully dimensions between a series of walls, but only when parallel.

I was thinking that as per the other approach, finding the intersections between Faces and the Curve could produce more robust results for different kinds of wall orientation.

0 Likes
Message 7 of 19

AH_Yafim
Enthusiast
Enthusiast

Another followup question if I may:

 

refIntersector = ReferenceIntersector(wallFilter, FindReferenceTarget.Edge, view3D)

 

seems to return only one "side" of the wall. Only one of the edges, not both. Specifically, the one in on the side of the origin of the projected ray. 

But how to get both edges of the wall to dimension the wall thickness as well...?

 

Thank you 

0 Likes
Message 8 of 19

jeremytammik
Autodesk
Autodesk

Normally, it returns all the faces traversed by the ray. Going through the middle of the wall, that would normally be two, the front and the back, both.

 



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

0 Likes
Message 9 of 19

AH_Yafim
Enthusiast
Enthusiast

@jeremytammik 

 

Would you recommend changing 

FindReferenceTarget.Edge

 

to 

FindReferenceTarget.Face

and then finding one of the edges of each face? 

0 Likes
Message 10 of 19

AH_Yafim
Enthusiast
Enthusiast

Adding onto my previous post, I've tried some more things:

 

I've tried changing FindReferenceTarget.Edge to FindReferenceTarget.Face but I get a "One or more dimension references are or have become invalid." error, which I can't understand. Setting it to FindReferenceTarget.Element does produce dimensions, on the center-line of the walls.

 

The thing is, if I display the type of reference element found in the following loop, it displays 6 references (all of which are , matching what you said about 2 faces of each wall. But the dimension itself is only drawn on the "first" face being hit by the ray direction:

 

 

wallFilter = ElementClassFilter(Wall)
refIntersector = ReferenceIntersector(wallFilter, FindReferenceTarget.Edge, view3D)

referenceWithContext = refIntersector.Find( origin, vec )
refArray = ReferenceArray()
for ref in referenceWithContext:
    wall = doc.GetElement(ref.GetReference())
    print(type(wall))
    print(type(ref))    
    refArray.Append(ref.GetReference())

 

 

The output is:

 

<type 'Wall'>
<type 'ReferenceWithContext'>
<type 'Wall'>
<type 'ReferenceWithContext'>
<type 'Wall'>
<type 'ReferenceWithContext'>

 

 

I'm also attaching an image showing the resulted dimension, where the ray intersects left to right and only hits the "first" edge of each wall.

Capture.JPG

 

Thank you 

0 Likes
Message 11 of 19

jeremytammik
Autodesk
Autodesk

Well, an edge is 1-dimensional, and thuds infinitely thin, so your chance of hitting it with a ray is infinitely small.

 

If you wish to raise your chance to something that differs significantly from zero, a face is a better bet than an edge.

 

Furthermore, you ned to take imprecision into account.

 

When trying to intersect two curves, or, in this case, a ray and an edge. you never know what you will get unless you add some fuzziness to your calculations:

 

https://thebuildingcoder.typepad.com/blog/2018/12/rebars-in-host-net-framework-and-importance-of-fuz...

 

 

 



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

0 Likes
Message 12 of 19

AH_Yafim
Enthusiast
Enthusiast

Thank you 🙂

Yes I agree, I've seen your remark regarding this elsewhere.

But seeing as .Face produces the error I mentioned, do you have an idea why that might be? I see no reason why going from Edge to Face should suddenly not work.

0 Likes
Message 13 of 19

jeremytammik
Autodesk
Autodesk

Yes, I definitely think requesting the element itself instead of a face or an edge from the ray tracer is the best place to start.

 

Regarding the faces found, you can always compare the results of your programmatic add-in solution with the required and desired results that you achieve manually through the user interface. Determine the differences, eliminate them, and Bob's your uncle:

 

http://thebuildingcoder.typepad.com/blog/2017/01/virtues-of-reproduction-research-mep-settings-ontol...

 



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

0 Likes
Message 14 of 19

jeremytammik
Autodesk
Autodesk

You can use the ray tracer to determine the elements that you wish to dimension, then request their geometry with ComputeReferences == true and pick any faces you like to create the dimensioning. Look at the two different approaches dimensioning parallel walls:

 

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.45

 

One of them uses references retrieved via the Geometry property, the other uses the ones produced by the ray tracer.

 

 

 



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

0 Likes
Message 15 of 19

RPTHOMAS108
Mentor
Mentor

The way these wall have been dimensioned isn't telling anyone how to set them out, it perhaps strikes through centre line of first wall but not others. If I were unfortunate enough to have to set out such a wall arrangement from an architect it would be done similar to below, this represents the minimum amount of geometric information needed to convey the location of the walls to site (excluding levels). We would obviously be using common grids to dimension from where possible.

 

Alternatively you could use spot coordinates for each wall end, angles and wall lengths from one end but not an inherently random point between the extents of a wall. Why a detail line and not a grid? 

 

200615a.PNG

 

 

In the UI all these references would be from from solid geometry or grids i.e. things permanently visible in the view. If you hide/remove your detail line/grid then so goes all your dimensioning with it. This is why you will struggle with this in the API because the way you are dimensioning would not be usual in the UI (creating references to dimension things rather than using inherent ones). You would have to tab to the intersection between detail line and wall face and then what would that point on the wall tell you?

 

Not sure if the discussion has evolved beyond this but the drive for these requests is usually to automatically dimension things. I think there is an art to dimensioning things a balance between eliminating errors from running dimensions and compacting the space taken up by absolute ones. Deciding which side of an element to drag the dimension text. Moving text clear of lines and into empty spaces. A long way to go before eliminating the human. Probably in the BIM world we should just list the setting out points in a table and mark them up with reference point keys on the plan. Easier to compare the changes in two lists of points in excel than overlaying dimensions on a plan that could be done in numerous different ways.

0 Likes
Message 16 of 19

AH_Yafim
Enthusiast
Enthusiast

Hi,

I've managed to retrieve the Face.Reference of all Wall Elements that intersect the Ray.

 

Each wall gives me 6 references, while I only want the 2 that the Ray intersects.

I might be able to boolean filter the faces by using Intersect Method(Curve) but I need a Curve, not an infinite Ray.

 

How would you recommend to best filter the faces I need?

Thank you

0 Likes
Message 17 of 19

jeremytammik
Autodesk
Autodesk
0 Likes
Message 18 of 19

AH_Yafim
Enthusiast
Enthusiast

@jeremytammik 

Thank you.

I opted for a simpler solution in the end. I discovered that I can get the faces I need by comparing the FaceNormal of each face to the direction of my Ray.

🙂

0 Likes
Message 19 of 19

jeremytammik
Autodesk
Autodesk

Congratulations! Much simpler! KISS: https://en.wikipedia.org/wiki/KISS_principle

 



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