How to improve efficiency about split surface by curves?


#1

Dear all,

I want to split surface by curves.


I using RhinoSplitBrepFace() to split.
It cost about 10 min.
I using “Split” command to split the same model.
It only cost about 5 sec.
How can I improve efficiency?

The model in the 3dm file.
SplitSrfTest.3dm (578.2 KB)

Kind regards,
Vaker


(Menno Deij - van Rijswijk) #2

The splitting performance, I think, is largely determined by the tolerance used. Are you sure you are using the same tolerance in both cases?


#3

My code:

The FaceCount = 1 (only one surface to split)
dTol only one value to call function of RhinoSplitBrepFace() one times.


(Menno Deij - van Rijswijk) #4

I’m sorry, I think my message is unclear.

The value of dTol - is it the same as the value of the model absolute tolerance when you run the Split command? If dTol << document tolerance (more strict), the split operation takes longer.


#5

dTol is same as the value of the model absolute tolerance (1e-4)

double dTol = RhinoApp().ActiveDoc()->AbsoluteTolerance();

#6

The sample code:

	CRhinoGetObject get1;
	get1.SetCommandPrompt(_T("Select surface to trim"));
	get1.SetGeometryFilter(CRhinoGetObject::surface_object);

	CRhinoGet::result rc1 = get1.GetObjects(1, 1);
	if (rc1 == CRhinoGetObject::cancel)
		return result::failure;
	if (get1.ObjectCount() == 0)
		return result::failure;

	CRhinoObjRef ObjRefSrf = get1.Object(0);
	const ON_Brep* pBrep = ObjRefSrf.Brep();

	CRhinoGetObject get2;
	get2.SetCommandPrompt(_T("Select curves to trim"));
	get2.SetGeometryFilter(CRhinoGetObject::curve_object);

	CRhinoGet::result rc2 = get2.GetObjects(1, 0);
	if (rc2 == CRhinoGetObject::cancel)
		return result::failure;
	if (get2.ObjectCount() == 0)
		return result::failure;

	ON_SimpleArray<const ON_Curve*> ArrCrvs;
	for (int index = 0; index<get2.ObjectCount(); index++)
	{
		CRhinoObjRef ObjRef = get2.Object(index);
		if (const ON_Curve* pCrv = ON_Curve::Cast(ObjRef.Geometry()))
		{
			ArrCrvs.Append(pCrv);
		}
	}

	::OutputDebugString(_T("Moldex3D-Mesh:: RhinoSplitBrepFace start"));

	ON_Brep* pOutBrep = NULL;
	double dTol = 1e-4;
	pOutBrep = RhinoSplitBrepFace(*pBrep, 0, ArrCrvs, dTol);

	::OutputDebugString(_T("Moldex3D-Mesh:: RhinoSplitBrepFace end"));

	if (pOutBrep == NULL)
		return result::failure;

	return CRhinoCommand::success;

Why RhinoSplitBrepFace() takes so long?


(Chuck Welsh) #7

I ran your code on your file and it took pretty much exactly the same amount of time as the Rhino Split command. About 25 sec in a debug build. I was using the V6 WIP. Were you doing this in V5?


#8

Yes, I was using Rhino 5.


(Chuck Welsh) #9

I seem to remember a problem in V5 like this that was fixed in the past year or so. I don’t remember whether the fix made it into the V5 code, though. I don’t have V5 code on this computer but will check as soon as I can get on a machine with V5.

@dale I’m not sure I can do this in the next couple days. If you get to this before I do, I think the problem was that CPA.SplitAtIntersections( *srf, tolerance ); was inside the for loop rather than outside in RhinoSplitBrepFace()


(Dale Fugier) #10

@chuck, yes this fix is in the Rhino WIP and not Rhino 5. @Vaker, have you tried your code in the Rhino WIP?

– Dale


#11

Hi Dale,

The feature is only in Rhino5.
Have any other solution to fix the problem (or pass around) in Rhino5?
Why the “Split” command has no performance problem in Rhino5?
Can I using the functions or procedures (used in “Split” command) to fix performance problem in Rhino5?
Thanks for your help.


(Dale Fugier) #12

Sorry, no, I don’t have any workarounds in V5.

Perhaps the Split command is not using RhinoSplitBrepFace

We are no longer working on Rhino 5. This is why I was hoping you’d try the Rhino WIP…


#13

The functions used in “Split” command are not in Rhin5SDK.
So I can’t call the functions like “Split” command.
Is that right?


(Dale Fugier) #14

Hi Vaker,

Have you tried trimming the plane just using ON_Brep::NewPlanarFaceLoop?

– Dale


#15

Hi Dale,

I used ON_Brep::NewPlanarFaceLoop() but nothing happened.

	ON_Plane Plane(ON_3dPoint(0.0,0.0,0.0), ON_3dVector(0.0,0.0,1.0));
	ON_PlaneSurface BasePlane(Plane);
	ON_Interval XAxis(90,115);
	ON_Interval YAxis(-3, 19);
	BasePlane.SetExtents(0, XAxis);
	BasePlane.SetExtents(1, YAxis);
	ON_Brep* pBrepCopy = BasePlane.BrepForm();

	if (pBrepCopy->NewPlanarFaceLoop(0, ON_BrepLoop::unknown, AddArrCrvs, false) == false)
		::OutputDebugString(_T("Moldex3D-Mesh:: NewPlanarFaceLoop failed"));

	::OutputDebugString(_T("Moldex3D-Mesh:: RhinoSplitBrepFace end"));

	CRhinoObjectManager OM;
	int iLayerIndex = OM.GetLayerIndex(_T("TrimSrf"));
	OM.AddOneBrepObject(*pBrepCopy, iLayerIndex);

There is nothing in “TrimSrf” layer.
I tried ON_BrepLoop::unknown、ON_BrepLoop::inner
Why?


(Dale Fugier) #16

With the sample model you originally posted, can you provide me a model of what you are looking to achieve. Some of the model’s curve are not closed, so its not clear to me what you want or expect…

– Dale


(Dale Fugier) #17

If you have a planer surface and you want to quickly punch a bunch of holes in it, then ON_Brep::NewPlanarFaceLoop can be quite useful. If the ‘hole’ curve are closed then you will need to add them one at a time.

I’ve attached a sample for you to review.

cmdTestVaker.cpp (3.0 KB)

– Dale


#18

Hi Dale,

Thanks for your sample code.
It works.
I want to split complex case(not only single closed loop).
ON_Brep::NewPlanarFaceLoop can not split complex case.
I will try running “Split” command by scrip.