Creating a view from an existing view

Hello everyone,

I’m trying to create a new view from an assembly view. To achieve this, I’m using the existing view’s origin, direction, and bounding box to create a new view with the same characteristics, but encompassing the entire model within the view, using the “SectionView.ByCoordinateSystemMinPointMaxPoint” node.
The problem I’m facing is creating a coordinate system that matches the existing view.
I’m having difficulty understanding the correct way to input these values into the “CoordinateSystem.ByOriginVectors” node.

Can anyone tell me if I’m on the right track and how I should approach these nodes?

Thank you all in advance!

Hello @lucas.a and welcome to the Dynamo Forum :slight_smile:

You´re not building a proper coordinate system, you are using only 1 vector for all 3 axis/directions.

There are a few nodes that will help you to get the 3 vectors you need, vector cross product, view up direction, …

Please always tell us which error messages you get.

Hi @gerhard.p, thanks for your reply!

Indeed, you are correct. I am facing challenges in understanding how to indicate the direction of my view. Upon further research, I imagine that I should first generate the view and then rotate it using the original ViewDirection However, I haven’t been able to fully comprehend the process of performing this rotation…

You can build the cs like that:

1 Like

Awesome!

It worked, but I need to make some changes to the connections of the dots. However, it helped me address the core of my doubts.

Basically, the “View.RightDirection” node represents the orientation of the X-axis, determining the positive direction along the width of the view. The “View.ViewDirection” node represents the orientation of the Z-axis, determining where the view is looking within the three-dimensional space. The Y-axis, which is orthogonal to both the X-axis and Z-axis, represents the vertical direction, determining the positive direction along the height of the view. The cross vector tip helped me achieve this purpose.

2 Likes

There is also a vector.reverse node, if you ever want to change a direction.

Okay, I thought my problem had been resolved, but no…

When I created the CS (Coordinate System), everything seemed to be in accordance with the original view. However, when the new view is created, the local origin point is shifted exactly by the width and height values of the BoundingBox. If you look at the attached image, you can see in the background the original origin points of two views that I isolated (the original and the copy) and their respective directions. Firstly, you can see that both View.ViewDirection (red) and View.RightDirection (blue) are inverted. Secondly, the distance between the origins of the two views is exactly the difference between the points of the BoundaryBox. It seems that the BoundingBox has flipped everything in my created view.

I’m a bit lost… I will attach the code so you can take a look if you want.


ViewDuplicating.dyn (52.4 KB)
ViewsInspection.dyn (52.4 KB)

To see whats going on i just create a coordinatesystem, create a section view and then try to get an equal CS from this view.

It seems the view.origin gives a stange result, i can´t explain why.

But here you have a python code to get the min point of the view.
And also the graph how to build an equal CS.

import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

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

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

view = UnwrapElement(IN[0])
cpbbx = view.CropBox
tfBBx = cpbbx.Transform 
newBBx = BoundingBoxXYZ()
newBBx.Min = tfBBx.OfPoint(cpbbx.Min)
newBBx.Max = tfBBx.OfPoint(cpbbx.Max)
ddsBBx = DS.BoundingBox.ByCorners(newBBx.Min.ToPoint(), newBBx.Max.ToPoint())

OUT = ddsBBx.MinPoint
1 Like

Thank you so much for your support. I truly appreciate it!

Have you had an opportunity to apply this script in a real project? I attempted to implement it myself, but unfortunately, it did not yield the desired results. Your intention with the phyton code was to utilize the minimum point of the bounding box as the origin for the coordinate system?

I´ll have a look.
Is tehre any reason why you don´t use view.duplicate?

Because I’m attempting to duplicate an assembly view as independent.

Hello @lucas.a

Here you have a graph that creates a rotated section view, gathers the information from it and creates a duplicated section view.

Duplicate_Section.dyn (92.3 KB)

As I´m still struggling with a boundingbox problem, this code will only work if the cropbox of the view is rectangular. I´ll get back to you as soon as i solved that problem.

A first draft of a code that duplicates a section:

import clr
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import System
from System import Array
from System.Collections.Generic import *
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
from Autodesk.DesignScript.Geometry import BoundingBox as bndBox
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager 
from RevitServices.Transactions import TransactionManager 

clr.AddReference("RevitAPI")
clr.AddReference("RevitAPIUI")

import Autodesk 
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication 
app = uiapp.Application 
uidoc = uiapp.ActiveUIDocument

def create_view_coordinatesystem(view):
	x_axis = view.RightDirection.ToVector()
	xrev = Vector.Reverse(x_axis)
	z_axis = view.ViewDirection.ToVector()
	zrev = Vector.Reverse(z_axis)
	y_axis = view.UpDirection.ToVector()
	yrev = Vector.Reverse(y_axis)
	cs = CoordinateSystem.ByOriginVectors(Autodesk.DesignScript.Geometry.Point.ByCoordinates(0, 0, 0), yrev, xrev, zrev)
	return cs

if isinstance(IN[0], list):
	views = UnwrapElement(IN[0])
else:
	views = [UnwrapElement(IN[0])]

collector = FilteredElementCollector(doc).OfClass(ViewFamilyType).WhereElementIsElementType()

view_family_types = collector.ToElements()

for view_family_type in view_family_types:
	if view_family_type.ViewFamily == ViewFamily.Section:# and viewFamilyType.Name == ""
		section_type = view_family_type

TransactionManager.Instance.EnsureInTransaction(doc)

for view in views:
	if view.ViewType == ViewType.Section:
		view_coordinatesystem = create_view_coordinatesystem(view)
		shape=view.GetCropRegionShapeManager().GetCropShape()
		lines=[]
		if len(shape) > 0:
			lines.append([s.ToProtoType() for s in shape[0]])
		else:
			lines.append(None)
		points = []
		for line in lines[0]:
			points.append(line.StartPoint)
			points.append(line.EndPoint)
		# Initialize variables with high initial values
		lowest_x = float('inf')
		lowest_y = float('inf')
		lowest_z = float('inf')
		highest_x = float('-inf')
		highest_y = float('-inf')
		highest_z = float('-inf')
		newpoints = []
		# Iterate over the points and update the lowest values
		for point in points:
			newpoint = Autodesk.DesignScript.Geometry.Point.Transform(point,view_coordinatesystem , CoordinateSystem.Identity())
			newpoints.append(newpoint)
		for np in newpoints:
			x = np.X
			y = np.Y
			z = np.Z
			lowest_x = min(lowest_x, x)
			lowest_y = min(lowest_y, y)
			lowest_z = min(lowest_z, z)
			highest_x = max(highest_x, x)
			highest_y = max(highest_y, y)
			highest_z = max(highest_z, z)
		
		min_point = Autodesk.DesignScript.Geometry.Point.ByCoordinates(lowest_x, lowest_y, lowest_z)
		max_point_planar = Autodesk.DesignScript.Geometry.Point.ByCoordinates(highest_x, highest_y, highest_z)
		
		view_depth = int(view.LookupParameter("Far Clip Offset").AsValueString())
		view_depth_vector = Vector.ByTwoPoints(Autodesk.DesignScript.Geometry.Point.ByCoordinates(0,0,0), Autodesk.DesignScript.Geometry.Point.ByCoordinates(0,0,view_depth))

		max_point = Autodesk.DesignScript.Geometry.Point.Add(max_point_planar, view_depth_vector)
		boundingbox = bndBox.ByCornersCoordinateSystem(min_point,max_point, view_coordinatesystem).ToRevitType()
		section = ViewSection.CreateSection(doc,section_type.Id , boundingbox)

		
TransactionManager.Instance.TransactionTaskDone()
OUT = newpoints,min_point ,max_point_planar , max_point,boundingbox ,section

While it does work there are still some mistakes…