Boundingbox of ON_Brep after RhinoBooleanDifference


#1

After i make a boolean difference with the function RhinoBooleanDifference the boundingbox does not update and returns a wrong size.

i made a small example:

	ON_Brep* sphere1 = ON_BrepSphere(ON_Sphere(ON_3dPoint(0, 0, 0), 10));
	ON_Brep* sphere2 = ON_BrepSphere(ON_Sphere(ON_3dPoint(0, 0, 5), 10));

	ON_SimpleArray<const ON_Brep*> inBreps1, inBreps2;
	inBreps1.Append(sphere1);
	inBreps2.Append(sphere2);

	bool bResult = false;
	ON_SimpleArray<ON_Brep*> outBreps;
	ON_SimpleArray<int> inputIndexForOutput;
	BOOL ret = RhinoBooleanDifference(inBreps1, inBreps2, 0.002, &bResult, outBreps, inputIndexForOutput);


	ON_BoundingBox bbSphere1, bbSphere2, bbBoolean;
	sphere1->GetBoundingBox(bbSphere1);
	sphere2->GetBoundingBox(bbSphere2);
	outBreps[0]->GetBoundingBox(bbBoolean);

	ON_wString dump;
	ON_TextLog textLog(dump);
	bbSphere1.Dump(textLog);
	bbSphere2.Dump(textLog);
	bbBoolean.Dump(textLog);
	RhinoPrint(CString(dump));

	RhinoApp().ActiveDoc()->AddBrepObject(*sphere1);
	RhinoApp().ActiveDoc()->AddBrepObject(*sphere2);
	RhinoApp().ActiveDoc()->AddBrepObject(*outBreps[0]);

The output in the command line window is as follow:
Bounding box: -10 to 10, -10 to 10, -10 to 10
Bounding box: -10 to 10, -10 to 10, -5 to 15
Bounding box: -10 to 10, -10 to 10, -10 to 15

As you can see, the bounding box of the resulting brep is in z direction -10 to 15, which is definitely not right! The result in 3D looks as expected. (I moved the 2 spheres afterwards to see the result, which is the red geometry)

Do you have any advise to get the right bounding box after the boolean difference?


(Menno Deij - van Rijswijk) #2

I think you want to use GetTightBoundingBox instead. It looks like GetBoundingBox only returns the bounding box of the constituent surfaces’ controlpoints, as you can see.


#3

Sorry, same behavior!
At least in my environment Rhino5 SR12, SDK SR9.


(Menno Deij - van Rijswijk) #4

Oh… Well, you could, in this specific case, maybe call bool ShrinkSurface( ON_BrepFace& face, int DisableSide=0) on the Brep. But it is not a general solution.

Also, I seem to recall that GetTightBoundingBox is calculated based on the (render?) mesh of the Brep if it is present. It may also be worthwile to see if calling const ON_Mesh* Mesh( ON::mesh_type mesh_type ) with one of the mesh types improves the behavior of GetTightBoundingBox, as it should create a mesh and store it with the Brep object.

The mesh types are below, but I don’t know which type should be used.

  {
    default_mesh  = 0,
    render_mesh   = 1,
    analysis_mesh = 2,
    preview_mesh  = 3,
    any_mesh      = 4
  };```

(Dale Fugier) #5

Hi Wolfgang,

Bounding box values are lazily calculated. That is, they are not calculated until they are needed, and then they are cached on the object so they can be retrieved quickly.

For a CRhinoBrepObject, the tight bounding box is based on the object display (render) mesh. If you needed the tight bounding box for any Rhino object, use RhinoGetTightBoundingBox as this function will automatically create the display mesh if needed.

For ON_Brep, a bounding box is never calculated until it is added to the document. Thus, if you need a tight bounding box, then you will need to calculate it on your own.

Here is how you can calculate the tight bounding box for any ON_Brep:

ON_Brep* brep = CreateMyBrep();

const ON_MeshParameters& mp = context.m_doc.Properties().RenderMeshParameters();
ON_SimpleArray<ON_Mesh*> meshes(brep->m_F.Count());
const int mesh_count = brep->CreateMesh(mp, meshes );

ON_BoundingBox bbox;
if (0 != mesh_count)
{
  for (int i = 0; i < mesh_count; i++)
  {
    if (0 != meshes[i]) 
    {
      bbox.Union(meshes[i]->BoundingBox());
      delete meshes[i]; // Don't leak...
    }
  }
}
else
{
  brep->GetTightBoundingBox(bbBoolean);
}

Does this help?

– Dale


#6

Hi Dale,

my first thought was, that’s crazy!! I’m shocked!
There is no hint in the documentation that the bounding box is absolute useless.
To cache the bounding box information or to calculate it on demand is a good thing, but to give back an invalid result is nothing i would like to have. I think that’s something like the “dirty cow” in rhino - everyone knows it but no one solves it!


(Menno Deij - van Rijswijk) #7

Welcome to the wonderful world of programming for Rhino :rolling_eyes:


(Dale Fugier) #8

That’s a new one for me. :wink:

But I agree that we need a better way of doing this.

https://mcneel.myjetbrains.com/youtrack/issue/RH-36015

– Dale


#9

Hi Dale,

i compared this issue with the linux kernel exploit CVE-2016-5195 aka “dirty cow”. Even if its not compareable :wink:


(Brian Gillespie) #10

RH-36015 is fixed in the latest WIP