tmduk Posted December 10, 2015 Posted December 10, 2015 Hi there all First post and it's a request for help (although been a long time lurker) I've got a 3d drawing that has a load of levels in 3d positions with text displaying the height value. These are all orientated and readable in plan view. I want to create some sections using the 3d information, and what I would like to work out is the best way to manipulate the level cross (block) and associated text so that it is rotated to a side on section view. (in model space not just in a paper space viewport) I've tried using the rotate3d command on mass and can't quite get the results I'm after, basically it rotates the text so that it is now readable in the section but when selecting multiple items it rotates the whole lot around one datum rather than rotating each item around it's own insertion / justification point. in the above image, to the left is what I'm starting with levels (red) in 3d - next is the result I get from using the command rotate3d (levels in white) when they are selected in one go. the text is rotated so that it's legible but has moved away from the 3d polyline - the 2 to the right show what i'm aiming for, having manually moved them to their representative points and then rotated, however there's gonna be quite a few to rotate and shift along different sections, so it would be good to have this a bit more automated any suggestions? am I not using rotate3d to it's full potential or is this something that would need to be solved with a lisp routine? picking a temp ucs along the section line and then selecting the relative objects to rotate thanks in advance Quote
marko_ribar Posted December 10, 2015 Posted December 10, 2015 You can try to firstly set UCS to desired plane - your elevation view, then you can select text entities and iterate through selection set entmodifying each 210 DXF association code to match normal unit vector of your UCS previously set at correct 3d orientation... Quote
Jef! Posted December 10, 2015 Posted December 10, 2015 Hi tmduk. First of all, welcome to the forum. If I understood correctly, you want to do a 3D rotation of the selected entities, but you want the texts (or datum blocs?) to keep facing the same direction after the 3d rotation. That is not the result you would get with the native rotate3D. I succeeded in doing it by making a routine. It is always a good way to save time by getting cad to do exactly what you need, especially if your needs are very specific. Here my suggestions: The easiest way I came up with... i retrieved the rotation axis using (getpoint), then made a selection set with ssget. After that i used an if statement. if it is not a block/text/mtext, i use (vla-Rotate3D. If it is a block/text/mtext, to avoid the hassle of dealing with their OCS, I created a temporary point on the insertion pointof the block/text/mtext, (vla-Rotate3D the temporary point, then retrieved its coordinate property and used it to change the insertion point of the block/text/mtext (instead of rotating it). I then deleted the temporary points. If it is a block, i also attsync'ed it to replace the attributes back to their correct position. Works like a charm! It is a good thing to use trans to take coordinates in WCS even if you are currently on a ucs, because you need to feed wcs coordinates to (vla-Rotate3D. It is of course necessary to trans back p1coord to feed it to the second (getpoint), as it requires a coord in the current ucs. Here, that is the code I made (defun c:test ( / p1coord p2coord point1 point2 delta obj vlss tmppoint) ;made by Jef! 2015-12-10. (princ "\nSelect things to rotate") (if (ssget) (progn (setq point1 (vlax-3d-point (setq p1coord (trans (getpoint "\nPick 1rst rotation axis point") 1 0))) point2 (vlax-3d-point (setq p2coord (trans (getpoint (trans p1coord 0 1) "\nPick 2nd rotation axis point")1 0))) delta (mapcar '- p2coord p1coord) ) (vlax-for obj (setq vlss (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)))) (if (or (eq (vla-get-objectname obj) "AcDbMText") (eq (vla-get-objectname obj) "AcDbText") (eq (vla-get-objectname obj) "AcDbBlockReference") ) (progn (setq tmppoint(vlax-ename->vla-object(entmakex (list (cons 0 "POINT") (cons 10 (vlax-get obj 'InsertionPoint)))))) (vla-Rotate3D tmppoint point1 point2 (/ pi 2)) (vlax-put obj 'InsertionPoint (vlax-get tmppoint 'coordinates)) (vla-erase tmppoint) (if (eq (vla-get-objectname obj) "AcDbBlockReference") (vl-cmdf "_.AttSync" "Name" (vla-get-name obj)) ) ) (vla-Rotate3D obj point1 point2 (/ pi 2)) ) ) ) ) ) I made the code to do a rotation of 90degres, it could be asked by a prompt and applied instead of the (/ pi 2)... There is no error handler, i'll leave some of the fun for you. I hope it helps. Cheers Jef! Quote
tmduk Posted December 11, 2015 Author Posted December 11, 2015 Hi there, thanks for the quick responses folks, tried your routine Jef and it works well but doesn't quite give the results I'm after... to try and explain a bit more, I would like the 3d polyline / profile to remain in the same place in 3d and the text / blocks to rotate to a new orientation but remain with the same insertion point. Using the Acad command rotate3d, rotates the selected items around one baseline, I'm after rotating the elements around individual baselines but along the same plane on a UCS set up per section line. hopefully the image below will illustrate this a bit better once again thanks for your help so far... Quote
Jef! Posted December 11, 2015 Posted December 11, 2015 Based on my first routine, i just removed the the rotations of the non block/text/mtext objects. I then added the rotation in the if for the texts/mtexts/blocks. instead of picking points, I took their original insertion points. As they are rotated around an axis I created from their own 'InsertionPoint coordinate I removed the 2 points hand picking. Now you only have to select all items from a view. All the texts/mtexts and blocks will get 3d rotation around an axis aligned on the x axis, passing by their individual insertion points. With a few quick modification the result was achieved. I also removed the delta variable which i finally never used, the vlss variable as well. I added an error handler, and I actually validate that a block has attributes before doing attsync. No fun left for you. Enjoy! (defun c:3rtx ( / *error* obj tmppoint) ;3D rotate texts mtexts and blocks aound an axis aligned ;on the x axis, passing by their individual insertion points. ;made by Jef! 2015-12-11. (defun *error* ( msg ) (if (not (member msg '("Function cancelled" "quit / exit abort"))) (princ (strcat "\nError: " msg)) ) (princ) ) (princ "\nSelect objects to rotate") (if (ssget) (progn (vlax-for obj (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))) (if (or (eq (vla-get-objectname obj) "AcDbMText") (eq (vla-get-objectname obj) "AcDbText") (eq (vla-get-objectname obj) "AcDbBlockReference") ) (progn (vla-Rotate3D obj (vlax-3d-point (setq tmppoint (vlax-get obj 'InsertionPoint))) (vlax-3d-point (mapcar '+ tmppoint '(1 0 0))) (/ pi 2)) (if (and (eq (vla-get-objectname obj) "AcDbBlockReference") (= (vlax-get-property obj 'HasAttributes) :vlax-true) ) (vl-cmdf "_.AttSync" "Name" (vla-get-name obj)) ) ) ) ) ) (princ "nothing selected") ) (princ) ) ps.: I hope your goal is learning... lisp is fun and powerfull. Cheers! Jef! Quote
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.