Counting Blocks and Polyline Length Inside a Block Boundary

Counting Blocks and Polyline Length Inside a Block Boundary

adaptacad
Advocate Advocate
1,302 Views
18 Replies
Message 1 of 19

Counting Blocks and Polyline Length Inside a Block Boundary

adaptacad
Advocate
Advocate

Good afternoon, I hope this post finds you well.

I have already tried to solve this with the help of AI, but I was not able to achieve the expected result, so I would like to ask for some guidance.

I have a block called VIEW. Inside this block, there are other blocks as well as some polylines.

My goal is to:

  • Count how many blocks exist inside the VIEW block;

  • Calculate the total length of polylines only within the internal area of the VIEW block;

  • Store these values in the attributes of the VIEW block itself.

Counting the blocks is not the main issue. The main challenge is:

  • Splitting the polylines exactly at the intersection points with the VIEW block boundary;

  • Correctly summing the length of all polyline segments that lie inside this boundary;

  • Restoring the polylines to their original state, so they are not left broken after the calculation.

I am attaching the DWG file to make the scenario easier to understand.

Has anyone dealt with a similar situation or could point me in the right direction to solve this?

adaptacad_0-1770312127043.png

 

0 Likes
Accepted solutions (1)
1,303 Views
18 Replies
Replies (18)
Message 2 of 19

Kent1Cooper
Consultant
Consultant

I can imagine an approach, at least:

Select a VIEW Block, or select them all and apply what follows to each.

Given the plain rectangular shape and orthogonal orientation of it, using its bounding box, draw a temporary Polyline rectangle over its boundary.

Using its opposite corners for a Crossing window, find all Polylines within or crossing it.

Using the same for a Window [not Crossing] window, find all the BLK_COUNT Blocks inside it.

Using the (intersectwith) method, find the intersections between the Polyline(s) and the VIEW Block boundary.

If there are 2 intersections of the same Polyline, find the distances along that at each intersection with (vlax-curve-getDistAtPoint) , and from those calculate the length along the Polyline inside.  [There should be no need to Break the Polyline.]

If there are 2 Polylines with 1 intersection of each with the boundary:

  Determine whether the end of each Polyline that's inside is its start or its end;

  Calculate the distances of each portion from that end to its intersection with the boundary;

  Add the distances for a total length.

Delete the temporary rectangle.

Use (setpropertyvalue) to put the appropriate values [converted to Text strings] into the appropriate Attributes.

 

Potential complications:

If a BLK_COUNT Block straddles the boundary between two VIEW Blocks [for example, one between 001 & 002], it will not be seen by a Window selection for either VIEW Block.  But it would be seen by Crossing selections for both VIEW Blocks.  Maybe it should be done by Crossing, so that all are seen, and every BLK_COUNT Block checked for which VIEW Block it should be credited to.  But that check would logically be for whether its insertion point is inside.  Unfortunately, the BLK_COUNT insertion point is not in the middle.  That one that straddles 001 & 002 has its insertion point inside 001, but more of itself inside 002.  And the one just to its right is fully [in extents and insertion point] inside 001, but the Polyline path near it is inside 002, if the location along the path is what matters -- it would not be seen by either variety of window in selection for 002.  How should those be assigned?

Could there ever be more than two Polylines associated with a given VIEW Block?  [I don't see any like that in the sample drawing, but....]

Could the VIEW Blocks ever be at some non-orthogonal rotation?

Would a Polyline ever exit a VIEW Block boundary and then come back inside before exiting again?  [That very nearly happens between 001 & 002.]  That would greatly complicate what I'm picturing.

Also:

There are at least 3 places where the Polylines go entirely outside of any VIEW Block.  This approach would not see the lengths of those bits.  You would presumably need to check for that yourself and shift VIEW Blocks to "catch" all of the lengths of all Polylines.

In 056 [and maybe also elsewhere], there's a little loop in the Polyline path.  The length of that loop would be included.  If it's just a graphic representation, and not of "real" size or shape, would that throw off your results to a meaningful degree?

Kent Cooper, AIA
Message 3 of 19

devitg
Advisor
Advisor

@Kent1Cooper I'll try to do as your way. 

Thanks for  it. 

 

Message 4 of 19

Sea-Haven
Mentor
Mentor

Just an idea you can select block X ie 001 and use a cutter lisp to cut around the block then look for plines inside that block and sub blocks, get pline length, matches your sample dwg, so you say but stuff is gone ! With lisp a variable is still saved even after doing undo so the cut step is undone, go to next block. 

 

Have to go now will try later to do something later.

 

 

0 Likes
Message 5 of 19

daniel_cadext
Advisor
Advisor

had a go with Python.   https://gist.github.com/CEXT-Dan/d802bf84977ecf16c98a102c40bc1c0d

 

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 6 of 19

daniel_cadext
Advisor
Advisor

I had written pl_clip to test intersections, AI said, nah bruh, let’s roll a Cohen-Sutherland algo

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 7 of 19

daniel_cadext
Advisor
Advisor

this fills out the attributes. code is here gist 

 

clipper.png

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 8 of 19

adaptacad
Advocate
Advocate

@Kent1Cooper Thank you for the considerations raised — they help clarify the rules and remove ambiguity. Below are the answers point by point, based on the intended behavior of the process:

  1. BLK_COUNT blocks on the boundary between VIEWs
    A BLK_COUNT block must be counted in the VIEW where its insertion / intersection point is located.
    If a block happens to lie exactly on the boundary between two VIEWs, it should be counted only once, and it may be assigned to either VIEW.
    In practice, this situation is rare, since blocks are unlikely to be placed exactly on a VIEW boundary.

  2. Polylines entering and exiting a VIEW multiple times
    Yes, a polyline may enter and exit the same VIEW more than once.
    Although this is uncommon, it can occur and must be handled correctly by summing all polyline segments that lie within the VIEW, regardless of how many intersections exist.

  3. More than two polylines per VIEW
    Yes, a single VIEW may contain more than two polylines.
    The calculation should include all polylines that intersect or cross the VIEW, adding together the internal lengths of each one.

  4. VIEW rotation
    VIEW blocks will never be rotated.
    They will always be orthogonal and aligned exactly as shown, which removes the need to handle rotation or complex transformations.

  5. Polyline segments outside any VIEW
    Polyline segments that fall outside of all VIEWs must not be counted.
    Only the portions of polylines that lie within a VIEW boundary are relevant and should be included in the total.

0 Likes
Message 9 of 19

adaptacad
Advocate
Advocate

@daniel_cadext Thanks for the reply, but I have no idea how to run Python in AutoCAD!

Message 10 of 19

daniel_cadext
Advisor
Advisor

Ah sorry,  it’s all the same API under the hood, so whom ever you recruit to write the final version can use this as inspiration. The clipping algorithm should handle items 2-5, since it works on segments, see https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm

 

I didn’t handle item 1, though it should be fairly trivial to mark the BLK_COUNTs that intersect with multiple VIEWs

 

Cheers : )

Dan

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 11 of 19

daniel_cadext
Advisor
Advisor

Side note, I updated my routine to account for BLK_COUNTs that overlap VIEWs. And I spotted this part of the polyline. So mine won’t work after all, since I split the polyline into segments.. oops.

 

edit: i added 

def pl_clip_arc_seg(self, _arc: Ge.CircArc2d):

assumes the curve never actually intersects the view. the results seem correct in that the circumference

is included in the polyline length 

 

oh no.png

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 12 of 19

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote [in Message 2]:

....

In 056 [and maybe also elsewhere], there's a little loop in the Polyline path.  The length of that loop would be included.  If it's just a graphic representation, and not of "real" size or shape, would that throw off your results to a meaningful degree?


@adaptacad , that's an as-yet-unanswered question, and a situation also noticed by @daniel_cadext in Message 11.  And in further looking into it, I find that there are very many VIEW Blocks with those inside, and also that all of those I checked [which was far from all of them] loop around 5 times over top of themselves!  They are of 10-unit circumference, which adds 50 drawing units of Polyline length for every one of them.  Within [randomly-selected] Block 009, the total length of Polyline is about 763 drawing units, as opposed to about 713 units omitting the loops -- about a 7% increase in length.  Does that matter?

If the Polylines are all always made up of only line segments apart from those overlapping loops, it may be possible to find a way to discount the length of the loopings, if that's appropriate.

Kent Cooper, AIA
0 Likes
Message 13 of 19

adaptacad
Advocate
Advocate

I hadn’t noticed that detail, but it makes no difference. The polyline can be counted, ignoring that “leftover.”

0 Likes
Message 14 of 19

daniel_cadext
Advisor
Advisor
Accepted solution

- I moved the code to a gist as not to spam the forum.

- I removed counting the loops, just uncomment the code if you need it

- I added output to pandas - > Excel, adjust the path.

- attached the drawing and excel if someone wants to validate

Sorry for spamming the lisp forum with python, seemed like a fun test, maybe the code can be useful 

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
Message 15 of 19

adaptacad
Advocate
Advocate

This is indeed the expected result. However, the solution is written in Python, and as far as I know, Python is not commonly used in AutoCAD — at least I don’t use it, and I’m not even sure how to load or run it (is there something like a pyload command?).

Thank you very much for taking the time to help. I’ll try to convert the logic to AutoLISP with the help of AI on my side. Much appreciated!

0 Likes
Message 16 of 19

daniel_cadext
Advisor
Advisor

Yes, there’s pyload / pyreload commands. There’s a link in my signature; look for the YouTube video on how-to install. You can think of it as a “Scripting ObjectARX”

AI should be able to generate a Cohen-Sutherland routine in Lisp. Just feed it the polyline segments and block extents. I’m sure there lisp samples to set attributes

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
Message 17 of 19

adaptacad
Advocate
Advocate

It works great! Thank you very much.

Message 18 of 19

Sea-Haven
Mentor
Mentor

Something I am playing with is use Bounding box make a pline around the block. I am trying Extrim and Coookie Cutter to trim any lines or plines that cross the block. Yes then will look at counting blocks inside. Again whilst using a cut method Undo puts the trimmed objects back but lisp has already saved the values. 

 

Trying to find time.

Message 19 of 19

daniel_cadext
Advisor
Advisor

I just noticed that there’s already a AcGeClipBoundary2d::clipPolyline in ARX that I must have missed wrapping. I’ve been adding my own methods to enhance some of the existing classes.

Extents2d.intersectsWith(other Extents2d)
Extents2d.intersectsWith(other LinearEnt2d)
Extents2d.contains (other Extents2d)
Extents2d.contains (other Point2d)

Maybe I should add Extents2d.clip(AcGeLinearEnt2d), and try LinearEnt2d.clip(AcGeCircArc2d), or the inverse AcGeLinearEnt2d.clip..

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes