Hello,
I need a (Modern) Fortran library for representing numerically lines and surfaces in space (possibly NURBS). What are your suggestions? I’ve already looked at the section Packages of fortran-lang.org but I’ve found nothing of interest related to my purposes. I need specifically to represent also closed surfaces.
Thank you
From a quick search I was able to find:
-
splf2003 (part of SPL; unfortunately, the library seems stale, but maybe you can contact the authors)
-
DT_NURBS: A Fortran 77 library mentioned in this thread at the Intel Fortran Forum and also in the Handbook of Grid Generation. A copy might be located in this “dump” of CFD Utilities from NASA. Some dead forum pages (from 1996) say the library is quite powerful, quoting:
In some respects, it’s more powerful and definitely more flexible than NLib which costs $4000-$8000! (and the code is about as readable, which should tell you something about NLib…)
Unfortunately the documentation, if you can find it at least, contains many errors. It seems the library was originally developed at the David Taylor Naval Ship Research and Development Center, a test facility for ship design in Carderock, Maryland.
The better solution is likely to interface to a C or C++ library. I’ve found the following ones (no particular order):
- NLib™ (commercial)
- libnurbs (the actual library seems to be here)
- tinynurbs
- tinyspline (documentation located here)
- openNURBS (requires some proprietary tools to be used effectively)
- SISL (the organization SINTEF has a number of other geometry toolkits)
- SplineLib (a preprint version of the article in the preceding link can be found here; unfortunately, I couldn’t locate the library implementation)
For representing B-splines I’ve found:
- gsl_bspline (part of the GNU Scientific Library in C; a Fortran interface is available)
- Einspline (a C library; last changes are from 2009)
In case you are feeling adventurous you could try porting the NURBS Toolbox by Mark Spink to Fortran. I’ve found a port of the toolbox to Python/Numpy by a naval architect Runar Tenfjord. His page says the code in MATLAB was much easier to understand than all the C++ NURBS libraries. An expanded version of the NURBS Toolbox is also available as an Octave package called nurbs.
Thank you very much. I’v also done some research with similar results. I’ve got CFD UTILITIES with DT_NURBS shipped, but only in form of a compiled library with no documentation. We can consider such library as dead (read similar comments on Fotran communities, posted years ago).splf is not actually completed and is not usable for a medium project (>1 year).
So here it ends the overview on Fortran NURBS libraries.
On interfacing: I find it very hard, but can give it a try. What about this ?
However, reimplementing a new NURBS library from scratch written in Fortran seems such a difficult and long project.
I also took a look at @jacobwilliams B-Spline module, but is there a method to manage closed curves or must be done manually?
Indeed, managing opaque pointers while wrapping C++ to Fortran is quite painful. Typically, you will only need a small subset of functions from a library, so it can be done in a few days once you get the hang of it. There are some resources in this thread.
The library looks nice and feature complete. Probably you would have to interface with the auto-generated C++ interface, and do a lot of cross-checking directly with the source to make sure you get the interface right.
At least from the documentation it seems like you would have to do it manually. According to this page by repeating some knots and control points you can get a closed curve. On the other hand bspline-fortran
might lack some of the tools you need like evaluating derivatives, tangent and normal vectors, finding intersections points, etc.
I enjoy reading in this forum and this is my first post here. Hopefully I can add some information.
- DT_NURBS The version linked by ivanpribec is not the latest release and has not the license restrictions from the latest one. The latest one provide more ‘high level’ functions to make it easier to work with. But from the perspective of today it is even for a Fortranner complicated to use. The code is F77 style with all the implicit interfaces and uses a work array to simulate pointers. However, I’ve worked many years with it and it does a good job. Unfortunately, one cannot get an official version and copies must not distributed by license restrictions. Has someone a connection to the authors or rights owners? Maybe it can be made open?
- SISL I made some tests in the past and this one maybe the best lib to wrap with Fortran, because it is written in C not C++.
- OpenCascade is a huge and matured lib but interfacing to Fortran might be tricky. There was somebody who wrote interfaces using Cray like pointers, but I do not find a link to it anymore. It was an optimization tool for wings or so. Sorry, this isn’t helping much.
I began to write a NURBS lib in modern Fortran as a side project based on ‘The NURBS BOOK’ by Piegl and Tiller (NLib), but I did not find the time to continue to a releasable status. I will look into splf2003. Maybe it’s the better starting point.
Especially if one is interested in intersections, bool operations and so on most existing libs will fail (SISL and OpenCascade provide such functions).
Is there an interest in creating a modern, pure Fortran NURBS lib out there?
Three other options (mostly old Fortran 77 though)
- Carl De Boors PPPACK - Burkhardt has an F90 version. The original is on netlib
- Paul Dierckx FITPACK - Also on netlib under DIERCKX - Note there is another FITPACK thats part of Alan Clines software but its not the same code.
- If you can find it, Tom Lyche had a package of Fortran code that was the predecessor to SISL. I have a copy but am unsure if its legal for me to distribute it.
Also, I too started to write a NURBS lib in Modern Fortran based on “The NURBS Book” along with the code and algorithms in Peigl and Tillers journal articles. That was about 12 or so years ago. I implemented most of the code through Chapter 5 but life got in the way and I had to put it down. The project I was writeing the code to support never got off the ground. I wrote a lot of code but never got a chance to really test it so its not something I would release into the wild. Maybe one day I’ll try to resurrect it.
RW
Writing a NURBS library from scratch requires a tremendous amount of efforts. time and pain However thanks in advance to whom has the will to distribute his/her own source code. The problem is that today a NURBS library must be OO and capable at least of computing surfaces intersection. I can have some spare time for a NURBS Fortran library, but in my opinion many years are required to advance such a project to an usable state. Maybe the best option is an interface to a well-developed, non-obscure and reliable C++ library. I wonder if SISL will be maintained in the next years.
Truely spoken. I agree that it will take a lot of time and effort. I think OO is no issue. I would add multithreading (most commercial NURBS kernel cannot do this ) and maybe GPU acceleration as a requirement. The latter one maybe not a strength of Fortran. However, most (GP)GPUs do not do a good job in double precision, which is IMHO needed for NURBS operations.
And also I agree totally, that interactions of NURBS objects like surface intersection should be present and have to work robustly (many commercial kernels suffer here).
The onyl well and actively maintained open NURBS lib, which includes things like surface intersection, is as far as I know OpenCascade. In my opinion this is a heavy weight lib with a very long learning phase. I’m also not sure, whether SISL and related libs are maintained in future.
Which lib would be your favorite for writing interfaces?
I think SISL will be around for a while. It’s a part of the SINTEF GoTools library which includes intersections as well as solid modeling etc. There has been a lot of interest in NURBS etc. in the Finite Element world since Tom Hughes and his students and co-workers introduced the Isogeometric Analysis(IGA) approach to Finite Element modeling in 2005. Since then there has also been a lot of work looking at alternatives to NURBS such as T-splines, LR-splines, subdivision surfaces etc. because of the problems related to generating watertight models with NURBS as well as the limitations of its tensor product formulation. Most of the computer animation models you see in movies are based on subdivision surfaces and not NURBS. Part of the GoTools library was written to support IGA. It’s all C++ but wrapping the C++ in a C routine and then using Fortran C-Interop to provide interfaces is not hard just potentially a lot of work (and probably not the most efficient way to get the functionality you want). So I would probably start with GoTools and SISL before openCASCADE etc. I would also suggest you read the following paper by Piegl, Tiller, and Ragab which gives an interesting view of NURBS along with their other papers on Knowledge-guided approachs to CAD etc.
Piegl, Tiller, and Ragab, “It is Time to drop the “R” from NURBS”, Engineering with Computers, V30, P 703-714, 2014.
I mention this because using the non-rational form (ie B-splines) makes life a lot easier if you need to compute derivatives etc.
I searched for the paper you suggested but it has restricted access.
Sadly, I’m no expert on subdivision surfaces but it seems that for representing surfaces exactly NURBS are more appropriate. T-splines and LR-splines suffer from a more recent introduction than NURBS. My expertise is not on Computational Geometry (although I really like it) so probably it’s better to just stick with NURBS and solve derived problems with glue.
You’ve made valid points, but after all, SISL seems well documented and it’s simpler to find help for a C interface than for a C++ interface.
So, I’m trying to interface SISL.
One of the things the paper I referenced points out is do you really need an “exact” representation of surfaces (and curves) or is defining something to some user specified level of engineering accuracy (or to use a saying common in the U.S. aerospace industry “close enough for government work”) more appropriate. The main reason NURBS and rational Bezier surfaces gained favor is they can “exactly” represent conic sections. For other types of geometries, I don’t think they buy you anything and lead to a lot of problems (trimming surfaces, lack of true watertight representation of geometry, control point explosion when you try to merge curves, etc.). T-Splines are now supported in some CAD packages (I think AutoCAD does and AutoDesks solid modeling package) . However, I agree that NURBS technology is the most mature and for generating something you can call from Fortran probably is the most logical place to start. My point is you need to look at your application and decide if you really need NURBS or would just sticking to non-rational B-splines and Bezier surfaces be better choice since Fortran packages that provide at least basic support for them already exist. Your time might then be better spent trying to implement whatever capabilities not found in the Fortran packages than trying to write C-interop interfaces which on the surface look straightforward but (and I know from personal experience of having written C-interop code for about 15 years now) have a lot of hidden traps and pitfalls that will have you chaseing segmentation faults if you are not very, very careful.
Your question re. SISL etc got me interested in what it would take to do Fortran interfaces for SISL so I spent a little of my free time this weekend and took a quick look at the code. Here are some of the things I found.
-
SISL has over six hundred *.c files containing at least one (some more) function or procedure. However, the users manual (which is unfortunately very out of date) only discusses a smaller subset of what are probably higher level interfaces so the logical place to start would be to just implement the routines described in the manual.
-
SISL is written in an “object-based” approach built around three principle structures (or objects), a curve, a surface and a intersection curve structure. Each of these structures contain a mix of scalar as well as array and sometimes curve and intcurve structs . The problem is that the arrays and imbedded structure components are defined as C pointers with multiple indirections (ie pointers to pointers to pointers (*** thisStruct) etc. Trying to unwind those levels of indirection into something you can use in Fortran is a challenge. It’s doable but it takes a lot of thought and great care and a lot more code than you might think.
-
SISL uses (and expects) two kinds of entities requiring dynamic allocation (memory). The first is memory that the user allocates outside the SISL functions. The second is memory allocated inside SISL. The latter is the big issue because you really have to be careful to free any Type(C_PTR) entity returned to Fortran using the C free function (you need to write your own Fortran interface for that also) and make sure you NULLIFY any Fortran pointers associated to them with C_F_POINTER.
Finally, if you haven’t done a lot of C-interop programming there are several thing that you need to be aware of that are not discussed in any great detail in any of the Fortran references I know of. I’ve found I spend a lot of time writting little mini-apps just to find the best procedure for doing a particular task (like unwinding multiple indirection pointers). An example of this is when you need to pass C_PTR objects by VALUE and when not to. I’m not sure if the new Fortran 2018 iso_fortran.h functions would help with this but that would mean you would have to write another level of C code just to interface with Fortran which (to me) defeats the purpose of the C-interop facility.
Concerning C / Fortran interoperability, you can have a look to our project:
It’s all about such problems. How to propose interfaces to 10000 C functions… In our case, it’s based on a Python script which is parsing all the .h header files of the GTK/GLib libraries and use heavily regular expressions to extract and transform the C functions prototypes into Fortran interfaces.
I have not yet look at novelties in Fortran 2018 concerning those aspects.
Maybe you could be also interested in:
We don’t use it, having developed our own script, but I kept it in my bookmarks.
Thanks for the interesting overview of what type of headache Fortran-C interop can bring.
You’re surely more experienced than me on Fortran-C interop. and after trying to write a small interface to SISL I must say that you’re right about hidden difficulties and problems.
I’ll try to glue some Fortran code of what is left on Internet.
@vmagnin
I’ll certainly take a look at that project. Thanks
My purpose was to interface only to the more interesting functions…
Thanks for your suggestions.
That was exactly what we were trying to do in our project in 2011! But as it happens, I was learning Python and regular expressions at that time. And the puzzle was in place… And it became far bigger than expected…
I don’t want to go off-topic, but : is your own code also capable of generating Fortran code from Python or from a pseudo- language describing predefined operations ? A sort of source-to-source translator.
No, no, it is just creating Fortran interfaces to C functions. And it was designed to deal specifically with the GTK and GLib libraries: if you try to adapt the cfwrapper.py script to other C libraries, it could be more or less painful. The regular expressions used to extract information were designed to deal with the GTK / GLib coding conventions. So if the coding conventions are too different, it could be a headache…
For 10 years, I was obliged time to time to adapt the script because there were some new things in their code that the script won’t manage correctly.
Note also, that in the gtk-fortran project you can have a look in the src/ directory to the *-auto.f90 files: they are automatically generated by the Python script and for each C function, you have:
- the C prototype in comments,
- the Fortran interface.
For example:
! GDK_AVAILABLE_IN_ALL
!void gtk_drag_source_set_icon (GtkDragSource *source, GdkPaintable *paintable, int hot_x, int hot_y);
subroutine gtk_drag_source_set_icon(source, paintable, hot_x, hot_y) bind(c)
use iso_c_binding, only: c_ptr, c_int
type(c_ptr), value :: source
type(c_ptr), value :: paintable
integer(c_int), value :: hot_x
integer(c_int), value :: hot_y
end subroutine
Therefore you will find examples of interfaces with all kinds of types.
There are few more tools to generate Fortran wrappers of C/C++ automatically:
- swig-fortran
- shroud (a presentation from FortranCon2020 is available here: FortranCon2020 [SP]: Shroud: generate Fortran wrappers for C and C++ libraries - YouTube)
It really depends what you are after. The tools in the ISO_Fortran_binding.h
allow you to write code in C with the added benefit that the Fortran interface can contain allocatable or pointer components. Unfortunately, apart from the book Modern Fortran explained, there are almost no examples so far and writing the interface code requires good knowledge of C.
Hopefully, down the road, (cross-language) compilers will appear that generate the interfaces automatically.