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: 

Hermite to Bezier (or NURBS)

6 REPLIES 6
Reply
Message 1 of 7
GeomGym
2446 Views, 6 Replies

Hermite to Bezier (or NURBS)

Hi,

 

Thanks in advance to anyone with advice or resources on the following.

 

I'm trying to find a way to convert a hemite spline to a bezier spline.

Take a flexible pipe (or duct) as an example.

I've had limited luck with google, one reference suggested the start and end tangent divided by 3 would give the bezier control points.

It seems Autodesk must have conversion routines in the core as DWG export provides a nurbs curve.

If I measure the control points from the exported curve, it's 451mm from the end point (which I can't seem to relate to a foot unit vector, certainly not by a factor of 3).

 

140602 hermite spline to bezier.png

 

Cheers,

 

Jon

6 REPLIES 6
Message 2 of 7
jeremy_tammik
in reply to: GeomGym

Dear Jon,

 

Maybe my Google is better than yours  🙂

 

These look like pretty useful candidates:

 

 

Cheers,

 

Jeremy

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 3 of 7
GeomGym
in reply to: jeremy_tammik

Thanks Jeremy for the reply.

 

Your links are similar to ones I'd found.  I've spent some time testing this (setting up a grasshopper script) and confirm that a hermite spline is equivalent to a bezier spline if you divide the hermite tangent vectors by 3 (and add/subtract from the end points).  

 

But I'd like some clarification of the behaviour Revit provides.  If I create a flexible pipe (code below), then revit doesn't give me what I specify (by my calculations).  I set tangents with vectors 0,0,3 and 3,0,0 and it seems you get vectors that are 0,0,3.1623 and 3.1623,0,0.  Why does Revit change this value?  Note if I change the code to unit vectors, the pipe shape (and tangent lengths) don't change.

 

If you query the created pipe (as I'd like to export these objects) using revit lookup, Revit reports normalized tangent vectors (which would be generate a very different spline) on the location curve.  How can I accurately extract the hermite tangent vector magnitudes?  Should I just assume this constant value that I observed above?

 

 I've attached a spreadsheet calculating the coordinate at a parameter of 0.5 to demonstrate the tangent length discrepency (which matches revit interpolated point at mid parameter).

 

Cheers,

 

Jon

 

140615 flexible pipe spline.png

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;

namespace GGYM
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class ImportIFCGeomGym : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

Document document = commandData.Application.ActiveUIDocument.Document;
Transaction trn = new Transaction(document, "ggTest");
trn.Start();
FilteredElementCollector collector = new FilteredElementCollector(document).OfClass(typeof(FlexPipeType));
ElementId pipeTypeId = collector.FirstElementId();

// find a pipe system type
FilteredElementCollector sysCollector = new FilteredElementCollector(document);
sysCollector.OfClass(typeof(PipingSystemType));
ElementId pipeSysTypeId = sysCollector.FirstElementId();

Level l = null;
FilteredElementCollector fec = new FilteredElementCollector(document).OfClass(typeof(Level));
foreach(Level lvl in fec)
{
l = lvl;
break;
}

FlexPipe pipe = null;
if (pipeTypeId != ElementId.InvalidElementId && pipeSysTypeId != ElementId.InvalidElementId)
{
List<XYZ> points = new List<XYZ>();
points.Add(new XYZ(0, 0, 0));
points.Add(new XYZ(3, 0, 1));

pipe = FlexPipe.Create(document, pipeSysTypeId, pipeTypeId, l.Id,new XYZ(0,0,3),new XYZ(3,0,0), points);
}
trn.Commit();
return Result.Succeeded;
}
}

}

Message 4 of 7
gopinath.taget
in reply to: GeomGym

Hello,

 

Got a couple of questions:

 

1) When you use tangents with other magnitudes (say 4 instead of 3) do you see Revit doing floating point changes?

 

2) What about when you use unit vectors, is it still approximate?

 

3) I am not familiar with Hermite splines so have to ask, why is the magnitude of the tangent important?

 

Cheers

Gopinath

Message 5 of 7
GeomGym
in reply to: gopinath.taget

Hi Gopinath,

 

I added 4 lines to the code (pasted below) to set a similar pipe with a tangent of 1 (instead of 3).  

 

1.  No noticeable floating point change to the inplane coordinate.  Image below.

 

2.  Aproximate to what?  I posted the spreadsheet showing the variation in shape.  A change in tangent magnitude should significantly affect the shape of the spline.

 

3.  I'm not so familiar with hermite splines either (hence the google references above).  It's a curious choice given every other software seems to have opted for nurbs.  I'd like to accurately and reliably create and extract geometry with Revit.

 

I look forward to hearing further expanation about the way Revit provides API access to this geometry.

 

Cheers,

 

Jon

 

140619 tangent comparsion.png

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;

namespace GGYM
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class ImportIFCGeomGym : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

Document document = commandData.Application.ActiveUIDocument.Document;
Transaction trn = new Transaction(document, "ggTest");
trn.Start();
FilteredElementCollector collector = new FilteredElementCollector(document).OfClass(typeof(FlexPipeType));
ElementId pipeTypeId = collector.FirstElementId();

// find a pipe system type
FilteredElementCollector sysCollector = new FilteredElementCollector(document);
sysCollector.OfClass(typeof(PipingSystemType));
ElementId pipeSysTypeId = sysCollector.FirstElementId();

Level l = null;
FilteredElementCollector fec = new FilteredElementCollector(document).OfClass(typeof(Level));
foreach(Level lvl in fec)
{
l = lvl;
break;
}

FlexPipe pipe = null;
if (pipeTypeId != ElementId.InvalidElementId && pipeSysTypeId != ElementId.InvalidElementId)
{
List<XYZ> points = new List<XYZ>();
points.Add(new XYZ(0, 0, 0));
points.Add(new XYZ(3, 0, 1));

pipe = FlexPipe.Create(document, pipeSysTypeId, pipeTypeId, l.Id,new XYZ(0,0,1),new XYZ(1,0,0), points);
points.Clear();
points.Add(new XYZ(0, 1, 0));
points.Add(new XYZ(3, 1, 1));
pipe = FlexPipe.Create(document, pipeSysTypeId, pipeTypeId, l.Id,new XYZ(0,0,3),new XYZ(3,0,0), points);

}
trn.Commit();
return Result.Succeeded;
}
}

}

 

Message 6 of 7
rakotoarisoa_m
in reply to: GeomGym

If you still searching a way to do this, check the RevitAPI 2017 they introduced a new method in NurbSpline converting Hermite spline to NurbSpline or Curve. 

http://www.revitapidocs.com/2017/cfb90f78-dc27-a305-031d-5e4ffac8a9ce.htm

Message 7 of 7

Wow, cool! Thank you for pointing out! Also

 

CreateCurve Method (HermiteSpline);

 

Creates a new geometric Curve object by converting the given HermiteSpline. The created curve may be a NURBSpline or a simpler curve such as line or arc.
 
 
Cheers,
 
Jeremy

 

 



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

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