A very basic question about boundingbox

unhandled

#1

@DavidRutten @dale

A very basic question. I just forgot. I did it 8 years ago in Rhino 3 and 4 :smiley: In between I did not use it at all.
I have created bounding box which looks perfectly fit on plane I have wanted. But when I am transforming it, the bounding box is changing it’s shape.
I wanted to create the minimum sized bounding box , which is created at zero, zero xy plane. Then when I transform back to the object orientation plane, the bounding box change shape. I want a bounding box, which is minimum is size and on the position on object orientation plane, not on origin(0,0,0) xy plane.
here object orientation plane is pln_c.

using System;
using System.Collections.Generic;

using Grasshopper.Kernel;
using Rhino.Geometry;

// In order to load the result of this wizard, you will also need to
// add the output bin/ folder of this project to the list of loaded
// folder in Grasshopper.
// You can use the _GrasshopperDeveloperSettings Rhino command for that.

namespace PLANNER_BEAM_BOUNDING_BOX_GH6
{
    public class PLANNER_BEAM_BOUNDING_BOX_GH6Component : GH_Component
    {
       public PLANNER_BEAM_BOUNDING_BOX_GH6Component()
          : base("PLANNER_BEAM_BOUNDING_BOX_GH6", "PLANNER_BEAM_BOUNDING_BOX_GH6",
              "PLANNER_BEAM_BOUNDING_BOX_GH6",
              "Taiyuan_Domes", "SEAM_STUDY")
        {
        }
        protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
        {
            pManager.AddCurveParameter("Curves_PLANNER_BEAM", "Curves_PLANNER_BEAM", "Curves_PLANNER_BEAM", GH_ParamAccess.list);
            pManager.AddBrepParameter("Breps_beams", "Breps_beams", "Breps_beams", GH_ParamAccess.list);
            pManager.AddSurfaceParameter("DOME_SURFACE", "DOME_SURFACE", "DOME_SURFACE", GH_ParamAccess.item);
        }
        protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
        {
            pManager.AddBrepParameter("Bounding_boxes_for_beams", "Bounding_boxes_for_beams", "Bounding_boxes_for_beams", GH_ParamAccess.list);
        }
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List<Curve> _crv_list_ = new List<Curve>();
            List<Brep> _brp_list_ = new List<Brep>();
            List<Brep> _brp_list_bbox = new List<Brep>();
            if (!DA.GetDataList(0, _crv_list_)) return;
            if (_crv_list_.Count < 1)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "count curve must have a value of 1 or higher");
                return;
            }
            //------------------------------------------------------------//
            if (!DA.GetDataList(1, _brp_list_)) return;

            if (_brp_list_.Count < 1)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "count curve must have a value of 1 or higher");
                return;
            }
            Surface srf = null;
            if (!DA.GetData("DOME_SURFACE", ref srf)) return;
            //-------------------------------------------------------------//
            for (int i= 0;i< _crv_list_.Count;i++ )
            {
                double t1 = 0.0;
                double t2 = 0.0;
                //---------------------------------------------------------//
                srf.ClosestPoint(_crv_list_[i].PointAtEnd, out t1, out t2);
                Vector3d normal_srf = new Vector3d();
                normal_srf = srf.NormalAt(t1, t2);
                Vector3d crv_dr = new Vector3d((Vector3d)_crv_list_[i].PointAtStart - (Vector3d)_crv_list_[i].PointAtEnd);
                Vector3d crv_dr_cross = new Vector3d();
                crv_dr_cross = Vector3d.CrossProduct(normal_srf, crv_dr);
                Plane pln_c = new Plane(_crv_list_[i].PointAtEnd, crv_dr, crv_dr_cross);
                BoundingBox bbox = new BoundingBox();
                bbox= _brp_list_[i].GetBoundingBox(pln_c);
                bbox.Transform(Transform.PlaneToPlane(Plane.WorldXY, pln_c));
                //----------------------------------------------------------//
                _brp_list_bbox.Add(bbox.ToBrep());
             }
                DA.SetDataList(0, _brp_list_bbox);
        }
        //-------------------------------------------------------------//
        protected override System.Drawing.Bitmap Icon
        {
            get
            {
                // You can add image files to your project resources and access them like this:
                return Properties.Resources.BBOX_ICON_icon;
                //return null;
            }
        }
        //-------------------------------------------------------------//
        public override Guid ComponentGuid
        {
            get { return new Guid("261ae48e-5d5a-4e6a-a271-0db3c683b1a6"); }
        }
    }
}

(David Rutten) #2

You can surround code by triple ticks to make discourse treat it as a single block:

```
Code csharpCode = someCode;
```

results in:

Code csharpCode = someCode;

You don’t have to mess with the indentation this way.


(David Rutten) #3

(I’m looking at your code, these are just quick comments).

You do not have to construct variables right before assigning them. First of all Vector3d is a struct, so using the default constructor is exactly the same as not using any constructor, i.e.:

Vector3d normal;
Vector3d normal = new Vector3d();

both do the same thing. But since you immediately assign a value to that variable you definitely don’t need a constructor first. You can just merge those two statements into:

Vector3d normal = srf.NormalAt(t1, t2);

(David Rutten) #4

This is the real problem though:

box.Transform(Transform.PlaneToPlane(Plane.WorldXY, plane));

BoundingBox is defined by the front-lower-left and back-upper-right corner. BoundingBoxes are always axis aligned. So when you transform them you end up with another axis aligned bounding box which contains the eight corners of the input box.

I haven’t run this (it’s getting a bit late here), but I think this is roughly what you are after. Note that you do not need Breps, you can store data directly as Boxes.

protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
{
  pManager.AddBoxParameter("Bounding_boxes_for_beams", "Bounding_boxes_for_beams", "Bounding_boxes_for_beams", GH_ParamAccess.list);
}
protected override void SolveInstance(IGH_DataAccess DA)
{
  List<Curve> curves = new List<Curve>();
  List<Brep> breps = new List<Brep>();
  List<Box> boxes = new List<Box>();
  if (!DA.GetDataList(0, curves)) return;
  if (curves.Count == 0)
  {
    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "At least a single curve is required.");
    return;
  }

  if (!DA.GetDataList(1, breps)) return;
  if (breps.Count == 0)
  {
    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "At least a single brep is required.");
    return;
  }

  for (int i = 0; i < curves.Count; i++)
  {
    Curve curve = curves[i];
    var span = curve.PointAtStart - curve.PointAtEnd;
    var plane = new Plane(curves[i].PointAtEnd, span);
    var bbox = breps[i].GetBoundingBox(plane);
    var box = new Box(bbox);

    box.Transform(Transform.PlaneToPlane(Plane.WorldXY, plane));
    boxes.Add(box);
  }
  DA.SetDataList(0, boxes);
}

You don’t need the surface as far as I can tell, but maybe I misunderstood the exact nature of your bounding box orientations.


#5

Hi David,
Thanks for the reply.
When I am at middle of a code, it looks bit of mess. after 10 years of c# dotnet, I am aware of that, what you wrote .
After all I am a human, not a monkey and I can learn. I clean code later specially when I am disturbed with other things.

For example, I avoid using word “var” at any cost. It make me crazy, when the code is too big.
I never use “var” and “var” is so annoying.
I was only not able to orient the bounding box correctly.

Thanks for the reply.