How to retrieve the cropBox's coordinates of a section view?

How to retrieve the cropBox's coordinates of a section view?

maisoui
Advocate Advocate
3,066 Views
10 Replies
Message 1 of 11

How to retrieve the cropBox's coordinates of a section view?

maisoui
Advocate
Advocate

Hi,

 

I'd like to retrieve the coordinates of a section view's cropBox.

(in red on the image below)

 

revit_view_cropbox.png

 

I have tried several things for a few hours, and I still have not found a solution. I read a lot of posts on this forums or on the Building Coder blog, but I run out of idea.

 

BoundingBoxXYZ box = view.cropBox;
Transform transform = box.Transform;

Does anyone have a solution?

--
Jonathan
0 Likes
Accepted solutions (1)
3,067 Views
10 Replies
Replies (10)
Message 2 of 11

Anonymous
Not applicable

The builtincategory is OST_Viewers and it has a boundingbox with a min and max value. Is that what you need ?

0 Likes
Message 3 of 11

maisoui
Advocate
Advocate

I have the Min and Max box of the 3d box with view.cropBox, but my problem is how to compute the points of the polygon (rectangle) of this box in the 2d (section or elevation) view?

--
Jonathan
0 Likes
Message 4 of 11

Anonymous
Not applicable
0 Likes
Message 5 of 11

maisoui
Advocate
Advocate

Thank you for your replay. I read all these posts and I guess I tried all the combinations of transformations/projections, but I'm not able to retrieve the correct coordinates of Min and Max points in plane view.

 

Does anyone have a code snippet or a suggestion?

--
Jonathan
0 Likes
Message 6 of 11

maisoui
Advocate
Advocate
Accepted solution

Finally I found a solution. Maybe it could help somebody:

 

private IList<XYZ> computeBound(BoundingBoxXYZ box, Plane plane)
{
	double width = box.Max.X - box.Min.X;
	double height = box.Max.Y - box.Min.Y;

	IList<XYZ> points = new List<XYZ>();
	points.Add(box.Transform.OfPoint(box.Min));
	points.Add(points[points.Count - 1].Add(plane.XVec.Multiply(width)));
	points.Add(box.Transform.OfPoint(box.Max));
	points.Add(points[points.Count - 1].Subtract(plane.XVec.Multiply(width)));

	//project points on plane
	for(int i = 0; i < points.Count; ++i)
	{
		points[i] = plane.ProjectOnto(points[i]);
	}

	return points;
}

To project a point on a plane, read this : http://thebuildingcoder.typepad.com/blog/2014/09/planes-projections-and-picking-points.html

 

--
Jonathan
Message 7 of 11

desdinova
Advocate
Advocate

Hi Jonathan

Could you share ProjectOnto Method ?

Thanks in advance...

0 Likes
Message 8 of 11

maisoui
Advocate
Advocate

Here is the code from the link provided:

(Jeremy's blog: http://thebuildingcoder.typepad.com/blog/2014/09/planes-projections-and-picking-points.html)

 

/// <summary>
  /// Return signed distance from plane to a given point.
  /// </summary>
  public static double SignedDistanceTo(
    this Plane plane,
    XYZ p )
  {
    Debug.Assert(
      Util.IsEqual( plane.Normal.GetLength(), 1 ),
      "expected normalised plane normal" );
 
    XYZ v = p - plane.Origin;
 
    return plane.Normal.DotProduct( v );
  }

/// <summary>
  /// Project given 3D XYZ point onto plane.
  /// </summary>
  public static XYZ ProjectOnto(
    this Plane plane,
    XYZ p )
  {
    double d = plane.SignedDistanceTo( p );
 
    XYZ q = p + d * plane.Normal;
 
    Debug.Assert(
      Util.IsZero( plane.SignedDistanceTo( q ) ),
      "expected point on plane to have zero distance to plane" );
 
    return q;
  }

 

Regards

--
Jonathan
Message 9 of 11

miguelmachadoecosta
Advocate
Advocate

@maisoui wrote:

Finally I found a solution. Maybe it could help somebody:

 

private IList<XYZ> computeBound(BoundingBoxXYZ box, Plane plane)
{
	double width = box.Max.X - box.Min.X;
	double height = box.Max.Y - box.Min.Y;

	IList<XYZ> points = new List<XYZ>();
	points.Add(box.Transform.OfPoint(box.Min));
	points.Add(points[points.Count - 1].Add(plane.XVec.Multiply(width)));
	points.Add(box.Transform.OfPoint(box.Max));
	points.Add(points[points.Count - 1].Subtract(plane.XVec.Multiply(width)));

	//project points on plane
	for(int i = 0; i < points.Count; ++i)
	{
		points[i] = plane.ProjectOnto(points[i]);
	}

	return points;
}

To project a point on a plane, read this : http://thebuildingcoder.typepad.com/blog/2014/09/planes-projections-and-picking-points.html

 


It helped me, but I had to do a few adjustments, depending on the view direction:

 

 

Public Const _eps As Double = 0.000000001
Private Function ComputeBound(box As BoundingBoxXYZ, plane As Plane, reverse As Boolean) As IList(Of XYZ)
    Dim width As Double = box.Max.X - box.Min.X
    Dim height As Double = box.Max.Y - box.Min.Y
    Dim points As IList(Of XYZ) = New List(Of XYZ)()
    points.Add(box.Transform.OfPoint(box.Min))
    Dim vector As XYZ
    If Math.Abs(plane.Normal.X) < _eps Then
        vector = New XYZ(width, 0, 0)
    Else
        vector = plane.XVec.Multiply(width)
    End If
    If reverse Then vector = vector.Multiply(-1)
    points.Add(points(points.Count - 1).Add(vector))
    points.Add(box.Transform.OfPoint(box.Max))
    points.Add(points(points.Count - 1).Subtract(vector))
    For i As Integer = 0 To points.Count - 1
        points(i) = plane.ProjectOnto(points(i))
    Next
    Return points
End Function

 

 

 

My criterion for reversing is:

 

 

Dim reverse As Boolean
If View.RightDirection.X < 0 Then reverse = True

 

 

 

0 Likes
Message 10 of 11

AmitMetzk
Explorer
Explorer

With the help of Remy van den Bor comment and Revit Lookup
i noticed that the viewSection BoundingBoxXYZ is different from the crop Region BoundingBoxXYZ.

viewSection in revit lookup -> Snoop Active View -> BoundingBox

crop Region in revit lookup -> Select the crop Region -> Snoop Current Selection -> BoundingBox

 

we need the crop Region (which is OST_Viewers Category) in order to retrieve the cropBox's coordinates

here is the code i used to get it

 

//Retrieve Section view
ViewSection sec = doc.ActiveView as ViewSection;

//Retrieve Crop Region BoundingBox
ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_Viewers);
IList<ElementId> dependants = sec.GetDependentElements(filter);
ElementId viewrId = dependants.First();
Element viewer = doc.GetElement(viewrId);
BoundingBoxXYZ secBoundingBox = viewer.get_BoundingBox(sec);
			
XYZ topRight = secBoundingBox.Max;
XYZ bottomLeft = secBoundingBox.Min;

XYZ diagonal = topRight - bottomLeft;
XYZ rightDirection = sec.RightDirection;
XYZ upDirection = sec.UpDirection;
				
double width = diagonal.DotProduct(rightDirection);
double height = diagonal.DotProduct(upDirection);
				
XYZ bottomRight = bottomLeft + width*rightDirection;
XYZ topLeft = topRight - width*rightDirection;

 

 

0 Likes
Message 11 of 11

ntopo7
Participant
Participant

Hi, this works for me, but not in all section views orientation

Im missing something?

    private IList<XYZ> computeBound1(BoundingBoxXYZ cropBox, Plane plane, Autodesk.Revit.DB.View view)
        {
            bool reverse = true;
   
            if(view.RightDirection.X < 0)
            {
                reverse = true;
            }
            else
            {
                reverse = false;
            }

            double _eps = 0.00000000;
            double width = (cropBox.Max.X - cropBox.Min.X);
            double height = (cropBox.Max.Y - cropBox.Min.Y);
            IList<XYZ> points = new List<XYZ>();
            points.Add(cropBox.Transform.OfPoint(cropBox.Min));
            XYZ vector = new XYZ();

            if (Math.Abs(plane.Normal.X) < _eps)
            {
                vector = new XYZ(width, 0, 0);
            }
            else
            {
                vector = plane.XVec.Multiply(width);
            }
       
            if(reverse)
            {  vector.Multiply(-1); }

           points.Add(points[points.Count - 1].Add(vector));
           points.Add(cropBox.Transform.OfPoint(cropBox.Max));
           points.Add(points[points.Count - 1].Subtract(vector));

           for (int i = 0; i < points.Count; ++i)
              {
              points[i] = plane.ProjectOnto(points[i]);
             }
           return points;

        }

 

Its works in some sections but i get this diagonal lines in other views:

ntopo7_0-1714135373092.png

any ideas?

Thanks

 

 

0 Likes