Add a default UV map to our torus mesh primitive #47489

Closed
opened 2016-02-19 12:19:01 +01:00 by Bastien Montagne · 35 comments

Torus primitive is generated from a python operator, unlike all others. So generating a default UV map for it should be added to that operator.

Torus primitive is generated from a python operator, unlike all others. So generating a default UV map for it should be added to that operator.
Author
Owner

Changed status to: 'Open'

Changed status to: 'Open'
Author
Owner

Added subscriber: @mont29

Added subscriber: @mont29

Added subscriber: @Lokesh-Sharma

Added subscriber: @Lokesh-Sharma

this is my first time contributing to blender . hope it goes well

this is my first time contributing to blender . hope it goes well

any more information . where to start

any more information . where to start

Added subscriber: @amdbcg

Added subscriber: @amdbcg

My first time too, I'm guessing

  1. Find that python operator
  2. rig up something to set the UV map - I'm not sure what the details of how the UV wrap will work, so I'm assuming just go for it and modify from the rough draft.
  3. put in a default true checkbox in the settings to create a UV.
  4. create a patch.
My first time too, I'm guessing 1. Find that python operator 2. rig up something to set the UV map - I'm not sure what the details of how the UV wrap will work, so I'm assuming just go for it and modify from the rough draft. 3. put in a default true checkbox in the settings to create a UV. 4. create a patch.

Added subscriber: @ChauHo

Added subscriber: @ChauHo

This comment was removed by @ChauHo

*This comment was removed by @ChauHo*

Can use this pattern for texture coordinate:
torusCoord.png

Can use this pattern for texture coordinate: ![torusCoord.png](https://archive.blender.org/developer/F318286/torusCoord.png)

Pseudo code for create texCoord use diagram above. Sorry I program C/ObjectiveC but I think good Python programmer can understand this!

  • major direction for u
  • minor direction for v
  • assume vertexArray have (numberMinorDivision+1)*(numberMajorDivision+1) elements
  • and vertexes for each minor circle together

def function createTexCoord( integer numberMinorDivision, integer numberMajorDivision, Tuple vertexArray ) {

 integer majorIndex = 0;

calculate u and v step size

 float uStep = 1.0/numberMajorDivision;
 float vStep = 1.0/numberMinorDivision;
 integer vertexArrayIndex = 0; 

go around torus major axis

 float u = 0.0; # start at texture's left side
 while( majorIndex < numberMajorDivision + 1 ) {
  # go back to texture's bottom for each minor circle
   float v = 0.0;
   integer minorIndex = 0;
 # create coordinate for each vertex of minor circle
    while( minorIndex < numberMinorDivision + 1 ) {
     # save coordinate
       vertexArray[vertexIndex].u = u;
       vertexArray[vetexIndex].v = v;
       v += vStep;  # move up one step
      vertexArrayIndex++;
      minorIndex++;
    }
    u += uStep; # move right one step
    majorIndex++;
 }

}

Pseudo code for create texCoord use diagram above. Sorry I program C/ObjectiveC but I think good Python programmer can understand this! - major direction for u - minor direction for v - assume vertexArray have (numberMinorDivision+1)*(numberMajorDivision+1) elements - and vertexes for each minor circle together def function createTexCoord( integer numberMinorDivision, integer numberMajorDivision, Tuple vertexArray ) { ``` integer majorIndex = 0; ``` # calculate u and v step size ``` float uStep = 1.0/numberMajorDivision; float vStep = 1.0/numberMinorDivision; ``` ``` integer vertexArrayIndex = 0; ``` # go around torus major axis ``` float u = 0.0; # start at texture's left side while( majorIndex < numberMajorDivision + 1 ) { ``` # go back to texture's bottom for each minor circle ``` float v = 0.0; integer minorIndex = 0; ``` # create coordinate for each vertex of minor circle ``` while( minorIndex < numberMinorDivision + 1 ) { ``` # save coordinate ``` vertexArray[vertexIndex].u = u; vertexArray[vetexIndex].v = v; v += vStep; # move up one step vertexArrayIndex++; minorIndex++; } ``` ``` u += uStep; # move right one step majorIndex++; } ``` }

I add mesh coordinates for torus object. I try run it in Blender's text editor but it do nothing, also not appear in Object Menu. I use Blender 2.76. Please try it and tell me if it work.

torusUV.py

I add mesh coordinates for torus object. I try run it in Blender's text editor but it do nothing, also not appear in Object Menu. I use Blender 2.76. Please try it and tell me if it work. [torusUV.py](https://archive.blender.org/developer/F328511/torusUV.py)

Added subscriber: @starintheuniverse

Added subscriber: @starintheuniverse
Masado Ishii self-assigned this 2016-08-23 06:48:11 +02:00

@ChauHo good start, looks like. Does anyone mind if I pick this up and give it a go?

@ChauHo good start, looks like. Does anyone mind if I pick this up and give it a go?

Please finish it. I not know enough detail about how Blender mesh system work. I hope some one see this and help me finish it.

Please finish it. I not know enough detail about how Blender mesh system work. I hope some one see this and help me finish it.

Well I am just learning too... Hopefully I can do something useful. :)

Well I am just learning too... Hopefully I can do something useful. :)
Masado Ishii removed their assignment 2016-09-14 08:39:36 +02:00

Here is what I did before I got busy with other things: I found relevant examples and documentation, and I created a workflow to modify and test the code for the operator. I added the property "Generate UVs" to the operator. I discovered that there must be some other way to access the UVs from Python, other than the first attempt made by @BlenderNavi.

My examples and references:

My in-progress modifications to the operator code, derived from @ChauHo's file:
add_mesh_torus-mai.py

My debugging environment/workflow:

  • Keep the above python file in some directory (need not be with Blender source code base).
  • Edit the file in an external editor.
  • Open a fresh instance of blender.
  • Open the above python file in a text block in a script editor.
  • Run the script.
  • Invoke the operator through the Mesh Add menu.

In a previous version, nothing happened when the script was run--the Blender code invokes the Python code some other way. Why does running the script have affect now? Thanks to the add-on tutorial, it has effect due to several lines I appended to the script (for debugging purposes only):

def menu_func(self, context):
    self.layout.operator(AddTorusWithUVMesh.bl_idname)

def register():
    bpy.utils.register_class(AddTorusWithUVMesh)
    bpy.types.INFO_MT_add.append(menu_func)

if __name__ == "__main__":
    register()

Disclaimer: This is certainly not the only way to test the file.

However, you can speed up the above workflow by creating a fresh .blend file, loading the script into a text block, and saving the .blend file. Each time you want to run the script, open the .blend file, RE-load the script, and run it--WITHOUT overwriting the .blend file.

I truly hope this is helpful to someone! Cheers.

Here is what I did before I got busy with other things: I found relevant examples and documentation, and I created a workflow to modify and test the code for the operator. I added the property "Generate UVs" to the operator. I discovered that there must be some other way to access the UVs from Python, other than the first attempt made by @BlenderNavi. My examples and references: - 3c6709a63c - https://www.blender.org/api/blender_python_api_current/bpy.types.Operator.html - https://www.blender.org/api/blender_python_api_current/bpy.props.html - https://www.blender.org/api/blender_python_api_current/info_tutorial_addon.html#menu-item My in-progress modifications to the operator code, derived from @ChauHo's file: [add_mesh_torus-mai.py](https://archive.blender.org/developer/F359724/add_mesh_torus-mai.py) My debugging environment/workflow: - Keep the above python file in some directory (need not be with Blender source code base). - Edit the file in an external editor. - Open a fresh instance of blender. - Open the above python file in a text block in a script editor. - Run the script. - Invoke the operator through the Mesh Add menu. In a previous version, nothing happened when the script was run--the Blender code invokes the Python code some other way. Why does running the script have affect now? Thanks to the add-on tutorial, it has effect due to several lines I appended to the script (for debugging purposes only): ``` def menu_func(self, context): self.layout.operator(AddTorusWithUVMesh.bl_idname) def register(): bpy.utils.register_class(AddTorusWithUVMesh) bpy.types.INFO_MT_add.append(menu_func) if __name__ == "__main__": register() ``` Disclaimer: This is certainly not the only way to test the file. However, you can speed up the above workflow by creating a fresh .blend file, loading the script into a text block, and saving the .blend file. Each time you want to run the script, open the .blend file, RE-load the script, and run it--WITHOUT overwriting the .blend file. I truly hope this is helpful to someone! Cheers.
Member

Added subscriber: @SebastianWitt

Added subscriber: @SebastianWitt
Sebastian Witt self-assigned this 2016-09-16 17:42:19 +02:00
Member

Hi,
for a first python project I started working on this, most of the work was done anyways ;)
Here is the diff of my solution:
https://developer.blender.org/P400

And here is the raw file:
add_mesh_torus.py

I hope this helps finishing this project. I am happy about every tip i can get about my coding style or the development pipeline!

best regards,
Sebastian Witt

Hi, for a first python project I started working on this, most of the work was done anyways ;) Here is the diff of my solution: https://developer.blender.org/P400 And here is the raw file: [add_mesh_torus.py](https://archive.blender.org/developer/F361236/add_mesh_torus.py) I hope this helps finishing this project. I am happy about every tip i can get about my coding style or the development pipeline! best regards, Sebastian Witt

Added subscriber: @VukGardasevic

Added subscriber: @VukGardasevic

In #47489#392222, @SebastianWitt wrote:
Hi,
for a first python project I started working on this, most of the work was done anyways ;)
Here is the diff of my solution:
https://developer.blender.org/P400

And here is the raw file:
add_mesh_torus.py

I hope this helps finishing this project. I am happy about every tip i can get about my coding style or the development pipeline!

best regards,
Sebastian Witt

Thank you for contributing.

This is a summary of the python style required for scripts.
https://wiki.blender.org/index.php/Dev:Doc/Code_Style#Code_Style_.28Python.29

For python development currently is recommended using flake8 as a style checker. Set it up for your IDE/ editor of choice.

The default line width is 120 except in cases when there is a pep8-80-compliant comment at the top.

Common mistakes are not having spaces around operators, trailing space character or in empty ones, lines are too long, more or less than two spaces between functions, more than one line of gap between lines in functions, no space between # and text in comments, unused imports and variables, mixing tabs and spaces.

Some of the warnings are ignored due to the Blender specifics. You can check them in tests/python/pep8.py in source code (like E402 etc.).

Your solution seems to produce a good result just address the style issues first, before gets reviewed for functionality. :)

Here is an example of a cleanup for reference:

add_mesh_torus.py

Here is the flake8 output with the style warnings in the raw file.

flake8_output.txt

> In #47489#392222, @SebastianWitt wrote: > Hi, > for a first python project I started working on this, most of the work was done anyways ;) > Here is the diff of my solution: > https://developer.blender.org/P400 > > And here is the raw file: > [add_mesh_torus.py](https://archive.blender.org/developer/F361236/add_mesh_torus.py) > > I hope this helps finishing this project. I am happy about every tip i can get about my coding style or the development pipeline! > > best regards, > Sebastian Witt Thank you for contributing. This is a summary of the python style required for scripts. https://wiki.blender.org/index.php/Dev:Doc/Code_Style#Code_Style_.28Python.29 For python development currently is recommended using flake8 as a style checker. Set it up for your IDE/ editor of choice. The default line width is 120 except in cases when there is a pep8-80-compliant comment at the top. Common mistakes are not having spaces around operators, trailing space character or in empty ones, lines are too long, more or less than two spaces between functions, more than one line of gap between lines in functions, no space between # and text in comments, unused imports and variables, mixing tabs and spaces. Some of the warnings are ignored due to the Blender specifics. You can check them in tests/python/pep8.py in source code (like E402 etc.). Your solution seems to produce a good result just address the style issues first, before gets reviewed for functionality. :) Here is an example of a cleanup for reference: [add_mesh_torus.py](https://archive.blender.org/developer/F365176/add_mesh_torus.py) Here is the flake8 output with the style warnings in the raw file. [flake8_output.txt](https://archive.blender.org/developer/F365177/flake8_output.txt)
Member

Thanks lijenstina,

thats exactly the type of feedback i need!
I've switched from xcode to atom for python coding and installed a flake8 Addon to get an instant stylecheck.

Here is the updated file:
add_mesh_torus.py

I hope it is now fitting to the guidelines :)

Thanks lijenstina, thats exactly the type of feedback i need! I've switched from xcode to atom for python coding and installed a flake8 Addon to get an instant stylecheck. Here is the updated file: [add_mesh_torus.py](https://archive.blender.org/developer/F365429/add_mesh_torus.py) I hope it is now fitting to the guidelines :)

Added subscriber: @brecht

Added subscriber: @brecht

Code review:

  • There's no need to convert to bmesh and back. You can do something like this:
mesh.uv_textures.new()
uv_layer = mesh.uv_layers.active

    ...
    loops = mesh.polygons[vertexIndex].loop_indices
    uv_layer.data[loops[0]].uv = (u, v)
    ...
    
  • Use underscores rather than camel case for variable names. Maybe use minor_seg, major_seg names for consistency too.
  • Default UV map should be named "UVMap", not "default" for consistency, just leave out the name when calling new().
  • For other mesh primitives the Generate UVs button goes above View Align, and there's a col.separator() between them.
Code review: * There's no need to convert to bmesh and back. You can do something like this: ``` mesh.uv_textures.new() uv_layer = mesh.uv_layers.active ... loops = mesh.polygons[vertexIndex].loop_indices uv_layer.data[loops[0]].uv = (u, v) ... ``` * Use underscores rather than camel case for variable names. Maybe use `minor_seg`, `major_seg` names for consistency too. * Default UV map should be named "UVMap", not "default" for consistency, just leave out the name when calling `new()`. * For other mesh primitives the Generate UVs button goes above View Align, and there's a `col.separator()` between them.
Member

Thanks for the review,

I've tried to address all of the points you mentioned and will keep them in mind for the next project!
Here is the reworked code:
add_mesh_torus.py

Thanks for the review, I've tried to address all of the points you mentioned and will keep them in mind for the next project! Here is the reworked code: [add_mesh_torus.py](https://archive.blender.org/developer/F371353/add_mesh_torus.py)

This issue was referenced by 95fa303efd

This issue was referenced by 95fa303efd0b6e2963af423e601bb2869ac82520

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'

Committed, thanks for the patch!

Committed, thanks for the patch!

Added subscriber: @coolpowers

Added subscriber: @coolpowers

add_mesh_torus.py

I was trying to track down a strange discontinuity in a normal map generated from a torus, which led to discovering Blender was generating two UV islands - all but one single face were joined together. If you're interested, you can see the visual example (and what a user would do to fix it) here: https://twitter.com/coolpowers/status/988504575912087552

When I realized the torus generation was in a Python script, I took a look and cannot for the life of me work out why this section of code is included:

if minor_index == minor_seg - 1 and major_index == 0:
    uv_data[loops[1]].uv = u_prev, v_prev
    uv_data[loops[2]].uv = u_next, v_prev
    uv_data[loops[0]].uv = u_prev, v_next
    uv_data[loops[3]].uv = u_next, v_next
else:
    uv_data[loops[0]].uv = u_prev, v_prev
    uv_data[loops[1]].uv = u_next, v_prev
    uv_data[loops[3]].uv = u_prev, v_next
    uv_data[loops[2]].uv = u_next, v_next

I tried removing that first special case and the UVs (and corresponding normal map render) looked as I expected. I tried a variety of odd & even segment values to see if it made any difference, and my "fix" appears to work fine. I admit math isn't my strong point so maybe I'm overlooking something, but perhaps this is just a legacy copy/paste issue? Anyway, I'm attaching the "fix".

[add_mesh_torus.py](https://archive.blender.org/developer/F3013060/add_mesh_torus.py) I was trying to track down a strange discontinuity in a normal map generated from a torus, which led to discovering Blender was generating two UV islands - all but one single face were joined together. If you're interested, you can see the visual example (and what a user would do to fix it) here: https://twitter.com/coolpowers/status/988504575912087552 When I realized the torus generation was in a Python script, I took a look and cannot for the life of me work out why this section of code is included: ``` if minor_index == minor_seg - 1 and major_index == 0: uv_data[loops[1]].uv = u_prev, v_prev uv_data[loops[2]].uv = u_next, v_prev uv_data[loops[0]].uv = u_prev, v_next uv_data[loops[3]].uv = u_next, v_next else: uv_data[loops[0]].uv = u_prev, v_prev uv_data[loops[1]].uv = u_next, v_prev uv_data[loops[3]].uv = u_prev, v_next uv_data[loops[2]].uv = u_next, v_next ``` I tried removing that first special case and the UVs (and corresponding normal map render) looked as I expected. I tried a variety of odd & even segment values to see if it made any difference, and my "fix" appears to work fine. I admit math isn't my strong point so maybe I'm overlooking something, but perhaps this is just a legacy copy/paste issue? Anyway, I'm attaching the "fix".
Member

I can confirm this is a bug.
The UV coords are flipped as to be expected by the code. I have no idea why this was in the code i wrote 2 years ago.

The provided fix should do it, just remove the first part of the condition.

I can confirm this is a bug. The UV coords are flipped as to be expected by the code. I have no idea why this was in the code i wrote 2 years ago. The provided fix should do it, just remove the first part of the condition.
Member

Added subscriber: @lichtwerk

Added subscriber: @lichtwerk
Member

@SebastianWitt: do you want to commit yourself? (I can do otherwise...)

@SebastianWitt: do you want to commit yourself? (I can do otherwise...)
Member

@lichtwerk go ahead, thanks for doing so!

@lichtwerk go ahead, thanks for doing so!
Member

commited in d37dcc4880

commited in d37dcc4880
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 project
No Assignees
11 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#47489
No description provided.