abraxus Posted September 20, 2013 Share Posted September 20, 2013 (edited) I am looking for an Autocad add-on that will detect blocks that are overlapping, but I was unable to find such a thing. Has anyone here ever heard of something like that which already exists? If not, any ideas on how to write some VBA to do this? The only way I can think of to write it would be to scan thru block references, comparing the size and location of each one to all the others. All the blocks would be simple rectangles. That's the easy part tho. The difficult part is - I would need a function that returns true or false when passed two block references after checking to see if they overlap at all. Anyone up to the challenge? Edited September 28, 2013 by abraxus typo Quote Link to comment Share on other sites More sharing options...
BlackBox Posted September 20, 2013 Share Posted September 20, 2013 In your sub-function / Method, extract the outer boundary coordinates of each BlockReference parameter, and iterate each coordinate to see if it resides within or without the other's coordinates (and the implicit lines that connect them), if either does so, return true, else return false. Depending on the coordinate system you work in, BoundingBox may not cut it, and you may need to dig through all nested entities within each BlockReference to extract all outer most coordinates from InsertionPoint (if Insertionpoint is not also one of the outer most points, that is). ... Hope this helps with your coding. Quote Link to comment Share on other sites More sharing options...
abraxus Posted September 20, 2013 Author Share Posted September 20, 2013 well that's basically what I was thinking, I'm just having a difficult time visualizing what the code would look like... maybe i'm making this more complex than it really is Quote Link to comment Share on other sites More sharing options...
BlackBox Posted September 20, 2013 Share Posted September 20, 2013 well that's basically what I was thinking, I'm just having a difficult time visualizing what the code would look like... maybe i'm making this more complex than it really is Perhaps... But even I suffer from doing that. It's part of the process, albeit a part I wish I could avoid more often than not, but still. No biggie (unless you're under a deadline! LoL). Why don't you post the code you've got so far? ... I jumped from Visual LISP to .NET API (skipping VBA), but I should be able to read enough, or offer some .NET code samples to try and help, until one of the VBA gurus comes along. Cheers Quote Link to comment Share on other sites More sharing options...
abraxus Posted September 21, 2013 Author Share Posted September 21, 2013 (edited) a bounding box wont work, because the blocks could be inserted at say a 45 degree angle... a bounding box would give a false positive of a collision i do know some .NET myself, but have never used it with Autocad, just as a web development creating ASP pages for a database interface for the most part, it's all just basic programming structure tho, so if you have any .NET examples that might help me too Edited September 21, 2013 by abraxus Quote Link to comment Share on other sites More sharing options...
abraxus Posted September 21, 2013 Author Share Posted September 21, 2013 (edited) oooo i just found this http://www.cadtutor.net/forum/showthread.php?6362-intersection-points-between-line-and-a-group-of-polylines as it turns out, the IntersectWith method supports all entity types, even blocks, so it's perfect for what i'm trying to do Edited September 21, 2013 by abraxus Quote Link to comment Share on other sites More sharing options...
abraxus Posted September 28, 2013 Author Share Posted September 28, 2013 I have made some progress with the code and I seem to have found a glitch with Autocad's IntersectWith method. Using the code example Autodesk provides for IntersectWith (which works just fine in most cases) I have slightly modified it for testing purposes. The glitch occurs only when the selected items are blocks, and at least one of the blocks is rotated at an odd angle. It comes close to the correct intersection points, but as you can see from my attached dwg file, it's not exact. It works just fine if the selected items are polylines instead of blocks (also shown in the test drawing) My question is - Is this a known glitch? Is there a way to report it to Autodesk? Is there a way to compensate for the glitch to make the points exact? In order to see the issue, open the dwg and delete all the lines that point to the items being compared, then run the code, and select the two items yourself and step thru the code if needed. Here is the code Sub Example_IntersectWith() Dim ptZero(2) As Double Dim ptLoc(2) As Double Dim f1 As AcadEntity Dim f2 As AcadEntity Dim basePnt As Variant Dim i As Integer Dim j As Integer Dim intPoints As Variant ' prompt the user to select the objects to compare ThisDrawing.Utility.GetEntity f1, basePnt, "Select an object" ThisDrawing.Utility.GetEntity f2, basePnt, "Select an object" ' Find the intersection points between the selected objects intPoints = f1.IntersectWith(f2, acExtendNone) If VarType(intPoints) <> vbEmpty Then For i = LBound(intPoints) To UBound(intPoints) ' draw a line from 0,0 to each point in the list ptLoc(0) = intPoints(j) ptLoc(1) = intPoints(j + 1) ptLoc(2) = intPoints(j + 2) ThisDrawing.ModelSpace.AddLine ptZero, ptLoc i = i + 2 j = j + 3 Next End If End Sub collision-test2.dwg Quote Link to comment Share on other sites More sharing options...
SEANT Posted September 28, 2013 Share Posted September 28, 2013 Apparently the IntersectWith function, when used with BlockRefs, only considers the Bounding Box of the reference, not the individual entities that make up the Block. If the routine requires BlockRef compatibility the Refs may need to be Exploded and a double For Each loop used to compare all geometry in one to all geometry in the other. And, unfortunately, BlockRefs may include other BlockRefs at multiple nested levels. It could get quite complex. Quote Link to comment Share on other sites More sharing options...
abraxus Posted September 28, 2013 Author Share Posted September 28, 2013 (edited) Thanks for the reply - explode the block - why did i not think of that approach? - but that WOULD solve the problem, however, i do need the original block to remain intact afterwards, as it is tied to an external database reference as for nested blocks, i am 100% sure that will not be an issue with what i need, as the blocks are very simple blocks with no nested blocks i wonder if i can explode it, process what i need to process, and then "undo" the exploding? but now i'm thinking that is not the best approach, as the block is defined as 4 separate lines, not a single polyline now that you have me thinking, maybe i could parse the block reference to get the endpoints and then create a polyline for it, using that for the IntersectWith method, since the blocks are always the same block type (different scale values) and are comprised of nothing but 4 lines in a rectangular format i am considering all approaches, as i need the absolute fastest way to do this... because of the very large amount of blocks i will be processing i am not looking for a solution that works in every single possible case of any type of block, just this specific block would be all that i would have to get working Edited September 28, 2013 by abraxus added more information/typo Quote Link to comment Share on other sites More sharing options...
abraxus Posted September 28, 2013 Author Share Posted September 28, 2013 (edited) still thinking... i should be able to create an "in memory only" polyline entity based on the size/scale of the 4 lines in the block reference without actually drawing it in the drawing, right? then pass that "in memory only" polyline to a function for processing the intersection instead of passing it the block reference - the reason i dont want to add it to the drawing is because doing that would take more time to process within the iteration - i have thousands of blocks to process for each of thousands of drawings sorry if my multiple posts are annoying anyone... i guess i am using this topic to help me keep track of my thought process for later reference, and to help out anyone else who might be interested in doing something similar - this website usually comes up first anytime i google something about "autocad vba" so it has been a great resource for me SEANT, if you could throw together a function for me that would process a "fixture_block" block reference in my attached DWG (collision-test2.dwg) and return a AcadPolyline object which doesnt actually exist in the main DWG, I would be forever grateful - but if you are busy, I suppose I will just have to research how to do that myself. again, thanks for your help getting me to "think outside of the box" (pardon the pun) Edited September 28, 2013 by abraxus Quote Link to comment Share on other sites More sharing options...
SEANT Posted September 28, 2013 Share Posted September 28, 2013 If I’m not mistaken, the VBA Explode method does not actually alter the entity upon which it was called. The method just returns an array of entities that are similar to the entities that made up the reference. It has been a while since I’ve programmed with VBA, I believe the array of objects would have the same rotation and scale as the original BlockRef – though I’m not sure if it compensates for a non-uniform scale. VBA does not offer the ability of creating entities without adding them to a database. Typically, the entities are just deleted after use. If the blocks are always just rectangles – and processing speed was critical – I’d be tempted to process the entities mathematically. Certainly this entails other complexities but it may eliminate numerous database operations that incur a heavy processing time penalty. I’ll ponder that, and post back if I come up with anything. Quote Link to comment Share on other sites More sharing options...
abraxus Posted September 28, 2013 Author Share Posted September 28, 2013 you are right on track, SEANT - you understand exactly what i'm asking, and i understand your answer, and very much appreciate your input so what you are saying is that given a selected "fixture_block" block reference, i should at least be able to process the block for the endpoints of each of the lines, store them into a memory array, and then get the coords? thank you again - you are helping me solve this complex issue - thank god we are dealing with such a simple block definition which is merely a 1" by 1" square, inserted using the scaleX and scaleY for size definition Quote Link to comment Share on other sites More sharing options...
BIGAL Posted September 28, 2013 Share Posted September 28, 2013 (edited) I am interested in this also to complete a moving object clash test, An old fashioned way with lisp was to use "Inters" function it just used 4 points not actual lines etc this way like you say your doing a mathematical method not creating objects. There should be a intersect with method using only points. (inters pt1 pt2 pt3 pt4) would return true or false for two imaginary lines. As your using a block you could add a external definition file of the outer boundary points making the block shape this way you could add more blocks and shapes but have only 1 routine and its easier to add more shapes to a external file than adding to say a hardcoded lisp or VBA etc. The rotated blocks would need a bit more to re-calc the new co-ords. Found this http://docs.autodesk.com/ACD/2013/ENU/index.html?url=files/GUID-A181D474-F817-4550-86E9-87649262FA8A.htm,topicNumber=d30e620107 Edited September 29, 2013 by BIGAL Quote Link to comment Share on other sites More sharing options...
abraxus Posted October 2, 2013 Author Share Posted October 2, 2013 just to let interested people know, my collision detection code is working flawlessly now in fact, it's working a bit TOO well, as it's detecting collisions to the ten thousandths of an inch... my company says, they dont want it to be that accurate... lol so now i need to add a quick distance tolerance check so that it doesnt detect anything less than 1/4" - which should be simple enough just compare each of the 4 corners of the "block" (which i converted to a polyline to get accurate collision points) to the collision point and find the smallest one - that is the overlap value unless you have a better idea, seant Quote Link to comment Share on other sites More sharing options...
SEANT Posted October 3, 2013 Share Posted October 3, 2013 Actually, that sounds really good. VBA’s IntersectWith method no doubt calls the native objectARX code, so is optimized pretty well. The database operations do tend to be rather heavy – conceivably you are adding Polys to the database, finding intersections, then deleting said polys – but modern processors are very fast. Your design is the most straightforward so, if it performs fast enough, I say go for it. The task presents an interesting optimization question, though. Native code (C++) is quite a bit faster than VBA. But for a VBA app to use that code it incurs numerous housekeeping penalties related to database operations. An alternative, which would require much more coding on your part, would be to do it mathematically. The attached spreadsheet demos the matrix formula for finding intersections based on line Endpoints. Of course, this would need to be repeated for all four lines. I have to imagine this same sequence is used in the native code method. My guess: VBA with the math would be faster, but would probably not be worth the effort. That “speed versus effort” benefit depends on your company, though. If there are an insane number of inserts, and an equally insane number of times this type of process needs to be run, a little extra speed may go a long way. IntersectingLines.zip Quote Link to comment Share on other sites More sharing options...
abraxus Posted October 3, 2013 Author Share Posted October 3, 2013 if you are inferring that i learn C++.... yeah every time i try to do that i fail - i am not sure what about C++ i do not understand... much like calculus.. it's like trying to read braille to me i agree that a mathematical way of doing it would be faster, but then i wouldnt be able to use the IntersectWith method as it requires entities to be passed to it - i would basically be creating my own version of the IntersectWith method, and that is just WAY over my head i havent had a chance to look at your attachment yet tho i did get the tolerance options working tonight tho... but i am still getting some false positives so i will have to debug that this weekend Quote Link to comment Share on other sites More sharing options...
SEANT Posted October 3, 2013 Share Posted October 3, 2013 Actually I didn’t mean to infer anything other than congratulation for a job well done. I posted the spreadsheet as an example of a starting point if you were interested in a math solution. There would still be much to do, but you may find it interesting and not nearly as incomprehensible as you first thought. I don’t do much VBA coding anymore, but I still hold the language in high regard. It was my introduction to programming, via Excel. As a matter of fact I think Excel VBA is the best learning environment for programming. The data and feedback is so visual, it makes some of the concepts easier to grasp. I suspect C++ is for people smarter than me, or at least have more time on their hands. C# and/or VB.NET is more my style. You, like myself, may also find the .NET languages quite a bit more accessible than C++ . Quote Link to comment Share on other sites More sharing options...
abraxus Posted October 4, 2013 Author Share Posted October 4, 2013 i do have experience with C# and .NET, but only on a fairly basic level... mostly in database applications where the object do most of the hard work for you and i am a very visual person, and also a math person, but some math is just beyond me - vba makes things simple to develop, and i'm considering just handing off my structural logic code to a more senior developer who can mimic the logic in objectARX, which i hear is much faster but to put it into quantitative terms, i have thousands of drawings to process, each drawing has about 4000 blocks to compare to one another... and with the code as written now, each of the 4000 blocks has to be compared to about 6 other blocks in each drawing... so that means my comparison routine has to run about 24,000 calculations per drawing, and each comparison has to "draw" 2 polylines in order to do it - it takes about 6 minutes for a computer with 8 processors to scan just one drawing.... that's why speed is so important - if i could get that down to like 30 seconds per drawing, that would be amazing still much faster than the 4 hours it takes for a human to do it all manually tho Quote Link to comment Share on other sites More sharing options...
reistyle Posted August 16, 2015 Share Posted August 16, 2015 I need something similar to this. Need something to control my pipe network any help is appreciated. Below is the picture of the network; http://postimg.org/image/r9srjn32n/ The green line is my main pipe and blue ones are network pipes. The red lines are hydrant points. What I want is to check whether my network drawing meet below conditions or not. And for those points which do not meet below conditions the algorithm to dye white on those network pipes. The conditions are; - All pipes should be connected to each other with 90 degrees (see pic below) http://postimg.org/image/cs1a3ms61/ - Pipes should touch each other (see pic below) Wrong connection: http://postimg.org/image/o67gjqrlf/ Correct connection:http://postimg.org/image/j9k6n52jd/ - All hydrants should touch on pipe (see pic below) Wrong connection: http://postimg.org/image/5dhzwymx5/ Correct connection: http://postimg.org/image/cs7jz64kf/ Cheers! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.