Get viewport window outlines ..?

Good day.
Does anyone know how I could get the outlines of the viewport and convert them into lines and then draw them on the plane where the view is located …??
thank you so much.
How would the code be in PYTHON SCRIPT …??

Hey @AM3D.BIM.STUDIO ,

As a starting point for you I managed to get the viewport outline using the .GetboxOutline() method and converting this into points and then a rectangle.

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

def toList(input):
	if isinstance(input,list):
		return UnwrapElement(input)
	else:
		return [UnwrapElement(input)]

def normalise(point):
	z_val = point.Z
	if z_val != 0.0:
		Pnt = Geometry.Translate(point, Vector.ZAxis(), (0-z_val))
		return Pnt
	else:
		return point
		
def RectangleBy2Points(min, max):
	rectangle = Rectangle.ByCornerPoints(min,Point.ByCoordinates(min.X,max.Y,max.Z),max,Point.ByCoordinates(max.X,min.Y,max.Z))
	return rectangle
	
VP = []

viewports = toList(IN[0])

for v in viewports:
	try:
		Outline = v.GetBoxOutline()
		min = normalise(Outline.MinimumPoint.ToPoint())
		max = normalise(Outline.MaximumPoint.ToPoint())
		
		rectangle = RectangleBy2Points(min, max)
	
		VP.append(rectangle)
	except:
		VP.append(None)
		
OUT = VP

Maybe there’s an easier method for converting an Outline into a dynamo curve? But wasn’t sure what the .ToPoint alternative is for curves (anyone??).

I don’t have the time right now to look at getting this as a scaled set on lines inside your view, I think that might be a bit harder as you have to deal with the scaling between paper and modelspace.

Hope this helps to start

Just re-reading your question, if you just want a line on your sheet (which I don’t think you do as that is literally just the viewport outline property) it is as simple as doing this:

There could be more to it than noted so far depending on what you really want.
The view’s Outline BoundingBox will give you the points for a rectangle. This is good for most views.

But…!

If the view has been edited, you need to dig further and get the ViewCropRegionShapeManager. This will give you the lines of the actual edited view shape.

The other condition is if you have a section or elevation, or plan that has been split. Now you have to pull the CropShape which will contain the CurveLoops of the view.

And then drafting and legend views are cropped based on the extents of the elements drafted. Not a problem, unless you want them to fit in a nice neat drawing grid.

now if you want a line on the sheet, you’ll have to pull all that infor out and then scale it from drawing scale back to sheet scale (full) and place it on the sheet relative to the view.

So, I’m guessing you want something like this.


I use a few tricks.

  • First the sheets contain a bunch of constants that describe the grid. This allows me to do layouts on different sheet sizes easily.
  • Next, I have a tool for users that places a 2d “BoundingBox” element in the view to help them set up their drawings. This is a detail component that sets itself to the nearest grid increment for what is drawn in the view. The view’s crop is then set to this BoundingBox and it can be deleted. Or it can be pasted to other views so they can be cropped exactly the same.
  • With the view cropped to a nice, neat grid, it can easily be placed on the sheet, and he corners lined up with our drawing grid.
  • Our sheet grid is nothing more than a simple titleblock. So, I’m placing a titleblock on a titleblock to make the final frames for the views. Again, these pull the info from the titleblock constant parameters and the view’s size.

Is there a way to replicate these nodes within Python "Explode and DetailCurve.ByCurve+ " ???

Note that a split view returns more than one CurveLoop.

myView = doc.ActiveView

def VPLines(view):
    out = []
    myOutline = myView.GetCropRegionShapeManager()
    myCropShape = myOutline.GetCropShape()
    myCurveLoops = myCropShape
    for c in myCurveLoops:
        for l in c:
            print(l)
            out.append(l)
    return out

lines = VPLines(myView)
1 Like

Hello,
The dynamo line transformation is not possible here by the ToProtoType() process (Because the lines are not created with CreateBound ?) (sorry for my low level and the slight off topic)

edit:

import sys
import clr

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
lines = VPLines(myView)
#lines_dynamo=lines.ToProtoType()
OUT=lines

image

Cordially
christian.stan

The lines. all have points and you can extract those in python with Line.Start and Line.End.
You can take this info and pass it back to dynamo via:

#Boilerplate Code
revit_xyz_1 = Line.Start
revit_xyz_2 = Line.End
revit_line = Line.CreateBound(revit_xyz_1, revit_xyz_2)
OUT = revit_line.ToProtoType()

See: 4.6 Geometry Conversion Methods - Dynamo Python Primer (gitbook.io)

If you are after the “Lines” in dynamo more directly, I think you can step up a level and just grab the CurveLoops. (I think that will translate over.)

1 Like

I succeeded, thanks to you :+1:, I had forgotten to think of a list (how lame I am sometimes)

line_dyn=[]
lines = VPLines(myView)
for i in lines:
    line_dyn.append(i.ToProtoType())
OUT=lines,line_dyn

image
Cordially
christian.stan