Sectioning/Contour through a Large Object File

Hello There,

At work we use a batch operation that calls a rhino script (rhino 6) to generate daily 2D sections out of 3D models.
In general the script works very good for reletively normal size files, taking max 30min to section a file with abt. 100Mb continaing only surfaces. However, one of the Models consists in importing all the files from a certain folder containing all kinds of geometry (generally dwg files containing equipment objects, engines, doors, hinges, etc…).
After importing operation is finished i end up with a file size of 1.5GB. and the procedure to section all these objects takes about 8h.
I have included in the code a sub routine to remove all non Surfaces/polysurfaces from the array of objects to be sectioned, but that didnt seem to improve anything.
Any clues, ideas, suggestions how to speed up this operation?
Many thanks in advance

Have you done some profiling pinpointing where the processing spends most of its time?

Is the processing run in parallel (this kind of work usually is suitable for threading).

Using traditional spinning disks? How much available memory (due to the huge file size, is the process swapping to disk?). Using NVme SSD disks for file processing helps a lot.

Aso. Finding bottle necks takes actuall testing/analyze of the code. Guesswork will (almost) always make you disappointed.

// Rolf

I don’t know how many sections you generate nor what you are actually doing with them, but that still seems very long if you are just using the standard Section or Contour commands.

For example I can generate 30 contours here through a 600Mb file in under 30 seconds. The file itself is composed of 797 curves, 3062 surfaces, 1973 polysurfaces, 11815 extrusions, 36 meshes…

Thank you for your feedback.
I actually haven’t got the opportunity the trace the resources the process is using just yet, as i leave it running through the night. I think the computer has normal rotating HD. I will post the code asap.

Could you please explain what you mean by: << Is the processing run in parallel (this kind of work usually is suitable for threading). >>

Thank you very much for your reply.

The no. of sections/contours varies (locations are stored in an excel worksheet) but it is around 120 in X direction, 60 in Y direction and about 50 in Z direction. It seems rather fast, considering that models are working surface models (ship hull, internal structure & compartments, etc). and 30min is more than acceptable for this case.

in brief, the Script;
All *.dwg files in folder XX are imported into an untitled *.3dm file (file A) ;
after importing is completed, the method “Rhino.AddSrfSectionCrvs (strObject, arrPlane)” is called. where strObject is an array of all Surface/Polysurface objects in the file A.
Each resulting crv is then given a name based on the arrPlane which created that crv.
Every contour/Sections (set of crvs with same name) is then exported to individual files depending on its X,Y,Z plane.
file A is closed without saving.
I will Post the full code ASAP.

OK, I expect that most of the time is spent reading the files to import and writing the files to export - that stuff is way slower in general than internal calculations such as sections.


Importing all files takes no more than 1h. Whereas Exporting the sections to individual files takes less than 1min once all objects have been intersected and the curves created. The operation is taking its 90% of its time intersecting/contouring/sectioning the objects in the file.

This is the part of the code which is taking a lot of time
’ ------------------FRAMES -----------------------
'This subroutine contours the Selected Surfaces - FRAMES and EXPORTS The resulting curves to INDIVIDUAL FILES per FRAME Identifier
Sub ContourSurfacesFRAMES()

'Variable Declaration
'Dim Fr_i, Fr_n, Intermediate
Dim span, Spacing
Dim i, j
Dim strObject_Approved,strObject_Prelim, arrPlane 
Dim arrSPlane(3)
Dim strFolderName

arrSPlane(0) = Array(0.0, 0.0, 0.0) ' Origin point -> will be redefined under the loop

arrSPlane(1) = Array(1.0, 0.0, 0.0) ' X-axis vector

arrSPlane(2) = Array(0.0, 1.0, 0.0) ' Y-axis vector

arrSPlane(3) = Array(0.0, 0.0, 1.0) ' Z-axis vector

'Puts emphasis in the correspondent view
Rhino.Command "_Plan" 
Rhino.ZoomExtents "LEFT"

'Creates Layers for the current Process/task
Layer01 = Layernaming(ProjectNum, MLWW, "FR-", Layer_str01)
Layer02 = Layernaming(ProjectNum, MLWW, "FR-", Layer_str02)

Rhino.Print "New layer: " & Rhino.AddLayer(Layer01, color_approved)
Rhino.Print "New layer: " & Rhino.AddLayer(Layer02, color_prelim)

'Cylcles throug the number of Frames/Longitudinals 
For i=0 To Ubound(Loc_Frames, 1) - 1 Step 1 
	arrSPlane(0) = Array(Loc_Frames(i, 2), 0.0, 0.0)
	arrPlane = Rhino.PlaneFromNormal(arrSPlane(0), arrSPlane(1))
	If IsArray(ApprovedObjects) Then 'Verifies if the Selection Set of Approvedy Objects contains Data

		Rhino.CurrentLayer(Layer01) 'Sets the current Layer for Approved Objects 
		For Each strObject_Approved In ApprovedObjects 'Cycles through the selection set and calculates the Intersection curves

			Rhino.AddSrfSectionCrvs strObject_Approved, arrPlane
	End If
	If IsArray(PrelimObjects) Then 'Verifies if the Selection Set of Preliminary Objects contains Data

		Rhino.CurrentLayer(Layer02) 'Sets the current Layer for Preliminary Objects 
		For Each strObject_Prelim In PrelimObjects 'Cycles through the selection set and calculates the Intersection curves

			Rhino.AddSrfSectionCrvs strObject_Prelim, arrPlane
	End If


'Add Object Name to recently created entities for easy of selection to export
Call RenameEntities(Layer01)
Call RenameEntities(Layer02)

'Sets current layer to Default

'Prompts the user to get Destination Folder Name 
strFolderName = XrefFolder02 'Rhino.BrowseForFolder("G:\Project\", "Select where to Store Sections.dwg", "RHS: AUTO-COUNTOURS")
If IsNull(strFolderName) Then Exit Sub

'Exports the MAIN Frames to individual files 
For i=0 To Ubound(Loc_Frames, 1) Step 1

	Call Exporttodwg(ProjectNum & MLWW & CStr(Loc_Frames(i, 1)), strFolderName)

End Sub

Note: “Loc_Frames” is a Public variant array defined earlier

After a few tests and twicks on the code i am lead to conclude the method Rhino.AddSrfSectionCrvs has low performance. I can get 3xtimes faster if I use the command contour manually with the same selection set.

Hi, is it redrawing throughout? Can redraw be disabled and does this reduce the time taken?

Hi Graham.

Thank you for the suggestion. I have tried with redraw disabled. its a little faster but not significantly.
The File contains 3hatches, 112curves, 6305Polysrfs. 106 extrusions, 24meshes and 2 linear dims. and Sectioning all objects with contour command manually (equal spacing) takes about 30min, whereas if i use the method in my code above (the array of positions contains unevenly spaced locations) it takes almost 4h…

Hmm and is it checking for intersections on every object at every plane? Is there a way to subdivide the space and is it quicker to check a quarter of the objects 4 times rather than all the objects once?

Yes indeed, every objects is checked for intersections at every plane (thus for a 6435 Objects and 110 Planes…707850 iterations) it is a lot. Your suggestion is very pertinent, I definitely need to include a way to filter the objects by their eligibility to be sectioned at a given plane… I will manually check your suggestion of subdividing the objects by area/zone and see what is the result. Thank you for the insight. will come back with my findings.

I have some good news. Besides disabling redraw, I have included a way to check if an object is eligible to be sectioned at a given plane before running the method Rhino.AddSrfSectionCrvs*. I have done this by using the method - Rhino.IsObjectInBox(Rhino.Allobjects, selectbox, False) - where selectbox is a pre-defined box at given plane XYZ. this has reduced the total computing to LESS THAN AN HOUR :slight_smile: So I thank you all for your valuable insights that ultimately lead me to figure this out.
Best Regards.

1 Like