Get Elements In View see from Viewport in Sheet.

Get Elements In View see from Viewport in Sheet.

Chuong.Ho
Advocate Advocate
345 Views
3 Replies
Message 1 of 4

Get Elements In View see from Viewport in Sheet.

Chuong.Ho
Advocate
Advocate

Hi, I'm finding the solution able to just get elements can see from ViewPort and Sheet after user drag the view in sheet. I tried to look around but can't find any the solution can help to filter it.

You can see what I want  get is from white box of the image.

firefox_5dFGL97RSw.png

Anyone have done filters elements like this before ?

Any comment is appreciated !

This is function filter elements from viewid but it not correct in this case :

var collector = new FilteredElementCollector(doc, view.Id)
                .WhereElementIsNotElementType()
                .Where(x => x.Category != null && x.Category.HasMaterialQuantities)
                .Where(x => x.Category != null && x.Category.CategoryType != CategoryType.AnalyticalModel)
                .Where(x => x.Category != null && x.Category.CategoryType != CategoryType.Internal);
            List<Element> elements = collector.ToList().Where(x => x != null).ToList();

 

Chuong Ho

EESignature

0 Likes
346 Views
3 Replies
Replies (3)
Message 2 of 4

jeremy_tammik
Alumni
Alumni

I am not aware of a perfect solution for this. Here are some recent discussions and attempts:

 

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 3 of 4

Moustafa_K
Collaborator
Collaborator

 

I trust it is possible to filter elements visible in a viewport, but it requires some calculations. The process involves:

  1. Getting the viewport outline – Retrieve the viewport's bounding box on the sheet.
  2. Projecting to model space – Convert the outline points to model coordinates using the viewport’s transform.
  3. Applying view range offsets – Adjust for top and bottom clipping to define a proper 3D selection box.
  4. Creating a bounding filter – Use the computed 3D outline to filter elements inside the viewport.
  5. Applying a tolerance buffer – This ensures elements exactly on the edges, like thick floors, are included.

I'm a bit confused about the OutLine class. Its constructor accepts minimum and maximum points, which makes it seem similar to of BoundingBoxXYZ class. I'm having trouble understanding the difference and why a BoundingBoxXYZIsInsideFitler requires an OutLine instead of a BoundingBoxXYZ. Even though the word "outline" typically, "at least for me" refers to a 2D shape, the OutLine class seems to be used in a 3D context here.

 

 

Filter elements in Viewport.gif

 

 

Here’s the final implementation:

public static XYZ ConvertToModelSpace(this XYZ pointOnSheet, Viewport viewPort)
{
    var Doc = viewPort.Document;
    var modelSpaceView = (View)Doc.GetElement(viewPort.ViewId);
    var viewTransform = modelSpaceView.CropBox.Transform;

    BoundingBoxUV modelSpaceOutline = modelSpaceView.Outline;
    var cgModelSpaceUV = (modelSpaceOutline.Min + modelSpaceOutline.Max) / 2;
    var cgModelSpace = new XYZ(cgModelSpaceUV.U, cgModelSpaceUV.V, 0);

    Outline vportOutLine = viewPort.GetBoxOutline();
    var cgVportOutline = (vportOutLine.MinimumPoint + vportOutLine.MaximumPoint) / 2;
    var offset = cgVportOutline.Subtract(cgModelSpace);

    int Scale = modelSpaceView.Scale;
    return viewTransform.OfPoint((pointOnSheet - offset) * Scale);
}

var outline = viewPort.GetBoxOutline();
var p0 = outline.MinimumPoint.ConvertToModelSpace(viewPort);
var p1 = outline.MaximumPoint.ConvertToModelSpace(viewPort);
var view = viewPort.ViewId.GetElement<View>() as ViewPlan;

var range = view.GetViewRange();
var maxZ = range.GetOffset(PlanViewPlane.TopClipPlane);
var minZ = range.GetOffset(PlanViewPlane.ViewDepthPlane);
double tolerance = 2;
p0 = new XYZ(p0.X, p0.Y, minZ - tolerance);
p1 = new XYZ(p1.X, p1.Y, maxZ + tolerance);

outline = new Outline(p0, p1);
var bbxFilter = new BoundingBoxIsInsideFilter(outline);
var elements = new FilteredElementCollector(Doc, view.Id)
    .WherePasses(bbxFilter)
    .WhereElementIsNotElementType()
    .Where(x => x.Category != null && x.Category.HasMaterialQuantities)
    .Where(x => x.Category != null && x.Category.CategoryType != CategoryType.Internal)
    .Where(x => x.Category != null && x.Category.CategoryType != CategoryType.AnalyticalModel);

List<ElementId> ids = elements.Select(o => o.Id).ToList();
UiDoc.Selection.SetElementIds(ids);

 

I have added more details of how this works in case any one likes the details. 

Hope this helps.

 

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
Message 4 of 4

Chuong.Ho
Advocate
Advocate

Hi @Moustafa_K  and @jeremy_tammik , sorry for my busy work late reply, the code is really useful . Many thanks for the solution, I haven't have time to test the code shared but I belive is still can't resolve 100% in this case.

Regards .

Chuong Ho

EESignature

0 Likes