Internal origin not located properly

Internal origin not located properly

lrs579
Contributor Contributor
259 Views
1 Reply
Message 1 of 2

Internal origin not located properly

lrs579
Contributor
Contributor

Hi, 
i'm trying to retrieve Z Point of my curve, however it is returning around -1500 when it supposed to be at 0. 

I assume there's something wrong in the internal origin of my project. How do I solve this so that my internal origin is located at the same point of my project base point?

 

Would appreciate any insights or tips!

0 Likes
260 Views
1 Reply
Reply (1)
Message 2 of 2

jeremy_tammik
Alumni
Alumni

For the sake of my own comfort, your convenience and the completeness of the answer, I asked Gemini to answer this, as described in my recent blog post. Here is its reply:

   

Let's dive into this internal origin issue and how to reliably retrieve curve Z-coordinates relative to the project base point, regardless of the internal origin's position. You're right to suspect the internal origin, but the solution isn't about moving it (generally not recommended). Instead, we'll work with coordinate systems.

Understanding the Challenge

Revit uses different coordinate systems:

  • Project Coordinate System: This is the coordinate system you typically work in, and its origin is the Project Base Point (PBP). This is what you care about for your Z-coordinate.
  • Internal Coordinate System: This is Revit's internal coordinate system. Its origin is the internal origin. This is what's causing your confusion.

The issue arises because the Curve.GetEndPoint(0).Z (or similar) returns coordinates in the Internal Coordinate System. We need to transform these coordinates to the Project Coordinate System.

The Solution: Coordinate Transformation

Here's the breakdown of the solution using the Revit API and C#:

C#
 
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

// ... inside your command class ...

public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
    Document doc = commandData.Application.ActiveUIDocument.Document;

    // 1. Get the Project Location (which defines the PBP's position)
    ProjectLocation projectLocation = doc.ActiveProjectLocation;
    Transform pbpToInternalTransform = projectLocation.GetTotalTransform();  // Transform from PBP to Internal Origin

    // 2. Get your curve (replace with your actual curve retrieval method)
    Curve curve = GetYourCurve(doc); // Example:  new FilteredElementCollector(doc).OfClass(typeof(Curve)).FirstElement() as Curve;  

    // 3. Get the curve's endpoint in Internal Coordinates
    XYZ curveEndPointInternal = curve.GetEndPoint(0);

    // 4. Create a Point in Internal Coordinates
    XYZ ptInternal = new XYZ(curveEndPointInternal.X, curveEndPointInternal.Y, curveEndPointInternal.Z);
    // or, if you have a reference to a curve end point.
    // XYZ ptInternal = curve.GetEndPointReference(0).ConvertToXYZ();

    // 5. Transform the point from Internal to Project Coordinates
    XYZ curveEndPointProject = pbpToInternalTransform.Inverse.OfPoint(ptInternal); // Use Inverse to go from Internal -> PBP

    // 6. Extract the Z-coordinate in Project Coordinates
    double zProject = curveEndPointProject.Z;

    TaskDialog.TaskDialog.Show("Curve Z", $"Z (Project): {zProject}"); // Display the result

    return Result.Succeeded;
}

// Helper function (replace with your actual curve retrieval logic)
private Curve GetYourCurve(Document doc)
{
    // ... your code to retrieve the curve ...
    // Example (replace with your selection or filtering method):
    return new FilteredElementCollector(doc).OfClass(typeof(Curve)).FirstElement() as Curve;
}

Explanation and Key Improvements:

  1. ProjectLocation and GetTotalTransform(): This is the crucial part. We get the ProjectLocation and use GetTotalTransform() to obtain the transformation that maps points from the Project Base Point (PBP) to the Internal Origin. This transform encapsulates the relationship between the two coordinate systems.

  2. Inverse Transform: We use pbpToInternalTransform.Inverse because we want to go from Internal coordinates back to Project coordinates.

  3. OfPoint(): The Transform.OfPoint() method applies the transformation to the point.

  4. Helper Function: The GetYourCurve() function is a placeholder. Replace it with your actual code to retrieve the curve you're working with (e.g., using FilteredElementCollector, picking a curve, etc.).

  5. Error Handling: In a production add-in, you would add error handling (e.g., checking if curve is null, handling exceptions).

Practical Demonstration and Further Tips:

  1. Debugging: Use the Revit API Debugger to inspect the pbpToInternalTransform and the resulting points to understand the transformation.

  2. Units: Be mindful of units. The Z-coordinate will be in the project's internal units (typically feet). You might need to convert to other units using UnitUtils.ConvertFromInternalUnits().

  3. Curve Parameterization: If you need the Z at a specific parameter along the curve (not just the endpoint), you can use Curve.EvaluatePoint() to get the point at that parameter, and then apply the same coordinate transformation. For example:

    C#
     
    double parameter = 0.5; // Example: midpoint of the curve
    XYZ pointOnCurveInternal = curve.EvaluatePoint(parameter, false); // Get point in internal coords
    XYZ pointOnCurveProject = pbpToInternalTransform.Inverse.OfPoint(pointOnCurveInternal);
    double zAtParameter = pointOnCurveProject.Z;
    

By using this coordinate transformation approach, you can reliably obtain Z-coordinates relative to the Project Base Point, regardless of the internal origin's position. This is the standard and most robust way to handle coordinate system differences in the Revit API. It's much cleaner and more reliable than trying to manipulate the internal origin itself.

   

This answer looks reasonable to me. Please check it suits your needs and please let us know how you end up solving this. Thank you!

   

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