Announcements
Due to scheduled maintenance, the Autodesk Community will be inaccessible from 10:00PM PDT on Oct 16th for approximately 1 hour. We appreciate your patience during this time.
VBA
Discuss AutoCAD ActiveX and VBA (Visual Basic for Applications) questions here.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Trim part of intersect polylines

19 REPLIES 19
Reply
Message 1 of 20
rmcefr
923 Views, 19 Replies

Trim part of intersect polylines

Hi everyone

 

if have 2 polylines as shown on here,

is there any function or procedure to get that intersect of polylines trimmed ?

Polyline_1 = ThisDrawing.ModelSpace.AddLightWeightPolyline(P1)

Polyline_2 = ThisDrawing.ModelSpace.AddLightWeightPolyline(P2)

 

thanks

 

Polyline_Trim.jpg

 

19 REPLIES 19
Message 2 of 20
grobnik
in reply to: rmcefr

@rmcefr Hi, just a question, have you the opportunity to select the polyline 1 and 2 ? in both cases you showed.

I'm asking this because inside VBA you can select two objects and get the intersection point, so starting from that point you can break the polyline (I guess), sincerely I never tried to break a polyline with VBA, but it's interesting opportunity. On the opposite, for example if there are a lot of polyline inside your drawing, you have to add a selection criteria, making a selection from those to break or those to not break.

As second issue could be better if you can share a sample dwg.

Bye

 

Message 3 of 20
grobnik
in reply to: rmcefr

@rmcefr Sorry to reply again

just for example here a simply code for selecting Polyline 1, Polyline 2 and got the two intersection points.

As you can see the variable intPoints, will contain intersection coordinates.

So you reach at least an half of your issue 🤣

Sub TestPline()
Dim intPoints As Variant
Dim P1 As AcadLWPolyline
Dim P2 As AcadLWPolyline
ThisDrawing.Utility.GetEntity P1, basePnt, "Select 1st PolyLine"
ThisDrawing.Utility.GetEntity P2, basePnt, "Select 2nd PolyLine"
    intPoints = P1.IntersectWith(P2, acExtendNone)

End Sub

grobnik_0-1650394264666.png

grobnik_1-1650394340796.png

 

 

Message 4 of 20
rmcefr
in reply to: grobnik

Dear friend "grobnik"

many thanks for reply

 

due to so many of polylines in drawing will not be suitable to go to "Select" option , because the output will not be fully automated generated dwg, and time consumption will be more..etc

 

after so many try we can go to that option

 

define Polylines as region and add it to the drawing, then use this command to subtract the polyline region which you don't like

PL1_Region.Boolean(acSubtraction, PL2_Region)

 

but in this case we need to delete our main polylines, and keep only the added regions and that will let us to loose a lot of tools works normally with polylines,

also, this can work with second case, but for the first case when the second polyline will be on the same boundary of other, still the regions cant subtract.

 

 

Message 5 of 20
rmcefr
in reply to: grobnik

.

Message 6 of 20
grobnik
in reply to: rmcefr

Hi @rmcefr ,

Thank you for message, my code was only an example, you can try to select the Polylines in several other methods, and if there will be an intersection between found polylines then coordinate value for sure will be higher than 0.

Of course check all conbination of all founded polyline could taken time. Still in hold how to subcract the exceeding part of intersections points. Perhaps region could be an option.

Message 7 of 20
rmcefr
in reply to: grobnik

Hi @grobnik

 

yes right,

the issue here , after getting the intersections points, how to trim polylines based on that points ?

 

regards

Message 8 of 20
grobnik
in reply to: rmcefr

@rmcefr , Still search a way I'm not so expert, mine it's an hobby. Probably @ed57gmc or @norman.yuan  help us in this topic

Thank you.

Message 9 of 20
ed57gmc
in reply to: rmcefr


@rmcefr wrote:

but in this case we need to delete our main polylines, and keep only the added regions and that will let us to loose a lot of tools works normally with polylines,


In order to write a program to fully automate it, you need to define what identifies pl1 and pl2, and in this case it has you have many pl1's and many pl2's. That may not be easy. A user can look at it and apply some logic to decide and filter everything else out. In this case, we can't write code for this until you can tell us what logic to use. Perhaps you can add some unique property to pl1 and pl2 when you create them.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 10 of 20
rmcefr
in reply to: ed57gmc

Hi @ed57gmc 

 

for whole project there is many options to control,

 

but as a concept, suppose if we have 2 polylines only as above drawing, does any command there will help to trim? 

 

thanks

Message 11 of 20
ed57gmc
in reply to: rmcefr

Here's a command I wrote that trims a line around blocks(schematic symbols) that are placed on it. It calls many other subs. If this looks like something you can use, I'll post the other subs.

Public Sub BreakLineByBlock()
    'Break lines around block insertions.
     
    Dim str As String
    Dim strHandle As String
    Dim objLine As AcadLine
    Dim objLine1 As AcadLine
    Dim objLine2 As AcadLine
    Dim objSubEnt As AcadEntity
    Dim objBlock As AcadBlockReference
    Dim ssBlocks As AcadSelectionSet
    Dim ssLines As AcadSelectionSet
    Dim vSubEnts As Variant
    Dim vMinPoint As Variant
    Dim vMaxPoint As Variant
    Dim vIntPoint As Variant
    Dim vCPoint As Variant      'compare point
    Dim vSPoint As Variant      'start point
    Dim vSPoint1 As Variant     'start point prime
    Dim vEPoint As Variant      'end point
    Dim vEPoint1 As Variant     'end point prime
    Dim dPickPoint(0 To 1) As Double
    Dim dPoint(0 To 2) As Double
    Dim dDistSP As Double       'shortest distance from start point
    Dim dDistEP As Double       'shortest distance from end point
    Dim dDistC As Double        'comparison distance
    Dim dVertList(0 To 7) As Double
    Dim iL As Integer           'lines counter
    Dim iP As Integer           'points counter
    Dim iSE As Integer          'sub entities counter
    Dim iCntL As Integer        'line count
    Dim iCntP As Integer        'point count
    Dim iCntSE As Integer       'sub entity count
    Dim PtsInsideBB As Integer  '0=none: 1=StartPoint: 2=EndPoint
    Dim varFilterType(0) As Integer
    Dim varFilterData(0) As Variant
    Dim vFT As Variant
    Dim vFD As Variant
    Dim BBpoints(0 To 4) As Point   'Bounding box points list
    Dim Cpoint As Point         'compare point

    On Error GoTo Err_Control
    'Set up undo for this command
    ThisDrawing.StartUndoMark
    'get blocks
    ThisDrawing.Utility.Prompt "Lines will be broken around selected blocks."
    Set ssBlocks = toolbox.ejSelectionSets.GetSS_BlockFilter
    For Each objBlock In ssBlocks
        'Use the block's bounding box to select ents that intersect with it.
        objBlock.GetBoundingBox vMinPoint, vMaxPoint
        BBpoints(0).x = vMinPoint(0): BBpoints(0).y = vMinPoint(1)
        BBpoints(1).x = vMaxPoint(0): BBpoints(1).y = vMinPoint(1)
        BBpoints(2).x = vMaxPoint(0): BBpoints(2).y = vMaxPoint(1)
        BBpoints(3).x = vMinPoint(0): BBpoints(3).y = vMaxPoint(1)
        BBpoints(4).x = vMinPoint(0): BBpoints(4).y = vMinPoint(1)
        Set ssLines = toolbox.ejSelectionSets.AddSelectionSet("ssLines")
        ssLines.Clear
        varFilterType(0) = 0: varFilterData(0) = "LINE"
        vFT = varFilterType: vFD = varFilterData
        ssLines.Select acSelectionSetCrossing, vMaxPoint, vMinPoint, vFT, vFD
        'get subent's of block
        vSubEnts = objBlock.Explode
        iCntSE = UBound(vSubEnts)
        For Each objLine In ssLines
            'Compare subentity intersection points with line start and
            'end points to determine new line segment. Points creating the
            'shortest line segments should be the outer limits of the block.
            'Any other intersections are inside the block and are discarded.
            '  Get reference info.
            vSPoint = objLine.StartPoint
            vEPoint = objLine.EndPoint
            dDistSP = toolbox.ejMath.XYZDistance(vSPoint, vEPoint)
            dDistEP = toolbox.ejMath.XYZDistance(vEPoint, vSPoint)
            Cpoint.x = vSPoint(0): Cpoint.y = vSPoint(1)
            If toolbox.ejMath.InsidePolygon(BBpoints, Cpoint) = True Then PtsInsideBB = PtsInsideBB Or 1
            Cpoint.x = vEPoint(0): Cpoint.y = vEPoint(1)
            If toolbox.ejMath.InsidePolygon(BBpoints, Cpoint) = True Then PtsInsideBB = PtsInsideBB Or 2
            For iSE = 0 To iCntSE
                'get list of points where the line intersects with the block
                Set objSubEnt = vSubEnts(iSE)
                vIntPoint = objSubEnt.IntersectWith(objLine, acExtendNone)
                'Compare to line segment lengths.
                If UBound(vIntPoint) > -1 Then
                    iCntP = (UBound(vIntPoint) + 1) / 3
                    For iP = 1 To iCntP
                        vCPoint = toolbox.ejMath.Point3D((vIntPoint(iP * 3 - 3)), (vIntPoint(iP * 3 - 2)), (vIntPoint(iP * 3 - 1)))
                        dDistC = toolbox.ejMath.XYZDistance(vSPoint, vCPoint)
                        If dDistC < dDistSP Then
                            dDistSP = dDistC
                            vSPoint1 = vCPoint
                        End If
                        dDistC = toolbox.ejMath.XYZDistance(vCPoint, vEPoint)
                        If dDistC < dDistEP Then
                            dDistEP = dDistC
                            vEPoint1 = vCPoint
                        End If
                    Next iP
                Else
                    'the array returned by IntersectWith is dimensioned
                    ' (0 To -1) when there are no points.
                End If
            Next iSE
            Select Case Round(objLine.Length, 14)
                Case Is = Round(dDistSP, 14)
                    'line did not intersect the block
                    'do nothing
                Case Is = Round(dDistSP + dDistEP, 14)
                    'One end of the line is inside the block and does
                    'not pass through, only one intersection point.
                    'Determine whether start point or end
                    'point is in the block and trim it. Assume the smaller
                    'distance is inside the block.
                    If dDistSP > dDistEP Then
                        'the endpoint is in the block
                        objLine.EndPoint = vEPoint1
                        objLine.Update
                    Else
                        'the startpoint is in the block
                        objLine.StartPoint = vSPoint1
                        objLine.Update
                    End If
                Case Else
                    'enough intersection points exist to break the line
                    'create two new lines and delete the original
                    Select Case PtsInsideBB
                        Case Is = 0 'neither end is inside
                            If ThisDrawing.ActiveSpace = acModelSpace Then
                                Set objLine1 = ThisDrawing.ModelSpace.AddLine(vSPoint, vSPoint1)
                                Set objLine2 = ThisDrawing.ModelSpace.AddLine(vEPoint1, vEPoint)
                            Else
                                Set objLine1 = ThisDrawing.PaperSpace.AddLine(vSPoint, vSPoint1)
                                Set objLine2 = ThisDrawing.PaperSpace.AddLine(vEPoint1, vEPoint)
                                'update new lines so that they will be seen by the next attempt to
                                'get a selection set
                            End If
                            objLine1.Update
                            objLine2.Update
                            objLine.Delete
                        Case Is = 1 'start point is inside
                            objLine.StartPoint = vEPoint1
                            objLine.Update
                        Case Is = 2 'end point is inside
                            objLine.EndPoint = vSPoint1
                            objLine.Update
                        Case Is = 3 'both ends are inside
                    End Select
                    PtsInsideBB = 0 'reset for next line
            End Select
        Next objLine
        For iSE = 0 To iCntSE
            Set objSubEnt = vSubEnts(iSE)
            objSubEnt.Delete
        Next iSE
    Next objBlock
    
Exit_Here:
    ThisDrawing.EndUndoMark
    Exit Sub
     
Err_Control:
    Select Case Err.Number
    Case -2147352567
        If GetAsyncKeyState(VK_ESCAPE) And &H8000 > 0 Then
            Err.Clear
            Resume Exit_Here
        ElseIf GetAsyncKeyState(VK_LBUTTON) > 0 Then
            Err.Clear
            Resume
        End If
'     Case -2145320928
'       'User input is keyword or..
'       'Right click
'       Err.Clear
'       Resume Exit_Here
    Case Else
        MsgBox Err.Description
        Resume Exit_Here
    End Select
End Sub

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 12 of 20
abbas.baghernezhad
in reply to: rmcefr

Hi, I need some thing like this, some how in reverse!

 

Untitled.jpg

I tried to run the code. I get These errors:

1)User-defined type... in this line

Dim BBpoints(0 To 4) As Point 

and the next line. I changed the type to Variant which let the error go away.

2)  on error handling...

GetAsyncKeyState(VK_ESCAPE)
GetAsyncKeyState(VK_LBUTTON)

I don't know much about it so I replaced it with 1>0

3) at last I get "Object required" error.

I want to deal with this code before posting a new topic because it is really close to what I need. I appreciate your kind help!

Message 13 of 20
rmcefr
in reply to: abbas.baghernezhad

you can try this:

on last command you can choose which polyline need to subtract and delete

 

       Dim Main_Polyline As AcadLWPolyline
        Dim P(7) As Double

        P(0) = 0 : P(1) = 0
        P(2) = P(0) + 500 : P(3) = P(1)
        P(4) = P(2) : P(5) = P(3) + 250
        P(6) = P(4) - 500 : P(7) = P(5)
        Main_Polyline = ThisDrawing.ModelSpace.AddLightWeightPolyline(P)
        Main_Polyline.Closed = True


        Dim Main_Polyline1 As AcadLWPolyline
        Dim P1(7) As Double

        P1(0) = 50 : P1(1) = 300
        P1(2) = P1(0) + 200 : P1(3) = P1(1)
        P1(4) = P1(2) : P1(5) = P1(3) - 100
        P1(6) = P1(4) - 200 : P1(7) = P1(5)
        Main_Polyline1 = ThisDrawing.ModelSpace.AddLightWeightPolyline(P1)
        Main_Polyline1.Closed = True



        Dim Main_Polyline_Regions_PL(0) As Object
        Dim Main_Polyline_Region As AcadRegion
        Dim Main_Polyline_PL(0) As AcadLWPolyline

        Main_Polyline_PL(0) = Main_Polyline
        Main_Polyline_Regions_PL = ThisDrawing.ModelSpace.AddRegion(Main_Polyline_PL)
        Main_Polyline_Region = Main_Polyline_Regions_PL(0)


        Dim Main_Polyline1_Region_PL(0) As Object
        Dim Main_Polyline1_Region As AcadRegion
        Dim Main_Polyline1_PL(0) As AcadLWPolyline

        Main_Polyline1_PL(0) = Main_Polyline1
        Main_Polyline1_Region_PL = ThisDrawing.ModelSpace.AddRegion(Main_Polyline1_PL)
        Main_Polyline1_Region = Main_Polyline1_Region_PL(0)


        Main_Polyline1_Region.Boolean(AcBooleanType.acSubtraction, Main_Polyline_Region)
        Main_Polyline1.Delete()

 

Message 14 of 20
abbas.baghernezhad
in reply to: rmcefr

Thank You. 🤗

two last lines turn red and nothing happens. Even if I delete them. 

I guess I need to do something more than just copy-paste you code, right?

Message 15 of 20
rmcefr
in reply to: abbas.baghernezhad

do you get polylines drawings? and polylines regions?

 

only subtract command not work?

could please send the error you got

Message 16 of 20
abbas.baghernezhad
in reply to: rmcefr

No. nothing is drawn. nothing happens. 

These line are red. I guess "=" sign and some stuff are missing!

Main_Polyline1_Region.Boolean(AcBooleanType.acSubtraction, Main_Polyline_Region)
Main_Polyline1.Delete()

 

Message 17 of 20
norman.yuan
in reply to: rmcefr

This is syntax error with the last 2 lines: they should be:

 

Main_Polyline1_Region.Boolean AcBooleanType.acSubtraction, Main_Polyline_Region 
Main_Polyline1.Delete

That is, with VBA, you do not use brackets with subroutines, unless you place "Call " in front of it, like this:

 

Call Main_Polyline1_Region.Boolean(AcBooleanType.acSubtraction, Main_Polyline_Region)

 

If it is Function that returns some value, then you must use bracket:

 

Dim num As Integer

num=MyAddingFunction(1, 2)

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 18 of 20

Thank You.
Absolutely Right. The Syntax error is gone but there is no function to run so I put all the code in a main sub.
I get "can't assign to array" related to this line:
Main_Polyline_Regions_PL = ThisDrawing.ModelSpace.AddRegion(Main_Polyline_PL)
Message 19 of 20
rmcefr
in reply to: abbas.baghernezhad

have you get drawing of 2 polylines?

Message 20 of 20
abbas.baghernezhad
in reply to: rmcefr

No. Nothing happens. that's because Main_Polyline and Main_Polyline1 are objects and we need to write "set" before the line:

Set Main_Polyline = ThisDrawing.ModelSpace.AddLightWeightPolyline(P)

and about 

Dim Main_Polyline1_Region_PL(0) As Object

Main_Polyline_Regions_PL(0) is an array!

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report