Data panel
Go to Coordinates
Move the view to a set of coordinates and mark the point with a cross.
On the ribbonStacked button, Data panel
NeedsAn open document
Shift+ClickClears the marker and leaves the view alone
What it does#
The other half of the pair. A point copied by Get Coordinates, or pasted out of a clash report or a survey schedule, is one click from being on screen. The camera keeps the direction it is already looking and only moves, standing five metres back from the point, so the angle you set up survives and the point lands in the middle of the view. A cross labelled with the coordinates is drawn on the point.
How to use it#
- Copy a point from anywhere: three numbers separated by commas, spaces, semicolons or
tabs, with or without brackets or X=/Y=/Z= labels. Lengths read the way every pyNavis
length field reads them, so a feet-and-inches document also takes
1' 6", -3' 3", 40', and any document takes1500mm, 2m, -3; values with feet and inches need commas between them. - Click Go to Coordinates. The box opens already filled if the clipboard held three numbers.
- Click OK. The camera moves and the cross appears. Orbit straight away and the view turns around the point, because the focal distance moved with it.
Limitations#
- Three values or nothing. A comma always separates, so "1,5 2 3" is four numbers and is refused rather than read as a European decimal.
- One marker at a time. A new point replaces the cross; Shift+Click removes it.
Other uses#
- Walk a list of survey points from a spreadsheet: copy, click, look, next row.
Source#
The tool's own files, word for word as shipped in Data.panel/Coordinates.stack/Go_to_Coordinates.pushbutton. Every pyNavis tool is an ordinary bundle: copy these into your own extension and change what you like.
script.py Runs on a click. View on GitHub"""Moves the view to a set of coordinates and marks the point.
The camera keeps the direction it is already looking and only where it stands
changes, so the angle the user set up survives and the point lands in the
middle of the view, coords.VIEW_DISTANCE_METERS away. The focal distance moves
with it, so an orbit straight afterwards turns around the point instead of
around wherever the camera was pivoting before.
The point is also drawn as a cross in the view, because a camera that has
moved to nothing in particular looks like a tool that did nothing. Shift+Click
(config.py) clears it.
Everything above the guard at the bottom is importable without Navisworks; see
lib/coords.py for the parsing and the arithmetic.
"""
import coords
from pynavis import app, forms, lengths, overlay, script, toast
from pynavis.clash import units_to_meters
def prefill(units):
"""The default for the box: the clipboard when it already holds three
coordinates, which is the round trip straight out of Get Coordinates, and
an empty box when it holds anything else."""
pasted = coords.parse(script.clipboard_text(), units)
if pasted is None:
return ''
return coords.format_point(pasted)
def viewing_distance(doc):
"""VIEW_DISTANCE_METERS in this model's own units, so the same 5m frames
the same thing in a model drawn in feet. units_to_meters reports metres per
model unit and already answers 1.0 for units it does not know; the guard is
for a document that reports nothing usable at all."""
per_unit = units_to_meters(doc)
if not per_unit:
return coords.VIEW_DISTANCE_METERS
return coords.VIEW_DISTANCE_METERS / per_unit
def move_camera(document, target, distance, log):
"""Stands the camera back from target along the direction it is already
looking. True when the view moved, False when the camera reported no
usable orientation.
CurrentViewpoint.Value does not track the live camera (it reports the same
coordinates however far the user has orbited), so the copy has to come from
CreateCopy(). Nothing reaches the view until CopyFrom, which is also what
makes this one change: the same shape pynavis.section and pynavis.viewstate
use.
"""
from pynavis._api import Api
viewpoint = document.CurrentViewpoint.CreateCopy()
rotation = viewpoint.Rotation
direction = coords.view_direction(
(rotation.A, rotation.B, rotation.C, rotation.D))
if direction is None:
return False
position = coords.camera_position(target, direction, distance)
log.info('direction (%.4f, %.4f, %.4f), camera to %s'
% (direction[0], direction[1], direction[2],
coords.format_point(position)))
viewpoint.Position = Api.Point3D(position[0], position[1], position[2])
# The focal distance is what a later orbit pivots on, so moving it with the
# camera is the difference between orbiting around the point and orbiting
# around thin air. An orthographic camera still takes the new position, so
# the point is centred either way; only this part may not apply, and a view
# that moved correctly must not fail over it.
try:
viewpoint.FocalDistance = distance
except Exception as error:
log.info('focal distance left alone: %s' % error)
document.CurrentViewpoint.CopyFrom(viewpoint)
return True
def mark(target, size):
"""Draws the cross on the point, labelled with its own coordinates. The
overlay answers False when its render plugin is not loaded; the view still
moved, so a missing drawing is not a failed tool."""
overlay.clear(coords.MARKER_TAG)
drawn = overlay.add(coords.MARKER_TAG, coords.marker_segments(target, size),
label=coords.format_point(target), label_at=target)
overlay.redraw()
return drawn
def run():
doc = app.get_doc()
log = script.get_logger()
units = str(doc.Units)
ask = 'Coordinates to move to (X, Y, Z):'
if lengths.is_imperial(units):
ask = 'Coordinates to move to (X, Y, Z), with commas between them for feet and inches:'
answer = forms.ask_string(ask, default=prefill(units), title='Go to Coordinates')
if answer is None: # None means cancelled: say nothing
return
target = coords.parse(answer, units)
if target is None:
toast.error('Could not read coordinates',
"Expected three values, like 12.5, -3, 40 or 1' 6\", -3' 3\", 40'.")
return
distance = viewing_distance(doc)
if not move_camera(doc, target, distance, log):
toast.error('Could not move the view',
'The current view reported no usable orientation.')
return
# An arm a twentieth of the viewing distance: big enough to find, small
# enough that it marks a point rather than covering what is around it.
drawn = mark(target, distance / 20.0)
units = str(doc.Units)
text = coords.format_point(target)
log.info('moved to %s (%s), %.4f units away, marker drawn=%s'
% (text, units, distance, drawn))
toast.success('Moved to coordinates', '%s %s' % (text, units))
if '__commandpath__' in globals():
run()config.py Runs on Shift+Click. View on GitHub"""Clears the marker Go to Coordinates left in the view."""
import coords
from pynavis import overlay, toast
overlay.clear(coords.MARKER_TAG)
overlay.redraw()
toast.info('Marker cleared')bundle.yaml The bundle contract: the keys pyNavis reads for this tool. View on GitHubtitle: Go to Coordinates
tooltip: Move the view to a set of coordinates and mark the point with a cross. The box opens with the clipboard's coordinates already filled in, so a point copied by Get Coordinates is one click away. Shift+Click clears the marker.
context: doc