OberonPlace.com Forums  

Go Back   OberonPlace.com Forums > Developer Forums > VBA > CorelDRAW/Corel DESIGNER VBA

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 10-12-2003, 17:31
IanVincent
Guest
 
Posts: n/a
Default finding node angles?

Using corelDraw10 VBA,

I want to able to draw a basic triangle shape, with two of the sides curved and have the code below that does it OK.

Set s5 = ActiveLayer.CreateCurve
With s5.Curve.CreateSubPath(1, 1)
.AppendCurveSegment False, 1, 2
.AppendCurveSegment False, 5, 1.2, 2, 20, 1.3, 145
.AppendCurveSegment False, 1, 1, 1.4, 170, 1.2, 30
s5.Curve.Closed = True
s5.Fill.UniformColor.CMYKAssign 0, 100, 0, 0
End With

But I want to be able to draw the triangle freehand, so that it looks like what I want, then transfer the parameters for angles etc from the hand drawn triangle to the VBA code, but I cant see how to access the numbers that define the curve. I acheived the numbers in code above by trial and error, but it took ages.

Is there any way to access the bezier angle settings for the nodes in an existing triangle?

TIA, Ian
Reply With Quote
  #2  
Old 11-12-2003, 20:54
IanVincent
Guest
 
Posts: n/a
Default

I see now that I was missing the point that the object that I have manually drawn already exists, so the properties of the shape already contain the information that I require, and are available via .activeselection. In that sense, why would I have to recreate the object, since it already exists.

I need to get more familiar with the Corel object model and VBA I think.

The DrawBezierHulls macro that come with "The Official Guide" also reveals the settings for the node angles, so I now have two options.

Sometimes it doesn't hurt to ask the dumb question.

Ian
Reply With Quote
  #3  
Old 11-12-2003, 21:41
Alex's Avatar
Alex Alex is offline
Administrator
 
Join Date: Nov 2002
Posts: 1,940
Blog Entries: 4
Default Re-creating curve with VBA

Ian,

Here is some code for you to re-create any curve with VBA in CorelDRAW.

For CorelDRAW 11:

Code:
Sub DumpCurveInfo()
    Dim s As Shape
    Dim sp As SubPath
    Dim seg As Segment
    
    Set s = ActiveShape
    If s Is Nothing Then
        MsgBox "Nothing selected", vbCritical
        Exit Sub
    End If
    
    If s.Type <> cdrCurveShape Then
        MsgBox "Please select a curve", vbCritical
        Exit Sub
    End If
    
    Open "C:\CurveInfo.txt" For Output As #1
    Print #1, "Sub ReCreateCurve()"
    Print #1, "    Dim s As Shape"
    Print #1, "    Dim crv As Curve"
    Print #1, "    Dim sp As SubPath"
    Print #1, "    Set crv = CreateCurve(ActiveDocument)"
    For Each sp In s.Curve.Subpaths
        Print #1,
        Print #1, "    Set sp = crv.CreateSubPath(" & GetNodePos(sp.Nodes(1)) & ")"
        For Each seg In sp.Segments
            If seg.Type = cdrLineSegment Then
                Print #1, "    sp.AppendLineSegment " & GetNodePos(seg.EndNode)
            Else
                Print #1, "    sp.AppendCurveSegment2 " & GetNodePos(seg.EndNode) & ", ";
                Print #1, CSng(seg.StartingControlPointX) & ", " & CSng(seg.StartingControlPointY) & ", ";
                Print #1, CSng(seg.EndingControlPointX) & ", " & CSng(seg.EndingControlPointY)
            End If
        Next seg
        
        If sp.Closed Then
            Print #1, "    sp.Closed = True"
        End If
    Next sp
    Print #1,
    Print #1, "    Set s = ActiveLayer.CreateCurve(crv)"
    Print #1,
    Print #1, "End Sub"
    Close #1
End Sub

Private Function GetNodePos(ByVal n As Node) As String
    GetNodePos = CSng(n.PositionX) & ", " & CSng(n.PositionY)
End Function
For CorelDRAW 10:

Code:
Sub DumpCurveInfo()
    Dim s As Shape
    Dim sp As SubPath
    Dim seg As Segment
    
    Set s = ActiveShape
    If s Is Nothing Then
        MsgBox "Nothing selected", vbCritical
        Exit Sub
    End If
    
    If s.Type <> cdrCurveShape Then
        MsgBox "Please select a curve", vbCritical
        Exit Sub
    End If
    
    Open "C:\CurveInfo.txt" For Output As #1
    Print #1, "Sub ReCreateCurve()"
    Print #1, "    Dim s As Shape"
    Print #1, "    Dim crv As Curve"
    Print #1, "    Dim sp As SubPath"
    Print #1, "    Set s = ActiveLayer.CreateCurve()"
    For Each sp In s.Curve.Subpaths
        Print #1,
        Print #1, "    Set sp = s.Curve.CreateSubPath(" & GetNodePos(sp.Nodes(1)) & ")"
        For Each seg In sp.Segments
            If seg.Type = cdrLineSegment Then
                Print #1, "    sp.AppendLineSegment False, " & GetNodePos(seg.EndNode)
            Else
                Print #1, "    sp.AppendCurveSegment False, " & GetNodePos(seg.EndNode) & ", ";
                Print #1, CSng(seg.StartingControlPointLength) & ", " & CSng(seg.StartingControlPointAngle) & ", ";
                Print #1, CSng(seg.EndingControlPointLength) & ", " & CSng(seg.EndingControlPointAngle)
            End If
        Next seg
        
        If sp.Closed Then
            Print #1, "    sp.Closed = True"
        End If
    Next sp
    Print #1,
    Print #1, "End Sub"
    Close #1
End Sub

Private Function GetNodePos(ByVal n As Node) As String
    GetNodePos = CSng(n.PositionX) & ", " & CSng(n.PositionY)
End Function
The difference between the two is that in CorelDRAW 11 there are some improvements in curve engine which allows to create a "virtual" curve object in memory then create a real object in the document. Also in Draw 11 there is a method Subpath.AppendCurveSegment2 which is faster and more precise.

Also the order of parameters in AppendLineSegment and AppendCurveSegment[2] is different between in Draw 10 and 11, that's why I provided two different versions of the macro.

The macro generates a text file (C:\CurveInfo.txt) which actually contains all the VBA methods needed to recreate any selected curve in the document.

Here is an example of code generated by the macro for one of the curves in CorelDRAW11:

Code:
Sub ReCreateCurve()
    Dim s As Shape
    Dim crv As Curve
    Dim sp As SubPath
    Set crv = CreateCurve(ActiveDocument)

    Set sp = crv.CreateSubPath(1.681661, 8.456827)
    sp.AppendCurveSegment2 1.875906, 6.622299, 1.487417, 7.874094, 1.487417, 7.118701
    sp.AppendCurveSegment2 3.214031, 6.341724, 2.15648, 6.276977, 2.825543, 6.125897
    sp.AppendCurveSegment2 4.271583, 7.982008, 4.163669, 6.881291, 2.890291, 8.56474
    sp.AppendCurveSegment2 5.199638, 6.902874, 4.616906, 7.830929, 5.54496, 7.420858
    sp.AppendCurveSegment2 6.34352, 5.996402, 4.767984, 6.255394, 5.911866, 5.478417
    sp.AppendCurveSegment2 6.66726, 6.363307, 6.386685, 6.039567, 6.559347, 6.514386
    sp.AppendCurveSegment2 6.645677, 5.478417, 6.926252, 6.017984, 6.883087, 5.82374

    Set sp = crv.CreateSubPath(2.026984, 4.248205)
    sp.AppendCurveSegment2 3.516189, 3.276984, 2.242811, 3.794969, 2.911874, 2.672669
    sp.AppendCurveSegment2 4.142087, 4.442449, 3.818347, 3.579142, 3.732016, 4.52878
    sp.AppendCurveSegment2 5.13489, 3.276984, 4.595323, 4.334536, 4.962228, 3.276984
    sp.AppendCurveSegment2 6.451433, 3.730221, 5.393882, 3.276984, 6.451433, 3.471228

    Set s = ActiveLayer.CreateCurve(crv)

End Sub
I hope this helps.
Reply With Quote
  #4  
Old 12-12-2003, 18:42
IanVincent
Guest
 
Posts: n/a
Default

Thanx Alex, it works great and shows me heaps of new stuff, like printing to .txt etc.

However when the new code creates the new shape, it appears in Draw10 as a shape that is selected, but somehow it is not. Pressing delete wont delete it, and trying to access it with other macro's using Activeshape results in failing the "nothing selected" test.

If I go to Draw10 and select it with the pick tool I can then access it as ActiveShape, but that is a pain.

I can access the newly created object using Activelayer.Shapes(1) but not using ActiveShape. What action would force the new shape to become the ActiveShape.

Could you explain this please?.

Also what is the difference between ActiveSelection and ActiveShape since they both reference a shape.?

Ian
Reply With Quote
  #5  
Old 12-12-2003, 23:32
Alex's Avatar
Alex Alex is offline
Administrator
 
Join Date: Nov 2002
Posts: 1,940
Blog Entries: 4
Default

Quote:
Originally Posted by IanVincent
However when the new code creates the new shape, it appears in Draw10 as a shape that is selected, but somehow it is not. Pressing delete wont delete it, and trying to access it with other macro's using Activeshape results in failing the "nothing selected" test.
Hmm, that's an interesting one. Well, to fix it, just add the following code at the end:

Code:
s.CreateSelection
However I must say that you don't have to do that. Once you created a shape in a macro, you don't have to select it to do something to it. Just use the shape reference and do the action direction. For example, if you want to fill the curve, just use:

Code:
s.Fill.UniformColor.CMYKAssign 0, 100, 100, 0
Quote:
Also what is the difference between ActiveSelection and ActiveShape since they both reference a shape.?
ActiveSelection returns a reference to a special shape called the Selection Shape. This "pseudo-shape" behaves as a group which has all currently selected shapes as its children and they can be accessed through Shapes collection of the selection shape.

Note that once a reference to the selection shape is established, it always references the current live selection which means that once the selection changes, the old reference will now "point" to the newly selected shapes. See this code:

Code:
Dim s As Shape
Set s = ActiveSelection
ActiveLayer.CreateRectangle 0, 0, 2, 2
s.Move 2, 0
ActiveLayer.CreateEllipse 2, 2, 3, 3
s.Move 2, 0
The above code gets the reference to the selection shape. Then a rectangle is created and it automatically gets selected. Therefore the object s reference the shape which contains the rectange as its sub-object. and the s.Move command moves the rectangle.

Then when the ellipse is created it gets selected and now the same reference s points to it. Note that the selection shape isn't the selected shape itself. It's a pseudo-object which can be used to operate all of the selected objects at once. If you want to change properties of individual shapes in the selection, use its Shapes properties:

Code:
ActiveLayer.CreateRectangle 0, 0, 1, 1
ActiveSelection.Shapes(1).Rectangle.SetRoundness 20
ActiveSelection will still return a valid shape object if there is no selected objects in the document. Just the Count property of its Shapes collection will be zero.

ActiveShape is essentially a shortcut to ActiveSelection.Shapes(1) and returns the last selected shape in selection (by default). So, ActiveShape will return the actual rectangle or ellipse. THis property will return Nothing if there is no selected objects. Also note, that if there is more than one object selected, ActiveShape will return only one of the selected objects (the one which was selected last).

I hope all this makes sense.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Node Coordinate designation ddonnahoe CorelDRAW/Corel DESIGNER VBA 5 24-02-2005 09:00
Node Mover ddonnahoe Code Critique 6 23-02-2005 16:33
vba question bumblebee CorelDRAW/Corel DESIGNER VBA 4 04-08-2004 15:07
Detecting Last Node Selected? barnold CorelDRAW/Corel DESIGNER VBA 4 21-04-2004 13:03
Node selection question Peter Clifton CorelDRAW/Corel DESIGNER VBA 1 02-12-2003 12:00


All times are GMT -5. The time now is 08:55.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
Copyright © 2011, Oberonplace.com