Trouble w/ Viewport Clipping+ DrawViewportWires

Q1: What am I doing wrong?

I have a component that is Drawing label meshes to the viewport and the labels work great when they are in the midst of other Rhino geometry in the scene. However, I am trying to implement a zDepth functionality that moves the label toward the viewport screen plane, by using a vector to move based on an amount and overriding the BoundingBox of the GH_Component. Unfotrunately, every time I move the label beyond the boundary of existing geometry in the Rhino scene, my label disappears.

Sample code:

public override void ClearData()
        {
            base.ClearData();
            this.tagObjects.Clear();
            this.ClipBox = BoundingBox.Empty;
        }

        public override BoundingBox ClippingBox
        {
            get
            {
                return this.ClipBox;
            }
        }

        public override void DrawViewportWires(IGH_PreviewArgs args)
        {
            bool debug = false;
            //args.Display.EnableClippingPlanes(false);
            int pIndex = 0;

            foreach (LabelContents mto in tagObjects)
            {
                
                TagStyle tts = mto.TagStyle;
                RhinoViewport viewport = args.Viewport;
                //Calculate change of basis from world origin to the camera plane
                Transform cameraXform = new Transform();
                // Get camera plane and set it to the Tag Origin
                Plane cameraPlaneRaw;
                args.Viewport.GetCameraFrame(out cameraPlaneRaw);
                //double length = towardLensVector.Length;
                Plane cameraPlane = new Plane(cameraPlaneRaw);
                cameraPlane.Origin = mto.TagOrigin;
                //cameraPlane.Translate(towardLensVector * tts.ZDepth);  // disabled while clipping plane issue is resolved
                //Plane nearClippingPlane = new Plane();
                Plane farClippingPlane = new Plane();
                //Circle debugCircle = new Circle(farClippingPlane, 100);
                //debugCircle.Translate(towardLensVector * tts.ZDepth);
                //args.Display.DrawCircle(debugCircle, Color.Black); // debug
                //args.Viewport.GetFrustumNearPlane(out nearClippingPlane);
                args.Viewport.GetFrustumFarPlane(out farClippingPlane);

                Vector3d towardLensVector = new Vector3d(args.Viewport.CameraLocation - mto.TagOrigin);
                towardLensVector.Unitize();
                Vector3d parallelVector = farClippingPlane.Normal;
                Vector3d zDepthVector = (args.Display.Viewport.IsParallelProjection) ? parallelVector : towardLensVector;
                zDepthVector.Unitize();
                Point3d origin = mto.TagOrigin + zDepthVector * tts.ZDepth;
                cameraPlane.Origin = origin;
                Sphere clippingSphere = new Sphere(cameraPlane, 15);
                ClipBox.Union(clippingSphere.BoundingBox);
                args.Display.DrawSphere(clippingSphere, Color.Black);
...
}

Q2: What is the difference between DrawViewportMeshes and DrawViewportWires? They both seem to function the same way.

Thanks!

Assigned to Scripting category.

BTW – I think I answered Q2 for myself by looking at the Rhinocommon docs (duh) – it seems that DrawViewportMeshes will only be called if the viewport + displaymode supports shaded meshes, whereas DrawViewportWires will be called by all viewports… simple enough, I was just confused by the naming, which seems to imply that you could only draw linework in DrawViewportWires, which is clearly not the case. Anywho.

Cheers.

Please note:

  • This problem occurs in all “regular” viewport displaymodes: Wireframe, Shaded, Rendered, etc, but does NOT exist in Pen, Artistic, Arctic (all objects appear fine regardless of depth).

Also not that I am drawing TextEntities, Hatches, and Curves, and none of them appear properly in the “regular” displaymodes. Any thoughts?

If you’re trying to draw to 2D screen space on top of 3D viewport geometry, have a look at this topic that demonstrates how to call the DrawForeground method in both GHPython and C#:

Edit: Missed the last post. This information probably isn’t relevant, my bad.

Hi @AndersDeleuran – Thanks for the response! I actually found that post in my research yesterday, and it’s very interesting for other purposes – unfortunately I’m not trying to accomplish a pure HUD with this project, but rather the ability to take a centerpoint of an object, draw a label, and move that label forward from the centerpoint to outside the bounds of the object so that it appears in front of the object (but behind other objects that may move in front of it and occlude it) – so I do need the bounding box clipping to work properly in the viewport.

An interesting UPDATE: Turning ON the Ground Plane in the DisplayMode’s options makes my labels magically appear! This is a great lead in terms of finding a solution, but unfortunately not sustainable as a deployable solution in our environment because it should work in any displaymode with any settings. This does lead me to believe there is a bug in the Display pipeline that is disappearing these objects from DrawViewportWires/Meshes when using render modes without a ground plane.

I have confirmed that this problem also exists in @andheum’s Screen-Oriented Mesh component, at least on my machine – I’m curious if others also see this issue and whether it is a bug or “as intended” (not sure why it would be intended)…

1 Like

Couldn’t you just take the vector from the object center to the view camera position, draw a line - not a line segment - with the vector as its direction, then intersect the line with the object or it’s bounding box to get the point outside where the label should be drawn and facing the camera?

Getting the appropriate location is not an issue, it’s the viewport not displaying the object when the ground plane is not enabled and the label is outside the bounding box of existing Rhino geometry that’s the problem. All viewports with the Ground plane enabled display correctly. Here is a GIF to illustrate.

labels-hellow world

that is probably because anything outside the scene bounding box will be clipped. To avoid that, expand your scene bounding box when moving the label.

I thought that was the point of manipulating the ClipBox, as in:

ClipBox.Union(clippingSphere.BoundingBox);

Is that not the correct way to “expand your scene bounding box”???

And why does my code work in some viewport displaymodes and not others?

I’m a C# noob, so not sure if this is going to be of any help, but in a plugin I wrote, I have a display conduit that draws custom graphs, and I solved the clipping this way:

        internal void CalcBbox(out BoundingBox bb)
        {
            Rhino.DocObjects.ObjectEnumeratorSettings oes = new ObjectEnumeratorSettings()
            {

                NormalObjects = true,
                LockedObjects = false,
                IncludeLights = false,
                HiddenObjects = false,
                DeletedObjects = false,

            };

            IEnumerable<RhinoObject> objs = doc.Objects.GetObjectsByType<RhinoObject>(oes);
            BoundingBox total_bbox = new BoundingBox();
            foreach (RhinoObject obj in objs)
            {
                BoundingBox bbox = obj.Geometry.GetBoundingBox(true);
                total_bbox.Union(bbox);
            }
            total_bbox.Inflate(EvalSettings.graph_scale);
            bb = total_bbox;
        }
        protected override void CalculateBoundingBox(CalculateBoundingBoxEventArgs e)
        {
            CalcBbox(out BoundingBox b);
            e.IncludeBoundingBox(b);
        }