Synopsis
Blender has had basic NURBS features for years with no upgrade and very little usability. As Blender attracts hard surface modelers and designers, the demand for improving precision surfacing has always existed.
As the following task presents #100127, upgrading the surface system means upgrading the core data structure since it is limited by past choices. Currently, NURBS surfaces share its data structure with curves, and not only have they both diverged, but the curves in question are getting replaced by a new system.
The making of a new data-block is also, as #100127 mentions, an opportunity to make surfaces compatible with GeometryNodes. Having procedural NURBS modelling would be a potential game changer for the modeling capabilities of Blender.
Since I have been coding a Blender add-on bringing NURBS modeling to Blender and I am currently learning C++, I believe that I am in the best position for undertaking such task.
Benefits
Since the project should not make any user-side changes, the benefits are indirect and long term.
For Designers and modelers
Currently, no open-source solution exists for creative-oriented surfacing. However, this doesn’t prevent designers and modelers from using Blender wherever high precision isn’t required (early concepts, video-game models…). Native NURBS surfaces would also eventually mean better exchanges with the CAD world. This would be appreciated for product rendering.
For Architects
Again, no open-source alternative for procedural NURBS modeling (as Rhino Grasshopper). GeometryNodes seems to be the perfect platform to change that.
For Scientists
NURBS can serve for point-cloud fitting, mesh interpolation, or simply representing continuous surfaces. This would certainly be appreciated by the scientific community, who already use blender for data visualization.
For Beginners
In the long term, investment in NURBS will spare new users the confusion and disappointment of knowing that NURBS exists in Blender, but are not usable.
For Future Proofing
It is another step for legacy curves deprecation.
Deliverables
-
A new surface data-block
-
The removal of legacy-curves surface features
-
One or more experimental build
-
Feature parity with existing system
Project Details
The first project goal is to separate surfaces from legacy curves. It can be done by careful duplications and cleanups. Doing it first has the advantage of better understanding of the existing system and everywhere it connects.
Next the goal is to create the upgraded surface data-block. From the requirements I collected, I made the following concept.
I. Architecture
I assembled the following class diagram :
Since implementing everything exceeds GSoC time scope, the goal is to implement only the branch going from the NURBS level to the object level. No trim contour, no dependency tree, no surface edges or 3D curves.
This class diagram has to be discussed carefully but here are some reasons for such structure :
-
Object level : Each surface object contains one surface data-block to stay consistent with current blender objects.
-
GeometrySet level : The surface data-block is part of a GeometrySet to be accessible through GeometryNodes.
-
Surface Data-Block level : The data-block contains mainly a list of surfaces. All the other data is added for boundary representation (explained later).
-
Individual Surface : Surfaces needs at least an ID, a boolean for normal orientation, a material and the ability to store generic attributes. They could also have a transform matrix to facilitate transform.
-
Sub-types : Each surface has a sub-type with attributes defining its geometric representation. NURBS is the priority sub-type, as they can represent any type of surface. In practice, however, surfaces such as plane surfaces or cylinders are unpractical and inefficient to edit as NURBS. It seems unlikely that we could create a good modeler without sub-types. So even if we keep only the NURBS sub-type for a time, planning for sub-types makes sense.
-
Dependency tree : This is the main component to achieve boundary representation. It stores relations between surfaces, curves and points in a tree. The tree is built chronologically along the modeling process to keep track of dependencies. This is essential to connect entities with non destructive link without dependency loops.
-
Trim contour : All surface sub-types are define geometry parameterized in U and V and should be trimmed by one or more boundary loop. Each boundary loop is made of 2D curve segments. Each surface have one outer loop and several inner loops which cannot intersect or be nested (to prevent defining several surfaces with one. Without contour, the surface is trimmed by its “natural boundary” (the control grid zone for NURBS). Trimmed surfaces need a meshing method which can be challenging to make reliable and clean.
-
Edges, 3D curves and points : Boundary representation is based on shared topological features (faces shares edges, edges shares points). It may seem strange to add those in a “surface” object when Blender already has overlapping concepts for curves and points, but they are required for any non-destructive editing.
-
It shares similarity with OpenCascade structure an established existing geometric kernel for CAD (Surface here is what OpenCascade calls face and sub-types here is what it calls surface, the best naming for Blender should be discussed).
II. Data Structure
Derived from the architecture, here is how data may be structured :
Whenever the data has the same length for every surface, it can be represented as a generic attribute (in one chunk). If the length defers, here the geometric data and the trim contour data, it is stored separately. The parent data simply stores the address for it.
This structured is registered as part of Blender DNA and BKE, similar to other data type.
III. Using and evaluating the new surface data
Once the new block is declared, it needs to wire correctly with all systems already using NURBS surfaces. Among them : edit mode, operators, modifiers, exporters, rendering, undo… Older files should also be converted seamlessly or at least without crashing. Exact backward-compatibility and feature parity may not be strictly necessary since users of the old system are very rare. However without explicit decision, it is assumed as needed.
Some systems will probably only require some simple checks while others will require some rewrite. One of the main unknown is on surface evaluation (going from geometric data to discrete surface point or mesh). Considering its age, the current NURBS evaluation may use some old standards or hacks which would make sens to cleanup at this stage.
If any time is left, I would look at how to make the new surfaces compatible with GeometryNodes as well as detail the design for trim contours.
Project Schedule
This is a large-sized project (350 hours) with 35h per week for 10 weeks (3 weeks unavailable on a 13 weeks span).
-
Week 1
- Investigate on current NURBS code
- Separate current surfaces from curve legacy
- Discuss the proposed plan
-
Week 2
- Not available
-
Week 3-5
- Make sure to have all the main requirements
- Prototype the new surface data-block
-
Week 6-8
- Implement, adapt and check dependent systems
- Fine-tune the data-block
-
Week 9
- Publish a build
- Fixes
-
Week 10-11
- Not available
-
Week 12
- Cleanup, fixes
- Ensure feature parity
- Ask for review, pull request
If remaining time : - Dig on GeometryNodes integration
- Detail the plan for trim contours representation
-
Week 13
- Free for probable delay and unknowns
Bio
I am a French 25 year old recently graduated engineer in mechanics-mechatronics. I am passionate about industrial design, drawing, image creation and animation. Currently working as a part time freelance designer and part time add-on developer.
I started learning Blender in 2014 for some naively ambitious animation projects with my friends, and I didn’t left it since. The Blender keyboard shortcut workflow began to feel so fluid and powerful, that when I later encountered CAD software in my internships, it felt like an other era. I really feared having to work daily with those. As I was working on the early development of some product, I could introduce Blender as a way to iterate on the product architecture in real time, while some engineers on my shoulders made suggestions. This was highly appreciated. The main limitation being of course possibilities of exchange with the mechanical world.
As a response, I started one and a half year ago to develop an open-source add-on called SurfacePsycho. It already has been successful in offering some actual NURBS modeling, with surface trimming and CAD file I/O. All of this in record time, considering my absence of prior knowledge of any of NURBS math! This was really made possible thanks to GeometryNodes instant feedback (and my determination '°u°).
With this project, I learned about the technical challenges associated with NURBS and I caught the attention of many professional designers. However, it slowly reaches its limitations : performances, mathematical stability, lack of external libraries… GeometryNodes was not design to make full software after all. So as the next logical step, I am gradually switching to C++. GSoC seems to be the perfect opportunity to make the most of this knowledge and benefit the community.