How to Get a Reference to an Intersection or Virtual Intersection Point in Revit for Creating an Associative 2D Dimension

How to Get a Reference to an Intersection or Virtual Intersection Point in Revit for Creating an Associative 2D Dimension

gopinadh7XTGG
Contributor Contributor
882 Views
7 Replies
Message 1 of 8

How to Get a Reference to an Intersection or Virtual Intersection Point in Revit for Creating an Associative 2D Dimension

gopinadh7XTGG
Contributor
Contributor

I am trying to create a dimension between the intersection points of detail lines in a drawing, as shown in the image.

While I managed to create a dimension using some workarounds (since I couldn’t directly reference the intersection point), the dimension is not associative. This means that when I move any of the detail lines, the dimension does not update to reflect the new intersection point—it stays in its original position.

Workaround Attempts

1. Creating Small Detail Lines at Intersection Points – Placing short detail lines at the intersection and using them as reference.

gopinadh7XTGG_4-1739338274155.png

gopinadh7XTGG_5-1739338281547.png

 

2. Using Endpoints of Detail Lines – Creating two detail lines at the intersection and using their endpoints as reference.

 

gopinadh7XTGG_6-1739339306278.pnggopinadh7XTGG_7-1739339413775.png

 

However, in both cases, the dimension is not associative, meaning it does not update when the detail lines move.

 

I also tried creating a point using the Point.Create() method, but the reference returns null.

Can someone help me resolve this issue?


Below is the code I am using.

UIDocument uiDoc = TestingUI.UIDocument;
Autodesk.Revit.DB.Document doc = uiDoc.Document;
 
IList<Reference> selectedRefs = uiDoc.Selection.PickObjects(
ObjectType.Element,
new DetailLineSelectionFilter(),
"Select four detail lines"
);
 
if (selectedRefs.Count != 4)
{
TaskDialog.Show("Error", "Please select exactly four detail lines.");
//return Result.Failed;
}
 
XYZ pos = TestingUI.SelectPoint();
 
List<Line> lines = new List<Line>();
List<Element> detailLines = new List<Element>();
 
foreach (Reference reference in selectedRefs)
{
DetailLine detailLine = doc.GetElement(reference) as DetailLine;
if (detailLine == null)
{
TaskDialog.Show("Error", "Selected elements must be detail lines.");
//return Result.Failed;
}
 
lines.Add((Line)detailLine.GeometryCurve);
detailLines.Add(detailLine);
}
 
// Find intersection points
List<XYZ> intersectionPoints = new List<XYZ>();
 
IntersectionResultArray results1;
lines[0].Intersect(lines[1], out results1);
 
intersectionPoints.Add(results1.get_Item(0).XYZPoint);
 
IntersectionResultArray results2;
lines[2].Intersect(lines[3], out results2);
 
intersectionPoints.Add(results2.get_Item(0).XYZPoint);
 
using (Transaction transaction = new Transaction(doc, "point to point"))
{
transaction.Start();
 
Line vline1 = Line.CreateBound(lines[0].GetEndPoint(1), intersectionPoints[0]);
DetailCurve vdetailCurve1 = doc.Create.NewDetailCurve(doc.ActiveView, vline1);
 
Line vline2 = Line.CreateBound(lines[1].GetEndPoint(1), intersectionPoints[0]);
DetailCurve vdetailCurve2 = doc.Create.NewDetailCurve(doc.ActiveView, vline2);
 
Line vline3 = Line.CreateBound(lines[2].GetEndPoint(1), intersectionPoints[1]);
DetailCurve vdetailCurve3 = doc.Create.NewDetailCurve(doc.ActiveView, vline3);
 
Line vline4 = Line.CreateBound(lines[3].GetEndPoint(1), intersectionPoints[1]);
DetailCurve vdetailCurve4 = doc.Create.NewDetailCurve(doc.ActiveView, vline4);
 
Reference vlineRef1 = vdetailCurve1.GeometryCurve.GetEndPointReference(1);
Reference vlineRef2 = vdetailCurve3.GeometryCurve.GetEndPointReference(1);
 
ReferenceArray referenceArray = new ReferenceArray();
 
referenceArray.Append(vlineRef1);
referenceArray.Append(vlineRef2);
 
Point point1 = Point.Create(intersectionPoints[0]);
Point point2 = Point.Create(intersectionPoints[1]);
 
Reference pointRef1 = point1.Reference;
Reference pointRef2 = point2.Reference;
 
//pointRef1 & pointRef2 references are null
 
 
Line dimensionLine = Line.CreateUnbound(pos, doc.ActiveView.RightDirection);
 
Dimension dimension = doc.Create.NewDimension(doc.ActiveView, dimensionLine, referenceArray);
 
transaction.Commit();
}




 

 

0 Likes
883 Views
7 Replies
Replies (7)
Message 2 of 8

jeremy_tammik
Alumni
Alumni

Maybe you can create a constraint to ensure that your helper objects remain in the correct position and move with the target objects when needed.

  

Another possible approach, but probably more programming effort and also more execution overhead, might be to implement an updater using the DMU framework.

    

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

reylorente1
Collaborator
Collaborator

It works for me; I don't see any errors.

0 Likes
Message 4 of 8

reylorente1
Collaborator
Collaborator

It works for me , I don't see any error

0 Likes
Message 5 of 8

gopinadh7XTGG
Contributor
Contributor

Hi @reylorente1, 

Thank you for quick reply.
Please Try moving a single line at a time to adjust the intersection. This will help you see the error more clearly.

Preview
 
 
 
0 Likes
Message 6 of 8

gopinadh7XTGG
Contributor
Contributor

Hi @jeremy_tammik,

 

Thank you for the suggestion. I couldn't find any APIs for constraints. The only constraint option I found in Revit is the Equal constraint, which ensures selected dimensions are of equal length.

Could you suggest how I can apply a coincidence constraint between the start/end points of my helper lines and the intersection point?

0 Likes
Message 7 of 8

jeremy_tammik
Alumni
Alumni

Afaik, this requires you to align the two constrained objects, create a linear dimension between them (which will show zero distance) and lock the dimension. Here is how Mistral le Chat formulates that suggestion:

   

Implementing a `CreateCoincidenceConstraint` method in Revit involves using the Revit API to create a geometric constraint between two points. In Revit, constraints are typically managed through dimensions and parameters rather than direct geometric constraints. However, you can simulate a coincidence constraint by ensuring that the points are aligned and possibly locked in position using parameters.

Here's a conceptual approach to implementing a coincidence constraint between two points:

### Steps to Implement Coincidence Constraint

1. **Identify Points**: Ensure you have the coordinates of the points you want to constrain.

2. **Create Dimensions**: Use the Revit API to create dimensions between the points to enforce the coincidence constraint.

3. **Lock Dimensions**: Lock the dimensions to prevent the points from moving relative to each other.

### Example Code

Below is an example in C# that demonstrates how you might implement a coincidence constraint between two points using dimensions:

```csharp
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;

[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication uiApp = commandData.Application;
UIDocument uiDoc = uiApp.ActiveUIDocument;
Document doc = uiDoc.Document;

// Example points (these should be obtained based on your specific context)
XYZ point1 = new XYZ(0, 0, 0);
XYZ point2 = new XYZ(10, 10, 0);

using (Transaction t = new Transaction(doc, "Create Coincidence Constraint"))
{
t.Start();

// Create a coincidence constraint between the points
CreateCoincidenceConstraint(doc, point1, point2);

t.Commit();
}

return Result.Succeeded;
}

private void CreateCoincidenceConstraint(Document doc, XYZ point1, XYZ point2)
{
// Create a line between the two points
Line line = Line.CreateBound(point1, point2);

// Create a dimension between the points
ReferenceArray references = new ReferenceArray();
references.Append(CreateReference(doc, point1));
references.Append(CreateReference(doc, point2));

// Create the dimension
Dimension dimension = doc.Create.NewDimension(doc.ActiveView, line, references);

// Lock the dimension to enforce the constraint
dimension.Lock();
}

private Reference CreateReference(Document doc, XYZ point)
{
// Create a reference to the point
// This is a placeholder method and should be implemented based on your specific context
// For example, you might create a model point or use an existing element reference
return null;
}
}
```

### Explanation

- **CreateReference Method**: This is a placeholder method where you should implement the logic to create a reference to the point. This could involve creating a model point or using an existing element reference.

- **Dimension Creation**: The `CreateCoincidenceConstraint` method creates a dimension between the two points and locks it to enforce the coincidence constraint.

- **Transaction**: The code uses a transaction to ensure that all changes are committed together.

### Additional Considerations

- **Error Handling**: Implement error handling to manage scenarios where the points cannot be constrained.
- **User Interaction**: Consider providing user interaction to select the points dynamically.
- **API Documentation**: Refer to the Revit API documentation for specific methods and classes to create dimensions and constraints, as the exact implementation may vary based on the Revit version and specific requirements.

This example provides a framework to create a coincidence constraint programmatically. You will need to adapt it to your specific project context and requirements.

   

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

gopinadh7XTGG
Contributor
Contributor

Hi @jeremy_tammik ,

Thank you for your prompt response! I'll give this a try and keep you updated.

0 Likes