Closed boustrephon closed 5 years ago
Here is a reduced example...
Note that the list of coords contains 9x4 triplets - i.e. should be 18 lines in the image, and yet what we see is 8 verticals, 10 horizontals and 2 diagonals.
from pythreejs import *
import numpy as np
from IPython.display import display
# Calculate bounding box
def boundingbox(coords):
"""Returns a tuplet of two 3D coordinates containing (xmin, ymin, zmin), (xmax, ymax, zmax)"""
c = coords[0]
b = [c[0],c[0],c[1],c[1],c[2],c[2]]
for c in coords[1:]:
if c[0] < b[0]: b[0] = c[0]
if c[0] > b[1]: b[1] = c[0]
if c[1] < b[2]: b[2] = c[1]
if c[1] > b[3]: b[3] = c[1]
if c[2] < b[4]: b[4] = c[2]
if c[2] > b[5]: b[5] = c[2]
return ((b[0], b[2], b[4]), (b[1], b[3], b[5]))
def plotframe(coords, colours, width=400, height=400):
linesgeom = Geometry(vertices = coords, colors = colours)
lines = Line(geometry=linesgeom,
material=LineBasicMaterial(linewidth=5, vertexColors='VertexColors'),
type='LinePieces')
bbox = boundingbox(coords) # (xmin, ymin, zmin), (xmax, ymax, zmax)
boxdiagmag = (sum((p2 - p1)**2 for p1, p2 in zip(*bbox)))**0.5
boxdiagvec = [(p2 - p1) for p1, p2 in zip(*bbox)]
centre = [0.5*(p1 + p2) for p1, p2 in zip(*bbox)]
scene = Scene(children=[lines, DirectionalLight(color='#ccaabb', position=centre), AmbientLight(color='#cccccc')])
cam_loc = [(p1 + 1.4 * p2) for p1, p2 in zip(centre, boxdiagvec)]
c = PerspectiveCamera(position=cam_loc, up=[0,0,1])
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)], width=width, height=height)
display(renderer)
text = 'box centre: {}\nbox diagonal vector: {}\nbox diagonal magnitude: {}\ncamera location: {}'
print(text.format(centre, boxdiagvec, boxdiagmag, cam_loc));
coords2 = [[7.2, 0.0, 0.0], [7.2, 0.0, 3.5], [7.2, 0.0, 3.5], [7.2, 8.4, 3.5],
[7.2, 0.0, 3.5], [14.4, 0.0, 3.5], [14.4, 0.0, 0.0], [14.4, 0.0, 3.5],
[14.4, 0.0, 3.5], [14.4, 8.4, 3.5], [0.0, 8.4, 0.0], [0.0, 8.4, 3.5],
[0.0, 8.4, 3.5], [0.0, 16.8, 3.5], [0.0, 8.4, 3.5], [7.2, 8.4, 3.5],
[7.2, 8.4, 0.0], [7.2, 8.4, 3.5], [7.2, 8.4, 3.5], [7.2, 16.8, 3.5],
[7.2, 8.4, 3.5], [14.4, 8.4, 3.5], [14.4, 8.4, 0.0], [14.4, 8.4, 3.5],
[14.4, 8.4, 3.5], [14.4, 16.8, 3.5], [0.0, 16.8, 0.0], [0.0, 16.8, 3.5],
[0.0, 16.8, 3.5], [7.2, 16.8, 3.5], [7.2, 16.8, 0.0], [7.2, 16.8, 3.5],
[7.2, 16.8, 3.5], [14.4, 16.8, 3.5], [14.4, 16.8, 0.0], [14.4, 16.8, 3.5]]
colours2 = ['red', 'red', 'blue', 'blue', 'green', 'green', 'red', 'red', 'blue', 'blue',
'green', 'green', 'red', 'red', 'blue', 'blue', 'green', 'green', 'red', 'red',
'blue', 'blue', 'red', 'red', 'blue', 'blue', 'green', 'green', 'red', 'red',
'blue', 'blue', 'green', 'green', 'red', 'red']
plotframe(coords2, colours2, width=400, height=400)
I haven't had time to go through the example in detail, but in general, note the difference between Line and LineSegments. From a quick glance, it looks like you might want to use LineSegments?
To orbit around the center of your model, you can do either of two things:
lines.position = - center
camera.target = center
Use whichever you feel is more easy for you to reason about :)
I haven't had time to go through the example in detail, but in general, note the difference between Line and LineSegments. From a quick glance, it looks like you might want to use LineSegments?
To orbit around the center of your model, you can do either of two things:
- Move the object so that its center is at (0,0,0):
lines.position = - center
- Set the camera target instead of position:
camera.target = center
Use whichever you feel is more easy for you to reason about :)
Thank you. Using LineSegments solves the extra line problem. As a matter of interest, shouldn't "Line" work in the same way? What is Line used for as distinct from LineSegments? Why would it not work, when LineSegments does?
With regard to the target issue, I have tried something, but I am not sure that I have done it right... It doesn't work, anyway. I don't want to move the object because I might want to query it again later.
from pythreejs import *
import numpy as np
from IPython.display import display
# Calculate bounding box
def boundingbox(coords):
"""Returns a tuplet of two 3D coordinates containing (xmin, ymin, zmin), (xmax, ymax, zmax)"""
c = coords[0]
b = [c[0],c[0],c[1],c[1],c[2],c[2]]
for c in coords[1:]:
if c[0] < b[0]: b[0] = c[0]
if c[0] > b[1]: b[1] = c[0]
if c[1] < b[2]: b[2] = c[1]
if c[1] > b[3]: b[3] = c[1]
if c[2] < b[4]: b[4] = c[2]
if c[2] > b[5]: b[5] = c[2]
return ((b[0], b[2], b[4]), (b[1], b[3], b[5]))
def plotframe(coords, colours, width=400, height=400):
linesgeom = Geometry(vertices = coords, colors = colours)
lines = LineSegments(geometry=linesgeom,
material=LineBasicMaterial(linewidth=5, vertexColors='VertexColors'),
type='LinePieces')
bbox = boundingbox(coords) # (xmin, ymin, zmin), (xmax, ymax, zmax)
boxdiagmag = (sum((p2 - p1)**2 for p1, p2 in zip(*bbox)))**0.5
boxdiagvec = [(p2 - p1) for p1, p2 in zip(*bbox)]
centre = [0.5*(p1 + p2) for p1, p2 in zip(*bbox)]
scene = Scene(children=[lines, DirectionalLight(color='#ccaabb', position=centre), AmbientLight(color='#cccccc')])
cam_loc = [(p1 + 1.4 * p2) for p1, p2 in zip(centre, boxdiagvec)]
#c = PerspectiveCamera(position=cam_loc, up=[0,0,1])
c = PerspectiveCamera(position=cam_loc, target = centre, up=[0,0,1])
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)], width=width, height=height)
display(renderer)
text = 'box centre: {}\nbox diagonal vector: {}\nbox diagonal magnitude: {}\ncamera location: {}'
print(text.format(centre, boxdiagvec, boxdiagmag, cam_loc));
coords2 = [[7.2, 0.0, 0.0], [7.2, 0.0, 3.5], [7.2, 0.0, 3.5], [7.2, 8.4, 3.5],
[7.2, 0.0, 3.5], [14.4, 0.0, 3.5], [14.4, 0.0, 0.0], [14.4, 0.0, 3.5],
[14.4, 0.0, 3.5], [14.4, 8.4, 3.5], [0.0, 8.4, 0.0], [0.0, 8.4, 3.5],
[0.0, 8.4, 3.5], [0.0, 16.8, 3.5], [0.0, 8.4, 3.5], [7.2, 8.4, 3.5],
[7.2, 8.4, 0.0], [7.2, 8.4, 3.5], [7.2, 8.4, 3.5], [7.2, 16.8, 3.5],
[7.2, 8.4, 3.5], [14.4, 8.4, 3.5], [14.4, 8.4, 0.0], [14.4, 8.4, 3.5],
[14.4, 8.4, 3.5], [14.4, 16.8, 3.5], [0.0, 16.8, 0.0], [0.0, 16.8, 3.5],
[0.0, 16.8, 3.5], [7.2, 16.8, 3.5], [7.2, 16.8, 0.0], [7.2, 16.8, 3.5],
[7.2, 16.8, 3.5], [14.4, 16.8, 3.5], [14.4, 16.8, 0.0], [14.4, 16.8, 3.5]]
colours2 = ['red', 'red', 'blue', 'blue', 'green', 'green', 'red', 'red', 'blue', 'blue',
'green', 'green', 'red', 'red', 'blue', 'blue', 'green', 'green', 'red', 'red',
'blue', 'blue', 'red', 'red', 'blue', 'blue', 'green', 'green', 'red', 'red',
'blue', 'blue', 'green', 'green', 'red', 'red']
plotframe(coords2, colours2, width=400, height=400)
PS I really appreciate all the work done in wrapping threeJS for Python and especially for maintaining and responding to queries!! :-) Thanks!
For a difference between Line
and LineSegments
, please see the three.js docs and examples.
Regarding the view issue, did you tried my suggestion point 2 above? That would not move the object at all.
Yes, I did try your second suggestion - the example I posted most recently was that one, but it didn't seem to do anything to change the centre of rotation.
And yes, I had already looked at the three.js documentation:
The key point appeared to be this:
"This is nearly the same as Line; the only difference is that it is rendered using gl.LINES instead of gl.LINE_STRIP."
However, there was nothing to suggest that it would generate trailing lines. Maybe I missed something?
Incidentally, I was using "Line" because this was the example that was given here: https://github.com/jupyter-widgets/pythreejs/blob/master/examples/Examples.ipynb
Anyway, thank you very much for your help. It is much appreciated.
On Wed, 24 Apr 2019 at 5:51 PM, Vidar Tonaas Fauske < notifications@github.com> wrote:
For a difference between Line and LineSegments, please see the three.js docs and examples.
Regarding the view issue, did you tried my suggestion point 2 above? That would not move the object at all.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jupyter-widgets/pythreejs/issues/257#issuecomment-486153499, or mute the thread https://github.com/notifications/unsubscribe-auth/ADK3ZHQ2QHGESFS3BPX36PDPSAUQXANCNFSM4HGVQN5A .
I am trying to create a wireframe of the structure of a building - columns & beams.
[ Note: Reduced example in next comment ]
The following script and image should explain the issue. The script should run in Jupyter. The image generated from this data should not include any diagonals. However, that is what we see. I wonder if there is something strange going on in the Line wrapper.
(PS I am also wondering why I cannot get the model to rotate about the centre of the model. I have identified the centre that I want the model to rotate about, and I thought that I needed to specify that in the Scene definition, but that does not appear to work. Any assistance gladly received.)
LineTest.txt