Table of Contents
Determine the Maximum Z Coordinate Value of a Surface
C++, .NET
The following sample code demonstrates how determine the maximum Z coordinate value of a surface or polysurface given some X,Y coordinate.
C++
CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context ) { double x = 0.0, y = 0.0; ON_wString sx, sy, sz; // Pick a brep to evaluate CRhinoGetObject go; go.SetCommandPrompt( L"Select surface or polysurface to evaluate" ); go.SetGeometryFilter( CRhinoGetObject::surface_object|CRhinoGetObject::polysrf_object ); go.GetObjects( 1, 1 ); if( go.CommandResult() != success ) return go.CommandResult(); // Get the brep geometry const CRhinoObjRef& ref = go.Object(0); const ON_Brep* brep = ref.Brep(); if( !brep ) return failure; // Prompt for an X coordinate value CRhinoGetNumber gn; gn.SetCommandPrompt( L"Value of X coordinate" ); gn.SetDefaultNumber( x ); gn.GetNumber(); if( gn.CommandResult() != success ) return gn.CommandResult(); x = gn.Number(); RhinoFormatNumber( x, sx ); // Prompt for a Y coordinate value gn.SetCommandPrompt( L"Value of Y coordinate" ); gn.SetDefaultNumber( y ); gn.GetNumber(); if( gn.CommandResult() != success ) return gn.CommandResult(); y = gn.Number(); RhinoFormatNumber( y, sy ); // Now that we have all of the input, we want to intersect // a line curve with the brep. To determine the magnitude of // the line, we will first get the brep's bounding box. ON_BoundingBox bbox; if( !brep->GetTightBoundingBox(bbox) ) return failure; // Calculate the height of the bounding box ON_3dVector v = bbox.Corner(0,0,1) - bbox.Corner(0,0,0); // Starting point of line ON_3dPoint p0( x, y, 0.0 ); // Ending point of line. To make sure the line // completely intersects the brep, we will double // the height. ON_3dPoint p1( x, y, v.Length() * 2 ); // Create the line curve ON_LineCurve line( p0, p1 ); // Intersect the line with the brep ON_SimpleArray<ON_Curve*> curves; ON_3dPointArray points; bool rc = RhinoCurveBrepIntersect( line, *brep, context.m_doc.AbsoluteTolerance(), curves, points ); if( false == rc | 0 == points.Count() ) { RhinoApp().Print( L"No maximum surface Z coordinate at %s,%s found.\n", sx, sy ); return nothing; } // Because it is possible that our line might intersect // the brep in more than one place, find the intersection // point that is farthest from our input coordinate. int i; ON_3dPoint pt = p0; for( i = 0; i < points.Count(); i++ ) { if( p0.DistanceTo(points[i]) > p0.DistanceTo(pt) ) pt = points[i]; } // Print results RhinoFormatNumber( pt.z, sz ); RhinoApp().Print( L"Maximum surface Z coordinate at %s,%s is %s.\n", sx, sy, sz ); // Optional, add a point object context.m_doc.AddPointObject( pt ); // Delete any overlap intersection curves that might have been calculated for( i = 0; i < curves.Count(); i++ ) { delete curves[i]; curves[i] = 0; } context.m_doc.Redraw(); return success; }
C#
public override IRhinoCommand.result RunCommand(IRhinoCommandContext context) { // Pick a brep to evaluate MRhinoGetObject go = new MRhinoGetObject(); go.SetCommandPrompt( "Select surface or polysurface to evaluate" ); go.SetGeometryFilter( IRhinoGetObject.GEOMETRY_TYPE_FILTER.surface_object | IRhinoGetObject.GEOMETRY_TYPE_FILTER.polysrf_object ); go.GetObjects( 1, 1 ); if( go.CommandResult() != IRhinoCommand.result.success ) return go.CommandResult(); // Get the brep geometry IRhinoObjRef objref = go.Object(0); IOnBrep brep = objref.Brep(); if( brep == null ) return IRhinoCommand.result.failure; double x = 0.0, y = 0.0; // Prompt for an X coordinate value MRhinoGetNumber gn = new MRhinoGetNumber(); gn.SetCommandPrompt( "Value of X coordinate" ); gn.SetDefaultNumber( x ); gn.GetNumber(); if( gn.CommandResult() != IRhinoCommand.result.success ) return gn.CommandResult(); x = gn.Number(); string sx = ; RhUtil.RhinoFormatNumber( x, ref sx); // Prompt for a Y coordinate value gn.SetCommandPrompt( "Value of Y coordinate" ); gn.SetDefaultNumber( y ); gn.GetNumber(); if( gn.CommandResult() != IRhinoCommand.result.success ) return gn.CommandResult(); y = gn.Number(); string sy = ; RhUtil.RhinoFormatNumber( y, ref sy ); // Now that we have all of the input, we want to intersect // a line curve with the brep. To determine the magnitude of // the line, we will first get the brep's bounding box. OnBoundingBox bbox = new OnBoundingBox(); if( !brep.GetTightBoundingBox( ref bbox) ) return IRhinoCommand.result.failure; // Calculate the height of the bounding box On3dVector v = bbox.Corner(0,0,1) - bbox.Corner(0,0,0); // Starting point of line On3dPoint p0 = new On3dPoint( x, y, 0.0 ); // Ending point of line. To make sure the line completely // intersects the brep, we will double the height. On3dPoint p1 = new On3dPoint( x, y, v.Length() * 2 ); // Create the line curve OnLineCurve line = new OnLineCurve( p0, p1 ); // Intersect the line with the brep OnCurve[] curves = null; On3dPointArray points = null; bool rc = RhUtil.RhinoCurveBrepIntersect( line, brep, context.m_doc.AbsoluteTolerance(), out curves, out points); if( false == rc | points == null | points.Count() == 0 ) { string msg = string.Format("No maximum surface Z coordinate at {0},{1} found.\n", sx, sy ); RhUtil.RhinoApp().Print( msg ); return IRhinoCommand.result.nothing; } // Because it is possible that our line might intersect // the brep in more than one place, find the intersection // point that is farthest from our input coordinate. On3dPoint pt = new On3dPoint(p0); for( int i = 0; i < points.Count(); i++ ) { On3dPoint testPt = points[i]; if( p0.DistanceTo(testPt) > p0.DistanceTo(pt) ) pt.Set(testPt.x, testPt.y, testPt.z ); } // Print results string sz = ; RhUtil.RhinoFormatNumber( pt.z, ref sz ); string msg2 = string.Format("Maximum surface Z coordinate at {0},{1} is {2}.\n", sx, sy, sz); RhUtil.RhinoApp().Print( msg2 ); // Optional, add a point object context.m_doc.AddPointObject( pt ); context.m_doc.Redraw(); return IRhinoCommand.result.success; }
VB.NET
Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) _ As RMA.Rhino.IRhinoCommand.result ' Pick a brep to evaluate Dim go As New MRhinoGetObject() go.SetCommandPrompt("Select surface or polysurface to evaluate") go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.surface_object Or _ IRhinoGetObject.GEOMETRY_TYPE_FILTER.polysrf_object) go.GetObjects(1, 1) If (go.CommandResult() <> IRhinoCommand.result.success) Then Return go.CommandResult() End If ' Get the brep geometry Dim objref As IRhinoObjRef = go.Object(0) Dim brep As IOnBrep = objref.Brep() If (brep Is Nothing) Then Return IRhinoCommand.result.failure End If Dim x As Double = 0.0, y As Double = 0.0 ' Prompt for an X coordinate value Dim gn As New MRhinoGetNumber() gn.SetCommandPrompt("Value of X coordinate") gn.SetDefaultNumber(x) gn.GetNumber() If (gn.CommandResult() <> IRhinoCommand.result.success) Then Return gn.CommandResult() End If x = gn.Number() Dim sx As String = RhUtil.RhinoFormatNumber(x, sx) ' Prompt for a Y coordinate value gn.SetCommandPrompt("Value of Y coordinate") gn.SetDefaultNumber(y) gn.GetNumber() If (gn.CommandResult() <> IRhinoCommand.result.success) Then Return gn.CommandResult() End If y = gn.Number() Dim sy As String = RhUtil.RhinoFormatNumber(y, sy) ' Now that we have all of the input, we want to intersect ' a line curve with the brep. To determine the magnitude of ' the line, we will first get the brep's bounding box. Dim bbox As New OnBoundingBox() If (Not brep.GetTightBoundingBox(bbox)) Then Return IRhinoCommand.result.failure End If ' Calculate the height of the bounding box Dim v As On3dVector = bbox.Corner(0, 0, 1) - bbox.Corner(0, 0, 0) ' Starting point of line Dim p0 As New On3dPoint(x, y, 0.0) ' Ending point of line. To make sure the line completely ' intersects the brep, we will double the height. Dim p1 As New On3dPoint(x, y, v.Length() * 2) ' Create the line curve Dim line As New OnLineCurve(p0, p1) ' Intersect the line with the brep Dim curves() As OnCurve = Nothing Dim points As On3dPointArray = Nothing Dim rc As Boolean = RhUtil.RhinoCurveBrepIntersect(line, brep, _ context.m_doc.AbsoluteTolerance(), curves, points) If (False = rc OrElse points Is Nothing OrElse points.Count() = 0) Then Dim msg As String = String.Format("No maximum surface Z coordinate at {0},{1} found.\n", sx, sy) RhUtil.RhinoApp().Print(msg) Return IRhinoCommand.result.nothing End If ' Because it is possible that our line might intersect ' the brep in more than one place, find the intersection ' point that is farthest from our input coordinate. Dim pt As New On3dPoint(p0) For i As Integer = 0 To points.Count - 1 Dim testPt As On3dPoint = points(i) If (p0.DistanceTo(testPt) > p0.DistanceTo(pt)) Then pt.Set(testPt.x, testPt.y, testPt.z) End If Next ' Print results Dim sz As String = RhUtil.RhinoFormatNumber(pt.z, sz) Dim msg2 As String = String.Format("Maximum surface Z coordinate at {0},{1} is {2}.\n", sx, sy, sz) RhUtil.RhinoApp().Print(msg2) ' Optional, add a point object context.m_doc.AddPointObject(pt) context.m_doc.Redraw() Return IRhinoCommand.result.success End Function