Collect elements from link document in view of host document

Collect elements from link document in view of host document

kiencent94
Enthusiast Enthusiast
6,034 Views
19 Replies
Message 1 of 20

Collect elements from link document in view of host document

kiencent94
Enthusiast
Enthusiast

Hello, i m trying to collect elements from link document in active view (plan view).

I create a solid from Cropbox ' s Bounding Box of Active View, then i used ElementIntersectsSolidFilter to collect elements which intersect with this solid

My code worked with model without adjust N/S E/W elevation.

But not working with model already adjusted N/S E/W elevation.

 

public static Solid CreateSolidFromBBox(this Autodesk.Revit.DB.View planView)
        {
            var inputBb = planView.get_BoundingBox(null);
            Autodesk.Revit.DB.Plane planePlanView = planView.SketchPlane.GetPlane();
            Autodesk.Revit.DB.PlanViewRange viewRange = (planView as Autodesk.Revit.DB.ViewPlan).GetViewRange();
            double cutPlaneHeight = viewRange.GetOffset(Autodesk.Revit.DB.PlanViewPlane.CutPlane);
            XYZ pt0 = PlaneUtil.ProjectOnto(planePlanView, new XYZ(inputBb.Min.X, inputBb.Min.Y, inputBb.Min.Z));
            XYZ pt1 = PlaneUtil.ProjectOnto(planePlanView, new XYZ(inputBb.Max.X, inputBb.Min.Y, inputBb.Min.Z));
            XYZ pt2 = PlaneUtil.ProjectOnto(planePlanView, new XYZ(inputBb.Max.X, inputBb.Max.Y, inputBb.Min.Z));
            XYZ pt3 = PlaneUtil.ProjectOnto(planePlanView, new XYZ(inputBb.Min.X, inputBb.Max.Y, inputBb.Min.Z));
            
            Line edge0 = Line.CreateBound(pt0, pt1);
            Line edge1 = Line.CreateBound(pt1, pt2);
            Line edge2 = Line.CreateBound(pt2, pt3);
            Line edge3 = Line.CreateBound(pt3, pt0);

            List<Curve> edges = new List<Curve>();
            edges.Add(edge0);
            edges.Add(edge1);
            edges.Add(edge2);
            edges.Add(edge3);
            CurveLoop baseLoop = CurveLoop.Create(edges);
            List<CurveLoop> loopList = new List<CurveLoop>();
            loopList.Add(baseLoop);
            Solid preTransformBox = GeometryCreationUtilities.CreateExtrusionGeometry(loopList, XYZ.BasisZ, cutPlaneHeight);

            var rliTf = FormData.Instance.SettingView.Setting.RevitLink.GetTransform().Inverse;
            Solid transformBox = SolidUtils.CreateTransformed(preTransformBox,rliTf * inputBb.Transform);

            return transformBox;

        }
public virtual IEnumerable<Element> InstanceElementsInViewRvL
        {
            get
            {
                if(RevitLinkDocument != null && instanceElementsInViewRvL == null)
                {
                    var bbActiveView = ActiveView.get_BoundingBox(null);
                    var solidActivew = ActiveView.CreateSolidFromBBox();
                    var solidIntersecFil = new Autodesk.Revit.DB.ElementIntersectsSolidFilter(solidActivew);
                    instanceElementsInViewRvL = new FilteredElementCollector(RevitLinkDocument)?.WhereElementIsNotElementType()
                        .WherePasses(solidIntersecFil);

                }
                return instanceElementsInViewRvL;
            }
        }

I need some help

 

Thanks a lot

Kien

0 Likes
Accepted solutions (1)
6,035 Views
19 Replies
Replies (19)
Message 2 of 20

TripleM-Dev.net
Advisor
Advisor

Hi,

 

I don't know what this line does:

var rliTf = FormData.Instance.SettingView.Setting.RevitLink.GetTransform().Inverse;

 

FormData.Instance.SettingView.Setting.RevitLink ? unkown object.

I assume it's a reference to the RevitLinkInstance?, try using the GetTotalTransform instead of GetTransform.

 

Maybe that that helps?

- Michel

0 Likes
Message 3 of 20

junkang.lau
Contributor
Contributor

Simple question, why is your linked model not using the shared coordinate from your host model then?? wouldn't it cause any discrepancy if you arent using shared coordinates??

0 Likes
Message 4 of 20

kiencent94
Enthusiast
Enthusiast

Thanks for your reply

FormData.Instance.SettingView.Setting.RevitLink = Link Doucument (When i pick a link document, it s will be save at FormData.Instance.SettingView.Setting.RevitLink). Then i get inverse matrix

 

 

 

 

 

0 Likes
Message 5 of 20

kiencent94
Enthusiast
Enthusiast

Thank for your reply

My link model has used share coordinate from host model already. U can see the picture below

1.png

0 Likes
Message 6 of 20

kiencent94
Enthusiast
Enthusiast

I need some help please!

0 Likes
Message 7 of 20

junkang.lau
Contributor
Contributor

Since you already got the bounding box and link document, why not use BoundingBoxIntersectsFilter Class?? That way you wouldnt need to create a new solid which requires you to translate your geometry.

 

EDIT: BUT if you really want to stick with your solid creation for whatever the reason is, I think the problem will be instead of using GetTransform() method, use GetTotalTransform() method. The GetTotalTransform() method will return the transform that includes true north, whereas the GetTransform() method doesnt. 

 

TIP: use the transform of the link instance to transform the solid in the host model then pass through your solid intersect filter collector

0 Likes
Message 8 of 20

kiencent94
Enthusiast
Enthusiast

Thanks for your reply.

i ve try the both way as u told, but it was not working too.

 

0 Likes
Message 9 of 20

TripleM-Dev.net
Advisor
Advisor

Hi,

 

I've done some testing, it seems if the view from which the boundingbox is taken has Orientation set to "True North" it's generates another boundingbox. If the view is set to "Project North" it works.

 

Is the view set to "True North" (and if it's not 0), try setting it to "Project North", see if it now selects the correct elements in the link. If this works also that the Project North rotation into account for those views.

 

- Michel

 

ps. In my apps I use the outline of the view's cropbox and not the boundingbox.

0 Likes
Message 10 of 20

kiencent94
Enthusiast
Enthusiast

Thanks for your reply

The orientation of active view set to Project North

Please see pictures below: My ActiveView is RedBox, Master Plan is BlackBox, When i use transform of link model to create transformed solid, the results return elements in BlueBox.

I dont understand clearly about transform in revit, but i think with this result and your knowledge about transform, u can help me to collect exactlly elements in RedBox. 123.png321.png

 Thanks a lot,

Kien

 

 

 

 

0 Likes
Message 11 of 20

TripleM-Dev.net
Advisor
Advisor

Hi,

 

In the test I did I just used the boundingbox min and max point directly to create the solid.

For floorplans I never use the sketchplane (i could been set to something else besides the level itself)

 

So create the pt0, pt2 etc from the boundingbox min/max.

xyz pt0 = inputBb.min
xyz pt1 = New XYZ(inputBb.max.X, inputBb.min.Y, inputBb.min.Z)
xyz pt2 = New XYZ(inputBb.max.X, inputBb.max.Y, inputBb.min.Z)
xyz pt3 = New XYZ(inputBb.min.X, inputBb.max.Y, inputBb.min.Z)

double solidheight = inputBb.max.Z - inputBb.min.Z

 

Secondly, I would expect the SolidBox of a moved linked document to display somewhere else.

See if the difference in boxes is thesame as the offset of the link? 

 

You can use directshape to create a 3D box (keep in mind the Box for the link SHOULD be offset if the link is offset!)

// Put this inside a transaction!
DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
ds.ApplicationId = "Test";
ds.ApplicationDataId = "testBox";
List<GeometryObject> GeoList = new List<GeometryObject>();
GeoList.Add(VirtualLinkSolid); // <-- the solid created for the intersection can be used here
ds.SetShape(GeoList);
ds.SetName("ID_testBox");

 - Michel

0 Likes
Message 12 of 20

kiencent94
Enthusiast
Enthusiast

i ve done the test as u told, the SolidBox 's location is the same as my previous post. Redbox is my active view, and the DirectShape was created at BlueBox. I dont know how to move it to redbox, i have tried to use ActiveView Transform for the SolidBox but it s not working

321.png

0 Likes
Message 13 of 20

TripleM-Dev.net
Advisor
Advisor

Could you post the Host and Link file?

0 Likes
Message 14 of 20

kiencent94
Enthusiast
Enthusiast
0 Likes
Message 15 of 20

TripleM-Dev.net
Advisor
Advisor
Accepted solution

Hi,

 

I've looked at it, and at first it works correctly, but not in callouts in combination of GetBoundingBox.

When i use the cropboundary as curve (View.GetCropRegionShapeManager > GetCropShape), and correct the Z-coordinat of the shape. (I only used the CutLevelOffset and the Z of the shape=level in this case.)

 

Here the reduced code for creating the solid for the active view and for the link

// Creation of intersecting solid box for active view (ONLY FLOORPLAN!)
ViewPlan vp = ((ViewPlan)(doc.ActiveView));
PlanViewRange PVR = vp.GetViewRange();
double CutOffset = PVR.GetOffset(PlanViewPlane.CutPlane);
ViewCropRegionShapeManager CR = vp.GetCropRegionShapeManager;
IList<CurveLoop> Crops = CR.GetCropShape;
Solid VirtualSolid = GeometryCreationUtilities.CreateExtrusionGeometry(new CurveLoop[] {Crops.First}, XYZ.BasisZ, CutOffset);

// Creation of the intersecting solid box for the link (in this case almost in origin)
RevitLinkInstance LinkInst = ((RevitLinkInstance)(doc.GetElement(new ElementId(2699682))));
Solid VirtualLinkSolid = SolidUtils.CreateTransformed(VirtualSolid, LinkInst.GetTotalTransform.Inverse);

 

Below the result for the Callout "F3 - COLUMNS AND WALL CALLOUT PLAN - Callout 05 Copy 1"

For the screengrab i disabled the Crop for the Callout, the boundary is still visible, and only elements in/through crop is selected.

 

Ps. Can't you use dependent views instead of the callouts, and you will also need to filter the elements based on the view's settings (or only structural columns needed?)

 

Callout selection in 3DCallout selection in 3DCallout selectionCallout selection

 

 

 

 

 

 

- Michel

0 Likes
Message 16 of 20

kiencent94
Enthusiast
Enthusiast

Thank you very much, i must finish some works so i have not tested your solution right now, i will test in the next few days.

Thankyou anyway

 

0 Likes
Message 17 of 20

kiencent94
Enthusiast
Enthusiast

It worked. But i have to CreateTranslation by Z direction to move the VirtualLinkSolid to Level 3 (active associated level of the active plan).

Thank you very much

 

 

0 Likes
Message 18 of 20

MattKincaid
Advocate
Advocate

Perhaps you could use the customer exporter API for this?  In Revit 2019 and earlier,  the CustomExporter API only worked for 3D views.  But as of 2020 it supports 2D views as well.

 

https://thebuildingcoder.typepad.com/blog/2013/07/graphics-pipeline-custom-exporter.html

 

https://thebuildingcoder.typepad.com/blog/2013/08/determining-absolutely-all-visible-elements.html

 

0 Likes
Message 19 of 20

jeanleocondori97
Observer
Observer

What if instead of a plan view, we were to work in a 3D view? How can we collect elements of a link that are visible in the current view?

0 Likes
Message 20 of 20

matthew_kincaidTPW6Y
Community Visitor
Community Visitor

That's what this solution does.
https://thebuildingcoder.typepad.com/blog/2013/08/determining-absolutely-all-visible-elements.html

It works with both 3D views and Plan Views.  If you only need elements from a particular link, you could add some logic to the OnLinkBegin method to filter out elements from the other links.  Hope this helps!

0 Likes