Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.


Compiling a standalone PRC exporter library

  • I was recently requested to help output models from the Open Source 3D toolkit OpenSceneGraph, to the PRC format for embedding in a PDF file. I think this is a very valuable application, and we quickly realized that engineering a PRC exporter from scratch was infeasible. During our studies we tested Asymptote's PRC exporter and found the API to be relatively easy to use and produced excellent PRC output, so we decided to try to re-use the Asymptote PRC code.

    This worked very well.

    We are planning on contributing our PRC saver code to the OpenSceneGraph project shortly, but in order to do so, we need to be able to tell others how to build the PRC saving code in Asymptote as a library they can link to (without needing the rest of Asymptote).

    OSG uses a derivative of the LGPL that explicitly permits static linking as well as dynamic linking. Because Asymptote is unadultered LGPL, if it were called by a closed-source program, the Asymptote-PRC code would need to be built as a dynamic link library to satisfy licenses. We were able to make this change fairly trivially to the Asymptote-PRC code with an EXPORT preprocessor macro (as is done in many projects). However, because we were unfamiliar with Asymptote's make system, for expediency we had built a new make environment based on CMake (as OSG itself is).

    So, I'd like now to contribute our changes back to Asymptote, but I wanted to discuss the changes and their implications with you guys first before shoving them in your face, as there may be a better way to accomplish some of what we did.

    There are two parts:

    • Add a PRC-library make target.
    • Add an EXPORT declaration (using a preprocessor definition) to allow this library to be built for static or dynamic linking on Windows targets.

    I'm reasonably sure that you guys, not being CMake-based, have no interest in CMake junk appearing in your project. So, I suspect it would be best to cooperate with you to replicate our CMake work into your existing autoconf/make build system.

    I have actually spoken to other users (like Norm Graf ) who have been using Asymptote's PRC code themselves in this fashion for some time, but have never tried to push a library target back into your build system. He expressed a desire to "legitimize" his usage of the PRC exporter code as we are trying to do.

    Are you guys receptive to this kind of change?

    I can always basically just publish what we have in an unrelated repository, but I think it would be best if our work joined with your work so that they stayed in sync in the future. I dislike un-necessary forks. :)

  • John Bowman
    John Bowman

    Yes, we should definitely coordinate our efforts.

    But first note that the LGPL allows for both dynamic and static linking. To quote from wikipedia:

    'Essentially, if it is a "work that uses the library", then it must be possible for the software to be linked with a newer version of the LGPL-covered program. The most commonly used method for doing so is to use "a suitable shared library mechanism for linking". Alternatively, a statically linked library is allowed if either source code or linkable object files are provided.'

    It shouldn't be hard to include a linkable object file of the PRC routines somewhere in your release. If there is some objection to this (although I can't imagine why; your users wouldn't even know that the object file is there) we would certainly be interested in working with you to supporting building a dynamic library. I assume your target platform is MSWindows?

    • Actually, we are perfectly happy to use Asymptote's PRC code as a DLL/.so.

      OSG is used frequently by closed-source packages, and there would be no way to use Asymptote-PRC as a static link library because it wouldn't be feasible for the user to re-link a static library.

      In this project, we target Linux and Windows, but OSG is Mac as well, so we want to target all of the above if possible.

      The source changes are relatively simple. Each export-able class or function gets a prefix stuck before it (OSG uses OSG_EXPORT) which works in conjunction with a header file like this:

      To replace it with declspec(dllexport) or declspec(dllimport) or nothing at all at compile time depending on whether you are BUILDING the DLL, USING the DLL, or building/using the static link library.

      The makefile is then configured to define OSG_LIBRARY_STATIC or OSG_LIBRARY during building to trigger these macros.

      We retrofitted these changes into our private fork of the Asymptote PRC codebase during our development, but of course, we were using CMake and we'd need to migrate these changes into your make system.

      Here is our repo:

      libPRC was originally intended to be a standalone PRC writer library that multiple projects (including our osg exporter, the original goal) could use. This was before we realized how difficult it is to write a proper PRC exporter, and how Asymptote's PRC support was already modular enough to utilize on its own.

      The OSG PRC exporter already works and is ready to announce, but we wanted to work out the back-contribution of the Asymptote library changes and the build process first.

  • Dear Chris,

    at this moment I am the most active developer of Asymptote PRC part.
    The code currently in Asymptote significantly lags behind PRC code development (in the ways that do not affect current Asymptote functionality).
    Do you have any patches or suggestions for PRC code (but the conversion to shared library)?

    Making current PRC code a shared library may be tricky, since STL containers are used in its API and that causes some problems in MSVC. I do not know Windows well enough to go into more detail.
    On the other hand I do not feel that ABI/API of the PRC code is going to get stable any time soon, so the only reason to make it a shared library are the licensing restrictions.

    I'd vote for making a separate project for PRC library, if such thing is possible, since installing Asymptote to get the PRC library can trigger TeX installation in a package management system.
    And John is unlikely to risk Asymptote stability by accepting PRC patches driven by the needs of other projects in his periods of Asymptote inactivity.

    BTW, I have evaluated the idea of writing PRC export support for OpenSceneGraph, but, as far as I remember, OpenSceneGraph lacks support for exporting NURBS, Bezier patches, Cylinders and other complex primitives.

    If it is possible now, then rewriting Asymptote to use OpenSceneGraph instead of immediate mode OpenGL, becomes worthwhile long-term idea.


  • Michael, I've tried twice to reply to your comments and the forum seems to be eating them. I'll try again in a bit.

  • Ok. Trying again.

    I'd be in support of a separate PRC library that Asymptote could use as a dependency and update to whenever it was stable. This is what we set out to do ourselves, before realizing it was a huge task, and had basically already been done -- by you! I just didn't want to be so presumptuous as to suggest doing that to your project.

    I'm not worried about the STL container aspect. I don't think many developers will link against binary distributions of the PRC code, instead they will want to build it themselves. And the DLL/.so aspect is, as you point out, just for licensing adherence. And actually, OSG itself uses lots of STL container stuff and we are able to distribute binaries of it ok.

    I'm not sure what you mean by this:

    BTW, I have evaluated the idea of writing PRC export support for OpenSceneGraph, but, as far as I remember, OpenSceneGraph lacks support for exporting NURBS, Bezier patches, Cylinders and other complex primitives.

    OSG does lack all of those things, but that doesn't reduce the usefullness of exporting OSG polygonal primitives to PRC.

    As far as Asymptote using OSG instead of raw OpenGL, I could certainly assist with that, but it would have to be a compelling benefit in order to justify Asymptote depending on such a large package as OSG. ;)

  • Just checking back in between being out of the office on trips.

    What can I do to help with this goal?

    Has anyone looked at our source changes in our GitHub repository?

  • I'd like to make some positive contribution here, and move forward on getting this to where someone outside of our developers can build and run the OSG->PRC exporter.

    Is there anything I can do to help with the standalone PRC library? I'd be happy to share our CMake-based build environment that is already in our repo. Then libPRC would just be a binary dependency of Asymptote.