# C++ Split brep with plane

**URL:** <https://discourse.mcneel.com/t/c-split-brep-with-plane/67070>\
**Category:** Rhino Developer\
**Created:** [July 16, 2018, 8:49pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070 "2018-07-16T20:49:25Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [July 16, 2018, 8:49pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/1 "2018-07-16T20:49:25Z")

</div>

Hi,

What is the method to split brep with plane in C++ sdk?

I found this sample file:

> **[Split Brep](https://developer.rhino3d.com/samples/cpp/split-brep/)**
>
> Demonstrates how to split a brep with another brep using the RhinoSplitBrep function.

But it use other breps for splitting in this function \*cutter is brep:  
RhinoBrepSplit(\*split, \*cutter, tol, pieces)

Is there anything with plane splitting?

---

<div class="post-metadata">

**Author:** ![dale](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/dale/32/685184_2.png) [@dale](https://discourse.mcneel.com/u/dale)\
**Post date:** [July 16, 2018, 9:38pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/2 "2018-07-16T21:38:50Z")

</div>

Hi @,

There is no SDK function that will split a Brep with a plane. If you have a plane, then create a plane surface, get it’s Brep form, and use it as the splitter.

Here is an sample, sans any error checking:

```auto
bool RhBrepSplit(
  const ON_Brep& brep,
  const ON_Plane& plane,
  double width,
  double height,
  double tolerance,
  ON_SimpleArray<ON_Brep*>& pieces,
  bool* bRaisedTol = nullptr
)
{
  ON_Interval d0, d1;
  d0.Set(0.0, width);
  d1.Set(0.0, height);

  ON_PlaneSurface* srf = new ON_PlaneSurface(plane);
  srf->SetExtents(0, d0, true);
  srf->SetExtents(1, d1, true);
  srf->SetDomain(0, d0.Min(), d0.Max());
  srf->SetDomain(1, d1.Min(), d1.Max());

  ON_Brep splitter;
  splitter.Create(srf); // splitter will delete srf...

  return RhinoBrepSplit(brep, splitter, tolerance, pieces, bRaisedTol);
}

```

– Dale

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [July 17, 2018, 8:07am UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/3 "2018-07-17T08:07:48Z")

</div>

Thank you Dale.

Probably the width and the height of plane would be enough of brep bounding box diagonal length?

And could you please explain why in this and many other rhino menthods variables passed to fuction must be “const” ?

---

<div class="post-metadata">

**Author:** ![jesterking](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/jesterking/32/771114_2.png) [@jesterking](https://discourse.mcneel.com/u/jesterking)\
**Post date:** [July 17, 2018, 8:33am UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/4 "2018-07-17T08:33:48Z")

</div>

`const` means non-modifiable. In an API it generally means a promise the passed in object will not undergo any changes

[https://www.cprogramming.com/tutorial/const\_correctness.html](https://www.cprogramming.com/tutorial/const_correctness.html)

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [July 17, 2018, 7:19pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/5 "2018-07-17T19:19:20Z")

</div>

Dear Dale,

Could please tell me what I am missing here when passing variables to RhinoBrepSplitPlane method?

The function returns true, but number of split breps are equal to 0:

```
bool RhinoBrepSplitPlane(
const ON_Brep& brep,
const ON_Plane& plane,
double tolerance,
ON_SimpleArray<ON_Brep*> pieces,
bool* bRaisedTol = nullptr
) {
	auto bbox = brep.BoundingBox();
	double length = bbox.Diagonal().Length();

	ON_Interval d0, d1;
	d0.Set(-length, length);
	d1.Set(-length, length);

	ON_PlaneSurface* srf = new ON_PlaneSurface(plane);
	srf->SetExtents(0,d0,true);
	srf->SetExtents(1, d1, true);
	srf->SetDomain(0,d0.Min(),d0.Max());
	srf->SetDomain(1,d1.Min(),d1.Max());

	ON_Brep splitter;
	splitter.Create(srf);//splitter will delete srf

	return RhinoBrepSplit(brep,splitter,tolerance,pieces,bRaisedTol);

}

CRhinoCommand::result CCommandLearning180704::RunCommand(const CRhinoCommandContext& context)
{

	//Get Geometry
	CRhinoGetObject g;
	g.SetCommandPrompt(L"Select Rectangle");
	g.SetGeometryFilter(CRhinoGetObject::curve_object);
	g.GetObjects(1, 1);

	//Check if it good
	if (g.CommandResult() != CRhinoCommand::success)
		return g.CommandResult();

	//Get first brep out of all breps
	const ON_Curve* curve = g.Object(0).Curve();

	//Check if it is good
	if (curve == 0)
		return CRhinoCommand::failure;

	//Try get Polyline
	ON_SimpleArray< ON_3dPoint > points;
    int n = curve->IsPolyline(&points);

	if (n == 5) {

		//Get plane from 5 points polyline

		//Get Center
		ON_3dPoint basePt(0, 0, 0);
		for (int i = 0; i < n - 1; i++) 
			basePt += points[i];
		basePt /= n - 1;

		//Get xdir and ydir
		ON_3dVector vec0 = points[0] - points[1];
		ON_3dVector vec1 = points[0] - points[n - 2];
		vec0.Unitize();
		vec1.Unitize();

		//Construct plane
		const ON_Plane cutPlane(basePt, vec0, vec1);

		//Get Brep and split it https://developer.rhino3d.com/samples/cpp/split-brep/
		// Pick the brep to split
		CRhinoGetObject go;
		go.SetCommandPrompt(L"Select surface or polysuface to split");
		go.SetGeometryFilter(CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object);
		go.GetObjects(1, 1);
		if (go.CommandResult() != success)
			return go.CommandResult();

		const CRhinoObjRef& split_ref = go.Object(0);

		const CRhinoObject* split_object = split_ref.Object();
		if (!split_object)
			return failure;

		const ON_Brep* split = split_ref.Brep();
		if (!split)
			return failure;

	

		ON_SimpleArray<ON_Brep*> pieces;
		double tol = context.m_doc.AbsoluteTolerance();

		bool flag = RhinoBrepSplitPlane(*split, cutPlane, tol, pieces);//Split method <--------------------

		int i, count = pieces.Count();
		if (count == 0 | count == 1)
		{
			if (count == 1)
				delete pieces[0];
			RhinoApp().Print(L"Nothing %d, %d.\n", count, flag);
			return nothing;
		}

		CRhinoObjectAttributes attrib = split_object->Attributes();
		attrib.m_uuid = ON_nil_uuid;

		const CRhinoObjectVisualAnalysisMode* vam_list = split_object->m_analysis_mode_list;

		for (i = 0; i < count; i++)
		{
			CRhinoBrepObject* brep_object = new CRhinoBrepObject(attrib);
			if (brep_object)
			{
				brep_object->SetBrep(pieces[i]);
				if (context.m_doc.AddObject(brep_object))
					RhinoCopyAnalysisModes(vam_list, brep_object);
				else
					delete brep_object;
			}
		}

		context.m_doc.DeleteObject(split_ref);
		context.m_doc.Redraw();

	}

	
	return CRhinoCommand::success;

	return success;
}
```

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [July 17, 2018, 8:23pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/6 "2018-07-17T20:23:00Z")

</div>

Solved.

I typed:

```
bool RhinoBrepSplitPlane(
const ON_Brep& brep,
const ON_Plane& plane,
double tolerance,
ON_SimpleArray<ON_Brep*> pieces,
bool* bRaisedTol = nullptr
) {

```

Instead of

```
bool RhinoBrepSplitPlane(
const ON_Brep& brep,
const ON_Plane& plane,
double tolerance,
ON_SimpleArray<ON_Brep*>& pieces,
bool* bRaisedTol = nullptr
) {

```

So it was not modifying brep by reference.

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [July 18, 2018, 1:20pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/7 "2018-07-18T13:20:53Z")

</div>

Dear Dale,

I was playing with this brep split function:

> <https://github.com/petrasvestartas/CPP_Rhino/blob/master/cmdLearning180704.cpp>

I would like to ask if it is possible to achieve something as interactive with rhino as this mirror cut script in maya.  
I basically want to move rectangle around and execute brep split method interactively (while moving rectangle)  
Instead of ctrl+z and repeating the command.  
Any reference you could give or describe how this kind of interactive workflow could be made?

I also tried to turn record history on, but it did not work.

---

<div class="post-metadata">

**Author:** ![dale](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/dale/32/685184_2.png) [@dale](https://discourse.mcneel.com/u/dale)\
**Post date:** [July 18, 2018, 5:06pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/8 "2018-07-18T17:06:52Z")

</div>

Hi @Petras_Vestartas,

I watched the video, admittedly not that closely. It looks like the script just mirrors meshes. Perhaps I am confused.

If you use Rhino’s build-in gumball, it might not take too much to put a similar tool together. I you plan on using a custom gumball, it would take more work, obviously.

Also, if you want to support history, you need to modify your command to record it. The samples repo has a couple of history-supporting command samples. Here is one.

[https://github.com/mcneel/rhino-developer-samples/blob/6/cpp/SampleCommands/cmdSampleHistoryDivide.cpp](https://github.com/mcneel/rhino-developer-samples/blob/6/cpp/SampleCommands/cmdSampleHistoryDivide.cpp)

– Dale

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [July 18, 2018, 6:11pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/9 "2018-07-18T18:11:52Z")

</div>

Dear @dale,

Yes it is nothing more than splitting geometry and mirroring it.

The most complicated part it seems the UI, epsecially when you mention using Rhino Gumball.  
Is the any guide for this sort of live update using Gumball?

---

<div class="post-metadata">

**Author:** ![dale](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/dale/32/685184_2.png) [@dale](https://discourse.mcneel.com/u/dale)\
**Post date:** [July 23, 2018, 9:53pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/10 "2018-07-23T21:53:25Z")

</div>

Hi @Petras_Vestartas,

There are a couple of SDK samples that use the gumball.

[https://github.com/mcneel/rhino-developer-samples](https://github.com/mcneel/rhino-developer-samples)

– Dale

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [July 24, 2018, 4:50pm UTC](https://discourse.mcneel.com/t/c-split-brep-with-plane/67070/11 "2018-07-24T16:50:58Z")

</div>

Thank you Dale
