Sketch Curve as Line Segments in VB.Net and C#

Here’s the VB.Net and C# versions of the VBA program from previous post.  To go from that VBA program to this VB.Net version was fairly easy.  I just copied and pasted the VBA code into a new VB.Net project.  The primary changes that I had to make were primarily to the array declarations.  Another change, although it wasn’t required, was to change the error handling from the On Error style to Try Catch.  I prefer the Try Catch style of error handling. 

The array declaration change is because in .Net declaring an array isn’t enough to  initialize it.  The VBA version of one of the declarations is here:

Dim startCoord() As Double

Here’s the .Net version of the same array.

Dim startCoord() As Double = {}

Here’s the full VB.Net program.  The Inventor Application object is passed in as an argument.  The act of pasting the VBA code into a .Net program automatically removed all of the Set statements because they’re not longer needed in .Net, which is nice.  I also like to enclose arguments to a method within parentheses.  In VBA the parentheses are optional and use have to use the Call statement to have them.  In VB.Net parentheses are required and using a Call statement is optional.  Other than these minor changes, it’s the same code as the original VBA version.

Public Sub CreateSegmentedCurve(ByVal invApp As Inventor.Application)          ' Check to see that a curved sketch entity is selected.              Dim entity As SketchEntity           Try               entity = invApp.ActiveDocument.SelectSet.Item(1)           Catch ex As Exception               MsgBox("A curved sketch entity must be selected.")               Exit Sub           End Try            If TypeOf entity Is SketchPoint Or _         TypeOf entity Is SketchLine Then               MsgBox("A curved sketch entity must be selected.")               Exit Sub           End If            ' Ask for the number of segments to break the curve into.              Dim prompt As String           prompt = "Enter the number of segments for the curve."           Dim segmentCount As Integer           segmentCount = Val(InputBox(prompt, "Number of Segments", "10"))           If segmentCount = 0 Then               MsgBox("Invalid segment count.")               Exit Sub           End If         ' Get the parent sketch.              Dim sk As Sketch = entity.Parent            ' Get the evaluator from the associate geometry.              Dim curveEval As Curve2dEvaluator = entity.Geometry.Evaluator           Dim minU As Double           Dim maxU As Double      curveEval.GetParamExtents(minU, maxU)            ' Determine if the entity is open or closed (circle,              ' ellipse, or closed spline)               Dim curveIsClosed As Boolean = False           If TypeOf entity Is SketchCircle Or _              TypeOf entity Is SketchEllipse Or _              TypeOf entity Is SketchSpline Or _              TypeOf entity Is SketchOffsetSpline Then               If TypeOf entity Is SketchSpline Or _                  TypeOf entity Is SketchOffsetSpline Then                   If entity.Closed Then                       curveIsClosed = True                   End If               Else                   curveIsClosed = True               End If           End If                 Dim tg As TransientGeometry = invApp.TransientGeometry            ' Determine if start point is at the min or max parameter.              Dim startPoint As SketchPoint = Nothing           Dim endPoint As SketchPoint = Nothing           If Not curveIsClosed Then               Dim startCoord() As Double = {}               Dim endCoord() As Double = {}          curveEval.GetEndPoints(startCoord, endCoord)               If entity.StartSketchPoint.Geometry.IsEqualTo( _                 tg.CreatePoint2d(startCoord(0), startCoord(1))) Then                   startPoint = entity.StartSketchPoint                   endPoint = entity.EndSketchPoint               Else                   endPoint = entity.StartSketchPoint                   startPoint = entity.EndSketchPoint               End If           End If            ' Get the curve length.              Dim length As Double      curveEval.GetLengthAtParam(minU, maxU, length)            ' Determine the length between segments.              Dim offset As Double           offset = length / segmentCount            ' Start a transaction to wrap the sketch creation as a              ' single undo operation.               Dim trans As Transaction = Nothing           Try               Dim transMgr As TransactionManager         &#160
;     transMgr = invApp.TransactionManager               trans = transMgr.StartTransaction( _                               invApp.ActiveDocument, "Segment Curve")                ' Defer updates on the sketch while the sketch entities                  ' are being created.  This will significantly improve                   ' performance.                   sk.DeferUpdates = True                ' Calculate the points and create a sketch                  ' point at each position.                   Dim points() As SketchPoint               ReDim points(segmentCount)               Dim currentLength As Double = 0               For i As Integer = 0 To segmentCount                   Dim currentParam As Double              curveEval.GetParamAtLength(minU, currentLength, _                                         currentParam)                   currentLength = currentLength + offset                    Dim params(0) As Double                   params(0) = currentParam                   Dim coords() As Double = {}              curveEval.GetPointAtParam(params, coords)                    If i = 0 Then                       ' Special case for the first point.                          If Not curveIsClosed Then                           points(i) = startPoint                       Else                           points(i) = sk.SketchPoints.Add( _                                  tg.CreatePoint2d(coords(0), coords(1)), _                                  False)                           endPoint = points(i)                       End If                   ElseIf i = segmentCount Then                       ' Special case for the last point                          points(i) = endPoint                   Else                       points(i) = sk.SketchPoints.Add( _                                  tg.CreatePoint2d(coords(0), coords(1)), _                                  False)                   End If               Next                ' Connect the points with lines.                  For i As Integer = 0 To segmentCount - 1              sk.SketchLines.AddByTwoPoints(points(i), points(i + 1))               Next                ' Make the selected entity construction geometry.                  entity.Construction = True                ' There's a current problem that when setting the                   ' construction property, the display isn't updated                   ' to reflect this change until something causes the                   ' sketch to recompute.  This performs a change on                   ' the sketch to kick a recompute.                   Dim originalPoint As Point2d               originalPoint = points(0).Geometry          points(0).MoveTo(tg.CreatePoint2d( _                                       points(0).Geometry.X + 0.001, _                                       points(0).Geometry.Y))          points(0).MoveTo(originalPoint)                ' Turn off the defer to the sketch will recompute normally.                  sk.DeferUpdates = False                trans.End()           Catch ex As Exception               sk.DeferUpdates = False                If Not trans Is Nothing Then                   trans.Abort()               End If                MsgBox("Unexpected error segmenting curve.")           End Try       End Sub

Here’s a C# version o
f the same program.  I’m not going to go into a lot of details now about the differences other than to say that there are several.  I’m working on an upcoming post that will describe the various issues when using C# to program Inventor.  The majority of this code was created using a VB.Net to C# converter, but there were still significant changes that had to be made after that to get it to run.

static void CreateSegmentedCurve(Inventor.Application invApp)      {           // Check to see that a curved sketch entity is selected.              SketchEntity entity = null;           try           {               entity = (SketchEntity) invApp.ActiveDocument.SelectSet[1];           }           catch      {               MessageBox.Show("A curved sketch entity must be selected.");               return;           }            if (entity is SketchPoint | entity is SketchLine)           {               MessageBox.Show("A curved sketch entity must be selected.");               return;           }            // Ask for the number of segments to break the curve into.              string prompt = null;           prompt = "Enter the number of segments for the curve.";           int segmentCount = 0;           segmentCount = (int) Conversion.Val(Interaction.InputBox(prompt,                                    "Number of Segments", "10", 20, 20));           if (segmentCount == 0)           {               MessageBox.Show("Invalid segment count.");               return;           }            // Get the parent sketch.              Sketch sk = entity.Parent;            // Get the geometry associated with the sketch entity.  Since              // the Geometry property will return one of various types of              // objects, we need to use late binding here which C# doesn't              // handle very nicely.               object geom = entity.GetType().InvokeMember("Geometry",                          BindingFlags.GetProperty , null, entity, null);            // Get the curve evaluator from the geometry.                Curve2dEvaluator curveEval =                (Curve2dEvaluator) geom.GetType().InvokeMember("Evaluator",                BindingFlags.GetProperty, null, geom, null);                 // Get the evaluator from the associate geometry.              double minU = 0;           double maxU = 0;           curveEval.GetParamExtents(out minU, out maxU);            // Determine if the entity is open or closed (circle,              // ellipse, or closed spline)               bool curveIsClosed = false;           if (entity is SketchCircle | entity is SketchEllipse |               entity is SketchSpline | entity is SketchOffsetSpline)           {               if (entity is SketchSpline | entity is SketchOffsetSpline)               {                   bool isClosed = (bool) entity.GetType().InvokeMember(                                  "Closed", BindingFlags.GetProperty,                              null, entity, null);                   if (isClosed)                   {                       curveIsClosed = true;                   }               }               else               {                   curveIsClosed = true;               }           }           TransientGeometry tg = invApp.TransientGeometry;            // Determine if start point is at the min or max parameter.              SketchPoint startPoint = null;           SketchPoint endPoint = null;           if (!curveIsClosed)           {               // Get the start and end sketch points from the curve.                  SketchPoint tempStartPoint =                         (SketchPoint) entity.GetType().InvokeMember(                         "StartSketchPoint", BindingFlags.GetProperty,                         null, entity, null);               SketchPoint tempEndPoint =                         (SketchPoint) entity.GetType().InvokeMember(                         "StartSketchPoint", BindingFlags.GetProperty,                         null, entity, null);          // Get the coordinate, as a Point object from                  // the start sketch point.                   Point2d tempStartCoord =                         (Point2d) tempStartPoint.GetType().InvokeMember(                         "Geometry", BindingFlags.GetProperty, null,                         tempStartPoint, null);                double[] startCoord = {};               double[] endCoord = {};               curveEval.GetEndPoints(ref startCoord, ref endCoord);               if (tempStartCoord.IsEqualTo(tg.CreatePoint2d(startCoord[0],                                       startCoord[1]), tg.PointTolerance))               {                   startPoint = tempStartPoint;                   endPoint = tempEndPoint;               }               else               {                   endPoint = tempStartPoint;                   startPoint = tempEndPoint;               }           }            // Get the curve length.              double length = 0;           curveEval.GetLengthAtParam(minU, maxU, out length);            // Determine the length between segments.              double offset = length / segmentCount;            // Start a transaction to wrap the sketch creation as a              // single undo operation.               Transaction trans = null;           try           {               TransactionManager transMgr = null;               transMgr = invApp.TransactionManager;               trans = transMgr.StartTransaction(invApp.ActiveDocument,                                                "Segment Curve");                // Defer updates on the sketch while the sketch entities                  // are being created.  This will significantly improve                   // performance.                   sk.DeferUpdates = true;                // Calculate the points and create a sketch                  // point at each position.                   SketchPoint[] points = new SketchPoint[segmentCount+1];               double currentLength = 0;               for (int i = 0; i

Comments

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading