Jump to content

VBA - 'Splinedit' equivalent?


Recommended Posts

Posted

Hi all,

 

I'm new to VBA in AutoCAD I've played with Inventor VBA a bit, but the API appears to be drastically different.

 

I need to manipulate existing splines on a drawing by joining them together via VBA. To achieve this manually, the user would use the command SPLINEDIT and go from there. What is the equivalent, or how do I access the command in VBA?

 

Any suggestions would be greatly appreciated.

 

Thanks and Regards

Posted

There isn’t much spline related functionality exposed via the ActiveX API in vanilla AutoCAD. I think a “ThisDrawing.SendCommand” targeting SPLINEDIT is the most viable option.

 

AutoLisp, .NET, and ARX are much better equipped for spline manipulation.

Posted

ActiveX? Forgive my ignorance, but I'm using VBA, how is that related to ActiveX API?

 

Either way I had started along the path of "ThisDrawing.SendCommand" expecting that would be the case, but I'm finding it really difficult to call on a selection set that I've defined earlier.

 

I have a selection set (called SSetTemp) and it contains one single spline. How do I call that into the "SendCommand"? Once I've started the "SendCommand" I can't call my VBA object SSetTemp, and I can't figure out how to recall the selection set from command line.

 

Thanks for your help.

Posted

The ActiveX (or COM) is just the name of the interface used to expose various bits of functionality to VBA. The “various bits”, unfortunately, aren’t all that plentiful.

 

 

 

Here was a way to use a SelectOnScreen call. I’m not sure how useful that “Previous” method would be with other (more automated) selection modes.

 

 

 

http://www.cadtutor.net/forum/showthread.php?19349

Posted

Thanks for that. Do you have any reference information regarding splines etc in LISP?

 

The piece of code I'm trying to write, in essence, will combine multiple splines (arranged end to end) into single splines, creating a loop. however there are many loops on the page.

 

My plan was to do something like this:

 

for each spline on thisdoc.modelspace

splinedit.join (All)

next spline

 

(excuse the home made syntax)

 

So, in VBA I can easily do a "for each" but I can't do a splinedit.

In LISP, I don't know how to do a 'for each' or a splinedit.

 

So, If you have info on 'for each' or 'splinedit' in LISP, I'd greatly appreciate it.

Posted

Sadly, it is not that easy in VBA. Lisp has a much better connection with the AutoCAD command line so, conceivably, would make the SPLINEDIT implementation easier. I don’t know enough autolisp to make an attempt, though.

 

Perhaps a post should be made in the AutoLISP, Visual LISP & DCL section to entice one of the guru’s there to take a look.

Posted

No worries.. I'll give the SendCommand another go (just found something that might be useful) then I'll take a look at the LISP threads. Thanks again for your help.

Posted

Okay... Getting warmer... How do I cancel the active command OR (preferably) get the prompt displayed in the command line?

Posted

Do you have any reference information regarding splines etc in LISP?

 

 

 

From AutoCAD open the Visual LISP Integrated Developement Environment using the VLIDE command. Then hit F1 to open the Developer Documentation - two sources:

  • DXF Reference > ENTITIES > SPLINE
  • ActiveX and VBA Reference > Object Model > Document > ModelSpace > Spline

The latter being similar to the VBAIDE's Object Browser.

 

The piece of code I'm trying to write, in essence, will combine multiple splines (arranged end to end) into single splines, creating a loop. however there are many loops on the page.

 

My plan was to do something like this:

 

for each spline on thisdoc.modelspace

splinedit.join (All)

next spline

 

(excuse the home made syntax)

 

So, in VBA I can easily do a "for each" but I can't do a splinedit.

In LISP, I don't know how to do a 'for each' or a splinedit.

 

So, If you have info on 'for each' or 'splinedit' in LISP, I'd greatly appreciate it.

 

Sadly, it is not that easy in VBA. Lisp has a much better connection with the AutoCAD command line so, conceivably, would make the SPLINEDIT implementation easier. I don’t know enough autolisp to make an attempt, though.

 

Perhaps a post should be made in the AutoLISP, Visual LISP & DCL section to entice one of the guru’s there to take a look.

 

Nawww... Occasionally we make house calls. :wink:

(^^ Yeah, right... I'm no Guru, but I think I can help ^^)

 

Perhaps this will help accomplish the task at hand:

 

(defun JoinSplines ( / ss)
 ;; Example function call: (JoinSplines)
 (while (/= nil (setq ss (ssget '((0 . "SPLINE")))))
   (command "._join" (ssname ss 0) ss ""))
 (princ))

 

The problem being that this will only work with a co-located group of splines.

 

More specifically... if one were, for example, to have two groups of splines and you selected all of them, only the group first selected would join (hence the included while loop, which will permit the user to do this task for each co-located group).

 

If you have an alternative example using either VBA, or VB.NET I *might* be able to port it to Auto/Visual LISP for you, as most of my development is done with ActiveX COM API via Visual LISP. I just don't work with Splines enough to know of a better way at the moment.

 

Hope this helps!

Posted
Okay... Getting warmer... How do I cancel the active command OR (preferably) get the prompt displayed in the command line?

 

Not sure how to cancel from VBA :oops:. I would imagine there's an exit, or quit method, no?

 

Sub Prompt(Message As String)

Member of AutoCAD.AcadUtility

Posts a prompt to the command line

Posted

Thanks guys, I greatly appreciate this.

 

Below is the code I've written so far. If you run through for one loop of the FOR loop, it works fine (check the numeral '5' on the attached example.dwg before and after you run the code), but when you run through a second time I get a catastrophic failure at line "SET ADDITEM(0) = SSET (X1)" and I'm not sure why. If you re-run through the first loop again, you'll error immediately after "THISDRAWING.SENDCOMMAND" because the selected spline is a closed loop.

 

Sub JoinSplines()

Dim SSet As AcadSelectionSet
Dim oSSetGroup As AcadGroup
Dim sGRName As String
Dim FilterType(0) As Integer
Dim FilterData(0) As Variant
Dim X1 As Integer
Dim AddItem() As AcadEntity

On Error Resume Next
If ThisDrawing.SelectionSets.Item("SSet") Is Nothing Then
   Set SSet = ThisDrawing.SelectionSets.Add("SSet")
Else
   ThisDrawing.SelectionSets.Item("SSet").Clear
   Set SSet = ThisDrawing.SelectionSets("SSet")
End If

On Error GoTo 0
Err.Clear

FilterType(0) = 0
FilterData(0) = "Spline"

SSet.Select acSelectionSetAll, , , FilterType, FilterData
ReDim AddItem(0) As AcadEntity

For X1 = 1 To SSet.Count
   Set oSSetGroup = ThisDrawing.Groups.Add("SG")
   sGRName = oSSetGroup.Name
   
  [color="red"] ''CATASTROPHIC FAILURE HERE[/color]
   Set AddItem(0) = SSet(X1)
   
   oSSetGroup.AppendItems AddItem
   
   [color="red"]'''NEED TO END ANY, AND ALL EXISTING COMMANDS BEFORE PROCEEDING[/color]
   On Error Resume Next
   ThisDrawing.SendCommand "splinedit" + vbCr + "G" + vbCr + sGRName + vbCr + "J" + vbCr + _
                           "all" + vbCr + vbCr + vbCr
   If Not Err Is Nothing Then
       ThisDrawing.SendCommand "!(command)" & vbCr [color="red"]'''NEED TO END CURRENT COMMAND HERE.[/color]
       Err.Clear
   End If
   On Error GoTo 0
   
   oSSetGroup.Delete
   ReDim AddItem(X1) As AcadEntity
   
Next
End Sub

 

The code sample you posted, RenderMan, works well if the loop contains only splines, but the code I've posted above works for loops containing loops, lines and arcs like the attached file (example.dwg). The code will process text loops like this almost exclusively. Once it's done joining splines, it will join any remaining polylines.

 

Thanks again.

Example.dwg

Posted

AutoCAD 2012 can use the standard JOIN command (i.e., not through SPLINEDIT) to join both splines and non splines into one large composite (See returned sample). So, depending on what the end result needs to be, perhaps this variation on your posted code would do.

I can’t test it myself because my install of AutoCAD 2012 is 64 bit, with which VBA does not play nice.

Sub JoinSplines()
   ' This example adds objects to a selection set by prompting the user
   ' to select ones to add.
   
   ' Create the selection set
   Dim ssetObj As AcadSelectionSet
   On Error Resume Next
   ThisDrawing.SelectionSets.Item("TEST_SSET").Delete
   On Error GoTo 0
   Set ssetObj = ThisDrawing.SelectionSets.Add("TEST_SSET")
   Dim mode As Integer
   Dim pointsArray(0 To 11) As Double
   mode = acSelectionSetCrossingPolygon
  'I just hardcoded a rectangle size to fit.  May want to use extmin and extmax
   pointsArray(0) = 0#: pointsArray(1) = 0#: pointsArray(2) = 0#
   pointsArray(3) = 950#: pointsArray(4) = 0#: pointsArray(5) = 0#
   pointsArray(6) = 950#: pointsArray(7) = 420#: pointsArray( = 0#
   pointsArray(9) = 0#: pointsArray(10) = 420#: pointsArray(11) = 0#
   
   ssetObj.SelectByPolygon mode, pointsArray
   ThisDrawing.SendCommand "JOIN" & vbCr & "Previous" & vbCr & vbCr
   
End Sub

Example_2012.dwg

Posted

Oh damn... that would be helpful... unfortunately we won't be rolling out 2012 here for quite some time (if at all).

 

Either way... I think I got it sorted...

 

Sub JoinSplinesOnDWG()

Dim SSet As AcadSelectionSet
Dim oSSetGroup As AcadGroup
Dim sGRName As String
Dim FilterType(0) As Integer
Dim FilterData(0) As Variant
Dim X1 As Integer
Dim SplCountLive As Integer
Dim AddItem() As AcadEntity
Dim acadDoc As AcadDocument

Set acadDoc = ThisDrawing

On Error Resume Next
If ThisDrawing.SelectionSets.Item("SSet") Is Nothing Then
   Set SSet = ThisDrawing.SelectionSets.Add("SSet")
Else
   ThisDrawing.SelectionSets.Item("SSet").Clear
   Set SSet = ThisDrawing.SelectionSets("SSet")
End If

On Error GoTo 0
Err.Clear

FilterType(0) = 0
FilterData(0) = "Spline"

ReDim AddItem(0) As AcadEntity

SSet.Select acSelectionSetAll, , , FilterType, FilterData
SplCountLive = SSet.Count

X1 = 0
Do Until X1 = SplCountLive
   X1 = X1 + 1
   Set oSSetGroup = ThisDrawing.Groups.Add("SG")

   sGRName = oSSetGroup.Name

   Set AddItem(0) = SSet(X1)
   
   oSSetGroup.AppendItems AddItem
   
   On Error Resume Next
   If AddItem(0).Closed = False Then
       ThisDrawing.SendCommand "splinedit" + vbCr + "G" + vbCr + sGRName + vbCr + "J" + vbCr + _
                               "all" + vbCr + vbCr + vbCr
   End If
   If Not Err = 0 Then
       ThisDrawing.SendCommand "!(command)" & vbCr
       Err.Clear
   End If
   On Error GoTo 0
   
   oSSetGroup.Delete
   SSet.Clear
   SSet.Select acSelectionSetAll, , , FilterType, FilterData
   SplCountLive = SSet.Count
Loop
End Sub

 

 

Next question... I found a good site yesterday explaining how to use multiple filters in your selection sets... But I can't find it again...

 

Here's what I've got...

 

 

Dim FilterType(1) As Integer
Dim FilterData(1) As Variant

FilterType(0) = 0
FilterData(0) = "Arc"
FilterType(1) = 0
FilterData(1) = "Line"

SSet.Select acSelectionSetAll, , , FilterType, FilterData

 

Unfortunately, this returns 0 items... but if I run either filter type separately, then I get plenty of objects returned...

 

What have I missed?

Posted

For that particular data type items can be strung together. Does this work any different:

 

Dim FilterType(0) As Integer
Dim FilterData(0) As Variant
FilterType(0) = 0
FilterData(0) = "Arc,Line"

SSet.Select acSelectionSetAll, , , FilterType, FilterData

Posted

Oh damn... that simple... I'll have to give that a shot tomorrow at work.

 

I got the method mentioned on that kxcad.net website to work.. so it's all good... now when I run both bits of code, it joins all splines together, then all lines and arcs together as polylines...

 

Next episode, we hatch and export... then add the whole lot to the Inventor code I wrote earlier.

 

Thanks heaps for your help.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...