Model Curve by best fit through points

Hello Dynamo Friends :slight_smile:

I Have 15.000 Points

And I want to make a line through them so I used nurbscurve by points.

But now I cant create a model curve from the nurbscurve because it is not planar. And I can´t explode it.

Whatelse can i do to get my model curve? polycurve by points is not giving a good result because it gives only straight lines and no arcs.

Appreciate any advice!

Results may vary based on your nurbs curve, but PolyCurve.ByJoinedCurves will accept nurbs curves. That should at least get you to a PolyCurve which you can begin breaking down as necessary (if necessary).

1 Like

Hello @Nick_Boyts

I´m afraid that doesn´t work, just getting nurbscurves again:

So if there is no obvious method to do this, I´ll try to set up a python code that creates nurbs curves but with planar pieces or something like that.

Well that’s annoying. Yeah, python might be the best option here if you want simplified geometry.

EDIT: Actually it looks like Curve.ApproximateWithArcAndLineSegments works on nurbs curves. Again, it may vary depending on how complex your nurbs curve is, but it works for me with a simple case. You’re still probably going to end up with a bunch of smaller segments, but that seems like a given with complex geometry.

2 Likes

Simple answer: don’t do it this way.

Detailed answer: move into the adaptive or massing environment, convert the points to reference points, and draw a model curve by points. Depending on your Revit version there should be out of the box nodes for each of these steps, but it can be done via Python rather easily as well.

2 Likes

ok, so such a model line can only exist in a family environment? :confused: My goal was to create a model line in the project environment…thats disappointing. Will have to change many scripts now ^^

Thanks @jacob.small !

As always, follow this rule:

If you can’t do it in the Revit UI, you shouldn’t do it in the Revit API even if it lets you.

While there are few exceptions to this they are few and far between (so much so that they escape me at the moment - maybe deleting a particular workset?). So when doing automations, I always ask myself two questions. The first is “If I had to draw that curve manually in the Revit, how would I go about it?”

Once I figure that out (often literally writing down the steps), it’s onto question two: “How do I tell the computer to take all of the same steps I just did manually?”

Then I finally launch Dynamo.

2 Likes

That makes perfect sense!

I managed to create a DB.Nurbspline but I can not find it in the adaptive family I´m working in.
Am I using the right method?

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Get the current document
doc = DocumentManager.Instance.CurrentDBDocument

# The input to this node will be a list of reference points
input_points = IN[0]

revit_points = [XYZ(point.X, point.Y, point.Z) for point in input_points]

# Assuming uniform weights for simplicity. Adjust as necessary.
weights = [1.0 for _ in revit_points]

# Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

try:
    # Create a NURBSpline through the reference points
    spline = NurbSpline.CreateCurve(revit_points, weights)

    # Commit the transaction
    TransactionManager.Instance.TransactionTaskDone()
    doc.Regenerate()

    OUT = spline

except Exception as e:
    # Handle exceptions
    TransactionManager.Instance.ForceCloseTransaction()
    OUT = str(e)

Can you post a DYN with the points, and let me know which Revit year?

Got it :smiley:
But as such lines can´t be used for sweeping it´s not what I was looking for, but good to know anyway!

import clr
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Get the current document
doc = DocumentManager.Instance.CurrentDBDocument

refPoints = UnwrapElement(IN[0])

# Start a transaction
TransactionManager.Instance.EnsureInTransaction(doc)

try:
    # Create ReferencePointArray and add points to it
    refPointArray = ReferencePointArray()
    for refPoint in refPoints:
        refPointArray.Append(refPoint)

    # Create the curve
    curve = doc.FamilyCreate.NewCurveByPoints(refPointArray)

    # Commit the transaction
    TransactionManager.Instance.TransactionTaskDone()

    OUT = curve

except Exception as e:
    # Handle exceptions
    TransactionManager.Instance.ForceCloseTransaction()
    OUT = str(e)

This is the corresponding dynamo node:

1 Like

99% sure you can sweep along this.

Look at hosting an adaptive profile family on the curve, and try sweeping that.

I believe the Dynamo node to host it is something like ‘AdaptiveFamilyByCurveParameter‘ or something along those lines. It’s the other ‘AdaptiveComponent’ constructor in the default library.

After that try to sweep the profile along the line in the UI, and then you can look into building up some Python to perform the loft action.

1 Like

That works!
In the UI I can make a freeform:

1 Like

And so your next task, should you choose to accept it, is to try and implement that node in Python, and then call this method: NewSweptBlendForm Method

1 Like

I fail at hosting the profile to the curvebypoints. As all parameter nodes dont work with this curve I tried it with python but still get an error.
Also tried using 0 or 1 or [0,1] as paramters, do not really know what to use here and always get the same error. DYN attached! Oh and I use Revit 23 and 24.

Adaptive.dyn (4.8 MB)
Profil_d20_adaptive.rfa (432 KB)

1 Like