Add support for NURBS surfaces in Wavefront .OBJ files. #117371

Open
Germain-Le-Chapelain wants to merge 5 commits from Germain-Le-Chapelain/blender:fixattemptcurveobjexport into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
First-time contributor

Signed-off-by: Germain Le Chapelain germain.lechapelain@lanvaux.fr

This is to address the sample data kindly provided in https://devtalk.blender.org/t/nurbs-import-export/17581/14?u=germain_le_chapelain

(Calling for feedback if possible, I don't really know what I am doing yet :/ )

Signed-off-by: Germain Le Chapelain <germain.lechapelain@lanvaux.fr> This is to address the sample data kindly provided in https://devtalk.blender.org/t/nurbs-import-export/17581/14?u=germain_le_chapelain (Calling for feedback if possible, I don't really know what I am doing yet :/ )
Iliya Katushenock added this to the Pipeline, Assets & IO project 2024-01-20 21:30:41 +01:00
Author
First-time contributor

Created #117430 to describe the problem this solves. I couldn't find it reported

Created https://projects.blender.org/blender/blender/issues/117430 to describe the problem this solves. I couldn't find it reported
Germain-Le-Chapelain requested review from Howard Trickey 2024-01-23 02:19:54 +01:00
Germain-Le-Chapelain requested review from Aras Pranckevicius 2024-01-23 02:19:55 +01:00
Author
First-time contributor

I am now looking at those tests and crashes without that code changes. Sorry I would have been out-of-order through and through on this.
I will post back my findings.,

I am now looking at those tests and crashes without that code changes. Sorry I would have been out-of-order through and through on this. I will post back my findings.,
Germain-Le-Chapelain changed title from Fix for 3D curves.. Why do we segment them ? to WIP: Fix for 3D curves.. Why do we segment them ? 2024-01-23 02:43:04 +01:00
Germain-Le-Chapelain changed title from WIP: Fix for 3D curves.. Why do we segment them ? to Fix for 3D curves.. Why do we segment them ? 2024-01-23 04:19:54 +01:00

There are 3 types of curves in Blender. Poly, Bézier and NURBS. The OBJ exporter currently only has code to export Poly and NURBS curves, and for that reason Bézier curves are exported as a mesh.

To be able to export Bézier curves, you'd need to check an OBJ wavefront specification, figure out what the syntax is for them and then implement the logic to write them out correctly. And then find an application that supports importing Bézier curves from OBJ and check that it works correctly.

If you change the code, it is normal for some tests to fail. The test works by comparing the exported OBJ against a reference file, and this will need to be updated, once it has been verified that the output is correct.

There are 3 types of curves in Blender. Poly, Bézier and NURBS. The OBJ exporter currently only has code to export Poly and NURBS curves, and for that reason Bézier curves are exported as a mesh. To be able to export Bézier curves, you'd need to check an OBJ wavefront specification, figure out what the syntax is for them and then implement the logic to write them out correctly. And then find an application that supports importing Bézier curves from OBJ and check that it works correctly. If you change the code, it is normal for some tests to fail. The test works by comparing the exported OBJ against a reference file, and this will need to be updated, once it has been verified that the output is correct.
Germain-Le-Chapelain changed title from Fix for 3D curves.. Why do we segment them ? to WIP: Fix for 3D curves.. Why do we segment them ? 2024-01-24 01:34:32 +01:00

Pretty sure the logic is not there, as there is no cstype bezier in the code, only cstype bspline.
https://paulbourke.net/dataformats/obj/

Pretty sure the logic is not there, as there is no `cstype bezier` in the code, only `cstype bspline`. https://paulbourke.net/dataformats/obj/

Yeah I'm not sure if the code as-is actually solves your problem properly. If you want to implement support for exporting Bezier curves as actual curves, then sure that could be implemented. I don't know why in the original code it was not implemented. My guess is that perhaps 1) the original Python OBJ export code did not have it implemented for some reason, and/or 2) generally other applications do not support Bezier curve types in OBJ files anyway.

Yeah I'm not sure if the code as-is actually solves your problem properly. If you want to implement support for exporting Bezier curves as actual curves, then sure that could be implemented. I don't know why in the original code it was not implemented. My guess is that perhaps 1) the original Python OBJ export code did not have it implemented for some reason, and/or 2) generally other applications do not support Bezier curve types in OBJ files anyway.
Author
First-time contributor

Hello !

I remembered I had got my hands on the document with the formulas (included. I forgot where I saved it from.
It should be easily retrievable.)

I updated the PR, Basically it is surfaces that I am really after,

I'll keep cracking

Hello ! I remembered I had got my hands on the document with the formulas (included. I forgot where I saved it from. It should be easily retrievable.) I updated the PR, Basically it is surfaces that I am really after, I'll keep cracking

So far to me it's not clear what are you after, actually. Are you after being able export curves as Beziers? Or after exporting surfaces/meshes as some sort of spline (e.g. NURBS) representation?

In either case, it would help to: 1) clarify which other software out there actually understands these obj format varieties, 2) implement code to do that, and check whether new curve/mesh type can export form blender and import into said software, and export form said software and import into blender correctly.

So far to me it's not clear what are you after, actually. Are you after being able export curves as Beziers? Or after exporting surfaces/meshes as some sort of spline (e.g. NURBS) representation? In either case, it would help to: 1) clarify which other software out there actually understands these obj format varieties, 2) implement code to do that, and check whether new curve/mesh type can export form blender and import into said software, and export form said software and import into blender correctly.
Author
First-time contributor

To any useful end: I am dropping here the file I am trying to load in:

I will update w/ what I have shortly.

Basically I don't understand jack-💩 to how those surface control-points are laid-out.
(I sure I am glad I had the document w/ them diagrams in it :D)

To any useful end: I am dropping here the file I am trying to load in: I will update w/ what I have shortly. Basically I don't understand jack-💩 to how those surface control-points are laid-out. (I sure I am glad I had the document w/ them diagrams in it :D)
Germain-Le-Chapelain force-pushed fixattemptcurveobjexport from fa717d8071 to 353a14096b 2024-02-13 04:32:04 +01:00 Compare
Germain-Le-Chapelain changed title from WIP: Fix for 3D curves.. Why do we segment them ? to Fix for 3D curves.. Why do we segment them ? 2024-02-13 04:34:01 +01:00
Germain-Le-Chapelain changed title from Fix for 3D curves.. Why do we segment them ? to WIP: Fix for 3D curves.. Why do we segment them ? 2024-02-13 04:34:44 +01:00
Germain-Le-Chapelain changed title from WIP: Fix for 3D curves.. Why do we segment them ? to WIP: Add support for importing NURBS & BSpline surfaces from Wavefront .OBJ files. 2024-02-13 04:36:29 +01:00
Germain-Le-Chapelain changed title from WIP: Add support for importing NURBS & BSpline surfaces from Wavefront .OBJ files. to WIP: Add support for NURBS surfaces in Wavefront .OBJ files. 2024-02-19 01:20:32 +01:00
Author
First-time contributor

Wouaïa ! So this is where the PR stands: When I try to import image (The file above)
I end-up w/ a model with holes in it. I am suspecting it has to do with these cyclic flag

Wouaïa ! So this is where the PR stands: When I try to import ![image](/attachments/42768f8e-4fa8-4c18-bd12-4f19281db635) (The file above) I end-up w/ a model with holes in it. I am suspecting it has to do with these cyclic flag
Germain-Le-Chapelain force-pushed fixattemptcurveobjexport from b8d4d26c41 to 7327a3f942 2024-03-14 00:33:21 +01:00 Compare
Germain-Le-Chapelain force-pushed fixattemptcurveobjexport from 7327a3f942 to 48a2207092 2024-03-29 01:11:55 +01:00 Compare
Germain-Le-Chapelain force-pushed fixattemptcurveobjexport from 48a2207092 to 42e8c81d17 2024-03-29 20:15:26 +01:00 Compare
Germain-Le-Chapelain requested review from Jesse Yurkovich 2024-03-30 00:56:47 +01:00
Author
First-time contributor

Wouaïa ! So this is where the PR stands: When I try to import image (The file above)
I end-up w/ a model with holes in it. I am suspecting it has to do with these cyclic flag

> Wouaïa ! So this is where the PR stands: When I try to import ![image](/attachments/42768f8e-4fa8-4c18-bd12-4f19281db635) (The file above) > I end-up w/ a model with holes in it. I am suspecting it has to do with these cyclic flag
Germain-Le-Chapelain force-pushed fixattemptcurveobjexport from 42e8c81d17 to b376773279 2024-03-30 01:14:25 +01:00 Compare
Author
First-time contributor

So my surfaces aren't precisely exporting as they import: ^^
That could be (one of) the problems.

image

So my surfaces aren't precisely exporting as they import: ^^ That could be (one of) the problems. ![image](/attachments/546c70dd-d476-4104-8a20-cf069a78c83a)
155 KiB
Germain-Le-Chapelain added 1 commit 2024-04-16 00:40:26 +02:00
438592a3e4 Fix:
[-] One typo for sure where writing control point for the surface in the wrong order:
Wavefront .OBJ file specification § `Surface vertex data', paragraph `Control points'.

 [?] They other one I have no clue:
     It's about the order/degree & `resolution' (# of control points ?  So I made it to that.
     rather than try guessing which was what I was doing before.

     But the original code just plain set it to 12 :|.  Perhaps was that the issue
     with the 2D curve (which should be working) was in that post from the forum thread I had
     cited initially in this PR.)
Author
First-time contributor

Closing for now,
I'll reopen when there be sthing to look-at

Closing for now, I'll reopen when there be sthing to look-at
Author
First-time contributor

For reference this is what I am sitting on on this branch:

image

For reference this is what I am sitting on on this branch: ![image](/attachments/63238433-e354-4c37-9ccb-0e350e84f468)
307 KiB
Germain-Le-Chapelain changed title from WIP: Add support for NURBS surfaces in Wavefront .OBJ files. to Add support for NURBS surfaces in Wavefront .OBJ files. 2024-05-02 03:58:43 +02:00
Author
First-time contributor

This is how it looks now:

image

Not shabby but not what's in the original software, still. I reloaded the exported data in it and the rendering checks out.
Could it be that Blender renders/evaluate NURBS differently than Ayam ? More likely I might be doing something wrong with the weight:

(One change is from bspline to rational B-splines.

This is how it looks now: ![image](/attachments/a6e815aa-b284-40e7-92b2-2d90a425fd86) Not shabby but not what's in the original software, still. I reloaded the exported data in it and the rendering checks out. Could it be that Blender renders/evaluate NURBS differently than Ayam ? More likely I might be doing something wrong with the weight: (One change is from bspline to **rational** B-splines.
307 KiB
First-time contributor

Looks like what would happen if you mixed up the weights on odd/even columns, possibly as a result of incorrectly compensating for 'cyclic'.

Looks like what would happen if you mixed up the weights on odd/even columns, possibly as a result of incorrectly compensating for 'cyclic'.
Author
First-time contributor

Looks like what would happen if you mixed up the weights on odd/even columns, possibly as a result of incorrectly compensating for 'cyclic'.

Thank you so much, let me have a look

When I wrote nothing is changed, it was not true.
I forgot but commit 7423a6c5fb change the order of operation

However I believe it is a bug in the original importer: I.e.: Cycling end point after importing the model shows something different than when it is initially loaded (It doesn't look correct the 1st load in. I think this is what is complained about in the forum post I site at the very beginning ?)

I can dig further/file a bug.

I will work off from NURBS Sphere on both software, also someone kindly pointed at the `screw modifier' in the chat

> Looks like what would happen if you mixed up the weights on odd/even columns, possibly as a result of incorrectly compensating for 'cyclic'. Thank you so much, let me have a look When I wrote _nothing is changed_, it was not true. I forgot but commit 7423a6c5fba8bc764614b76402e1b4ab341b4370 change the order of operation However I believe it is a bug in the original importer: I.e.: Cycling _end point_ after importing the model shows something different than when it is initially loaded (It doesn't look correct the 1st load in. I **think** this is what is complained about in the forum post I site at the very beginning ?) I can dig further/file a bug. I will work off from NURBS Sphere on both software, also someone kindly pointed at the `screw modifier' in the chat
Author
First-time contributor

So that cycli..sm.. It should only matter upon export, not importing ?

I.e. this isn't represented in the .OBJ file. It merely has a CP index pointing back to the 1st one in the sequence ?
(Though then my change should output and re-read nicely a NURB Sphere from Blender.
Spoiler: it does not. I did get that export part wrong. But again that isn't the pb in the picture above)

I'm putting the two file exports I get from each software package. (They don't have the same # of CP.
But I think there are different ways to represent a sphere w/ NURBS so I don't want to get hooked-up on that. )
I'll look and fix my export.

Also, the issue I was mentioning in the forum post seems to be about these endpoints not being ticked at all.
Once they are checked, the model appear like it was out of Rhino. I am not saying this is right, however it does look like it does in Rhino when loaded-in that other Ayam software package:

image

Now w/ all that and the specs up-above there should be everything that's needed to crack this conundrum :D
I would love to get my hands on Rhino too but got no reason to question Ayam so far.

Cheers again for the look-at & the exchange!

So that cycli..sm.. It should only matter upon export, not importing ? I.e. this isn't represented in the .OBJ file. It merely has a CP index pointing back to the 1st one in the sequence ? (Though then my change should output and re-read nicely a NURB Sphere from Blender. Spoiler: it does **not**. I did get that export part wrong. But again that isn't the pb in the picture above) I'm putting the two file exports I get from each software package. (They don't have the same # of CP. But I think there are different ways to represent a sphere w/ NURBS so I don't want to get hooked-up on that. ) I'll look and fix my export. Also, the issue I was mentioning in the forum post seems to be about these endpoints not being ticked at all. Once they are checked, the model appear like it was out of _Rhino_. I am not saying this is right, however it does look like it does in _Rhino_ when loaded-in that other _Ayam_ software package: ![image](/attachments/58de2ab8-b7fe-4fa4-bb03-d0f9f378a21c) Now w/ all that and the specs up-above there should be everything that's needed to crack this conundrum :D I would love to get my hands on _Rhino_ too but got no reason to question _Ayam_ so far. Cheers again for the look-at & the exchange!
First-time contributor

I haven't used NURBS for anything serious and can't tell you how common or uncommon specific settings are.

I know that in the idTech series of game engines, "curve patches" behave like Blender NURBS with both "Bezier" checkboxes ticked, both "Endpoints" ticked, no "Cyclic" option available (instead the last row/column is a duplicate of the first one) and 3x3 "Order" (which limits them to odd number of points along both axes).

The weight issue seems really easy to debug: just check the values at specific points once imported. On a perfect circle/cylinder/lathe/sphere, the corner points would have weight 0.707. If this isn't the case, something is going wrong during import.

A NURBS sphere primitive in Blender has 40 points. 45 if you turn off cyclic and append first row as last. Consistent with this, Ayam output obj has 45 points. So if that's your reference (why?), you should be adding a duplicate row on export and possibly skipping one on import.

Your Blender output obj has 40 points, yet also has numbers from 1 to 50 in the surf definition. This seems incorrect, but I don't know enough about obj syntax to say for sure. In Ayam's case there are 45 indices, matching the number of points. It's possible (I'm just guessing) that you can re-use these indices, which would allow you to do cyclic surfaces without duplicating rows. Then again, even if this is allowed by the spec, it's also possible that other software (e.g. Ayam) won't be able to open the file afterwards.

I haven't used NURBS for anything serious and can't tell you how common or uncommon specific settings are. I know that in the idTech series of game engines, "curve patches" behave like Blender NURBS with both "Bezier" checkboxes ticked, both "Endpoints" ticked, no "Cyclic" option available (instead the last row/column is a duplicate of the first one) and 3x3 "Order" (which limits them to odd number of points along both axes). The weight issue seems really easy to debug: just check the values at specific points once imported. On a perfect circle/cylinder/lathe/sphere, the corner points would have weight 0.707. If this isn't the case, something is going wrong during import. A NURBS sphere primitive in Blender has 40 points. 45 if you turn off cyclic and append first row as last. Consistent with this, Ayam output obj has 45 points. So if that's your reference (why?), you should be adding a duplicate row on export and possibly skipping one on import. Your Blender output obj has 40 points, yet also has numbers from 1 to 50 in the surf definition. This seems incorrect, but I don't know enough about obj syntax to say for sure. In Ayam's case there are 45 indices, matching the number of points. It's possible (I'm just guessing) that you can re-use these indices, which would allow you to do cyclic surfaces without duplicating rows. Then again, even if this is allowed by the spec, it's also possible that other software (e.g. Ayam) won't be able to open the file afterwards.
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u fixattemptcurveobjexport:Germain-Le-Chapelain-fixattemptcurveobjexport
git checkout Germain-Le-Chapelain-fixattemptcurveobjexport
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#117371
No description provided.