tpaviot / pythonocc-core

Python package for 3D geometry CAD/BIM/CAM
GNU Lesser General Public License v3.0
1.39k stars 380 forks source link

Option for rendering edges in JupyterRenderer as continuous in addition to dashed #751

Closed Krande closed 4 years ago

Krande commented 4 years ago

Hello,

I came across some issues using the JupyterRenderer to render a simple wire (comprised of 2 edges) using the following code (and pythnocc 7.4.0RC1)

from OCC.Core.gp import gp_Pnt
from OCC.Extend.ShapeFactory import make_wire
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge

h = 0.18
wbtn = 0.033
p1 = (0, 0, 1)
p2 = (0, -h, 1)
p3 = (wbtn, -h, 1)

e1 = BRepBuilderAPI_MakeEdge(gp_Pnt(*p1), gp_Pnt(*p2)).Edge()
e2 = BRepBuilderAPI_MakeEdge(gp_Pnt(*p2), gp_Pnt(*p3)).Edge()

mywire = make_wire([e1, e2])

# Visualize using SimpleGui
from OCC.Display.SimpleGui import init_display
display, start_display, add_menu, add_function_to_menu = init_display()
display.EraseAll()
display.DisplayShape(mywire)
display.FitAll()
start_display()

# Visualize using JupyterRenderer
my_renderer = JupyterRenderer(size=(800, 600))
my_renderer.DisplayShape(mywire, update=False, render_edges=False)
my_renderer.Display()

This is visualized just fine using the SimpleGui in the code above

image

However the JupyterRenderer resulted displaying only one of the edges as shown below:

image

Now the problem (as far as I can tell) is the dash-spacing in the default dashed line geometry in the JupyterRenderer. By editing the above example using larger numbers (as shown below) I am able to display both edges.

from OCC.Core.gp import gp_Pnt
from OCC.Extend.ShapeFactory import make_wire
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge

h = 100
wbtn = 10
p1 = (0, 0, 1)
p2 = (0, -h, 1)
p3 = (wbtn, -h, 1)

e1 = BRepBuilderAPI_MakeEdge(gp_Pnt(*p1), gp_Pnt(*p2)).Edge()
e2 = BRepBuilderAPI_MakeEdge(gp_Pnt(*p2), gp_Pnt(*p3)).Edge()

mywire = make_wire([e1, e2])

image

I have tried debugging in order to figure out where the dashed line geometry is being set, however I have yet to find exactly where the dashed line geometry is applied. It may be a long shot but, could it somehow be related to the Tessalator defined here?

https://github.com/tpaviot/pythonocc-core/blob/076b22229c73905503c28c46c125e7fe35cc715e/src/Display/WebGl/jupyter_renderer.py#L539-L543

To circumvent this, would it be possible to add an option to set a continuous line geometry representation as an alternative to the default dashed line geometry?

Best Regards Kristoffer

tpaviot commented 4 years ago

I can't reproduce the issue : in the second case, I dont' see anything, no dashed line.

Edge display style depends on the "Material" affected to the shape. It's basically a LineBasicMaterial and I don't see any dash option. It's defined at the python level, in the jupyter_renderer

Krande commented 4 years ago

Ah okay,

that could be my bad. For the figure I moved the geometry a bit on the z-axis in order for the dashed line not to be covered by the primary axis (as shown below).

I updated my original post with the correct input

from OCC.Core.gp import gp_Pnt
from OCC.Extend.ShapeFactory import make_wire
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge
from OCC.Display.WebGl.jupyter_renderer import JupyterRenderer

h = 100
wbtn = 10
p1 = (0, 0, 1)
p2 = (0, -h, 1)
p3 = (wbtn, -h, 1)

e1 = BRepBuilderAPI_MakeEdge(gp_Pnt(*p1), gp_Pnt(*p2)).Edge()
e2 = BRepBuilderAPI_MakeEdge(gp_Pnt(*p2), gp_Pnt(*p3)).Edge()

mywire = make_wire([e1, e2])

my_renderer = JupyterRenderer(size=(800, 600))
my_renderer.DisplayShape(mywire, update=False, render_edges=False)
my_renderer.Display()

image

Are you still not seeing the dashed line?

rainman110 commented 4 years ago

@tpaviot i also have the dashed line issues for curves only.

The reason is the wrong opengl enum used for line renderings. The fix is a one liner!

tpaviot commented 4 years ago

@rainman110 Where is this enum defined or used ?

tpaviot commented 4 years ago

I confirm that curves (only, not shape edges) are rendered using a dashed line.

tpaviot commented 4 years ago

I think it comes from the line

https://github.com/tpaviot/pythonocc-core/blob/master/src/Display/WebGl/jupyter_renderer.py#L522

It's currently

edge_material = LineBasicMaterial(color=color, linewidth=2, fog=True)

it should be

edge_material = LineBasicMaterial(color=color, linewidth=1)

I can't run a test today, can you @Krande try to manually modify your jupyter_renderer.py and check the result ?

Krande commented 4 years ago

Unfortunately from what I can tell removing "fog=True" did not change the line representation.

The altered code

print('fog is not included')
edge_material = LineBasicMaterial(color=color, linewidth=1)
edge_lines = LineSegments(geometry=edge_geometry, material=edge_material)

resulted in image

I will continue debugging the python part of the code to see if I can track down the source of the dashed lines.

rainman110 commented 4 years ago

@tpaviot LineSegments must be replaced by Line.

Then, you should not have any dashed lines anymore.

Krande commented 4 years ago

That worked like a charm!

print('Line replacing LineSegment')
edge_material = LineBasicMaterial(color=color, linewidth=1)
edge_lines = Line(geometry=edge_geometry, material=edge_material)

resulted in the expected shape

image

For my part, feel free to close this issue!

Best regards Kristoffer

rainman110 commented 4 years ago

@Krande feel free to contribute a pull request to fix this problem ;-)

Krande commented 4 years ago

Sure, I'll give it a shot!

tpaviot commented 4 years ago

LineSegments2 also works. I dont' know which one is better between Line and LineSegments2. I'll push a fix tomorrow. I also other change to upload.

@rainman110 If you have comments/requests related to the jupyter renderer, it's a good time, I will work on that topic this week, it's been a while I didn't work on this part of the project.

rainman110 commented 4 years ago

Line is definitely the right choice. See the three.js documentation https://threejs.org/docs/#api/en/objects/Line

rainman110 commented 4 years ago

If you have comments/requests related to the jupyter renderer, it's a good time, I will work on that topic this week, it's been a while I didn't work on this part of the project.

It's been a while, since I modified the jupyter renderer for us to work better. This is what I changed:

I am right now on a conference and can not really work on anything, therefore I can give you only tiny information right now.

tpaviot commented 4 years ago

@rainman110 Is this code publicly available somewhere ?