Reply

How to correctly create a complexstring from a perimeter

I'm trying to manipulate exported flat pattern DXF's. One of the things I wanted to do was create a complexstring from everything in the outer loop. Below is the code. I am sure this is a foolish way to do this, but it semi-works. I am having issues with it snapping to the wrong points on radii and fillets, I assume because I am not adding these objects to the array in the right order. This makes a mess out of the perimeter. 

 

How should I go about doing this?

 

        Dim objApp As SolidEdgeFrameWork.Application
        Dim objDoc As SolidEdgeDraft.DraftDocument
        Dim objSheet As SolidEdgeDraft.Sheet

        Dim dblTotalInterior As Double = 0
        Dim dblTotalExterior As Double = 0
        Dim dblUnknownLayer As Double = 0
        Dim objCompStrns As SolidEdgeFrameworkSupport.ComplexStrings2d
        Dim objCompStrn1 As SolidEdgeFrameworkSupport.ComplexString2d = Nothing
        Dim objarray(0) As Object
        Dim dblarea As Double
        Dim ConversionFactor As Double = 39.3700787


        Const PI = 3.14159265358979
        objApp = GetObject(, "SolidEdge.Application")
        objDoc = objApp.ActiveDocument
        objSheet = objDoc.ActiveSheet
        objCompStrns = objSheet.ComplexStrings2d




        For Each objdraw As Object In objSheet.DrawingObjects
            If TypeOf objdraw Is SolidEdgeFrameworkSupport.Line2d _
                Or TypeOf objdraw Is SolidEdgeFrameworkSupport.Circle2d _
                Or TypeOf objdraw Is SolidEdgeFrameworkSupport.Arc2d _
                Or TypeOf objdraw Is SolidEdgeFrameworkSupport.BSplineCurve2d _
                Or TypeOf objdraw Is SolidEdgeFrameworkSupport.Ellipse2d _
                Or TypeOf objdraw Is SolidEdgeFrameworkSupport.EllipticalArc2d _
                Or TypeOf objdraw Is SolidEdgeFrameworkSupport.FilletGeometry2d _
                Or TypeOf objdraw Is SolidEdgeFrameworkSupport.LineString2d Then

                'Calculate perimeters
                If objdraw.layer = "OUTER_LOOP" Then
                    objarray(objarray.Length - 1) = objdraw
                    ReDim Preserve objarray(objarray.Length)
                    dblTotalExterior = dblTotalExterior + objdraw.Length
                ElseIf objdraw.layer = "INTERIOR_LOOPS" Then
                    dblTotalInterior = dblTotalInterior + objdraw.Length
                Else
                    dblUnknownLayer = dblUnknownLayer + objdraw.length
                End If
            End If
        Next

        ReDim Preserve objarray(objarray.Length - 2)
        objCompStrn1 = objCompStrns.AddByObjects(ArraySize:=objarray.Length, members:=objarray)

 

-Dylan Gondyke
16 REPLIES

Re: How to correctly create a complexstring from a perimeter

Here's a few pictures of a .dxf flat pattern that I'm attempting to make the complexstring from. The two arcs with the arrows on them in the first picture are the ones that fail to locate properly, as shown in the second picture. If I simply manually toss connect relationships on the ends of the arcs to connect them to the lines, the complexstring creates correctly. How can I fix this??

 

 

 

 

 

 

 

 

-Dylan Gondyke

Re: How to correctly create a complexstring from a perimeter

[ Edited ]

Dylan,

 

I tried to recreate the issue you presented by drawing few lines and arcs on a Draft sheet as seen below:

Note the lower arc which I created using the Arc command.

The upper arc is made using the Fillet command and has a 'c' relationship symbol.

Also the upper arc did not establish a Connect relationship with the lines it was created from.

This failed to create the ComplexString for me too.

 

Next I removed the 'c' relationship and conected the arc endpoints with the adjacent lines.

This was a success.

 

In your green colored profile, the arc you pointed with arrows appear to be fillets, though it is not clear from the second image too.

Note that only those two arcs you pointed with arrows are concave i.e. Fillets i.e. center of arc lies outside the flat pattern profile.

All other arcs are convex i.e. 'Rounds' i.e. center of arc lies inside the flat pattern profile.

 

Further during debugging I could see Solid Edge trying to connect the StartPoint of the arc to the StartPoint of the Line - perhaps while attempting to create a complex string, whereas it is expected to connect the EndPoint of the arc to the StartPoint of the line. This is when there are no connect relations applied manually.

 

This is not a fix though, but some observations and derived insights.

I don't know how the green flat pattern profile was created - manually or using Solid Edge ?

If it were Solid Edge generated then you may want to request GTAC to change the behavior or style of generation of the concave i.e. fillet arcs.

 

If you have more data to test with, there are chances my presumptions could be proved wrong.

Sorry for not being able to profive a Solid Edge fix that you were actually asking for.

 

Now for a brute force fix, I would suggest to loop through all items in the array programatically and check if the end point of each object is coincident and connected to the startpoint of the next or any other object in the array and if not then fix it by applying the relation programmatically. At times it may be requried to reverse the direction of lines and arcs by deleting and redrawing them. It is not so scary as it may sound. I have done this before in an application which reads through just line and arc objects on a layer and 'fixes' their connectivity, ultimately generating the CNC code.

  Let me know - I can reply with the pseudo code or also work out the VB code.

 

Hope this works for you.

~Tushar

http://surfandcode.blogspot.in

 

Re: How to correctly create a complexstring from a perimeter

Hi Tushar,

 

First, thank you for the detailed response you took the time to write!

 

I have attached the actual DXF file I'm working with. It was produced by Solid Edge using SaveAsFlatDXFEx. Those problem arcs were originally fillets, as were every other arc on the model. The mixed start/end point problem occurs in anything but the most basic sheet metal model exported to DXF. I am afraid applying connect relationships programmatically is beyond my limited abilities...If you have time to jot down a few notes, I'd be grateful. Regardless, I'll chip away at this at lunch again today.

 

EDIT: I have attached the example file with the extension changed from '.dxf' to '.doc' in order to allow upload

 

-Dylan Gondyke

Re: How to correctly create a complexstring from a perimeter

You pointed it correctly, it is a problem with mixed start-end points for arcs.

Gievn a center, start and end point, the API too constructs a complimentary arc to the one desired. This could have fixed the issue since it was only a matter of looping through the entities, checking key points and reversing them. Alas !

 

Re: How to correctly create a complexstring from a perimeter

Hi Dylan,

 

Are you still working on this problem or have you found a solution/workaround ?

I have been working on this issue all the time and also posted to an existing query on this forum.

A solution was also posted there but it didn't work.

So I have found a workaround. Let me know if you are still looking for a solution or workaround - I will share what I have.

 

Best regards,

Tushar Suradkar

 

Re: How to correctly create a complexstring from a perimeter

Hi Tushar.

 

Yes, please share! I have not found a workaround and abandoned that portion of my macro with plans to revisit later.

 

I read through the post you linked to. I had actually found that exact older post before you posted to it. 

-Dylan Gondyke

Re: How to correctly create a complexstring from a perimeter

[ Edited ]

Dylan,

 

Developments after posting my last reply were silly.

While I waited for you to reply today, thought of giving the solution from JB another shot.

And I found it indeed works. Here's the loop that I run on the DXF you originally attached.

The two arcs in question were fixed and are now having proper start and end points by changing their orientation to Clockwise.

 

Initially when JB suggested changing the orientation, I simply applied it to the original arcs in the DXF which was creating a complimentary arc and looked unacceptable. Later today, I tweaked it such that when the in-correct arc is found, I deleted it and created a new one in its place and then chaged its orientation which worked.

 

This however gives rise to another problem. Earlier the drawing objects in the DXF were not only  lying ene-to-end connected but were also added to the sheet in the same sequence. Meaning the two arcs you pointed to were in order or proper sequence in the peipheral loop, Since the original arcs are gone and new ones have replaced them as seen in the code below, they are added to the end of the sequence, though geometrically in proper location and Solid Edge while creating the ComplexString is reading them in the order created and applying relations which is messing it up again. I am sure I can work on this further to finally get the proper complex string. Here is the loop that fixes the two arcs:

 

Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
Dim oApp As SolidEdgeFramework.Application
Dim oDoc As SolidEdgeDraft.DraftDocument
Dim oSheet As SolidEdgeDraft.Sheet

oApp = Marshal.GetActiveObject("SolidEdge.Application")
oDoc = oApp.ActiveDocument
oSheet = oDoc.ActiveSheet

Dim oDraws As SolidEdgeFrameworkSupport.DrawingObjects
oDraws = oSheet.DrawingObjects

For i As Integer = oDraws.Count To 1 Step -1
      Dim oDraw As Object = oDraws.Item(i)
      If TypeOf oDraw Is SolidEdgeFrameworkSupport.Arc2d Then
          Dim oArc As SolidEdgeFrameworkSupport.Arc2d = oDraw
          Dim dXS As Double, dYS As Double : oArc.GetStartPoint(dXS, dYS)
          For j As Integer = oDraws.Count To 1 Step -1
              Dim oDrawN As Object = oDraws.Item(j)
              If TypeOf oDrawN Is SolidEdgeFrameworkSupport.Line2d Then
                  Dim oLine As SolidEdgeFrameworkSupport.Line2d = oDrawN
                  Dim dXSL As Double, dYSL As Double : oLine.GetStartPoint(dXSL, dYSL)
                  If (Math.Round(dXS, 5) = Math.Round(dXSL, 5)) And (Math.Round(dYS, 5) = Math.Round(dYSL, 5)) Then
                      Dim dXE As Double, dYE As Double : oArc.GetEndPoint(dXE, dYE)
                      Dim dXC As Double, dYC As Double : oArc.GetCenterPoint(dXC, dYC)
                      oArc.Delete()
                      oArc = oSheet.Arcs2d.AddByCenterStartEnd(dXC, dYC, dXE, dYE, dXS, dYS)
                      oArc.Orientation = SolidEdgeFrameworkSupport.Geom2dOrientationConstants.igGeom2dOrientClockwise
                      oArc.Layer = "OUTER_LOOP"
                      Exit For
                  End If
              End If
          Next j
      End If
  Next i
End Sub

Note that:

1. When creating a new arc, I swapped the start and end points data from the original arc - this was the root cause.

2. The For loops are in reverse order since the arc is deleted from the DrawingObjects.

 

If it works for you so far, please let me know - I will work on further fixing the issue.

 

Tushar Suradkar

http://surfandcode.blogspot.in/

 

Further, also try this little piece of code on your DXF file opened in SE:

First: Before fixing the drawing objects in the DXF by using the code above. Note carefully the sequence in which the arcs are deleted. The first arc you pointed to in the image is deleted followed by some other arcs, then the second arc you pointed to gets deleted and then the remaining arcs - indicating the two problem arcs you mentioned are in a proper order in the overall string of objects.

 

Second: After fixing the two arcs using my code - note again the sequence of arc deletion. First both arcs that you pointed are deleted and the remaining arcs then are deleted, indicating the sequence of objects in the DrawingObjects collection has changed hence the ComplexString won't be formed properly.

 

 Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
        Dim oApp As SolidEdgeFramework.Application
        Dim oDoc As SolidEdgeDraft.DraftDocument
        Dim oSheet As SolidEdgeDraft.Sheet

        oApp = Marshal.GetActiveObject("SolidEdge.Application")
        oDoc = oApp.ActiveDocument
        oSheet = oDoc.ActiveSheet

        Dim oDraws As SolidEdgeFrameworkSupport.DrawingObjects
        oDraws = oSheet.DrawingObjects

        For i As Integer = oDraws.Count To 1 Step -1
            Dim oDraw As Object = oDraws.Item(i)
            If TypeOf oDraw Is SolidEdgeFrameworkSupport.Arc2d Then
                Dim oArc As SolidEdgeFrameworkSupport.Arc2d = oDraw
                MessageBox.Show("Deleting Arc " + i.ToString())
                oArc.Delete()
            End If
        Next i
    End Sub

 

Re: How to correctly create a complexstring from a perimeter

Now I have noticed two more functions SetStartPoint and SetEndPoint for the arc which should hopefully resolve the issue without having to delete the arc and again adding it.

I am working on this.

~Tushar

Re: How to correctly create a complexstring from a perimeter

[ Edited ]

Bingo! the issue is solved - in the sixth attempt.

Here is all the code in the world you need to run on the DXF after you open it in Solid Edge.

Then run your ComplexString creation code.

 

Private Sub Button6_Click(sender As System.Object, e As System.EventArgs) Handles Button6.Click
        Dim oApp As SolidEdgeFramework.Application
        Dim oDoc As SolidEdgeDraft.DraftDocument
        Dim oSheet As SolidEdgeDraft.Sheet

        oApp = Marshal.GetActiveObject("SolidEdge.Application")
        oDoc = oApp.ActiveDocument
        oSheet = oDoc.ActiveSheet

        Dim oDraws As SolidEdgeFrameworkSupport.DrawingObjects
        oDraws = oSheet.DrawingObjects

        For i As Integer = oDraws.Count To 1 Step -1
            Dim oDraw As Object = oDraws.Item(i)
            If TypeOf oDraw Is SolidEdgeFrameworkSupport.Arc2d Then
                Dim oArc As SolidEdgeFrameworkSupport.Arc2d = oDraw
                Dim dXS As Double, dYS As Double : oArc.GetStartPoint(dXS, dYS)
                For j As Integer = oDraws.Count To 1 Step -1
                    Dim oDrawN As Object = oDraws.Item(j)
                    If TypeOf oDrawN Is SolidEdgeFrameworkSupport.Line2d Then
                        Dim oLine As SolidEdgeFrameworkSupport.Line2d = oDrawN
                        Dim dXSL As Double, dYSL As Double : oLine.GetStartPoint(dXSL, dYSL)
                        If (Math.Round(dXS, 5) = Math.Round(dXSL, 5)) And (Math.Round(dYS, 5) = Math.Round(dYSL, 5)) Then
                            Dim dXE As Double, dYE As Double : oArc.GetEndPoint(dXE, dYE)
                            Dim dXC As Double, dYC As Double : oArc.GetCenterPoint(dXC, dYC)
                            oArc.SetStartPoint((dXS + dXE) / 2, (dYS + dYE) / 2)
                            oArc.SetEndPoint(dXS, dYS)
                            oArc.SetStartPoint(dXE, dYE)
                            oArc.Orientation = SolidEdgeFrameworkSupport.Geom2dOrientationConstants.igGeom2dOrientClockwise
                            oArc.Layer = "OUTER_LOOP"
                            Exit For
                        End If
                    End If
                Next j
            End If
        Next i
    End Sub

What the loop does is :

1. Goes to each arc in the sheet and gets start point.

2. For a given arc, it then loops through all the lines and checks if the start point matches the start point of the arc - this should not be so - the start point of an arc should always be the end point of a line. In that case we have got our problem arc. Fix it by swapping the start and end point and changing its orientation to Clockwise. All other arcs are OK since their start points coincide with end points of other lines and end points coincide with start points of lines, except the two problem arcs.

Note: This can however fail if there are two arcs end-to-end since this is not checked. Should work for the present case though and can always be updated when there is a case of two consequtive arcs one of them being a problem arc.

 

~Tushar Suradkar

www.cadvertex.com

 

Here's the ComplexString in all its glory !!