Revit plan view bounding center in 3D seems off

Revit plan view bounding center in 3D seems off

tebogo.schultzH5FH3
Contributor Contributor
1,134 Views
6 Replies
Message 1 of 7

Revit plan view bounding center in 3D seems off

tebogo.schultzH5FH3
Contributor
Contributor

See the code that obtains the center, then see the screenshot of a sphere (gray wireframe sphere circle) placed at said center.  The sphere is not correctly in the center of the view's bounds on the sheet.  Ignore the viewport border (from another placed view) that overlaps the screenshot section.  I've tried bounding box, crop box, I get the same incorrectly shifted position instead of the exact center of the plan on the sheet.

 

Note I'm talking about the else clause of the code here (this particular view plan has no scopebox set, so I'm trying to read the bounds of the view itself)

 

 

            foreach(ElementId id in viewSheet.GetAllPlacedViews())
            {
                Element element = doc.GetElement(id);
                View placedView = (element as View);

                Parameter boxParam = placedView.get_Parameter(BuiltInParameter.VIEWER_VOLUME_OF_INTEREST_CROP);
                if(boxParam == null)
                {
                    continue;
                }

                String boxName = placedView.get_Parameter(BuiltInParameter.VIEWER_VOLUME_OF_INTEREST_CROP).AsValueString();
                Element scopeBox = getScopeboxByName(doc, boxName);
                XYZ refCenter;
                BoundingBoxXYZ bb = null;
                double radius = 1.0;

                if(scopeBox != null)
                {
                    bb = scopeBox.get_BoundingBox(null);
                }
                else
                {
                    bb = placedView.get_BoundingBox(null);
                }

                refCenter = bb.Min.Add(bb.Max.Subtract(bb.Min).Multiply(0.5));  // min + ((max-min)*0.5)

 

 

What am I missing here?

0 Likes
Accepted solutions (2)
1,135 Views
6 Replies
Replies (6)
Message 2 of 7

AGGilliam
Collaborator
Collaborator

Have you tried moving the Grid line down? I think it might be affecting the size of your bounding box.

0 Likes
Message 3 of 7

tebogo.schultzH5FH3
Contributor
Contributor

Can you elaborate on the grid line?  Also lets assume I have no control over the input file and I want this to be completely automated.  All I want is to calculate the exact geometric center of the viewport so that my sphere appears in the center of the viewport on the sheet.  

0 Likes
Message 4 of 7

AGGilliam
Collaborator
Collaborator

Sorry for the vagueness, I just noticed one of your grid lines was extending past the viewport which might affect the bounding box. If you have any grid lines in the view that are extending outside of it, I would recommend hiding them or shortening them to fit within the viewport and see how that affects the bounding box. Another way to visualize what's happening could be to create something at the outer extents of the bounding box to see where Revit thinks the center is (spheres at each corner, model lines around the edges, etc.)

0 Likes
Message 5 of 7

tebogo.schultzH5FH3
Contributor
Contributor
Accepted solution

That's a good idea..  I'll try that.  Also, any idea why the crop box isn't a 1:1 exact counterpart to the view outline on the sheet?  I was hoping I could just determine that box and simply grab the center of it (irrespective of whether or not certain elements are visible).  In other words, when I swap out get_BoundingBox for the CropBox property, I don't get the correct result either.

 

This is only an issue with extremely tight spaces (like elevators and narrow chutes).  The larger viewports the sphere is "close enough" to the center to not be an issue.  

0 Likes
Message 6 of 7

AGGilliam
Collaborator
Collaborator
Accepted solution

I'm not too familiar with crop boxes, but I took a look at the SDK and it appears to be a BoundingBoxXYZ object just like the bounding box property. In that case, the issue you're seeing is likely the same for both properties; it's circumscribing elements you aren't expecting.

One method that might work well if you have a crop box is to use ViewCropRegionShapeManager.GetCropShape() which will return a list of CurveLoops that make up the crop box. You can access the ViewCropRegionShapeManager through View.GetCropRegionShapeManager() and then find the extents of the CurveLoops to get your max and min values.

0 Likes
Message 7 of 7

tebogo.schultzH5FH3
Contributor
Contributor

It worked!  thank you!

 

My code is horrible though, but i chalk that up to me being annoyed with C#'s lack of class member modifiability.  I looked around for a bounding box utility to do this for me but I didn't find one.  Either way, thanks so much!

 

                    var cropShape = placedView.GetCropRegionShapeManager().GetCropShape();
                    XYZ max = null, min = null;

                    foreach(CurveLoop curveLoop in cropShape)
                    {
                        foreach(Curve curve in curveLoop)
                        {
                            for(int i = 0; i < 2; i++)
                            {
                                var cp = curve.GetEndPoint(i);
                                if(max == null)
                                {
                                    max = cp;
                                }
                                else
                                {
                                    if(cp.X > max.X)
                                        max = new XYZ(cp.X, max.Y, max.Z);
                                    if(cp.Y > max.Y)
                                        max = new XYZ(max.X, cp.Y, max.Z);
                                    if(cp.Z > max.Z)
                                        max = new XYZ(max.X, max.Y, cp.Z);
                                }

                                if(min == null)
                                {
                                    min = cp;
                                }
                                else
                                {
                                    if(cp.X < min.X)
                                        min = new XYZ(cp.X, min.Y, min.Z);
                                    if(cp.Y < min.Y)
                                        min = new XYZ(min.X, cp.Y, min.Z);
                                    if(cp.Z < min.Z)
                                        min = new XYZ(min.X, min.Y, cp.Z);
                                }
                            }
                        }
                    }