Assign new CropBox to SectionView :: problem with my transform?

I acknowledge this topic has been covered in other threads. I’ve read through a bunch of posts but i’m stuck and not sure what i’m misunderstanding.

I am trying to set the crop box of an existing elevation based on part of a room boundary with an offset. This should be functionally similar to the procedure described by Jeremy Tammik The Building Coder: Create Section View Parallel to Wall (typepad.com)

i’m working with this situation where elevations are not aligned to room walls

I’m trying to change this view’s CropBox from the default (red) to the wall (green)

From the posts i’ve read it seems like the procedure is supposed to go like this

create bounding box aligned to project origin and internal CS

update the transform with the view orientation components
transform.origin = midpoint of wall curve
transform.BasisX = view right direction
transform.BasisY = up (for a section view)
transform.BasisZ = view direction (towards viewer)

set the bounding box transform = to the transform

set the view cropbox to the new bounding box

when i snoop the unmodified view, some things don’t make sense.
the view origin is not located at the element or even in the view

if i measure this out to the ‘observed’ origin, i would expect (-143.486,-110.642,0)
so it looks like the view origin is just setting the Y coordinate?
and when i get the unmodified CropBox, it is not located at the UCS

I’ve tried two different procedures:

  1. using Dynamo

transform the target geometry to the Internal Coordinate System

i think this is where my error is. I’ve tried a couple different configurations, but it seems like i’m choosing the wrong point as the CS origin. My best results, which give the view in the correct orientation, but just in the wrong location, occur when i use the midpoint of the wall and set the Z value = 0

construct the bounding box
set the cropbox with Views.SetCropBox

dynamo geometry preview of the BoundingBox looks like this
image

  1. using Python

Here, i tried to follow more explicitly what’s written in JT’s post, but it gives a similarly incorrect result.

import sys
import clr

clr.AddReference('ProtoGeometry')
clr.AddReference('RevitNodes')
clr.AddReference('RevitServices')
clr.AddReference('RevitAPI')

from Autodesk.Revit.DB import *

import Revit
clr.ImportExtensions(Revit.GeometryConversion)

from RevitServices.Transactions import TransactionManager
from RevitServices.Persistence import DocumentManager
import Autodesk.DesignScript.Geometry as DS

doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIDocument

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

views = UnwrapElement(IN[0])
points = IN[1]
cs = IN[2]

watch = []

TransactionManager.Instance.EnsureInTransaction(doc)

# need to set the new crop box!
watch.append("view found, activate view")
t = Transform.Identity
t.Origin = cs.Origin.ToRevitType()
t.BasisX = cs.XAxis.ToRevitType()
t.BasisY = cs.YAxis.ToRevitType()
t.BasisZ = cs.ZAxis.ToRevitType()
   
"""
t = Transform.Identity
t.Origin = XYZ()
t.BasisX = views.RightDirection
t.BasisY = XYZ.BasisZ
t.BasisZ = views.ViewDirection
"""
minT = points[0].ToRevitType()
maxT = points[1].ToRevitType()

##  I found this procedure included in a related post somewhere. i've commented it out to try and match 
## the JT post about sections aligned to wall
#minpX = min(minT.X, maxT.X)
#minpY = min(minT.Y, maxT.Y)
#minpZ = min(minT.Z, maxT.Z)
#maxpX = max(minT.X, maxT.X)
#maxpY = max(minT.Y, maxT.Y)
#maxpZ = max(minT.Z, maxT.Z)
#
#vsBBmin = XYZ(minpX, minpY, minpZ)
#vsBBmax = XYZ(maxpX, maxpY, maxpZ)

vsBBmin = minT
vsBBmax = maxT

vsBB = BoundingBoxXYZ()
vsBB.Enabled = True
vsBB.Transform = t
vsBB.Min = vsBBmin
vsBB.Max = vsBBmax

vsBB.set_MinEnabled(0,True)
vsBB.set_MinEnabled(1,True)
vsBB.set_MinEnabled(2,True)
vsBB.set_MaxEnabled(0,True)
vsBB.set_MaxEnabled(1,True)
vsBB.set_MaxEnabled(2,True)

views.CropBox = vsBB
    
TransactionManager.Instance.TransactionTaskDone 


OUT = vsBB.ToProtoType()

I think my problem has something to do with a poor understanding of the relative location of the view’s origin. I don’t understand why the starting origin is so far from the expected value, and how to modify the origin i use to generate the new transform. It seems like the approach for constructing the transform to set/modify the BoundingBox transform is different than when generating a new SectionView?

here’s my test file. You do need to select the room and the elevation marker independently. There’s a integer slider to switch between the different elevation vews

test_ResetCrop.dyn (184.5 KB)

Trying to break this down into simpler actions:

With the node SectionView.ByCoordinateSystemMinPointMaxPoint, i configured the ‘view’ coordinate system as follows:

Origin: center of wall
X: calculated view right
Y: BasisZ
Z: calculated view direction

this seems to generate a section with the appropriate CropBox, albeit in the wrong direction

Somehow i guess that’s still the wrong transform to use when modifying the cropbox of an existing view? This just doesn’t seem to track with what i’ve read…

What’s the goal here. To get the elevations to align with the walls instead of being on the X/Y axis?

One tip I always go to is “how would you do this if Dynamo wasn’t involved?”.

Work out the difference in angles and then rotate the elevation marker. That’s the way I’ve approached in scripts for creating elevations anyway. Create the marker, rotate it, then get the outline of the wall or whatever the object is, offset it, then crop the view.